OmniAICreator/Qiita-1.07M huggingface dataset:
Amazon EKSでNGINX Ingress ControllerにAWS Certificate Managerを利用する

# はじめに
Amazon EKSで[NGINX Ingress Controller](https://github.com/kubernetes/ingress-nginx)にAWS Certificate Managerを設定する方法をまとめます。
Mac環境を想定しています。

# 実行環境の準備
1.  AWS CLIの設定
[AWS CloudFormationを動かすためのAWS CLIの設定](https://qiita.com/miyabiz/items/fed11796f0ea2b7608f4)を参考にしてください。

1.  EKSクラスタの構築
[Macでeksctlを利用してAmazon EKSのクラスターを構築する](https://qiita.com/miyabiz/items/75f83237795b0b7d52bd)を参考にしてください。

1.  EKSのコンテキストの設定
[MacにてAmazon EKSの設定をする](https://qiita.com/miyabiz/items/b98d145cedb35dab9524)を参考にしてください。

1.  Helmの設定
[Amazon EKSでHelmを利用する](https://qiita.com/miyabiz/items/453361e6af64b324443c)を参考にしてください。

1.  NGINX Ingress Controllerの設定
[Amazon EKSでNGINX Ingress Controllerを利用する](https://qiita.com/miyabiz/items/33258b8fefb9b161a2dd)を参考にしてください。

# 環境設定
1. Route53でカスタムドメインを取得します。

1. AWS Certificate Managerを取得します。

1.  `patch.yaml` を作成する
    ※[AWS L7 ELB with SSL Termination](https://github.com/helm/charts/tree/master/stable/nginx-ingress#aws-l7-elb-with-ssl-termination)を参考にしてください。
    ※`ACMのARN`を設定する

    ```yaml:patch.yaml
    controller:
      service:
        targetPorts:
          http: http
          https: http
        annotations:
          service.beta.kubernetes.io/aws-load-balancer-ssl-cert: ${ACMのARN}
          service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
          service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https"
          service.beta.kubernetes.io/aws-load-balancer-connection-idle-timeout: '3600'

    ```

1.  NGINX Ingress ControllerのチャートをHelmでアップグレードする
    ※事前にKubernetesクラスターのコンテキストの設定をします。

    ```sh
    helm upgrade -i nginx-ingress-controller \
        ingress-nginx/ingress-nginx \
        -n nginx-ingress-controller \
        -f patch.yaml
    ```

# クリーンアップ

1.  クラスターから削除する

1.  NGINX Ingress ControllerをHelmで削除する

    ```sh
    helm delete nginx-ingress-controller -n nginx-ingress-controller
    ```

1.  Namespaceを削除する

    ```sh
    kubectl delete ns nginx-ingress-controller
    ```
Amazon Aurora Serverless v2 ハンズオンやってみた

# はじめに
Amazon Aurora Serverless v2 とは、AWSのサーバーレスのデータベースサービス。
[AWS公式日本語ハンズオン集](https://aws-samples.github.io/jp-contents-hub/ "JP Contents Hub") にAurora Serverless v2 のハンズオンがあったのでやってみた。  
  
[Aurora\-Serverless\-v2/Amazon Aurora Serverless v2 ワークショップ\.pdf GitHub](https://github.com/harunobukameda/Aurora-Serverless-v2/blob/main/Amazon%20Aurora%20Serverless%20v2%20%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%83%E3%83%97.pdf)

# ハンズオンの内容
ServerlessでないAurora起動して、readerとしてAurora Serverless v2を作成。
フェイルオーバーでServerlessに切り替える。

ハンズオン集はMySQLだが、個人的にPostgreSQLのほうがよく使うのでPostgreSQLでやってみた。

■ フェイルオーバー実施前はserverlessはリーダーインスタンスになっている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2857191/a7f95a46-92da-e83e-a63a-19438c635b9e.png)


■ フェールオーバー実施後、serverlessがライターインスタンスになった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2857191/9156192b-0f67-8dd5-d6db-5c4245fa198c.png)


# まとめ
今回のハンズオンにかかった料金 $0.56
次の記事ではAurora Serverless v2の料金を調べてまとめようと思います。
OpenJ9系VMのダンプファイルからヒープダンプを取り出すメモ

クラッシュして落ちると
core.20221028.xxxxxx.xxxxx.xxxx.dmp
のようなコアダンプ出力されるので、これを基に解析したときのメモ。

# jdmpview
javaインストール先のbinの下にあるので起動する。
```
jdmpview -core core.20221028.xxxxxx.xxxxx.xxxx.dmp
```
コマンドを叩きヒープダンプをファイルに出力する。
```
> heapdump
```
core.20221028.xxxxxx.xxxxx.xxxx.dmp.phd
というファイルが作成される。

# コアダンプ解析
Eclipse Memory Analyzer Tool の拡張版で先ほどのphdファイルを読み込む。
https://www.ibm.com/support/pages/eclipse-memory-analyzer-tool-dtfj-and-ibm-extensions
IPV6ヘッダをかんたんに説明してみる

# 勉強前の理解度
* 種類がいっぱいある(IPv4よりは種類が少ない)
* 固定長だった気がする

# IPv6ヘッダの中身
[]の中はbit数。

#### バージョン[4]
　IPv4のバージョンと同様、**IPヘッダのバージョン**を示す。IPv6の場合は6が入る。

#### トラフィッククラス(Traffic Class)[8]
　**QoS(Quality of Service)に関わる**。元々はIPv4のTOSにあたるが、TOSはほとんど利用されなかったため、削除が検討された。しかし、今後の研究に期待するためにフィールドが残された。DiffServ(先頭6bit)、ECN(末尾2bit)として利用されることが検討されている。

#### フローラベル(Flow Label)[20]
　**パケットの経路を統一するためのラベル**。QoSに関わる。同じフローラベル、送信元IPアドレス、宛先IPアドレスをもつパケットは同じ経路で転送されるため、パケットが並び替えられることを防ぐことができる。
　音声のやり取りのようなリアルタイム性に重点が置かれるやり取りで用いられるらしい。

#### ペイロード長(Payload Length)[16]
　**ペイロード(データ)の長さを表す**。ヘッダ長は含まない。なお、IPv6ヘッダは固定長であるため、可変長の拡張ヘッダを利用した場合、その長さもペイロード長に含める。


#### 次のヘッダ(Next Header)[8]
　**上位層のプロトコルを表すが、拡張ヘッダを利用する場合はそのタイプを表す**(固定ヘッダの場合は最初の拡張ヘッダのタイプを表し、最後のヘッダ内の場合は上位層のプロトコルを表す)。
　拡張ヘッダはルーティングに不要であるため、ルーティングに必要なフィールドと分離することで、ルーティング処理の際に参照する領域を小さくしている。


#### ホップリミット(Hop Limit)[8]
　通過できるルーターの数を表す。IPv4のTTL(Time To Live)と同義。ルーターを通過するごとに1ずつ減算され、値が0になるとパケットが破棄される。


#### 送信元IPアドレス[128]
　送信元IPv6アドレスが入る。


#### 宛先IPアドレス[128]
　宛先IPv6アドレスが入る。


#### 拡張ヘッダ[可変長]
　**機能を拡張するために使用する**。
　例えばIPsecを利用する場合は、暗号化に利用するESPヘッダと認証に使用するAHヘッダを利用する。また、ホップバイホップオプションヘッダ(HOPOPT)を指定すれば、通信経路のすべてのノードで参照されるべき情報を記述することができる。


# 参考
[IPv6とは](https://www.infraexpert.com/study/ipv6z1.html)
[ネットワークエンジニアを目指して・TCP/UDP - IPv6 ヘッダフォーマット - ネットワークエンジニアを目指して](https://www.itbook.info/study/ipv6-4.html)
[IPv6パケット - Wikipedia](https://ja.wikipedia.org/wiki/IPv6%E3%83%91%E3%82%B1%E3%83%83%E3%83%88)
[フローラベル ‐ 通信用語の基礎知識](https://www.wdic.org/w/WDIC/%E3%83%95%E3%83%AD%E3%83%BC%E3%83%A9%E3%83%99%E3%83%AB)
[第2回　IPv6パケットの構造を知る：Windows管理者のためのIPv6入門（1/2 ページ） - ＠IT](https://atmarkit.itmedia.co.jp/ait/articles/1201/05/news113.html)
Azure Databricks にて、Azure Storage（Azure Data Lake Storage Gen2）に SAS キーで接続する際 400 エラーへの対応方法 


## 概要

Azure Databricks にて、Azure Storage（Azure Data Lake Storage Gen2）に SAS キーで接続する際 400 エラーへの対応方法の１つを共有します。

SASキーをコピー＆ペーストすると、最初の `?` が不要なことが原因でした。

本記事で SAS キーをそのまま記載しておりますが、既に無効なキーです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/54343187-d4ed-766a-1211-374487cd3f09.png)

## エラーメッセージ

> Operation failed: "A query parameter that's mandatory for this request is not specified.", 400, GET, https://synapsetest123345.dfs.core.windows.net/synapse-load?upn=false&resource=filesystem&maxResults=5000&directory=tpch&timeout=90&recursive=false&?sv=2021-06-08&ss=b&srt=sco&sp=rwdlacyx&se=2022-11-04T18:45:33Z&st=2022-10-28T10:45:33Z&spr=https&sig=XXXX, MissingRequiredQueryParameter, "A query parameter that's mandatory for this request is not specified. RequestId:d223c343-b01f-006b-46bf-ea6966000000 Time:2022-10-28T11:22:06.3664002Z"

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/b8107d3d-023a-259b-bd4a-0e42aa56526e.png)

## 対応方法

SASキーの最初の `?` を削除します。

**変更前**

```python
spark.conf.set(f"fs.azure.sas.fixed.token.{storage_account}.dfs.core.windows.net", "?sv=2021-06-08&ss=b&srt=sco&sp=rwdlacyx&se=2022-11-04T18:45:33Z&st=2022-10-28T10:45:33Z&spr=https&sig=XJLZh9FVzHZvia2VYlTzfKHa7%2FYcKljfo%2F9z3DxdG0I%3D")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/27be67b2-603e-183f-e181-a81503c74fe0.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/325979e4-6108-2e25-51a9-0f05ae041b2e.png)


**変更後**

```python
spark.conf.set(f"fs.azure.sas.fixed.token.{storage_account}.dfs.core.windows.net", "sv=2021-06-08&ss=b&srt=sco&sp=rwdlacyx&se=2022-11-04T18:45:33Z&st=2022-10-28T10:45:33Z&spr=https&sig=XJLZh9FVzHZvia2VYlTzfKHa7%2FYcKljfo%2F9z3DxdG0I%3D")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/4d39bfa6-604c-3661-f294-ff473e5a10dd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24031/26b53b61-8734-3e19-4994-6b69ffd12bea.png)
php 外部api呼び出す


```
api_sample1.php

<?php
// APIアクセスURL
$url = 'https://umayadia-apisample.azurewebsites.net/api/persons';

// ストリームコンテキストのオプションを作成
$options = array(
    // HTTPコンテキストオプションをセット
    'http' => array(
        'method'=> 'GET',
        'header'=> 'Content-type: application/json; charset=UTF-8' //JSON形式で表示
    )
);

// ストリームコンテキストの作成
$context = stream_context_create($options);

$raw_data = file_get_contents($url, false,$context);

// debug
//var_dump($raw_data);

// json の内容を連想配列として $data に格納する
$data = json_decode($raw_data,true);
?>
<table>
    <tr>
        <th>name</th>
        <th>note</th>
    </tr>
    <?php foreach($data as $key => $value){ // 連想配列を取り出す ?>
        <?php if(is_array($value)){ // 値が配列のみループで回して表示 ?>
            <?php foreach($value as $column){ ?>
            <tr>
                <td><?php echo $column['name']; ?></td>
                <td><?php echo $column['note']; ?></td>
            </tr>
           <?php } ?>
        <?php } ?>
    <?php } ?>
</table>
?>

実行
http://localhost/api_sample1.php

```
下記結果なら　OK
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531298/362f7588-d429-94b6-a1fd-0952e326bc20.png)
wkhtmltopdfで大量の画像を含むPDFを書き出すと途中でエラーが出る件

# はじめに
MLモデルに大量の画像を食わせて、それらの結果を一覧表示したいときにいろいろな方法があると思います。
jupyter-notebookを用いている場合はそのまま出力すれば良いですし、OpenCVやmatplotlibなどを使うのも良いでしょう。

ただ、その画像が大量にある場合。検証目的でできるだけ複数の画像を並べる必要がある場合。
HTMLに書き出してPDF化してしまうのが一番楽なのではないかと思いました。
ということでjinjaを使ってHTMLを書き出して、wkhtmltopdfでPDF化しようとしてみますが、ちょっと困った事があったのでメモ。

# 起こったこと
```sh
$ wkhtmltopdf --enable-local-file-access src.html dst.pdf
```

を実行すると、以下のエラーが大量に出る。

```sh
file:///path/to/image1.jpg (ignore) Warning: Failed to load
file:///path/to/image2.jpg (ignore) Warning: Failed to load
file:///path/to/image3.jpg (ignore) Warning: Failed to load
```

出力されたPDFを見ると、最初の方こそ画像が表示されているけど、後半に行くにつれて画像が出なくなっていました。
原因を調べてみると、リソース制限に到達しているためでした。これを緩和します。

# 解決方法
`ulimit`コマンドを用いてリソース制限を緩和します。

```sh
$ ulimit -n 8192
```

ただし、対象ホストにsshで接続している場合は次のようなエラーが出ます。

```sh
ulimit: error setting limit (Operation not permitted)
```
僕の環境では外部からアクセスできるサーバでなかったため、`/etc/ssh/sshd_config`に`UsePrivilegeSeparation no`を追記して再接続しました。
このオプションがyesになっている場合は、sshdが非rootの子プロセスを作ることで、root権限と分離しています。

# おまけ：その他のエラー
もし以下のエラーが発生した場合……
```sh
Warning: Blocked access to file file:///path/to/image1.jpg
```
`--enable-local-file-access` オプションがないとローカルのファイルへのアクセスができないようですので忘れずにつけましょう。

# 参考
https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2757
Anaconda環境でFlaskを動かす

# Anacondaの仮想環境作成～Flaskのインストール

## 仮想環境を作る

名前は "senerio" とする。

```
conda create -n senerio python==3.10
```

ここでPythonの指定を失念すると以下のエラーで *conda install* が止まってしまうので注意。

> CondaSSLError: OpenSSL appears to be unavailable on this machine. OpenSSL is required to download and install packages.

## 仮想環境を有効化する

```
conda activate senerio
```

## 仮想環境にFlaskをインストール

```
conda install flask
```

## 適当なサンプルコードを書いて実行

```python:app.py
# -*- coding: utf-8 -*-
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'It works!'

if __name__ == '__main__':
    app.run()
```

```
python app.py
```

> Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

がコンソールに出てきたら起動成功。 http://127.0.0.1:5000/ へアクセスすると *It works!* が表示される。
重複確認編 〜 リストとマップの重複確認 〜 

# 目次
　[1.リストの重複確認](#1-リストの重複確認)
　[2.マップの重複確認](#2-マップの重複確認)

# 1. リストの重複確認
例）確認用果物リストの果物のうち、果物リストと重複しないもののみ、果物リストに追加。
```java
package jp.co.study.sample;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Qiita {
	public static void main (String args[]) {
		// 果物リスト
		List<String> fruitList = new ArrayList<String>();
		fruitList.add("りんご");
		fruitList.add("ぶどう");
		fruitList.add("なし");
		
		// 確認用果物リスト
		List<String> confirmFruitList = new ArrayList<String>();
		confirmFruitList.add("ばなな");
		confirmFruitList.add("ぶどう");
		confirmFruitList.add("もも");
		
        // 果物リストに確認用果物リストの果物が含まれているか確認
		for (String fruit : confirmFruitList) {
			if (!fruitList.contains(fruit)) {
				fruitList.add(fruit);
			}
		}

		// 出力
		System.out.println(fruitList.toString());
    }
}
```
出力結果は [りんご, ぶどう, なし, ばなな, もも]

確認用果物リストの要素をひとつずつ確認するため、拡張for文で確認用果物リストをループ。
containsメソッドを使用し、果物リストに、確認用果物リストの要素が含まれているか確認。
含まれていない場合のみ追加。



# 2. マップの重複確認
例）確認用野菜リストの野菜のうち、野菜マップと重複しないもののみ、野菜マップに追加。

```java
package jp.co.study.sample;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Qiita {
	public static void main (String args[]) {
		// 野菜マップ
		Map<Integer, String> vegetableMap = new HashMap<Integer, String>();
		vegetableMap.put(1, "きゃべつ");
		vegetableMap.put(2, "にんじん");
		vegetableMap.put(3, "こまつな");
		
		// 確認用野菜リスト
		List<String> confirmVegeList = new ArrayList<String>();
		confirmVegeList.add("だいこん");
		confirmVegeList.add("こまつな");
		confirmVegeList.add("なす");
		
		int num = 0;
        // 野菜マップに確認用野菜リストの野菜が含まれているか確認
		for (String vegetable : confirmVegeList) {
			if (!vegetableMap.values().contains(vegetable)) {
				vegetableMap.put(4 + num, vegetable);
				num ++;
			}
		}
		
		// 出力
		System.out.println(vegetableMap.entrySet());
	}
}

```
出力結果は [1=きゃべつ, 2=にんじん, 3=こまつな, 4=だいこん, 5=なす]

確認用野菜リストの要素をひとつずつ確認するため、拡張for文で確認用野菜リストをループ。
valuesメソッドを使用し、野菜マップの値すべて（"きゃべつ"、"にんじん"、"こまつな"）を取得。
その値に、確認用野菜リストの要素が含まれているか確認。含まれていない場合のみ追加。


※entrySetはキーと値のペアを全て取得するメソッド。
人生のタスクをGitHubで管理する

GitHub には Projects という機能があり、  
1つのリポジトリの中で複数のタスクをカンバン方式で管理することができる。  
例えば、[PyTorch](https://github.com/pytorch/pytorch/projects?query=is%3Aopen) だとこんな感じ  
![PyTorch_Projects.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675511/8fb249a6-28c0-ee8f-b6f4-b8c360168f62.png)
![PyTorch_Board.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675511/b45814f0-c9c7-2a55-e4a6-08cd859bcffd.png)
この機能をToDoリストとして使ってみたい！と思い、やってみました

## 1. プロジェクトを作成

New project -> Board -> Create  
をクリックしていくと、カンバン方式の View が表示される
![new_project_0.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675511/1c6eaff5-fb71-5ae3-e1bc-5156e9c5fbe8.jpeg)
![new_project_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675511/d1dc0196-f072-9558-734f-f76c842f16ac.jpeg)

## 2. プロジェクトにTodoを追加

Todo カラムの下の Add item をクリックすると入力フォームが表示されるので、任意のタスクを入力して追加する  
タスクに着手したら、タスクをドラッグアンドドロップで In Progress に持っていく
タスクが完了したら、 Done に移動させる  
![task.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675511/b3528839-d4c5-0e8a-b69d-7df73e72f74e.gif)

## 良い点

- 各タスクにMarkdownでメモを残せる

## 微妙な点

- スマホからだとタスクを横に移動できない

## 公式ドキュメント

- <https://docs.github.com/ja/issues/planning-and-tracking-with-projects>
onResume などのライフサイクルメソッドのオーバーライドが非推奨になっていた件

「 [Recommendations for Android architecture](https://developer.android.com/topic/architecture/recommendations) 」の一文に次が書いてありました。

> [Lifecycle](https://developer.android.com/topic/architecture/recommendations#lifecycle
)
Do not override lifecycle methods such as <b>onResume</b> in Activities or Fragments. Use <b>LifecycleObserver</b> instead. If the app needs to perform work when the lifecycle reaches a certain <b>Lifecycle.State</b>, use the repeatOnLifecycle API.

そもそも `onResume` はAndroidにおける主要なライフサイクルの1つ、他にも `onCreate` や `onStart` といったものもあり、今回このライフサイクル系メソッドのオーバーライドが基本非推奨（ <font color="Green">Strongly recommended</font> ）になった。


## そもそもなんで非推奨になったの？

上記の1文では「オーバーライドしないでください。 `LifecycleObserver` を代わりに使ってください。」と書いてある。

つまりこれまで次のように記述していた部分が非推奨となり、
```kotlin
override fun onResume() {
    super.onResume()
    textview.text = "hoge"
}
```

サンプルにあるように [LifecycleObserver](https://developer.android.com/reference/kotlin/androidx/lifecycle/LifecycleObserver) を使ってライフサイクルの状態における変更を受け取るようなカタチになるらしい。
```kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    viewLifecycleOwner.lifecycle.addObserver(object: DefaultLifecycleObserver {
        override fun onResume(owner: LifecycleOwner) {
            textview.text = "hoge"
        }
    }
}
```

そもそもなぜ Observer を使うのか？

「 [Handling Lifecycles with Lifecycle-Aware Components](https://developer.android.com/topic/libraries/architecture/lifecycle) 」には次が書いてありました。

> Moreover, there's no guarantee that the component starts before the activity or fragment is stopped. This is especially true if we need to perform a long-running operation, such as some configuration check in `onStart()`. This can cause a race condition where the `onStop()` method finishes before the `onStart()`, keeping the component alive longer than it's needed.

つまりコンポーネントが開始する前にアクティビティやフラグメントが停止する可能性やコンポーネントの競合状態が発生すると、必要以上に長い間稼働し続けることになるらしい。

つまり次のようなサンプルだと、状態の変化次第で本来の想定（画面を閉じる）とは逆の onStop -> onStart の順で呼ばれた場合 `myLocationListener.start()` が実行され続けてしまうからです。

```kotlin
public override fun onStart() {
    super.onStart()
    myLocationListener.start()
    // manage other components that need to respond
    // to the activity lifecycle
}

public override fun onStop() {
    super.onStop()
    myLocationListener.stop()
    // manage other components that need to respond
    // to the activity lifecycle
}
```

そのため `LifecycleObserver` を代わりに使うことで、上記の問題を解決するために推奨されたのだと理解しました。


以上です。
別の考察大歓迎なのでコメントください。
リスト編② 〜 入れ子のリスト・リストの要素除外 〜

# 目次
　[1.入れ子のリスト](#1-入れ子のリスト)
　[2.リストの要素除外](#2-要素除外)

# 1. 入れ子のリスト
実際の使用例。


```java
package jp.co.study.sample;

import java.util.ArrayList;
import java.util.List;

public class Qiita {
	public static void main (String args[]) {
		// なんでもリスト
		List<List<String>> whateverList = new ArrayList<List<String>>();
		
		// 魚リスト
		List<String> fishList = new ArrayList<String>();
		fishList.add("あじ");
		whateverList.add(fishList);
		
		// 鳥リスト
		List<String> birdList = new ArrayList<String>();
		birdList.add("すずめ");
		birdList.add("からす");
		whateverList.add(birdList);
		
		// 花リスト
		List<String> flowerList = new ArrayList<String>();
		flowerList.add("ひまわり");
		flowerList.add("さくら");
		flowerList.add("すみれ");
		whateverList.add(flowerList);
		
		// 出力
		System.out.println(whateverList.toString());
    }
}
```
出力結果は [[あじ], [すずめ, からす], [ひまわり, さくら, すみれ]]。


なんでもリスト（whateverList）に、
魚リスト（fishList）、鳥リスト（birdList）、花リスト（flowerList）が設定されている。



# 2. リストの要素除外

色々な方法があると思いますが、今回は新たにリストを作成して除外する方法を記載します。
ひとつ前のソースのなんでもリスト（whateverList）内3つのリストのうち、
要素数が3以上でないものを除外。

```java
package jp.co.study.sample;

import java.util.ArrayList;
import java.util.List;

public class Qiita {
	public static void main (String args[]) {
		// なんでもリスト
		List<List<String>> whateverList = new ArrayList<List<String>>();
		
		// 魚リスト
		List<String> fishList = new ArrayList<String>();
		fishList.add("あじ");
		whateverList.add(fishList);
		
		// 鳥リスト
		List<String> birdList = new ArrayList<String>();
		birdList.add("すずめ");
		birdList.add("からす");
		whateverList.add(birdList);
		
		// 花リスト
		List<String> flowerList = new ArrayList<String>();
		flowerList.add("ひまわり");
		flowerList.add("さくら");
		flowerList.add("すみれ");
		whateverList.add(flowerList);

		// あたらしいリスト作成
		List<List<String>> newWhateverList = new ArrayList<List<String>>();
		
		// whateverList内3つのリストの要素数を確認
		for (List<String> strList : whateverList) {
			if (strList.size() >= 3) {
                // 要素数が3以上のリストのみnewWhateverListに追加
				newWhateverList.add(strList);
			}
		}
		
		// whateverListのアドレス自体をnewWhateverListのアドレスで上書き
		whateverList = newWhateverList;
		
		// 出力
		System.out.println(whateverList.toString());
	}
}
```
出力結果は [[ひまわり, さくら, すみれ]]

なんでもリスト（whateverList）内、
魚リスト（fishList）、鳥リスト（birdList）、花リスト（flowerList）のうち、
要素数が3以上あるのは花リスト（flowerList）のみのため、花リスト（flowerList）のみ出力。
Windows Server にフェールオーバークラスタリングをインストールする

こんにちは！haruです。
SQLServer でクラスター環境を構築するには、フェールオーバークラスタリングが必要となるため、こちらをインストールしていきます。

**WSFC(Windows Server Failover Cluster)**
稼働している複数台のサーバーを1つのサーバーが稼働しているかのように使うことができる機能です。
1つのサーバーが停止しても、利用者側で特に操作をすることなくシステムを再開することができます。

## フェールオーバークラスタリングのインストール  ※クラスターを構成する全サーバーで実施します。
1.サーバーマネージャーを起動し、「役割と機能の追加」をクリックします。
![WSFC1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/403505bd-9ec4-0a7d-f94e-8ada59ac9130.png)

2.「機能の選択」の「機能」まで「次へ(N)」で進み、「フェールオーバークラスタリング」を選択します。
![WSFC2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/c5e7a4da-7be5-f945-0c6d-f0f932306f99.png)

3.「機能の追加」をクリックします。
![WSFC2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/746668b0-9aa0-758d-f7c4-a0d70db50a7d.png)

4.「はい(Y)」を選択して再起動を行います。
![WSFC3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920045/37b7e6c1-3189-2d6f-a597-5b51cb5004c6.png)

以上です。
php API 開発メモ


```
■出力側プログラム(api.php)

<?php
// 文字コード設定
header('Content-Type: application/json; charset=UTF-8');

// numが存在するかつnumが数字のみで構成されているか
if(isset($_GET["num"]) && !preg_match('/[^0-9]/', $_GET["num"])) {
    // numをエスケープ(xss対策)
    $param = htmlspecialchars($_GET["num"]);
    // メイン処理
    $arr["status"] = "yes";
    $arr["x100"] = (string)((int)$param * 100); // 100倍
    $arr["x500"] = (string)((int)$param * 500); // 500倍
} else {
    // paramの値が不適ならstatusをnoにしてプログラム終了
    $arr["status"] = "no";
}

// 配列をjson形式にデコードして出力, 第二引数は、整形するためのオプション
print json_encode($arr, JSON_PRETTY_PRINT);

?php>

実行   ブラウザに貼り付け
http://localhost:1024/api.php?num=10

★実行結果 {"status":"yes","x100":"1000","x500":"5000"}



■呼び出し側プログラム(api_call.php)

<?php
// 文字コード設定
header('Content-Type: text/html; charset=UTF-8');

// numパラメータにセットする値
$num = 10;
// WebAPIのURL
$url = "http://localhost:1024/api.php?num=${num}";
// URLの内容を取得し、json形式からstdClass形式に変換し取得
$data = json_decode(file_get_contents($url));
// 連想配列で取得したかったら第二引数にtrueを指定↓
// $data = json_decode(file_get_contents($url), true);

// dataのstatusがyesだったら(出力に成功したら)
if($data->status == "yes") {
    // 100倍の値をprint
    print $data->x100;
}

if($data->status == "yes") {
    // 500倍の値をprint
    print $data->x500;
}

?>

実行   ブラウザに貼り付け
http://localhost:1024/api_call.php

実行結果  
1000
5000



おまけ

郵便番号⇒住所API
http://zipcloud.ibsnet.co.jp/api/search?zipcode=1350006

外部api呼び出す
https://laraweb.net/surrounding/9720/
paiza.ioでelixir その21

# 概要
paiza.ioでelixirやってみた。
Supervisor使ってみた。

# 参考にしたページ

https://qiita.com/song_ss/items/6a8c2ecd688a61ebebe6

# サンプルコード

```

defmodule Counter.Server do
	use GenServer
	require Logger
	def start_link(current_number) do
        Logger.info "ok"
		GenServer.start_link(__MODULE__, current_number, name: __MODULE__)
	end
	def count_up do
		GenServer.call __MODULE__, :up
	end
	def count_down do
		GenServer.cast __MODULE__, :down
	end
	def current_number do
		GenServer.call __MODULE__, :current
	end
	def handle_call(:up, _from, current_number) do
		{:reply, current_number + 1, current_number + 1}
	end
	def handle_call(:current, _from, current_number) do
		{:reply, current_number, current_number}
	end
	def handle_cast(:down, current_number) do
		{:noreply, current_number - 1}
	end
	def kill do
		Logger.info "ok2"
		pid = Process.whereis(__MODULE__)
		Process.exit(pid, :kill)
	end
end

defmodule Counter.Supervisor do
	use Supervisor
	def start_link(arg) do
		Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
	end
	def init(_) do
		children = [{Counter.Server, 0}]
		Supervisor.init(children, strategy: :one_for_one)
	end
end

Counter.Supervisor.start_link([])
|> IO.inspect
Counter.Server.current_number
|> IO.inspect
Counter.Server.count_up
|> IO.inspect
Counter.Server.count_up
|> IO.inspect
Counter.Server.kill
|> IO.inspect
:timer.sleep(100)
Counter.Server.current_number
|> IO.inspect
Counter.Server.count_up
|> IO.inspect



```

# 実行結果

```
10:12:16.472 [info]  ok
{:ok, #PID<0.99.0>}
0
1
2
true

10:12:16.477 [info]  ok2

10:12:16.477 [info]  ok
0
1
```

# 成果物

https://paiza.io/projects/iNolnAK34ij6y7uUhzxFsw


以上。
R: NIMBLE の使い方 (その1)

こちらのページと同じことを行いました。
[Introduction to NIMBLE](https://oliviergimenez.github.io/nimble-workshop/)
冬前に、57匹の動物を放し、冬が開けたら、19匹の動物を捕まえたという状況の分析です。

## ライブラリーのインストール

```text
install.packages('nimble')
install.packages('MCMCvis')
```

## プログラム

```r:animals.R
#
library(nimble)
library(MCMCvis)
#
computeLifespan <- nimbleFunction(
    run = function(theta = double(0)) { # type declarations
        ans <- -1/log(theta)
        return(ans)
        returnType(double(0))  # return type declaration
    } )
#
computeLifespan(0.8)
# nCcomputeLifespan <- compileNimble(computeLifespan)
# CcomputeLifespan(0.8)
#
model <- nimbleCode({
  # likelihood
  survived ~ dbinom(theta, released)
  # prior
  theta ~ dunif(0, 1)
  # derived quantity
  lifespan <- computeLifespan(theta)
})
#
my.data <- list(survived = 19, released = 57)
parameters.to.save <- c("theta", "lifespan")
initial.values <- function() list(theta = runif(1,0,1))
n.iter <- 5000
n.burnin <- 1000
n.chains <- 2
mcmc.output <- nimbleMCMC(code = model,
                          data = my.data,
                          inits = initial.values,
                          monitors = parameters.to.save,
                          niter = n.iter,
                          nburnin = n.burnin,
                          nchains = n.chains)
MCMCsummary(object = mcmc.output, round = 2)
#
```

## 実行結果

```text
$ Rscript animals.R 
nimble version 0.12.2 is loaded.
For more information on NIMBLE and a User Manual,
please visit https://R-nimble.org.

 次のパッケージを付け加えます: ‘nimble’ 

 以下のオブジェクトは ‘package:stats’ からマスクされています:

    simulate

[1] 4.48142
Defining model
Building model
Setting data and initial values
Running calculate on model
  [Note] Any error reports that follow may simply reflect missing values in model variables.
Checking model sizes and dimensions
Checking model calculations
Compiling
  [Note] This may take a minute.
  [Note] Use 'showCompilerOutput = TRUE' to see C++ compilation details.
Running chain 1 ...
|-------------|-------------|-------------|-------------|
|-------------------------------------------------------|
Running chain 2 ...
|-------------|-------------|-------------|-------------|
|-------------------------------------------------------|
         mean   sd 2.5%  50% 97.5% Rhat n.eff
lifespan 0.93 0.16 0.67 0.92  1.28    1  1799
theta    0.34 0.06 0.22 0.34  0.46    1  1818
```

次のバージョンで確認しました。

```text
$ Rscript --version
Rscript (R) version 4.2.1 (2022-06-23)
```
WindowsにPycharmの「Failed to create a virtual environment」解決

# 事象
Windows11にPycharm CE版を入れて、「Python Interpreter」を設定する時に、「Failed to create a virtual environment」というエラーメッセージが出てしまって、設定できなかった。
メモとして、解決案を残します

# 解析
* Pycharmに対して、何か環境にエラーが起きた時に、「idea.log」にエラーメッセージとか普通に残っています。
* 「Help」→「Show log in Explorer」を押す
* 「idea.log」中の内容を確認する

# 解決
## エラー内容
```
INFO - #c.j.p.p.PyPackageManagerImpl - Fatal Python error: init_stdio_encoding: failed to get the Python codec name of the stdio encoding
Python runtime state: core initialized
LookupError: unknown encoding: windows-31j

Current thread 0x00000aa0 (most recent call first):
  <no Python frame>
```
## 原因
起動のdefault encodingは「windows-31j」にしてしまいました

## 解決方法
* Pycharmのインストールフォルダーに「bin/pycharm64.exe.vmoptions」という起動オプション設定ファイルが存在しています
* 最後に、encodingを「utf-8」に設定するようなオプションを追加する
```
-Dfile.encoding=UTF-8
```
* Pycharmを再起動してからこの事象は直しました
macOS Version 13.0 Venturaで Homebrew をアップデートした際に躓いた点と解決法

# お、OSのアップデート来てるやん。ポチー
こんにちは、けこです。軽率なアップデートは混乱を（自分に）招く。
またやってしまいましたが親切な記事のおかげで解決したので共有の意味を含めて記事を書くことにしました。

## 今回の出来事
gitでリポジトリをcloneしようとしたところ、gitが入っていないと怒られる。
```
~/Desktop/Routine $ git clone https://github.com/keko5342/Daily-production.git
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
~/Desktop/Routine $ git
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
```
gitをbrewで入れようとしても怒られる
```
~/Desktop/Routine $ brew install git
Warning: You are using macOS 13.
We do not provide support for this pre-release version.
You will encounter build failures with some formulae.
Please create pull requests instead of asking for help on Homebrew's GitHub,
Twitter or any other official channels. You are responsible for resolving
any issues you experience while you are running this
pre-release version.

Error: No developer tools installed.
Install the Command Line Tools:
  xcode-select --install

Error: 'git' must be installed and in your PATH!
Warning: You are using macOS 13.
We do not provide support for this pre-release version.
You will encounter build failures with some formulae.
Please create pull requests instead of asking for help on Homebrew's GitHub,
Twitter or any other official channels. You are responsible for resolving
any issues you experience while you are running this
pre-release version.

Error: No developer tools installed.
Install the Command Line Tools:
  xcode-select --install
```
こちら`xcode-select --install`を実行しても動作するようにならなかったため、

以下の記事を参考に、
https://zenn.dev/tyamahori/articles/56188e6ede0306

1. https://developer.apple.com/download/all/ にアクセスして、`Command Line Tools for Xcode 14.1 Release Candidate 2` をダウンロード&インストール
2. `brew updrade`を実行

したところ解決しました。原因はxcodeのコマンドラインツールが古かったことが原因なので先のコマンドでも解決するはずなのですが、解決しない方がいる場合はお試しください。
【Linux】コマンドでファイル数を出力する方法

## `ls`コマンド

`ls`コマンドを使用してファイル数を出力するには以下のように実行します。  

```zsh
ls -fp パス | grep -v / | wc -l
```

* `ls -fp パス`  
  ディレクトリ内のファイル一覧を表示。  
  ファイルを並べ替えずドットファイルも含めて表示。  
  ディレクトリの場合`/`を出力。  
* `grep -v /`  
  `/`を含まないもののみ出力。
* `wc -l`  
  出力結果の行数をカウント。

## `find`コマンド

`find`コマンドを使用してファイル数を出力するには以下のように実行します。  

```zsh
find パス -type f | wc -l
```

* `find パス -type f`  
  指定したパス以下の全ファイルのパスを出力。
* `wc -l`  
  出力結果の行数をカウント。
Google UXデザイン：振り返り（Empathize〜Define〜Ideate)

# はじめに

わたしが[Google UX Design Certificateで得られた素晴らしい体験][google]を、特に重要だと思われるポイントを小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ Google UX Design Certificateを受講してみてください。

[google]: https://qiita.com/mapami/items/7a0d0a3d4661c50f8bec

https://www.coursera.org/professional-certificates/google-ux-design

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/c3d622bb-c1ed-447b-c15e-c1bccff32a4a.png" width="800">

# 振り返り（Empathize〜Define〜Ideate)

これまで
- [共感マップ][map]
- [ペルソナ][persona]
- [ユーザーストーリー][story]
- [ユーザージャーニーマップ][journey]

[map]: https://qiita.com/mapami/items/44d441768bb9e7b35ed4
[persona]: https://qiita.com/mapami/items/8a6894d0ca86ff8bc17f
[story]: https://qiita.com/mapami/items/9631b603ec05266725a8
[journey]: https://qiita.com/mapami/items/f185213bb21c660216c8

を使って、ユーザーが体験しそうなペインポイントを特定しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/8ed68fda-e655-994f-799d-9a6253951f5a.jpeg" width="400">

<table>
  <thead>
    <tr>
      <th>名前</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td>共感マップ</td>
　　　　　　　　<td>ユーザーの心と体に触れ、ある状況におけるユーザーの考えや感情を理解する。</td>
  </tr>
  <tr>
    <td>ペルソナ</td>
　　　　　　　　<td>誰のためにデザインしているのかを思い出す。</td>
  </tr>
  <tr>
    <td>ユーザーストーリー</td>
　　　　　　　　<td>ペルソナを発展させ、ユーザーグループに対する理解を深める。<br>また、どのニーズを解決することが最も重要であるかを決定する。</td>
  </tr>
  <tr>
    <td>ユーザージャーニーマップ</td>
　　　　　　　　<td>私たちが「ペインポイント」を軽減するデザインのアイデアを思いつく。</td>
  </tr>
</table>

リサーチ結果は、ユーザーが本当に必要としているものに基づいて製品をデザインする方法を理解するために役立ちます。そ

UXデザイナーとして、私たちは常にユーザーのことを第一に考えています。そのため、リサーチで得られた知見をアイデア出しに活用することは、非常に有効なのです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f907118e-5af8-5efb-f1be-9cc4bbe5cc89.jpeg" width="400">
[備忘録] MUI v5でTypographyに独自のvariantを追加する方法

# はじめに

MUI v5でTypographyに独自のvariantを追加する方法を調べたとき、ググるとv4の情報が出てきたりして意外と見つけにくかったのでメモしておきます。

[MUIの公式サイト](https://mui.com/material-ui/customization/typography/#adding-amp-disabling-variants)にやり方は書いてありますが、手っ取り早く知りたい人（＝自分）向けに。


# 追加方法

（例）**label**という名前のvariantを追加する場合。


```typescript:theme.ts
import { createTheme } from "@mui/material/styles";

declare module "@mui/material/styles" {
  interface TypographyVariants {
    label: React.CSSProperties;
  }

  // allow configuration using `createTheme`
  interface TypographyVariantsOptions {
    label: React.CSSProperties;
  }
}

// Update the Typography's variant prop options
declare module "@mui/material/Typography" {
  interface TypographyPropsVariantOverrides {
    label: true;
  }
}

const theme = createTheme({
  typography: {
    label: {
      color: "#C03030",
      fontSize: 24,
      fontWeight: "bold",
    },
  },
});

export default theme;
```

と書いておけば、あとは以下のように使える。

```typescript:App.tsx
import React from "react";
import { Typography } from "@mui/material";
import { ThemeProvider } from "@mui/material/styles";
import theme from "../src/theme";

function App() {
  return (
    <ThemeProvider theme={theme}>
      <Typography variant="label">
        ラベル
      </Typography>
    </ThemeProvider>
  );
};

export default App;
```
RIBSアーキテクチャー入門

* RIBsは絵の各要素で構成されている。各要素は各自クラスによって実装される。
![ribs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087353/46f34faa-c075-c66c-63c7-6cebf4029c33.png)

# RIBsの部品
## Interactor
* ビジネスロジックを持つ。
Rxのsubscriptionを行う所であって状態を変更の決定をする所でもある。どこにどのデータを保存するかを決めるまた他のどのRIBsがchildrenとして付けるかを決めるところでもある。
* 全ての操作はInteractorがアクティブの場合のみ行われる。


## Router
Interactorのイベントを聞いてChild RIBsを貼りつけたり切り離したりする。つぎの３つの理由で存在する。
* Humble Objectとして動く。複雑なInteractorをMock Interactorを作ることなくテストしやすくする
* 親Interactorと子Interactorの抽象的なレイヤーを作る。Interactor同士のむずかしいコミュニケーションとreactive communicationを勧める。
* 他のInteractorに実装されるrouting logicを含む。

## Builder
* RIBsの構成クラスのインスタンスを生成する。RIBsのchildも生成する。

## Presenter
* ビジネスロジックをViewModel変換したりその逆をしたりする状態独立なクラス
* Presenterは必須クラスではないので省略された場合はView(Controller)またはInteractorが代わりにする。

## View(Controller)
* UIを生成して更新する。インスタンス生成とUI Componentの描画とユーザの操作、アニメーション。情報を表示する以外にはなるべくロジックを少なくする。UTが必要なロジックは含まない。

## Component
* RIB依存関係を管理する。Buildを補助してRIBのインスタンスを生成する。RIBを生成時に必要な外部依存クラスに接近することを許容する。一般的に子RIBが親RIBに接近できるように親RIBは子Buildに注入される。

# 状態管理
* アプリ状態は現在貼り付けられたRIBsツリーによって管理され表現される。RIBsはツリー構造を持っている。RIBsは子RIBsのみ管理する孫RIBsは知らない）
* ただ全ての状態がRIBsが貼り付けられるか切り離されることで表現される訳ではない。
例えばユーザプロフィールを変更した場合RIBsツリーに変更はない。
![state.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1087353/17a146c4-b4d2-d731-75b3-0642fa7c9cdf.gif)


* Humble Object pattern
https://shtnkgm.com/blog/2020-05-17-humble-object-pattern.html
要はテストしにくいロジックを少なくする
Humble Object pattern is mentioned in the book - Clean Architecture: A Craftsman's Guide to Software Structure and Design by Uncle Bob, Chapter 23 - PRESENTERS AND HUMBLE OBJECTS



参照：https://github.com/uber/RIBs/wiki
AppleのMac M1/M2マシンにTeradata Studioをインストールする方法

著者 [Satish Chinthanippu](satish.chinthanippu@teradata.com)
最終更新日 2022年9月1日

:::note warn
警告
本記事はTeradata Corporationのサイト[Getting Started](https://quickstarts.teradata.com/index.html#getting-access-to-vantage)に掲載された内容を抄訳したものです。掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。正確な内容については、原本をご参照下さい。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::

# 概要
このハウツーでは、Apple Mac M1/M2マシンへのTeradata StudioおよびTeradata Studio Expressのインストールを説明します。

# 手順
①	Rosettaバイナリトランスレータをインストールし、有効にします。[Apple Mac M1 Rosetta インストールガイド](https://support.apple.com/en-us/HT211861)に従います。
②	x64ベースのJDK 11をご希望のベンダーからダウンロードし、インストールします。例えば、[Azul](https://www.azul.com/downloads/?version=java-11-lts&os=macos&architecture=x86-64-bit&package=jdkGet)からx64 JDK 11をダウンロードすることができます。
③	Teradata Downloadsページから、最新のTeradata StudioまたはTeradata Studio Expressのリリースをダウンロードします。
　○　[Teradata Studio](https://downloads.teradata.com/download/tools/teradata-studio)
　○　[Teradata Studio Express](https://downloads.teradata.com/download/tools/teradata-studio-express)
④	Teradata Studio/Teradata Studio Expressをインストールします。詳細は、[Teradata StudioおよびTeradata Studio Expressインストールガイド](https://quickstarts.teradata.com/_attachments/Studio-Express-InstallGuide.pdf)を参照してください。


# まとめ
Appleは、Apple MAC M1マシンにARMベースのプロセッサを導入しました。Intel x64ベースのアプリケーションは、ARMベースのプロセッサーではデフォルトでは動作しません。Teradata StudioまたはTeradata Studio Expressも、現在のStudio macOSビルドがintel x64ベースのアプリケーションであるため、デフォルトでは動作しません。このハウツーでは、Apple Mac M1にIntel x64ベースのJDKとTeradata StudioまたはTeradata Studio Expressをインストールする方法について説明します。

#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
Google Search Consoleの所有権の確認が更新されない

Google Search Consoleの所有権の確認済みだが，
別ネームサーバーに移し替えたい。

## TXTレコードを削除しても所有権の確認がされ続ける
設定済みのTXTレコードを削除してもGoogle Search Console側では待てど暮らせど確認が取れない．．
気長に待てば認証が外れると思いますが，せっかちな私は24時間経ったところでギブアップしました

## 解決法方
### 別アカウントから従来のアカウントの権限を削除し，再度設定する
一旦別Googleアカウントから当該アカウントの管理を削除しましょう
別GoogleアカウントのSearchConsoleに入り，プロパティの追加から該当のアカウントを入力。
TXTレコードが出力されるので，新たに設定したネームサーバーへTXTレコードを入力。
認証が取れたら，
権限→ユーザーと権限
へアクセスし従来アカウントを削除します

![スクリーンショット 2022-10-28 17.20.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869250/faea82e9-925e-cd53-d460-1760dae844e0.png)
上記画像のように権限を制限付きにしておかないと削除できないようです


削除できたら従来アカウントで同じことをやればいいだけです
再度TXTレコードを発行し，ネームサーバーへ設定します
CreateMLで回帰分析すーる

# はじめに
CreateMLで回帰分析していきまーす

# 開発環境
- MacBook Pro (13-inch, 2018)
- macOS Monterey 12.6
- Xcode 14.0.1 

# 導入
1．Xcode -> Open Developer Tool -> Create MLを開きます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/ed5cea04-f608-a07a-5924-31610c3e7cc3.png)

2．New Documentをクリックして、新規作成します

3．Tabular Regressionを選択し、Nextをクリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/e40e9580-ff54-229f-6631-6aafd89b1ad5.png)

4．Project Nameを入力し、Nextをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/197e9bbd-c518-18c7-22f4-1bab42875c10.png)

5．SettingsタブでTraining Dataを入力します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/df6cdb06-f6c0-e4c9-a5ed-4ad3740e3fbf.png)

6．住宅価格の予測をしてみましょう

https://www.kaggle.com/competitions/house-prices-advanced-regression-techniques/data

7．train.csvをtrain_1.csvとtest_1.csvに分けておきます

8．train_1.csvをTraining Dataに入力しましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/fe87aae9-7089-c648-d8a6-c24c75f76fb8.png)

9．TargetにSalePriceを選びます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/a2ac49f1-0a1b-dbc5-9844-d6107731a6ca.png)

10．Featuresを全て選択します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/42ac0efe-c79d-d80c-9ac9-31d65838bbb6.png)

11．Trainボタンをクリックし、学習を開始します

12．欠損値があるとエラーが出るようです

- LotFrontage
- GarageYrBlt
- MasVnrArea

をFeaturesから外します

※PoolQCは全てNAなので自動的に削除されているようです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/aa1f0ff3-10ad-9565-f208-a38769130c86.png)

13．Training Completedが表示されたら学習完了です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/dd5aa55a-0d9f-b6aa-8ca1-41c3dd934ce6.png)

14．Evaluationタブでtest_1.csvをTesting Dataに入力しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/e58502db-d1ea-6d3e-2e37-efba8733b7e7.png)

15．testボタンをクリックしてテストします

16．テスト結果が出ました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/9b452170-1a32-66fe-40cb-003291cd8d3b.png)

18．OutputタブでGetボタンをクリックするとCore MLのモデル（.mlmodel）が保存できます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/5e1f6d7e-57ad-6a30-21bf-dd5f9b4446de.png)

お疲れ様でした
AWS Black Belt Online Seminar IAM Part1 まとめ

# はじめに

「AWS Black Belt Online Seminar IAM Part1」を視聴したので備忘録です

https://www.youtube.com/watch?v=K7F5yTThynw&t=1s

# IAM とは

## IAM の定義

AWSリソースをセキュアに操作するために認証・認可の仕組みを提供するマネージドサービス

## IAM の特徴

・各AWSリソースに対して別々の権限をユーザ毎に割り当てることができる
・多要素認証にも対応
・一時的なトークンを用いた認可ができる
・料金は無料

# IAM 用語解説

## ルートユーザ

ルートユーザとは
そのアカウントの全てのAWSサービスとリソースに全ての権限を持つユーザ(なんでもできる)

注意事項
・基本的なオペレーションはルートユーザでは行はない
・ルートユーザのアクセスキーは作成しない
・ルートユーザの認証情報をプログラムに埋め込まない
・多要素認証を有効化する(強い権限を持つIAMユーザにも多要素認証を有効化した方がいい)

ルートユーザでしかできない操作
・ルートユーザのパスワード/メールアドレスの変更
・IAMユーザに課金情報の権限を与える

## アクセスキー

アクセスキーとは
ルートユーザ、IAMユーザが持つことのできる長期的な認証情報
(手動で削除または無効化しない限り有効)

使用用途
・AWS CLI や AWS SDKからリクエストを出す際に使用する

注意点
・アクセスキーは共有しない
・Git HubやAMIの中への埋め込みなどはしない
・設計書などのドキュメントに記載しない

## IAMユーザ

IAMユーザとは
AWSで作成するユーザ

IAMの識別方法
・ユーザ名
・ユーザのARN(Amacon resource name)

認証方法
・コンソールパスワード(AWSコンソールにログインするときに使う)
・アクセスキー(プログラムを使ってアクセスするときに使う)
(ユーザ作成時に作成する認証情報を選べる)

注意点
・ルートユーザを使わず、必要に応じてIAMユーザを作成する
・強力なパスワードポリシーを設定する
　　

個別にIAMユーザを作成することのメリット
・認証情報を個別に変更できる
・Amazon Cloud Trailログからアクションを追跡できる

## IAMポリシー

IAMポリシーとは
IAMアイデンティティ(ユーザ、ロール、AWSリソース)に関連づけてアクセス許可を定義するもの

IAMポリシーの特徴
・JSONのポリシードキュメントで定義する

IAMポリシーの種類
・AWS管理ポリシー
　　AWSによって定義されたポリシーで、ユースケースに合わせた定義が沢山ある。
　　定義の種類2つ
　　　①リソースごとのポリシー：S３フルアクセス、S3リードオンリーなど
　　　②ジョブごとのポリシー：アドミンポリシーなど
・カスタマー管理ポリシー
　　ポリシーの内容をカスタマイズできる
　　そのため、別のAWSアカウントでは使用できない
・インラインポリシー
　　1つのエンティティに直接埋め込まれたポリシー
　　エンティティが削除されると一緒に削除される

注意点
・インラインポリシーはあまり使わないようにする

## ポリシードキュメント

ポリシードキュメントとは
JSONで記述された、権限の定義

ポリシードキュメントの主な要素
・version：ポリシードキュメントのバージョン、必須ではない
・statement：具体的なアクセス許可を記載する、以下5つの要素を記載できる
　・effect：Allow/Denyを指定
　・principal：AWSリソースへのアクセスが許可/拒否されるIAMエンティティを指定する
　　　　　　    IAMグループ、ワイルドカードは指定できない
　・action：許可/拒否される特定のアクションを指定する
　　　　　　 NotActionを使うと、指定したもの以外を許可という指定ができる
　　　　　　 ワイルドカードで許可するアクションを指定可能
　・resource：プリンシパルがアクセスできるAWSリソースを指定する
　　　　　　　　ワイルドカードで許可するリソースを指定可能
　・condition：ステイトメントが有効になるタイミングの条件を指定する
　　　　　　　　 必須ではない

アクセス可否の決定ロジック
　明示的な許可　> 暗黙的な拒否
　明示的な拒否　> 明示的な許可

## IAMグループ

IAMグループとは
IAMユーザの集合体

IAMグループの特徴
・IAMユーザしか所属させることができない
・IAMユーザは複数のグループに所属させることができる
・IAMグループ自体は認証情報を持っているわけではない

IAMグループの使い方
・IAMユーザが増えたときに管理を簡単にするために使う

## IAMロール

IAMロールとは
AWSサービスやアプリケーション等のエンティティに対してAWSリソースの操作の権限を付与するための仕組み


## AWS CloudTrail

AWS CloudTrailとは
AWSリソースにどのような操作が加えられたかの記録を残す機能

使用用途
・どのようなユーザがAWSリソースを操作しているかの確認
・正しい運用ができているかを評価するために使用する

## アクセスアドバイザー

アクセスアドバイザーとは
IAMエンティティが最後にAWSリソースにアクセスした日付と日時を表示する機能

使用用途
IAMの最小限のアクセスを設定するための指針にする。
(作ったときに必要だと思った権限だけど、使われていないものや使わなくなったものが分かる)

## IAM認証情報レポート

IAM認証情報レポートとは
CSV形式でIAMの認証情報の記録を出力する
4時間毎に一回出力できる

出力情報の例
・最後にユーザが使われた日時
・AccessKeyがアクティブか
・AccessKeyを最後に使用した日時
・AccessKeyが最後に使用したAWSリソース
・証明書はActiveか
・AccessKey、証明書をローテートした日時

使用用途
不要な認証情報を削除するために使用する
認証情報の適切なローテーションができているかどうかを確認するために使用する(パスワード変更)

IAMユーザのローテーション
IAMユーザのパスワードポリシーで自身のパスワードを変更できるように設定。
パスワードに有効期限を設けて、利用者が定期的にパスワードをローテーションできるようにする。

AccessKeyのローテーション
新しいアクセスキーを作成してテストしたのちに、既存のキーをインアクティブにする。
問題が発生した場合は元のキーに戻すことができる

# IAM運用例

![スクリーンショット 2022-11-02 17.49.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/837136/adcedbbf-9464-55a4-4c6b-7a5c768e51fa.png)
学習したい内容

# 自己紹介
- おっさん
- システムエンジニア歴10年超(2社)

# きっかけ
転職活動を通じて、自身の技術力のなさを実感し、このままじゃだめだと感じた

# 学習したいこと
- AWS、Azure、GCP
- ネットワーク基礎知識
- システム構成
- 英語
- アウトプットする(Qiita投稿など)
Spring Boot + MyBatisで自作TypeHandlerを使う

# 環境
- JDK 17
- Spring Boot 2.7
- mybatis-spring-boot-starter 2.2.2



# やり方
## 型の作成
```java:Hoge.java
package com.example.entity;

public record Hoge(String value) {
}
```

## TypeHandlerの作成
`@MappedTypes` を付加するのがポイント。

```java:HogeTypeHandler.java
package com.example.typehandler;

import com.example.entity.Hoge;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

@MappedTypes(Hoge.class)
public class HogeTypeHandler extends BaseTypeHandler<Hoge> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Hoge parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, parameter.value());
    }

    @Override
    public Hoge getNullableResult(ResultSet rs, String columnName) throws SQLException
        String value = rs.getString(columnName);
        if (value == null) {
            return null;
        }
        return new Hoge(value);
    }

    @Override
    public Hoge getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String value = rs.getString(columnIndex);
        if (value == null) {
            return null;
        }
        return new Hoge(value);
    }

    @Override
    public Hoge getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String value = cs.getString(columnIndex);
        if (value == null) {
            return null;
        }
        return new Hoge(value);
    }
}
```

## application.propertiesの設定
自作TypeHandlerが含まれているパッケージ名を指定する。

```properties:application.properties
mybatis.type-handlers-package=com.example.typehandler
```

# 参考資料
- [MyBatis公式ドキュメント](https://mybatis.org/mybatis-3/ja/configuration.html#typehandlers)
- [mybatis-spring-boot-starterの使い方](https://qiita.com/kazuki43zoo/items/ea79e206d7c2e990e478)
GPU非搭載 CPU上でOpenAIのWhisperを試して音声データを文字起こししてみた。

## まえがき
社内で打ち合わせ時に録画しているデータを元に、議事録を起こしているため  
文字起こしサービスやOSSを探していてWhisperを試してみることにした。

## スペック
- Intel(R) Xeon(R) CPU E5-2667 4コア
- RAM 8GB
- CentOS Linux 8.x

## 導入
### Dockerfileの準備
```Dockerfile
FROM python:3.9-slim

WORKDIR /workspace

# 以下は、プロキシサーバがある場合は記載
ENV http_proxy http://proxy.xxxx.co.jp
ENV https_proxy http://proxy.xxxx.co.jp 
ENV HTTP_PROXY http://proxy.xxxx.co.jp
ENV HTTPS_PROXY http://proxy.xxxx.co.jp

RUN apt-get update && apt-get install -y \
    build-essential \
    gcc \
    git \
    ffmpeg \
    && rm -rf /var/lib/apt/lists/*

RUN pip install --upgrade pip
RUN pip install setuptools-rust
# 以下は、プロキシサーバがある場合は記載
RUN git config --global http.proxy http://proxy.xxxx.co.jp
RUN git config --global https.proxy http://proxy.xxxx.co.jp
RUN git config --global http.sslVerify false

RUN pip install git+https://github.com/openai/whisper.git
```

### Dockerイメージの作成
```bash
# ./ にはDockerfileのパスを指定 例として./としている
docker build -t whisper ./
```

### コンテナ実行
```bash
docker run -it -d -v $(pwd):/workspace/ --name whisper whisper
```

## 実際に文字起こし
- Dockerfileと同ディレクトリに音声ファイルを配置する。

```bash
ll
-rw-r--r-- 1 root root Dockerfile
-rw-r--r-- 1 root root audio.m4a
```


- 文字起こし実行

```bash
docker exec -it whisper bash -c "whisper audio.m4a --language ja"
100%|███████████████████████████████████████| 250M/250M [00:20<00:00, 13.5MiB/s]
/usr/local/lib/python3.9/site-packages/whisper/transcribe.py:78: UserWarning: FP16 is not supported on CPU; using FP32 instead
  warnings.warn("FP16 is not supported on CPU; using FP32 instead")
```

## 生成ファイル
```bash
ll
-rw-r--r-- 1 root root Dockerfile
-rw-r--r-- 1 root root audio.m4a
-rw-r--r-- 1 root root audio.m4a.srt
-rw-r--r-- 1 root root audio.m4a.txt
-rw-r--r-- 1 root root audio.m4a.vtt
```

## 内容はどうか
内容を把握できるかというレベルで言うと十分把握ができ、議事録に改めて起こす必要があるため
あまりに理解しづらいことがない文字起こしレベルであると言えるので、実用性は高いと思われます。
```
[20:20.400 --> 20:23.400] はい、承知しましたありがとうございます
[20:23.400 --> 20:29.400] すみませんガーッと喋ってますけど理解できました?
[20:29.400 --> 20:31.400] 大丈夫です
[20:31.400 --> 20:32.400] よかったよかった
[20:32.400 --> 20:34.400] よくわかんなくなったらまた聞いてください
[20:34.400 --> 20:39.400] 私もなんか全然うまくする気がしない
[20:39.400 --> 20:41.400] はい、ありがとうございます
```

## かかった時間
20分程度の音声データで、1時間かかりました。
ただ他のプロセスが稼働している状態での試行だったので、実際はもう少し短いかもしれません。
公式には、`Multilingual model`を`large`を指定する際の、推奨VRAMは10GBと記載されてあります。[^1]
GPUを搭載するのがやはり一番いいですね・・


## 参考
https://openai.com/blog/whisper/
https://github.com/openai/whisper

[^1]: https://github.com/openai/whisper#available-models-and-languages
M5StickC-PlusにVSCodeのPlatformIOを利用して書き込む

`VSCode`の拡張機能に`PlatformIO`という、`Arduino`や`mbed`、`ESP-IDF`などの開発環境やさまざまなフレームワークに対応した組み込み型の`IDE`(統合開発環境)があります。
![スクリーンショット 2022-10-25 10.24.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/9034bc05-5c85-377a-ee53-32f2224456fb.png)
今回はこちらを使って、`M5StickC-Plus`にプログラムを書き込んでみたいと思います。
![スクリーンショット 2022-10-25 10.26.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/958c3366-6ec5-173e-5978-d1d2778a0885.png)
`＋　　New Project`を選択して
![スクリーンショット 2022-10-28 15.27.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/9fc9669f-718b-1979-eb2f-4191d724a15c.png)
以下を入力したら`Finish`をクリックします。
![スクリーンショット 2022-10-28 15.30.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/3dfc2181-2ca5-b90a-1b63-1d3c120ed32a.png)
すると、`M5Stick-C`に対応した環境構築が一瞬で出来上がります。
![スクリーンショット 2022-10-28 15.43.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/f823110c-6010-c597-3610-ecae541371c7.png)
`HOME`に戻って`Libraries`の検索で`m5stickcplus`と入力すると
![スクリーンショット 2022-10-28 15.47.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/1a74805c-28eb-2cd0-6567-196ea7559e53.png)
こちらが出てくるのでクリックします。
![スクリーンショット 2022-10-28 15.53.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/ef02c484-44fd-ab44-e564-b19e417fe4df.png)
`Add to Project`を押してもらって
![スクリーンショット 2022-10-28 15.55.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/e86d7e91-1ee5-4f61-2c7c-cf968abe5bc5.png)
![スクリーンショット 2022-10-28 15.59.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/485517ea-4e6c-81f6-7b2c-a12789575af8.png)
`Congrats!`と出てきたら、`platformio.ini`を確認しましょう。
![スクリーンショット 2022-10-28 16.00.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/a6787e63-b348-2dd1-8968-6fdf751b4e7d.png)
`lib_deps`に`M5StickCPlus`が付与され使えるようになります。
![スクリーンショット 2022-10-28 16.09.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/e0f80e35-bc7d-eaa2-d5d4-947b141f6253.png)
`srcディレクトリ`の`main.cpp`を書き換えてLチカできるようにしてみます。
![スクリーンショット 2022-10-28 16.19.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/4b42a23d-c950-11f4-49d5-d97c216f964b.png)
```main.cpp
#include <M5StickCPlus.h>

void setup()
{
  M5.begin();

  Serial.begin(115200);
  delay(500);
  Serial.print("M5StickC-plus Start\n");

  M5.Lcd.print("Hello World");

  pinMode(10, OUTPUT);
}

void loop()
{
  digitalWrite(10, HIGH);
  Serial.print("LED TURN ON\n");
  delay(1000);
  digitalWrite(10, LOW);
  Serial.print("LED TURN OFF\n");
  delay(1000);
}
```
左下アイコンからビルドしてエラーが出なかったらアップロードを実行します。
![スクリーンショット 2022-10-28 16.47.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/fe8f71e0-d3f5-9367-ce6c-6dc52c585564.png)
点灯して`Hello World`が出力されました。
![スクリーンショット 2022-10-28 16.57.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1134006/c0ccd846-21ab-0e66-bcce-77d2e1aafc60.png)