OmniAICreator/Qiita-1.07M huggingface dataset:
【AWS】ローカルからプライベートサブネットにあるRDSに接続したい

## 現在の構成
ローカルから踏み台サーバを経由してRDSに接続できるようになっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/562737f4-e162-c635-6428-3dc39e24558c.png)

## やりたいこと
javascriptでDB(MySQL)のコネクションを作ってデータをローカルで取得したい

現状だとRDSはプライベートサブネットにあるのでアクセスできない。
アクセスしようとするとエラーをはかれる

## やること
***SSHポートフォワーディング***をする
1\. EC2,RDSのセキュリティグループの設定
* EC2のセキュリティグループ　仮セキュリティグループ名：EC2-sg

| タイプ    | プロトコル | ポート範囲 | ソース        | 値             |
|----------|-------------|------------|---------------|----------------|
| SSH      | TCP       | 22         | カスタム       | 0.0.0.0/0       |

* RDSのセキュリティグループ　仮セキュリティグループ名：RDS-sg

| タイプ    | プロトコル | ポート範囲 | ソース        | 値             |
|----------|-------------|------------|---------------|----------------|
| MySQL/Aurora     | TCP       | 3306         | カスタム       | EC2-sg       |

EC2のセキュリティグループを指定します。

2\. TeraTermを使ってポートフォワーディングする
TeraTermにSSH接続をします。
その後、設定から`SSH転送`をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/0504ca14-b969-ab69-3fb9-a5e0c4b29c84.png)

次に、ポート転送の追加をクリック
ローカルのポート:`3306`
リモート側のホスト:`RDSのエンドポイント`
ポート:`3306`
を入力してOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/5dc85870-6c83-a952-5cc5-e4812fc1ff4b.png)

3\. MySQL WorkBenchで接続する
WorkBenchでは丸の3つを入力すれば接続できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/1eb656b8-b97b-fe0a-0447-69d4b02a4844.png)

4\. javascriptのコードから確認
db.jsを作成して、`node db.js`で動かしてみます

ポートは3100番を開けていて
http://localhost:3100/data
にアクセスすると正常に取得することができました。

また、TeraTerm(SSH)の接続を切ると取得することができなくなるので、セキュリティ面でもメリットがあると思います

コード↓
```javascript:db.js
const mysql = require("mysql");
const express = require("express");
const app = express();

const connection = mysql.createConnection({
  user: "admin",
  password: "***",
  database: "***",
});

app.get("/data", function (req, res) {
  connection.connect(function (err) {
    if (err) throw err;
    connection.query(
      "SELECT * FROM DB名.テーブル名",
      function (err, result, fields) {
        if (err) throw err;
        res.json(result);
      }
    );
  });
});

app.listen(3100, function () {
  console.log("API listening on port 3100!");
});
```

### 参考
[RDSにSSHポートフォワーディングを利用して接続してみた](https://dev.classmethod.jp/articles/rds-portforward/)
バッチファイルを作り、robocopyによってフォルダをミラーリングする

## 概要

robocopy.batは以下の効果を持つ。

* sourceからdestにミラーリング(ファイル内容を完全に同期)する
* ログをlogfolder下に日付付きファイルで出力(robocopy_2023-01-30.log)
* 1週間前のログファイルは実行と同時に削除される

```bat:robocopy.bat
@echo off
rem ファイル保存時のエンコードにより、以下の数値を変えること(Shift-JIS:932, UTF-8:65001)
chcp 932

rem -----Params-----
rem ミラーリング源
set source="C:\work\source"

rem ミラーリング先
set dest="C:\work\dest"

rem ログファイルを作成するフォルダ
set logfolder="C:\work\log"
rem -----Params-----

rem -----Function-----
rem logfolder下に日付付きのlogファイルを作る(robocopy_2023-01-30.log)
set logfile=%logfolder%"\robocopy_%date:~0,4%-%date:~5,2%-%date:~8,2%.log"

rem robocopyコマンドでフォルダをミラーリングする
robocopy "%source%" "%dest%" /MIR /LOG+:"%logfile%"

rem ログフォルダにある、更新日時が7日前の.logファイルを全て削除する
forfiles /P "%logfolder%" /M "*.log" /D -7 /C "cmd /c del @file"
rem -----Function-----
```

## 注意

### batファイルのエンコード

.batファイルをShift-JISで保存する場合は```chcp 932```
UTF-8の場合は```chcp 65001```を指定すること。

### batファイルのテスト実行は「管理者として実行(A)」

robocopyコマンドは「管理者として実行(A)」じゃないと動かない？
[Android][Jetpack Compose]You cannot access the NavBackStackEntry's ViewModels after the NavBackStackEntry is destroyed.

NavControllerのpopBackStackを使って前画面に戻るという実装をしたが
実行時にエラーが起きてアプリが落ちた。

```
FATAL EXCEPTION: main
Process: ........, PID: 6785
java.lang.IllegalStateException: You cannot access the NavBackStackEntry's ViewModels after the NavBackStackEntry is destroyed.
at androidx.navigation.NavBackStackEntry.getViewModelStore(NavBackStackEntry.kt:202)
at androidx.navigation.compose.NavHostKt.NavHost(NavHost.kt:104)
at androidx.navigation.compose.NavHostKt.NavHost(NavHost.kt:67)
.
.
.
省略
```

解決方法
===
popBackStack()ではなくて
```kotlin
navigateUp()
```
を使う

参考
==
https://developer.android.com/reference/androidx/navigation/NavController#navigateUp()

>navigateUp
>ナビゲーション階層で上に移動することを試みる。
>ユーザーが、アプリ UI の左上（または開始）隅にある左向きの矢印でマークされた「Up」ボタンを押したときに適しています。

> popBackStack
> コントローラのバックスタックをポップしようとします。
> これは、ナビゲーションホストにフォーカスがあるときに、ユーザがシステムの戻るボタンを押したときに似ています。
esp-idf: ssid のスキャン

[esp-idf/examples/wifi/scan/](https://github.com/espressif/esp-idf/tree/master/examples/wifi/scan) を参考にしました。
M5Stack Core2 で動作確認をしました。

## プログラム

コンパイル前のフォルダー構造

```text
$ tree scan
scan
├── CMakeLists.txt
├── README.md
└── main
    ├── CMakeLists.txt
    └── scan.c
```

```text:main/CMakeLists.txt
idf_component_register(SRCS "scan.c"
                    INCLUDE_DIRS ".")
```

```c:main/scan.c
// -----------------------------------------------------------------------
/*
	main/scan.c

					Jan/30/2023
*/
// -----------------------------------------------------------------------
#include <string.h>
#include <unistd.h>

#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"

#define DEFAULT_SCAN_LIST_SIZE 16

#define	VERSION	"2023-1-30 AM 11:29"
// -----------------------------------------------------------------------
static void wifi_scan_aa(void)
{
	ESP_ERROR_CHECK(esp_netif_init());
	ESP_ERROR_CHECK(esp_event_loop_create_default());
	esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
	assert(sta_netif);

	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
	ESP_ERROR_CHECK(esp_wifi_init(&cfg));
}

// -----------------------------------------------------------------------
static void wifi_scan_bb(void)
{
	uint16_t number = DEFAULT_SCAN_LIST_SIZE;
	wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
	memset(ap_info, 0, sizeof(ap_info));
	uint16_t ap_count = 0;

	ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
	ESP_ERROR_CHECK(esp_wifi_start());
	esp_wifi_scan_start(NULL, true);
	ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));
	ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));

	printf("Total APs scanned = %u\n", ap_count);

	for (int it = 0; (it < DEFAULT_SCAN_LIST_SIZE) && (it < ap_count); it++)
		{
		printf("%d\tSSID \t%s\n", it,ap_info[it].ssid);
		}

	printf("\n");
}

// -----------------------------------------------------------------------
void loop(void)
{
	while (1)
		{
		printf("*** loop *** %s ***\n",VERSION);
		wifi_scan_bb();
		sleep(5);
		}
}

// -----------------------------------------------------------------------
void app_main(void)
{
	// Initialize NVS
	esp_err_t ret = nvs_flash_init();
	if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
		ESP_ERROR_CHECK(nvs_flash_erase());
		ret = nvs_flash_init();
	}
	ESP_ERROR_CHECK( ret );

	wifi_scan_aa();
	sleep(3);
	printf("*** %s ***\n",VERSION);

	loop();
}

// -----------------------------------------------------------------------
```

## コンパイル、実行

```bash
idf.py -p /dev/ttyUSB0 flash
```

## 実行結果

```text
*** loop *** 2023-1-30 AM 11:29 ***
Total APs scanned = 11
0	SSID 	Buffalo-G-7008
1	SSID 	rs500m-e1eaf5-2
2	SSID 	rs500m-e1eaf5-1
3	SSID 	TP-Link_E2EE
4	SSID 	C0B47DD1BB49-2G
5	SSID 	DIRECT-D30B7833
6	SSID 	Buffalo-G-37E8
7	SSID 	ssw-pc-639639
8	SSID 	HG8045-549F-bg
9	SSID 	Buffalo-G-8E70-WPA3
10	SSID 	aterm-6c79cc-gw
```
【AWS】VSCodeのターミナルからEC2の踏み台サーバを通してRDSに接続したい

## 今回したこと
RDSに接続する際、`TeraTerm`を使用して`EC2→RDS`に接続していたが、`VSCode`から接続を試みた
（VSCodeというより普通のターミナル powershell）

今回はやっていませんが、Remote-sshという拡張機能を使用するともう少し楽にできそうです

## やってみる
***1\. AWS上で踏み台サーバの確認→接続***
踏み台サーバーのEC2インスタンスにアクセスを行い、チェックボックスにマークを入れて、右上の接続をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/a6e44f0d-662a-7a08-9417-be05a95daa03.png)

***2\. SSHクライアントのコマンド確認***
ターミナル上でSSH接続するためのコマンドが表示されます。
3の「キーが公開されていないことを確認する」は必須ではないと思いますが、やっておきましょう
※注意点　ファイルの指定方法
.pemファイルはどこかのフォルダに置いていると思いますが、そこに対してのパスを指定しましょう
（デスクトップの下にあるなら deckctop/xxx.pemのような感じ）

4番の指定方法も同じでパスを指定してあげましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884542/e68a73da-e926-e0fa-d269-689ceec69bde.png)

***3\. VSCodeのターミナルで確認***
4番のコマンドを入力すると
```
Are you sure you want to continue connecting (yes/no)?
```
と表示されるので`yes`と入力しましょう

すると・・
```

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
15 package(s) needed for security, out of 16 available
Run "sudo yum update" to apply all updates.
```
いつもの画面が出てきました。
画面解像度(画素数)のあれこれ

# はじめに

仕事でComputer Visionに関わっているけど、HDやらFull HDやらのことをちゃんとわかっていなかったなと思ったのでここらで一度まとめてみる。

# そもそも画面解像度(画素数)とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2043769/6486b68b-0f9c-3cd6-427f-043c607a8552.png)


[wiki](https://ja.wikipedia.org/wiki/%E7%94%BB%E9%9D%A2%E8%A7%A3%E5%83%8F%E5%BA%A6)の説明では

> 慣用的にコンピュータ等のディスプレイに表示される総画素数を指す。
> 本来の「解像度」の言葉通り、画面の精細さを指すこともあるが、区別する場合は画素密度またはピクセル密度 (pixel density) と称される。
> 画素数を表す場合は「横×縦」や「横x縦」などの形（例えば1024×768, 1920×1080）で示され、密度を表す場合は「○ dpi」や「○ ppi」の形（例えば96 dpi, 600 ppi）で示される。

とのこと。

同じ様な表現で画像解像度があるが、こちらは1インチ中にドット(ピクセル)がどれくらい含まれているかを表したもので若干ではあるが示しているものが異なる。

1. 画面解像度：画像全体に含まれるピクセル数の総数
1. 画像解像度：1インチ中に含まれるピクセル数の総数

# 画面解像度の規格

> 詳細は[wikiの表](https://ja.wikipedia.org/wiki/%E7%94%BB%E9%9D%A2%E8%A7%A3%E5%83%8F%E5%BA%A6#%E8%A6%8F%E6%A0%BC)をご覧ください。

よく聞く規格についてまとめておく。

| 規格名 | 横x縦(px) | アスペクト比 |
| --- | --- | --- |
| HD | 1280x720 | 16:9 |
| FHD | 1920x1080 | 16:9 |
| 4K | 3840x2160  | 16:9 |
| 8K | 7860x4320 | 16:9|

> 自分の知っている代表的なものを上げたけど基本16:9の比率...

他にも様々な規格があるので、見かけたときに気にしてみる。

# さいごに

- 解像度、と一言で表現していたが、画面解像度と画像解像度の2つがあるのは知らなかった
- 主な規格の横x縦、アスペクト比をまとめられたのでなんとなくニュアンスをつかめｔ
Visual Studio Code でNeovim pluginを導入する

Visual Studio Code で**Neovim plugin**を導入する手順を解説します。  
Visual Studio Code へのvim導入なら、**Vimプラグイン**を導入すれば手っ取り早いのですが
下記のような動作でイライラすることが何度かあったので、この際**Neovim plugin**へ乗り換えることにしました。

- ファイルを切り替えた際にカーソル位置が1行目に移動してしまう。
- 挿入モードでウィンドウ切り替えができない。

## Neovim インストール

- 下記ページから、zip形式インストールファイル`nvim-win64.zip`をダウンロードします。  
<https://github.com/neovim/neovim/releases/tag/stable>
- ダウンロードしたファイルを任意のフォルダへ展開します。  
ここでは、`C:\home\app\nvim-win64`を展開フォルダに指定したとします。

## Neovim 設定

- Neovim設定フォルダを作成します。  
Neovimの設定フォルダは`%LOCALAPPDATA%/nvim`です。  
例) ログインユーザー：`user999`の場合、Neovim設定フォルダは`C:\Users\user999\AppData\Local\nvim`です。
- Neovim設定ファイルを作成します。
Neovimの設定ファイルは`Neovim設定フォルダ\init.vim`です。
例) ログインユーザー：`user999`の場合、Neovim設定ファイルは`C:\Users\user999\AppData\Local\nvim\init.vim`です。
- Neovim設定ファイルへ設定を反映します。　　
Neovim設定ファイルへ、設定を書き込みます。  

[init.vim 設定例]

```init.vim
set clipboard+=unnamedplus

nnoremap x "_x
nnoremap c "_c
nnoremap d "_d
vnoremap d "_d
```

## Neovim プラグイン インストール

- VSCode Neovim プラグインをインストールします。
![image](https://user-images.githubusercontent.com/38905609/215370492-42c1befd-39c0-4dcf-b297-e4048546b127.png)

## Neovim プラグイン 設定

- VSCode 設定でVSCode Neovim プラグインを設定します。
![image](https://user-images.githubusercontent.com/38905609/215371296-b01a1807-1309-4714-812e-6d275853e506.png)

[setting.json]

```:json
"vscode-neovim.neovimExecutablePaths.win32": "C:\\home\\app\\nvim-win64\\bin\\nvim.exe"
```

## 👇参考URL

- <https://zenn.dev/yutakatay/articles/vscode-neovim>
- [WindowsにNeoVimをインストールして設定ファイルinit.vimを読み込ませるまで](https://qiita.com/karakuri-t910/items/81f005ab6992ff54d5a5)

[Visual Studio Code でNeovim pluginを導入する](https://docusaurus.plant11.com/tips/neovim)
[クロスアカウント]S3バケット間でのS3sync(S3アクセスポイント編)

# はじめに
AWSアカウントを跨いで、データ・ファイル連携をしたい場面が多く、
手軽に実装できるS3を介した連携について、まとめてみました。
S3での連携方法はいくつかありますが、今回はS3アクセスポイントを使用した方法について記載します。

# やりたいこと
アカウントAにあるEC2から、アカウントBが所有するS3バケットにS3アクセスポイント経由でアクセスし、アカウントAが所有するS3バケットにファイル連携がしたいです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2740559/58c6d4f9-b3e5-af94-2499-1bc3c567035a.png)

# 作成手順
ポリシーの記載内容が混乱しがちなので、主にポリシーについて記載します。

## アカウントA側
- S3バケット作成
- EC2作成
- EC2にアタッチするIAMロール作成
IAMロールのポリシーは下記の通りです。
```json
{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "s3:List*",
            "s3:Get*",
            "s3:Put*"
        ],
        "Resource": [
            "arn:aws:s3:::{アカウントA側のS3バケット名}/*",
            "arn:aws:s3:::{アカウントA側のS3バケット名}",
            "arn:aws:s3:::{アカウントB側のS3バケット名}/*",
            "arn:aws:s3:::{アカウントB側のS3バケット名}",
            "arn:aws:s3:{リージョン}:{アカウントB側のAWSアカウント番号}:accesspoint/{S3アクセスポイント名}",
            "arn:aws:s3:{リージョン}:{アカウントB側のAWSアカウント番号}:accesspoint/{S3アクセスポイント名}/object/*"
        ]
    }
}
```
- S3エンドポイント作成
## アカウントB側
- S3バケット作成
　S3バケットのポリシーは下記の通りです。
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{アカウントA側のAWSアカウント番号}:role/{アカウントA側のIAMロール名}"
            },
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:::{アカウントB側のS3バケット名}",
                "arn:aws:s3:::{アカウントB側のS3バケット名}/*"
            ],
            "Condition": {
                "StringLike": {
                    "s3:DataAccessPointArn": "{アカウントB側のS3アクセスポイントarn}"
                }
            }
        }
    ]
}
```
- S3アクセスポイント作成
　S3アクセスポイントのポリシーは下記の通りです。
```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::{アカウントA側のAWSアカウント番号}:role/{アカウントA側のIAMロール名}"
            },
            "Action": [
                "s3:ListBucket",
                "s3:GetObject"
            ],
            "Resource": [
                "arn:aws:s3:{リージョン}:{アカウントB側のAWSアカウント番号}:accesspoint/{アカウントB側のS3アクセスポイント名}/object/*",
                "arn:aws:s3:{リージョン}:{アカウントB側のAWSアカウント番号}:accesspoint/{アカウントB側のS3アクセスポイント名}"
            ]
        }
    ]
}
```
【基礎学習】ETLとELTの違い

# 今回の課題
ETLとELTの違いについて理解したかった。

## ETLとは
抽出、変換、書き出しの手順でデータを処理する。
データソース→ストレージと、ストレージ→DWHの2種類のETLが必要になる。

データの転送もあるので、JavaやPythonなどのプログラミング言語で処理を実装する必要があるため、一部のデータエンジニアではないと対応が難しかった。

## ELTとは
抽出、変換、書き出しの手順でデータを処理する。
データレイク層が「DWH」システム上に構築されるようになったもの。
データソース→BigQuery（データレイク＆DWH）という一回のELTで済む。

データ変換であれば、SQLで対応可能なので、アナリストやマーケターでも対応しやすい方法。
BigQueryなどの、ストレージ課金が最小化されていて、処理速度が向上したDWHサービスが台頭し始めたことによって、こちらで対応されることが増えた。

※参考:[なぜETLではなくELTが流行ってきたのか](https://qiita.com/hiro_koba_jp/items/f7f85511937cb6603a65)
【mysql】最新の日付を取得する

# 最新の日付のレコードを取得する

## max関数を使用する
```sql
SELECT max(日付のカラム) FROM テーブル名;
```
* 結果として最新のカラムのみ取得できる。

## ORDER BYを使用する
```sql
SELECT * FROM テーブル名 ORDER BY カラム名 DESC LIMIT 1;
```
* 結果として最新のレコード全体が取得できる。
rex0220 プラグイン 複数レコードのテーブルを１テーブルにまとめて取得 その３


複数レコードのテーブルを１テーブルにまとめて取得後、指定した数値で小計を求め、さらに集計します。
[その２](https://qiita.com/rex0220/items/43a92ed89e451e52d691)の内容にセット数を入力して、セット毎に数量・金額計算。商品毎の集計するを計算式プラグインで行います。

# 概要

セット情報に追加したセット数で、明細テーブルの小計数量・小計金額を計算します。
集計テーブルには、商品がどのセットのものなのかセット番号を表示します。

- 編集画面
![2023-01-30_00h45_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d07f509e-32eb-e4f1-137c-819e241766dd.png)

- 詳細画面
![2023-01-30_10h00_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/f1fce082-dea5-6c86-266a-8a74e3b5c516.png)


# 操作例

![2023-01-30_00h51_06.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/9988b453-def0-5f2e-4e96-d0477f3a4106.gif)

# 集計アプリ

セット数と数値・金額の小計を追加します。
集計テーブルのTセット番号は、商品がどのセットのものなのか表示します。

![2023-01-30_09h27_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5bae2665-f07f-43a8-e741-d1fee156bd1b.png)

# アプリ集計プラグインの設定

明細テーブルに追加した項目は、そのまま

![2023-01-30_09h35_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/7b69e678-bc8c-990b-f35f-6ecc8aa8cb29.png)

# 計算式プラグインの設定

セット数で、セット小計・小計数量・小計金額を計算し、集計テーブルに集計します。
セット番号を"join" で集計すると、「SET-002, SET-003」のように連結して表示します。

~~~
// 合計金額
SUMIF(AND(有効,商品セット名),セット小計)
// セット情報概要
JOIN(
  TARRAYIF(AND(有効,商品セット名),
    商品セット名&"("&FIXED(セット数)&")"),
  " ")
// セット小計
セット金額*セット数
// 明細テーブル　：　チェックのみで、テーブル項目が入力不可になります。
// 小計数量
数量*セット数1
// 小計金額
金額*セット数1
// KEY1 ：　非表示
// 集計テーブル
TLTABLE(明細テーブル,
　TPFILTER(IN(分類,"明細","小計")),
　TPKEY(分類,KEY1,単価),
　TPVAL(数量*LET(sn,セット番号1,FIRSTIF(AND(有効="有効",セット番号=sn),セット数)),"sum",
   金額*LET(sn,セット番号1,FIRSTIF(AND(有効="有効",セット番号=sn),セット数)),"sum",セット番号1,"join"),
　TPOUT(T分類,T商品,T単価,T数量,T金額,Tセット番号),
   TPSORT(T分類,0,T商品,1)
)
// TNo
ROWNO(集計テーブル)+1
// T分類、T商品、T単価 ： チェックのみ
// T数量
IF(T分類="明細",T数量)
// T金額　：　チェックのみ
~~~

![2023-01-30_09h39_32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/2c7000f5-2bc8-cf34-d788-3e6663426179.png)
rex0220 プラグイン 複数レコードのテーブルを１テーブルにまとめて取得 その２

アプリ集計プラグインを使って、複数レコードのテーブルを１テーブルにまとめた後、計算式プラグインで商品ごとに集計してみます。
[その１](https://qiita.com/rex0220/items/045ecbec9a5836df4e8d)の内容に商品ごとの集計する処理を計算式プラグインで追加します。
今回は、アプリ集計プラグイン、計算式プラグイン、項目書式プラグイン、ちょっと便利なプラグインを使います。

- [rex0220 プラグイン 複数レコードのテーブルを１テーブルにまとめて取得 その３](https://qiita.com/rex0220/items/0ca31e05fc63e0131f0f)

# 概要

セット番号をルックアップで複数指定して、商品をテーブルにまとめたセットマスタアプリから、商品情報を明細テーブルに取得します。
明細テーブルから商品ごとに集計して、集計テーブルにセットします。
セット番号を指定すると、すぐに明細テーブルと集計テーブルに反映されます。

ただし、明細テーブルの行数が多くなると、動作が遅くなります。
明細テーブルは、３０行程度までが実用範囲だと思います。

- アプリ集計プラグインでテーブル内のルックップで指定された複数のセット番号の商品を１テーブルに取得
- 計算式プラグインで、商品ごとに集計

![2023-01-29_14h10_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/312d681a-7961-c806-ac6b-d05900403881.png)

# 操作例

![2023-01-29_15h13_04.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5859f5e9-c947-cbf1-273f-b30dee19b561.gif)

# マスタアプリ

その１と同じです。
![2023-01-29_16h42_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/c3f1fe3c-0695-bf9b-1132-5c1bfd624822.png)

# 集計アプリ

 集計先テーブルを追加します。

- セット情報：　取得するセットを指定するテーブル
    - 有効：　取得対象にチェック
- 明細テーブル：　マスタアプリから取得したセット情報
    - KEY1: 集計キーとして使います。
- 集計先テーブル：　部品ごとの集計先

![2023-01-29_16h53_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/9b2bf4ba-a9c4-c04e-fab4-c0247cfc4d5e.png)

# アプリ集計プラグインの設定

マスタアプリから、明細テーブルへデータを取得する設定を行います。
その１とほとんど同じです。

- テーブル項目
    - KEY1 ：集計キー
        - IF(分類="明細",商品,"")
            - 明細の場合は、商品。それ以外は、"" をセット

![2023-01-29_17h37_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/65f7ac88-0ed6-8558-a2a3-1d9dc9d09165.png)

# 計算式プラグインの設定

明細テーブルから集計テーブルに商品ごとの集計をおこないます。
その他に、いくつか集計と編集不可等の指定をします。

- 「循環参照を許可」をチェック

~~~
// 合計金額
SUMIF(AND(有効,商品セット名),セット金額)
// セット情報概要
JOIN(
  TARRAYIF(AND(有効,商品セット名),
    商品セット名&"("&FIXED(セット金額)&")"),
  " ")
// 明細テーブル　：　チェックのみで、テーブル項目が入力不可になります。
// KEY1 ：　非表示
// 集計テーブル
TLTABLE(明細テーブル,
　TPFILTER(IN(分類,"明細","小計")),
　TPKEY(分類,KEY1,単価),
　TPVAL(数量,"sum",金額,"sum"),
　TPOUT(T分類,T商品,T単価,T数量,T金額),
   TPSORT(T分類,0,T商品,1)
)
// TNo
ROWNO(集計テーブル)+1
// T分類、T商品、T単価 ： チェックのみ
// T数量
IF(T分類="明細",T数量)
// T金額　：　チェックのみ
~~~

![2023-01-29_19h46_14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/72a8aaca-b0a6-a652-3cc0-687c7f97c55c.png)

# 項目書式プラグインの設定

テーブルが見やすくなるように、テーブル行の背景色をかえます。

- セット情報：　無効の時に書式指定
    - 有効=""
- 明細テーブル：　小計行に書式指定
    - 分類="小計"
- 集計テーブル：　小計行に書式指定
    - 分類="小計"

![2023-01-29_19h57_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/2685b816-d7e3-bb36-67bb-a0c9eedc20a4.png)

# ちょっと便利なプラグインの設定

テーブル操作を少し便利にするオプションを指定します。

- F24 テーブルのヘッダ固定
- F30 詳細画面でテーブル行数表示
- F31 詳細画面でテーブルフィルター

![2023-01-29_20h02_28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/cc01f3a6-caff-adda-0816-dcb0f7178926.png)
表の相関係数を一覧で見たいときはどうしたらいい？

# 問題
一覧で相関係数を見たいときはどうしたらいい？
pythonのdataframeを使っている

# 解法
pandas.DataFrame.corr()をつかおう！

# 解答例

~~~python
df_corr = df.corr()
print(df_corr)
print(type(df_corr))
#           A         B         C
# A  1.000000  0.958927  0.905882
# B  0.958927  1.000000  0.987130
# C  0.905882  0.987130  1.000000
# <class 'pandas.core.frame.DataFrame'>
~~~

# 参考文献
Coursera data analysis with python　と
[https://note.nkmk.me/python-pandas-corr/](https://note.nkmk.me/python-pandas-corr/)
【基礎学習】DataLake, DWH, DataMart, RDBMSについて

# 今回の課題
DataLake, DWH, DataMart, RDBMSの違いについて、理解したかったため調べてみた。

## DataLake
規模に関わらず、WEBサイトやSNSなど、様々なソースから収集した生データを構造化データと非構造化データを問わず保存できる一元化されたリポジトリ。

### 構造化データ
2次元の表形式（Excelなど）となっているデータ。
### 非構造化データ
構造化データではないデータ。
PDF,音声,画像,動画など。


## DWH
* 様々なシステムからデータを保存し、それを分析するために整理するデータの倉庫。
└データ分析を目的としているので、アプリケーションではもう利用しなくなったアクセスログなどの情報も格納され、また一度格納されたデータが消されることは少ない。
* データ分析に特化したDB。
* 超並列処理アーキテクチャを採用していて、１つのクエリ処理を同時並行で行えるため、通常のDBよりも高い検索・分析機能を発揮する。
* 構造化データを格納する。

## DataMart
DWHの中から、構造化データを目的別に切り出し、小規模単位で管理しておくための収納庫。
目的ごとにテーブルを作成するので効率的にデータ分析ができる。


## RDBMS
リレーショナル・データベース・マネジメント・システム。
データベースのうち、データを表に似た構造で管理するもの。

DWHのようにデータ活用までは想定しておらず、あくまでデータを使いやすい形に整理して保管するもの。
データ活用までは想定していないため、
DWHとは異なり、目的に沿わないデータは更新・削除される。（例えば、人事データを格納するデータベースにて、新入社員が入社すれば社員のデータが追加され、退職者が出ればデータが削除される。といったイメージ。）

RDBMS以外に、DBにはいろいろな種類がある。
※参考：[【データベースの種類比較表】RDB以外も違いがわかるよう徹底比較](https://sonnaka.com/210201-2/)
Flaskでpprint

こんな感じで良いと思う

```python
from flask import Flask, render_template
import pprint

app = Flask(__name__)

@app.route('/')
def index():
    variable = {'key1': 'value1', 'key2': 'value2'}
    formatted_variable = pprint.pformat(variable)
    return render_template('index.html', variable=formatted_variable)
```

```html
<html>
  <body>
    <pre>{{ variable }}</pre>
  </body>
</html>

```
Azure Administrator(AZ-104)：Azure での ID とガバナンスの管理「Azure Policyの作成手順」

Microsoft Learnを用いたMicrosoft Azure Administrator(AZ-104)の試験内容をまとめる投稿です。
この投稿ではMicrosoft Learnで学ぶ内容をできるだけ簡潔にまとめております。
Azureの勉強を一から始め、AZ-900取得後の資格としてAZ-104取得を目指している方の参考になれば幸いです。
※AZ-900の内容は本投稿では省略しております。再度復習したい方は下記をご参照ください。
[Azure Fundamentals(AZ-900)：試験合格に向けた学習内容のまとめ](https://qiita.com/fsd-jume/items/e4ec76959adb547ac5e8)

## 今回の学習内容
**◆「Azure Policyの作成手順」**
◇対応するMicrosoft Learn ラーニングパス
[AZ-104:Azure での ID とガバナンスの管理](https://learn.microsoft.com/ja-jp/training/paths/az-104-manage-identities-governance/)
◇対応するモジュール
[Azure Policy を作成する](https://learn.microsoft.com/ja-jp/training/modules/configure-azure-policy/4-create-azure-policies)
[ポリシー定義を作成する](https://learn.microsoft.com/ja-jp/training/modules/configure-azure-policy/5-create-policy-definitions)
[イニシアチブ定義を作成する](https://learn.microsoft.com/ja-jp/training/modules/configure-azure-policy/6-create-initiative-definitions)
[イニシアティブ定義のスコープを指定する](https://learn.microsoft.com/ja-jp/training/modules/configure-azure-policy/7-scope-initiative-definition)
[コンプライアンスを決定する](https://learn.microsoft.com/ja-jp/training/modules/configure-azure-policy/8-determine-compliance)

※前回の投稿は下記から確認できます。
[Azure Administrator(AZ-104)：Azure での ID とガバナンスの管理「Azure Policy」](https://qiita.com/fsd-jume/items/76402c98a2d0c50635fa)

## Azure Policyの作成手順
### 手順1：ポリシー定義を作成
**◆ポリシー定義**
・リソースを評価する条件と条件を満たす際に実行するアクションをJSON形式で記述
・種類
　-用意された組み込みのポリシー定義
　-独自のポリシー定義(作成やインポートが可能)

**◆組み込みのポリシー定義(一例)**
・許可されている仮想マシンSKU：デプロイできるVMのSKUを指定
・許可されている場所：リソースをデプロイできる場所を制限(geoコンプライアンス要件)
・リソースへのタグの追加：デプロイ時にタグを指定していない場合に、必要なタグと既定値を適用

**◆独自のポリシー定義**
・新しい定義を追加/作成可能
・GitHubからAzure Policyへのインポートも可能
・ 新しい定義はほぼ毎日サンプルリポジトリに追加される

### 手順2：イニシアティブ定義を作成
**◆イニシアティブ定義**
・1つ以上の関連するポリシー定義をグループ化したJSON形式の定義
・リソースがセキュリティ規則に準拠していることを確認可能
・ポリシー定義の管理と割り当てを簡素化
・種類
　-用意された組み込みのイニシアティブ定義
　-独自のイニシアティブ定義

**◆組み込みのイニシアティブ定義(一例)**
・セキュリティで保護されていないパスワードのセキュリティ設定があるマシンを監査する
　-安全ではないパスワードセキュリティ設定をされているマシンを監査
・Azure Monitorエージェントを実行しデータ収集ルールに関連付けるようにWindowsマシンを構成する
　-Windows VM、仮想マシンスケールセット、Arcマシンの監視とセキュリティ保護を実施
　-Azure Monitorエージェント拡張機能がデプロイされ、データ収集ルールにリソースが関連付けられる
・ISO 27001:2013
　-情報セキュリティ管理システム(ISMS)を確立/実装/維持/継続的に改善するための要件の一部に対処

### 手順3：イニシアティブ定義のスコープを指定
・スコープ：定義が適用される範囲
⇒スコープによりポリシー割り当てを強制するリソース/リソースグループが決まる
・スコープは管理グループ/サブスクリプションから選択可能
・オプションとしてリソースグループも選択可能(省略可)
・除外：ポリシーの割り当てから除外するリソースを選択可能(省略可)
⇒スコープのレベルよりも一つ下のレベルで適用
⇒割り当てごとに個別に処理

### 手順4：コンプライアンスを決定
・コンプライアンス機能でスコープ内の既存のリソースに対して条件を評価
⇒該当した場合、そのリソースはポリシーに準拠していないと表示される
・Azure Portalには評価ロジックは表示されない
⇒コンプライアンスの状態の結果(対応/準拠していない)は表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2851723/9a331a3b-75e0-54a2-b0ac-4f80dd06a6f6.png)

## 次の学習内容
**◆Azure RBAC**

https://qiita.com/fsd-jume/items/19426ff0bba0ba7424d4

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

https://qiita.com/fsd-jume/items/6eda24728c9c03c36bc3
IBM i PTFダウンロード＆適用手順とIBM i サービス便利な使い方

以前はCD/DVDメディアでPTF配布が標準でしたが最近はFix Centralからオンラインでダウンロードが主流になっています。このため、このやり方がわからん、、という問い合わせが時々入るためメモとして。

■簡単な手順
こちらに一連の手順が記載されています。
Fix CentralからPTFをダウンロード・適用する手順
https://www.ibm.com/support/pages/program-temporary-fix-download-and-installation

■マニュアル
https://www.ibm.com/docs/ja/i/7.4?topic=fixes-ordering

以上スタンダードなガイドです。

以下はIBM i サービス（外部からSQLでIBM i OS機能やAPIをコールするI/F）を使用したPTF適用の例です。サンプルコードもそちらに記載しています。
*2023/1/30注　リンク先のデモ動画リンクが現在切れております。（復旧作業中・・）

■IBM i サービスを使用したPTF適用の自動運用のサンプルデモ
https://ibmi-demo-portal.com/030d19c3de3d4bbbab0b8d80922d5290

シナリオ：自システムのPTFレベルとIBMサイトの最新PTFレベルを比較し、差異のある（更新されたPTFがある）場合、自システムにダウンロードして適用可能状態にする。

実際の業務ではこの後PTFの適用作業を実施する必要がありますが、システムによってまちまちだと思うので自社なりにCLP等を作成いただけると思います。
本を読むのが苦手なエンジニアの読み方アドバイス

# 本を読むのが苦手なエンジニアの読み方

## 前提
ここで、記載する話は、あくまで自力で読み進めるのが難しい本を前提としています。自力で読み進められる（自身で興味を持って読める）本や、必要な箇所だけ読む技術書を対象にはしていません。文章形式で記載されたハウツー本などをイメージしています。

## 前書き
私は、本を読むのが苦手です。というより、あまり好きではありません。遅まきながら、30才を過ぎたころから、本の価値に気が付きました。しかし、それまであまり読んで来なかった本を、好き好んで読むのは難しいです。そこで、私が試行錯誤しながらあまり苦にならずに読めるようになった方法や同僚から聞いた方法をお伝えしたいと思います。

同じように本を読むのが苦手な方の一助になればと思います。

## 熟読 or 流し読み？
知識としてなんとなく知っていればいいのか、それを活かして何か成したいのかによって、読み方が変わります。前者は、流し読みを基本とし、興味がある部分のみ熟読すればＯＫです。基本、気になった部分は付箋などを付けて後でアクセスしやすくしておきます。後者は、しっかりメモを取り、今後どう活かすのかも合わせて考えながらまとめていく必要があります。得た知識を活かすなら、ただ分かるだけでは不十分で、それができるようにならなければなりません。さらに、活かせたのかチェックできるようにしなければなりません。まとめて終わりだと無価値だからです。さらに、その1冊だけでは足りません。関係する本や参考文献を芋づる式に読んでいくことで、　関連記憶（記憶へのアクセスパスを増やす事で、物事を覚えていく方法）を促し、知識の定着を図っていきます。結果、活かすことができるようになります。

## 読む為の理由だけ並べる
その本を読む目的を明確化にしましょう。
読むと何がいいのか、読まないとどんな不都合があるのか。

これから、読もうと決めているのだから、読む理由だけをテキストにたくさん書き留めてください。

書き留めたら眺めてみましょう。

どうでしょう？読む理由が明確になり、モチベーションが少し上がったでしょうか？

モチベーションが上がらないなら、あなたにとっては、その本を読む価値がないという事です。読まないといけない理由を確認するか、他の読みたい本を探す方がいいでしょう。

読めない、読まない理由を並べる人がいます。
時間がない、仕事が忙しい、もっと優先する事がある、読んでも何も変わらない、すぐ収入に繋がらない。さらには、字を読むと目が疲れる、頭が痛くなる、自分は実践派だから読書は不要。などなど・・

小学生高学年くらいになってくると、いくつでも出来ない理由を並べられるようになります。しかし、それをいくつ並べても無意味です。それなら、時間が無駄になるので、最初から読もうとしない方がいいでしょう。

それをするとどんな良いことがあるのか、どんなより良い未来が待っているのか、夢を含まらせ、読む理由を並べることが大切です。

## 読み方
1. 前書きを読む
   この人はなぜこの本を書いたのかその意図を汲み取る（ググってもいい）
1. 後書きを読む
   この本で著者が最も重視している点が書いている為把握する。要点を掴むことができます。

1. 目次を読む
   要点が記載されている箇所と。それに紐づく流れを、全体像として捉えます。結果、強弱をつけて読み進めることできます。
   著者が重視している点を熟読し、蛇足部分は流し読みでＯＫです。

   また、自分が最も興味がある点を見つけてください。そこで、疑問文で書き留めてください。
例：「〇〇とは？」「〇〇が重要な意味は？」

　　その答えを見つける形で本文を読んでいくと飽きずに読み進められます。

４. 本文を読む
　 自分の興味のある部分から読み進めても構いません。書き留めた疑問文に応える形で読み進めてもOKです。まずは、楽しんで読み進められることが大事です。
　　　　　　　　　　
## 集中力が続ない
本を読んでいると飽きてきます。15分もすれば集中力が切れます。その場合は、以下を試してみてください。

・ 読みながらメモを取る
・ 飽きたらメモを読み返し、気になった事などをググって、知識を深める。また読み進める
・ まとめたメモはブログなどで公開し、モチベーションアップと、他者からのコメントや質問による関連記憶向上を図る

## まとめて読もうと思ったがやる気が出ない
まとめて読むと負担が大きくなるので、とっかかりにくくなります。まずは、3分ででもいいです。毎日読む習慣、スタイルを身に付けていく事が大事です。もう一度書きますが、本を読むという習慣、スタイルが大事です。
寝る前でも、お風呂の時間でもいいので、習慣を作っていくところから始めましょう。
なんでも中間テーブルにすればいいと思ってたけど違った



中間テーブルで勘違いしていた内容にレビューの指摘で気づいたので投稿しました。なんでも中間テーブルにすればいいと思ってた、先週までの俺は恥ずかしいやつです。

## 記事を読むのにかかる時間
- 2分


## 結論
- 中間テーブルを作る前にテーブル毎の関係性を考える。多対多の場合は有効。１対多の場合だと、中間テーブルを作らなくても管理できる。
- 現状１対多の場合でも、将来的に仕様が変わる可能性がある場合は、最初から中間テーブルにしておいた方が楽。
- 中間テーブルを作ることで、手間が増えるので、作ればいいというものではない



## 背景
次の仕様のテーブル設計をしてました。
- ある機能のアクセスキーを管理するテーブルを新たに作る
- access_keyはユーザー毎に発行され、複数ユーザーが同じaccess_keyを持つことはない


### 指摘前のテーブル設計
```
usersテーブル
{
id
user_name
}

user_access_keyテーブル
(中間テーブルを作った)
{
user_id
access_key_id
}

access_keysテーブル
{
id
access_key
expired_date
}
```
しかし、リーダーからの指摘で
- 1対多のテーブルなので中間テーブルしなくていいよ

ときて、

### ほにょ!????? となり、

中間テーブルについて、とにかく使えばいいと思っていので
改めて調べました。


## テーブル同士の関係性について

### 1対多のイメージ
- 一つテーブルが別のテーブルの複数レコードと関連づいている状態
- 今回の仕様。access_keyが各ユーザーに紐づいている状態

### 多対多のイメージ
- あるテーブルの複数レコードが別のテーブルの複数レコードと関連づいている状態
- 今回の仕様に`複数ユーザーが同じaccess_keyを使っている場合`を追加した状態

## 中間テーブルを作る場合の条件
- 多対多の関係性を持つ場合
- 二つのテーブルの主キーを外部キーとする

## 自分が間違えたこと
- 一対多の関係性だったのに、安易に中間テーブルを作ってしまった。一対多だった場合は下記のようにすれば十分だった(将来的に仕様が変わることもない)

```
usersテーブル
{
id
user_name
}

access_keysテーブル
{
access_key_id
user_id
access_key
expired_date
}
```
- 中間テーブルにした場合のデメリットを考慮できていないかった。
   - Join作業が増え、大変になる.
   - テーブルが増えるので、データ容量が増える


## 最後に

中間テーブルを作ればいいというものではなさそうなので気をつけていきましょう
協調フィルタリングについて誤解してたこと

協調フィルタリングのユーザベースとアイテムベースって誤解されやすいと思ってて、実際誤解してた。

【概略】
ユーザベース: 似てるユーザーをレコメンド
アイテムベース: 似てるアイテムをレコメンド

【誤解してたこと】
ユーザベース: 
年齢やアクセス記録を
機械学習に食わせた時の類似度を見る

アイテムベース: 
タイトル、タグ情報、売れ具合などアイテムに閉じた情報を
機械学習に食わせた時の類似度を見る

【正しくは】
ユーザベース:
ユーザがあるアイテムに対して起こしたアクションを
機械学習に食わせて、
どういうタイプのアイテムが好きかという傾向の類似度を見る

アイテムベース
アイテムに関わったユーザ群を
機械学習に食わせて
どういうひとに好かれやすいかという傾向の類似度を見る
Lightboxのような画像リンクにwebpを対応させる方法

webp対応したときに、Lightbox系の画像にaリンクが必要な実装をした場合、対応ブラウザの可否で `.webp` と `.png` を書き換えなければいけなかったのでメモ。

## 前提：webp対応はModernizrを使用

ここでは前提として、JavaScriptライブラリ「Modernizr」を利用して、webpのブラウザ機能のサポート状況を自動的に検出してもらいます。

[Modernizr](https://modernizr.com/)

導入方法は割愛。（以下参考）

https://blanche-toile.com/web/css-background-webp

http://mtrad-blog.com/2021/11/11/post-2665/

## 例：スライダーなどんお画像リストにaリンクのポップアップなどがある時

```html
<ul class="gallery">
  <li>
    <a href="img/sample1.webp">
      <picture>
        <source srcset="img/sample1.webp" type="image/webp">
        <img src="img/sample1.png" alt="サンプル">
      </picture>
    </a>
  </li>
  <li>
    <a href="img/sample2.webp">
      <picture>
        <source srcset="img/sample2.webp" type="image/webp">
        <img src="img/sample2.png" alt="サンプル">
      </picture>
    </a>
  </li>
</ul>
```

## Jsでhref属性をwebpとpngで切り替え

HTMLの画像をまとめて取得して、ループでhref属性の `.webp` を `.png` に書き換えます。

```js
$(function () {
    if ($('html').hasClass('no-webp')) {
        let link = document.querySelectorAll('.gallery > li > a');

        for (var i = 0; i < link.length; i++) {
            // console.log(link[i]);
            let oldHref = link[i].getAttribute('href');
            // console.log(oldHref);
            let newHref = oldHref.replace('.webp', '.png');
            // console.log(newHref);
            link[i].setAttribute('href', newHref);
        }
    }
});
```

こうすることで、webp対応ブラウザでは、`.webp` になり、非対応ブラウザでは `.png` のリンクになります。
PhpStormで別リポジトリのコミットを大量Cherry-Pickする


# 前提条件
- リポジトリが異なる
- ファイル構成やソースがほぼ一緒
    - (例:別リポジトリでシステムの作り直しが進行している
- ブランチは一致していない


## 状況
リポジトリBで開発が進んでいて、
リポジトリBのコミットのいくつかを、リポジトリAに取り込みたいと考えています

![スクリーンショット 2023-01-30 7.03.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/ef884249-f72a-2427-480b-facc66c87292.png)

![スクリーンショット 2023-01-30 7.07.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/3fde22ce-bb50-a629-b263-2d677eee1bc2.png)

しかし、リポジトリが異なるため、rebaseやmergeという方法が取れません。

このような状況の時
PhpStormのGit機能を使ってコミットを取り込むという方法を書いていきます。

# 方法
## (1)リモートリポジトリにリポジトリBを追加
[Git] > [リモートの管理]
![スクリーンショット 2023-01-30 7.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/bfaefb90-5096-3ed4-61a0-0fc16636fffe.png)
[+] からリモートリポジトリの追加をする  
ここのURLはgit cloneするときのURLを入力
![スクリーンショット 2023-01-30 7.19.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/e5d1603a-8692-ddee-f59f-33308dec0477.png)


## (2) フェッチ
下部メニューの[Git] > [取り込みたいリモートリポジトリ]　> [フェッチ]
![スクリーンショット 2023-01-30 7.29.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/1941aa78-917d-02b5-7d20-c9ad263ce405.png)

時間かかる...
ローカルにコミット空っぽのブランチを作って
ブランチ指定でpullしてもいいかも(未検証)

## (3) cherry-pickする

1. 取り込み先のブランチにチェックアウトする
1. 取り込み元(ここではリポジトリBのリモートブランチ)の特定ブランチを選択
1. 取り込みたいコミットを右クリック > 🍒Cherry-Pick
![cherry-pick.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/108154/70e053a9-746e-ee6e-4ef7-6fca20396177.png)



---
大量にやる場合は
1. 取り込み先のブランチにチェックアウトする
1. 取り込み元(ここではリポジトリBのリモートブランチ)の特定ブランチを選択
1. 取り込みたいコミット選択（この時マージコミットを選択すると失敗するので選ばないこと)
1. 選択上で右クリック > 🍒Cherry-Pick



## (4) コンフリクトしたら解決する
慎重に確認しながらコンフリクトを解消してコミットを取り込んでいく



# さいごに
当初は、git format-patch を使って、特定コミットを起点として、
パッチを作成して取り込み先に当てるという方法を考えていたんですが
あまりに慣れぬことで上手くいかず、
普段よく使うcherry-pickで対応という策に落ち着いたという背景があります。

やっていることの状況が、なかなかのレアケースなので
絶対忘れると思い備忘録として書き残します。

---
弊社では、一緒に働いてくれるエンジニアを募集しています。
個人的には、PhpStorm好きーな人が来てくれたら、IDE談義したいっす

↓そんな感じで興味のある方はこちらから↓
[Wantedly - スタジオアンビルト株式会社](https://www.wantedly.com/companies/studiounbuilt)

こんなWebサービスを作っています。
・[マドリー](https://madree.jp/)
・[Studio Unbuilt](https://www.studiounbuilt.com/)
顧客分析の手順 - 複数のセグメントを比較する 

:::note
この本書は2017年4月1日にTeradata Japanのブログに掲載された内容を、再掲載したものです。
掲載内容の正確性・完全性・信頼性・最新性を保証するものではございません。
また、修正が必要な箇所や、ご要望についてはコメントをよろしくお願いします。
:::

著者 山本 泰史 （やまもと やすし）


# 顧客分析の手順

## 第9回： 複数のセグメントを比較する
セグメントは、選定基準によって何らかの特徴づけがなされています。性別にとって分類された「女性セグメント」は、当然ながら女性の集団であり、それ自体が大きな特徴の一つです。しかしながら、本来このような形式でセグメンテーションを実施する理由は、「女性に特徴的な傾向」を理解するためであり、選定基準に性別を選択した段階で「女性」であることは明白であるため、それ以外の傾向を把握することが目的となります。今回はこのような特徴を理解するための方法を考えます。

### セグメントが有している属性
顧客セグメントは常に、複数の顧客によって構成されています。したがって、このセグメントがどのくらいの「顧客数」によって構成されているかはそのセグメントを理解する上で重要な属性です。そして自社の顧客数全体に対してどの程度の割合を有しているかもここから導き出されます（「顧客数構成比」）。

また、そのセグメントをここまでで捉えてきた各種の変数で捉えることも可能です。平均的な買上金額、合計の買上金額、平均的な借入額、合計の借入額、特定商品／サービスへの利用の偏り（構成比）等がそのセグメントを特徴づけ、また、他のセグメントと比較を実施する際に役立てることができます。


### 他のセグメントとの比較
セグメント間での比較によって、得られる知識の最たるものとして、セグメント間の重要度が挙げられます。例えばセグメントA とセグメントB が、それぞれ同じ顧客数であるとすれば、平均的な支出額（=合計支出額）の大きなセグメントの方が重要なセグメントです。同様に平均支出額が同じ 2つのセグメントが存在し、それぞれのセグメント顧客数に違いがある場合には、顧客数の多いほうがより重要度が高いと言えます。以下の図16 は、2つのセグメントを比較した例です。いくつかの変数を用いることによって、セグメント間の違いを際立て、特徴を理解することが可能となります。

<img width="700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/7f19b12e-6be3-afd6-31a7-3589118ec55c.png">

### 母集団との比較
同じテクニックを用い、自社の顧客数全体（母集団）と、特定のセグメントを比較することも可能です。図17 は図16 と同じセグメントを母集団と比較しています。これによって、自社顧客全体を基準とした場合の特徴を理解することが可能となります。

<img width=700" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2768546/455f1a8c-91f5-45d9-cd34-ed82ae7dcbb3.png">

ただし、自社の母集団自体が偏っている可能性があることも認識すべきです。例えば自社の市場領域が日本国内であるとし、日本国人口の男女構成比が男性 : 女性 = 8 : 2 であるとしましょう。このとき、自社データベースの母集団における男女構成比が 6 : 4 であったとしたら、自社顧客には男性が多いと言い切れるでしょうか。絶対数で見た場合には確かにそうなのですが、人口という全体構造の中で相対的に見たら、女性が多いとも理解できます。自社の、データ取得範囲外である市場領域の基準値、そして自社母集団の基準値の両方で比較できれば、より正確なセグメント理解が可能となります。

もちろん男女構成比のように、統計資料等から拾うことができる変数ばかりではありません。そのため、優先順位としてまずは自社顧客を母集団として理解し、続いて可能であれば市場基準値とも比較します。


### セグメントの利用
このようにして得られ、そして特徴付けられたセグメントは、以下に示すようないくつかの用途で利用できます。そしてこれは自社の顧客全体、つまり母集団に対しても適用可能なアイデアです。

### １． 重要セグメントの時系列傾向を把握する：
特定セグメントが自社の収入および利益構造上重要であると理解できたとき、このセグメントの膨張と収縮が自社の収入、利益に大きな影響を与えることも容易に想像がつきます。したがって、時系列でこのセグメントに属するようになる新規顧客、このセグメント内で脱落／離反／解約する顧客の増減を継続的に監視する必要があります。また、当該顧客の支出額増減に関しても重要な監視対象です。このような管理を自社顧客において 8 - 9割を占める複数セグメントに対して実施していければ、それはすなわち自社の顧客数全体と、顧客から得られる収入、利益を管理できることとほぼ同義です。本稿の初回に、「新規顧客の獲得」、「顧客リテンション」、「優良顧客の育成」、「経費効率の向上」が顧客管理上の重要なテーマであると述べました。端的にはこれを指標値に落とし込み、セグメント別に指標値モニタリングすることを意味します。

### ２． さらなる分析の対象として利用する：
セグメントを分析の対象、つまり母集団として考え、そこに属する顧客群を特定の分析フォーマットに流し込むことによって、より深くそのセグメントを理解することが可能となり、そのセグメントに対して実施するべきキャンペーンのアイデアを導き出すことが可能となります。つまり、具体的な行動を規定するための分析にセグメントを利用することが可能です。顧客行動を「誰が？（顧客属性）」、「何を？（商品やサービス）」、「いつ？（タイミング）」、「どこで？（チャネル）」、「どの位？（定量指標）」の観点から分解し、キャンペーンを実施すべきポイント、決定すべき構成要素（誰に、何を、いつ、どこで案内すべきか？） を理解することが可能となります。


これについてはより詳細に解説する必要があるため、次回以降で、特定の分析フォーマットを利用した分析について解説していきます。


#### Teradata Vantageへのお問合せ
[Teradata Vantage へのお問合せ](https://www.teradata.jp/About-Us/Contact)
`gradlew bootBuildImage`で作成したSpringBootアプリコンテナでThymeleafテンプレートがmight not existになる

# TL;DR
application.ymlから`spring.thymeleaf.*`系のキャッシュ設定を削除することで解決。
```diff:application.yml
spring:
-   thymeleaf:
-     cache: false # アプリリロードなしで変更を反映
-     cache-period: 0
-     prefix: file:src/main/resources/templates/
```

# stacktrace
```
Error resolving template "list", template might not exist or might not be accessible by any of the configured Template Resolvers
```

# 状況
- 任意のページにアクセスするとThymeleafエラー。テンプレートファイルがないと言われる。
- ローカル環境ではエラーなし
- `gradlew bootBuildImage`で作成したdockerイメージをコンテナ起動した場合のみエラー発生

# 解決策
- cache周りが怪しかったので、application.ymlから以下を削除
```diff:application.yml
spring:
-   thymeleaf:
-     cache: false # アプリリロードなしで変更を反映
-     cache-period: 0
-     prefix: file:src/main/resources/templates/
```


参考： 

https://github.com/spring-projects/spring-boot/issues/2057
Power Apps で選択肢列の値を元に色を変更する方法

# はじめに

今回は、よく聞かれる、Power Apps で選択肢列の値を元に色を変更する方法について、以下のような働き方、出社予定を共有するアプリをベースに紹介します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/2f565a6c-9030-e4a6-dc52-68ec78ec7ab3.png)
※弊社内では、主に出社の予定を共有して同僚との対面でのコミュニケーションを促進させる目的で、
　実際にこのアプリを利用しています

# 働き方の設定について

Dataverse または、Dataverse for Teams で利用することを想定しているアプリのため、働き方については、以下のように選択肢列で定義しております。
※組織の働き方に応じて必要に応じて変更します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/467663c9-8a25-e1f2-73b8-263908382cad.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/e3e9ecb2-152f-290e-2ecc-4441b3b75f8c.png)

# 働き方に応じた色の変更について

それでは、働き方 (選択肢列) の値に応じて色を変更します。

アプリ内で、働き方 (選択肢列) の値に応じて色を変更しているコントロール (今回はラベルコントロールを利用しています) を選択します。
そして、コントロールの塗りつぶしを意味する `[Fill]`プロパティを選択します。
※新規にアプリを作る場合は、対象となるコントロールの`[Fill]`プロパティを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/67f62839-aa4d-484a-c1c6-4eca66a25841.png)

`[Fill]`プロパティの設定を以下のように設定します。

```
Switch(
    Text(ThisItem.cr841_plan),
    "出社",
    gblAccentColor,
    "WFH",
    gblMainColor,
    "外出",
    gblMainColor,
    "休暇",
    gblBaseColorGray,
    "午前休暇",
    gblBaseColorGray,
    "午後休暇",
    gblBaseColorGray,
    gblBaseColorLightGray
)
```

以下の部分が、働き方 (選択肢) の列を指しています。こちらは、作成するアプリの列名に応じて変更ください。

```
Text(ThisItem.cr841_plan)
```

:::note 
ギャラリー内でデータソース内の列名を指定する際は、**ThisItem.列名** といった表記になります。
:::

Switch 関数については以下の情報を参考にしていただければと思いますが、今回のように、式の結果が多岐に渡る場合によく利用します。
If 文も使えなくはないですが、例えば、今回のケースでは、働き方の種類は 6 種類ほどあるため、If で書こうとすると構文が冗長になり、また、混乱してしまうと思います。

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-if

色の設定について、今回は、アプリで色に統一感を持たせるために以下のように変数定義したものを使っています。

```
Set(
        gblMainColor,
        RGBA(
            75,
            203,
            146,
            1
        )
    )
```
もちろん、以下のいずれかの方法で定義いただいても問題ないです。

https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-colors

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/984acc4f-a3f3-a77d-fef5-bb510dc526ec.png)

最後に、必要に応じて、文字の色を`[Color]`プロパティも同様の書き方で変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/c062db3d-1921-5379-5a6e-47777a67ec67.png)

上記のような方法で、選択肢列の値に応じて色を変更し、アプリの見た目をリッチにすることができます。
C#でDataverseにテーブルを作成してみた

# はじめに
PowerAppsのモデル駆動の設定が面倒なのでC#からDataverseを操作してみたくなった。
今回はdataverseにテーブルを作成するC#のコードを動かしてみる。

# 前提
参照ライブラリやCreateCrmService関数の中身は以前の以下の記事を参考に

C#でDataverseに接続してテーブル一覧を表示してみた
https://qiita.com/akihiroe_/items/2db8e2634d7962ef0df7

# コード
CreateEntityRequestを作成して実行すれば良いだけのようだが、Web画面で作成する場合と同様にプライマリ列の指定が必要。

```C#
var organizationService = CreateCrmService(user, password, url);

var tableLogicalName = "test_table1";
var tableDisplayName = "テーブル１";
var primaryNameColumnLogicalName = "test_name";
var primaryNameColumnDisplayName = "名前列";

CreateEntityRequest createrequest = new CreateEntityRequest
{
    Entity = new EntityMetadata
    {
        SchemaName = tableLogicalName,
        DisplayName = new Label(tableDisplayName, 1041),
        DisplayCollectionName = new Label(tableDisplayName, 1041),
        OwnershipType = OwnershipTypes.UserOwned,
    },
    PrimaryAttribute = new StringAttributeMetadata
    {
        SchemaName = primaryNameColumnLogicalName,
        RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
        MaxLength = 100,
        DisplayName = new Label(primaryNameColumnDisplayName, 1041),
    }
};
var createResponse = organizationService.Execute(createrequest) as CreateEntityResponse;
Console.WriteLine(createResponse.Results["EntityId"]);
```
*Labelクラスの引数1041は日本語の言語コード
# おわりに
テーブルの作成もシンプルなコードでいけました。当初列名にnameを指定していると「The schema name name for type Attribute is invalid or missing....」とエラーになったので注意。これはWeb画面でも強制されるソリューションの接頭辞をつけて解決しました。
なお、列の追加も参考情報で紹介されている方法でできました。これでExcelで記載したテーブル定義書から自動的にDataverseのテーブルを作成することができそう。:smiley:

# 参照情報
https://learn.microsoft.com/ja-jp/power-apps/developer/data-platform/org-service/create-custom-entity
ChatGPTで作る - 京都の衛星画像を機械学習で解析するプログラム

以前、京都の衛星画像を機械学習で解析する記事を書きました。

https://qiita.com/dg4101/items/2968864714fe72b0d7bf

今回は同じことをChatGPTに頼んでコードを書いてもらいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799224/d52271e2-36de-e0d2-f9d7-5598a9ab3e48.png)
先ずはこのようにChatGPTに入力します。
するとあっという間に以下のような返答が

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799224/7afda0fa-5e2a-2a07-ad98-4733e29036c0.png)
日本語でコメント付きです。

解析した画像の保存は次の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799224/3c97b2de-001a-ca03-ade7-9cd59e3f5e9e.png)

さらにどのようなことをするか簡単な解説まであります。

しかし、このコードはバグがありました。エラーを何もコメントも付けずにそのままコピーしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799224/ccbaab66-43a1-1c2e-a603-f65d67d38d01.png)

これで変更されたのが以下の点です。

データ切り出し部分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799224/5fd0f5f8-908d-8857-d0cb-655635ce5f35.png)
画像保存部分
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799224/d7b4a75a-9b69-bf7c-b110-215e86cdf76e.png)


これでできたコードが以下の通りです。切り取り個所など若干の修正は入れてますが、ほとんどChatGPTで書かれたコードです。
```python
import rasterio
import numpy as np
import glob
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

# dataフォルダーにあるGeoTIFF画像を全て読み込む
files = glob.glob("data/*.tiff")
images = []
for file in files:
    with rasterio.open(file) as src:
        images.append(src.read(1))

# x,y地点から高さh、幅wで指定してデータを切り出し
x=5570
y=2083
h=900
w=500

cut_images = []
for image in images:
    cut_images.append(image[y:y+h, x:x+w])

# クラスタリングを行う
data = np.concatenate(cut_images)
kmeans = KMeans(n_clusters=10, random_state=0)
kmeans.fit(data.reshape(-1, 1))

# 結果を高さh、幅wの画像で保存する。
labels = kmeans.labels_.reshape(h, w)
plt.imshow(labels, cmap="turbo")
plt.colorbar(ticks=np.arange(10))
plt.savefig("images/clustered_image.png")

```
どのようにクラスタリングを行うか指定していませんが、ChatGPTはk-meansを選択したようです。

完成した画像はこの通り。色使いなど修正の余地はありますが。京都盆地の画像がしっかりと表示されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/799224/248bb2ba-453e-47df-b592-e282e1096dd1.png)

鴨川デルタ、京都御所、桂川などはっきりと見えて取れますし巨椋近辺の土地利用の違いも出ています。

k-meansは深層学習などではありませんが機械学習の一部で、そのプログラムをAIを使って作れました。

* * *

>ランドサットデータについて (https://landbrowser.airc.aist.go.jp/landbrowser/index.html)
> “ The source data were downloaded from AIST’s LandBrowser,　(https://landbrowser.airc.aist.go.jp/landbrowser/). Landsat 7/8 data courtesy of the U.S. Geological Survey.”
ChatGPTについて

# はじめに
去年の終わりぐらいから[ChatGPT](https://chat.openai.com/chat)なるものが流行っているけど、何者なのか全く分からない...。
どうやら便利なものらしいので、駆け出しエンジニアとして触れてみようと思う！
ということで、ついでに「まだChatGPTのこと知らないよ〜(いるか分からないけど笑)」という人のために、ちょっとした記事にしてみました！

# ChatGPTとは
OpenAIが2022年11月に公開したチャットボット。
OpenAIのGPT-3.5ファミリーの言語モデルを基に構築されていて、自然な文章での対話が可能。

# 使ってみた
一応エンジニアなので、それっぽい内容で使ってみました！

#### ①調べ物
まず「5桁の数字をJavaの正規表現で表してください。」と頼んでみました！
![スクリーンショット 2023-01-28 17.22.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2871906/1307808a-2131-8f6a-4118-b4f6219bb9d2.png)
正しく答えてくれました！

では「Javaでint型をString型に変換するコードを教えてください。」だとどうでしょうか？
![スクリーンショット 2023-01-29 23.34.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2871906/6b38e5dc-7e38-31ca-7042-bf2b2219c7e3.png)
「python」と書いてあるのが気になりますが、一応Javaでも正しく動作するコードを答えてくれました！
まだ細かい部分の精度は微妙なのかもしれません...。

### ②コード生成
エンジニアなら1回は記述するであろう、「FizzBuzzテスト」を書いてくれるか頼んでみました！
![スクリーンショット 2023-01-28 18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2871906/108b59df-edc4-663c-0a04-6c6c4b84b5b2.jpeg)
5秒で書いてくれました笑
しかも説明付きです！
学びたての頃はこのコードを書くのにも悩まされていたのに...。
なんだか自分に不甲斐なさを感じてしまいますね笑

### ③エラー潰し
「Javaで記述された次のコードの間違いを教えてください。」と頼んでみました！
``` 
public class Test {
    public static void main(String[] args) {
        int num = "abc";
        System.out.println(num);
    }
}
``` 
コードは上記のように書きました！
![スクリーンショット 2023-01-30 0.07.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2871906/95001fff-2640-9741-6752-392a8607267e.png)
正しく間違いを指摘してくれました！

次のコードならどうでしょうか？
``` 
public class Test {
    public static void main(String[] args) {
        int [] num = {0, 1, 2, 3};
　　　　　　　　　　　　　　　　System.out.print(num[4]);
    }
}
``` 
1つ目と同様に、「Javaで記述された次のコードの間違いを教えてください。」と頼んでみました！
![スクリーンショット 2023-01-30 0.18.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2871906/0f4cb52c-af8c-7c0b-7573-692380b490ba.png)
凄いですね！
簡単なエラー潰しなら出来るということが分かりました！

# まとめ
だいぶ遅れましたが、ChatGPTの優秀さを知ることができました！
簡単な調べ物だけでなく、コード生成やエラー潰しもしてくれるので、「学習効率が上がりそうだな」と感じました！
ただ精度に微妙な部分もあるので、使う場面は限られそうです...。
今後精度が上がり、使える幅が広がってくることに期待します！
Python: クローラーってどうつくるの？種類と作り方の概要について

# はじめに
備忘録です
# そもそもクローラーとは
+ WEB上の情報を取得するプログラムの事
+ クローリングとはウェブページをたどって次々とデータをダウンロードすること
+ **ウェブサイトの特徴に合わせたクローラーを作成する必要がある**
# クローラーの種類は3種類
+ 状態を持つクローラー
+ JavaScriptを解析するクローラー
+ 不特定多数を対象とするクローラー
## 状態を持つクローラーの作り方
状態を持つクローラーとは、cookieとかをつかうサイトに必要！
作り方
+ RequestsのSessionオブジェクトを使用する
    + サーバーからもらったcookieを保存して、次回以降のリクエストを出す時に一緒に送信してくれる。
+ または、、Referer
    + ひとつ前に見ていたサイトのURLをサーバーに送るHTTPヘッダー
        + これをもとに処理を決定するウェブサイトがあるらしい
## JavaScriptを解釈するクローラーの作り方
JavaScriptで作られているウェブサイトをクローリング＆スクレイピングするときに必要
+ 直接、ウェブブラウザを操作する
+ 使用ツール
+ Selenium
+ Puppeteer
+ chromeやfireboxのヘッドレスモード
    + 普通とは違うモードで操作できるみたいだ
    + CUIで動かす
## 不特定多数のウェブサイトを解析するクローラーの作り方
分からん
めっちゃ難しいっぽい

# 参考文献
加藤耕太さん「Python　クローリング＆スクレイピング」
本当に回線速度について理解してますか？

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
今回は回線速度について更に詳しく調べてみましょう！

![インスタスライド_202301092.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/052b8ec8-ac3a-c7d9-92d4-d965ab245f68.gif)


# 回線速度について
回線速度についてご存知ですか？
固定回線であれば、１Gとかあります。
スマホの5Gだと、10Gと言われてます。
Gがイッパイで意味不明ですね。
実際は、速度は全然違います。

# 回線速度を図ってみる
https://fast.com/ja/
等の回線速度を図るサイトがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/148b555a-e3d8-b080-c29f-5c04763b17ea.png)

ウチのマンションのネット回線速度です

# 回線速度を図ってみる
スマホの5G(Y mobileです）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/5d3e7d15-2453-e2e9-db09-e7a243f4b4e1.png)

# 何故遅いのか？
公表速度と全然違いますね。

何故かと言うと**転送効率**というのがあります。

他の人が大量のデータを送ったり、回線の状況が変化するために実効値が落ちてしまう訳です。

# 計算式にすると
理論転送速度 x 伝送効率= 実効転送速度

なので、ウチのマンションの場合は、

1Gbps x 伝送効率=200Mbps
なので伝送効率は0.8という事になります。

# bpsとは
bpsは、bit per secondの略で
１秒辺りのバイト転送速度です。

1Gbpsであれば、
１秒間に1Gビット転送できます。

1G/8=1024*1024*1024/8=128MBps
1秒間に128Mバイト転送できます。
1Byte=8bit

# まとめ
ー　 回線速度は、理想値と実測値がある

ー　理論転送速度 x 伝送効率= 実効転送速度

ー　bpsは、bit per second

ー　１秒間のビット転送速度

ー　Bpsは、byte per seconde

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
Python・スクレイピング：再実行を意識したクローラーってどう作るの？概要について

# はじめに
備忘録です
# 本文
+ 再実行を意識したクローラーの作成
    + 一意のKeyを持たせること
    + クローラーを実行したら更新する
    + 新しいデータは追加する
    + パーマリンクがカギになる
+ パーマリンク
    + URLが変わらない。
    + WEBサイトごとに仕様が違うので、どういう風になっているのか観察しよう！
+ 作り方
    + 一覧ページからパーマリンクを抜き出す
    + 詳細ページをスクレイピングする
    + RequestsのSessionオブジェクトは便利
    + データを保存する
+ 途中途中でするといいこと
    + developerツールを使って、どんな風にWEBサイトが作られているか観察する
        + これが、どうやって情報を抜き出したらいいかという問いの答えにつながる

# memo
# 参考文献
加藤耕太さん「Python　クローリング＆スクレイピング」
#######
RDBのリレーションとはなにか? あるいはリレーショナルモデルへの誘い

# はじめに
RDB(リレーショナル・データ・ベース）のRは英語のrelation(関係)から来ています。
「このrelationはテーブル同士の関連（外部制約)ではなく、集合のことである」という雑学(?)があります。
RDBで大事なのはテーブルを集合として考えることである、という警句でもあります。

英語のrelationに集合的な意味はないのに、なんで集合なんでしょう？
本記事ではrelationとは一体どういった意味なのかをリレーショナルモデルから説明します。

# Relationの定義

relation(関係)の数学的な定義をみてみます。

**定義(直積集合)**
```math
A,Bを集合として、 A\times B = \{(a,b)|a \in A, b\in B\}を集合AとBの直積集合という。
```

**定義(関係)**
```math
A,Bを集合として、AとBの直積集合(A\times B)の任意の部分集合RをAからBへの関係という。
```
噛み砕くと、集合A,Bのすべての要素を組み合せた直積集合{(a,b)}に含まれる任意の**集合**のことをrelation(関係)といいます。


関係の定義だけでは、イメージがわかないので具体的をみてみます。

# リレーションの具体例
具体的な２つの集合を考えます。Aを名前の集合、Bを整数の集合とします。
ことき直積集合 $A\times B$は {(田中,1),(山田, 5), ...}のように名前と整数を組み合せた集合となります。
関係Rは直積集合の任意の部分集合なので、(名前, 整数)の組み合せから好きなものを集めてみます。

```
R = { (川端康成, 1968),(大江健三郎, 1994) }
```
私が好きに選んだ組み合せですが、なんだか恣意的な人名が選ばれています。
川端康成は1968年、大江健三郎は1994年にノーベル文学賞を受賞した小説家です。
私が定義した**名前から整数への関係R**は、「(日本人の)ノーベル文学賞受賞者の名前と受賞年」の**関係**です。
つまり、relation(関係）というのは、２つの集合からある**関係**をみたす要素を集めた集合と考えることができます。

# RDBとの関係
ここで、関係Rを少し拡張してみます。
あらたな集合Cを任意の文字列の集合としましょう。RとCの直積集合 $R \times C$ を考えます。
すると新しく関係R'が定義できて

```
R' = { 
(川端康成, 1968, 『伊豆の踊子』『雪国』など、日本人の心情の本質を描いた),
(大江健三郎, 1994, 『個人的な体験』『万延元年のフットボール』など、現実と虚構が一体となった世界を創作した)
 }
```
と定義することができます。任意の文字列から選んできたのは受賞理由です。（本当はもっと長いけど見にくいので短くしました）

この関係を表にしてみます。

| 受賞者名 | 受賞年 | 理由 |
|:-:|:-:|:-:|
| 川端康成  | 1968  |  『伊豆の踊子』『雪国』など、日本人の心情の本質を描いた  |
| 大江健三郎  | 1994  | 『個人的な体験』『万延元年のフットボール』など、現実と虚構が一体となった世界を創作した  |

(受賞者名, 受賞年, 理由）というタイトルは私が付けましたが、これを**属性名**といいます。
そして、この関係はノーベル文学賞という関係性において私がA, B, Cの集合から抜き出したものです。よってこの関係R'に**ノーベル文学賞**という名前を付けてみます。これをリレーション名といいます。
RDBの言葉で表現すると、relation(関係)は**ノーベル文学賞テーブル**、属性は**カラム名**(受賞者名, 受賞年, 理由）に対応することになります。

# 本当の雑学
RDBの元となったリレーショナルデータモデルの創始者コッドさんは、なぜrelationalなのかについて、当時緊張関係にあった米中関係のrelationからとったという本当なのか冗談なのかわからない話が、『リレーショナルデータベース入門』(サイエンス社)に書いてありました。

リレーショナルデータモデルとRDBの関係性をもっと知りたい方はぜひ読んでみてください。

# 参考
- 『リレーショナルデータベース入門』(サイエンス社)
- [日本人のノーベル賞受賞者](https://ja.wikipedia.org/wiki/%E6%97%A5%E6%9C%AC%E4%BA%BA%E3%81%AE%E3%83%8E%E3%83%BC%E3%83%99%E3%83%AB%E8%B3%9E%E5%8F%97%E8%B3%9E%E8%80%85)