OmniAICreator/Qiita-1.07M huggingface dataset:
Siv3DからDiscordにメッセージを送信してみた

# はじめに
Discordには簡単にプログラムからメッセージが送信できるWebhookが使用できます。
Webhookは、外部のサービスからデータを受け取り、それをトリガーに特定のアクションを行う仕組みです。
今回はOpenSiv3DとDiscordのWebhook連携について説明します。

# Discord Webhookでできること
DiscordのWebhookでは送信に関することができます。
メッセージを受信に反応して何かする系はWebhookでは行うことができません。
- テキスト送信 (今回の記事で取り上げる内容)
- 画像送信
- ファイル送信
- 埋め込みテキストの送信
    - DiscordにURLを貼ったときにプレビューが出るあれです

# DiscordでのWebhook作成
自分で作成したサーバーで行うことをおすすめします。
他の人の作成したサーバーで行う場合、権限がなく設定ができない可能性があります。
- 送りたいチャンネルの設定を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258693/fa14ef67-1a67-fe55-fef9-64e4152856bc.png)
- Integrations(連携サービス)を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258693/8d3dc133-0941-965e-3da5-3833a34a26e8.png)
- Create Webhook(新しいウェブフック)を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258693/c055bf30-301d-9554-6d6c-be6c0df6abe7.png)

- 名前、プロフィール画像の設定
    - プログラム側でも変更できます
    - 後ほどURLを使うので、CopyWebhook URL(ウェブフックURLをコピー)を押してメモをしてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258693/b02dc50d-d08d-d868-3ba8-138c2f3d12bb.png)


# Webhook送信
WebhookURL、メッセージ、ユーザー名、アバターURLを指定しWebhookを送信する例です。
普通に書くと大量にリクエストが送られるので、トリガーをかけて書きましょう。
以下のコードでは、スペースキーを押すとDiscordにメッセージが送信されます。

```cpp
# include <Siv3D.hpp> // Siv3D v0.6.13

void Main() {
	while (System::Update()) {
		if (KeySpace.down()) {
			// 作成したWebhook URL
			const URL url = U"https://discord.com/api/webhooks/...";
			// 送りたいメッセージ
			const String message = U"Hello Webhook!";
			// 表示されるユーザー名
			const String userName = U"Siv3D";
			// アバターURL
			const URL avaterUrl = U"https://avatars.githubusercontent.com/u/7557228?s=200&v=4";

			const HashTable<String, String> headers = {{U"Content-Type", U"application/json"}};
			const std::string data = JSON{
				{U"content", message},
				{U"username", userName},
				{U"avatar_url", avaterUrl}
			}.formatUTF8();
			const FilePath saveFilePath = U"post_result.json";

			SimpleHTTP::Post(url, headers, data.data(), data.size(), saveFilePath);
		}
	}
}
```

Discordでこのようなメッセージが確認できると成功です！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258693/45fd577b-2df9-77fe-f663-7b4b7376426f.png)


# 活用例
### ゲームのプレイ回数カウント
- 文化祭などで複数PCを使ってゲームを展示する際、各ゲームが何回プレイされたかをある程度簡単に記録することができます
- ゲームの開始時にDiscordにWebhook送信を行うように実装し、後ほどDiscordの検索機能を使うことでプレイ回数をカウントすることができます

### 簡易フィードバックシステム
- Formsなど外部サービスを使わず、Webhookを使うことで簡単なフィードバックシステムを作成することができます
- ゲーム内でフィードバックシステムを作ることで、バグ報告をする際に簡単にセーブデータも送信することができ、開発者はバグの検証をスムーズに行うことができると考えています

# まとめ
今回はOpenSiv3Dを使ってDiscordにメッセージ送信する方法を紹介しました。
Webhookは簡単に使用できるので、ぜひ皆さんも使ってみてください！
Windows2016構築

# Windows2016構築を振り返って

### 概要
28台のサーバ構築を行いました。
環境は独自サービスを使用した案件に参画してます。
マルチクラウドの案件で、仮想と物理どちらも行うハイブリットの現場です。
今のところ物理の方が多い気がします。
時代はクラウドだが、物理にインフラの基礎が詰まっていると思っているので毎日必死に勉強させていただいてます。



### 環境
PowerEdge R630
https://i.dell.com/sites/csdocuments/Shared-Content_data-Sheets_Documents/ja/jp/Dell-PowerEdge-R630-Spec-Sheet-JA-HR.pdf
R630は現行から３世代くらい前に出ているものなので、仕様が古くとても困りました。。。
Windows2016

### 構築の流れ
①FWアップデート
②Zonig設定と確認(１パス)
③システムLUN作成/マスキング
④SAN Bootデバイス登録(1パスのみ)
⑤Windows2016導入設定 その1
⑥Zonig設定と確認(3パス)
⑦Windows2016導入設定 その2
⑧データLUN作成/マスキング
⑨スナップショット作成/バックアップサーバへマスキング
⑩物理サーバコンソール設定
⑪バウチャ・aD登録
⑫データバックアップ設定
⑬データバックアップ設定
⑭単体試験
⑮監視抑止解除

### 一番困ったこと
今回想定外が発生したのですが、
Zoning設定をしている際になぜかデバイスが見えない状況が発生しました。
原因を突き止めるために色々なところを確認したのですが、「ポートは上がっている」のに帯域設定の画面でポートが見えない.....なぜ!!!!
他にも確認したが、原因となりそうなところがない。。。

ということで、ネットワークチームにデータセンターに行ってもらい現地で確認してもらいました。
結果としてはスイッチ側のポートの不調でした。もう7年ぐらい起動したままらしいです。
ただ、GUIで見たときはポートは上がっているように見える。矛盾しているが結果として治ったのでよし!!!!!

他にも色々と立ち止まってしまったところはあったが、調べるなりして解決することができました。
仕様が古いことがすべて悪い方向に向いてしまい、原因不明のエラーなどありました。


### 後書き
ほんとはもっと細かい構成など書きたいのですが、案件の都合上書けないのでとても残念です。
構築のながれもざっくりとしか書かれていませんが、この中にたくさん項目が詰まっています。
Windows構築は今後バージョンは違えど構築する機会はたくさんあると思います。
【スターウォーズ】帝国軍に学ぶコードレビュー心得

## 遠い昔、はるか彼方の銀河系で:milky_way:
_ダース・ベイダー：今日は特別にコードレビューの授業を行う。_

_ストームトルーパー：は、はい、ベイダー卿！いつも通り厳しい指導を期待しています！_

_ダース・ベイダー：では、始めよう。フォースと共にあらんことを・・・_

## プルリクエストはデス・スターくらい大きくしよう！:first_quarter_moon:
<strong>_「次はこの完成した宇宙要塞の恐るべき威力をその目でとくと見届けるがいい。」 - ダース・シディアス_</strong>

細々とした修正は銀河を支配しようという帝国にはふさわしくありません。

いきなり大きなプルリクを投げて銀河を震撼させましょう。

納期ギリギリで巨大なプルリクを投げることでチームに壮大なインパクトを与えることが可能です。チーム一丸となって取り組むことでチームワークの強化につながるでしょう。

さらに一度に全てをレビューすることで何度も会議を開く必要がなくなり全体像も初めから把握することが出来るためレビューの効率化にもなる必須のテクニックです。

## 「これはダメだ」とだけコメントしよう！:no_good:
<strong>_「なすべきことをなせ、ベイダー卿。ためらうでない、情けは無用。」 - ダース・シディアス_</strong>

コード作成者(トルーパー)は未熟なのであなたがレビューすれば修正するべき箇所はすぐに見つかります。

この時にやってはいけないのが、具体的なフィードバックを残してしまうことです。

どこがどう悪いのか、どう修正するべきかなど手取り足取り教えることはトルーパー達の成長の機会を奪うことになるので御法度です。

ただ一言「これはダメだ」とだけコメントしましょう。

自力で解決方法を見つけられないトルーパーは成長の見込みがないのでケッセルのスパイス鉱山送りにしましょう。

銀河統一のためには厳しい決断も必要なのです。

## コーディングスタイルの違いを全てエラーとして扱おう！:warning:
<strong>_「提督、お前は致命的なミスを犯した。」 - ダース・ベイダー_</strong>

銀河統一を目指すのであれば自分のコードスタイルは貫かなければなりません。

変数の命名、改行の位置が気に入らないなど自分の好みと異なる記述は全て修正を指示しましょう。

その際に「これは読みやすさや効率性に影響しない」だったり「チームのコーディング規約を作ろう」などと言ってくる輩(反乱軍)がいるかもしれませんが断固拒否してください。

コーディング規約ではなく自分に従わせることが最優先です。

重要なのは、多様性の尊重やチームで共に成長する事ではなく銀河全体が自分のスタイルで統一されることなのです。

## 指摘や反論は絶対に許さない！:rage:
<strong>_「私を疑うのか。信念がなさすぎる。」 - ダース・ベイダー_</strong>

もはやコードレビュー自体を否定するメソッドですが、会社という組織には上司と部下、先輩後輩など明確な上下関係が存在します。

レビューで反論されるのはあなたが舐められているからです。

こういった事態を防ぐためには日頃のチーム員との関わり方がとても重要になります。

挨拶や雑談などは付け入る隙を与えてしまうので一切行わないようにしましょう。

仕事での会話も最低限に、質問が来た時にはまず舌打ちするのも効果的です。

話しかけやすいな、関係性ができたな、と思わせてしまった時点で負けです。

チームというのはフォースの暗黒面で支配するべきものなのです。

完全なる縦社会、昭和スタイルを貫くことが銀河統一の第一歩です。

## 完璧なコードを求めて永遠にレビューを続けよう！:relaxed:
<strong>_「無限のパワーをくらえ！」 - ダース・シディアス_</strong>

コードの一行ごとに改善点を見つけ、完璧なコードを求めて永遠にレビューを続けましょう。

コード作成者の努力にレビュワーも全力で応える必要があります。

タスクの優先度や、限られた時間の中で良いものを作ろうなどと言う反乱軍の言葉に耳を貸してはなりません。

妥協は悪です。初代デス・スターが換気ダクトの設計ミスを突かれて破壊されてしまったことを忘れてはいけないのです。

## あとがき
賢明な読者であれば気付かれたと思いますが、この記事に書かれたことはもちろん全てアンチパターンです。

実際にやってはいけないよということをまとめました。

アイデア先行で書き始めたのですが上手くいったかは自信がありません。

以下に影響を受けた記事を共有いたします。(100倍面白いのでぜひ読んでください)

[エンジニアのやる気を削ぐ会議術](https://qiita.com/miumiu0917/items/11e682f45611468e53f3)

個人的にはエンジニア一年目に会議室に集まってチームのエンジニア10人くらいの前で行ったコードレビューが人生で一番きつかったです。

実力もないのに生意気だった私は全員からボコボコにされて(されたと感じて)見事半泣きになりました。声を震わせながら、ただただ時間が過ぎることを願っていたのを覚えています。

今思い返すと大したことは言われなかったのかもしれませんが自分が書いたコードに指摘が入ったことで自分が否定された気持ちになっていたのだと思います。

新人の方やレビューで傷ついているという方には、レビューでたくさん指摘をされても決してその人自身を否定しているわけではないということを心に留めていただきたいです。

そしてレビューする側も心理的安全性に配慮して有意義な意見交換の場にしたいですね。

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

フォースと共にあらんことを！
2023/12/11主にITとかセキュリティの記事

クラウドに関する記事のまとめ(2023.12.4～2023.12.9）
https://blogs.itmedia.co.jp/business20/2023/12/20231242023129.html?ref=rss

「ChatGPT」から個人情報含む学習データの抽出に成功--Google DeepMind研究者ら(12/9)
https://japan.cnet.com/article/35212333/

「サイバー攻撃を受けた」でも「昇進できない」でもない、セキュリティ担当者“最大の悩み”は「ストレスで眠れない」――調査で分かった英国企業の実態(12/9)
https://news.yahoo.co.jp/articles/b2fa67b3374c7655af3ef6578aa5c2cb949f6c7a?source=rss

ユーザ端末から5G通信インフラが攻撃されるリスク：5GコアのASN.1に潜む脆弱性(12/8)
https://www.trendmicro.com/ja_jp/research/23/l/asn1-vulnerabilities-in-5g-cores.html

認証と署名の整理をしましょう（またかよ）(12/9)
https://qiita.com/lemiyachi/items/e64de854e714843ea62e

デジタル相「政府の支援体制を強化」　サイバー攻撃で サイバー・イニシアチブ東京(12/9)
https://www.nikkei.com/article/DGKKZO76816820Y3A201C2EA4000/

【総まとめ】GuardDutyによるコンテナランタイム脅威検知の注意事項と設定手順と検出の様子 #AWSreInvent(12/9)
https://dev.classmethod.jp/articles/ecs-fargate-runtime-detection/

新概念の鍵変換で暗号の物理安全性が飛躍的に向上(12/9)
https://www.jiji.com/jc/article?k=000000459.000078149&g=prt

ＥＵ、ＡＩ利用の包括規制案で暫定合意　違反企業に罰金(12/9)
https://www.epochtimes.jp/2023/12/190880.html

世界初のAI規制法にEUが合意、政策執行機関の委員長は「世界初のAI法」であることを強調(12/9)
https://gigazine.net/news/20231209-eu-lawmakers-global-first-ai-rules/

米国議会、国防権限法で仮想通貨関連条項を不採用(12/9)
https://coinpost.jp/?p=497324

Amazon GuardDuty 新着情報: Amazon ECS と AWS Fargate でランタイムセキュリティに対する脅威を検知しましょう(12/9)
https://aws.amazon.com/jp/blogs/news/introducing-amazon-guardduty-ecs-runtime-monitoring-including-aws-fargate/

次世代CPUのセキュリティ機能に新たな脆弱性、Intelは対応を発表(12/9)
https://news.mynavi.jp/techplus/article/20231209-2836313/

Dockerによる開発環境構築のための概念理解と方法解説(12/9)
https://qiita.com/S4nTo/items/977d28b0eac316915702

【2023年12月更新】メタバース未来予測！今後の可能性や課題を徹底解説(12/9)
https://xrcloud.jp/blog/articles/business/665/
ログイン時の認証トークンの発行について

### はじめに

個人開発メモ📝

### 今回行いたいこと

ユーザー登録後、初回ログインで認証が通った際に認証トークンを発行し、クライアント側で認証トークンを保持する。

### laravel sanctumの使用

:::note info
laravel sanctumを今回使用したのは、CSRFトークンの保護を自動で行ってくれることと、トークンベースの認証を簡単に実装できるメリットがあったためです。
:::


laravel 9.0xを使用しているのであらかじめ入っていましたが、インストールするなら⇩

```
composer require laravel/sanctum
```

sanctum設定ファイルと移行ファイルを公開する必要があるため以下を実行する。

```
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
```

APIトークンを保存するため、データベースにテーブルを作成する。

```
php artisan migrate
```

:::note info
上記を実行すると、personal_access_tokensというテーブルが作成されています。
:::

sanctumを使用して、SPA認証を使用するため以下を修正する。

```app/Http/Kanel.php
'api' => [
    \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, // コメントアウトになっていたので外す
    'throttle:api',
    \Illuminate\Routing\Middleware\SubstituteBindings::class,
],
```

参考サイト⇨https://readouble.com/laravel/9.x/ja/sanctum.html?header=%25E3%2582%25A4%25E3%2583%25B3%25E3%2582%25B9%25E3%2583%2588%25E3%2583%25BC%25E3%2583%25AB


### 認証トークンを発行する

```
$token = $request->user()->createToken($request->token_name ?? 'null');
return response()->json([
  'token' => $token->plainTextToken,
  'message' => '認証成功',
　　　　'redirectTo' => '/calender',
], 200);
```

createToken()を使用して、認証トークンの生成を行い、plainTextTokenでトークンの文字列を返しています。

:::note info
認証が成功すると、personal_access_tokensテーブルに認証トークンが保存されていました。
:::

### react側で認証トークンを取得し、ローカルストレージへ保存・ページ遷移を行う

:::note warn
react routerのuseHistory()はv6になってから、useNavigate()に推奨になったとのこと。
:::

参考サイト⇨https://dev.classmethod.jp/articles/react-router-5to6/

:::note alert
今回は、バックエンド側で遷移先を設定していたのでreact-routerは使用していません。
:::

```
// 認証トークンをローカルストレージに保存し、カレンダーページへ遷移
if(responseLoginData) {
   localStorage.setItem('token_name', responseLoginData.token);
   window.location.href = responseLoginData.redirectTo;
}
```

### まとめ

認証トークンがクライアント側で保持されているのが確認できたので、今度は投稿データの検索処理に入っていきたいと思います。
「Ultra Form」でフォーム営業に革命が起こった話

この記事は [Panda株式会社 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/pd-panda) 10日目の記事です。
[Panda株式会社](https://pd-panda.com/)は東京大学松尾研究室・香川高専発のスタートアップで、AR技術とAI技術を駆使したシステム開発と研究に取り組んでいます。
このアドベントカレンダーでは、スタートアップとしての知見、AI・AR技術、バックエンドなど、さまざまな領域の記事を公開していきます。

# 自己紹介

皆さんこんにちは、Panda株式会社代表取締役の田貝奈央です。AR技術が好きで、X（旧：Twitter）でARに関する投稿の巡回をしています。また、私はコーヒーとジャスミン茶も大好きです。

# 「Ultra Form」って？

「スタートアップ営業はエンジニアリングの力を借りて営業効率を最大化するべきだ！！！！」ということで、Panda株式会社アドベントカレンダー2023に寄稿させていただきます。

スタートアップでの営業担当が創業者なことは多々あると思います。私も例に漏れず、営業に取り組んでいます。

営業には、展示会での営業・テレアポ・メール営業などいろいろな方法があると思います。

その中でも、特に悩んでいたのが、問い合わせフォームを活用した営業でした。

せっかく作ってもらった営業リストの中から問い合わせフォームを開いても、サイトごとに微妙に仕様が変わるので、少し頭を使わないと入力ができません。

何も考えず単純作業にしたくても、各お問い合わせフォームの形式が異なるため、スムーズに入力することは難しいです。

そんな中、スタートアップコミュニティのメンバーに便利なツールを教えてもらいました。

それが「[Ultra Form](https://ultra-form.code-company.co.jp/how-to-start)」です。

「Ultra Form」は事前に登録した名前・会社名・問い合わせ内容などを、フォームの要素を元にテキストボックスを自動で埋めてくれるChrome拡張機能です。
例えば、以下に良さげなAR・AIスタートアップのお問い合わせフォームがありますね。

![Panda株式会社のお問い合わせフォーム.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414103/6f71e7cb-4484-b2b4-b477-0bf86c595264.png)

このページに営業フォームを送ろうと思うと、名前とメールアドレス、問い合わせの題名、メッセージの本文を記入する必要があります。1件であれば簡単ですが、複数件送る場合何度も同じことを入力するのは面倒です。そんな時にはUltra Formを使いましょう。

拡張機能ボタンをクリックし、メニューバーを開き、「自動入力」のボタンをクリックするだけです。

![Chrome拡張機能のポップアップ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414103/73595ddc-4115-0f51-5cf4-5a4344a951a2.png)

以下のように、事前に登録した名前やメールアドレス、問い合わせの題名、本文が自動で入力されます。クリックが面倒な人はショートカットキーを利用してみましょう。macOSであれば`command` + `B` で自動入力を実行できます。

![自動入力後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414103/248e683b-5ccc-5b81-94d2-2925b6421edd.png)

これだけでフォーム営業の速度が向上するはずです。

無料プランでは、月50件自動で入力してくれますので、ぜひ試してください。

この機能も魅力的ですが、1番のミソは、テキストボックスを選択した時に、右側に入力候補が表示されることです。この機能は入力パッドといい、無料プランで無制限に使うことができます。

![入力パッド](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/414103/ce4d4a00-b08b-ef40-916a-48f9a0660a2d.png)

入力候補のボタンを押すだけで、そのままテキストボックスに入力することができます。

自動入力はページによって反映ミスが多くあるので、この機能を使いこなす方が効率がいいかもしれません。

慣れるまでは、UIを見ながら選択する必要がありますが、慣れてくるとなんとなくの位置でクリックできるようになります。実質[おばけキャッチ](https://www.mobius-games.co.jp/Zoch/GeistersBlitz.html)ですね。

もしフォーム営業する人がいたら、「Ultra Form」を使ってみてください。

## おわりに

今回は「「Ultra Form」でフォーム営業に革命が起こった話」というテーマでPanda株式会社 Advent Calendar 2023 10日目を執筆させていただきました。
本記事では、「Ultra Form」というフォーム営業中に活躍するChrome拡張機能を紹介しました。

明日は、弊社のバックエンドエンジニア黄さんによるFastAPIに関する記事です。お楽しみに！
1年やってわかったAI・機械学習系施策を効率よく進める方法

# はじめに

こんにちは。@mktoX です。
1年ほど前に機械学習を使用した機能の実装および改善をする機会をいただき、

- 勾配ブースティング決定木による二値分類を用いた成約予測
- Embeddingsを用いた文書の類似検索
- ランキング学習を用いた検索精度の向上

について検討を行ってきました。
本記事では、それらをやっていくなかで気づいた機械学習・AI系施策を効率良く進める方法について

- 前提編
- データ編
- 検証編
- テスト運用編

の4つの観点に分けて書いていきたいと思います。


# 対象

- これから機械学習・AI系施策やっていきたい方
- なかなかテスト運用に進めない方


# 前提編

## どう解決するか考える
まず、その課題は機械学習でやる必要があるか考える。
そして機械学習だけで解決を出そうとしないことも大事。
例えば、機械学習で検索結果の並び順を最適化するのみでなく、
ルールベースでのフィルタリングも組み合わせると
納得感のある検索結果になったりする。

## ゴールを設定する
どの程度の性能があれば本番環境でテスト運用できるか、
機械学習の評価指標だけでなくビジネス面の指標を使って説明できるとよい。
また、例えば検索結果の並び順など、
如何に最適かがフィーリングによる部分が大きい場合、
本番環境でも使えそうか実際使用する方に確認してもらうことも考える。


# データ編

## ドメイン知識を得る
ドメイン知識があると、

- 特徴選択がやりやすくなる
    - 予測結果に影響する特徴がイメージしやすくなる
    - リークに気づきやすくなる

ドメイン知識は詳しい人から聞いたり、コードから読み取ったりする。

## データにアクセスしやすくする
Metabase等のBIツールがあるなら使用させてもらえるようにするとよい。
対象データを集めたりデータの時系列を確認したりなど、
データを参照する機会は何度もある。
ただカンマで区切られたデータしか出せない状況とかだと、
DataFrameに変換するだけでも時間がかかってしまう。


# 検証編

## 検証は小さく早く回せるようにする
最初からあらゆる特徴量を試そうとしない。
データの収集加工にも時間がかかる。
これに時間をかけていると進捗らしい進捗を出せずに苦しくなる。
まずはモデルにデータを学習させて予測値を出せるところまで作り、試せるようにする。
少ない特徴でも良い結果が出ることもある。


# テスト運用編

## まずは必要最低限の構成にする

モデルを自動更新させる等、最初から作り込まない。
まずは本番環境でも効果が出るか確認して、
どうすればより良くなるかを考えられる状態を作る。
早くフィードバックを得てモデルやシステムの改善にまわす。

最低限、エラー検知や監視の仕組みは要る。
本番環境では予期していなかったデータが来ることもある。
加えて、モデルの性能の低下や変化がないかの監視は必要。

実際の例を挙げると、
AWS Lambda + Route 53でデータを加工し予測値を返すAPIを作った。
モデルは手元(Google Colaboratory)で学習させ、AWS Lambdaに格納していた。
監視については、
Metabaseで予測結果と評価指標とビジネス面の指標をみるSQLを書き、
モデルの性能の低下や変化がないかを定期的にみていた。


# まとめ
機械学習・AI系施策を1年程度やっていくなかで気づいた効率良く進める方法について、
4つの観点から書いた。

- 前提
    - どう解決するか考える
    - ゴールを設定する
- データ
    - ドメイン知識を得る
    - データにアクセスしやすくする
- 検証
    - 検証は小さく早く回せるようにする
- テスト運用
    - まずは必要最低限の構成にする


# おわりに
よかったらいいねや感想等いただけると嬉しいです。
PowerShellでパスに半角スペースが含まれるファイルの実行方法

## はじめに

PowerShellで`C:\Program Files\`配下などのファイルを実行する方法を記載します。
ディレクトリ移動して実行すればいいじゃん！と言われてしまえばそれまでですが、ワンライナーで書きたい時などにこの方法が使えます。
コマンドプロンプトだとダブルクォーテーションで囲むだけで実行できるのに、なぜPowerShellで出来ないのかは神のみぞ知る所です。

## 結論

パス全体をダブルクォーテーションで囲った後に、先頭に`&`を付けることで実行できます。

```powershell
&"C:\Program Files\hogehoge\hoge.exe"
```

## まずは普通に実行

そのまま実行すると以下のようになります。

```powershell
PS C:\> C:\Program Files\hogehoge\hoge.exe
# C:\Program : 用語 'C:\Program' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認
# 識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試
# 行してください。
# 発生場所 行:1 文字:1
# + C:\Program Files\hogehoge\hoge.exe
# + ~~~~~~~~~~
#     + CategoryInfo          : ObjectNotFound: (C:\Program:String) [], CommandNotFoundException
#     + FullyQualifiedErrorId : CommandNotFoundException
```

## ダブルクォーテーションを付けて実行してみる

ダブルクォーテーションを付けただけだと、文字列としてそのまま表示されてしまいますね。

```powershell
PS C:\> "C:\Program Files\hogehoge\hoge.exe"
# C:\Program Files\hogehoge\hoge.exe
```

## ではどうするか

パスの先頭に`&`を付けることで、ファイルを実行することが出来ます！

```powershell
PS C:\> &"C:\Program Files\hogehoge\hoge.exe"
```
Raspberry PIのGPIOをDockerで検証する

# Raspberry PIのGPIOをDockerで検証する

以前執筆した、
「ミーティング中を検知して周囲の人間に知らせる」
の番外編です。（第二回で番外編かよって感じですが）

私のお家にはRaspberryPI4が一台あるのですが、RaspberryPIで動くアプリの開発をしていく上で毎回実機で検証を行うのは面倒です。
かと言って、RaspberryPI上で直接開発するのは別の開発端末でちょっとコードを変えたいときなどに不便です。

そこで、Docker上でGPIOの動作確認を含めてRaspberryPIの開発ができるようにします。

## 手順

RasberryPIには専用OSの"Raspberry Pi OS"がインストールされています。
このOSのファイルを抜き出してそれをもとにDockerImageを作成してあげればDocker上でRaspberry Pi OSを動かすことができます。
Docker上のRaspberry Pi OSからGPIOを操作する方法は後述します。

## Raspberry Pi OSのダウンロード

以下のリンクから、ブラウザなりCURLなりでRaspberry Pi OSのファイルをダウンロードします。
```
https://downloads.raspberrypi.org/raspios_lite_arm64/root.tar.xz
```

## DockerImageの作成

上記でダウンロードしたファイルをもとにDockerImageを作成します。

```
docker image import {ダウンロードしたOSファイルへのパス} {イメージ名}
```

## DevContainerを作成

以下のdevcontainer.jsonとdocker-compose.ymlを作成します。

devcontainer.json

``` json
{
    "name": "raspi",
    "dockerComposeFile": [
        "../docker-compose.dev.yml"
    ],
    "service": "raspi",
    "workspaceFolder": "/workspace",
    "remoteUser": "root"
}
```

docker-compose.yml

``` yaml
version: '3'

services:
  raspi:
    image:  {先程作成したイメージ名}
    tty: true
    volumes:
      - .:/workspace
    environment:
      - GPIOZERO_PIN_FACTORY=mock
```

上記docker-compose.ymlの```GPIOZERO_PIN_FACTORY=mock```がミソです。
この環境変数をmockに設定すると、GPIOのピンが存在していなくてもOS内で仮想でGPIOを再現してくれます。

## GPIOの状態を確認する

上記で作成したdevcontainerを起動し、ターミナルで以下のコマンドを実行してください。

``` bash
pinout
```

すると以下のように仮想のGPIOが有効になっていることがわかります。

``` text
,--------------------------------.
| oooooooooooooooooooo J8     +====
| 1ooooooooooooooooooo        | USB
|                             +====
|      Pi Model 3B  V1.2         |
|      +----+                 +====
| |D|  |SoC |                 | USB
| |S|  |    |                 +====
| |I|  +----+                    |
|                   |C|     +======
|                   |S|     |   Net
| pwr        |HDMI| |I||A|  +======
`-| |--------|    |----|V|-------'

Revision           : a02082
SoC                : BCM2837
RAM                : 1GB
Storage            : MicroSD
USB ports          : 4 (of which 0 USB3)
Ethernet ports     : 1 (100Mbps max. speed)
Wi-fi              : True
Bluetooth          : True
Camera ports (CSI) : 1
Display ports (DSI): 1

J8:
   3V3  (1) (2)  5V    
 GPIO2  (3) (4)  5V    
 GPIO3  (5) (6)  GND   
 GPIO4  (7) (8)  GPIO14
   GND  (9) (10) GPIO15
GPIO17 (11) (12) GPIO18
GPIO27 (13) (14) GND   
GPIO22 (15) (16) GPIO23
   3V3 (17) (18) GPIO24
GPIO10 (19) (20) GND   
 GPIO9 (21) (22) GPIO25
GPIO11 (23) (24) GPIO8 
   GND (25) (26) GPIO7 
 GPIO0 (27) (28) GPIO1 
 GPIO5 (29) (30) GND   
 GPIO6 (31) (32) GPIO12
GPIO13 (33) (34) GND   
GPIO19 (35) (36) GPIO16
GPIO26 (37) (38) GPIO20
   GND (39) (40) GPIO21

For further information, please refer to https://pinout.xyz/
```

## おわり

これでラズパイを持ってない人でもラズパイ開発ができますね。
DBって200種類あんねん〜DynamoDBと仲良くなるために〜

# はじめに

株式会社OMJテクノソリューションズ Advent Calendar 2023　18日目の記事です。

皆さんはNoSQLに触れたことがありますか？
私は学生時代も含めると10年近くRDBを何となく使っている程度だったのですが、
この1～2年でRDBではないデータストアに触れるようになりました。
（よちよち歩き状態を支えてくださった社内のメンバーには本当に感謝です・・・。）

「NoSQLという単語自体はなんとなく知っているけど結局何なんだ」
とずっと疑問だったのですが、

DynamoDBに触れているうちにわかってきたこと
DynamoDBとRDBの差異

を主観ベースで列挙しようと思います！

これからNoSQL（主にDynamoDB）やサーバーレスに触れる、あるいは興味がある人の一助となれば幸いです。

# 前提
## まずNoSQLってなに？
そもそもNoSQLってなんだい？というところなんですが、
「RDB以外のDB」と説明されていることが多い（ような印象）です。

書いて字の如く「SQLではない」
つまり、問い合わせなどの命令をする際にSQLは使わないのです。
ここで思い浮かぶ疑問としては「SQLじゃないなら何でDBに問い合わせするのよ」ということです。
これに関しては各サービス、プロダクト（NoSQL）ごとに異なりますが、
ざっくりとした理解として
「APIに専用メソッドでjsonを送る」
と捉えておくのが良いかなと思います。

NoSQLの特徴としては上記のような問い合わせ方法のため、直感的にコードの中にデータストアとの連携を埋め込むことができます。
話を簡単にまとめると、SQLを使ってRDBとやり取りするよりもかなりシンプルな構成にできるのです。

そして、NoSQLと言えばサーバーレス構成の要のようなイメージです。

## サーバーレスってなに？
サーバーレスという言葉がさほど珍しくもない時代ですが、
やはり私と同じように昔ながらの一般的？なシステム構成に触れる機会が多い方は
あまり馴染みがないかと思います。
これまた用語解説となりますが、
サーバーレスは
「サーバリソースを考慮して物理的にサーバを用意して構築しなくてもよいシステム構成」
という解釈を私はしております。
※明らかに間違ってるだろという場合はご指摘ください。

「つまりどういうことだってばよ」という方向けの説明しますと、
仮にWebサービスを作ろうとしたときにまずはWebサーバ、APIサーバ、DBサーバを構築するかと思います。
端的に申し上げますと、そもそもこの構築の手間がなくなります。
デプロイするサービスの設定は必要になりますが、「サーバを用意してサーバの設定をする」という手間が格段に省けるわけです。
これはマイクロサービスをさくっと作ってさくっとリリースしたいなどの場合に大きく効果を発揮します。
サーバの設定等の人的リソースはかなり削減できますし、サーバ自体の費用は（変な組み方さえしなければ）サーバーレスの方が格安です。
このあたりは[公式が出しているハンズオン](https://aws.amazon.com/jp/beginner-handson-series/)を実際にやってみると実感できるかと思いますのでぜひ！

# 感覚を掴むまでは検索すら大変
前置きがかなり長くなりましたが、ここから具体的にDynamoDBに関することを列挙していこうと思います。

まず前項までに述べたとおり、SQLで問い合わせを行うわけではないのでレコード検索する時点で苦しみました。
更にRDBのようなプライマリーキーや外部キーの概念がないため「DynamoDBの概念ってなんだ」がもうひとつの苦しみポイントでした。

詳しくはDynamoDBのチュートリアルや解説を読んでいただければと思うのですが、
DynamoDBは各レコードにパーテーションキーとソートキーというものを設定できます。
このパーテーションキーとソートキーの組み合わせが、RDBでいうプライマリーキーという読み替えができます。
そしてレコードに対して操作するには、このパーテーションキーとソートキーを指定する必要があります。
※全件検索などごく一部例外あり

まずは概念を理解してこの感覚を掴むまでにそこそこの時間がかかってしまいました・・・。

# 設計が大変
先ほど「レコードに対して操作するには、このパーテーションキーとソートキーを指定する必要があります」と記載しました。
SQLでは当たり前にWHERE句で「この条件に当てはまるレコードを操作～♡」と簡単に条件指定できていたのですが、
DynamoDBはパーテーションキー、ソートキーとして設定したカラムが一致するレコードのみ操作できます。

パーテーションキーとソートキーは一意性を表すだけじゃないんかい！！！！！

**そしてどの値（カラム）をパーテーションキーとソートキーにするかはテーブル作成時に設定しなければいけません。**

つまりどういうことかと言いますと
あまりに適当に（無考慮に）テーブルを作成すると、開発しているうちに
「あれ・・・この機能を実装するためのレコード条件が指定できない・・・」
なんてことが起こったりします。

救済措置？としてGSI（グローバルセカンダリーインデックス）という、
テーブルにパーテーションキーとソートキーの組み合わせを更に追加できる機能もあるのですが、
DynamoDBは従量課金制で、GSIは課金を加速させます。
DynamoDBを動かす回数やレコード数が多くないうちはさほど問題にならないかもしれませんが、ゴリゴリ回したりサービスのアクティブユーザが増えた時に請求金額を見るときっと青ざめることでしょう・・・。
なんとなくRDB的に中間テーブルを作成したり、ロジックで無理やり進めることもできなくはありませんが、コストや保守性の面でいろいろと問題が出てきます。

こうならないためにもテーブル設計はとても大事なのです。
「サーバーレスって構築簡単なんでしょ！」というのはインフラ構築時のコスト的なお話なだけで、
設計がいらないというわけではまったくございません・・・。


# 最後に
驚かすようなことばかり書いてしまいましたが、慣れてくるとDynamoDBはかなり使いやすいです！
ネガキャンの意図があるわけではないのであしからず・・・。

冒頭でも述べたように「コストをかけたくないけどマイクロサービス組みたい」という時は特に効果を発揮するかと思います！
また、公式のチュートリアル（ハンズオン）がしっかりしているので、とりあえずはそちらをなぞることで何とかなるかと思います。

当カレンダー21日目には私のサーバーレスの師匠である方がAWS Lambdaに主軸を置いたしっかりした技術記事を公開してくださるみたいです！
公式チュートリアルでもあるように、DynamoDBはLambdaと組み合わせる使われ方が非常に多いと思いますので、是非合わせてご確認いただければと思います！！！
（後日リンク貼ります）
ラップアラウンドの関数化

## ラップアラウンドの関数化
ラップアラウンドとは、ある範囲内で値がループするような計算のことです。下限値から上限値の間で数値をループさせたいときに利用します。

## コード
```
int Wrap(int num, int low, int high)
{
    //ゼロ除算回避
    if ((high - low) == 0)return num;

    //エラー
    if (low > high)
    {
        printf("エラー：下限値が上限値を上回っています");
        return num;
    }

    const int n = (num - low) % (high - low);
    return  (n >= 0) ? (n + min) : (n + high);
}

```
【Rails】パスを見てDBを切り替えるとテストが落ちるのを回避

# 概要

前回「パスによってDBのアクセスを変更する」といった記事を書きました

https://qiita.com/yothio/items/e2cfbbee215d0dfab324

普通に使う分には問題なかったのですが意図せずテストがコケてしまったので調査を兼ねて残しておきます

結論としては「**Rspecのhookでコネクションをデフォルトに接続し直す**」ことで回避しました

具体的に状態、問題、解決方法について見ていきます

## 状態
問題が発生したコードは以前の記事で説明した通り以下の要件を満たすものです
- Railsでマルチデータベース構成を行う
- マルチデータベースでは異なるスキーマを取り扱う
  - Contentテーブルにnameカラムの有無
  - PostテーブルとCardテーブルが片方にしかない
- マルチデータベースの接続切り替えはモデル単位ではなくアクセスするパスを参照

「原則としてはAデータベースを参照するが、特定のパスから始まる場合はBデータベースを参照。同一のテーブルがあってもカラムが異なる」という状態です

## 問題
次に発生した問題について見てみます
今回は書いたコードを運用し続けていくためにテストを導入、内容は「特定のパスでリクエストが成功するテスト」「モデルが特定の属性を所持しているか確認するテスト」といった内容です

今回はテストにRSpecを利用します

「Aデータベースを参照するが、特定のパスから始まる場合はBデータベースを参照」なので予期している事としては下記の通り
- **モデルのテスト**は特定のパスにアクセスしないので、**Aデータベース**を見てほしい
- **リクエストのテスト**は特定のパスにアクセスするので、**Bデータベース**を見てほしい

リクエストはmiddlewareで明示的に接続する処理を記述しているので問題ありませんが、モデルに記載はないため「リクエスト」→「モデル」と実行されると「モデルのデータ取得時にBデータベースを参照する」となり意図しない正しくテストが動かなくなります

これが今回の問題です

rails_helperにフックを書いて確認してみます

```ruby:spec/rails_helper.rb
  config.around(:each) do |example|
    puts "Running: #{example.file_path}:#{example.metadata[:line_number]}"

    puts "before: #{ActiveRecord::Base.connection_db_config.database}"
    example.run
    puts "after #{ActiveRecord::Base.connection_db_config.database}"
  end
```

```log:実行結果
# >>>>>>>モデルから先に実行される場合
Running: ./spec/models/content_spec.rb:6
before: kanban_test
after kanban_test
.Running: ./spec/controllers/contents_controller_spec.rb:5
before: kanban_test
after board_test
.

Finished in 0.65759 seconds (files took 3.16 seconds to load)
2 examples, 0 failures

# >>>>>>>リクエストから先に実行される場合
Randomized with seed 31590
Running: ./spec/controllers/contents_controller_spec.rb:5
before: kanban_test
after board_test
.Running: ./spec/models/content_spec.rb:6
before: board_test
after board_test
F

Failures:

  1) Content attributes has the expected attributes
     Failure/Error: subject { Content.create(title: 'hoge', name: 'fuga') }

     ActiveModel::UnknownAttributeError:
       unknown attribute 'name' for Content.
     # ./spec/models/content_spec.rb:5:in `block (3 levels) in <main>'
     # ./spec/models/content_spec.rb:7:in `block (3 levels) in <main>'
     # ./spec/rails_helper.rb:80:in `block (2 levels) in <top (required)>'

Finished in 0.79844 seconds (files took 4.69 seconds to load)
2 examples, 1 failure
```

モデルのテスト時のbefore,afterのデータベースが切り替わったままになっているのが確認できます

## 解決方法
request spec実行後にdefaultに接続し直すことで回避します

```ruby:spec/rails_helper.rb
  config.after(:each, type: :request) do
    ActiveRecord::Base.establish_connection(:default)
  end
```

当たり前っちゃ当たり前なのですがもうちょっとスマートに解決したいところではあります...

## 最後に
middlewareで切り替えたりなどを普通は行わないので今回のようなケースはあまりないと思いますが参考になれば幸いです
RSpecのコネクション周りをもうちょっと見ていきたいですね

実行環境やサンプルコードはこちらに載せています

https://github.com/yothio/rails_multi_db_test/tree/modify_database_for_middleware
【ゼロから学ぶNuxt3×Typescript】②nuxt3でcomponentを作成

## Nuxt３×TypeScript 学習
下記の参考サイトを見ながら、Nuxt３とTypescriptを学ぶ第二回。

▼　神回|vue3.js nuxt3 typescriptどうやる？【ゼロから解説】

https://field.asia/%E7%A5%9E%E5%9B%9Evue3-js-nuxt3-typescript%E3%81%A9%E3%81%86%E3%82%84%E3%82%8B%EF%BC%9F%E3%80%90%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E8%A7%A3%E8%AA%AC%E3%80%91/


前回はこちら👇

https://qiita.com/sakuc47/items/2770d40720070b682ee9

では始めます💪

## Nuxt3でcomponentを作成する

### 1.header.vueを作成する
pagesフォルダと同階層にcomponentsフォルダを作成、その中にheader.vueを作成

<INS>・header.vue</INS>

``` vue
<template>
  <header class="header">
    <h1>ヘッダータイトル</h1>
  </header>
</template>

<style>
.header {
  background-color: peachpuff;
  color: #fff;
  display: flex;
}
</style>
```

### 2.footer.vueを作成する
同じくcomponentsフォルダの中にfooter.vueを作成

<INS>・footer.vue</INS>
```vue
<template>
  <footer>
    フッター
  </footer>
</template>
```

### 3.app.vueでコンポーネントを呼び出す
` <Header /> `のように頭文字が大文字になる点に注意

<INS>・app.vue</INS>
```vue
<template>
  <Header />
  <NuxtPage />
  <Footer />
</template>
```

### 4.localhost:3000を確認
![FireShot Capture 025 -  - localhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/2e36f73b-237f-aefe-e26b-b2aaef5916da.png)

### 5.jobsフォルダの中にページを作成する
pages配下にjobsフォルダを作成
さらに、jobsフォルダの中に下記ファイルを作成
・`index.vue`
　↪︎localhost:3000/jobs 
・`[id].vue`
　↪︎localhost:3000/jobs/1等

### 6.pages配下にprefecturesフォルダを作成する
prefecturesフォルダ内に `[prefecture].vue` を作成

---
参考サイトでは、ここでyarn devすると下記サイトが見られるとありますが、
http://localhost:3000/prefectures/pref

こちらの環境ではターミナルに下記エラーが出ました。
（実は前回も出ていました）

```
At least one <template> or <script> is required in a single file component.
```

翻訳
> 単一のファイル コンポーネントには、少なくとも 1つの `<template>` または `<script>` が必要です。

作成したvueファイル内が空なのがよろしくないようです。
指示通りに`<template>`  `<script>` を書きます。


・jobs/index.vue
・jobs/[id].vue
・prefectures/[prefecture].vue
 
```vue
<template>

</template>
```

もう一度`yarn dev`するとエラーが消えます。

---

### 7.ページを確認
下記にアクセスする
http://localhost:3000/jobs
http://localhost:3000/jobs/hoge
http://localhost:3000/prefectures/pref

![FireShot Capture 026 -  - localhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/2bd09105-64be-8027-f7e0-13a938ae86e7.png)

※混乱を避けるための補足
この参考サイトでは求人サイトを作成する過程を題材としているため「prefecture＝県」としているようです。
（⚪︎⚪︎県の求人、というイメージ）

:::note info
`[id].vue`、`[prefecture].vue`の中の`[]`で囲まれている部分は動的な値が入ります。

例えば、jobs/hogehugaやprefectures/monyomonyoでも上記添付画像と同じように表示されます。
:::

### 第二回はここまで


### 参考サイト
https://field.asia/%E7%A5%9E%E5%9B%9Evue3-js-nuxt3-typescript%E3%81%A9%E3%81%86%E3%82%84%E3%82%8B%EF%BC%9F%E3%80%90%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E8%A7%A3%E8%AA%AC%E3%80%91/
dockerでPostgreSQLを使うときに、ビルドが必要な拡張機能(Extension)を導入する

# はじめに
タイトルの通り。
ビルドのタイミングだったり、SQLファイルを特定の場所にコピーする等、意外とやったことないことが多かったので書き残しメモ。

# 確認環境
- WSL2(Ubuntu22.04.3 LTS)
- PostgreSQL 14.10-1
- Docker (24.0.6)
- pg_ivm（導入するextension）

# フォルダ構成
```

--
[projectfolder]
 ├─ compose.yml
 ├─ Dockerfile
 └─ docker-entrypoint-initdb.d
    └─ 90_pg_ivm.sql (extentionを登録するSQL)
```

# ソース
```yaml:compose.yml
services:
  db:
    build:
      context: .
    restart: always
    volumes:
      - postgresql:/var/lib/postgresql/data
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    tty: true

volumes:
  postgresql:
```

```Dockerfile:Dockerfile
# postgresのバージョン14最新
from postgres:14

# パッケージ更新＆パッケージのビルドで必要なもの
RUN apt-get update && apt-get install -y \
    git \ 
    make \ 
    gcc \
    postgresql-server-dev-14
# 必要なパッケージのインストール

# ------ pg_ivm導入
# git展開フォルダ
WORKDIR /tmp
# git で取得
RUN git clone https://github.com/sraoss/pg_ivm
# フォルダ移動
WORKDIR /tmp/pg_ivm
# make & install
RUN make USE_PGXS=1 
RUN make USE_PGXS=1 install

# EXTENTION登録SQLをコピー
COPY ./docker-entrypoint-initdb.d/90_pg_ivm.sql /docker-entrypoint-initdb.d
# (一応)ディレクトリはデフォルトに戻す
WORKDIR /

# 使わないので削除
RUN apt-get purge -y \
    git \ 
    make \ 
    gcc \
    postgresql-server-dev-14
# ファイルも使わないので一応削除
RUN rm -rf /tmp/pg_ivm

```

```sql:docker-entrypoint-initdb.d / 90_pg_ivm.sql
CREATE EXTENSION IF NOT EXISTS pg_ivm;
```

# 起動コマンド
```shell
docker compose up -d
```

# ざっくり解説
- Dockerfileでビルドして、拡張機能登録用のSQLファイルを/docker-entrypoint-initdb.d にコピーしてコンテナ作成時に実行している（バインドマウントでフォルダ共有しても良い）
- Extensionには、以下の３つがあるみたい
    1. デフォルトでPostgreSQLに入っているもの(`CREATE EXTENSION` だけすればよいもの)
    1. Linuxのパッケージとしてインストールできるもの(`apt`や`yum`等で取得したあとに`CREATE EXTENSION`するもの )
    1. ソースをビルドしてインストールがひつようなもの(`今回の対象`)
- docker-entrypoint-initdb.d で make はできない(makeの実行ユーザーがpostgresユーザーになるため、permissionエラーとなる)


# Extensionが導入されているかの確認
```sql
postgres=# SELECT * FROM pg_extension;
  oid  | extname | extowner | extnamespace | extrelocatable | extversion | extconfig | extcondition
-------+---------+----------+--------------+----------------+------------+-----------+--------------
 13766 | plpgsql |       10 |           11 | f              | 1.0        |           |
 16384 | pg_ivm  |       10 |           11 | f              | 1.7        | {16386}   | {""}
```

# おまけ
```sql
SELECT * FROM pg_available_extensions;
```
とすると、導入可能（`CREATE EXTENSION`だけすればよいもの）と導入済みのextension一覧が表示される(導入済みのものは、`installed_version`に値が入っている)

# 終わりに
拡張機能を自身で導入したことなかったので、色々調べるとこになり、結構勉強になりました。
pg_ivm は マテリアライズドビューを自動更新するという、結構面白そうな拡張機能です。


# 参考

https://qiita.com/nuko_yokohama/items/d7a1be2594120c32b136

https://dev.classmethod.jp/articles/tsnote-rds-extension-cehck-001/
官報が高いのでgeminiで公告したい！

# はじめに

N高生です。空いてたので書きます。

官報掲載高い！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/09ec4a9a-91b4-738d-6dac-38cad0779c25.png)
> https://kanpou.npb.go.jp/pdf/s_guide.pdf


生きているとどうしても決算公告しないといけないことがあります。
ですが、Webでの電子公告は5年間掲載しないといけなかったり、[開示範囲が広かったりします。](https://coralcap.co/2020/06/incorporation-best-practices-for-startups-04/) 
そういうこともあり官報で公告する方も多いのではないでしょうか。[^1]

ですが、零細企業からすると74,331円も払うのは結構きついです。[^2]




そこでgeminiプロトコルを使えば、決算公告をあまり見られることもなく公に開示できるのではと考えました。


# Geminiとは？
> 任意のファイルを配布するためのアプリケーションレベルの新しいプロトコルで、2019 年に生まれた、割と最近の作られたばかりプロトコルです。
https://qiita.com/taiju/items/accd8bd48d13581d33a1

だそうです。


# やってみた


- クライアント
    - [amfora](https://github.com/makew0rld/amfora)
- サーバー
    - [agate](https://github.com/mbrubeck/agate)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/b463f4db-5929-9f57-1fcd-3a65d20c7d37.png)

:::note warn
テーブルはないそうです....
:::


# 最後に

出来上がったものは

`gemini://ir-test.starthype.co.jp`

からアクセスできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/9081bc80-608e-38fe-6133-5ef1fb34fc43.png)

<br/>
<br/>
あくまで空想のお話です。

登記時、官報掲載と書いてしまったのでgeminiで公告するには定款変更（3万円）をしないといけません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/ef0451fa-a17b-958e-aa7d-f47cfc7e55bc.png)

またクライアント/フォントによって表示が絶望的に崩れてしまいます。。いい方法あれば教えてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437056/0fc562e2-8a4b-3960-60c7-078a72199476.png)



リポジトリ:
https://github.com/hirossan4049/gemini-kokou


[^1]: noindexで公告しているところが多い気がしますが`公告`なのでnoindexにしたくない事情があります。
[^2]: 噂によると公告してない会社が大半だそうです。
LeetCode備忘録_その2_Arrays & Hashing_Contains Duplicate

# 概要
- LeetCodeを始めました。１テーマごとに解法と学びをメモします
- 今回テーマは「Arrays & Hashing_Contains Duplicate」

# テーマ詳細
### 原文
Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct.

Example 1:

Input: nums = [1,2,3,1]
Output: true
Example 2:

Input: nums = [1,2,3,4]
Output: false
Example 3:

Input: nums = [1,1,1,3,3,4,3,2,4,2]
Output: true
 

Constraints:

1 <= nums.length <= 105
-109 <= nums[i] <= 109

### 日本語訳
※G翻訳
整数配列 nums を指定すると、配列内に値が少なくとも 2回出現する場合は true を返し、すべての要素が異なる場合は false を返します。

例 1:

入力: 数値 = [1,2,3,1]
出力: true
例 2:

入力: 数値 = [1,2,3,4]
出力: false
例 3:

入力: 数値 = [1,1,1,3,3,4,3,2,4,2]
出力: true

制約:

1 <= nums.length <= 105
-109 <= nums[i] <= 109

# 解法
```
class Solution(object):
    def containsDuplicate(self, nums):
        return len(nums) != len(set(nums))
```
# 結果
- Runtime:420ms  
- Beats 82.84% of users with Python

# 学び
- リストをset型（集合型）に変換することでリスト内で重複する要素は削除される。（例：[1,1,2,3]→[1,2,3]）

# 感想
- ２つの異なるlist間で重複する要素やユニーク要素を取得するときにsetは使っていたが、今回の利用意図のように型変換することで重複要素が除外されることは初めて知った
低レベルPerlスクリプトのススメ ～  「readtsv」の紹介


# はじめに
昨年に比べて、今年の[Perl Advent Calendar](https://qiita.com/advent-calendar/2023/perl)への投稿は少し低調のようです。まだ多くの空白日が残っていますね。

確かに昨今perlはあまり流行とは言えません。かつてのCGIの需要はjavascriptやRubyに持っていかれ、AIだの機械学習だのの脚光はもっぱらPythonが浴びています。もう時代の最先端をperlを走る時は来ないのかもしれません。

しかし私は今でもperlについて世に問うことには大いに意義があると考えています。私が考えるに、perlは低レベルスクリプトこそが命です。

ここでいう「低レベル」は、「最先端ではなく、地味で、時代遅れなように見え、しかしあればあっただけ何らかの意義が感じられるような」レベルとうけとっていただきたい。どちらかというとかつて月刊アスキーで連載されていた[『低レベルソフトウェア研究所』](https://amzn.to/3NhRCdN)にて提唱されていた概念に近い（同じとは言いません）ものです。この観点に限れば、perlは今も他の多くの言語を押しのけて上位に君臨しているのではないでしょうか。

というわけで、私から自作の「低レベルソフトウェア」を紹介させてください。GitHubに公開しているPerlスクリプト「readtsv」です。

https://github.com/Koji-Doi/readtsv

# readtsv: TSVファイルを簡単に扱うスクリプト
「readtsv」は、TSVファイル閲覧・簡易整形ツールです。

## なぜ誕生したのか？
今から14年前、私は業務で大量のTSVファイルを作成しあるいは共有していかなければならない状況でした。

TSVはシンプルで使い勝手の良いフォーマットです。しかし、自作ツールが（あるいは同僚の誰かが）吐き出してきたファイルが約束にちゃんと従っているのかとか、自分が欲しいデータがいったい第何カラム目に入っているのかとか、確認に手間取ることがあります。lessとか使うわけですが、なにしろタブは目に見えないからわかりにくい。一行が何百文字もあると目視と言っても簡単に死ねます。

そこでとりあえず、TSVファイルのタブコードを"|"に置き換えて出力するという単純なワンライナーを書きました。しかし、目視確認の必要はその後も頻繁に生じたため、これをスクリプトファイルとして保存し、簡単に呼び出せるようにしました。これがreadtsvの起源です。

その後、複行レコード化やHTMLテーブル化などをやりたい機会があり、そのたびに機能を追加していきました。

最初にワンライナーを書いたところから3回職場を変わり、その倍の回数のマシン乗り換えを経験しましたが、このスクリプトは全ての環境に持っていくことになりました。今も職場・自宅の両マシンで頻繁に使っています。それにしても、ほんの軽い思い付きでかいたスクリプトを14年間も使い続けることになるとは思ってもみませんでした。

## 使用方法

もっとも基本的な使い方はTSVファイルの中身を見ることです。
まずタブ文字を可視化。それでも見にくい場合は、フィールドごとに行を変えて出力し（複行レコード化）、内容を楽に目視確認できます。

![tab_space.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/8cc5dc2d-4eb1-2d93-9474-988a1a0fb508.png)
**「スペースじゃなくタブで区切れつってんだよ。全く素人は困るぜ!」**

- 基本コマンド: `readtsv input.tsv`
  - このコマンドは、指定されたTSVファイル（ここでは`input.tsv`）を読み込み、タブ文字を"|"に置き換えて出力します。

### オプションによる機能拡張
- `-k a,b`: 指定列のみを抜き出して出力
- `-m`: 複行レコードとして出力
- `--html`: HTMLテーブルとして出力
- `-ifs ','`: 入力時のフィールド区切り文字を指定
- `-n`: フィールド数、行番号、ファイル名を付加して出力
- `-s ','`: 出力時のフィールド区切り文字を指定

### 使用例
```
$ cat test1.tsv
かな	性別	ID
あいうえお	男	0120-1234-1111	
かきくけこ	男	0120-1234-2222	
さしすせそ	女	0120-1234-3333

$ readtsv test1.tsv
かな|性別|ID
あいうえお|男|0120-1234-1111
かきくけこ|男|0120-1234-2222
さしすせそ|女|0120-1234-3333

$ readtsv -m test1.tsv
1-0: かな
1-1: 性別
1-2: ID
2-0: あいうえお
2-1: 男
2-2: 0120-1234-1111
3-0: かきくけこ
3-1: 男
3-2: 0120-1234-2222
4-0: さしすせそ
4-1: 女
4-2: 0120-1234-3333

$ readtsv -k 0,2 test1.tsv
かな|ID
あいうえお|0120-1234-1111
かきくけこ|0120-1234-2222
さしすせそ|0120-1234-3333

$ readtsv -s '/' test1.tsv
かな/性別/ID
あいうえお/男/0120-1234-1111
かきくけこ/男/0120-1234-2222
さしすせそ/女/0120-1234-3333

$ readtsv -k 0,2 --html test1.tsv
<html><body><table border="1">
<tr><td>かな</td><td>ID</td></tr>
<tr><td>あいうえお</td><td>0120-1234-1111</td></tr>
<tr><td>かきくけこ</td><td>0120-1234-2222</td></tr>
<tr><td>さしすせそ</td><td>0120-1234-3333</td></tr>
</table>
</body></html>
```

### インストール方法
このスクリプトを適当なディレクトリに置き、Perl5がインストールされている環境で使用してください。

# むすび
perlの縁の下の力持ち的なニーズは今も存在していますし、今後もそれが絶えることはないと思います。perlをディスリ最先端の需要にばかり目を向けている意識高い系のITエンジニアのことは放っておいて、私たちはPerlを使って実り豊かなITライフを送りましょう。

そのためには、このような「低レベルスクリプト」を共有することも、非常に有効だと思います。皆さんも、手元にある同じようなスクリプトをぜひ紹介してください。
Golang×gRPC入門 ~実装からデプロイまで~

## はじめに

最近、GoでgRPCサーバーの開発をするきっかけがありました。今回は、helthcheckのエンドポイント `/grpc.health.v1.Health/Check` の開発を通してGoでgRPCサーバーの実装からECSへのデプロイまでまとめていきます。

gRPCやProtocol Buffersの詳細な概念については今回は割愛しますが、興味があれば2年前にまとめた記事もご覧いただければと思います。

https://qiita.com/ymktmk/items/f7b8949301fac29685dd

## ツールのインストール

まず最初に、開発に必要なツールをインストールします。以下は、必要なツールの一覧です。

```
go install google.golang.org/protobuf/cmd/protoc-gen-go
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc
go install github.com/grpc-ecosystem/grpcurl/cmd/grpcurl
```

## protoファイルからコードを自動生成する

次に、Protocol Buffersの定義を含む .proto ファイルからGoのコードを自動生成します。以下は、helthcheck用のprotoファイルとコード生成のコマンドです。

```proto:health.proto
syntax = "proto3";

package grpc.health.v1;

option go_package = "pb/grpc_health_v1";

message HealthCheckRequest {
  string service = 1;
}

message HealthCheckResponse {
  enum ServingStatus {
    UNKNOWN = 0;
    SERVING = 1;
    NOT_SERVING = 2;
    SERVICE_UNKNOWN = 3;
  }
  ServingStatus status = 1;
}

service Health {
  rpc Check(HealthCheckRequest) returns (HealthCheckResponse) {}
}
```

```
protoc  --go_out=. --go-grpc_out=require_unimplemented_servers=false:. proto/health.proto
```

## gRPCサーバーの実装

生成されたコードを基に、gRPCサーバーの実装を行います。以下は簡単な例です。

```go:main.go
package main

import (
	"context"
    "net"

    "google.golang.org/grpc"
	"google.golang.org/grpc/reflection"

    "github.com/ymktmk/golang-grpc/pb/grpc_health_v1"
)

type HealthHandler struct{}

func NewHealthHandler() *HealthHandler {
	return &HealthHandler{}
}

func (hc *HealthHandler) Check(ctx context.Context, req *grpc_health_v1.HealthCheckRequest) (*grpc_health_v1.HealthCheckResponse, error) {
	return &grpc_health_v1.HealthCheckResponse{
		Status: grpc_health_v1.HealthCheckResponse_SERVING,
	}, nil
}

func main() {
	listen, err := net.Listen("tcp", ":50051")
	if err != nil {
		panic(err)
	}

	grpcServer := grpc.NewServer()
	reflection.Register(grpcServer)

	healthHandler := NewHealthHandler()
	grpc_health_v1.RegisterHealthServer(grpcServer, healthHandler)

	if err := grpcServer.Serve(listen); err != nil {
		panic(err)
	}
}
```

## grpcurlで動作確認

実装が完了したら、grpcurlを使用してサーバーの動作を確認します。以下は、grpcurlを使用してhealthcheckを行う例です。

```
grpcurl -plaintext localhost:50051 grpc.health.v1.Health/Check
```

## ECSへのデプロイ

TerraformでECSへデプロイします。唯一異なるのは以下の3点です。

- matcher = "0"
- protocol_version = "GRPC"
- path = "/grpc.health.v1.Health/Check"

matcher = "0"とするのは、HTTPのステータスコードにあたる概念がgRPC Codeであり、成功は`OK = 0`です。

```hcl:alb.tf
resource "aws_lb_target_group" "lb_target_group" {
  name             = "gRPC-ALB"
  port             = 50051
  protocol         = "HTTP"
  protocol_version = "GRPC"
  vpc_id           = aws_vpc.vpc.id
  target_type      = "ip"

  health_check {
    enabled             = true
    healthy_threshold   = "3"
    unhealthy_threshold = "2"
    interval            = "30"
    matcher             = "0"
    timeout             = "5"
    path                = "/grpc.health.v1.Health/Check"
    port                = "traffic-port"
  }
}
```

## おわりに

今回は、helthcheckのエンドポイント `/grpc.health.v1.Health/Check` の開発を通してGoでgRPCサーバーの実装からECSへのデプロイまでまとめました。皆さんの参考になれば幸いです。
🔑パスフレーズ付きの秘密鍵でRemote SSHする

この記事は さくらインターネット [Advent Calendar 2023](https://qiita.com/advent-calendar/2023/sakura) 11日目の記事です。

## 概要
皆様こんにちは、やすです。
今回は、macOSでVisual Studio Codeの拡張機能の一つである [Remote - SSH](https://code.visualstudio.com/docs/remote/ssh) を使って、パスフレーズ付きで公開鍵認証する際の手順と注意したいことについて共有させてください。

## 手順
いままでリモートサーバーでのファイル編集などはターミナル上でおこなっていたのですが、Remote SSH 拡張機能の存在を知り早速試してみました。
あらかじめ公開鍵をサーバーに登録しておき、Remote SSHをマーケットプレースからインストールします。
今回はこちらのバージョンを利用しました。
![スクリーンショット 2023-12-11 0.48.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223921/6ce336a0-bd0b-612b-ed5a-149581f2a0b5.png)

インストールが完了したらウィンドウの左下のアイコンをクリックします。
![スクリーンショット 2023-12-10 23.50.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223921/9427f288-7abb-69a3-018f-d17a527aa2f8.png)

すると画面上部に「ホストに接続する...」と表示されるのでこちらをクリック。
![スクリーンショット 2023-12-10 23.51.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223921/256010da-29e2-3ace-3b2c-651a80937b8c.png)

次に接続先サーバーの情報を「`ユーザー名`@`ドメイン名 or IPアドレス`」の形式で入力します。
![スクリーンショット 2023-12-10 23.53.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223921/01ab2e33-675b-dcaf-0218-b26e23d6b3df.png)

ここでパスフレーズなしで生成した公開鍵をサーバーに登録している場合はこのまま問題なく接続できると思います。
しかし、パスフレーズ付きで生成した鍵を登録している場合については VS Code 上でパスフレーズを聞かれることがなく、接続に失敗してしまいます。

## 解決方法
`ssh-add` コマンドで秘密鍵をローカル端末の ssh-agent に登録することで失敗なく接続できるようになります。

```
ssh-add /path/to/id_rsa
```

ssh-agent は ssh 接続時に事前に登録してある秘密鍵のパスフレーズを代理で入力する役割を担ってくれます。
ただし、PC本体の再起動などで登録した秘密鍵の情報が消えている場合がありますので、再度接続できなくなった場合は、 `ssh-add -l` などで情報が残っているか確認してみてください。

## まとめ
今回はRemote SSH の使い方とパスフレーズ付きで公開鍵認証する際の注意点について共有させてもらいました。
もし `ssh-add` を使わなくても接続できる方法があったり、他にもっと使いやすい拡張機能があればコメントなどで教えていただけると幸いです:pray:

それでは〜:wave:


## 参考文献
https://qiita.com/nlog2n2/items/1d1358f6913249f3e186

https://qiita.com/Yarimizu14/items/6a4bab703d67ea766ddc

https://qiita.com/slotport/items/e1d5a5dbd3aa7c6a2a24
MOVからMP4へ変換すーる（Python）

# はじめに
[がちもとさんアドベントカレンダー](https://qiita.com/advent-calendar/2023/gachimoto3)10日目の記事です。
今日は、iPhoneの動画がMOVなのでMP4に変換していきます。

縦動画をmoviepyでMP4に変換した際に、横長の動画になってハマりました。。
プロパティでは幅が3840、高さが2160になってしまってます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63863/0a9a5c3a-04d7-a193-5f5d-2887740fe3e8.png)

そこで、回転情報を取ってきて幅と高さを入れ替えて変換しました。

# 開発環境
- Windows 11 PC
- Python 3.11

# 導入

1．ライブラリのインストール
pip install moviepy

2．プログラムを作成

~~~mov2mp4.py
from moviepy.editor import VideoFileClip

# 入力ファイルと出力ファイルを指定
input_file = 'IMG_3657.mov'
output_file = 'IMG_3657.mp4'

# 動画情報を取得
video_clip = VideoFileClip(input_file)

# 解像度を取得
width = video_clip.size[0]
height = video_clip.size[1]
rotation = video_clip.rotation
fps = video_clip.fps
duration = video_clip.duration
print("video_clip.size:", width, height, rotation, fps, duration)

# MOV動画をMP4に変換して保存
if rotation == 90:
    video_clip.write_videofile(output_file, codec='libx264', ffmpeg_params=["-vf", f"scale={height}:{width}"])
else:
    video_clip.write_videofile(output_file, codec='libx264', ffmpeg_params=["-vf", f"scale={width}:{height}"])
~~~

<details><summary>コード解説</summary><div>

1．VideoFileClipを使用して、入力動画ファイル（'IMG_3657.mov'）を読み込みます。

2．動画情報を取得します。これには、動画の解像度（幅と高さ）、回転角度、フレームレート（fps）、および動画の長さ（秒単位でのduration）が含まれます。

3．動画の回転角度（rotation）を確認し、回転が90度の場合は、幅と高さを入れ替えて正しい解像度にする必要があります。

4．write_videofileメソッドを使用して、指定された出力ファイル名（'IMG_3657.mp4'）で動画をMP4形式で保存します。この際、コーデックとしてlibx264を使用し、ffmpeg_paramsを設定して、必要に応じて解像度を調整します。

</div></details>

お疲れさまでした。
Ubuntu環境にてDockerインストール後の一般ユーザーへの切り替え方法

こちらの記事は[ジャンルなしオンラインもくもく会 Advent Calendar 2023](https://adventar.org/calendars/8821)の11日目の記事になります。

最近仮想環境のUbuntuでDockerを使用することがあり、インストール後の一般ユーザーへの切り替え手順を毎回忘れてしまうので、メモ書きとして残しておく

## Ubuntu
- Ubuntu Jammy 22.04 (LTS)

## Dockerのインストール
下記を参照してインストールを実行
https://docs.docker.com/engine/install/ubuntu/


## 一般ユーザーへの切り替え
```bash
# 現在のユーザーをDockerグループに追加
$ sudo usermod -aG docker ${USER}

# 下記いずれかを実行
$ su - ${USER}
$ newgrp docker

# 変更が正しく適用されているか確認
$ groups ${USER}

```

上記の手順を行う場合、Dockerデーモンはrootとして動作し、Dockerグループのユーザーは実質的にroot権限を持つ可能性があるため、信頼できるユーザーのみをDockerグループに追加する方がいいかも。
あくまで仮想環境の検証用として使うだけなのでここまでにします。
自分用　Linuxの基本操作

## ディレクトリ操作
### pwd
pwd（Print Working Directoryの略）は、現在の作業ディレクトリ（カレントディレクトリ）の絶対パスを表示するためのコマンドです。
絶対パスは、ファイルやディレクトリがルートディレクトリからのパスで表される形式です。
```
# 現在の作業ディレクトリのパスを表示する
pwd
```
```
# 出力結果の例
/home/username/documents
```
### ls
ls（Listの略）は、ファイルやディレクトリの一覧を表示するためのコマンドです。

```
# カレントディレクトリ内のファイルやディレクトリを一覧表示する
ls
```
ただlist表示するだけでなく、表示形式を変えるために様々なオプションがあります。
-l: 詳細な情報を含む長い形式で表示します。
-a: 隠しファイルも含めて表示します。
-h: ファイルサイズを人間が読みやすい形式で表示します。
-t: ファイルやディレクトリを最終更新時刻順に並べ替えて表示します。
```
# オプションの使用例
ls -t
```

### cd
cd（Change Directoryの略）は、作業ディレクトリを変更するためのコマンドです。
```
# ホームディレクトリに移動する
cd
# ユーザーのホームディレクトリに移動する
cd ~
# 相対パスでディレクトリに移動する
cd 相対パス
# 絶対パスでディレクトリに移動する
cd /絶対パス
#　最上位のディレクトリ（通常はルートディレクトリ）に移動
cd /
```
#### 相対パスとは
相対パスは、現在の作業ディレクトリから見た目標ディレクトリまたはファイルまでのパスです。
lsを使って、どのディレクトリに移動するか確認できます。
```
# 現在のディレクトリから"documents"ディレクトリに移動
cd documents
# 現在のディレクトリから親ディレクトリに移動
cd ..
```

#### 絶対パスとは
絶対パス（Absolute Path）は、ファイルやディレクトリがルートディレクトリからの完全なパスで指定される形式です。つまり、ファイルやディレクトリの位置を、ファイルシステムのルートからの階層で正確に示すものです。
```
# Unix/Linux系システム
/home/ユーザー名/documents/example.txt
# Windowsシステム
C:\Users\ユーザー名\Documents\example.txt
```
### mkdir
mkdir（Make Directoryの略）は、新しいディレクトリ（フォルダ）を作成するためのコマンドです
```
mkdir ディレクトリ名
```
### rmdir
Unix/Linux システムでは、rmdir ディレクトリ名で指定したディレクトリが削除されます。
```
rmdir 古いディレクトリ
```

## ファイル操作
### cp
cp（Copyの略）は、ファイルやディレクトリをコピーするためのコマンドです。
```
cp ソースファイル デスティネーション
```
例えば、ファイル "example.txt" をディレクトリ "backup" にコピーする場合
```
cp example.txt backup/
```
### mv
mv（Moveの略）は、ファイルやディレクトリを移動するためのコマンドです。
```
mv ソース デスティネーション
```
例えば、ファイル "example.txt" をディレクトリ "documents" に移動する場合：
```
mv example.txt documents/
```
ファイルやディレクトリの名前を変更する場合も同様に、mvコマンドを使用します。
```
mv 古い名前 新しい名前
```
### rm
rm（Removeの略）は、ファイルやディレクトリを削除するためのコマンドです。
```
rm ファイル名
rm -r ディレクトリ名
```
### less
lessは、UnixやLinuxシステム上でテキストファイルの内容を閲覧するためのコマンドラインユーティリティです。
```
less ファイル名
```
このコマンドを実行すると、指定したファイルの内容がページ単位で表示され、lessモードが開始されます。ファイルの内容が画面に収まりきらない場合は、矢印キーなどを使用してスクロールできます。
大きなログファイルやテキストファイルを手軽に閲覧できます。
### tail
tailは、UnixやLinuxシステム上でテキストファイルの末尾を表示するためのコマンドラインユーティリティです。
```
tail ファイル名
```
このコマンドを実行すると、指定したファイルの末尾の内容が表示されます。ただし、これは静的な表示であり、ファイルが更新されると表示が変更されません。
### grep
grepは、UnixやLinuxシステム上でテキストデータの中からパターンに一致する行を検索するためのコマンドラインユーティリティです。grepは非常に柔軟で強力なテキスト検索ツールであり、標準入力やファイルからテキストを検索してマッチする行を表示します。
```
grep パターン ファイル名
```
例えば、ファイル "example.txt" から文字列 "search" を含む行を検索する場合
```
grep "search" example.txt
```
該当するファイルを見つける
```
grep -rl "検索文字列" /path/to/search
```
-r: 再帰的に検索。
-l: ファイル名だけを表示します。
LinuxとWindowsのデュアルブートの解除方法。もうデュアルブートなんてしない

# はじめに
えか太郎です。三者面談って素晴らしいですよね。なにせ一週間の間学校が午前中で終わるんですよ！もはや人生の夏休みと言っても過言ではない（過言である）本日は私のPCからUbbuntu君を追放したいと思います。SSDが128GbしかないのでVisual Studio入れるだけでほぼいっぱいです。
# 解除方法
なんかネット上ではパーティションの管理からLinuxの領域を削除して大丈夫という意見とコマンドでGPTだとかGRUBのおブートローラーのLinuxを消してからという意見に二分されておりどっちが正しいか分からなかったので簡単なパーティションから消す方法を取りました。まあどうせ回復用のUSB持ってますしその時はその時考えればよかろうなのです。
## LinuxのOSを消したら
その後は管理者権限でコマンドプロンプトを開いて「diskpart」を使用して回復パーティションを削除しました。私の場合ほかのPCSでインストールメディア作れるので回復パーティションは不要なのです。詳細は書いても以下のページの模倣でしかなくなると思ったのでリンク貼っときます。この記事は以下の方法でも大丈夫だったという例の一つくらいに考えておいてください。

https://pc-karuma.net/windows-10-delete-recovery-partition-diskpart/

# 結果
失われし64GBを取り戻すことに成功しました。SDカードによる増設も検討しています。SDXCカードは2TBまで対応してるのでだいぶ増やせますね。
# 終わりに
解除していて思いましたがデュアルブートって作成は簡単なんですが解除が面倒くさすぎる。それに間違えてデュアルブートマネージャーを消したりでもしたら起動しなくなるなんて罠過ぎませんかね。もうデュアルブートなんてしたくない。最低でもデュアルストレージ、または仮想でやります。対戦ありがとうございました。
DB TECH SHOWCASE2023に行ってきました

# 感想
DB TECH SHOWCASE2023が先日行われて、参加してきました。
https://www.db-tech-showcase.com/2023/

私はDBエンジニアではないのですが、業務で利用するDBなどの選定に関わることもあるので情報収集を目的に参加しました。
いくつかの観点で感想を書かせていただきます。

## 時代の傾向
Databaseのカンファレンスなのだが、生成AIという言葉が当たり前に飛び交う状況でした。
データがAIを動かすためのエネルギーとも言えるのでDBサイドから見ても収集、利活用できることは時代の流れなのだと感じた。
クローズドセッションですら、AIのシンギラリティの話をしてしまうといった正直数年前では想像が着かないような状況であることを再実感した。
多くの企業がDWHを作ろうとして苦労してきた中、技術で多くの手法が取れるようになったことで選択肢もある中で、AIの台頭とエンジニアがどう向かい合うべきなのか？と考えらさせられる3日間でした。
AIが学習できる形に処理すること？可視化できるためのデータ整形？全体を俯瞰したデータフローの整備？まだまだ人の手によって補われつつあるも、機械的にできる作業は本当に人の手でやらなくなるんだろう感じつつ、クリエイティブな仕事をしなければいけないなと思いました。

## Databaseトレンドは？
業務ではRDB系のものを使用することが多い中で、セッションで圧倒的な人気を持っていたのはTiDBというNewSQL型のデータベースだった。関連セッションは予約できなかった人のために座席を用意するといった満席を通り越していた。
私も今回一番いろいろ話を聞いてみたかったDBだったし、話を聞いてみて可能性を感じれたことは収穫だったと思えました。（フリーでも使えるので時間があるときに構築して記事にしようかな）
ですが、用途に応じた使い方は必要でエンジニアには状況に応じた選択が迫られる時代になるんだと感じました。
他にも時系列型ＤＢやGraphDB、NoSQLが廃れてきているわけではなく、このデータ社会の中で有効的に使える道を備えていた。すべてが置き換わるわけではないのだと実感できて自分の認識の正しさが再確認できてよかったです。

## 統括
データ社会になるつつあり、私たちが認識していないところでもデータが取られていることがある世界になってきまた。ですが、データを単純に貯める時代から利活用することに時代はシフトしてきていました。正直まだまだ利活用できてきているのかという観点では、まだまだなのでは？と思えることは多かったですが、実現できた手法もあるので挑戦していく姿勢は必要なんだと思いました。
クローズドセッションでも話題になりましたが、今AIの進化が想像もつかないような速度で進む中エンジニアとして取り残されないように日々の情報収集、検証が怠れないと思えました。（サラリーマンエンジニアを否定するわけではないです）
LeetCode備忘録_その１

# 概要
LeetCode(https://leetcode.com/) を始めてみた。
せっかくなので１テーマごとに解法と学びをアウトプットしてみる。

# きっかけ
「世界一流エンジニアの思考法」内で紹介されており、筆者と現在の自分が重なるところがあったため。

https://www.amazon.co.jp/%E4%B8%96%E7%95%8C%E4%B8%80%E6%B5%81%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E6%80%9D%E8%80%83%E6%B3%95-%E7%89%9B%E5%B0%BE-%E5%89%9B/dp/4163917683

# 取り組む内容
- こちらのロードマップ（https://neetcode.io/roadmap) に沿って実施する。
- 言語はPython


![スクリーンショット 2023-12-11 1.31.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3636949/294af7ca-d769-b5ca-51d2-1a05b58036d5.png)

# まとめ
- LeetCodeを始めます
- アウトプットとして１テーマごとにQitaに記事投稿します