OmniAICreator/Qiita-1.07M huggingface dataset:
【メモ】Exploring Active Information Gathering

# 参考書：[HUMBLE TECH BOOK BUNDLE: CYBERSECURITY & CYBER WARFARE BY PACKT](https://bundlescan.com/bundles/humble-cybersecurity-cyber-warfare-packt/)
  - The Ultimate Kali Linux Book
    - Exploring Active Information Gathering（アクティブな情報収集）

## DNSゾーン転送の設定ミスを手動で見つける

### ゾーンレコードをリークしているかの調査

```
host -l zonetransfer.me nsztm1.digi.ninja
```


第1引数：調査したいサイト。zonetransfer.me は、公開されているやられサイト
第2引数：使用するDNS。これはなくても良い

### ターゲットドメインのすべてのネームサーバーのリークチェック

```
dnsenum zonetransfer.me
```

## ドメインからのOSINT（Spiderfoot）

```
sudo spiderfoot -l [ipaddress]:80
```


以下のエラーが出たら、
[CRITICAL] sf : Correlation rules directory does not exist: /usr/share/spiderfoot/correlations/
/usr/share/spiderfootに correlations ディレクトリを作る

ブラウザで以下URLにアクセス
```
http://[ipaddress]:80
```


様々なサイトから情報を収集できるがAPIが必要なサイトは、名前の横に鍵マークがついている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155700/70a577bb-4ba9-b19c-ccf3-e79a83b2bca9.png)

[New Scan] を選択し、[Scan name][Scan Target]を入力。
[Footprint] を選択し、[Run Scan Now]を押すとターゲットに関する OSINT の情報が収集できる（結構時間かかる）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155700/ee390712-c319-882b-3c08-bcc02b77dd6c.png)
自分のハニーポットにスキャンをかけた様子

### AWS S3 に公開されているファイルの確認（s3scanner）

ターゲットのドメインのIPを確認
```
nslookup flaws.cloud
```

IPアドレスにマップされているAWSのホスト名の取得(nslookup内でやる)
```
> set type=ptr
> [ipaddress]
```

s3-website-us-west-2.amazonaws.com にホストされていることが分かる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155700/47709a2e-70d4-05ca-fdbf-6902500dd322.png)

S3バケット内の確認
```
aws s3 ls s3://flaws.cloud/ --region us-west-2 --no-sign-request
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155700/26da545a-9475-7bdc-6af3-ab77f31d6167.png)

S3バケット内のファイルのダウンロード
```
s3scanner dump --bucket --bucket flaws.cloud --dump ~/Download/
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155700/056a35f7-7816-e623-6b1b-047f060dde23.png)
逆算的な発想をする


## はじめに

言葉にするのは難しいが、最終的にこういった答えになってほしいから、てことはこれに当てはまる数を求めればいいよねといった発想を求められるとき。

## 配列を２種類の数字にしたい

### 代表問題
引用元（ABC111-C）
https://atcoder.jp/contests/abc111/tasks/arc103_a


> 数列 a1,a2,...,an が以下の条件を満たすとき、`/\/\/\/` と呼ぶことにします。
> * 各 i=1,2,...,n−2 について、ai=a(i+2)
> * 数列に現れる数はちょうど 2 種類
> 偶数長の数列 v1,v2,...,vn が与えられます。
> 要素をいくつか書き換えることでこの数列を `/\/\/\/` にしたいです。
> 書き換える要素の数は最小でいくつになるか求めてください。


### 考え方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199864/3b46e7e7-f04d-e169-fbd4-51c83bbc4ccd.png)



実際に上記の問題を解いた時のコードは以下となる。

```c++
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // sort

using namespace std;

int main()
{
	long n;
	cin >> n;

	// 奇数番目の項で１番出現する数を求める
	// 同じく、偶数番目の項で１番出現する数を求める

	long itr_max = 100001;
	vector<long> even(itr_max, 0);
	vector<long> odd(itr_max, 0);

	long v;
	for (long i = 0; i < n; i++)
	{
		cin >> v;

		if (i % 2 == 0) odd[v]++;
		else even[v]++;
	}


	long max_e = -1, max_o = -1;
	long itr_e = 0, itr_o = 0;
	for (long i = 0; i < itr_max; i++)
	{
		if (even[i] > max_e)
		{
			max_e = even[i];
			itr_e = i;
		}

		if (odd[i] > max_o)
		{
			max_o = odd[i];
			itr_o = i;
		}
	}

	// 数字１種になっちゃうとき
	if (itr_e == itr_o)
	{
		long max_e2 = -1, max_o2 = -1;

		even[itr_e] = -1;
		odd[itr_o] = -1;
		
		for (long i = 0; i < itr_max; i++)
		{
			if (even[i] > max_e2) max_e2 = even[i];
			if (odd[i] > max_o2) max_o2 = odd[i];
		}

		if (max_e2 > max_o2) max_e = max_e2;
		else max_o = max_o2;
	}

	long ans = n - max_e - max_o;
	cout << ans;
}
```
Union Findのrust記事と簡単な理解

## Union Findに関して
下記を見るのが一番早い
https://atcoder.jp/contests/atc001/tasks/unionfind_a
C++ではなくrustで実装されているものを探した。

## rust実装
こちらのコードを丸パクリ
https://quantized-cube.com/rust-union-find/

また、使い方を勉強するため試しに
下記の問題の入力例を突っ込んでみて、その時のそれぞれの関数が何が出力されるかを見た
https://atcoder.jp/contests/abc177/tasks/abc177_d

今回の場合は
{1,2,5}と{3,4}がグループになる
この実装だとグループにしたのが早いほうが根になる。
rootだと根、それぞれ1,3が出力され
sizeはそれぞれ3,2となり
issameで同じグループにいるかどうか確認するといった流れのようだ。
parがグループわけの記録
sizがグループのサイズみたい。

```rust
use proconio::{input};
// Union-Find
pub struct UnionFind {
    par: Vec<i64>,
    siz: Vec<u64>,
}

impl UnionFind {
    pub fn new(n: usize) -> Self {
        Self {
            par: vec![-1; n],
            siz: vec![1; n],
        }
    }

    // 根を求める
    pub fn root(&mut self, x: usize) -> usize {
        if self.par[x] == -1 {
            return x; // x が根の場合は x を返す
        } else {
            self.par[x] = self.root(self.par[x] as usize) as i64;
            return self.par[x] as usize;
        }
    }

    // x と y が同じグループに属するかどうか (根が一致するかどうか)
    pub fn issame(&mut self, x: usize, y: usize) -> bool {
        self.root(x) == self.root(y)
    }

    // x を含むグループと y を含むグループとを併合する
    pub fn unite(&mut self, x: usize, y: usize) -> bool {
        // x, y をそれぞれ根まで移動する
        let mut x = self.root(x);
        let mut y = self.root(y);

        // すでに同じグループのときは何もしない
        if x == y {
            return false;
        }

        // union by size (y 側のサイズが小さくなるようにする)
        if self.siz[x] < self.siz[y] {
            // swap(x, y);
            let tmp = y;
            y = x;
            x = tmp;
        }

        // y を x の子とする
        self.par[y] = x as i64;
        self.siz[x] += self.siz[y];
        return true;
    }

    // x を含むグループのサイズ
    pub fn size(&mut self, x: usize) -> u64 {
        let r = self.root(x);
        return self.siz[r as usize];
    }
}

fn main() {
  input!{
  n:usize,
  m:usize,
  ab:[[usize;2];m]
  }
  let mut uf = UnionFind::new(n);
  for i in ab{
    uf.unite(i[0]-1, i[1]-1);
  }
//root,size,issame 括弧数字は+1すると元の数字、セミコロンの右コメントが出力
println!("{}",uf.root(1)+1);//1
println!("{}",uf.size(1));//3

println!("{}",uf.root(3)+1);//3
println!("{}",uf.size(3));//2

println!("{}",uf.root(4)+1);//1
println!("{}",uf.size(4));//3
println!("{}",uf.issame(1,4));//true

}
```
ソート後もインデックス情報が必要


## はじめに

ちょいちょい出てくる、ソートする必要があるけど、元のインデックス情報も持っておかなければいけない問題を解くとき。

## 代表問題
引用元（ABC113）
https://atcoder.jp/contests/abc113/tasks/abc113_c

> Atcoder国には N 個の県があり、これらの県には合計で M 個の市が属しています。
> 市 i が誕生したのは Yi 年であり、県 Pi​ に属しています。
> ただし、同じ年に誕生した市が複数存在することはないとします。
> それぞれの市に 12 桁の認識番号を割り振ることとなりました。
> 市 i が 県 Pi に属する市の中で x 番目に誕生した市のとき、市 i の認識番号の上 6 桁は Pi 、下6桁は x となります。
> ただし、Pi や x が 6 桁に満たない場合は 6 桁になるまで 0 を左に追加するものとします。
> 全ての市の認識番号を求めてください。

## 考え方

問題整理
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199864/2d0cfb24-a081-0203-56dd-6f03134fda4b.png)

解く方針
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199864/066cdd58-083a-fdf1-1b20-8095d48fea14.png)



実際に上記の問題を解いた時のコードは以下となる。

```c++
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // sort
#include <map> // pair,multimap
#include <tuple>

using namespace std;

int main()
{
	long n, m;
	cin >> n >> m;

	vector<tuple<long, long, long>> pyi;

	long p, y;
	for (long i = 0; i < m; i++)
	{
		cin >> p >> y;
		pyi.push_back(make_tuple(p, y, i));
	}

	sort(pyi.begin(), pyi.end());

	string tmplate = "000000";
	p = get<0>(pyi[0]);

	long cnt = 0;
	vector<string> ans(m);

	for (long i = 0; i < m; i++)
	{
		if (p == get<0>(pyi[i]))
		{
			cnt++;
		}
		else
		{
			cnt = 1;
			p = get<0>(pyi[i]);
		}

		string str_p = to_string(p);
		long len = str_p.length();
		string pi = tmplate.substr(0, 6 - len) + str_p;

		string str_cnt = to_string(cnt);
		len = str_cnt.length();
		string xi = tmplate.substr(0, 6 - len) + str_cnt;

		ans[get<2>(pyi[i])] = pi + xi;
	}

	for (long i = 0; i < m; i++)
	{
		cout << ans[i] << endl;
	}
}
```
【Python 3】Windowsでバージョン確認する方法

# はじめに

WindowsにインストールしたPythonのバージョン確認方法を調べた結果の備忘録。

# 動作環境

- Windows10 バージョン 21H1

# 確認手順

## １．コマンドプロンプト起動

## ２．バージョン確認コマンド実行

```shell-session
>python --version
Python 3.10.5

>python -V
Python 3.10.5

>python -VV
Python 3.10.5 (tags/v3.10.5:f377153, Jun  6 2022, 16:14:13) [MSC v.1929 64 bit (AMD64)]
```

-VVは バージョン3.6で追加されたらしい。

# 備考

- [ 3.10.4 Documentation » Python のセットアップと利用 » 1. コマンドラインと環境](https://docs.python.org/ja/3/using/cmdline.html)
frameとboundsのちがい

# frameとboundsのちがい

両方viewのsizeやoriginに関するプロパティだけど、frameは親から見た時、boundsは自分自身から見た時を前提とするみたいです。

# ギモン

だからsizeに関しては全く同じ値になるのかな？
boundsのoriginに関してはどんな状況でも(0, 0)になると思うんだけどどうなんだろう。意味あるのかなこれ

# わかりやすかった記事
https://qiita.com/tanaka-tt/items/0b2df30e1c79638580f7

https://www.yoheim.net/blog.php?q=20120502
numpyで2つの配列の最近傍値を取得したい。

#  はじめに

入力配列にある最も近い値を取得するコードは[これ](https://stackoverflow.com/questions/2566412/find-nearest-value-in-numpy-array)にあるように差分が最小になる値を取得すれば良い。だが、探索したい値が配列の場合にはどうするのだろうと思い考えてみた。

もちろん[ここにある関数](https://stackoverflow.com/questions/2566412/find-nearest-value-in-numpy-array)をリスト内包表記で計算すればよいのだが、ここではあくまで`numpy`で行う事を考えてみた。


# コード

```python
import numpy as np

def search_nearestvalues(a, v):
    ids = np.argmin(((np.tile(a, (len(v), 1))) - v[:, np.newaxis])**2, axis=1)
    return a[ids]

np.random.seed(0)
a = 10*np.random.rand(10)
v = np.array([8, 10, 3])
print(search_nearestvalues(a, v))  # [7.15189366 9.63662761 3.83441519]
```

# 解説
ポイントは`v[:, np.newaxis]`で`v`を(3)から(3, 1)の配列にして差分を取ることで各値との差を求めることができる。もちろん`np.rehape(-1, 1)`でも可能である。ちなみに[`np.newaxis`](https://numpy.org/doc/stable/reference/constants.html#numpy.newaxis)は`None`のエイリアスみたい。


# 締め

配列を`numpy.tile`関数で複製して探索しているのでメモリに余裕があるときしか動かないからあまり賢い方法には思えないかな。他に良い方法があれば（あるはず）コメント頂けたら幸いです。

# 追記

@nkayさんに、np.tileはなしでも自動でブロードキャストしてくれると教えていただきました。また、2乗よりも絶対値のほうが速いみたいです。ありがとうございます！

```python
def search_nearestvalues(a, v):
    ids = np.argmin(abs(a - v[:, None]), axis=1)
    return a[ids]
```
特定操作を繰り返して３つの数字を同じにする


## はじめに

ABC093のC問題の解き方が公式の解答とやり方違ったのでメモで残しておく。
ただ、計算量は明らかに公式の解き方より多くなるので、いい解き方ではない。


## 問題
引用元
https://atcoder.jp/contests/abc093/tasks/arc094_a

> 3 つの整数 A,B,C が与えられます。
> 以下の 2 種類の操作を好きな順で繰り返して A,B,C をすべて等しくするために必要な操作の最小回数を求めてください。
> 
> * A,B,C のうち 2 つを選んで、その両方を 1 増やす
> * A,B,C のうち 1 つを選んで、その整数を 2 増やす



## 解き方の方針
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1199864/5b9bb4e8-21c2-c18b-a68f-c33c626805ea.png)




## 実際の提出コード

```c++
#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // sort

using namespace std;

int main()
{
	vector<long> a(3);
	for (long i = 0; i < 3; i++)cin >> a[i];

	sort(a.begin(), a.end());

	long cnt = 0;
	while (true)
	{
		if (a[0] == a[1] && a[0] == a[2])break;

		if (a[2] != a[1])
		{
			a[2]--;
			cnt++;
		}

		if (a[1]!=a[0])
		{
			a[0] += 2;
			cnt++;
		}
		sort(a.begin(), a.end());
	}

	cout << cnt;
}
```
iOSアプリを開発しようと思ったら読むべき記事

iOSアプリの開発ってどうやったらいいのか全くわからなかったので調べてみました。

↓以下のサイトがアプリの開発からリリースまでの流れがとてもわかりやすくまとまっていたのでおすすめです！
https://i-app-tec.com/ios/developer-registration.html
XcodeをAppStoreダウンロードできない時の対処法

XcodeをAppstoreでダウンロードできなかったのでその対処法について書いていきます。

結論、Appleの公式ページからならダウンロードできるみたいです。

↓以下のサイトからダウンロードできます。
https://developer.apple.com/download/all/?q=xcode
XMLのvariableパラメータでジェネリックな型を指定する方法

# はじめに
XML上でジェネリックなパラメータを指定する実装を少し調べる機会がありましたので、議事録的に残しておこうと思います。

# 指定方法
指定方法は以下です。

```
<variable
   name="livedata"
   type="androidx.lifecycle.LiveData&lt;Boolean&gt;" />
```

以上になります。
variableには特殊文字は使用できないので、記号部分は上記のように記載する必要があります。

# さいごに
上記の実装頻度は高くはないものの、実装するとなると少し考えてしまう方もいるかもしれません。
その際にはこちらの実装をお役に立てていただけますと幸いです。
【図解】Azure Storageとストレージアカウントの違い

## 概要
Azureを学習することになり、AADの次にぶつかった壁であるAzure Storageとストレージアカウントの違いに関して解説します。
**日本語での解説記事があまりに少ない & 図を用いた解説が英語、日本語ともに少なかった**ので、記事にしてみました。
### 想定読者：

- Azureの学習を始めたが、**Azure Storageとストレージアカウントの違いについてイマイチ分からない**方。
- **Azure Storageの文脈とストレージアカウントの文脈で同じような単語が何度も出てきて理解できない**方。
- MS公式ドキュメントでは**日本語サービス名の表記ゆれが多く**理解できない方。
- Azure学習歴は長いがAzure Storageとストレージアカウントの違いについて**イマイチ分からないまま使用している**方。

## Azure Storageとは（サービスの切り口）
公式Doc（[Azure Storage の概要](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-introduction)）には下記のように記載されています。

>Azure Storage は、クラウド内のさまざまなデータ オブジェクトに対して、可用性が高く、スケーラビリティ、持続性、安全性に優れたストレージを提供します。 Azure Storage のデータ オブジェクトには、REST API を使って HTTP または HTTPS 経由で世界中のどこからでもアクセスできます。 また、Azure Storage には、.NET、Java、Python、JavaScript、C++、Go を使ってアプリケーションやサービスを構築する開発者向けのクライアント ライブラリも用意されています。


つまり、**Azure StorageはブラウザやAPI、SDK経由でアクセス可能なストレージサービス**です。
また、[ブロック BLOB、追加 BLOB、およびページ BLOB について](https://docs.microsoft.com/ja-jp/rest/api/storageservices/understanding-block-blobs--append-blobs--and-page-blobs)には下記のように記載されています。

>ストレージ サービスには、ブロック BLOB、追加BLOB、およびページ BLOB の 3 種類の BLOB が用意されています。

以上より、**Azure Storageは具体的なサービスとして下記の5種類を提供しており、さらに5種類のうち、Azure Blobsはblock, append, pageに分けられる**ことが分かります。

|Azure Storage	|Types			|
|-				|-				|
|Azure FIles	|-				|
|Azure Blobs	|block, append, page|
|Azure Disks	|-				|
|Azure Queues	|-				|
|Azure Tables	|-				|


## ストレージアカウントとは（アカウントの切り口）
公式Doc（[ストレージ アカウントの概要](https://docs.microsoft.com/ja-jp/azure/storage/common/storage-account-overview)）に下記の説明があります。
>このストレージ アカウントでは、世界中のどこからでも HTTP または HTTPS 経由でアクセスできる Azure Storage データ用の一意の名前空間が提供されます。 
Azure Storage では、数種類のストレージ アカウントが提供されています。 各種類は異なる機能をサポートし、独自の価格モデルがあります。


つまり、**Azure ストレージサービスとAzure ストレージアカウントは異なる概念**です。
Azure Storageサービスを利用するためには、ストレージアカウントと呼ばれるアカウントを作成します。さらに**ストレージアカウントに紐づく形で各種Azure Storageサービスを利用する**ことになります。

|ストレージアカウント|
|-|
|Standard general-purpose v2|
|Premium block blobs|
|Premium file shares|
|Premium page blobs|

このように、Azure Storageを理解するには**サービスの切り口とアカウントの切り口**で分けて整理する必要があります。

## ストレージアカウントの種類をAzure Portal上で確認してみる
それでは、実際にストレージアカウントを作成してみて、アカウントの種類がどのように表示されるか挙動を観察してみます。
ストレージアカウント作成は以下の選択肢が表示されます。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197157/4cb57478-209a-fcf0-4479-14f950d558e2.png)

ストレージアカウントの表と同じ選択肢です。これらのアカウントをすべて作成してPortal上で一覧化した結果が下記になります。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197157/dff57291-ad8d-8879-eba3-a23635b3e55b.png)

このように**ストレージアカウント作成時に選択したアカウントの種類がPortal上でそのまま表示されない仕様**になっています。


## サービスとアカウントを分けて考える
以下の図は**Azure Storageサービスとストレージアカウントの対応関係**を示しています。
一番左側の列には**Azure Storageにて提供されている「サービス」**、
真ん中の列には**各サービスを利用するのに作成する必要のある「ストレージアカウントの種類」**、
一番右の列には**Azure Portal上に表示される種類**を示しています。


![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197157/90277851-17c5-fa76-c584-036db917b82a.png)

### Standard / Premium page blobs アカウントの見分け方
作成後にAzure portalから一覧画面を表示してもStorageV2とだけ表示されており、一見見分けがつきません。**各詳細画面に遷移して対応するサービスまたはパフォーマンスタイプ（StandardかPremium）を確認する**必要があります。


### 「ブロックBLOB」という名称がサービスの切り口にもアカウントの切り口にも出てくる
- Azure Storageサービスで提供されるAzure Blobsのblock blobを指している場合
- Premium block blobsをさしている場合
の二種類が考えられます。
IPアドレスとドメイン名の権利に関して調べてみた

# そもそもIPアドレスとかドメイン名って何？
権利がどこ？の前にIPアドレスとかドメイン名はいったい何なのかを調べていきます。
IPアドレスには、外向け（全世界の人が利用できる）のグローバルIPと内向け（自宅や職場等の限られた場所で利用できる）のローカルIPがあります。インターネット上からは、グローバルIPアドレスを持つPCを指定できますが、ローカルIPを使用して指定することは（直接は）できません。
ローカルIPにインターネットから接続するには、ゲートウェイを経由します。外（インターネット上）から見ると見えない（指定できない）ですが、内（ゲートウェイ）から見ると内側なので見ることができます。グローバルIPを持つPC一台あれば、その一台を踏み台（プロキシ）にすることでローカルにあるPCに接続できます。
そして、ドメイン名というのはグローバルIPを名前に変換したものです。ドメイン名とIPアドレスを相互変換するシステムをDNSと言います。
つまりは、ドメイン名=グローバルIPということなのでドメイン名を指定することは、グローバルIPアドレスを指定することと同じです。
このグローバルIPなのですが、枯渇するという問題が起きます。外から接続するためのIPアドレスなのですが、数に限りがあるので接続する数が増えた現在は足りなくなってしまうという問題を持っています。そのため、グローバルIPは動的に変化するようにしています。この動作は契約しているプロバイダやルータが自動で行います。
なのですが、外＝インターネット上から接続してほしいサーバはIPを変更してほしくありません。（毎回設定を変更しなくてはならないので）そのために、プロバイダにお金を払って固定IPを取得しています。
また、ドメイン名は枯渇することは考えられないのですが（文字列なので極端に言うと組み合わせが無限にある）被ってしまうとPCを指定できなくなるので被らないようにしています。これもお金を払ってドメイン名を取得しています。

今回の記事は、このドメイン名を誰が管理しているのか疑問に思ったので書きました。

# グローバルIPアドレスの管理者
グローバルIPアドレスは、プロバイダが持っています。まあ、読んで字のごとくprvider（=提供する人）なので当たり前です。なので、どうじてプロバイダはグローバルIPアドレスを持っているのかを調べました。まず、IPアドレスはIPアドレスポリシーに基づきIANAという組織を頂点として管理されています。日本では、JPNICが国内のIPアドレスを管理しています。プロバイダはこのJPNICに委託された業者です。なので、グローバルIPアドレスからは、「日本であること」「どこのプロバイダ」であるかが分かります。インターネットに接続するために自分のグローバルIPアドレスは公開されますが、プロバイダに地域性はなく、かつ通常であれば動的IPなので住所などが分かることはあり得ません。（逐一プロバイダがログを取っていない限り）ちなみに、ここで言うプロバイダはIPのプロバイダ（so-netやOCNなど）で、インターネットのプロバイダ（ドコモ光やnuro光など）ではありません。グローバルIPから国はわかるので、おま国はされます。

# ドメイン名の管理者
本題のドメイン名です。これは、枯渇することはほぼ考えられないのですが、ドメイン名を取得できる業者にお金を払って取得します。「.com」や「.jp」などのドメイン名ごとに料金が変動します。ドメイン名もIPと同じようにICANNを頂点として管理されています。日本では、「.jp」のみがJPRSによって管理されており、委託された業者（レジストラ）はそのレジストリに登録する業務を請け負っています。

# 結論
なぜ、お金を払ってIPやドメイン名を取得する必要があるのだろうと疑問でしたが、管理している組織から業者に委託しているからということが分かりました。んー、なぜ金儲けのためにお金を払わなければいけないんだろうと思いましたね。まあ、なにかしら基準があってのことなんでしょうけど。むやみやたらに取られてもしょうがないのでお金をとるのはいいですけど、そのお金が国じゃなくて企業に行くのがどうにも。国の力だけでなんとかなるものじゃないのでしょうがないですが...
Jetpack Composeに触れる


Jetpack Composeの各コンポーネントについて紹介をしていきます。
今回は準備とプロジェクト生成時のMainActivityの中身について触れていきます。

# Jetpack Composeとは
Jetpack Composeは、ネイティブUIをビルドするためのAndroidの最新ツールキットです。
既存のAndroid開発ではレイアウトにXMLを使用していました。
Jetpack ComposeではXMLを使用せずにUIの構築を行うことがことができます。

## 環境
- Android Studio Android Studio Bumblebee | 2021.1.1 Patch 3

## 準備
Jetpack Composeのプロジェクトを作成するには
Android StudioのFile -> New -> New Project -> Empty Compose Activity
で作成します。
<img src= "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651213/402f37f4-8296-21c3-1923-5a45c9dc623b.png" width=500px>



## MainActivity
プロジェクトを作成すると以下のようなコードが生成されます。

```kotlin
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            SampleJetpackComposeTheme {
                // A surface container using the 'background' color from the theme
                Surface(modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background) {
                    Greeting("Android")
                }
            }
        }
    }
}

@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
    SampleJetpackComposeTheme {
        Greeting("Android")
    }
}

```
onCreateメソッドのsetContentの中に表示するUIの部品（コンポーネント）を配置することができます。
<img src= "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651213/3047eec4-939e-0fc9-931f-688269abba9f.png" width=250px>

## `Composable`
Jetpack Composeでは各UI部品をコンポーネントという部品単位にわけることで構築を行います。
その際`Composable`アノテーションをつけます。
上記のコードでは`Greeting`というコンポーネントが生成されています。
`Greeting`の中にある`Text`もコンポーネントです。
`Text`に文字列を渡すことで、渡したテキストが画面に表示されます。

Jetpack Composeのコンポーネントの
名前はアッパーキャメルケースで記述します。



## PreView
Previewアノテーションを付けることで、シミュレータや実機を起動しなくても、
プレビュー画面からコンポーネント単位でUIの確認を行うことができます。
<img src= "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651213/e99bb47c-0ed8-3adf-394e-0ce6c4b02268.png" width=600px>


## 参考
[Compose を導入する理由](https://developer.android.com/jetpack/compose/why-adopt?hl=ja)
地震情報を簡単に扱いたい！

:::note warn
読みにくい記事に注意してください....。
:::

## tl;dr
地震情報を簡単に扱えるようにするやつ

## はじめに...

まずは皆さんに、P2PのAPIのすばらしさをば
・[WebScoketAPI](https://www.p2pquake.net/json_api_v2/#/)から送られてくるやつはJSONなので扱いやすい（最高）
・情報伝達がすごいほど早い
・すごい

## 今回作った奴

https://github.com/akikaki-bot/p2pws_getter

今回はTypeScriptで大部分を書きました。TSは簡単なやつでしか書いてないので結構難しかった....。

## しくみ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2594613/ed3b92f1-71c4-3547-1f59-47b14ce82236.png)

## 感想

たのちかった。TypeScriptだいちゅき。

## Link
APIの本
https://www.p2pquake.net/json_api_v2/#/
フローチャート作成に使った
https://app.diagrams.net/
【雑記】アジャイル"っぽい"案件への向き合い方

### 前提
- 書き手はアジャイルについて詳しくなく、"正しいアジャイルとは？"といったこともよくわかっていないです。
- そのため、アジャイル"っぽい"としていますが、そもそもそれはアジャイルではないと言われる可能性もあることを承知した上で書いていますので、ご了承ください。
- ただ嘘を書きたいわけでは全くないので、気になる点があればコメントいただければと思います。


### アジャイル"っぽい"とは?
- 新しい案件へのアサインの相談で、アジャイルっぽい進め方をする案件という話。
- 案件概要で提案書を使って、実装したい機能の概要とおおまかなスケジュールについて説明を受けた。
- 後日、別にいる案件担当者から案件の詳細をMtgで説明を受ける予定。
    - ここでQCDのうち、CとDが確定しているアジャイルってどういうことだろう？と疑問が湧く。

※まだ案件詳細を聞いていないので、以下から書き手の推測を含みます。

- まずアジャイル"っぽい"ってなんだろうというところを考えるところから始めてみます。
    - アジャイルとはなんぞやという記事はqiita検索をかけるとたくさん出てきますね。
        - [【初心者向け】アジャイル開発とは何ぞや？をまとめてみた](https://qiita.com/c_tomioka/items/97711a9b831e68ff0e32)
        - [認定スクラムマスターの俺が正しいスクラムの理論をまとめてみた](https://qiita.com/gold-kou/items/90ba982a14ca79d843c9)

    - また、アジャイルってこう思われているよねという記事も出てきます。
        - [アジャイル勘違い集](https://qiita.com/yuzuru-akiyama/items/6fe6f7f4568edb96faf6)
        - [アジャイル開発のよくある勘違いまとめ](https://qiita.com/nskydiving/items/6dfd6b259b9dce4cae0c)

- これらの記事を統合するとアジャイル"っぽい"と呼ばれる案件は以下のような特徴がありそうだと推察できそうです。
    - **一旦の完成をもって動作確認、うまく動かない部分を修正しつつ最終的に正しいものにする。**
        - 上記をスプリントとみなしてしまう。
            - 要求から機能、非機能要件（周辺の関連システム仕様を含む）が抜け漏れが想定されるため、柔軟に対応してほしい
    - **進捗管理やドキュメントを楽にできる。**
        - 計画を容易に変更して良い、ドキュメントより動作するコードといった部分を上記のように解釈してしまう。
            - 契約期間が決まっている案件で計画の自由度は高くない（PMに期間内でできないので途中で終わりですor追加で契約期間伸ばしてくださいって言ってもらえますか？）
            - ドキュメントに全てを残すことはもちろん難しいが、他メンバーやクライアント担当者、将来システムを運用するメンバーのため、いざというときの免責か否かの判断材料のためなど役に立つ場面がまだまだ多い（自分だけでそのシステムをずっと運用し続けますか？）

### アジャイル"っぽい"案件って。。。
- 上記２点がアジャイル"っぽい"案件だとすると、結構大変になりそうな案件だと予想されそうです。。。(あくまで勝手な予想)

### アジャイル"っぽい"案件への向き合い方
(タイトル回収です)
- 大変になりそうな案件に対して、１メンバーとしてどう向き合う予定かという方針です。（案件終わった時にどうだったかもできれば書きたいです。）
    - ウォーターフォールに基づき計画をし、手順をちゃんと踏む、ドキュメントを書き起こす
        - 基本的には、ちゃんと要件を確認し要件定義書を書き起こす、設計書を記載し担当者にレビューしてもらう、単体テストや結合テストで要件や設計を満たしていることを確認するというウォーターフォールに基づいた方法を実直に行うことが必要に思われます。
    - 早めの対応を心がける
        - ウォーターフォールになるべく従いつつ、アジャイル"っぽい"と言われている以上、要件や仕様の抜け漏れが発生することは踏まえておくべきだと思われます。であれば、それらに対応できるようなバッファを意識的に作る必要があり、スプリントもどきのような対応ができる状況を作っておく方が精神衛生的に良さそうに思います。
    - 全てを複数人が確認できるシステムに記録する
        - 実際、全てを記録することはできませんが、仕様の検討内容や設計書の修正履歴、担当者の承認など残せるものは残しておくことで自分の身を守ることができる（かも）。
        - 環境に反映したリソースもバージョン管理ツールを利用して、AWSインフラであればCfn+CodeCommit、アプリでもCodeCommitを利用することでいつ、なにを、なぜ反映したか分かるような状態を作っておく。
        - AWS Configなども設定することでいつ、どのリソースが反映、修正されたか追跡できるようにしておく。


### まとめ
- アジャイル"っぽい"案件に対しても、通常の案件と同じことをしっかりと行うことで対応できそう。
- ただ、怪しい部分もあるので早めに怪しい箇所や不明な箇所を潰していくような動きをすることが求められそう。

### 参考URL

https://qiita.com/c_tomioka/items/97711a9b831e68ff0e32

https://qiita.com/gold-kou/items/90ba982a14ca79d843c9

https://qiita.com/yuzuru-akiyama/items/6fe6f7f4568edb96faf6

https://qiita.com/nskydiving/items/6dfd6b259b9dce4cae0c
sshでwarningが出たとき

### sshで接続しようとしたら、warningができたので、その時の対応メモ

sshで接続する際に、
```
$ ssh ip-address
```
と打つと
```
WARNING : REMOTE HOST IDENTIFICATION HAS CHANGED!
```
と出ることがある。


ssh-keyを更新する
```
$ ssh-keygen -R ip-address
```
を行い更新をする

そして、再度接続する
```
$ ssh ip-address
```
で接続を行う
ReactでWarning: task: `key` is not a prop. Trying to access it will result in `undefined` being returned.の対処法


## 概要
Reactで`key={hogehoge}`としてコンポーネントに値を渡すとundefinedとなってハマったので、原因と解決策をまとめました。

## 問題
### コード

key="test"として、Column.jsに値を渡します。

```App.js
import React from 'react';
import Column from './Column';

const App = () => {
  return (
    <Column key="test"/>
  );
}

export default App;
```

keyの値を表示してみます。
期待する値は"test"です。

```Column.js
import React from 'react';

const Column = props => {
  console.log(`key = ${props.key}`);
  return (
    <></>
  );
}

export default Column;
```

### 結果
以下のように、undefinedとなります。
```
key = undefined
```

## 解決策

keyではなく別の名前でColumn.jsに値を渡す必要があります。
Reactの公式ドキュメントにも以下記載がありました。

> Most props on a JSX element are passed on to the component, however, there are two special props (ref and key) which are used by React, and are thus not forwarded to the component.

要は、`key`と`ref`はReact内で使われる特別な値でコンポーネントに値は渡されないということのようです。

https://reactjs.org/warnings/special-props.html

### コード

以下のようにmyKeyとしてコンポーネントに値を渡してみます。

```App.js
import React from 'react';
import Column from './Column';

const App = () => {
  return (
    <Column myKey="test"/>
  );
}

export default App;
```

Column.jsではprops.myKeyとして値を表示します。

```Column.js
import React from 'react';

const Column = props => {
  console.log(`myKey = ${props.myKey}`);
  return (
    <></>
  );
}

export default Column;
```

### 結果
以下のように値の受け渡しができました。

```
myKey = test
```

## 参考

https://stackoverflow.com/questions/33661511/reactjs-key-undefined-when-accessed-as-a-prop
【CocoaPods】ライブラリのインストール時にバージョンに関して警告が出る

# 警告文
```
[!] Automatically assigning platform `iOS` with version `15.4` on target `LicensePlist-Demo` because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.
```

# 解決方法
警告文で表示されているバージョンを`Podfile`ファイルに記載する
![スクリーンショット 2022-06-14 15.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b4fbe765-58f2-9d97-2d27-0315fffce91f.png)
```diff_ruby
  # Uncomment the next line to define a global 
  platform for your project
+ platform :ios, '14.0'

  target 'LicensePlist-Demo' do
    # Comment the next line if you don't want to use 
  dynamic frameworks
    use_frameworks!

    # Pods for LicensePlist-Demo
    pod 'LicensePlist'

  end
```
研修日程が知りたい。こんな時はVoiceflowにおまかせ！

![New file (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/f0c6d87c-245e-8894-9e83-ee875613107e.png)

こんにちは:blush:
スーパーマーケット事業で働く会社員です。
普段は教育の仕事をしています。

前回投稿した記事では「**研修日程がわからない**」というお問い合わせを受けて
**研修日程を確認できる**アプリを『**Glide**』で作成しました。
手元の**スマホでいつでもどこでも確認できる**って便利ですね。

https://qiita.com/maeda-kosaku/items/ef2cfd75792c4fab4c42

今回は音声認識ツール**Voiceflow**を使って**研修日程の確認でスマホを見る作業すら
省いて**みようかと思います。
これができれば
・**スマホや手帳を開かなくても日程が確認できる。**
・**教育部署のメンバーで共有できれば、間違いもなし。**
とても便利な予感がしているので挑戦してみました。

## 使用ツール
**[Voiceflow](https://creator.voiceflow.com/signup)**
　⇒音声アプリを作成できるノーコードアプリです。
**[Google Spread Sheets](https://www.google.com/intl/ja_jp/sheets/about/)**
　⇒連携させて情報の更新ができるようにします。

## ひとまずできました。

https://twitter.com/Maepon517/status/1537602507324567552

## 使用方法

最初に**Voiceflow**を立ち上げます。
作りたい全体フローはこちらです。
![スクリーンショット (120).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/a8fad10c-d9d6-6745-86f0-8edf7ad74b12.png)

①左のブロック一覧から**Resuponse** `Speak`ブロックをを選び、**Start**に繋げる。
Alexaにしゃべってほしい内容を入力する。
![スクリーンショット (121).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/c9cc9186-4202-d3b5-b100-34e11e1c534f.png)

②次に**User Input** より`Capture`ブロックを選んで繋げる。
今回は「**研修名を伝えて日程でかえす**」をしたいので
**Spread Sheets**のB列の『`name`』を一つ目の変数に設定する。
![スクリーンショット (122).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/9f98ffaf-7eab-d919-f836-eef39126acc8.png)
![スクリーンショット (114).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/aedf8ae0-004d-6462-708c-709509786b38.png)

③次に **Integration** より`Google Sheets`ブロックを繋ぎ、連携内容を入力する。
上から
・「データを抽出する」機能の『`Retrieve Date`』を選択。
・**As User**に抽出先のアドレスを入力。
・**Using Sheet** に抽出したい`Spread Sheets名`を指定。
・**Spread Sheets内**の使いたい`Sheet名`を指定。
・**With Settings**では先ほどの設定した一つ目の変数`{name}`を入力。
![スクリーンショット (123).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/c31b7cab-7994-d82b-7dd6-132ce1085617.png)
・**Mapping Output**にかえす内容を入力。
今回は日程でかえしたいのでA列の『`date`』を二つ目の変数に設定。
![スクリーンショット (124).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/e0044805-f103-a9ff-2dfd-cea03de60b3f.png)
![スクリーンショット (126).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/de24a9b0-5304-ec9f-74ea-448cb9df5a81.png)

④最後に**Resuponse** `Speak`ブロックを選んで繋げる。
話してほしい内容を入力。
二つの変数を使用したいので「`次回の{name}は{date}です。`」にしました。

:::note warn
{ }の全角・半角に注意です。
:::

![スクリーンショット (125).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2670703/20b0adcb-a7a8-d0c7-2276-8a3b49dc2f9d.png)
これで完成です。

## 実際に聞いてもらいました。
今回も同じ部署のメンバーに試作品を聞いてもらいフィードバックをいただきました。

**メンバーの皆さんより**
良い点:smile:
* 日程確認する機会は多いので声で教えてくれるのはいいですね。
* Alexaほしくなっちゃいます。

改善点:frowning:
* 事務局だけではなく、受講者も使えると良い。

他にもアイデアをいただきました。
* 資料を探して⇒パソコンからデータを出してくれる機能があるといい。
* 宿泊予約フォームを音声入力する。
* よくある電話のお問い合わせを記録し、共有できる。

たくさんのフィードバックありがとうございます。
確かに受講する人も確認できたら便利ですね。
パソコンのマイクで反応できるかな・・・。
いろいろ調べてみたいと思います。
音声認識機能を使った解決ってけっこうありそうですね。

## あとがき
最近いろいろなデジタルツールを試す機会が増えていましてとても勉強になります。
社内PCのセキュリティ上の問題で、**Spread Sheets**がデジタルツールと
連携できないことが多かったんですが
なんと今回の**Voiceflow**は初めて**Spread Sheets**と連携ができたので
うれしさ倍増でした:satisfied:
まだまだ改良の余地ありですので引き続き実装に向けて頑張ります。
gRPCとGraphQLのマイクロサービスでの使われ方とBFFの技術選定について

gRPCとGraphQL
---

gRPCという言葉は以前から知っていたのですが、Rest APIの新しい物という認識ぐらいで
あまり良く分かっておりませんでした。

エンジニアたる物
一度使われ所といったことを調べておかないと思い、
メリカリさんの記事を見て、少し理解したので記事にさせて頂きます。

結構ざっくりな説明になりますが、よろしくお願いします。

まず、gRPCはどういう時に使われるのかというと、マイクロサービス間の通信に使われる事が多く、
GraphQLは、フロントエンドとバックエンド間の通信の際に良く使われます。

※ GraphQLとは簡単にいうと、FaceBookが作った新しいAPI通信規格なのですが
クエリーを投げ、必要なデータのみ取得することにより、通信自体が軽くなるようです。

https://zenn.dev/gakin/articles/graphql_introduction

でマイクロサービスでのgRPCとGraphQLの使われ方についてなのですが、

BFF(Backend For Frontend)

という設計で作られることが多くなっているようです。

https://zenn.dev/offers/articles/20220418-what-is-bff-architecture

BFF採用企業
---

メリカリさんやzozoさん、andpadといった企業さんが利用されています。

https://engineering.mercari.com/blog/entry/20210810-mercari-shops-tech-stack/

https://techblog.zozo.com/entry/zozo-aggregation-api-bff

https://tech.andpad.co.jp/entry/2021/07/09/100000

---

BFFはフロントとバックエンド(各マイクロサービス)間に入る

ルーティングみたいなのものです。

その際に、遅いとされるマイクロサービスの速度を改善する為に、

フロントとBFFの通信はGraphQLで、BFFとバックエンド(マイクロサービスで作られた)間の
通信はgRPCで通信することにより、速度が遅くならないでしょという感じです。


![スクリーンショット 2022-06-18 16.14.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981122/1ebd3f83-d241-9a35-dc9d-501cbd24134a.png)

BFFの技術選定について
---

ただ、BFFはフロントとはGraphQLで通信し、バックエンドではgRPCとやりとりする必要がある為、
BFFは、GraphQLとgRPCを両方使える必要があるようです。

その為、BFFはnode.jsのフレームワークのNestJSがよく使われているみたいです。

https://tech.mfkessai.co.jp/2020/08/bff-by-nestjs/


https://engineering.mercari.com/blog/entry/20210818-mercari-shops-nestjs-graphql-server/#batch-api-definition

![スクリーンショット 2022-06-18 15.01.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/981122/813e2010-0241-f8b9-188c-2ad24f2ca53d.png)

https://findy-code.io/pick-up/interviews/souzoh-engineer

記事一部抜粋

```
──効率性と将来性を考えてGraphQLを採用されたのですね。

末田：ライブラリについても言及すると、BFFの実装にはNestJSのGraphQLのモジュールを使用しています。
コードを書いてデコレーターでスキーマ情報を定義し、自動的にスキーマを書き出すコードベースの方式を採用しています。

全体としては、BFFサーバーの中でgRPCクライアントを生成し、そこから各マイクロサービスにリクエストして、各フィールドに必要な情報を取得しています。

──なるほど。技術選定の際、NestJS以外の候補はありましたか？

名村：マイクロサービスに対するアクセスとGraphQLのインターフェースを両方カバーしているフレームワークは、NestJS以外にあまりないんですよ。

また、NestJSはJavaのようなDependency Injection(DI)の考えがあるので、DIの仕組みに乗っかっていれば、
マイクロサービスが肥大化してもコード量をたくさん増やさなくてもいい。必要なサービスをGraphQLのリゾルバーで呼び出すことができると思ったので、NestJSを採用しました。

使用する上での制約もありますが、DIのレイヤーで依存関係を構築できたので、NestJSを採用して良かったと思っています。
```
---
【Kotlin/JVM】一定期間ごとの日付を出力する

一定期間ごとの日付を出力する。

```Kotlin
import java.time.LocalDate

fun main() {
    // 起点の日付
    val initial: String = "2022-06-18"
    // 間隔[日]
    val interval: Long = 10
    // 出力回数
    val count: Int = 5

    sequence {
        var date = LocalDate.parse(initial)
        while(true) {
            date = date.plusDays(interval)
            yield(date)
        }
    }.take(count)
        .forEach { println(it) }
}
```

出力結果

```
2022-06-28
2022-07-08
2022-07-18
2022-07-28
2022-08-07
```

／以上
【機械学習】Feature Scalingの基礎(標準化/正規化/fit/transform/fit_transform)

# はじめに
8月から機械学習の案件を行うことになり、最近学習をはじめました。
統計やPythonまわりについて、自分用のメモとして記事を書いていこうと思います。

# Feature Scalingとは
Feature Scaling(特徴量スケーリング)は機械学習の前処理の1つで、KNNなどのアルゴリズムで真価を発揮します。
例えば、特徴量によって単位や値の大きさが違っているときに、各次元の関係をわかりやすくすることで、学習モデルの精度改善ができます(言いかえると、特徴量による単位や値の大きさの違いが学習モデルに影響を及ぼさないような決定木などのアルゴリズムには、Feature Scalingは不要となります)。

# 標準化と正規化
Feature Scalingの代表的な手法として、標準化と正規化があります。

## 標準化(Standardization)
標準化は元のデータの平均を0、標準偏差を1のものへと変換する手法で、`Z-score normalization`とも呼ばれます。
一般的に、標準化は最大値や最小値が決まっていない場合や外れ値が存在する場合に利用されます。
Z-scoreは以下のように求められます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/4246bc5e-e5c4-06bf-fd8a-c61359c752b7.png" width="200">

また、sklearnで標準化を行う場合には、`StandardScaler`を使用します。
標準化は説明変数(X_train, X_test)のみに対して行います。
目的変数(y)を標準化してしまうとそもそもの予測対象の値が変わってしまうため、yの標準化は不要となります。

```py
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(X_train)
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
```

## 正規化(Normalization)
正規化は特徴量を最小値0、最大値1の範囲に変換する手法です。
標準化と異なり、外れ値がスケーリングに与える影響が大きいため、最大値と最小値が決まっている場合(画像処理など)に使用されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/af718089-587b-1ea7-6556-e4fec22228ea.png" width="400">

sklearnで正規化を行う場合、`MinMaxScaler`を使用します(使い方はStandardScalerとほぼ同じため割愛)。


# fit, transform, fit_transformの使い分け
sklearnのスケーリング関数(`StandardScaler`や`MinMaxScaler`)にはfit, transform, fit_transformというメソッドがあります。

## fit関数
データを変換するために必要な統計データ(標準化であれば標準偏差σと平均値μ、正規化であれば最大値Xmaxと最小値Xmin)を計算します。
fitは訓練データのみに適用し、テストデータには適用しません。

## transform関数
fit関数で計算した統計データを元にスケーリング(標準化、正規化)を実行します。

## fit_transform関数
fit関数とtransform関数をつなげて実行します。

fit_transformがあればfitやtransformが必要なさそうにみえますが、そのようなことはありません。
というのも、テストデータの変換には、 訓練データで計算された統計データを使用する必要があるためです。

テストデータにはfit_transformを使わないよう、以下の流れでFeature Scalingを行いましょう。

- 訓練データとテストデータを分割する
- トレーニングデータをfitする
- トレーニングデータをtransformする
- テストデータをtransformする

# 参考資料

https://www.udemy.com/share/103I003@geAjiIIbeAp6lHVBzVyuAuftmVcYHgO5YkABYiTzdgGLkL2ZAtnxAxL89ek4pF60/

https://aiacademy.jp/texts/show/?id=555

https://di-acc2.com/programming/python/3748/

https://mathwords.net/fittransform
【対応メモ】npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.


Reactを使おうと思ったら

```
npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
```
(npm 警告 グローバル設定 `--global`, `--local` は非推奨です。代わりに `--location=global` を使ってください。)

みたいな警告が。

## 調べてみる

調べてみると、こちらのstackoverflowの記事がヒット。

https://stackoverflow.com/questions/72401421/npm-warn-config-global-global-local-are-deprecated-use-location-glo

Windowsで起こる現象みたいですね…？

## 対応策

どうやら…**node.js**がインストールされているディレクトリ（**Program Files/nodejs**のはず）の中にある

- npm
- npm.cmd
- npx
- npx.cmd

という4つのファイルの中に書かれている`prefix -g`という記述を、それぞれ`prefix --location=global`に置き換えると解決するっぽいです。

実際に書き換えてみたら、警告は出なくなりました。

（ただ、これが最善策かどうかは分からないので、もし何か問題があれば教えてください…。）
【Git】cherry-pick

# cherry-pick
他のブランチで必要なコミットを現在のブランチにコピーしたいときに便利な`cherry-pick`コマンドを紹介します。


別のブランチのコミットを今のブランチにコピーしコミットします。
```
$ git cherry-pick <コミットのハッシュ値>
```

上記は取り込んだ内容がそのまま、コミットされます。
コミットをせず、ワークツリー内に反映するだけの場合は`-n`オプションを使います。
```
$ git cherry-pick -n <コミットのハッシュ値>
```


## 参考
[第10話 git cherry-pick でいいとこ取り！【連載】マンガでわかるGit ～コマンド編～ - itstaffing エンジニアスタイル](https://www.r-staffing.co.jp/engineer/entry/20200327_1)
サイレントインストール化（自動化）

ユーザインターフェイスなしで実行されるインストール。
InstallShieldで作成したインストーラはサイレントインストールに対応している。

【InstallScript MSI および InstallScript プロジェクト】
① コマンドラインから /r オプションを指定してインストールを実行し、応答ファイルを作成する。
※ダイアログで操作した内容が、自動的に応答ファイルへ記録される。
~~~
setup.exe /r
~~~

② Setup.iss（応答ファイル）が Windows フォルダー（c:\windows）に作成されていることを確認する。

③Setup.iss（応答ファイル）をsetup.exeと同じ場所に置き、setup.exe -sとして実行する。
無線LANの事前設定方法（自動化）

既に入っているPCから取得するとラク。認証情報他configをそのまま使えるため。

①これでSSIDと必要な情報を調べる。
netsh wlan show profile

②表示された中に、例えばYOKOHAMA-WLANがあれば、以下を打ってxmlを出力する。
netsh wlan export profile name="YOKOHAMA-WLAN" folder=C:\


入れたいPCでバッチ実行。
バッチは以下のように書く。keymaterialはSSIDのパスワード。
上述のXMLを指定して実行する。

~~~
@echo off
 
SET wifi_prof="%~dp0WIFI\Wi-Fi-YOKOHAMA-WLAN.xml
netsh wlan add profile filename=%wifi_prof%
netsh wlan set profileparameter name=YOKOHAMA-WLAN nonBroadcast=yes keymaterial=SSID_PASSWORD connectionmode=manual

pause
end
その他の投稿

|[../](https://qiita.com/taconana/items/d382d08a83a2a67f3b6a) |
|---|

- [WindowsへのPostgreSQLのインストール手順](https://qiita.com/taconana/items/405678ccd1654985de9d)
- [PostgreSQLでのsequenceの使い方](https://qiita.com/taconana/items/cb6d3a49e3b6542b477e)
- [Java検定問題](https://qiita.com/taconana/items/5ae13e9d85135cf78333)

|[../](https://qiita.com/taconana/items/d382d08a83a2a67f3b6a) |
|---|
CentOS Stream 8でポートの使用状況／空き状況を確認する手順

|[../](https://qiita.com/taconana/items/d382d08a83a2a67f3b6a) |
|---|

CentOS Stream 8でポートの使用状況／空き状況を確認する手順を調べてみた。nmapがいいみたい。
```
$ dnf list nmap
nmap.x86_64                       2:7.70-7.el8                        @appstream

$ dnf install nmap

$ nmap 153.xxx.xxx.xxx
$ nmap kankeri.com
Starting Nmap 7.70 ( https://nmap.org ) at 2022-06-18 09:52 JST
Nmap scan report for kankeri.com (153.xxx.xxx.xxx)
Host is up (0.000051s latency).
rDNS record for 153.xxx.xxx.xxx: yyy.yyy.com.localdomain
Not shown: 986 closed ports
PORT     STATE SERVICE
22/tcp   open  ssh
25/tcp   open  smtp
80/tcp   open  http
110/tcp  open  pop3
111/tcp  open  rpcbind
143/tcp  open  imap
443/tcp  open  https
587/tcp  open  submission
993/tcp  open  imaps
995/tcp  open  pop3s
3306/tcp open  mysql
5901/tcp open  vnc-1
8080/tcp open  http-proxy
9090/tcp open  zeus-admin
Nmap done:

$ ss -nat
State    Recv-Q  Send-Q   Local Address:Port   Peer Address:Port   Process     
LISTEN   0       128      0.0.0.0:8070         0.0.0.0:*                     
LISTEN   0       100      0.0.0.0:587          0.0.0.0:*                     
...

$ firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources: 
  services: cockpit dhcpv6-client http imap mysql pop3 smtp smtp-submission vnc-server
  ports: 8080/tcp 8443/tcp 8009/tcp
  protocols: 
```

## CentOSでよく使われるポートの一覧：
```
20		ftp-data	ファイル転送（データ本体）
21		ftp			ファイル転送（コントロール）
22		ssh			リモートログイン（Secure Shell）
23		telnet		リモートログイン
25		smtp		Simple Mail Transfer Protocol
53		dns			Domain Name System
80		http		Hypertext Transfer Protocol  

110		pop3  		Post Office Protocol
111		rcpbind		Remote Procedure Calls
143		imap   		Internet Message Access Protocol 
443		https		HTTP over SSL/TLS
587		submission 	Message Submission
993		imaps 		IMAP over SSL/TLS
995		pop3s 		POP3 over SSL/TLS
   
1521	Oracle DB
3306 	MySQL 
5432	PostgreSQL
5900   	VNC			Virtual Network Computing 
5901	vnc-1
5902	vnc-2
5903	vnc-3

8005 				Apache Tomcat's Shutdown port
8009 	ajp13		Apache JServ Protocol
8080	http_alt	HTTP alternate（代替HTTPポート）
8443				Apache Tomcat's https
```
|[../](https://qiita.com/taconana/items/d382d08a83a2a67f3b6a) |
|---|
laravel9 Password系のバリデーション

# 概要

- laravel9からのバリデーションで、パスワード文字列の複雑さチェックを管理するものが追加されたので簡単にまとめてみる。
- ちなみに細かい内容は公式にわかりやすく記載されているのでそちらを参照いただきたい。
    - [パスワードのバリデーション](https://readouble.com/laravel/9.x/ja/validation.html#rule-current-password)

# 記載方法

- パスワードバリデーションでは下記の内容がチェック可能である。
    - 最低文字数 `Password::min(最低文字数)`
    - 最低1つの文字が必要 `Password::min(最低文字数)->letters()`
    - 最低1つの数字が必要 `Password::min(最低文字数)->numbers()`
    - 最低1つの記号が必要 `Password::min(最低文字数)->symbols()`
    - 最低大文字小文字が1文字ずつ必要 `Password::min(最低文字数)->mixedCase()`
- 下記のように`Illuminate\Validation\Rules\Password`をuseして静的呼び出しのメソッドチェーンを用いて設定する　。（キーpasswordの値は必須かつ最低8文字かつ最低1文字の数字含む）

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'password' => ['required', Password::min(8)->numbers()],
        ];
    }
    ```

- `numbers()`だけの呼び出しはできない模様。必ず`min()`を指定する必要あり。

# 参考文献

- [https://readouble.com/laravel/9.x/ja/validation.html#rule-current-password](https://readouble.com/laravel/9.x/ja/validation.html#rule-current-password)
laravelとvueを使ってaxiosでcsvファイルをpostして処理する

__laravelでvueを使うには__
laravelでは簡単にvueを使うことができます。

なぜならデフォルトで設定がされているからです。

pacakge.jsonファイルをみると、"bootstrap"や"jquery"や"sass"などが記述されています。

これらのパッケージはインストールする必要があり、`npm install`でインストールします。

インストールしたら次はビルドして実際に使えるようにします。

`npm run dev`でビルドします。

これで使えるようになりました。あとはプロジェクトに合わせてファイルの構成を決めてください。

blade内でvueを仕様するためにコンテナとコンポーネントタグを用意します。
```hoge.blade.php
<div id="app">
  <test-componet></test-componet>
</div>
```

スクリプトを読み込み。スクリプトタグでjsファイルを読み込みます。
`<script src="{{ mix('js/app.js') }}">`


__vueでaxiosを使う__
vueでaxiosを使うために`Vue.use(VueAxios, axios);`をapp.jsファイル内で追記する必要があります。

```app.js
Vue.use(VueAxios, axios);
```
__次にコンポーネントの登録です__
app.jsファイルでコンポーネントを登録します。
```app,js
Vue.component('test-component',require('/components/TestComponete.vue');
```

__vueファイルの作成__
resources/js/components/内にvueファイルを作成します。
TestComponent.vueを作成し次のように記述します

```TestComponent.vue
<template>
    <div>
        <form action="/hoge/hoge" method="POST">
            <input type="hidden" name="_token" :value="csrf">
            <label for="file">ファイル</label> 
            <input @change="selectedFile" type="file" name="file" accept=".csv" ref="csvfile">
　　　　　　　　　　　　　　　　<button type="submit">送信</button>
    </div>
</template>

</script>
```
ここではポイントが3つあります。

   * csrfトークンを設定しないとpostリクエストが送れません。
      いくつか方法はあると思いますがpropsで渡してv-bind(:を使用)で参照するやり方が一番簡単だと思います。

   * @changeでファイルが選択されたら処理を行ないようにしました。

   * refを設定しているところです。これがないと選択したファイルを取得することができません。
  
templateタグの下にscriptを書いていきます。
```TestComponent.vue
<script>
export default {
    data () {
        return {
            file: "",
        }
    },

    methods: {
            selectedFile: function() {
                let formData = new FormData();
                let file = this.$refs.csvfile.files[0]
                formData.append('file', file);
                this.axios
                    .post('/送りたいURL', formData)
                    .then((response) =>  {
                        const data = response.data
                        console.log(data)
                    })
                    .catch(function(error) {
                        alert(error)
                    })
            },
        },
    props: ['csrf'],
}
</script>
```

methodsの中で@changeで指定した`selectedFile`の関数を呼び出します。
`FormData()`のインスタンスを生成します。csvファイルをcontrollerで処理する際に、この方法じゃないとエラーになりました(違う方法もあるとおもいます)。
次に選択されたファイルを参照するために`this.$refs.csvfile.files[0]`を使用します。
ここで3つ目のポイントの`ref`が役に立ちます。これは`ref`を使うことでどこの何を取得するか明確になり、vue側も値を参照できるようになります。

__axios__
axiosを使用するのは簡単で`this.axios`で使用できます。
`.post`で第一引数に送りたいURLを指定し、第二引数で送りたい情報を指定します。
`.then((response)=>{})`でコントローラーで処理した後に帰ってきたものを受け取ります。
今回は受け取ったものを`data`に格納して`console.log(data)`で出力しました。
もしエラーだった場合は`.catch(function(error){})`で処理しました。

以上laravelでvueを使ってaxiosでcsvファイルをpostして処理する方法を簡単に紹介しました。
csvファイルを処理することができれば色々と開発でできることが増えると思います。

この記事がお役に立てれば幸いです。
VMware Fusionでubuntuを動かせなかった時の代替方法（NOBUTAKA OSHIROさんを参考に）

VMware　Fusionを使って動かそうとしたのですが、下記写真①のようなエラーが出てしまし上手く動きませんでした。原因は、VMがintelアプリらしいのですが、そのintelアプリを上手く動かすRosettaが上手く動かず、macbookにしたことを後悔😭

![スクリーンショット 2022-06-17 14.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707455/2f35dade-404c-351c-92c5-7aeb47ef2b83.png)


そこで、NOBUTAKA OSHIROさん
https://qiita.com/notakaos
の記事
https://qiita.com/notakaos/items/928987623fc61e815363
を参考にmaltipassを使ってMacOS上でubuntuを動かして見ました。

### パソコンのバージョン
```
% uname -a
Darwin ユーザー名noMacBook-Air.local 21.5.0 Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:29 PDT 2022; root:xnu-8020
```

まず初めにbrew（バージョン管理システム）をインストールしていない方は下記コマンドからbrewをインストールします。

brewとは
https://ja.wikipedia.org/wiki/Homebrew_(パッケージ管理システム)

```
%　/bin/bash -c "$(curl -fsSL　https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```
この後、下記のようなメッセージが出ます。（下記のようなメッセージが出なければ上手くいってないかもです。）
```
==> Next steps:
- Run these two commands in your terminal to add Homebrew to your PATH:
    echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/ユーザー名/.zprofile
    eval "$(/opt/homebrew/bin/brew shellenv)"
```
そしたら、上記メッセージ通りに
```
$/opt/homebrew/bin/brew shellenv
```
という感じにメッセージ通り３つのコマンドをterminalに入力していきます。
下記のようなメッセージが出たらインストール完了です。
```
% brew -v
Homebrew 3.5.2
Homebrew/homebrew-core (git revision 52309396f4d; last commit 2022-06-18)
```

これでようやく今回のメインであるmaltipassをインストールします。

### maltipassのインストール
```
%　brew install --cask multipass
```
成功したら下記のようなメッセージが出ます。

```
🍺 multipass was successfully installed!
```
そしたらmultipass versionコマンドでちゃんと入ったかチェックして見ましょう。
### maltipassでubuntuVMの作成
つぎにmaltipassでubuntuVMを作成します。
上記記事を参考に今回は CPU: 2コア、ストレージ20GB、メモリ4GB で作成しました。
```
% multipass launch --cpus 2 --disk 20G --mem 4G --name ubuntu
```
これが上手くいけば下記のようになるはず、、
```
% multipass list
Name                    State             IPv4             Image
ubuntu                  Running           192.168.64.2     Ubuntu 20.04 LTS
```

最後に下記コマンドを実行したら終わりです。
```
%　multipass set client.primary-name=ubuntu
```
そしたら、下記コマンドでubuntuの設定が見れます。見れていれば完了です。
```
%　multipass exec ubuntu -- uname -a
Linux ubuntu 5.4.0-120-generic #136-Ubuntu SMP Fri Jun 10 13:46:10 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
```

拙ない説明でしたが、最後まで読んでいただきありがとうございました。より詳しい情報を知りたい方は下記URLから参考にした記事が読めますのでそちらを読んでください。
https://qiita.com/notakaos/items/928987623fc61e815363
VScode コード上で発生している問題を一覧表示してみる

## 概要

- VScodeにて開いているコードのアクティブウインドウで発生している問題を一覧表示で確認する方法を教えていただいたのでまとめる。

## ありがとうございます

- 本件は同じプロジェクトのエンジニアさんに教えていただいた知見です。
- かなり初歩的なことでしたが自分が知らなかった内容だったので記事にします。

## 発生している問題を一覧表示する方法

- 下記画像のようにVScodeはコードに問題があると赤色の下線で知らせてくれる。

    ![ContentRequest_php_—_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/399ee8c6-315b-d10f-62b8-eea409a272fd.png)

- 下線部分にマウスカーソルを持っていき、ホバーすることでエラーの内容を確認する事ができる。（これは筆者も知っていた。）

    ![スクリーンショット 2022-06-18 14.43.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/eb96b4d8-801f-5f6e-048c-98d25136e17f.png)

- ただ、これが何百行もあるファイルで複数箇所で発生したエラー箇所にマウスホバーするのは大変である。
- そこで発生している問題を一覧で確認する方法がある。
- VScodeでターミナルを開き「問題」をクリックする　。（Macの場合「command」 + 「shift」 + 「m」でもOK）

    ![ContentRequest_php_—_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/e5d5806b-6be0-85a2-210c-de34b6fa3850.png)

- 下記のように問題を一覧で表示する事ができる。

    ![ContentRequest_php_—_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/01fa9032-4d2d-3f2b-d537-e6581054bda5.png)

- ちなみにtypoなどをチェックしてくれる拡張機能の問題もこちらに表示してくれる。

    ![ContentRequest_php_—_project.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/69787cd2-ede3-f67e-f349-4e19646451bc.png)
ServiceNowでフロー変数を定義する


# ServiceNowでフロー変数を定義する(Flow Designerを利用)

分からなかったので、気づいた喜びで投稿しておきます。

下記の画面で、右端の（・・・）をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2694206/730a1b30-1694-99e9-c260-9ed35dabcdef.png)

すると、こんな感じで、『フロー変数』が選べるようになるので

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2694206/78dcb9aa-d957-8ee6-f54f-6cc3c0169ef1.png)

選ぶと、画面がポップアップされるので

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2694206/a9632e2d-5547-c68f-b6cc-89ce3d9c8bb8.png)


ここで、フロー変数を追加してあげましょう。

以上です。
laravel バリデーション sometimes

# 概要

- キーが送信された場合のみ設定されているバリデーションチェックを行う`sometimes`についてまとめる。

# 記載方法

- このバリデーションは若干filledと似ている。
    - [laravel バリデーション filled](https://qiita.com/miriwo/items/1223bb644fe65b5da5dc)
- しかし`filled`は「キーが送られた場合、空ではないこと」をバリデートしている。
- 今回の`someimes`は「キーが送られた場合、その他の設定されているバリデーションチェックを行う」というルールである。
- キーが有るときだけ 「`filled`は空でないことだけのチェックを実施」「`sometimes`は空でないことを含むその他のチェックを実施する事ができる（その他のバリデーション設定次第）」という違いのようだ。
- 下記のように記載する。（content_1のキーが送られた場合「'required', 'integer'」のチェックが行われる。）

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content_1' => ['sometimes', 'required', 'integer'],
        ];
    }
    ```

- ちなみにバリデーション`sometimes`を一番最初に指定しないと行けないわけでない。下記でも上記と同じ動作をする。

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content_1' => ['required', 'integer', 'sometimes'],
        ];
    }
    ```

- さらに、`sometimes`を用いて`filled`と同じチェックをする事ができる。（多分同じチェックになっているはず。動作的には変わらなかった。）
- `sometimes`を使用

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content_1' => ['sometimes', 'required'],
        ];
    }
    ```

- `filled`を使用

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content_1' => ['filled'],
        ];
    }
    ```
laravel バリデーション filled

# 概要

- キーが送られた場合、空ではないことをバリデートする`filled`についてまとめる。

# 記載方法

- このバリデーションルールは「キーが送られている」 & 「値が空」の場合弾く。
- 逆に「キーが送られている」 & 「値が入っている」と「キーが送られていないとき」は特にエラーを出さない。
- なので、更新系の処理などの不特定の「不特定数のキーが送られてくるが、送られたキーの必須は許したくない」ときに使える。
- 下記のように設定する。（content_1キーが送られたとき値が空ではないことをチェック）

    ```formRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'content_1' => ['filled'],
        ];
    }
    ```

# 参考文献

- [https://readouble.com/laravel/8.x/ja/validation.html#rule-filled](https://readouble.com/laravel/8.x/ja/validation.html#rule-filled)
mailtrapで'no mechanism available'が出た

Docker環境にpostfix入れてmailtrapで受けようと
メールを送ったら

```/var/log/maillog
Jun 18 04:43:33 27f83077ba22 postfix/smtp[1025]: 17DCF77C0D: 
to=<hoge@fuga.com>, relay=smtp.mailtrap.io[xx.xx.xx.xx]:2525, 
delay=471, delays=469/0.05/2.2/0, dsn=4.7.0, status=deferred 
(SASL authentication failed; 
cannot authenticate to server smtp.mailtrap.io[xx.xx.xx.xx]: 
no mechanism available)
```

と、どうにもメールが送れない・・

自分の環境的(FROM centos:7)では
```
yum -y install cyrus-sasl-plain cyrus-sasl-md5
```
とすることで解決できました。



##ちなみに・・
Docker(FROM centos:7)だとsyslogがないから、エラー追っかけ難しいので
```Dockerfile
RUN yum -y install rsyslog
```
しておくといいですね
Pandasで計算式をapplyするときに複数列を参照する

（説明不足だったのでタイトル・内容共に修正しました。）

DataFrameのある列に対して、何らかの処理をした値を新しい列に反映したいとき
applyの括弧内にlambda式を書くことがあります。

```python:sample.py
import pandas as pd

df = pd.DataFrame([
    [1,100],
    [2,200],
    [3,300],
    [4,400],
], columns=['A','B'])

df['C'] = df['A'].apply(lambda x: x + 1 if x > 2 else 0)

#   A    B  C
# 0  1  100  0
# 1  2  200  0
# 2  3  300  4
# 3  4  400  5
```
複数列の値を使って計算したい場合は、DataFrame自体にapplyすることで、
複数列を参照させることができるようになります。
```axis=1```を忘れずに!

```python:sample.py
df['D'] = df.apply(lambda row: row['A'] + row['B'] if row['A'] > 2 else 0, axis=1)

#   A    B  C    D
# 0  1  100  0    0
# 1  2  200  0    0
# 2  3  300  4  303
# 3  4  400  5  404
```