OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】bundlerでプロジェクト毎にgemを管理する根拠と方法(5分)

## 本記事の趣旨

初学者の方でもわかりやすいように、5分で読めるくらいの軽さで下記の項目についてまとめます！
1. bundlerとは何か？
1. プロジェクト（アプリ)毎にgemを管理する根拠
1. bundlerを使ってプロジェクト毎にgemを管理する方法
1. プロジェクト毎にGemを管理するときはgitignoreしよう

※ OSはmacを想定しています。
※ rbenvを使用していることを想定しています。

## bundlerとは何か？

ざっくり言うと、**Gemfileに書いているGemをよしなに管理してくれる超便利マン**です。

各種のGemを人の手で管理すると、非常にだるい、だるすぎるので、bundlerさんの力を借りて簡単に管理するのが定石となります。

下記の記事でわかりやすくまとめてくれているので、詳しく知りたい方は参照してください。
https://pikawaka.com/rails/bundler

## プロジェクト毎にgemを管理する根拠（メリット）

上記の通り、Gemをよしなに管理してくれるbundlerさんですが、デフォルトではinstallすると、rbenv配下でGemを管理することになります。
参考: https://qiita.com/chro96/items/35f67767d0b511939fea

実は、デフォルトのrbenv配下にプロジェクトのGemをインストールするのはあまり良くないんですね…

### rbenv配下でプロジェクトのGemを管理すると何が悪いか

プロジェクトで使うGemをrbenv配下にインストールしていくと、どんどんrbenv配下が汚くなります。
例えば、一つのプロジェクトが終わったことを仮定します。
そのプロジェクトのソースコードを削除したとしても、インストールしたGemはrbenv配下に下記のように残り続けるわけです。
```
~/.rbenv/versions/2.7.2/lib/ruby/gems/2.7.0/gems/faker-2.20.0
```

その後、そのプロジェクトで使ったGemを使うとも限らないですし、他のプロジェクトにアサインした時にfaker-2.19.0を使うことになったとしたら、**Gemのバージョンが競合を起こしてしまいます**。

そうなると、いちいちプロジェクト毎にGemを消したり、Gemのバージョンを直したりする必要が出てしまうんですよね。

だから、プロジェクト毎にGemを管理するのが楽なんです。

## bundlerを使ってプロジェクト毎にgemを管理する方法

めちゃくちゃ簡単です。

下記の通り**bundleのconfigにパスを設定してから`bundle install`をしてあげる**ことで、プロジェクト（アプリ)毎にGemを管理することができます。
※ みなさんのプロジェクト配下（ここではsample_appとします）で実行してください。
```
sample_app $ bundle config set --local path vendor/bundle
または
sample_app $ bundle config set path 'vendor/bundle'
```
次に`bundle install` 
```
sample_app $ bundle install
```

このコマンドを実行してあげると、下記のようにプロジェクトのディレクトリ配下に`vendor/bundle`というディレクトリが追加されて、そこにGemがインストールされます。
```
sample_app $ ls -la vendor/bundle/ruby/2.7.0/gems
total 0
drwxr-xr-x  67 {ユーザーネーム}  staff  2144  8 16 11:53 .
drwxr-xr-x   9 {ユーザーネーム}  staff   288  8 16 11:53 ..
drwxr-xr-x   7 {ユーザーネーム}  staff   224  8 16 11:52 actioncable-6.0.4
drwxr-xr-x   9 {ユーザーネーム}  staff   288  8 16 11:52 actionmailbox-6.0.4
drwxr-xr-x   6 {ユーザーネーム}  staff   192  8 16 11:52 actionmailer-6.0.4
drwxr-xr-x   6 {ユーザーネーム}  staff   192  8 16 11:52 actionpack-6.0.4
drwxr-xr-x   9 {ユーザーネーム}  staff   288  8 16 11:52 actiontext-6.0.4
...
```

※ 上記のbundleのconfig設定方法はコメントでご指摘いただいて修正いたしました。（ご指摘いただき、本当にありがとうございます！）
以前は、下記の方法で定義してましたが、非推奨になったようです。

```
sample_app $ bundle install --path vendor/bundle
```
参考記事: https://qiita.com/devzooiiooz/items/8babd82f780f01812f9d

※ なぜ`vendor/bundle`なのか？この問いについては、僕も答えを知りません。以前慣習と聞いた覚えがあって、それで納得したので放置しています。（詳しい方がいたら教えてください）

## プロジェクト毎にGemを管理するときはgitignoreしよう

上記の通り、プロジェクト毎にGemを管理できるようになりましたが、このままだとgitにGemが全部ブッ込まれてしまいます。
これは実務でやるとある種のテロ活動となるため、**必ず`.gitignore`に下記の定義を記載して、vendor配下を無視するようにしましょう**！
【.gitignore】
```
（前略）

# Ignore vendor
/vendor/*
!/vendor/.keep
```

## まとめ

ここまで、使用するGemをプロジェクト毎に`vendor/bundle`ディレクトリで管理する方法についてまとめました。

要は、みなさんのプロジェクト配下で下記のコマンド叩くんだぜ！ってことになります。
```
sample_app $ bundle install --path vendor/bundle
```

rbenv配下でプロジェクトのGemを管理して泣きを見た方が散見されたので、本記事がそのような方の一助となれれば幸いです。
【Visual Studio】"非推奨" とされた関数に対する警告をオフにする方法C4996

〇エラー内容
コンパイラの警告 (レベル 3) C4996
"非推奨" とされた関数、クラス メンバー、変数、または typedef がコードで使用されています。

〇対処法
プロジェクトのプロパティ>C/C++>詳細設定> [指定の警告を無効にする]に 4996 を追加する。
PowerShellフォーマット演算子について

[前回](https://qiita.com/AnimaLibera/items/4add9a9502202704d729)PowerShellにて16進数ダンプ。の記事で触れたが内容がずれるのでこちらに記事とした。

フォーマット演算子について
「-f」はフォーマット演算子

```powershell:フォーマット演算子.ps1
#文字列
$a="hello"
Write-Output("'{0,8}'"-f$a)#文字列の前にスペースが3つある
Write-Host("'{0,-8}'"-f$a)#文字列の後にスペースが3つある
Write-Host""

#数値
$a=254
Write-Host("{0}"-f$a)#数値の後にスペースはない
Write-Host("{0,8}"-f$a)#数値の前にスペースが5つある
Write-Host("{0,-8}"-f$a)#数値の後にスペースが5つある
Write-Host("{0:00000000}"-f$a)#数値のまえに「0」が5つある
Write-Host("{0:d8}"-f$a)#数値のまえに「0」が5つある

#基数変換

$a=0xEA
Write-Output("{0:x4}"-f$a)#「x」小文字で表現、「00ea」となる

$a=0xea
Write-Output("{0:X4}"-f$a)#「X」大文字で表現、「00EA」となる


```
【参考文献】

https://www.miajimyu.com/docs/powershell/powershell-tips/how-to-radix-conversion/
【SwiftUI】画面サイズに応じて広告数を変化させる

# はじめに
かなり限定的なお題ですが同じ事をする方がいると思うので記事にしておきます。

# やりたい事
|iPhone12|iPadPro11(縦)|iPadPro11(横)|
|:-:|:-:|:-:|
|![simulator_screenshot_2CBECF57-4401-4526-95D5-EC1044944B8B.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/b99a4fac-5008-c3c7-58e6-4c2bd704b269.png)|![simulator_screenshot_9C0BCD94-3C2C-4E1E-BE31-E7A0A9DAC4DF.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/10d3f599-c38b-d92a-8245-044c89276827.png)|![simulator_screenshot_95EDA013-9111-40FF-AD02-4D3425A7CD71.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4a53393d-aa20-be64-ac10-f5242a7f6714.png)|

このように画面の横幅によって横に並ぶ広告数を増やしていきたい。

# 条件
- 左右に`padding`が20
- `HStack`の`spacing`は5
- 広告の横幅は`355`以上`408`以下

全てのiPhoneとiPadで上記の条件をクリアしたい

# 実装
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        GeometryReader { geo in
            HStack(alignment: .center, spacing: 5) {
                ForEach(0..<Int(geo.size.width)/355, id: \.self) { _ in
                    SmallNativeView()
                        .frame(minWidth: 355, maxWidth: 408, maxHeight: 76)
                        .cornerRadius(10)
                }
            }
            .padding(.horizontal, 20)
            .frame(width: geo.size.width, height: geo.size.height, alignment: .center)
        }
        .background(Color.yellow)
    }
}
```

:::note info
**ポイント**
`GeometryReader`を使用して動的な画面サイズを取得しています。
:::

:::note info
**ポイント**
`frame(minWidth: 355, maxWidth: 408, maxHeight: 76)`
`minWidth`と`maxWidth`を指定する事で自動でサイズ調整をしてくれます
:::

:::note info
**ポイント**
広告の横幅の基準は、
iPhoneの横幅から左右のpaddingの20を引いた数値を基準としています。

最大はiPhone13 Pro Maxで`428`
最小はiPhoneSEで`375`

よって、
広告1つの横幅は、最大`408`最小`355`となります。
:::

:::note info
**ポイント**
`Int(geo.size.width)/355`
画面サイズを広告の最小サイズで割る事で画面内に何個広告が表示できるかを計算しています。
:::

# おわり
広告を横に並べることはよくあると思うのでこの方法はかなり使えるのではないでしょうか。
deprecated and will be removed in Dart Sass 2.0.0.のエラー

## 前提

Next.jsに移行中案件で発生した
※古い環境のものは結構メンテナンスされてないもの

## 結論
sassで非推奨になったものがあるらしい


## 

```
@use "sass:math";

を読み込み

該当箇所を以下に変更

sassファイル(test.scss)


(($test-height - $test-computed) / 2);

⇓


math.div($test-height - $test-computed, 2);

```

nextでモジュールのsassを導入して、新規環境に移行中に発生したのですが
いい勉強になりました〜
Teamのためのより良いPull Requestタイトル作成について調べてみた

# 目的
coventional commit仕様に沿ったPull Requestタイトルを作成するため

## Introduction
明示的なmerge commitを作るためにPRのtitleを当該ルールに基づいて作成


## Usage
PRタイトルは ``type``(``option``): ``description``で作成

### PR title
- ``type`` - Typeのうち一つ[オプション範囲]-追加情報
- ``description`` - PRについての説明

### Type

- ``build`` - ビルドシステムまたは外部従属性に影響を及ぼす変更事項(従属性アップデート)
- ``ci`` - CI構成ファイルおよびスクリプト変更(基本的に.github/ワークフローディレクトリ)
- ``docs`` - ドキュメントのみ変更される時
- ``feat`` - 新しい機能
- ``fix`` -バグ修正時
- ``chore`` - コードに触れない変更事項(例:リリースノートの手動アップデート)
- ``refactor`` - コードのリファクトリングに集中している時
- ``style`` - コードの意味に影響を及ぼさない変更事項(白色空白、書式、セミコロン脱落など)
- ``test`` - テストコードの追加


### Example

- feat: Add billable minutes to JSON output report 
- refactor: config entities and arguments
- build: Disable Auto Doc Generation


### Reference


- https://www.conventionalcommits.org/en/v1.0.0/
- Google
【SwiftUI】iOS15以降 & SwiftUIでATT許可ダイアログを出す

以前は didFinishLaunching でATT許可ダイアログ出してもいけましたが、iOS15からはアプリがアクティブな状態でないとダイアログが出なくなりました。
そこでSwiftUIでATTダイアログを出す方法です。
```swift
struct MainView: View {
    var body: some View {
        VStack {
            Text("Hello!")
        }
        .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
            if ATTrackingManager.trackingAuthorizationStatus == .notDetermined {
                ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in })
            }
        }
    }
}
```
.onReceive で UIApplication.didBecomeActiveNotification を受け取って処理しています。
.NET6.0のSDKをインストールしたのに認識されない

3.1から.NET6へのコンバートをすることになり、VisualStudio2022を使用したところ、次のようなエラーに遭遇しました。

```
error NETSDK1045: 現在の .NET SDK は、ターゲットとする .NET 6.0 をサポートしていません。.NET 5.0 以下をターゲットとするか、.NET 6.0 をサポートする .NET SDK のバージョンを使用してください。
```

VisualStudio for Mac 2022をインストールしただけだからかと思い、最新のSDK 6.0.400をインストールしたが、状況は変わらず同じメッセージが表示されます。

コンソールでSDKのインストール状況を確認すると
```
$ dotnet --list-sdks
:
3.1.422 [/usr/local/share/dotnet/sdk]
5.0.203 [/usr/local/share/dotnet/sdk]
:
5.0.408 [/usr/local/share/dotnet/sdk]
6.0.400 [/usr/local/share/dotnet/sdk]
```

念のため、別のバージョン(6.0.100)をインストールしたらエラーが出なくなり、ビルドも可能となりました。

```
$ dotnet --list-sdks
:
3.1.422 [/usr/local/share/dotnet/sdk]
5.0.203 [/usr/local/share/dotnet/sdk]
:
5.0.408 [/usr/local/share/dotnet/sdk]
6.0.100 [/usr/local/share/dotnet/sdk]
6.0.400 [/usr/local/share/dotnet/sdk]
```

複数のバージョンを入れたからなのか、特定バージョンが必要なのかまでは調べていませんが前進しましたのでご報告させていただきました。
【PowerAutomate】実行したフローの名前を取得・表示したい【workflow関数】

# workflow関数
PowerAutomateで自動通知や自動メール送信を設定していると、
「表示するデータを追加したい、不要なデータは消したい、データの表示をリスト形式にしたい、リンクを貼りたい。。。」など実際に使うようになってから、ユーザーの使い勝手に合わせて変更すること多くないですか？

「このメールや通知ってどのPowerAutomateフローで設定したっけ？」と、
たくさんのフローを稼働させている場合、分からなくて探すところからスタートとなると面倒ですよね。
かといってメールや通知のメッセージの最後にフロー名を直打ちというのは格好悪い。そういう時活躍するのがworkflow関数です。

# フロー名の取得方法　workflow().tags.flowDisplayName
いくつかプロパティがありますが、フロー名を取得するプロパティは
.tags.flowDisplayNameです。

関数を「式」のところから設定するだけ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322371/0bc748f5-21ef-e694-c72b-c259f66704f0.png)

フロー名が取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322371/7c61ef4a-6a0c-4eb1-680d-d21bbc26311e.png)




## 余談
Micorosoftの式関数のリファレンスを説明しているページでは、

>例1
この例は、ワークフローの現在の実行の名前を返します。
workflow().run.name

とあるのですが、
workflow().run.nameで取得される値は、実行時の数字とアルファベットで合わらされるコードのようなものでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322371/3531ad84-6cc5-3dfb-ad23-1a50731348dd.png)
どういう時に使うんでしょうね！

以上
enebularでalexaスキル その2

# 概要
enebularで、alexaスキルのwebhookを返してみた。
herokuに、デプロイしてみた。
サービスリクエストをスクラッチで組み立てて、plunkerから、叩いてみた。
jsonを見直した。

# 投入したjson

```
{
	"session": {
		"new": true,
		"sessionId": "SessionId.hogehoge",
		"application": {
			"applicationId": "amzn.hogehoge"
		},
		"attributes": {
			"count": 1
		},
		"user": {
			"userId": "amzn.hogehoge"
		}
	},
	"request": {
		"type": "IntentRequest",
		"requestId": "EdwRequestId.hogehoge",
		"intent": {
			"name": "GenkiIntent",
			"slots": {
				"GenkiSlot": {
					"name": "GenkiSlot",
					"value": "元気"
				}
			}
		},
		"locale": "ja-JP",
		"timestamp": "2022-07-20T07:43:46Z"
	},
	"context": {
		"AudioPlayer": {
			"playerActivity": "IDLE"
		},
		"System": {
			"application": {
				"applicationId": "hogehoge"
			},
			"user": {
				"userId": "hogehoge"
			},
			"device": {
				"supportedInterfaces": {}
			}
		}
	},
	"version": "1.0"
}

```

# 実行結果

```
{"version":"1.0","sessionAttributes":{"count":"2"},"response":{"outputSpeech":{"type":"PlainText","text":"1 回目です。やたら、元気です。"},"card":{"type":"Simple","title":"カードここに書く","content":"今日は新しいことを学ぶチャンスが訪れるでしょう。 それをやり通せば可能性は無限です。"},"reprompt":{"outputSpeech":{"type":"PlainText","text":"他にも質問はありますか？"}},"shouldEndSession":false}}
```

# 成果物

https://embed.plnkr.co/plunk/w2mG3SHia76URwAY


以上。
VS CodeのGit関連の拡張機能が使えなくなったときに試したこと

# 記事の概要
VS Codeの拡張機能「Git Graph」が突然`No Git repositories were found in the current workspace when it was last scanned by Git Graph.`というエラーを吐いて表示されなくなってしまったときにやったことの備忘録。
※とき同じくして、「GitLens」という拡張機能も使えなくなった

# 環境
* Windows11

# やったこと
該当のファイル・ディレクトリを、`safe.directory`に追加する。たったそれだけ。

````
git config --global --add safe.directory 該当のファイルパス
````
Git Lensに関しては、上述の処理後、再インストールをすることで、再び履歴などを追いかけられるようになりました。

しかしリモートリポジトリ設定で`add.safedirectory`したはずなのになぁ……。
ライブラリなしでプッシュ通知を自作する

ポートフォワーディングができなかったり、ブラウザもインストールできないときに使えます。

https://github.com/GitHub30/own-push-notification

## 通知を待つ

音を鳴らすことも可能です。

### Windows

```powershell
$HttpWebRequest = [System.Net.HttpWebRequest]::Create('https://rppico-default-rtdb.asia-southeast1.firebasedatabase.app/msg.json')
$HttpWebRequest.Accept = 'text/event-stream'
$ResponseStream = $HttpWebRequest.GetResponse().GetResponseStream()
$StreamReader = [System.IO.StreamReader]::new($ResponseStream)

while (($line = $StreamReader.ReadLine()) -ne $null)
{    
    if (-! $line.StartsWith('data: {')){ continue }
    $ToastText01 = [Windows.UI.Notifications.ToastTemplateType, Windows.UI.Notifications, ContentType = WindowsRuntime]::ToastText01
    $TemplateContent = [Windows.UI.Notifications.ToastNotificationManager,Windows.UI.Notifications, ContentType = WindowsRuntime]::GetTemplateContent($ToastText01)
    $TemplateContent.SelectSingleNode('//text[@id="1"]').InnerText = ($line.Substring(6) | ConvertFrom-Json).data
    $AppId = '{1AC14E77-02E7-4E5D-B744-2EB1AE5198B7}\WindowsPowerShell\v1.0\powershell.exe'
    [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($AppId).Show($TemplateContent)
}

$StreamReader.Close() > $null
$ResponseStream.Close() > $null
```

### Mac

```bash
curl https://rppico-default-rtdb.asia-southeast1.firebasedatabase.app/msg.json -H Accept:text/event-stream --no-buffer \
  | grep '^data: {' --line-buffered \
  | while read line; do osascript -e 'display notification "'"${line:26:-2}"'"'; done
```

### Linux

```bash
wget --header Accept:text/event-stream -qO- https://rppico-default-rtdb.asia-southeast1.firebasedatabase.app/msg.json \
  | grep '^data: {' --line-buffered \
  | while read line; do notify-send "${line:26:-2}"; done
```

## 通知を送る

好きなメッセージを送ることもできます。

### Windows

```powershell
Invoke-WebRequest -Method PUT -Body ([System.Text.Encoding]::UTF8.GetBytes("`"🕊$(date -Format yyyy-MM-ddTHH:mm:ss.fff)`"")) https://rppico-default-rtdb.asia-southeast1.firebasedatabase.app/msg.json
```

### Mac

```bash
curl -X PUT -d '"🐥'$(date --iso-8601=ns)'"' https://rppico-default-rtdb.asia-southeast1.firebasedatabase.app/msg.json
```

### Linux

```bash
wget --method PUT --body-data '"🐧'$(date --iso-8601=ns)'"' -qO- https://rppico-default-rtdb.asia-southeast1.firebasedatabase.app/msg.json
```

## エンドポイント

[Firebase コンソール](https://console.firebase.google.com/)を開いて、URLをコピーします。

![Screenshot from 2022-08-14 02-15-45](https://user-images.githubusercontent.com/12811398/184504259-5bf12e7a-c2c4-438c-af09-52632830ff15.jpg)

![image](https://user-images.githubusercontent.com/12811398/184505058-3a7e5885-31d6-48cf-a026-baf32b4735d2.png)

# 参考

https://firebase.google.com/docs/reference/rest/database#section-streaming
SO-02Jの充電不可(バッテリー不良)でLINE移行できなかったので、SO-01Gのバッテリーを繋いで移行

# 背景
娘のスマホSO-02Jが充電しても起動できないと言われ、見てみると、赤ランプが点滅して充電がされていない状況のようであった。参考1などを見て、修理しないとダメってことで買った方が安いので、Xperia Ace を購入。しかし、LINEを移行しようとしたところ、参考2で診断した結果、引き継ぎ不可と出た。
壊れた端末を何とかして起動しないと！
で、昔使っていたSO-01G（中古で使っていたが落として破損）のバッテリーを使えばどうにかならないかとチャレンジ！

# SO-01Gを分解
参考3を見て、実施。
ドライヤーで温めてから実施したが、非常に取れにくく、背面が破損していたので、裏蓋が粉砕。
でも、何とかバッテリーを取り出せた！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211945/7954a5d6-2e15-28e8-d72a-fceac15b437a.png)

# SO-02Jを分解
参考4を見てから実施。
裏蓋を外して、NFCはくっつけたままで、バッテリーだけを外して横へコロンと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211945/18f63d2a-2180-d459-0173-b19dfc7755a2.png)

# SO-02JにSO-01Gのバッテリーを接続
虫眼鏡で端子を確認して、方向を合わせて接続。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211945/c2b804be-5374-2af8-c9f3-b34e11837774.png)
見事に起動した！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211945/70a88462-8582-342a-da3c-684b51174a9e.png)
端子が外れないようにそ～っと操作してLINEのバックアップとアカウント移行を設定し、無事に移行完了！(^^)v

# 参考
1. https://smahospital.jp/column/android/59776/
1. https://appllio.com/line-transfer-account-talk-data-when-iphone-android-smartphone-lost-broken
1. https://became-free.com/xperia-touchpanel-change/
1. https://www.youtube.com/watch?v=TJCy8tlz33M
Linux パーティションについて１



ハードディスクは「パーティション」と呼ばれる部分に分割して利用します。ディスク全体をひとつの領域とする場合にも、全容量を割り当てたひとつのパーティションを作る必要があります。

ハードディスク全体のパーティションの情報をパーティションテーブルと呼びます。パーティションテーブルの管理方式は従来のMBR（Master Boot Record）と新しいGPT（GUID Partition Table）の2種類。

●MBRでは、パーティションには基本（Primary）パーティションと拡張（Extended）パーティションがあり、基本パーティションは 4 個までしか作成することができません。それ以上の数に分割するためには、基本パーティションのひとつを拡張パーティションとして割り当て、そのパーティションをさらに論理（Logical）パーティションに分割します。
これらパーティションに関する操作には fdisk というコマンドを使用します。

fdisk [-l] デバイス名

サブコマンド
・m サブコマンドのメニュー表示
・l パーティションタイプの一覧表示
・n パーティションの作成
・d パーティションの削除
・p パーティションテーブルの表示
・t パーティションタイプ（システムID）の変更
・w パーティションテーブルの変更を保存して終了
・q ペーティションテーブルの変更を保存せずに終了


※「-l」オプションは指定したデバイスのパーティションテーブルを表示しますが、指定しない場合は、指定したデバイスのパーティションを対話的に操作することができます。

※作成したパーティションを利用するには、「mkfs」や「mke2fs」コマンドを利用してパーティションにファイルシステムを作成する必要があります。
また、作成したパーティションをスワップ領域として使用するには「mkswap」コマンドを利用


●GPTでは基本パーティションが128個作成できるようになっています。そのため拡張パーティション、論理パーティションという考え方はなくなりました。また、MBRにあったハードディスク容量が2.2TB（2TiB: テビバイト）までしか管理できないという制約がなくなり、理論上9.4ZB（8ZiB: ゼビバイト）までの容量のハードディスクを管理することができるようになっています。
GPTでのパーティションに関する操作には gdisk というコマンドを使用します。

各パーティションはただの領域であり、それだけではデータの読み書きに利用することができません。
パーティションをファイルシステムで「フォーマット」することで、ファイルを単位としたデータの管理が行えるようになります。
この操作には mkfs などのファイルシステムを作成するコマンドを使用します。

そして実際にファイルの読み書きを行うためには、さらにそのファイルシステムを現在のルートファイルシステム上のどこかにマウントし、ルート (/) からのパスを使ってアクセス可能にしなければなりません。
この操作には mount コマンドを使用します。

したがって、新しいハードディスクを Linux システム上で利用するためには
1. パーティションを切る（基本パーティション、拡張パーティション、論理パーティションを作成）
2. 各パーティションをフォーマットし、ファイルシステムを作る
3. 作ったファイルシステムをマウントする
という手順を踏む必要があります。

●パーティションの種類

・基本パーティション
基本パーティションは1つのハードディスクにMBRだと最大4個、GPTだと最大128個作成することができます。また、それぞれのパーティションにはファイルシステムを作成することができます。ファイルシステムを作成することで、パーティション内でファイルやディレクトリのようなデータを扱うことができるようになります。

1番目のSCSIハードディスクの基本パーティションは以下のように表します。

・/dev/sda1　1番目のパーティション
・/dev/sda2　2番目のパーティション
・/dev/sda3　3番目のパーティション
・/dev/sda4　4番目のパーティション

なお、MBRでは基本パーティションのうち1つを拡張パーティションにすることができます。

・拡張パーティション
論理パーティションを作成するためのパーティションです。拡張パーティションにファイルシステムを作成することはできません。
拡張パーティションは基本パーティションの1つに割り当てますので、上記のSCSIハードディスクの場合、表記は「/dev/sda1」から「/dev/sda4」のどれかになります。

・論理パーティション
論理パーティションは拡張パーティション内に作成します。MBRで管理するハードディスクにおいて、基本パーティションのみでは足りない場合(パーティションが5つ以上必要な場合)に論理パーティションを利用します。それぞれのパーティションにはファイルシステムを作成することができます。
なお、論理パーティションは作成された基本パーティションの数に関わらず、5番目のパーティションからの表記となります。上記のSCSIハードディスクの場合、「/dev/sda5」からです。
個別のcsvファイルから列を抜き出して一つの表にする→記事の内容よりコメント見てください(切実)！！！

### for文を用いて表を作る   
 &emsp;**自分用の備忘録です。もし参考になる方がいればコピペしてください！**   
**モチベーション：** たくさんの個別ファイルにcsvファイルが格納されている。その中で必要なcolumnのみを抜き出して新たに表を作りたい。しかし、個別ファイルの下記のGenes(遺伝子)の項目は変異があるときのみ記載されていて、変異がないときは表に入らない。従って、全てのファイルを結合して最終的に欠損しているところは変異なし(No Mutation)を入れることになる。

(追記 8/17) CbioPortalというサイトから遺伝子変異情報を集めて結合するときに使いました。自分自身PyThonそんなに得意ではなくてこのコードが無駄が多いとも思ってますのでコメントいただけると嬉しいです！ ⇨ @WolfMoon さんにRとPythonでのコードをいただきました、ということで動作するとはいえど素人の私のコードよりコメント欄を見ていただいた方が良いです！！！Sorry！

例：ファイル1, ファイル2, ・・・と各ファイルに患者データが入っている。例えばファイル1には患者番号0001のデータが下記のように格納されている。(Genesに対してMutationがあるときのみ行が作られているようなファイルで、Mutationがないときはそもそも列として入ってない)
|  Genes  |  Mutation Type  |Information| Project|
| ---- | ---- | --- | ---|
|  TP53  |  Missense  | Complete| IMPACT sequencing|
|  KRAS  |  Nonsesense  | Half-way| METABORIC cohort|
| EGFR  |  deletion  | Unevalueted| IMPACT sequencing|

|  Genes  |  Mutation Type  |Information| Project|
| ---- | ---- | --- | ---|
|  STK11  |  Missense  | Complete| IMPACT sequencing|
|  KRAS  |  deleteion  | Complete| IMACT sequencing|
| SMARCA4  | Nonesense  | Unevalueted| IMPACT sequencing|


といった個別ファイルがたくさんあります、、、、
このうち遺伝子変異情報のみを取り出し、それを各患者について集めて下記のような表を作りたい
|  PatientID  | TP53  | KRAS  | EGFR  |STK11  |SMARCA4  |
| ---- | ---- | ---- |---- |---- |---- |
|  Patient0001  |  Missense  |None  |Missense  |Missense  |Missense  |
|  Patient0002  |  None  |Indel  |Indel  |No mutation  |Missense  |
| Patient0003 |  deletion  | Nonsense  |Nonsense  |Deletion| No Mutation|

以下にコードを示す (Google colaboratory上を想定)
```python
from pandas._libs.algos import diff_2d
import pandas as pd
from pathlib import Path
import glob
#Google colab上でdataというフォルダに無数のcsvファイルを格納している
#従って、指定するpathは下記の通り
path = Path('/content/data')
#.csvとなっているcsvファイルを全て取得する。関係ないcsvファイルは消すか、より詳細に指定する
#最初にファイルが全部入ったリストを作っておく
file_list1 = glob.glob('**/*.csv')

for i, file in enumerate(path.glob('*.csv')):
#filenameを取得する。これは各個別ファイルの名前にPatientIDが入っているのを想定している
#例えばファイル名がPatient0001, Patient0002などとなっている際にこれを列に入れる
#[5:17]とは、file_list[i]がpathも含めたものを返すからである。試しにfilename[0]を出力してdata/PatientID0001/となっていれば欲しいのは[5:17]のみである
    filename=file_list1[i][5:17]
#csvファイルを読み込む
    df = pd.read_csv(file)
#各ファイルからほしい列を抜き出してリストにする
    genes=df["Genes"].tolist()
#insertしているのは、個別の表を転置して結合するので、一番左の列を新しく作るため
    genes.insert(0, "PatientID")
    mutation=df["MutationType"].tolist()
    mutation.insert(0,filename)
    df2 = pd.Series(data = mutation, index = genes)
    df2 = pd.DataFrame(df2).T
#colab内にshapedという名前のファイルを作り、そこへ格納する。
    df2.to_csv('shaped'+str(filename)+'.csv')

csv_files = glob.glob('*.csv')
#csvファイルの中身を追加していくリストを用意
data_list = []
#読み込むファイルのリストを操作
for file in csv_files:
    data_list.append(pd.read_csv(file))
#リストを全て行方向に結合
#axis=0:行方向に結合, sort
df = pd.concat(data_list, axis=0, sort=True)

df.to_csv("complete.csv",index=False)
```
WIndowsのSourcetreeでSSHのURLでリポジトリのクローンができない

私はMacユーザーですが、Windowsだと少し違うんだということを知ったので。

## 手順
1.Gitをインストール
2.SSHキーを生成
3.Gitlabに公開鍵を登録
4.Gitコマンドでお試しリポジトリにブランチ作成、ダミーデータをコミット、プッシュ

## 問題発生の経緯
ここから、私はよくSourceTreeを使うので、インストールし、
お試しリポジトリのクローンをSSHのURLから作成して、問題なくコミットプッシュまでできました。

ただ、Windowsユーザの人がSourceTreeをインストールして、
同じようにSSHのURLからリポジトリをクローンしようとしたら、
なにやらSSH鍵に関するエラーがでてきて、クローンを作れなかった。

## 調べてみた
そんなことがあるのか、と調べてみると、SSH鍵って種類があるんですね。
MacだとデフォルトでOpenSSHという種類のものが入っていて、
GitもデフォルトOpenSSHなので、特に意識することなく使用できていたのですが、
WindowsだとデフォルトでOpenSSHがない（？設定がされていない？）。

Windowsの場合、手順1のGitをインストールの時点で、
OpenSSHが使用できるようオプションで選べるようで、
コマンドラインからGitを使用する場合であれば、上記手順のままでOKみたいです。

ただWindows版SourceTreeだと、基本PuTTYという種類のSSHクライアントを使用するようになっているとのこと。
PuTTYだと鍵の保存場所もOpenSSHと違ったりしてなにやら面倒くさいことになってきたなぁという時に、
下記ページをみつけました。

## 解決の参考になったページ
https://community.atlassian.com/t5/Sourcetree-questions/Cloning-over-SSH-Doesn-t-Work-for-a-Remote-Account-When-Repo-Has/qaq-p/879008

要するにSSHクライアントの種類をPuTTYではなく、OpenSSHを使用するように設定すればOKとのこと。

## ただし
手順1のGitインストールの時点で、HTTPS接続の場合にOpenSSHライブラリを使用するように選択していれば、
別にSSHのURLからクローンを作成せず、HTTPSのURLからクローンを作成するのでもOKだったぽいですね。
SSHのURLにこだわる必要もなかったみたいです。

https://www.sejuku.net/blog/72673

## 最後に
SSHについて深いところまでわからないままですが、種類があるのを知れたので、へぇ〜という感じでした。
PuTTYの小さいuは一体なんなんだよ。
【Rails】devise_token_auth でパスワードをリセットする流れをまとめる


RailsAPI でパスワードリセットを実装したので、議事録として残します。

# 目的

devise_token_authにて、パスワード再設定を実装する

# パスワードリセットの流れ
![スクリーンショット 2022-05-29 15.51.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690622/27ceb0c8-01bf-390b-f6e1-b8166953f625.png)


1. パスワードリセットメールを送信する
2. 送信されたメールのリンクから、パスワード再設定画面へ遷移する
3. パスワードを更新する

# passwords_controller.rbの各アクションについて

passwords_controller.rbで定義されている3つのアクションを使用します。

https://github.com/lynndylanhurley/devise_token_auth/blob/master/app/controllers/devise_token_auth/passwords_controller.rb#L3

# password#create

パスワードリセットメールを送信する

![スクリーンショット 2022-05-29 15.49.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690622/972665c1-69e9-c748-7f5f-b3983c93a9ad.png)

## 詳細

リクエスト: post passwords#create

パラメータ：redirect_url, email

リクエストのタイミング： 送信ボタンをクリックしたとき

email: リセットメールを送信するメールアドレス。そのメールアドレスを持つユーザーが存在することが前提。

redirect_url: リセットメールをクリックした後に遷移するURL

## 結果

- ユーザーに認証に使用する情報が登録される

```ruby
# 更新されるカラム
reset_password_token: nil → トークン
reset_password_sent_at: nil → メール送信日

#  reset_password_token: 認証用トークン。リセットメールのリンクにも付与され、editアクションで認証を行うために使用
#  reset_password_sent_at: リセットメールの送信日。有効期日かどうかの判定に使用
```

- リセットメールが送信される

リセットメールのリンクに、ユーザーに付与されたreset_password_tokenがが埋め込まれる

# password#edit

リセットメールのリンクに付与されているトークン情報を元に、認証を行う。

認証に成功した場合、パスワード再設定画面に遷移する

![スクリーンショット 2022-05-29 15.49.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690622/92bbd440-3dee-b8a9-fa30-0cef9d872ab5.png)

## 詳細

リクエスト：patch password#update

パラメータ： reset_password_token, redirect_url

リクエストのタイミング： 「リセットメールのリンク」をクリックしたとき

## 結果

- 認証情報の判定を行う
    - メールに付与されている tokenと、password#create でユーザーに保存したreset_password_token が一致しているか
    - rest_password_sent_at が期日内であるか


- 認証が成功した場合、ユーザーの情報が更新される

```ruby
# 更新されるカラム
allow_password_change:  false → true
```

- 認証が成功した場合、指定されたURLに遷移する
- password#create で指定されてた redirect_url に遷移する
    

# passwprd#update

パスワードを更新する
![スクリーンショット 2022-05-29 15.49.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690622/190bbf91-ee7a-b3cd-77ca-b4142f16d249.png)


### 詳細

リクエスト：patch password#update

パラメータ：password, password_confirmation,reset_password_token

リクエストのタイミング： 「パスワードの設定ボタン」をクリックした時

*パラメータで必要である `reset_password_token` は、urlに付与されているので、それを使用する

```ruby
# 例
# 分かりやすいように、他のパラメータは省略しています。
# &token="パラメータに含めるトークン"
http://localhost:8000/password_updatereset_password=true&token=S4XXFnUGy1FR2IXinixU9w
```

## 結果

- ユーザーのパスワードを更新される
`encrypt_password` に再設定したパスワードを暗号化して保存する
- パスワード更新に関わるカラムが更新される

```ruby
# 更新されるカラム
reset_password_token: トークン → nil
reset_password_sent_at: リセットメール送信日 → nil
allow_password_change: true → false
```
以上の3つのアクションを利用することで、パスワード再設定を実現することができました。

# まとめ

- 必要なパラメーター、値がどのように変化するかを把握することができました。

# 補足

1. 有効期限は `devise.rb` で設定できる

```ruby
# devise.rb

# パスワードの有効期限
config.reset_password_within = 1.hours
```

2. パスワードが変更されたときに再度クリックしたとき、ルーティングエラーになるので、別途対応が必要。
超簡単firewalldのコマンド一覧

超簡単firewalldのコマンド一覧です。
メモ程度です。

起動
systemctl start firewalld

終了
systemctl stop firewalld

自動的に起動させる
systemctl enable firewalld

起動状態チェック
systemctl status firewalld

現在の設定
firewall-cmd --list-all
more /etc/firewalld/zones/public.xml

会社からのアクセスを全て許可しとく
firewall-cmd --remove-service=ssh --zone=public --permanent
firewall-cmd --permanent --zone=public --add-rich-rule="rule family="ipv4" source address="xxx.xxx.xxx.xxx" port protocol="tcp" port="22" accept"

7000のポートを開けてみる。
firewall-cmd --add-service=7000  --zone=public --permanent

設定を反映させる
firewall-cmd --reload
Dockerで環境構築するときに 'Host 'IPアドレス' is not allowed to connect to this MySQL server' というメッセージが出る。

## 背景

Docker + MySQL で環境構築をしていると下記のメッセージに遭遇することが多かったので調べた。

```
Host 'IPアドレス' is not allowed to connect to this MySQL server
```

## 原因
不明。

キャッシュが残っていることが原因だと思うけどうまく説明できるようにしたい。




## 解決策

一応「キャッシュが残ってるから消してみてねー」という風な記事が多かったので対応するコマンドを打つことにより解決した。

```
docker-compose down --rmi all --volumes --remove-orphans
```


## 解説

- `docker-compose down` : 
docker-compose up で作成したコンテナ、ネットワーク、ボリューム、イメージを削除。
   
- `--rmi` :  イメージの削除。今回は allというオプション。
- `--volumes` : Compose ファイルの `volumes` セクションの名前付きボリュームを削除。　また、コンテナがアタッチした匿名ボリュームも削除。
- `--remove-orphans` : Compose ファイルで定義していないサービス用のコンテナも削除。
AWSでEC2でWebページを公開メモ

昔　AWSでEC2でWordPressやEC-Cubeで色々やっていたのですが
違う業界（？）に行っていたので忘れてしまった気がするので再設定のメモ失礼します。

イ）まずルートユーザーのアカウント作成

ロ）EC2起動っ

ハ）Puttyでアクセス出来るようにする。

（以下コメントで追記予定）
enebularでalexaスキル

# 概要
enebularで、alexaスキルのwebhookを返してみた。
herokuに、デプロイしてみた。
サービスリクエストをスクラッチで組み立てて、plunkerから、叩いてみた。

# 参考にしたページ

https://qiita.com/sayakaitooo/items/c6b3e177a409a3be0791

# node-redのフロー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/77a2736a-c55a-c522-7cd1-6c7bb948719e.png)

# 投入したjson

```
{
	"session": {
		"new": true,
		"sessionId": "SessionId.hogehoge",
		"application": {
			"applicationId": "amzn.hogehoge"
		},
		"attributes": {},
		"user": {
			"userId": "amzn.hogehoge"
		}
	},
	"request": {
		"type": "IntentRequest",
		"requestId": "EdwRequestId.hogehoge",
		"intent": {
			"name": "hogehoge",
			"slots": {
				"gohanNames": {
					"name": "gohanNames",
					"value": "カツカレー"
				}
			}
		},
		"locale": "ja-JP",
		"timestamp": "2017-11-20T07:43:46Z"
	},
	"context": {
		"AudioPlayer": {
			"playerActivity": "IDLE"
		},
		"System": {
			"application": {
				"applicationId": "hogehoge"
			},
			"user": {
				"userId": "hogehoge"
			},
			"device": {
				"supportedInterfaces": {}
			}
		}
	},
	"version": "1.0"
}

```

# 実行結果

```
{"version":"1.0","sessionAttributes":{"count":1},"response":{"outputSpeech":{"type":"PlainText","text":"発言がぬるぽでした。もういちどおねがいします。"},"card":{"type":"Simple","title":"GenkIntentに入ったけど、GenkiSlot=nullですぜって表示される","content":"発言がぬるぽでした。もういちどおねがいします。"},"reprompt":{"outputSpeech":{"type":"PlainText","text":"他にも質問はありますか？"}},"shouldEndSession":false}}
```

# 成果物

https://embed.plnkr.co/plunk/fTD6zrJmrKhsVmsG

以上
C言語 環境構築

# 目次
1. はじめに
1. gccインストール
1. 確認

# 1. はじめに
事前に以下のものは実行済とする
>vscodeインストール
>vscodeにて拡張機能Cをインストール

# 2. gccインストール
gcc - C言語のコンパイラ

[Windows]
>参考サイト
>https://katakago.sakura.ne.jp/pgm/gcc.html

以下のサイトの左側の tdm64-gcc-10.3.0-2.exe をクリック

https://jmeubank.github.io/tdm-gcc/

# 3. 確認
C言語ソースファイルを作成
```c:test.c
int main(){
	printf("Hello World!");
	return 0;
}
```
先ほどインストールしたgcc.exeのpathを取得して、コンパイル
```bash
"<インストール先パス>\gcc.exe" -o test.exe test.c
```
test.exeを実行して Hello World! と出力されたらOK
Elasticsearchクラスタ検証(6): クラスタの基本構成

##### [前回] [Elasticsearchクラスタ検証(5): Elasticsearchシステム構成の基本](https://qiita.com/mingchun_zhao/items/92929225d06e3e596324)

## はじめに

Elasticsearchクラスタの基本構成と用語をおさらいします。

## Elasticsearchクラスタとは

- 各ノードが固有の役割を持ち、お互い通信しながら協調動作

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523098/e21d0158-c2ef-1a23-94d7-fc42c1bde7fa.png)

※ 引用元: https://raw.githubusercontent.com/exo-addons/exo-es-search/master/doc/images/image_05.png

## ノードの種類と役割

- Master(Master-eligible)ノード
    - Masterノードはクラスタのリーダー
        - クラスタ管理を担当し、クラスタに必ず1台存在
    - Master-eligibleはリーダー候補
        - Masterノードがダウンしたら、Master-eligibleから選出
    - 役割
        - 全ノードの管理(参加、離脱、生死)
        - クラスタメタデータの管理
        - シャードの管理(割り当て、再配置)
- Dataノード
    - データ格納を担当
    - Luceneインデックスファイルのマージ
    - クライアントからのインデックスリクエストをハンドリング
        - 格納対象シャード番号を決定し、処理をルーティング
    - クライアントからの検索リクエストのハンドリング
        - 関係する複数ノードのシャードへ処理をルーティング(scatter)
        - 各ノードの結果を集約し返却(gather)
- Ingestノード
    - クライアントからのデータに対し前処理を行う
    - パイプラインを定義可能
- Coordinatingノード
    - クライアントからのリクエストのハンドリングのみ行うための専用ノード
        - scatter
        - gather
    - 役割
        - 負荷分散
        - Aggregateなど高負荷処理を切り出す

## Masterノード選出とノードのクラスタ参加

### クラスタブートストラップを設定

- クラスタの最初の形成時のみ必要
- Masterノードは投票によって選出される
    - 投票設定として、Master-eligibleノードの初期セットの設定が必要
- 設定方法(elasticsearch.yml)
    - `cluster.initial_master_nodes`
- 各ノードで投票設定の共有
    - クラスタ参加済みノードは、データフォルダ内に投票設定を格納し再利用
    - 新規参加ノードは、選出されたMasterノードから情報を受け取る

### ディスカバリサブシステムを設定

- ノードがお互いを見つけられるようにするための設定
- 設定方法(elasticsearch.yml)
    - `discovery.seed_hosts`
    - `discovery.seed_providers`

### スプリットブレインの問題

- スプリットブレインとは

ネットワーク障害などによりクラスタが二つに分断され、
それぞれMasterノードを持つ複数クラスタになってしまう事象

- Masterノードの表記
    - ◆ 

- スプリットブレイン前は1つのクラスタ
    - { [node1◆] [node2] [node3] [node4] }
        - Masterノードは、node1
- スプリットブレイン後は二つのクラスタ
    - { [node1◆] [node2] }
        - Masterノードは、node1
    - { [node3◆] [node4] }
        - Masterノードは、node3

## おわりに

Elasticsearchクラスタの基本構成と用語をおさらいしました。
次回も続きます。お楽しみに。
LPIC Lv1-101 ハードウェアの設定についてまとめてみた

# はじめに

LPIC Lv1-101
ハードウェアの設定についてまとめてみた

# 最終更新日

2022年08月16日


# 環境の情報

OS
Ubuntu20.04


# 注意

最新の状態を確認して下さい。


# 公式さま

https://www.lpi.org/

# 参考さま

https://mondai.ping-t.com
https://uquest.tktk.co.jp/embedded/learning/lecture15-1.html
https://qiita.com/uguis410/items/17ec1e447e9716bfdca7


# カーネルは何しているのか？
・プロセス管理
・プロセススケジューラ
・メモリ管理
・ファイルシステム




# /proc/meminfo
メモリの使われている状況を示す。


# SCSIデバイス
SCSIバスに繋げる機器のこと。


# DMA方式
制御する機能のこと。
CPUを介さずに「直接」メモリにアクセスすること。周辺機器とメモリとのデータのやり取りを行う。



# DMAチャネル
DMA channel
通信経路。
DMAの転送において各装置が、DMAコントローラに対して、転送を求めるに使われる。



# /proc/scsi/scsi
SCSIデバイスに関する情報を示す。


# /proc/dma
デバイスが使われているDMAチャネルに関する情報を示す。


# modprobe
コマンド。
依存関係を考えて、カーネルモジュールを、
ロードまたはアンロード（読み込んで展開されたプログラムやデータを消して、占有していた記憶領域を解放すること）をする。

# lsusb
コマンド。
接続されたUSBデバイスの情報を表示する。


# /proc/bus/usb/devices
接続されたUSBデバイスの情報が格納されている。



# /proc/interrupts
IRQに関する情報が書いてある。



# IRQ
Interrupt ReQuest
マウスやキーボードなどの周辺機器(デバイス)からCPUへの割り込み要求のこと。




# Audio Class
USBのデバイスクラス。
スピーカー、マイクなどが属している。


# sysfs
/sys以下
カーネルは、デバイスを検知すると情報を更新する。
その更新をudevは検知し、/dev以下にデバイスファイルを動的に作る。


# /etc/udev/rules.d
拡張子「.rules」の設定ファイルが置ける。
デバイスファイルが作られた時は、
「/etc/udev/rules.d」ディレクトリに
配置された設定ファイルに、
記述された情報に基づいて行われる。















# lspci
コマンド。
PCIデバイスの情報を表示する。


# /proc/cpuinfo
CPUに関する情報が書いてある。


# lspciコマンドで取得できる情報。
I/Oポートアドレス
ベンダー名（ベンダーID）
バスの速度
IRQ番号


# PCIデバイス
Peripheral Components Interconnect
PCIバスに接続されたデバイスのこと。
ネットワークカード(NIC:Network Interface Card)やSCSIカードなどがある。



# modprobeの設定ファイルに記述できる設定。
options
alias
install
remove
blacklist
お母さんでもわかるJavaScript returnについて

returnを理解するのは難しくまだまだ勉強中ですが、基礎を私なりにまとめてみました。

「値を返す」と「戻り値」の関係性は下記画像参照。
![F1A0073C-C4F6-4FD8-B3CB-868B80503ABE.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782070/a3ec0c49-224b-5101-e138-eb681ae19964.jpeg)


# returnとは

私なりの言葉で伝えると ”形にする” です！
例えば学校のテストで「１＋１」の問題が出たときに、頭の中で答えを思い浮かべるだけでは0点です。
ではどうやって点数を取るか・・・。それはテストの解答欄に「2」と記述すれば取ることができます。

つまり「return」はプログラミング上の、「テストの解答欄に記述する作業」だと思ってくれれば理解しやすいかなと思います！

頭の中で答えを思い浮かべただけの作業例２選！
```main.js
function sum(a, b) {
  a + b; 
}
const sum1 = sum(1, 2);
const sum2 = sum(3, 4);
sum3 = sum1 + sum2;

console.log(sum3); //NaN(値がない)
```

```main.js
function sum(a, b) {
  console.log(a + b); 
}
const sum1 = sum(1, 2);
const sum2 = sum(3, 4);
sum3 = sum1 + sum2;

console.log(sum3); //NaN(値がない)
```
紛らわしいですが「console.log()」は形にするものではなく、ブラウザのコンソールで確認するだけのもの。
つまり、、、解答欄にはまだ答えを記述していない!


ではどうすれば解答欄に答えを記述することができるのか。
↓
```main.js
function sum(a, b) {
  return a + b; 
}
const sum1 = sum(1, 2);
const sum2 = sum(3, 4);
sum3 = sum1 + sum2;

console.log(sum3); //10
```
このようにreturnを記述することで、sum(1, 2)とsum(3, 4)のsumに「戻り値」という答えを返してあげることができる。
返すとそこに「値 = 答え」が存在しているので、計算に使うこともできちゃう

## まとめ
とりあえずreturnを使わないと”形”にならないんだなーと思ってくれれば大丈夫かなと思います。
もしご指摘等があれば教えてくれると助かります。。。
ログイン機能を実装中（自分でログインできない)

ログイン機能を実装中（自分でログインできない）

シードファイル
rails db:seed
テーブルのサンプル読み込みの役割

bundle exec rake db:seed
を行ってからログインする

シードファイル
rails db:seed
テーブルのサンプル読み込みの役割
を忘れていた。

seedデータとは
初期データやテストデータのことで動作確認用データを登録する目的で行います。投入したいデータの件数が増えた場合にもこれさえあれば迅速に投入できる環境を構築することができます。
seedデータの投入
下記コマンドを実行します。

rake db:seed
dockerを使用している場合
docker-compose exec web bundle exec rake db:seed
をおこなえば良い。


ファイルにgemを入れる
bundle install

テーブルの作成
rails db:create

マイグレーションを実行
rails db:migrate

テストの実装
rake db:seed

の流れ

❯ bundle exec rake db:seed
を叩いたところ解決しました。
rtsp の使い方

gstreamer で動画を送信し、mpv で受信する方法です。
次のページを参考にしました。
[GStreamerを使用したRTSPサーバを構築し、Macから動画を送信してみました。](https://dev.classmethod.jp/articles/amazon-kinesis-vidseo-streams-gstreamer-rtsp-server/)

## 送信サーバー

必要なライブラリーのインストール

```bash
sudo apt install automake
sudo apt install autopoint
sudo apt install libtool
sudo apt install gtk-doc-tools
sudo apt install libglib2.0-dev
sudo apt install gstreamer1.0-plugins-base gstreamer1.0-tools
sudo apt install libgstreamer1.0-dev
sudo apt install libgstreamer-plugins-base1.0-dev
```

ソースのダウンロードとコンパイル

```bash
git clone git://anongit.freedesktop.org/gstreamer/gst-rtsp-server
cd gst-rtsp-server
git checkout 1.4
./autogen.sh
make
sudo make install
```

mp4 の送信

```bash
cd examples
./test-mp4 /tmp/sample-5s.mp4
```

```text
$ ./test-mp4 /tmp/sample-5s.mp4 
stream ready at rtsp://127.0.0.1:8554/test
```

## mpv で受信

```bash
mpv rtsp://localhost:8554/test
```

## ffplay で受信

```bash
ffplay rtsp://127.0.0.1:8554/test
```

## python3-opencv で受信

ライブラリーのインストール

```bash
sudo apt install python3-opencv
```

```py:camera.py
#! /usr/bin/python
#
#	camera.py
#
#					Aug/16/2022
# ------------------------------------------------------------------
import sys
import cv2
#
# ------------------------------------------------------------------
sys.stderr.write("*** start ***\n")
url = 'rtsp://127.0.0.1:8554/test'
cap_file = cv2.VideoCapture(url)
print(type(cap_file))
print(cap_file.isOpened())
width = cap_file.get(cv2.CAP_PROP_FRAME_WIDTH)
height = cap_file.get(cv2.CAP_PROP_FRAME_HEIGHT)
print(height,width)

while True:
	ret, frame = cap_file.read()
	if ret:
		cv2.imshow('frame',frame)
		if cv2.waitKey(1) & 0xFF == ord('q'):
			break
	else:
		break

cap_file.release()
cv2.destroyAllWindows()
#
sys.stderr.write("*** end ***\n")
# ------------------------------------------------------------------
```

実行結果

```text
$ ./camera.py 
*** start ***
<class 'cv2.VideoCapture'>
True
1080.0 1920.0
*** end ***
```
Salesforceの「取引先責任者へのケースコメント通知を有効化」について調べてみた

Salesforceのサポート設定で
「取引先責任者へのケースコメント通知を有効化」というチェックがあります。

今回はこの「取引先責任者へのケースコメント通知を有効化」について調べてみました


![サポート01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/71e43e7e-2522-ddca-6594-9b655176592c.png)

## 有効すれば何が設定できるの？

ケースコメントの部分に
・通知メールを送信する
のチェックが出ます
![ケースコメント.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/7ac8b969-608f-cf19-5047-c82418ac669d.png)

こちらの
・通知メールを送信する
のチェックをして「保存」をすると、メールテンプレートで設定したメールを送信します
（メールの送信先は取引先責任者のメールです）

ちなみに、送信されたメールをお客様が返信してもSalesfoceにデータが返信内容が記録されることはないです

## どういう場合に使用するの？
では、この「取引先責任者へのケースコメント通知を有効化」はどのような場合に使うでしょうか

ヘルプを見てましょう

※参考ヘルプ
ケースフィードのポータル返信メール通知の有効化
https://help.salesforce.com/s/articleView?id=sf.case_interaction_enabling_portal_email_notifications.htm&type=5

より抜粋

＞組織でポータルまたは Experience Cloud サイトを使用している場合、サポートエージェントはケースフィードのアクションを使用して顧客に応答できます。

この機能はExperience Cloudを利用している場合、Experience Cloudユーザにケースコメントのメール通知をする場合に使用する機能です

Experience CloudのメンバーとしされているExperience CloudユーザがExperience Cloud上から作成したケースレコードでは、デフォルトで取引先責任者がExperience Cloudユーザになります。

なので内部Salesforceユーザがケースコメントを作成した際、Experience Cloudユーザにメール通知したい場合に使える機能です

## そもそもExperience Cloudって何？

簡単にざっくり言えば「Salesforce上でサイトを作成し、お客様をサイトに読んでコミュニケーションできる」機能です。詳細はTrailheadなどをご確認ください

※参考Trailhead
Experience Cloud の使用開始
https://trailhead.salesforce.com/ja/content/learn/modules/community_cloud_basics/communities_intro_to_community_cloud

## 分かりやすいように（？）図にしてみた

![Salesfroce環境.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/840743df-05f2-91d1-ea84-f3ac8db81be6.png)
「循環小数（英: recurring decimal、repeating decimal）」について調べてみた。

オリジナル

https://ja.wikipedia.org/wiki/%E5%BE%AA%E7%92%B0%E5%B0%8F%E6%95%B0

https://en.wikipedia.org/wiki/Repeating_decimal

# wolframalphaで

https://www.wolframalpha.com/input?i=%E5%BE%AA%E7%92%B0%E5%B0%8F%E6%95%B0&lang=ja

# 入試問題
循環節の長さ4桁,円グラフ,素因数分解,連分数,エジプト式分数＜wolframalpha

https://kamelink.com/blog/2022/08/16/13-2-22-touhokugakuinndai-kou-a-1-1/
【初心者】HTTP/3の特徴を調べてみた

# 背景・目的
CloudFrontでHTTP/3がサポートされた[ブログ](https://aws.amazon.com/blogs/aws/new-http-3-support-for-amazon-cloudfront/)を見つけました。
HTTP/3をあまり良くわかっていないので、このタイミングで概要を学ぼうと思います。

# まとめ
- HTTP/3はQUICという技術を使用している。
- 転送はバイナリで行われる。
- ハンドシェイクが1回だけで済む。（従来はTCPやTLSでは複数回のハンドシェイクが必要とされていた）
- UDPを基盤として使用している。
- メタデータを含めて完全に暗号化され、通過するNATデバイス、ファイアウォールなどで参照、操作がされない。
- TLS1.3を必須としている。
- 低速NW、遅延の影響を受けやすい接続で実行速度が向上する。

# 概要
## What is HTTP/3?
> HTTP/3 は QUIC を使用し、TCP の制限の多くを克服し、それらの利点を HTTP にもたらします。 TCP および TLS で既存の HTTP/2 を使用する場合、TCP はクライアントとサーバー間のセッションを確立するためにハンドシェイクを必要とし、TLS もセッションが保護されていることを確認するために独自のハンドシェイクを必要とします。各ハンドシェイクは、クライアントとサーバーの間で完全な往復を行う必要があります。これは、クライアントとサーバーがネットワーク的に遠く離れている場合、長い時間がかかる可能性があります。しかし、QUIC は安全なセッションを確立するために必要なハンドシェイクは 1 回だけです。

> また、TCP は、ファイアウォールやネットワーク アドレス変換 (NAT) デバイスなど、無数のさまざまなミドルボックスによって理解され、操作されます。 QUIC は UDP を基盤として使用して、企業またはパブリック ネットワークでのパケット フローを許可し、メタデータを含めて完全に暗号化されるため、ミドルボックスはその詳細を検査または操作できなくなります。
HTTP/3 ストリームは個別に多重化され、リクエストとレスポンス間のヘッドオブライン ブロッキングを排除します。これは、HTTP/2 over TCP のようなアプリケーション層ではなく、トランスポート層でストリームの多重化が行われるため可能です。これにより、特に低速のネットワークや遅延の影響を受けやすい接続で、Web アプリケーションの実行速度が向上します。


- QUICを使用している ＝ RFCドラフト「Hypertext Transfer Protocol(HTTP) over QUIC」を使用している。
    - QUICは、Googleによって開発された実験的なトランスポート層プロトコルです。
- HTTP/2とHTTP/3の通信の動作は、下記の通り。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/65b884c5-e06f-2ec3-1398-0ac837ebd8fc.png)
※出典：[　New – HTTP/3 Support for Amazon CloudFront](https://aws.amazon.com/blogs/aws/new-http-3-support-for-amazon-cloudfront/)

### なぜHTTP/3で、通信速度が速くなるのか
- 接続確立時のハンドシェイク数の減少
    - HTTP/2では、TCPを使用している。TCPでは信頼性確保のためスリーウェイハンドシェイクが必須になっており、通信の状態を確認するために3回の通信が必要になりオーバヘッドが多い。
    - HTTP/3では、1度のスリーウェイハンドシェイクにより通信が確保され暗号化されれば、その後のハンドシェイクは不要になる。
- ヘッドオブラインブロッキングの解消
    - 従来、UDPはTCPよりも信頼性が低く、手続きは簡単、リアルタイム処理向きとされていた。
    - HTTP/3では、TCPではなくUDPを採用しTCP特有のヘッドオブブロッキングを回避しつつ、通信の信頼性を担保するためのデータの再送要求や、パケットロス対策が施されている。
        - パケットロスが発生しても、各パケットのデータ転送は止まらず、ロスのあったパケットのみ再送される。
    - HTTP/2では、ヘッダー圧縮にHPACKという仕様が使われてきた。TCPの手続きに合わせた仕様であり、HTTP/3ではこれがQPACKというUDPやHTTP/3に合わせた新しい仕様でヘッダーの圧縮を効率化している。
- 優先度制御の再設計
    - HTTP/2では、複数のHTTPリクエストを処理しリクエスト処理の優先度制御が取り入れられており、画像やCSSなどどのような順番で読み込むかといった制御が可能であった。しかし、この優先度制御を行うために使用されている順序ツリーは複雑でブラウザにより、表示速度や表示順に違いが生まれていた。
    - HTTP/3では、拡張仕様としてヘッダーに優先度を明確に指示ができるようになっている。
    - これにより、ファーストビューを優先的に制御できる。

## HTTP/3を利用するための条件
- クライアントとサーバがHTTP/3に対応していること
    - サーバがTLS1.3が利用できることが必要。
    - クライアントは最近のブラウザを使っていれば良さそう。
- NWでは、クライアントとサーバの両方でUDPの443ポートが開放されている必要がある。
    - TCPはあるがUDPはまだそれほど多くなさそう。
- ファイアウォールやセキュリティソフトなどでUDP443の利用を許可すること
    - UDPは、DDoSなど使われることもありセキュリティルールによりポート開放されていない場合もある。

::: note
HTTP/3による通信ができない場合でも、従来のTCPを使ったHTTP/2や1の通信は可能とのこと。
:::

# 考察
HTTP/3の採用により、通信速度が向上するサイトが増え、利用側としても気づかずに恩恵が受けられそうです。
Googleさんのように、このような基礎的な技術に貢献している方たちに感謝です。

# 参考
https://aws.amazon.com/blogs/aws/new-http-3-support-for-amazon-cloudfront/

https://ja.wikipedia.org/wiki/HTTP/3

https://directcloud.jp/contents/webhttp-3quic/
ActiveRecord::PendingMigrationError

ActiveRecord::PendingMigrationError


You have 2 pending migrations:
 2件の保留中のmigrationファイルがある。
→rails db:createは終わっているが、rails db:migrateしていないでしょと言われている。何をrails db:migrateしていないのかを確認するために

 rails db:migrate:statusを行う

＊
migrationは、SQL文を書かずにデータベースの構造を変更したり、元に戻したりできる

実行後の内容
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20220815060217  ********** NO FILE **********
   up     20220815060220  ********** NO FILE **********
   up     20220815073501  ********** NO FILE **********
  down    20220815144028  Devise create admin users
  down    20220815144031  Create active admin comments

Status欄に「up」と表示されているmigrationファイルは、データベースに適用済みです。
一方、Status欄に「down」と表示されているmigrationファイルは適用されていません。

migrationファイルが増えてきたり、up/downで編集することが多くなったときは、再現性（冪等性：べきとうせい）を確認する。
再現性を確認するためには、データベースを一度削除してから、すべてのmigrationファイルを適用して、実行結果を確認すれば良い。
データベースを一度削除したり再適用したりといった作業が大変そうなイメージですが、railsではbin/rails db:migrate:resetコマンドを実行するだけです。


rails db:migrate:resetを行ったあと

Running via Spring preloader in process 91209

database: active_admin_sample_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20220815144028  Devise create admin users
   up     20220815144031  Create active admin comments

再度rails sを実行すると
エラーが解消され、正常に起動した。



以下
https://qiita.com/Jwataru/items/78074acc463620a2311a
の引用

三つのパターン
1.単純にrails db:createのあとrails db:migrateし忘れている
マイグレーション実行の下記のコマンドを打ち込みましょう
$ rails db:migrate

 2.すでにmigrationが完了している(up)状態でマイグレーションファイルを更新しrails db:migrateしてしまった
方法１ 既存のテーブルを全削除し、再度マイグレーションの状態をupにする下記のコマンドを打ち込みましょう
$ rails db:migrate:reset

方法２（未実施） マイグレーションの最新のものだけ実行を取りやめて編集可能(down)にするコマンドrails db:rollbackののち、マイグレーションファイルの更新コマンドrails db:migrateを打ちましょう

$ rails db:rollback
$ rails db:migrate

※マイグレーションの状態を調べるコマンドは下記の通りです

$ rails db:migrate:status

 3,マイグレーションファイルの中に入れた外部参照キーが参照するテーブルがない状態でrails db:creatしてしまった
①-1外部参照されるマイグレーションファイルを作成し、app/modelの中のファイルにアソシエーションを追記（または修正）する ①-2マイグレーションファイルから不必要な外部参照キーを消す
②上記①のどちらかの修正のあとに下記コマンドを打ち込みましょう
$ rails db:migrate:reset

4,すでにデータベースにレコードを入れてしまい、それを残したまま修正する方法（補足）
新たに追加したい項目のテーブルを作成し、本来追加したかったテーブルのidを外部キーとする方法をとりましょう。



https://qiita.com/Jwataru/items/78074acc463620a2311a

https://www.sejuku.net/blog/14229

こちらに助けられました。ありがとうございます。
pycordでボイスチャンネルに接続するdiscord botを書いてみた

仕事などでdiscordでミーティングしている時、「予定していた時間を過ぎても参加者が居たらアラート音声を再生するbotとかあったら便利では？」と思ったので、ざっくりと作った過程の覚書。

discord botを作るためのPythonライブラリは何がいいのか調べたが、[pycord](https://docs.pycord.dev/en/master/)が良さそうだったのでこれに決定。
決定理由及びpycordの導入については下記の記事を参考にした。

* https://qiita.com/melonade/items/25c038e8e4e6800aa639

discord bot自体の準備については下記を参考にした。

* https://discordpy.readthedocs.io/ja/latest/discord.html

## 実装

```python:timer-bot.py
import asyncio
import sys

import discord
from discord.commands import Option
bot = discord.Bot()

@bot.slash_command(guild_ids=['...']) #コマンドをインストールするサーバーIDを列挙。グローバルコマンドにするには不要。
async def start_timer(
  ctx,
  minutes: Option(int, 'アラートを上げるまでの時間を入力してください（単位：分）')):
  #Optionのメッセージは/start_timerコマンドをdiscordで実行したときに表示される
  secondint = int(minutes * 60)
  if secondint > 3600:
    await ctx.send_response("タイマーは1時間以内にして下さい")
    raise BaseException
  if secondint <= 0:
    await ctx.send_response("タイマーは1分以上の値に設定して下さい")
    raise BaseException
  message = await ctx.respond(f"Timer: {minutes}")
  await asyncio.sleep(secondint)
  await ctx.channel.send(content=f"{ctx.author.mention} 終了")
  if ctx.channel.type is discord.ChannelType.voice:
    vc = await ctx.channel.connect()
    try:
      if len(ctx.channel.members) == 1:
        return
      vc.play(discord.FFmpegPCMAudio("alert.mp3")) #任意の音声ファイルを。
      while vc.is_playing():
        await asyncio.sleep(1)
    finally:
      await vc.disconnect()

bot.run(sys.argv[1])
```

## 実行

```bash
python3 timer-bot.py "..." #予め取得してたトークンを渡す
```

botを落とす場合はPythonのプロセスを落とせばよい。

## コマンド実行例

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531760/07cab99f-9f72-bb26-aa6b-a48f83578d2e.png)
![無題2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531760/d5815107-810d-6971-889c-d3efe33a8dc5.png)

## 実装していく上で調べた事

* slash commandは`Bot#slash_command`デコレーターを使って実装できる。
* guild_ids未指定だとグローバルコマンドになるが、使用可能になるまで時間がかかるらしいのでサーバーIDを指定して使っている。
* ctxの型はApplicationContext。
* `ApplicationContext#respond`はslash commandの関数が呼ばれてから3秒以内に呼び出す必要があるようだ。呼び出さなかった場合はアプリケーションの応答なしとしてエラーになる。
* slash commandの呼び出し元のチャンネルがボイスチャンネルかどうかは、`ApplicationContext#channel`の`type`属性を見ることで判別できる。
* ffmpegがインストールされているなら、`discord.FFmpegPCMAudio`で音声を簡単に流せる。
* `VoiceClient#play`はコルーチンではないので、再生中の待機処理は別途記述する必要がある。
WordPressで自作テーブルを検索できるようにした

本稿は下記案件の続きです。併せてご参照下さい。

https://qiita.com/mindwood/items/85c365e2ab03df0ccf7e

前回は、データベースに商品情報テーブルを作成し、ホームページで各商品の価格を表示できるようにしました。
そうなると欲が出てきます。
せっかく信頼できるデータがWeb/DBサーバにあるのだから、検索できた方が便利ですよね。

サービスセンターには、卸売業者や小売業者、代理店から一般消費者まで、じつに様々な関係先から、商品に関するお問い合わせがあります。
その対応は、内製のMicrosoft Accessアプリケーションで捌きますが、関係先が自己解決できるなら皆にとってハッピーです。

ということで作りましたよ。簡単なので是非やってみて下さい。

# 検索フォームを作ろう
画像のような検索フォームを作成し、トップページに置きました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/70d57db8-0d64-62fb-92ce-2014edcef079.png)
HTMLはこんな感じになりますね。

```html:HTML
<form action="/search" method="post">
    <span>商品コード</span>
    <input type="text" name="p_code" placeholder="前方一致" autofocus>
    <span>品名</span>
    <input type="text" name="p_name" placeholder="部分一致">
    <input type="submit" value="商品検索">
</form>
```

# 検索用のコードを書こう
検索ボタンをクリックしたら、入力データを`/search`にPOSTするので、`/search`に対応するWordPressのページに、PHPでコードを埋め込むだけです。

Qiita向けに改変した上で掲載します。

```php:page-search.php
<?php
while(true) {
	// POSTメソッドで無ければ何もせずに抜ける
	if($_SERVER['REQUEST_METHOD'] !== 'POST') {
		break;
	}
	global $wpdb;
    // 商品コードが入力されていたら
	if (isset($_POST['p_code']) && !empty($_POST['p_code'])) {
		$str = trim(strtoupper(mb_convert_kana($_POST['p_code'], 'as')));
		if (strlen($str) < 2) {
			echo '<p>商品コードは２文字以上で指定して下さい</p>';
			break;
		}
		$message = '商品コードが <span class="nor">' . htmlentities($str) . '</span> で始まる商品の一覧です。';
        // 商品コード検索SQL作成
		$query = $wpdb->prepare("SELECT * FROM $wpdb->foo_product WHERE code like %s ORDER BY code", $wpdb->esc_like($str).'%');
    // 品名が入力されていたら
	} elseif(isset($_POST['p_name']) && !empty($_POST['p_name'])) {
		$str = trim(strtoupper(mb_convert_kana($_POST['p_name'], 'as')));
		if (strlen($str) < 3) {
			echo '<p>品名は３文字以上で指定して下さい</p>';
			break;
		}
		$message = '品名に <span class="nor">' . htmlentities($str) . '</span> を含む商品の一覧です。';
        // 品名検索SQL作成
		$query = $wpdb->prepare("SELECT * FROM $wpdb->foo_product WHERE name like %s ORDER BY code", '%'.$wpdb->esc_like($str).'%');
	} else {
		echo '<p>商品コードまたは品名を指定して下さい</p>';
		break;
	}
    // SQL実行
	$rows = $wpdb->get_results($query);
	if(empty($rows)) {
		echo '<p>検索条件に一致する商品の登録がありません</p>';
		break;
	}
	if($wpdb->num_rows > 100) {
		echo '<p>検索条件に一致する商品数が多すぎます。検索条件を見直して下さい</p>';
		break;
	}
// エラーが無ければここにくる
?>
<table>
	<tr>
		<th>商品コード</th>
		<th>品名</th>
		<th>定価</th>
		<th>区分</th>
	</tr>
	<?php foreach($rows as $row) { ?>
	<tr
    	<?php
		$p_name = esc_html($row->name);
        // 品名に「廃盤」が含まれていればグレーアウト
		if (mb_strpos($p_name, '廃盤') !== false) {
			echo ' class="gray-out"';
		}
		?>
	>
		<td><?php echo $row->code ?></td>
		<td><?php echo $p_name; ?></td>
		<td><?php echo number_format($row->price); ?></td>
		<td><?php echo $row->class ?></td>
	</tr>
	<?php } ?>
</table>
<?php break; } ?>
```

ページネーションは少し面倒くさかったので実装しませんでした。
全角／半角、大文字／小文字の区別なく、検索できるようにしています。
いかかでしょうか。