OmniAICreator/Qiita-1.07M huggingface dataset:
k3dを使う

# 前提

kubectl, Dockerが利用可能

# install

https://github.com/rancher/k3d


```zsh
$ curl -s https://raw.githubusercontent.com/rancher/k3d/main/install.sh | bash
```

`k3d --help`コマンドでk3dコマンドが有効化されていることを確認します。

# cluster create `otameshi`

`k3d cluster create CLUSTER_NAME`でクラスターを作成できるので試しに作ってみる。

```
% k3d cluster create otameshi
INFO[0000] Prep: Network                                
INFO[0000] Created network 'k3d-otameshi'               
INFO[0000] Created volume 'k3d-otameshi-images'         
INFO[0000] Starting new tools node...                   
INFO[0001] Creating node 'k3d-otameshi-server-0'        
INFO[0003] Pulling image 'docker.io/rancher/k3d-tools:5.1.0' 
INFO[0004] Pulling image 'docker.io/rancher/k3s:v1.21.5-k3s2' 
INFO[0007] Starting Node 'k3d-otameshi-tools'           
INFO[0012] Creating LoadBalancer 'k3d-otameshi-serverlb' 
INFO[0016] Pulling image 'docker.io/rancher/k3d-proxy:5.1.0' 
INFO[0020] Using the k3d-tools node to gather environment information 
WARN[0020] failed to resolve 'host.docker.internal' from inside the k3d-tools node: Failed to read address for 'host.docker.internal' from command output 
INFO[0020] HostIP: using network gateway...             
INFO[0020] Starting cluster 'otameshi'                  
INFO[0020] Starting servers...                          
INFO[0020] Starting Node 'k3d-otameshi-server-0'        
INFO[0027] Starting agents...                           
INFO[0027] Starting helpers...                          
INFO[0027] Starting Node 'k3d-otameshi-serverlb'        
INFO[0033] Injecting '172.21.0.1 host.k3d.internal' into /etc/hosts of all nodes... 
INFO[0033] Injecting records for host.k3d.internal and for 2 network members into CoreDNS configmap... 
INFO[0035] Cluster 'otameshi' created successfully!     
INFO[0035] You can now use it like this:                
kubectl cluster-info
```

# update kubeconfig

`k3d kubeconfig merge CLUSTER_NAME --kubeconfig-switch-context`

このコマンドでデフォルトのkubeconfigをアップデートします。

```
% k3d kubeconfig merge otameshi --kubeconfig-switch-context
/Users/akito/.k3d/kubeconfig-otameshi.yaml
```

# 試しに、podを見てみると動いています。

```zsh
% kubectl get pods --all-namespaces
NAMESPACE     NAME                                      READY   STATUS      RESTARTS   AGE
kube-system   metrics-server-86cbb8457f-4gx64           1/1     Running     0          4m31s
kube-system   local-path-provisioner-5ff76fc89d-mstx4   1/1     Running     0          4m31s
kube-system   coredns-7448499f4d-qprmk                  1/1     Running     0          4m31s
kube-system   helm-install-traefik-crd-8ff4m            0/1     Completed   0          4m31s
kube-system   helm-install-traefik-qtxq5                0/1     Completed   1          4m31s
kube-system   svclb-traefik-gwm8x                       2/2     Running     0          3m54s
kube-system   traefik-97b44b794-knl7b                   1/1     Running     0          3m54s
```
.distance(to: Int)について（Int型）　　

# 今回の内容

* 今日、初めて`.distance(to: Int)`を知ったので、記録しておく為に書いてます。

#コードと簡単解説

* 対象のInt型の値に対して、`.distance(to: Int)`の`(to: Int)`との差を取得してきます。
* print結果に`-7`と表示された事を考えると、`.distance(to:  Int) - 対象のInt型`のようになってる様です。

```Swift:
     let testInt = 10
        
     print(testInt.distance(to: 3))
     print(testInt.distance(to: 100))
```

```:print結果
     -7
     90
```

# 終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
AOJトライに関する知識知見の記録共有 ：Volume0-0008

# 概要
Sum of 4 Integers

https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=0008
 
# コード
TIPS：オペランド定義域を可変化

```
import itertools

def calc_num_opr(sm, inf=0, sup=10):
    c = range(inf, sup)
    return [[a,b,c,d] for a, b, c, d in itertools.product(c, c, c, c) if sum([a,b,c,d]) == sm]

def core(arg):
    num_opr = calc_num_opr(int(arg))
    return len(num_opr), num_opr

def app(*args):
    return [[arg, core(arg)] for arg in args]

from pprint import pprint
try:
    pprint(app(
        # base
        35,
        1,
        # additional
        51,
        # exception
        #"str"
    ))
except Exception as e:
    print(e)
```

# 実行結果
デバッグログ出力部含む

```
[[35, (4, [[8, 9, 9, 9], [9, 8, 9, 9], [9, 9, 8, 9], [9, 9, 9, 8]])],
 [1, (4, [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]])],
 [51, (0, [])]]
```

# 補足
残課題：探索途中での枝刈り高速化
DockerでMosquittoを起動

# はじめに

MQTTブローカーのmosquittoをDockerで起動しようとしたらちょっとだけ躓いたのでメモ。

# 躓いたやり方

デフォルトで起動したMQTTブローカーが欲しかっただけなので[ここ](https://hub.docker.com/_/eclipse-mosquitto)を参考に、

```bash
$ docker run -it -d -p 1883:1883 -p 9001:9001 eclipse-mosquitto
```

でmosquittoを起動し、paho-mqttを使って書いた以下のようなpublisher, subscriberを起動しましたがうまくつながりませんでした。

```python:publisher.py
from paho.mqtt import client as mqtt_client
import time


CLIENT_ID = 'publisher'
BROKER = 'localhost'
PORT = 1883
TOPIC = 'pyjackal/mqtt'


def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("Connected to MQTT Broker!")
    else:
        print("Failed to connect, return code %d\n", rc)


def run():
    client = mqtt_client.Client(CLIENT_ID)
    client.on_connect = on_connect
    client.connect(BROKER, PORT)
    client.loop_start()
    count = 0
    while True:
        time.sleep(1)
        msg = f"message{count}"
        result = client.publish(TOPIC, msg)
        status = result[0]
        if status == 0:
            print(f"Send `{msg}`")
        else:
            print(f"Failed to send message to {TOPIC}")
        count += 1


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

```python:subscriber.py
from paho.mqtt import client as mqtt_client


CLIENT_ID = 'subscriber'
BROKER = 'localhost'
PORT = 1883
TOPIC = 'pyjackal/mqtt'


def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("Connected to MQTT Broker!")
    else:
        print("Failed to connect, return code %d\n", rc)


def on_message(client, userdata, msg):
    print(f"Received `{msg.payload.decode()}` from `{msg.topic}` topic")


def run():
    client = mqtt_client.Client(CLIENT_ID)
    client.on_connect = on_connect
    client.connect(BROKER, PORT)
    client.subscribe(TOPIC)
    client.on_message = on_message
    client.loop_forever()


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

docker logsでlogを見ると、以下のようなログが出ていました

```bash
$ docker logs quizzical_wu
1636985393: mosquitto version 2.0.13 starting
1636985393: Config loaded from /mosquitto/config/mosquitto.conf.
1636985393: Starting in local only mode. Connections will only be possible from clients running on this machine.
1636985393: Create a configuration file which defines a listener to allow remote access.
1636985393: For more details see https://mosquitto.org/documentation/authentication-methods/
1636985393: Opening ipv4 listen socket on port 1883.
1636985393: Opening ipv6 listen socket on port 1883.
1636985393: Error: Address not available
1636985393: mosquitto version 2.0.13 running
$
```

# うまくいったやり方

ログや[こちら](https://mosquitto.org/documentation/migrating-to-2-0/)に記載されている通り、mosquitto2.0からデフォルトだとlocalhost以外からのアクセスを禁止していたからでした。
以下のような設定ファイルを用意し、設定ファイルを指定してコンテナを起動するとうまくいきました。

```conf:mosquitto.conf
listener 1883  # 0.0.0.0:1883でlisten
allow_anonymous true  # 認証なしでの接続を許可
```

```bash
docker run -it -d -p 1883:1883 -p 9001:9001 -v $PWD/mosquitto.conf:/mosquitto/config/mosquitto.conf eclipse-mosquitto
```
ExcelでPairwise組み合わせパターンを作成

# はじめに
PictMasterを使ってやりたかったのですが、諸事情で使えないため、ExcelでVBAを使って組み合わせパターンを作成することに...

# ベースマクロ＆使い方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88262/92f935ef-2960-e2c5-a221-b41ca6fd73d1.png)

```vb:pairwise.vb
Sub PairWise()
    '変数宣言
    Dim inputSheetName As String
    Dim outputSheetName As String
    '作成したい組み合わせパターン分追加
    Dim inputCounter01 As Long
    Dim inputCounter02 As Long
    Dim inputCounter03 As Long
    '
    Dim outputLine As Long

    '初期設定
    inputSheetName = "conf"
    outputSheetName = "data"


    '作成したい組み合わせパターン分追加(初期値：開始行(ヘッダ無視なら2を指定))
    For inputCounter01 = 1 To Worksheets(inputSheetName).Cells(Rows.Count, 1).End(xlUp).Row
    For inputCounter02 = 1 To Worksheets(inputSheetName).Cells(Rows.Count, 2).End(xlUp).Row
    For inputCounter03 = 1 To Worksheets(inputSheetName).Cells(Rows.Count, 3).End(xlUp).Row
    
    'ここに条件を記載すると設定されないようにできる
    If (Worksheets(inputSheetName).Cells(inputCounter01, 1) = "b") And (Worksheets(inputSheetName).Cells(inputCounter02, 2) = "1") Then
        '条件スキップ1
    ElseIf (Worksheets(inputSheetName).Cells(inputCounter01, 1) = "a") And (Worksheets(inputSheetName).Cells(inputCounter02, 2) = "3") Then
        '条件スキップ2
    Else
        Worksheets(outputSheetName).Cells(outputLine + 1, 7) = Worksheets(inputSheetName).Cells(inputCounter01, 1)
        Worksheets(outputSheetName).Cells(outputLine + 1, 8) = Worksheets(inputSheetName).Cells(inputCounter02, 2)
        Worksheets(outputSheetName).Cells(outputLine + 1, 9) = Worksheets(inputSheetName).Cells(inputCounter03, 3)
        outputLine = outputLine + 1
    End If

    '作成したい組み合わせパターン分追加
    Next inputCounter03
    Next inputCounter02
    Next inputCounter01
End Sub

```

- マクロの貼り付け方
　上記のコードをコピーして、エクセルのワークシート上で「Alt」+「F11」でVBE画面を出す
　「メニュー」→「挿入」→「標準モジュール」をクリックして、コードを貼り付け

- マクロの実行
「Alt」+「F8」を押すと、マクロのダイアログが出るので、
「PairWise」が選択された状態で「実行」を押下

# 参考サイト
◆Excelを使って全ての組み合わせを表示させたいです。 - マトリッ... - Yahoo!知恵袋
　https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1496151024
◆EXCEL上で動作するPairwise組み合わせテスト設計支援ツールPICT-PAPP公開
　https://qiita.com/sho1884/items/a46bb9bb5aca490f90f5
シンプルな CSV ファイル読み込み Javaサンプル (Apache commons-csv を利用)

ちょっと CSV ファイルを読み込む Java プログラミングを実装したい場合に役立ちそうなサンプルをメモしておきます。
CSVファイル読み書きには [RFC 4180](https://datatracker.ietf.org/doc/html/rfc4180) を実装する必要がありますが、一般的にはライブラリ利用により実現します。
この例では Apache commons-csv を利用した CSVファイル読み込みサンプル記述を残しておきます。

# Maven (pom.xml)

まず最初に、CSV ファイル読み込みを実現するためのライブラリである `Apache` `commons-csv` をビルドに組み込みます。 `pom.xml` ファイルの `<dependencies>` に以下の `Maven Repository` 記述を追加します。 (ビルドでの自動ダウンロードの実現のためには、インターネットに接続されている必要があります)

```xml
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.9.0</version>
</dependency>
```

なお、[Maven Repos 上の commons-csv はこちら](https://mvnrepository.com/artifact/org.apache.commons/commons-csv)を参照してください。

# Java コード

`commons-csv` が利用可能になったので、早速これを Java で利用して CSVファイル読み込みを実行するコードを記述しましょう。

このサンプルコードでは、以下のCSVファイルをサンプルとして読み込む前提となっています。

* 郵便局: 読み仮名データの促音・拗音を小書きで表記しないもの(zip形式)
    * https://www.post.japanpost.jp/zipcode/dl/oogaki-zip.html
    * 全国一括


```Java
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

public class App {
    public static void main(String[] args) throws IOException {
        try (CSVParser parser = CSVFormat.DEFAULT.parse( //
                new BufferedReader(new InputStreamReader(new FileInputStream( //
                        "./src/KEN_ALL.CSV"), "Windows-31J")))) {
            for (CSVRecord record : parser) {
                System.err.println(record.get(2) //
                        + ": " + record.get(6) + " " + record.get(7) + " " + record.get(8));
            }
        }
    }
}
```

## 簡易な解説

* `CSVFormat` から `CSVParser` インスタンスを作成します。
* CSVファイルの 1行ごとを `CSVRecord` インスタンスとして取得します。
* 1行の各列を get メソッドで取得します。

# 文書情報

* 初出: 2021-11-15

## 関連情報

* [シンプルな JSON 読み込み Java サンプル (jackson-databind 利用)](https://qiita.com/igapyon/items/14c6ff9430c5d8727e91)
* [シンプルな JSON 書き出し Java サンプル (jackson-databind 利用)](https://qiita.com/igapyon/items/384b88d364e0d241f91b)
* [シンプルな HTTP クライアント Javaサンプル (Apache HttpComponents 4.5系を利用)](https://qiita.com/igapyon/items/b0f9918db992c308949b)
* [シンプルな CSV ファイル書き出し Javaサンプル (Apache commons-csv を利用)](https://qiita.com/igapyon/items/7972e5dd899ec9ced776)
* [シンプルな CSV ファイル読み込み Javaサンプル (Apache commons-csv を利用)](https://qiita.com/igapyon/items/e28788c3edc720922393)
DockerのMySQLコンテナにSequelProで接続する方法

## はじめに
DockerのMYSQLコンテナにSequelProを接続しようとしたところ、アクセスを拒否されてしまったので、正しい接続方法について調べました。

この記事では、その成功した方法について記します。

## ステップ① まずdocker-compose.ymlを確認
docker-compose.ymlの中身を確認して、現在のDB(MySQL)コンテナの設定がどうなっている確認する。

```terminal
version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: *******
volumes:
  db-volume:
```

某UdemuyのRailsの教材通りにdocker-compose.ymlを記述したのでこんな感じ。

はじめてのDockerを使った開発だったので、SequelProにいつも通り接続してみるとデータベース一覧にあると思っていたデータベース名が無いことに気づく。

**「あ、あれ〜？汗」**

### ステップ② 検索してみると、「port」と「port番号」の記述が必要だとわかる
どうしたらDockerのMySQLコンテナにSequelProで接続できるのか検索してみたところ、docker-compose.ymlファイルのDB(MySQL)コンテナ下に「port」と「port番号」の記述が必要だとわかる。

**【修正前】**

```terminal
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: *******
```

**【修正後】**

```terminal
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    ports:
      - '4306:3306'
    environment:
      MYSQL_ROOT_PASSWORD: *******
      MYSQL_USER: root
      MYSQL_DATABASE: root
      MYSQL_PASSWORD: *******
```

新しくportsとports番号を追加。(enviromentにも何行か追加)

このport番号の「4306:3306」だが、「3306:3306」でも良いらしいが、localhostですでにmysqlを利用している場合は4306にしなくちゃいけないとのこと。

docker-compose.ymlを編集したら「docker-compose up -d」でコンテナを起動。

### ステップ③ SequelProに接続してみる

![スクリーンショット 2021-11-15 22.57.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366336/ab0d8914-3ada-e6f7-6c30-3ece80255d4a.png)

SequelProを開いて、画像赤枠の「標準」をクリック。

![スクリーンショット 2021-11-15 22.58.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366336/f35fcaf8-33df-3367-4699-6c745a0c1ae2.png)

docker-compose.ymlに記述した通り、ポートは4306にする。ホストは「127.0.0.1」になっているが、ここら辺については以下の記事が参考になった。

参考記事：「[127.0.0.1とlocalhostと0.0.0.0の違い](https://qiita.com/1ain2/items/194a9372798eaef6c5ab)」
参考記事：「[localhost と 127.0.0.1 の違い](http://tooljp.com/windows/chigai/html/TCPIP/localhost-127.0.0.1-chigai.html)」

![スクリーンショット 2021-11-15 22.58.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366336/9121a1c6-a730-5593-adfd-56bff3a2bd6f.png)

データベース一覧を見たところ、しっかりSequelProで見れるようになってた！感動。
[Python] 相関係数を計算したい


# はじめに

Pythonを使ってデータの相関係数を計算する方法を何通りか示します。

## 使用データ

方法を示すだけなので適当なデータ

```text:data.csv
sqrt2,pi
1,3
4,1
1,4
4,1
2,5
1,9
3,2
5,6
6,5

```
を使用します。

# 計算方法例

## Pandas

一番簡単なやりかたですね

```python
import pandas as pd
df = pd.read_csv('./data.csv')
print(df.corr())
```
 ↓

```
          sqrt2        pi
sqrt2  1.000000 -0.205738
pi    -0.205738  1.000000
```

## NumPy

```python
import numpy as np
import pandas as pd

df = pd.read_csv('./data.csv')
col1 = df['sqrt2'].tolist()
col2 = df['pi'].tolist()

print(np.corrcoef(col1, col2))
```
 ↓

```
[[ 1.        -0.2057378]
 [-0.2057378  1.       ]]
```

## NumPyその2

データの読み込みにpandasを使っているのでわざわざNumPyにする必要がない…という方のために

```python
import csv
import numpy as np

with open('./data.csv') as f:
	reader = csv.DictReader(f)
	col1, col2 = [], []
	for row in reader:
		col1.append(float(row['sqrt2']))
		col2.append(float(row['pi']))

print(np.corrcoef(col1, col2))

```
 ↓

```
[[ 1.        -0.2057378]
 [-0.2057378  1.       ]]
```

(Pandasでいいじゃん…)

## 自前で頑張る

ライブラリなんて使いたくない人向けです
(だったら正直Pythonである必要がないと思いますが)

```python
with open('./data.csv') as f:
	lines = f.readlines()[1:]

col1, col2 = [], []
for line in lines:
	data = list(map(float, line.split(',')))
	col1.append(data[0])
	col2.append(data[1])

def avg(l):
	return sum(l) /len(l)

def s(l1, l2):
	avg1, avg2 = avg(l1), avg(l2)
	return sum((v1-avg1)*(v2-avg2) for v1, v2 in zip(l1, l2))

r = s(col1, col2) / (s(col1, col1) * s(col2, col2)) ** .5
print(r)

```
 ↓

```
-0.20573779994945587
```

# さいごに

下に行くほどPythonである必要性を失っている気がしますが自分が何をしているのかが見えやすいという意味では勉強になるのではないでしょうか
Macでの便利な技 

Macはトラックパッドを使うことが多い。
Windowsユーザーとしては右クリックが使いたいところ...

そこでトラックパッドを二本指で同時に押すと...![スクリーンショット 2021-11-15 23.04.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/aa18591d-7580-c04c-db64-ffd4c714847a.png)

Windowsのような右クリックメニューが出ました！！

またスクリーンショット（画面撮影）はshift+command+3。スニッピングツールはshift+command+４で行うことができます！！
Atcoder ABC214-C Distribution 解

##問題
https://atcoder.jp/contests/abc214/tasks/abc214_c

##考察
次のように時刻ではなく重さに直して考えた:
人 $i$ は重さ $T_i$ の荷物を持っている。各 $i$ は渡された荷物にさらに重さ $S_i$ の荷物を追加して隣人 $i+1$ に渡す。各人が受け取る$n$個の荷物の最小値を各 $i$ ごとに求めよ。

こう読み替えると初期時点で全員荷物を持っているところからスタートできる（つまり、高橋君の存在を捨象できる）ので、隣人に荷物を渡すことだけを考えればいい。
目的の最小値を得るには、全ての荷物が一周する必要があるので $2n$ 回のループが必要。$n$ 回だけだと一周するのは先頭の人の荷物だけなので。

##実装
実装自体は公式解説のものと同じ。
人 $i$ の初期時点での荷物の重さ`t[i]`を、手渡された荷重`t[i] + s[i]`で更新していく。実装では円環処理のため、vector `t`,`s`などの引数を`i`ではなくて`i%n`としている。

```cpp
#define rp(i, n) for (int i = 0; i < n; ++i)
template <class S, class T>
inline bool chmin(S &a, const T &b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

int main() {
    // read input
    auto n = in<ll>();
    auto s = vin<ll>(n);
    auto t = vin<ll>(n);
    // pass luggage
    rp(i, 2 * n) chmin(t[(i + 1) % n], t[i % n] + s[i % n]);

    // show
    for (auto ti : t) print(ti);
}

```
vscodeでテキストの表示の折り返しをvscodeのページ幅に合わせるショートカットキー

![スクリーンショット 2021-11-15 22.52.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/1baf2960-dd41-0f33-1764-9d18f40b1676.png)

vscodeでテキスト文字が横長になり、スクロールしないと見れない時の対処法

option＋Zを押すと...
![スクリーンショット 2021-11-15 22.56.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2284920/167831d0-0576-5ae8-414e-d1df6d39c27a.png)

ページの幅に収まりました！！

追記
Macではかな入力ではΩが入力されるだけなので、英数入力にしてoption＋Z押すとページ幅に収めてくれる。
ADFS からアプリケーション認証移行を設計する前に知っておきたい事

# はじめに
本記事では、ADFS に接続されている既存アプリケーションの認証の連携先を Azure AD へ変更する際に知っておきたいことをお伝えします。
移行設計のポイントは、大きく 2 点あります。

* ADFS で実装されているアクセス制御についての確認
* アプリケーションの数に応じた無理のない移行期間の見積もり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/deb3efd3-d495-a6bd-d862-b45b85364358.png)

# アプリケーションに対してどのようなアクセス制御が実装されているかを知ることが第一歩
移行設計を円滑に進めるための **1 つ目のポイント**として、既存のアプリケーションのアクセス制御を技術的に把握しておくことが挙げられます。
事前に活用できていると便利な 2 つのレポート機能を紹介します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/fd65edcc-05da-8894-fe7b-33bc44a3b91f.png)


* [ADFS アプリケーションアクティビティ レポート](https://docs.microsoft.com/ja-jp/azure/active-directory/manage-apps/migrate-adfs-application-activity)
Azure AD Premium Plan1 以上のライセンスをお持ちの方は、Azure AD の機能である ADFS アプリケーションアクティビティ レポートを活用できます。Azure のポータルへアクセスするだけで、自動で集計されたアプリごとのアクセス制御の実装状況が確認できます。
ただし要件として、Azure AD Connect Health という機能の有効化と ADFS および WAP サーバーへのエージェント導入が必要です。また、クラウドサービスに対するHTTPSのアウトバウンド通信も必要となります。

* [ADFS アプリケーション移行支援のためのエクセル形式レポート](https://github.com/AzureAD/Deployment-Plans/tree/master/ADFS to AzureAD App Migration)
Azure AD Premium のライセンスをお持ちでない方、Azure AD の機能要件(上記)を満たすことが難しい環境である場合は、手動で集計するエクセル形式のレポートツールをご利用いただけます。AD FS アプリケーションアクティビティレポートと同程度の情報が確認可能です。ただし、最新状況を確認するためには、毎回手動で集計を行う必要があります。
GitHub上で無償公開されているスクリプトツールですのでどなたでもご利用いただけます。

2 つのレポート機能のどちらかを利用すればよく、環境に合わせて使い分けることが可能です。
次に、レポートで得られた情報をどのように活用するかについて説明します。
レポートの確認点として、ADFS アプリケーションの数がどれ位あるのか、およびアプリごとの移行ステータス（可否）が重要です。
移行ステータスについては、チェック項目に対して Pass か Warning の 2 種類のマークが表示されます。
この情報を参考に計画を調整すると良いでしょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/ccfa8e43-953c-08c7-4f5e-f17f543b5f71.png)

* AD FS アプリケーション アクティビティの例（参照：[Azure Active Directory のアプリケーション アクティビティ レポートを確認する | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/active-directory/manage-apps/migrate-adfs-application-activity)）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1879870/a75b932f-acf3-e717-4e88-9d6dd5e2c8e9.png)


# ADFS アプリケーション移行計画事例から無理のないスケジュールを見積もる

移行設計を円滑に進めるための **2 つ目のポイント**として、アプリケーションの数に応じた無理のない移行期間の見積もりです。
ここで、参考情報として、実際の案件から ADFS アプリケーション移行計画のサンプルを提示します。

|企業名 (匿名) | アプリケーション数 | 移行期間 | 作業リソース | 備考 |
|:-|:-|:-|:-|:-|
| A 社 | 10 個 | 4 週間  |自社のみ  |1 つのアプリ移行に数週間を消費  |
| B 社 | 80 個 | 6 ヶ月  |自社のみ  |アプリの種類ごとに段階的な移行  |
| C 社 | 400 個| 1 年以上|自社およびコンサルティングサービス利用  |すべてのアプリは移行しない<br>オンプレ MFA はユーザー移行を伴う|

A 社は 10 個の ADFS アプリケーションを 1 か月で Azure AD へ移行させ、B 社は 80 個のアプリケーションを半年間で移行させました。アプリケーションによって掛ける時間が異なるため、段階的な移行を取っていたようです。
多くのお客様が A 社か B 社に近い状況であると思います。400 個のアプリケーションの移行にチャレンジした C 社からは以下のことが分かります。
> コンサルティングサービスのアドバイスを得て自社の作業負荷を軽減した
> すべてのアプリケーションを移行しないという判断を行った
> アプリケーションだけでなくユーザー移行が伴う場合は時間を要した

# まとめ
本記事では、ADFS 移行のヒントとして、アプリケーションの移行設計を進めるためのレポートツール、計画サンプルを紹介させていただきました。
次回の記事では、「サンプルアプリケーションを使って ADFS から AAD への認証移行ステップを確認する」について掲載する予定です。

どれか 1 つでも活用していただける情報があれば幸いです。
＊本稿は、個人の見解に基づいた内容であり、所属する会社の公式見解ではありません。また、いかなる保証を与えるものでもありません。
数字のお遊びもほどほどに。

一部のサイトにおいては，予測式をいかに上手く作るかを競っている。

たとえば，サンプルサイズが 1000 だとして，一つのサンプルを正解にする（正解率を 0.001 上げる）ために，どれだけの特徴量（まあ，独立変数にすぎないのだが）をひねり出していることか。Titanic の元データがなんだか知らないが，乗客の名前から特徴量を紡ぎ出すというようなことも行われているようだが（そもそも，大元の Titanic のデータにそんなものがあるのかどうなのかしらないのではっきりとはいえないのだが），どうかなあ？と思う。

まあ，せめてもの防波堤は，どんな特徴量を紡ぎ出そうが，それは train data でのことで test data ではそのような特徴量が機能するかどうかは保証できない。

しかし，恐るべきことに，test data に含まれない特徴量を train data に含まれる特徴量で，推定？して test data でも有効な予測式を作り上げようという試みまで出てきたのか？

ここまで来ると，もう，ゲームだよね...

所詮，train data と test data という閉じたデータ空間で，どれだけ正解率を上げることができるかという。

train data と test data 合わせてサンプルサイズが数億，数兆という場面であっても，数のお遊びに過ぎないと思う。
逆に，サンプルサイズが数億，数兆なので，ちょっとしたモデルの差（ある特徴量を含むか含まないか）が誇張されるんだから。
【PHP】時間帯が重複しているかをチェックする

## どんなときつかうか
予約システムつくるとき、よく使う。例えば予約したい時間帯に**「空きがあるがどうか」**を調べたいときなど。

### 重複している時間帯をチェックするプログラム

```index.php
// 予約したい時間帯
$reserveStartDate = '2021-10-21 14:00';
$reserveEndDate = '2021-10-21 15:00';
		
// 予約ができないorうまっている時間帯
$fullSinceDate = '2021-10-21 14:30';
$fullUntillDate = '2021-10-21 15:30';

// invertは間隔が負の数になっている場合は1、正の数なら0を返す
$is_duplication = isTimeDuplication($reserveStartDate,$reserveEndDate,$fullSinceDate,$fullUntillDate);
if($is_duplication){
  print_r('重複しています。空きがありません');
}
else {
  print_r('重複なし。予約可能です。');
}

/*
* @param int $startTimeTarget 比較対象元の時間範囲開始時間
* @param int $endTimeTarget 比較対象元の時間範囲終了時間
* @param int $startTimeSource 比較対象の時間範囲開始時間
* @param int $endTimeSource 比較対象の時間範囲開始時間
* @return bool 重複している場合はtrueを返す
*/
public function isTimeDuplication($startTimeTarget, $endTimeTarget, 
  $startTimeSource, $endTimeSource)
  {
    $startTimeTarget = new DateTime($startTimeTarget);
    $endTimeTarget = new DateTime($endTimeTarget);
    $startTimeSource = new DateTime($startTimeSource);
    $endTimeSource = new DateTime($endTimeSource);
    $interval_1 = $endTimeSource->diff($startTimeTarget);
    $interval_2 = $endTimeTarget->diff($startTimeSource);
    return ($interval_1->invert > 0 && $interval_2->invert > 0);
  }Ï
```

## New Datetime()の注意点
### 日時比較
大小比較だけ行いたい場合は

```php
$deadline_date = "2021-11-20";
$objToday = new DateTime();
$objDeadlineDate = new DateTime($deadline_date);

if ($objDeadlineDate <= $objToday) {
  print_r('締切オーバー');
}else {
  print_r('まだ締め切ってません');
}
```

でも可能だが、**差分も取得したい場合はdiffを使う**

```php
$diff = $objToday->diff($objDeadlineDate);
// 締切前の場合
if (!$diff->invert) {
  print_r('締切日まで'.$diff->d.'日です');
}
```
###  format()はDateTime Objectの中のdateそのものを変形しない
+ format()は指定されたフォーマットに整形したDateTime Object内の**date**を値を返す。

```php
$objToday = new DateTime();
print_r($objToday->format('Y-m-d'));
print_r($objToday);
```
```出力結果.php
// 出力結果
2021-10-20
DateTime Object
(
    [date] => 2021-10-20 14:09:49.185645
    [timezone_type] => 3
    [timezone] => Asia/Tokyo
)
```

### modify()はDateTime Objectの中のdateそのものを変更する

```php
$objToday = new DateTime();
$arrWeek = array('日', '月', '火', '水', '木', '金', '土');
for ($i = 0; $i < 3; $i++) {
  $arrThreeDays[$i]['date'] =  $objToday->format('Y-m-d');
  $arrThreeDays[$i]['week'] = $arrWeek[$objToday->format('w')];
  $objToday->modify('+1 day');
  print_r($objToday);
}
print_r($arrThreeDays);
```
```出力結果.php
// 出力結果（$objToday）
DateTime Object
(
    [date] => 2021-10-21 14:31:31.710356
    [timezone_type] => 3
    [timezone] => Asia/Tokyo
)
DateTime Object
(
    [date] => 2021-10-22 14:31:31.710356
    [timezone_type] => 3
    [timezone] => Asia/Tokyo
)
DateTime Object
(
    [date] => 2021-10-23 14:31:31.710356
    [timezone_type] => 3
    [timezone] => Asia/Tokyo
)

// 出力結果（$arrThreeDays）
Array
(
    [0] => Array
        (
            [date] => 2021-10-20
            [week] => 水
        )
    [1] => Array
        (
            [date] => 2021-10-21
            [week] => 木
        )
    [2] => Array
        (
            [date] => 2021-10-22
            [week] => 金
        )
)
```
型

ポインタ型　pointer type 
被参照型（referenced type）と呼ぶ関数型、オブジェクト型または不完全型から派生することができる。被参照型Tから派生されるポインタ型は、”Tへのポインタ”と呼ぶ。被参照型からポインタ型を構成することを”ポインタ型派生”と呼ぶ。

関数型

指定された返却値の型を持つ関数を表す。

算術型
整数型および、浮動小数点数型を総称して算術型と呼ぶ。算術型は一つの型傾斜に属する。実数型領域は、実数型からなり、複素数型傾斜領域は、複素数型からなる。
FaultExceptionに変換されたSoapExceptionの中身を取り出す【actor,detail,code,message】

#　何をしたいのか
Webサービスに`<WebMethod>`の関数を作成して、SOAPを使って通信します。
例外が発生したらSoapExceptionとやらを返却します。

実際にWebサービスではそういう感じで、

```
'実際のパラメータは違う型です
Throw New SoapException("Message", "Code", "Actor", "Detail") 

```

みたいに書きました。

## 何が起きたのか
`SoapException`でCatchしようとしたらCatchできませんで、一体何が……と思ったら`FaultException`とかいう例外が返ってきてました。

なるほど道理でCatchできないわけですね。

型が違うもんね。

### なんでだよ。

と自分に突っ込むのも虚しく、調査のための検索結果はそれ以上に寂しいものでした。
SOAP、情報がない……いくらなんでもなさすぎる……

探すのが下手なだけかも知れませんがそれは下手っぴにとっては情報がないのと同義です。

なければ編み出せばいいじゃないってマリーも言ってるから編み出してみました。

ここまでが前振りです。

茶番にお付き合いいただきありがとうございます。

# 取得方法
まず、**なんでSoapExceptionが変換されるのかという理由はわかりません。**
<small>おしえてください</small>

ちなみに今回おしごとでこういうことをしてる（人に聞けないのでマリーの言う通り編み出してる）んですが、既存の他のクライアントを流用して通信したところSoapExceptionがちゃんと受け取れたので、呼び出し元の問題というのは間違いなさそうです。

さらに編み出そうとしてる通信方法はSoapExceptionを受け取るのがメインではなく、設定値がちゃんと連携されていることがわかればよい状況でした。

というわけで設定値さえ拾えれば問題ない……そんな感じのニッチな話なのですが、肝心の拾う方法が検索しても出てこず、総当たり的に探し出す羽目になったので記録に残しておきます。

Soap設定値|Fault格納場所
:-:|:-
Message|ex.Message
Code|ex.Code.Name ServerかClientが入る。
Actor|ex.CreateMessageFault.Actor
Detail|ex.CreateMessageFault.GetReaderAtDetailContents.Value<br>設定側で`detail=`に入れた値が取れる。

どっとはらい。
[React] シンタックスハイライト＆mermaid付きMarkdownを表示するコンポーネント

## コード

```tsx
import hljs from 'highlight.js/lib/core';
import typescript from 'highlight.js/lib/languages/typescript';
import marked from 'marked';
import mermaid from 'mermaid';
import {useEffect, useRef} from 'react';

import 'highlight.js/styles/github.css';

hljs.registerLanguage('typescript', typescript);

export const Markdown = ({text}: {text: string}) => {
  const elmRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const elm = elmRef.current;
    if (!elm) return;
    elm.innerHTML = marked(text, {
      breaks: true,
      highlight: (code, lang) => {
        if (hljs.getLanguage(lang))
          return [
            '<code class="hljs">',
            hljs.highlight(code, {language: lang}).value,
            '</code>',
          ].join('');
        if (lang === 'mermaid')
          return ['<div class="mermaid">', code, '</div>'].join('');
        return code;
      },
    });
    mermaid.init('.mermaid');
  }, [text]);

  return (
    <div>
      <div ref={elmRef} />
    </div>
  );
};
```

## 説明

このコードに説明が必要だとも思えないが、一応ポイントだけ。

`breaks: true`は完全に個人の趣味である。

highlight.jsはサイズが非常に大きいので、

```ts
import hljs from 'highlight.js';
```

ではなく、

```ts
import hljs from 'highlight.js/lib/core';
import typescript from 'highlight.js/lib/languages/typescript';

hljs.registerLanguage('typescript', typescript);
```

して、必要な言語だけ読み込む。

textが変わるたびに再レンダリングされるので、リアルタイムプレビューにも使える。
一文字入力する度に再レンダリングはさすがに重たそうなので、underscoreのdebounceと組み合わせると良いだろう。
インフラエンジニア学習1115 Linux

wコマンドの特徴
・現在時刻
・起動時間
・ユーザーのログイン状態
・ロードアベレージ
※Whoコマンドでも同じように確認できる。


grepコマンドの特徴
指定した文字列を検索する際に使用するコマンド

-i  大文字と小文字を区別せず検索する

-v 一致しないものを検索する

-n　検索結果を行番号を表示する
おすすめのマシューズ相関係数

マシューズ相関係数（英: Matthews correlation coefficient、MCC）とは、二項分類中の評価指標である。
周知のように、不均衡データの場合に誤解を招くから、精度は良くない指標だ。F1値のほうかいいが、二項分類中（0と1）どちらラベルは陽性ラベルかは問題だ。選択の違いならF1値も違いだ。原因は混同行列中、4つ要素がある。こらは真陽性(TP)、真陰性(TN)、偽陽性(FP)、偽陰性(FN)でおり、精度やF1値などに完全に考えられない。
MCCの定義は

$$
\text{MCC} = \frac{ \mathit{TP} \times \mathit{TN} - \mathit{FP} \times \mathit{FN} } {\sqrt{ (\mathit{TP} + \mathit{FP}) ( \mathit{TP} + \mathit{FN} ) ( \mathit{TN} + \mathit{FP} ) ( \mathit{TN} + \mathit{FN} ) } }
.$$

そう、この公式をやってみよう！

参考文献：

https://bmcgenomics.biomedcentral.com/articles/10.1186/s12864-019-6413-7
WSL2でSpresense開発環境を構築する

Windows WSL2上にSpresense SDK開発環境を構築する際のメモ書きです。

Windows PCしか持っていない、シリアルターミナルは使い慣れた`TeraTerm`が良い、という方にWSL2はおすすめです。WSL2のビルド時間がかなり速いです。(ベンチマーク結果はこちら:point_right: [Spresense開発環境のビルド時間を比較してみた](https://qiita.com/baggio/items/efc78d8b3862b5890c9f))

## WSL2インストール

WSL2のインストール方法は次のサイトを参考にしてください。
`Ubuntu-20.04`をインストールします。

https://codeaid.jp/blog/wsl2のインストールと更新方法/

## Spresense開発環境セットアップ

Spresense開発環境のセットアップは公式のマニュアル通りに実行するだけです。

https://developer.sony.com/develop/spresense/docs/sdk_set_up_ja.html

```console:インストールスクリプト実行
curl -L https://raw.githubusercontent.com/sonydevworld/spresense/master/install-tools.sh > install-tools.sh
bash install-tools.sh
```
```console:リポジトリからclone
git clone --recursive https://github.com/sonydevworld/spresense.git
```
### USBドライバインストール

`ダウンロード`タブ→`CP210x Universal Windows Driver`をダウンロードしてインストールする。

https://jp.silabs.com/developers/usb-to-uart-bridge-vcp-drivers

## Spresenseビルド手順

`Hello World`を動かします。

```console:PATH設定(.bashrcに追加してしまうのが楽です)
source ~/spresenseenv/setup
```
```console:ディレクトリ移動
cd spresense/sdk
```
```console:コンフィグレーション実行
./tools/config.py examples/hello
```
```console:ビルド
make -j
```

### 書き込み

2021/11/15現時点では、WSL2標準環境から直接USBポートにアクセスすることができないので、WSL2からWindows側のコマンドを実行して書き込みを行います。exeを付けて実行すれば勝手にWindows側のコマンドと解釈してくれます。便利ですね〜。`COM4`はWindows環境のシリアルCOMポート番号です。使用環境に合わせて変更してください。

```console:flash_writer
./tools/windows/flash_writer.exe -d -n -c COM4 nuttx.spk
```
(2022/6/5追記)
SDKv2.5.0バージョンでWSL2からの書き込みが正式対応されていました。
`flash.sh`を使って書き込みできるようになってました。
```console:flash.sh
./tools/flash.sh -c COM4 nuttx.spk
```


(2022/1/9追記)
WSL2 kernelを変更して直接USBポートにアクセスすることもできます。
詳しくは、[WSL2環境からUSBシリアルデバイスを使う](https://qiita.com/baggio/items/28c13ed8ac09fc7ebdf1)を参照してください。

### ターミナル

書き込みと同様に、`minicom`ターミナルなど直接USBポートを開くことができないので、ここではWeb Serial APIを使用します。Chromeブラウザ(できるだけ最新バージョン)で開いてください。

https://googlechromelabs.github.io/serial-terminal/

![スクリーンショット 2021-11-15 21.55.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432852/20897464-0383-c90b-50cb-08977682c4a2.png)

COMポートを指定してConnectして、無事に`hello`コマンドが実行できました。

![スクリーンショット 2021-11-15 22.06.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/432852/6f9a39f8-0eb3-2ebd-9096-d1cd23c244f6.png)

終わり。
ラムゼイ干渉を用いた量子センシング


$$
\def\bra#1{\mathinner{\left\langle{#1}\right|}}
\def\ket#1{\mathinner{\left|{#1}\right\rangle}}
\def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}
$$

#量子センシング理論

今回は、量子センシングの一番基本的な理論の部分について解説したいと思います。量子センシングに関しては、[こちらの記事](https://note.com/quantum_note/n/n68dcf5725150)に簡単な入門記事を書いています。

##ラムゼイ干渉

今回は、基本的な量子センシングのプロトコルである、ラムゼイ干渉を用いた量子センシングについて解説します。そもそも量子センシングとは、量子ビットの重ね合わせ状態といった量子的なコヒーレンスを利用した計測技術です。そして、重ね合わせ状態に用意した量子ビットが、種々の摂動によって位相を獲得します。この獲得した位相を評価することで、外場を評価することができるのです。そして、この位相差を検出する際に、有用な手法がラムゼイ干渉なのです。

具体的に、ラムゼイ干渉のプロトコルを確認しながらみていきましょう。ラムゼイ干渉は、以下のパルスシーケンスのように、二つの$\pi/2$パルスを量子ビットに与えることで実現されます。

![シーケンス - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2254220/cc2f3112-c2e4-9624-ea0d-0cf9131e9c43.png)


##ラムゼイ干渉のプロトコル

###1. 初期状態の生成
量子ビットの初期化を行います。
$$\ket{\psi}=\ket{0}$$

![Ramsey_initial_state - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2254220/40f55b1b-0145-765c-9674-51fbdd371b4e.png)

###2. π/2パルス
量子ビットを重ね合わせ状態に用意。
$$\ket{\psi}=\frac{1}{\sqrt{2}}(\ket{0}+\ket{1})$$

![Ramsey_pi_over_2 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2254220/38f1b889-2f21-3b6f-5542-b3c6a27aa5a9.png)

###3. 時間発展
位相シフト$\phi$が生じる。(ここでは、$\phi=\pi$を考える。)
$$\ket{\psi}=\frac{1}{\sqrt{2}}(\ket{0}+e^{i\phi}\ket{1})$$

![Ramsey_phase_shift - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2254220/fc65c9b0-c416-061a-8ca9-783a199fa453.png)


###4. π/2パルス
ここで、量子ビットが獲得した位相変化に関する情報を知りたいのだが、このままだと、量子ビットの射影測定、つまり$\hat{\sigma}_z$に関する測定を行っても、位相変化に関する情報を得ることができません。そこで、再度$\pi/2$パルスを照射することで、$\hat{\sigma}_z$基底で測定した際に、その位相変化の情報が得られるようにします。
$$\ket{\psi}=\frac{1}{\sqrt{2}}(\frac{1}{\sqrt{2}}(\ket{0}+\ket{1})-e^{i\phi}\frac{1}{\sqrt{2}}(\ket{0}-\ket{1}))=\frac{1}{2}(1-e^{i\phi})\ket{0}+\frac{1}{2}(1+e^{i\phi})\ket{1}$$


![Ramsey_second_pi_over_2 - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2254220/a423d649-fe70-8b99-2fc9-fca262bbd8dc.png)

###5. 状態観測
最後に量子ビットの測定を行う。この時、$\ket{0}$と$\ket{1}$がそれぞれ観測される確率は、
$$P_0 = |\braket{0|\psi}|^2=\frac{1}{2}(1-\cos{\phi})$$
$$P_1 = |\braket{1|\psi}|^2=\frac{1}{2}(1+\cos{\phi})$$
となります。これらの確率をプロットすると以下のような干渉が観測されます。この干渉をラムゼイ干渉と呼ぶのです。

![Ramsey - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2254220/f3d00766-92fd-bbd3-cd06-99cfe5a03215.png)

もうすこし、分かりやすいように干渉信号とその時のブロッホ球の振舞いを同時に示しておきます。

![Ramsey_with_bloch - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2254220/4cba469a-f998-7a15-ffb7-30b3b1f4c1aa.png)


この図のように、位相シフトの大きさによって$\ket{0}$を検出する確率が変化するのです。

##ラムゼイ干渉を用いた量子センシング

ここで、ラムゼイ干渉を用いた量子センシングの具体例を考えてみましょう。代表的な例として、磁場によって量子ビットの周波数が$\omega$から$\omega+\Delta\omega$に変化すると仮定します。

![Ramsey_two_level - コピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2254220/c2d0b31f-d86b-7c09-c64c-613e5b23410c.png)


この時のハミルトニアンは、
$$H=\frac{\omega}{2}\hat{\sigma}_z$$
と記述されます。つまり、ラムゼイ干渉を用いて、Z軸周りの回転による位相シフトを読みだすことにより、外場の大きさ、この場合磁場の大きさを測定することができるのです。
重回帰分析-総論

重回帰分析において，予測が旨くいくためにはどの独立変数を選択すれば良いかというのは，喫緊の問題だ。

独立変数が数百あるということでもない限り，まずは従属変数と独立変数の相関係数を計算して，余り相関係数が低い変数はモデルに含めないようにしようと考えるのはやむを得ないかも知れない。

しかし，それは間違いだ。

単変量解析（単回帰分析）の結果を積み上げれば，多変量解析（重回帰分析）の結果に反映できる。
というは，大間違いだ。

この観点からだけいえば，まだ「機械学習」の観点の方がまともだ。

機械学習の立場は，「要するに，上手く予測できればいいんでしょ！」ということだ。全ての独立変数のあらゆる組み合わせで，もっとも正解率の良いのが良いモデルだ。

単回帰分析（あるいは，相関分析）で，有望そうな変数を抽出して，それらに基づいて重回帰分析を行っても，「決して優れた予測式は得られない」。

どころか，「不適切な予測式が得られるかも知れない」ということだ。

どすればよい？

機械学習派と理論派の中間を探って，理論的に妥当なもっとも優れた予測式を探索するしかないのだ。
IPマスカレードを確認

## 勉強前イメージ

忘れたーなんだっけ、、、NAPT的なあれだった気がする

## 調査

### IPマスカレード とは

2つのネットワーク間でIPアドレスやポート番号を変換して、IPアドレスを有効に使うための技術。
一般的な名称は `NAPT` で、LinuxでのNAPTの実装で `IPマスカレード` という名称が付けられました。
機能としてはNAPTと同様になります。

### NAPT(IPマスカレード)の仕組み

簡単に仕組みとしては以下になります。

- 仕組み
	- IPアドレスとポート番号を変換する
- 動く場所
	- ルーターやファイアウォールで動く

### NAPT(IPマスカレード) の種類

- 静的IPマスカレード
	- IPアドレスとポート番号を1対1で変換
	- 事前にテーブルに登録しておく
	- グローバル側からセッションを始められる

- 動的IPマスカレード
	- 送信元IPアドレスを1つのGIPに変換する、複数対1の変換
	- よく使われている
	- グローバル側からセッションを開始できない

## 勉強後イメージ

パッと出てこなかったからこれで覚えた。
linuxで使われるのがIPマスカレードで、正式にはNAPTなんだね。

## 参考

- [NAPT 【Network Address Port Translation】 IPマスカレード / IP masquerade](https://e-words.jp/w/NAPT.html)
- [NATとIPマスカレード](https://www.gadgety.net/shin/tips/internet/nat.html)
Visual Studio: クリーンや、ビルドがスキップされた際の見直しポイント

# 背景
新しい PC になって Azure DevOps からソース取得したら、クリーンやビルドがスキップされて「え？」となったのでメモ

# 結論
- 拡張機能がインストールされていなくて、ソリューション内のプロジェクトがビルド出来なくなっていた。

# 気付かなかった理由
インストーラープロジェクトだけロードエラーになっていたから、気付いてはいたが、インストーラーだったから、後でいいやって思ってて放置してた・・。
暫く悩んだ結果、とりあえずロードエラーを解決しておくかと試したら解決・・故に、記録画像無し・・

今回は、以下の拡張機能が入れてなかった為発生・・愚か・・

![2021-11-15_10h56_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/ff7c4770-083b-5070-e367-96c9d9ea958e.png)
M1 MacとIntel Macの両方に対応したコマンドを作る

Go言語を使って、M1 MacとIntel Macの両方に対応したコマンドの作り方。

[なでしこ3配布キット](https://nadesi.com/doc3/go.php?16421)で、mac用のバイナリは、ユニバーサルバイナリとした。作り方を忘れそうだったのでここにメモ。


# 最初にMacで対応アーキテクチャを調べる方法

`file`コマンドで確認できる。

```
$ file (コマンド)
```

例えば以下のように表示される。

```
% file nadesiko3
nadesiko3: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64]
nadesiko3 (for architecture x86_64):	Mach-O 64-bit executable x86_64
nadesiko3 (for architecture arm64):	Mach-O 64-bit executable arm64
```


# Go言語で特定CPU向けのバイナリを作る

簡単に言うと、`go build`コマンドで`arm64`と`amd64`のバイナリを作っておいて、`lipo`コマンドでユニバーサルバイナリに結合する。以下のような感じで。

```
APP_NAME=hoge
ROOT_DIR=./src
OUT_DIR=./bin
ARM=$OUT_DIR/$APP_NAME.arm64
AMD=$OUT_DIR/$APP_NAME.amd64

# 各種CPU向けバイナリを生成
cd $ROOT_DIR
GOOS=darwin GOARCH=amd64 go build -o $ARM
GOOS=darwin GOARCH=arm64 go build -o $AMD

# 結合する
cd $OUT_DIR
lipo -create -output $APP_NAME $ARM $AMD
```

なお、注意点だが、この記事を書いた時点で、lipoを使う時は、ディレクトリが出力ディレクトリが同一でないとうまく動かなかった。何時間もはまった。



# 参考

 - [How to cross-compile Go app for Apple Silicon (M1)](https://dev.to/tidalmigrations/how-to-cross-compile-go-app-for-apple-silicon-m1-27l6)
Python SDKでOCI Vaultを操作する③ - シークレットでDB接続 - 

Vaultには、ユーザー名やパスワード、APIキーといった機密情報をシークレットとして管理することができます。シークレット情報は最大25KBの文字情報を保存でき、APIによる読み書きが可能です。プログラムにDBの接続情報をハードコーディングする、パスワードやSSHキーなどをメールやチャットなどで平文のままやり取りするなど、Vaultを一旦経由することでそのような漏洩リスクを減少させることができます。
また、シークレットはHSMではなく、Vault内のソフトウェア領域に保存され、5000シークレットまでは無償で利用できます。

ここでは、プログラムのDB接続情報をVaultのシークレット経由で取得する方法を紹介します

##Vaultにシークレットを作成する

- Vaultのシークレットの作成をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/f589a404-eb64-87c6-4fa8-8eed390871d6.png)

- シークレットを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/cca0d3e9-17d9-a575-af24-7b83e8ad59a0.png)
    - 名前: dbuser
    - 暗号化キー: 任意の暗号化キー
    - シークレットコンテンツ: DBの接続ユーザー名

同じようにパスワードと接続情報のためのシークレットをdbpassword, connectstrという名前で2つ作成します。
以降は、Pythonのサンプルコードですが、cx_OracleとOracle Instance Clientのインストールと設定は済ませておいてください。


## シークレットの値でDBに接続する

アプリケーションのコードの中では、以下のようにDB接続に必要な設定を直接ハードコーディングしている場合があるかと思います
connection = cx_Oracle.connect("ユーザー名", "パスワード", "接続文字列またはサービス名")

以下のコードでは、接続に必要な情報はVaultのシークレットから呼びだすように変更しています。それぞれのシークレットのOCIDを追記して下さい

```
import cx_Oracle,os,oci,base64
cx_Oracle.init_oracle_client(r"C:\Program Files\instantclient_21_3")
config = oci.config.from_file("~/.oci/config","DEFAULT")
secret_client = oci.secrets.SecretsClient(config)

#シークレットのDBUserを取得
response  = secret_client.get_secret_bundle('<dbuserシークレットのOCID>')
dbuser = base64.b64decode(response.data.secret_bundle_content.content)

#シークレットのDBPasswordを取得
response = secret_client.get_secret_bundle('<dbpasswordシークレットのOCID>')
dbpasswd = base64.b64decode(response.data.secret_bundle_content.content)

#シークレットのconnectstrを取得
response = secret_client.get_secret_bundle('<connectstrシークレットのOCID>')
connectstr = base64.b64decode(response.data.secret_bundle_content.content)

#Oracle Databaseに接続
connection = cx_Oracle.connect(dbuser, dbpasswd, connectstr)

cur = connection.cursor()
cur.execute("select sysdate from dual")
rows=cur.fetchall()
    print("DB接続成功")
    print(row)
```

サンプルコードをdbconnect.pyとして保存し実行します。
接続が成功すれば、select sysdate from dualの結果が返ります。

```
#実行例
python .\dbconnect.py
DB接続成功
2021-11-15 11:52:03
```

シークレットは削除したり、バージョンを作成するなどして、漏洩リスクをコントロールすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/c32e00b2-35f6-0150-1f86-af71449f7497.png)

DBだけでなく、OCIのFunctionsやバッチのシェルスクリプトなど、機密情報を外だしで管理したい利用ケースが多いと思うので、比較的お手軽に利用できます。
【Nuxt.js】ビュー　デフォルトレイアウトのカスタマイズ

#はじめに
こんにちは！
今回は【Vue.js】デフォルトレイアウトのカスタマイズについてアウトプットしていきます！

デフォルトのレイアウトはページの基本的なレイアウト定義するものです。

#カスタマイズ法
`layouts⏩default.vue`を開きます。

```default.vue
<template><!--⏪コンポーネントの基本となるプロパティ。
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　このテンプレートに設定した内容がコンポーネントとしてページに表示される。-->
  <div>
    <nuxt /><!--⏪各ページ異なるページコンポーネントを表示するために使われるもの-->
  </div>
</template>

<style> /*⏪各ページで使用されるstyle*/
html {
  font-family: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, 'Segoe UI',
    Roboto, 'Helvetica Neue', Arial, sans-serif;
  font-size: 128px;
  word-spacing: 1px;
  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  -moz-osx-font-smoothing: grayscale;
  -webkit-font-smoothing: antialiased;
  box-sizing: border-box;
}
```

各ページで使用される`style`は`defaulte.vue`に書くと◎。この`defaulte.vue`はレイアウトが明示的に指定されていない全てのページに使用されます。

#関係性

```
app.html(⏪HTMLの大枠を記述)
|
layouts/default.vue(サイト共通のstyleなどを記述)
|
pages/index.vueなど(pagesディレクトリに配置した各ページごとのコンポーネント)
```

#まとめ
関係性にある３つを使って１つのページを表示しています。各ページごとに共通化できる部分は１箇所にまとめてメンテナンス性を高めていきましょう！

#最後に
今回はデフォルトレイアウトについてアウトプットしました。
今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
[PHP] データベースから取得した文字列などの定型文への、動的な値・変数の埋め込み/置き換え

（サンプルソースはPHP/Laravelで記述しています。）

例えばメールの定型文や、記事のテンプレートなど、何かしらの文字列・文章がすでにある中へ、日時に応じて、ユーザーに応じてなど、動的な値をその時々で変えながら埋め込みたいということがあると思います。

文章・定型文中への、動的な値・変数の埋め込みを行うには、結論から言うと、```str_replace``` や ```mb_ereg_replace``` を使用して文字列を置き換えて表現します。

短いサンプルは以下の通りです。

```php:sample.php
$replacement = [
    '%%word1%%' => 'こんばんは',
    '%%word2%%' => '綺麗'
];
$text = '%%word1%%、今夜は月が%%word2%%ですね。';
echo str_replace(array_keys($replacement), array_values($replacement), $text);
// 結果 => こんばんは、今夜は月が綺麗ですね。
```

要するに、置き換える前のキーワードが index かつ置き換えた後に表示したい文字列を value とした配列 `$replacement` を用意して、それら文字列を埋め込みたい文章を `$text` の変数として用意して、 `str_replace()`, `array_keys()`, `array_values()` の関数をそれぞれ駆使し動的に文章中へ値を埋め込み/置き換えしているということになります。

それぞれの関数について詳しくは公式のマニュアルをご参照ください。

[str_replace — 検索文字列に一致したすべての文字列を置換する](https://www.php.net/manual/ja/function.str-replace.php)
[array_keys — 配列のキーすべて、あるいはその一部を返す](https://www.php.net/manual/ja/function.array-keys)
[array_values — 配列の全ての値を返す](https://www.php.net/manual/ja/function.array-values)

下記はLaravelでメッセージテンプレートがDBに保存してあると仮定して、そのテンプレートのタイトルや本文、日付部分などをメッセージ閲覧時の情報で置き換えるサンプルソースとなります。

```php: MessageController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Message;
use App\Repositories\MessageRepository;
use Carbon\Carbon;

class MessageController extends Controller
{
    // 説明上不要なメソッドなどは削除しています

    public function view(Request $request)
    {
        $messages = Message::all();
        $text = [];

        foreach ($messages as $message) {
            $text[] = $this->convert($message);
        }

        return view('pages/message/index', compact('text'));
    }

    public function convert($text)
    {
        $now = new Carbon();
        $deadline = $now->endOfMonth();

        $replacement = [
            '%%deadline%%' => $deadline->month . '月' . $deadline->day . '日',
            '%%now%%' => $now->year . '年' . $now->month . '月'
        ];
        return str_replace(array_keys($replacement), array_values($replacement), $text);
    }
}

```

仮に ```$message``` に

```php
"%%now%%のお知らせ\n
今月の締め切りは%%deadline%%となります。"
```

のような文字列が入っていた場合、 ```$replacement``` として定義されている配列の内容にそって文字列が置きかわりますので、実行時が2022年1月1日だったとすると、

```php
"2022年1月のお知らせ\n
今月の締め切りは1月31日となります。"
```
のような文字列を得ることができます。




#### 参考URL
[メールの定型文に可変文字列（変数）を埋め込みたいとき](http://bashalog.c-brains.jp/18/01/17-110000.php)
[the_contentの置換を動的に行う](https://masaroku.com/?p=614)
[【PHP】複数文字列の置換(str_replace)](https://qiita.com/kazu56/items/35c10fdd79393686b26d)
[【PHP入門】文字列の置換 | str_replace・str_ireplace・strtr](https://www.sejuku.net/blog/23430#i-5)
Julia でパスから拡張子を取り除く

[`splitext`](https://docs.julialang.org/en/v1/base/file/#Base.Filesystem.splitext) で拡張子を分離したタプルが得られるので、`splitext(path)[1]` や `splitext(path)[begin]` でパスから拡張子を取り除いたものが得られる。

```julia
path = "/home/hello.jl"
name = splitext(path)[1]
println(name) # `/home/hello
```
AMPページが常に8秒遅れて表示される原因

# はじめに

AMP対応のページ（[恐竜に肉食と草食がいたのはなぜ？：朝日新聞](https://www.asahi.com/amp/articles/ASPBT5HZMPB6ULBJ00Z.html)）を開いたら空白ページが8秒間表示された後でページが表示された。

そこでJavaScriptを動かして`document.styleSheets`のそれぞれに対して`disabled`を`true`にしてから`false`に戻したら空白ページが8秒間表示された後でページが表示された。

なぜモバイルでのウェブサイト閲覧を高速化させるためのAMPのページが常に8秒遅れて表示されるのか？その原因を調べた。

# 原因

原因はズバリ広告ブロッカーでサードパーティースクリプトをブロックしたことだった。広告ブロッカーがブロックしたのは`https://cdn.ampproject.org/v0.js`などのスクリプトだった。`ampproject.org`のスクリプトのブロックを解除したら遅れて表示されなくなった。

スタイルシートに次の記述があることも原因だった。

```css
<style amp-boilerplate="">
body{ animation:-amp-start 8s steps(1,end) 0s 1 normal both }
@keyframes -amp-start{ from {visibility:hidden} to {visibility:visible} }
</style>

<noscript>
<style amp-boilerplate>
body{ animation:none }
</style>
</noscript>
```

このスタイルシートは`body`を非表示にして8秒後に表示するアニメーションを指定する。JavaScriptが無効化されていたらそのアニメーションを無効化する。

デベロッパーツールでこの記述を削除したところ`document.styleSheets`の`disabled`を変えても遅れて表示されくなった。

# ampprojectのスクリプト

AMPは`body`を非表示にして`ampproject`のスクリプトがその非表示をやめてページを表示するようになっている。`ampproject`のスクリプトをブロックしたかネットワークの状態が悪いために8秒以内に読み込まなかったら8秒後にフォールバックしてページを表示するようになっているようだ。

AMPとは何か？[ウィキペディア(Accelerated Mobile Pages)](https://ja.wikipedia.org/wiki/Accelerated_Mobile_Pages)によれば、Googleにより運用されているAMP Cacheを通すことなどでパフォーマンスを改善するものだ。`ampproject`のスクリプトがパフォーマンス改善の動作を担っていると思う。

`ampproject`のスクリプトを読み込むことでGoogleにページの閲覧履歴などの個人情報が漏れないかを心配する。同ウィキペディアによれば、AMPの設立者はGoogleであり、AMPは、Googleなどによるウェブに対するコントロールをさらに強める可能性があるとして批判されてきた。

# さいごに

AMPページが常に8秒遅れて表示される原因を調べたら広告ブロッカーのブロックが原因だった。原因を調べたといっても、調べようと思って調べられるものではない。偶然HTMLの該当部分を見たことで原因が判明した。

AMPページが常に8秒遅れて表示され何かがおかしいと思いながら調査を後回しにしてきたが原因がわかって良かった:blush:。原因を調べることでAMPが少しわかって良かった:yum:。
Laravel6でlaravel/uiがインストールできない

#はじめに
Laravel6でlaravel/uiをインストールしようとしたらエラーが出たのでその対処法

#エラー内容
コマンドを実行したら以下の様になった。

```php:ターミナル
**@** docker-laravel % docker-compose exec app composer require laravel/ui
Using version ^3.3 for laravel/ui
./composer.json has been updated
Running composer update laravel/ui
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/ui[v3.3.0, ..., 3.x-dev] require illuminate/console ^8.42 -> found illuminate/console[v8.42.0, ..., 8.x-dev] but these were not loaded, likely because it conflicts with another require.
    - Root composer.json requires laravel/ui ^3.3 -> satisfiable by laravel/ui[v3.3.0, v3.3.1, v3.3.2, 3.x-dev].

You can also try re-running composer require with an explicit version constraint, e.g. "composer require laravel/ui:*" to figure out if any version is installable, or "composer require laravel/ui:^2.1" if you know which you need.

Installation failed, reverting ./composer.json and ./composer.lock to their original content.
```

##　解説
composer require laravel/uiは最新のパッケージを拾ってくるみたいです。
調べてみると、Laravel6はlaravel/ui:1.xが対応してるみたいです。
そのため、composer require laravel/uiでlaravel/ui:3.3をインストールしようとしてのエラーが出ています。

#解決法
```php:ターミナル
**@** docker-laravel % docker-compose exec app composer require laravel/ui:^1
./composer.json has been updated
Running composer update laravel/ui
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: laravel/tinker
Discovered Package: laravel/ui
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
68 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
```

laravel/ui:１を指定することで、解決しました。

#まとめ
Composer は、バージョンを指定しない場合に最新をインストールとすることを頭に入れなきゃですね。
また、Laravel6を使用する際は互換性にも気をつけないといけないですね。

バージョンを意識するの重要です。
EC2のWindows Server起動時の日本語化など

#はじめに
Windows ServerをEC2で起動した際、言語やタイムゾーンの変更などなど日本で使う場合の各種設定をまとめます。

#リモートデスクトップでの接続方法
AWSコンソールで対象EC2の接続画面から、Administratorの「パスワードを取得」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/311957e5-a397-e010-b8a9-a8920c47497e.png)

キーファイルを選択して「パスワードを複合化」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/92354132-99e3-63f1-4306-8cf00e026d40.png)

複合されたパスワードを使ってリモートデスクトップでログインします。
RDPで接続するためには接続元と同じネットワークにサーバーがある必要があります。

#Windows Server 2019 の場合
1. Administratorでログインしたら、Windowsメニューから[Settings]->[Times & Language]を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/0ea6d4b3-fa62-46ba-b29d-0029b527afc5.png)

1. Language メニューで +Add a Languageをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/c80b27ca-36a9-7881-b30b-3e402173f720.png)

1. Choose a language画面で[日本語 Japanese]を選択して[Next]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/159ee344-145c-ce42-2eaf-d2798718fe5a.png)

1. Install language features画面で[Install]ボタンをクリックすると、ダウンロードとインストールが始まります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/f1196fcb-7dcd-19ab-4f7e-16607338e9ae.png)

1. Region画面でRegionをJapanに、Regional formatをJapanese(Japan)に変更してSettingsメニューに戻ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/4909e1f0-a320-9a06-d5e1-3582873c6c77.png)

1. Date & time画面でTime zoneを[(UTC+09:00)Osaka,Sapporo,Tokyo]にセットしてSettingsメニューに戻ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/0803aed2-c5a9-77f6-cc2a-c39a4b3f9d08.png)

#Windows Server 2022 の場合（2019とのちがい）

* Install language features画面で、日本語を選んだあと、[Set as my Windows display langeage]にチェックを付けておくと、表示言語が日本語になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/940466/c5e3a78d-9888-52df-1678-4fb55d1d68b4.png)

#その他の注意点
* Language変更と同時にAdministratorのパスワード変更を行う場合、キーボードが英語配列の状態でパスワードを設定して、そのあとキーボードが日本語配列になってしまうと、パスワードが分からなくなります。

#おわりに
毎回お決まりで行う設定なので、まとめました。Powershellで同じことが実行できれば起動スクリプトとして自動化も可能ではないかと思いますが。。。