OmniAICreator/Qiita-1.07M huggingface dataset:
サーバー上のGUIアプリを手元のWindowsPCで表示する方法

## WSL上あるいはサーバー上のGUIアプリを使えるようにする
WSLや研究室の計算サーバ上で動くGUIアプリを、手元のPCで表示できるように設定します。

### Windows側のインストール (VcXsrv Windows X Server)
- 以下からVcXsrvをダウンロードしてインストールする
[https://sourceforge.net/projects/vcxsrv/](https://sourceforge.net/projects/vcxsrv/)

- XLaunchを起動する (デスクトップ？にできたはずのXLaunchから起動)

デフォルトのMultiple windowsを選ぶ

<img width="379" alt="xlaunch1" src="https://user-images.githubusercontent.com/64639043/204116530-96f97bdd-495c-4a7d-86c2-529dcbd169db.png">

デフォルトのStart no clientを選ぶ

<img width="378" alt="xlaunch2" src="https://user-images.githubusercontent.com/64639043/204116532-ff978a62-4c26-4c52-bb38-c3a61850a5bf.png">

Extra settings。Disable access controlを有効にするのを忘れずに。

<img width="379" alt="xlaunch3" src="https://user-images.githubusercontent.com/64639043/204116534-5348c899-7bac-4cd8-8242-92b09f76ced7.png">

→ 完了

毎回XLaunchを起動するのが面倒なので、Windowsのスタートアップに登録しておくと便利。[こちら](https://rin-ka.net/windows-x-server-vcxsrv-start/)

### Ubuntu@WSL側の設定
- x11-appsをインストールする
```
sudo apt install x11-apps -y
```
- 環境変数に反映させる。~/.bashrcをVimで開いて、最終行に以下を追記して保存する
```
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
```
- .bashrcを反映させる
```
source .bashrc
```

- 動作確認。マウスに連動する目玉が出てきたら成功
```
xeyes
```
<img width="133" alt="xlaunch4" src="https://user-images.githubusercontent.com/64639043/204118509-92d7c6c8-0a77-45ad-9989-8eff1024dccf.png">
【Python】Cythonで高速化備忘録

## Cythonとは

Python 用の C言語拡張機能を簡単に実装できる言語。書き方はPythonとほぼ同じだが、C言語の関数を直接呼び出したり、C言語の変数の型やクラスを宣言できるなど可能である。PythonコードをC言語に変換し、コンパイルすればPythonの拡張モジュールが出力できる。

https://cython.org/

## 使い方
pipでCythonをインストール。

```
pip install Cython
```

高速化したいPythonコードを書く。

```python:sample.pyx
def func(int n):
    for i in range(1, n):
        i = i + 1
    print(i)
```

Cython実行用のコードを書く。

```python:setup.py
from setuptools import setup
from Cython.Build import cythonize

setup(
    ext_modules=cythonize("sample.pyx")
)
```

以下のコマンドでビルドを行う。

```
python setup.py build_ext --inplace
```

ビルドしたプログラムの呼び出し方。

```python:sample_call.py
import sample 

if __name__ == "__main__":
    sample.func(10000000)
```

## まとめ
CythonでC/C++言語でビルドして、Pythonモジュール化による高速化の備忘録でした。
Flutter useMemoizedでメモ化

頻繁に行われるレンダリングを抑え、コンポーネントの不要なレンダリングを防ぐことでパフォーマンス向上させる`useMemoized(関数の結果を保持する)`や`useCallback(関数自体をメモ化)`を使うのをお勧めします。
`state`が更新される度に再レンダリングされるが、更新前との変更に差がなければ高頻度に行われる再レンダリングを安全にスキップできます。
## メモ化とは
同じ結果を返す処理について初回のみ処理を実行→記録しておき、値が必要になったら２回目以降は前回の処理結果を計算することなく呼び出し、値を得られるようにすること。
`メモ化`によって都度計算する必要がなくなるのでパフォーマンスの最適化が期待できます。

繰り返し同じ結果を呼び出すことで同じ処理の繰り返しを避けることができるのが`useMemoized`の特徴です。
```dart
final memo = useMemoized(() => 値を計算する関数の呼び出し, [値の計算に必要な要素の配列]);
```
## 第２引数に空の依存配列(値の計算に必要な要素の配列)を渡した場合
初回の１度のみ実行され２度目以降のレンダリング時には`キャッシュ(関数を実行した結果の値)`から値を取得します。
```dart
final memo = useMemoized(() => memoFuncsion(num1 + num2), []);
```
第２引数に空の依存配列を渡した場合、初回の計算結果を保持し続けます。イメージとしては初回の計算結果を使い回す感じです。

## 第２引数の依存配列が空でない場合や、要素の値に変更があった場合

`memoFuncsion`の計算に必要な要素(`num1`または`num2`のいずれか)に変更があった場合にのみ値が再計算されます。
```dart
final memo = useMemoized(() => memoFuncsion(num1 + num2), [num1, num2]);
```
【ひとり輪読会】モノリスからマイクロサービスへ その1

読もう読もうと思っている「[モノリスからマイクロサービスへ](https://www.oreilly.co.jp/books/9784873119311/)」がぜんぜん読めないので、ここでひとり輪読会として強制的にアウトプットするきっかけを作って自分を鼓舞しようと思う。

# どんな内容の本なの？

この本は

> モノリスからマイクロサービスアーキテクチャへと移行するための実践的なガイド

と商品説明にある通り、既存のモノリスシステムをマイクロサービスアーキテクチャへ移植する仕事をしている私にぴったりな本となっています。
いまそういう仕事をしているのです。わりと大変です・・・。
なので色々勉強するためのひとつとして本書を手に取りました。

さて、タイトルの「その1」は、どこまで数字が伸びるのでしょうか・・・。

# どんな評価なの？

アマゾン評価は75個の評価が付いて、星は4.4でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2387604/b540ebf2-cdac-1469-3572-71efd2355b31.png)
まぁまぁポジティブ。

Qiita内の記事も多数あるので、皆さん関心のある本のようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2387604/4291363e-c5d7-fc04-252f-a195ae3a857d.png)

# 最後に

とりあえず決意表明としてのエントリーです。
尻切れトンボにならないように頑張ります・・・。
（自信ないな・・・）
試しにインタフェースクラスでプログラミングをしてみる。


# はじめに
lombokのアノテーションの意味を理解をしていることを前提として記事を書いています。
解説はしない。メモ用だ。


# 簡単な setter/getter 

二通りの設計がある。
* 従来のメソッド
* チェーンメソッド

前者は、一行/一メソッドである。可読性重視コーディング方法、メソッドを細かくまとめたメソッドを書いていくことによって解消される。

後者は、一行/複数メソッドである。適切なフォーマットをしなければ可読性が下がってしまう。それとチェーンメソッドの設計( Builder クラス)がとんでもなく難しい。
これにパラメータの型を使用しているクラス（Map, Supplierなど）とかを使うと難易度、爆上がりか？

後者のチェーンメソッドで設計する。

## 従来のメソッド
古いライブラリ　や　初心者向け などで見かけるコーディング設計
```Java
@Data
public class Test 
implements ITest {
    public int num;

    public void testcode() {
        // print -> 100
        this.setNum(100);
        this.getNum();    
    }
} 

public interface ITest {
    void setNum(int num);

    int getNum();
}
```
## チェーンメソッド
jquery などで見かけるコーディング設計
```Java
@Data
@Accessors(fluent = true)
public class Test 
implements ITest {
    public int num;

    public void testcode() {
        // print -> 500
        this.num(500).num();    
    }
} 

public interface ITest {
    ITest num(int num);

    int num();
}
```

# プログラミング

lombokの@Dataによってかなり手間が省ける実装方法。
こういう方法にすごい憧れてたから今回は、とても満足した。
いちいち
```Java
public interface ICalc<NUMBER extends Number> {
    ITest num(NUMBER num);

    NUMBER num();

    //
    default ITest add(NUMBER num){
        return this.num(num() + num);
    }

    default ITest sub(NUMBER num){
        return this.num(num() - num);
    }

    default ITest mul(NUMBER num){
        return this.num(num() * num);
    }

    default ITest div(NUMBER num){
        return this.num(num() / num);
    }
}

@Data
@Accessors(fluent = true)
public class CalcImpl
implements ICalc<Integer> {
    private Integer num;
}
```
Pythonユーザーを襲うAtCoderの初見殺し

# はじめに
AtCoderのSteak Sumも126日に達し、レートも緑になったということでAtCoder関係の記事もどんどん書いていこうと思います。AtCoderをやっているとアルゴリズムは合っていると思うのに言語仕様の問題でACできないということが多々あります。そんな初見殺し的な要素をPythonに関して紹介できたらと思います。

## その１再帰上限　RecursionError
UnionFindや深さ優先探索を実装するときに起きがちなエラーです。
これは初見だとまず気がつかないと思います。
というのも問題ページのテストケースではまずこのエラーが生じることはないからです。
<a href="https://note.nkmk.me/python-sys-recursionlimit/">このサイト</a>によると大体未設定では1000ぐらいまでしか再帰できないようになっているそうです。実際に提出してみると<font color="Orange">Re</font>とだけ表示されて何が原因なのか自分の環境ではなかなか割り出せません。RecursionErrorが起きてます！
```Python
import sys
sys.setrecursionlimit(10000000000)
```
みたいな感じで再帰上限を増やしてあげましょう。

## その２　大きな桁の演算は遅い
これは有名ですね。
主に10^18とかので掛け算とかをしようとすると<font color="Orange">TLE</font>をもらう可能性が高いです。
**ただしシフト演算(<<)は桁数を増やしてもあまり遅くならない**ので注意が必要です。それを利用した問題がABCのE問題の過去問にあって難しかったです。

## その3 モジュロ逆元
モジュロ逆元についてご存知ない方は<a href="https://www.creativ.xyz/modulo-basic/">こちら</a>をご覧ください。
Pythonにはモジュロ逆元を求める関数を組み込みのpow関数で使用することができます。

```Python
mod = 10**9+7
pow(7, -1, mod)
```

と書くと

```math
    7x ≡ 1(mod 10**9+7)
```

となるxを求められます。
しかしこの関数AtCoderのPythonでは使えるのですがPyPy3ではなぜか使えません！（なんで？）
この前の日曜日、間違えて提出してペナルティをもらい、それがなければ1000番以内になれてました。

# 最後に
他にも何かあると思うので、思いつき次第記事にしていこうと思います。

参考リンク
クリエイティヴなブログ ふるやんのほぼ競プロ日記 競技プログラミングにおける剰余の基礎と mod 逆元
https://www.creativ.xyz/modulo-basic/


note.nkmk.me Pythonの再帰回数の上限を確認・変更
https://note.nkmk.me/python-sys-recursionlimit/
AWS Well-Architectedの全ての柱を図解化してざっくり内容をまとめる

# 内容
AWSのベストプラクティス環境構築の指針として`Well-Architected`があります。これらはホワイトペーパーにまとめられていますが、技術的な要素だけではなく、ビジネス的な観点、組織や運用プロセスに関する項目もあり、AWSの資格試験などを通して学習しただけでは内容も分かりづらい箇所があったため、一度体系的に学習を行い、内容を図解化して何が書いてあるかをざっくりとまとめました。

# 資料
`Well-Architected`は６つの柱がありますが、下記2つの資料に分けて解説を行っています。
両方ともJAWS-UG朝会で発表させて頂いたものですが合わせて100ページ程度の内容となっています。

* `信頼性の柱`・`パフォーマンス効率の柱`・`コスト最適化の柱`・`持続可能性の柱`

https://speakerdeck.com/toru_kubota/well-architected2

* `運用上の優秀性の柱`・`セキュリティの柱`

https://speakerdeck.com/toru_kubota/well-architected

![スクリーンショット 2022-11-24 9.19.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/38a72b22-524a-740d-d3dd-72b625a16511.png)

# 資料の見方

## 各柱の概要確認

各柱に「こういうポイントを意識して設計しましょう」という`設計原則`と「設計原則を実現するために具体的に何をやればいいか（ベストプラクティス）」の記載がある`定義`があります。本資料の中では「具体的に何をやればいいか（ベストプラクティス）」の`定義`について解説しています。
下記は`信頼性の柱`の例になりますが、`基盤`・`ワークロードアーキテクチャ`・`変更管理`・`障害の管理`の4つが定義されているのでここを詳しく見ていく形になります。

![スクリーンショット 2022-11-24 9.25.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/3382eb0a-777f-9307-acc9-cdb58e371732.png)

## 各柱の定義確認

下記は`信頼性の柱`の`基盤`の例になります。基盤という定義の中で考慮する点は大きく`サービスクォータ管理`・`ネットワークトポロジー計画`の2つがあります。
![スクリーンショット 2022-11-24 9.47.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/c8376b7b-1bfa-40e8-23a0-eae5563567e2.png)

下記は上記の中の`ネットワークトポロジー計画`の箇所になります。この中でさらに青丸で記載の考慮点があり、それを表す簡単なアーキテクチャ図があります。各柱のどの`定義`を説明しているか（今どこにいるのか??）は、右上のオレンジ色の箇所を見ることで分かります。なお本資料は概要のみを記載していますので、各項目の詳細に関してはホワイトペーパーを参照下さい。

![スクリーンショット 2022-11-28 10.35.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/c986cf96-00e6-f268-f063-ef264b5b2cd3.png)

## 各柱のまとめ
最後に各柱のまとめがあります。各`定義`毎にざっくりと具体的に何をやればよいかをまとめたものになっています。

![スクリーンショット 2022-11-24 9.25.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/079d26fa-de57-c68e-da6e-226d8b461406.png)

# Well-Architectedの導入について

## IT部門以外との連携

`Well-Architected`の導入については<font color="Red">「技術的な視点」</font>が必要になるもの以外にも<font color="Red">「ビジネス的視点」</font>・<font color="Red">「組織的な視点」</font>が必要になるものなど、様々な観点から考える必要があります。下記は`運用上の優秀性の柱`の`組織`の箇所になりますが、「外部環境、内部環境を分析して組織としての優先順位を決める」、「それを実現していくための最適な組織モデルを選択して責任範囲を定義する」というフェーズになります。その他`コスト最適化の柱`の中では最適なコストモデルの選択やコスト配分決定のため、ファイナンス部門との連携や事業部制組織の場合は各事業部門との連携が必要になることがあります。

![スクリーンショット 2022-11-24 10.53.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/fcd3e88a-3eb4-9abf-f939-b71f56d6bdf8.png)

![スクリーンショット 2022-11-24 10.53.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523652/f876dc17-a284-9ed7-4daf-f414a2c1cc00.png)

## 全てを教科書通りにやらなくてよい
ベストプラクティスであるため、全てを書いてある通りに実施する必要は無いかと思います。これは`Well-Architected`に限らず`ITIL`や`SRE`など他のフレームワークと同様です。ただし、例えば「ベストプラクティスA」というものがあって、それを実装していない場合、下記の2つのパターンでは大きく意味合いが異なります。

* 「ベストプラクティスA」を知らなくて実装していない
* 「ベストプラクティスA」を検討をしたが、要件・環境などから不要と判断し実装していない

上の場合はただ実装していないだけですが、下の場合は<font color="Red">「実装しないという設計がされた」</font>ことになります。
また、検討のフェーズや結果を文章化していくことの積み重ねが会社として大きなナレッジを形成していくと思います。
このような観点から`Well-Architected`などのフレームワークを学習するこは無意味では無いと感じております。
集客の目的で、モーションセンサーを用いて簡易版サイネージを作ってみた

<h1>目的</h1>
モーションセンサーをマーケティングに活用したい。

<h1>概要</h1>
人の動きを検知したら、指定の動画を再生する。再生回数を集計して、広報に活用する。
イメージは：

![プレゼンテーション1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007201/56960b36-4de4-9213-a248-f3e354610203.jpeg)


![IMG_1220.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3007201/3f5b9f3a-5008-c465-685a-8fc1cff87533.jpeg)


<h1>必要なもの</h1>
１．obniz board

２．モーションセンサー
３．YouTube API（iframe）
４．Wi-Fi

コードは適度に書いたものなので、参考にならないかもしれない。
```signate.html

  <!-- youtube -->
  <div id="player"></div>
  <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>

<script>

  obniz.onconnect = async function () {

    // motionセンサーをobnizに接続    
    sensor = obniz.wired("HC-SR505", {vcc:0, signal:1, gnd:2});
  }

  obniz.onloop = async function() {
    //Youtube API
    $(function () {
      var w = $(window).width()
      var h = $(window).height()
      var videoId = '指定したいyoutube動画のid'

      var tag = document.createElement('script');
      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    
      var player;
      window.onYouTubeIframeAPIReady = function() {
        player = new YT.Player('player', {
          width: w,
          height: h,
          videoId: videoId,
          playerVars: {
            rel: 0,
            autoplay: 1,
            loop: 0,
            playlist: videoId,
          },
          events: {
            'onReady': onPlayerReady,
          }
        });
      }
      function onPlayerReady(event) {
        event.target.setVolume(0);
      }
    });
   });

</script>
```

<h1>課題</h1>
モーションセンサーはやっぱり限界があるので、今後、カメラを使って、性別、年齢を検知したうえて、異なる動画コンテンツを再生してみる。
【Ansible + Semaphore】Inventory とは【Ansible 用語、Semaphore 設定編】

[Ansible](https://ja.wikipedia.org/wiki/Ansible_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2)) 用語のうち `Inventory` の項目についての概略です。Ansible の GUI の 1 つである [Semaphore](https://www.ansible-semaphore.com/) を使う際に、悩んでしまったので、自分のググラビリティ（備忘録）として。

## Inventory とは

インベントリ（`Inventory`）とは、`Ansible` で**接続する先のホスト名一覧**を設定する項目です。この項目で使う秘密鍵やパスワードなどの設定は、事前に `Key Store` の項目で登録しておく必要があります。

- [Inventory](https://docs.ansible-semaphore.com/user-guide/inventory) | User Guide @ docs.ansible-semaphore.com
- [How to build your inventory](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html) | Inventory | Guide @ docs.ansible.com

### `Semaphore` の `New Inventory` で設定する項目

- `Name`:
    - ホスト名の一覧が認識できる名前を付けます。
- `User Credentials`:
    - SSH 接続時に使う秘密鍵もしくはパスワードの登録名を選択します。事前に `Key Store` の項目で登録しておく必要があります。
- `Sudo Credentials (optional)`:
    - SSH 接続後、管理者権限に昇格させる（`sudo` を利用する）際に必要な秘密鍵もしくはパスワードの登録名を選択します。事前に `Key Store` の項目で登録しておく必要があります。（オプション）
- `Type`:
    - 登録するホスト名の書式を選択します。書式には 3 種類あります。
        1. `Static` 
            - [`INI` 形式のホスト名一覧](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#defining-variables-in-ini-format)です。`Semaphore` の GUI 上から設定できます。
        2. `Static YAML`
            - `YAML` 形式のホスト名一覧です。`Semaphore` の GUI 上から設定できます。
        3. `File`
            - `Semaphore` がアクセスできる先に保存されているファイルのパスを指定します。

### ホスト名一覧の書式設定例

#### INI形式（Static）

```ini:INI形式（Static）の例
[website]
172.18.8.40
172.18.8.41
    
[atlanta]
host1 http_port=80 maxRequestsPerChild=808
host2 http_port=303 maxRequestsPerChild=909
```

#### YAML形式（Static YAML）

```yaml:YAML形式（Static YAML）の例
website:
  hosts:
    172.18.8.40:
    172.18.8.41:
    
atlanta:
  hosts:
    host1:
      http_port: 80
      maxRequestsPerChild: 808
    host2:
      http_port: 303
      maxRequestsPerChild: 909
```

#### グループ化などの、より高度な（細かい）設定

- [Inheriting variable values: group variables for groups of groups
](https://docs.ansible.com/ansible/latest/inventory_guide/intro_inventory.html#inheriting-variable-values-group-variables-for-groups-of-groups) @ docs.ansible.com

```ini
[atlanta]
host1
host2

[raleigh]
host2
host3

[southeast:children]
atlanta
raleigh

[southeast:vars]
some_server=foo.southeast.example.com
halon_system_timeout=30
self_destruct_countdown=60
escape_pods=2

[usa:children]
southeast
northeast
southwest
northwest
```

```yaml
all:
  children:
    usa:
      children:
        southeast:
          children:
            atlanta:
              hosts:
                host1:
                host2:
            raleigh:
              hosts:
                host2:
                host3:
          vars:
            some_server: foo.southeast.example.com
            halon_system_timeout: 30
            self_destruct_countdown: 60
            escape_pods: 2
        northeast:
        northwest:
        southwest:
```
PHP エラーや警告が出る処理を書いても処理が止まらないようにする

:::note info
この記事は[miriwoお一人様 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/miriwo)の8日目の記事です
:::

# 概要

- PHPの式にて値が得ることのできるものの場合、エラーになる処理を書いても処理が止まらない様にする方法をまとめる。

# 注意

- エラーで止まってしまう処理に本記事で紹介する内容を記載しても根本解決にはならないので注意すること。

# 方法

- 当該処理の前にエラー制御演算子`@`を設置する。

# 具体例

- 下記のような処理があったとする。

    ```php
    <?php

    echo $hoge;

    $fuga = 1;
    echo $fuga;
    ```

- 上記を実行すると当たり前だが`$hoge`は未定義状態で呼び出されているので下記のエラーが出る。そして`echo $hoge;`で処理が止まるので、その後の処理は実行されない。

    ```
    PHP Warning:  Undefined variable $hoge
    ```

- 下記の様にエラー制御演算子を記載すると処理が止まらず走り切る。

    ```php
    <?php

    echo @$hoge;

    $fuga = 1;
    echo $fuga;
    ```
AWS Ec2 Nginx Timeout 設定(忘備録)

# 経緯
### 処理時間が60秒超えたら、`504 Gateway timeout`が発生する

# 対応
### 対応1.
 - Ec2に連結されているApplication Load Balancer の問題かと思い、```アイドルタイムアウト3600 秒```で設定する

### 対応2. 
 -  `対応1`を行ってたら、3分後に同様のタイムアウトが発生する
 - ちなみにタイムオーバする処理でDuplicateエラーが発生してた（内部ロジックの都合）

### 対応3.
 - [ネッドで調べ](https://www.google.com/search?q=nginx+%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88&oq=nginx+%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%A2%E3%82%A6%E3%83%88&aqs=chrome..69i57.6350j0j7&sourceid=chrome&ie=UTF-8)てみたら下記の設定で行っていた

```
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_send_timeout 300;
```

### 対応4.
 > 上司：サーバ設定は内容知った上で設定しましょ

1. [proxy-connect-timeout](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout)
プロキシサーバの連結する時間

2. [proxy-send-timeout](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout)
プロキシサーバにリクエストする時間

3. [proxy-read-timeout](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout)
プロキシサーバから回答を待つ時間

うちらの場合、バックエンド側の処理が長かったので、アップロードや連結時間などは関係なかった
```
proxy_read_timeout 300;
```
こちらのみの設定で遠かった


# 追記
- ~~proxy_read_timeoutの基本設定が60秒だが、レスポンスがなければ1分間リトライしている模様~~
- ~~リトライ3回行ってたらバックエンド動作が動いているかどうか関係なく接続を切る模様~~

# 2022/12/18 追加
- 上記の問題はブラウザーの問題でした。下記の記事を確認してほしいです

https://qiita.com/wk0012345/items/9e0f12dd99c1ef9fa566
CISM合格メモ

# きっかけ
今年度の OffJT の目標で CISM取得と書いたが、上期に何もやっていなくてお尻を叩かれたので慌てて勉強を始めた。

# 基礎知識
- MSS/SOC業務を 10年程度
- 情セキュ/情シスを 2年程度
- CISSP保持

# 勉強ツール
- 試験サンプル問題＆解答・解説集 第10版 ( https://store.isaca.org/s/#/store/browse/detail/a2S4w000005FRB3EAO )
円高で高かった。。

問題集のみを使った。
CISM試験レビューコース ( https://www.isaca.gr.jp/cism/ ) も受講したかったが、土日連続して時間を作るのが難しかったため、受講なし。

## 試験サンプル問題＆解答・解説集 第10版
- 各ドメイン 200問程度と模擬試験(150問) が収録

まず、全問題 2周し、間違えた問題に付箋を付けていった。
その後は、付箋がついている問題を中心に、試験日まで繰り返し解いていく。

答えを覚えるのではなく、問題の意図と選択肢の各回答を紐づけていく。
実務で経験していたドメイン4 は、「CISM で求められている立場」と「実務の立場(経験)」のギャップをなくすのに少し苦労した。

# 試験当日
## 持ち物
- 身分証明書 1点 (運転免許証)
- 食料
    - チョコレート
    - 飲み物

4時間と長丁場なので、途中で当分補給をしようかと考えていたが、結果的には休憩を取らずに終わらせた。

## 試験
試験の内容は NDA を結んでいるため記載することはできない。
ただ、ほかの方も書かれているとおりで、問題集の内容を暗記していれば解けるという問題ではなかった。
受け終わった身としても、どういう勉強法が合格に一番近いのかは不明なままである。

もともと「1周終わらせたら休憩して見直し」を予定していたが、1周終わった段階で 1時間半弱(50問30分ペース)だったので、そのまま見直しに入った。

CISSP の時もそうだったけど、消去法で 2択までいくけど、どっちも決め手に欠ける、みたいな問題が多く、気持ちよく答えられる問題はあまりなかった。

ペース的には
00:00 開始
　　　150問
+1:30 1周目終了
　　　150問
+0:30 2周目(見直し)終了

## 試験終了
完了ボタンを押した後、「合格」の文字が見えて一安心。

# 試験後
試験から 10日後に、無事合格の通知が届いた。
スコアは以下で、勉強時の体感のとおりドメイン4 のスコアが悪かった。

|    |  SCORE  |
| ---- | ---- |
|  Information Security Governance  |  696  |
|  Information Security Risk Management  |  563  |
|  Information Security Program  |  658  |
|  Incident Management  |  545  |
|  OVERALL SCORE  |  611  |

この後、CISM認定の申請出したり、きちんとCPEを稼いだりと、やらないことがもりもりだけど、きちんと片付けていく。
アジャイル開発でのQA活動で思ったこと


私は2019年に認定スクラムマスターの資格を取得し、これまでに複数の案件でアジャイル開発における品質保証活動に従事してきました。

アジャイル開発は従来型開発（ウォーターフォール開発など）と異なり、"スピード"が早いことが特徴としてあります。
従来型開発に比較して、要件定義から実装・リリースまでの期間が早いアジャイル開発でのQAを複数やってきて、
「ここが従来型開発とは大きく違ったこと」について思ったことをざっくばらんに紹介したいと思います。

# ①開発ドキュメントが（ほとんど）ない
以下に掲載しているのは、有名な「**アジャイルソフトウェア開発宣言**」です。
このアジャイルソフトウェア開発宣言を読む時に、人によっては左記を軽視する方もいらっしゃいます。
「<font color="red">とにかく動くソフトウェアを！</font>」となってしまうことが多々あり、
そうなってしまうと起きてしまうのが、「**ドキュメントが存在しない**」もしくは「**ドキュメントはあるが更新されていない**」です。

従来型開発でのＱＡは仕様書などのドキュメントからテストを進めていきますが、
アジャイル開発案件では、その方法が取れないので、その解決方法を考えることが重要なのだなと思いました。
※どのように解決したかを④に記載しようと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288745/0f0c602c-242a-4db8-e8bb-02a97e1323ef.png)
参考：[アジャイルソフトウェア開発宣言](https://agilemanifesto.org/iso/ja/manifesto.html)




# ②それぞれ独自のアジャイル文化を持っている
アジャイル開発とは、「アジャイルソフトウェア開発宣言」を基本とする開発手法のことで、
具体的にどのようなプロセスで開発を行えばいいのかまで言及されていません。
そのため、数多くのフレームワークが存在します。
代表的なものだと **「スクラム」** です。

ただ、このスクラムに「**カンバン**」を合わせた 「**スクラムバン**」というやり方があったり、独自の進化を遂げていたり、
企業や組織、チームによってさまざまなアジャイル開発のプロセスが存在します。

従来型開発では、ある程度QAプロセスが似通った現場が多く、取り組み手法をほぼそのまま横展開することができました。
アジャイル開発案件では、組織が変わると文化が異なる場合が多く、
各組織のにあったQAプロセスを構築する必要があるだと思いました。
（合わないQAプロセスでやっていくと、開発者とQAとでスピード感が違ってしまい不協和音をとなってしまう　と思っています。）

# ③QAエンジニアに求められている領域が広い
これまで多くの現場でQAエンジニアとして活動してきて、
多くの場合が「システムテスト」や「ユーザー受入テスト」などのUIに対してのQA活動がメインでした。。
これがアジャイル開発案件では、場合によっては要件定義の場からQA目線でのコメントを求められたり、
デザインを決める場に同席したりとこれまでよりも、上流工程から関わる機会が増えました。

いわゆる **シフトレフト** の取り組みが非常に大切で、単にテストの事を考えるのではなく、
「<font color="red">利用者の価値</font>」をどれだけ考えてQA活動するのかを要求されるのだと思いました。

# ④これまでのQA技術をより進化させる必要がある
従来型開発のプロセスが異なること、そのプロセスに合わせられる柔軟性、幅広い知識が必要なことがより重要なのだと思っています。
そのためには、QA技術をより進化させる必要があるのだと思いました。
具体的には、モデルベースドテスト（MBT）や探索的テストにおけるレベルアップ。

ドキュメントがないシステムをテストする上でモデル化は非常に有効な取り組みだと思っており、
このモデルを上手く活用することで、より早くより価値を提供できるQA活動が出来るのではと思っています。
また、ドキュメントが無くても実施できる探索的テストについても有効だと考えています。
もちろん、ドキュメントがあればこれまでの取り組み方でも良いと思いますが、それではスピードについていけないこともあります。

私個人の取り組みの中で、よりスピード感を追求している組織では、このモデルベースドテストと探索的テストはとても有効的に活用が出来ました。

その他にも、何か有効な手段はないのかと日々考えながらQA活動をしており、
もっともっとQA技術を進化させる必要があると日々考えています。

# おわりに

ここまで、私個人が思ったアジャイル開発におけるQA活動についてを書いてみました。
まだまだアジャイル開発におけるQA活動は課題が多く、解決すべき問題も多岐に渡ります。

正直なところ、QA活動としてやることは変わっていないと思っていますが、
考え方や意識は異なっていて、そこに上手く合わせることが大切なのだと思っています。

いわゆる「アジャイルマインド」ですね。
この「アジャイルマインド」のQA版を考えられれば、アジャイルQA人材育成にも使えると思っています。
これについては、またどこかでまとめられたらと思っています。

以上
Swift TopLeft座標上で点を回転させる

# 経緯
移動・回転・伸縮させたViewをUIGraphicsImageRendererで画像化する時に
SwiftUIがくれるViewのposition(親Viewの左上を原点とした子Viewの中心点の位置)ではなく
親Viewの左上を原点とした子Viewの左上の点の位置がほしかった。

point: 親Viewの左上を原点として、回転させる点の位置
centerOfRotation: 親Viewの左上を原点として、回転の中心点の位置
angle: 回転角
scale: 回転後にcenterからの距離を伸縮したい場合に使用

# 完成品
```swift
func rotatePointOnTopLeftCoordinates(point:CGPoint, centerOfRotation center:CGPoint = CGPoint(x:0,y:0), 
angle:Angle, scale:CGFloat = 1)->CGPoint{
    let x = center.x -   ((point.x-center.x) * cos(angle.radians) - (point.y-center.y) * sin(angle.radians)) * scale
    let y = center.y -   ((point.x-center.x) * sin(angle.radians) + (point.y-center.y) * cos(angle.radians)) * scale
    
    let rotatedPoint = CGPoint(x: x, y: y)
    
    return rotatedPoint
}
```


# 解説

原点を中心に点A(x:a,y:b)を角度θだけ回転させた点P(x:X,y:Y) は
     X = acosθ - bsinθ
     Y = asinθ + bcosθ
     
点A(x:point.x,y:point.x)を回転の中心点center(x:center.x,y:center.y)から見たいので引く。
     a = point.x-center.x
     b = point.y-center.y
     
回転させた後scaleを掛けて伸縮させる。
     原点視点に戻したいのでx:center.x,y:center.yを足す。
AWS::CDK::Metadataの中身

AWS::CDK::Metadataっていう謎データがAWS CDKでデプロイされると生成されるわけだが、当然、長いテンプレートでは見てるだけ疲れるという意見が大半だろう

では、その中身というのは何なのだろうか

AWS::CDK::Metadataリソースには、「Analytics」というただ1つのプロパティが定義されており、そこには「v2:deflate64:」で始まる文字列がある。

これはAWSに統計情報を提供するためのリソースである。さて、その中身というのはどうなっているだろうか？

まず、後ろの文字列はBase64エンコードされた文字列なので、これをデコードする。当然、バイナリなので中身はぐちゃぐちゃであるが、「1F8B0800」で始まることから、これはGZIPエンコードされていることが推定できる。

Deflate64と聞くと馴染みがないとは思うが、要するに小さいデータであればDeflateとだいたい同じはずなので、普通に展開する。すると、「どのバージョンを使っているか」「どのパッケージを使っているか」「どの言語で作成したか」の情報が出てくる。

まず最初の!より前がCDKのバージョンである。次に、CDK 1系であれば`@aws-cdk/`という文字列の後に利用しているリソース群が入っている。CDK 2系であれば`aws-cdk-lib.`という文字列の後に利用しているリソース群が入っている。色々中括弧を挟んでリソースが入れ子になっているが、最終的にそれらが終わるとカンマがくる。その後に処理系とそのバージョン番号がスラッシュ区切りでくる。その後、最後に`!jsii-runtime.Runtime`という文字列がくるが、これはJavaScript側の話だろうというのは想像がついたが、それ以上の情報はわからない。

だいたい、これらの情報をオフにする方法というのが出てくるが、これは空のテンプレートにもかかわらず大量のデータが吐き出されてうざいから、というのが理由である。だが、こうしてみればわかるが、機密情報は(一応)入ってないことがわかる。
HTML, CSS, JavaScriptで掲示板システムを作ってみた【その4-imgとvideo】

# 初めに
<a href="https://qiita.com/gakusei_programmer/items/54302b34a7e5afe7a70f">前回の投稿</a>から一年半程度空いてしまいました。主に院試や卒論といった学生の仕事のメインの方に時間を取られてしまい、なかなか記事の投稿に着手できていませんでした。
しかし、ここ数ヶ月で当掲示板やゲーム制作など、自分がプログラミングでもともと表現したかったものを作成するという目標が果たせそうなのでここにアウトプットしていきたいと思います。

# imgとvideo
まず初めに<a href="http://colorful-wall.com/board/boards">作成したウェブアプリ</a>をご覧ください。
書き込みテストのスレッドに適当なスクリーンショットの画像と動画がアップロードされていると思います。
これは現在ChromeブラウザとSafariで同じように表示されているはずですが、作成当初はSafariでは表示されるがChromeでは表示されないというバグを含んでいました。
キャッシュの削除等色々試してみた結果**safariではimgタグで画像も動画も扱える一方でChromeではimgタグでは画像のみで動画はvideoタグを使わないと動画を再生できない**らしいことが判明しました。
私のようにMacで開発中の方は是非違うブラウザでも作成したウェブサイトを表示してみてください！
ちなみに無音での自動再生は<a href="https://www.omakase.net/blog/2021/04/video.html">こちらのサイト</a>に教えていただいたところ次のように書けば実行できます。
  
    <video src="○○.mp4″ autoplay muted></video>

Safariだとimgタグのsrcを動画にするだけで自動的にこのモードになると思います(そんな挙動でした)。



参考リンク
videoタグを使って動画を埋め込む
https://www.omakase.net/blog/2021/04/video.html
【Python】try～except文でsys.exitをしたときにfinallyで書いた内容が実行されるか

## 結論：される

``` python
import sys

print("start")

try:
    print("try")
    raise Exception

except:
    print("except")
    sys.exit(1)

finally:
    print("finally")

print("end")
```

``` shell
$ python3 ./test.py 
start
try
except
finally
```
Kubernetesクラスターを構成しているubuntu 20.04のネットワークトラフィックをMRTGでグラフにする

# はじめに

Ubuntuにsnmpdを導入し、CentOS7側のmrtgからデータを取得し、グラフにしてみました。

Ubuntu側はKubernetesクラスターのノードなので、``ip link | wc -l``の出力は82とかになっています。
今回はとりあえず全部のトラフィックを取得してグラフにすることを目指します。

# 環境

## MRTGホスト 1台

* OS: CentOS7
* HW: HP MicroServer gen8
* IP: 192.168.1.1

## SNMPdホスト (K8sクラスター) 4台

* OS: Ubuntu 20.04 (LTS)
* HW: TX120 S3p
* IP: 192.168.100.51-54

# 作業ログ

## Ubuntu側にsnmpdを導入する

ansibleを使って制御するようになっているので、適当に設定を行なって、全台にsnmpdパッケージを追加しました。

次のような/etc/snmp/snmpd.confファイルを作成し、配布しています。

```text:/etc/snmp/snmpd.conf
## $ sudo grep -v ^# /etc/snmp/snmpd.conf  | grep -v ^$ の出力

sysLocation    Kubernetes Cluster Host
sysContact     YasuhiroABE <yasu@yasundial.org>
sysServices    72
master  agentx
agentaddress  udp:161,udp6:[::1]:161
view   systemonly  included   .1.3.6.1.2.1.1
view   systemonly  included   .1.3.6.1.2.1.25.1
rocommunity  public 192.168.1.1
rocommunity  public localhost
rocommunity  public default -V systemonly
rocommunity6 public default -V systemonly
rouser authPrivUser authpriv -V systemonly
```
主な変更点は、以下のとおりです。

* sysLocationとsysContactを適当に編集した
* agentaddressで161ポートを開放した
* rocommunityにmrtgホストを追加した

## CentOS側のMRTGホストの設定

作業自体は、シンプルにcfgmakerとindexmakerを実行した。

```bash:mrtgの基本的な設定
$ cfgmaker public@192.168.100.51 public@192.168.100.52 public@192.168.100.53 public@192.168.100.54 | sudo tee /etc/mrtg/mrtg.conf
$ echo "WorkDir: /var/www/mrtg/" | tee -a /etc/mrtg/mrtg.conf

$ sudo indexmaker /etc/mrtg/mrtg.conf | sudo tee /var/www/mrtg/index.html
```

CentOSではmrtgコマンドの定期自動実行は設定されないため、手動で/etc/cron.d/mrtgファイルを配置した。([参考情報 Server World - CentOS7 MRTGインストール](https://www.server-world.info/query?os=CentOS_7&p=mrtg)) 

## Ubuntu 20.04をMRTGホストにした場合の設定

```bash:mrtgの基本的な設定
$ cfgmaker public@192.168.100.51 public@192.168.100.52 public@192.168.100.53 public@192.168.100.54 | sudo tee /etc/mrtg.cfg

$ sudo indexmaker /etc/mrtg.cfg | sudo tee /var/www/mrtg/index.html
```
Ubuntu 20.04をホストにした場合には、/etc/cron.d/mrtg ファイルは配置されていたので、手動で作成する必要はなかった。

## Ubuntu 22.04をMRTGホストにした場合の設定 (24.04でも同様)

mrtg.cfg が CentOS と同様に /etc/mrtg/ 以下に配置するように変更されている。

```bash:mrtgの基本的な設定
$ cfgmaker public@192.168.100.51 public@192.168.100.52 public@192.168.100.53 public@192.168.100.54 | sudo tee /etc/mrtg/mrtg.cfg

$ sudo indexmaker /etc/mrtg/mrtg.cfg | sudo tee /var/www/html/mrtg/index.html
```
Ubuntu 22.04をホストにした場合には、/etc/cron.d/mrtg ファイルは配置されていないが、/etc/init.d/mrtg が配置されて systemd の管理下にある。

そのため次の要領でmrtgを定期的に実行する。

```bash:
$ sudo systemctl enable mrtg.service
$ sudo systemctl start mrtg.service
```

# 結果の閲覧

CentOS, Ubuntuのいずれをホストにしても、/var/www/mrtg/ディレクトリにファイルが配置されているため、rsyncなどで手元のシステムにコピーし、内容を確認しています。

以上
話のネタになる名刺を作リスマス

ごきげんよう！あるがです。
皆さんはもうメリーな気持ちになっている頃でしょうか？

この時期にスーパーに行くと
メリーなものと、ハッピーなものが混在して陳列していて
華やかで、面白いですよね。

さて、皆さんは、自分の名刺を持っていますか？
会社の名刺ではなく個人の名刺です。
まだ、もっていない？

でしたらこんな名刺を作ってみるのはいかがでしょうか？
個人事業主の方もおすすめです。

## そもそも名刺のサイズって?
これには厳密にこうしなさい、というサイズ指定はありませんが、
もっともポピュラーなサイズが `55×91mm` のようです。

> 日本で使われている名刺は、「55×91mm」が標準サイズとなっています。名刺の寸法は明治時代以来、尺貫法に基づいて10種類以上の独自規格がありましたが、1959年1月のメートル法施行以降は寸分からcm・mmに換算されて現在の寸法になりました。現在、一般に使用されている名刺のサイズを規格化した人物の1人が、株式会社 山櫻の創業者、市瀬邦一氏だといわれています。

> 男性は4号（55×91mm）、女性は3号角丸（49×85mm）、花柳界の女性は小型4号角丸（39×70mm）あるいは小型3号角丸（33×60mm）というのが一般的でしたが、1986年に男女雇用機会均等法が施行され浸透するに従って、男女ともに4号名刺が多く使われるようになりました。この寸法は日本の和紙の寸法に由来すると同時に、ほぼ「黄金比※1」でもあることが普及し定着してきた要因の一つと考えられています。

> ※1　黄金比
名刺のサイズには「黄金比1：（1＋√5/2)」が影響していると言われており、これは古くから安定した美しい比率だといわれています。パルテノン神殿やピラミッドなど歴史的建造物や美術品、また、自然界にも見出すことができると言われ、様々なカードのサイズにも使われています。55×91mmというこのサイズは、19世紀中頃にフランスの写真家デリスデリが考えた写真付名刺が元になっていると言われています。日本では書籍の四六判に由来し、その4分の1が当時の名刺1寸8分×3寸に近く、昭和34年のメートル法執行後、ミリ換算した数字が55×91mmです。

[TSUTAFU様より引用させていただきました](https://tsutafu.yamazakura.jp/shop/pages/blog-0013.aspx)

これは、`B8サイズとほぼ同じ` になるんです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528622/4088c205-2653-20d1-405e-97791d78ef3c.png)

> よく利用される印刷物の規格サイズには「Aサイズ」と「Bサイズ」があります。Aサイズはドイツ発祥の国際的な印刷物のサイズで、世界中で使用されている規格。
一方Bサイズは日本独自の印刷物の規格で、その起源は江戸時代に使用されていた美濃紙に始まったと言われています。
明治時代になると、明治政府が公文書をBサイズで作るようになり、戦後もJISの規格で帳簿類の大きさはBサイズと定められていました。

[ラクスル様より引用させていただきました](https://raksul.com/magazine/column/b8size/)

このサイズに注目したのはほかでもありません。

今回の名刺アイデアには、いわゆる名刺サイズではなく、
B8サイズで作ることができるからなのです。

## こんなオプション加工を行います
今回の名刺アイデアは印刷会社にお願いする形になるのですが、
こんな👇 `ミンシ目入れ加工` オプションを付けてもらう必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528622/df8d587a-7807-668a-8c36-4e5e47fb7fc3.png)

>ミシン目入れ加工とは
印刷物の一部を切り離しやすいように、飛び飛びに切れ目を入れておくのが「ミシン目入れ加工」です。
破線状のこの切れ目が、裁縫用のミシンを使って縫った縫い目の形と似ているために「ミシン目」と呼ばれています。
日常生活でもチケットやクーポン券、申込書付のチラシなどいろいろな場面で見かけます。
上手に切れると気持ちいいですよね。

[プリントハウス様より引用させていただきました](https://www.print-house.com/tips/1115/)

ミンシ目入れ加工オプションを印刷会社にお願いするときは
いわゆる、名刺サイズでお願いするときには使えない加工でして、
このミシン目入り加工オプションを使うときは、名刺とほぼ同等のB8サイズでお願いすると
オプションでミシン目加工入りを付ける事ができました。
（ミシン目、という響きが気持ちいいので多用させてもらいました！）

:::note
これは私が制作した当時のお話なので、今は名刺サイズでお願いしても、ミンシ目入れ加工オプションはあるかもしれません
:::

## 結局どんな名刺を作るの？
これでどんな名刺を作るのか、皆さんならば、もうわかって頂けたかと思います。
（ちなみに私はこういう言い回しをされた時点で、わかったことは一度もありません）

### 名刺（とほぼ同等）サイズの紙の中央にミシン目加工をいれて、
### 上下２つに分割できるようにするんです！！

# こんな風に！！！
![meishi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528622/297223da-14be-b945-da91-d94a760f74b1.jpeg)

## どんな情報がこの名刺には入っているの？
この名刺には、中央のミシン目を堺に、上下同じ情報が入っているのです。
画像だと上下違いますが、これらの裏には、
表で書かれた内容と同じものが、上下の位置が逆になって、入っているのです！

## これを配るとどうなるの？
ワイ：この名刺、こんな👆加工がされています。
相手：珍しい！

ワイ：この名刺は、上下分割しても、情報量は失われません。
相手：ふむふむ！！

ワイ：もし、相手がどこかで私の話を誰かにした場合、
　　　この名刺を切り取った半分を、別の相手に渡してください。
　　　そうすれば、相手にも別の相手にも、同じ情報が残り
　　　私が、自ら営業活動をせずとも、名刺効果で２倍の営業力になるのです。
　　　相手は別の相手と私をつなげる手間はいりません！
　　　この名刺を切り取って別の相手に渡すだけですから！！
相手：面白い！！！　すごい！！！！　画期的！！！！

## その後、「名刺を分割して使用した」という話は一度も聞きませんでした！
と、いったオチがついたところで、この辺にしたいと思います。
どうやら相手方は名刺を切り取る際、躊躇が生まれるようです。

が、もしかしたら、私が聞いていない、もしくは忘れていただけで、
使用してくれているかも知れませんよね！！

とはいえ、タイトル通り、`話のネタ` になります！
### 名刺を作りたいと思ったときは、ぜひ思い出してみてくださいね！！
UNIX パイプで分子生物学実験

この投稿の趣旨は簡単な生物学的現象や分子生物学実験を UNIX コマンド上で再現することです。生物学に馴染みのない方はまず以下のページを見ていただくと良いかもしれません。

https://ja.wikipedia.org/wiki/%E3%82%BB%E3%83%B3%E3%83%88%E3%83%A9%E3%83%AB%E3%83%89%E3%82%B0%E3%83%9E

https://ja.wikipedia.org/wiki/%E5%88%B6%E9%99%90%E9%85%B5%E7%B4%A0

---

## ランダムな塩基配列を生成

生物の遺伝情報は DNA 分子中のアデニン・チミン・グアニン・シトシンの4つの塩基の配列としてコードされています。それぞれが `A`、`T`、`G`、`C` の4文字に割り当てられているものとして、次のコマンドでランダムな塩基配列が生成され標準出力に書き出されます。

```shell
# DNA
$ cat /dev/urandom | base64 | tr -dc 'ATGC'
# RNA
$ cat /dev/urandom | base64 | tr -dc 'AUGC'
```

![スクリーンショット 2022-12-08 9.16.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125062/6f8f067a-e378-e485-2f08-461ad7ccac3b.png)

終了するときは `ctrl + C` でキャンセルしてください。

### コマンドの詳細

#### `/dev/urandom`

乱数生成器です。
`cat /dev/urandom` を実行すると標準出力でランダムなビット列が得られます。

#### `base64`

パイプ元から得られたランダムなビット列を base64 でエンコードします。

#### `tr -dc 'ATGC'`

ATGC 以外の文字を削除します。 チミンの代わりにウラシルが含まれれる RNA の場合は `T` を `U` に変えると対応できます。

## 転写

DNA は RNA ポリメラーゼの働きで RNA に転写されます。rna-polymerase-stream というライブラリを使ってこの働きを再現してみます。このライブラリでは Node.js の TransformStream のインターフェースを実装して、標準入力された ATGC の文字列に対して　`A` -> `U`、 `T` -> `A`、 `G` -> `C`、 `C` -> `G` の変換を行います。

https://github.com/molecular-biology-lab/rna-polymerase-stream

```shell
$ cat /dev/urandom | base64 | tr -dc 'ATGC' | \
  npx rna-polymerase-stream
```

## 翻訳

mRNA 中の3文字の塩基配列の組み合わせ（コドン）はそれぞれ20種類のアミノ酸に対応していて、この順序に従ってアミノ酸が重合することで様々なタンパク質になります。この塩基配列を元にタンパク質を合成する仕組みを翻訳といい、細胞内にあるリボソームで行われます。
次のライブラリはリボソームの働きを模し、コドン表に基づいて RNA の塩基配列をタンパク質に翻訳します。イニシエーター配列(`AUA`、`AUG`、`GUG`)とターミネーター配列(`UAA`、`UAG`、`UGA`)を認識してその間の塩基配列をタンパク質に翻訳し、 `Arg.`(アルギニン) などの記号に置換します。


https://github.com/molecular-biology-lab/ribosome-stream

```shell
$ cat /dev/urandom | base64 | tr -dc 'ATGC' | \
  npx rna-polymerase-stream | \
  npx ribosome-stream
```

![スクリーンショット 2022-12-08 9.25.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125062/6b51faf1-4160-37e7-05af-d2de5575b30e.png)

## 制限酵素

制限酵素の働きを模して特定の塩基配列を認識し切断します。回文配列が対象です。  
例: `AAGCTT` `GATATC`

制限酵素で切断された DNA 断片は改行区切り文字列としてストリームに流します。

https://github.com/molecular-biology-lab/restriction-endonuclease

```shell
$ cat /dev/urandom | base64 | tr -dc 'ATGC' | \
  npx restriction-endonuclease AAGCTT
```

![スクリーンショット 2022-12-08 11.14.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125062/0bdfc030-ecbe-a7bc-4937-958e9a5d0228.png)

## 電気泳動

DNA 断片が得られたら最後は電気泳動です。DNA 断片の重さ = 文字数の長さとしてカウントしヒストグラムを作成します。以下のライブラリを使います。　`--resolution` オプションはヒストグラムのステップ間隔で小さい値を指定するとヒストグラムが細かくなります。

https://github.com/molecular-biology-lab/electrophoresis

```shell
$ cat /dev/urandom | base64 | tr -dc 'ATGC' | \
  npx restriction-endonuclease AAGCTT | \
  npx electrophoresis --resolution=10000
```

![Dec-08-2022 12-24-12.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125062/f2550e57-0ecc-0c5b-c345-373e2b1ee900.gif)

---

そのほかに CLI で再現できそうなおもしろい生物学的現象や実験方法などがあればぜひコメントで教えてください。
mi band のデータのエクスポート



## 2024/09/05 アプリの開発会社がband8から変わったため更新する

[How to download/export data from Mi Fitness App?](https://www.mi.com/global/support/article/KA-11566/)

https://account.xiaomi.com/ からログインする

操作手順:
1. プライバシー
2. データの管理
3. MI Fitness
4. 右側の [ダウンロード] ボタンをクリック
4. メールを入力



# 以下はzepplifeの場合の手順


## 概要
1. アプリから操作して手続きをする
1. メールにエクスポートしたデータのダウンロードページ案内がくる
1. ダウンロードする




## アプリから操作して手続きをする

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/a51cb515-a0ad-2267-aa3a-ce2eae333914.png" width="200" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/e4ba26e4-c207-22f1-15bf-310cfb260582.png" width="200" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/d24382dd-312b-766d-8aa7-25b31adebc36.png" width="200" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/e7a0c59b-6dd8-2712-6016-d352f36c1de7.png" width="200" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/ce702a30-1921-d4b0-e476-687bd91a06ae.png" width="200" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/a8ed5d18-1a33-628d-7acf-7f3855c265de.png" width="200" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/966c13c1-2fb3-b9dd-9048-82280ce51942.png" width="200" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/fc742949-b7e1-d303-9b2f-767a1dd75e83.png" width="200" />
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/ed43ceb5-78fa-899d-ed5f-d89859a1de96.png" width="200" />


## メールが来るのでダウンロードする



## まとめ

ネストが深いところの設定なので
GDPRなどに向けた設定に感じた。

データ形式はCSVになっていて取り回ししやすい印象でした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5472/2f64e9b1-6809-66fb-9b49-3ddc44542063.png" width="400" />
paiza.ioでelixir その130

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
アセンブラでfizzbuzzを求めよ。

# サンプルコード

```
File.write "hello.s", """

.code64
.text
.global main
main:
	sub	 	$8, %rsp
	mov	 	$1, %r8
loop:
	mov	 	$0, %r10
	mov	 	$0, %rdx
	mov	 	%r8, %rax
	mov	 	$3, %rsi
	div	 	%esi
	cmp	 	$0, %rdx
	jne	 	skip1
	add	 	$1, %r10
skip1:
	mov	 	$0, %rdx
	mov	 	%r8, %rax
	mov	 	$5, %rsi
	div	 	%esi
	cmp	 	$0, %rdx
	jne	 	skip2
	add	 	$2, %r10
skip2:
	cmp	 	$0, %r10
	je	  	printNum
	cmp	 	$2, %r10
	jb	  	printFizz
	je	  	printBuzz
	ja	  	printFizzBuzz
printNum:
	lea	 	num(%rip), %rdi
	jmp	 	loope
printFizz:
	lea	 	fizz(%rip), %rdi
	jmp	 	loope
printBuzz:
	lea	 	buzz(%rip), %rdi
	jmp	 	loope
printFizzBuzz:
	lea	 	fizzbuzz(%rip), %rdi
loope:
	mov	 	$1, %rax
	mov	 	%r8, %rsi
	push	%r8
	push	%r10
	call	printf
	pop	 	%r10
	pop	 	%r8
	add	 	$1, %r8
	cmp	 	$101, %r8
	jne	 	loop
	add	 	$8, %rsp
	ret
.data
num:
	.asciz "%i "
fizz:
	.asciz "Fizz "
buzz:
	.asciz "Buzz "
fizzbuzz:
	.asciz "FizzBuzz "  

"""

{result, 0} = System.shell("gcc -no-pie hello.s")
IO.puts result

{result, 5} = System.shell("./a.out")
IO.puts result





```

# 実行結果

```
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29 FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44 FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59 FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74 FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89 FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz 
```

# 成果物

https://paiza.io/projects/ZhsDREwPqDcoc5qUkQ_2yw?language=elixir


以上。
1クリックでページタイトルとURLをコピーできる [Chrome拡張機能]

## Simple URL Copy について

ブラウザで閲覧したサイトをSNSなどで誰かに伝えようとするとき
サイトのタイトルとURLをコピーしようと思ったときに、長いページタイトルをコピーしたり、手動でタイピングするのは結構めんどくさいです。


「Simple URL Copy」は1クリックするだけでページタイトルとURLをクリップボードできるGoogle Chrome拡張機能です。
シンプルな見た目をしているので、無駄がないところが素晴らしいです。

![Monosnap Monosnap 2022-12-08 12-28-38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/987057/7995c833-69ae-2123-1970-2bb267c61b35.png)


## インストール先

https://chrome.google.com/webstore/detail/simple-url-copy/cefkgjbbpagcilodnhboolbppdjlplip


## クリップボードにコピーされるスタイル

- Title URL
```
 1クリックでページタイトルとURLをコピーできる [Chrome拡張機能] - Qiita https://qiita.com/omo_taku/items/8cd8f95714eefdaa6770
```

- Title
 URL
```
1クリックでページタイトルとURLをコピーできる [Chrome拡張機能] - Qiita
https://qiita.com/omo_taku/items/8cd8f95714eefdaa6770
```

- Markdown Style
```
 [[1クリックでページタイトルとURLをコピーできる [Chrome拡張機能] - Qiita:https://qiita.com/omo_taku/items/8cd8f95714eefdaa6770]]
```

- Backlog Style
 ```
 [[1クリックでページタイトルとURLをコピーできる [Chrome拡張機能] - Qiita:https://qiita.com/omo_taku/items/8cd8f95714eefdaa6770]]
 ```
[OnsenUI] ons-navigator

覚書です

# ナビゲータとは
* 開いたページ情報を保持してくれるもの
* `page`属性に与えたDOMを表示してくれるぞ

# かんたんなせつめい
## 生成
bodyの頭とかに置くことがおおいぞ

```html
<body>
    <ons-navigator  id="my-navigator" page="はじめに表示するページ"></ons-navigator>

...
</body>
```

最初に表示したいファイルが"page.html"なら`page="page.html"`でよいぞ

## ページの変更
ナビゲータの`page`属性を変更してあげるといいぞ
JSから任意のイベントに実装してあげよう

```js
// 任意のページを開いたとき
document.addEventListener('init', function(event) {
  var page = event.target;

  // 開いたページによって処理を分ける
  if (page.id === 'page1') {
    // push-button クラスを持ったボタンとかが押されたとき
    page.querySelector('#push-button').onclick = function() {
      // page2に遷移するぞ
      document.querySelector('#my-navigator').pushPage('page2.html', {data: {title: 'Page 2'}});
    };
});
```
OPTIONSリクエスト・プリフライトリクエストとは

## OPTIONSリクエスト
- サーバが許可しているリクエストメソッドの情報を取得できるメソッド
  - レスポンスヘッダの`Allow`に、サーバで許可されたメソッドが入る

```sh
$ curl -X OPTIONS http://hoge.com/fuga -i
HTTP/1.1 200 
Allow: POST,OPTIONS
Accept-Patch:
Transfer-Encoding: chunked
Date: Mon, 05 Dec 2022 09:29:39 GMT
```

## プリフライトリクエスト
- CORSのリクエストを行う前に、ブラウザが自動的に実行する`OPTIONS`リクエストのこと
  - サーバにCORSのリクエストを送れるかどうかを確かめる。
  - `Access-Control-Request-Method`、`Access-Control-Request-Headers`、`Origin`の３つのヘッダーを送る。
- 例:

```
OPTIONS /resource/foo
Access-Control-Request-Method: DELETE <= 送るリクエストのメソッド
Access-Control-Request-Headers: origin, x-requested-with <= 送るヘッダー
Origin: https://foo.bar.org <= リクエスト元のオリジン

HTTP/1.1 204 No Content
Connection: keep-alive
Access-Control-Allow-Origin: https://foo.bar.org <= CORSを許可するオリジン
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE <= 許可するメソッド
Access-Control-Max-Age: 86400 <= プリフライトリクエストの結果をキャッシュする時間
```

## いつ発生するのか
- 超ざっくりいうと、`GET`以外のほとんどのリクエスト！！！
    - 例外:[単純リクエスト](https://developer.mozilla.org/ja/docs/Web/HTTP/CORS#simple_requests)
    - `POST`でも、特定の条件(`Content-Type `が `application/x-www-form-urlencoded ` など → 単純にブラウザからformをポストするだけ)なら単純リクエストになる。
 
 
## なぜ必要なのか
- 行おうとしているリクエストをサーバが許可しているか、事前に調べるため
  - 許可していない場合はリクエストを中断して、CORSエラーとなる。

## プリフライトで出てくるヘッダー集
### リクエストヘッダー
- `Access-Control-Request-Method`
    - 送ろうとしてるリクエストメソッド 
- `Access-Control-Request-Headers`
    -  送ろうとしてるヘッダー
- `Origin`
    - リクエスト元のオリジン 
 
### レスポンスヘッダー  
- `Access-Control-Allow-Methods`
    - サーバが許可しているリクエストメソッド 
- `Access-Control-Allow-Headers`
    - サーバが許可してるヘッダー
- `Access-Control-Max-Age`
    - プリフライトレスポンス内容をキャッシュする時間 
- `Access-Control-Allow-Origin`
    - サーバでCORS許可しているオリジン 

## 参考
https://developer.mozilla.org/ja/docs/Glossary/Preflight_request
Go言語でスライスから特定の要素を削除する方法

# 概要

Go言語でスライスから特定の要素を消す方法がわからなかったので調べてみました。
スライスには削除の関数のようなものがないため、`append`や`copy`などの関数を使用してスライスを操作して最終的に削除を実現していく必要があります

# ハマったポイント

Goのスライスの要素を確認して、もしも消したい文字列と一致する要素があれば削除したいなと思う処理がありました。
例えば商品のJANコードなどの、string型の識別子で判定して該当の商品を削除した位ケースなどです。

Rubyであれば、そのような文字列判定での配列の削除は`delete`メソッドなどを使って下記のように実行できます。

```ruby
array = ["apple", "grape", "orange"]
# => ["apple", "grape", "orange"]
array.delete("grape")
# => "grape"
array
# => ["apple", "orange"]
```

Goでも同じことをやりたいと思ったのですがどうすればよいかわかりませんでした。

# Goのスライスの仕組み

GoのスライスはGoならではの特殊なデータ構造です。
実はスライスの裏側には配列があり、スライスが保持するのは
- 先頭の要素へのポインタ
- 長さ
- 要素数

の3つになっています。
Goの配列は固定長で使い勝手がよくないのですが、スライスによって、配列を作り変えながらデータを移し変える操作によって可変長の配列のように扱うことができます。

これが便利な反面で、削除する際には少し手間がかかるようになっています。


# Goのスライスから`i`番目の要素を削除する方法

Go wikiのSliceTricksを見てみたところ、Goのスライスでは下記の2つの方法で要素の削除ができるということでした。

## 削除後の順不同のやり方

```go
a = append(a[:i], a[i+1:]...)
// or
a = a[:i+copy(a[i:], a[i+1:])]
```

まずはこちらの処理を読んでみます、。
```go
a = append(a[:i], a[i+1:]...)
```
`Slice[:end]`と書くことで、先頭から（end - 1（までの要素を取り出せます。
また、`Slice[start:]`と書くことで、先頭から（end - 1（までの要素を取り出せます。
`append`は第一引数に与えたスライスに、第二引数以降の値を追加する関数になるので、ここで行っている操作はi -1 番目までのスライスに、i+1番目移行の値を追加する処理です。
結果的にi番目の要素が消えたスライスが作成されます。

次にこちらの処理を見てみます。
```go
a = a[:i+copy(a[i:], a[i+1:])]
```

`copy`は2つの引数で与えられたスライスにて右項から左項へコピーする関数で、戻り値はコピーした個数になります。
`copy(a[i:], a[i+1:])`を実行すると、スライスのi番目以降の要素が、i+1番目以降の要素で上書きされます。結果としてはコピーした要素が返ってくるので、`a[:i+copy(a[i:], a[i+1:])]`は最初にあった要素数-1のスライスになり、こちらもi番目の要素がなくなっているということになります。

## 順番不動での削除

```go
a[i] = a[len(a)-1] 
a = a[:len(a)-1]
```

これは削除後のスライスの順が変わってしまってもいい場合に使える方法です。
やっていることはシンプルで、スライスの最後の要素をi番目の要素に上書きし、要素数を1だけ減らしたスライスをもとのスライスに上書きしています。


https://github.com/golang/go/wiki/SliceTricks#delete

結果として今回やりたかったコードは下記のようにすれば良さそうです。
順番は考えなくても良かったので最後の方法で実現しました。

```go
var deleteTargetJan string
deleteTargetJan = "hogeCode" 
for i, product := range products {
    if product.JAN == deleteTargetJan {
    	products[i] = products[len(existingShops)-1]
    	products = products[:len(products)-1]
    }
}
```

# 自作の削除関数を用意する

もしも関数の中でなんどもスライスの削除を行う必要があるのであれば、削除関数を定義しても良さそうです。
string型のスライスの場合下記のように書けそうです。
```go
for i, product := range products {
    if product.JAN == deleteTargetJan {
    	products[i] = products[len(existingShops)-1]
    	products = products[:len(products)-1]
    }
}

func remove(slice []string,  deleteTarget: string) []string {
    result := []string{}
    for i, v := range slice {
        if v == deleteTarget {
            result = append(result[:i], result[i+1:])
        }
    }
    return result
}
```



# 感想
Goの独自の型であるスライスも最初は理解しづらかったですし、合わせてこちらの削除の処理もなかなかに大変でしたが、このように新しい学びがあるので、普段とは異なる言語を学ぶのは面白いと感じました。

# 参考

https://zenn.dev/mattn/articles/31dfed3c89956d


https://tsujitaku50.hatenablog.com/entry/2017/02/25/112049
paiza.ioでelixir その129

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
アセンブラでcpuidを求めよ。

# サンプルコード

```
File.write "hello.s", """


.code64
.text
.globl main
main:
	lea	 	msg(%rip), %rdi
	xorl	%eax, %eax
	cpuid
	movl	%ebx, (%rdi)
	movl	%edx, 4(%rdi)
	movl	%ecx, 8(%rdi)
	mov   	$1, %rax;
	mov   	$1, %rdi;
	mov   	$msg, %rsi;
	mov   	$12, %rdx;
	syscall;
	mov   	$0, %rax;
	syscall;
.data
msg:
	.asciz "Hello world!"
"""

{result, 0} = System.shell("gcc -no-pie hello.s")
IO.puts result

{result, 0} = System.shell("./a.out")
IO.puts result




```

# 実行結果

```

GenuineIntel

```

# 成果物

https://paiza.io/projects/_isq3BBstbENhz8A5J4UyA?language=elixir


以上。
Nuxt/Vueで多階層(入れ子)に対応したアコーディオンを実装する

# 多階層でないシンプルなアコーディオンは自作コンポーネントで対応できる

↓シンプルなアコーディオンの内容は、
こちらの方の記事がとても分かりやすいので、ぜひ見てみてください

https://zenn.dev/shunk_py/articles/894f35eeb922db


# 問題は多階層の場合

![ezgif-4-3c67c584c4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248219/b677b843-ee29-6a64-0c22-fff7ffebdad4.gif)

↓こちらのライブラリで実装できます

https://www.npmjs.com/package/@ivanv/vue-collapse-transition

↓こんな感じのvue-collapse-transitionのラッパーのコンポーネントを作成して、

```vuejs:Accordion.vue
<template>
  <collapse-transition>
    <div v-show="isOpen">
      <slot />
    </div>
  </collapse-transition>
</template>

<script>
import { CollapseTransition } from '@ivanv/vue-collapse-transition'

export default {
  name: 'MoleculesAccordion',
  components: {
    CollapseTransition,
  },
  props: {
    isOpen: {
      type: Boolean,
      required: true,
    },
  },
}
</script>
```

↓こんな感じで好きなページでAccordion.vueを使用したらOKです！

```vuejs:pages/aiueo.vue
<template>
  <div :class="$style.wrapper">
    <div :class="$style.button" @click="isOpen1 = !isOpen1">&gt; 1つ目のアコーディオン</div>
    <Accordion :is-open="isOpen1">
      <div :class="$style.inline">
        <div :class="$style.button" @click="isOpen2 = !isOpen2">&gt; 2つ目のアコーディオン</div>

        <Accordion :is-open="isOpen2">
          <div :class="$style.result">OK</div>
        </Accordion>
      </div>
    </Accordion>
  </div>
</template>

<script>
import Accordion from '~/components/molecules/Accordion.vue'

export default {
  name: 'PageAiueo',
  components: {
    Accordion,
  },
  data() {
    return {
      isOpen1: false,
      isOpen2: false,
    }
  },
}
</script>

<style lang="sass" module>
.wrapper
  width: 400px
  margin: 0 auto
  margin-top: 100px

.button
  color: gray
  padding: 16px
  font-size: 16px
  background-color: white
  cursor: pointer

.inline
  padding-left: 24px

.result
  font-size: 16px
  color: white
  background-color: #87caff
  padding: 16px
  margin-left: 24px
</style>

```
Java8で16進数の論理和を計算するのだ。

# いきさつ
- 仕事で論理和のコードを書くことになったのだけれど、完全に忘れていたので調査した次第なのだ。

# 論理和とは
- 一つでも正しかったらOK、全部ダメだったらNG
- 要するに「OR」
- 参考：https://wa3.i-3-i.info/word11663.html

# 書いてみた
```java:main.java
public static void calcOr(){
    Integer num1 = Integer.decode("0x007F");
    Integer num2 = Integer.decode("0x0030");
    
    Integer or = num1 | num2;
    System.out.println("OR(Decimal) : " + or);    // OR(Decimal) : 127
    System.out.println("OR(Hex) : " + Integer.toHexString(or));   // OR(Hex) : 7f
}
```
APIを用いてDatabricksのMLflowモデルサービングエンドポイントを停止する

Databricksで機械学習モデルをREST APIから呼び出せる様にするための、[モデルサービング](https://qiita.com/taka_yayoi/items/b5a5f83beb4c532cf921)は便利ですが、サービングを有効化するとクラスターが起動し、これは明示的に止めない限り稼働し続け、コスト増につながります。自動停止がないので止め忘れも結構あるかと思います。すみません。

なお、新たな[サーバレス推論エンドポイント](https://qiita.com/taka_yayoi/items/32266655075795f5ab65)は、REST APIのリクエストがない場合、0ノードまでダウンスケールします。

そこで、サンドボックス環境など実験がメインの環境においては、一定時間ごとにモデルサービングエンドポイントを停止する処理をジョブで実行することがベストプラクティスと言えます。Databricksの[MLflow REST API](https://docs.databricks.com/dev-tools/api/latest/mlflow.html)を活用することで、ノートブックからMLflowモデルサービングエンドポイントを制御することができます。

サンプルノートブックはこちらです。

https://github.com/taka-yayoi/public_repo_2/blob/master/terminate_model_serving_endpoint/terminate_model_serving.py

:::note
**注意**
- すべてのモデルサービングエンドポイントを停止するには、管理者権限を持つユーザーでこのノートブックを実行してください。
- ジョブでこのノートブックを実行する際には、ユーザーにエンドポイントの運用を周知(xx時間ごとに停止ジョブが実行される等)してください。
:::

# ワークスペースURLとトークンの取得

ノートブックからREST APIを呼び出します。

[こちらの記事](https://community.databricks.com/s/question/0D53f00001GHVZiCAP/how-can-i-make-databricks-api-calls-from-notebook)にあるように、ノートブックからREST APIを呼び出す際には、パーソナルアクセストークンを発行しなくてもREST APIにアクセスすることができます。

```py:Python
databricksURL = dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiUrl().getOrElse(None)
myToken = dbutils.notebook.entry_point.getDbutils().notebook().getContext().apiToken().getOrElse(None)
```

# エンドポイント一覧の取得

稼働中のエンドポイント一覧を取得します。

```py:Python
import requests
import json

header = {'Authorization': 'Bearer {}'.format(myToken)}
endpoint = '/api/2.0/mlflow/endpoints/list'
payload = """{}"""
#print(payload)
 
resp = requests.get(
  databricksURL + endpoint,
  data=payload,
  headers=header
)

data = resp.json()
print (json.dumps(data, indent=4))
```

(アクセス権を持つ)稼働中のモデルサービングエンドポイントを取得することができます。
![Screen Shot 2022-12-08 at 11.44.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d0fe5b28-1fbd-ec85-e345-183237414341.png)

# エンドポイントの停止

エンドポイントに対して、`endpoints/disable`を呼び出すことで、モデルサービングエンドポイントを停止することができます。

```py:Python
for rest_endpoint in data["endpoints"]:
  print(rest_endpoint["registered_model_name"], ":", rest_endpoint["state"])

  # REST APIの停止
  header = {'Authorization': 'Bearer {}'.format(myToken)}
  endpoint = '/api/2.0/mlflow/endpoints/disable'
  payload = {"registered_model_name": rest_endpoint["registered_model_name"]}
  # JSON形式の文字列に変換
  payload = json.dumps(payload)
  #print(payload)

  resp = requests.post(
      databricksURL + endpoint,
      data=payload,
      headers=header
    )

  result_data = resp.json()
  print (json.dumps(result_data, indent=4))
```

# ジョブの設定

ノートブック右上の**スケジュール**をクリックして定期実行の設定を行えば、このノートブックがジョブとして実行され、モデルサービングエンドポイントが停止されます。
![Screen Shot 2022-12-08 at 11.45.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/0b6302ce-740b-5041-52cf-3879d52cff6a.png)

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
Javaで何か作ってみる(2022/12/7 Day48)

## 今日やった事
- オブジェクト指向の動画教材を見た。（**J2-02_コンストラクタ** まで見た。）
## 参考にしたもの
- [Spring 入門 ～ SpringBoot 2 を使ってお問い合わせアプリとToDoアプリを作る ～](https://www.udemy.com/course/java_spring_beginner/)  
- [【超初心者も必見】Javaプログラミングの「オブジェクト指向」が絶対理解できる講座【プロ講師が丁寧解説】](https://www.udemy.com/course/uz-java-obj/)  
## 所感
- thisの使い方について、理解出来た。
- ただ、thisは便利な反面、「どのthisなのか」を把握した上で使わないとバグに繋がるので気を付けたいと思った。
## 明日の予定
- 引き続き、動画教材を進めていく。