OmniAICreator/Qiita-1.07M huggingface dataset:
クライアントの動的IPアドレスと各種制御

# クライアントの動的IPアドレスと各種制御

クライアントの動的IPアドレスについて、いくつかの考察してみた。

おそらく現在(2020年)のISPの多くは、本稿のような設定にはなっていないとは思うが、キャリアグレードNATなどがもっと普及していくと、本稿のような状態を考慮する必要が出てくるかもしれない。

# NAT とクライアントのグローバルIPアドレスとしての動的IPアドレス

![nat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/b2f918f5-364c-7852-bdf2-f131cb01d566.png)


NATの場合は、クライアントのIPアドレスと、グローバル(インターネット)へ出ていくIPアドレスは1:1に対応するでしょう。

現在(2020年)のISPの多くはこのような設定だと思う。

# NAPT とクライアントのグローバルIPアドレスとしての動的IPアドレス

![napt.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182822/284ed580-8b45-4be5-8d9c-a621ea34c0d0.png)

NAPTの場合は、クライアントのIPアドレスと、グローバル(インターネット)へ出ていくIPアドレスが必ずしも1:1対応はしないだろう。
特に、冗長化しており、グローバル(インターネット)へ出ていくIPアドレスを複数保持しているような場合、TCP接続毎に異なるIPアドレス(グローバル(インターネット)へ出ていくIPアドレス)となる場合があるだろう。

このような場合、以下のような機能に影響を与えるだろう。

<dl>
 <dt><b>DynamicDNS</b>
  <dd>DynamicDNSへのTCP/UDP通信の送信元IPアドレス(のポート全て)が、自分に割り当てられているとは限らないということになるかもしれない<br>こういうのって、ISPの規約に「外部から接続するようなサービスには対応していません」とかって書かれるのだろうか・・・<br><br>
 <dt><b>クライアントのIPアドレスに基づいたアクセス制御</b>
  <dd>「確認くん」とかで送信元IPアドレスを調べて、それを管理者へ通知して、そのアドレスだけ一時的に穴開けする。とかいう(謎な)ルールは、今後通用しなくなるかもしれない。
</dl>

# 関連リンク

- [ネットワークアドレス変換](https://ja.wikipedia.org/wiki/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E5%A4%89%E6%8F%9B)
- [ポートアドレス変換](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%BC%E3%83%88%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E5%A4%89%E6%8F%9B)
- [キャリアグレードNAT](https://ja.wikipedia.org/wiki/%E3%82%AD%E3%83%A3%E3%83%AA%E3%82%A2%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89NAT)
- 2020/08/04 [これにアクセスして気づいたんだけど、自分が使ってるISPのIPoEはJPNEのv6プラス(MAP-E)で、グローバルIPを複数ユーザで共有する構成だったことを知る。わいわい](https://twitter.com/matsuu/status/1290614182849593346)
- 2020/08/14 [noteが投稿者のIPアドレスをお漏らししたので2ch/5chで特定祭りになっているということだが、今は昔よりもさらにISP内NATが一般的になっているし、カフェなどでWiFiを提供することも進んでいるので、単にIPアドレスで名寄せすると危険な巻き込みが発生しうる。](https://twitter.com/EzoeRyou/status/1294118820148154368)
- 2020/08/14 [1つのグローバルIPv4アドレスを複数の契約者で共有するISPの構成があるため、Webサービスなどを提供している皆様にはIPv4アドレスに加えて (1) 送信元ポート番号 (2) UTCタイムスタンプ (3) トランスポート層プロトコル(TCP/UDP)を記録することをRFC6302で推奨しています。](https://twitter.com/yuyarin/status/1294158583496503296)
- 2020/08/14 [noteのIPアドレス漏洩は、ページの下の方のJSON部分で、JSONでデータ出すときに余分な情報を出してしまうサービスってたまにありますね。noteは各所にアーカイブされているので、消すのは大変そう。2015年のころのアーカイブにもありました。](https://twitter.com/lumin/status/1294165196492046337)
- 2020/08/14 [雑な個人データの取り扱いによる濡れ衣問題というのがしばしば問題になりますが (たとえば内定辞退するつもりがないのに内定辞退率高と判定される「濡れ衣」は個人に大きな不利益をもたらす)、故意でないデータ漏洩によって濡れ衣問題が生じることもあるわけですね。](https://twitter.com/bakera/status/1294157161530966018)


# 以上
シーケンスの名前を変更する方法

# シーケンスの名前を変更する

以下のSQL(DDL)文を実行するだけ。
ALTER SEQUENCEで調べ始めて、迷い込んでしまいました。。。

```sql
RENAME SEQ_A TO SEQ_B
```

# 確認バージョン
- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
UFTのオブジェクトスパイでオブジェクトをうまく取得することができない

UFTでオブジェクトスパイを使用して、Windowsアプリのオブジェクトを取得しようとしました。
しかしフォームを選択しても思ったところではなく、あらぬところを指定してしまい、うまく取得することができず困ったので、対処方法を記載しておきます。

## 前提

実際に使用していた環境は以下の通り
Windows10 Pro
UFT ONE 15.0
対象のアプリはJavaで作成されたもの

## 解決方法

1. PCの設定でディスプレイの「拡大縮小とレイアウト」で「テキスト、アプリ、その他の項目のサイズを変更する」を**100％**にする（ここが150%になっていてうまくオブジェクトを判別できていなかった）
![設定.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/121319/92d454d7-03f1-42fd-0ede-f10460010348.png)

2. UFTを起動している場合は再起動する

たったこれだけでオブジェクトスパイでのオブジェクト取得はうまくいきました。
が、設定を変更してしまうと表示サイズが小さくなり、オブジェクトスパイを使い終わった後にまた設定を戻して……
と手間がかかってしまうので、他の解決策がないかも探してみたいと思います。
【メモ】SCSSで配列を使ったforによるループ処理

複数の箱に異なるサイズを指定する例

```haml:sample.haml
.box1
.box2
.box3
.box4
.box5
```

```scss:sample.scss
$boxSizes: (271px, 366px), (360px, 241px), (360px, 244px), (360px, 239px), (360px, 239px);
@for $num from 1 through length($boxSizes){
  .box#{$num}{
    width: nth(nth($boxSizes, $num), 1);
    height: nth(nth($boxSizes, $num), 2);
  }
}

```

eachの場合、配列に重複が存在するとコケる・・・。
きっと重複してても処理をする方法があるんだろうけど、ざっと探したけど見つからなかった。
まぁFORでやれば意図した結果になるので深追いするのやめましたｗｗ
私のための学習忘備録

#コマンド忘備録　（Linuxのlevel１試験にむけて勉強）
gzip形式で圧縮したファイル　hoge.txt →　hoge.txt.gzが出来上がる。

##gzipの圧縮コマンドのオプション
-d 　圧縮ファイルを開く時
→gunzip　これでも圧縮ファイルを開ける。

-c 　元ファイルを残して標準出力に出力
-r　ディレクトリ内の全てのファイルを再帰的にそれぞれ圧縮

##圧縮率
xz> bzip > gzip



##cpioコマンドオプション
cpioでコピーイン、アウトの意味らしい。標準入力や出力に使用する。
findやlsコマンドを使ってファイルの一覧を取り出し,パイプを使ってcpioコマンドの出力をする。
ちなみに、オプションでは

-o　新しいアーカイブを作成
-i アーカイブからファイルを展開

##XZ
xz形式でファイルを圧縮するときはこれ！(圧縮率が高い）
オプション　-d 圧縮ファイルを開くとき（これはgzipと一緒）
　　　　　　unzxコマンドでも展開できる。
　　　　　　-k 圧縮ファイルを元のファイルを削除しない
　　　　　　-l 圧縮ファイルの情報を表示する。

##lsコマンド
ファイルやディレクトリの表示にはこのコマンド
オプション多すぎだろ

-a 隠しファイルを含む全てのファイルを表示
-A 上と同じ
-d 指定したディレクトリの情報を表示
-i inode番号をつけて表示
-l 詳細情報をつけてくれる　ユーザーやパーミッションなど
-R サブディレクトリの内容も再帰的に表示
-F　後ろにファイルのタイプ表示してくれる
（通常ファイル：なし、/：ディレクトリ、＊：実行可能ファイル）

##tarコマンド
tar は複数のファイルをまとめて1つのファイルにする、展開をする時に使用するもの。オプションまた多い。
-c　新しいアーカイブの作成
-x アーカイブからファイルを展開
-t アーカイブの内容を一覧表示
-f アーカイブファイル名を指定
-v 処理の詳細情報を表示
-z gzipを通じて圧縮・展開
-j bzipを通じて圧縮・展開
-J xzを通じて圧縮・展開

##touch
からのファイル制作、ファイルのタイムスタンプ を制作してくれる。
タイムスタンプ ＝アクセス時刻や修正時刻
-t 時刻　アクセス時刻と修正時刻を指定した時刻に変更
-a アクセス時刻を変更
-m 修正時刻を変更

##ファイルからデバイスにコピーを行う時
ddコマンドを使用する。
if=入力ファイル　入力側ファイル（デバイス）を指定
of=出力ファイル　出力側のファイル（デバイス）を指定

##mv 
名前の変更or ファイルやディレクトリの移動

##cpコマンド
-f 同名のファイルやディレクトリがある際は強制的に上書きをする。
-i 上書きするか問い合わせる
-p ファイルの属性（ユーザや更新時間、パーミッション）を保持したままコピー
-r,R　ディレクトりをコピー

##タイムスタンプ のファイル更新がされるコマンド
echo original>original これはoriginalファイルリダイレクトされタイムスタンプ が更新される。
ls -l > これもレダイレクトなんでタイムスタンプ 更新
touch はファイルのタイムスタンプ 更新する。
そもそもタイムスタンプ とは、ある出来事が発生した日時、日付、時刻を示すこと。ファイルの更新とかしたときの時間のことかな？

##viコマンド
l 1文字右へ
h　1文字左へ　キーボドも同じ配置やん
j 1文字下へ
k　1文字上へ

:5 = 5G 同じ意味５行目に行くって。
:set nonu = :set nonumber　行数をつけない
:set number :set nu 行番号をつける



a カーソルのある右からの入力
i カーソルのある左からの入力
I カーソルのある行の頭から入力
A　カーソルのあるお尻から入力
o カーソルのある行の下に空白行を挿入し、その行からの挿入
O カーソルのある上の行に空白行を制作し、その行からの挿入!


?~　カーソルの位置から上に向かって検索をかける
/~ カーソルの位置から下に向かって検索をかける
:e! viを終了せずに現在開いてるファイルを閉じて新しいファイルを出すこと。
！があるのでこれで保存してくれる。！がなければただ閉じるだけー。
:e 系は今いるファイルを開いて新しいのを出すイメージだね〜

![スクリーンショット 2020-06-13 11.45.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620109/c3f143e2-1f24-d2ee-b25f-fcf07d4e16e6.png)

L 画面の最下位へ持ってくる
＄　行末へ
H　画面の最上位へ
:q vi を終了する、しかし内容が変更されているときは警告が出て終了できない。
０　カーソルを行の頭へ持っていくこと
:set ts =１０、：tabstop＝１０で tabの幅を数値で指定する。

:r　指定したファイルの内容をカレント行の後に読み込んで挿入するには、：rを使う

:!コマンド　viエディタを終了することなくLinuxコマンドを実行するにはこのコマンドを使う。
/と？は検索をかける際に使用するコマンド（/はファイルのお尻に向かって検索するのに対し、？の方は、頭（逆に）向かって検索をかける。）
n　お尻に向かって進める
N　頭に向かってすすめる

:q!  保存せずにエディタ終了する
:q viを終了するが編集内容が変更されているん場合には警告が出るので終了できない
:w 編集しているファイルを終了することなく、保存をしたい！
編集内容を保存して終了　：wq！＝：x＝ZZ

yyとY　カーソルの位置の行をコピーする
yw カーソルの位置にある単語をバッファにコピー
dd　カーソルの位置の行を削除し、バッファにコピー
dw カーソルの位置にある単語を削除し、バッファにコピー
p　バッファの内容を挿入（文字や単語カーソルの右へ、行は下へ）
P バッファの内容を挿入する（文字や単語はカーソルの左へ、行は上へ）

X　カーソルの位置の左の文字を削除してバッファにコピー
x　カーソルの位置の文字を削除してバッファにコピー



##プロセスとジョブ
![スクリーンショット 2020-06-15 16.44.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620109/7a2ecc59-a17a-3165-0d88-115dd8785653.png)

これわかりやすすぎでしょwww

bg[ジョブ番号]　一時停止しているところバックグラウンドに戻してくれるコマンド
fg バックグラウンドからフォアグラウンドに戻るとき、一時停止の状態からフォアに戻るとき
Ctrl＋Z　一時停止
Ctrl＋C　強制終了
pgrep　　実行中のプロセスから特定の名前をもつプロセスIDを検索することができる。

STOPとTSTPはプロセスを一時停止するシグナル。シグナル番号にすると19と２０それぞれ。
-f 完全なフォーマットでプロセスを表示する
禁断手法を使って社内のGitLab Runnerを爆速化した話(DinDの場合)

毎度、ググっても出てこない小ネタを取り扱っております。
本記事は個人的な見解であり、筆者の所属するいかなる団体にも関係ございません。

# 0. はじめに

社内のGitLab Runnerを爆速化したくて禁断の技に手を出したという話になります。
(※なぜ禁断かというと、オンメモリーストレージというのは再起動すると消えてしまいますし、大きい容量を用意するのも難しく、気をつけないと容量を使い尽くしてしまってジョブが実行できなくなってしまうからです。)

# 1. 何が問題だったか

事の元凶は、GitLab Code Quality です。

GitLab Code Qualityは、ソースコードを読み込んで問題点をチェックしてくれるGitLab組み込みツールです(注：2020年6月12日の時点で使えるのはStarter Edition以上、今後Community Editionでも利用できるようになると[アナウンス](https://about.gitlab.com/blog/2020/03/30/new-features-to-core/)されている)。

Code Quality | GitLab
https://docs.gitlab.com/ee/user/project/merge_requests/code_quality.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/82ef40af-bd0a-244b-978a-f8ad2446b681.png)
https://about.gitlab.com/2017/06/22/gitlab-9-3-released/

このCode Qualityの実行が遅いのです。。。

# 2. なぜ遅い？

Code Qualityは、ソースコードを解析するためにCode Quality用のDockerイメージをダウンロードして、Docker-in-Docker workflowという方式で動いています。以下のように動作します。

1. Code QualityのDockerイメージのダウンロード
2. Dockerイメージの展開
3. ソースコードの解析

この中で1と2に時間がかかっており、Diskの書き込みに待ちが発生していることが分かりました。

# 3. 改善

2でDiskへの書き込みが遅いことは分かりました。しかし、Diskのパフォーマンスをおいそれとは上げることができません。RAID-6で組んだHDDストレージではありましたが、4世代ぐらい前のRAIDコントローラーに4世代ぐらい前の2．5インチHDDです。これ以上はパフォーマンスが出そうにありません。

## 3-1. 対策 1. HDDをSSDに交換する

この方法は確かにいくらかはスピードアップするでしょう。
しかし、安くなっているとはいえ、いまさら先の見えているSATA SSDを6本も買う気にはなれませんでした。また、RAIDコントローラーがオンボロな為SSDに交換してもどこまでスピードアップするかは未知数でした。

## 3-2. 対策 2. Dockerに必要なファイルをオンメモリーのファイルシステムで動かす

マシンのメモリーが余っているならば、一番手軽ですぐにできて絶対に早くなる保証があります。
(いくらSSDが速いとはいえ、オンメモリーには敵わないでしょう)

さらにGitLab Runner(Code Qualityは特に)はコンテナで実行されていて、ステートフルではありません。コンテナイメージがローカルにあれば、それはそれでいいのですが、無くても最悪、自動的にダウンロードされるので問題になることはありません。それを考えるとオンメモリーで動かす事ができるワークロードと言えるでしょう。

# 4. 対応

対応は簡単です。
仮想環境でVMマシンにメモリーを追加して(20GBにしました)、fstabに以下のように書くだけです。
OS用に2GBとしました。

```file:/etc/fstab
tmpfs     /var/lib/docker         tmpfs   defaults,size=18g,nofail 0       0
```

**`※メモリーを増やす場合には仮想環境のメモリー利用状況に注意しましょう。`**

# 5. 結果

どうなったか、どうだったか。

5分30秒かかっていたCode Qualityの実行が4分まで短縮されました。

残りの4分は何に使われているか。

残りの4分は以下のことに使われていました。
1. Code QualityのDockerイメージダウンロード(約1分)
2. Dockerイメージの展開(2分30秒)
3. Code Qualityの実行(30秒)

1については、ローカルにリポジトリーを作成するなどすればもう少し短くできるでしょう。
(キャッシュされると最高なのですが、DinDからのDockerコンテナ実行ではDockerイメージキャッシュが効きません)
2については、Dockerイメージをひたすらuntarしている状況でこれ以上早くはなりそうにありません。(CPUもtmpfsへの書き込みも余裕があるのでoverfay2の課題なのだと思います。)
3については、Code QualityはRubyのようなのでDocker内でRubyの実行スピードが上がればもう少し短くなるかも知れません。

# 6. **`注意`**

注意ポイントは、Code QualityのDockerイメージが7GBほどあることです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15176/46973121-1be2-6d46-2d36-a75d4cb08ca3.png)

tmpfsの残り容量が7GBを下回るとCode Qualityの実行に失敗します。

1日に1回チェックして、Dockerイメージを削除しましょう。
【PHP】データ型の基本

こちらの記事は以下の書籍を参考に執筆しました

[独習PHP 第3版](https://www.amazon.co.jp/dp/B01FH3KVNU/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

#データ型
PHPで扱えるデータ型は3つに分類できます。

- スカラー型
- 複合型
- 特殊型

**1つの変数に1つの値を扱う**事ができるのがスカラー型。
**スカラー型と対照的**なのが複合型。
**スカラー型でも複合型でもない**のが特殊型。

以下は詳細。

###スカラー型

|データ型|概要|
|---|---|
|論理型(bool.boolean)|true,false|
|整数型(int,integer)|10進数、16進数(0xで始まる値)など|
|浮動小数点型(float,double,real)|1.8✕10^308が最大|
|文字列型(string)|クオートで囲まれた文字|



###複合型

|データ型|概要|
|---|---|
|配列型(array)|データの集合|
|オブジェクト型(object)|データと手続きの集合|

###特殊型##

|データ型|概要|
|---|---|
|リソース型(resource)|外部リソースへの参照|
|ヌル型(null)|値が未定義である|

##論理リテラル
複合型とリソース型は後述し、スカター型とヌル型とその値(**リテラル**)の説明から。
リテラルとは変数に格納できる値そのもの、またはその値をスクリプトの中で,表現することをいいます。

PHPの論理リテラルでは以下をfalseとみなす。

- 空文字列、または文字列の0
- 整数リテラルの0
- 浮動小数点リテラルの0．0
- 要素数が0である(空)の配列
- null(未定義値)

##整数リテラル

整数リテラルの分類

```
整数リテラル
├---------10進数リテラル(0,3,-12)
├---------2進数リテラル(0b1111,0b101)
├---------8進数リテラル(0777，0644，0600)
└---------16進数リテラル(0xFF,0xAA00BB)
```
>出典：[独習PHP 第3版](https://www.amazon.co.jp/dp/B01FH3KVNU/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

10進数以外の表現にはプレフィックス(接頭辞)として以下のようにします。

|進数|接頭辞|例|
|---|---|---|
|2進数|0b|0b1010|
|8進数|0|0777|
|16進数|0x|oxc0|

このように接頭辞をつけることで表現できます。
変数にこれらが代入された時点で10進数に変換されます。

##浮動小数点リテラル
`3.14`以外にも`3.534E5`や`1.1414e-3`のような指数表現もできます。
例えば`3.534E5`は`3.534✕10^5`を表します。
指数表現を表す`e`は大文字小文字を区別しないので
`3.534E5`と`3.534e5`は同じ意味です。

##文字列リテラル

###`"`と`'`の違い

|項目|"|'|
|---|---|---|
|変数展開|する|しない|
|エスケープシーケンス認識|する|しない|

###ヒアドキュメント
ヒアドキュメントとは改行を含む長い文字列を表すのに適しています。
例えば

```php5
$msg=<<< EOD
aaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccc
EOD;

print $msg;
```
結果

```
aaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccc
```

このように改行も表現されます。
ヒアドキュメントでは`<<< EOD`から`EOD`までを文字リテラルとみなし、`EOD`は区切り文字なので、任意の文字を指定できます。
人が認識しやすいように大文字で表すのが一般です。

##ヌル型
以下はヌルであるとみなします。

- 変数に値が代入されていない場合
- 変数に明示的にnullが代入された場合
- unsetで変数の内容が破棄された場合
SORACOM LTE-M Button powered by AWS を使ったリモートコンサートの利用アイデア

１．概要

これは、「SORACOM LTE-M Button powered by AWS 」を使ったアイデアであり、実現はできてません。

２．アイデアの内容

コロナの関係で、コンサートなどが無観客で開催されています。しかし、演者との一体感を得るために何かできないか、考えました。

（１）「SORACOM LTE-M Button powered by AWS 」ボタンを押すと、画面にサイリウムが光る。演者から見れるモニターで、サイリウムが表示される。

（２）曲の終わりなど、拍手タイミングで「SORACOM LTE-M Button powered by AWS 」と拍手が演者が見れるモニターに表示される。

「SORACOM LTE-M Button powered by AWS 」を利用する利点は、以下の通り

（１）テレビならDボタンでできるが、最近では、スマホやタブレットで見るひとが多い。

（２）showroom,17ライブ,ラインライブ、ポコチャなどの投げ銭システムも利用できるが、ユーザー登録やコインの購入が面倒。

「SORACOM LTE-M Button powered by AWS 」を使えばSIMの利用料金から徴収できる。ただし、ライブ事前にチケット購入と同時に「SORACOM LTE-M Button powered by AWS 」ID登録が必要。

（３）配信システムと投げ銭システムが、別物なので、配信システムに負荷がかからず安定配信が可能。

（４）投げ銭システムを異なるプラットフォーム（TV,インターネット）で同一システムで実現。

（５）システム構成が簡単
　　　ユーザー：「SORACOM LTE-M Button powered by AWS 」
　　　演者：５０インチ４KTV＋FireTV　４K＋アプリ（アマゾンが協力してくれるといいかも）

以上
Let's Encrptでサーバー証明書を作成するのにHTTP（TCP　PORT 80）も必要？

結論  必要です。

Windows IISにLet's Encrypt（win-acme）でサーバー証明を作成する際、外部よりhttp（TCP PORT80）でアクセスしてきます。
よってインターネット側からHTTPを開放しておく必要があります。

元ネタ
https://letsencrypt.org/ja/docs/allow-port-80/
Python超初心者の超初心者のためのPython #.txtファイルを作業中の.pyで読み込む

環境
windows7　（Mac Book Pro 16inch欲しい）
Visual Studio Code
chrome

この記事はプログラミング初心者かつPython初心者に向けて記述します。

##.txtファイルを作業中の.pyファイルで読み込む

作業中のpythonファイルでテキストファイルを読み込もうとしても` No such file or directory:`とエラーが出てしまいテキストファイルを読み込めません。
格闘すること4時間・・・・。
解決に至りました。

###序章～全てはここから始まった

```python:file.py
f = open("trial_data.txt")
print(f.read())
f.close()
#FileNotFoundError: [Errno 2] No such file or directory: 'trial_data'

```

がびーん！！！です。
ググり倒して早4時間。

###解決～ハッピーエンド

####`カレントディレクトリ`の場所にテキストファイルを置く
ということに気付かされました。
それは、質問サイトに「python カレントディレクトリでググれ」。
この一言が解決に導いてくれました。

```python:file.py
import os

currentdir = os.getcwd()

print(currentdir)
#C:\Users\（ユーザー名）

```

そこでtrial_dataをC:\Users\（ユーザー名）に置いて無事解決です。

PC初心者かつプログラミング初心者の恥ずかしいスキルでした・・・。

Fin
[Oracle Cloud] 複数のVCN越しに疎通できるようにしてみた

# はじめに
**Oracle Cloud Infrastructure ドキュメント**
*リモートVCNピアリング(リージョン間)*
https://docs.cloud.oracle.com/ja-jp/iaas/Content/Network/Tasks/remoteVCNpeering.htm
には、下図のように複数のVCNを跨いだ通信ができると記載されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/3e04233e-a3b7-45c9-dd01-53a20c422843.png)

ただし、実際にどのような設定をOracle Cloud Infrastructure (以下OCI)上で行えばよいか、マニュアル的な記載が無いので、設定者にとっては戸惑ってしまうかもしれません。
本書では実際にOCIを構築し上図のような通信を実現させた際の設定例について記載します。

# 事前準備 -OCI環境作り-
適切なrouting設定を行う前に、まずはOCIの各コンポーネントを作成する必要があります。
下記ポイントに注意し、対象リージョン毎にOCIの環境を構築します。

- VCN作成
- Subnet作成
- Security List作成
- Route Table作成（後述）
- Local Peering Gateway作成&接続
- DRG作成
- Remote Peering Connect設定
- (通信試験用のインスタンス作成)

# 論理NW図とルーティング
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567355/b4544bc8-0a23-c19d-cc10-3635d857da19.png)
私が実際に構築した環境及び設定したルーティングの情報を上図に纏めています。
二つのリージョンにそれぞれ2つずつVCNを作成しLocal Peeringで接続、
各リージョンに1つずつDRGを作成してVCNにアタッチ (DRGとVCNは1:1でしかアタッチができません)、
DRG間でRemote Peering接続しています。

Route Tableは、

- Subnet
- Local Peering Gateway (以下LPG)
- DRG

に関連付けることができます。

図中の、

- VCN : 10.100.0.0/16
- VCN : 10.0.0.0/16

はハブの役割を果たし、
VCN(10.70.0.0/16) -----> VCN(10.100.0.0/16) -----> VCN(10.0.0.0/16) -----> VCN(10.60.0.0/16)
まで到達できます。 (逆方向も然り)
具体的にトラフィックをTransit Routeする役割はLPG , DRGが担うので注意して設定しましょう。

# 参考URL
リモートVCNピアリング(リージョン間)
https://docs.cloud.oracle.com/ja-jp/iaas/Content/Network/Tasks/remoteVCNpeering.htm
【jQuery】ページのスクロールで背景色を変える。

## やりたいこと
特定の範囲内でページがスクロールされている時だけ背景色を変えたい。
# 完成形
[![Image from Gyazo](https://i.gyazo.com/e2a882c9a57b93469c464e7b3c204061.gif)](https://gyazo.com/e2a882c9a57b93469c464e7b3c204061)

# 1. HTMLの準備

```html:sample.html
<div class="title">
 Works
</div>
<div class="color-man">  ⬅️背景色を変えるところ
  <img src="img/ruby.png" class="ruby-image">
  <img src="img/ruby.png" class="ruby-image">
</div>  
```

# 2. CSSの準備
適当に横並びにして、幅と高さを与えておきます。

```css:sample.css
  .color-man {
    margin: 0 auto;
    border-radius: 10px;
    padding: 20px;
    width: 900px;
    height: 300px;
    display: flex;
    justify-content: space-between;
  }
  
  .ruby-image {
    width: 300px;
    cursor: pointer;
  }
```

# 3. JSの準備
スクロール量を取得し、その量によって背景色を変える記述と戻す記述をする。

```js:sample.js
window.onscroll = function(){
  var scrollTop = window.pageYOffset ;   //スクロール量を取得
  if (scrollTop > 900 ) { 　　
    $('.color-man').css('background-color', 'skyblue');
    $('.color-man').css('transition', '1.3s')
  }
  if (scrollTop < 1400 ) { 
    $('.color-man').css('background-color', '');
    $('.color-man').css('transition', '1.0s')
  }
}
```
____________________________
以上で終了です。
ご覧いただきありがとうございました。
[serverless.yml] 複数の環境変数の設定でも楽がしたい!

# serverless.ymlで環境変数を環境ごとに設定するよくあるサンプル

まず、外部のファイルに環境変数を定義して、

```yml:conf/dev.yml
ENV_1: "dev"
ENV_2: "hoge"
ENV_3: "fuga"
 :
 :
ENV_100: "HENSU_TAKUSAN"
```

それをserverless.ymlで一つずつ読み込む

```yaml:serverless.yml
provider:
  name: aws
  stage: ${opt:stage, self:custom.defaultStage}
  ... ランタイム周りの設定

custom:
  defaultStage: dev
  otherfile:
    environment:
      dev: ${file(./conf/dev.yml)}
      stg: ${file(./conf/stg.yml)}
      prod: ${file(./conf/prod.yml)}

functions:
  nanika:
    handler: nanika
    environment:
      ENV_1: ${self:custom.otherfile.environment.${self:provider.stage}.ENV1}
      ENV_2: ${self:custom.otherfile.environment.${self:provider.stage}.ENV2}
      ENV_3: ${self:custom.otherfile.environment.${self:provider.stage}.ENV3}
        :
        :
      ENV_100: ${self:custom.otherfile.environment.${self:provider.stage}.ENV100}
```

#### 正直、環境変数が多いと、見づらいしコピペミスしそう。。
一つずつ設定しなくても、上記のconf/dev.ymlをそのまま使えないの??

# conf/[dev|stg|prod].ymlをそのまま使う
環境変数を一つずつ設定する代わりに、ファイルをそのまま書けばOKだった。

```yml:serverless.yml
provider:
  name: aws
  region: ap-northeast-1
  stage: ${opt:stage, self:custom.defaultStage}

custom:
  defaultStage: dev
  otherfile:
    dev: ${file(./conf/dev.yml)}
    stg: ${file(./conf/stg.yml)}
    prod: ${file(./conf/prod.yml)}

functions:
  nanika:
    handler: nanika
    environment: ${self:custom.otherfile.${self:provider.stage}}
```

これで環境変数が100あってもconf/*.ymlを修正するだけでOK。

# そもそも
多くの環境変数を使うこと自体よろしくないので、設定ファイルに書き出すなり、データストア使うなり、機密情報はKMSなどを使うのが良いのだけれども、プロトタイプをゴリゴリ描く時はこれで良いかも。
[Alexa Skills Kit SDK] slot や intent についての簡単なまとめ

今の発話がどのインテントであるかという判断は、アレクサ側でやってくれる。
こっちは、インテントとサンプル発話を用意するだけでいい。
**アレクサ側で音声認識をし、それを文字に起こし、どのインテントに当てはまりそうかをサンプル発話を参考に判定する。**

例：
HungryIntentというインテントを用意。
サンプル発話は「お腹がすいた」

アレクサのデベロッパーコンソールのテストでスキルを起動し「お腹がすいた」と発話すると、以下の情報がバックエンドに送られる。↓

「`IntentRequest`であるかつ、intentの名前は`HungryIntent`である」という情報。

```json
"request": {
    "type": "IntentRequest",
    "requestId": "リクエストのID",
    "timestamp": "タイムスタンプ",
    "locale": "ja-JP",
    "intent": {
        "name": "HungryIntent",
        "confirmationStatus": "NONE"
    },
    "dialogState": "STARTED"
}
```

バックエンドは、インテントの名前を受け取り、HungryIntentHandlerの処理を行う。

```python
class HungryIntentHandler(AbstractRequestHandler):
    def can_handle(self, handler_input):
        return is_intent_name("HungryIntent")(handler_input)
    
    def handle(self, handler_input):
        handler_input.response_builder.speak('わかる').ask('わかるよ')
        return handler_input.response_builder.response
```

この場合、アレクサが「わかる」と言ってくれる。
非同期処理導入。レイアウトがずれる、失敗例について

###  <font color='lightblue'>１）背景</font>
※備忘録的ですが、レイアウト崩れなど遭遇した方は一度参照してみて下さい。

検索ボタンを押下し、リストを表示。
表中の番号のリンクをクリックすると、非同期で画面が描写されるのですが、画像の通り、レイアウトがずれてしまいます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647299/9f44750d-5cf0-0f56-497a-6421dac63a2c.png)


###  <font color='lightblue'>２）環境</font>

| 項目              |               内容 | 
|:-----------------|:------------------:|
| OS.Catalina      |           v10.15.4 |      
| Ruby             |            v2.5.1 |  
| Ruby On Rails    |           v5.2.4.3 |       


###  <font color='lightblue'>３）内容</font>
**対応１）今回はソースを確認し、微修正を施します**
以下で、必要な箇所のみレンダリングして再描写します。

```erb:show.js.erb
$('.main-krown-area').html("<%= escape_javascript(render 'mainknowledge' ) %>");
```

元々、文章を表示する部分（mainknowledge）と画像を表示する部分(mainimage)を別々にレンダリングするようにしていました。

```erb:show.html.erb
1  <!-- クラウン表示 -->
2  <%= render "mainknowledge" %>
3  <!-- クラウンイメージ表示 -->
4  <%= render "mainimage" %>
```

これが原因だったようで、文章の部分だけが再描写することで、レイアウトが崩れたようです。
文章の表示と画像をscssで同じクラスにまとめて、レンダリングも一つだけ再描写するようにすると、以下のようにおさまるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647299/2f94a53f-1ab5-5e1a-d153-2ded67307e25.png)

以上です。
EdgeのDevToolsは日本語化されている

最近、Edge (Chromium)をメインブラウザとして使っているのですが、DevTools（デベロッパーツール）のCommand Menuからスクリーンショットを取ろうとしたら、何故かスクリーンショット機能が見つかりません。

<img width="322" alt="スクリーンショット 2020-06-12 14.37.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16060/939f1ed0-1232-37de-c471-73a7f382a9c2.png">

検索をかける前のCommand Menuを見てみると、メニューが日本語化されているようです。（それ以前に「ネットワーク」も「コマンドが見つかりませんでした」も日本語ですね）

<img width="334" alt="スクリーンショット 2020-06-12 14.36.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16060/f7ca1e38-d04b-cced-261c-8e67ac35aa5d.png">

ということは日本語でコマンドを検索すればいけます。

<img width="329" alt="スクリーンショット 2020-06-12 14.37.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16060/fd5426e7-e694-c40c-0400-9b6e8fc970f4.png">

多言語対応はマイクロソフトの手によるらしいです。

Bringing the Microsoft Edge DevTools to more languages
https://blogs.windows.com/msedgedev/2020/02/04/localizing-edge-devtools/

日本語化対応はありがたいものの、コマンドは英語で慣れ親しんでいる人が多いでしょうし、Mac環境だと上のような「スクリーン」を変換した状態で変換確定のためにエンターキーを押すと1番上のコマンドが実行されてしまったりと動作が不安定のようです。（Mac + Edge + Google日本語入力で再現してますがどこが原因か不明）

マイクロソフトによる投稿には多言語設定の説明もあり `edge://flags/`を開いた後に `Enable localized Developer Tools` の設定をDisabledにすることで多言語対応を無効化できます。

<img width="725" alt="スクリーンショット 2020-06-12 14.37.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16060/256130c8-2e32-191d-a7ea-376b4729f455.png">

Macの場合はDefaultの設定の場合は端末の言語設定が適用されるようですが、手元の端末で確認したところ、Windows 10 2004 + Edge 83.0.478.45でもDefault設定の場合はDevToolsが（OS設定の）日本語になっているので、現在はWindowsでも同様の挙動となっているようです。

<img width="323" alt="スクリーンショット 2020-06-12 15.04.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/16060/da95afcd-c4b6-7531-4130-ee72affb0aaf.png">

Disabledに変更して再起動したところ慣れ親しんだ英語のコマンドでスクリーンショットが取れるようになりました。
嬉しいですね。
[Python] 変数っていつ作られるの？クラスインスタンスっていつ消されるの？

変数はそのファイルがimportされた時に作られる。

クラスのインスタンスは、その関数が終了したら破棄される。

```python
class A:
    def __init__(self):
        self.a = 'a'
        self.b = 'b'

    def __del__(self):
        print(self.__dict__)
        
def main():
    a = A()
    
main()
-> {'a': 'a', 'b': 'b'}
``` 

`__del__` はクラスインスタンスが破棄されるタイミングで実行される。
(`main()`が実行され、その処理が終わるときにインスタンスが破棄されるためprintが実行される)
[Java]文字列結合の速度比較

javaで文字列の結合を手軽に行うときは+を使うが、
```StringBuilder```の```append```メソッドで結合すればパフォーマンスが上がるらしい。

```java
public class StringConcate{
    public static void main(String args[]){
        for(int i=0; i<5; i++){
            // n=[10,100,1000,10000,100000]
            int NumOfProcess = (int)Math.pow(10, i+1);
            System.out.println("* n="+NumOfProcess);

            plusString(NumOfProcess);
            builderString(NumOfProcess);
        }
    }

    /** "+"を用いて文字列の結合を行い速度を表示する
     * @param n 結合処理回数
     */
    public static void plusString(int n) {
        long stime = System.currentTimeMillis(); // 処理開始時刻

        String s = "abc" ;
        for(int i=0; i<n; i++){
            s = s+"java" ;
        }

        long etime = System.currentTimeMillis(); // 処理終了時刻
        System.out.println("plusString process-time : "+(etime-stime)+"[ms]");
    }

    /** StringBuilderのappendメソッドを用いて文字列の結合を行い速度を表示する
     * @param n 結合処理回数
     */
    public static void builderString(int n) {
        long stime = System.currentTimeMillis(); // 処理開始時刻

        StringBuilder s = new StringBuilder("abc") ; // StringBuilderインスタンス生成
        for(int i=0; i<n; i++){
            s = s.append("java") ;
        }

        long etime = System.currentTimeMillis(); // 処理終了時刻
        System.out.println("StringBuilder process-time : "+(etime-stime)+"[ms]");
    }
}
```

それぞれ2つのメソッドに対して
"java"という文字列の結合を10回～100万回繰り返してみた。

```sh
* n=10
plusString process-time : 0[ms]
StringBuilder process-time : 0[ms]
* n=100
plusString process-time : 0[ms]
StringBuilder process-time : 0[ms]
* n=1000
plusString process-time : 2[ms]
StringBuilder process-time : 0[ms]
* n=10000
plusString process-time : 67[ms]
StringBuilder process-time : 1[ms]
* n=100000
plusString process-time : 3336[ms]
StringBuilder process-time : 0[ms]
* n=1000000
plusString process-time : 778282[ms]
StringBuilder process-time : 12[ms]
```

歴然たる差。100万回の結合では+を使うと13分もかかってしまった。
普段は+で、大量の結合処理を行うときにはStringBuilderを使うのがよさそう？

## version情報
```sh
$ java -version
java version "14.0.1" 2020-04-14
Java(TM) SE Runtime Environment (build 14.0.1+7)
```

## 参考
[スッキリわかるJava入門-実践編 第2版](https://www.amazon.co.jp/dp/4844336770)
PHP echoとprintについて

## PHP echoとprintの違いについて
PHPには echo と print というよく似た出力機能があります。
今回はこの二つの機能の違いについて調べてみました。

## 関数ではない
echoとprintはどちらも厳密には関数ではなく、PHPの言語構造だと説明されています。
そのため()をつけなくても正常に動作します。
https://www.php.net/manual/ja/function.echo.php
https://www.php.net/manual/ja/function.print.php

```test1.php
<?php
    print("Hello world\n");
    print "Hello world\n";

    echo("Hello world\n");
    echo "Hello world\n";
?>
```

出力結果

```
Hello world
Hello world
Hello world
Hello world
```

動作の違いとしては、echo()はカンマ「,」区切りで複数の引数を指定できるのに対し、print()はできません。
※ただし、echo文でも()をつけるとエラーが出ます。

```test2.php
<?php
    print 'Hello', 'world'; // この構文はエラーが出ます
    echo 'Hello', 'world'; // こっちは正しい構文です
?>
```

## printは式(expression )、 echoは式ではない(statement)
例えば、echoをif式で評価することはできませんが、printは評価することができます。
printは常に1を返すため、以下のような書き方ができます。

```test3.php
<?php	
	//正常に評価する
	if (print 1) {
   		 print 'success';
	}
?>
```

処理結果

```
1success
```



echo で上記のような書き方をするとエラーとなります。

## どちらを使えばよいか
結論から言えばどちらでもよさそうです。
返り値を持たない分、echoの方が処理速度が速いらしいですが、体感できるほどの差はないかと思います。
RailsチュートリアルCh5 をAurelia2 で作り直す（コンポーネント作成）

# やること

- RailsチュートリアルのCh5 をAurelia2 で作成する

# ToDo

- Ch5 のワイヤーフレームから作成するコンポーネントを分割する

- 各コンポーネントを作成する


## ワイヤーフレームをコンポーネントに分割する
共通部分であるヘッダーとフッターとその他のページとに分ける。その上で下記のコンポーネントでアプリケーションを構成したい。

- shared/header
- shared/footer
- pages/home
- pages/help
- pages/login
- pages/about
- pages/content
- pages/news

makesコマンドで作成したsrcディレクトリ内にsharedディレクトリを作成し、さらにその中にheaderディレクトリ、footerディレクトリを作成する。同様にpagesディレクトリとその中に各ページ用のディレクトリを作成する。
## コンポーネントの作成
各コンポーネントはそれぞれ個別の役割を負うものとする。例えばヘッダーコンポーネントであれば、ヘッダーナビゲーションをユーザーに提供する、等。

### コンポーネント作成の基本
コンポーネントは、view-model を提供するためのJavaScript(TypeScript)のクラスとレンダリング対象となるHTMLで構成される。
具体的には、jsまたはtsファイルとhtmlファイルのセットが最小構成になる。例えば、home-pageを作成する場合、
> home-page.ts
> home-page.html

となる。これに追加で各コンポーネント用のcssファイルも追加する。この際、ファイル名がコンポーネントの名称となる。名称には必ず“-”を使用して命名する必要がある。また、tsファイルとhtmlファイルの名称は拡張子を除いて同一である必要もある。

### HomePageコンポーネントの実装

```TypeScript

/*
HomePage コンポーネントで使用するモデル
*/
export class HomePage {
}
```

```HTML
<div class="center jumbotron">
   <h1>Welcome to the Sample App</h1>
   
   <h2>
     This is the home page for the Ruby on Rails Tutorial sample application.
   </h2>
</div>
```
必要最低限の実装はおこなった。次は、アプリケーションのルートコンポーネントで新しく作成したHomePageコンポーネントを使用したい。

### アプリケーションルートコンポーネントへのインポート
最初にアプリケーションを作成されるファイルにmain.tsがある。

```TypeScript
import Aurelia from 'aurelia';
import { MyApp } from './my-app';

Aurelia
  .app(MyApp)
  .start();
```

Aurelia は上記のコードでインポートされているmy-app.ts ファイルのクラスMyAppをアプリケーションのルート、大元のコンポーネントとして構成している。先ほど作成したHomeコンポーネントもただファイルを作成しただけではアプリケーションに組み込まれていない。作成したコンポーネントをアプリケーションに組み込む方法はいくつかあるが、今回は使用するコンポーネントのhtmlファイルに直接インポートする方法で実装する。
（別章の実装時に今みているmain.tsファイルに登録する方法に変更する。）

### my-appコンポーネントへのインポート
自動生成されたmy-app.htmlのコードをすべて削除して、下記のコードに書き換える。

```html
<import from="./pages/home/home-page"></import>
<home-page></home-page>
```

コンポーネントを利用するためには、利用するコンポーネントのhtmlファイルに<import>タグを追加し、importタグ内で使用したいコンポーネントを指定する。

> import from="コンポーネントの存在する相対パス/コンポーネント名称"

コンポーネントの名称は先ほど作成したファイル名となる。続いて、使用するコンポーネントのタグを記載する。

## アプリケーションをサーブする
最後にnpm startコマンドでアプリケーションをローカルで起動して、先ほど作成したhomeページの記載内容がレンダリングされているか確認する。

# 次にやること
- 残りのコンポーネントを作成する
- 複数のコンポーネントをルータによりルーティングする
- Bootstrapによりデザインを調整する
oxalis-sanのタグへの検索リンク

# 言語

- [C++](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3AC%2B%2B)
- [C#](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3AC%23)
- [Python](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3APython)
- [JavaScript](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3AJavaScript)
- [PowerQuery](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3APowerQuery)
- [R](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3AR)

# 環境・ライブラリ

- [Windows](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3AWindows)
- [Boost](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3ABoost)
- [STL](https://qiita.com/search?sort=created&q=user%3Aoxalis-san+tag%3ABoost)

# 全部

[](https://qiita.com/search?sort=created&q=user%3Aoxalis-san)
LaTeXでレポート書くときによくつかうやつ

自分に向けた自分のための備忘録記事（予防線の鬼）
ギリギリLaTeXを自分の環境で使える程度のまとめです。

# `\documentclass`
```LaTeX
\documentclass[10pt, a4j]{jsarticle}
```

用紙サイズとか内容の全体的な体裁とか指定できたはず。
`a4j`はA4サイズ指定だったような気がする。

# `\usepackage`

```latex
\usepackage{listings, jlisting, liststyle}
\usepackage[dvipdfmx]{graphicx}
```

`.sty`を読み込む。
コンパイルするファイルと同じディレクトリか、グローバルなところに`.sty`を配置して、ファイル名拡張子抜きを指定する。

`listing`はソースコードを貼るときに役に立つ。
`jlisting`は`listing`の日本語対応版。

# タイトル・著者・日付
```latex
\title{タイトル}
\author{お名前}
\date{9999年6月12日}
```

# 環境
```latex
\begin{document}
レポート本文
\end

\begin{lstlisting}[caption=リスト題名,label=listlabel]
ソースコード
\end
```

# セクション
```latex
\section{節見出し}
\subsection{小節見出し}
\subsubsection{少々節見出し}
```

セクションの題名を挿入する。

# 図
```latex
\begin{figure}[ht]
\includegraphics[(options)]{path-to-image.jpg}
\caption{図題}
\label{labelname}
\end{figure}

\ref{labelname}
```

`\begin{figure}[ht]`の`[ht]`は位置調整。

オプションには横幅とか指定できる。
`width=0.8\linewidth`とか書くと用紙幅の8割の幅で画像を挿入できる。

# listing関係
## キャプションの単位を変える
```latex
\renewcommand{\listlistingname}{リスト}
```

ソースコード1 を リスト1 に変えられる

[LaTeXにソースコードを【美しく】貼る方法 - Qiita](https://qiita.com/ta_b0_/items/2619d5927492edbb5b03)

## シンタックスハイライト的なことをする
```latex
\begin{lstlisting}[language=c++]
```

[LaTeXでソースコードを書く - しがないエンジニアのブログ](http://turgure.hatenablog.com/entry/2016/08/19/183501)
ラズパイ上に立てたgit labにアクセスしようとして詰まった件

自分のための備忘録
ラズパイ上で立てたgitlabからリポジトリをclone使用したら失敗した話。
ポート指定しなかったからできなかったという

これだと☓
```
 git clone http://localhost/User/repo.git
```

これだと○
```
git clone http://localhost:8080/User/repo.git
```
【jQuery】要素表示がなぜかできない【原因はd-noneでした】

## 概要

デフォルト非表示にしている要素に対し、jQueryのshowメソッドを使い、要素を表示(追加)させる実装をした際、**d-none**にやられた話です。
言わずもがな、デザインはBootstrapを使ってます。

## 実装したこと

+ボタンを押すと、d-noneしている入力フォームを表示させたい。
コードは以下の通り。大したことはしていない。

```test.html

<div class="col-md-4">
  <button type="button" class="btn btn-success rounded-circle p-0　style="width:2rem; height:2rem;" id="plus">
  ＋
  </button>
</div>

<div class="col-md-4 d-none" id="addText">
  <input type="text" name="memo" class="form-control">
</div>

```

```test.js
jQuery(function () {
    $('#plus').click( function () {
        $('#addText').show();
    })
})

```

## 何が起きたか

#### 表示されない。。。

デバッグした所、ログも吐けているのに何でやねんと思って調べた所、要素非表示の為の**d-none**が悪さをしておりました。

原因は、
#### d-noneがshowメソッドより優先されてしまうから ####
でした。

詳しく追うと以下の通り。

- d-noneは、**display: none!important;**というCSSスタイルを追加する
- 一方、jQueryのshowメソッドでは**display: block**というCSSスタイルを追加する
- 優先されるのは**display: none!important;**（つまりd-noneが優先されてしまい、要素は非表示のままになる）

## 解決策

要素非表示を**d-none**ではなく、cssの**display: none;**を使って解決。

```test.css
#addText{
  display: none;
}
```
（html側のd-noneは削除してください）

無事表示出来ました。

## まとめ

表示on/offの実装をしたい時は**d-none**は避けましょう
もしd-noneを使う場合は、show()ではなく**removeClass('d-none')**を使いましょう

##文献
[jquery - jQuery show()はBootstrap d-noneクラスを表示しません](https://ja.coder.work/so/jquery/892256)
iOS/AndroidのWebViewで再生できるスマホ撮影動画

iOS/Androidで撮影した動画ファイルについて、WKWebView/WebViewで再生できるかどうかを確認したのでメモ。

# 使用機器

- iOS: iPhone 7 (iOS 13.4.1)
- Android: Pixel 3a (Android 11-beta2)

# 動画ファイル

iOS(MOV)/Android(MP4)のそれぞれで、下記の組み合わせで10秒撮影したものを使用。

- コーデック: H.264, H.265
- サイズ: FullHD, 4K
- フレームレート: 30fps, 60fps

# 結果

## iOS

| 動画 | 結果 |
| :-- | :-- |
| iOS H.264 FullHD 30fps | OK |
| iOS H.264 FullHD 60fps | OK |
| iOS H.264 4K 30fps | OK |
| iOS H.265 FullHD 30fps | OK |
| iOS H.265 FullHD 60fps | OK |
| iOS H.265 4K 30fps | OK |
| Android H.264 FullHD 30fps | OK? (自動再生はされないがシークバーを操作すると再生される) |
| Android H.264 FullHD 60fps | OK? (自動再生はされないがシークバーを操作すると再生される) |
| Android H.264 4K 30fps | OK? (自動再生はされないがシークバーを操作すると再生される) |
| Android H.265 FullHD 30fps | OK? (自動再生はされないがシークバーを操作すると再生される) |
| Android H.265 FullHD 60fps | OK |
| Android H.265 4K 30fps | OK? (自動再生はされないがシークバーを操作すると再生される) |

## Android

| 動画 | 結果 |
| :-- | :-- |
| iOS H.264 FullHD 30fps | OK |
| iOS H.264 FullHD 60fps | OK |
| iOS H.264 4K 30fps | OK |
| iOS H.265 FullHD 30fps | NG (音のみ再生) |
| iOS H.265 FullHD 60fps | NG (音のみ再生) |
| iOS H.265 4K 30fps | NG (音のみ再生) |
| Android H.264 FullHD 30fps | OK |
| Android H.264 FullHD 60fps | OK |
| Android H.264 4K 30fps | OK |
| Android H.265 FullHD 30fps | NG (音のみ再生) |
| Android H.265 FullHD 60fps | NG (音のみ再生) |
| Android H.265 4K 30fps | NG (音のみ再生) |

# まとめ

- 基本的に、サイズとフレームレートは再生可否に関係しない
- AndroidではH.265の動画は再生できず、音声のみ再生される
- Androidで撮影した動画をiOSで再生しようとすると、シークバーを複数回操作しないと再生されなかったり、少し挙動が怪しい(再生できなくはない)
- 両OSとも、iOSで撮影したH.264の動画は問題なく再生できる

Web上での動画再生はYoutubeの埋め込みなどが主流かと思いますが、何かの参考程度にどうぞ。
AWS transit gatewayの基本と、クロスアカウントで設定をするときに詰まったこと

hirokihelloです。今のインターン先の入社時はbashとshellの違いもわからなかったのに来るところまで来たなあと言う感じがあります。

今回業務でAWSのtransit gatewayの設定をするときに勘違いをしていて詰まったので、transit gatewayの基本概念と詰まった部分を残しておきたいと思います。

## transit gatewayとはなんぞや

外部に公開していないネットワーク内部への通信を、他のvpcやvpsから通信できるようにするAWSのハブみたいな機能。

#### 何が嬉しいのか?

例えば異なるVPCに置かれた二つのAPIサーバーがあったとします。

ALB経由でのみアクセスが前提の場合、private networkにそれらのAPIサーバーは置かれるので、普通nat gatewayなどを使用して外部のネットワーク経由でのみ二つのAPIサーバーはやりとりできます。(そりゃそうだ。)

しかし外部のネットワークを経由せずに直接vpnなどでやりとりした方が、特に業務向けのサービスの場合はセキュアにした方が良いので、そのように独立した外部に公開していないネットワーク同士を直接つなげたいとの要望が出てきます。

#### じゃあvpnでいいやん？

二つのAPIサーバなら、直接つなげばいいでしょう。
しかし4つになった場合を考えてください。

例えば4つのサーバーA,B,C,Dがあるとします。

その場合A-B, A-C, A-D, B-C, B-D, C-D間でvpnの設定をしなければなりません。
これは正直めんどくさいです。

#### transit gatewayのいいところ。

transit gatewayの場合は上記の例で言うと、A~Dのサーバーに加えてxと言うハブを新規で作ります。
そしてA-x, B-xのように、xとそれぞれのサーバーをつなげます。

そしてxにroutingの設定を行い、ip rangeでtransit gatewayに結び付けられたどのvpcの向け先に向けるかを設定します。

つまりハブ経由で全てアクセスさせると言うことです。

## 今回詰まった部分
#### transit gatewayをinternet gateway的なものだと勘違いしていた。
それぞれのアカウントでtransit gatewayを立てvpcに紐付け、そこからvpc同士をくっつけるのだと思ってました。
つまり、internet gateway的なインターネットにアクセスするための出口的なものとして認識していました。

#### 解決策

まずクロスアカウントの場合は共有元となる一つのアカウントで、transit gatewayをどっかのvpcに立てます。

その後、**そのtransit gatewayをResource Access Managerを使って他のアカウントに共有します**。

その後にそれぞれのアカウントで紐付けたいvpcをattachmentを作成してtransit gatewayに紐づけます。

つまり共有もとのtransit gatewayをそれぞれのアカウントで使えるようにして、それぞれのアカウントが一つのtransit gatewayを共有してそこにそれぞれ紐付けていくと言うことが必要なのです。


#### 追記

後で余裕があれば図などを付けます。

現在文学部3年ですが、絶賛就活中なのでtwitterなどに連絡くださると幸いです！！
Flutterでアプリ内課金 ライブラリ選定

Flutter公式？[in_app_purchase](https://pub.dev/packages/in_app_purchase) よりも、[flutter_inapp_purchase](https://pub.dev/packages/flutter_inapp_purchase) が良さそうなのか？

[in_app_purchase](https://pub.dev/packages/in_app_purchase) を使っているが、
購入済みのリストが取れなかいなど問題に遭遇。
解決ができないでいる。

同様の現象が、こちらのissueに上がっている。
https://github.com/flutter/flutter/issues/53534

[flutter_inapp_purchase](https://pub.dev/packages/flutter_inapp_purchase) を使って解決したって書き込みが。

パッケージの変更、ちょっと面倒くさいがやってみる。
PixiJSで拡張子が画像ファイルでないURLを読み込んでTextureとして扱う

PHPなどでjpgを出力させ、それをPixiJSで読み込むときの方法

resource-loaderの中身はPIXI.Loaderのようだが引き続き要調査

```ts
import * as PIXI from 'pixi.js'
// Pixiをインストールすると使える。要調査↓↓
import { Loader, Resource } from 'resource-loader'

const container = new PIXI.Application({
    resolution: devicePixelRatio,
    transparent: true,
})

const imageLoader = new Loader()
//画像のURLと読み込みタイプの設定
imageLoader.add('image', './api/imageGenerate.php?' + new Date().getTime(), { loadType: Resource.LOAD_TYPE.IMAGE})
//完了時のイベントハンドラ
imageLoader.onComplete.add(() =>
    .imageLoaded()
)
//読み込みを開始
this.imageLoader.load()

//完了時に実行
imageLoaded() {
		const imageSprite = new PIXI.Sprite()
		container.stage.addChild(.imageSprite)
		//読み込まれるデータがImage(imgタグ)なのでTextureに変換する
		this.imageSprite.texture = new PIXI.Texture(new PIXI.BaseTexture(imageLoader.resources.image.data))
}
```
Swiftのループ文の早期退出はbreak/continue/return何を使えば良いか

Swift書いてて、ループ文をreturnで抜けたとき、どこまで抜けるのかがよくわからなくなったので、サンプルコードを書いて確かめてみることにしました。

# サンプル
```swift:Dice
struct Dice {
    func roll(from startIndex: Int, to endIndex: Int) {
        for i in (startIndex...endIndex) {
            guard i <= 6 else { return } //<-ここをreturn/break/continueそれぞれ試す
            print(i)
        }
        print("サイコロの目は６までです")
    }
}
```

もしreturn = breakなら、"サイコロの目は６までです"まで出力されるはずですね。
まずはbreakから。

# break
```swift
Dice().roll(form: 1, to: 7)
```

これで挙動を試しました。

```swift:出力結果
1
2
3
4
5
6
サイコロの目は６までです
```

想定どおりですね。

# continue
このサンプルだとcotinueとbreakの差がわかりづらいので、`guard i == 6 else { continue }`にして試します。

```swift:出力結果
6
サイコロの目は６までです
```

はい。
早期退出してもループ文は次の要素に対して継続するので、6のときだけprint出力が実行されます。

# return
んで、returnなんですが……

```swift:出力結果
1
2
3
4
5
6
```

となりました。
よく考えたら当然で、returnで抜けるスコープは**メソッド**であって、ループ文から抜けるわけじゃないんですね。
（……と説明されると当たり前じゃん、と思ってしまうんですけど、実際にコード書いてると、いつの間にかbreak≒returnみたいな感覚になってました）

# ちなみに
実際に使ったことはないんですけど、Swiftのbreak/continueにはラベルというのがつけられるそうで、

```swift
struct Dice {
    func roll(form startIndex: Int, to endIndex: Int) {
        parent: for _ in (startIndex...endIndex) {
            for i in (startIndex...endIndex) {
                guard i <= 6 else { break parent }
                print(i)
            }
            print("サイコロの目は６までです")
        }
    }
}
```
という風に、親スコープのループを抜けることができます。
この例だと、普通のbreakだと、上記のbreakを使ったときの出力例が７回出るんですけど、
ラベルをつけてあげると、1〜６を出力した時点で、親ループを抜けます。

使いどころはありそうなんですけど、実際に使ったことはないですね。
vistaでquartus その4

#概要

vistaでquartusやってみた。
serial叩いてみた。

#環境

windows vista 32bit
quartus ii v13.0
ep2c5t144ボード

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b40ccc78-5f8d-bd38-6d1e-f6a5f6424e3d.png)

#サンプルコード


```

module test1(input clk, input rst, output reg tx = 1);
	reg [7:0] data;
	reg [15:0] cnt_p;
	reg [15:0] cnt_n;
	reg out_p;
	reg out_n;
	reg [4:0] state;
	parameter rate = 5208;
	assign uart_clk = out_p ^ out_n;
	initial
	begin
		cnt_p = 16'd1;
		cnt_n = 16'd1;
		out_p = 0;
		out_n = 0;
		state = 0;
		tx = 1;
		data = 8'h55;
	end
	always @(posedge clk)
	begin
		cnt_p <= cnt_n + 16'd1;
		if (cnt_n == rate)
		begin
			cnt_p <= 16'd1;
			out_p <= ~out_p;
		end
	end
	always @(negedge clk)
	begin
		cnt_n <= cnt_p + 16'd1;
		if (cnt_p == rate)
		begin
			cnt_n <= 16'd1;
			out_n <= ~out_n;
		end
	end
	always @(posedge uart_clk or negedge rst)
	begin
		if (!rst)
		begin
			state <= 0;
			tx <= 1;
		end
		else
		begin
			if (state == 0)
			begin
				state <= 1;
			end
			else if (state != 0)
			begin
				state <= state + 1;
				if (state == 2)
				begin
					tx <= 0;
				end
				else if (state > 2 && state <= 10)
				begin
					tx <= data[state - 3];
				end
				else if (state == 11)
				begin
					state <= 0;
					tx <= 1;
				end
			end
		end
	end
endmodule




```

以上。
array_searchの返り値が0の場合の条件分岐

#array_searchとは

指定した値を配列の中から検索し、見つかったら最初のキーを返す。


例えば、

`$array = {'いちご','さくらんぼ','めろん'};`

の場合、
`$key = array_search('さくらんぼ', $array); `

とすると
`$key = 1`となる。

##$key=0の場合

例えば、検索するワードをもつ配列の要素が存在する場合としない場合で条件分岐したいとき、
keyが0になる場合のことを考慮しなければならない。

keyが0の場合、

```php
if($key)[
echo 'keyがあります';
}

if(!empty($key)){
echo 'keyがあります';
}
```

という書き方をすると`false`になる
なぜなら`if($key)`は`0`を`false`、
`empty($key)`は`0`を`true`とみなすため。

そのため、

```php
if($key !== false){
echo 'keyがあります';
}
```
とする必要がある。

```php
if($key != false){
echo 'keyがあります';
}
```
こうしてしまうと、データ型まで一致しているか検証してくれないので、
`0`は`false`とみなされる


**==** 値が同じ
**===** 値とデータ型が同じ
fetchメソッド内で他のメソッドを呼ぶと、 Chromeでは上手くいくのにSafariではうまくいかない問題

#困ったこと

fetchメソッド内で、他のメソッドを呼ぶと、
Chromeでは上手くいくのにSafariではうまくいかない。

言葉でつらつら書くよりコードを見ていただいた方が早いので、コードで示します。

```javascript
        const word_area     = document.getElementById("word_area");
        const btn_to_submit = document.getElementById("btn_to_submit");
        const def_list      = [];
        const url           = "hogehoge";

        btn_to_submit.addEventListener("click", () => {
          console.log(eng_word);
          fetch(url)
          .then(response => {
            return response.json();
          })
          .then(data => {
            // jsonファイルで取得した特定の値をdef_listという配列に詰めていく。
            data[0].shortdef.map(def => {
              def_list.push(def);
            })
            // addMeaning()というメソッド呼び出し
            addMeaning();
          })
          .catch(error => {
            console.log('error');
          });
        })

        function addMeaning() {
            // 本当はここでdef_listという配列をいろいろいじってます。
            console.log(def_list);
        }
```

上でも書いたように、これだとchromeではうまくいきますが、Safariではうまくいきません。
うまくいかないというのは、```addMening()```を呼び出すと、
catchメソッドが呼ばれてしまうのです。（＝fetchメソッド内でエラーが起きている）

詳しく見ていったところ、```addMening()```の```def_list```をうまく参照できていない？？？

#解決策
##functionを使った関数ではなく、アロー関数にする！

```javascript
        // ダメな例
        function addMeaning() {
            // 本当はここでdef_listという配列をいろいろいじってます。
            console.log(def_list);
        }
```

```javascript
        // 良い例
        const addMeaning = () => {
            // 本当はここでdef_listという配列をいろいろいじってます。
            console.log(def_list);
        }
```

```javascript
        // これでもいけました。
        const addMeaning = function(){
            // 本当はここでdef_listという配列をいろいろいじってます。
            console.log(def_list);
        }
```

#まとめ

なんでかは分かりませんが、アロー関数を使うことでSafariでも動作するようになりました。
これ、どなたか理由が分かる方がいらっしゃいましたら、ご教授してくださると幸いです。

最後まで読んでくださり、ありがとうございました。
以上です。
BootCamp環境でmacOSとWindowsの共有パーティションを作成する方法


# はじめに
* Macの内蔵ディスクにmacOSと、Windowsの両方から読み書き可能な領域が欲しい!
* ドライバーの類が入らないと困るので、Boot Campを使わないWindowsインストールは避けたい...

この2点の要求を満たすべく、MacにWindowsのインストールを試みたのですが、なかなか思うようにパーティションが作れずハマりました。
この記事は、最終的にうまくいった方法の覚え書きです。ただし、半ば荒技のような手順ですので、お試しの際はくれぐれも自己責任でお願いします :bow: 
なお、環境を構築してから3か月ほど経ちますが、私のマシンは今の所問題なく稼働しています。
(あまりWindowsを立ち上げる機会は多くありませんが :imp: )

# 目指す構成
このような形で、macOSが使っていた領域からパーティション2と3を削り出します。

* パーティション1(APFS): macOS用
* パーティション2(FAT): macOS, window共用
* パーティション3(NTFS): Windows用

# 環境
* MacBook Pro(15-inch, 2019)
* macOS Catalina(10.15.14)
* Windows10 Pro

# 手順
Boot Campアシスタントが起動している裏側で、ディスクユーティリティを使って共有パーティションを作成してしまいます。
※別のマシンでキャプチャを撮ったため、出来上がりとストレージのサイズが異なります。

1. BootCampアシスタントを起動し、Windowsの領域を指定します。
ここでは、**Windows OSで必要な分と、共有パーティションの分を合計**したサイズを指定します。
(Windows: 250GB, 共有パーティション: 50GBならばサイズを300GBとする)
<img width="413" alt="BootCamp" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653162/08bbb148-1a65-6288-cbde-d25141bca6d4.png">
ISOイメージは選択しても構いませんが、まだインストールは実行しないでください。

1. BootCampアシスタントを起動したままディスクユーティリティを起動し、共有用の新規パーティションを作成します。パーティション情報を入力し、「適用」ボタンをクリックします。
 * 名前: わかりやすい名前
 * フォーマット: MS-DOS(FAT)<br>
<img width="413" alt="DiskUtil" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653162/f673a2d0-a812-5930-8252-0b775e27e7da.png">

1. パーティションが出来たら、BootCampアシスタントに戻ります。(未選択ならば)ISOイメージファイルを選択し、「インストール」ボタンを押してWindowsのインストールを実行します。
1. あとは、画面の指示通りにWindowsのインストールを進めれば完了です。

# 出来上がり
このような形で、無事Windows用のパーティション`BOOTCAMP`と、共有パーティション`SHARE_DRIVE`が作成されました。
<img width="294" alt="mac_storage.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653162/d47668d6-e9d5-be83-7909-6190c5e93983.png">

Windowsのエクスプローラーでドライブを表示すると、このような感じになります。
macOSの入っているパーティションが見えていません。
<img width="364" alt="win_explorer" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653162/6c0d2291-9803-2a62-ee14-b9761244e30b.png">
クラウド・インフラ技術を学んでいくためにAWSを始めてみた（その３：TCP/IP基礎）


#はじめに

　インフラ・クラウド編の3回目です。今回は、`TCP/IP`についてまとめます。

概要は下記です。

+ TCP/IPとは
+ HTTPについて
+ TCP/UDPについて
+ IPについて
　


参考にさせて頂いたサイト

+ [TCP/IP]
(https://www.infraexpert.com/study/tcpip.html#:~:text=TCP%2FIP%E3%81%AE%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B9%E3%83%9D%E3%83%BC%E3%83%88,%E5%B1%A4%E3%81%AB%E7%9B%B8%E5%BD%93%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)

+ [AWS：ゼロから実践するAmazon Web Services](https://www.udemy.com/course/aws-and-infra/)


##TCP/IPとは
　
　`TCP/IP`(Transmission Control Ptrotocol/ Internet Protocol)は、現在のインターネット通信及びイントラ通信ネットにおいて**最も利用される通信プロトコル**のことです。

　※プロトコルとはコンピュータ同士の通信をする際の手順や規格のことです。

　`TCP/IP`は複数のプロトコル（`IP,ICMP,TCP,UDP,HTTP`等）からなりますが、中心的な役割を果たすプロトコルは`TCP,IP`であることから`TCP/IP`と呼ばれるようになりました。

　歴史的には`OSI`(Open System Interconnection)と呼ばれる階層モデルが提案されていましたが、普及しませんでした。結果、`TCP/IP`が広く利用されるようになっています。
 
###TCP/IPの階層モデル

　`TCP/IP`における階層モデルは4階層から構成されています。下記図のように、アプリケーション層、トランスポート層、ネットワーク層、ネットワークインターフェース層の4つです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/72f48766-6a9d-057b-887b-7cb092a4f8dd.png)


 コンピュータ間で通信する場合、送信側のコンピュータでは「アプリケーション層」→「トランスポート層」→「インターネット層」→「通信ケーブル」の順番でカプセル化を行いデータが創出されます。
　また、受信側のコンピュータでは「通信ケーブル」→「ネットワークインターフェース層」→「インターネット層」→「トランスポート層」→「アプリケーション層」の順番で非カプセル化を行っています。
　

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/d1cd3b73-be05-b0ba-c9e5-0cebd26b27c0.png)




##HTTPについて

　`HTTP`(HyperText Transfer Protocol)とは、HTMLなどのコンテンツの送受信に用いられる通信の約束事です。
　
　`HTTP`はリクエストとレスポンスの通信を基本としています。下記に概要をまとめています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/4037853a-3fdd-b7f2-0b39-70c7333a0607.png)

　`HTTP`リクエストは、クライアントからサーバへの要求メッセージのことです。また、`HTTP`レスポンスはその要求を受けたサーバがクライアントへ返すメッセージのことです。




##TCP/UDPについて

続いて、`TCP`と`UDP`についてです。そもそもトランスポート層とは、データを正しく渡すための規定でした。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/66bfabe8-a172-8a4a-daa9-4b4deb7e8fce.png)

　同じ`IP`アドレスであってもどのアプリケーションにアクセスすべきかを規定する必要があります。
　ここでアプリケーション間のコネクションを確立する際にあ、ポート番号を用いて識別します。
　トランスポート層において重要なプロトコルに`TCP`と`UDP`があります。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/66bb7b98-93d7-d7c2-b55f-9f96d0628a4b.png)

　`TCP`と`UDP`は使用用途によって使い分けます。
　Webメールの送受信などの信頼性が求められる通信は`TCP`、リアルタイムの動画やり取りなどは`UDP`を使っていきます。

　


##IPについて

さて、最後にネットワーク層の代表的な`IP`についてです。
ネットワーク層とは、最終的な宛先のコンピュータにパケット（データを分割したもの）を届けることです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/9f7723cb-84d8-27d8-7961-21e3346a3a3e.png)


　上記に`IP`に関する代表的な役割を3つ挙げています。

　`IP`アドレスは`MAC`アドレスと異なり、個々のノードに付与される`IP`アドレスは状況によって変化します。`MAC`アドレスは`PC`製造時に決まり一生同じ値であるという差があります。

　



#終わりに

　今回、`TCP/IP`の概要とそれぞれの層における概要をまとめました。
Zabbix 5.0でslack通知を設定する

zabbix5.0でslackに通知を投げるのにはまったのでメモを残す。

https://www.zabbix.com/jp/integrations/slack
基本的には上記の通りに行えばいいが、いくつかはまりどころがある。

https://www.youtube.com/watch?v=3-ONmc43vMw
こちらの動画の通りにパラメータ設定すれば、うまくいく。


# 目的
- zabix 5.0のデフォルトメディアタイプ設定を利用してslackに通知を投げる。

# slackの設定
4.4ではIncoming webhookを使っていたが、5.0ではbotsを利用するように変更された。

## zabbix用Appを作成する
[Your Apps](https://api.slack.com/apps)からCreate New Appで新Appを作成する
App Nameはわかりやすい名前を、workspaceは投稿するworkspaceを設定する

Basic InformationのAdd features and functionalityでBotsを選択する。

「First, assign a scope to your bot token」と言われるので、セクション最後（又は左メニュー）のOAuth & Permissionsリンクを選択する。

ScopesセクションのAdd an OAuth Scopeで```chat: write```を追加する。
（用途によっては```chat: write.customize```、```chat: write.public```も追加する）
公式ドキュメントでは、作成後にslack側がOAuthの権限仕様を変更したらしく、この記述がない。

OAuth Tokens & Redirect URLsセクションでInstall App to Workspaceを選択する。

Bot User OAuth Access Tokenをコピーしておく

## チャンネルの設定
slack上で新規チャンネルを作成する。
チャンネル名がascii以外だと投稿できないので日本語名などつけないこと。
チャンネルのユーザーに作成済のbotを追加する。
```chat: write.public```がScopeにあればユーザー追加は不要。

# Zabbix側の設定
## マクロ設定
管理 -> 一般設定 -> マクロから```{$ZABBIX.URL}```を設定する。
これは、slack投稿された際に該当トリガーを開くためのリンクに使われる。
なので、zabbixのwebインターフェースURLのトップを設定する。
（テスト中でリンクがまともに動かなくてもいいなら```http://127.0.0.1/```とでもしておけばいい）

## メディアタイプ設定
管理 -> メディアタイプ からSlackを選択する。
デフォルト設定を残しておきたければ、複製を選択して別の名前を付ける。
```bot_token```に先ほどクリップボードにコピーしたBot User OAuth Access Tokenを設定する。(xorb-で始まる文字列）
```host_ip```が```{HOST.IP}```になっているが、後ろに何か文字を追加する。
```{HOST.IP} .```など
zabbix server自体のトリガーなどではHOST.IPが空の通知が来ることがあるのに、デフォルトのスクリプトではそれをイリーガルとしてはじいているため、これを設定する。

メッセージテンプレートタブに移って、テンプレートを追加する。
障害、障害復旧、障害更新あたりを最低追加しておく。
全部追加しても問題はない。（たった七種）

それ以外はデフォルト設定のまま追加（更新）を選択する。

## メディアテスト
管理 -> メディアタイプ から作成したslackメディアの右端にあるテストを選択するして、テストダイアログを開く。
```channel```に先ほど作成したチャンネル名(#で始まる文字列)を設定する。
```zabbix_url```に先ほど```{$ZABBIX.URL}```に設定したURLを設定する。
あとは、テストボタンを押す -> エラーメッセージに従って項目を修正する、を繰り返す。
だいたい数字を入れろというエラーなので、1を設定してまわればいい。
具体的な項目としては```event_id```、```event_nseverity```、```event_update_status```、```event_value```、```trigger_id```。
ここで0か1を設定しろというものに対して0を設定すると投稿できなかったりするので、各パラメータの意味をスクリプト読んでしっかり把握したい人以外は全部1を設定しておくのが無難。
テスト投稿が成功したら次へ進む

## ユーザーに割り当て

管理 -> ユーザーで適切なユーザーにslackメディアを追加する。

ユーザーを開いたらメディアタブ -> 追加
タイプを先ほど設定したslackのメディアタイプを設定する。
送信先に先ほどテストでchannelに設定したチャンネル名を設定する。
あとはデフォルト設定のまま追加を選択、ユーザーを更新or追加で設定する。



# 参考
https://www.youtube.com/watch?v=3-ONmc43vMw
https://www.zabbix.com/jp/integrations/slack
go修行1日目 九九表


## ディレクトリを作る

```bash
mkdir $(ghq root)/github.com/vampire-yuta/99
cd $(ghq root)/github.com/vampire-yuta/99
```

## main.goを作る

```golang

package main

import "fmt"

func main() {
	for i := 1; i <= 9; i++ {
		for n := 1; n <= 9; n++ {
			if i*n < 10 {
				fmt.Printf("  %d", i*n)
			} else {
				fmt.Printf(" %d", i*n)
			}
		}
		fmt.Println()
	}
}
```

## ビルド

```
go build 99.go
```

## 実行

```
~/g/s/g/v/99 ❯❯❯ ./99
  1  2  3  4  5  6  7  8  9
  2  4  6  8 10 12 14 16 18
  3  6  9 12 15 18 21 24 27
  4  8 12 16 20 24 28 32 36
  5 10 15 20 25 30 35 40 45
  6 12 18 24 30 36 42 48 54
  7 14 21 28 35 42 49 56 63
  8 16 24 32 40 48 56 64 72
  9 18 27 36 45 54 63 72 81
~/g/s/g/v/99 ❯❯❯
```

## 参考
https://qiita.com/Solpha/items/757c070f1e122a97ce69