OmniAICreator/Qiita-1.07M huggingface dataset:
windowsでiverilog その130

# 概要
　
windowsでiverilogやってみた。
verilog見つけたので、テストベンチ書いてみた。

# 参考にしたページ

https://qiita.com/takeru0x5569/items/ed12c3b097d0f8ff6ac9

# サンプルコード

```
module test;
	reg i_clk,
		i_rst_n,
		i_SPI_CLK,
		i_SPI_CS_n,
		i_SPI_MOSI;
	wire [31:0] o_data;
	wire o_valid;
	SPI_RECEIVER_32BIT u(.i_clk(i_clk), .i_rst_n(i_rst_n), .i_SPI_CLK(i_SPI_CLK), .i_SPI_CS_n(i_SPI_CS_n), .i_SPI_MOSI(i_SPI_MOSI), .o_data(o_data), .o_valid(o_valid));
	initial
	begin
		$display("mo   o_d   o_v");
		$monitor("%h %h %h", i_SPI_MOSI, o_data, o_valid);
		i_clk = 1;
		i_rst_n = 1;
		i_SPI_CLK = 1;
		i_SPI_CS_n = 1;
		i_SPI_MOSI = 0;
	#5
		i_rst_n = 0;
	#8
		i_rst_n = 1;
		i_SPI_CS_n = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_MOSI = 1;
	#5
		i_SPI_MOSI = 0;
	#5
		i_SPI_CS_n = 1;
	#5
		i_SPI_CS_n = 0;
	#5
		$finish;
	end
	always
	begin
		#2
			i_clk = ~i_clk;
		#2
			i_clk = ~i_clk;
			i_SPI_CLK = ~i_SPI_CLK;
	end
	initial
	begin
		$dumpfile("test.vcd");
		$dumpvars(0, test);
	end
endmodule







```

# 実行結果

```
>iverilog spi12.v

>vvp a.out
mo   o_d   o_v
VCD info: dumpfile test.vcd opened for output.
0 xxxxxxxx 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
1 00000000 0
0 00000000 0
0 739ce739 1
0 739ce739 0



```


以上。
ビッグエンディアン、リトルエンディアン、BOMについてまとめる


### はじめに
業務で実際にBOMに触れるまでエンディアンについて全く意識していなかったので、、、
今回、エンディアンについての記事を投稿しようと思いました。

### エンディアンって何？
エンディアンとは**2バイト以上のデータのメモリの格納方式**を意味する。
バイトオーダーなんて呼び方もある。

PCは基本的に0と1の2進数でデータを管理している。
`01001001`
例として、ここに0と1だけで構成された8桁の数字があるとする。
1桁を1ビットという単位で扱っていて、8ビットを1バイトとして扱う。

そして、メモリは1バイト単位でデータを取り扱っており、
2バイトのデータを格納する時には2つのメモリにデータを格納する必要がある。

2バイトのデータ: `0x1278`
メモリ番地が1000番目、1001番目にある時にデータをどの様に格納していくのか？

`1000番目→0x12`
`1001番目→0x78`

先頭のデータからメモリに格納していくというのが一般的な感覚になると思います。
これを**ビッグエンディアン**と呼びます。

**リトルエンディアン**とはこの逆であり、下位のビットのデータからメモリに格納されていく方式になります。
`1000番目→0x78`
`1001番目→0x12`

エンディアンの形式は使うCPUによって異なってくる。

### BOMって何？

**BOM**とは**Byte Order Mark**の略です。

#### BOMはUnicodeで符号化したテキストの先頭に定義される数バイトのデータです。

**Unicode**には**UTF-8**や**UTF-16**など様々な符号化形式が存在しており、
このBOMを使ってUnicodeの符号化形式を判別している。

また、Unicodeではビッグエンディアン、リトルエンディアンのどちらの形式も許容している。
どちらの形式も許容しているので、ビッグエンディアンかリトルエンディアンのどちらかを判断する際にもBOMが使われている。

基本的にBOMは必須という訳ではないので、何でもBOMを付与すればいいという訳ではない。

ただ、MicrosoftのExcelではUTF-8のデータを使う時にBOMを使わないと、
文字コードがUTF-8だと認識されずに文字化けをすることがある。

場合によってはBOMを付与する処理がプログラムの中に必要になってくる。
逆にBOMが付与されているファイルの処理を想定していない場合はBOMを取り除く処理が必要になってくる。

### この記事のまとめ

**ビッグエンディアン、リトルエンディアンとはメモリにデータを格納する時の格納形式。**
**BOMはUnicodeで符号化したテキストの先頭に定義される数バイトのデータ。**
Dockerを始めよう!




`docker run it ubuntu bash` Ubuntuのコンテナを作る時にbashを実行する
`ubuntu`イメージ、デェフォルとコマンドを上書きしている
`-it` bashを開いた状態をキープする
`bash`実行するプログラム　

`docker run`ホストにUbuntuイメージがなければdockerhubから`pull`してくれる。
`docker run it ubuntu bash` 実行後すぐにbashが起動されていて、ubuntuに命令`pwd` `ls`できる。

~~`Docker image`イメージは複数のイメージレイヤーで構成されている~~

- docker run を詳しく見ていく
`docker run <image>` = `docker create <image>` + `docker start <container id>`
`docker create <image>` ：コンテナの状態は`Created`
`docker start` ：コンテナの状態は`Up`、デフォルトのコマンドが実行される。


<details><summary>docker ps -a　は何が確認できるのか</summary>

container id
image
status
デフォルトのコマンド
</details>

- `-it`は何をしているのか
- コンテナ削除
(`docker ps -a`：コンテナを確認）
`docker rm <contianer>`：状態が`UP`のものは削除できない、その場合`docker stop <contianer>`
`docker stop <contianer>`：`UP`から`Exited`状態にする
`docker system prune`：`Exited`状態のコンテナ全削除

- コンテナに名前を付ける
`docker run --name <name> ubuntu`
名前に付けないとDockerが適当に名前を付ける。
起動させ続けるコンテナを立てる時に。
共有サーバを使う時に。
他のプログラムから呼び出す時に。


`docker exec -it <container> bash` <container>に対して、bashというプログラムを実行する、コンテナに入って、bashでOSに命令を出したい。

`-it` bash起動時のおまじない
`bash`実行するプログラム　

`exit` 作業が終わったら、コンテナから出る。
【Salesforce】【資格】Salesforce 認定 Marketing Cloud アドミニストレーター 合格までのあれこれ

当記事は受験体験記です。
※2023年2月（Spring ’23）時点の情報です。
※あくまでもぴえさん個人の考えです。

# Salesforce 認定 Marketing Cloud アドミニストレーター とは　（ざっくり）
・Marketing Cloud 管理者向けの資格、基本的な設定や操作について出題
・受験資格：なし
・受験料：税込22,000円
・105分60問（合格基準は67％以上）
・選択式　**※選択肢3つの単一選択！！**
・試験終了後、即座に合否がわかる

# ぴえさんの受験記録
【受験日程とバージョン】
日時：2023/2/22
受験方法：オンサイト受験
バージョン：Spring ’23

【受験データ】
ウェブアセッサーのスクショ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/bc25dfdc-3084-df12-3132-0aeed2edcda0.png)

分かりにくいので表にしました↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/173061f0-fac0-3710-115f-ea3743270ec2.png)

【感想】
・2022年11月のウェビナーでもらった70%OFFクーポンが2月末期限のため受験しました。
・いつものオンサイト試験でした。会場の方に「この前も来てましたよね？」って言われました。
　→　4日前に [ServiceCloudコンサル](https://qiita.com/piepie1231/items/7a415b97f1a98caf6f21) もクーポンで受けました。
・業務経験なしかつDEもないので全部イメージで覚えてました。まじ意味わからん。
・勉強時間も取れない上に、最初読んでた過去問がMarketing Cloud **コンサル**のでした(´;ω;｀)
・ぎりぎり受かったけど短期記憶だけでただ取っただけになりました、こういうの嫌だなぁ。

# 勉強方法

**※今回は過去一最悪な勉強方法です、おすすめしません。**

JPN試験の4つを繰り返し解く。のみ。
重複があるので実質100問くらいかと思います。

https://www.jpnshiken.com/shiken/Salesforce.Marketing-Cloud-Administrator-JPN.v2023-01-03.q55.html

https://www.jpnshiken.com/shiken/Salesforce.Marketing-Cloud-Administrator-JPN.v2022-02-03.q55.html

https://www.jpnshiken.com/shiken/Salesforce.Marketing-Cloud-Administrator-JPN.v2021-04-21.q37.html

https://www.jpnshiken.com/shiken/Salesforce.Marketing-Cloud-Administrator-JPN.v2020-10-13.q33.html

実際の試験を受けたときにはじめて知ったのですが、すべて選択肢3つの単一選択の出題でした。
英語表記・日本語表記も実際とはちぐはぐでとにかく過去問通りとはいかなかったですが
出題の難易度自体は低いのかなと思いました。

Marketing Cloud アドミニストレーター、日本語の過去問や模擬問題がヒットしなさすぎる。。
最近はよくお世話になっているSalesforce認定試験ハックさんもSalesforce過去問+模擬問題の解説（note）さんも
問題出してなかったので泣く泣く、、
でもまあ数年前まで普通のアドミンもほとんどなかったよね！

Salesforceの他資格についてはこちらの記事にまとめています↓

https://qiita.com/piepie1231/items/78a0dd6bdfa2c64568cd
【Salesforce】【資格】Salesforce 認定 Service Cloud コンサルタント 合格までのあれこれ

当記事は受験体験記です。
※2023年2月（Spring ’23）時点の情報です。
※あくまでもぴえさん個人の考えです。

# Salesforce 認定 Service Cloud コンサルタント とは　（ざっくり）
・コンサルタント向け資格？
・受験資格：Salesforce 認定アドミニストレーター資格
・おもにService Cloudについて出題
・受験料：税込22,000円
・105分60問（合格基準は67％以上）
・選択式
・試験終了後、即座に合否がわかる

# ぴえさんの受験記録
【受験日程とバージョン】
日時：2023/2/18
受験方法：オンサイト受験
バージョン：Spring ’23

【受験データ】
ウェブアセッサーのスクショ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/33d31d19-9a3c-e9d3-d6e1-3c89117e91e4.png)

分かりにくいので表にしました↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461666/1d23be65-dcd1-a7c2-0b33-7b20014c8e28.png)



【感想】
・2022年11月のウェビナーでもらった70%OFFクーポンが2月末期限のため受験しました。
　→　4日後に[MarketingCloudアドミン](https://qiita.com/piepie1231/items/f4f1a7b09f494c97da07) も同じクーポンで受けました。
・例のごとくオンサイト試験でした。
・ServiceCloud自体は導入経験があるので、多少アドバンテージがありました。
・土曜日午前が試験だったので、木金の夜に勉強しました。
・勉強時間が取れない分、過去問は選別しました。そのまま出た問題も多くラッキーでした。


# 勉強方法

１．受験ガイドを読む
　　　[資格一覧ページ](https://tandc.salesforce.com/credentials)から取得できます。模擬問題で試験の雰囲気をつかみます。
２．無料ウェビナー（できるだけ新しめ）を受ける
　　　[Salesforce資格の無料ウェビナー開催情報](https://www.salesforce.com/jp/campaign/trailhead-academy/certification-days/)で確認できます。
３．個人が出している練習問題や過去問を解く
　　今回はSalesforce認定試験ハックさんの30問とSalesforce過去問+模擬問題の解説（note）さんの120問を解きました。

https://salesforce-certification-hack.com/?cat=15

https://note.com/salesforce777/m/md84aca57a394

https://note.com/salesforce777/m/m87bd18308e6d

４．２～３で分からない単語や疑問点を、ヘルプを読んで確実に解消する

https://help.salesforce.com/s/articleView?id=sf.service_cloud.htm&type=5

# 覚えてる限りで出題に出た内容
下記は確実に抑えたほうが良い単語かと思います！
・メールtoケース(3題出た、オンデマンドの違いは確実に抑えること）
・SLAとエンタイトルメントについて
・ソフトフォンの使用、CTIアダプタ
・openCTIとは？
・顧客ロイヤルティ
・オムニスーパーバイザー
・ケースチーム


また70％OFFクーポン出してくれないかな～ 
Salesforceの他資格についてはこちらの記事にまとめています↓

https://qiita.com/piepie1231/items/78a0dd6bdfa2c64568cd
SQLの実行計画確認方法（製品別）

# Oracle

## 実行計画を取得するためのSQL文を実行します。

```sql
EXPLAIN PLAN FOR [クエリ文];
```

## 取得した実行計画を表示します。

```sql
SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);
```

# MySQL、postgreSQL、Amazon Aurora、MariaDB

## 実行計画を取得し表示します。

```sql
EXPLAIN [クエリ文];
```


# Microsoft SQL Server

## SQLを実行しながら実行計画を表示する

```sql
SET STATISTICS XML ON;
[クエリ文];
SET STATISTICS XML OFF;
```
LaravelでS3に画像を保存して表示するときにはまった話

# 概要
LaravelでS3に画像を保存してviewに表示するときに表示されなかったのでメモ
(初投稿です。よしなに)

# この記事の対象者
S3に画像を保存することは出来たけどviewに表示されなくて困っている人

# 前提
- S3バケットを設定していること
- LaravelでS3への画像投稿機能を実装していること

# 方法
## ブロックパブリックアクセス(バケット設定)を編集する
1. S3のコンソール画面を開いて、アクセス許可タブから、ブロックパブリックアクセス (バケット設定)の編集ボタンを押します。
2. 設定項目を全てオフにしてパブリックアクセスが可能な状態にしておく
![スクリーンショット 2023-01-09 15.41.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2871384/adf15c6d-922e-db22-a110-e80cd2ac9606.png)

## バケットポリシーを編集する
1. 同じくアクセス許可タブから少しスクロールしたところにバケットポリシーという項目があるので編集ボタンを押します。
1. ポリシーを以下のように編集します。
```json
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Sid": "PublicRead",
			"Effect": "Allow",
			"Principal": "*",
			"Action": [
				"s3:GetObject",
				"s3:GetObjectVersion"
			],
			"Resource": "arn:aws:s3:::バケット名/*"
		}
	]
}
```
- オブジェクトを取得できるようにする。
```json
"Action": [
				"s3:GetObject",
				"s3:GetObjectVersion"
			],
```
-  `/*`とすることで全てのオブジェクトにアクセスすることができる。
```json
"Resource": "arn:aws:s3:::バケット名/*"
```

# 結論
`/*`を指定していなかったため、全てのオブジェクトにアクセス出来なかったみたいです！
PHP：PHPUnit：MacのDockerでComposer経由でインストールし、テスト実行まで

他のパッケージと少し要領が違うからか、composer.jsonやXMLファイルの設定が変だった。

# インストール

これは簡単。公式サイトでComposerでのインストール方法をチェックし、コマンドラインでのインストールが紹介されていたので以下でインストール（もちろん手動でもできるが）。
compser.jsonやcomposer.lock の中身も自動で追記適用される。

https://docs.phpunit.de/en/10.0/installation.html#composer

```warp
composer require --dev phpunit/phpunit
```

# ディレクトリ構造の整備

実行するアプリケーションのコードのファイルとテストのコードのファイルは、
(1) ファイルを分ける
(2) ディレクトリを分ける
これをすべき。
本番コードとテストコードが混在すると間違って繋がりやすい。

アプリケーションコードのディレクトリ・・・　lib、app、sourceなどが多い。今回は lib とする。
テストコードのディレクトリ・・・　tests で良いだろう。

lib ディレクトリにアプリケーションコードのphpファイル（Main.phpとする）を作成・設置。
tests ディレクトリにテストコードのphpファイル（MainTest.phpとする）を作成・設置。
※どちらのファイル名も頭大文字なのは、テストコードに登場するClass名と合わせたいから。
　ただ、phpファイル名を頭大文字に普通しないので所属会社の方針によるだろうが。


# テストコードの書き方（専用の書き方があり）

公式
https://docs.phpunit.de/en/10.0/writing-tests-for-phpunit.html

```php
<?php

// TestCaseというClassを使わねばならない。
use PHPUnit\Framework\TestCase;

// テストのためのClass。テストケースクラス。「MainTest」は任意のClass名で、これを一応phpファイル名と一致させている。「TestCase」は決められていて、それを継承している。
class MainTest extends TestCase {
    // 当然、メソッド名はtest何々としておく
    public function testAmount() {
        // このテストするアプリケーションコードファイルはこのClassの外に記載している例もあり、どちらがベストなのか不明
        require_once(__DIR__ . '/../lib/Math.php');
        // assertSameは同じかどうかを比較する機能をもつ
        $this->assertSame(11000, amount(10000));
    }
}

```


# コマンド

最初にautoload.phpを読み込む必要がある。このファイルのおかげでtestCaseクラスが使えるようになる。マッピング関連。


```warp
./vendor/bin/phpunit tests --bootstrap vendor/autoload.php
```

OK (1 test, 1 assertion)
と表示されれば成功。テストは通った。

phpUnitのコマンドラインランナーは、これによってまず現在の作業ディレクトリにあるソースファイル　を探して読み込み、mainTest というテストケースクラス名を探す。
見つけたらクラス内のテストを実行する。


# テストの自動化

## XMLファイルの作成（Composer経由だと自動的に生成されたはずだが）

公式サイトでXML設定ファイルの紹介ページがあるので確認。
https://docs.phpunit.de/en/10.0/configuration.html

ただ、上記のPHPUnitのインストールで、XMLファイルは自動的に生成されていた。
そして、生成されたXMLファイルを加工してその後でテストを実行すると、加工が許されないメッセージが出るため加工ができない。

ちなみに、「<directory>tests</directory>」の欄で「tests」ディレクトリをチェックする指定をできている。自動生成時にここは指定できたのだろうが記憶にない。

```xml
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" bootstrap="vendor/autoload.php" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd" cacheDirectory=".phpunit.cache">
  <testsuites>
    <testsuite name="Tests">
      <directory>tests</directory>
    </testsuite>
  </testsuites>
</phpunit>

```

XMLファイルが正常に動作するか？を以下のコマンドでチェックしておく。
※注意点：　コマンドは正常なのに、なぜかエラーになる時があり、意味不明。
　まぁ、正常に使えるときが多いからまだ良い。

```warp
./vendor/bin/phpunit
```

## composer.json の追記

scripts欄にコードを追記する。
 ```json
"phpunit": "./vendor/bin/phpunit"
```

これで短縮完了したので、あとは短縮できたコマンドを走らせてテストを実施する

```warp
composer phpunit
```
【Wordpress】BackWPupを使って静的データ・動的データのバックアップを行うべし！

# Wordpressバックアップについて
* `style.css`など重要なデータを編集する場合は、バックアップをとっておくことをお勧めします。何かあった時に戻れないと大変です。Wordpressは静的データ・動的データがありますが、どちらも保存できる方法が好ましいです。
* バックアップファイルは、不正アクセスや不具合トラブルの時にも有効活用できます。
* バックアップを取る方法は色々ありますが、下記プラグインは実施方法もカバー範囲もお勧めです。

# BackWPup
* [BackWPup – WordPress Backup Plugin - プラグイン](https://ja.wordpress.org/plugins/backwpup/)
    *  データベース、ファイル、インストール済みプラグイン一覧などのバックアップが可能です
    *  定期的(自動)or手動でバックアップが簡単に取れるのが嬉しいですね。自動バックアップを取る場合は、`WordPressのcron`を選択します。
        *  cron（クーロン）とは、スケジュール通りに設定プランを実行する機能のこと
    *  定期的なバックアップの場合、あまり頻繁すぎるとサーバーの容量が重くなるので、ご自身の更新頻度に合わせて少なくするか、「フォルダー内に保持するファイルの数」を下げるか、対応すると良いでしょう。
    *  ジョブを使って、バックアップ方法を任意で設定・取得することができます。
    *  バックアップの実行時間はデフォルトでは午前3時になっていますが、他サービスや他のユーザーも同時刻で設定しておりサーバー負荷が高まる可能性があるので少し時間帯ずらした方が良いそうです。
    * 参考：[BackWPUpで確実にWordPressのバックアップを取る方法](https://lucy.ne.jp/bazubu/how-to-use-backwpup-3-23804.html)
* 保存先は「フォルダー」を選択するとデフォルトでは以下になるようです。メールやS3とも連携できますのでお好みで変えることも可能です。Wordpressから独立させておくという観点では、S3やDropboxの方が良いかもしれません。

```
/var/www/html/xxxxxxx/wp-content/uploads/
```

* 念の為：プラグインの導入については、WordPressやPHPのバージョン、テーマやプラグインの相性などの観点において、不具合が生じる可能性があるので、自己責任でお願いします。
AIエンジニアにおすすめのYoutubeチャンネル

AIエンジニアとして勉強する際に参考にさせて頂いているYouTubeチャンネルについて記載します。

# 深層学習系
- [AIcia Solid Project](https://www.youtube.com/@AIcia_Solid)
深層学習関連の技術や数学について、嚙み砕いて解説してくれます。
- [Neural Network Console](https://www.youtube.com/@NeuralNetworkConsole)
深層学習関連の技術について、入門レベルから解説してくれます。

# 数学系
- [3Blue1BrownJapan](https://www.youtube.com/@3Blue1BrownJapan)
数学の話題について、直観的に分かるシミュレーションを駆使して解説してくれます。
【 AWS 】RDSとは?

## はじめに
こちらの記事は、AWS-CLF取得にむけての自身のメモ、アウトプット記事となります。

## RDSとは?
RDSとは**Amazon Relational Detabase Service**の略称である。
RDSはリレーショナル型データベースであり、行と列の2軸を表形式で管理するデータベースのことを指す。

データベースは、特定の条件に基づいて複数のデータを管理し、必要に応じて目的のデータ検索・編集を行うために必須である。


## RDBMSとは?
RDBMSとは**Relatinal Detabase Management System**の略称である。

コンピュータ上で、リレーショナルデータベースを構築する際には、
リレーショナルデータベースを管理するためのソフトウェアを使う必要性がある。


## AWS RDSで利用できるRDBMS

①**Amazon Aurora**
→MySQL/PostgreSQL互換のクラウドに最適化されたリレーショナルデータベース

②**MySQL**
→オープンソース型のリレーショナルデータベース
シンプルなデータベースでの利用に向いている

③**PostgreSQL**
→オープンソース型のリレーショナルデータベース
多機能なため、大量のデータを処理するWebシステムのバックエンド処理などに向いている

④**MariaDB**
→MySQLを基に作られたデータベース
MySQLの互換性が高いため、今後シェアが拡大する可能性が高い

⑤**Oracle**
→世界で最初に採用されたRDBMS
データベースにおける信頼が高いため、大手企業などを中心に利用されている

⑥**Microsoft SQL Server**
→Windowsとの相性が良い


## RDSのメリット
①**インフラ管理はAWSが行うため、開発に注力ができる**

②**RDSインスタンス作成時にバックアップ設定が行われる為、サードパーティの用意が必要ない**

③**マルチAZ配置設定を行うことで、レプリケーション・フェイルオーバーが自動的に行われるため、SPOFとならない設計、高可用性を実現**

④**整合性や複雑なクエリの処理に強い**
【結局一緒？】複数行テキストとテキスト領域【PowerApps】

・複数行テキスト（Multiple Line）
・テキスト領域（Text Area）

結局何が違うんやって話。
↓詳細項目を作って両パターンを入力仕分けてみた写真

![Screenshot 2023-02-23 17.53.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524942/d201a888-e90b-5536-32ea-914485d0aca9.png)

## 結論
・入力できる文字数が違う
・複数行テキストのほうがたくさん入力できる
・複数行テキストは後々ペン入力にも変更できる

## 最大文字数
複数行テキスト：1,048,576（デフォルトは2000）
テキスト領域：4000（デフォルトは100）

## ペン入力
サインなどを求められるときに使える機能で、フォームのカスタマイズ画面から切り替えることができます。

## リッチテキストエディター
より凝った文章を作りたいときに使えます。
・太字
・フォント
・文字の大きさ
・下線
・テーブル
・カラー etc...
これもどちらもあとから切り替えられます。ご心配なく。
フォームのカスタマイズ＞コンポーネント＞コントロール

## どう使い分ける？
基本的には入力文字数で使い分けるのがいいと思います。
日報など簡単なものであれば4000は超えないと思いますし、調べ物を貼り付けたりたくさんのURLを必要とする場合は複数行テキストがいいと思われます。（URLはURL型の列を作るのが最適ですが…）

強いて言うならそこまで長い文章が必要でないのであれば入力文字数制限は少なければ少ないほうがデータ容量をキープできると思います。
ダラダラと長い文章で読みづらいアプリを作るのはナンセンスですから。

## まとめ
・ほぼ一緒
・文字数が多そうなときは一旦複数行テキストで保持


## 個人的感想
昔の名残なんだろうけどどっちかに統一でええやん。
PowerAutoamteの方で挙動が違った気がするのでそのへんは要検証。
HTML1つだけでVue3とVuetify3が試せるテンプレート(2023年2月23日動作)

## すぐつかえます

サクッと試したいのに、ソフトウェアの進歩が速くて、検索してもエラーだったり動かなかったり。

次の記事がシンプルで良かったのですが、Vue2+Vuetify2 なので、Vue3 + Vuetify3 に書き換えました。**著者様に感謝。**

https://qiita.com/10size/items/21fc5b0c3af22fbeb7c5

## テンプレート(HTML)

```html
<!DOCTYPE html>
<html>
  <head>
    <link
      href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900"
      rel="stylesheet"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css"
      rel="stylesheet"
    />
    <link
      href="https://cdn.jsdelivr.net/npm/vuetify@3.1.5/dist/vuetify.min.css"
      rel="stylesheet"
    />
  </head>

  <body>
    <div id="app">
      <!-- ここから -->

      <v-app>
        <v-system-bar app> Single HTML Template </v-system-bar>

        <v-navigation-drawer app>
          <v-sheet> Hello! </v-sheet>

          <v-divider></v-divider>

          <v-sheet> Left Bar </v-sheet>
        </v-navigation-drawer>

        <v-main>
          <v-toolbar></v-toolbar>

          <v-container fluid>
            <h1 class="display-3">GYU-DON</h1>

            <div class="display-1">message:{{message}}</div>
            <div class="display-1">chip1:{{chip1}}</div>

            <v-chip
              closable
              v-if="chip1"
              @click:close="onClose"
              @click="onChipClick"
            >
              <v-avatar>
                <img
                  src="https://randomuser.me/api/portraits/men/35.jpg"
                  alt="trevor"
                />
              </v-avatar>
              GYUDON MAN
            </v-chip>
          </v-container>
        </v-main>

        <v-footer app>hoge</v-footer>
      </v-app>

      <!-- ここまで！ -->
    </div>

    <script src="https://unpkg.com/vue@next"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@3.1.5/dist/vuetify.min.js"></script>
    <script>
      const { createApp, ref } = Vue;

      const App = {
        setup(props, context) {
          const message = ref("this is a pen.");
          const chip1 = ref(true);

          const onChipClick = () => {
            message.value = "Magica Norica!";
          };

          const onClose = () => {
            chip1.value = false;
            message.value = "good night!";
          };

          return { message, chip1, onChipClick, onClose };
        },
      };

      const app = createApp(App);
      app.use(Vuetify.createVuetify());
      app.mount("#app");
    </script>
  </body>
</html>
```

## 参考

https://qiita.com/10size/items/21fc5b0c3af22fbeb7c5
【Pandas】DataFrameの特定の列の値を使って計算を行う方法

# はじめに
PandasのDataFrameを使っていて、特定の列の値を使って計算を行い
新たに列方向に項目を追加し、ここに計算した値を設定する方法まとめた

データは下記のものを扱う

https://qiita.com/wooooo/items/a0751b83cb71c3911827

# やること
seasonConceded_home:ホーム失点数(h)
seasonConceded_away：アウェイ失点数(a)
lostPoint:総失点数(p)
（項目名は括弧書きの文字列で表記しています）
```python
print(df)
  a  h
0 11 12
1 12 10
2 27 12
```

上記のようなデータがある場合、このようにp列を追加し、hとa列の合計値を設定する
```python
print(df)
  a  h  p
0 11 12 23
1 12 10 22
2 27 12 39
```

# コード
```python
import pandas as pd

# dfに必要なデータが入っている
df['lostPoint'] = df['seasonConceded_away'] + df['seasonConceded_home']
```
右辺でDataFrameから列の値をそれぞれ取り出し、加算の処理を行う
加算した値を新たな列名を宣言し、ここに格納する


# 備考
サンプルAPIのレスポンスパラメータを見ると
"seasonConceded_away"と"seasonConceded_home"の合計した値が
"seasonConceded"と異なっているので計算してDataFrameに入れ直すハメになりました
計算方法をググって理解して、記事にしました。
Shift+Fn+Insertでペースト出来なかったので、Change Keyから無変換をInsertにすると解決した【HP Pavilion Aero 13-be】

検索しても全然情報なかった。。。
同じ悩み持つ人に届け！！
## 経緯
+ 製品: HP Pavilion Aero 13-be
+ OS: Windows11
+ **BIOSのAction Keys ModeはDisableが良い**
(ファンクションキーはなんだかんだ使うので、いちいちFn押すのはストレス)
+ InsertキーはF12にある。Fn+Insertでインサートモードにすることは可能
+ **しかし、Shift+Fn+Insertではペーストできない**
(Shift+FnはFn押下扱いにならないようで、F12が実行されてしまう)
+ Git BashなどCtrl+Vできないとき不便、右クリック貼付は嫌だ

## Change Keyで無変換→Insertに置き換える
Change Keyをインストール。
[「Change Key」非常駐型でフリーのキー配置変更ソフト - 窓の杜](https://forest.watch.impress.co.jp/library/software/changekey/ "「Change Key」非常駐型でフリーのキー配置変更ソフト - 窓の杜")

.LZHの解凍ソフト持ってなかったので、7-Zipをインストール。
64ビット x64
[圧縮・解凍ソフト 7-Zip](https://sevenzip.osdn.jp/ "圧縮・解凍ソフト 7-Zip")


解凍方法は
ChgKey15.LZHを右クリック→その他のオプションを表示→7-Zip→展開…→OK

ChgKey15\ChgKey.exeを**管理者権限**で実行
※普通に開くと以下の表示になるが、**カレントユーザー権限だとキーの変更が適用されなかった。**
　Windowsのユーザ分けてない人は出ないかも
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919799/77f31760-673d-303b-7998-a7a8500caf10.png)

変更方法は
無変換キーをクリック→Insertキーをクリック→[登録]>[現在の設定内容で登録します]をクリック→再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919799/d445849f-0d15-2674-d5c8-96c24a82b51a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919799/366a8422-44eb-9250-794c-4078c50e6e42.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919799/42617bfa-3925-e3e0-3c69-4d9ed3524267.png)

## 結果
Shift+無変換で貼付できるようになりました。
片手でできるのでむしろF12のInsert使うより良いかもしれない。Insertモードには注意！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1919799/ca0bd7c6-4c6d-d202-af74-0669377b8f2d.png)
MySQLインデックスの基本

## 概要

MySQLのインデックスは、データベース内のテーブルにおいて、特定の列を高速に検索するために使用されます。
インデックスを使用することで、テーブル内のレコードの検索速度が向上します。

逆にインデックスがないとMySQLは関連するレコードを見つけるために、先頭行から始めてテーブル全件読み取ることになりレコード数によっては実行速度がかなり遅くなります。(**フルテーブルスキャン**)

## 構文

例として、以下のようなユーザーテーブルを考えてみます。

```sql

CREATE TABLE users (
  id INT(11) NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL,
  age INT(11) NOT NULL,
  PRIMARY KEY (id)
);
```

このテーブルには、ユーザーのID、名前、メールアドレス、年齢が含まれています。ここで、例えば、ユーザーの名前を使って検索する場合を考えてみましょう。

```sql
SELECT * FROM users WHERE name = 'John';
```

この検索クエリは、テーブル内のすべてのレコードをスキャンして、名前が"John"であるレコードを検索します。しかし、テーブルに多くのレコードがある場合、この検索は非常に遅くなります。

この問題を解決するために、名前列にインデックスを作成することができます。

インデックスは、テーブル内の各レコードに対応する、名前の値を持つインデックスエントリを作成します。これにより、MySQLはインデックスを使用して、名前が"John"であるレコードを迅速に検索できます。

```sql
ALTER TABLE users ADD INDEX name_index (name);
```

このインデックスを作成した後、同じ検索クエリを実行すると、MySQLはインデックスを使用してレコードを検索します。

また、複数の列に対してインデックスを作成することもできます。例えば、名前と年齢列に対して複合インデックスを作成することができます。

```sql
CREATE INDEX ON users (name, age);
```

この複合インデックスを使用することで、名前が"John"であるかつ年齢が25歳以上であるレコードを検索する場合、MySQLはインデックスを使用して効率的にレコードを検索できます。

## インデックスの種類

MySQLには、いくつかのインデックスの種類があります。

以下によく使用されるインデックスの種類を一部説明します。

- B-Treeインデックス（基本コレ）
B-Treeインデックスは、MySQLで最も一般的に使用されるインデックスです。B-Treeインデックスは、データを木構造で管理し、各ノードが複数の子ノードを持つことができます。B-Treeインデックスは、検索、範囲検索、ソートなどの操作を高速に実行できます。
- Hashインデックス
Hashインデックスは、ハッシュ値を使用してデータを管理するインデックスです。Hashインデックスは、完全一致検索や`=`や`<=>` といった単純な比較の場合は、速いですが文字列検索などは、`B-Tree Index`の構造上前方一致の方が速度が出やすいです。

## インデックスの利点と欠点

インデックスは、データベースのパフォーマンスを改善するために非常に重要ですが、利点と同時に欠点もあります。

### メリット

- 検索速度が向上する：インデックスを使用することで、テーブル内のデータを高速に検索できるようになります。
- データの一貫性が保たれる：UNIQUEインデックスを使用することで、データの一貫性が保たれます。

### デメリット

- ストレージの使用量が増加する：インデックスを作成することで、ストレージの使用量が増加します。
- インデックスの更新に時間がかかる：テーブルにデータを追加、更新、削除する場合、インデックスの更新に時間がかかることがあります。

## **インデックス対象となるカラムの候補**

- WHEREやJOINで使用される
- レコード件数が1万件を超えるテーブル
    - 明確な闘値ではないが、レコード数の多さによってインデックスを検討
- 外部キー
    - MySQLの場合、外部キーを作成すると自動的にインデックスが作成
- カーディナリティ(カラムの数)が20以上目安

## 参考
https://zenn.dev/hk_206/articles/ec5f4e347caff4
https://qiita.com/C058/items/1c9c57f634ebf54d99bb
https://www.javadrive.jp/mysql/index/index1.html
https://qiita.com/kodai-saito/items/541e4fe46c2d3edc9634
https://zenn.dev/hk_206/articles/ec5f4e347caff4
https://yut.hatenablog.com/entry/20110418/1303083112
https://qiita.com/K-jun/items/a86a3829cf796b6d5ad8
AIサーバーの見積もり

業務でAI向けのGPUサーバーを見積もったので、その際のメモを記載していく。

# サーバー選定観点
サーバーを選定する際の観点には以下が挙げられる。
1.GPU
2.CPU
3.メインメモリ
4.ストレージ
5.ケース
6.電源

### サーバー選定観点①GPU
GPUはAI開発にダイレクトに影響する。どのようなモデルを開発するか、投入データ量はどれくらいかを踏まえ、以下について検討する。
- GPUメモリ
GPUメモリのキャパシティ次第でAIモデルのサイズや、1stepで投入できるデータサイズ（バッチサイズ、1つあたりのデータサイズ）を制約するため
- TFLOPS
処理速度の指標であるため
- NVLinkやNVSwitch
GPUを複数基搭載する場合はNVLinkNやVSwitchを利用して性能向上させる

### サーバー選定観点②CPU
CPUは入力データや教師データを前処理する際の処理速度に影響する。
- コア数及びスレッド数
同時に実行できる並列処理や並行処理の数に影響するため
- L3キャッシュ
特に大規模データでの処理速度に影響するため
- 搭載数
金額次第になるが可能であればマルチCPUを搭載して性能向上を図る

### サーバー選定観点③メインメモリ
- メモリサイズ
教師データの投入サイズを制約するため

### サーバー選定観点④ストレージ
- ストレージサイズ
プロジェクトごとに存在するデータ量や中間生成物、結果ファイル等を格納するため、大きいほど安心
- 搭載ディスク数
金額的に余裕があれば複数積むことを検討する。
- RAID
複数ディスクを搭載する場合は耐障害性や処理速度向上を考慮して、RAID構成を検討する

### サーバー選定観点⑤ケース
設置予定箇所に合わせて選定する
- ケースの種類
ラックマウントケースやスタンドケースなど
- 大きさ
2U、4Uなど
- 重量

### サーバー選定観点⑥電源
こちらも設置予定箇所に合わせて選定する
- 電源
100V、200Vなど
- 消費電力
サーバー構成から消費電力を見積もっておく

# AIのサーバー見積もり手順
おすすめの手順はオンライン見積もりサービスで金額感を参考にしつつ、各メーカーに問い合わせてみること。

### オンライン見積もりサービス
- [GDEP Adavnce](https://www.gdep.co.jp/products/)
筐体を指定できる。各パーツを細かく調整できる。
- [NTTPC COMMUNICATIONS](https://www.nttpc.co.jp/cgi-bin/gpu/simulation/custom/index.cgi)
選択できる項目のバリエーションは多くないが、手軽に見積もりできる。
【git】特定のブランチを除外して、ローカルブランチを一括で削除するコマンドの解説

## これは何

手元に不要なブランチが溜まってきた時に必要なブランチ以外一括で削除したくて色々調べたのですが、そもそもコマンドが全然わからなくて怖かったので調べた記事です。

:bulb: ということでかなり初心者向けの記事になっております。

:::note warn
何か間違ってるところなどありましたら、編集リクエストやコメントで指摘していただけると大変助かります...！
:::

## 結論（コマンド）

このコマンドを打てば、特定のブランチ以外のローカルのブランチを削除できます。🔽

```zsh
git branch -r | grep -v "除外するブランチ名" | xargs git branch -D
```

:bulb: "除外するブランチ名"の部分を削除したくないブランチ名に変えて使います

ex) `git branch | grep -v master | xargs git branch -D`

複数除外したい時はこんな感じです🔽

```zsh
git branch | grep -v -E "除外するブランチ名A"|"除外するブランチ名B" | xargs git branch -D
```

ex) `git branch | grep -v -E "master|development" | xargs git branch -D`

## このコマンドで何をしている？

ざっくりやってることはこんな感じです。

- `git branch`
    - ローカルブランチを取得
- `grep -v -E a|b`
    - 除外したいブランチをOR条件で複数指定
- `xargs`
    - 前のコマンドの実行結果を次のコマンドに引数として渡す
- `git branch -D`
    - ブランチを削除

:::note
ここから先はコマンドの細かい解説になるので、そんなの知ってるよという方は読み飛ばしてもらって大丈夫です
:::

### git branch

ローカルブランチを取得しています。

### grep -v

`grep`は正規表現を使って指定したパターンに一致する行を抽出します。

 `-v`はパターンに一致しない行を表示するオプションです。

なので、この後の`"除外するブランチ名"`に一致しない行を抽出しています。

Ref [Man page of GREP | -v](https://linuxjm.osdn.jp/html/GNU_grep/man1/grep.1.html#:~:text=%E3%82%88%E3%81%86%E3%81%AB%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,%2Dv%2C%20%2D%2Dinvert%2Dmatch,-%E3%83%9E%E3%83%83%E3%83%81%E3%81%AE%E6%84%8F%E5%91%B3)

### -E "除外するブランチ名A|除外するブランチ名B"

`-E`オプションを使うと、`grep`で拡張正規表現が使えるようになります。
また、`|`（パイプ記号）は正規表現でOR条件になるので、「いずれかに一致」したものを抽出することができます。

Ref [Man page of GREP | -E, --extended-regexp](https://linuxjm.osdn.jp/html/GNU_grep/man1/grep.1.html#lbAB:~:text=%2DE%2C%20%2D%2Dextended%2Dregexp)

Ref [正規表現言語 - クイック リファレンス | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/standard/base-types/regular-expression-language-quick-reference#alternation-constructs)

### xargs

標準入力（前のコマンドの実行結果）を引数として、次のコマンドを実行します。

なので、今回の場合だと`git branch | grep -v -E "除外するブランチ名A|除外するブランチ名B"`の実行結果である「削除したくないブランチを除外したローカルブランチの一覧」を引数として受け取って`git branch -D`を実行します。

Ref [Man page of XARGS](https://linuxjm.osdn.jp/html/GNU_findutils/man1/xargs.1.html)

### git branch -D

指定したブランチの削除をします。

### コマンド同士を繋いでる`|`（パイプ記号）

`|`（パイプ記号）は、前のコマンドの出力結果を次のコマンドの入力に渡します。
sed を使って複数ページに Google アナリティクス を埋め込む

Google アナリティクスを使ってみようかなと思ったら、以下をしておかないといけないらしいです。

> Google タグを手動でインストールする
以下は、このアカウントの Google タグです。このタグをコピーして、ウェブサイトのすべてのページのコード（<head> 要素の直後）に貼り付けます。各ページに複数の Google タグを実装することはできません。
> ```
> <!-- Google tag (gtag.js) -->
> <script async src="https://www.googletagmanager.com/gtag/js?id=G-hogehoge"></script>
> <script>
>   window.dataLayer = window.dataLayer || [];
>   function gtag(){dataLayer.push(arguments);}
>   gtag('js', new Date());
> 
>   gtag('config', 'G-hogehoge');
> </script>
> ```

ということで、これをファイルにし、ga.txt とします。

```
<html>
<head>
</head>
<body>
Hello!
</body>
</html>
```

これを file1.html とします。


# r 命令

<head> の直後に ga.txt を入れるには、

```
$ sed '/<head>/r ga.txt' file1.html 
```

sed の r 命令を使うと `<head>` 行の後ろに `ga.txt` が差し込まれます。

```

<html>
<head>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-hogehoge"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-hogehoge');
</script>

</head>
<body>
Hello!
</body>
</html>
```

# 正規表現を使う


ところがこのやりかたでは、

`<head>` と書かれているだけの行が存在しないといけない。

正規表現などは使えないようだ。


なので通常の

sed "s/<head>/<head> hogehoge " file1.html

の形を元にして考える。


`hogehoge` の代わりに ga.txt の内容が書かれるようにしたい。


# 解決

以下のようにする

```
$ sed -i "s/\(<head[.]*>\)/\1$(cat ga.txt | tr -d '\n' | sed 's/\//\\\//g')/i" file1.html

```

結果
```
<html>
<head><!-- Google tag (gtag.js) --><script async src="https://www.googletagmanager.com/gtag/js?id=G-hogehoge"></script><script>  window.dataLayer = window.dataLayer || [];  function gtag(){dataLayer.push(arguments);}  gtag('js', new Date());  gtag('config', 'G-hogehoge');</script>
</head>
<body>
Hello!
</body>
</html>
```

# 解説

`sed -i 〜〜 file1.html`

file1.html に 〜〜 の処理を行い、上書きします。

`s/\(<head[.]*>\)/\1〜〜/g')/i`


<head> や <head ほにゃらら> を <head>〜〜 や  <head ほにゃらら>〜〜 に変換します。 head は大文字小文字を問いません。


`$(〜〜)`

〜〜 の中身を実行し、その結果を変数に入れます。



`cat ga.txt | tr -d '\n' `

ga.txt の改行を取り外し、1行にします。

`| sed 's/\//\\\//g'`

sed に与える置換先に `/` が含まれていると s 命令の終了と解釈されてしまうので、`\/` に変換します。

# 一度に複数 html を書き換える

以下のようにすればOK

```
g$ sed -i "s/\(<head[.]*>\)/\1$(cat ga.txt | tr -d '\n' | sed 's/\//\\\//g')/i" *.html

```
firefox コンテナを作成しよう

スクレイピングなんてしてると
「あ、こいつボットだな」
なんて思われちゃうの悲しいですよね。

そこで、 container

# firefox をインスコし、以下のアドオンをインスコ

・Container Tabs Sidebar
（containertabsのサイドバーが消えたら右上のグレーアイコンをクリックするとまた出現する。）
・Container proxy
・Conex
・firefoxnodevpn
・Privacy Badger


# ピン止め
container tabs sidebar
conex

をツールにピン止め


# firefox の設定

・設定 > 一般 > 下の方までスクロールして更新の確認は行うが、インストールするかを選択する(C)にする。

・設定 > プライバシーとセキュリティ
1『Firefox を閉じたときに Cookie とサイトデータを削除する』のチェックが外れていることを確認。

2 位置情報の設定を変更し、『位置情報へのアクセスの要求をブロック』

3 Firefox のデータ収集と利用についてをすべて外す

# container の作成

conex をクリック
> プラスボタンを押下
> 0001 と入力し add

するとコンテナができる。

また、一気に作成したい場合
everythingなどで、
containers.json

を検索して直接編集すれば一気にコンテナを作ることもできる。
【Laravel】Mailable VS Notification 使い分けについて

# はじめに
先日アサインされた案件で、メール送信機能の実装を行いました。
その際に、`Mailable` or `Notification`どちらの方法で行うべきか悩んでおりました。

そこで、自分なりの選定基準をまとめましたので、紹介します。

# それぞれの違い
- `Mailable`は、メールを送信するためのもの
- `Notification`は、メールを含む複数の通知方法を抽象化したもの

メールに限って言えば、`Mailable`の方が`Notification`と比較してカスタムしやすく、設定も簡単です。
→各メール毎のレイアウト変更など

対して`Notification`はModelとの紐付けなど設定が必要になるが、
メールに限らず通知を送ることができるので、そういったケースで使用します。

# Mailable VS Notification
某サイトでも似たような質問が存在します。
[Laravel Mail or Notification? which one should use for email sending? and Why?](https://stackoverflow.com/questions/40683957/laravel-5-3-notification-vs-mailable)

上記回答を翻訳すると、このようになります。

> 送信する各メールのレイアウトが異なる場合は、Mailable を使用する必要があります。
Mailable は、メールを送信するための非常に柔軟な方法です。また、通知よりもカスタマイズ可能です。
通知は、異なるチャネルで定義済みのレイアウトを送信する必要がある場合に役立ちます。
通知のレイアウトをカスタマイズできますが、通知の複数のレイアウトを持つことは範囲外であるため、お勧めできません。



# 最後に
　自分なりの選定基準
- メール送信のみ行いたいなら`Mailable`を使用する
- 様々なチャネルに通知したい場合は`Notification`を使用する

# 参考サイト
[Laravel Notification System On Slack And Email](https://www.cloudways.com/blog/laravel-notification-system-on-slack-and-email/)
オープンソースによるフォトグラメトリの実行方法

前記事（[オープンソースによるフォトグラメトリを実行するための環境構築](https://qiita.com/keita-n-ac/items/06f4214c7ae3292c5e44)）からの続きの話です．

#### 1. OpenSfMとOpenMVSを利用してフォトグラメトリを行う方法．
- 前回作成した'3d'ディレクトリに，ディレクトリ（名前はプロジェクト名的なもの）を作成する．
- 作成したそのディレクトリに'images'ディレクトリを作成し，そのimagesディレクトリにフォトグラメトリに適用した全画像データを追加する．
- カレントディレクトリを最初に作成したプロジェクトディレクトリにし，以下のコマンドを順番に実行すれば，フォトグラメトリ結果を得ることができる．
```BASH:OpenSfMとOpenMVSを利用した場合
# OpenSfMの処理
$ ~/3d/OpenSfM/bin/opensfm_run_all .
$ ~/3d/OpenSfM/bin/opensfm export_openmvs .
# OpenMVSの処理
$ ~/3d/openMVS/openMVS_build/bin/DensifyPointCloud ./undistorted/openmvs/scene.mvs
$ ~/3d/openMVS/openMVS_build/bin/ReconstructMesh ./undistorted/openmvs/scene_dense.mvs
$ ~/3d/openMVS/openMVS_build/bin/TextureMesh ./undistorted/openmvs/scene_dense_mesh.mvs
```
- フォトグラメトリ結果は上のコマンドを実行した際に作成される「undistorted/openmvs/scene_dense_mesh_texture.ply』となる．

#### 2. COLMAPとOpenMVSを利用してフォトグラメトリを行う方法．
- 前回作成した'3d'ディレクトリに，ディレクトリ（名前はプロジェクト名的なもの）を作成する．
- 作成したそのディレクトリに'images'ディレクトリを作成し，そのimagesディレクトリにフォトグラメトリに適用した全画像データを追加する．
- カレントディレクトリを最初に作成したプロジェクトディレクトリにし，以下のコマンドを順番に実行すれば，フォトグラメトリ結果を得ることができる．

```BASH:COLMAPとOpenMVSを利用した場合
# COLMAPの処理
$ colmap feature_extractor --database_path database.db --image_path ./images
$ colmap exhaustive_matcher --database_path database.db
$ mkdir sparse
$ mkdir dense
$ colmap mapper --database_path database.db --image_path ./images --output_path ./sparse
$ colmap image_undistorter --image_path ./images --input_path ./sparse/0 --output_path ./dense
# OpenMVSの処理
$ ~/3d/openMVS/openMVS_build/bin/InterfaceCOLMAP -i ./dense -o scene.mvs
$ ~/3d/openMVS/openMVS_build/bin/DensifyPointCloud ./scene.mvs
$ ~/3d/openMVS/openMVS_build/bin/ReconstructMesh ./scene_dense.mvs
$ ~/3d/openMVS/openMVS_build/bin/TextureMesh ./scene_dense_mesh.mvs
```
- フォトグラメトリ結果は上のコマンドを実行した際に作成される「scene_dense_mesh_texture.ply』となる．

#### 3. テストデータと自動実行スクリプト
テスト画像データと自動実行スクリプトを[github](https://github.com/keita-n-ac/SfM-MVS)にuploadしました．
使い方は，以下の動画を参考にしてください．

<iframe width="560" height="315" src="https://www.youtube.com/embed/zKJP_eKZiFs" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
Windowsの画面下部(タスクバー)を各種アプリ、ブラウザの前面にしたい

# 前提
- Windows10 ~ (そうじゃなくても、もしかしたら対象

# やりたい事
- Windowsの画面下部(タスクバー)を各種アプリ、ブラウザの前面にしたい。

# 期待値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3081664/0af695f0-e478-7304-95c3-3b36a0dd03e2.png)


# 対応したこと
- Epic Pen(画面上にお絵描きするツール)の起動終了
    - 全画面系のコントロールを奪っている為、関連して影響している。
    - 使用したいときにだけ使用するのがよさそう。



# 参考情報
タスク バーが最前面表示ではなく、ウィンドウの下に隠れるようになってしまった。
https://answers.microsoft.com/ja-jp/windows/forum/all/%E3%82%BF%E3%82%B9%E3%82%AF/967b692a-d254-4221-9561-e84909c8d3b2


# 関連キーワード
windows, タスクバー, ブラウザ, トラブル, 画面
Glass Break Sensor by Cove 

The ultimate <a href="https://www.covesmart.com/products/glass-break-detector/">glass break sensor</a> has arrived. When intruders can’t find a way in through the doors, they might try to come in through your windows. Our glass break sensor detects the specific tone and frequency of shattering glass, so when a burglar (or a neighborhood kid) throws a rock at your window, you’ll know.
競プロに使えるPython小技集

# まえがき
競プロで使えるPythonの小技をまとめてみました。定数倍は遅いものも多いかも。
他のテクニックなども教えてください。追加します。
## 再帰
PyPy、Pythonだと再帰が遅いのは周知の事実(そうか？)だと思います。
ですが、Cythonだと再帰が割と速いということはあまり知られていない気がします。PyPy、Pythonで通らない再帰DP、再帰DFSなどでもCythonでそのまま提出するだけで通ることもあるのでどうしても非再帰にするのが面倒だったりするときは試してみてもよいでしょう。
## -~n
これは`n+1`です。それだけだとあまり使いどころが無いですが、`-~n`を使うと`l=[0]*(n+1)`の代わりに`l=[0]*-~n`と書くことができます。かっこを書く時間が無くなって少しコーディングの速度が上がるかもしれません。

追記`~n`単体だと`-n-1`を意味するのでリストの後ろから見るときなどに`l[~i]`と書くと`l[-i-1]`と書くより少し楽になります。
## list[-1]を活用する
累積和、DPなどを1-indexedで書いている人はいませんか？書くものによって1-indexedか0-indexedかを変えるとバグが発生しやすくなり、可読性も低くなってしまいます。
Pythonならlist[-1]でリストの最後の要素にアクセスすることができるので、無駄な条件分岐を入れずに累積和やDPを0-indexedで行うことができます。例えば、下のコードのようなことができます。
```py
#入力
n=int(input())
l=[*map(int,input().split())]
#累積和
c=[0]*-~n#一つ多く要素を作っておく
for i in range(n):
    c[i]=c[i-1]+l[i]
#アクセスするときも簡単
c[r]-c[l-1]#c[-1]は0になっている
```
## sum(hoge for i in l)
リストの中からある条件を満たすものの個数を求めたいとき、
```py
cnt=0
for i in l:
    if i>hoge:cnt+=1
```
のようなことをしていませんか？このように書くと時間がかかるし、なによりエレガントではありません。代わりに、
```py
cnt=sum(i>hoge for i in l)
```
と書くとエレガントかつ短いコードを書くことができます。

## map(lambda x:hoge,l)の利用
リスト全体に対してある操作をしたいとき、for文を使って書くと時間がかかるし、なによりエ(以下略)
代わりに、`l=[*map(lambda x:x+1,l)]`のように書くとエレガントかつ短いコードを書くことができます。

## print(*l,sep="hoge")
整数のリストを改行区切りで出力したいとき、`for i in l:print(i)`などと書く代わりに、`print(*l,sep="\n")`と書くことができます。`"\n".join(l)`だとリストの要素が文字列である必要があるので迷ったらこの技を使うとよいかもしれません。
## open(0)
```tex
N M
K
A_1 A_2 ... A_N
```
受け取る入力がこのようなとき、
```py
n,m=map(int,input().split())
k=int(input())
a=[*map(int,input().split())]
```
と書くと少し長すぎますよね。そんなときは`n,m,k,*a=[*map(int,open(0).read().split())]`と書くと少し短くコードを書くことができます。
## hoge=huga=piyo
これは少し有名かもしれません。
複数の変数を同じ値にセットしたいとき、
```py
a=1
b=1
c=1
```
のように書くとあまりエレガントではありません。`a=b=c=1`と書くとシンプルに書くことができます。
CKA試験、kubeadm upgrade

# kubeadm upgrade

> Ubuntu基準で説明します

## チートシート
https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/

# control plane upgrade(Master)

### 1. 現在アップグレードできるバージョンを取得
```
sudo apt update
sudo apt-cache madison kubeadm
```

### 2. control plane upgrade(Master)
```
 sudo apt-mark unhold kubeadm && \
 sudo apt-get update && apt-get install -y kubeadm=1.26.x-xx && \
 sudo apt-mark hold kubeadm
```
> x のところに、バージョンの番号を入れる

### 3. upgradeの計画を確認する
```
sudo kubeadm upgrade plan 1.26.x-xx
```

### 4. upgradeを行う
```
sudo kubeadm upgrade apply 1.26.x-xx
```

### 5. master のnodeたちを全体削除する

```
### 6. sudo kubectl drain <node-to-drain> --ignore-daemonsets
```
>  < node-to-drain > -> PC名

```
sudo kubectl drain ip-172-31-23-75.ap-northeast-1.compute.internal --ignore-daemonsets
```

### 7. kubeletとkubectlをアップグレード
```
sudo apt-mark unhold kubelet kubectl && \
sudo apt-get update && apt-get install -y kubelet=1.26.x-xx kubectl=1.26.x-xx && \
sudo apt-mark hold kubelet kubectl
```

### 8. kubeletを再起動
```
sudo systemctl daemon-reload
sudo systemctl restart kubelet
```

### 9. node uncordon
```
kubectl uncordon <node-to-uncordon>
```
>  < node-to-uncordon > -> PC名



# worker node upgrade(Node)
### 1. ノードPCにアクセス
```
ssh <node>
```

```
sudo apt-mark unhold kubeadm && \
sudo apt-get update && apt-get install -y kubeadm=1.26.x-00 && \
sudo apt-mark hold kubeadm
```
> x のところに、バージョンの番号を入れる


### 2. kubedam node upgradeを実行する
```
sudo kubeadm upgrade node
```

### 3. master Pcでノード PCのdrain 命令ごを実行す
```
ssh <master>
kubectl drain <node pc name> --ignore-daemonsets
```

### 4. ノード PCにアクセスし、kubeletとkubectlをアップグレード
```
ssh <node>
sudo apt-mark unhold kubelet kubectl && \
sudo apt-get update && apt-get install -y kubelet=1.26.x-xx kubectl=1.26.x-xx && \
sudo apt-mark hold kubelet kubectl
```

### 5. kubectlを再起動
```
sudo systemctl daemon-reload
sudo systemctl restart kubelet
```

### 6. node uncordon
```
ssh <master>
kubectl uncordon  <node pc name> 
```
PowershellからGitHubのAPIを使用する

## この記事の概要
https://qiita.com/tomy_hara/items/b10da96c99dfd155bdcc

以前書いたこの記事ではPowerShellForGitHubというライブラリを使用していたのですが、実際にあるAPIにはあっても使用できないものが多かったので自分でAPIを直接Powershellから叩くことにしました。

JenkinsなどでGitHubに連携をする場合に任意のタイミングでPull Requestにコメントを打ちたいときなどが発生した際に便利です。 
Windowsで使用したいのでPowershellでInvoke-requestを使用していますが、Linuxで組む場合はbashでcurlでできます。
そういえばMacでもPowershell使えるのでMacでも行けるかも(zsh使いなよ・・・)

## APIについて

APIを使用するためのtokenなどは上の記事を参照

## 基本的な使用方法

### Pull requestの情報を取得する場合

```powershell
function GetPullRequestInfo
{
    param(
        [string] $api_url,
        [string] $token,
        [string] $repo,
        [string] $pr_num
    )
    $url = $api_url + "/repos/" + $repo + "/pulls/" + $pr_num
    $resp = (Invoke-WebRequest -H @{"Authorization"="token ${token}"} ${url})
    $resp_StatusCode = $resp.StatusCode
    Write-Host $resp_StatusCode
}
```
ここではAPIのtokenとapiのURL、レポジトリ名(ユーザ名\レポジトリ名)、Pull requestの番号が必要になります。
これでStatus codeが200の場合正常に情報が取得できています。

取得できる情報は、
```powershell
$content = $resp.Content | ConvertFrom-Json
```
でJSONファイルの形で取得することができます。その後の処理はJSONの構造に従ってがんばってください。

### Pull Request(Issue)にコメントする

```powershell
function CreatePullRequestComment
{
    param(
        [string] $api_url,
        [string] $token,
        [string] $repo,
        [string] $pr_num,
        [string] $body
    )

    $url = $api_url + "/repos/" + $repo + "/issues/" + $pr_num + "/comments"

    $string_body = @{
        body = $body
    }

    $json_body = $string_body | ConvertTo-Json
    $resp = (Invoke-WebRequest -H @{"Authorization"="token ${token}"} -Method Post ${url} -body ${json_body})

    $resp_StatusCode = $resp.StatusCode
    Write-Host $resp_StatusCode
}
```
APIのURLとtoken、レポジトリ名、Pull Request番号(Issue番号)、コメント内容($body)を渡してやります。

status codeに200が帰ってきたら成功です。

このときに、コメント内容などのオプションをJSON形式で渡してやる必要があるので、ConvertTo-Jsonを使用して構造体を変換してやります。

ちなみに改行はPowershellの改行と同じく「`n」になります。

注意すべき点は、Pull requestとIssueの番号は共通で使われるという点なのでIssue用のAPIがPull reqestにも使用できてしまうという点です。

### それ以外

https://docs.github.com/ja/rest/quickstart?apiVersion=2022-11-28

こちらを参考にしてください。基本形は上の２つになります。PowewrShellで一行づつ確認しながらできると思います。
渡すオプションがいっぱいある場合はIssueにコメントを与えるときのようにbodyの構造体に入れてあげてやればできるはずです。
glibc_2.28' not found libqt6core.so.6 こういうのが出たら

### ubuntu18.04がそろそろ限界

- QGroundControlやPlotJugglerを使おうとしても、機能がおかしい。
- コマンドラインから実行すると、表題のようなエラーが出てくる

### glibcをアップデートすれば良い、なんて考えてはいけない

- StackOverFlowなどでみても、同様のエラーの人は多い。
- しかし、glibcを無理やりアップデートしてOSがブートできなくなる人が多いようです。
- もうそうなったらディストリビューションを新しくするのが回り回って一番早いですね。
- また、dist-uggradeもうまく行かないことも多いので、いろいろ手をこまねいて工夫するより、ubuntu20のインストールメディアを作成して、もともとubuntu18があったパーティションに上書きインストールするのが良い。


寒かったり暖かかったりしますね

2023年2月23日
NTFS のディレクトリが Ubuntu で読めなくなった

Ubuntu 22.04 にマウントしていた NTFS の HDD。

```
$ sudo fdisk -l /dev/sda
ディスク /dev/sda: 7.28 TiB, 8001563222016 バイト, 15628053168 セクタ
Disk model: ST8000DM004-2CX1
単位: セクタ (1 * 512 = 512 バイト)
セクタサイズ (論理 / 物理): 512 バイト / 4096 バイト
I/O サイズ (最小 / 推奨): 4096 バイト / 4096 バイト
ディスクラベルのタイプ: gpt
ディスク識別子: 0152CC16-0BE1-4EED-9A8F-C3C8F2B3909F

デバイス   開始位置    最後から      セクタ サイズ タイプ
/dev/sda1      2048 15628052479 15628050432   7.3T Microsoft 基本データ
```

書き込み中に、突然の電源断を行ったら読めなくなった。なお電源断の原因は関係のない別の処理。

```
$ cd /media/nanbuwks/202105/encoded/
$ ls
ls: ディレクトリ '.' を読み込んでいます: 入力/出力エラーです
```

なお、  /dev/sda1 は  /media/nanbuwks/202105 にマウントしていて、


` /media/nanbuwks/202105/ `

は読めて、

` /media/nanbuwks/202105/encoded/ `

これだけ読めない。

# 問題の切り分け

ハードウェアエラーでないことは確認済み。なお、Windows7 マシンに接続すると該当ディレクトリは読める。
 
# ntfsfix (効果なし)


Ubuntu 22.04 に ntfsfix が入っていたので使ってみる。
アンマウントして

```

$ cd ../..
$ sudo umount 202105
```

実行


```
$ sudo ntfsfix /dev/sda1
Mounting volume... OK
Processing of $MFT and $MFTMirr completed successfully.
Checking the alternate boot sector... OK
NTFS volume version is 3.1.
NTFS partition /dev/sda1 was processed successfully.
nanbuwks@nanbuwks-B550M-S2H:/media/nanbuwks$ ls 202105/encoded
ls: ディレクトリ '202105/encoded' を読み込んでいます: 入力/出力エラーです
```

効いてないですね。


# Windwos7 上で chkdsk

再度、Windows7 に接続して起動する。手動で chkdsk をやろうとしたけれども、今回は自動で chkdsk した。一度目は chkdsk が発動しなかったけどこの条件はなんだろう?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/3454c84b-b6ce-4a9b-8cf1-335dbba2c818.png)

終了後、Ubuntu マシンに接続し直したら読めるようになっていた。

```
$ ls
.
.
. 
 encode.py
 ffmpeg_output
 ffmpeg_output.txt
 test.mp4
 test.ts
```

今回の結果として、 ntfs-3g 上で

- 特定のディレクトリが読むことができなかった
- それの修復ができなかった

ということになります。

NTFS システムを USB 起動の Linux でサルベージしたりすることがありますが、このようなことがあったということは注意ですね。
【Cisco Packet Tracer for Mac 】コマンドラインの読み上げとサウンドを停止する方法




## 目次
1.はじめに
2.動作環境
3.エラーと症状
4.解決策
5.おわりに


## はじめに
CCNAを勉強するにあたってCiscoのPacketTracerを使ってみると良いとのことでMACにインストールしたところ、致命的ではないがうざい挙動をしてきたのでその解決法を備忘録として書いておきます。
同じ思いをした誰かの役に立てばと思っています。

## 動作環境
・MacBook Air (M1,2020)
・macOS Monterey(バージョン12.6)
・Cisco Packet Tracer 8.2.0 MacOS 64bit

## エラーと症状
(1) タブやアイコンをクリックするたびにサウンドが再生される。
(2) コマンドプロンプトでコマンドを実行すると結果が勝手に読み上げられてしまう。

## 解決策
(1)Packet Tracerを起動した状態でメニューバーから "Cisco Packet Tracer">"Preferences"をクリックします。
次に"Interface"タブの"Play Sound"からチェックを外します。


(2)Packet Tracerを起動した状態でメニューバーから "Cisco Packet Tracer">"Preferences"をクリックします。
次に"Interface"タブの"Disable CLI Text to Speech"からチェックを外します。


## おわりに
インターネットでこの解決策がぱっと見、見つからなかったのでここに掲載して供養しておきます。
解決したところで、それではよいPacket Tracerライフをお過ごしください。
Tektonでtkn task strart するとhe API version in the data (tekton.dev/v1beta1) does not match the expected API version (tekton.dev/v1)エラーが出る

# はじめに

~~この記事では根本的解決しておらず、代替え手段で解決を行っています~~

以下の書籍をやっていてつまづいたことをまとめています

https://www.amazon.co.jp/Kubernetes-CD%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%AE%E5%AE%9F%E8%A3%85-impress-top-gear/dp/4295012750/ref=sr_1_3_sspa?keywords=kubernetes&qid=1677129595&sprefix=kubern%2Caps%2C197&sr=8-3-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEyRFFMSE9GR08zUlZQJmVuY3J5cHRlZElkPUEwMDEyMjEySzZXQUNPNkpHUTNPJmVuY3J5cHRlZEFkSWQ9QTJXWDdKNkUzWlBXWTgmd2lkZ2V0TmFtZT1zcF9hdGYmYWN0aW9uPWNsaWNrUmVkaXJlY3QmZG9Ob3RMb2dDbGljaz10cnVl

# 問題

書籍第3章Tekton Pipelinesの概要でPersitentVolumeにリポジトリをクローンしてその中身をみるTaskを起動するときに以下のエラーがおきました

```
watanabejin@watanabejin-Latitude-3520:~/workspace/bookinfo-manifests/sample/tekton$ tkn task start source-lister --showlog --workspace name=output,claimName=bookinfo
? Value for param `contextDir` of type `string`? (Default is `reviews`) reviews
Error: the API version in the data (tekton.dev/v1beta1) does not match the expected API version (tekton.dev/v1)
```

おそらく`tkn task start`が現在のバージョンで利用できないという感じがしました

# 解決方法

これは`tkn cli`のバージョンが起因していました

そこで書籍通りv0.20.0をいれることでうまく動かせるようになりました

https://github.com/tektoncd/cli/releases/tag/v0.20.0

# 解決方法(代替)

代替としてCLIで起動するのでなく、`TaskRun`で起動することでうまく行きました

```yaml:source-rister-run.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  generateName: source-liter-run-
spec:
  taskRef:
    name: source-lister
  workspaces:
    - name: output
      persistentVolumeClaim:
        claimName: bookinfo
```

```
$ kubectl apply -f source-rister-run.yaml
$ tkn taskrun list
$ tkn taskrun logs [タスク名]
```

# おわりに

根本的な解決はできていないのでわかる方はコメントお願いします
そもそもCLIで実行することが頻繁にあるのでしょうか。ネットを見ても同じような減少の方があまりいませんでした

# 参考

https://github.com/tektoncd/cli/releases/tag/v0.20.0
TektonでTaskRunしてもPendingになって失敗するときのデバックと解決方法

# はじめに

以下の書籍をやっていて詰まったことがあったのでまとめます。
書籍が少し古いため現在のバージョンで動かすためにいろいろ試行錯誤した過程になります

https://www.amazon.co.jp/Kubernetes-CD%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%AE%E5%AE%9F%E8%A3%85-impress-top-gear/dp/4295012750/ref=sr_1_3_sspa?keywords=kubernetes&qid=1677129595&sprefix=kubern%2Caps%2C197&sr=8-3-spons&psc=1&spLa=ZW5jcnlwdGVkUXVhbGlmaWVyPUEyRFFMSE9GR08zUlZQJmVuY3J5cHRlZElkPUEwMDEyMjEySzZXQUNPNkpHUTNPJmVuY3J5cHRlZEFkSWQ9QTJXWDdKNkUzWlBXWTgmd2lkZ2V0TmFtZT1zcF9hdGYmYWN0aW9uPWNsaWNrUmVkaXJlY3QmZG9Ob3RMb2dDbGljaz10cnVl

# 問題

書籍3章Tekton Pipelinesの概要のGitのリポジトリをPersitent Volumeに保存するところで問題が置きました
TaskRunでTaskを起動して状態を確認すると`Pending`になり失敗しました

ポッドを確認すると以下のように`Init`で失敗していることがわかりました

```
watanabejin@watanabejin-Latitude-3520:~/workspace/bookinfo-manifests/sample/tekton$ kubectl get po
NAME                      READY   STATUS      RESTARTS   AGE
git-clone-run-22l7z-pod   0/1     Init:0/2    0          4m11s
```

ロクを確認すると以下のようなログが出ており、おそらく`PVC`の設定で失敗しているような気がいしました

```
watanabejin@watanabejin-Latitude-3520:~/workspace/bookinfo-manifests/sample/tekton$ kubectl logs git-clone-run-srmjn-pod
Defaulted container "step-clone" out of: step-clone, prepare (init), place-scripts (init)
Error from server (BadRequest): container "step-clone" in pod "git-clone-run-srmjn-pod" is waiting to start: PodInitializing
```

PVCは以下の記事のように作成しています

https://qiita.com/Sicut_study/items/3b2ac0357355a680c3f8

# 解決方法

PVCの作り方が間違っていたのが原因でした
以下2つは正しいものと間違ったものを比べたものです(以前の記事では間違えて作っていました)

```
on$ kubectl get pvc
NAME           STATUS        VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
bookinfo       Bound         pvc-0993d11d-2f29-42b1-ad92-c9679c328fc0   1Gi        RWO            standard-rwo   17s
bookinfo-pvc   Terminating   bookinfo                                   200Mi      RWO            cache          4d4h
watanabejin@watanabejin-Latitude-3520:~/workspace/bookinfo-manifests/sample/tekton$ kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM              STORAGECLASS   REASON   AGE
bookinfo                                   1Gi        RWO            Retain           Terminating   dev/bookinfo-pvc                           4d3h
pvc-0993d11d-2f29-42b1-ad92-c9679c328fc0   1Gi        RWO            Delete           Bound         dev/bookinfo       standard-rwo            8s
```

STORAGECLASSが`cache`から`standard-rwo`に変えました
以下がその時に使った設定ファイルになります

```yaml:bookinfo-pvc.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: bookinfo
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  gcePersistentDisk:
    pdName: bookinfo
    fsType: pd-balanced
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: bookinfo
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 1Gi
```

これで無事クローンできたことが確認できました

# おわりに

デバック方法がわからないことで問題解決まで時間がかかりましたが、このような作業が本番で運用していくときに原因を解決できる力になるのかなと思うので、引き続きがんばります