OmniAICreator/Qiita-1.07M huggingface dataset:
X-Frame-OptionsにALLOW-FROMを設定するときはスラッシュを忘れずに

## はじめに

本記事は、特定のドメインのコンテンツをiframeで読み込みを許可する設定を実装していた際に、なかなか辿り着かなったX-Frame-Optionsの設定方法のメモです。

## メモ

Content Security Policyの[frame-ancestors](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Security-Policy/frame-ancestors)を設定することがありますが、Internet Explorerは、frame-ancestorsは非対応のため、[X-Frame-Options](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/X-Frame-Options)で同様の設定が可能です。

Railsアプリにおいて、当初下記のように設定しました。

```ruby
config.action_dispatch.default_headers['X-Frame-Options'] = 'ALLOW-FROM https://test.jp'
config.action_dispatch.default_headers['Content-Security-Policy'] = 'frame-ancestors https://test.jp'
```

IE以外のブラウザでは、frame-ancestorsの設定が効きましたが、IEのみ下図のエラーが出てX-Frame-Optionsが効かない状況でした。

![unnamed.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481946/a3fd1f6c-6cdf-a450-a174-e61cbbf9746a.jpeg)

最終的に[RFC7034](https://datatracker.ietf.org/doc/html/rfc7034)に辿り着き、2.2.1項に設定例を見つけました。

> 2.2.1.  Examples of X-Frame-Options
> X-Frame-Options: ALLOW-FROM https://example.com/ 👈 スラッシュが付いている

スラッシュ付きに修正すると上手くiframeで表示されました。

```ruby
config.action_dispatch.default_headers['X-Frame-Options'] = 'ALLOW-FROM https://test.jp/'
config.action_dispatch.default_headers['Content-Security-Policy'] = 'frame-ancestors https://test.jp'
```

## まとめ

IE対応が必要で、X-Frame-Options ALLOW-FROMを設定する場合には、uriにはスラッシュを付けよう。
【初心者向け】クラスとインスタンスについて

簡単にクラスとインスタンスについて書いていきます！！

#クラスとは
・プロパティ(変数)とメソッド(関数)を持つオブジェクトで、いわゆる設計図のようなもの。
　→　プロパティは情報が入っている箱、メソッドは処理がまとめられている箱のようなイメージ。
・クラスのプロパティやメソッドにアクセスするときは、スコープ定義演算子「::」を使う。（PHPの場合）

#インスタンスとは
・クラスの定義をもとに作成された実体のこと。
・インスタンスを生成することをインスタンス化という。
・インスタンスのプロパティやメソッドにアクセスするときは、アロー演算子「->」を使う。（PHPの場合）

#コード記述例
```php
class クラス名 {
   public $プロパティ名;
   
   public function メソッド名 () {
          ~~~ 処理 ~~~
   }
}

$インスタンス名 = new クラス名();
$インスタンス名->プロパティ名 = 値;
$インスタンス名->関数名(); 
```

#最後に
クラスとインスタンスについては、車の設計図と車本体に例えている記事をよく見ますが、とてもイメージがわきやすいですね！！
【Python】globで取得したファイルリストの並び替え

# globで取得したファイルリストの並び替え

glob.glob()でファイルを読み込んだ際, ファイル名の順番に困ったことはないでしょうか？

そんなときは,**「natsort」**というライブラリを使うと便利です.

フォルダの構造はこんな感じ

```
hoge/
　└ data/
　 　├ 1-a_n.wav
　 　├ 2-a_n.wav
　 　├ 3-a_n.wav
  ├  ．．．
  ├ 2575-a_n.wav
  └ 2576-a_n.wav
```

まず, pipでインストール

```
pip install natsort
pip install glob
```

####1. ひとまず, globでファイルリストを取得

```py
import glob
filepath = 'data/'
filelist = glob.glob(filepath + '*.wav') # jpg, png, csvなどお好みで
filelist
```

↓のように, ファイルの順番がでたらめ

```
['data/1034-a_n.wav',
 'data/43-a_n.wav',
 'data/1126-a_n.wav',
 'data/124-a_n.wav',
 'data/1703-a_n.wav',
 'data/993-a_n.wav',
 'data/701-a_n.wav',
 'data/1883-a_n.wav',
  ．．．
```

きちんと, 番号順に並べたい...
####2. natsortを追加！

```py
import glob
from natsort import natsorted

filepath = 'data/'
filelist = glob.glob(filepath + '*.wav')
new_filelist = natsorted(filelist)
new_filelist
```


実行すると, 

```
['data/1-a_n.wav',
 'data/2-a_n.wav',
 'data/3-a_n.wav',
 'data/4-a_n.wav',
 'data/5-a_n.wav',
 'data/6-a_n.wav',
 'data/7-a_n.wav',
 'data/8-a_n.wav',
  ．．．
```
番号の小さい順にできました！

####参考 (sortの場合)

```py
import glob

filepath = 'data/'
filelist = glob.glob(filepath + '*.wav')
new_filelist = sorted(filelist)
new_filelist
```
```
['data/1-a_n.wav',
 'data/10-a_n.wav',
 'data/100-a_n.wav',
 'data/1000-a_n.wav',
 'data/1001-a_n.wav',
 'data/1002-a_n.wav',
 'data/1003-a_n.wav',
 'data/1004-a_n.wav',
  ．．．
```
sortでは, 辞書順に並び替えられます.
n進数について　[n進数の足し算・引き算]

#２進数の計算方法

**そもそもPCは足し算しかできない**

<font color="red">これはPCがなるべくシンプルに物事を考えるため</font>





##2進数の足し算

１１１１　＋　１０１　＝　１０１００

![スクリーンショット 2021-08-18 21.20.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/0e78306b-6440-c1f8-6171-92d580f2a306.png)




<font color="red">※単純に足していくが、２進数は０と１しか使えない
つまり１＋１＝１０になるので、繰り上がって答えはこうなる</font>

##補数

**そもそも足し算しかできないPCが、どのように引き算を行うか**

それは・・・
　　　　　　　<font color="red">**補数**</font>を使う

**補数とは**

１０進数で見ると

例）５５６という数字がある

１０進数で見ると
５５６　　　１０００（次の桁）→ １０００　−　５５６　＝　４４４

つまり
５５６　＋　４４４　＝　１０００　となる

**要は次の桁に行くために足す数字が１０の補数**
この<font color="red">”４４４”</font>が<font color="red">１０の補数</font>

##２進数の引き算

**基本的な決まり事**
・数値は８ビットで表す
・先頭が”０”→正の数
　　　　”１”→負の数



**２進数の引き算とは**

１０進数と同じく、補数を足すことで次の桁に行く

が、

８ビットで表す決まりなので、９ビットになれば**桁あふれする**

![スクリーンショット 2021-08-18 22.02.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1803385/0c164144-4246-9277-be49-5e5d2825eecf.png)

この計算は２進数の

３　＋　（−３）＝　０
※”１１１１１１０１”がなぜ”−３”なのかは次項で説明

”０”となるには８ビット全て”０”とならなければダメ

<font color="red">８ビットを見ると全て０になっている</font>

**２進数の補数**

例）　００００００１１という数字がある　　　
１０００００００（次の桁）→ １００００００００　−００００００１１＝１１１１１１０１

つまり
００００００１１　＋　１１１１１１０１　＝１００００００００
　　　↓
<font color="red">”３”は２進数で”１１”
”３”を”０”にするために足すものは”−３”しかない</font>


**２進数では、次の桁に行くために足す数字は２の補数という**
この<font color="red">”１１１１１１０１”</font>が<font color="red">２の補数</font>

##要するに

<font color="red">**引きたい数字の補数を足してやると答えが出る**</font>

##法則

３　→　００００００１１　　　
　　　　　　　↓
　　　　１１１１１１００　　　　　　”０”と”１”を反転させる
　　　　　　　↓
−３  →　１１１１１１０１　　　　　　最後に”１”を足す

**これで２の補数を求められる**

例）
※２進数は４桁で表現

１０進数
５　− 　３　＝　２

２進数
０１０１　− ００１１

０１０１　＋　　（−００１１）

０１０１　＋　　１１０１　　　←２の補数に（−３）

０１０１　＋　　１１０１　　＝　　１００１０
　　　　　　　　　　　　　　　　　↓
　　　　　　　　　　　　４桁なのでここは桁あふれ

よって　”００１０”←”２”となる


>参考書籍
>>きたみりゅうじ 『キタミ式　イラストIT塾　基本情報技術者　令和０３年』 技術評論社 2020年
Reactで無限スクロール

##概要
Reactで無限スクロールをしたかったけど一から作るのは面倒だった。
検索しているとすでに用意されていた！

https://github.com/danbovey/react-infinite-scroller

##使い方

###react-infinite-scrollerのインストール
READMEに記載の通りまずはインストール
今回はnpmで行った

```
npm install react-infinite-scroller --save
```

###ファイル編集
importを追加

```
import InfiniteScroll from 'react-infinite-scroller'
```

InfiniteScrollタグを追加

```javascript:hoge.js
class Hoge extends Component {
  // 省略
  async loadMore() {
    // スクロールした時に読み込み処理
  }

  render() {
    // 省略

    const loader = <div className="loader">Loading ...</div>

    return (
      <InfiniteScroll
        loadMore={this.loadMore.bind(this)}
        hasMore={true}
        loader={loader}>

        // 表示する項目はここに書く
      </InfiniteScroll>
    );
  }
}
```

loadMore：スクロール時の読み込み処理
hasMore：読み込むかどうかの判定、falseで読み込まない
loader：読み込み時のローディング表示
無効になったダイナミックディスクからデータ回収

## 要約
ダイナミックディスク化によりミラーリングしていたHDDが「無効なディスクです」になったが、Acronis True Image 2019でデータ回収出来た。

## 環境
+ Windows 10 Home(21H1)
+ Acronis True Image 2019
+ パーティションを切ってからダイナミックディスクに変換したか、ダイナミックディスクにしてからパーティションを切ったかでディスクの構成と復元の難易度が異なるらしいが、前者。
+ GPTかMBRかよく覚えていないのだが、MBRだった気がする。

## 現象
2TBのHDDを2台ダイナミックディスクでミラーリングしており、先頭のUEFI領域?以外に200GBをOS、データとバックアップにそれぞれ900GBのパーティションを切っていた。

事情によりシステムを解体したので、HDDは取り外してそのままにしていたが、保管スペースが足りないので2台のうち1台は廃棄してしまった。

しばらくして、このHDDに保存していたデータが必要になったので、別のマシンにこのHDDを接続したら、「無効なディスクです」と表示された。UEFI用のパーティションも含めてミラーリングしていたので2台ともまったく同じドライブだと思っていたが、ドライブ構成の情報が一方にしかないらしい。もしかしたら他に原因があるのかもしれないが、ダイナミックディスクに関する情報は少なく、これ以上はよく分からなかった。

## 検討内容
### Windows 10 Pro
元のシステムはWinodows 10 Proだったのだが、Windows 10 Homeのシステムに接続しようとしていた。~~Windows 10 Homeはダイナミックディスクに対応していないとのことで、~~別のWindows 10 Proにつなぎ直したが、やはり「無効なディスク」のままであった。

### バイナリエディタ
バイナリエディタでディスクの情報を書き換えるとベーシックディスクに戻せるという[記述も見られた](http://www.corso-b.net/itaya/TIPS/DDtoBD/index.html)が、複雑そうな上にMBRとGPTで手順が異なっていた。先述のようにMBRかGPTかも思い出せない状況なので試してみる気が起きず、ディスクユーティリティソフトを探す方針にした。

### EaseUS
「ダイナミックディスク 復旧」で検索すると真っ先に名前があがるのが[このソフト](https://jp.easeus.com/file-recovery/dynamic-disks-recovery.html)。どうも無料でダイナミックディスクの復元ができるっぽい。.comドメインだが調べてみると[開発企業が中国籍](https://jp.easeus.com/company/overview.html)らしい。

フリーウェアにアドウェアが付いてきた経験があるので、有償製品を軸に探し直すことにした。

### ファイナルデータ
実績と歴史のある[日本企業の有償製品](https://www2.finaldata.jp/trial-fd/)。もちろん有償製品だから安心という保証はないが、より少ないリスクが見込まれる手段があるなら優先してみるという程度の判断。

ダイナミックディスクの復元ができるのか確認するため、試用版をダウンロードしてドライブをスキャンするとパーティションの復元候補が表示されたのだが、パーティションの数が本来の数より多い。HDDはアラインメント調整のためパーティションの間に数MBの隙間があるものだが、どうもその隙間を(先頭に)含めたものと含めないもの両方が復元候補に挙がるらしい。

~~復元内容を別のドライブに書き出せるなら試しても良かったのだが、パーティション開始位置を間違えて復元すると致命的なことになりそうだったので、ドライブをクローニングしてから試みる予定にした。~~OKのボタンを押さなかったので気づかなかったが、別のドライブにしか復元できない仕様だった(2021/9/23訂正)。

### [Acronis True Image 2019](https://www.acronis.com/ja-jp/support/documentation/ATI2019/)
2019となっていることから分かるように、もともと別の用途で持っていた。本当はファイナルデータで試すためにディスクのセクタ単位のクローニングをしようと思っていたのだが、「無効なディスク」はクローニングの対象に出来なかった。

ところがバックアップの対象にはできるらしく、バックアップのメニューには分割したパーティションがしっかり表示されていた。ただし、ファイナルデータでの解析結果だと先頭にUEFI用の領域があるっぽいのだが、それは表示されなかった。必要な情報のあるパーティションを選択してバックアップし、バックアップから復元すると目的のファイルを取り出すことが出来た。

## 考察
ダイナミックディスクは[現在では非推奨](https://docs.microsoft.com/ja-jp/windows-server/storage/disk-management/change-a-dynamic-disk-back-to-a-basic-disk)ということになっているらしい。OSに追加インストール無しでRAIDできるのでお手軽に始めてみたが、始めるのは簡単でも元に戻すのは至難の業という罠。

## 改訂履歴(表現の修正などは除く)
+ 2021/8/14: 執筆開始。
+ 2021/8/18: 公開。
+ 2021/8/19: 要約などを追加。
+ 2021/9/23: ファイナルデータの仕様を訂正。
dockerでpytorch 立ち上げ #memo



シンプルなtorch170のdockerの環境です。

環境：titanV
実行コマンド：nvidia-docker build --no-cache -t torch171_cu101 .


```
FROM nvidia/cuda:10.1-cudnn7-devel-ubuntu18.04

ARG use_cudnn=1

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get -y update
RUN apt-get -y install \
    sudo \
    apt-utils \
    git \
    curl \
    vim \
    unzip \
    wget \
    build-essential \
    cmake \
    libopenblas-dev \
    automake \
    openssh-client \
    openssh-server \
    lsof \
    python3.6 \
    python3-dev \
    python3-pip \
    python3-tk \
    libcupti-dev
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/*

#
# generate python script
#
RUN ln -s python3 /usr/bin/python
#
# update pip
#
RUN python3 -m pip install --upgrade pip==20.2.4 setuptools==50.3.2

# numpy 1.14.3  scipy 1.1.0
RUN python3 -m pip --no-cache-dir install numpy==1.14.3 scipy==1.1.0

RUN pip install torch==1.7.0+cu101 torchvision==0.8.1+cu101 torchaudio==0.7.0 -f https://download.pytorch.org/whl/torch_stable.html 

# RUN wget https://pypi.flyai.com/packages/c2/36/e9c43cfa694562954e7ae05d553f757b69beab6e2860faa46504a95ff489/nni-2.0-py3-none-manylinux1_x86_64.whl#sha256=fad8139253660e2ec72cfe2c8769e5c7bb4e909fea0baccfbfb088c6ff85f021
# RUN python3 -m pip install nni-2.0-py3-none-manylinux1_x86_64.whl

WORKDIR /root
```
GAS 基本編メモ①

ドットインストールでGASの勉強を始めました。
簡単なメソッドから勉強していっていますので、勉強用に使用したGASのメモを残しておきます。
自分用なので特に説明がありません。

## カスタム変数

```javascript
function GETRESULT(input) {
  if (input >= 80) {
    return 'PASS';
  } else {
    return 'FAIL';
  }
}
```

## カスタム変数 (複数のセルを扱う際)

```javascript
function GETRESULT(input) {
  if (input.map){
    return input.map(GETRESULT);
  } else {
    return input >= 80 ? 'PASS' : 'FAIL';
  }
  // if (input >= 80) {
  //   return 'PASS';
  // } else {
  //   return 'FAIL';
  // }
}
```

## スプレッドシートの操作

```javascript
# アクティブなシートを選択？
function initSheet() {
  var sheet = SpreadsheetApp.getActiveSheet();

# シートを一度白紙にする
  sheet.clear();

# セルを選択、そのままvalue(値)を記入
  sheet.getRange(1, 1).setValue('taguchi');
  sheet.getRange(1, 2).setValue(82).setBackground('tomato');
}
# 背景色を変えたい時の記入。同じセルに効かせたい時は続けて書く。
```

## 繰り返し処理

```javascript
# 繰り返し処理のための変数定義 i
function initSheet() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var names = ['taguchi', 'fkoji', 'dotinstall'];
  var i;

  sheet.clear();

# i++ で　１ずつ増やしている
  for (i = 1; i <= 100; i++) {
    sheet.getRange(i, 1).setValue(names[Math.floor(Math.random() * names.length)]);
    sheet.getRange(i, 2).setValue(Math.floor(Math.random() * 101));
  }
}
# Math.floorは小数点以下を切り捨てるメソッド
# Math.randomは乱数を発生させるメソッド
```
未経験からテックキャンプに通っての感想

2021年３月から約３ヶ月間テックキャンプに通っていました。
未経験からエンジニアになろうとしている方、テックキャンプへの入学に迷っている方の参考に少しでもなれば幸いです。

#授業形態
コロナ真っ只中ということもあり、全てオンラインでの受講でした。
授業というよりカリキュラムを進めながらわからないところや詰まったところは都度、ビデオ通話でメンターさんに聞けるというスタイルで、人によって相性があると思いますが自分のペースで進められるという意味ではやりやすい形態だと思います。メンターさんもほぼ全ての人が優しく丁寧に教えてくれるので質問しやすいですし、質問回数に上限もないので通常の授業形式より学びやすいというのが個人的な感想です。
#スタッフの方
テックキャンプに入学して関わるスタッフの方はライフコーチ１名、キャリアアドバイザー１名、メンターの方々になります。
これはどんな方が担当になるか運な部分もあると思いますが、自分は恵まれていたのか関わるスタッフの方は全て熱心で優しい方でした。自分の場合は少し特殊で開始してから２週間後にチームが合併になったので実質２名のライフコーチにお世話になりましたが、２人とも毎日有益な情報やモチベーションを維持させてくれるような言葉をくださり、非常にありがたかったです。
#１日の流れ
まず朝１０時にチームメンバーとの朝礼があります。ここで５分間瞑想を行い、その後毎朝送られるドリルを解く時間があります。この２つがルーティンとなってやる気が出ない日でも自動的に学習モードに脳が切り替わります。
その後は各自それぞれカリキュラムを進め約５０分毎くらいにアウトプットの時間があります。ここでその時間に自分が学んだ内容をアウトプット相手に１分間ほど説明します。個人的にはこのアウトプットが実に有益で、自分の口で説明することでただ闇雲に暗記するより格段に記憶に残るように感じました。
その流れを２０時前まで繰り返し基本的な1日は終了です。ただ、メンターさんへの質問は２２時まで可能となっています。
#テックキャンプに入学して良かったと思うこと
授業や学習で得られたことや他のスクールと比べての意見は人それぞれ感じ方が違うと思うのであえてここでは書きません。
自分はテックキャンプでの３ヶ月でのチームメンバーとの出会いが一番大きな収穫だったと思います。
同じ時期に同じ目標を持っているということも大きいですが自分の場合、特に素晴らしい仲間とチームメンバーになれたことがテックキャンプに入って良かったと思える一番の理由です。
これからテックキャンプへの入学を選択肢に入れている方もぜひアウトプットの時間やチームとの交流の時間にコミュニケーションをとって素晴らしい仲間に巡り合ってほしいと思います。
VLSMとは

## 勉強前イメージ

ネットワーク系のなにかの用語だった気がする・・・

## 調査

### VLSMとは

`Variable Length Subnet Mask` の略で、
可変長サブネットマスクのことです。
ネットワークアドレスとホストアドレスの大きさを自由に変えて必要に応じたIPアドレスを利用できるようにしたもので、
例えば2台のホストしかないネットワークにクラスCのアドレスと無駄が増えるので、
必要な分だけ割り振れるようにサブネットマスクを変更したものです。

### CIDR とは

似たような用語でCIDRというものがあります。
こちらに関しても確認します。

`Classless InterDomain Routing` の略で、
IPネットワークの経路情報を集約する際にクラスの概念をなくした技術のことで、
複数のクラスCアドレスを1つのネットワークに集約することができます。

例えば
5.0.0.0 - 5.0.255.0 のIPアドレスを割り振るときに
5.0.0.0/24 として扱うことが出来ます。

元々は以下のクラスごとにIPアドレスを配っていました。

- 0.0.0.0 - 127.255.255.255 → クラスA
- 128.0.0.0 - 191.255.255.255 → クラスB
- 192.0.0.0 - 223.255.255.255 → クラスC

しかしそれでは配布し尽くしてしまう可能性が出てきたので、
クラス分けを廃止して任意のbit長でIPアドレスを割り振るようになりました。
これがCIDRになります。

### VLSMとCIDRの違い

- VLSM : 1つのネットワークを小さなサブネットに分ける
- CIDR : 複数のネットワークを1つにまとめる

## 勉強後イメージ

小さなサブネットに分けるというところにも用語があるって知らなかった

## 参考

- [IP address - VLSM / CIDR / ip subnet-zero](https://www.infraexpert.com/study/ip8.html)
- [【絶対分かる!】CIDR/VLSM/FLSMの違い、classful/classlessの違い、RIPv1/v2の違い　～サブネットマスクの進化～](https://milestone-of-se.nesuke.com/nw-basic/ip/cidr-vlsm-flsm-subnet/)
- [VLSM](https://www.weblio.jp/content/VLSM)
【備忘録】プルリク(Pull Request)の手順

# 手順

#### 1. GitHubでリポジトリのメインページにアクセス

#### 2. Codeボタンをクリック

#### 3. URLをコピー

Clone with HTTPSの下にあるURLをコピー。

#### 4. ターミナルを開く

#### 5. カレントワーキングディレクトリをクローンしたい場所に変更

```
（例）
cd ~/project
```

#### 6. git clone と入力して前の手順でコピーしたURLを貼り付ける

```
（例）
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
```

#### 7. Enterを押してローカルクローンを作成

```
（例）
$ git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
> Cloning into `Spoon-Knife`...
> remote: Counting objects: 10, done.
> remote: Compressing objects: 100% (8/8), done.
> remove: Total 10 (delta 1), reused 10 (delta 1)
> Unpacking objects: 100% (10/10), done.
```

#### 8. Pull Request用のBranchを作成

```
①cloneしたディレクトリに移動
$ cd ~/project/YOUR-REPOSITORY

②developという名前のBranchを作成
$ git checkout -b development
```


#### 9. Cloneしたディレクトリを編集

```
①現在のフォルダをVSCodeで表示
$ code .

②編集
略
```


#### 10. ローカルでadd⇒commit、Githubへpushする

```
①編集ファイルをステージングに移す
$ git add .

②編集ファイルをcommitする
（例）
$ git commit -m "modified README"

③developブランチからGithub上のoriginブランチにpushする
$ git push origin development
```


#### 11. Github上でPullRequest

```
①右上の緑色のCompare & pull requestボタンをクリック

②どういった変更を加えたのかを説明する内容を記入
（例）コメントにHello!!!をつけました

③どのブランチからどのブランチにpull requestするかを確認する
※developブランチからmasterブランチへのpull request

④緑色の[Create pull request]ボタンを押して、Pull Requestを作成
```

#### 12. Github上でMergeする

※通常この作業は、自分以外のレポジトリ管理者がコードを確認して実行する。

```
①左下の緑色の[Merge pull request]ボタンを押して、Mergeを実行する
```

これで本番環境に反映される。

▼参考にさせていただいた記事

https://qiita.com/matsukazu1112/items/1633e7392c827c03d533

https://qiita.com/samurai_runner/items/7442521bce2d6ac9330b

https://qiita.com/maedatakumi/items/2683da7286d3d9b242eb
SpringBootアプリをService(デーモン)として起動する方法

# はじめに
SpringBootアプリは「java -jar」コマンドで実行できますが、ログアウトするとアプリが停止します。
起動し続けるためにはサービスとして起動させる必要があります。
今回はSpringBootアプリケーションをService(デーモン)として起動する手順を記載します。
※デーモンとは常駐プログラムのUNIX系OSにおける呼び名です。

# 環境
OS：CentOS7

# 手順
1. Fully Executable Jarの作成
2. confファイルの作成
3. Service(デーモン)の登録
4. Service(デーモン)の自動起動設定

# 1. Fully Executable Jarの作成
SpringBootアプリを常駐させるために通常のjarファイルは起動スクリプトを書く必要があるが、
Fully Executable Jarは起動スクリプトが組み込まれています。

作成方法は、pom.xmlに次のようなの<build>タグを追加します。

```xml:pom.xml
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <executable>true</executable>
            </configuration>
        </plugin>
    </plugins>
</build>
```

# 2. confファイルの作成
起動するjarファイルと同名で拡張子を`.conf`に変えたファイルを作成します。
![confファイル作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1798422/a2d07b11-1410-33d7-0bd7-a752aeaa3662.png)
.confファイルに環境変数の定義、javaオプション、jarの実行時引数を記載します。
環境変数は`export`、Javaオプションは`JAVA_OPTS`、jarの実行時引数は`RUN_ARGS`で定義します。

```:.conf
export LANG="ja_JP.UTF8"
JAVA_OPTS="-Xms1024M -Xmx1024M"
RUN_ARGS="--spring.profiles.active=production"
```

# 3. Service(デーモン)の登録
Service(デーモン)の登録は`/etc/systemd/system/`にserviceファイルを作成します。
任意のファイル名でオッケーです。

```:/etc/systemd/system/hoge.service
[Unit]
Description = サービスの説明

[Service]
ExecStart = /opt/bin/hoge.jar  // 起動jarのファイルパス
Restart = always
Type = simple
User = root
Group = root
SuccessExitStatus = 143

[Install]
WantedBy = multi-user.target
```

Service(デーモン)を再読み込みします。

```:Service(デーモン)再読み
$ sudo systemctl daemon-reload
```

Service(デーモン)を起動します。

```:起動
$ sudo systemctl start hoge
```

起動を確認します。
「Active: active (running)」になっていればオッケーです。

```:起動確認
$ sudo systemctl status hoge

hoge.service - hoge
   Loaded: loaded (/etc/systemd/system/hoge.service; disabled)
   Active: active (running) since Mi 2021-08-18 15:20:57 CEST; 4min 18s ago
```

Service(デーモン)を停止する場合は次のコマンドを実行します。

```:停止
$ sudo systemctl stop hoge
```

# 4. Service(デーモン)の自動起動設定
サーバー起動時にService(デーモン)を自動起動したい場合は以下の設定をします。

自動起動を有効にする場合は次のコマンドを実行します。

```:自動起動の有効
$ sudo systemctl enable hoge.service
```

自動起動設定を確認します。

```:自動起動設定の確認
$ sudo systemctl list-unit-files -t service
```

自動起動を無効にする場合は次のコマンドを実行します。

```:自動起動の無効
$ sudo systemctl disable hoge.service
```
AWS CLIとShellであれこれするTips

# これは何？
- 調査タスクで書いているAWS CLIのケース集
- 運用に組み込むならリファクタリングしたほうが良い
    - リソースの数だけLoopしながらAWS CLIを叩いているものもある
    - 標準エラー出力まわりの処理が雑
- AWS CloudShellで実行する前提で書いています
    - デフォルトでAWS CLIとjqなどが入っている＆いちいちAWS_PROFILEやMFA対応しなくて良いので楽
    - ローカルで実行したい場合は^を指定するオプションを適宜加えてくださいね
- 表に出せるコードに書き直してから追記していきます。きっと。


# ケース集
## [EIP]AWS Resourceに紐付けられていないEIP一覧を取得する

```
aws ec2 describe-addresses |jq -c '.Addresses[] | select(.InstanceId | not) | [.PublicIp, .AllocationId]'
```

下記のように一覧される。^のnotを外せばAWS Resourceに紐付いたEIP一覧になるよ。
```
..(snip)..
["52.xxx.xx.xxx","eipalloc-xxx"]
["52.xxx.xx.xxx","eipalloc-xxx"]
["52.xxx.xx.xxx","eipalloc-xxx"]
..(snip)..
```

## Tips
- jqのnotはbooleanを返す。Select対象が存在しない場合はfalseを返すので超便利

## [EIP]AWS Resourceに紐付いたEIP一覧を取得する

[[EIP]AWS Resourceに紐付けられていないEIP一覧を取得する](https://qiita.com/nntsugu/items/cef659e9ca4dd9e39820#eipaws-resource%E3%81%AB%E7%B4%90%E4%BB%98%E3%81%91%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84eip%E4%B8%80%E8%A6%A7%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B)
のjq中のnotを外せばOK
T系インスタンスについてざっくり理解する

# はじめに
AWS EC2には、T3,M4,C4など様々なインスタンスタイプがありますが、
ややクセがあるT系のインスタンスタイプについて理解が深まる機会があったので
そちらについて書いておこうと思います。

# T系インスタンスとは
・T2インスタンス
>T2 インスタンスは、ベースラインレベルの CPU パフォーマンスを提供するバースト可能パフォーマンスインスタンスで、ベースラインを超えるレベルにパフォーマンスをバーストさせる機能を備えています。

・ T3インスタンス
>T3 インスタンスは、ベースラインレベルの CPU パフォーマンスを提供する次世代のバースト可能な汎用インスタンスタイプで、いつでも必要な時間だけ CPU 使用率をバーストさせる機能を備えています。T3 インスタンスはバランスの取れたコンピューティング、メモリ、およびネットワークのリソースを提供し、使用中に一時的なスパイクが生じる中程度の CPU 使用率を持つアプリケーション向けに設計されています。

以上が公式ドキュメントからの引用になります。
簡単に言えば、普段はしょぼい（ベースラインレベルCPU）けど
必要に応じてパワーアップ（バースト可能）できるよって理解でいいかと思います。

そこでパワーアップする際に重要になるのが「CPUクレジット」という考え方。

# CPUクレジットとは
T系インスタンスは、
CPUスペック(ベースラインレベル)を超えてCPUを稼働させる(バースト)ことができ、
その処理の際にCPUクレジットが消費されます。
（100%のｖCPU使用率の場合、１分間で１CPUクレジットが消費される)

CPUクレジットは、インスタンスが起動している間、１時間ごとに
おこづかいのように獲得できるものになります。
（t2.microの場合、１時間に6CPUクレジットがもらえる）

そして、インスタンスを停止した場合、
CPUクレジットの残高は引き継がれないためまた0からスタートになります。
（T3は7日間だけ維持され、その後0になる)

# T系インスタンスでのパフォーマンスが出ない
つまり、このおこづかい(CPUクレジット)の獲得数より、消費数の方が
恒常的に多くなってしまっている場合、ベースラインのでの動作になってしまいます。
対応策としては２つ
①無制限（Unlimited）に変更する。
（T3はデフォルトで無制限になっています。変更も可能です）
②T系ではない、M系などのインスタンスタイプに変更する。
（よりCPUリソースを必要とする場合は、C系など）

①の変更方法
対象のインスタンスを選択した状態で、「アクション」→「インスタンスの設定」→「クレジット仕様の変更」の画面から「無制限モードを有効にする」にチェックを入れ保存します。
（T3の場合は、ここがデフォルトでチェックが入っている）
![スクリーンショット 2021-08-18 21.47.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/598a7310-4748-801b-bdf2-ffb70dbf2285.png)

![スクリーンショット 2021-08-18 21.49.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/e5e1a09a-be40-3076-0bea-7fcf7474e912.png)

ただ注意点として、変更の画面にもありますが、
無制限になるということは、「おこづかいを前借り」しているような状態なので
前借りしている分の料金が追加で発生してしまうことに注意が必要です。

# 実際にモニタリングしてみた
起動したあとにstressコマンドで負荷をかけた状態がコチラ↓
![スクリーンショット 2021-08-18 21.27.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/348fc6ad-1bc7-4902-0e64-b04a7bf5e88c.png)
![スクリーンショット 2021-08-18 21.27.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/26c8cfd0-81e1-fc49-13f0-b47cc1813d3c.png)

CPU使用率が100%に達した、
やや後にCPUクレジット使用量が上がっているのがわかるかと思います。

![スクリーンショット 2021-08-18 21.26.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/575134/d67e067e-d377-8e0b-4396-6bb2b94c697b.png)

CPUクレジットの残高は、起動した後から獲得されるため
最初はやや右肩上がりですが、CPU使用率が100%に達しはじめた18:15頃から
グングンと下がっている（CPUクレジットが消費されている）のがわかるかと思います。

# まとめ
T系インスタンスを使っているときに、
恒常的にCPU使用率が100%に張り付くような場合は
インスタンスタイプの変更を検討しましょう。

# 引用
https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/burstable-credits-baseline-concepts.html

https://tech.smartcamp.co.jp/entry/aws-ec2-t2-unlimited
Pythonでテキストファイルの途中に追記

テキストファイルの2行目に「あいうえお」を追記します。

追記前

```ruby:text.txt
ヘッダー
かきくけこ
さしすせそ
たちつてと
なにぬねの
はひふへほ
まみむめも
やゆよ
らりるれろ
わをん
```

実装方法

全行取得
↓
途中に挿入
↓
既存のファイルデータを全削除
↓
ファイルの先頭にストリーム位置を移動
↓
書き込み

という流れにします。

```python

# ファイルの2行目に追記。
import os

with open('text.txt', 'r+', encoding='utf-8') as file:
    # 全行取得
    line = file.readlines()
    # 途中に挿入
    line.insert(1, 'あいうえお\n')
    # ファイルデータ全削除
    file.truncate(0)
    # 先頭にストリームを移動
    file.seek(0, os.SEEK_SET)
    # 書き込み
    file.writelines(line)
```

追記後

```ruby:text.txt
ヘッダー
あいうえお
かきくけこ
さしすせそ
たちつてと
なにぬねの
はひふへほ
まみむめも
やゆよ
らりるれろ
わをん
```


全データ取得して全削除するのでメモリの無駄遣いな気もするんですが、他にいい方法がわかりませんでした。

100万行くらいまでであればそれほど問題ないですかね（印象）。
docker起動時のエラー対処

##概要
docker起動時にエラーが発生したので対処方法を記載

##エラー内容
```
$ docker-compose up
ERROR: Named volume "postgres-data:/var/lib/postgresql/data:rw" is used in service "db" but no declaration was found in the volumes section.
```

##原因
docker-compose.ymlの記載ミスが原因だった。
volumesの設定で「./」を付け忘れていた。

###修正前
```ruby:docker-compose.yml
volumes:
- postgres-data:/var/lib/postgresql/data
```

###修正後

```ruby:Dockerfile
volumes:
- ./postgres-data:/var/lib/postgresql/data
```

##参考
https://obel.hatenablog.jp/entry/20191014/1571058968
基本情報技術者試験勉強0818

本日の積み上げ結果
基本情報技術者試験勉強
平成20年春過去問
平成20年秋過去問
間違えた問題の復習
AWSの本を読む

RASIS(レイシス)は、システムの信頼性を評価する5つの概念の頭文字を合わせた言葉です。
Reliability … 信頼性
故障を起こしにくさの度合い。評価指標としてMTBF(平均故障間隔)が用いられる
Availability … 可用性
必要な時に必要なだけシステムが使用可能状態である度合い。評価指標として稼働率が用いられる
Serviceability … 保守性
システム障害の時の修理しやすさの度合い。評価指標としてMTTR(平均修復時間)が用いられる
Integrity … 保全性・完全性
保存されているデータの完全であるかどうかの度合い
Security … 安全性・機密性
保存されているデータが、災害や障害などに対してもつ耐性の度合い。

スーパスカラ　複数のパイプラインを用いて，同時に複数の命令を実行可能にすることによって，高速化を図る方式である。

デザインレビュー　仕様の不備や誤りを早期に発見し，手戻り工数の削減を図る。

主記憶へのアクセスを伴う演算命令を実行するとき，命令解読とオペランド読出しの間に行われる動作　実効アドレス計算

デュプレックスシステム　2系統のシステムで構成され，一方は現用系としてオンライン処理を行い，もう一方は待機系として現用系の故障に備えている。通常，待機系はバッチ処理を行っている。

コンパイラによる最適化の主な目的　プログラムの実行時間を短縮する。

ボリュームライセンス契約　企業などソフトウェアの大量購入者向けに，マスタを提供して，インストールの許諾数をあらかじめ取り決める契約

ストアドプロシージャ機能　企業などソフトウェアの大量購入者向けに，マスタを提供して，インストールの許諾数をあらかじめ取り決める契約。

磁気ディスク装置の性能　アクセス時間は，回転速度を上げるか位置決め時間を短縮すると短くなる。

エキスパートシステム　知識ベースを利用して推論。

リスク分析　考えられるすべてのリスクに対処することは，時間と費用がかかりすぎるので，損失額と発生確率を予測し，リスクの大きさに従って優先順位を付けるべきである。

メモリインタリーブ　主記憶装置の高速化の技法として，主記憶を幾つかのアクセス単位に分割し，各アクセス単位をできるだけ並行動作させることによって，実効アクセス時間を短縮する方法。

PDPC 実施過程で起こりうる不測の事態を事前に予測しながら，計画の開始から最終結果に至る過程や手順を時間の推移に従って矢印で結合した図であり，試行錯誤を避けられない状況における最適策の立案に役立つ。

SNMP  TCP/IPの環境で使用されるプロトコルのうち，構成機器や障害時の情報収集を行うために使用されるネットワーク管理プロトコル。

NAT プライベートIPアドレスとグローバルIPアドレスを相互に変換する機能である。

CORBA 分散システム環境で，オブジェクト同士がメッセージを交換するための共通仕様である。

パケット交換方式　情報を幾つかのブロックに分割し，各ブロックに制御情報を付加して送信する方式であり，誤り制御は網で行う。

動的リンクライブラリ　アプリケーションの実行中，必要になったときにOSによって連係される。

POP3 メールサーバのメールボックスから電子メールを取り出すときに使用するプロトコルである。

シリアルATA ホットスワップ対応が可能である。

2進数の有限小数は，10進数にしても必ず有限小数になる。

HTTP 攻撃を防止するためにファイアウォールのIPパケットフィルタリングを設定する場合，フィルタリングルールでインターネットからDMZへのパケットの通過を禁止できないプロトコル。

トロイの木馬　データの破壊，改ざんなどの不正な機能をプログラムの一部に組み込んだものを送ってインストールさせ，実行させるもの。
RailsでECサイトのカート機能を実装する（改訂版）

## はじめに
[RailsでECサイトのカート機能を実装する](https://qiita.com/akmhmgc/items/a40b91aa4f469c397f85)
での
- URI設計
- コントローラーに寄りすぎたロジック
の二点を改善しました。

## ER図
Userモデルは除いています。
![ec.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1053396/483ee996-0db3-f64f-90ee-66c13d68ba40.png)


## Cart、Item、Productテーブルのmigrationファイルの作成
```
$ rails g model Cart
$ rails g model Product name:string price:integer
$ rails g model Item cart:references product:references quantity:integer
$ rails db:migarate
```

## ルーティング
```route.rb
  resources :carts, only: %i[create destroy] do
    resources :items, only: %i[create destroy update index], param: :item_id, controller: :cart_items
  end
```
- id:cart_idを持つCartを示すリソースのパスは`carts/:cart_id`
- id:cart_idを持つCartに関連するid:item_idを持つItemを示すリソースのパスは`carts/:cart_id/items/:item_id`
といった感じでRESTfulな設計にします。
ただ、cart/:idといった形で商品カートにアクセスできるインターフェースを用意するべきなのかどうかは疑問です。セッションで紐付けたcartしかアクセスしないのであれば`/cart`のパスと現在のカートを紐付けても良いかもしれません。


## モデル
```models/cart.rb
class Cart < ApplicationRecord
  has_many :items, dependent: :destroy

  #    カートアイテムの追加
  def add_item(product_id:, quantity:)
    # カートに入っていない商品を追加する場合はItemレコードを新規作成
    item = items.find_by(product_id: product_id) || items.build(product_id: product_id)
    item.quantity += quantity.to_i
    item.save
  end

  #    カートアイテムの更新
  def update_item(product_id:, quantity:)
    items.find_by(product_id: product_id).update(quantity: quantity.to_i)
  end

  #    カートアイテムの削除
  def delete_item(product_id:)
    items.find_by(product_id: product_id).destroy
  end

  #    カートの合計の算出
  def total_price
    items.sum("quantity*price")
  end
end
```

```models/item.rb
class Item < ApplicationRecord
  belongs_to :cart
  belongs_to :product
end
```
バリデーション等の処理を適宜追加します。


## コントローラー
モデルの時点でほぼ完成なのですが、一応カート内商品の操作周りのコントローラーは以下となります。

```app/controllers/cart_items_controller.rb
class CartItemsController < ApplicationController
  def index
    @total_price = my_cart.total_price
    @items = my_cart.items
  end

  def create
    if my_cart.add_item(product_id: params[:product_id], quantity: params[:quantity])
      # カートアイテムの追加に成功した時の処理
    else
      # 失敗した時の処理
    end
  end

  def update
    if my_cart.update_item(product_id: params[:product_id], quantity: params[:quantity])
      # カートアイテムの更新に成功した時の処理
    else
      # 失敗した時の処理
    end
  end

  def destroy
    if my_cart.delete_item(product_id: params[:product_id])
      # カートアイテムの削除に成功した時の処理
    else
      # 失敗した時の処理
    end
  end

  private

  def my_cart
    Cart.find(params[:cart_id])
  end
end
```
これらをViewで表示して完成です。
tableView Cell　右にスライドさせてボタンなどを表示

#今回の内容

<img width="150" alt="82068F31-ECB3-4B5C-9EF2-74611AA582F3_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/eca00a96-8021-1125-f838-b6c2eb20f899.jpeg"> 

#コードと簡単解説

* 右スライドでボタンを表示させる場合は`func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {}`を使用します。

```Swift:
    func tableView(_ tableView: UITableView, leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        
        let rightSlideMoves = { () -> [UIContextualAction] in
            
            let slideActionArray = [UIContextualAction(style: .normal, title: "01", handler: { _, _, _ in
                                    print("右のボタン01が押されました")}),
                                    UIContextualAction(style: .normal, title: "02", handler: { _, _, _ in
                                    print("右のボタン02が押されました")})]
            
            return slideActionArray
        }()
        
        rightSlideMoves[0].backgroundColor = .systemIndigo
        rightSlideMoves[1].backgroundColor = .systemBlue
        
        return UISwipeActionsConfiguration(actions: rightSlideMoves)
    }
```
#終わり
ご指摘、ご質問などありましたら、コメントまでお願い致します。
magentoが500エラーになっていたら行うこと

# はじめに
magentoが500エラーになっていたら下記を行うこと。

# 最終更新日
2021年8月25日

# 環境の情報
OS
ubuntu 20.04

# 実際に

```
cd /var/www/html/magento
find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +
find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
sudo chown -R :www-data . # Ubuntu
chmod u+x bin/magento
```

パーミッションの変更。
ファイヤーウォールを止める

ホスト側にて行う。

```
$ sudo /etc/init.d/firewalld status
● firewalld.service - firewalld - dynamic firewall daemon
     Loaded: loaded (/lib/systemd/system/firewalld.service; enabled; vendor preset: enabled)
     Active: inactive (dead) since Mon 2021-08-16 15:57:07 JST; 16s ago
       Docs: man:firewalld(1)
    Process: 22458 ExecStart=/usr/sbin/firewalld --nofork --nopid (code=exited, status=0/SUCCESS)
   Main PID: 22458 (code=exited, status=0/SUCCESS)
```
ファイヤーウォールの状態の確認。

```
 8月 16 15:54:59  systemd[1]: Starting firewalld - dynamic firewall daemon...
 8月 16 15:54:59 systemd[1]: Started firewalld - dynamic firewall daemon.
 8月 16 15:57:06 systemd[1]: Stopping firewalld - dynamic firewall daemon...
 8月 16 15:57:07 systemd[1]: firewalld.service: Succeeded.
 8月 16 15:57:07 systemd[1]: Stopped firewalld - dynamic firewall daemon.
```

```
$ sudo /etc/init.d/firewalld stop
Stopping firewalld (via systemctl): firewalld.service.
```
ファイヤーウォールを止める。
[Python]XMLファイルから特定要素を抽出する方法 メモ

* 特定のフォルダに配置されたXMLファイルの一覧から特定要素を抽出する方法についてメモする。


## テストデータ

* [こちら](https://docs.python.org/ja/3.6/library/xml.etree.elementtree.html)のXMLをテストデータとして利用させていただく。

* `test1.xml`

  ```xml
  <?xml version="1.0"?>
  <data>
      <country name="Liechtenstein">
          <rank>1</rank>
          <year>2008</year>
          <gdppc>141100</gdppc>
          <neighbor name="Austria" direction="E"/>
          <neighbor name="Switzerland" direction="W"/>
      </country>
      <country name="Singapore">
          <rank>4</rank>
          <year>2011</year>
          <gdppc>59900</gdppc>
          <neighbor name="Malaysia" direction="N"/>
      </country>
      <country name="Panama">
          <rank>68</rank>
          <year>2011</year>
          <gdppc>13600</gdppc>
          <neighbor name="Costa Rica" direction="W"/>
          <neighbor name="Colombia" direction="E"/>
      </country>
  </data>
  ```

  

## コード

* `test.py`
  * 本コードと同一階層に存在する`xmls`フォルダの`xml`ファイルを解析し、その結果を`result/cdata.csv`ファイルに保存する。
  * 上記テストデータの国名とランクを抽出する。

```python
import xml.etree.ElementTree as ET
import glob
import csv

# XMLファイル一覧取得
# 前提:同一階層のxmlsフォルダにxmlファイルを配置する
xmls = glob.glob('xmls/*.xml', recursive=True)

# 解析結果格納用リスト
cdata_list = []

# ファイルごとに解析する
for xml in xmls:
    # XMLファイルパース
    tree = ET.parse(xml)
    root = tree.getroot()
    # 子要素(country)解析
    for country in root:
        # 子要素の中身を解析
        name = country.attrib["name"]
        rank = ""
        for child in country.iter():
            # 特定要素の抽出
            if child.tag == 'rank':
                # ファイル名、国名、ランクを出力
                rank = child.text
                print(
                    f'{xml},{name},{rank}')
                cdata = [xml, name, rank]
                cdata_list.append(cdata)

# CSVファイルに保存
with open('result/cdata.csv', 'w', newline="") as f:
    writer = csv.writer(f)
    writer.writerows(cdata_list)

```



## 動作確認

* 実行

```shell
python test.py
xmls\test1.xml,Liechtenstein,1
xmls\test1.xml,Singapore,4
xmls\test1.xml,Panama,68
```

* CSV

```csv
xmls\test1.xml,Liechtenstein,1
xmls\test1.xml,Singapore,4
xmls\test1.xml,Panama,68
```



## 参考情報

* [【Python】XMLを読み取りするパターン(ElementTree)](https://pg-chain.com/python-xml-elementtree#toc3)
* [xml.etree.ElementTree](https://docs.python.org/ja/3.6/library/xml.etree.elementtree.html#module-xml.etree.ElementTree)
Power BI/Query で グレイコードを数値に変換

# 目的
グレイコードで計数されているデータが有って、単純に Bin2Dec じゃ当然ダメ。
特殊な為にな処理が必要だけど今どき流行らない？のか情報も少なめなんで、Power Query の実装例を残しておこう、と。

:::note info
Dec2Grayは必要なかったんで用意してません。欲しい場合はご相談を。
:::

## グレイコードとは
組込み系で使う特殊な二進化表現です。
詳しくは [Wiki](https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AC%E3%82%A4%E3%82%B3%E3%83%BC%E3%83%89) をどうぞ

https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AC%E3%82%A4%E3%82%B3%E3%83%BC%E3%83%89

# 実装例
![2021-08-18_17h01_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1645569/34d4b700-f653-807f-9099-6dd740bb2e61.png)

```c#:GrayCode2Bin
(Bin0, Bin1, Bin2, Bin3, Bin4, Bin5, Bin6, Bin7) =>
let
    // Bit(1 or 0) 故、最初にText化＆結合。Text("01010101")の場合は、GrayCodeにそのまま入れればOK
    GrayCode = Text.Combine({ Text.From(Bin0), Text.From(Bin1) ,  Text.From(Bin2) ,  Text.From(Bin3) ,  Text.From(Bin4) ,  Text.From(Bin5) ,  Text.From(Bin6) , Text.From(Bin7)}),
    GrayCodes = Text.ToList(GrayCode),
    BinaryCodes = List.Generate(
        () => [ index = 0, grayBool = GrayCodes{0} = "1", gray = Number.FromText(GrayCodes{0})],    // initial
        each [index] < List.Count(GrayCodes),    // condition
        each [
            index = [index] + 1,
            grayBool = (GrayCodes{index} = "1" or [grayBool]) and (not ((GrayCodes{index} = "1") and ([grayBool]))),
            gray = if grayBool then 1 else 0   // Number.Power で数値利用するので、数値としておく
        ],   
        each [gray] // next
    ),
    dimension = List.Count(BinaryCodes) - 1,
    Decimals = List.Sum(
        List.Transform(
            {0 .. dimension},
            each BinaryCodes{_} * Number.Power(2, dimension - _)
        )
    )
    
in
    Decimals
```

## あとがき
- Bitデータの入力だったので、そのまま渡すようにしたけど、結合させてからの方が関数呼び出しの際に楽だったかも・・
- Endian に疑問があったので、後で直しやすいようにって思ったんだけど、どっちもどっちだった気がしてます・・🙄
GitHubがパスワード認証を廃止してPushができない件について

#Sourcetreeからプッシュができない…。
#####2021年8月13日にGitHubがパスワード認証を廃止し、それに伴いSourcetreeにてPushをしようとすると…
```
remote:Support for password authentication was removed on August 13, 2021.Please use a personal access token instead.
```
####日本語訳
```
remote：パスワード認証のサポートは2021年8月13日に削除されました。代わりに、個人用アクセストークンを使用してください。
```
#####という403Errorなるものが出てきてPushできなくなりました。

#解決策
#####SourceTreeの画面右上の設定→リモートの順にクリック。
![スクリーンショット 2021-08-18 20.38.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656839/be09c522-a54a-7d7a-38e1-f0c9e81df69f.png)
#####通常リモートリポジトリのパスは下記のようになっているかと思います。
```
https://github.com/[ユーザ名]/[リポジトリ名].git
```
#####下記のようにリモートリポジトリのパスにアクセストークンと@を追加してください。
※必ず@を忘れずに！！！

```
https://[アクセストークン]@github.com/[ユーザ名]/[リポジトリ名].git
```
####これで私は無事解決しました！
#アクセストークンてどこから取ってくるの…。
#####アクセストークンはGitHubのSetting→Developer Settings→Personal access tokensから取得することができます。
rubyのHash#slice メソッドについて

みなさまお久しぶりです！
プレイライフの熊﨑です。
最近整体に行ったら、「君の身体は５０代の人なみに凝っている」と言われましたw（私はまだ20代です。）
本日は、業務で使用したsliceメソッドについてまとめようと思います。

## Hash#sliceメソッドとは
rubyのメソッドで、Hashクラスに用意されているメソッド
Ruby 2.5.0から標準メソッドになった。

## どのようなメソッドか？
引数に指定されたキーと、それに対応する値をハッシュで返すメソッド。

```sample.rb
hash = { id: 1, name: "佐藤太郎", address: "東京都中央区〇〇...", sex: "男性" }
hash.slice(:name) # => {:name=>"佐藤太郎"}
```

## 使用するメリット
- 単純に記述量を減らせる。
- sliceによって、取り出した属性を明示的に示せるため、可読性があがる。

### 例 ユーザーのデータから名前と性別を使用して、別のモデルに活用したい場合

```sample.rb

user = { id: 1, name: "佐藤太郎", address: "東京都中央区〇〇...", sex: "男性" }

# 下の書き方でも間違ってはいないが、どの属性がuserから取り出したものなのか分かりづらい。今は属性の数も少ないのでそこまでわかりづらさを感じないかもしれないが、属性の数が増えていくにつれて、もっとわかりづらくなる。
# また、単純に記述量が多くなる。
params = {
           name: user.name,
           sex:  user.sex,
           age:  age
         }

# hashメソッドを使用することで、:nameと:sexはuserから取り出したものであり、:ageはmergeするものだと明示的に示せる。
params = user.slice(:name, :sex).merge(age: age)
Otheruser.new(params)
```

## まとめ
- sliceメソッドを使用することで、シンプルかつわかりやすいコードをかける。

## reference
[https://docs.ruby-lang.org/ja/latest/method/Hash/i/slice.html](https://docs.ruby-lang.org/ja/latest/method/Hash/i/slice.html)
propsの書き方


##はじめに

Vueで親コンポーネントから子コンポーネントに値を渡すpropについて、簡単にまとめました。


Propsはプロパティを意味します。
Propsを利用することで親コンポーネントから子コンポーネントに文字列、数値、配列やオブジェクトなどの値を渡すことができます。
逆に子コンポーネントから親コンポーネントに渡すときはemitを使う。

コンポーネント間でのデータ受け渡しが頻繁に行われたり階層が増えてくる場合はVuexを使った方が便利。
Propsは読み取り専用で子コンポーネントからの編集は不可。親コンポーネントが値を持っています。


<br>
子コンポーネント
propsで親コンポーネントのデータ、postを受け取り表示させる。propsは子コンポーネントに書く。

```Child.vue

  <template>
  <div>
      <h4>{{ props.blogTitle }}</h4>
   　　<h4>{{ props.blogbody}}</h4>
  </div>
</template>

<script>

export default {
  name: "Child",
  props: ["props"],

};
</script>
```


親コンポーネント

```Parent.vue

<template>
  <div>
   <!-- 変数の値を渡したい場合はv-bindを使用 -->
     <Child :props="post" v-for="(post, index) in sampleBlogCards" :key="index"/>
  </div>
</template>

<script>
import Child from "../components/Child";

export default {
  name: "Parent",
  components: {
    Child
  },
    data() {
    return {
         sampleBlogCards: [
        {
          blogTitle:'Blog Card 1',
          blogbody:'stock-1',
          blogDate:'May 1, 2021',
        },
         {
          blogTitle:'Blog Card 2',
          blogbody:'stock-2',
          blogDate:'May 1, 2021',
        },
         {
          blogTitle:'Blog Card 3',
          blogbody:'stock-3',
          blogDate:'May 1, 2021',
        },
          {
          blogTitle:'Blog Card 4',
          blogbody:'stock-4',
          blogDate:'May 1, 2021',
        }
      ],
    };
  },
};
</script>

```

違う例。


子コンポーネント。propsで親からのデータをもらう。

```Child.vue
<template>
    <div>
        <p>{{ message }}</p>
    </div>
</template>
<script>
export default {
    props: ['message']
}
</script>
```
<br>
親コンポーネント

子コンポーネントをimportして”message”でHello Vue!!という値を子に渡している。


```Parent.vue
<template>
    <div>
        <child message="Hello Vue!!"></child>
    </div>
</template>
<script>
import Child from './Child';
export default {
    components: {
        Child
    }
}
</script>
```
Hello Vue!!が表示される。



参考
https://www.freecodecamp.org/news/how-to-use-props-in-vuejs/
https://reffect.co.jp/vue/vue-js-master-props-for-beginner
[3分クッキング]PostgreSQLデータベースおよびWeb APIサーバを爆速で構築する。

# はじめに

デジタル化を進める上で、データベース（以下、DB）やWeb API（以下、API）の構築が必要になることがあります。
AWSやGCP、Azureが提供するサービスを活用することで、比較的容易に構築可能です。
しかし、企業によってはセキュリティの都合で、クラウドの活用が制限されることがあります。
そこで、オンプレ（非クラウド）において、3分でDBとAPI環境構築する手順についてまとめます。
※プロダクション環境（本番環境）向きではございません。

# 前提条件

Dockerとgitがインストールされていること。
Dockerを活用するのため、OSはLinuxでもMac、WindowsでもOKです。
Linux（Ubuntu）については、下記に環境構築手順をまとめております。（拙著で恐縮です）

https://qiita.com/hiyasichuka/items/f46a363101c18d1bfd70


# 3分クッキング

### STEP1. ターミナルを立ち上げて、gitリポジトリをクローンします。

```shell
git clone https://github.com/hiyasichuka/pgweb.git
```


### STEP2. gitリポジトリに移動して、Dockerのコマンドを叩きます。

```shell
cd pgweb
docker-compose up -d
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/2b279237-a501-2971-c93f-74af40fecd92.png)



### STEP3. WEBからDB操作をします。

http://localhost:8081 にアクセスして、Queryタブを選択します。
SQLクエリを書いて、Run Queryを押すことで、DB操作します。

```sql
select * from users
```

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/df5a5a6f-7c88-e273-8c99-59b6f4351d19.png)

※今回は予めテストDBにテーブルを用意して、ダミーデータを投入しています。


### STEP4. Web APIからDBデータを取得してみます。

http://localhost:3000/users にアクセスします。
データベースに格納されたデータがJSON形式で取得できます。

実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533960/f20fec4e-2967-00ea-95f0-c4bf92e417e8.png)


以上で、構築と確認が完了です。


# 構築内容

Dockerを活用して、３つのコンテナ（機能）を構築しました。

|コンテナ名|機能|
|--|--|
|pgweb|DB操作機能|
|postgres|DB|
|postgrest|API|


docker-composeの中身

```yml:docker-compose.yml
version: "3"
services:
  pgweb:
    image: sosedoff/pgweb:0.11.8
    container_name: pgweb
    restart: always
    ports: 
      - 8081:8081
    environment:
      - DATABASE_URL=postgres://postgres:pgweb@postgres:5432/test_db?sslmode=disable
    depends_on:
    - db
  db:
    image: postgres:13-alpine
    container_name: postgres
    restart: always
    ports:
      - 5432:5432
    volumes:
      - ./initdb:/docker-entrypoint-initdb.d
    environment:
      POSTGRES_DB: test_db
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: pgweb
      POSTGRES_INITCB_ARGS: "--encoding=UTF-8 --locale=ja_JP.UTF-8"
      TZ: Asia/Tokyo
  api:
    image: postgrest/postgrest:v7.0.1
    container_name: postgrest
    restart: always
    ports:
      - 3000:3000
    links:
      - db:db
    environment:
      PGRST_DB_URI: postgres://postgres:pgweb@postgres:5432/test_db
      PGRST_DB_SCHEMA: public
      PGRST_DB_ANON_ROLE: postgres
      TZ: Asia/Tokyo
    depends_on:
      - db
```


初期実行したSQL文

```sql:initdb/setup.sql
create table users (
  id int,
  full_name varchar(50),
  update_at timestamp default current_timestamp
);

insert into
  users
values
  (1, 'hoge'),
  (2, 'fuga'),
  (3, 'foo'),
  (4, 'bar');
```

# おわりに

通常、企業で利用するデータベースを構築する場合、「信頼性」「可用性」「保守性」「保全性」「安全性」を考慮した設計が必要になります。
またオンプレ（非クラウド）の場合、機器の選定から発注、納入、セットアップ、テスト、更にはネットワークインフラの工事が必要になってくることがあります。
実際に、
サーバを複数台用意（冗長化）して、
無停電電源装置(UPS) を用意して、
サーバルームやラックを用意して、
配線して、・・・
など、オンプレ環境を構築したのですが、めちゃくちゃ大変でした。
今振り返ると、クラウドを活用することができれば、数ヶ月以上早く構築できたと思います。
オンプレはフルマラソン(42.195km)、クラウドは50m走ぐらいスピード感が違うイメージです。
オンプレの構築方法を提示しておいてなんですが、クラウドを積極的に活用することで、企業のデジタル化を推進していきましょう。


以上です。
AtCoderログ：0082 - ABC 214 C

# 問題

https://atcoder.jp/contests/abc214/tasks/abc214_c

## 問題文
> $N$ 人のすぬけ君が円周上に並んでおり、反時計回りに $1,2,\cdots,N$ の番号がついています。
> $i~(1 \le i \le N)$ 番目のすぬけ君は時刻 $t$ に宝石をもらうと $S_i$ 単位時間後、すなわち時刻 $t+S_i$ にその宝石を $(i+1)$ 番目のすぬけ君に渡します。ただし、$(N+1)$ 番目のすぬけ君とは $1$ 番目のすぬけ君のことを指すとします。
> また、高橋君は時刻 $T_i$ に $i$ 番目のすぬけ君に宝石を渡します。
> 全ての $i~(1 \le i \le N)$ について、$i$ 番目のすぬけ君が初めて宝石をもらう時刻を求めてください。なお、宝石の受け渡しにかかる時間は無視できるものとします。

## 制約
> ・$1 \le N \le 200000$
> ・$1 \le S_i,T_i \le 10^9$ 
> ・入力は全て整数である。

# 回答
## 回答1 (AC)
すぬけ君がはじめてもらう宝石は(1)となりのすぬけ君から渡される場合,と(2)高橋君から渡される場合,の2通りがあります。$i$ 番目のすぬけ君が宝石をはじめてもらう時刻を $R_i$ とすると、$i$ 番目のすぬけ君が(1)の方法で宝石を渡される時刻は $R_{i-1}+S_i$、(2)の方法で宝石を渡される時刻は $T_i$ なので、$R_i={\rm min}(R_{i-1}+S_{i-1}, T_i)$ となります。あとは $i$ を小さい方から変化させていけば全ての $R_i$ が求まります。

ところが、最初のすぬけ君がはじめて宝石を渡される時刻 $R_1$ を求めるのが少し面倒です。というのも、すぬけ君たちは円周上に並んでいるため、$R_1$  を求めるには $N$ 番目のすぬけ君がはじめて宝石を渡される時刻 $R_N$ が必要になるのです。$R_N$ を求めるには $R_{N-1}$ が必要で...と考えていくと、どこから手をつけて良いかわからなくなってしまいます。

そこで、暫定的に $R_1$ の初期値を $T_1$ に設定し、この初期値で各 $R_i$ を $2$ 周計算していけば正しい値を求めることができます。というのも、そもそも $R_1=T_1$ ならば $1$ 周目で正しい値が求まるので、計算を $2$ 周させても問題ありません。また、$R_1=R_N+S_N$ となるならば、$1$ 番目のすぬけ君は $N$ 番目のすぬけ君から宝石を渡されたことになります。その宝石は $i$ 番目のすぬけ君が高橋君から受け取ったとすると、$1$ 週目の計算で $R_i,R_{i+1},...,R_N$ は正しく計算できているので、もう $1$ 周すればすべての $R_i$ を正しく計算できます。

以上の考察をまとめたコードは以下のようになりました。

```C++:abc214c-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n;
  cin >> n;

  vector<int> s(n);
  for ( int i=0; i<n; i++ ) {
    cin >> s.at(i);
  }

  vector<int> t(n);
  for ( int i=0; i<n; i++ ) {
    cin >> t.at(i);
  }

  vector<int> r(n);
  r.at(0) = t.at(0);
  for ( int i=1; i<n; i++ ) {
    r.at(i) = min( r.at(i-1)+s.at(i-1), t.at(i) );
  }
  r.at(0) = min( r.at(n-1)+s.at(n-1), t.at(0) );
  for ( int i=1; i<n; i++ ) {
    r.at(i) = min( r.at(i-1)+s.at(i-1), t.at(i) );
  }
  
  for ( int i=0; i<n; i++ ) {
    cout << r.at(i) << endl;
  }
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc214/tasks/abc214_c/editorial) → [公式解説](https://atcoder.jp/contests/abc214/editorial/2438)
回答1と同じ方針でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc214/tasks/abc214_c/editorial) → [公式解説](https://atcoder.jp/contests/abc214/editorial/2451)
グラフの最短経路問題に帰着できるとのことです。

## [AtCoder の解説](https://atcoder.jp/contests/abc214/tasks/abc214_c/editorial) → [ユーザ解説](https://kanpurin.hatenablog.com/entry/2021/08/14/225854)
優先度つきキューの問題に帰着できるとのことです (意味がわからずに書いています...)。

## [AtCoder の解説](https://atcoder.jp/contests/abc214/tasks/abc214_c/editorial) → [ユーザ解説](https://atcoder.jp/contests/abc214/editorial/2455)。
回答1を発展させて解法です。高橋君から宝石を受け取ったすぬけ君を見つけ、そこからそれぞれのすぬけ君がはじめて宝石を受け取る時刻を求めています。

## [AtCoder の解説](https://atcoder.jp/contests/abc214/tasks/abc214_c/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2021/08/15/034629
)。
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0081 - ABC 057 C](https://qiita.com/RoadLynton/items/ca1662135c7c04c4d4f6)
AtCoderログ：0081 - ABC 057 C

# 問題

https://atcoder.jp/contests/abc057/tasks/abc057_c

## 問題文
> 整数 $N$ が与えられます。ここで、$2$ つの正の整数 $A,B$ に対して、$F(A,B)$  を「$10$ 進表記における、$A$ の桁数と $B$ の桁数のうち大きい方」と定義します。
> 例えば、$F(3,11)$ の値は、$3$ は $1$ 桁、$11$ は $2$ 桁であるため、$F(3,11)=2$ となります。
> $2$ つの正の整数の組 $(A,B)$ が $N=A×B$ を満たすように動くとき、$F(A,B)$ の最小値を求めてください。

## 制約
> ・$1 \le N \le 10^{10}$
> ・$N$ は整数である。

## 収録されている問題セット
- [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 (TLE)
$A,B$ は $N$ の約数なので、$A$ を $1$ から $N$ まで変化させ、$A$ が $N$ を割り切る場合に関数 $F(A,N/A)$ を計算し、その最小値を調べれば良いでしょう。コードは以下のようになります。なお自然数 $M$ の桁数は $\lfloor \log_{10}{M} \rfloor +1$ という計算によって求められます。

残念ながらこのコードは TLE となります。このコードの繰返し回数は $N$ 回で、その最大値は $10^{10}$ 回なので、時間内に処理できない場合が生じています。

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

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

  int fmin;
  for ( int64_t a=1; a<=n; a++ ) {
    if ( n%a==0 ) {
      int f = max( floor(log10(a))+1, floor(log10(n/a))+1 );
      fmin = min( fmin, f );
    }
  }

  cout << fmin << endl;
}
```

## 回答2 (AC)
回答1では、例えば $A=1$ のときに $F(A,B)=F(1,N)$ を計算する一方で、$A=N$ のときに $F(A,B)=F(N,1)$ と同じものを計算しており、効率が悪いです。そこで $A$ が $N/A$ より小さい場合に限定することで、上記のような繰り返し計算を避けることが出来ます。$A \le N/A$ を整理すると $A \le \sqrt{N}$ となるので、変数 $A$ は $\sqrt{N}$ まで変化させれば良いことがわかります。$A \le N/A$ であることから、$F(A,N/A)$ は常に $N/A$ の桁数を調べれば良いこともわかります。

これらの考察を用いたコードは以下のようになります。

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

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

  int fmin = floor(log10(n))+1;
  for ( int a=2; a<=floor(sqrt(n)); a++ ) {
    if ( n%a==0 ) {
      fmin = min( fmin, (int)floor(log10(n/a))+1 );
    }
  }

  cout << fmin << endl;
}
```

このコードの繰り返し回数は $\sqrt{N}$ 回なので、最大繰返し回数は $\sqrt{10^{10}}=10^5$ 回となり、十分処理可能であることがわかります。

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

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0080 - ABC 214 B](https://qiita.com/RoadLynton/items/6e8f9b592e331bd9e7ca)
正規表現で文字列をマッチさせるサンプル集

## 概要
今更だけど、いつも忘れるのでよく使う正規表現の例を記録。

## 肯定、否定
`(?=文字列A)` 肯定。文字列Aを含む場合。
`(?!文字列A)` 否定。文字列Aを含まない場合。

## OR, AND
`(?=文字列A|文字列B)` OR。文字列Aもしくは文字列Bを含む場合。
`(?=文字列A)(?!文字列B)` AND。文字列Aを含む且つ、文字列Bを含むない場合。

## 例
- `(?=GitHUB)` -> GitHUBという文字列を含む
- `(?!GitHUB)` -> GitHUBという文字列を含まない
- `(?=GitHUB|BitBucket)` -> GitHUBもしくはBitBucketという文字列を含む
- `(?=GitHUB)(?=Enterprise)` -> GitHUB且つEnterpriseという文字列を含む


## 実用例
実際に使う場合は、以下を組み合わせて使うことが多い。

`^` 文字列の先頭を意味する。
`$` 文末を意味する。
`.*` ワイルドカード。

- `^(?=GitHUB).*$`
    - `GitHUBはレポジトリです` -> マッチする
    - `これが私のGitHUBレポジトリです` -> マッチしない
- `^(?=.*GitHUB).*$`
    - `GitHUBはレポジトリです` -> マッチする
    - `これが私のGitHUBレポジトリです` -> マッチする


## 演習問題
文章のいずれかの位置に、`GitHUB`もしくは`BitBucket`を含む且つ、`GHE`もしくは`Enterprise`を含まない正規表現を作れ。


### 解答

```
^(?=.*GitHUB|.*BitBucket)(?!.*GHE|.*Enterprise).*$
```

### 検証結果

| 文字列 | matched |
| --- | :--: |
| これが私のGitHUBのURLです。 | Y |
| BitBucketのURLを教えてください。 | Y |
| これは私のGitHUBのURLです。GitHUB Enterpriseではありません。 | N |
| これは私のGitHUBのURLです。GHEではありません。 | N |

## 参考
- [正規表現：AND（かつ）の表現方法](https://www-creators.com/archives/5332)
- [正規表現チェッカー](https://weblabo.oscasierra.net/tools/regex/)