OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry piで作るSOHOルータ

小さなネットを組むことになったのですが、定番商品のRTX1210がなかなか手に入らない。そこで、入手が容易なラズパイをルータに仕立ててみました。

##構成
本体はラズパイ4, 4GB版を使いました。インターフェースはUSB イーサネットドングルを追加して、無線LAN(wlan0)，Ethernet x2（eth0,eth1)としています。

- wlan0は、外部ネットワーク接続用としてNAPTを構成する。ネットワークはDHCPクライアント設定。
- eth1は、ルータセグメント(192.168.YY.0/24)接続用とする。ネットワークはstatic設定(192.168.YY.XX)。
- eth0は、スタブセグメント(192.168.XX.0/24)として端末接続用とし、dhcpサーバの管理対象とする。ネットワークはstatic設定(192.168.XX.1)。
<pre>[Raspberry Pi  wlan0(dhcp)]-----(外部ネットワーク)
[                  eth0(1)]-----(192.168.XX.0/24)
[                 eth1(XX)]-----(192.168.YY.0/24)--[(ZZ) Router]--(192.168.ZZ.0/24)
</pre>

##設定
###インターフェースの設定
かつては/etc/networkに設定していたようですが、現在は/etc/dhcp.confに設定する。

```/etc/dhcp.conf
interface eth0
    static ip_address=192.168.XX.1/24
    static routers=
    static domain_name_servers=
    static domain_search=
interface eth0
    static ip_address=192.168.YY.XX/24
    static routers=
    static domain_name_servers=
    static domain_search=
```

###DHCPサーバの設定
インストール
```sudo apt-get install isc-dhcp-server```

配布情報の例、あとDNSのリゾルバ情報も追加する。

```:/etc/dhcp/dhcpd.conf
subnet 192.168.XX.0 netmask 255.255.255.0 {
    range 192.168.XX.100 192.168.XX.199;
    option routers 192.168.XX.1;
    ignore declines;
}
```

対象インターフェース

```:/etc/default/isc-dhcp-server
INTERFACES="eth0"
```

DHCPサーバの自動起動

```shell
#起動
systemctl start isc-dhcp-server
#チェックしてよければ
systemctl enable isc-dhcp-server
```

interfaceの固定アドレス設定が完了するまで起動を遅らせる。

```/etc/init.d/isc-dhcp-server
#startの記述の直前に以下を挿入
sleep 10
```
##ルーティング
IPv4のルーティング機能を有効化する

```/etc/sysctl.conf
net.ipv4.ip_forward=1
```
静的経路を適宜設定する。

```:shell
# 192.168.ZZ.0/24あてのGWが192.168.YY.ZZの場合
route add -net 192.168.ZZ.0 netmask 255.255.255.0 gw 192.168.YY.ZZ
```
pingなど打って問題なければ、rc.localの末尾などに上記記述を追加

### NATの設定
こちらの記事が参考になります。
https://edosha.hatenablog.jp/entry/2017/07/06/134439

## dns サーバ設定

```
sudo apt install dnsmasq -y

/etc/dnsmasq
domain-needed
bogus-priv
no-resolv
server=8.8.8.8
server=8.8.4.4
interface=eth0

sudo systemctl restart dnsmasq
sudo systemctl enable dnsmasq
```

##まとめ
ラズパイは情報を得やすいのが良いですね。
特に注意する点は、interfaceの設定が完了するまで、dhcpサーバや経路の設定を遅らせるところです。これを忘れると、テストではうまくいっても、再起動するとうまくいかないという症状がでることがあります。

###参考記事

- [edosha,"Raspberry pi を NAT ルーター兼 DHCP + DNS サーバーにしたい",子育てしながらエンジニアしたい](https://edosha.hatenablog.jp/entry/2017/07/06/134439)
- [野上雅洋,"Linuxマシンをルータにする方法",Linuxドキュメント（手順書）](http://redhatlinux.kt.fc2.com/cont/router.htm)
- [r271-635,"Raspberry Piでルータを構築",r271-635 An Archive Area](https://netlog.jpn.org/r271-635/2013/04/raspberry_pi_router.html)
フロントエンドの技術選定に時間がかかった話

# あらすじ
バックエンドがメイン開発な私がフロントエンドに苦闘した２週間を振り返る。HTML,CSS,JSの知識が多少なりともあってフレームワークだったらBootstrapが一番使ったことがあるって感じのエンジニアが、既存のデザインをいじったがレスポンシブ対応を完全にできなかった。そんな出来事から良くなかったことを反省して次に生かそうと思う。

# VueのライブラリVuetifyを導入する策を講じた
RailsオンリーのSSRでコツコツerbを使ってフロントエンドをつくってきたプロジェクトですが、レスポンシブ対応ができないんだったらVuetifyを入れてサーバーサイドとクライアントサイドで完全に分けちゃおうって思って、この策を講じることにした。vueをなぜ使おうかと思ったのは今後デザインの管理がしやすいのと、ライブラリが多様にあるのでレスポンシブやらSPAやらうまい具合に使ってUIめっちゃ向上するんじゃないのかと思ったからです。結論は、erbを使ったSSRでは、長時間かけないと切り替えられないなという結果でした。erb前提のroutingになっているのでAPI化にするのは作業工程が多すぎるなと感じて撤退しました。

# そのまま突っ走って既存CSSで対応していこう
メディアクエリが一応設けられているcssなのでこのまま細分化していって対応することもできると考えましたが、リソースがないのを考えるとbootstrapやらbulmaやらのフレームワークつかっちゃった方が得策だなと感じフレームワークを使うことになりました。

# Bootstrapを使いましょうか
私自身がBootstrapを使ったことが一番多いので、他のフレームワークを使わずにBootstrapを使いますかと脳筋スタイルで進めようと思っていましたが、アメリカ人エンジニアさんがBootstrapは重いから軽量のレスポンシブ対応のみできるフレームワークを使おうよとなりBulmaへ。

# Bulmaで決まりだ
結果的にBulmaになりました。実際に実装してもらったのはアメリカ人エンジニアさんなのですが、ボタンもBootstrapから卒業してレスポンシブ対応の方法も簡潔で違ったフレームワークを使うとデフォルト感がなくなるので良いですね。どうしてもBootstrap使うと見慣れた感を感じるユーザーがいると思うのでデザインに手を抜いているなとか思われる可能性考えたら良い到着点だったのかなと思います。本当、試行錯誤は長い時間かけたらまずいですが、早いスパンで繰り返すのは大切だなと改めて感じました。

# まとめ
フロントエンドに時間をかけるリソースがない開発は、用途にあったフレームワークを決めるのは大切。
vueやらreactを使った方が間違いなくUIは改善できると思う。
話し合いは大切。
技術選定はなるべく早く。切り替えるのは時間がもったいない。
pythonを便利に使おう第一回！

#初めに
試験というのは自分の実力を試すためのものですが、それは問題解決能力を問われていると言い換えても良いかもしれません。社会に出たときに必要なのは結局の所、個人での問題解決能力ですから。
　しかし、だとすれば、自分の実力の限りを尽くして、取れる手段のすべてを尽くして、問題を解決させるのが、試験の正しいあり方なのではないかと思いました。
###とかいう言い訳はさておき！
数学の問題をpythonで解いてやろうというお話です。
問題を解く上でのレギュレーションとしては人に答えを聞きに行かないこと、それ以外であれば問題を解くための何をしてもOK!という気分でやってきます。

>問題としてこちらを使わせていただきました。
https://web.math-aquarium.jp/reidai-sikinotennkaitoinnsuubunnkai.pdf

#式の展開と因数分解
数学においても何にしても、ルールというものは覚えるしかなく、その覚える作業は苦手にする人が多いところです。かく言う私もその一人ですが、pythonのsympyだったらそんな心配する必要はない！というところを見せつけて差し上げます！

##第一問　次の整式の同類項をまとめて整理せよ。

```math
2x^2+3xy+2x+2xy+3y^2+2y+2x+3y+2
```

とりま、sympyにぶち込みましょうか。

```python
>>> from sympy import symbols
>>> x=symbols('x')
>>> y=symbols('y')
>>> 2*x**2+3*x*y+2*x+2*x*y+3*y**2+2*y+2*x+3*y+2
2*x**2 + 5*x*y + 4*x + 3*y**2 + 5*y + 2
```

こういう問題であれば、逆に入力が手間ですし、ミスもしそうですね。持ってくる問題が、データであれば、画像解析をAIにさせて問題を抽出とかさせてもいいかもしれません。それはともかく答えが出ましたね。

```math
2x^2+5xy+4x+3y^2+5y+2
```

##第二問　次の整式の [ ] 内の文字に着目したときの次数と定数項を答えよ。
```math
x^2＋2xy＋y^2－1 [ x ] 
```

あれ、早速だけどこんな機能があるのか知らないものが出てきたぞ？
と、ここで何でも使っていいルールを発動。Google先生をバトルゾーンに召喚。sympy 係数　と調べれば、ぱっと…は出てこなかったけど、３番目ぐらいに出てきた！
coeffというものを使うのか。

```python
>>> from sympy import symbols
>>> x=symbols('x')
>>> y=symbols('y')
>>> a=x**2+2*x*y+y**2
>>>a.coeff(x,1)
2*y
```

xの1乗なのでa.coeff(x,1)で係数を出します。ここでxの2乗について係数を取り出したければ、a.coeff(x,2)となるようです。答えは言わずもがな。

##第三問　次の整式を，x について降べきの順に整理せよ。

```math
2x+x^3-2-x^2 
```
```python
>>> from sympy import symbols
>>> x=symbols('x')
>>> y=symbols('y')
>>> 2*x+x**3+-2-x**2
x**3 - x**2 + 2*x - 2
```

標準で降べきに整えられるようになっているみたいです。しかしこれでは味気ないので、このような出力方法では見辛くて仕方がない！という声も聞こえてきそうなところ、整えてくれるらしい関数を探してきました。
sympy.init_printing()これを先頭に書けばいいそうで。
早速試してみましょう。

```python
>>> from sympy import *
>>> init_printing()
>>> x=symbols('x')
>>> y=symbols('y')
>>> 2*x+x**3+-2-x**2
 3    2          
x  - x  + 2⋅x - 2
```

なるほど、そうなるのか。

##第四問　A,Bが以下の時、次の計算をせよ

```math
A=x^2+xy+y^2
```

```math
B=3x^2+3xy-y^2
```

計算式

```math
A+B
```

```math
4B-[3A-2(A-2B)]
```

```python
>>> from sympy import *
>>> init_printing()
>>> x=symbols('x')
>>> y=symbols('y')
>>> A=x**2+x*y+y**2
>>> B=3*x**2+3*x*y-y**2
>>> A+B
   2        
4⋅x  + 4⋅x⋅y
>>> 4*B-(3*A-2*(A-2*B))
   2          2
- x  - x⋅y - y 
```

という風に。知識不足という面もありましたが、大問1を解くだけで、1時間はかかってしまいました。このqiitaで記事を書きながらやっていたというのもあるかもしれませんが、しかし、このままだったら紙でやったほうが便利となってしまいます。見やすいしね。
しかし、しかし！あくまで私はpythonを使いたい！pythonで遊びたい!
そんなわけで、これからもpythonで遊ぼうと思います。出来ることならば、関数を作って作業を便利にしたりしながらね。
POWERSHELL　PINGを指定IPに出し続ける、グリッドビューで確認

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614609/90f19148-a935-4b60-924f-c25a2dbcf2c8.jpeg)
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1614609/ef3981e2-875f-1494-1da5-e8674465dbc2.jpeg)


```powershell
# 黒い画面を閉じる
powershell -WindowStyle Hidden -command "exit"
# INPUTBOXのおまじない
[void][System.Reflection.Assembly]::Load("Microsoft.VisualBasic, Version=8.0.0.0, Culture=Neutral, PublicKeyToken=b03f5f7f11d50a3a")

# pingを実行する宛先を指定する
$targets = [Microsoft.VisualBasic.Interaction]::InputBox("IPを入力してください（例）10.10.10.10","pingを出し続けます")

# 設定
# pingを実行する間隔(ミリ秒)
$interval = 500

# 繰り返し数
$repeat   = 100

@(1..$repeat) | foreach {
    $targets | foreach {
        # 間隔をあけるためのsleep
        Start-Sleep -Milliseconds $interval
        try {
            # ping実行
            $tc = Test-Connection $_ -count 1 -ErrorAction Stop

            #結果の格納
            $result = "○"
        } catch [Exception] {
            # 失敗した場合
            $result = "×"
        }
        # 現在時刻
        $datetime = Get-Date -F "yyyy/MM/dd HH:mm:ss.fff"

        # CSV形式で結果情報を作成
        $row = $result + "," + $datetime  + "," + $tc.Address + "," + $tc.ResponseTime 

        # CSVからオブジェクトを出力
        $row | ConvertFrom-Csv -Header @("Result","DateTime","Target","ResponseTime(ms)")
    }

} | Out-GridView -Title "Ping Results" # グリッドビューを表示する


```
初学者が「rails new 〜」　で起きたエラー

環境構築をし、ブラウザで「Hello　World」を表示させようとしたときに起きた話

スペック
-
macOS Big Sur バージョン11.3.1
MacBook Air (M1, 2020)
を2021年5月に購入しました。それまではWindowsをずっと使っていました。

手順
-
●rails環境構築
１、Command Line Toolsをインストール
２，Homebrewをインストール（ver 3.1.12）
３，rbenvをインストール（ver 1.1.2）
４，Rubyをインストール（ver 3.0.1）
５，railsをインストール（ver 6.1.3.2）
６，yarnをインストール（ver 1.22.10）

●プロジェクト作成
１、railsでプロジェクト作成

```
% mkdir ruby_project
% cd ruby_project
% rails new hello_app
```

２、hello_appをvscodeで開く

３、「Hello World」実行



起きたエラー
-
```
% rails new hello_app
.
.
.
Argumenterror: method name must be a Symbol but Falseclass is given
.
.
.

```
訳: Argumenterror：メソッド名はSymbolである必要がありますが、Falseclassが指定されています

んー、よくわからない…
どこで指定されているのかもわからない…

とりあえずインストールしたものを上からバージョンを確認していったところ、
rubyのバージョンが古いものをインストールしている事が判明（最新のをインストールしたつもり…）

ruby 3.0.1 をインストールし、railsとyarnも一応再インストールすると
今度はなんの問題もなく、プロジェクト作成に成功

```ruby:application_controller.rb
class ApplicationController < ActionController::Base
    def hello
        render html: "Hello World"
    end
end

```

```ruby:routers.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  root 'application#hello'
end
```
と変更し、rails sでサーバーを立ち上げ
![スクリーンショット 2021-06-20 12.01.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1573831/042dff2d-34e9-b423-e15c-fc06c5be51ad.png)

見事「Hello World」に成功！！！！



その他
-
```
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint: 	git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint: 	git branch -m <name>
```
```
warning webpack-dev-server > sockjs > uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
warning webpack-dev-server > webpack-log > uuid@3.4.0: Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.
```
プロジェクト作成が上手くいったものの、途中でこんなログが表示された。
gitやwebpackのことが書かれているので、こちらも調べて改善していきたい。


感想
-
M1Macに環境構築するのは初学者では躓いてしまう可能性があると言われている中購入したので
不安はありましたが、今の所なんとかやれているので、大丈夫そうです
これからもいろいろな壁にぶつかると思いますが、めげずに頑張りたいと思います。
Qiitaにもアウトプットしていき、同じようなところで躓いている初学者の方のためになったらいいなと思います。
windows で npm の shell 設定を変更したら別窓に開くようなってしまったのを直す

たちまちやり方がわからなかったので`npm`の設定ファイルのリセットで直しました。
`npm`の設定ファイルを修正すればリセットする必要はないと思われますが、方法がわかりません。

ユーザーのデフォルトをリセットするには
これをコマンドライン（またはWindowsではgit bash）で実行します。

```sh
echo "" > $(npm config get userconfig)
npm config edit
```

グローバルデフォルトをリセットするには
```sh
echo "" > $(npm config get globalconfig)
npm config --global edit
```

```sh
sudoが必要な場合は、代わりにこれを実行してください。
sudo sh -c 'echo "" > $(npm config get globalconfig)'
```

## 引用元
node.js - How to restore/reset npm configuration to default values? - Stack Overflow
https://stackoverflow.com/questions/20934343/how-to-restore-reset-npm-configuration-to-default-values
【解決】2ndモニターをつけると、Wifi接続不安定になる

# 2ndモニターをつけると、Wifi接続不安定になる

HDMIの外部モニターに接続するときに使っているThunderbolt-HDMIの変換アダプタを使うとWifiが極端に遅くなることが判明。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/b1d7b710-cdd3-eb89-08a2-a4b8f053c5ca.png)

# 対策

アルミホイルを巻く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/793062ce-5723-8b9e-989d-2f2bc0cb8b73.png)


# 対策前

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/aef9be9f-8c5f-06e6-215b-3f6f714a5e8b.png)

# 対策後

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/1dd02f06-0875-f0ef-6e50-30cd60087048.png)

# 参考

5GHzで接続しています。もともと電波が弱い場所なので、HDMIのアダプターのノイズを受けやすい環境だと思われます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/24d6c894-2dd4-f001-8d9a-0871c5d5edef.png)

もう一つもってる、このアダプターは問題ありませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/8987b203-53a7-345f-e845-ffc8dc9f1320.png)

Type-CのHDMIアダプターやUSB 3.0の機器などでも同じような事があるかもしれません。
5GHzだったら外部のノイズも少ないとおもってたんですが、HDMIやUSB3は高速な通信をしているので、ノイズの発生源になるんですね。
しっかりシールドされている製品を使いましょう。
Bitcoin Coreの使い方


# Bitcoin Coreとは

Bitcoin Coreは、コミュニティによって運営されているフリーソフトウェアプロジェクトであり、MITライセンスの元に公開されています。

Bitcoin Coreをインストールし、Bitcoin Coreが立ち上がった状態で8333ポートを開け、PCを起動したままにする事で、ビットコインのネットワークの維持に協力できます。

# Bitocoin Coreの構成

以下の３つの要素から構成されています。

- bitcoin-qt : bitcoin coreのGUIクライアントです。
- bitcoind(deamon) : バックエンドで常時動くデーモンプログラムです。
- bitcoin-cli : bitcoin coreのCUIからbitcoindに対するコマンドを実行するのに使用します。
 
# 前提条件

Bitcoin Coreの初期同期では、長い時間をかけて大量のデータがダウンロードされます。
全ブロックチェーンをダウンロードする上では、アップロード速度が毎秒400kbps（50kb）以上のブロードバンドインターネット接続とストレージ容量(370GB以上)がある事が前提となります。(2021年7月現在時点)

また、ノードの実行中はスクリーンセーバーの設定を確認し、自動「スリープ」または「一時停止」オプションを無効にして、コンピューターが実行されているときはいつでもネットワークをサポートしている必要があります。

# 実行環境

今回、実際に使用した環境は以下の通りです。

【OS】Windows 10 Home 64bit
【CPU】Corei7-8700 @3.20GHz
【RAM】16[GB]
【HDD】Dドライブに1[TB]以上の空き

# インストールの手順

###### １．公式サイトよりインストールパッケージをダウンロードします。

https://bitcoin.org/ja/download

###### ２．インストーラを実行して、インストール先を指定します。
今回は、Dドライブ直下にBITCOINというフォルダを作成し、そこへインストールしました。
　　
###### ３．Bitcoin Coreを起動します。
インストール完了後、はじめてBitcoin Coreを起動すると、空のブロックチェーンのデータを格納するデータベースが作成されます。続いて、ビットコインネットワーク上で稼働している他のノードからブロックチェーンのデータを受け取りはじめます。このデータ転送は、自分のノードのブロゥクチェーンの内容がビットコイン・ネットワークの他のノードと同じ動きになるまで続きます。これをIDB(初期ブロックダウンロード)といいます。
この間、残りブロック数と現在の動機の進捗状況が表示されますが、同期が完了するのには数時間かかります。
同期が完了したらPCを再起動します。
　
###### ４．テストネットの起動

   
###### ５．Bitcoin Coreのアップグレード
古いバージョンを実行している場合は、一旦シャットダウンして、Windowsの場合インストーラを実行します。
（古いバージョンでは数分かかる場合がありますので、完全にシャットダウンするまで待ちます）


データディレクトリ内のブロックチェーンファイルとウォレットファイルは、バージョン間で互換性があるため、アップグレード時にデータディレクトリに変更を加える必要はありません。
これらのファイルの形式が変更されることがありますが、新しいビットコインコアバージョンには、ファイルを新しい形式に自動的にアップグレードするコードが含まれているため、手動による変更は必要ありません。
Goの外部パッケージが$GOPATH/srcではなく$GOPATH/pkg/modにインストールされる

# Goの外部パッケージをsrc配下にインストールするには
環境はMacBook (Retina, 12-inch, 2017)
OSはBigSurバージョン11.4
Goはgo1.16.3です。
以下のコマンドを叩くとsrc配下にインストールされるようになります。

```
$export GO111MODULE=off
```
例えばその後

```
$go get github.com/markcheno/go-talib
```

を叩くと以前はGOPATH/pkg/mod/github.comにインストールされていましたが、GOPATH/srcにgithub.comディレクトリが作成され、正しい場所にインストールされるようになります。

# 参考
[リンク](https://stackoverflow.com/questions/66284870/go-get-not-downloading-to-src-folder)
java用語集

①クラス　プログラム実行に必要な処理をまとめた設計図

②メソッド　いくつかの処理をひとまとめにしたもの
　インスタンスメソッド　インスタンスに紐づけられたメソッド　インスタンス固有の振る舞いを表す
　クラスメソッド　クラスに紐づけられたメソッド　クラス全体の固有の振る舞いを表す
　※車クラスがあった場合に、インスタンスメソッドは1台の車インスタンスごとの振る舞いを表すのに対し、クラスメソッドは車全体の振る舞い。

 

③引数　メソッドに渡す値　入力値

④戻り値　返ってくる値　出力値
※和を計算するメソッドを作成した場合、数値が引数、和が戻り値

⑤変数　データを一時的に格納する箱
　
⑥データ型　取り扱うことができるデータのタイプ

⑦整数型　（byte型、short型、int型、long型）

⑧浮動小数点数型（double型、float型）

⑨文字型（char型）

⑩論理型（boolean型）

⑪インターフェース　クラスに含まれるメソッドの具体的な処理内容を記述せず、変数とメソッドの型のみを定義したもの

⑫インスタンス　クラスから作られるオブジェクト（実体）

⑬文字列　複数の文字で構成される文字列を扱うときは、Stringクラスを利用

⑭配列　複数の値をまとめて扱うことができる機能

⑮コンパイル　プログラムをコンピューターが実行できる形に翻訳すること

⑯演算子　データ処理の基礎となる重要な手続き
　算術演算子　「+」（足し算）　「-」（引き算）「*」（かけ算）　「/」（割り算）　「%」（余り）
　
　代入演算子　「=」「+=」「a += b」とすると、「a = a + b」　　「-=」　「*=」「a *= b」とすると、「a = a * b」
　　　　　　　「/=」　「%=」「a %= b」とすると、「a = a % b」
　
　比較演算子　「==」「x == y」とした場合、xとyが等しいときにtrue、そうでないときにfalse返す。
　　　　　　　「<」「x < y」とした場合、xがyよりも小さいときにtrue、そうでないときにfalseを返す。
　　　　　　　「>」「x > y」とした場合、xがyよりも大きいときにtrue、そうでないときにfalseを返す。
　　　　　　　「 <=」「x <= y」とした場合、xがyよりも小さいか等しいときにtrue、そうでないときにfalseを返す。
　　　　　　　「 >=」「x >= y」とした場合、xがyよりも大きいか等しいときにtrue、そうでないときにfalseを返す。
　　　　　　　「!=」「x != y」とした場合、xとyが等しくないときにtrue、等しいときにfalseを返す。

⑰制御文 基本構造である「順次」「選択」「反復」といった処理を実現するための構文
 if文 条件分岐を行うため
for文　処理を決まった回数繰り返す際に利用
while文　条件式を満たす間、処理をループさせるための構文
break文　for文やwhile文のループ処理中にbreak文が読み込まれると、処理を中断
continue文　for文やwhile文のループ処理中にcontinue文が読み込まれると、現在実行している処理を終了し、次のループ処理に移る。
switch文　多分岐処理をさせるときに便利な構文

⑱条件分岐　与えられた条件の真偽に応じて実行する処理を変えること

⑲オブジェクト　設計図に基づいて作られた自動車（例）クラスを実体化（インスタンス化）したもの

⑳オブジェクト指向　オブジェクトを部品のように組み合わせてシステムを構築する考え方

㉑継承　あるクラスのフィールドやメソッドを引き継いで、新しいクラスを定義すること
　スーパークラス　継承を行う際、継承元となるクラス
　サブクラス　　継承先となるクラス

㉒オーバーライド
ラムダ式を使った配列の実験(Java編)

ラムダ式を使った配列の実験(Java編)です。


```Java
package nogizaka
// ラムダ式の実験プログラム
// 2021/6/20 新規作成
// Author 乃木坂好きのITエンジニア


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

//ラムダ式実験プログラム
public class hairetsu_test {
	public static void main(String[] args) {
		//配列
		List<Integer> data = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12));
        //ラムダ式で3で割り切れない数字を要素から削除する
		data.removeIf( (Integer i) -> { return i % 3 !=0; } );
		System.out.println(data);
	}
}
```

勉強をかねてラムダ式を使ってプログラムを作りました。
【PHP】.env は絶対に使おう

## はじめに

プロジェクトや個人開発で **`.env`** ファイルを使用しないことはほぼないと思います。

**`.env`** ファイルとは開発や本番など環境ごとに変わるDB情報や**Git**で管理したくないパスワードなどプロジェクトの設定を書いたファイルです。

今回は簡単に **`.env`** を読み込み出力するというプログラムを作成しました。（　**Laravel**　（フレームワーク）を使用するときは直接 **`.env`** を読み込まず **`config`** ファイルから読み込むことにご注意ください）

https://qiita.com/mpyw/items/34f37742d9a18b80a08c

https://biz.addisteria.com/env_config/

#### この記事でわかること

- **`.env`**　の使用方法



## 目次

- はじめに

    - この記事でわかること

- 目次

- 導入

    - composer
    - .gitignore
    - .env
    - メインファイル

- 参考文献

## 導入

#### composer

ライブラリを導入します。

- [GitHub（Installation）](https://github.com/vlucas/phpdotenv#installation)

```terminal:ターミナル
composer require vlucas/phpdotenv
```

#### .gitignore

**`.gitignore`** を作成して **Git** で管理しないようにします。
対象は **vendor** ディレクトリと まだ作成していませんが **`.env`**　です。

```sh
# すでにファイルがある場合は飛ばしてください
touch .gitignore
```

```:.gitignore
vendor
.env
```

#### .env

**`.env`**　を作成していきます。

```sh:ターミナル
# ルート直下
touch .env
```


```:.env
GREETING="こんにちは"
```

#### メインファイル

- [GitHub（Usage）](https://github.com/vlucas/phpdotenv#usage)

```php:.php
<?php

// 自動で読み込み
require './vendor/autoload.php';

// .envを使用する
Dotenv\Dotenv::createImmutable(__DIR__)->load();

// .envファイルで定義したGREETINGを変数に代入
$greeting = $_ENV['GREETING'];

// 出力
print($greeting) . PHP_EOL;

// 出力結果
// => こんにちは
```

## 参考文献

- [GitHub (PHP dotenv)](https://github.com/vlucas/phpdotenv)

- [PHPマニュアル($_ENV)](https://www.php.net/manual/ja/reserved.variables.environment.php)

- [PHPのオートロード(autoload)](https://qiita.com/atwata/items/5ba72d3d881a81227c2a)

- [envファイルとはなんだろう。](https://qiita.com/harutakaoka522/items/e0abddfd0311eb4fb32b)

- [Laravel では env() を config 系ファイル以外の場所に書いてはいけない](https://qiita.com/mpyw/items/34f37742d9a18b80a08c)

- [Laravel .envとconfigの役割の違い【初心者のLaravel講座】](https://biz.addisteria.com/env_config/)
rpmでインストールしたプログラムのインストール先を調べたときのお話

# はじめに
yumやrpmでインストールしたプログラムがどこにインストールされたのかを確認する方法を調べたので
メモ書きとして残す。

# 結論
https://oshiete.goo.ne.jp/qa/8029047.html
によると、特に指定が無ければFHSに従ってインストールされるとのこと。
　※FHSについて：https://linuc.org/study/knowledge/503/

```:リンク先より抜粋
yumやrpmで特にオプションを付けずにインストールすればこの作法に則った場所にインストールされます。
・必要なコマンドは/bin,/sbin,/usr/binなどに
・設定ファイルは/etc/xxxx/xxxx.conf などに
・ライブラリは/lib,/user/lib などに
などなど。
```

プログラムのインストール先は↓↓のコマンドで確認できる。

```
rpm -ql [パッケージ名]
```

 ※：[【 rpm 】コマンド（応用編その1）――パッケージの情報を調べる（1）](https://www.atmarkit.co.jp/ait/articles/1609/20/news019.html)

結果がコチラ。これは簡単ですね！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/bc35a762-54b0-3c4b-73a7-b7f2f673a5cd.png)






※↓↓は、もともとやってみたことのメモ書き。色々やった結果、↑↑の結論にたどり着いたので
　そのときの思い出ってことでそのまま残す。

#はじめに
yumでインストールしたhttpdの初期設定ってrpmファイルを分解したらわかるんじゃない？
という好奇心から始まった夏の自由研究的なお話です

# やること
1.yumdownloaderを使ってrpmを取得する
 > yumdownloader [パッケージ名]

2.rpm2cpioを使ってrpmを展開する
 > rpm2cpio [rpmファイル]

3.ガッツで初期設定を探す
  > grepで…

# yumdownloaderを使ってrpmを取得する

```
# yumdownloader httpd
```

結果がこちら。ＤＬしたrpmはカレントディレクトリに保管されてました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/649785b5-0ccd-94f3-c239-960d1c3b63b2.png)

# rpm2cpioを使ってrpmを展開する

```
# rpm2cpio httpd-2.4.46-1.amzn2.x86_64.rpm | cpio -id
```

結果がこちら。etcディレクトリとかがいきなりとれる。ちゃんとディレクトリを用意しておいたらよかったかな…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/438a8317-dbd6-4aaa-22c4-c5154b71d50c.png)

# ガッツで初期設定を探す
ここからが本来の目的！
…が見つからない。。。Makefileとかconfigureの設定とかあるんじゃないのか…っと思ったけど何もなく
すでに出来上がった状態のbinファイルなどが保管されているだけだった…。

# 突然の解決
https://oshiete.goo.ne.jp/qa/8029047.html
が完璧すぎる回答を書いていたのでそのまま記載。
特に指定が無ければFHSに従ってインストールされるそうだ。なんてこった…
　※FHSについて：https://linuc.org/study/knowledge/503/

```:リンク先より抜粋
yumやrpmで特にオプションを付けずにインストールすればこの作法に則った場所にインストールされます。
・必要なコマンドは/bin,/sbin,/usr/binなどに
・設定ファイルは/etc/xxxx/xxxx.conf などに
・ライブラリは/lib,/user/lib などに
などなど。
```

わざわざ、rpmを展開しなくてもよかったんやーーー！ということで解決。
そして一番知りたかった「yumでインストールしたアプリケーションはどこにインストールされているかってどうやって知ったらいいの？」については↓↓でわかるよってことらしい。

```
rpm -ql [パッケージ名]
```

…やってみると、、、ほんとだー。
勉強したことが身についてないことがよくわかるお手本のような事例。。。
 ※：[【 rpm 】コマンド（応用編その1）――パッケージの情報を調べる（1）](https://www.atmarkit.co.jp/ait/articles/1609/20/news019.html)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/bc35a762-54b0-3c4b-73a7-b7f2f673a5cd.png)

#オマケ：yum、rpmであえてインストール先を指定する方法
https://oshiete.goo.ne.jp/qa/8029047.html
にて、追加の説明でわかった。

```:リンク先より抜粋
インストール先を指定する場合はyumなら"installroot"、rpmなら"prefix"オプションで指定出来ます。
```

んーーー。installrootのこと考えると話がどんどん脱線するのでこれはまた今度にしよう。
最後に・・・当初想定していた結果と違っちゃったので「結論」を先に書いてこれまでの紆余曲折は思い出として後ろに残すようにしよう。

～おしまい～
DDD 集約とは

# 集約とは
集約とは、それぞれのエンティティや値オブジェクトを、どういう単位で作成したり削除したりするか、といったことをあらわす。

エンティティや値オブジェクトの設計と比較して、どういう集約をつくるか、という設計は環境によってもさまざまなパターンがあり得て、開発を進めながら増やしたり減らしたりといったことがおきやすいとおもわれる。

# 集約の基本ルール
・集約にはルートとなるエンティティがひとつ存在し、外部から集約内のオブジェクトにアクセスするときはルートを経由しておこなう。

・集約の外から集約内部への参照をすることはできないが、集約の外部へ向けて値を渡すだけであれば許容される。

# ルールの背景
集約とはオブジェクトをつくったり消したりする単位であるが、そもそもなぜいくつかのオブジェクトをまとめてつくったり消したりするかといえば、それはそれらのオブジェクトはシステムにとって、まとまっていて初めて意味をなすからとおもわれる。

制御する意味のある単位をあらわすのが集約であり、外部からそのまとまり全体を指し示して処理を命令することを可能にするために、命令の受け手となるオブジェクトをルートとして定義する。

# 集約はおおきくなりがち
まずはトランザクションの単位で集約をザックリつくっていくのがよさそう。
でもそうすると場合によっては集約に含まれるオブジェクトが多くなってしまい、メモリやデータベースの性能面で問題が発生する可能性がある。

そのため、いったんつくった集約を小さくすることができないか検討する。

# 集約同士の関連
集約同士のつながりを表現するには、集約のルートエンティティを外部の集約ルートエンティティが直接アクセスするのではなく、値オブジェクトを使って関連を表現したほうがいいとおもわれる。

これは、エンティティと違って値オブジェクトは不変なので、意図しない操作をあらかじめ防げるからである。

しかし場合によっては、値オブジェクトをつかった外部の集約ルートへのアクセスは、その属性にアクセスできないことでオーバーヘッドが生じることもあるので、ここも開発を通じてたびたび変更がはいることはありえるとおもわれる。


# 結果整合性
集約を分割した場合には、それらの集約は同一のトランザクションで整合性をとらないため、かわりに結果整合性を確保する。

これは、ある集約のトランザクションが実行されたことをトリガーにしてイベントを発行し、それを別の集約に通知してトランザクションを実行する整合性のとりかたである。

同一トランザクションでの整合性はとれないが、そのかわりに集約を小さくして複雑さを軽減し、リソースの節約に資すると判断できるときには選択する。
STM32L010と温度,S-5851で液晶温度計 (Mbed)(AQM0802A)


x Mbedのリビジョン125


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

忙しい人よう

https://os.mbed.com/users/caa45040/code/i2c_lcd_s5851_010/


x プログラムは、STM32F303K8と違うのは、i2cとエラー



```c++

//I2C i2c(I2C_SDA, I2C_SCL); //767 303
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010


```


```c++

//容量削減
void error(const char* format, ...){}


```

プログラム


```c++

#include "mbed.h"

//#define S5851A 0x48
#define ADDR        ((0x48)<<1) //  address
#define ADDR_LCD    (0x7C)      //  address

//I2C i2c(I2C_SDA, I2C_SCL); //767 303
//I2C i2c(dp5, dp27); //1114
I2C i2c(PA_10, PA_9); //010

//10の割り算 0から1028までは、正しい。主に0から999
#define DVI10(n) ((n*205)>>11)

int     tempval;        //温度
char    data_read[6];   //i2cバッファー
int     n10;            //10の桁
int     ii;             //ループカウンター

char INIT_com[]={0x0,0x38,
0x0,0x39,
0x0,0x4,
0x0,0x14,
0x0,0x70,
0x0,0x56,
0x0,0x6C,
0x0,0x38,
0x0,0xC,
0x0,0x1,
0x40,0x41};

char INIT_cls[]={0x0,0x1};

int main()
{

    //液晶の初期化
    for(ii=0;ii<11;ii++){
        i2c.write(ADDR_LCD, &INIT_com[ii*2], 2);
        wait_ms(2);
    } //for

    while (1) {

        //液晶のクリア
        i2c.write(ADDR_LCD,INIT_cls,2);
        wait_ms(2);

        //初期化
        //set address 0
        i2c.write(ADDR, "\000", 1); //addres 0

        //温度の読み込み
        // Read temperature register
        i2c.read(ADDR, data_read,1,false);

        //温度の保存
        // Calculate temperature value in Celcius
        tempval =  data_read[0];

        //tempval = 12; //debug

        //計算
        // Calculation temp
        n10 = DVI10(tempval);             //10の桁
        tempval = tempval - ( n10 * 10 ); //1の桁

        //液晶に出力
        // Display result
        data_read[0] = '@';
        data_read[1] = '0' + n10;
        data_read[2] = '0' + tempval;
        //data_read[3] = '\r';
        //data_read[4] = '\n';
        data_read[3] = 0;
        i2c.write(ADDR_LCD, data_read ,3);

        //1秒待つ
        wait_ms(1000);

    }//while

}//main

//容量削減
void error(const char* format, ...){}



```

![i2c_lcd_s5851_010_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/f0d483d1-2f20-4988-7014-f72f5d83f516.jpeg)


![i2c_lcd_s5851_010_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/521a2dec-c31f-2e28-5f93-56d5fc9f6239.jpeg)
所有者が削除されたファイルは誰のものになるのか

ふと気になったので検証してみました

## 環境
* CentOS Linux release 7.8.2003 (Core)

## 検証

### まずrootになる
```
sudo -i
```

### ユーザーを作成、確認する
```
useradd tester
```

```
cat /etc/passwd | grep tester
```

* 実行結果

```
tester:x:1001:1001::/home/tester:/bin/bash
```

### グループが作成されていることを確認する
```
cat /etc/group | grep 1001
```

* 実行結果

```
tester:x:1001:
```

### 適当なファイルを作成する
```
vim abc.txt
```

### 現在の所有者を確認する
```
ls -la abc.txt
```

* 実行結果

```
-rw-r--r-- 1 root root 11  6月 20 09:33 abc.txt
```

### 所有者を変更、確認する
```
chown tester:tester abc.txt
```

```
ls -la abc.txt
```

* 実行結果

```
-rw-r--r-- 1 tester tester 11  6月 20 09:33 abc.txt
```


### ユーザーを削除、確認する
```
userdel -r tester
```

```
cat /etc/passwd | grep tester
```

* 実行結果（何もなし）

```
```

### グループが削除されていることを確認する
```
cat /etc/group | grep 1001
```

* 実行結果（何もなし）

```
```

### 所有者を確認する
```
ls -la abc.txt
```

* 実行結果
  * 元の所有者のユーザーIDとグループID`1001`になった:open_mouth:


```
-rw-r--r-- 1 1001 1001 11  6月 20 09:33 abc.txt
```

* これはプライマリグループIDを変更しても変わらなかった

### 番外編：ユーザー削除後に再度同じ名前でユーザーを作成すると・・・
* 実行結果
  * 所有者が復活！:clap:


```
-rw-r--r-- 1 tester tester 11  6月 20 09:33 abc.txt
```

## 結論
* ファイルの所有者を削除すると、**元の所有者のユーザーIDとグループID**になった（実質元の所有者のまま）
* 削除したユーザー名で再度作成すると、所有者が復活する
  * 未調査ですが、ユーザーを削除しても情報はどこかに残ってそう
* 何かの拍子にユーザーを削除してしまっても所有者は復活できる
    * 削除時`-r`とかでホームディレクトリを削除していなければ最悪助かる
【個人的備忘】Swiftで端末の言語設定に合わせてテキストを切り替える

```
    let langId = Locale.current.identifier.prefix(2)
    let langInt: Int

    init() {
        switch langId {
        case "ja":
            self.langInt = 0
        case "en":
            self.langInt = 1
        case "fr":
            self.langInt = 2
        default:
            self.langInt = 1
        }
    }
    
    func getText(textId: Int) -> String {
        return texts[textId][langInt]
    }
```
HTMLについて

# 　　　　HTMLについて


皆さんこんにちは！駆け出しエンジニアのコジマです！
本日は、HTMLについてお話しして行きたいと思います。

## 　　そもそもHTMLの正式名称は？

まずは、HTMLについて簡単に解説して行きますね！
ハイパーテキスト・マークアップ・ランゲージ
（Hyper Text Markup Language）の略称になります。
最初自分は、いきなり魔法の呪文みたいな正式名称を
聞いて、びっくりしてしまいました　（笑）

## 　　　　　役割について

基本的に、WEBページに文字を出力してくれる役割を
担当してくれているのがHTMLになります！
ちなみに文字に色を付けたり、大きくしたりする担当は、
CSSが担当しています！

HTMLだけだと白黒テレビ状態ですがCSSを使うと、
カラーテレビみたいになると認識してます（笑）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1405238/d80568d8-2bed-3b66-68c5-702a5ef001eb.png"width=40%>
不具合（バグ）とは？　を視覚的に表現。

# はじめに
「不具合」「バグ」という単語は、どうも使う人、立場によっても指しているものが違う気がしている。。
ということで、不具合に関連する用語を視覚的に表現してみました。


# 不具合とは？
## JSTQB Foundation Level [シラバス](http://jstqb.jp/dl/JSTQB-SyllabusFoundation_Version2018V31.J03.pdf)[^1]より引用
> 人間はエラー（誤り）を犯す。そのエラーがソースコードや他の関連する作業成果物の欠陥（フォールトまたはバグ）となる。1 つの作業成果物で欠陥を発生させるエラーは、他の関連する作業成果物でも欠陥を発生させる可能性がある。例えば、要件の導出のエラーは要件欠陥をもたらし、結果的にプログラミングエラーをもたらし、コード内に欠陥をもたらす。
コードの欠陥が実行されると、故障が起きることがあるが、すべての状況で故障が起きるわけではない。例えば、欠陥によっては、故障を起こすためにきわめて特別な入力や事前条件が必要である。そのような故障は発生すること自体が非常に稀であったり、決して発生しなかったりする。

## 視覚的に表現するとこうなる
![不具合とは？.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/75dc0801-54fe-3e4d-953e-953c56e1a48c.jpeg)
![不具合とは？ (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/19b2a5c6-93d9-56ed-f8f2-92b393e1c671.jpeg)


[^1]: ISTQBテスト技術者資格制度 Foundation Level シラバス 日本語版 Version 2018V3.1.J03
[Spring Boot]Spring Data JDBCでDBにアクセスする

# SpringDataJDBCでDBにアクセスする

Spring BootでMySQLの操作を行います。データベースアクセスには Spring Data JPA と Spring Data JDBC の2つあるようですが、SQLを書く練習をしたいのでJDBCを使っていきます。
今回はXAMPPのMySQLのデータベース（test）のテーブル（item）にしてみます。
<hr>

## 1. Springで Spring Data JDBCを使うポイント

大事なポイントは以下の3点のみです。

- Spring Starterプロジェクトで 「**Spring Data JDBC**」 と 「**MySQL Driver**」 を追加する
- DB接続情報は src/main/resource/application.propeties に追加する
- **JdbcTempalte**のメソッドを実行する

<hr>

## 2. DB接続情報を設定する

DB接続情報を src/main/resource/application.propeties に追加します。他にも方法があるようですが最も簡単な方法で実現します。

**[src/main/resource/application.propeties]**

```
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test
spring.datasource.username=（ユーザー名）
spring.datasource.password=（パスワード）
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
```
<hr>

## 3. JdbcTemplateのメソッド

色々なメソッドがありますが、このメソッドを抑えておけば大丈夫そうです。

|やりたいこと|メソッド|
|---|---|
|SELECT|query、queryForList、queryForObject|
|INSERT|update|
|UPDATE|update|
|DELETE|update|

## 3.1. Queryの書き方（SELECT文）

[【JdbcTemplate】Queryの書き方（SELECT文）](https://loglog.xyz/programming/java/jdbctemplate_query_select) を参考にします。

SELECTの方法は 3通り あります。

- BeanPropertyRowMapper
- RowMapper
- Map

Mapを使えば複雑なSQLを実行して結果を取得できそうです。
@lombok.Data アノテーションを付けたBeanなら BeanPropertyRowMapper を使う方法が簡単です。今回は、 **BeanPropertyRowMapper + query メソッド** を使ってSELECT文を作成します。

**Item.java**

```java
@lombok.Data
public class Item {
	private Integer id;
	private String name;
}
```

**ItemDao.java**

```java
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

//DBアクセスのコンポーネントには @Respository を付ける
@Repository
public class ItemDao {

  //@Autowiredを使ってインスタンスを注入すうｒ
	@Autowired
	private JdbcTemplate jdbcTemplate;

  //全件取得する場合は、queryか queryForList メソッドを利用します。
  public List<Item> selectAll() {
    //全件取得のSQLを作成
    String sql = "select * from item;";
    //SQLを実行
    return jdbcTemplate.query(sql, new BeanPropertyRowMapper<Item>(Item.class));
  }

  //1件だけ取得したい場合は queryForObject メソッドを利用します。
  public Item selectOne(Integer id) {
    //PKを使って1件のみ取得
    String sql = "select * from item where id=?;";
    //SQLを実行
    return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Item>(Item.class), id);
  }

	//DBを更新したい場合は update メソッドを利用します。
  public int insertOne(Item item) {

		//1件を新規追加するSQLを作成
    String sql = "insert into item (id, name) values (?, ?);";
		//SQLを実行
		return jdbcTemplate.update(sql, item.getId(), item.getName());
	}

	//DBを更新したい場合は update メソッドを利用します。
	public int updateOne(Item item) {
		//PKを使って1件のみ更新
		String sql = "update item set name=? where id=?;";
		//SQLを実行する
		return jdbcTemplate.update(sql, item.getName(), item.getId());
	}

	//DBを削除したい場合は update メソッドを利用します。
	public int deleteOne(Integer id) {
		//PKを使って1件のみ削除
		String sql = "delete from item where id=?;";
		//SQLを実行する
		return jdbcTemplate.update(sql, id);
	}
```
PHP クロージャー（無名関数）をアロー関数を使って定義してみる

# 目的

- PHP クロージャー（無名関数）の定義をアロー関数を用いて行ってみる

#　ご注意

- アロー関数を用いたクロージャーの定義はPHP7.4からのみサポートされている

# 情報

- 下記のWebサイトをつかって筆者はクロージャーの振る舞いを確認した。
    - [https://paiza.io/ja](https://paiza.io/ja)
- 下記のようなクロージャーを用いた簡単な処理があるとする。

    ```php
    <?php
    $str_2 = 'japan';
    
    $add_str = function ($str_1) use ($str_2) {
        return $str_1 . $str_2;
    };
    
    echo $add_str('hello');
    ```

# 方法

- 「情報」に記載したクロージャーの定義部分をアロー関数を用いて書き直してみた。

    ```php
    <?php
    $str_2 = 'japan';
    
    $add_str = fn($str_1) => $str_1 . $str_2;
    
    echo $add_str('hello');
    ```

# 参考文献

- [https://www.php.net/manual/ja/functions.arrow.php](https://www.php.net/manual/ja/functions.arrow.php)
はじめてのyumdownloader

#はじめに
yumdownloaderつかってrpmをダウンロードできるって話を知って
実際どんなものか確認する

## やってみる
お試しでsysstatをyumdownloaderでとりに行く

```
# yumdownloader sysstat.x86_64
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/abb9a287-d420-730b-c774-ff4b3d0005e6.png)

とってきたパッケージってどこにあるんだろ？って思ったところ
実行時のカレントディレクトリにおいてあった。わかりやすい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/e0433540-33dc-00db-a961-463f504a1b98.png)

# yumdownloaderでDLしたrpmを使ってインストールする
localinstallでいける。ちゃんとDLしたrpmを指定してやるところがコツ。

```
# yum localinstall ./sysstat-10.1.5-18.amzn2.0.1.x86_64.rpm
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/fd78d580-b251-48ec-e62c-1615b4f75f07.png)

#失敗例：rpmの指定をしないとNG
ファイル指定しないと、こんな感じでファイル無いよ、ってことでスキップする。悲しい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/03a228f6-b050-39b3-0e87-fac400dda95a.png)
MySQLに接続できなくなったときの解決策

#エラー

`Can't connect to MySQL server on 'localhost:3306'`
MySQLに接続しようとしたら上記のようなメッセージが出た。

#解決策
私の場合は以下の手順を行ったら接続できるようになった。
➀タスクマネジャーを起動する
➁「サービス」タブを選択する
➂「MySQL80」で右クリックし、「再起動」を選択する
④状態が「実行中」になったのを確認する
お金をかけず　データベーススペシャリストに合格　

#1.はじめに
令和２年(2020年)の10月にデータベーススペシャリストの試験に合格しました。
1回目の受験で合格しました。参考書、講座などは使わずに、ダウンロードした過去問と無料のサイトのみで勉強しました。
ここでは、私の勉強法などについて紹介します。これから、データベーススペシャリストを受験される方の一助になれば幸いです。
![情報処理12.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606353/d3c59520-b073-0016-39df-3d4fd8b8f79d.jpeg)

#2.データベーススペシャリストを受験した動機
会社で昇進する為の点数の中に、国家資格の取得があり、その中に難関資格に分類されているデータベーススペシャリストがありました。業務的には、データベースを専門にしている訳ではなかったのですが、情報処理資格の中でも比較的、取りやすいとの記載があった点と、11月に思い立ったので、次の春にある試験の中から選択する事にしたら、データベーススペシャリストにしました。実際には、令和2年4月の試験はコロナ禍で延期され10月になりました。

#3.勉強方法
私の場合、応用情報技術者試験に合格していたのですが、合格から３年が経過しており、午前Ⅰの免除は受けられませんでした。午前Ⅰも含めてフルで受験しました。

##3-1.午前Ⅰ対策
午前Iの問題は、応用情報技術者試験の午前の問題と共通で出題されます。その為、応用情報技術者試験の午前の過去問を反復勉強しました。[応用情報技術者試験ドットコム](https://www.ap-siken.com/)のサイトがあります。過去12年分の過去問題、答え、解説がまとめられており、スマホからアクセスすると反復して練習する事ができます。無料で利用できます。12年×2(春秋)=24回は、少し多すぎるので過去５年分×2＝10回分を片道30分の通勤電車の中で解いていました。会社のある平日のみです。
最初の2,3回はぜんぜん分からなくて、くじけそうになり、１日10問ぐらいしか進みませんでしたが、5，6回目になると答えを覚えてきて、1日40問ぐらい解けるようになりました。
試験には、過去問が多く出るので、答えを覚えるぐらいがちょうどいいです。

##3-2.午前Ⅱ対策
午前Ⅱの問題は、[データベーススペシャリストドットコム](https://www.db-siken.com/)のサイトを使って、過去10年分の午前Ⅱの過去問を反復して勉強しました。こちらも無料で利用できます。これを通勤電車の中でスマホからサイトにアクセスして、過去問を解いていました。朝の通勤の30分で午前Ⅰを40問、夕方帰りの通勤30分で午後Ⅱを25問解くのを日課にします。

##3-3.午後Ⅰ対策
午後Ⅰは、3問の中から2問を選択して回答する形式ですが、問題の傾向は、似通っています。問1,2はER図やSQLの問題で、問3はテーブル設計の問題の傾向がありました。私の場合、問1,問2を選択すると前提して、過去問を反復して解く練習をしました。過去問は試験管轄元の[IPA(情報処理推進機構)](https://www.jitec.ipa.go.jp/1_11seido/db.html)のページからPDFでダウンロードできます。過去５年分を平日に1日1問を毎日、ノートに答えを書いて解いていました。2日で2問で1年分、平日5日間なので2週間で5年分が練習できる計算になります。1問解くのに最初は30分悩んでも解けなかったですが、3，4回やって慣れてきて答えを覚えてくれば、15分ぐらいで解けるようになります。平日の就寝前や、時間があれば朝の出勤前に日課としてノートに向かうようにします。

##3-4.午後Ⅱ対策
午後Ⅱは、2問から1問を選択して回答する形式です。こちらも問題の傾向は、毎年、似ており。私は、最初からER図の作成が中心の問2と決めて、問2の練習のみしていました。こちらも、過去5年間の過去問題をノートに回答を書いて、反復して練習しました。土日の休日に、1日1問と決めて取り掛かっていました。2.5週間で5年分の練習になります。午後Ⅱは、問題文も長いので解くのに時間が掛かります。最初は1問を解くのに2,3時間掛かってて、ほとんどわからなかったですが、3,4回解けば、慣れてきて1時間ぐらいで解けるようになります。

##3-5.勉強期間
11月にデータベーススペシャリストの受験を思い立って、いろいろと調べたりして、勉強を始めたのは12月からでした。12-3月までの4ヶ月間勉強していたのですが、4/7に春試験の中止が発表され、勉強も中断しました。その後、6/30に10月に試験を実施する事が発表されました。そして、7月から慌てて勉強を再開して、10月までの3ヶ月間、トータル7ヶ月勉強しました。途中に中断があったので思い出しも含んでいます。

#4.試験当日
私の受験した会場は、大学の教室で、20名程度が受験していました。受験者は20-50才台ぐらいで、30才代の方が多い印象を受けました。私は45才と受験者の中では、高齢の部類に属するのかもしれません。試験中は、鉛筆の音が方々からして、みんなスラスラ解けてるように感じて、気負ってしまいました。でも後から考えたら、合格率が15%程度だったので、実際に合格したのはその中で、私を含め３名でした。みんなスラスラとは解けずに、間違ったり分からなかくて、合格できていないのです。十分に準備をして、試験に挑めば、自信を持って、周りに気負う必要はなかったのです。

#5.最後に
上記のように私の場合、過去問を反復して解く事以外の勉強はしておりません。出題される問題は難しく、過去問を解くのに最初の1-2回は苦労します。しかし、ここを乗り切れば3,4回目には、答えを覚えてきて、時間も早くなり、やり易くなります。5,6回目以降は、作業になってきて、楽になります。そこで、出題傾向や関係する語句や意味なども気になり始めて、調べて知識の幅を広がる余裕が出てきます。
勉強は、平日は通勤電車の往復で１時間、夜に0.5-1時間、休日は午後Ⅱ用に1-2時間を確保して日常化させ継続させられた事が勝因に繋がったと思います。
データベーススペシャリストの勉強には、[データベーススペシャリストドットコム](https://www.db-siken.com/)、
[応用情報技術者試験ドットコム](https://www.ap-siken.com/)に大変お世話になりました。
毎日のようにサイトを開いて勉強していました。このようなサイトを無料で開設して頂いた運営会社、管理者の方に心より感謝いたします。
最後に、これから受験される皆さんの幸運をお祈りします。
AWS Service Quotas とは？

## 勉強前イメージ

サービスの制限？
ユーザが使えるサービスを制限するの？
でもIAMとは違うのかな

## 調査

### AWS Service Quotas とは

AWSの各サービスには制限があり、
リージョンごとに作れるサブネットの数だったり、VPCごとのサブネットに制限があります。
元々はサポートセンターにケースを投げて、緩和申請をしていましたが
それをせずともダッシュボードから現在の適応状況や申請履歴などを確認することが出来ます。

AWS Organizations で作った新しいアカウントに適応して
制限を緩和することもできます。

### どこから見れる？

コンソール > Service Qotas で見れることが出来ます。
ダッシュボードから現在適応されてる制限や
リクエストの一覧を確認することが出来ます。

![1ダッシュボード _ AWS Service Quotas - Google Chrome 2021-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/3d5ce18a-a1cd-fac1-97f5-8a00e3bc1466.png)


## 勉強後イメージ

ユーザに制限じゃなくて、サービスの制限かーーー
でも制限あるの知ってたけど、ここで見れるって知ってたっけ？知らなかったっけ？
でも便利だね。


## 参考

- [AWS Service Quotas (サービスクォータ) を使ってみた](https://blog.serverworks.co.jp/tech/2019/10/04/post-74230/)
- [AWS Service Quotas がリリースされました](https://aws.amazon.com/jp/blogs/news/aws-service-quotas/)
特定のユーザーのみSFTP接続させてみる

# 概要
特定のユーザーでのみSFTP接続可能にする設定する必要があったので実施してみた。
備忘がてら、流れをメモする。


# 前提
Webサーバー（今回はさくらインターネットの専用サーバーを使用）
vsftpがインストールされている
SSHでアクセスできる環境


# 手順
## 1.サーバー側でユーザーの設定
SSHでアクセスし、ユーザーを作成する

```
$ ssh -i {key情報} sample@xxx.xxx.xxx.xxx -p xx
Last login: xxxxx from xxxx.jp

SAKURA Internet [Virtual Private Server SERVICE]


# 管理者権限に昇格
[sample@xxxx ~]$ sudo su
[sudo] password for sample:

 # test_userを追加
[root@xxxx sample]# useradd -s /sbin/nologin -d /home/test_user test_user

# パスワード設定
[root@xxxx sample]# passwd test_user
ユーザー test_user のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: 全ての認証トークンが正しく更新できました。

# ユーザーが作成されているか確認
[root@xxxx sample]# /home/
sample/   test_user/

# ディレクトリのパーミッションを設定
[root@xxxx sample]# chmod 755 /home/test_user

# パーミッションの確認
[root@xxxx sample]# cd /home/
[root@xxxx home]# ls -la
合計 xx
drwxr-xr-x.  7 root       root        4096  6月 20 09:20 2021 .
dr-xr-xr-x. 22 sample     sample      4096  8月  7 11:01 2019 ..
drwxr-xr-x   2 test_user  test_user   4096  6月 20 09:20 2021 test_user
```

## 2.sshd_configでSFTP設定

PasswordAuthentication yesにして、SFTPユーザーのみパスワード認証を許可する。

`/etc/ssh/sshd_config`

```vim
：
：
#Subsystem      sftp    /usr/libexec/openssh/sftp-server ← コメントアウトする
Subsystem sftp internal-sftp

Match User test_user
    ChrootDirectory /home
    PasswordAuthentication yes
    X11Forwarding no
    AllowTcpForwarding no
```

設定が完了したら、設定情報のチェックをする

```
[root@xxxx home]# sshd -t
```

問題がなければsshdを再起動する。

```console
[root@xxxx home]# /etc/rc.d/init.d/sshd restart
sshd を停止中:                                             [  OK  ]
sshd を起動中:                                             [  OK  ]
```


## 3.SFTPクライアントから接続する
今回はFileZillaを使用してSFTP設定をする。

### 接続確認

* プロトコル：SFTP
* ホスト：サーバーのIPアドレス
* ポート：SSH接続ポート
* ログオンタイプ：通常
* ユーザー：手順1で作成したユーザー：test_user
* ユーザー：手順1で作成したパスワード：*****

<img width="400" alt="スクリーンショット 2021-06-20 9.45.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248644/3894d276-0639-5002-241c-c8228ea82ec0.png">


### 接続ログ
<img width="400" alt="スクリーンショット 2021-06-20 9.45.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248644/5b307144-e87c-0af5-bde2-618d68734f1c.png">

### 接続完了
リモートサイト側にtest_userが表示された
<img width="400" alt="スクリーンショット 2021-06-20 9.48.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248644/d109ac4f-5f21-e648-12e4-fde72cd60a89.png">


これで一旦接続完了した。

## その他
### グループを使った指定方法
今回はユーザー指定でSFTP設定をしたが、複数のアカウントでSFTP接続できるようにしたい場合は、sshd_configに設定をすれば可能みたい。

```
Match Group {グループ名}
    ChrootDirectory /home
    PasswordAuthentication yes
    X11Forwarding no
    AllowTcpForwarding no
```

特定ユーザーをグループに設定すればよさそう。

```
[root@xxxx home]# usermod -G {グループ名} {ユーザー名}
```

### アクセス制限
ホームフォルダはroot所有にしているため、ファイルのダウンロードはできてもファイルのアップロードはできない。
これは、userフォルダのroot所有にすると、userフォルダ直下にファイルを置くことが原因らしい。
 
## さいごに
個人的にセキュリティ面が気になるが、今回の操作でOS周りの設定に関して少し知識が蓄積された気がする。

## 参考URL
https://worklog.be/archives/3510
【第4章】Railsチュートリアルで手が止まった箇所まとめ（range、inspect、ファイル作成)

[Railsチュートリアル第4章(第6版)](https://railstutorial.jp/chapters/rails_flavored_ruby?version=6.0#cha-rails_flavored_ruby)で、少し悩んだ点を挙げる。

#①－4.2 文字列とメソッド－ にて
● ```nano```エディタからCtrl-Xで離脱する際、```y```キーを押して保存したあと、下記画面で何をすればいいのか分からなかった。
![Railsチュートリアル第4章(2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505219/ee69c2f8-20c2-166c-6d7d-c85f85bbbb65.png)
　→Enterを押せば良いだけだった。


#② －4.3.1 配列と範囲演算子－ にて
● 範囲(range)の```0..9```は省略した説明だと思い、```(0123456789).to_a```などと入力してエラーが発生した。
　→テキストのまま```(0..9).to_a```で良かった。

#③－4.3.3 ハッシュとシンボル－ にて
● いきなりinspectメソッドが使用されていた為、どういうメソッドか一生懸命調べていた。
　→説明が後述されていた。こういうこともあるので、悩んだら後に書かれていないか見てみよう。

#④－4.3.5 ユーザークラス－ にて
● ルートディレクトリに```example_user.rb```ファイルを作成しようとするのだが、コマンド何だったっけ？と思った。
前章に戻って調べてみたが、これまで出てきていないようだ。この時はCloud9から、対象フォルダに```New File```で追加した。
![Railsチュートリアル第4章.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1505219/61dfc01f-5163-e97d-30cf-6b7634d095e2.png)
　→~~後で調べると```touch ファイル名```で作成できることが分かったが、Railsチュートリアルのこれまでの丁寧な説明を考えると、違和感があった。~~
2021/06/25 追記：第3章(3.3.3 Green)に書いてありました。

#まとめ
①②③④で手が止まったが、すぐに解決できた。
[JSTQB AL TM] 　4.欠陥マネジメント　を視覚的にまとめてみた

# はじめに
2021年8月のJSTQB　Advanced Level Test Manager(TM)の試験を受験予定のMa5am1nです。
[シラバス](http://jstqb.jp/dl/JSTQB-Syllabus.Advanced_TM_Version2012.J04.pdf)[^1]を読んでいるのですが、どうも文字が多くて頭に入りにくいので、図など視覚的に入ってきやすそうな形式でまとめてみます。

[^1]: 2012年度版 Advanced Level シラバス　日本語版　-テストマネージャ
**※あくまで私個人の解釈で作成したものです。内容が100%シラバスの通りであることは保証できませんので、ご了承ください。**
**※スライドの青文字、青線になっている箇所は、シラバスに記載されていない、私独自の解釈で記載した内容です。**

このページでは、4.欠陥マネジメントについて扱います。


# 4.欠陥マネジメント
## 4.1 イントロダクション
![JSTQB AL TM.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/06bb4d14-8f02-e384-0358-494f99e79563.jpeg)
![JSTQB AL TM (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/66a0d702-aeb0-a812-2ee0-a0e55ab63b65.jpeg)



## 4.2 欠陥ライフサイクルとソフトウェア開発ライフサイクル
![JSTQB AL TM (2).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/8b7f02aa-ccbe-11db-aac7-fab4abd3ef5b.jpeg)
![JSTQB AL TM (3).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/1839dfaf-4750-7684-a8d8-27a11bcfff63.jpeg)
![JSTQB AL TM (4).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/9c370927-f963-d5c4-6c3b-11db3441110e.jpeg)
![JSTQB AL TM (5).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/d201fe25-b1af-62e8-599b-1f7c417a04bb.jpeg)


### 4.2.1 欠陥ワークフローと状態
![JSTQB AL TM (6).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/c0783fea-6f87-1fb1-9d86-e3ca36d56331.jpeg)


### 4.2.2 無効および重複した欠陥レポートのマネジメント
![JSTQB AL TM (7).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/c2a66ecb-eefb-4ef3-03e4-ac2a44aae4d5.jpeg)


### 4.2.3 クロスファンクショナルな欠陥マネジメント
![JSTQB AL TM (8).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/4de74576-5d07-0756-0c35-4e46dac3aa14.jpeg)


## 4.3 欠陥レポート情報
![JSTQB AL TM (9).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/c7005ea0-e032-d054-08f3-b825a8778363.jpeg)
![JSTQB AL TM (10).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/9526acba-bdca-5579-358e-d3c72fa31f93.jpeg)
![JSTQB AL TM (11).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/56f1a202-7743-bbc1-cc11-e51b0e168884.jpeg)
![JSTQB AL TM (12).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/c60928c6-754c-4461-0692-8416002820fe.jpeg)
![JSTQB AL TM (13).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/92a8c825-4fcb-05ed-cd42-684d3b6f57d5.jpeg)
![JSTQB AL TM (14).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/25759120-713a-c943-eafa-3abb4c7b8976.jpeg)


## 4.4 欠陥レポート情報によるプロセス能力の評価
![JSTQB AL TM (15).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/a1cc87da-1c29-9f61-3e8f-854a50f5214f.jpeg)
![JSTQB AL TM (16).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1636570/efec17ec-1ad7-e092-6db8-32f493a639af.jpeg)
【Ruby】キーワード引数をハッシュ変数として受け取る

## やりたいこと

このようなメソッドがあるとする。

```ruby
def my_method(key1:, key2:)
  # do something
end
```

このメソッドの中で `{key1: 引数値, key2: 引数値}` のような hash が欲しい。

## まずはメソッドの引数の定義情報を得る

定義したメソッドの引数名の一覧は [Method\#parameters](https://docs.ruby-lang.org/ja/latest/method/Method/i/parameters.html) で得られる。

```ruby
def my_method(key1:, key2:, key3:)
  p method(__method__).parameters
  # => [[:keyreq, :key1], [:keyreq, :key2], [:keyreq, :key3]]
end

my_method(key1: "val1", key2: "val2", key3: "val3")
```

上記の様に [Method\#parameters](https://docs.ruby-lang.org/ja/latest/method/Method/i/parameters.html) は引数の数だけの要素数の配列を返す。各要素の1つ目の要素は **引数の種類を表すシンボル**、2つ目の要素は **引数名** となる。実際の引数の値は含まれない点に留意する。

今回はキーワード引数のデフォルト値を定義してない為、各1つ目の要素は「必須のキーワード引数」を表す `:keyreq` となっている。

キーワード引数を表すシンボルは `:keyreq` か `:key` なので、これらに一致する変数をハッシュに変換できれば実現できそう。

ということで実現方法は以下。

## キーワード引数をハッシュとして受け取る方法

eval で変数名を評価した結果（つまり変数の値）をハッシュに入れていく。

```ruby
def my_method(key1:, key2:)
  named_params = method(__method__).parameters.each_with_object({}) do |p, h|
    parameter_type, name = p
    is_keyword_parameter = [:key, :keyreq].include? parameter_type
    next unless is_keyword_parameter

    h[name] = eval(name.to_s)
  end

  p named_params
  # => {:key1=>"val1", :key2=>"val2"}
end

my_method(key1: "val1", key2: "val2")
```

### 短縮版

```ruby
def my_method(key1:, key2:)
  named_params = method(__method__).parameters.each_with_object({}) do |p, h|
    h[p[1]] = eval(p[1].to_s) if [:key, :keyreq].include? p[0]
  end

  p named_params
  # => {:key1=>"val1", :key2=>"val2"}
end

my_method(key1: "val1", key2: "val2")
```

## 参考

- [Method\#parameters \(Ruby 3\.0\.0 リファレンスマニュアル\)](https://docs.ruby-lang.org/ja/latest/method/Method/i/parameters.html)
- [ruby \- How can I get named parameters into a Hash? \- Stack Overflow](https://stackoverflow.com/questions/21998417/how-can-i-get-named-parameters-into-a-hash)
【Cloudflareを用いた独自ドメインのSSL対応】Herokuで無料で独自ドメインありのウェブサービスを運用するための手順

## この記事を書くモチベーション
お名前ドットコムで取得した独自ドメインを用いて、Herokuで無料プラン内で運用するための設定について書いていきます。

独自ドメインの適用、ならびにSSL対応部分についてはCloudflareを利用します。
こちらも無料プラン内で利用するので、結果的に無料で独自ドメイン対応&SSL対応させたウェブサービスの運用が可能です。

もちろん無料プランだとHerokuはアクセスがないとサーバが寝てしまうので、ある程度そういうものを許容した上での運用となります。
Herokuの無料プランで運用する上での注意点などは書きません。

なお、このような情報はもういくつもの記事が書かれています。

ただ、自分が必要としたときにサクッと手順を確認できるような、まとめられた記事が見つからなかったので(探し方が下手なのかも)、まとめようと思った次第です。

数年前にもHerokuでここに書くような設定を行っていたはずですが、今回再び同じような手段を用いようとしたとき、すっかり記憶から設定手順が抜け落ちて、10~20分ほどインターネット検索のために時間が取られてしまいました。

おそらく数年後に、また同じような手段を用いて私はHerokuでウェブサービスをリリースしようとするでしょう。

そのときにサクッと見返せるドキュメントがウェブ上に転がってほしい。この記事を書くモチベーションはそこにあります。

## やることの概要

やることは下記ですが、Herokuに関する設定の記述は殆どありません。
ほぼほぼCloudflareの話でした。

* Herokuの無料プランを用いてWebアプリをデプロイ
* お名前ドットコムで取得した独自ドメインを適用する
* Cloudflareを利用してSSL対応(無料プラン)
* `www.example.com` から `example.com` への301リダイレクト設定

## Herokuの無料プランを用いてWebアプリをデプロイ

特に説明はありません。

まずは普通にHerokuの無料プランでウェブアプリをデプロイします。

この時点で `example.herokuapp.com` 的なドメインが割り当てられています。

このドメインをお名前ドットコムで取得したドメインに差し替えます。
(ここでは例として`example.com`とします。Herokuは例として `example.herokuapp.com` で書いていきます。適宜読み替えてください)

## お名前ドットコムで取得した独自ドメインを適用する

お名前ドットコムで独自ドメインを取得します。

ここもドキュメントに残すことが特にありません。

ドメインを取得したら、あとでネームサーバを変更するので、ログインしたままにしときます。

## Cloudflareを利用してSSL対応(無料プラン)
まずはCloudflareにログインして、ドメインの追加を行います。

ここで追加するドメインはお名前ドットコムで取得したドメインです。

ドメインの追加を行うとどのプランを使うのか聞かれるので無料プランを選択します。

![Cloudflareの無料プランを選択](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205976/73127408-ed74-dd77-db37-2d8d630bd5a7.png)

次にCloudflareのネームサーバーが２つ表示されるので、これを下記のようにお名前ドットコム側で設定します。
(特にマスクしなくても良い気がしましたが、一応しときます)

![お名前ドットコムのネームサーバーを変更](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205976/35f9ce6c-846a-4a51-4c6e-232d249d3136.png)

次にメニューから `DNS` を選択し、CNAMEの設定を行っていきます。

![CloudflareのDNS設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205976/39239f67-172a-19f5-6ded-be6f22f0136e.png)

下記のように設定しました。

今回、 `A`, `AAAA` ではなく、`CNAME`でどちらも(`example.com` も　`www.example.com`も)追加しています。

![CloudflareのDNS設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205976/3b5a5dd4-7d49-f98d-1075-f736f9a449ef.png)

これでDNSの設定は完了です。


## www有りから、www無しにリダイレクトを行う
今回www付きのドメインを含めた２種類をCloudflareに登録しましたが、www有りのドメインについてはwwwなしの方にリダイレクトさせます。

ここの詳細については、[Cloudflare - すべてのユーザーに必須のPage Rule](https://www.cloudflare.com/ja-jp/features-page-rules/must-use-page-rules/)を参照しています。

![CloudflareでPage Ruleの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205976/63c908b8-12d8-d2c0-8cda-2af9602f5ba7.png)

ちなみに無料プラン内だとページルールは３つまで設定できるそうです。

今回はwww有りからwwwなしへの301リダイレクトのみを設定するので、設定は１つだけです。

下記のように設定しました。
(初回の設定画面だと `保存してデプロイ` というボタンがあり、それを押すことで適用されます。キャプチャは一度デプロイし終えたあとの編集画面なので文言は微妙に異なります)

![CloudflareでPage Ruleの設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205976/38b33c66-4b43-c52e-b946-d489ac62615a.png)

これで `www.example.com` から `example.com` へ301リダイレクトするようになります。

これらの設定を行い、だいたい数時間から１日ぐらい待っていると設定が完了されます。

自分の場合はどれぐらいで設定が反映されたか計っていないですが、就寝前に設定して起きたら反映が完了していました。
AWSのアカウント作成

前提
-
無料枠を使い切ったので解約して新しくAWSアカウントを作成します

用意するもの
-
メールアドレスとパスワード
クレカかデビットカード
スマホ（認証するので）
パスワードにする文字列を考えておく
メモちょう

手順
-

①既存のAWSアカウントを解約する（必要なら残しておく）
②新しくAWSアカウントを作成する
クレカ情報・住所氏名・パスワード
③作成できたらログインして請求アラートが届くようにする
④ルートアカウントにMFAを設定する
スマホのアプリに現れた最初の文字列を入力
↓
スマホの画面を凝視して30秒更新後の文字列を入力する
⑤IAMユーザを作成する。AdministratorAccessを割り当てる
⑥ルートのアカウント情報から、IAMユーザで請求情報が見られるようにする。
また、USDからJPYに請求の表示を変更する（見やすいので）

所感
-
はじめてAWSでMFA認証を設定した。