OmniAICreator/Qiita-1.07M huggingface dataset:
PythonZen & PEP 8 検定試験を受験した所感と活用法について

# 概要

3月より公開されたPythonZen & PEP 8 検定試験を受験したので、それについて所感をまとめます。

# PythonZen & PEP 8 検定試験とは

おおまかには、無料で受験することができるPythonの記法に関する試験。


[Link: Pythonのお作法ともいえるPython ZenとPEP8の理解度を無料で測定できるPythonZen & PEP 8 検定試験を公開しました。](https://www.pythonic-exam.com/archives/news/python-zen)

試験設立の経緯は以下の通り。

>Pythonは人工知能、機械学習、ビッグデータ、ネットワークインフラ（自動運用等）で中心的に使用されています。各分野の成長が著しく、Pythonの求人数は年間1.5倍前後で増えています。Python需要の増加に伴い、Pythonの関連書籍やプログラミングスクールが増える一方、Pythonを知らない人が書いている書籍やPythonZenやPEP 8を知らない講師が、不適切なPython文法を教えてしまうケースが散見されています。このままの状況が続くと、不適切なPython文法を書いてしまうPythonエンジニアが増える可能性があり、Pythonエンジニア育成推進協会はPythonZenやPEP 8を学ぶ意識を市場で高めるべく、PythonZenとPEP 8から出題する「PythonZen & PEP 8 検定試験」を無償で提供することにいたしました。


試験概要は以下の通り。

>◆「PythonZen & PEP 8 検定試験」概要
試験名称：PythonZen & PEP 8 検定試験
概要：PythonZen（The Zen of Python）とPEP 8に関する知識を問う試験
受験料金：無料
問題数：20問（すべて選択問題）
合格ライン：正答率70％
試験方式：WBT（インターネットが接続できるブラウザ環境があれば、だれでも受験できます）
出題範囲：PythonZenとPEP 8より出題


# 受験した所感

受験時は、PythonZenについて軽く目を通した上で、挑戦しました。
（PEP8については大まかに理解していたと自負していたため省略）


結果は、何とか初回で合格。

受けてみての感想としては、PEP8やPythonZenについて何度か目を通しておけば合格できるくらいの難易度だと感じました。
逆に言うと、Pythonにそれなりに慣れている人でも、事前勉強なしの場合、1回で合格するかというとそうとは言えないように感じました。

一方で、実際にプログラムを記述するわけでなく、全問選択肢形式であるため、基本知識ゲーで実践的ではないかなとも感じました。（これに限らずPython認定試験全般に言えるが）

そのため、正直そこまで慣れていなくても合格は可能だろうと思ますし、無料で(恐らく何度も)受験もできるので、認定証自体にそこまで大きな価値はないでしょう。

# 活用法について

前述の通り、資格取得を目的としてこの試験に取り組むのはそこまで意味はないと思います。

しかし、冒頭で引用した通り、不適切にPythonを実装しているエンジニアも多いです。
いくつか理由はあると思いますが、その一つとして、近年増加してきたデータ分析系の利用を目的とした、Python以外のプログラミング言語経験がないようなデータサイエンティストの存在が考えられます。
私もデータ分析系のキャリアを歩んできた上で、プログラミングスキルが若干心許ない人材と出会うことも度々あり、彼らの再利用性や可読性の低い実装に遭遇したことがあります。

Pythonは比較的習得の敷居が低い言語ではありますが、言語仕様の自由度が高いこともあり、コーディング規約を大きく外れたトンデモ実装も生まれやすいです。
そういった実装は後々問題が生じますし、それは個人の問題でなく、チーム開発の場合、全体の生産性に影響を与えてしまいます。

前置きが長くなりましたが、このPythonZen & PEP 8 検定試験は、設計や一般的な規約の方針を確認するための１つのツールとして役立つと思いました。

特にPythonを使ったチーム開発を行っている場合、無料であることで受験自体の敷居も低いので、チームビルディング的にメンバー全員で受験してみて、その結果を受けて振り返りながらチームとしての開発時の指針を立てるのも面白そうです。

# 関連

- [コードレビューに関する指針](https://qiita.com/calderarie/items/a447cb0d1b034f951a90)
- [弊チームのマネジメント・ビルディング取り組み](https://qiita.com/calderarie/items/521e6b077abeaaa2e6d5)
sourcetreeでpre-commitに追加したときに、php: command not found　が出たときの対応方法

.git/hooks/pre-commitにスクリプトを入れ、SourceTreeでcommitすると
下記のエラーが出た
```php
.git/hooks/pre-commit: line 25: php: command not found
```
対応方法

pre-commitファイルの二行目に、echo $SHELLをして、出てくる、下記を入れる

source ~/.zshrc

また、~/.zshrc　の中には下記のようにPHPへのPATHを入れておく

export PATH=/opt/homebrew/opt/php@8.1/bin:$PATH



参考
https://www.underthecocotree.co.uk/blog/a-tale-of-sourcetree-and-git-hooks


別に
https://qiita.com/masato_makino/items/43787b6dfc49fe3b4d94
というやり方もあるみたい。
【１日目】ボタンを押したら何かが表示されるプログラムを作る

# ０.はじめに
この記事はプログラミングの特訓をしている高専4年生(もうすぐ5年生)がその日勉強した内容を記録していきます。
何か月か続く予定。

# １.本日の課題
今日はHTMLとJavaScriptを使ってボタンを押したら何かを表示させるプログラムを作成する。
HTMLもJavaScriptもあまり触ったことがなくネットを参考に自分なりに書いてみた。

```html
<html>
 <body>
  <input type="button" value="test button" onclick="buttonClick()">
 <div id="id1"></div>
  <script>
   function buttonClick()　{
   p = document.getElementById("id1");
   p.innerHTML = "表示されました！";
   }
  </script>
 </body>
</html>
```


このプログラムを先生に評価してもらったところ次の改善点を告げられた。
***
- id名はどういった役割かの名前にする
- 変数の前にletを付ける
- 関数の名前
***

これらの改善点からプログラムを修正した↓
```html
<html>

<body>
    <input type="button" value="test button" onclick="clickedButton()">
    <div id="output"></div>


    <script>
        function clickedButton() {
            let output = document.getElementById("output");
            output.innerHTML = "表示されました！";
        }
    </script>

</body>

</html>
```

# ２.本日の学んだこと
- HTMLの基本的な使い方のおさらい、JavaScriptを少し理解することができた。
- 関数やidの名前の付け方は意識してみる。
- プログラムは結構見た目大事。


今日から本格的に就活に向けてのプログラミングの勉強を始めた。Qiitaに書き込むのもこれが初めてなので拙い点があればごめんなさい…
AWS セキュリティサービスの考察

# AWSセキュリティサービス

<table><tr><td>ネットワークセキュリティ</td><td>AWS Network Firewall</td></tr>
<tr><td>DDos保護</td><td>AWS Shield (Advanced)</td></tr>
<tr><td>悪意のあるウェブトラフィックをフィルタリング</td><td>AWS Web Application Firewall (WAF)</td></tr>
<tr><td>アクセス元/先およびポートの設定</td><td>VPC　Security　Groups</td></tr>
<tr><td>DNS保護</td><td>Route 53 Resolver DNS Firewall</td></tr>
<tr><td>※上記ルールの一元管理</td><td>AWS Firewall Manager</td></tr>
</table>

# AWS Network FireWallとは
- AWS Network Firewall は、すべての Amazon Virtual Private Cloud (VPC) に不可欠なネットワーク保護を簡単にデプロイできるようにするマネージドサービスです。

-特徴 
-
- トラフィックのフィルター　＜ドメイン、IP＞
- パケットのインスペクション
- シグネチャベースの検出を使用して脆弱性の悪用を特定してブロック
- 既知の不正な URL へのトラフィックを停止し、完全修飾ドメイン名を監視できるウェブフィルタリング
- プロトコルのフィルター　＜HTTPSなど＞

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1348505/110ac908-230b-2480-05bd-280ebb81631c.png)

リンク：https://aws.amazon.com/jp/network-firewall/?c=sc&sec=srv&whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc

# AWS Web Application Firewall (WAF)とは
- AWS WAF は、可用性、セキュリティ侵害、リソースの過剰消費に影響を与えるような、ウェブの脆弱性を利用した一般的な攻撃やボットから、ウェブアプリケーションまたは API を保護するウェブアプリケーションファイアウォールです。

-特徴 
-
- ウェブトラフィックフィルタリング
(SQL インジェクションやクロスサイトスクリプティングなどの一般的な攻撃パターンをブロックするセキュリティルールを作成できる)
- 特定のトラフィックパターン
- AWS WAF Bot Control
- アカウント乗っ取り詐欺の防止
- フル機能 API
- リアルタイムの可視性


# AWS Shieldとは
- AWS Shield はマネージド型の分散サービス妨害 (DDoS) に対する保護サービスで、AWS で実行しているアプリケーションを保護します。

-特徴 
-
- DDoS 保護
(アプリケーションのダウンタイムとレイテンシーを最小限に抑える常時稼働の検出と自動インライン緩和策を提供)
- インフラストラクチャ (レイヤー 3 および 4) を標的とするすべての既知の攻撃を総合的に保護、緩和
- アプリケーションを標的とした攻撃に対する高レベルな保護(AWS Shield Advanced)
(Amazon Elastic Compute Cloud (EC2)、Elastic Load Balancing (ELB)、Amazon CloudFront、AWS Global Accelerator、および Amazon Route 53)
- アプリケーショントラフィックパターンに基づいてカスタマイズされた検出(AWS Shield Advanced)
- 正常性に基づく検出(AWS Shield Advanced)
- 高度な攻撃緩和機能(AWS Shield Advanced)
- 自動アプリケーションレイヤー DDoS 緩和策(AWS Shield Advanced)
- 積極的なイベント応答(AWS Shield Advanced)


また、AWSプラットフォームの不正検出、評価/監査については、
＞Amazon Detective
※https://aws.amazon.com/jp/detective/features/

＞Amazon Inspector
※https://aws.amazon.com/jp/inspector/features/?nc=sn&loc=2&refid=d1ff3f5f-6dcd-4f4c-b4df-5fabf2f83c66

＞Amazon GuardDuty
https://aws.amazon.com/jp/guardduty/features/

＞AWS Audit Manager
https://aws.amazon.com/jp/audit-manager/features/
エクスプローラーのアドレスバーから管理者権限でコマンドプロンプトを起動する

# 経緯
先日上司(?) にケースレビューをお願いしてる際にふと、エクスプローラーからコマンドプロンプトを起動したところ
「今のそれどうやったんすか！？」
と熱い食いつきをされて下記でコマンドプロンプトを起動する術を紹介する機会がありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/aa97d5f2-1f2d-f040-4973-4f5c70e3ef7d.png)
(アドレスバーに cmd を入力して Enter)

これでコマンドプロンプト自体は起動するのですが、
残念ながらこのレビュー時には regsrv32 を扱うため管理者権限がないとダメで、
「そっかぁ…」
と上司(?)に残念がられるがっかり案件になってしまいました。

# で。
悔しかったので実現してみました。

# 結論
下記のバッチファイルを C:\Windows\System32 などの、環境変数でパスが通っている箇所に放り込みます。
名前はここではca (cmd admin)としておりますがご自由に。

```powershell:ca.bat
powershell start-process cmd -verb runas -ArgumentList '/k ""cd /d %CD%""'
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/6225cd93-6785-2bae-bd50-d85d7f170967.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48302/82933a8e-dca2-4dec-8bdc-60619fab556e.png)

これで任意のフォルダのアドレスバーに "ca"と打ち込むと管理者権限でコマンドプロンプトが起動します。
やっ↓たぜ↑。
Power Automate for desktop のインストーラーをダウンロードする方法


# Power Automate for deskutop のインストーラーがある場所
Power Automate for desktop の公式サイトからのインストールが、Microsoft Store からのインストール手順に変更になり、インストーラーがダウンロードできないという話題を見るようになりました。

Power Automate for desktop のインストーラーは以下のリンクからダウンロードすることできます。
(リンクをクリックすると EXE ファイルのダウンロードが始まります)

https://go.microsoft.com/fwlink/?linkid=2102613

上記は、以下の公開情報でも紹介されているリンクになります。

https://docs.microsoft.com/en-us/power-automate/desktop-flows/install
【Azure】QnA Makerでノーコードでbot作ってみた


# 概要

試作的に一問一答botを作ってみた。

Dos Commandのbot
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411736/7b1d3a6c-a6c6-e0aa-f6d2-e6d5c1d53c00.png)



## 大まかな流れ
・AzureのQnA Makerを利用。
・ナレッジベースはDos Commandの逆引き情報をExcel化して取り込み

## やったこと


### 1.QnA Maker を検索し作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411736/d36dec90-ba9f-f9d5-7890-927422b6752f.png)


### 2.プロジェクトの詳細を入力
サブスクリプション・リソースグループ・価格レベル・Azure searchの詳細を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411736/fd011913-aa20-274e-30be-8abc5c85926f.png)


### 3.knowledge baseを作成
各ステップ項目に入力していく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411736/b90149eb-931d-e917-1e68-41347c6a14da.png)

ステップ4にて、ナレッジのソースを選択可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411736/938fbaa5-b209-c747-999d-9209cd13949a.png)



URL　　　：FaQサイトのURLを入れると、なんとサイトのFaQの内容が、そのままbotで利用できる。
※うまく反映されないサイトもあり

ファイル：QA形式の問と回答が一対となったExcelファイルを取り込むと、そのままbotで利用できる。

※なにも入力せず、作成するとナレッジベースを1つずつ手入力も可能。

ここでは、Dos commandのExcelファイルの取り込みを実施。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411736/f8d18e6d-1b2b-ef26-1410-15a53f531deb.png)

### 4. trainingしてテストを実施
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411736/5dfdabe3-ae3b-81d8-d0e1-e3d0f9e9f1ee.png)

### 5.publish→bot作成OK

## 分かること•気づいたこと

・完全一致で質問すればスコアが当然高いが、完全一致でなくても作成当初から回答される

・完全一致でない場合は、候補のうちスコアが高いものが抽出される。

・誤ったスコアであった場合は、正解を選択してあげると次回以降学習してくれる。

•代替の質問文を追加できる

・スコアがつかないものは対象外となる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411736/edfddfe1-9034-00eb-7ac5-956b74eeb45d.png)

## 感想
シンプルな一問一答botなため活用方法は限られるが、
さらにluisなど使って文章に幅を持たせても活用できるようなモノをトライしたい。
（ユーザーからの問い合わせをこれに任せる、なんてことしたい）

## 引用

Dos Command　
https://www.pg-fl.jp/program/dos/doscmd/index_p.htm
透過の背景色を指定したらタブレットでグレー表示されてしまった話

現場での業務からのお話です。

デザイナーさんから頂いたPSDファイルを元にコーディング作業を進めるのですが、
今回、背景画像の端っこがフェードアウトしていくデザイン（画像背景→白背景）になっておりました。
背景がループしたデザインなので、いつも通りCSSプロパティの「background-repeat」で表示を繰り返していき、端っこの部分は疑似要素（after）を用いてフェードアウト専用のエリアを作成。そこにグラデーションを作れるプロパティ「linear-gradient」を使えば再現出来ると考え実行しました。
```ruby
linear-gradient(to bottom, '画像', '白');
```
単純に白を使うと万が一他のエリアで背景色を使いたいとなった際や、画像と被った時に手間がかかってしまうので透明色を使おう！という事で透明色である「transparent」を設定しました。
再現出来たので各ブラウザ（ChromeやEdge）で確認し、表示に問題ないのを見ているとタブレット端末で悲劇は起きました……

<img width="400" alt="prev_001.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2151781/5c127a76-c92b-72ae-6544-f5f60a60f348.jpeg">

###### 「謎の濃いグレーの線が入っている」
 

再度PCの各ブラウザで確認しましたがそれらしき物は見当たりませんでした。しかしタブレット端末で見ると何故か入っている……
linear-gradientの指定方法に誤りがあると思い、調べてみましたが特に間違った点が見つからない……
調べ方を変えて、同じ様な現象が起きた人はいないか調べたところ下記の記事に辿り着きました。

https://www.msng.info/archives/2021/09/css-transparent

記事を読み進めると自分に起きた現象と全く同じ事が起きていました。
どうやら<font color="red">機種によって見え方に違いがある</font>様です。
※タブレット機種にだけ起きたのは自分が担当していたのがPC・タブレット専用のページであった為ですね。参画している現場はレスポンシブをせずにPC・タブレットとスマートフォン用で別々で構成されたページになっています。

>「厳密には、transparent は rgba(0,0,0,0) のショートカットです」
>（MDN Web Docsから引用）
> https://developer.mozilla.org/ja/docs/Web/CSS/color_value

これは盲点でした。ただ「透明色」という認識でしたが正しくは「<font color="red">透明化された黒色</font>」という訳だったのですね。
rgbaのaは「アルファ値」を示していて0が透明で1が透過されてない状態を表すので、
この部分もグラデーションを設定した事により数値が変わっていく……という事でした。

今回の解決策として
```ruby
linear-gradient('背景画像', rgba(255, 255, 255, 0))
```

この様に記述して「透明化された白」とした所、問題の濃いグレーの線はタブレット端末の画面から姿を消してくれました。

<img width="400" alt="prev_0002.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2151781/86cb3db0-911d-9e9d-e351-56d461c77623.jpeg">

便利なので何かと使う機会の多いtransparentですが、この様な落とし穴があるとは思いませんでした。
皆さんも使い慣れたはずのプロパティの仕様で混乱しないように、時々調べ直してみると良いと思います！
エンジニアの仕事に必要なエクセル関数

エンジニアとしてプログラムを書くうんぬんの前に、エクセルの知識をつけておくこともとっても重要です。関数を知らなくて大恥をかいたのでメモ。内容は走り書きなので後日詳しくしていこうと思います。
<br>


## よく使う関数たち
#### 1.COUNTIF
#### 2.VLOOKUP
#### 3.TRIM
#### 4.SUBSTITUTE
<br>
上の関数を順に見ていきたいと思います。


## 1.COUNTIF
特定の検索条件(1つ)に一致するセルの個数を返す関数。構文は以下のとおり。
```
COUNTIF(検索範囲,検索条件)
```
例えば、A列から「hoge」という文字列が記述されているセルの数を求める場合、記述例は以下のようになる。
```
COUNTIF(A:A,"hoge")
```
なお、COUNTIF関数の注意点は以下のとおり。

:::note warn
1.大文字と小文字は区別されない</b>
2.検索条件を複数設定することはできない。(複数の場合はCOUNTIFS関数を使用する)
:::

なお、結果を数字ではなくマルやバツ(○☓)で表示したい場合は以下のとおり。検索条件に一致するセルが1つ以上ある場合はマルバツで結果が返ってくる。
```
IF(COUNTIF(検索範囲,検索条件),"○","×")
```
この書き方を利用することも多いかもしれない。
<br>


## 2.VLOOKUP(Vertical Look Up)
エクセル表の列方向(縦方向)にデータを検索し、値が一致したセルがある行(横方向)のデータを返す関数。特定の値で表を検索して、表の中の必要な値を抽出することが可能。構文は以下のとおり。
```
VLOOKUP(検索値,検索範囲,列番号,検索の型)
```
記述例は以下のとおり。
```
VLOOKUP("hoge",A:C,1,FALSE)
```
なお、COUNTIF関数の注意点は以下のとおり。エクセルに書いたデータベースのテーブル表から値を取得する時などに使用することになりそう。便利。
<br>



## 3.TRIM
対象のセルに書かれた文字列の前後にあるスペースを削除する関数。文字列の間にあるスペースは削除できないので注意。(文字列の間にあるスペースを削除する場合は次のSUBSTITUTE関数を参照)構文は以下のとおり。
```
TRIM(対象のセル)
```



## 4.SUBSTITUTE
対象のセルに書かれた任意の文字を置換した結果を表示することができる関数。構文は以下のとおり。
```
SUBSTITUTE(対象のセル,置換したい文字,置換後の文字)
```
例えば、A1セルにHello Worldと書かれているとする。このセルのHelloの部分をhogeに置換する場合は以下のとおり。
```
SUBSTITUTE(A1,"Hello","hoge")   #hoge World とセルに出力される
```

<br>
とりあえず以上。どんどん追記していきたいと思います。
2021年度 新卒エンジニアが2か月でAWS-SAAを取得できた。

2022年3月5日にAWS認定ソリューションアーキテクトアソシエイトに合格できたことから、経験の浅い人でも合格できる、その理由を解説したいと思います。初投稿！！

# 1.資格取得の理由
　はじめに、私がなぜAWS-SAAを取得しようと考えたのか。
　1番は実務に活かしたいから。ただそれだけではやる気出ない方が多いと思います（私もそうでした）:relaxed::relaxed:
 あと2つほどやる気がでるかなあと思ったのが以下2つ

## 2.やる気だすために知っておきたいこと！！！
### 2-1.世界シェアの高さ
![synagy-2022-01-1024x696.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2584969/8170026a-0e63-1c9c-a71a-08b320208f2a.jpeg)
上記画像を見てわかるように、amazonのAWSは世界シェアトップ(30~35%)を占めています。
　また、amazonはAWSへの投資額を毎年増やしています。規模の経済というものがあるように、AWSの規模が大きくなればなるほど利用費用が下がります。みなさん安い方がいいですよね～。クライアントもそうです。今後もAWS案件は増え続けるといわれています。

### 2-2.AWSエンジニアは給料がいい
　AWSエンジニアの年収は600万円が相場といわれています。(もちろんインフラ全般知識が必要)
　フリーランスにもなると900万円ほどになります。(正社員以上に知識必要)

## 3.使った参考書や問題集
　ではやる気の出たところで、実際使ってよかったものを紹介します。
私は2か月間毎日コツコツやって受かりました。

### 3-1.おすすめ参考書
　おすすめとは言ったのですが、実務経験者 + AWSクラウドプラクティショナー取得者は必要ないかもしれません。いきなりAWS-SAAに挑む人におすすめです。
https://www.amazon.co.jp/dp/B08SGSD479/?coliid=I301BGND8VGX98&colid=312QNGRRMXOJT&psc=0&ref_=lv_ov_lig_dp_it_im
[改訂新版 徹底攻略 AWS認定 ソリューションアーキテクト − アソシエイト教科書［SAA-C02］対応 徹底攻略シリーズ
鳥谷部 昭寛  (著), 宮口 光平 (著), 菖蒲 淳司 (著) ]
![519DqB8xIvL.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2584969/67c696f5-3318-c955-0013-c60461ee1222.jpeg)
実務経験者におすすめしない理由は、内容があまりにも簡単だからです。全体的な知識をザーっと確認するにはいいかもしれません。

### 3-2.おすすめ問題集
なんといってもこちらの問題集がおすすめです。ほかの教材で迷ってる時間がもったいない！
koiwaのweb問題集です。本番に近い形式で構成されています。大体3割が同じような問題。

　https://aws.koiwaclub.com/

　プラン・料金は公式サイトを見ていただきたいのですが、AWS-SAAに合格するためには4480円(90日間)かかります。

　まあ、受験料16500円に比べれば安い物です。再受験なんてなったら最悪ですよね。。。
　こちらは7問一括り(←これが160個=1200問ほど)になっていて取り組みやすいです。
　実践形式のテストもあります。
このテストで8.5割とれていれば合格ライン(公式)だそうです。
実際、私も8.5割ほどで本試験に受かることができました。

## 4.まとめ
　参考になりましたでしょうか:hugging:
初学者でも合格できて、市場価値も高めることができるAWS資格！
　私の経験が駆け出しエンジニアだったり、未経験からのエンジニア転職を考えている方、そんな人たちの目に留まるとうれしいです！:relaxed:

　初投稿であったので、文章拙いですが、お許しを:sweat_smile:
VSCodeでデフォルトから変更を加えた事項

# 設定
- Editor > Bracket Pair Colorization:Enabledのチェックボックスにチェック
- Editor > Guides:Bracket Pairsを「true」へ変更
- Files : Trim Trailing Whitespaceのチェックボックスにチェック
- Editor : Render Whitespaceを「all」へ変更
- Files : Trim FinalNewlinesのチェックボックスにチェック


# 拡張機能
- Japanese Language Pack for Visual Studio Code
- indent-rainbow
- zenkaku
    - 一時的に有効にする場合：VSCodeのメニューバー→表示→コマンドパレット
→zenkakuと入力→「Enable Zenkaku」を選択
    - 常に有効にする場合：ホームディレクトリ配下の/.vscode/extensions/mosapride.zenkaku-○.〇.〇/extension.jsファイルを開き、5行目のvar enabled = false;→var enabled = true;へ変更）
- Code Spell Checker
- Duplicate action
- Ruby（インストールすると「VSCode Ruby」という拡張機能も自動でインストールされる）
- endwise（endが必要なときに自動で挿入される機能）
- GitLens
- Live Server
Lightsail の WordPress で E メール を有効にする

# 環境
* AWS LightSail
* 512 MB RAM、1 vCPU、20 GB のSSD
* WordPress
* 独自ドメイン（お名前ドットコム）

# 経緯
SESのUIが新しくなったのか分からないが、公式の手順も他の手順も無いため、備忘として残す。

# Identityの作成
>Amazon SES では、ドメインを検証して、それを所有していることを確認し、他のユーザーに使用されないようにする必要があります。
1. アイデンティティの作成<br>Verified identities＞Create Identity<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/8f8a2da8-9f07-a883-48b6-12f1d031d6d8.png)
1. 以下を選択
Identity type：domain
domain：（Lightsail上で利用している独自ドメイン）
Identity type：Easy DKIM
Publish DNS records to Route53:Enabled
DKIM signatures:Enabled
1. Create identityをクリック

# ドメインの検証
1. 「登録したidentities＞Authenticationタブ」にCNAMEが3つあるので、それをLightsailのネットワーキングでレコードの追加をする。
Name→サブドメイン（※Nameのドメインを抜いた形で張り付ける）
Value→マップ先
1. 作成したIdentityのステータスがVerifiedになるのを待つ

# メールを確認
1. 先ほど入力したアドレスに以下のような確認メールがくるので、URLに飛ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/44c26be4-671a-624b-e6ce-03c711595c02.png)
1. 飛ぶことでメールアドレスの検証が完了する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/00a50e5f-19bd-d6e5-db2b-3a2edc370057.png)
1. メールアドレスが検証済みになる
Verified identitiesを確認する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/65786eeb-4c79-2b8d-d293-948db44554cc.png)

# SMTPクレデンシャルの作成
1. SESのダッシュボードのCreate SMTP credentialsをクリック
1. ユーザ作成画面になるので、デフォルトのまま作成
1. SMTP認証?の情報があるのでコピペなりして保存しておく。

# メールアドレスの作成
1. アイデンティティの作成<br>Verified identities＞Create Identity
1. 以下を選択
Identity type：emailaddress
emailaddress：作成したいアドレスを入力
1. Create identityをクリック
1. 作成され、Verifiedになっていることを確認<br>ドメインがVerifiedになっていれば、そのメールはすぐにVerifiedになるらしい。

# メールのテスト
1. ドメインにチェックを入れてsent test emailをクリック
1. Fromaddressに作成したアドレスを入力し、件名や内容を入力
1. Test send emailをクリック
1. success的な通知がコンソール上に出ればOK

# WordPress インスタンスに WP Mail SMTP プラグインを設定する
1. WordpressにWP Mail SMTP プラグインを有効化する
1. 送信元メールアドレスに作成したアドレスを入力
1. このメールを強制使用にチェックを入れる
1. フォーム名にメールの送信元となる名前を入れる
1. この名前を強制使用にチェックを入れる
1. メーラーをその他のSMTPを選択する
1. 返信先の「送信元アドレスを返信先 (return-path) として設定」のチェックを入れる
1. SMTP ホストにSESのダッシュボードにあるSMTP endpointをコピペ
1. 暗号化はTLSを選択
1. SMTPポートは587
1. 認証はON
1. ユーザー名、パスワードはさきほどメモったのを入力
1. 設定を保存
1. メールテストで送信先を入力し、メールを送信する<br>※サンドボックス制限中は検証したアドレスにしか送れないため、事前に送信先のアドレスもSESでCreate Identityで登録しておく必要がある。
1. メールが送れればOK

# サンドボックス制限を外す
1. SESのダッシュボードのRequest production accessをクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/be523e1c-0563-b1bc-c1e0-68d6444ec0d7.png)
1. 入力箇所を埋める<br>ユースケースのデスクリプションは他者のサイトをコピペ<br>コンタクトは24時間以内に来るらしいが、Englishの方が早そうなので英語のままで提出。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/642dc57d-8a69-b838-7148-4450dc75df3f.png)
1. 3秒ほどで拒否の通知がきた...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/758644/9d4e32d6-ecf6-69bb-4cf8-75ef44559192.png)
1. ケースに返信する形で返答
>以下の用途で利用します。
・予約が完了したことをクライアントに通知するメールを送る。


# 参考URL
https://docs.aws.amazon.com/ja_jp/ses/latest/dg/setting-up.html
PCからラズパイへVNC接続する。

Raspbian OSの画面をラズパイにHDMIを接続してディスプレイに表示するのが手間なので、VNC Viewerを使ってPCから接続できるようにしました。

# 環境
OS: windows: 10.0
デバイス : RaspberryPiZeroW
Linux raspberrypi: 5.10.63+

# VNCの有効化
Raspbian OSを開き、設定 -> RaspberryPiの設定 -> インターフェース -> VNCを有効化を選択します。
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/a27583c7-7d47-fca8-73d1-0c024fe88598.png)

# IPアドレスの確認
ラズベリーパイに割り振られたIPアドレスを確認します。右上のVNCのアイコンを選択し、Connectibityの下に書かれているIPアドレスをメモする。これは、VNC接続するときに使用します。
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/dceb7815-8f33-faaf-44fa-3ff127c41a58.png)

# VNC接続
## VNC viewer
PCからRaspbian OSを見るため、VNC接続をします。
1. [VNC Viewer](https://www.realvnc.com/en/connect/download/viewer/) をPCにインストールします。
2. 下記の部分にラズベリーパイの IP アドレスを入力し、Enterを押します。
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176158/b9f3ec5f-f27b-cc60-473d-e3cb35ecc39b.png)
3. ラズベリーパイにログインするユーザー名・パスワードを入力し、OKを押すと接続できます。

## macターミナル上からの接続
1.ターミナル上で下記のようにコマンドを入力する。
```
ssh ユーザー名@IPアドレス
```
例えば、ユーザーが、`pi`、Iアドレスがが、`192.168.166.139`だと、`ssh pi@192.168.166.139`になる。

# その他
VNC接続で画面が小さくみづらいときがあります。その場合、Raspbian OSを開き、設定 -> RaspberryPiの設定 -> ディスプレイ -> 解像度を設定 -> 適当に設定(DMT mode 35 1280x1024 60HzくらいでOK) -> OK　を押し、リブートすると画面のサイズ変更が反映されます。
ACM会員がO'Reilly Online Learningにログインする方法

ACM会員になったので、オライリーのサブスクを使い倒すぞと意気込んでいます。
しかし、いざログインしようとしたときに手こずったため、ログインの方法をまとめます。

### 1. ログイン画面にアクセスする
Web: https://www.oreilly.com/member/login/
iOS: https://apps.apple.com/jp/app/oreilly/id881697395
WebもiOS(おそらくAndroidも)も同じフローで登録可能です。

### 2. ACMのメールアドレスをフォームに入力する
ACM会員になったときに生成されたユーザーネームを使い、メールアドレスを入力します。
ユーザーネームが`foobar`の場合、メールアドレスは`foobar@acm.org`となります。

### 3. ACMのアカウントでサインインするか問われるので`Singin with SSO`をクリックする
![スクリーンショット 2022-03-09 23.28.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331354/c9b16c1f-5687-c206-0b94-f60e3eb9bada.png)

### 4. ACMのログイン画面が開くのでユーザー名とパスワードを入力しログインする
認証成功後にオライリーのサイトにリダイレクトされ、サービスを利用可能できるようになります。

![スクリーンショット 2022-03-09 23.28.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331354/343e3b3b-1a06-e05a-9642-7b2448a28cd6.png)

### 参考
公式のFAQに書いてありました。
以下、翻訳です。

> 1.iOSアプリはApple App Storeから、AndroidアプリはGoogle Playからダウンロードしてください。
> 2.アプリを起動する。
> 3.ようこそ画面では、ACMウェブアカウントのユーザー名または電子メールを入力するよう求められます。ACM.orgのEメールアドレスを入力してください。Sign Inボタンをクリックします。
> 4.Eメールを入力すると、'Authenticate'ボタンが表示されます。それをクリックすると、ブラウザのページが開きます。この画面で、ACM Web Accountのユーザー名とパスワードを入力してください。
> 5.認証されると、O'Reillyアプリにリダイレクトされます。
https://learning.acm.org/faq/oreilly-faqs#what
全社のWindowsUpdateがいきなりエラーになってハマった件

# はじめに
このエラー情報はテック系記事でも引っかからなかったのでQiitaに綴ります。
毎月MSより配信されるWindowsUpdateをWSUS経由で社内PC（1,000台以上）に配信しているのですが、ある時を境にユーザーから「WindowsUpdateが失敗する」と一斉に問い合わせがきました。
以下キャプチャ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320647/e8220dcf-d52e-38c9-4f6d-2f1a00ac5b84.png)


# エラーが起きる環境・前提条件
以下条件の環境であればこのエラーが起こる可能性があります。
- ActiveDirectory環境の社内LAN
- WSUSでWindowsUpdateを制御
- WSUSとはSSL接続するよう設定 <- **ここ重要** :warning:

# 原因・対応
エラー文言上ではNTPサーバー関連の問題のように匂わせているのですが、真の原因はWSUSのSSL対応で使用している**サーバー証明書の期限切れ**です。
なので以下2点対応で解消されました。
　- 新たに期限有効のサーバー証明書の発行
　-  IISでポート（443or8531）に再バインドしてIISを再起動

# このエラーのトラップ

>「お使いのデバイスの日付と時刻の情報に問題があるため、更新プログラムをインストールできませんでした。日付、時刻、およびタイムゾーンの設定が正しいことを確認してください。..」

このエラー文言を素直に受け止めADのNTPサーバーの設定や、クライアントのNTP同期状態など数時間かけて調べたのですが特に問題が見当たらず、初動は原因追及にお手上げ状態でした。。
以下切り分けでWSUS側に問題があるとこまで突き詰めてサーバー証明書の期限切れに辿り着きました。
- WORKGROUPであればWindowsUpdate正常 
　-> **MSのNTPサーバーは問題ない**
- ドメイン環境下でMSのNTPサーバーに変更
   -> エラー症状変わらず。**ということは元々のNTPサーバーも関係もなく、ドメイン環境（WSUS経由）に問題あり**

ちょうど社内にWindows大型アップデートをアナウンスをしていたため、多くの方がWindowsUpdateのエラーに直面し、一斉に問い合わせがきてパニック:dizzy_face:になりましたが、エラー発生した当日に原因特定・解消することができました。

WSUSにSSL設定されている場合はサーバー証明書の更新をお気をつけください。。
Rust 言語仕様07 トレイト（trait）

今回はトレイトについてアウトプットしていこうと思います。
トレイトとは、共通の振る舞いを抽象的な形で定義することであり、トレイト境界を使用すると、あるジェネリックが特定の振る舞いをもつあらゆる型になり得ることを指定できます。
利用シーンは、複数の型のタイプに合わせて共通で持たせたい機能を実装したい時に使用します。

### まずはコード

```rust
trait Fruits {
    // & 参照の形で受け取る
    fn price(&self) -> u32;
}
struct Apple;
impl Fruits for Apple {
    // & 参照の形で受け取る
    fn price(&self) -> u32 {
        10
    }
}
let apple = Apple {};
get_price(apple); // price is: 10

// トレイト境界 <T: Fruits>
// ジェネリクス
fn get_price<T: Fruits>(fruits: T) {
    // fruitsの中にprice関数があることが保証されているので実行できる
    println!("price is: {}", fruits.price())
}
```

さらに

```rust
trait Message {
    // & 参照の形で受け取る
    fn message(&self) -> String {
        String::from("Message")
    }
}

struct NewsArticle {
    headline: String,
    location: String,
    author: String,
    content: String,
}

impl Summay for NewsArticle {}
impl Message for NewsArticle {}

// 構造体が2つのトレイトによってimplされていると以下のようにできる
// 2つの関数を呼び出せる
fn notify_another(item: &(impl Summay + Message)) {
    println!("Breaking news! {}", item.summarize());
    println!("Message! {}", item.message());
}
```

まだトレイトは馴染みがあったので理解はスムーズでした。
OpenSSH for Windowsのssh-agentをPutty Pageant利用アプリから使用する 

## はじめに 

Visual Studio Code(VSCode)の環境と`Putty Pageant`利用アプリとの共存を行うための設定についてのメモです。

Visual Studio Code(VSCode)などを利用して, OpenSSH for Windowsと付属のssh-agentを利用したリモートファイル編集などを行うように設定している環境下で, WinSCPなどの`Putty Pageant`利用アプリでもssh-agentを用いたファイル転送を行うための設定方法を説明しています。

* `.ssh`ディレクトリをC:ドライブに置かない(少しでも使用容量を減らしたい)
* 普通の作業マシン(Windows10 HomeやWindows10 Pro)を使用している
* 他の作業者とのやりとりの関係で, WinSCPなどを使用したファイル転送を残さざるを得ない

という状況下での作業メモです。

OpenSSHのインストールやssh-agentの設定は済んでいる前提です。

## Pageant利用アプリケーションのための設定

WinSCPなどのPutty Pageant利用アプリケーションとOpenSSHのssh-agentとの間で通信を中継するためのプログラムである`winssh-pageant`を導入し, 自動起動するように設定します。

1. Windows版Go言語をインストールします。
   公開されているバイナリからインストールする場合は、本工程は不要です。
2.  [winssh-pageant](https://github.com/ndbeals/winssh-pageant)からソースを取得し, アーカイブを展開してできる`build.ps1`を実行します。
公開されているバイナリからインストールする場合は、本工程は不要です。

3. `build`ディレクトリ配下に`winssh-pageant-amd64.exe`ファイルができるので, プログラムファイルディレクトリにコピーします。
公開されているバイナリからインストールする場合は、アーカイブ中の`winssh-pageant.exe`ファイルをプログラムファイルディレクトリにコピーします。
4. `winssh-pageant-amd64.exe`のショートカットを作成します。
公開されているバイナリからインストールする場合は、アーカイブ中の`winssh-pageant.exe`ファイルのショートカットを作成します。
5. 作成したショートカットをスタートアップディレクトリに追加します。
   なお、`WindowsKey`-`R`でファイル名を指定して実行を開き, `shell:startup`を入力して, `OK`を押すことでスタートアップディレクトリを開けます。

## 参考リンク

* OpenSSH for Windowsのインストール
[Windows 10 で SSH Agent を使用する](https://scientre.hateblo.jp/entry/2021/06/17/windows-ssh-add)
* .ssh/配下のファイルの権限変更方法
[OpenSSH for Windows の使用方法](https://qiita.com/akiakishitai/items/9e661a126b9c6ae24a56)
* [Winssh-pageant](https://github.com/ndbeals/winssh-pageant) PageantサポートアプリケーションとOpenSSH Authentication Agentの仲介を行うツール
* [WinSCPでの`OpenSSH Authentication Agent`利用に関する議論](https://winscp.net/forum/viewtopic.php?t=26033)
* [Windows用Go言語のダウンロード先](https://go.dev/dl/)
remoteにpushしているのにrebaseしちゃった時〜

気づいたら```git rebase```してしまっている時ありますよね。~~ない~~

ある時いつものように無意識に```git rebase```を打って作業、よしリモートに上げようと思ったらこんなエラーが出ました。
```bash
! [rejected]        branch-a -> branch-a (non-fast-forward)
error: failed to push some refs to 'https://github.com/hoge/git.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

そう。リモートブランチにプッシュしているのにrebaseしてしまっているのです。。。

もちろん一人で開発しているブランチなら```git push --force```で強制的に上げてしまっても良いのですが、実はこれはあまりオススメされていません。rebaseは過去のコミット履歴を改変しているので共同開発をしているかつ同じブランチでコミットを上げていた場合にそのコミットが吹き飛ぶかもしれません。

仮に個人開発をしていても変な癖はつけたくない、そこでremoteにpushしているのにrebaseしちゃった時の対処法を2つ紹介します

# 1. --force-with-lease
一つ目の案は```git push --force-with-lease```です。
これは安全確認をした後に```push --force```をするといったニュアンスのもので他の誰もがリモートにプッシュしていないことを確認してpushすることができます。
ただ一つ注意点があり、```git fetch```などで追跡ブランチを更新してしまうとリモートとの差分を検出できず```--force-with-lease```でrejectされないということが起きます。
詳細🔽

https://blog.developer.atlassian.com/force-with-lease/

# 2. rebaseを取り消し
もしrebaseをしてすぐ過ちに気づいたならばrebaseを取り消すことが良いかもしれません。
rebaseを取り消す方法は```git reflog```を使えば良いです。
```git reflog```では```git log```よりさらに細かいlog。操作を全て参照することができます。
ここでresetしてしまえばok
``` git reset --hard HEAD@{n}```
改めてTypescriptに入門してみた。

# はじめに
プロジェクトでNuxt.jsとTypescriptを使用したフロントエンド開発を経験してきて今までなんとなく書いていたので基礎をしっかり身に着けることで同じような技術スタックの案件の時に即戦力になりたいと思い、改めて学び直してみた。

# Typescript で Hello World するまで


### Typescript をグローバルにインストール


terminalで下記コマンドを入力する。ちなみに今回は node はすでにインストールされている前提。

```
$ npm install -g typescript
```

### 任意の場所でディレクトリを作成して新規tsファイルを作成する。ここではindex.tsを作成。

index.tsに下記を記述。

```index.ts
let hello:string = 'hello'
console.log(hello)
```

### 作成したindex.tsをjsにコンパイル

お使いのterminalで下記コマンドを実行(`tsc` はTypescriptをインストールしたことで使用可能なコマンド)

```
$ tsc index.ts
```

同じファイルにindex.jsが自動作成される。
![tsコンパイル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496032/5073109e-49a6-ec13-df3b-cfba3a497a74.png)

jsファイルを確認するとTypescriptがJsに変換されている。

```index.js
var hello = 'hello';
console.log(hello);
```

### JSファイルを実行

terminalで下記コマンド実行

```
$ node index.js
```

helloが出力される

```
hello
```
PCの運用保守をする1年目はとりあえずLinuC level1を目指す

僕と似た境遇の人がいればLinuC取得を目標に勉強したら良いという話。:ok_hand:

#### 僕の職場でやってた仕事
* Windowsを標準PCとして利用しているユーザーのサポート
* PCのキッティング
* PCの廃棄（データ消去も含む）
* ファイルサーバーのアクセス権付与・容量変更
などなど

#### 僕が資格を取ろうと思った理由
* LinuC level2まで取得すれば会社から資格手当がもらえる
* 開発系の仕事にも興味あったので、環境構築のためにLinuxの勉強もしておきたい
* サーバー運用保守の仕事も任されて、サーバーを触る機会が増えた

こうして見ると、「自分はサーバー触る仕事なんてやらないし、ましてやLinuxなんて・・・」って思われるかもしれません。
でも、**運用・保守の仕事しかない人でもLinuCのlevel1ぐらいは取っておくと役に立つ**と思ってます。

#### 実務と結びついてる部分
LinuCの出題範囲（2022/3/9現在)と紐づけて書いていきます。

##### PCのキッティング

僕の職場でのキッティング作業を一部抜粋：
1. 固定IPアドレス・サブネットマスク・デフォルトデートウェイを設定
2. DNSサーバーのプライマリ・セカンダリのサーバーアドレスを設定
2. .batファイルを実行し、セキュリティアドインなどをインストール

主題1.07：ネットワークの基礎
ここを勉強しておけば、
* サブネットに分ける意味って何なの？
* なんかデフォルトゲートウェイとアドレスの値がほぼ一緒な気はするけど・・・？
* 間違って設定してしまうとどうなるの？
* DNSって何？　何のために設定するの？
って疑問は解消されると思います。

主題1.06：シェルおよびスクリプト
ここを勉強しておけば、
* 「バッチファイル実行してね」って言われるけど、バッチファイルって何？
* 毎回同じ作業ばっかりで面倒・・・　もしかして自分でバッチ処理して自動化できるのでは？
って疑問が解消されるかと。
もちろん、Windowsの.batファイルを作成するにはもう少し別で勉強する必要ありですが。

##### PCの廃棄（データ消去も含む）
僕の職場でのPC廃棄作業を一部抜粋：
1. BIOSを起動
2. ブートの軌道順序を変更してSSDよりDVD優先にする
2. データ消去用のDVDソフトを使ってデータ消去
ということをやっています。

1.01.3 ブートプロセスとsystemd
ここを勉強しておけば、
* 「そもそもBIOSって何？」
* 「F○キー連打して出てくるこの画面って何？」
* 「WindowsのOSが立ち上がる前の段階？　どういうこと？」
って疑問は解消されると思います。

##### ファイルサーバーのアクセス権付与・容量変更
僕の職場でのファイルサーバー作業を一部抜粋：
1. ユーザーから受け取った申請書に基づき、クォータの容量を変更
1. 新規フォルダを作成するときは、クォータも新たに作成する
1. 新しいクォータを追加した場合は反映のために論理ボリュームを非アクティブにしてから再度アクティブにする

1.05.2 ハードディスクのレイアウトとパーティション
ここを勉強しておけば、
* ファイルサーバーを「マウントする」ってどういうこと？
* ボリュームって表現するけど、フォルダやドライブとどう違うの？
* って疑問は解消されると思います。

ここまで読んでくださりありがとうございます。

特にプロジェクトのリーダーの人などは、業務に必要なスキルを資格勉強の過程で身につけておいてもらえたら、現場で育成にかける時間を短縮できるので、取得を促してみても良いのではないでしょうか。

こうして資格取得を促す発言をすると、「資格を取っただけで活かせないなら取る意味ない」と言われる方も多いですよね？
確かに、実務に活かせない資格勉強に時間を使うぐらいなら、業務を覚えることに注力させた方が仕事の生産性は上がることでしょう。
しかし、業務に必要なことだけを覚えさせると、**その職場でしか通用しないエンジニア**にしてしまいがちです。

業務で使わない範囲も含めて体系的に技術を理解し、その技術を使って業務をやっているのだと分かってもらえたら、色んな職場で通用するエンジニアに育成しやすいのではないかと思いますね。

以上
ユーザー対応とかPCの障害対応などに関する範囲は別の記事で書こうと思います。:raised_hand:
Material UI の styled() ユーティリティは CSS を直接書く実装もできる

`@mui/styles` が MUI v5 で legacy になったという事で、`@mui/system` について少し調べた時の memo.

https://mui.com/styles/basics/

`createTheme`, `ThemeProvider` を利用している想定の場合、公式のサンプルコードの通りこんな形となる。
​
```JavaScript
import * as React from 'react';
import { styled, createTheme, ThemeProvider } from '@mui/system';
​
const Logo = styled('img')(({ theme }) => ({
 height: '32px',
}));
```

backtick（`` ` ``） を利用すると、CSS がそのまま記述できる。

```JavaScript
const Logo = styled('img')(
 ({ theme }) => `
 height: 32px;
`,
);
```

どちらかで揃えたいですね。


## 参考

https://mui.com/system/styled/

https://zenn.dev/syu/articles/0f92abf7f0b5c5

https://zenn.dev/h_yoshikawa0724/articles/2021-09-26-material-ui-v5
SQLで移動平均を計算する 

# 背景

株式分析を始めてみようと、データベース（RDB）に株価を格納した後、分析の第一歩として、とりあえず移動平均を算出してみようと思って調べてみました。 

# 実現方法

標準SQLの中に窓関数（ウィンドウ関数）と呼ばれる関数があります。その関数を使うことで、部分的に切り出した行に対して、集約関数の結果を得ることができます。 

GROUP BYと似ていますが、窓関数はレコードを集約せずに各レコードごとに結果を出力します。 

例えば、5日移動平均価格であれば、過去4日分の株価と当日の株価の平均になります。つまり、各行に対して、avg(過去4日の株価と当日の株価)という、値を求める事になります。通常このような書き方はできませんが、ウィンドウ関数を使うことで、過去4日の株価と当日の株価を部分的に切り出した形で集計することが可能になります。 

# 要件定義
株価が格納されたDBにMovingAverage（移動平均）という各移動平均価格を持つViewを作成します。 
移動平均に使用する価格は終値にします。 

# 実行環境とテーブル設計

下記環境で実行 
- OS: Windows10 
- DB: SQLite ver.3.36.0 
- クライアントソフト: DB Browser for SQLite 

テーブル設計
~~~
CREATE TABLE "prices" ( -- 4本値と売買高
  "code" TEXT,　 -- 証券コード 
  "date" TEXT,   -- 日付/SQLiteは日付型がないため文字列
  "open" REAL,   -- 始値 
  "high" REAL,   -- 高値 
  "low" REAL,    -- 安値 
  "close" REAL,  -- 終値 
  "volume" INT,  -- 売買高 
  PRIMARY KEY("code","date") 
) 
~~~

# 具体的なSQL文とその説明

まずは、具体的に5日移動平均価格（d5_moving_average）を出力します。

~~~
select date, code, close,    
  avg(close) over (PARTITION by code order by date rows between 4 preceding and current row)as d5_moving_average  
from prices   
order by code asc, date asc; 
~~~

移動平均価格を窓関数で計算している箇所は下記になります。 
~~~
avg(close) over (PARTITION by code order by date rows between 4 preceding and current row) 
~~~

一つずつ、意味を確認していきます。 
~~~
avg(close) over   -- OVER以下で記述した範囲で終値の平均を返す 
PARTITION by code -- 証券コード(code)でグループ分け
（テーブル内には、複数の銘柄の価格が入っているため、銘柄ごとに計算する） 
order by date     -- 日付で昇順ソートする（過去に遡る） 
rows between      -- 集計する行の範囲は次の間[between] 
4 preceding and current row -- 4行前[PRECEDING]から現在[current]の行まで 
~~~

日本語で整理すると 

:::note 
コードごとに区切り、日付でソートした表の各行に対して、4行前から現在の行までの範囲で終値の平均を取る 
:::  

という意味になります。 

なので、4を 
* 24にすれば、25日移動平均線 
* 74にすれば、75日移動平均線
* 199にすれば、200日移動平均線
とそれぞれ計算ができます。 

また、over以下の長い部分をまとめて、Window句以下で定義する表記もあります。 

~~~
select date, code, close,    
avg(close) over w_5 as d5_moving_average -- w_5はWindow以下で定義されている 
from prices  
WINDOW  
w_5 as (PARTITION by code order by date rows between 4 preceding and current row)
order by code asc, date asc; 
~~~
よく見る他の指標も追加して、私は下記のビューを作成しました。 

~~~
CREATE VIEW MovingAverage as select  
date, code, close, volume,  
avg(close) over w_5 as d5_moving_average, 
avg(close) over w_25 as d25_moving_average, 
avg(close) over w_75 as d75_moving_average 
avg(close) over w_200 as d200_moving_average, 
from prices  
WINDOW  
w_5 as (PARTITION by code order by date rows between 4 preceding and current row), 
w_25 as (PARTITION by code order by date rows between 24 preceding and current row), 
w_75 as (PARTITION by code order by date rows between 74 preceding and current row), 
w_200 as (PARTITION by code order by date rows between 199 preceding and current row) 
order by code asc, date asc; 
~~~

特定のコードや日付で絞る場合は、Where句を入れてもらえれば、その範囲や銘柄で表示されます。 

# まとめ
窓関数を使って、株価データから移動平均線の価格をSQL文で記述しました。
他にも窓関数を使えば、平均(avg)ではなく、最大値(max)などにすれば、直近10日の高値を計算するなども可能です。
ブレイクアウトや逆張りなど取引戦略に応じて、色々な指標がSQL文で計算可能になりました。

# 補足
SQLite標準だと、sqrt（平方根）がなく、ボリンジャーバンドは計算できませんでした。「SQLite 拡張ライブラリ」等でググってもらうと、SQLiteに集計関数を追加する方法がでてきましたので、ご参考まで。
GoでHTML (+ CSS, JavaScript) を表示する

# 問題
Go言語でサーバーを立ち上げてHTMLを表示させる際、cssとjsファイルをHTMLに適用させるのに少し時間がかかりました。
備忘録としてHTML + CSS + JavaScriptのページを表示する方法を記載していきます。

# 解決方法
結論から言うと、go:embedを使用しました。
下記のテックブログを参考にして、静的ファイルを変数に格納 -> ファイルシステムを取得して読み込むという方法で課題を解決しました。

https://future-architect.github.io/articles/20210208/ 

下記にコードを記載しますが、全てを記載すると記述が多くなるため省略してあります。
全コードが気になる方はgitを確認してください。
https://github.com/Makoto87/test_go_embed

goのバージョン
```
go version go1.17.3 darwin/amd64
```

ディレクトリ構成
```
.
├── go.mod
├── main.go
└── views
    ├── main.html
    ├── scripts
    │   └── textarea.js
    └── styles
        └── stylesheet.css
```

goファイル
```main.go
package main

import (
	"embed"

	"html/template"
	"net/http"
)

// viewsディレクトリ下のファイルを全て変数に格納する
//go:embed views/*
var views embed.FS

// メイン画面の表示
var templates = template.Must(template.ParseFS(views, "views/main.html"))

func viewHandler(w http.ResponseWriter, r *http.Request) {
	if err := templates.ExecuteTemplate(w, "main.html", nil); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func main() {
	http.HandleFunc("/view/", viewHandler)

	// viewsに格納したファイルを全て公開
	http.Handle("/views/", http.FileServer(http.FS(views)))

	// httpサーバーを立ち上げ
	http.ListenAndServe(":8080", nil)
}
```
htmlファイル
```main.html
<!DOCTYPE html>
<html lang="en">
<head>
      <!-- 前略 -->
      <!-- go:embedで読み込んだviewsディレクトリ下のcssを読込 -->
      <link rel="stylesheet" href="/views/styles/stylesheet.css">
</head>
<body>
      <!-- 前略 -->
      <!-- go:embedで読み込んだviewsディレクトリ下のjsファイルを読込 -->
      <script src="/views/scripts/textarea.js"></script>
</body>
</html>
```

# 書いたコードで表示された画面
ちゃんとCSSが適用されています
CSSではtextareaの高さを指定しました
![image1](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515839/f7bddfa8-3cd3-c4bf-55e6-6913e02a69ca.png)

JavaScriptも適用されています
入力した文字に合わせてtextareaが変化するようになっています
![image2](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515839/0be6d5e1-ead7-5300-6b0d-5202ebc85a96.png)


# 解説
`embed` をインポートし、変数の上に `//go:embed views/*` という記述をすれば、viewsディレクトリ下のファイルを変数に読み込んでくれます。

embedパッケージについて公式ドキュメントではこう記載されています。
> Package embed provides access to files embedded in the running Go program.
> 
> Go source files that import "embed" can use the //go:embed directive to initialize a variable of type string, []byte, or FS with the contents of files read from the package directory or subdirectories at compile time.

https://pkg.go.dev/embed

簡単に訳すと、
embedを使用することで、コンパイル時にパッケージディレクトリまたはサブディレクトリから読み取られたファイルの内容で変数を初期化できる。
という感じの内容になっています。

ファイルを変数に格納した後は、ファイルを読み込めるようにする処理を記述します。それが下記のコードになります
```go
http.Handle("/views/", http.FileServer(http.FS(views)))
```
このコードによって、
http.FSで`views`をhttp.FileSystemに変換し、
http.FileServerでファイルシステム(views)の内容をHTTPリクエストに返すhandlerを返し、
http.Handleで、httpサーバーが立ち上がった後に、`/views/`というパスを指定されたらファイルシステムが返されるようになります。
ただしhttp.Handleを使うときは、http.ListenAndServeの第二引数をnilにしておく必要があります。

パスを指定してファイルシステムが返されるようになれば、htmlファイル上でそのパスを活用して、cssファイルとjsファイルを読み込んだHTMLを表示できます。
cssを読み込む場合は下記の記述になります。
```html
<link rel="stylesheet" href="/views/styles/stylesheet.css">
```

embedで読み込んだファイルはバイナリにも埋め込まれるというメリットがあります。
これによって、ビルド時のディレクトリ構成とは異なる構成になったとしても、影響を受けずに正常に静的ファイルを返すことができます。
ドットインストールでHTML基礎文法をやってみた

# 一周してみて、気になった点をメモ書きしたのでアウトプットと復習を兼ねて

動画1〜順にメモしてるので良かったら理解度プラスにして頂きたい


- `Ctrl + /` = HTMLのコメントショートカットキー 
- `rel` = relation (関係 )
- `href` = hypertext referece ( 参照 )
- `Charset` ( キャラセット ) 文字コードの事
- `<meta>` = Webサイトに表示されないがSEO/ブラウザ用
- `<hr>` = horizontal rule ( 水平方向の罫線 )
- `<backquote>` ( 引用 )
- 文字実体参照　; 忘れない
    - `" &lt; "` = less than (小なり)　`" &gt; "` = grater than ( 大なり )


- `<pre>` = preformatted
　すでに整形されたテキストをそのまま表示する
- `<cord>` = ソースコードをそのまま表示する
※正直理解半分ぐらい
エディタに書いた際に上記コードがないと段落が付かないとかそういう表示になる(おおざっぱ）

- `<ul>` = un ordered list ( 順序無し )
- `<list>` = listと思いきや list item
- `<ol>` = ordered list ( 順序有り )

## リスト
- `<dl>` = description list ( 説明 )
- `<dt>` = ~ term ( 用語 )
- `<dd>` = ~ detail ( 詳細 )
※間違えそう
大体項目=>回答の順の記述だろうからdt=>ddの順という覚え方で良さそうではある


## 表の作成
■大枠に`<table>`
1. 見出し　`<thead> + { <th> & <tr> * n ( 行の数分 ) }`
2. 本体　　`<tbody> + { <td> & <tr> * n ( 行の数分 ) } * n ( 列の数分 )`
- `<th>` = table header cell
- `<td>` = table data dell


- `<a>` = anchor ( リンク可能な目印 )
- 新しいタブでリンクを開かせる場合はリンクの記述の後ろに`target="_blank"`

<pre>リターン = エンターキーの事
※macだとリターンキーと呼ぶことがある(らしい)
教材ならエンターキーと呼ぶので問題なくない？macユーザーはリターンって言ってるのかしら・・・
</pre>


- ` # ` = パウンド記号
あんま良く分からぬ・・・
アメリカのポンドから来てるらしいHTMLと何か関連するようなのは見つけられなかったから「ふーん」程度で終了


- `id` = 1 : 1 のリンクを結びつける
- `class` = 1 : 多


- 先頭へ戻る = ` # ` もしくは ` #top `


- header,footerなどのタグ
    - HTML5から登場　(timeタグも)
    - SEO対策とコード自体の意味が伝わりやすくなる。(伝えなくても伝わると言った意味合いも大きい)


- `<article>`は外部に配信するような独立したコンテンツの場合にしようすると良い


- `<div>` `<span>`　とりあえずはスタイリング用のタグなんだなーという程度の理解


- HTML / CSS の仕様はMDNサイトで確認
    - 一番信頼性がある
    - 公式ドキュメントという位置付けだろうか
ユーザー情報の編集機能

ユーザーの編集機能を実装する。

編集の時に登録したパスワードは変更しないようにしたいので、今回の編集項目にはパスワードは入れない。

パスワードを不要にするための手順は以下の通り。

ますは``controller/users/registrations_controller.rb``を編集する。

```ruby:controller/users/registrations_controller.rb
 #　以下を追記する
  protected
   def update_resource(resource, params)
    resource.update_without_password(params)
  end
```
※registrations_controller.rbを生成するためには、ターミナルで``rails g devise:controllers users``を実行する必要がある

続いて``routes.rb``を編集。

```ruby:routes.rb
Rails.application.routes.draw do

#以下を追記する
  devise_for :users, controllers:{
    registrations: 'users/registrations',
  }
```

次にバリデーションに追記する。

```ruby:models/user.rb
 VALID_PASSWORD_REGEX = /\A(?=.*?[a-z])(?=.*?\d)[a-z\d]+\z/i
  validates :password, length: { minimum: 6 }, format: { with: VALID_PASSWORD_REGEX }, on: :create
  #passwordのバリデーションの最後に on: :create を追記する
```

最後に``controllers/users_controller.rb``を編集。

```ruby:controllers/users_controller.rb
  def edit
  end

  def update
    if current_user.update(user_params)
      redirect_to user_path
    else
      render :edit
    end
  end

  private
  def user_params
    params.require(:user).permit(:department_name, :image)
  end
```

これで完成！
のはずが、挙動を確認すると、編集後に詳細ページへ遷移させたはずが、ルートパスへ飛んでいる。
DBを確認するとデータの更新もされていない。

そもそもなぜルートパスへ遷移するかがわからない。更新に失敗したら、再び編集ページへ戻るように条件分岐しているはずなのに・・・

ビューファイルを見返してみると、1点気になる記述が。

```erb:views/users/edit.html.erb
<%= form_with model: current_user, url: user_registration_path, class: 'registration-main', local: true do |f| %>
```

urlが新規登録ページに設定されている。
もしかしてこれが原因では？
urlをまるまる削除し、以下に修正してみる。

```erb:views/users/edit.html.erb
<%= form_with model: current_user, class: 'registration-main', local: true do |f| %>
```

挙動確認すると、DBも更新され、詳細ページに遷移することもできた。
SQLiteの書き込みを高速にする（EntityFrameworkCoreのMicrosoft.Data.Sqlite版）

# はじめに

EntityFramework**Core**でSQLiteを使ってみようと思ったが、書き込み速度が遅かった。（実際は十分速いんだけど、大量のデータを保存する必要があって、さすがに時間がかかった…）
なんとか改善できないかいろいろ調べてみたところ、SQLiteの設定でやれることがあるっぽかった。

過去、**System.Data.SQLite**の時代…
接続文字列でSyncModeとJournalModeを指定することで、書き込み速度を改善することができる。

https://devlights.hatenablog.com/entry/2014/02/01/151642

しかし、EntityFrameworkCoreの**Microsoft.Data.Sqlite**の時代で、この接続文字列の方法は使えない。

https://docs.microsoft.com/ja-jp/dotnet/standard/data/sqlite/compare

いろいろな経緯により、接続文字列で指定できるものが大幅に削除されてしまったようだ。

# 解決方法

もともとの接続文字列のやつは、接続時にプラグマを送信してくれている。それを手動でやればよい。
こうだ！！！！↓↓↓↓

```cs
await using var context = await _contextFactory.CreateDbContextAsync();
await using (var connection = context.Database.GetDbConnection())
{
    await connection.OpenAsync();
    await using var command = connection.CreateCommand();
    command.CommandText = "PRAGMA synchronous=OFF;PRAGMA journal_mode=WAL;";
    await command.ExecuteNonQueryAsync();
}

context.Database.AutoTransactionsEnabled = false;

// Addしまくる処理
```

Context作った後に、データベースのConnectionを取得する。
そこにプラグマを送り付ければOK

同期モードの設定のプラグマの名前は、`sync_mode`とかじゃなくて`synchronous`。
`context.Database.AutoTransactionsEnabled`も`false`にしておけば完璧では。

ところで、設定を変えるということは、もちろんメリット以外にデメリットもある。よく確認して使ってください。
プラグマの詳細はここに。

https://www.sqlite.org/pragma.html
連番画像を動画にするためのプログラム

# 連番画像を動画にするためのプログラム

自分のPCではシーケンサーからの出力をaviとして得るとなんかきもかったので，連番画像として出力したのち，いい感じのものだったら動画に変換した．
実行例は，

```
$ python3 conv.py d1 1800
```

自分の場合シーンごとにシーケンサと名前を変えていたのでこんな感じに
入力としてほしい画像の名前は，imgファイルにある`ren_d1.0001.jpg`....`ren_d1.1799.jpg`のような感じ
出力される動画は`movies_aft`フォルダ内に`ren_d1.mp4`のように保存される
お好みで変えてもらえればいいと思います

```
├ conv.py
├ img/
│  ├ ren_d1.0001.jpg
│  │     ・
│  │     ・
│  │     ・
│  └ ren_d1.1799.jpg
└ movies_aft/
   └ ren_d1.mp4 →これが作られる
```

```conv.py
import cv2
import numpy as np
import time
import sys

def main():

    args = sys.argv
    try:
        stage=args[1]
        mcount = int(args[2])
        print(args[0],type(stage),stage,type(mcount),mcount)

    except IndexError as e:
        print(e)

    origpath = "img/"
    imname = f"ren_{stage}.NUM.jpg"

    startTime = time.time()
    for i in [0]:
        num = str(i).zfill(4)
        print(num+"  ",end="")
        print(type(num))
    fIm= cv2.imread(origpath+imname.replace("NUM",num))
    if not fIm is None:
        print("pic is arive")
    else:
        print("yes")
        return
    # cv2.imwrite("uni.png",fIm)
    img_last = None

    frame_rate = 30.0 # フレームレート
    # 幅と高さを取得
    imShape = fIm.shape
    size = (imShape[1],imShape[0])
    print(size)

    codec = cv2.VideoWriter_fourcc(*'mp4v') # ファイル形式(ここではmp4)
    print(f'movies_aft/ren_{stage}.mp4')#
    writer = cv2.VideoWriter(f'movies_aft/ren_{stage}.mp4', codec, frame_rate, size) # ライター作成

    for i in range(30,mcount,2):
        deltime = time.time() - startTime
        if i!=0:
            print(f'\r{str(i).rjust(4)}/{mcount}  予想時間残り:{str(int((mcount-i)*deltime/i)).rjust(4)}s',end='')

        num = str(i).zfill(4)

        fIm= cv2.imread(origpath+imname.replace("NUM",num))
        writer.write(fIm)
    # endfor

    writer.release()
    print("\ncomplete!!!")
    return
#end main

if __name__=='__main__':
    main()
# endif
```

# 参考

いろいろと参考にしましたが忘れました
すみません
特に，コマンドラインでの処理経過を残す部分ができて個人的には満足しています
わからないだれかありがとうございました
【BootStrap】他のCSS style.cssが適用されなくなる。

はい。
### 問題
Laravelでページネーションを行い、Bootstrapを繋いだときに
問題は起きました。

ページネーションのCSSはいい感じですが、
今まであったCSSが適用されなくなってしまいました、、

![スクリーンショット 2022-03-09 22.05.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525372/b4b717c8-7a1e-9ee1-d874-40221685909e.png)

### 解決方法
CSSを適用させるときはLinkで行なっていますよね。
![スクリーンショット 2022-03-09 22.07.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525372/d0e38837-910e-dda4-2d86-a39dff8880b0.png)

これって実は、順番で適用優先度があるぽいんですよね。
なんでかというと、順番を変更したらCSS問題が解消したからです。
ページネーションCSSもOK,元のCSSも適用された。

つまり、後から追加した```link```が優先順位高いぽいですね。。
![スクリーンショット 2022-03-09 22.08.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525372/b5f413bd-a14c-fe9e-fa3e-b80f8feec52c.png)

うん、いい感じ！
【Rspec】Error: raise WrongScopeError の解消法

RSPecでテストを実行すると以下のエラーが発生。

```
Failure/Error:
       raise WrongScopeError,
             "`#{name}` is not available from within an example (e.g. an " \
             "`it` block) or from constructs that run in the scope of an " \
             "example (e.g. `before`, `let`, etc). It is only available " \
             "on an example group (e.g. a `describe` or `context` block)."
     
       `name` is not available from within an example (e.g. an `it` block) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). It is only available on an example group (e.g. a `describe` or `context` block).
     
                 raise WrongScopeError,
                 ^^^^^
```



バージョンを 5.1.1にしたら解消されました！

バージョンが古かったのが原因だと思われます。

```
gem 'rspec-rails','~> 5.1.1'
```
AWS CLIのバージョンアップ試してみた

# はじめに
以前からなんとなく気になっていたので、AWS CLIを`v1` → `v2`へバージョンアップしてみた！

AWS CloudFormationで、EC2とEIPをセットしたAWS CLIのバージョンアップを試すだけの贅沢なスタックを作成し、スタックの作成・削除だけで簡単にグローバルIPを紐づけたEC2の立ち上げを行う。


AWS CLIだが、ver1とver2では同じ`aws`コマンドが使用されるので共存はできるみたいなのだが、あまり推奨はされていないらしいので、今回はver1とはおさらばしてみる。


- 実行環境：Amazon Linux2

# インストール手順
アップロードしたいEC2にSSH接続し、以下の手順で行なっていく。
```shell:EC2
##################################
■ 現状確認とv1の削除
#################################
$ aws --version
=> aws-cli/1.18.147 Python/2.7.18 Linux/4.14.243-185.433.amzn2.x86_64 botocore/1.18.6ｓ

$ which aws
=> /usr/bin/aws

# ver1のCLIを削除
$ sudo rm -rf /usr/bin/aws
# ちゃんと削除されているか確認
$ sudo find /usr -name aws

$ aws --version
=> command not found: aws

##################################
■ ここからがver2のインストール
#################################
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip

$ sudo ./aws/install
=> You can now run: /usr/local/bin/aws --version

$ sudo ./aws/install --update
=> Found same AWS CLI version: /usr/local/aws-cli/v2/2.4.23. Skipping install.
```

パスが前のバージョンを参照したままの可能性があるので一度EC2からでて、再度入り直し確認
```sh:EC2
$ aws --version
=> aws-cli/2.4.23 Python/3.8.8 Linux/5.10.96-90.460.amzn2.x86_64 exe/x86_64.amzn.2 prompt/off
```
https://www.secuavail.com/kb/tech-blog/tb-211005_01/

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html

# 失敗した時
```sh:EC2
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install
$ sudo ./aws/install --update

$ aws --version
=> aws-cli/1.18.147 Python/2.7.18 Linux/4.14.243-185.433.amzn2.x86_64 botocore/1.18.6ｓ
```

同じような手順で実行しても上手くいかない時があった。
インストールまで終わり、`aws --version`で確認するとどうしても`ver1`のまま・・・

ver2はインストールされているが、前のバージョンが生き残っており、そちらを参照している模様。

なので、↓の手順でver2インストール前に事前にしっかりと削除しておくことで対処できました。
（削除しなくてもパスの変更とかで出来そうな気がし、試したのが力及ばす・・・・😢）
```sh:EC2
$ which aws
=> /usr/bin/aws
# ver1のCLIを削除
$ sudo rm -rf /usr/bin/aws
```

# AWS CLI v２になって変わったこと
個人的にいいなと思った部分は、↓のようなところ。
Command Line Interfaceと言ってるだけあり、やはりUIを意識した点にはさすがと感じました！
- リソース名の補完
- 自動プロンプト
- ウィザード


https://aws.amazon.com/jp/blogs/news/aws-cli-v2-is-now-generally-available/

https://dev.classmethod.jp/articles/aws-cli-v2-is-now-generally-available/



さっそく使ってみる

```sh
$ aws --cli-auto-prompt
#　実行したいコマンドを入力すると合わせて、補完候補が表示されていく
> aws cloudformation deploy
~~~
~~~
```
![スクリーンショット 2022-03-09 21.14.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/8a624c52-384c-b73c-386f-937ae0a8526c.png)


# おまけ
## AWS CLIは、`help`が優秀すぎる!
AWS CLIは本当にhelpが優秀だなと感じます。
オプションの書き方なんて、ほとんどうろ覚えじゃないですか、、、
そんなときに `aws ~~~ help`すれば、アマゾンプライム会員以上の速度で自分の欲しい情報が手に入ります。

```shell:例
$ aws cloudformation deploy help

# grepで絞り込んでも良い
$ aws cloudformation deploy help | grep stack
```

![スクリーンショット 2022-03-09 20.59.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669969/394149cc-fdfe-8e9c-1a28-c1f30b29f308.png)
【Laravel8】ページネーションのCSS（Bootstrαp）が反映されないとき

### エラー状況
:::note alert
Laravelでページネーション機能を導入したが
下記画像のように、上手くページ番号が表示されない。
:::

![スクリーンショット 2022-03-09 21.47.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525372/259b6878-c445-e433-ae24-91168090b89d.png)


ページネーション導入はこちらの記事を参考しました！

https://leben.mobi/blog/laravel8_pagination/php/

https://biz.addisteria.com/laravel8_pagination/


### 何が原因だったか

```CSS```が反映されていないことが原因です。
では、CSSを見てみました。

![スクリーンショット 2022-03-09 21.52.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525372/484f8fdd-9862-5315-28aa-14e4f40732f7.png)

こんな感じになってました。
これはBootstrapを紐づけようとしてる動作です。

では、実際に```パス```があるのか確認してみました。

![スクリーンショット 2022-03-09 21.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525372/bb86d2fc-ffa6-d639-1463-84cb9f9270f7.png)

これは```Bootstrap.css```がないので、___パスが存在してない___ ことになります。

### 結論
パスが通ってないので、どのCSSファイルにBootstrapが入っているか確認したら
上記画像の```app.css```に入ってました！

なので、このようなパスにしたら。。。
![スクリーンショット 2022-03-09 21.55.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525372/7c8175ca-cf07-df3b-e905-13c3856e89f7.png)


見事、綺麗なCSSが通り、ページネーションを完了することができました！

![スクリーンショット 2022-03-09 21.54.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2525372/181ba720-3dc0-2aa4-7b2a-f699080db1ac.png)