OmniAICreator/Qiita-1.07M huggingface dataset:
Grepコマンドを知ろう

Linuxには便利なフィルタコマンドなるものが存在します。
今回はそのフィルタコマンドの中でも「Grep」コマンドを紹介します。
では早速見ていきましょう！

# Grepコマンドとは
まずはGrepコマンドとはどういう役割なのかを知りましょう。
Grepコマンドは**文字列を検索するコマンド**です。
役割から大事なコマンドであることがわかると思います。
細かく言うと、**指定した文字列と一致する文字列のある行を取得する**という機能があります。
この「一致」の範囲はオプションで定めることができます。
オプションについては後で説明しますので、次はGrepの基本的な使い方を見てみましょう！

# Grepコマンドの使い方
```sh
grep <検索文字列> <検索対象ファイル名>
```
※ここではわかりやすいように「検索文字列」としていますが、正確に言うと「検索パターン」といって、正規表現等でも大丈夫です。今回は文字列に絞って説明をするので文字列と表現します。
  
これだけです！
では実際に使ってみましょう！
例えばsample.txtというファイルに以下の内容が記述されているとします。
※東京23区をランダムに20個入れています。ない区もあれば重複している区もあります。
```tex
東京都足立区
東京都中央区
東京都新宿区
東京都北区
東京都荒川区
東京都江戸川区
東京都中野区
東京都杉並区
東京都練馬区
東京都葛飾区
東京都荒川区
東京都練馬区
東京都足立区
東京都江戸川区
東京都大田区
東京都台東区
東京都北区
東京都目黒区
東京都杉並区
東京都文京区
```
さて、突然ですが問題です。
1．この中に「渋谷区」は含まれているでしょうか？
2．この中に「練馬区」はいくつあるでしょうか？
・
・・・
・・・・・
はい！答えはわかりましたか？
たった20個とはいえ漢字だらけで探すのが大変ですよね。
ではGrepを使ってそれぞれの解答を見ていきます。
最初に渋谷区です。
```sh
grep '渋谷区' sample.txt
# 
```
何も表示されません。
そうです。この中に渋谷区は含まれていないんです。
では次に練馬区を見てみましょう。
```sh
grep '練馬区' sample.txt
# 東京都練馬区
# 東京都練馬区
```
お！2つ表示されました。
先程も伝えたとおり、Grepは**指定した文字列と一致する文字列のある行を取得する**コマンドでしたね。
つまり練馬区は2つ存在するということです。
ということで答えは
  
**1．渋谷区は含まれていない**
**2．練馬区は2つある**
  
となります。

「え？それだけ？」
と不満に思ったあなた！
ご安心ください。
Grepにはオプションが存在しており、オプションをつけることでグッと便利になるのです！！
基本的な使い方はわかったので次はオプションについて見ていきましょう！

# Grepコマンドのオプション
先述したとおり、Grepには便利なオプションが存在します。
使い方は簡単で、
```sh
grep [オプション] <検索文字列> <検索対象ファイル名>
```
というふうに、grepの直後に記述するだけです。
では実際に便利なオプションをいくつか紹介していきます！

### 検索結果を行番号付きで表示する「-n」
上記のsample.txtをそのまま使います。
練馬区が2つ存在することはわかりました。
ただ、次に問題となるのが、**「練馬区がどこにあるのか？」** です。
そこで「-n」オプションの登場です。
では早速使ってみましょう！
```sh
grep -n '練馬区' sample.txt
# 9:東京都練馬区
# 12:東京都練馬区
```
今度は左側に番号がついてます。
そうです、これが行番号です。意外と近くにありましたｗ
実際に確認してみると9行目と12行目に「東京都練馬区」があることがわかります。
どうですか？便利ですよね？？
他にもいくつかオプションを紹介します。

### 一致した文字列の数を表示する「-c」
これはわかりやすいですね！検索した文字列と一致する数をカウントしてくれます。
```sh
grep -c '練馬区' sample.txt
# 2
```
これも使えそうですね！

### 完全一致した行を表示する「-x」
これは使う場面は限られそうですが、知っておいて損はないはずです。
```sh
grep -x '練馬区' sample.txt
#
```
「練馬区」だけでは完全一致ではないので表示されません。
```sh
grep -x '東京都練馬区' sample.txt
# 東京都練馬区
# 東京都練馬区
```
ちゃんと「東京都練馬区」といった具合にフルネームで指定する必要があります。

ちなみにオプションは2つ以上つけることができます。
```sh
grep -xc '東京都練馬区' sample.txt
# 2
```
```sh
grep -xn '東京都練馬区' sample.txt
# 9:東京都練馬区
# 12:東京都練馬区
```
といった感じです。
他にもオプションはたくさんあります。
今回のsample.txtでは説明できない便利なオプションもあるので興味があったり、
「これできないのかな？」と思ったら是非 **「grep　オプション」** で調べてみてください！

# Grepは他のコマンドや処理と併用すると便利さが爆上がり？！
最後に、これは実践ではないのですが、Grepコマンドは単体でも大変便利で強力なコマンドです。
ですが他のコマンドや処理と併用することでその能力を120％発揮します。
例えば、
sedコマンドと組み合わせて特定の行のテキストの置き換えを行ったり、
awkコマンドと組み合わせて特定の行の特定テキストを含む行を抽出したり、
リダイレクションと組み合わせて特定の行を別のファイルにコピーしたり、、、
といった具合に様々な事ができます！！

# まとめ
いかがでしたでしょうか？
Grepコマンド便利ですよね！
私はLinuxの学習過程でパスワードマネージャーを作成したのですが、
その時このGrepコマンドの便利さに大変助けられました！

この記事を読んだ方が、
- 特定な文字列を検索したい
- 特定な文字列を検索して何か処理を施したい
 
といった場合に、Grepコマンドを思い出すきっかけになれれば幸いです。
円グラフについて ChatGPT が語る

**問**
ChatGPT 3.5 さんですね?
統計グラフとして円グラフは不適切であると言われます。その理由をわかりやすく説明してください。

**回答**
はい、私はChatGPT 3.5です。

円グラフは、データの相対的な割合を示すためによく使用されますが、多くの場合、適切なグラフとしては選ばれません。以下に、円グラフが不適切な理由をいくつか説明します。

視覚的に比較が難しい
円グラフは、各部分のサイズを直接比較することが難しいため、相対的な割合を明確に理解することが困難です。例えば、3つ以上の要素を比較する場合、円グラフは混乱を招く可能性があります。

データを隠す可能性がある
円グラフは、適切なスケールで表示されていない場合、実際のデータを隠す可能性があります。また、円グラフが多数の小さなセグメントで構成されている場合、データの正確な相対的な割合を認識することが難しくなる可能性があります。

視覚的に美しく見えるが実際には誤解を招くことがある
円グラフは、美しく見えるため、視覚的に強調されることがあります。しかし、このような強調は、データを歪める可能性があります。また、円グラフの各セグメントにラベルを付ける必要があり、ラベルの重複や位置の問題が発生することがあります。

これらの理由から、データを視覚化するためには、円グラフではなく、棒グラフや折れ線グラフなど、他のグラフがより適切な場合があります。

**問**
「データを隠す」というのはどういうことですか?

**回答**
「データを隠す」とは、グラフのスケールや表示方法が不適切であるため、実際のデータをうまく表現できず、見る人が本来の情報を正確に理解できないことを指します。

円グラフの場合、特定のセグメントが小さい場合、そのセグメントのサイズを小さく表示してしまうと、その部分が実際に占める割合が小さく見え、そのセグメントが実際に占める割合を正確に理解できない可能性があります。また、円グラフの中に多数の小さなセグメントがある場合、各セグメントを細かく分けて表示することになり、データ全体の正確な相対的な割合が分かりにくくなることがあります。

例えば、あるデータセットで、セグメントAが10％、セグメントBが20％、セグメントCが70％を占めるとします。しかし、円グラフのスケールが適切に設定されていない場合、セグメントAやBのサイズが小さく表示され、セグメントCが大きく見えることがあります。この場合、データの実際の比率を正確に理解することが難しくなります。

**問**
スケールの設定は，セグメントA，B，C の面積が 1:2:7 になるので，別にセグメントA，B が不当に小さく表示されるわけではないと思いますが?

**回答**
申し訳ありません、私の前の回答に不正確な表現が含まれていました。セグメントA、B、Cが面積比1:2:7になるように、円グラフのスケールが適切に設定されている場合、セグメントA、Bが不当に小さく表示されるわけではありません。

しかし、円グラフには、各セグメントの比較が難しいという問題があります。例えば、円グラフで複数のセグメントを比較する場合、各セグメントのサイズや角度を比較する必要があり、それが正確でないと、視覚的な比較が困難になることがあります。

また、円グラフには、データセットが複数の小さなセグメントで構成されている場合、視認性が低下する可能性があります。この場合、各小さなセグメントにラベルを付ける必要がありますが、ラベルが重複する可能性があり、誤解を招く可能性があります。

以上のような理由から、円グラフは、他のグラフ（例えば、棒グラフや折れ線グラフ）よりもデータの比較に適していないとされています。
JavaのBean Validationが機能せずエラーになる

## Bean Validationが機能せずエラー画面に遷移する
* Modelにバリデーションのアノテーションはつけている
* Thymeleafの記述もIDE上でエラーになっていない
* Controllerにもバリデーションチェック対象に@Validatedをつけている

上記の通り設定しているのに、何故かエラーになり続けて解決まで時間がかかったので、備忘録として残しておきます。

## コンソール上は下記のような警告が出ている
WARN 15692 --- [nio-8080-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 2 errors<EOL>Field error in object

エラー内容を見る限り、Bind変数に値を渡すのに失敗している。
いろいろ調べたところ、Controller側の記述に問題がありました。

## @Validatedの次の変数はBindingResultでなければいけない
最初Contollerメソッドの引数は次のようになっていました。

public String method(@Validated FormModel formModel,Model model,BindingResult result）

次のように引数の順番を変えたら解決しました。

public String method(@Validated FormModel formModel, BindingResult result, Model model）
staticメソッド

 # staticメソッド

### 効果：メソッド間を超えて変数を使えるようになる。

ルール①：使用したい変数の頭に **static** を付ける。

例：　

```java
private **static** int count = 0;
```

ルール②：ルール①で設定した変数を出力するメソッドの頭に **static** を付ける。

例：　

```java
public **static** void display(){
    System.out.println(count + "台作成済みです。");
  }
```

ルール③：実行用クラスで、ルール②で設定したところを **クラス名**.変数名（メソッド名）に変更する。

例：

```java
Car4 c1 = new Car4();
c1.display();
　　　　　　　↓
Car4 c1 = new Car4();
**Car4**.display();
```

---
About recent malware and incident guidelines, etc. part1 (in English)

# Introduction

We'll also touch on some security news.

# Who am I ?

I'm a humble engineer.

# Expected readers of this article

- Those who want to read security news quickly
- Those who want to receive security topics on a regular basis
- others

# Recent Malware Articles

EsxiArgs

https://piyolog.hatenadiary.jp/entry/2023/02/05/012609

SpyNote

https://japan.zdnet.com/article/35198261/

Using PyInstaller to evade anti-virus software detection

https://gamingpc.one/dev/python-pyinstaller/

# Publications from IPA, NISC and other government agencies

CRYPTOREC cipher list update

https://www.cryptrec.go.jp/list/cryptrec-ls-0001-2022.pdf

Publication of Guidelines for Post-Quantum Computer Cryptography by CRYPTOREC

https://www.cryptrec.go.jp/report/cryptrec-tr-2001-2022.pdf

Publication of Cyber Security Management Guidelines Ver3.0

https://www.meti.go.jp/press/2022/03/20230324002/20230324002-1.pdf

Article by NRI Secure (Cyber Security Management Guidelines Ver3.0)

https://www.nri-secure.co.jp/blog/cybersecurity-management-guidelines-3.0

# Trends in foreign countries

Increase in ransomware damage

https://enterprisezine.jp/article/detail/17667

About NIST's Cyber Security Framework (CSF) 2.0

https://www.nist.gov/system/files/documents/2023/01/19/CSF_2.0_Concept_Paper_01-18-23.pdf


# lastly

I've put together a quick security article. We will continue to do so.
Proxmox7.4 を試してみる　その１　インストールなど

# proxmox VE ってなに？
公式では「DebianベースのOpen-Source-仮想化プラットフォームの操作と管理のためのWebインターフェースを持つ仮想アプライアンスである」とありますがいわゆる vSphere とか windows server とかのvm作成＆管理する奴です。とりあえず proxmox はお試し度高い＝勉強できます。
※ちなみに [vSphere](https://www.proxmox.com/en/)  は残念ながら自分の持っているハードウエアがダメだったのか、インストールできなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/d5c0b410-e12b-f0cc-16cf-9edcd314aebe.png)

# ハードウエア条件とかインストールについて（ごめん、前置きだけ）
Debianベースもあるのか[蟹LAN](https://www.realtek.com/ja/)は全て網羅しているようで200円位のUSB-LANでも認識してくれます（CPU忖度しないのがとても素敵ですね）。とりあえず、proxmox インストールするのは Linux インストールするより簡単でした。サブスクなにそれ美味しいの？（＝死語）っていうのおいといてインストールしましょう。

https://dareblo.com/proxmoxve-install/

https://zenn.dev/northeggman/articles/0203320c4a2690

https://blog.nishi.network/2023/02/12/proxmox7-3-repository/

# ネットワークを参照する
`https:自分のIP:8006`でネットワークを参照みてみると以下が確認できるはず。
※デバイス名は異なる可能性があります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/ee90b81e-af8e-cdc1-c13c-db609d922d1d.png)

# USB-LANを差してみる
結果とすれば、Debian すごいな。です。
まず。物理的に２つのUSB-LANを差してみた結果すぐに認識。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/aebc1ffe-5025-8567-e995-d4d7166428aa.png)

そしてproxmox ネットワークを参照みてみると・・・当たり前だが認識しとる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/984ac191-d89e-0ad8-0d6b-1900016e1465.png)

すごいな。。ちなみに proxmox のインストール方法は、巷にあふれているので割愛しました。
最終的にvmwareで運用中のサーバを移行するまでの記事にしたいと思います。

# ストレージの追加でエラーになる
自宅NASに SMB/CIFS で接続しようと思ったらエラーとなってしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/b8ed1b21-3be1-c8a1-68c9-9de9e5cf4661.png)

割とあきらめていたのですが解決した。SMBバージョンが 3 以降でないとだめだった。
なので synology 管理画面で・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/48ddcc58-b607-dde1-ff44-68434d2bde44.png)

解決した！！

https://www.smarthomebeginner.com/add-synology-to-proxmox-cifs/

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

https://blog.nishi.network/2020/08/12/proxmox-part1/

https://zenn.dev/northeggman/articles/0203320c4a2690

https://engineers.fenrir-inc.com/entry/2018/12/06/110000
最近のマルウェアやインシデント・ガイドライン等について part1

# はじめに
セキュリティのニュースについても少しずつ触れていこうと思います。

# Who am i ?
しがないエンジニアです。

# この記事の想定読者
- セキュリティのニュースを手っ取り早く読みたい方
- 定期的にセキュリティトピックスを入手したい方
- その他

# 最近のマルウェアに関する記事
EsxiArgs

https://piyolog.hatenadiary.jp/entry/2023/02/05/012609

SpyNote

https://japan.zdnet.com/article/35198261/

PyInstallerを使って、アンチウイルスソフトの検知回避

https://gamingpc.one/dev/python-pyinstaller/

# IPAやNISCその他の政府機関からの公表

CRYPTOREC暗号リストの更新

https://www.cryptrec.go.jp/list/cryptrec-ls-0001-2022.pdf

CRYPTORECによる耐量子計算機暗号に関するガイドラインの公表

https://www.cryptrec.go.jp/report/cryptrec-tr-2001-2022.pdf

サイバーセキュリティ経営ガイドラインVer3.0の公表

https://www.meti.go.jp/press/2022/03/20230324002/20230324002-1.pdf

補足：NRIセキュア社の記事（サイバーセキュリティ経営ガイドラインVer3.0）

https://www.nri-secure.co.jp/blog/cybersecurity-management-guidelines-3.0

# 諸外国の動向

ランサムウェア被害の増大

https://enterprisezine.jp/article/detail/17667

NISTのサイバーセキュリティフレームワーク（CSF）2.0について

https://www.nist.gov/system/files/documents/2023/01/19/CSF_2.0_Concept_Paper_01-18-23.pdf


# 最後に

ざっとセキュリティ記事をまとめてみました。今後も続けていきます。
Vimの基本操作まとめ

# はじめに
Vimは初めて触ると文字の入力すらまともにできませんが、
触って慣れていくと便利に感じるエディタです。
そこで今回は、Vimの基本操作(コマンド)を表でまとめていきたと思います。

# Vimについて
Vimはviエディタから派生・発展したエディタであり、キーボードのみで全ての操作が可能となっています。
複数のモードを用いて編集を行うエディタであり、大別すると下記4つのモードに分類することができます。
- ノーマルモード
- インサート(挿入)モード
- ビジュアルモード
- コマンドモード

これら4つのモードを駆使して文字入力やコピー、削除等の作業を行なっていきます。



# 基本コマンド
ここからはVimの基本コマンドを、カテゴリごとにまとめていきたいと思います。

## モード変換コマンド
### ノーマルモード→インサート(挿入)モード
| コマンド | 内容 |
|:-:|:-:|
|i   | 現在のカーソル左から挿入|
|I   | 現在のカーソル行頭から挿入  |
|a   | 現在のカーソル右から挿入  |
|A   | 現在のカーソル行末から挿入  |
|o   | 現在のカーソル行下に空行を入れて挿入  |
|O   | 現在のカーソル行に空行を入れて挿入  |


### インサート(挿入)モード→ノーマルモード

| コマンド | 内容 |
|:-:|:-:|
|Esc | インサート(挿入)モードからノーマルモードへ  |
|Ctrl + [   | 同上  |

### ノーマルモード→ビジュアルモード
| コマンド | 内容 |
|:-:|:-:|
| v  | カーソル位置から範囲選択  |
| V  | カーソル行を範囲選択|
| Ctrl + v  | カーソル位置から矩形選択  |


## カーソル移動コマンド
`j`〜`E`のコマンドに関しては、コマンドの前に数字を入れることで、
数字分移動することが可能。
例. `2j` → ２つ下へ移動

| コマンド | 内容 |
|:-:|:-:|
| j  | 下へ移動(↓カーソルキーと同義)  |
| k  | 上へ移動(↑カーソルキーと同義)  |
| h  | 左へ移動(←カーソルキーと同義)  |
| l  | 右へ移動(→カーソルキーと同義)  |
| w  | 次の単語の先頭へ移動  |
| W  | 次の単語(空白単位)の先頭へ移動  |
| b  | 前の単語の先頭へ移動  |
| B  | 前の単語(空白単位)の先頭へ移動  |
| e  | 現在の単語の末尾へ移動  |
| E  | 現在の単語(空白単位)の末尾へ移動  |
| 0  | 行頭へ移動  |
| ^  | 行頭の非空白文字へ移動  |
| $  | 行末へ移動  |
| {  | 段落ごとに上へ移動  |
| }  | 段落ごとに下へ移動  |
| [[  | セクションごとに上へ移動  |
| ]]  | セクションごとに下へ移動  |


## 行移動
| コマンド |　内容 |
|:-:|:-:|
| :10  | 10行目へ移動 |
| 10G  | 10行目へ移動 |
| gg  | カーソルをファイルの先頭へ移動  |
| G  | カーソルをファイルの末尾へ移動  |

## コピー&ペースト
`yy`コマンドは、コマンドの前に数字を入れることで複数行コピーすることが可能。
例. `3yy` → カーソル位置から3行コピー

| コマンド | 内容 |
|:-:|:-:|
| y  | コピー(範囲選択してから使用)(`y`はヤンクを表す)  |
| yy  | 行コピー |
| yiw  | カーソル位置の単語をコピー |
| p  | 下の行へペースト  |
| P  | 現在の行へペースト  |

## 削除
コピーの時と同様に`dd`や`cc`コマンドも、コマンドの前に数字を入れることで複数行削除可能。
例. `3dd` → カーソル位置から3行削除
| コマンド | 内容 |
|:-:|:-:|
| d  | 削除(範囲選択してから使用)(`d`はdeleteを表す)  |
| dd  | 行削除  |
| diw  | カーソル位置の単語を削除  |
| c  | 削除してインサートモードへ(範囲選択してから使用)(`c`はcutを表す)  |
| cc  | 行削除(インサートモードへ)  |
| ciw  | カーソル位置の単語を削除してインサートモードへ  |
| x  | カーソル位置の文字を削除  |
| s  | カーソル位置の文字を削除してインサートモードへ  |


## 検索&置換
| コマンド | 内容 |
|:-:|:-:|
| /hoge  | hogeを下方向検索  |
| ?hoge  | hogeを上方向検索  |
| *  | カーソル上の単語を下方向検索  |
| #  | カーソル上の単語を上方向検索  |
| n  | 次の検索結果に移動  |
| N  | 前の検索結果に移動  |
| :%s/hoge1/hoge2/g  | hage1をhoge2へ置換(`%`はファイル全体を表す)  |
| :%s/hoge1/hoge2/gc  | hage1をhoge2へ置換(1つ1つ確認して置換)  |
| r  | カーソル位置の文字を置換  |
| R  | 置換  |

## 編集
| コマンド | 内容 |
|:-:|:-:|
| .  | 直前の変更を繰り返す  |
| u  | 変更を取り消す(`u`はundoを表す)  |
| Ctrl + r  | やり直す(redo)  |
| >>  | 右にインデントを移動  |
| <<  | 左にインデントを移動  |


## ファイル操作
| コマンド | 内容 |
|:-:|:-:|
| :w  | 保存  |
| :q  | ファイルを閉じる  |
| :wq  | 保存してファイルを閉じる  |
| :q!  |保存しないでファイルを閉じる   |
| ZZ  | 保存しないでファイルを閉じる  |

## その他
| コマンド | 内容 |
|:-:|:-:|
| :!command  | comamandを実行する  |
| !!  | 前のコマンドを実行する  |


# 終わりに
Vimの基本操作についてまとめてみました。
ぜひこれらのコマンドを使ってVimを使いこなし、効率を上げていただければ幸いです。
それでは皆さん良きVimライフを〜
HTML基本の「キ」

こんばんは！(21時に執筆してます)
今日の講義聞いてて明日は我が身だなと思ったので記録用に残そうかなと。
# HTMLのファイル構造について
現状の段階で習ってることはこんな感じ。↓
![html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351947/492db75f-f6bc-92d5-d820-e9e761a8f3c2.png)
(私作 意外と作るの難しかった)
## 　猫の階層から牛さんまでたどり着くためにはどうしたらいい？<br>　～相対パスの考え方～
うーん難しい。けど一個づつ考えていけばいける。
予備知識として持っておくべきなのは、階層を一個戻るときは「<b>../</b>」をつければいいってこと。
この図で言うなら猫ちゃんはCh1の中にいるよね。
とりあえず出してあげよう。
```html
<a href="../"></a>
```
これでCh1まで来れた。けどまだ遠いね
壁をぶち破って移動はできないから戻ろう。
```html
<a href="../../"></a>
```
よしSam2まで来れた。あと一息！！
Sam1までこれればあとはindex.htmlだからSam1までの行き方を考えよう。
Sam2とSam1はおんなじ階層にあるね。あれ？もう行けるじゃん
```html
<a href="../../Sam1/index.html"></a>
```
行けたね！！
自分がいるところからどうやって動けばいいかが相対パス！
覚えとこう！！
Homebrewを使用してインストールしたMySQLの停止方法

# 概要
`Homebrew`を使用してインストールした`MySQL`すると自動で`3306`portを使用して`MySQL`が起動します。ローカル環境で開発を行う際、`3306`portを使用して何らかの接続を行いたい時がありますので、そうなると`MySQL`が邪魔になる可能性があります。
今回は、`Homebrew`を使用してインストールした`MySQL`の停止方法を記載します。

# 前提条件
- `Homebrew`をインストールしている
- `Homebrew`を使用して`MySQL`をインストールしている
- `Homebrew`を使用して`MySQL`インストールする場合のコマンドは、下記に示す
```sh
$ brew install mysql
```

# バージョン
```sh
$ brew --version                                             
Homebrew 4.0.16
Homebrew/homebrew-core (git revision dc48899a2fc; last commit 2023-03-05)
Homebrew/homebrew-cask (git revision b6bd6570de; last commit 2023-03-05)
```



# portの使用確認
- `lsof`コマンドを使用して、指定したportの使用状況を確認する
- `mysqld`が表示されたら、`MySQL`で使用されている状況である事が分かる 
```sh
$ lsof -i:3306
# or
$ sudo lsof -i:3306

# 出力結果
COMMAND PID   USER   FD   TYPE DEVICE              SIZE/OFF NODE   NAME
mysqld  1234  test   1**  IPv4 ******************    *t*    TCP localhost:mysql (LISTEN)
# 隠す必要性はないですが、一部`*`で文字を隠しています
```

# `MySQL`の停止方法
MySQLは下記のコマンドで停止する事ができる。
`Homebrew`を使用しないで直接`MySQL`をインスールした場合は、下記のコマンドで停止する
```sh
$ mysql.server stop
Shutting down MySQL
.... SUCCESS! 
```
`Homebrew`を使用して`MySQL`をインスールした場合は、`mysql.server status`で起動ステータスを確認すると`SUCCESS! MySQL running`となっている
```sh
$ mysql.server status
 SUCCESS! MySQL running (*****)
```

`brew list`でローカル環境に入っているば`MySQL`を確認する
```sh
$ brew list  

# 著者は、下記の MySQLが導入されてた
==> Formulae
mysql
mysql@5.6
```
バージョンを指定して、改めて`MySQL`の停止コマンドを押下する
```sh
$brew services stop mysql@5.6
#　出力された結果
Stopping `mysql@5.6`... (might take a while)
==> Successfully stopped `mysql@5.6` (label: homebrew.mxcl.mysql@5.6)
```
改めてステータスを確認し、エラーが表示されたら、完全に`MySQL`が停止した状態となる
```sh
$ mysql.server status            
 ERROR! MySQL is not running
```

# 参考資料
- [mysql クライアントコマンド](https://dev.mysql.com/doc/refman/8.0/ja/mysql-commands.html)
- [【Mac】MySQLの停止・起動・状態確認の基本コマンド](https://freeheroblog.com/mac-mysql/)
- [Linuxのポート状況を確認する](https://www.linuxmaster.jp/linux_skill/2009/02/linux-4.html)

# 感想
`Cloud SQL`にローカルから接続を行いたい為、今回は`brew`で導入した`MySQL`を停止する必要がありました。分かってしまえば簡単に終わるんですが、実際ここまで辿り着くのに、かなり時間を要しました。今回は新しい事を行っているので、またこのような事態に陥る事は多々あるとは思いますが、開発メンバーに教えて頂きながら困難に立ち向かいたいと思います。
解像度を下げる


pythonでファイル名一覧をとって　jpgファイルをffmpegで解像度下げる

```

import glob
import subprocess
import os
import time
import sys
import re
from unittest import result

# ファイル名と拡張子に分離する
def parse_filename(content):
    filename1 = re.search('^[a-zA-Z\d_]*[^.]', content);
    extend = re.search('[.][a-zA-Z\d]+', content);
    return [filename1.group(), extend.group()]


def mainloop():
    path = r'./'

    folderfile = os.listdir(path)
    for file in folderfile:
        if file.find(".JPG") > 0 or file.find(".jpg") > 0:
            print(file) 
        
            t_file = parse_filename(file)
            t_filename = t_file[0]
            t_extend = t_file[1]

            cmd = 'ffmpeg -i {0}{1} -vf "scale=1440:-1" -q 2 {0}_1440x1{1}'.format(t_filename,t_extend)
            subprocess.call(cmd)

            print(cmd) 
            return 0

    return 0

if __name__ == "__main__":

    mainloop()
    exit(1)


```
Udemyのコンテンツの字幕を翻訳し合成音声で読み上げるChrome拡張を作りました

## モチベーション
- 最近、プログラミングの勉強にUdemyという動画サービスを使っています。
- プログラミングに関するコンテンツは圧倒的に英語が多く、英語の字幕を見ながら動画を見ることが必要です。
- しかし、字幕を読みながらプログラミングの動画を見るのは大変で、動画を見るスピードが遅くなったり、集中力が切れたりします。
- そこで、英語の字幕をGoogle翻訳で日本語に翻訳して合成音声で読み上げるChrome拡張を作りました。

## Chrome Web Store URL
- [Udemy translate & speech](https://chrome.google.com/webstore/detail/udemy-translate-speech/deajnmcnjlonmjkaibbiflnmihlmbdbc?hl=ja&authuser=0)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184922/c8b5126e-3a18-4b98-02d8-5f866d96db52.png)

## 実装面
### 字幕の取得
- 字幕はclass属性が同じdiv要素に書かれているので、そのdiv要素を取得して、その中身のテキストを取得します。

### 翻訳
- 翻訳はGoogle翻訳のAPIキー不要のエンドポイントがあったのでそれを使用しました。
- `Found a Google Translate endpoint that doesn't require an API key.`
    - [https://github.com/ssut/py-googletrans/issues/268](https://github.com/ssut/py-googletrans/issues/268)

### 合成読み上げ
- 読み上げには、Web Speech APIのSpeechSynthesisを使用しています。以下のコードだけで読み上げができます。
``` JavaScript
const synth = window.speechSynthesis
const utterThis = new SpeechSynthesisUtterance()
utterThis.text = 'こんにちは'
utterThis.pitch = 1
utterThis.volume = 1
utterThis.rate = 1
utterThis.lang = 'ja-JP'
synth.speak(utterThis)
```
Web Speech APIは簡単に実装できるので、他のアプリでも使ってみたいと思います。

### 今後の機能更新
- 翻訳した文字列を動画内に表示する機能を追加する予定です。
    - 実装しました。(2023/05/04)
- [O’Reilly online learning](https://learning.oreilly.com/home/)の動画にも適用してみたいです。
【SwiftUI】iOS14からのナビゲーションバーボタン

# はじめに
ナビゲーションバーボタンを実装するのに`navigationBarItems`を使用していましたが、
iOS14から非推奨らしいので代用の`toolbar`を使ってみます。

# スクリーンショット
![simulator_screenshot_D49B16FF-6650-4BC6-9153-1E4EEC047AA9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/178d8fb0-377f-a736-a5f5-e976ea438df5.png)

# 実装
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationStack {
            Text("Hello, world!")
                .toolbar {
                    ToolbarItem(placement: .navigationBarLeading) {
                        Button {
                            
                        } label: {
                            Text("左のボタン")
                        }
                    }
                    
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button {
                            
                        } label: {
                            Text("右のボタン")
                        }
                    }
                }
        }
    }
}
```

# おわり
https://developer.apple.com/documentation/swiftui/view/toolbar(content:)-5w0tj
解説・ExecutableMusic。

## まえがき

だいたいの方は初めまして、MachiaWorksです。

Sessions終了お疲れ様でした。
自分はMusicCompoに曲を提出して5位でしたが、今回面白かったのは「StreamingMusicが全体の半分くらいだった」ということかと。ほかはTracked（トラッカーを使った曲）とExecutableMusicになってました。
そういう意味ではわりとエッジのきいたコンペではあったかと考えます。
（ちょっくら数えてみたらStreaming6、Tracked4、Executable2というコンペでした）

TrackedMusicは他のところでも情報があるしそれは省略するとして、
今回は（多分自分くらいしか情報もってねえんだろうなと思う）ExecutableMusicについて情報を書いておこうと思います。

## 概要・ExecutableMusicとは

ExecutableMusicとは、実行ファイルしかなくて、その時に音声データを生成するというファイル、という形で伝わっています。

この実行ファイルしかないというのが曲者で、X68000のように音源を搭載している環境ならまだしも、Windowsではどうやって音声を鳴らすのかという部分から考えないといけません。

この部分でいかに緻密かつ容量少なくWAVを生成する、というのが実質的なトレンドになっているものと考えます。

言い方を変えると、メガデモで生成される曲のプログラムを単体で切り出したものをExecutableMusicと定義したと考えていいと思います。

よって、音楽を作ったことない人でもメガデモの制作経験があれば十二分に知識を流用できるものと考えます。

## 例えばこういうもの

自分が作ったやつ
https://youtu.be/NP8bjmesy2Q?list=PLOfPKPePZaWlrP5XE11RmFMxogxyrBdAM&t=14197

今回のSessions、PC demo Compoのうち、5作品はプログラムで音を生成してます。
（数え間違ってたらスイマセン）
https://youtu.be/NP8bjmesy2Q?list=PLOfPKPePZaWlrP5XE11RmFMxogxyrBdAM&t=36799

## ExecutableMusicの基本的な構成

構成はWindows環境であれば主に以下のステップに分かれます
（音源を持ってるPCであれば少し変わった形になりますが基本的にはこのステップで分類できるかと）

1\. ウィンドウの生成
2\. 波形の作成
3\. 波形の再生

1.および3.については、割と定型的な処理になってくるかと思います。
1.はAPIを使うなり自前で描画するなりすれば済みますし、3.についても同じくそこまでの選択肢がないのでAPIで鳴らすことになるかと思います。

結局2.に大量の時間を費やして作ることになるわけですね。
2.にて製作者のオリジナリティを主に発揮することになります。

## 波形生成の実例

ここでは、上記のExecutableMusicについて「こんな感じで作ってみましたよー」というご紹介を書いておきます。

Githubにソースコードもアップ済みです。

https://github.com/MachiaWorks/GPUTrance3gou

### GPUで波形生成？

まず今回の楽曲ではGPUで曲を作ってます。
なんのことかわからんかたは、下記URLを見てみて下さい。
https://qiita.com/MachiaWorx/items/68f8691d0866e0e0ff68

つまり、GPGPU的なアプローチで音楽を生成しているわけですね。

結構有名なものだと、よっしんさん＋Yet11さんのこのデモでもGPU生成で曲が作られてます。

https://www.youtube.com/watch?v=KH1STcQd4Zs

ちょっと書き方にクセがあるため、ちょっと記述内容にむずかしいところはあるんですが、生成速度も早いですし、比較的短いコードに形になるので、慣れると扱いやすいかと。

自分はツールも自作しておいて、Shadertoy上で書くよりちょっぱやで試行錯誤できる環境を構築しました。
よかったら使ってみて下さい。
https://machiaworx.net/?p=332

### どうやって譜面書いてるの？

https://github.com/MachiaWorks/GPUTrance3gou/blob/main/20181114_demoTemplate/synth_shader.h

内部では配列に音の高さを格納して、相対的な音の高さを指定してます。
加えて、毎データ拍数をカウントしておいて、特定の拍になったら音の高さを変更する、といった処理を追加しております。

結果、移調や途中でのフレーズ変更が楽に行える状態になりました。

### どうやって波形を生成しているの？

https://qiita.com/MachiaWorx/items/68f8691d0866e0e0ff68

TransformFeedbackですね。
（Shadertoyだと2*WAVの長さ分のテクスチャに書き込んでるみたいですが）

で、上記のソースコードでWAVを生成して、TransformFeedbackでCPU上でWAVデータを使えるようにしてそれを再生すれば終わりと。
意外とシンプルですね。
アセンブラとかも使わなくていいのでプログラムの入門にももってこい。

### どうやってソースコードにしているの？

ExecutableMusicは1個のファイルに全部格納する必要があるので、別ファイルを読み込んで再生ということがやりづらいです。
よって、ソースコード内にシェーダのコードを記入します。

自分はShader Minifierを利用しています。
https://ctrl-alt-test.fr/minifier/?main

オプションは「--no-renaming」を利用。

これは、マクロや最適化すると動作しないことを確認しているためです。
可能だったら変数名だけ最適化するのがよさそうですが、検証のための時間がなく文字列そのまま載せています。

この手の最適化は「動かなくなることがある」のを前提として検証していくのが確実です。

## 思いついたら

また色々書く予定です。
そもそもサイズコーディング関連の事ほとんど書いてないので。
VirtualBox＋CentOS7＋Laravel9.9 の開発環境構築をする

# はじめに
この記事ではVirtualBoxを使用して、Laravelの開発環境を構築します。

VirtualBoxを使用した、CentOSの環境構築については以下の記事を参考にしてください。
[VIrtualBox（Windows10）にCentOS7環境を構築し、TeraTermでssh接続をする](https://qiita.com/zoohataisetu/items/c079d688e33a9752398c)
[VirtualBox＋CentOS7+Apach2.4＋PHP8.1＋MySQL8.0 の開発環境構築をする](https://qiita.com/zoohataisetu/items/393e9ea735cb0db49e23)

# 環境
- VirtualBox:7.0
- ホストOS:Windows10
- ゲストOS:CentOS 7.9
- Apache:2.4.6
- PHP:8.1.15
- Mysql:8.0.27
- Laravel:9.9

# 1.composerのインストール
composerをインストールする。

```
# yum install composer
```

composerがインストールされたことを確認。

```
# composer -V
```
# 2.Laravelプロジェクトの作成
gitのインストール。

```
# yum install -y git 
```

composerでLaravelのライブラリを読み込む。

```
# composer global require laravel/installer
```

Laravelのプロジェクトを作成。

```
# cd /var/www/html  
# composer create-project --prefer-dist "laravel/laravel=9.*"  laravel
```

Allowed memory size of 1610612736 bytes exhaustedエラー がでたら
以下記事が参考になります。

https://codelikes.com/php-ini-file-path/

作成したプロジェクトのアクセス権限を変更。(本番環境時は注意)

```
# chmod -R 777 /var/www/html/laravel/storage
```

Laravelでmysqlが使用できるように.envを編集。

```
# vi /var/www/html/laravel/.env

(省略)
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=mysqlのデータベース名(別途作成してください。)
DB_USERNAME=root
DB_PASSWORD=mysqlのパスワード
```

Laravelを日本語環境に変更。

```
# vi /var/www/html/laravel/config/app.php

(省略)
'timezone' => 'Asia/Tokyo',

(省略)
'locale' => 'ja',
```

DocumentRootを変更

```
#  vi /etc/httpd/conf/httpd.conf

(省略)
DocumentRoot "/var/www/html/laravel/public"
```

Apacheを再起動。

```
systemctl restart httpd
```

# 2.node, npm インストールとadminlte追加
node, npm インストール

```
# yum install epel-release
# yum install nodejs npm
```

バージョン管理「n」を導入

```
# npm install -g n
# n stable
```
cross-env cross-spawnをglobalでインスコ

```
# npm -g install cross-env cross-spawn
```

# 3.ララベル初期化

phpライブラリ

```
#  cd /var/www/html/laravel && composer install
```

JSライブラリ

```
# cd /var/www/html/laravel && npm install
```

ブラウザでhttp\://{ipアドレス}に接続し、Laravelの初期画面が表示されることを確認。

以上！
読書メモ-ユースケース駆動開発実践ガイド-

## 1. まとめ
・ICONIXプロセスと言う開発手法がある。
・ユースケース駆動開発とは、「まずユーザーガイドを書き、それからコードを書く」こと。
・要求されたシステムの振る舞いを明言するユースケースを作成することが肝。

## 2. 内容
#### 2-1. ICONIXプロセス(図示)
<img width="300px" alt="img1" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/5e20080f-ed87-803e-7949-d5d763f5a537.png">

コーディングまでの道のりが長い。。
大事な点は、以下の3点です。
```
・ドメインモデリングを最初に行い、プロジェクトの共通語を定める。
・ドメインモデルとユースケースは常に見直す。
・要求レビューにはユーザーも入ってもらう。
```
#### 2-2. ユースケースモデリング
```
・ユースケースは機能要求ではない。明確に叙述的に簡潔に手順を示す。
・システムとユーザーの対話を記述する。
・ユースケースはドメインモデルの名前を使う。
```
例)
顧客は書店のホームページのURLを入力し、システムはそれを表示する。
システムはカタログから書籍一覧を取り出して表示し、ホームページ上にクリック可能なリンクの形式で表示する。

#### 2-3. ロバストネス分析
```
・ユースケースのオブジェクトを図示したもの。
・"ユースケース"と"詳細設計"を繋ぐことが目的。
・ここで試験的な設計を行うことで要求をより理解できる。
```
例)
上記ユースケースの例のロバストネス図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/e098e9ad-10a4-5daf-a4db-be14d6834db9.png)
スクレイピングするとChecking if the site connection is secureがでて欲しいHTMLがスクレイピングできない

# はじめに

スクレイピングを使ってアプリを開発しているときにつまづいたのでまとめていきます
今回はPythonを使っている場合の解決策をのせます

# 問題

BeautifulSoupでスクレイピングをしたところ

```
Checking if the site connection is secure
```

といった内容のHTMLを取得できるのですが、お目当てのページはスクレイピングできませんでした

https://blog.halpas.com/archives/16474

# 解決方法

ウェブサイトは、Cloudflareを使用しており、自動的なスクレイピングやボットからのアクセスを防止するためにセキュリティチェックを実行しているようです

そこで`cloudscraper`を利用することで回避しました

```bash
$ pip install cloudscraper
```

```py:main.py
import cloudscraper

scraper = cloudscraper.create_scraper()  # Create a cloudscraper instance
url = "https://example.com"  # Replace with the URL you want to scrape

response = scraper.get(url)

if response.status_code == 200:
    html_content = response.text
    print(html_content)
else:
    print(f"Error: {response.status_code}")
```

# おわりに

ChatGPTにきいて解決したものですが、メモ程度にまとめとこうと思いました
Qiitaに書く必要ないのではと最近思い始めてきています。
ChatGPT本当にすごい、、

# 参考

https://blog.halpas.com/archives/16474
読書メモ-漫画でわかるCPU-

## 1. まとめ
・CPUはコンピューターの制御と計算をする。
・CPUの中身は1と0で動く電子回路。
・計算する回路と短期記憶する回路から出来ている。

## 2. 内容
#### 2-1. CPUって？
よく"計算するところ"ところと言われて”脳みそ"に例えられます。
**C**om**pu**terの略ではなく、**C**entral **P**rocessing **U**nit (中央演算処理装置)の略です。
コンピューターの中では、図のオレンジの部分を担当してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/977acee6-1886-36f8-cffd-455326ba839a.png)


#### 2-2. CPUの構造
物理的に言うとCPUは**電子回路**です:electric_plug:
さらに**演算する回路**と**記憶する回路**があって、
この二つをうまく組み合わせて計算&制御をしてる感じになります。(雑)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/87508cd4-714e-ed8e-e12e-67eb33ac860e.png)


#### 2-3. 回路とは？
CPUは回路の中でも論理回路です。
1(High)と0(Low)の電圧で足し算などの計算ができる回路です。
論理回路は、論理ゲートと呼ばれる基本的な計算ができるパーツを組み合わせてできています。
FlutterエンジニアがJetpack Composeを学んでみた（感想編）


<b>こんにちは。Flutterエンジニアになって、2年ぐらいが経ちました。始めた頃は、本当にエンジニアになれるのかな？？と思いながら勉強していました。今でも本当にFlutterエンジニアとしてちゃんとできているのかと不安になりますが、毎日勉強しています。</b>

Flutterを書いていく中で、どうしてもネイティブの実装をしなければいけないと感じることが多くなり、ネイティブ（iOS/Android）のコードを見たりしていました。

たまたま時間があったため２日間、Jetpack Composeを勉強してみることにしました。


Jetpack Composeを勉強してみたいと思った理由として
- <b>Androidエンジニアの同期に聞いてみたところ、「Swiftを少しでもやっていたら、基本的な文法が似ている」とおすすめされた。</b>

- <b>Jetpack ComposeはFlutterの書き方に似ていることをうっすらと知っていた。</b>

- <b>名前がカッコよかった。</b>

などの理由で始めてみました。


# やってみたこと

## １、Android Composeのチュートリアルを進めてみる。

https://developer.android.com/jetpack/compose/tutorial?hl=ja

このページでは、
- Android Composeのチュートリアルで書かれている単語の理解（コンポーズなど）
- 簡単なUIの作り方（Text）
- サンプルアプリに書いてあるコードの理解(@Composableの意味など)

をしていました。

その中でも特に力を入れたことは、

- <b>書いてあるコードはFlutterで言うと何のコードになるのか</b>

を考えながら調べていました。その理由としては、理解が早いと思ったからです。

例えば、


#### Jetpack Compose
```kotlin
@Composable
fun Greeting(name: String) {
    Column {
        Text(text = "Hello!")
        Text(text = "Android!")
    }
}
```

#### Flutter
```dart
Column(
 children: const [
    Text('Hello!'),
    Text('Flutter!'),
  ],
),
```

個人的な意見として多少「ん？？？」となる部分がありましたが、書き方としてはほぼ同じだなと感じました。どちらもみるだけで理解できるとても簡単な書き方ですね。


## ２、Widgetについて慣れてみる。

https://developer.android.com/courses/pathways/android-basics-compose-unit-1-pathway-3?hl=ja


特にこの２つのGifはとても理解するのに助かりました。


#### Column
![df69881d07b064d0.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/f0be2fe8-99ad-18f0-f702-41b285cb4576.gif)


#### Row
![c1e6c40e30136af2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/c964d707-6fb0-9d0f-e0a9-ed77b5e64ad3.gif)


Flutterで使っている`MainAxisAlignment`や`CrossAxisAlignment`の書き方がとても似ていることがわかりました。



## ３、Todoアプリを模写してみる

これは正直なところ、完全には理解できないくらい難しい難易度でした。Widgetの理解がまだまだだったのに加えて、データベースの操作など、わからないことばかりでした。とりあえず動かせるぐらいになりました。

https://qiita.com/MasashiHamaguchi/items/6e96703cb8b512c41aac

https://qiita.com/MasashiHamaguchi/items/4402101572af09d55551


上の実装のままだとエラーになることがありましたので少し手を加えたものを載せておきます。

https://github.com/iseruuuuu/jatpack_compose_todo_app

`app/src/main/java/com/example/android_todo_app`のファイルにあります。

ここでは、
- dabase
- model
- ui/theme
- utils
- viewmodel
- MainActivity.kt 

に分けてみました。（間違っていたりしたら教えていただけると幸いです。）
僕なりにFlutterっぽいフォルダー構造にしてみました。


# 感想

とりあえず、２日間やってみての感想としては、

- <b>WidgetがFluterっぽくてオモシロイ。
- <b>importが多すぎ
- <b>ファイルの切り分けがとても楽
- <b>書き方に癖があるものの、全く理解できないわけではない
- <b>関数で UI を描画できるのが鬼すごい


ゴールデンウィークでお休みなので初めてみてもいいのではないかと思いました。
ポエムだけだと、いい情報を共有できていないので、後日に技術的な記事を投稿いたします。
Misskeyでリノートやリプライのハードミュートを実行するUserScript

# 概要

Misskey v13.11現在、**ハードミュートはリプライ元やリノートを貫通**します。

プラグイン等で弄れる部分ではないため、ブラウザ側で強制非表示にするUserScriptを作成しました。
ブラウザにTampermonkeyなどの拡張機能を入れることで利用できます。
仮想DOM生成の度にループ処理を回すので、NGワードの数が多いと重くなります。ご注意ください。

# コード
下記の`// @match https://misskey.io/*`の部分を使用するサーバーに書き換えてください。
`ngWords = ["ミュート", "NGワード"];`部にNGワードを指定/追加してください。
(AND指定などはできません)
```javascript
// ==UserScript==
// @name     Misskey Mute
// @version      0.1
// @description  Mute words on misskey
// @author  @noc_turn@nijimiss.moe
// @grant    none
// @match        https://misskey.io/*
// @run-at   document-idle
// ==/UserScript==

(function () {
    'use strict';
    // NGワードを設定
    const ngWords = ["ミュート", "NGワード"];
    const observerConfig = {
        childList: true,
        subtree: true
    };

    function observerCallback(mutationsList, observer) {
        for (let mutation of mutationsList) {
            if (mutation.type === 'childList') {
                const divs = document.querySelectorAll('div[tabindex="-1"]');
                divs.forEach(div => {
                    const divText = div.innerText.toLowerCase();
                    for (let word of ngWords) {
                        if (divText.includes(word.toLowerCase())) {
                            div.style.display = 'none';
                        }
                    }
                });
            }
        }
    }

    const observer = new MutationObserver(observerCallback);
    observer.observe(document.body, observerConfig);
})();
```

# 導入方法
各ブラウザへの導入方法です。
## iOS, MacOS
上記のソースをテキストエディタにて適当な名前（misskeyng.jsなど）で保存し、iCloudドライブなどに適当なフォルダ(Userscriptsなど)を作って入れておきます。

下記のアプリをインストールします。
[Userscripts](https://apps.apple.com/jp/app/userscripts/id1463298887)
UserScriptをiOSのSafariでも実行できるようになるアプリです。

1. iOSの「設定」→「Safari」→「機能拡張」→で「UserScripts」をオンにします。できればすべてのWebサイトを「許可」にしておきます
2. UserScriptアプリを起動して「**Set Userscripts Directory**」ボタンをタップし、先程のiCloudフォルダを指定します。
3. Safariで該当のMisskeyサイトを開き、URLの横の左上の「ああ」or「AA」のアイコンをタップし、UserScriptをタップして該当のスクリプトをオンの状態にします。ここにない場合アドレスバーに`</>`のアイコンがあるかもしれません。

Macも同アプリにて利用できるようです。今Macbookが使えないので下記などを参照ください。
[UserScripts 公式GitHub](https://github.com/quoid/userscripts)

## Android
Chromeは拡張機能が使用できないので利用できません。

FireFoxは
[Tampermonkey - Android Firefoxアドオン](https://addons.mozilla.org/ja/android/addon/tampermonkey/)
から導入できます。

Firefoxの右上の︙からTampermonkeyを選び、新規スクリプト作成を行って上記コードを記述してください。

## PC版
Tampermonkeyやgreasemonkeyなどの拡張機能を導入することで使用できます。
[Tampermonkey - Chromeアドオン](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=ja)
[Tampermonkey - Firefoxアドオン](https://addons.mozilla.org/ja/android/addon/tampermonkey/)
[Tampermonkey - Edgeアドオン](https://microsoftedge.microsoft.com/addons/detail/tampermonkey/iikmkjmpaadaobahmlepeloendndfphd?hl=ja-JP)

拡張メニューの「新規スクリプトを追加」から上記コードを記述してください。
git 割り込み作業が入った時(git-stash)のチートシート

coding中に、割り込み作業を指示された事はありませんか？
**コミットしないまま、** 変更内容を一時的に避難するコマンドです。
## must
|コマンド|説明|コマンド例 or 出力例|補足|
|:-|:-|:-|:-|
|git stash save "退避メッセージ"|一時退避を行う|git  stash save "README更新"|
|git stash list|保存したstashを確認|stash@{0}: On master: README更新|
|git stash apply stashの値|保存内容を復旧|git stash apply 0|git stash listで、{}で囲まれた値を指定する|

## want
|コマンド|説明|コマンド例 or 出力例|補足|
|:-|:-|:-|:-|
|git stash show stashの値|stashした内容を確認|git stash show 0|git stash listで、{}で囲まれた値を指定する|
|git stash drop stashの値|指定したstashを削除する|git stash drop 0|
|git stash clear|すべての退避したstashをクリアする|
AWS DVAの試験結果

## 受験経緯
[前回の試験](https://qiita.com/ozil/items/d0e64b89fda70ca882ef)に合格してから、忘れないうちにDVA（デベロッパー・アソシエイト）の試験も受験。

## 学習開始前の知識レベル
AWS SAAは取得済みの状態。
業務でも多少使う程度。

## 試験勉強
[ポケットスタディ AWS認定 デベロッパーアソシエイト](https://www.amazon.co.jp/%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%82%B9%E3%82%BF%E3%83%87%E3%82%A3-AWS%E8%AA%8D%E5%AE%9A-%E3%83%87%E3%83%99%E3%83%AD%E3%83%83%E3%83%91%E3%83%BC%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E8%A9%A6%E9%A8%93%E3%83%9D%E3%82%B1%E3%83%83%E3%83%88%E3%82%B9%E3%82%BF%E3%83%87%E3%82%A3-%E5%B1%B1%E4%B8%8B%E5%85%89%E6%B4%8B/dp/4798063401/ref=sr_1_12?adgrpid=117466963410&hvadid=655145537687&hvdev=c&hvqmt=b&hvtargid=kwd-363167283004&hydadcr=15815_13655231&jp-ad-ap=0&keywords=aws%E8%AA%8D%E5%AE%9A&qid=1683028818&s=books&sr=1-12)を用いて学習。
他のサイトでもこちらを勧めている人が多いので、迷った方はこちらの教材で問題ないと思う。
かなり分厚い教材だが、図が多く文字量が多くないため、それほど時間はかからない。
この教材を進めながら、[TechStock](https://techstock.jp/)の問題集を用いて学習を実施。
TechStockの難易度は実際の問題よりも簡単になっている。
ただし、こちらの問題集で9割とれるほどの知識がつけば、本番でも8割ほどとれると実感。

## 試験本番
AWS SAAを取得済みのため、新しい知識を覚えることも少なく、余裕をもって合格することが出来た。
個人的には、SAAの方が覚えることが多く、難しく感た。

試験の結果は860点。
今回も受験日の夜にスコアレポートをダウンロードでき、合否を確認できた。
Databricksでテーブルに頻繁にアクセスするクエリーやユーザーを参照する

[View frequent queries and users of a table \| Databricks on AWS](https://docs.databricks.com/data/table-insights.html) [2023/3/16時点]の翻訳です。

 :::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

Unity Catalogに登録されている全てのテーブルに対して最近頻繁に実行されているクエリーや頻繁にアクセスしているユーザーを参照するためにデータエクスプローラにおける洞察タブを活用することができます。

この情報は以下のような質問に答える助けとなります:

- このデータを信頼していいのか？
- このデータを活用する良い方法は何か？
- このデータに関する自分の疑問に答えてくれるユーザーは誰か？

:::note
**注意**
洞察タブに表示されるクエリーやユーザーはDatabricks SQLを用いて実行されたクエリーに限定されます。
:::

# 始める前に

洞察タブで頻繁に実行されているクエリーや頻繁にアクセスしているユーザーを参照するには以下の権限が必要です。

- 当該テーブルに対する`SELECT`権限。
- 当該テーブルの親スキーマに対する`USE SCHEMA`権限。
- 当該テーブルの親カタログに対する`USE CATALOG`権限。

メタストア管理者はデフォルトでこれらの権限を持っています。[Manage privileges in Unity Catalog](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/index.html)をご覧ください。

Databricks SQLでは:

- クエリーに対する`Can View`権限。参照権限がないクエリーを参照することはできません。[Query access control](https://docs.databricks.com/security/auth-authz/access-control/query-acl.html)をご覧ください。

# 洞察タブの参照

1. Databricksワークスペースでデータエクスプローラをオープンするために![](https://docs.databricks.com/_images/data-icon.png)**Data**をクリックします。
1. 洞察を参照したいテーブルを検索します。
    [Search for workspace assets](https://docs.databricks.com/search/index.html)や[Explore tables](https://docs.databricks.com/data/explore-tables.html)をご覧ください。
1. テーブルページで**洞察**タブをクリックします。
    過去30日間にテーブルに実行されたクエリーやアクセスしたユーザーが頻度順に表示されます。
![](https://docs.databricks.com/_images/insights-tab.png)

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
【UiPath】スニペットをつかってみよう！（環境設定編）

## 皆もすなるQiitaといふものを、儂もしてみむとてするなり。

と言う訳で、こん＊＊は！はなっち！です。

【初めに】
前回、

https://qiita.com/HANACCHI/items/400fb44f0b9a141d1fdd

を書きまして。自分なりに作った`スニペット用xaml`を **格納** し、それを使って、さくさく開発をしていたのでした。

所が、先日来のコミュニティエディションのバージョンアップのあと、いざ使おうと思った時、`スニペット`が **消えた** 事に気が付いたのです。

「まったく、近頃のアップデータは...」と一人怒っていたのですが...

今回は、`スニペット`の正しい使い方（ **環境設定** ）を書こうと思います。
- - - 
## １）どうやって、`スニペット`を設定していたのか（振り返り）
Studioの中のフォルダも、所詮はExplorerで扱えるフォルダだよね？だから`スニペット`ファイルが格納されているフォルダの注目すればいいのでは？って **浅知恵** が働く訳で...

1-1 `スニペットダブ`を開き、いずれかのフォルダを選択し、右クリックし、「開く」を選択します。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/984e975b-6ebc-4275-5a84-f02cdd244bfc.png">

1-2 開いた`スニペット`が格納されているフォルダに、`スニペット用xaml`や、独自に作成したフォルダに`スニペット用xaml`を **格納** しました。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/bd16d626-8163-944c-e33f-e8a8211e8770.png">

1-3 Studioの`スニペット`タブから見た目
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/a9471f23-be67-c300-a2c7-682be4d4b02c.png">

:::note alert
このやり方では、ダメなんです。
:::

## ２）本来の`スニペット`への設定
この数か月、頻出していたコミュニティエディションのバージョンアップを経て、改めて`スニペット`タブを開き、あれ、 **格納** したはずの`スニペット用xaml`がない。仲間内でも`最近スニペットが消えている事に気が付いて困っていたんです`って話もチラホラ。いろいろ会話をしていると、そもそもの **設定方法が間違っている** 事に気が付く訳で...

2-1 まず、UiPath所定の`スニペットフォルダ`以外の場所に、フォルダを作成し、そこに`スニペット用xaml`を **格納** します。例えば、UiPathフォルダ直下ですね。ここでは、UiPathフォルダ直下に`HANACCHI'S SNIPPETS`フォルダを作成しました。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/368f1401-e6a4-d789-4692-72429288c4f1.png">
[参考:UiPathのスニペットフォルダ]
`C:\Users\****\AppData\Local\Programs\UiPath\Studio\Snippets`

2-2 UiPath Studioを起動し、`スニペットタブ`を開き、タブの上部の左から４つ目のアイコン（`フォルダを追加`）をクリックします。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/66495d12-dc60-0efb-1ad4-c83e06f4e812.png">

2-3 表示された`スニペットに追加するフォルダーを選択`ダイアログで、2-1で作成したフォルダを選択し、UiPath Studioに **登録** します。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/9962ccf6-e1f1-2385-e916-699d59047131.png">

2-4 Studioの`スニペット`タブから見た目
一番したに、先ほど指定した`HANACCHI'S SNIPPETS`フォルダ、`スニペット用xaml`が見えます。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669015/18d8a6ad-02ec-b75f-03f4-51b882e7bb1a.png">

:::note info
これが正しいやり方
:::

## 〔参考〕
この方法で登録した情報は、UiPathのシステム設定ファイルに登録されます。

<details><summary>UiStudio.v2.settings</summary>

```ruby:UiStudio.v2.settings
      <UserLibraryFolders xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
        <d2p1:string>C:\Users\****\Documents\UiPath\HANACCHI'S SNIPPETS</d2p1:string>
      </UserLibraryFolders>
```
</details>



## 【まとめ】
・浅知恵でやってはいけないですね（ **反省** ）
・でも浅知恵から得る知識もあります（ **大切** ）
・`スニペット`は、やはり便利。いろいろと登録して、開発生産性をあげていきましょう！
・[ **MarketPlace** ](https://marketplace.uipath.com/)にも出品できますよ。


- - - 

##おわりに
いかがでした？

今回も読んでいただきありがとうございました！
是非UiPathでのロボ開発の一助になればと思っています。

ありがとうございました！
Windows TerminalでVim

Windows Terminalの導入
参考：[Windows ターミナルをインストールしてセットアップを開始する](https://learn.microsoft.com/ja-jp/windows/terminal/install)

~~~
winget search Vim
~~~
結果
~~~
名前                ID                          バージョン  一致       ソース
------------------------------------------------------------------------------
Vim Cheat Sheet     9WZDNCRDMCWR                Unknown                msstore
Vimar VIEW Pro      9NNG9QXL8W3Z                Unknown                msstore
Vim                 vim.vim                     9.0.1504               winget
qutebrowser         qutebrowser.qutebrowser     2.5.3       Tag: vim   winget
win-vind            pit-ray.win-vind            5.0.2       Tag: vim   winget
Neovim Nightly      Neovim.Neovim.Nightly       0.10.0      Tag: vim   winget
Neovim              Neovim.Neovim               0.9.0       Tag: vim   winget
Vieb                Jelmerro.Vieb               9.7.0       Tag: vim   winget
lf                  gokcehan.lf                 r29         Tag: vim   winget
Helix               Helix.Helix                 23.03       Tag: vim   winget
4K Video Downloader OpenMedia.4KVideoDownloader 4.24.1.5353 Tag: vimeo winget
~~~
インストール
~~~
winget install --id vim.vim --source winget
~~~
実行するが、PATHが通っていないのでエラー
~~~
vim : 用語 'vim' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認
してから、再試行してください。
発生場所 行:1 文字:1
+ vim
+ ~~~
    + CategoryInfo          : ObjectNotFound: (vim:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
~~~
解決する方法
1. PATHを通す（コマンドプロンプトでも利用可能）
1. エイリアスを設定する（PowerShellのみ）

+ PATHを通す
1. スタートアイコン上で右クリック
1. 「システム」を選択
1. 「関連設定」から「システムの詳細設定」を選択
1. 「環境変数」を選択
1.  「ユーザ環境変数」の「Path」にVimのインストールフォルダを追加（Pathがない場合は新規で追加する）

+ エイリアスを設定する
参考：[Set-Alias](https://learn.microsoft.com/ja-jp/PowerShell/module/microsoft.powershell.utility/set-alias?view=powershell-5.1)
~~~
set-alias vi 'C:\Program Files\Vim\vim90\vim.exe'
set-alias vim 'C:\Program Files\Vim\vim90\vim.exe'
~~~
再起動してしまうと、エイリアス設定が消えてしまうのでPowerShellプロファイルに記載する
（PowerShellプロファイルはPowerShellの開始時に実行されるスクリプト）
参考：[about_Profiles](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-7.3)
+ PowerShellプロファイルのパスを確認
~~~
$profile
~~~
+ PowerShellプロファイルの作成
参考：[about_Profiles](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_profiles?view=powershell-7.3)
~~~
New-Item -ItemType File -Path $PROFILE -Force
~~~
-Forceを指定することによって、フォルダがない場合にもフォルダを作成して、指定の場所にファイルを作成する。
参考：[New-Item](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.management/new-item?view=powershell-7.3)
+ PowerShellプロファイルを開き、エイリアス設定を追加
~~~
notepad $profile
~~~

これで、WindowsでVimが利用可能になる。
年齢認証なしでLINEアカウント共有アプリ🌾

年齢認証できないときはおすすめ

<p class="codepen" data-height="598" data-default-tab="result" data-slug-hash="zYmEWXr" data-user="04" style="height: 598px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/04/pen/zYmEWXr">
  Untitled</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

`リンクをコピー`を押してURLを入力してね
![Screenshot_20230502-204959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/6eecab2f-4ca9-7e80-e1a9-309062725ee2.png)


```vue
<!-- Use preprocessors via the lang attribute! e.g. <template lang="pug"> -->
<template>
  <div id="app">
    <h1>{{message}}</h1>

    <input type="url" v-model="url" placeholder="https://line.me/ti/p/********">
    <input type="text" v-model="id" placeholder="ID">
    <button @click="doSomething">共有する</button>
    <p v-if="id">このURLをお友達に教えてあげてね！</p>
    <a v-if="id" :href="'https://ine.deno.dev/' + id" target="_blank">https://ine.deno.dev/{{ id }}</a>
    <button v-if="id" @click="copy">コピー</button>
  </div>
</template>

<script>
function copyToClipboard(text){
  // テキストコピー用の一時要素を作成
  const pre = document.createElement('pre');

  // テキストを選択可能にしてテキストセット
  pre.style.webkitUserSelect = 'auto';
  pre.style.userSelect = 'auto';
  pre.textContent = text;

  // 要素を追加、選択してクリップボードにコピー
  document.body.appendChild(pre);
  document.getSelection().selectAllChildren(pre);
  const result = document.execCommand('copy');

  // 要素を削除
  document.body.removeChild(pre);

  return result;
}
  
export default {
  data() {
    return {
      message: '年齢認証なしでLINEアカウント共有！',
      url: '',
      id: ''
    };
  },
  methods: {
    doSomething() {
      if (!this.url) return
      if (!this.id) this.id = Math.random().toString(16).slice(-4)
      fetch('https://ine.deno.dev/' + this.id, {method: 'POST', body: this.url})
    },
    copy() {
      copyToClipboard('https://ine.deno.dev/' + this.id)
      Toastify({
        text: "コピーしました！"
      }).showToast();
    }
  }
};
</script>

<!-- Use preprocessors via the lang attribute! e.g. <style lang="scss"> -->
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
  display: flex;
  flex-direction: column;
  align-items: center;
}
  
  #app > * {
    margin: 8px;
  }

a,
button {
  color: #4fc08d;
}

button {
  background: none;
  border: solid 1px;
  border-radius: 2em;
  font: inherit;
  padding: 0.75em 2em;
}
</style>
```
HoloLensをインストールしていないのにConfig以下にHoloLens用のiniが生成されるのを防ぐ方法

# はじめに
(おそらく)UE5.0以降でプロジェクトを作成し、ビルドしてエディタを起動するとHoloLensをインストールしていないのにも関わらず`[Project]/Config/Hololens/`にHoloLens用のiniファイルが生成されていることがあります。
バージョン管理を使っているとコミットやサブミットをするたびにHoloLensのiniファイルを含めないように気を付ける必要があるため少し厄介です。

# 原因について
どうやらプロジェクト設定からHoloLensの設定を変更したりすれば修正できるタイプではなくエンジンの不具合のようです。

[Why is UE5.1 creating a HoloLens folder, even though I do not have HoloLens installed?](https://forums.unrealengine.com/t/why-is-ue5-1-creating-a-hololens-folder-even-though-i-do-not-have-hololens-installed/733228/9)

# 解決策について
`[EngineRoot]/Engine/Platforms/`以下にあるHololensフォルダを削除することで、HoloLens用のiniファイルが生成されることを防げます。
もしHoloLensの開発をする必要出てきたら、GithubのUnrealEngineのリポジトリから上記のフォルダだけコピーしてくるかEpic Game LauncherからインストールされているエンジンをVerify(認証する)でも対応可能かと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325493/c13a064a-6f30-5f22-9918-9076d29aac2a.png)

## 追記
こちらの対処法を行うとUATなどからビルドする際に`AutomationTool`で`HoloLens.Automation.dll`が見つからず失敗するため、普段はPlatformフォルダ以下を圧縮しておき、`AutomationTool`を使う際は元に戻せるようにしておくと楽かと思います。

# おわりに
そこまで害があることでもないため放置してしまいそうなものですが、この記事をみてそういえば気になっていたという方は簡単に修正できるの是非試して見てください。
Rspecでモデルテストを書く

Rspec初心者の備忘録の記事です。
Rspecでテストを書くためのセットアップや、基本となるモデルのバリデーションテストを記述していきます。

# Rspecのインストール

```.Gemfile
group :development, :test do
# 省略
gem 'rspec-rails' end
```

```
$ bundle install
```

```config/database.yml
test:
<<: *default
database: happylunch_test
```

もしテストデータベースをまだ作っていないなら、下記を実行しましょう。すでに作成 済みなら、rails タスクはテストデータベースがすでにあることを教えてくれます。既存のデータベースを間違って消してしまう心配はありません。
```
$ rails db:create:all
This task only modifies local databases. happylunch_development is on a remote host.
This task only modifies local databases. happylunch_test is on a remote host.
This task only modifies local databases. happylunch_production is on a remote host.
```


では RSpec 自体の設定に進みます。

次のようなコマンドを使って RSpec をインストールしましょう。


```
$ rails generate rspec:install
Running via Spring preloader in process 325
      create  .rspec
       exist  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
```

次に、必須ではありませんが、RSpec の出力をデフォルトの形式から読みやすいドキ ュメント形式に変更します。これによってテストスイートの実行中にどのスペッ クがパスし、どのスペックが失敗したのかがわかりやすくなります。先ほど作成された .rspec ファイルを開き、以下のように変更します。


```.rspec
--require spec_helper
--format documentation
```

```config/application.rb
# 省略

module Projects
class Application < Rails::Application
    config.load_defaults 7.0

    config.generators do |g| 
      g.test_framework :rspec,
        fixtures: false, 
        view_specs: false, 
        helper_specs: false, 
        routing_specs: false
        g.factory_bot false
    end
  end 
end
```
```g.factory_bot false```はFactory Bot のジェネレータを一時的に無効化 するためです。

# モデルスペック
最初 のモデルスペックを作成するため、この作業の出発地点となるファイルを実際に生成します。
まず、```rspec:model``` ジェネレータをコマンドラインから実行します。

するとP```user_spec.rb```ファイルが作成されるので、まずは基本となるバリデーションテストを書いてみます。

```
$ rails g rspec:model user
```

```user_spec.rb
require 'rails_helper'

RSpec.describe User, type: :model do
  # 名前、メール、パスワードがあれば有効であること
  it "is valid with a name, email, and password" do
    user = User.new(
      name:  "Ace",
      email:      "tester@example.com",
      password:   "dottle-nouveau-pavilion-tights-furze",
    )
    expect(user).to be_valid
  end
  # 名前がなければ無効であること
  it "is invalid without a name" do
    @user = User.new(name: nil)
    expect(@user.valid?).to eq(false)
  end
  # メールアドレスがなければ無効であること
  it "is invalid without an email address" do
    @user = User.new(email: nil)
    expect(@user.valid?).to eq(false)
  end
  # 重複したメールアドレスなら無効であること
  it "is invalid with a duplicate email address" do
    User.create(
      name: "John",
      email:      "test@example.com",
      password:   "i-am-john"
    )
    @user = User.new( 
      name: "Peter", 
      email:      "test@example.com",
      password:   "i-am-peter"
    ) 
    @user.valid?
    expect(@user.valid?).to eq(false)
  end
end
```

```
$ bundle exec rspec
```

テストがパスします。

以降のモデルテストやコントローラテストはまた次の記事で書きます！



参考：
Everyday Rails - RSpecによるRailsテスト入門

https://qiita.com/jnchito/items/42193d066bd61c740612