OmniAICreator/Qiita-1.07M huggingface dataset:
AtCoderログ：0084 - ABC 121 B

# 問題

https://atcoder.jp/contests/abc121/tasks/abc121_b

## 問題文
> $N$ 個のソースコードがあり、$i$ 個目のソースコードの特徴は $A_{i1},A_{i2},\ldots,A_{iM}$ の $M$ 個の整数で表されます。
> また、整数 $B_1,B_2,\ldots,B_M$ と 整数 $C$ が与えられます。
> $A_{i1}B_1+A_{i2}B_2+\ldots+A_{iM}B_M+C>0$ のときに限り、$i$ 個目のソースコードはこの問題に正答するソースコードです。
> $N$ 個のソースコードのうち、この問題に正答するソースコードの個数を求めてください。

## 制約
> ・入力は全て整数である。
> ・$1 \le N,M \le 20$
> ・$−100 \le A_{ij} \le 100$
> ・$−100 \le B_i \le 100$
> ・$−100 \le C \le 100$

## 収録されている問題セット
- [[BfB-E]\(AtCoder Problems Boot camp for beginners Easy 100\)](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) #005 

# 回答
## 回答1 (AC)
$i$ 個目のソースコードが正答しているかどうかは、その特徴 $A_{i1},A_{i2},\ldots,A_{iM}$ に対して$A_{i1}B_1+A_{i2}B_2+\ldots+A_{iM}B_M+C$ を計算し、これが正ならば正答となります。この作業を繰り返して、正答の個数を求めれば良いでしょう。ソーソコードは以下のようになりました。

```C++:abc121b-1.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n, m, c;
  cin >> n >> m >> c;
  
  vector<int> b(m);
  for ( int j=0; j<m; j++ ) {
    cin >> b.at(j);
  }

  vector<vector<int>> a(n,vector<int>(m));
  for ( int i=0; i<n; i++ ) {
    for ( int j=0; j<m; j++ ) {
      cin >> a.at(i).at(j);
    }
  }

  int sum, answer = 0;
  for ( int i=0; i<n; i++ ) {
    sum = c;
    for ( int j=0; j<m; j++ ) {
      sum += a.at(i).at(j)*b.at(j);
    }
    if ( sum>0 ) {
      answer += 1;
    }
  }
  
  cout << answer << endl;
}
```

## 回答2 (AC)
回答1を少しだけ改良します。ソースコードの特徴 $a_{ij}$ は1回しか使わないので、わざわざ配列の保持するに必要がありません。cin で読み込んだらすぐに計算することで、全体の処理をスリムにすることが出来ます。コードは以下のようになりました。

```C++:abc121b-2.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
  int n, m, c;
  cin >> n >> m >> c;
  
  vector<int> b(m);
  for ( int j=0; j<m; j++ ) {
    cin >> b.at(j);
  }

  int a, answer = 0;
  for ( int i=0; i<n; i++ ) {
    int sum = c;
    for ( int j=0; j<m; j++ ) {
      cin >> a;
      sum += a*b.at(j);
    }
    if ( sum>0 ) {
      answer += 1;
    }
  }
  
  cout << answer << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc121/tasks/abc121_b/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/abc121/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0083 - ABC 112 C](https://qiita.com/RoadLynton/items/f224d731b109d83dda00)
- 次の記事 → [AtCoderログ：0085 - ABC 049 C](https://qiita.com/RoadLynton/items/41948daf753fd82b878a)
SSHで接続できない場合の対処方法

LinuxをさくらのVPSで立ち上げようとしていた際に、何度もOSの再インストールをしたところ、SSH接続時に下記のようなエラーが出ました。

OSはMac、ターミナルにて。

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Please contact your system administrator.
Add correct host key in /Users/myusername/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /Users/myusername/.ssh/known_hosts:1
ECDSA host key for xxx.xxx.xxx.xxx has changed and you have requested strict checking.
Host key verification failed.
```

このエラーが出た場合には ssh-keygen コマンドでいったん情報を消して、再度接続してみてください。

```
$ ssh-keygen -R xxx.xxx.xxx.xxx
```

これでSSH接続が普通にできるようになります。
AtCoderログ：0083 - ABC 112 C

# 問題

https://atcoder.jp/contests/abc112/tasks/abc112_c

## 問題文
> 古代すぬけ国では, AtCoder 社長「高橋君」の権威を高めるために, ピラミッドが建てられていた.
> ピラミッドには 中心座標 $(C_X,C_Y)$ と 高さ $H$ が定まっており, 座標 $(X,Y)$ の高度は ${\rm max}(H−|X−C_X|−|Y−C_Y|,0)$ であった.
> 探検家の青木君は, このピラミッドの中心座標と高さを求めるために調査を行った. その結果, 次のような情報が得られた.
> ・$C_X,C_Y$ は $0$ 以上 $100$ 以下の整数で, $H$ は $1$ 以上の整数であった.
> ・上記と別に $N$ 個の情報が得られた. そのうち $i$ 個目の情報は, 「座標 
$(x_i,y_i)$ の高度は $h_i$ である」
> この情報は, ピラミッドの中心座標と高さを特定するのに十分であった. 情報を手掛かりに, これらの値を求めなさい.

## 制約
> ・$N$ は $1$ 以上 $100$ 以下の整数
> ・$x_i,y_i$ は $0$ 以上 $100$ 以下の整数
> ・$h_i$ は $0$ 以上 $10^9$ 以下の整数
> ・$N$ 個の座標 $(x_1,y_1),(x_2,y_2),(x_3,y_3),\ldots,(x_N,y_N)$ はすべて異なる
> ・ピラミッドの中心座標と高さをちょうど $1$ つに特定することができる

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067) ([第08問類題](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-8-%E5%95%8F--abc-085-c---otoshidama-300-%E7%82%B9))

# 回答
## 回答1 (AC)
ピラミッドの中心座標 $(C_X,C_Y)$ とヒントの個数 $N$ はすべて $1$ 以上 $100$ 以下なので、各 $(C_X,C_Y)$ に対し $N$ 個のヒントが当てはまるかどうかをチェックしていくことで解を求められそうです。

問題はピラミッドの高さ $H$ です。あいにく高さは $0 \le H \le 10^9$ となっているため、全検索は不可能です。そこで $H$ は計算で求める必要があります。問題文で $H$ を使っているのは、高度を求める式 ${\rm max}(H−|X−C_X|−|Y−C_Y|,0)$ だけです。座標 $(x_i,y_i)$ の高度 $h_i$ は $h_i={\rm max}(H−|x_i−C_X|−|y_i−C_Y|,0)$ によって求められるので、$h_i > 0$ ならば $h_i=H−|x_i−C_X|−|y_i−C_Y|$ となり、$C_X,C_y,x_i,y_i,h_i$ から $H$ を求めることができます。ただし、$h_i>0$ となっている $i$ を事前に見つけておく必要があります。

以上の考察をまとめたコードは以下のようになりました。繰返し回数は $C_X C_Y N \le 10^6$ なので、十分処理可能です。

```C++:abc057c-1.cpp
#include <bits/stdc++.h>
using namespace std;

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

  int index;
  vector<int> x(n), y(n), h(n);
  for ( int i=0; i<n; i++ ) {
    cin >> x.at(i) >> y.at(i) >> h.at(i);
    if ( h.at(i)!=0 ) {
      index = i;
    }
  }
  
  for ( int cx=0; cx<=100; cx++ ) {
    for ( int cy=0; cy<=100; cy++ ) {
      int ch = h.at(index)+abs(x.at(index)-cx)+abs(y.at(index)-cy);
      for (int i=0; i<n; i++ ) {
        if ( max(ch-abs(x.at(i)-cx)-abs(y.at(i)-cy),0)!=h.at(i) ) {
          break;
        }
        if ( i==n-1 ) {
          cout << cx << ' ' << cy << ' ' << ch << endl;
        }
      }
    }
  }
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc112/tasks/abc112_c/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2018/10/06/233650)
回答1と同じ方針でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc112/tasks/abc112_c/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/abc112/editorial.pdf)
回答1と同じ方針でした。$h_i > 0$ となる $i$ が存在することが指摘されていました。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0082 - 214 C](https://qiita.com/RoadLynton/items/96771109d3be9993587d)
JavaScriptを基本からまとめてみた【12】【関数( function )】

##はじめに

####学習するに至った経緯

2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、卒業後、フロントエンドのエンジニアを目指す事に。
Javascriptの学習した事を言語化し、認識の深化による備忘録として記載。

##JavaScriptにおける関数（function）とは
『関数』とは、複数の処理をひとまとまりにしたもの。メソッドと呼ばれることもある。JavaScriptにおける基本的な構成要素のひとつであり、Function型のオブジェクトとして扱われ、関数をオブジェクトとして扱うことが出来るのはJavaScript特有の特徴。

##関数を使うメリット
関数を利用することで目的ごとに処理を分割したり、似たような処理を何度も書かなくて済むようになる。全ての処理を関数を使わずに書いた場合と、関数を使って書いた場合とではコードの文量が何倍にも変わる。場合によっては何倍どころか何十倍、何百倍になることもある。

##関数を定義する
####① 関数宣言で関数を定義する

もっとも代表的な関数定義の方法として『関数宣言』がある。 
関数宣言は 『function 関数名(引数) { 処理 } 』という記法で関数を定義する。

```main.js
/** 引数で指定した名前に挨拶をする文字列を返す関数 */
function hello1(name) {
  let message = "Hello, " + name
  return message
}
```
#####※ 宣言の中にある『引数』とは関数に渡して処理の中でその値を使うことができるもの。

ここでは、hello1関数の引数に変数nameが指定されており、その変数nameは関数の処理の中で「Hello, ◯◯◯（引数で指定した名前）」という文字列を返却するように組み込まれている。同じような仕組みの処理を何度も必要とするときに引数を利用すれば、引数の値を変えるだけで同じ仕組みで算出された別の値を何個も取得できるようになる。

また、値や文字列などを関数の外に返却（出力）する処理は、上記コード中にもあるように return 返却値 という記法で書く。
#####※return文は書かなくても問題ないが、その場合その関数は値を何も返却しない関数になる。

####② 関数式で関数を定義する
JavaScriptにおいて関数はfunction型のオブジェクトで、そのため、関数は式として変数に渡すことも出来る。式として関数を作成する記法を、関数式と呼ぶ。

```main.js
/** 引数で指定した名前に挨拶をする文字列を返す関数 */
let hello2 = function(name) {
  let message = "Hello, " + name
  return message
}
```
このように let 変数名 = function(引数) { 処理 } という記法で変数名の関数を作成できる。上記コードでは、hello2という名前の変数が関数になっている。

####③　アロー関数式で関数を定義する
アロー関数式とは、ECMAScript 2015（ES2015）という2015年に公開されたJavaScriptの新しい標準に含まれる記法で、従来の関数式のいくつかの要素を省略し、その他の細かな挙動を調整した式。

```main.js
/** 引数で指定した名前に挨拶をする文字列を返す関数 */
let hello3 = name => {
  let message = "Hello, " + name
  return message
}
```
関数式では式の右辺は function(引数) { 処理 } という記法で書かれていたが、アロー関数式ではこの記法のうち function や、引数を囲む括弧などが省略されている。
#####※ただし引数が複数ある場合にはこの括弧は省略出来ない。

また、関数の処理を囲んでいる波括弧ですが、これについても『波括弧内の処理が一行である』という条件を満たせば省略が可能。この条件を満たし波括弧を省略した場合、関数が値を返却するreturn文の『return』も省略が可能。

##関数の呼び出し方
関数を呼び出すには 関数名(引数として渡す値) という記法で書く。

```main.js
// 関数の定義
function hello1(name) {
  let message = "Hello, " + name
  return message
}
// 関数の呼び出し
let result1 = hello1("yamada")
// コンソールへ結果を出力
console.log(result1) 
```
実行結果

```
Hello, yamada
```

上記コードでは関数を呼び出した式を左辺の変数result1に格納していますが、この変数にはhello1関数を呼び出した実行結果が設定されている。
#####※ 実行結果とは、前項で説明したreturn文で返却した値のこと。
また、引数の存在しない関数を呼び出す場合ですが、その場合は呼び出す際にも引数を設定する必要はない。


##参考サイト
[JavaScriptのfunctionを基本から解説]
(https://techplay.jp/column/568)
【Dart/Flutter】Shift-JISでストレージにファイルを出力

#何を解決する記事か？
Dart/Flutter開発において、日本語文字列をShift-JISでエンコードしてテキストファイルを出力する方法を記載します。
（標準ではおそらく対処できず、一工夫します。）
#結論
charset_converterライブラリ  を使用して、下記のように処理します。

```dart
final encoded = await CharsetConverter.encode("Shift_JIS", contents); //encoding
await File(filePath).writeAsBytes(encoded); //save
```
contentsは書き込む本文、filePathは保存するパスです。いずれもString型です。

通常、テキストファイルの出力はFile.writeAsString関数を使用しますが、ここではライブラリを使用してバイト配列にエンコードした上でファイルに書き込みしているところがポイントです。
#背景
Flutter開発において、テキストファイル（txt,csv等）をストレージに出力したいという場面はあるかと思います。
ところが、Dart SDKに含まれるdart:ioでは、日本語を表現できるフォントはutf8以外に現状選択肢がないようです。

内部処理に使うなら良いのですが、ファイルのメール送信やアップロード等するとなると、utf8では文字化けする場合が結構あります。
今回、何とかShift-JISで出力しようとして色々試した結果、うまくいった方法があったので共有しておきました。

#参考
環境等。
- Dart SDK version: 2.13.3 (stable)
- Flutter 2.2.2
- charset_converter 2.0.0 https://pub.dev/packages/charset_converter
【Ruby on Rails】他テーブルのカラムも検索して表示する方法


#対象者

* 他のモデルのカラムまで検索をする方法を考えている方

#目的

* 他モデルのカラムを検索してViewに表示する

#実際の手順と実例
###1.前提

下記を元に実装しています

https://qiita.com/nao0725/items/1dbe59c63419179d1818

* ここでは記事のタグ名を検索します。
* Article、Tag、ArticleTagの３つのモデルを使用
* ArticleTagを中間テーブルとして実装しています。
* tag_nameカラムをTagテーブルで確認します。



###2.joinsメソッドを使用

**joins**メソッドとはテーブル同士を内部結合して検索するためのメソッドです。

これを元に検索メソッドを使用すると

```article.rb
 def self.search(search_word)
  Article.joins(:tags)#①
         .where(["title LIKE(?) OR body LIKE(?) OR sub_title LIKE(?) OR tag_name LIKE(?)",
             "%#{search_word}%", "%#{search_word}%", "%#{search_word}%", "%#{search_word}%"]).distinct#②
 end
```

①でjoinsを使ってtagsテーブルを結合し、tag_nameを検索できるようにしました。

②distinctは記事の重複を割ける（重複するものがあれば一つにしてくれる）メソッドです。


これで実装完了です！



#参照

>[【Rails入門】joinsの使い方まとめ](https://www.sejuku.net/blog/26522)
> [【SQL入門】DISTINCTで重複行をまとめる方法をわかりやすく解説](https://www.sejuku.net/blog/54990)

####投稿者コメント
初めてjoinsというものを使ったのでメモしておきます。
これで検索の幅が広がると思います！

####My Profile
プログラミング学習歴３ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。
Databricksランタイム9.0のGA、dbutils.data.summarizeのサポート

[Databricks Runtime 9\.0 and Databricks Runtime 9\.0 Photon \| Databricks on AWS](https://docs.databricks.com/release-notes/runtime/9.0.html#new-api-for-summary-statistics-of-datasets-public-preview)にあるように、今回のランタイムでは新たなユーティリティコマンド`dbutils.data.summarize`がサポートされました(パブリックプレビュー)。pandasデータフレーム、Sparkデータフレームのサマリー統計を簡単に確認することができます。

[Databricks Utilities \| Databricks on AWS](https://docs.databricks.com/dev-tools/databricks-utils.html#data-utility-dbutilsdata)

```py:Python
df = spark.read.format('csv').load(
  '/databricks-datasets/Rdatasets/data-001/csv/ggplot2/diamonds.csv',
  header=True,
  inferSchema=True
)
dbutils.data.summarize(df)
```

```scala:Scala
val df = spark.read.format("csv")
  .option("inferSchema", "true")
  .option("header", "true")
  .load("/databricks-datasets/Rdatasets/data-001/csv/ggplot2/diamonds.csv")
dbutils.data.summarize(df)
```

このように各カラムのデータ分布、欠損値の割合などを簡単に確認できます。
![Screen Shot 2021-08-19 at 8.40.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7a6581ca-d583-257a-7288-f0bb0a2e728e.png)


### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
UiPath Orchestrator のユーザー ライセンスの管理方法が変更された件(備忘メモ)

こんにちは。[UiPath Friendsコミュニティ](https://uipath-friends.doorkeeper.jp/)運営メンバの @masatomix です。


今回は備忘メモです。[ユーザー ライセンスの管理(公式)](https://docs.uipath.com/automation-cloud/lang-ja/docs/user-license-management) に書かれている、

:::note
ユーザー ライセンス管理は、2021 年 3 月 1 日より後に作成されたすべての組織に対して既定で有効になります。
:::

って書いてある「**ユーザー ライセンスの管理**」について。
有効になっている状態と、そうでない状態の違いを見くらべてみました。

あ、今回の環境は**クラウドの Orchestrator (バージョン 21.x.x Enterprise/Community)** です。

### 有効か、無効か

状態はヒトによるというかサインアップをしたタイミングによるっぽくて、[UiPath Automation Cloud](https://cloud.uipath.com/) の 管理 >> 組織設定 が下記のようになっていれば「**有効**」状態なようですね。

![kanri](https://imgur.com/t3iHSww.png)


**新しい管理方法を有効化するか無効化するか、このボタンで制御**できます。押すと「ココが変わるよ」的なアラートも出ますので、大事な環境では慎重に作業しましょう。

![alert](https://imgur.com/GBiAp6s.png)

> さらには**「2021 年 3 月 1 日より後に作成されたすべての組織」はたぶんこの項目自体がなくて、有効**状態っぽい。
> それ以前に作成した組織が、デフォルトでは無効になってそうですね。
>
> さらにさらに環境によっては (すごく昔に作ったヤツ？) は**項目がなくても無効になっているものも**ありそう。



### 有効状態だと

先の公式の情報をみると、今後こちらの方式に移行していく雰囲気ですね。

さて、有効状態だと、[UiPath Automation Cloud](https://cloud.uipath.com/)  の

- 管理 >> ユーザーとグループ >> グループ >> グループ割り当てルールを編集
- 管理 >> ユーザーとグループ >> ユーザー >> ライセンスの割り当てを編集

を選択してでてくる画面で、(下記サンプルはグループのばあい)

![on_group0](https://imgur.com/FIcE1Qe.png)

このように、ユーザやグループに対して、**利用可能なライセンスを選択できる**ようになります。

![on_group](https://imgur.com/VuHrHmk.png)

そのかわり、既存の Orchestrator >> テナント >> アクセス権を管理 >> ロールを割り当て の画面から、**ライセンスの種類を選ぶ機能がなくなって**います。

![on_oc_group](https://imgur.com/mtfOFv7.png)



### 無効状態だと

逆に無効状態だと、先のAutomation Cloudの画面からライセンス管理系の機能がなくなり、![off_group](https://imgur.com/1Lc1l3q.png)

かわりに Orchestrator >> テナント >> アクセス権を管理 >> ロールを割り当て の画面から、**ライセンスの種類を選ぶ機能が表示され**ました。
![off_oc_group](https://imgur.com/X3bTN5A.png)

### まとめ

新しいライセンス管理ってのはこのように**ライセンスを割り当てるところがAutomation Cloudの画面に移った**、ってことのようですね。 [UiPath Orchestrator のバージョンその他による挙動の違いにぐったりきたので整理(用語集) ](https://qiita.com/masatomix/items/48a6cd104be52c53a618) したのですが、さらにこれによる挙動の違いもあったので備忘で書いておきました。


お疲れさまでしたー。

### 関連リンク

- [公式](https://docs.uipath.com/automation-cloud/lang-ja/docs/user-license-management)
- [ちょっとまえにこの変更に出会ったときのつぶやき](https://twitter.com/masatomix/status/1419512901019193346)
- [権限管理ーユーザー設定編【UiPath Orchestratorをもっとよく知る動画シリーズ】#10](https://www.youtube.com/watch?v=fh0NWVqvsbk&t=0s) 公式。まだ無効状態の環境で説明しているぽい。
Twilio Functions で HTTP Headers を取得する

:::note alert
2023年5月1日を持ちまして、株式会社KDDIウェブコミュニケーションズのTwilioリセール事業が終了したため、本記事に記載されている内容は正確ではないことを予めご了承ください。
:::

# はじめに

みなさん、こんにちは。
KDDIウェブコミュニケーションズの Twilioエバンジェリストの高橋です。

今回は、Twilio Functions で HTTP Headers を取得する方法を解説します。従来、Functions ではヘッダー情報を取得することができず、例えばLINEのMessaging APIをセキュアに扱うことができなかったり、なにかと不便でした。
今回、ベータ版ではあるものの、ヘッダー情報が取得できるようになったとのことで早速試してみました。
https://www.twilio.com/docs/runtime/functions/headers-and-cookies

**<font color='red'>重要</font>**
本機能は現時点（2021/8/19）ではベータ版のため、サポートの対象外となります。また、今後のバージョンアップで機能が変更になることもあります。

## 準備

### 管理コンソールを利用する

Twilio Functions を管理コンソールから利用する場合は以下の手順でセットアップを行います。

- 管理コンソールにログインします。
- Functionsに移動します。
- 新しいサービスを作るか、既存のサービスを選択します。
- **Settings** > **Dependencies** を選択します。
- **MODULE** 欄に「@twilio/runtime-handler」、**VERSION**に「1.2.0-rc.3」と入力します。
![スクリーンショット 2021-08-19 7.34.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/ebd2091c-8e4f-c579-78c0-8bc23d411a98.png)

- **Add** ボタンを押します。

### Serverlessを利用する

**<font color='red'>重要</font>**
Node.jsのバージョンが12.22.1以上でないとローカル実行ではエラーになります。

- 以下のコマンドでモジュールをインストールします。

`npm i -S @twilio/runtime-handler@1.2.0-rc.3`

- `package.json`に、`"@twilio/runtime-handler": "^1.2.0-rc.3",`ができていることを確認します。
- このままだとデプロイ時にエラーがでるため、上記の行を以下のように編集しておきます。
- `"@twilio/runtime-handler": "1.2.0-rc.3",` （バージョンの^を削除）

## コーディング

ヘッダを取得するためのコードは以下のとおりです。

```javascript:Functions
  // Get headers
  const testHeader = event.request.headers['test-header'] || '';
  console.log(`test-header: ${testHeader}`);
```

この例では、`test-header`というヘッダー値を取得しています。実際のヘッダーが大文字になっていても取得できます。

管理コンソール上で作成したサンプルコードは以下のようになります。
![スクリーンショット 2021-08-19 7.33.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/a6114b73-58f7-bf39-df0d-55b92d305f03.png)

## テスト

作成したコードをデプロイして、早速テストをしてみましょう。
今回はヘッダー情報を送るために、[Postman](https://www.postman.com/)を利用したいと思います。

- メソッドに「POST」を選択します（GETでもOKです）。
- デプロイした Functions のパスを指定します。
- headersの**KEY**に`test-header`を定義し、**VALUE**に`test`を入れておきます。
- **Send**します。

![FunctionsHeaders.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/bb4a2420-6b03-0046-a076-9b99111bc571.png)

上記のように、VALUEとして指定したtestが戻ってくればテストは成功です。

# まとめ

Functionsでヘッダー情報を取得したいというニーズは以前より多く寄せられていたものなので、今回それが実現したことで、よりFunctionsの使いみちが増えたと思います。
なお、この記事では触れていませんが、ヘッダー同様にCookies情報も取得できるようになっています。

~~現時点では、Serverless でローカル実行したときはうまく動かなかったりするのですが、とりあえずサーバー上での動作は確認できているので、ぜひ活用していきたいと思います。~~
（追記）`1.2.0-rc.3`では、Node.jsのバージョンを12.22.1以上にすることでエラーは解消されています。

---
### Twilio（トゥイリオ）とは

https://cloudapi.kddi-web.com
Twilio は音声通話、メッセージング（SMS /チャット）、ビデオなどの 様々なコミュニケーション手段をアプリケーションやビジネスへ容易に組み込むことのできるクラウド API サービスです。初期費用不要な従量課金制で、各種開発言語に対応しているため、多くのハッカソンイベントやスタートアップなどにも、ご利用いただいております。

自己紹介|　
:--|:--
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86046/b51a8b88-abd5-ce5e-195a-de3564ba2ae6.png" height='200' width='150'/>|高橋克己（Katsumi Takahashi） 自称「<font color='red'>赤い芸人</font>」<br />グローバル・インターネット・ジャパン株式会社　代表取締役<br />株式会社KDDIウェブコミュニケーションズ　Twilio事業部エバンジェリスト<br /><br />2001年より大手通信事業者の法人サービスの教育に携わり、企業における電話のしくみや重要性を研究。2016年よりTwilio事業部にジョインし、Twilioを使ったスマートコミュニケーションの普及活動を精力的に行っている。<br />2015 Hall of Doers<br />2019 Twilio Champions
Swift スタックを理解する

スタックとは
--
LIFOを実装した構造体のことくをいう。一番最後にいれたものが一番先にでる（逆がFIFOであるキュー）

スタックの３つの機能
１,pop スタックの一番上にあるデータを先に出す
2,push　スタックの一番上にデータを入れる
3,peek　スタックの一番上にあるデータを読み取る


```swift:お魚.swift

 //swift
public struct Stack<T> {
    
  　 var array = [T]()

  //中身が空かどうか調べる。
  public var isEmpty: Bool {
    return array.isEmpty
  }

  //スタックの一番上にプッシュする。　構造体を変更するのでmutating　が必要
  public mutating func push(_ element: T) {
    array.append(element)
  }

  //スタックの一番上を取り出す。　構造体を変更するのでmutatingが必要
  public mutating func pop() -> T? {
    return array.popLast()
  }

  //スタックの一番上にあるデータを読み取る。
  public var peek: T? {
    return array.last
  }
}

//スタック構造を利用して配列を逆に返す
　func reverse(arr:[String])->[String]{
   var stack = Stack(array:[]);
   for i in 0..<arr.count {
    stack.push(arr[i])
  }
    //下記、配列の数だけ繰り返し処理してreversedに入れていく処理
    var reversed:[String] = [];//reverse用のからの配列を設定
    while(stack.peek() != nil { //nilではない限りはループ処理させる
        reversed.push(stack.pop());//スタックの最後の要素をプッシュしていく
    }
    return reversed;
}

// スタックを作成する
var stackOfFish = Stack(array: ["🐟", "🐠", "🐡", "🐳","🐬"])


// サメさんを末尾にプッシュする 
stackOfFish.push("🦈")

//サメさんを末尾から取り出す
stackOfFish.pop()

//イルカさんが読み取れる
stackOfFish.peer

```
Apexトリガーが重複して起動する


やっぱり結論はApexトリガーの他に自動化処理があったようです。
ここでも混ぜると危険だなぁって思います。

https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000BrMgeSAF

[トリガと実行の順序](https://developer.salesforce.com/docs/atlas.ja-jp.232.0.apexcode.meta/apexcode/apex_triggers_order_of_execution.htm)
STM32G031で温度,S-5851Aをシリアル出力


x シリアルを使うから上級者用
x SWD-CLKをシリアルと共有する
x Bootと共有する為、注意
x すごくシンプル

1.SCLとSDAを接続、プルアップも忘れずに
2.電源の接続
3.下記のソースコードを書き込む
4.コンパイル実行で表示されたら終了
5.おわり


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7509eff1-6d2d-24ce-b96b-d4c5a0e2301f.png)


![h_con8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/2e43bf03-2375-9177-72f5-0562b6aa427c.jpeg)


![h_con9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/27948146-1a76-651b-d236-1ee95a0db030.jpeg)



```c++

#include <Wire.h>

//STM32G031J6M6 i2cピンの定義
#define sdaPin PA12    // ArduinoA4
#define sclPin PA11    // ArduinoA5

#define S5851A 0x48

int     tempval;                //温度
char    data_read[3];           //バッファー

//文字列の表示
int pc_printf(char *str1) {

    //文字の中身がゼロか
    while(*str1){

        //一文字出力
        //pc_putc(*str1 ++);
        Serial.print( *str1 ++ ); //uno

    } //while

    //戻り値
    return(0);
}//pc_printf

//初期化
void setup()
{
  delay(3000); //not delete

  Wire.begin(sdaPin,sclPin); //STM32G031J6M6

  Serial.begin(9600);

} //setup


//メインループ
void loop()
{

  //0番目のレジスター
  Wire.beginTransmission(S5851A);
  Wire.write(0);
  Wire.endTransmission();
  delay(1);

//  //温度の読み込み
  tempval = 99;
  Wire.requestFrom(S5851A, 1);
  while(Wire.available())  {    // 要求より短いデータが来る可能性あり
    tempval = (int)Wire.read(); // 1バイトを受信
  }//while
  delay(1);

  //tempval=12; //debug

  //表示
  data_read[0] = '0' + (tempval / 10);
  data_read[1] = '0' + (tempval % 10);
  data_read[2] = 0;
  pc_printf( data_read );
  pc_printf( "\r\n" );

  delay(1000); //1秒待つ

} //loop



```
M1 Mac vs Intel Mac のビルド速度対決

ほぼほぼスケルトン状態のiOSアプリをビルド。

![写真 2021-08-18 14 14 48.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/5fe77f18-a209-e2ff-2f63-c38961dc1570.jpeg)
２１秒９６

![写真 2021-08-18 14 15 50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/09a90fd0-8cd5-cd43-907f-f41cf18b4623.jpeg)
１秒１５、、、

勝負になっとらんがな🤣🤣🤣
Flutter調べ備忘録

## この記事は？
Flutter調べたことメモ。
全体像の俯瞰用にシンプルにまとめ。
（気が向いたら随時更新）

## 記載範囲は？
- 言語の特徴
- UIに関して
- アーキテクチャ
- メリデメ

## 言語の特徴
### dart
- オブジェクト指向
- 静的型付け

JAVAライク。

## UIに関して
### 大きく2種類
#### material
Android、MaterialDesignのUI。
[Material Components widgets](https://flutter.dev/docs/development/ui/widgets/material)

![スクリーンショット 2021-08-19 043125.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/220a2fee-92cf-494c-a920-6ffe379634d5.png)

#### Cupertino
iOSなUI。　iOSでよく見るUI部品は大体ある。
[Cupertino (iOS-style) widgets](https://flutter.dev/docs/development/ui/widgets/cupertino)

![スクリーンショット 2021-08-19 043200.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/31870505-930a-7a74-f88a-7d94ba2c92eb.png)


###　Widget分類
- StatelessWidget
- StatefullWidget
- InheritedWidget
- RenderObjectWidget

(工事中)
参考
[InheritedWidget/InheritedModelとは何か](https://qiita.com/ko2ic/items/d7b744f19f213ef1e647)

## アーキテクチャ
### Provider
主流。[Document](https://pub.dev/packages/provider)には以下記載

> - simplified allocation/disposal of resources
- lazy-loading
- a largely reduced boilerplate over making a new class every time
- devtools friendly
- a common way to consume these InheritedWidgets (See Provider.of/Consumer/Selector)
- increased scalability for classes with a listening mechanism that grows exponentially in complexity (such as ChangeNotifier, which is O(N²) for dispatching notifications).


### BLoC(Business Logic Component)

```
制約

1 インプットとアウトプットは、単純なStreamとSinkに限定する。

2 依存性は、必ず注入可能でプラットフォームに依存しないものとする。

3 プラットフォームごとの条件分岐は、許可しない。

上記の制約を守れば、どのような実装でも構わない。
ただし、reactive programmingを推奨したい。
```
以下から引用、日本語記事は以下がわかりやすい
[BLoCパターンとはなにか - FlutterとAngularの間でModelのコードを再利用する実践を通じての考察](https://ntaoo.hatenablog.com/entry/2018/10/08/072933)

他参考サイト
[【Dart/Flutter】導入したBLoCパターンアーキテクチャについて全体像をまとめてみた](https://qiita.com/arthur_foreign/items/4b1bf1892439780c4690)


### メリデメ
#### メリット
- ビルドキャッシュ機能がAndroidStudioより高性能(HotLoad)
- 公式ドキュメントがシンプルで充実
- 以下実例 (2次情報)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">GooglePayがFlutter採用してこの辺りの実例は覚えておくと役立ちそう。<br>・170万行→110万行に<br>・技術的負債が90%減<br>・エンジニアの生産性が20%向上</p>&mdash; coka @Flutterライフ (@coka__01) <a href="https://twitter.com/coka__01/status/1368076317711724546?ref_src=twsrc%5Etfw">March 6, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#### デメリット
- カメラ周辺はバグが多いらしい
- 新しめの技術はNative一択
   - AR
   - 機械学習

## 終わり
果たして、工事中は工事されるのか。。
Windows WSL(Subsystem for Linux)で使い捨てのUbuntuをポコポコ作る

WSLでUbuntuなどを立ち上げてサーバの開発するのほんと便利です。Ubuntuにコードを置きながらWindowsのVisual Studio Codeでコードを編集しコマンドの実行はTerminalから行えて、ローカルに立てた鯖にはWindowsのChromeで確認できる。

でもこれだとMacでいいじゃんって事になるのだけど、WSLはLinuxのインスタンスをいくつでも立ち上げられるのだ。プロジェクトごとにUbuntuを立ち上げてそれ用の環境を構築して作業ができる。素敵じゃない。その方法を簡単に書きます。

WSL2でUbuntu-20.04がインストールされた状態から始めます。ユーザー名は ```ubuntu``` です。ターミナルはWindows Terminalを使います。WSL2を有効にする方法などはぐぐってください。

まずはUbuntuがインストールされているか確認。

```shell-session
PS C:\Users\akira> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         2
PS C:\Users\akira>
```

Ubuntu-20.04が入ってます。

Ubuntu-20.04のイメージを保存して、そのイメージを使って新しくUbuntuをインストールするという流れになるので、その作業場所としてWindows側のユーザーディレクトリの下に ```wsl``` ディレクトリを作って移動します。

```shell-session
PS C:\Users\akira> mkdir c:\Users\akira\wsl

    ディレクトリ: C:\Users\akira

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2021/08/18     10:23                wsl

PS C:\Users\akira> cd c:\Users\akira\wsl
PS C:\Users\akira\wsl>
```

既にインストールされているUbuntuからイメージファイルを作ります。

```shell-session
PS C:\Users\akira\wsl> wsl --export Ubuntu-20.04 Ubuntu-20.04.tar
PS C:\Users\akira\wsl> ls

    ディレクトリ: C:\Users\akira\wsl

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2021/08/18     10:31     1082163200 Ubuntu-20.04.tar
```

```Ubuntu-20.04.tar``` が作成されました。 ```Ubuntu-20.04.tar``` から ```Project1``` という名前の新しいインスタンスを作ります。

```wsl --import <インスタンス名> <インストール先のパス> <イメージファイルパス>``` となります。

```shell-session
PS C:\Users\akira\wsl> wsl --import Project1 Project1 Ubuntu-20.04.tar
```

```C:\Users\akira\wsl\Project1``` にインストールされました。wslで確認してみます。

```shell-session
PS C:\Users\akira\wsl> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         2
  Project1        Stopped         2
```

```Project1``` ができてますね。最後にWindows Terminalの設定を少しします。設定画面を開きます。

![2021-08-18_10h36_07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/b5bdd57f-c667-54f7-a004-60e52d4dc166.jpeg)

```Project1``` を開き、コマンドラインには起動ユーザーの ```-u ubuntu``` を追加し、~~ディレクトリの開始にはユーザーホームの //wsl$/Project1/home/ubuntu に変更します。~~ （この設定は効かなくなったようです）


![2021-08-18_10h51_10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33704/65b1f7e3-5e73-1ced-a1c4-9daf9f90e46c.jpeg)

削除するコマンド

```shell-session
PS C:\Users\akira\wsl> wsl --unregister Project1
```

おしまい。
AWS CloudFormationからConfig適合パックをデプロイする

AWSのConfig適合パックを、ConfigではなくCloudFormationからデプロイする方法です。

## テンプレートの書き方

CloudFormationテンプレートは、例えば次のように書きます。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  MyConformancePack:
    Type: AWS::Config::ConformancePack
    Properties:
      ConformancePackName: my-conformance-pack
      TemplateBody: |-
        <Config適合パックのテンプレート>
```

ここで、`<Config適合パックのテンプレート>` は、デプロイしたい適合パックのテンプレートに置き換えます。例えば、次のようにします。

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  MyConformancePack:
    Type: AWS::Config::ConformancePack
    Properties:
      ConformancePackName: my-conformance-pack
      TemplateBody: |-
        Resources:
          EipAttached:
            Properties:
              ConfigRuleName: eip-attached
              Scope:
                ComplianceResourceTypes:
                - AWS::EC2::EIP
              Source:
                Owner: AWS
                SourceIdentifier: EIP_ATTACHED
            Type: AWS::Config::ConfigRule
          Ec2SecurityGroupAttachedToEni:
            Properties:
              ConfigRuleName: ec2-security-group-attached-to-eni
              Scope:
                ComplianceResourceTypes:
                - AWS::EC2::SecurityGroup
              Source:
                Owner: AWS
                SourceIdentifier: EC2_SECURITY_GROUP_ATTACHED_TO_ENI
            Type: AWS::Config::ConfigRule
          Ec2VolumeInuseCheck:
            Properties:
              ConfigRuleName: ec2-volume-inuse-check
              Scope:
                ComplianceResourceTypes:
                - AWS::EC2::Volume
              Source:
                Owner: AWS
                SourceIdentifier: EC2_VOLUME_INUSE_CHECK
            Type: AWS::Config::ConfigRule
```

また、Config適合パックを `TemplateBody` に直書きせず、次のようにS3に保存したConfig適合パックを指定することもできるようです。（動作未確認）

```yaml
AWSTemplateFormatVersion: 2010-09-09
Resources:
  MyConformancePack:
    Type: AWS::Config::ConformancePack
    Properties:
      ConformancePackName: my-conformance-pack
      TemplateS3Uri: s3://bucketname/prefix
```

詳細は [AWS::Config::OrganizationConformancePack - AWS CloudFormation](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-config-organizationconformancepack.html) をご覧ください。

## 参考動画

下記の動画はとても参考になりました。本記事で取り上げなかった、パラメーターの受け渡しについても説明されています。

 <iframe width="560" height="315" src="https://www.youtube.com/embed/baA5eN5zyrg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## YAMLのパイプとハイフン `|-` って？

[YAML Multiline Strings](https://yaml-multiline.info/) に記載がありました。

パイプは複数行の文字列を扱うための記号で、直後のハイフンは文字列の最後の改行を消す記号だそうです。ハイフンはなくても動くと思いますが、本記事では参考動画に合わせた記述にしました。
Power Appsとは？

皆さんは、PowerAppsはご存じですか？
PowerAppsとはマイクロソフトが提供してる、「Power Platform」の一つで業務アプリケーション開発のプラットフォームになります。

■■■
■■
■


*特徴
１、直感的な操作で画面が作成でき、プログラミング無しで簡単にPCやスマホで使える業務のアプリケーションを作成できる
　　→開発に長い期間をかけたり、コストをかけることなく作成ができます。また、プログラムを組むことなく作成できるので習得の時間も短縮できます。

２、office365(利用可能なバージョンに限ります)があれば誰でも無料で使え簡単に作成することができます。
　　→作成はWeb画面から行うので、特にほかのものをインストールするなどは必要ないです。

３、自由なUIで使いやすく
　　→自由に簡単な使いやすい画面を自分で作成できます。操作方法は簡単で起きたい素材を反映すれば、PowerPointのように移動などができます。

４、いろんなデータと接続して使いやすく。
　　→OneDriveに置いたExcelやCSVファイル、SharePointリスト、PowerAutomate、各種いろんなDBなどと接続をして利用することも可能です。

■■■
■■
■

*PowerAppsを使うには
Office365の画面からPowerApps を開いたらいきなり画面が出てきて作成ではなく、まずは何で作成するかといった形で作成するかを決めていきます。


１、キャンパスアプリ
　　→デザイン性に優れていて、操作感覚を優先して自分や周りが使いやすいものを利用することが可能なのが一番の特徴だと思います。

２、モデル駆動型アプリ
　　→業務の流れや膨大なデータを可視化するなどといった表現に強いUIになる、キャンバスアプリよりデザインに自由がないイメージになります・・・表現が難しいですがもとからあるデータと連動するような形で自動で画面が出来上がるので私は祖プ感じるのかもしれません。また、標準でPC、タブレット、スマホすべてに最適な形で利用することが可能です。（上のキャンパスアプリでもデータ連動で自動で作成ができますがあくまで、自分で一から作成ができ自由度があると思うと少し考えてしまいます。）

３、ポータルアプリ
組織内外のユーザーへ公開可能なサイトを簡単に作成できます。例：アンケート・会員向け専用ページ機能・一般向けページと会員向けページを組み合せたサイトを作成できます。

上記三つの中から利用したいものを選ぶと、作成することができるようになります。
VSCode Remote Containerをコマンドラインから直接開くことができるようになったのでやってみた

VSCodeの[Remote-Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)でContainerをコマンドラインから直接開くことができるようになりました。
これまではVSCodeを起動した後にContainerを開く必要があり手間に感じていたため、試してみました。

https://code.visualstudio.com/docs/remote/devcontainer-cli

# 準備
**devcontainer cli**をインストールする必要があります。
私はWSL2(Debian)で実施しましたが、Macでも同様の手順になると思います。

1. [Remote-Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)の**v0.188.0**以降がインストールされていることを確認します。

1. F1を押下してコマンドパレットを開き、**Remote-Containers: Install devcontainer CLI**を選択します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123126/37eb73a4-9802-55aa-2afa-18f48cf26dcb.png)

1. **Add**でPASSを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123126/5993a623-001b-c034-d628-f69a7e037469.png)


1. **OK**を押して、メッセージに従ってシェルを再起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123126/ab6325e1-2b2c-e28c-8698-da1ffebfe544.png)

1. **devcontainer cli**がインストールされていることを確認します。

    ```
    $ devcontainer --help
    devcontainer <command>

    Commands:
      devcontainer open [path]             Open a dev container in VS Code
      devcontainer build [path] [options]  Build a dev container image

    Options:
      -h, --help  Show help  [boolean]
    ```


1. 準備は以上です。

# 動作確認
**open**コマンドでContainerを直接開くことができました✨
なお、Containerの設定ファイルがあるディレクトリに移動するか、引数のpathを指定する必要があります。

```bash
$ devcontainer open
```
React 入門道場　~選択のメリット~

# Reactを選択するメリットって？

昨今では多数のフレームワーク、ライブラリが存在します。それぞれに長短はありますが、Reactを選択する利点は何でしょうか。

私は以下の２点だと思います。

1. 学習コストの低い点
2. 拡張性が高い点

##学習コストの低い点
 ReactはJavaScriptライブラリのため、ベースとなるプログラミング言語もJavaScript。そのため、JavaScriptの知識がある方なら容易に習得できます。また、Reactに深い知識がなくとも、JavaScriptの基本知識があればスタートできる点は利点だと思っています。中には独自APIやシンタックスが多数あるフレームワーク、ライブラリでは、そのルールに従って記述する必要性があります。そのために膨大な学習コストが掛ってしまうのはネックですね！
一方、ReactではJavaScriptで完結するため、学習のコスト面では良い点だと考えます。
## 拡張性が高い点
コンポーネント指向は、Webサイトに表示する構成要素をそれぞれ独立したオブジェクトとして扱う概念です。各オブジェクトが独立しているため、Webサイトの一部だけ変更したいときでも必要箇所だけの変更で済みます。必要な部分だけ選択して使用し、余計な処理を省けアプリケーションをシンプルに保つ事が一助となります。

そのため保守性が高く、Web開発で頻繁にReactが用いられる傾向にあります。オブジェクトを再利用して別の部品を作ることもできるため、拡張性が高いのはメリットだと考えます。

***

以上がReactの選択について纏めた内容でした。
これからも得た情報を発信していきます。
Linux ubuntu SSH ポート変更　ファイアウォール設定

##手順
1. configファイル内 Port番号を変更 (本記事のサンプルは2222へ変更)
2. ファイアウォール設定変更 （ufw 使用）
3. ファイアウォールの再読み込みとLinuxの再起動 


##contigファイル Port番号変更
```:sshd_config
sudo vi /etc/ssh/sshd_config

```

|変更前|変更後|
|----|----|
|#Port 22|port 任意のポート番号|

* 任意のポート番号に変更する。例）port 2222
* 「# 」はコメントを意味する為、消す。

##ファイアウォール設定変更
```title:root権限付与
sudo su
```
uwf:Uncomplicated FireWall
>ufw は Ubuntu Firewall の略……ではなく、
Uncomplicated Firewall （複雑じゃないファイアウォール）の略です。
iptables の操作が複雑なので、それを簡単に操作するためのラッパーです。

https://nekonenene.hatenablog.com/entry/ufw-log-meaning

```title:ufwの状態確認 
sudo ufw status
sudo ufw status numbered 
```
|ufw有効|ufw無効 (デフォルト値)|
|----|----|
|Status: active|Status: inactive|
　

```title:ufw起動（すべてのポートを拒否）
sudo ufw enable
``` 
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
【ポイント】
→実行(y)しても現在接続中の通信は切断されない。
 
```title:SSH(ポート2222)を許可
ufw allow 2222
```

```:ルール1を削除
sudo ufw delete 1
```

##ファイアウォールの再読み込みとLinuxの再起動 
```:ufw再読み込み
ufw reload
```
```:Linux再起動
sudo reboot
```
これを行わないと、Linaxログイン時ソケットエラー10061が発生する可能性がある。


参考ページ

https://armadillo.atmark-techno.com/blog/53/3762

https://server-network-note.net/2021/08/ubuntu-server-20-04-lts-firewall-ufw/

https://qiita.com/RyoMa_0923/items/681f86196997bea236f0

https://www.netinbag.com/ja/internet/what-are-the-common-causes-of-socket-error-10061.html
UnityのLODグループでLevel of Detailサンプル作ってみた（その２）

# 概要
以前、UnityのLODグループでLevel of Detail（LOD)サンプル作った

https://qiita.com/tsune2ne/items/338e3b89d23cbf3bc93b

ここのデメリットで下記をあげたので検証してみる

```
・メモリにはすべてのメッシュが載ってる気がするのでメモリも節約したい場合には向かないかも
　→Renderer指定にすれば動的ロードしてくれるかも？
```

# 検証

LOD 0（一番近いときに表示されるモデル）にテクスチャを当てる
![LODGroup_Memory0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/954513f8-80b6-4433-474f-d99174391749.png)

LOD 1（近くないときに表示されるモデル）にはテクスチャを当てない
![LODGroup_Memory0-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/ccf259bc-0d31-ebc1-baaf-ee4824772747.png)

この状態で再生し、LOD 1しか表示しない状態でWindow -> Analysis -> Profilerを開き、
Memory行を選択して下ViewをDetailに変更、
◎を押してRec、しばらくしたら停止し、「Take Sample Playmode」でスナップショットを保存
するとAssets -> Texture2DにLOD 0しか使ってないテクスチャがいるのが分かる
![LODGroup_Memory2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7680/27b39234-d020-4398-f4cb-572fe1ac85f2.png)

# 結論

つまり、LOD Groupで軽減できるのは描画負荷だけであり、
メモリ負荷を減らすことはしてくれない

むしろ複数パターン用意するのでメモリには優しくない
ということがわかる
Rails Bootstrapの環境設定の仕方

##Bootstrapの環境設定の仕方
###1:Gemfileにコードを追加
```Gemfile
gem 'bootstrap', '~> 4.1.1'
gem 'jquery-rails <=Rails6では追加の必要がない
gem 'bootstrap-sass'
```

```ターミナル
$ bundle install
```
###2:application.html.erbにコードを追加
```views/layouts/application.html.erb
<head>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
    integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous">
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"
    integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous">
  </script>
  <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.bundle.min.js"></script>
</head>
```
###3webpackの設定ファイルを編集
```config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery/src/jquery',
    jQuery: 'jquery/src/jquery
```
###4application.jsファイルを編集
```javascript/packs/application.js
//= require popper
//= require bootstrap-sprockets
```
##参考記事
[【Rails6】jQueryがなかなか使い始められない人へ](https://qiita.com/iiyama_makoto/items/940b130fd20540fd70f1)
Slack Workflow の作り方 (入門)

Slack Workflow を使ってシンプルな Workflow の作り方について紹介します。

# Slack Workflow とは？

簡単にいうと、Slack で何かしらのアクションが生じた時に自動的に処理するためのツールです。例えば、slack のチャンネルにユーザーが加入するときに Welcome Kitを本人に送ったり、毎週水曜日の 15:30 に定例の通知をしたい場合に使用します。ちなみにプロのプランであれば利用可能です。詳しくはこちらを参考に：[ツールの連携とタスクの自動化](
https://slack.com/intl/ja-jp/help/articles/360035692513-%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%83%93%E3%83%AB%E3%83%80%E3%83%BC%E3%82%AC%E3%82%A4%E3%83%89)

# Workflow の作り方

今回はユーザーが `#general` に追加された時にダイレクトメールを送信する Workflow を作ります。

左上にある企業名を選択 > ツール > ワークフロービルダーを選択

![Screen Shot 2021-08-18 at 21.41.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/872ebc73-4db3-66cd-c80b-284c79c83eb2.png)

ワークフロービルダーを選択 > 作成

![Screen Shot 2021-08-18 at 21.44.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/fb4865ee-f8e0-8248-afc1-ee1fa64d765c.png)

Workflow の名前を入力
（今回 Welcome Kitにします）

![Screen Shot 2021-08-18 at 21.45.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/b0d85aef-dfc1-8494-77ed-5a9570a5634e.png)

チャンネルの新しいメンバーを追加

![Screen Shot 2021-08-18 at 21.45.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/0464b9fd-8ff2-d557-98b7-329a2c7ee03b.png)

チャンネルを指定
(ここでは `#general`を指定)

![Screen Shot 2021-08-18 at 21.45.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/89d56fc1-601c-343f-bbee-d354ae82aef6.png)

ステップを追加

![Screen Shot 2021-08-18 at 21.45.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/04f3eb76-7125-dd6e-deea-f3add164e8c6.png)

メッセージを送信を選択

![Screen Shot 2021-08-18 at 21.46.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/72b6f505-4c1f-8e94-c368-70530466555a.png)

メッセージを入力
テキストボックスの右下にある変数を挿入するを選択することで、メンバーやチャンネルを表示することができる
終わったら保存してください

![Screen Shot 2021-08-18 at 21.47.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/e2c10e20-85b5-edf2-c0c9-4c9cb3ff7db8.png)

（他の人に管理者にしたい場合は）設定 > コラボレータを設定

![Screen Shot 2021-08-18 at 21.51.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/3dbffdb6-fa9f-0602-fd2e-d797a8d67d7a.png)

完了したら、「公開する」をクリック

![Screen Shot 2021-08-18 at 21.47.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/650642/8eac3996-436d-ee27-a8c5-cda883e9f110.png)


以上で、完了です。

# まとめ

今回 Workflow とはどのようなものか、どのように使うかについて紹介しました。
今回の記事では、チャンネルに誰が追加したタイミングで Workflow を動作させるようにしましたが、他にも Slack のショートカット や webhook によって動作させることもできます。また、メッセージ以外にもボタンやフォーム等を表示することもできるので、もし Slack を使った煩雑な作業等あれば一度ご検討するのもいいかと思います。
以上。
CentOS7のポート開放手順


# 概要
ポート開放の手順
1. Apacheで開放するポートを Listen する
2. firewalldのポートを開ける

今回は例としてポート 81番 を開放します。

# 環境
OS：CentOS7
Apache：2.4.6

# 1. Apacheで開放するポートを Listen する
httpd.conf に Listen するポートを設定します。
「/etc/httpd/conf/httpd.conf」を開いてください。
以下のように「Listen 81」を追記します。

```:/etc/httpd/conf/httpd.conf
====中略====
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to 
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 80
Listen 81  ←ここに追加

====中略====
```

httpdを再起動します。

```:
# service httpd restart
```

# 2. firewalldのポートを開ける
firewalldのポートを開けるには次のコマンドを実行します。

```:
# firewall-cmd --zone=public --add-port=81/tcp --permanent
```

firewalldの設定を確認します。
「ports: 81」が表示されていればオッケーです。

```:
# firewall-cmd --list-all

public (default, active)
  interfaces: enp0s3 enp0s8 enp0s9
  sources:
  services: dhcpv6-client http ssh
  ports: 81/tcp
  masquerade: no
  forward-ports:
  icmp-blocks:
  rich rules:
```
シートに書いた設定情報を呼び出す VBA

## はじめに

複数の人で利用するマクロ付きのエクセル、プログラムのソースコード内部に書いてしまうような設定情報をワークシート上に残しておきたい。ワークシート上で設定情報を変更してふるまいを制御したい、そんな状況に陥ったことはありませんか？私は毎回です。

- 複数の人で設定を変更しながら、同じファイルを使う
- マクロに習熟していない人が使う

上記のような状況の方にはぴったり。設定情報をシートから読み出す VBA です。つまり、下記のようなエクセルシートがあって：
![qiita_getConf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41223/398182cc-4eb6-5b7d-aa70-a5fd6e416bf3.png)
ソースコードで:

 `getConfig("target_file")` 

とすると、

**`sample.txt`** 

と帰ってくるような、そんなヤツです。何度も作る羽目になりましたので、皆さんにも紹介します。
## 準備するもの
上記を実現するには設定情報用のワークシートと、呼び出し用のモジュール、この二つが必要になりますので皆さんの環境にも準備をしてください。
### 設定情報用のワークシート
このシートへのアクセスはシート名で行います。今回の例では、シート名を `Conf` としておきます。任意のワークシート上に、下記のような VBA の中から呼び出したい名前と、その設定情報をつけた一覧表を用意します。前述の例では KeyやValueといった名前がついていますが今回の呼び出しには全く使用しません。その代わり、設定テーブルが何行目の何列目から始まっているのかが必要です。

| 項目 | 設定値 |
|---|---|
| シート名 | Conf |
| 設定テーブル開始列 | 2列目 |
| 設定テーブル開始行 | 3行目 |


### モジュール

先般の設定情報を呼び出す関数を作ります。シート内部に記載してしまってもよいですが、間違ってシート削除するとソースコードまで一緒になくなるのでモジュール化しておきましょう。モジュールの中には、下記の情報をコピペすれば大丈夫です。


```vb
' mConf Module

Option Explicit

    ' getConfigを使用するために必要な情報
    ' テーブルがあるシート名
    Private Const gC_WS_NAME As String = "Conf"

    ' 1. テーブル「開始行」(初期値:4行目から開始) ヘッダは入れない
    Private Const gC_i_ROW_START As Integer = 3

    ' 2. 「キー」となる列
    Private Const gC_i_COL_KEY As Integer = 2

    ' 3. 「値」の列
    Private Const gC_i_COL_VALUE As Integer = 3

    ' getConfigで使用するHashmap Object
    Private hashMap As Object

    '
    ' getConfig 本体
    ' ----------------------------------------------------
    ' シートにある設定項目を読み出す。入力は文字列
    ' 出力も文字列に限定
    Public Function getConfig(ByRef key As String) As String
        Dim hm As Object ' hash map object 取得用の変数
        Set hm = getInstance()
        getConfig = hm.Item(key)
    End Function

    ' getInstance - singleton pattern
    Private Function getInstance() As Object
        ' getInstanceを呼び出して、何度もHashMapの生成をさせない
        If hashMap Is Nothing Then
            Call initHM(hashMap)
        End If
        Set getInstance = hashMap
    End Function

    ' initHM - initialize HashMap Object
    ' getConfig を呼び出した際に、hashMap が初期化されていない場合に
    ' 限り呼び出される初期化サブルーチン
    Private Sub initHM(ByRef hm As Object)
        Set hm = CreateObject("Scripting.Dictionary")

        ' テーブル開始行からデータ取得開始
        Dim i As Integer: i = gC_i_ROW_START
        Dim key As String: key = ""
        Dim value As String: value = ""

        ' 該当するワークシートがないとエラー
        Dim ws As Worksheet: Set ws = Worksheets(gC_WS_NAME)

        ' key列に情報が入っている限り、key / value のペア取得を続ける
        Do While ws.Cells(i, gC_i_COL_KEY) <> ""
            key = ws.Cells(i, gC_i_COL_KEY)
            value = ws.Cells(i, gC_i_COL_VALUE)

            ' set into Key-Value-Store and increase counter number
            hm.add key, value
            i = i + 1
        Loop
    End Sub
   
```

モジュール名を `mConf` にした場合だと、`mConf.getConfig("target_file")`という呼び出しになると思います。同じ悩みを思っている方はぜひお試しください。
[Rails] GitHubでプルリクエストを受けたときの動作確認方法

自分用の備忘録となります。

## 前提として
- プルリクエストを受けたブランチの名前を `ブランチ名` と定義します


- 利用環境
  - Ruby 2.7.3
  - Rails 6.1.4

## GitHubとローカル環境の連携
- github上でプルリクエストを受けたブランチを開く
- そのブランチでURLをコピーする
- プロジェクトのあるローカルリポジトリに移動し下記を実行

```terminal:ターミナル
$ git remote add ブランチ名 githubでコピーしたURL
```

リモートを確認する。

```terminal:ターミナル
❯ git remote

ブランチ名
origin
```
このように表示されていればOKです。

## Fetchを実行する
今回のFetchの意味合いとしてはGitHub上にあるブランチ情報をとってくるという意味になります。
`$ git fetch ブランチ名` を実行

```terminal:ターミナル
❯ git fetch ブランチ名
From https://github.com/〜URL〜
 * [new branch]      develop    -> ブランチ名/develop
 * [new branch]      ブランチ名 -> ブランチ名/ブランチ名
 * [new branch]      main       -> ブランチ名/main
```

上記の真ん中にあるブランチの情報をローカルに取り込みます。

念の為、参照できるブランチを確認する。

```terminal:ターミナル
❯ git branch -a

* develop
  remotes/ブランチ名/develop
  remotes/ブランチ名/ブランチ名　
  remotes/ブランチ名/main
  remotes/origin/develop
```

## ローカル環境に取り込み
まずはローカル環境でブランチを切ります。（ここでのブランチ名は自分で把握できれば何でも可）

```terminal:ターミナル
$ git switch -c ブランチ名（指定なし）
```

ブランチを切った後そのブランチへ移動できていることを確認します。
そしてその `ブランチ名(指定なし)` へマージします。

```terminal:ターミナル
$ git merge ブランチ名/ブランチ名
```

あとは `$ rails s` だったり `$ rails c`などで動作確認を行う。

## LGTM！(問題なし)だった後の操作
まずは `develop` ブランチへ移動する。
※ `master` や `main` からブランチを切っている場合はそちらへ移動する。

```terminal:ターミナル
$ git switch develop
```

そしてローカルで作成した `ブランチ名(指定なし)` を削除する

```terminal:ターミナル
$ git branch -D ブランチ名(指定なし)
```

あとは `develop` ブランチへマージして完了です。

## 最後に
まだまだ勉強中の身でありますので、どこか誤りがあったりこうした方がいいなどありましたらご指摘お願い致します！
【RestTemplate】ステータスコード401でレスポンスボディが入っていない不具合

#背景
NestJSで発生させた。401のエラーレスポンスをSpring　Bootに返却し、RestTemplate上でエラーを返すようにしたかったのですが、なぜかレスポンスボディが入ってこず、対応に時間がかかったので、備忘録として書き記したいと思います。

#原因

先に結論を言うと、以下のようにRestTemplateに別のHTTPクライアンライブラリーに切り替えることで、レスポンスボディが入ってくるようになります。

```
HttpClient httpClient = HttpClientBuilder.create().build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate(requestFactory);
```

ソース：https://stackoverflow.com/questions/17177107/getting-400-bad-request-when-using-spring-resttemplate-to-post


原因は以下にSpring公式に記載のある通り、デフォルトの通りだと(java.netHTTP)だと、エラーを表す応答ステータスにアクセスする際に例外が発生する可能性があるからだそうです。問題に応じて別のHTTPクライアンライブラリーに切り替える必要があるようです。
https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#rest-resttemplate-create
【Flutter】Flutterのバージョンを下げる

# 概要
不具合調査などでFlutterのバージョンを下げたい時などの対処法。

# 対応

バージョンを下げる場合

```
cd flutter
git checkout <tag>
flutter doctor
```

元に戻す場合

```
cd flutter
git checkout stable
flutter doctor
```

# 注意事項
## 依存パッケージのDartSDK要件
下げるバージョンによっては、Flutterのバージョンと一緒にDartSDKのバージョンも下がる。
そのため、場合によっては利用しているパッケージのDartSDK要件が合わなくなる可能性がある。
そうなった場合、そのパッケージのバージョンも下げてみるとよい。

## Android Studioのキャッシュ
Flutterのバージョンを下げた後にAndroid Studioでビルドが通らない場合は、`Invalidate Caches / Restart`を試してみると動いたりする。
GAS 基本編メモ②

GASで勉強始めました。
自分用メモです。

## 処理時間の計算

```javascript
function initSheet() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var names = ['taguchi', 'fkoji', 'dotinstall'];
  var i;
# ここで変数を定義
  var startTime = new Date();

  sheet.clear();

//  2060ms

  for (i = 1; i <= 1000; i++) {
    sheet.getRange(i, 1).setValue(names[Math.floor(Math.random() * names.length)]);
    sheet.getRange(i, 2).setValue(Math.floor(Math.random() * 101));
  }

# Loggerで処理時間を表示させます
  Logger.log(new Date() - startTime);
}
```

## 処理を高速化させる

```javascript
function initSheet() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var names = ['taguchi', 'fkoji', 'dotinstall'];
  var i;
  var startTime = new Date();
  var scores = [];

  sheet.clear();

//  2060ms

  // for (i = 1; i <= 1000; i++) {
  //   sheet.getRange(i, 1).setValue(names[Math.floor(Math.random() * names.length)]);
  //   sheet.getRange(i, 2).setValue(Math.floor(Math.random() * 101));
  // }

  for (i = 1; i <= 1000; i++) {
    scores.push([
      names[Math.floor(Math.random() * names.length )],
      Math.floor(Math.random() * 101 )
    ]);
  }

  sheet.getRange(1, 1, 1000, 2).setValues(scores);

  Logger.log(new Date() - startTime);
}
```

## 判定処理

```javascript
function initSheet() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var names = ['taguchi', 'fkoji', 'dotinstall'];
  var i;
  var startTime = new Date();
  var scores = [];

  sheet.clear();

  for (i = 1; i <= 10; i++) {
    scores.push([
      names[Math.floor(Math.random() * names.length )],
      Math.floor(Math.random() * 101 )
    ]);
  }

  sheet.getRange(1, 1, 10, 2).setValues(scores);
}

function showResults() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var scores = [];
  var i;
  var results = [];

  // scores = sheet.getRange(1, 2, 10, 1).getValues();
  scores = sheet.getRange(1, 2, sheet.getLastRow(), 1).getValues()

  for (i = 0; i < scores.length; i++) {
    results.push([scores[i] >= 80 ? 'PASS' : 'FAIL']);
  }
  sheet.getRange(1, 3, results.length, 1).setvalues(results);
}
```




```
IPアドレスってなに？

#はじめに#

勉強してきたことの備忘録として記事を残していこうと思います。
未経験初学者による記事ですので温かい目で見守っていただけると幸いです。
また、誤り等ありましたらぜひご指摘いただければと思います。

では早速始めていきます。

#IPアドレスとは#

IPアドレスとは何なのでしょうか。
あまり馴染みのない言葉ですね。

IPアドレスとは*Internet Protocol address*の略称です。
何だか余計分からなくなりましたね(笑）
一つずつ紐解いていこうと思います。


まず、プロトコルとは何でしょうか。
　プロトコルとはコンピュータ同士がお互いに通信するための規約のことです。
言い換えれば、OSやメーカーが違うコンピュータ同士でも会話ができるように作られた言葉のようなものです。



　細かく見ていくと、プロトコルにもいくつか種類があり、その中の一つがIP（インターネット・プロトコル）というものです。

　IPとはプロトコルの中でも非常に重要なものの一つで、通信先のコンピュータを判別する役割を担っています。
　例えば、メール一つ送るのにも、どのコンピュータに送れば良いかが分からないとコンピュータも迷ってしまいますよね。それを迷わず送れるようにしたのがIPです。



　さて、本題に戻ります。ここまでくると何となく分かるかと思いますが
IPアドレスとは、**IPにおいて通信の相手先を判別するために割り振られた一意の番号**のことです。
　いわば、コンピュータの住所のようなものですね。


#表記方法#

　IPアドレスは1〜3桁の数字をドット区切りで4つ並べた形で表記されます。
例えば　

192.168.10.10　

のような感じですね。
見覚えのある方もいらっしゃるのではないでしょうか。

この表記法を**ドット付き10進表記**などと呼びます。


　コンピュータは2進数を使っていますので、実は0か1しか認識できないというのは有名な話かと思います。（0か1の最小単位を**ビット**と呼びます。また、8ビットを1バイトと呼びます。）
　本来IPアドレスは8ビット×4の32ビットで表されます。
　(※例　11000000.10101000.00000000.00000001)

　これだと我々には非常に見にくいので、10進数で書き換えたものがよく見るIPアドレスというものです。

　ちなみに、2進数の最大値は11111111で、これを10進数に置き換えると255ですので、1バイトの最大値は255ということになります。つまり、IPアドレスは256の4乗で約43億通りあります。すごい数ですね。

　しかし、この43億通りのIPアドレスは実はほとんど使われており、誰かが割り当てを放棄しない限り新しいIPアドレスが取得できないという問題も出てきているそうです。
それだけ世の中にはたくさんのコンピュータが溢れているということですね。

現在はこのIPアドレス枯渇問題を解消するため、新しいIPv6というバージョンの普及が進められています。
ちなみにこちらのIPv6では2の128乗通りのIPアドレスが使用可能です。
もはや単位も分かりません。

どのくらい多いかというと、全世界70億人に１兆個ずつ割り当てても0.00000001%にも満たないくらいの数だそうです。（笑）
流石にしばらくは大丈夫そうですね。


#まとめ#
◆IPアドレスとは、コンピュータの住所のようなもので通信において相手先を判別するために割り振られた番号のこと。
◆IPアドレスは10進数で1〜3桁の数字をドット区切りで4つ並べた形で表記される。

ちなみに、10進数でもまだ我々には少し見にくいので、実際にはドメインというものと紐づけられて使われます。
y○hoo.ne.jpみたいなやつですね。
これについてはまた機会があれば書いていこうと思います。

それでは、ありがとうございました！