OmniAICreator/Qiita-1.07M huggingface dataset:
【Grafana】Zabbix Pluginの有効化(Enable)でちょっとハマった話

# はじめに
今回はZabbixとGrafanaを連携するときに少しハマった話をご紹介します。

## Grafana とは
**Grafana**とは、データの視覚化と監視を行うためのオープンソースのプラットフォームです。様々なデータソースから情報を取得し、ダッシュボードで表示することができます。

## Zabbix とは
**Zabbix**とは、オープンソースの監視ツールです。システムの稼働状況、リソース使用率、ネットワークトラフィックなどをリアルタイムで監視し、異常が発生した際にはアラートを通知します。柔軟な設定が可能です。

# 環境説明

| MacOS | Multipass | Ubuntu | Zabbix | Grafana | Grafana Plugin |
|:-:|:-:|:-:|:-:|:-:|:-:|
| 15.0.1  | 1.15.0-dev.2929.pr661+gc67ef6641.mac  |  20.04 LTS | 5.0.44  |  11.2.2 | 4.5.5  |

`Grafana Plugin` : `alexanderzobnin-zabbix-app`

# 実施していた手順

1. Zabbixのインストール
2. Grafanaのインストール
3. Zabbix用のGrafana Pluginのインストール
4. ZabbixとGrafanaの連携設定
5. Grafanaのリバースプロキシ用設定   

# つまったこと

Pluginをインストールした後、[公式ドキュメント](https://grafana.com/docs/plugins/alexanderzobnin-zabbix-app/latest/configuration/)通りにPluginの`Enable`を行おうとしましたが、`Enable`と書かれたボタンが表示されていませんでした。

![スクリーンショット 2024-10-16 19.20.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/99031365-63a3-fb83-9766-4c1cf1b1d556.png)

既にインストールしたはずなのに、右上に`Install`と表示されています。

# 解決方法

`grafana`ユーザーがPluginにアクセス出来なかったことが問題でした。

```
sudo chown -R grafana:grafana /var/lib/grafana/plugins
sudo chmod -R 755 /var/lib/grafana/plugins
```
適切なアクセス権限を付与すると、画面が変わりました。

![スクリーンショット 2024-10-16 19.20.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3862159/5c4106f5-12cc-a090-e0c7-4a1f75e8010b.png)

右上に`Enable`が表示されました。その後は公式ドキュメント通りに進めることが出来ました。

# おわりに

ここまでお読み頂きありがとうございました。
今回の記事がどなたかのトラブルシューティングの役に立つと嬉しいです。

# 宣伝：エンジニアコミュニティのご案内

私が所属しているエンジニアコミュニティ **TechBull** では、定期的に輪読会やもくもく会を開催しています。これらのイベントは外部の方も参加可能です！ぜひ一緒に学びませんか？

## 輪読会
同じ書籍を読み進めながら、互いに意見を交換し、理解を深める場です。自分一人では難しい内容も、他のエンジニアと一緒に学ぶことで、新たな視点や理解が得られます。現在**connpass**などで外部の方も含めて行う形にはなっていませんが、もし興味があればご連絡ください！

## もくもく会
集中して作業を進める時間を共有する場です。自分のペースで学びたい方にぴったりです。自分の知らない領域を学ばれている方と交流する貴重な機会にもなり、たまに参加すると刺激があります。時には雑談に発展するかも？

興味のある方やご質問などがあれば、ぜひお気軽にご連絡ください！

https://techbull.connpass.com/

私が**TechBull**に参加して1ヶ月の感想記事はこちらにあります！
興味を持たれた方はお読みいただけると嬉しいです。

https://techbull.cloud/archives/1121
VSCodeのターミナルでtouchコマンド以外の方法で新規ファイルを作成する【Windows】

WindowsでTouchコマンドが使えなかった
検索で代替コマンドがすぐに出てこなかったので、ここに残す

<h2>直下にファイルを作成する</h2>

```terminal:直下に作成
ni hoge.text
```

<h2>ディレクトリ指定</h2>

```terminal:直下に作成
ni src/hoge.text
```

<h2>参考</h2>

https://qiita.com/oioigohan/items/8166634183a40de692f9
pythonでYouTubeの動画をダウンロード

pythonでYouTubeの動画をダウンロードする方法
```
pip install yt-dlp
```


```
import yt_dlp as youtube_dl

def download_channel_videos(channel_url):
    # ダウンロードオプションを定義
    ydl_opts = {
        'format': 'best',  # 動画の最適なフォーマットをダウンロード
        'outtmpl': '%(title)s.%(ext)s',  # 保存するファイル名のフォーマット
        'ignoreerrors': True  # エラーがあっても処理を継続する
    }

    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        ydl.download([channel_url])

# チャンネルのURLを指定
channel_url = 'https://www.youtube.com/@/チャンネルのID/videos'
download_channel_videos(channel_url)

```

特定のチャンネル動画を一括DL
このコードはYouTubeの利用規約や著作権に関する法律に遵守する範囲で使用
cloudflareドキュメントの日本語訳サイトをつくった

技術系のドキュメントを読むときにはGoogle翻訳にお世話になっているが、`<code>`などが多用されている都合上、レイアウトが崩れたりするので、いっそ日本語訳サイトを作った。

https://ja.cloudflare.opendocs.dev
GemfileのコメントはWHATではなくWHYを記載しよう

## はじめに

Gemfile内のコメントを見直す機会があったため、効果的なコメントの記述方法について再確認しました。
<br>

この記事では、コメントに記載すべき「WHAT」と「WHY」の違いや、よくあるミス、具体的な記述例をまとめます。

## WHATとWHYの違い

- **WHAT（何をしているか？）**：コードが何をするか、どのように動作するかを説明
- **WHY（なぜそれをするのか？）**：そのコードが必要な理由、背景、意図を説明
<br>

多くの場合、コード自体やGemの公式ドキュメントを読めば「WHAT」は理解できます。
<br>

しかし「WHY」はコードだけでは伝わらないことが多く、保守運用を行う際の障壁となります。

## Gemfileのコメントでありがちなミス

```ruby:Gemfile
# 認証機能を提供するGem
gem 'devise'

# ページネーションを実装
gem 'kaminari'
```
<br>

たとえば上記のようなコメントは一見親切に思えますが、実際には冗長です。
<br>

Gemの名前からすぐに推測もしくは検索できる情報だからです。
<br>

これではコメントの価値が半減してしまいます。

## WHYを記載するメリット

1. **将来の変更に備える**；特定のGemのバージョンを固定している理由や削除できない訳を記載することで、後続の開発者がメンテナンスする際のリスクを減らせます
2. **問題の再発防止**；過去に遭遇したバグや互換性の問題を記載しておくと、同じ理由で悩む時間を節約できます
3. **ナレッジ共有**：「なぜその選択をしたのか」を記すことでチーム全体の理解が深まります

## 具体例

### バージョンを上げられない場合

```ruby:Gemfile
# Rails 7へのアップグレードで互換性の問題が発生するため、バージョンを固定
gem 'some_gem', '~>1.2.3'
```

### Gemを削除してはいけない場合

```ruby:Gemfile
# 旧システムとの連携で必要なので削除不可
gem 'legacy_support_gem'
```

### 特定のGemを採用した理由

```ruby:Gemfile
# パフォーマンスの問題からcarrierwaveではなくactive_storageを使用
gem 'active_storage'
```

## まとめ

Gemfileのコメントでは「WHAT」ではなく「WHY」に焦点を当てることで、可読性と保守性を向上させられます。
<br>

無意味なコメントを避け、必要な情報を的確に記述する習慣をつけていきましょう。
JavaScriptで本格カレー作りをシミュレートする


JavaScriptの勉強を始めたばかりの頃、数値やアルファベットを扱うだけではなかなか実感が湧かないことってありますよね。私もいろいろな本や動画で学んできましたが、一番面白くて理解しやすかったのは、先輩が教えてくれた「カレー作りを再現するJavaScriptの説明」でした。
そこで今回は、その経験を活かして備忘録と復習＋αを兼ねて、JavaScriptで本格的なクッキングに挑戦してみましょう！
## 1. カレーを作る関数：makeDetailedCurry
まず、カレーを作る手順を一つずつ書いた関数があります。この関数の名前は `makeDetailedCurry`（「本格カレー作り」）です。
関数とは、特定の処理をまとめた部分のことです。
```javascript 
const makeDetailedCurry = () => { console.log("本格カレー作りスタート！"); }
```
最初に「カレー作りがスタートしたよ！」というメッセージを表示します。
## 2. 材料を準備する
次に、カレーの材料を準備します。ここで使う材料を `ingredients` という名前のオブジェクト（たくさんの物をまとめた箱のようなもの）にまとめています。
```javascript 
const ingredients = { 玉ねぎ: "みじん切り", にんじん: "乱切り", じゃがいも: "一口大にカット", 鶏肉: "一口大にカット", にんにく: "すりおろし", しょうが: "すりおろし", }; 
```
例えば、「玉ねぎ」は「みじん切り」にしておく、といった風に、準備方法も一緒に書かれています。
## 3. スパイスの準備
次に、使うスパイスをリストにして準備しています。
```javascript 
const spices = [ "カレーパウダー", "ガラムマサラ", "クミンシード", "コリアンダーパウダー", "ターメリック", "チリパウダー", "カルダモン", "クローブ", "シナモン", "フェヌグリーク" ];
```
これらはカレーを特別な味にするためのスパイスです。
## 4. カレー作りの手順を書く
カレー作りの各手順をリストにして、順番に行います。
```javascript 
let steps = []; 
```
まずは空っぽのリスト（手順を入れる箱）を `steps` として作ります。そして、材料の準備から始めて、順番に手順をリストに追加していきます。
### 材料の準備
```javascript 
Object.entries(ingredients).forEach(([ingredient, preparation]) => { steps.push(${ingredient}を${preparation}にする); }); 
```
これは、各材料（`ingredient`）をどのように準備するか（`preparation`）をリストに入れています。例えば「玉ねぎをみじん切りにする」といった感じです。
### 他の手順も追加
次のステップではスパイスを使ったり、材料を炒めたりする手順を書いています。
```javascript 
steps.push("フライパンでクミンシードを乾煎りして香りを引き出す");
```
これは「クミンシードというスパイスを炒めて香りを引き出す」という手順です。他にもたくさんの手順を順番に追加しています。例えば、
「玉ねぎを炒める」
「にんにくとしょうがを加える」
「鶏肉や野菜を加える」
「スパイスを全部加える」
 ```javascript 
 spices.forEach((spice) => { steps.push(`${spice}を加える`); });
 ```
「水を加えて煮込む」
などの手順を全部リストに入れています。
## 5. 手順を表示する
最後に、全ての手順を順番に実行して表示します。
```javascript 
steps.forEach((step, index) => { console.log(ステップ${index + 1}: ${step}); }); 
```
`steps` リストの中身をひとつずつ取り出して、「ステップ1」「ステップ2」といった感じで順番に表示します。
## 6. カレー完成のメッセージ
```javascript 
console.log("本格カレーが完成しました！おいしいカレーを召し上がれ！"); 
```
最後に「本格カレーが完成しました！」というメッセージを表示します。
## 7. カレーを返す
関数 `makeDetailedCurry` は最後に「本格カレー」という文字を返します。これは、このカレーを他の関数で使うためです。
```javascript 
return "本格カレー"; 
```
## 8. スプーンを添える関数：serveWithSpoon
次に、カレーにスプーンを添えるための関数があります。この関数の名前は `serveWithSpoon` です。
```javascript 
const serveWithSpoon = (dish) => { console.log(${dish}にスプーンを添えて、いただきましょう！); }; 
```
この関数は、「`dish`（料理）」にスプーンを添える、というメッセージを表示します。
## 9. カレーを作ってスプーンを添える
最後に、カレーを作り、そのカレーにスプーンを添えます。
```javascript 
const curry = makeDetailedCurry(); serveWithSpoon(curry); 
```
まず `makeDetailedCurry()` でカレーを作って、その結果を `curry` という名前に入れます。そのあとで `serveWithSpoon(curry)` で、作ったカレーにスプーンを添えるメッセージを表示しています。
## まとめ
いかがでしたか？`makeDetailedCurry` 関数でカレーを作り、`serveWithSpoon` 関数でスプーンを添えることで、本格カレーができました。カレー作りだとJavaScriptでの処理の流れをより具体的に理解できたのではないでしょうか。私ももっとコードに関する理解を深めていきたいなと思いました。
## 採用拡大中！

アシストエンジニアリングでは一緒に働くフロントエンド、バックエンドのエンジニア仲間を大募集しています！
少しでも興味ある方は、カジュアル面談からでもぜひお気軽にお話ししましょう！
お問い合わせはこちらから↓
[https://official.assisteng.co.jp/contact/](https://official.assisteng.co.jp/contact/)
PythonでPDF文書から余白を削除する

PDF文書を扱う際、ページの余白が大きすぎる場合に遭遇することがあります。この過剰な余白は、ページのスペースを無駄にするだけでなく、印刷や電子閲覧時にユーザー体験にも影響を与えることがあります。この不要な余白を削除することで、ページのエリアをより効果的に活用し、内容をよりコンパクトに読みやすくすることが可能です。特に印刷が必要な文書の場合、紙のコスト削減にもつながります。Pythonを使用して、この問題を効率的に解決し、**PythonコードでPDF文書の余白を削除**し、自動化することで、文書整理のニーズに対応できます。

この記事で使用する方法では、[Spire.PDF for Python](https://jp.e-iceblue.com/introduce/spire-pdf-for-python.html)を使用します。PyPIからインストールするには：`pip install spire.pdf`。

[無料ライセンスの申請](https://www.e-iceblue.com/TemLicense.html)

## PythonでPDF文書の余白を削除する
Spire.PDFの`PdfDocument.PageSettings.Margins`プロパティを使って、PDF文書の上下左右の余白を取得し、新たに余白のないページを作成した上で、元のページを余白を削除した位置から新しいページに描画し、最後に元のページを削除することで余白の削除を実現できます。以下はその手順の例です：
1. 必要なモジュールをインポートします。
2. `PdfDocument`オブジェクトを作成し、PdfDocument.LoadFromFile()メソッドでPDF文書を読み込みます。
3. `PdfDocument.PageSettings.Margins`プロパティで文書の余白を取得します。
4. `PdfDocument.Pages.Count`プロパティで現在のページ数を取得します。
5. 文書内の各ページをループ処理します：
    - `PdfDocument.Pages.get_Item()`メソッドで現在のページを取得します。
    - `PdfDocument.Pages.Add(pageSize: SizeF, pageMargins: PdfMargins)`メソッドで、余白を引いたサイズで、かつ余白がゼロのページを作成します。
    - `PdfPageBase.CreateTemplate()`メソッドで元のページのテンプレートを作成します。
    - `PdfPageBase.Canvas.DrawTemplate()`メソッドで、余白を引いた位置から新しいページにテンプレートを描画します。
6. 元のページをループ処理し、`PdfDocument.Pages.RemoveAt()`メソッドで全ての元のページを削除します。
7. `PdfDocument.SaveToFile()`メソッドで文書を保存します。
8. リソースを解放します。

**コード例**
```python
from spire.pdf import *

# PdfDocumentのインスタンスを作成
pdf = PdfDocument()

# PDF文書を読み込む
pdf.LoadFromFile("Sample.pdf")

# PDF文書の余白を取得
margins = pdf.PageSettings.Margins
top = margins.Top
left = margins.Left
right = margins.Right
bottom = margins.Bottom

# PDF文書内の全てのページを処理
pageCount = pdf.Pages.Count
for i in range(pageCount):
    # 現在のページを取得
    page = pdf.Pages.get_Item(i)
    # 新しいページを作成し、そのサイズと余白を設定
    newPage = pdf.Pages.Add(SizeF(page.Size.Width - left - right, page.Size.Height - top - bottom), PdfMargins(0.0))
    # 元のページのテンプレートを作成
    template = page.CreateTemplate()
    # 元のページの内容を余白を引いた位置に新しいページに描画
    newPage.Canvas.DrawTemplate(template, PointF(-left, -top))

# 元のページを削除
for i in range(pageCount):
    pdf.Pages.RemoveAt(0)

# 変更後のPDFファイルを保存
pdf.SaveToFile("output/PDFの余白を削除.pdf")
pdf.Close()

```

結果
![PythonでPDFの余白を削除](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/877b90bc-9c88-7f50-dcea-01dfd8c83f4c.png)

この記事では、Pythonを使用してPDF文書のページ余白を削除する方法を紹介しました。
【jQuery】DataTablesで`<sample>`のような文字列をHMTLタグとして認識させずに表示させる方法

# 概要
jQueryのDataTablesを利用中のサイトで`<sample>`のような`<>`で括られた文字列を扱うと、HMTLタグとして認識されてしまい表示されない事象を確認しました。こちらの原因と解決方法を紹介します。

# 原因
原因は、データを適切にエスケープしていなかったためでした。
jQueryの`text`メソッドを使用してデータをエスケープすることができます。

以下、サンプルコードです。

```js
$(document).ready(function() {
    $('#example').DataTable({
        "ajax": {
            "url": "/your-data-url/",
            "dataSrc": ""
        },
        "columns": [
            {
                "data": "sample_data",
                "render": function(data) {
                    return $('<div/>').text(data).html();
                }
            },
            // 他のカラム設定
        ]
    });
});
```


`render`関数は、データを表示する前にカスタム処理を行うために使用できます。

`return $('<div/>').text(data).html();`がjQueryを使用してデータをエスケープしている箇所。
`$('<div/>').text(data)`は、データをテキストとして`<div>`要素に設定し、`.html()`はエスケープされたHTMLを取得します。

これにより、`<sample>`といった文字列がDatatables上に正常に表示されました。

ちなみに、`text()`と似たメソッドに`html()`があります。
ただ、

`return $('<div/>').html(data).html();`

のようにすると、`<sample>`はDataTablesに表示されませんでした。
これは、`html()`だとエスケープされずにHTMLタグとして認識するためです。
`<p>`タグなどを実際にタグ要素として認識させたい場合には活用できます（今回はただの文字列として扱いたいので`text()`の方でOK）。

## 参考記事

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


https://www.techscore.com/blog/2013/10/15/javascript%E3%81%AE%E3%82%A8%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%97%E3%81%82%E3%82%8C%E3%81%93%E3%82%8C/

## 公式ドキュメント

https://api.jquery.com/text/
Pythonのisと==の違い

Pythonにおいて`is`と`==`は、両方とも比較を行うために使用されますが、用途と意味が異なる

### isと==の違い

|比較演算子	|説明	|使用例|
|---|---|---|
|is	|オブジェクトの同一性を比較。2つのオブジェクトが同じメモリ上の場所を指しているかどうかを確認。|	x is y|
|==	|値の等価性を比較。2つのオブジェクトが同じ値を持つかどうかを確認。	|x == y|

### is の詳細

- 同一オブジェクトであるかを確認します。
- これは、2つの変数が同じメモリ位置を指しているときのみ`True`になる
- 主にシングルトンオブジェクト（`None`や`True`など）やインスタンス比較につかう

```python
a = [1, 2, 3]
b = a  # bはaと同じオブジェクトを参照

print(a is b)  # True（同じオブジェクトを参照）
print(a == b)  # True（値も等しい）

```

### == の詳細

- 値が等しいかどうかを確認します。
- 2つのオブジェクトが異なるメモリ位置にあっても、内容が同じであれば`True`を返す

```python
a = [1, 2, 3]
b = [1, 2, 3]  # bは新たなリストを生成

print(a is b)  # False（異なるオブジェクト）
print(a == b)  # True（値は等しい）
```

### is と == を使う際の注意点

- `is`は`None`の比較でよく使われます。`==`でも比較可能ですが、`None`の比較には`is`を使うのが慣習である

```python
x = None

if x is None:
    print("xはNoneです")  # 推奨される書き方
```

- イミュータブルなオブジェクト（`int`や`str`など）の場合、isは一見使えるように見えることがありますが、特定の条件で予測しづらい挙動を示すため、`==`を使う方が安全である

```
a = 1000
b = 1000

print(a is b)  # False（大きい整数では異なるオブジェクト）
print(a == b)  # True（値は同じ）

```

- 小さな整数（例：-5～256の範囲）はキャッシュされるため、`is`が`True`になる場合がある

```
a = 10
b = 10

print(a is b)  # True（キャッシュされたオブジェクト）
```

### まとめ

- `is`：2つの変数が同じオブジェクトかどうかを確認する
- `==`：2つの変数の値が等しいかどうかを確認する
- `None`の比較にはisを使用するのが推奨される
- 値の比較には基本的に`==`を使い、オブジェクトの同一性が重要な場合にのみ`is`を使う

### 採用拡大中！

テックオーシャンでは一緒に働く情シス担当、データエンジニア仲間を大募集しています！

少しでも興味ある方は、カジュアル面談からでもぜひお気軽にお話ししましょう！

応募はこちらから↓

https://hrmos.co/pages/techocean/jobs/1898172211721719822
駆け出しフロントエンドエンジニアが『フロントエンドの知識地図（株式会社ICS著）』を読んだ感想

# 結論
フロントエンドの実務で必要な内容と、モダンな内容が網羅されており、中身もカラーで印刷されていて読みやすいと感じました。

ただ、こういった書籍あるあるかなとも思うのですが、実際に活用する場面がないと定着しないのかなとも思いました。
私自身も実務でまだ使わなそうだなという部分に関しては、すっかり忘れている気がします笑

ですが、一度耳にしたことがある部分に関しては改めて整理することが出来たので、そういった点は良かったかなと思います。

フロントエンドの技術の移り変わりは激しいとよく耳にしますが、それらの内容が網羅されていると感じました。ただどうしても書籍は出版された時点からどんどん時が経っていくので、最新の情報については自身で調べにいく必要があると思いました。

# おすすめする人
この本をおすすめする人は、
- フロントエンドエンジニアとして働いている人
- フロントエンドの実務内容について網羅したい人
- なんとなくフロントエンドの内容について整理してみたい人
- フロントエンドのモダンな内容についてキャッチアップしたい人（最新の内容は該当しない）

これらに該当する方が読むと納得しやすいのかなと思いました。
ただWeb系の場合、不明な点はその場で調べることが大半だと思いますので、

- 書籍で勉強するのが好き
- 書籍で勉強したい

という場合でなければ特に買わなくても良いかと思います...値段もそれなりにするので（汗）

でもなんとなく頭に入っているだけでも、何か課題を解決する時に引き出しが多くなるので読むのに越したことはないという、、、なんとも曖昧な結論ですね笑 ごめんなさい！！

気になった方はKindleや本屋さんでちらっと読んでみるのもよいかもしれません！
実数の精度が足りない

Atcoderの実数を出力する問題で精度が足りず中々ACできなかった。
## オプションなし
そのままcoutで実数を出力してみる
```a.cpp
#include<iostream>
using namespace std;

int main(){
    double pi = 3.141592653589793;
    cout << pi << endl; //3.14159
}
```
本来double型は16桁保持できるはずだが、6桁しか出力されていない。
真の値との相対誤差が$10^{-6}$以下の場合、丸め処理の関係でギリギリWAがでてしまう。

## オプションあり
`fixed`と`setprecision`を使うと
```b.cpp
#include<iostream>
#include<iomanip>
using namespace std;
int main(){
    long double pi = 3.141592653589793;
    cout << fixed << setprecision(15) << pi << endl; //3.141592653589793
}
```
`iomanip`をインクルードする必要があることに注意。
`fixed`と`setprecision`の説明は[c++ 浮動小数点数 表示方法](https://qiita.com/ryupim/items/1cbeb860d4a2f056358a)を見ていただいた方が分かりやすい。
## 一番楽な方法
C言語の`printf`関数を使うのが一番簡単。
```c.cpp
#include<iostream>
int main(){
    long double pi = 3.141592653589793;
    printf("%Lf\n", pi); //3.141593
}
```
`cout`よりも1桁多く出力されるので、丸め処理でWAが出ることはない。
M5NanoC6をRGB.LEDスレーブI2Cして遊ぶ。



目的
I2Cのテスト

結果

![o_coq521.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/8459d1f4-5313-70eb-1951-c6a79a0b006a.jpeg)

![o_coq522.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/c49e62ce-d2be-54c8-3a86-1e70fccc7cc2.jpeg)

![o_coq523.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/afd2bf9f-4eac-f85e-fb3e-15d111520a64.jpeg)



プログラム

受信 I2Cスレーブ M5NanoC6

```c++



//I2C_RGB_LED_V1_M5NanoC6_1


//インクルド
#include <Arduino.h>
#include <Wire.h>
#include <M5NanoC6.h>
#include <Adafruit_NeoPixel.h>


//ネオピクセルの定義
#define NUM_LEDS 1
Adafruit_NeoPixel strip(NUM_LEDS, M5NANO_C6_RGB_LED_DATA_PIN,
                        NEO_GRB + NEO_KHZ800);


//初期化
void setup() {

  // Enable RGB LED Power
  pinMode(M5NANO_C6_RGB_LED_PWR_PIN, OUTPUT);
  digitalWrite(M5NANO_C6_RGB_LED_PWR_PIN, HIGH);

  strip.begin();
  strip.show();


  //i2cの初期化
  Wire.begin( (0x80)>>1 );      //I2Cスレーブアドレスの設定
  Wire.onReceive(receiveEvent); //データが来ると呼ばれる関数

} //setup


//メインループ
void loop() {
  delay(1); //ダミー
} //loop


//レシーブイベント
void receiveEvent(int howMany) {

  int r = Wire.read(); //I2C受信データの読み込み
  int g = Wire.read(); //I2C受信データの読み込み
  int b = Wire.read(); //I2C受信データの読み込み

  //                                 r  g  b
  strip.setPixelColor(0, strip.Color(r, g, b));
  strip.show();

} //receiveEvent


```

送信 I2Cマスター M5Stamp S3

```c++



//I2C_PUT_RGB_LED_M5S3_1


//インクルド
#include <Arduino.h>
#include <Wire.h>


//初期化
void setup() {

  Wire.begin();    //I2Cの初期化

} //setup


//メインループ
void loop() {

  //R 転送
  Wire.beginTransmission( (0x80)>>1 );
  Wire.write(255);
  Wire.write(0);
  Wire.write(0);
  Wire.endTransmission();
  delay(1000); //1秒待つ

  //G 転送
  Wire.beginTransmission( (0x80)>>1 );
  Wire.write(0);
  Wire.write(255);
  Wire.write(0);
  Wire.endTransmission();
  delay(1000); //1秒待つ

  //B 転送
  Wire.beginTransmission( (0x80)>>1 );
  Wire.write(0);
  Wire.write(0);
  Wire.write(255);
  Wire.endTransmission();
  delay(1000); //1秒待つ

} //loop


```
日常業務で必須のExcelコマンド【10選】

<br>

# ■ はじめに
<br>

今やExcelは、様々な業務で使用することになるメジャーなツールです。
しかしExcelには膨大な機能があるため、どのコマンドを覚えれば良いのか迷うこともありますよね。
この記事では日常の業務で役立つ「必須のExcelコマンド10選」を紹介します。

# ■ 目次
<br>

1. [SUM（合計）](#1-sum合計)
2. [IF（条件分岐）](#2-if条件分岐)
3. [VLOOKUP（検索）](#3-vlookup検索)
4. [COUNT/COUNTA（数値とセルの数を数える）](#4-countcounta数値とセルの数を数える)
5. [CONCATENATE（文字列結合）](#5-concatenate文字列結合)
6. [INDEX & MATCH（検索）](#6-index--match)
7. [SUMIF/SUMIFS（条件付き合計）](#7-sumifsumifs条件付き合計)
8. [TEXT（形式設定）](#8-text形式設定)
9. [LEFT/RIGHT/MID（文字列抽出）](#9-leftrightmid文字列抽出)
10. [ピボットテーブル](#10-ピボットテーブル)

# 1. SUM（合計）
<br>

最もよく使われるExcelのコマンドが`SUM`です。
指定した範囲の数値を合計することができます。


```excel
=SUM(A1:A10)
```

この例では、A1からA10のセルの合計を計算します。

# 2. IF（条件分岐）

<br>
条件に応じて異なる結果を表示する場合に使用します。

```excel
=IF(A1>10, "大きい", "小さい")
```

A1に入力した値が10より大きい場合、「大きい」と表示されます。
10以下の場合には「小さい」と表示されます。

# 3. VLOOKUP（検索）
<br>
指定した範囲の中から縦方向に値を検索し、対応するデータを返します。<br>
表などのデータから情報を探す際に便利なコマンドです。

```excel
=VLOOKUP(B1, A1:C10, 2, FALSE)
```

B1の値をA1～C10の範囲で検索し、2列目のデータを返します。

# 4. COUNT/COUNTA（数値とセルの数を数える）
<br>
COUNTは数値が入力されているセルの数、
COUNTAは空でないセルの数を数えます。

```excel
// 範囲の数値のみ
=COUNT(A1:A10)

// 範囲の空でないセルすべて
=COUNTA(A1:A10)
```

# 5. CONCATENATE（文字列結合）
<br>
複数のセルの内容を結合して1つの文字列にする際に便利なのがCONCATENATEです。

使い方:
```excel
=CONCATENATE(A1, " ", "太郎")
```

A1に「田中」と入力されていた場合、上記の結果としては「田中 太郎」と出力されます。

# 6. INDEX & MATCH
<br>
INDEXとMATCHを組み合わせると、VLOOKUPよりも詳細な検索ができます。

```excel
=INDEX(A1:C10, MATCH("検索したい値", B1:B10, 0), 1)
```

順序としてはまずMATCH関数でB列から値を探し、次にINDEX関数で対応するA列の値を取得する流れになります。

# 7. SUMIF/SUMIFS（条件付き合計）
<br>
条件に基づいて合計を計算したい場合には、SUMIFや複数条件のSUMIFSを用います。

```excel
// A列の値が10を超える場合にB列の値を合計
=SUMIF(A1:A10, ">10", B1:B10)

// 複数条件
=SUMIFS(B1:B10, A1:A10, ">10", C1:C10, "<20")  
```

# 8. TEXT（形式設定）
<br>
数値や日付を特定の形式で表示する際に、TEXT関数が使えます。

```excel
=TEXT(A1, "yyyy-mm-dd")
```

上記ではA1の値が「年-月-日」の形式で表示されます。

# 9. LEFT/RIGHT/MID（文字列抽出）
<br>

LEFT、RIGHT、MIDは文字列の一部を抽出するために使います。

```excel
// 左から5文字を抽出
=LEFT(A1, 5)

// 右から3文字を抽出
=RIGHT(A1, 3)

// 2文字目から4文字を抽出
=MID(A1, 2, 4)  
```

A1が「あいうえお」であった場合の出力は以下のようになります。
LEFTの場合：あいうえお
RIGHTの場合：うえお
MIDの場合：いうえお


# 10. ピボットテーブル
<br>
大量のデータを集計・分析するのに便利な機能がピボットテーブルです。
ピポットテーブルを使用することでデータを簡単に整理し必要な情報を素早く取得できます。

データ範囲を選択
「挿入」→「ピボットテーブル」をクリック
表示したいフィールドをドラッグ＆ドロップ

# まとめ

 - SUM
     範囲内の数値の合計を計算
 - IF
     条件に基づいて異なる結果を表示
 - VLOOKUP
     データ範囲から指定した値を検索
 - COUNT/COUNTA
     数値または空でないセルの数をカウント
 - CONCATENATE
     複数のセルの内容を結合
 - INDEX & MATCH
     高度な検索が可能
 - SUMIF/SUMIFS
     条件に基づく合計を計算
 - TEXT
     数値や日付の形式を整える
 - LEFT/RIGHT/MID
     文字列の一部を抽出
 - ピボットテーブル
     データを集計・分析する
macbook の開発環境セットアップメモ

macbook の開発環境をセットアップしたのでメモ書き

windows + wsl から mac (m3) に移行。

開発環境以外は省略。

## 言語系

[asdf](https://asdf-vm.com/guide/getting-started.html)を使う。しばらく使っているが特に困ったこともなく、便利。強いて言えば python の site-packages が探しにくいかも[^1]。

言語は必要なものを適宜入れる。ビルドに必要なツールは別途インストールする必要がある。

node, python はとりあえずグローバル設定をしておく。知らないうちに使われてたり、npm や pip でツールをインストールしたりするので。

筆者の環境だと github copilot (vim) で node が使われてる。

プロキシを使う場合、node については各バージョンで npm の設定が要るので忘れない。

```bash
npm config set proxy http://proxy.example.com:8080
```

.zshrc でのプロキシ設定も忘れない。

## neovim (vim)

neovim のインストールは brew なら一発。wsl のときはダウンロードしたバイナリにパスを通していた。

init.vim は[こちら](https://qiita.com/onzuka24/private/37ef03030385a3e90b51)

nvim-tree で使うフォントファイル(nerdfonts)も入れてみた。

リンターは使うものを適宜入れる。neovim では ALE プラグインを使っていて、
CLI　で使える状態のリンターを登録すれば保存時とかに実行してくれる。

### vscode

メインのエディタは neovim だが、vscode も使うのでインストール。

git graph が非常に便利。見やすい。

vscode 内で neovim を使うプラグインもあるが、リーダーキー周りの設定が面倒だったのでほぼ使っていない。

## docker

docker engine だけ導入する。Linux 固有の機能を使うようなので、mac だと一手間かかる。wsl だとすんなりインストールできたのだが。
今回は colima を試してみる。

localhost のポートでアクセスするために
`~/.colima/default/colima.yaml` で

```yaml
network:
address: true
```

を設定しておく。

rancher desktop で問題ないが、rancher のために稼働するコンテナが多くて見づらいので避けた。

colima のプロキシ設定はしていない気がするが、不要になったのか。

## ターミナル関係

[このサイト](https://zenn.dev/sprout2000/articles/bd1fac2f3f83bc) を参考に設定した。
`zsh-autosuggestions` くらいしか使っていないが、色々入れておくと便利そう。

よく使うコマンドだけエイリアスを設定。
nvim 用の `nv` と `docker compose` の `dc` を設定。

カーソルの色を変更した。vim のハイライトでたまに見づらくなるので、競合しない色にしておいた方が良い。

`grep` の代わりに `ripgrep` を導入した。段違いに速い。

## aws 関係

aws cli の設定を旧pcから移行。横着して `~/.aws` をコピーした。

---

[^1]: `~/.asdf/installs/python/3.12.3/lib/python3.12/site-packages` とかにある。asdfのコマンドから探せる。
MIAW を外部Webサイトへ埋め込み方法について

### 外部サイトのURLをCORSに登録

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/abf3641d-d5e7-c749-a631-29b98f18b011.png)

### MIAWサイトエンドポイントを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/701f07bd-667c-93b5-90a5-de79c177c910.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/deba7a0b-aa86-994f-10bd-98a018846e77.png)

### コードをコピー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/c27f54b5-546b-1372-13ba-7d5c726129a1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/6b04da44-5dda-4c7a-05e2-f1b195abe379.png)

### Trusted Domains for Inline Framesに外部サイトのドメインを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/9bf01d2c-ae06-d211-5fdd-25be1ec88414.png)


注意：サイトエンドポイント: ESW_MiwaService_17277500521321
より１桁少ない
ESW_MiwaService_1727750052132となっているサイト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/5096e9ea-61c9-d5e2-2580-83865e41803b.png)

Trusted Domains for Inline Framesに外部サイトのURLを追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/47e0cfa3-c14c-2760-3e8d-bd7816b6f4b1.png)

外部サイトが "https://gaibusite.com" の場合は、以下のように

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/8464b51d-5238-b198-01a1-29080b5cf62b.png)

追加しないと以下のエラーが発生
```
Refused to frame 'https://xxxxx-dev-ed.develop.my.site.com/' because 
an ancestor violates the following Content Security Policy directive: 
"frame-ancestors xxxxx-dev-ed--c.develop.f.force.com 
xxxxx-dev-ed.develop.my.site.com *.xxxxx-dev-ed.develop.my.site.com".
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/0f0fb495-f98b-7615-6a92-d962ca0c5f08.png)

注意：LocalにHTML形式のファイルを作るだけでは、動かない。
サーバーがある所に作らないと行けない。



### sample code
xxxxx部分はマスキングしたもの
```html
<html>
 <head>

<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
 <title>はじめてのMIAW</title>
 </head>
 <body>
   <h1>Hello MIAW</h1>
   <p>エンジニアをxxxxx </p>
<script type='text/javascript'>
	function initEmbeddedMessaging() {
		try {
			embeddedservice_bootstrap.settings.language = 'ja'; // For example, enter 'en' or 'en-US'

			embeddedservice_bootstrap.init(
				'00DIT000003nFQ5',
				'MiwaService',
				'https://xxxxx-dev-ed.develop.my.site.com/ESWMiwaService1727750052132',
				{
					scrt2URL: 'https://xxxxx-dev-ed.develop.my.salesforce-scrt.com'
				}
			);
		} catch (err) {
			console.error('Error loading Embedded Messaging: ', err);
		}
	};
</script>
<script type='text/javascript' src='https://xxxxx-dev-ed.develop.my.site.com/ESWMiwaService1727750052132/assets/js/bootstrap.min.js' onload='initEmbeddedMessaging()'></script>

</body>
</html>
```

### テスト結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/9c9d9c85-3b94-5956-e012-668ce161559c.png)
Power Platform の従量課金制プランを試してみた

Power Platform の従量課金制プランを試してみました。
[従量課金制プラン](https://learn.microsoft.com/ja-jp/power-platform/admin/pay-as-you-go-overview)

# Power Platform 従量課金制について知っておきたいこと
・Power Platform の従量課金プランを使用するには**Azure サブスクリプションが必要**
・従量課金制にするかどうかは**環境毎**に設定できる
・従量課金をオンにした環境では、**per app プランは併用できない**
・いつでも従量課金制を無効にすることができる

※2024年10月現在の情報です。最新情報はMS Learn などの公式ドキュメントをご確認ください。
# 設定方法
## 1. 請求ポリシーの作成

Power Platform 管理センターからポリシー＞請求ポリシー
請求ポリシーに付ける名前を記入
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/8e4db371-7dbb-b144-70cf-b514beeca416.png)


請求を紐づけたいAzureサブスクリプションとリソースグループを選択
地域を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/0a8d9560-8e4d-d9ce-45b8-9152974f9d08.png)


環境の選択
現状選択できる環境がないので何も選択せずに次へ進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/3a6fc7fe-0da7-f92e-536e-ebdb72bffc5c.png)
※請求ポリシーに追加できるのは、運用環境とサンドボックス環境のみです。また、環境の場所は請求ポリシーのリージョンと一致する必要があります。

内容を確認し、請求ポリシーを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/c952b79e-7877-5200-8654-739f551d77bb.png)

請求ポリシーが作成されるまでしばらく待ちます。

数分で請求ポリシーが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/4e7af5a2-eee3-36bb-c3b0-9a233fa7bb15.png)

## 2. 環境の作成
Power Platform 管理センターの環境から新しい環境を作成します。
Azureの従量課金をはいにして、先ほど作成した請求ポリシーを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/4c7ea432-0002-2d02-1f81-945ce88ba9b0.png)

必要項目を設定し保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/667a0006-2125-3c64-bbf6-bcfd84f7e716.png)

数分待つと、環境が使用できるようになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1004488/9827fbc1-b7bc-b380-1a09-e8158dc2238d.png)


## 気づき・メモ
Power Apps Premium ライセンスのない環境で新しい環境を作成しようとしたところ、新規環境作成に必要なDataverse容量1GBがなかったため環境を作成できませんでした。
そこで、請求ポリシーを作成してからその請求ポリシーに紐づけて環境の作成を試みたところ無事環境を作成することができました。

# まとめ
既にAzure サブスクリプションを持っている組織でクイックにPower Platform の使用を始めたい場合などに従量課金制は便利だと感じました。
（Power Apps Premium 購入する予算を取るのに時間がかかる場合など）
一方で、従量課金制は割高になる傾向があるため、Power Platform の利活用を拡大していく中で、必要に応じてライセンス制に移行していくことも検討していく必要がありそうです。
RailsでDBのカラムにtime型を使ってみた

先日、日時は必要のない時間だけを扱うカラムを作成しようとして、初めてTime型という型を使ったのですが、そこで少しハマったので記事にしてみました。
Time型についてあまり知らない、使ってみたいよって方はぜひ読んでみてください。

## 環境
Rails7
PostgreSQL

## 起こったこと
コンソールで作成したTime型のカラムを含むテーブルを試しにコンソールで作成してみると、このようなデータが作成されてしまいました。
(対象カラムはstart_timeとend_timeです。)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819517/93a603ba-1166-2c8d-8426-1e8c65009eeb.png)

Time型で作成したのに、なぜ？
DBで確認してみるとちゃんと時間だけが保存されてました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3819517/a703ad3a-6b24-6cce-82ad-62586b016f6d.png)

## 理由
なぜだろうと思いググってみると、こちらの記事を見つけました。
https://blog.willnet.in/entry/2015/06/12/063731


>Ruby や Rails には、時間のみを扱うクラスはありません。DB の Time 型は Ruby の Time オブジェクトに変換されます。Time オブジェクトは年月日の情報を持っています。その際、タイムゾーンは utc (正確には ActiveRecord::Base.default_timezone で設定されたタイムゾーン) として扱われます。


DBのTime型をRailsのTimeオブジェクトが日付を追加していたようでした。
そんな仕様があるとは…

## 最後に
DBの値をActiveStorage経由で出力する時にどう変換されるのかを意識したことがなかったので、良い機会でした。
DBの内容とActiveStorageを経由した出力結果は必ずしも一緒ではないというのを頭の片隅に入れながら、作業してきたいと思います。
あのフォトリアルなデジタルヒューマン「Saya」が生成AIを使って展開加速!?

登場当初から<font color=green>「不気味の谷」を超えた</font>と言われ<font color=green>「情熱大陸🔥」</font>でも話題になったデジタルヒューマン「Saya」が、NEC（日本電気）の生成AI技術と組み合わせて展開をするそうです。

生成AI、特にGPT-4oによって応答精度が早く回答精度も向上してきている中、このようなフォトリアリアルのデジタルヒューマンと生成AIとの組み合わせは最強ですね！

検索のユーザインタフェースが従来のブラウザからこのようなフォトリアルな対話エージェントに急速に切り替わっていく気もします（あくまでも個人的な感想ですが、、、）。

<iframe width="560" height="315" src="https://www.youtube.com/embed/rTDJlHcf-SY?si=84FcT_ba99WVuc3s" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

NECプレスリリース
「NEC、アイシンと共同で生成AIとデジタルヒューマン技術を組み合わせたパートナーAIシステムの開発を開始」

https://jpn.nec.com/press/202410/20241015_02.html

今後、街中で「Saya」や様々なフォトリアルなデジタルヒューマンが当たり前に見られる時代が来るのでしょうか？ とても楽しみです。

スマホにも搭載されることを期待しています！
FlutterのWidgetTestで、様々な設定のAleartDialogを独自のアプリから呼び出すことでテストする方法

AlertDialogの設定ごとにアプリを実装するのはナンセンスなので、外部から与えたコールバック内で指定できるようにします。

https://gist.github.com/comoc/d95f55d91974d50f0d1de8527ebb34e3
fletのソース

# Fletについて調べていると・・・
どうも書き方が、inner functionを使うことになっているようで・・・
同じファイル内にタラタラと書かないといけないのかなと思いいろいろ調べておりました。

小さなアプリケーションならそれでいいけれど、大きくなると１つのファイルで管理するのはいかがなものかと思ってしまうわけでして・・・

で下記の書き込みを発見したので参考にさせていただきました。
@donraq様の記事より
[Fletを試す(2) - 再利用できるようにコンポーネント化](https://qiita.com/donraq/items/043bde2e480d5359261b)
[Fletを試す(3) - 画面遷移（ルーティング）の調査](https://qiita.com/donraq/items/b0cc1ad273996477b25a)

これによると、クラスを使ってコンポーネント化、Viewによるページ遷移を使うとページ毎（場合によっては機能ごとのクラスファイル）に分割して管理ができそうだったので以下のようなソースを作ってみました。

# メインのソース
メインのソースでは、主にページ制御だけ行うようにしています。
```py
import flet as ft
from nview import views1

def main(page: ft.Page):
    nview=views1()
    def route_handler(handler):
        ftroute = ft.TemplateRoute(handler.route)
        page.views.clear()
        if ftroute.match("/view1"):
            page.views.append(nview.nview(page, "view1","view2"))
        elif ftroute.match("/view2"):
            page.views.append(nview.nview(page, "view2","view1"))
        page.update()

    # ルート変更時のロジック設定
    page.on_route_change = route_handler

    # Page レイアウト
    page.title = "route handle example"
    page.go("/view1")


if __name__ == "__main__":
    ft.app(target=main)
```

# ページコンテンツのソース
ページコンテンツでは簡単に表示で切り替わったことがわかるものを作ってみました。
```nview.py

import flet as ft

class views1():
    def __init__(self):
        pass
    
    def nview(self, page, cview, toview):
        return ft.View("/{}".format(cview), [
            ft.AppBar(title=ft.Text(cview)),
            ft.Text(cview+" Test contents."),
            ft.TextButton(text="Go to {}".format(toview), on_click=lambda _: page.go("/{}".format(toview))),
        ])
```
__★注意__ 以前のソースはViews1クラスをfl.viewを継承するようにしていましが、Viewを継承する必要はないので訂正しました。

これでファイルを分離して開発はできそうですね！

# 謝辞
@donraq様、参考になるご投稿ありがとうございました。
大変助かりました。
【超偏見】Chromeの入れてよかった拡張機能　TOP5

# はじめに
今回は、入れてよかったChromeの拡張機能5選を独断と偏見120%で紹介します。そのため、順位に対する意見や文句は一切受け付けておりません。
また、前提条件として、業務での利用となると使用に制限がかかり拡張機能を使えない場面がほとんどだと思うので、あくまで私用の環境で利用する場面に限っています。
早速参りましょう！

## 第5位　[Black Menu for Google](https://chromewebstore.google.com/detail/black-menu-for-google/eignhdfgaldabilaaegmdfbajngjmoke?hl=ja&authuser=4)
#### 概要
こちらの拡張機能は、**様々なGoogleサービスにかんたんアクセスするツール**です。

#### 理由
小さいプレビュー画面で操作するため、今いるページから離れる必要もないし、邪魔にもならないので、一つのモニターでYoutube見ながら何か調べ物をしたいときにかなり役立っています。


## 第4位　[Speed Dial 2 新しいタブ](https://chromewebstore.google.com/detail/speed-dial-2-%E6%96%B0%E3%81%97%E3%81%84%E3%82%BF%E3%83%96/jpfpebmajhhopeonhlcgidhclcccjcik?hl=ja)
#### 概要
こちらの拡張機能は、**お気に入りのWebサイトを保存および整理できる、シンプルで高速かつ直感的な新しいタブページを追加するツール**です。

#### 理由
新規のタブからどこかのページに移動するとき、ブックマークに登録されている小さなアイコンが見づらく、直感的に操作できないなと感じていました。（自分の性格所管理が雑なのもありますが...）
この「Speed Dial 2」では、アイコンが大きく表示され、ページごとにカテゴリ分けをすることができるので、「開きたいのこのページじゃないや」と無駄な操作をする機会が極端に減り、地味に助かっています。


## 第3位　[Shazam](https://chromewebstore.google.com/detail/shazam%EF%BC%9A%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E3%81%8B%E3%82%89%E6%9B%B2%E5%90%8D%E3%82%92%E8%A6%8B%E3%81%A4%E3%81%91%E3%82%8B/mmioliijnhnoblpgimnlajmefafdfilb?hl=ja&authuser=4)
#### 概要
こちらの拡張機能は、**動画やゲームで流れている音楽を認識して曲名を教えてくれるツール**です。

#### 理由
自分の場合、スポーツ観戦中に「スタジアムで流れているこの曲は何だ？」と気になることがあるので、非常にありがたいツールです。チームの公式サイトに情報が載ってないことも多いので、とても重宝しています。

#### ワンポイント
Shazamはスマホアプリもあります。自分は有線で流れている曲を調べるときとかによく使用してお気に入りのツールです。


## 第2位　[Picture-in-Picture Extension (by Google)](https://chromewebstore.google.com/detail/picture-in-picture-extens/hkgfoiooedgoejojocmhlaklaeopbecg?hl=ja)
#### 概要
こちらの拡張機能は、**動画や画像を別のウィンドウとして表示、他のウインドウにいても動画を視聴することができるツール**です。

#### 理由
解説動画を見ながら、自分の環境でも作業するのをひとつのモニターで行いたいときにかなり役立っています。
Youtubeのミニプレイヤー機能と違い、任意の場所に動画鵜のウインドウを表示することができる上に、他のウインドに行っても表示がされ続けるという点が、これ以上ない最高のポイントです。

#### ワンポイント
ウィンドウ上にスキップボタンは無く、再生/停止ボタンのみ搭載されているため、動画を飛ばしたいときは元のウインドウから操作しなければいけないという懸念点があります。

# 番外編
第1位の紹介の前に番外編ということで、自分にはあまり恩恵はなかったが人によっては痒い所に手が届くようなありがたいツールやちょっと変わったユニークなツールを紹介します。

### ① OneTab
こちらの拡張機能は、現在開いているタブをリスト化し、タブを整理することができるツールです。
自分の場合は、不要になったタブはすぐに閉じてしまうタイプなのでそこまで恩恵は得られませんが、ページのアイコンしか表示されないくらいにタブを残しておく方は、非常にありがたいツールなのではないかと思います。

### ② ネッコサーフィン
こちらの拡張機能は、ウインドウ上に現れた猫がマウスカーソルを追いかけ、時に飛びついてくるといった癒し系のツールです。

とても癒されました:cat:

# 閑話休題
本題に戻りまして、「超偏見で選んだChromeの入れてよかった拡張機能」第1位を紹介します！

## 第1位　[Volume Master](https://chromewebstore.google.com/detail/volume-master-%E3%83%9C%E3%83%AA%E3%83%A5%E3%83%BC%E3%83%A0%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC%E3%83%A9/jghecgabfgfdldnmbfkhmffcabddioke?hl=ja&authuser=4)
### 概要
こちらの拡張機能は、**ブラウザのタブごとに音量調節ができるツール**です。

### 理由
この拡張機能が自分に刺さった理由としては、自分の趣味である海外サッカーの試合観戦時に非常に役立ったという点です。
中継画面と別に、一緒に試合観戦しようという趣旨のYoutuberの配信も同時視聴しているため、ちょうどいい音量バランスで試合を観るのに非常に役立っています。

#### ワンポイント
この拡張機能を使用すると、全画面表示した際は全画面になりません。そこで、「F11」を押すことで全画面表示をすることができます。

参考：https://note.com/tora_tanu/n/n4b626bce0871

## まとめ
今回は、私が超偏見で選んだChromeの入れてよかった拡張機能TOP5を紹介しました。
ほとんど娯楽ために使用しているツールばかりを紹介しましたが、ストアにある拡張機能の中には現場の業務でも使えたらいいのになぁと思うものもあります。
また、今回紹介した拡張機能は基本的に無料なものばかりですので、この記事を読んで興味を持たれた方は是非インストールしてみてください！

ストアはこちら → [Chorme ウェブストア](https://chromewebstore.google.com/category/extensions?hl=ja&authuser=4)
生成AIを用いた爆速コーディング例１（VDM未経験者でも最速でできる）

前回の記事
https://qiita.com/Andhy/items/d7af72d2586606fa9468
で触れたVDMとChatGPTを用いたプログラミングの実践編です。VDMやVDMを用いたコーディングの概要については前回の記事を参照してください。

## この記事の特徴
- VDMの文法を一切理解する必要はない
- VDMのコードは書かず、概念だけを用いる。


今回は、Webショップ「VDMランド」の店長さんの悩みを解決します。
VDMランドでは、ECサイトの使用上商品を一括登録するにはCSVファイルをアップロードするため、商品画像をスプレットシートで管理しています。

### VDMランドのスプレットシートの一部。
![スクリーンショット 2024-10-18 16.19.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112409/4acf1eff-700a-30fc-a094-64f42b952370.png)

店長へのヒアリングの結果、以下の課題が浮き彫りになりました。

## 課題
スプレットシートで商品画像の管理をしたいが、商品画像が多すぎて面倒である。
現状スタッフが全て手入力をしている。（これを自動化したい）

## 仕様
### 働き

#### ボタンを押すと商品画像が自動で入力される。

- 前提条件
  - 商品IDがC列に定義されていること
  - 商品画像のパスは{ドメイン_※１}/{商品ID＿※2}/{ファイル名_※3}.jpgであること
  - 商品画像は1000以下であること
- 事後条件
  - カンマ区切りであること
  - 商品画像のパスは全てにおいて画像が存在すること
  - 商品画像のパスの最後のパスの番号に1を加えたものは画像が存在しないこと
  - 生成された商品画像のパスは、対象商品IDと同じ行であること

処理
　画像パス生成関数でファイル名1の存在をパスが存在するか関数を用いて確認する。存在すればファイル名に＋１して再度存在確認、存在がなくなるまで繰り返し、存在がなくなればカンマ区切りにしてD列に出力

### 定義
ドメイン＿※1：店舗ECサイトのドメインである(https://hoge.com)
商品ID＿※2：任意の文字列である。C列から取得
ファイル名_※3：自然数の連番であること（途中欠番なし）

### 関数
#### 画像パス生成関数: 第一引数（ドメイン＿※１）、第二引数（商品ID＿※2）、第三引数（ファイル名_※２）

#### パスが存在するか：第一関数（パス）


## 設計

### 言語
Apps Script

仕様上の以下の処理単位は全てfunctionで定義すし、具体的な関数名は（）内に示す
ボタンを押すと商品画像が自動で入力される。（main）
画像パス生成関数(generateImagePath)
パスが存在するか(isPathExists)


## コーディング

ChatGPTに

```
以下の仕様に基づいて、Google Apps Scriptで商品画像パスを自動入力するプログラムを作成してください。
```

という文言のあとに上記仕様と設計を放り込みます。

### 生成されたコード

```Javascript
// メイン関数：ボタンを押したときに実行
function main() {
  var domain = "https://hoge.com";   // ドメイン
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); // 現在のシート取得
  var lastRow = sheet.getLastRow();  // 最終行を取得（C列の商品IDが定義されている範囲）

  // C列の商品IDを1行目から最終行までループ
  for (var row = 1; row <= lastRow; row++) {
    var productID = sheet.getRange(row, 3).getValue(); // C列（3列目）の商品IDを取得
    if (productID) {
      var imagePaths = []; // 商品画像パスを格納する配列
      var startNumber = 1; // ファイル名の連番（開始は1）

      // 画像パスの存在を確認しながら生成
      while (isPathExists(generateImagePath(domain, productID, startNumber))) {
        imagePaths.push(generateImagePath(domain, productID, startNumber)); // 存在するパスを配列に追加
        startNumber++; // 次の連番に進む
      }

      // 画像パスをカンマ区切りでD列（4列目）に出力
      sheet.getRange(row, 4).setValue(imagePaths.join(","));
    }
  }
}

// 画像パス生成関数
function generateImagePath(domain, productID, fileNumber) {
  return domain + "/" + productID + "/" + fileNumber + ".jpg"; // パスの生成
}

// パスが存在するかを確認する関数
function isPathExists(path) {
  try {
    var response = UrlFetchApp.fetch(path, { muteHttpExceptions: true });
    return response.getResponseCode() === 200; // 200なら存在、その他は存在しない
  } catch (e) {
    return false; // エラーの場合も存在しないとみなす
  }
}

```
zshで日本語ファイル名をローマ字でタブ補完する

# はじめに

zshで日本語から始まるファイル名をタブ補完したい場合に、先頭数文字の入力のためにIMEを日本語入力に切り替えるのが手間[^menu-complete]なので、  
ローマ字で日本語ファイル名を補完できるようにしてみました。今回はその方法を紹介します。  
動作はUbuntu 24.04で確認しています。

![zsh_completion.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2542709/40dd5c31-f643-15a1-bbb7-42833def8980.gif)

# 方法

日本語→ローマ字変換に[KAKASI](http://kakasi.namazu.org/index.html.ja)を使用するため、あらかじめインストールしておきます。  
自分でビルドしても良いですが、Ubuntuであれば`apt install kakasi`でインストール可能です。

インストール後、`.zshrc`に以下の内容を追加すれば、ローマ字での補完が可能になります。

```zsh:.zshrc
_expand_japanese()
{
  setopt localoptions rematchpcre # [:ascii:] を使用出来るようにする

  local IFS=$'\0' suffix file romaji
  if [ "$words[1]" = cd ]; then
    # cdコマンドの場合はフォルダのみを対象とする
    suffix=/
  else
    suffix=""
  fi

  # ファイル名一覧でループ
  for file in $(print -nN "${1:h}"/*"$suffix"); do
    if [[ "${file:t}" =~ [^[:ascii:]] ]]; then
      # 先頭が非ASCII文字の場合、ファイル名をローマ字に変換する
      romaji=(${(f)$(kakasi -iutf8 -Ha -Ea -Ka -Ja <<< "${file:t}")})
      if [[ "$romaji" == "${1:t}"* ]]; then
        # 変換後のファイル名先頭部分が入力と一致すれば展開候補に追加
        reply+=(${(q)"${file#./}"})
      fi
    fi
  done
}

# ローマ字展開関数を_user_expandに登録
zstyle ':completion:*' user-expand _expand_japanese

# ローマ字展開の候補一覧に all expansions や original が出現しないようにする
zstyle ':completion:*:user-expand:*' tag-order expansions

# デフォルトのcompleter(_complete _ignored)をまず実行し、候補が無ければローマ字展開を実行する
zstyle ':completion:*' completer _complete _ignored _user_expand
```

# 解説

zshの補完システムには、入力文字の続きを自動入力する通常の補完とは別に、  
入力文字自体を別の内容で置き換える**展開機能**(expansion)が存在します。 
 
どのような補完や展開を行うかを定義したcompleterというものが複数存在し、どれをどの順で使用するかは自由に設定可能です。  
この内、`_user_expand`というcompleterには自作の展開関数を登録することが可能で、  
展開関数内で`reply`配列に追加した値が展開候補として表示されます。[^completer]  

上記`.zshrc`では、「ローマ字に変換したファイル名の先頭と入力文字が一致する場合に展開する」という展開関数を実装して登録しています。

# おわりに

この設定は完璧ではなく、ローマ字展開より通常の補完が優先されるため、例えば  
「`日本語`というファイルと`niwatori`というファイルがある場合、`ni`→Tab と入力すると`niwatori`となり、`日本語`に展開できない」  
という欠点があります。  
completerの指定順で`_user_expand`を先に指定すれば展開可能ですが、その場合逆に`niwatori`を補完できなくなります。  
そもそもシェル上で日本語ファイルを扱う頻度はそこまで高くないため、通常の補完を優先する設定にしています。

ちなみに、zshのタブ補完は`Ctrl+x u`でundo可能なので、
> `日本語`というファイルと`niwatori`というファイルがある場合、`ni`→Tab と入力すると`niwatori`となり

このような場合でもundoで`ni`に戻してから`h`→Tabと入力すれば`日本語`に展開できるため、わりとどうにかなります。

[^menu-complete]: Tabキーを連打していればその内目的ファイルに辿り着きますが、同一フォルダ内のファイル数が多いとそれも面倒です
[^completer]: https://zsh.sourceforge.io/Doc/Release/Completion-System.html#Control-Functions
ドMエンジニア必見！女王様コードレビュアーで、ドSなコードレビュー体験を！

## はじめに
こんにちは、コーディングの「ちょっとしたミス」や「サボり」が許せないドSなレビューを受けたいそこのドMエンジニアの皆様！
本日はそんな方々に向けた、新感覚のコードレビューサービス『女王様コードレビュアー』をご紹介します。

「自分の書いたコード、どうせレビューされるなら、ちょっとスリルがあって、厳し〜い指摘を受けてみたいなぁ…」なんて思ったこと、ありませんか？
このツールを使えば、コードを提出するだけで、ドS女王様があなたのコードをレビューし、時には**辛辣な指摘**、時には**鞭打ち**までしてくれることも！
そう、あなたは幸運です！
<br><br>

*女王様コードレビュアー*

https://sm-code-reviewer.vercel.app/

## 機能紹介
#### コードレビュー機能

あなたのコードを提出すると、**ドS女王様**がチェックし、点数をつけてくれます。辛辣なコメントやお褒めの言葉（？）をもらうことができます。もちろん、悪い点数だと**厳しいお叱り**が待っています。
#### コード修正提案機能

ただの指摘だけじゃなく、ちゃんとコードの**修正提案**もしてくれます。ドSながらもプロフェッショナルな女王様です。例えば、「インデントが汚いわよ、直しなさい！」という具合です。

#### お楽しみの鞭打ち機能

レビュー結果が特にひどい場合（または運がいい場合？）、**女王様からの厳しい鞭打ち**メッセージが届きます。優しく（ドSに）改善点を教えてくれますが、時には「こんなコード、恥ずかしくないの？」と叱られることも。

## 実際の使い方
#### ステップ1. コードを貼り付ける
まずは簡単に、自分の書いたコードをこのフォームにペーストするだけ！
例えば、以下のような簡単なコードをレビューしてもらうことができます。
```javascript
function helloWorld() {
  console.log("Hello World);
}
```
#### ステップ2. 女王様からのレビューを受け取る
次に、女王様からの辛辣なレビューを受け取ります。例えばこんな感じです：

*まぁ、愛しき下僕よ、幼きコードの中に些細なミスを見つけてしまったわ。`console.log("Hello World);` の中で、閉じ忘れたダブルクオーテーション（"）があるの。これが原因でエラーが出てしまうわ、華やかな場にふさわしくないわね。*

もちろん、もっと高度なコードにも対応しています！

#### ステップ3. 点数と評価
レビューとともに、コードには点数が付けられます。例えば、100点中60点だと「あなた、これで満足してるの？次はもっと良いものを書いてきなさい！」といった評価が。


## コードレビュアーの仕組み
この「女王様コードレビュアー」は、以下の技術を使って開発しました：

- フロントエンド: React でシンプルなインターフェースを構築
- OpenAI API: GPTモデルを使用して、レビュー内容を生成。ユーザーが提出したコードをAIが分析し、女王様風のコメントを自動生成します。
こちらの[Udemy講座](https://www.udemy.com/course/react-product-development/?couponCode=24T1MT101824)を参考にしました。

## 最後に
「女王様コードレビュアー」は、コードを改善しながらちょっとスリリングな体験も味わえる、ドMエンジニア向けのツールです。楽しみながら自分のスキルを磨き、女王様に褒められるようなコードを書けるようになりましょう！

さぁ、あなたも今日から「女王様コードレビュアー」でドSなレビューを体験してみませんか？
FastAPIで例外を見やすく表示


# はじめに

FastAPIの例外を[PrettyErrors](https://github.com/onelivesleft/PrettyErrors)で見やすく表示する[fastapi-pretty-errors](https://github.com/savvan0h/fastapi-pretty-errors)を作成しました。

https://github.com/savvan0h/fastapi-pretty-errors

こういうエラーが...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303869/2e4260bd-ca51-97b5-fef5-57ae6acc3ec3.png)

こうなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303869/d9954f7c-3fd9-7e58-1979-7462b2dc81b4.png)

# PrettyErrorsとは

PrettyErrorsはPythonの例外を見やすく表示するライブラリです。

https://github.com/onelivesleft/PrettyErrors

FastAPIでの利用についてはこちらのIssueで提案されていますが、
より簡単に導入できるように `fastapi-pretty-errors` を作成しました。

https://github.com/onelivesleft/PrettyErrors/issues/16#issuecomment-751463605

# インストール

pipでインストールします。

```
pip install fastapi-pretty-errors
```

Poetryを使っている場合は以下のように追加します。

```
poetry add fastapi-pretty-errors
```

# 使い方

FastAPIに `PrettyErrorsMiddleware` を[ミドルウェア](https://fastapi.tiangolo.com/tutorial/middleware/)として追加します。

```python
from fastapi import FastAPI
from fastapi_pretty_errors import PrettyErrorsMiddleware

app = FastAPI()
app.add_middleware(PrettyErrorsMiddleware)
```

PrettyErrorsの設定を変更する場合は、以下のように引数を指定します。
設定可能なオプションについては、[PrettyErrorsのドキュメント](https://github.com/onelivesleft/PrettyErrors?tab=readme-ov-file#configuration-settings)を参照してください。

```python
app.add_middleware(
    PrettyErrorsMiddleware,
    # 以下に設定を追加
    line_number_first=True,
    lines_before=5,
    lines_after=2,
    # ...
)
```

# 例

`PrettyErrorsMiddleware` をセットアップし、例外を発生させるエンドポイントを作成します。

```python:main.py
from fastapi import FastAPI
from fastapi_pretty_errors import PrettyErrorsMiddleware
import pretty_errors

app = FastAPI()
app.add_middleware(
    PrettyErrorsMiddleware,
    line_number_first=True,
    lines_before=5,
    lines_after=2,
    line_color=pretty_errors.RED + "> " + pretty_errors.default_config.line_color,
    code_color="  " + pretty_errors.default_config.line_color,
    truncate_code=True,
    display_locals=True,
)


@app.get("/")
async def root():
    raise ValueError("An error occurred")
```

FastAPIを起動して、エンドポイントにアクセスすると以下のようにフォーマットされたトレースバックが表示されます。

```
curl http://localhost:8000
{"detail":"Unexpected error occured."}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303869/d9954f7c-3fd9-7e58-1979-7462b2dc81b4.png)

# さいごに

PrettyErrorsをFastAPIで使いやすくした `fastapi-pretty-errors` をご紹介しました。
ぜひ使ってみてください！
Karabinerを使っていて、Mac + US配列キーボード で ` (バッククォート) を入力すると § (セクション) が出力されてしまう

MacOSのアップデートを行ったところ、突然キーボードの設定モーダルがでてきてISOを選択したところから悲劇がはじまりました。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360277/fc8149e5-1b83-91d8-7411-bc4f7ab0704c.png)

` (バッククォート) を入力すると § (セクション) が入力されるようになり、
§の読み方もわからず困っていたところ以下の記事が大変参考になりました。

https://qiita.com/HitoroOhria/items/ea49739e6a3fa9d6f944

ただこちらの記事を参考に設定しても自分の環境では解決に至りませんでした。

諦め半分でKarabinerの設定を流し見していたところまさかの解決に至りました。
以下の設定をANSIに変えてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360277/3234f7d7-2002-9499-eb1e-63b15350874e.png)

元記事の方がどうなのかはわかりませんが、自分はすでにKarabinerが入っている状態から途中で変えてしまったため、macの設定をKarabinerが上書きしていることが原因だったようです。

バッククォートが簡単に入力できるのがこんなにうれしいのかと思った日でした。

おしまい。
PATENT PREPARATION

Introduction:
Effective patent preparation plays a pivotal role in securing robust patent protection. It requires thorough documentation, precise claims, and a deep understanding of patentability criteria. This article highlights the key steps involved in patent preparation to enhance your chances of success, with the guidance of IP Attorneys New Zealand.
Inventor Disclosure:
Clearly document all aspects of the invention, including its functionality and benefits.
Identify all inventors and contributors involved.
Keep comprehensive records of the invention's development stages.
Patent Search:
Perform an in-depth patent search to evaluate the novelty and inventiveness of your idea.
Identify any prior art that may affect the patentability of your invention.
Patent Specification:
Write a clear, concise description of the invention, detailing its background, technical aspects, and benefits.
Use accurate terminology and precise language.
Include detailed diagrams or illustrations to visually represent the invention.
Patent Claims:
Draft precise and concise patent claims to define the scope of protection.
Focus on the invention's critical and unique features.
Consider different claim types, such as independent and dependent claims, to broaden protection.
Patent Filing:
Prepare the patent application, ensuring it includes the specification, claims, and drawings.
Complete all necessary forms and submit the required fees.
File the application with IP Australia.
Tips for Effective Patent Preparation:
Consult with a patent attorney for expert assistance.
Maintain clarity and brevity in the specification to avoid confusion.
Protect confidentiality by using non-disclosure agreements.
Consider filing a provisional patent to establish an early priority date.
Conclusion:
Comprehensive patent preparation is vital to maximize the potential of your invention. By adhering to these steps and seeking expert guidance, such as from Lexgeneris, you can significantly increase your chances of securing a strong and enforceable patent. Remember, thorough preparation forms the foundation of a successful patent portfolio.
For more information on pursuing a career in patent law, read our guide on How to Become a Patent Attorney
Swift: Linux で Visual Studio Code を使う

次のページを参考にしました。
[UbuntuでSwiftの環境構築を行う方法](https://zenn.dev/tns_00/articles/install-swift-on-ubuntu)
Ubuntu 24.04 で確認しました。

## 環境

```text
$ which code
/usr/bin/code

$ code --version
1.88.1
e170252f762678dec6ca2cc69aba1570769a5d39
x64

$ code --help
Visual Studio Code 1.88.1

Usage: code [options][paths...]

To read from stdin, append '-' (e.g. 'ps aux | grep code | code -')
（省略）
```

## コードの作成

```bash
mkdir ex01
cd ex01
swift package init --type executable
```

フォルダー構造

```text
$ tree
.
├── Package.swift
└── Sources
    └── main.swift
```

Sources/main.swift を修正

```swift:Sources/main.swift
// The Swift Programming Language
// https://docs.swift.org/swift-book

print("*** 開始 ***")
print("Hello, world!")
print("Oct/17/2024")
print("*** 終了 ***")
```

## VS Code の起動

```bash
code .
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/4f0649af-2392-1bc0-9191-ddbede9d5efc.png)


プログラムの実行

>実行結果は ターミナルに出ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/270f5ff0-254a-5854-7622-dd57fb3b199a.png)
7日間でハッキングを始める本 - 4日目 -

# 本記事の目的
書籍「7日間でハッキングを始める本」の
Day4に出てきたコマンド・用語などの整理

Day5から本記事の投稿を開始しDay7まで完了したため、改めてDay2-4について復習しながら足りない部分を記述する
※Day1は環境構築がメインのため割愛
※そのため、既に過去の記事でまとめた内容については割愛することもある

## 関連記事
- [Day2](https://qiita.com/akebono-san/items/f835c32a16e35893729f)
- [Day3](https://qiita.com/akebono-san/items/2825c49f4fc894c63fb5)
- Day4 <- 本記事
- [Day5](https://qiita.com/akebono-san/items/7103ba63a983103da7c3)
- [Day6](https://qiita.com/akebono-san/items/a190a63db00eb4679388)
- [Day7](https://qiita.com/akebono-san/items/1d36460b63fb74a79b84)

## コマンド・ツール
### Burp Suite
ローカルプロキシツール
WebブラウザとWebサーバの間に入って通信を中継する

## セキュリティ攻撃関係の用語集
### OWASP
Open Worldwide Application Security Projectの略
セキュリティを向上させる開発者、技術者、エヴァンジェリストのコミュニティ
有名なプロジェクトの一つとして、Webアプリケーションのセキュリティリスクをまとめた"OWASP Top 10"がある
Next.js Error: Super expression must either be null or a function

一見何のエラーかわからないし、文章的にはか心当たりがあるわけでもないこのエラー。
![スクリーンショット 2024-10-18 16.21.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147005/0d69e920-2179-9639-7e79-ae9038c0082d.png)

```js
"use client"
```

をつけましょう。