OmniAICreator/Qiita-1.07M huggingface dataset:
Next.jsで究極のマークダウンエディタを作成する話 その2

# ReactMarkdownを使うのが良さそう
前回までの調査でmarkdownをリアルタイムプレビューには成功しました

今回は拡張で欲しい機能を追加できるものの調査と設計をしていきます

1 スタイリングを当てられる

2 コードブロックに言語に応じたハイライトがある

3 htmlを埋め込める

4 github準拠のものが使える

5 Texを用いて数式を扱える

## 1.スタイリングを当てる

https://github.com/sindresorhus/github-markdown-css/tree/main

こちらのものを使わせていただきました

```zsh
npm install github-markdown-css
```

をして、

```_app.tsx
import "github-markdown-css";
```
を追記

```tsx
        <ReactMarkdown className="markdown-body">
          {markdown}
        </ReactMarkdown>
```
と変更するだけ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3303371/07816812-a619-eddb-7b01-77654e2cf4d5.png)

となります！👏


## 2.コードブロックに言語に応じたハイライトがある

どうやらHighlightのライブラリがたくさんあるらしい
どれを使ってもうまくいかないので現在調査中です

## 3.htmlを埋め込める

```zsh
npm i rehype-raw rehype-sanitize
```

```tsx
import rehypeRaw from "rehype-raw";
import rehypeSanitize from "rehype-sanitize";
...
    <ReactMarkdown
      rehypePlugins={[rehypeRaw, rehypeSanitize]}
    >
      {markdown}
    </ReactMarkdown>
```

## 4.github準拠のものが使える

```zsh
 npm i remark-gfm
 ```
 ```tsx
 import remarkGfm from "remark-gfm";
...
     <ReactMarkdown remarkPlugins={[remarkGfm]}>
      {markdown}
    </ReactMarkdown>
```

## 5.Texを用いて数式を扱える

```
remark-math rehype-katex
```
```tsx
import remarkMath from 'remark-math';
import rehypeKatex from 'rehype-katex';
...
    <ReactMarkdown remarkPlugins={[remarkMath]} rehypePlugins={[rehypeKatex]}>
      {markdown}
    </ReactMarkdown>
```

```_app.tsx
import "katex/dist/katex.min.css";
```

# 全てを詰め合わせたサンプル

```tsx
import { useState, useRef, useEffect } from "react";
import remarkGfm from "remark-gfm";
import ReactMarkdown from "react-markdown";
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";
import rehypeRaw from "rehype-raw";
import rehypeSanitize from "rehype-sanitize";

export function MarkdownEditor() {
  const [markdown, setMarkdown] = useState("");

  return (
    <div className="flex gap-5 p-5">
      <div className="flex-1">
        <textarea
          className="w-full p-3 text-lg border border-gray-300 rounded resize-none"
          placeholder="Write your Markdown here..."
          value={markdown}
          onChange={(e) => setMarkdown(e.target.value)}
        />
      </div>
      <div className="flex-1 p-3 border rounded overflow-y-auto max-h-[400px]">
        <ReactMarkdown
          remarkPlugins={[remarkMath, remarkGfm]}
          rehypePlugins={[rehypeRaw, rehypeSanitize,rehypeKatex]}
          className="markdown-body"
        >
          {markdown}
        </ReactMarkdown>
      </div>
    </div>
  );
}
```

:::note warn
    rehypePlugins={[rehypeRaw, rehypeSanitize,rehypeKatex]}
はこの順番でないと正常動作しません
:::
シングル・レスポンシビリティ・プリンシプル（SRP）について詳しく解説

## はじめに

シングル・レスポンシビリティ・プリンシプル（SRP: Single Responsibility Principle）は、ソフトウェア設計の基本原則の一つであり、オブジェクト指向設計のSOLID原則の一部です。

## SRPの定義

### SRPの定義
- 「クラスは、変更の理由が一つだけになるようにするべきである」

### シンプルな解釈
- 1つのクラスは1つの責任だけを持つべきである。
- クラスは単一の機能を提供し、その機能に関連する変更の理由が一つだけになるようにする。

## SRPの目的

- **保守性の向上**: クラスが一つの責任に集中しているため、変更が必要になったときにどのクラスを変更すればよいかが明確になります。
- **再利用性の向上**: クラスが単一の責任を持っていると、他のコンテキストでも再利用しやすくなります。
- **理解の容易さ**: クラスが一つの責任を持っているため、そのクラスの役割と動作を理解するのが簡単になります。

## 具体例

### 例1: 書籍の管理システム

書籍管理システムにおいて、以下のようなクラスを考えます：

#### 悪い例（SRPに従っていない）

```java
public class Book {
    private String title;
    private String author;
    private String text;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    // 本を印刷するメソッド
    public void print() {
        // 印刷ロジック
    }

    // 本を保存するメソッド
    public void save() {
        // 保存ロジック
    }
}
```

この`Book`クラスは、書籍の情報を管理する責任の他に、印刷や保存の責任も持っています。これにより、クラスが複数の責任を持ち、変更の理由が増えます。

#### 良い例（SRPに従っている）

```java
public class Book {
    private String title;
    private String author;
    private String text;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

public class BookPrinter {
    public void print(Book book) {
        // 印刷ロジック
    }
}

public class BookRepository {
    public void save(Book book) {
        // 保存ロジック
    }
}
```

この設計では、`Book`クラスは書籍の情報を管理し、`BookPrinter`クラスは印刷を管理し、`BookRepository`クラスは保存を管理します。これにより、各クラスが単一の責任を持つようになり、変更の理由が明確になります。

## SRPの適用方法

1. **責任の特定**: クラスが現在持っている責任を特定します。
2. **分割**: クラスが複数の責任を持っている場合、それを複数のクラスに分割します。
3. **テスト**: 各クラスが単一の責任を持つようにテストし、変更があった場合の影響範囲を確認します。

## SRPのメリットとデメリット

### メリット
- **保守性の向上**: 変更の理由が明確になるため、コードの保守が容易になります。
- **再利用性の向上**: 単一責任を持つクラスは他のプロジェクトやコンテキストでも再利用しやすくなります。
- **理解の容易さ**: クラスが単一の責任を持つため、その役割を理解しやすくなります。

### デメリット
- **初期の設計コスト**: 責任を分割するために、初期設計時により多くのクラスを作成する必要があります。
- **過剰な分割**: 責任を過剰に分割すると、クラスが増えすぎて管理が難しくなる可能性があります。
Next.jsで現在のページと一致した時にナビゲーションリンクのスタイルをStorybookで表現したい

現在のページパスと一致したときにナビゲーションリンクを変更したい場合があります。
実装はできてもStorybookにはどうやって反映させるんだ？となったのでTipsとして残します！

## 現在のページの判定方法は？
Sotrybookへの反映方法を知りたい方が記事を読んでいると思うので説明不要な部分だと思いますが…。
それも一緒に知りたかった！って方のためにサラッと書いておきます！

Next.jsを利用していれば`usePathname`を利用できます！

https://nextjs.org/docs/app/api-reference/functions/use-pathname

下記利用方法の例を記載しておきましたので参考にしてください！

```typescript
import { usePathname } from 'next/navigation'

export const Component = ({
  href,
  text,
}) => {
  const pathname = usePathname()
  const active = pathname === href

  return (
    <a href={href} className={active ? 'red' : 'black'}>
      {text}
    </a>
  )
}
```

次に本題のStorybookの書き方について説明します！

## Storyの定義部分にて`parameters`で`path`を渡してあげる！

下記の記事をそのまま流用しました！

https://dev.to/heymarkkop/how-to-use-nextjs-pathname-in-storybook-8-5ac9

```typescript
export const Default: Story = {
  parameters: {
    nextjs: {
      appDirectory: true,
      navigation: {
        pathname: '/top/hoge/',
      },
    },
  },
  args: {...}
```

### 補足説明
`appDirectory: true,`の部分はStorybookの`preview.(js|ts|tsx)`に記載してあればこちらで指定する必要はありません。

:::note
プロジェクトにpagesディレクトリがない構成であれば`preview.(js|ts|tsx)`に記載してあると思いますので確認してください！
:::

https://storybook.js.org/docs/8.0/get-started/nextjs#nextjs-navigation

## まとめ
調べる前は少し複雑なことを考えてしまってましたが、Storybookが用意してくれてました！
皆さんのStorybookがより良いものになることを祈っております！
小説・三体で理解するPCの仕組み

## はじめに
遅ればせながら小説三体を読みました。とにかく面白いSF小説でした。
元エンジニアの方が書いた本だけあり、エンジニアの方にもオススメしたいです。

:::note alert
本記事は三体のネタバレを含みます。
:::


## 三体とは
[**三体**](https://www.amazon.co.jp/%E4%B8%89%E4%BD%93-%E5%8A%89-%E6%85%88%E6%AC%A3/dp/4152098708)（さんたい）は、中国のSF作家による長編SF小説です。
2019年時点で全世界累計発行部数は2900万部を記録し、20か国以上の言語で翻訳されています。SFの世界最大の賞である「ヒューゴー賞」を受賞しています。


2024年2月に文庫版が発売され、より手に取りやすくなったかと思います。
私は通勤中に読むことが多いので文庫化は嬉しいです。


## 著名人のレビュー

バラク・オバマ氏
> 『とにかくスケールがものすごく大きくて読むのが楽しい。これに比べたら、議会との日々の軋轢なんかちっぽけなもので、くよくよする必要はないと思えてくるのも三体を読んだ理由のひとつだね』


小島秀夫氏
>「普遍性と、娯楽性、そして文学性の、まさに『三体』の重力バランスの絶妙なるラグランジュ点でこそ生まれた、奇跡の『超トンデモSFだ』

曽根原氏
> 想像力、知識、哲学の塊のような本。
ページをめくる手を止めたくない。この本と出会えたことに感謝したい。



他にもマーク・ザッカーバーグやジェイムズ・キャメロンも絶賛しています。



## そろそろ本題へ
オブラートに包んで紹介しますがネタバレにご注意ください。

### はじめに
ある星に生命体(以降 3Body)がいます。その星は過酷な環境が予測できない周期で訪れます。その周期を予測するために莫大な計算量が必要と判明し、登場するのが**人列コンピューター**です。ちなみに3Bodyのコミュニケーションは方法は人類のように音声ではなく光のため高速です。


Netflixで映像化されているので紹介します。

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

PCも人列コンピューターと同様で二進数（バイナリ）を使用しています。
3Bodyのコミュニケーションは光のためPCに匹敵するスピードで相互にコミュニケーションを行います。


### 人列コンピューターの構造
初めて中華統一した秦の始皇帝の配下約3000万の兵士で構成されています。OSの名前は秦1.0です。SFなのに中国史に話が飛躍していますが、詳しくは原作をお読みください。

人列コンピューターでは、以下のような役割分担がされています。

**兵士と指揮官**

- 兵士： 基本的な算術（加算、減算、乗算、除算）および論理演算（AND、OR、NOTなど）を行う
- 指揮官：兵士たちに指示を出し、全体の計算を管理するユニット

**現代のPCの構造との比較**

- CPU（中央処理装置） 加算器、レジスタ、スタックメモリ：主に計算を行うユニット
→ 最精鋭の五つの兵団で構成
- ストレージ：データやプログラムを長期間保存する場所
→ 教育水準の高い者たち三百万名で構成し、メモと筆記具を持っている。
- メモリ: データを一時的に記録しておく場所で取り出すのがストレージより早い
→ 外側を囲んできちんと整列している集団。訓練されている。
- バス：各構成要素間でデータをやり取りする通信路
→ 軽騎兵を用いて情報伝達を早めている


おそらくですが人列PCのアーキテクチャはノイマン型と呼ばれるものです。

https://ja.wikipedia.org/wiki/%E3%83%8E%E3%82%A4%E3%83%9E%E3%83%B3%E5%9E%8B

## まとめ
とにかく著者の想像力に驚かされました。始皇帝の兵でPCを再現するという発想を知れただけで三体を読めてよかったです。映像化作品は未見なので楽しみです。


## 余談
**好きな一節**
> 生命にははかりしれない価値があり、すべてが泰山のように重い存在だと思うこともあれば、人間なんかとるにたりないもので、そもそも価値のあるものなんかこの世に存在しないと思うこともあった。ともかく、わたしの人生は、この奇妙な感覚とともに、一日また一日と過ぎていって、知らぬ間に年をとっていた･･････

**文庫化を希望している本** 
文庫化していたら教えて下さい。

[**プロジェクトヘイルメアリー**](https://www.amazon.co.jp/プロジェクト・ヘイル・メアリー-上-アンディ-ウィアー-ebook/dp/B09NBZLC7J/ref=mp_s_a_1_1?adgrpid=132819788603&dib=eyJ2IjoiMSJ9.HYFFKJ2kHgmneMwO2oNeCWeDhtCSq-4VcFMuQvt3QTHrZaJlTb7NLdPNfBPsFeGIycgt8XzA8mMsAJUMGe-1eXCfl5knKlHpuduFoyDEUkl_yqtEm4bo1E-QjKerLZf9A0Z9bdKIZQu0YCPl5AjiceXsJVZ1a5qfMIlvpHyyHc1rymWpKzSJTiS_gPgpyGBKm2dQDKp0osL_vkNc3kAbww.olZYzTyv6vWpYtfmFcSM_Qw6oc87O46tTr2Y9QN3Sy8&dib_tag=se&hvadid=679074481903&hvdev=m&hvlocphy=1009280&hvnetw=g&hvqmt=e&hvrand=3343097418955202424&hvtargid=kwd-1620632334869&hydadcr=3112_13722513&keywords=プロジェクトヘイルメアリー&linkCode=plm&qid=1718834504&sr=8-1)

## 最後に
私の働いている会社で経験の有無を問わず採用を行っています。
興味のある方は是非カジュアル面談から応募してみてください！

https://jambo-support.com/recruit_engineer/
[AWS #10] AWS ShieldとDDoS攻撃について

## はじめに
こんにちは
今回は「AWS Shield（シールド）」について紹介したいと思います。

AWS ShieldはAWSで実行している **「WebアプリケーションをDDoS攻撃から保護するサービス」** のことです。
:rolling_eyes:DDoS攻撃？どんな攻撃なのでしょうか
:upside_down:ではAWS Shieldの前提知識となる、「DDoS攻撃」から紹介いたします。
## DDoS攻撃
DDoS攻撃とは **「Distributed Denial of Service Attack」** の略称です。
**対処しきれないほどの通信をサーバに送りつけることで、<font color=red>サーバーダウンをさせるサイバー攻撃**</font>です。攻撃者が複数の機器を踏み台にして、特定のサーバー、アプリケーションなどに**一斉攻撃を仕掛けること**とも言えますね。
![AWS10_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/3612d37d-c982-9930-161a-0bcfa93584df.png)
図のように攻撃対象のサーバーに大量のアクセスを送ることで、**サーバーが処理に追い付かずサービスダウンしてしまうことを狙って攻撃**してきます。（怖いですね:scream:）
## AWS Shield
では改めて**AWS Shield**に入ります。
AWS Shieldは**常時モニタリングや通知・DDoS攻撃の保護をしてくれるマネージ型サービス**です。
![AWS10_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806875/f91227e1-6aa2-5e38-b5af-095a9dac50c6.png)

そんな「Shield」には **「Standard」** と **「Advanced」** という2つの**提供形態**があります。
### Standard
・**無料**で使用できる
・**ネットワークレイヤー（レイヤー3）**、**転送レイヤー（レイヤー4）** を保護する
・**履歴の参照不可**
・攻撃を**自動で緩和**

:::note info
何も設定していなくても、**無料**でネットワーク層、トランスポート層を保護している
:::
### Advanced
 ・**有料である（[AWS Shield料金はこちら](https://aws.amazon.com/jp/shield/pricing/)）**
 ・アプリケーション層（レイヤー7）を保護する（一部のユーザーは**監視サポート**も付けられる）
 ・Standardよりも**高度で大規模なDDoS攻撃を自動緩和**
 ・攻撃が検知されたら**数分で通知される**
 ・**攻撃履歴の保管**
 ・**24時間365日のサポート**

:::note info
Advancedはサブスクリプションサービスで、**重要なサービスの保護**に検討する
:::

## おわりに
ちょっとしたまとめになります。

:::note info
AWS Shieldとは、マネージド型のDDoS攻撃に対する**保護サービス**
:::
:::note info
AWS Shield **Standard**は、AWSを利用すると**自動的に適用される**
:::
:::note info
AWS Shield **Advanced**は、**アプリケーションレイヤー(L7層)** における**DDoS攻撃も保護する**
:::
簡単な所感ですが、DDoS攻撃からAWSサービスを守るためには、AWS Shieldなどのサービスを組み合わせて備える必要があるのだということが理解できました。

最後までお読みいただきありがとうございました！

>日頃より活用している参考書です。
>> **「参考書」**
[AWS認定クラウドプラクティショナー改定第3版](https://x.gd/19i6N)
>
> **「AWS公式サイト」**
[AWS Shield](https://www.hcnet.co.jp/column/04.html)
>
> **「参考元」**
[OSI7 階層モデル](https://aws.amazon.com/jp/shield/)
>
> **「参考元」**
[AWS Shieldとは？](https://business.ntt-east.co.jp/content/cloudsolution/column-85.html#section-4)
>
> **「参考元」**
[AWS環境でのDDoS対策はどうすればいい？](https://www.wafcharm.com/jp/blog/aws_ddos/)
>
> **「Youtube」**
[【CLF-C02：AWSクラウドプラクティショナー】第14回 AWS Shield (セキュリティとコンプライアンス分野)](https://x.gd/JUitI)
Google Cloudでよく使われるgsutil コマンドをまとめてみた

## はじめに
Google Cloud の `gsutil` は、Google Cloud Storage (GCS) との間でデータを操作するための強力なコマンドラインツールです。今回は、よく使われる `gsutil` コマンドとその使い方、ユースケースについて説明します`gsutil` コマンドを使用すると、GCS 上のバケットやオブジェクトを簡単に管理できます。これにより、データのアップロード、ダウンロード、同期、削除などの操作を効率的に行うことができます。

## 1. gsutil cp
`gsutil cp` コマンドは、ファイルやディレクトリをコピーするために使用されます。

**使い方**:
```sh
gsutil cp [SOURCE] [DESTINATION]
```
**ユースケース**:
- ローカルシステムから GCS へのファイルアップロード。
- GCS バケット間でのファイルコピー。

## 2. gsutil mv
`gsutil mv` コマンドは、ファイルやディレクトリを移動するために使用されます。

**使い方**:
```sh
gsutil mv [SOURCE] [DESTINATION]
```
**ユースケース**:
- GCS バケット内でのファイル移動。
- 異なる GCS バケット間でのファイル移動。

## 3. gsutil rm
`gsutil rm` コマンドは、ファイルやディレクトリを削除するために使用されます。

**使い方**:
```sh
gsutil rm [FILE_PATH]
```
**ユースケース**:
- 不要になったファイルやディレクトリの削除。
- バケット内のクリーンアップ。

## 4. gsutil ls
`gsutil ls` コマンドは、ファイルやディレクトリのリストを表示するために使用されます。

**使い方**:
```sh
gsutil ls [DIRECTORY_PATH]
```
**ユースケース**:
- バケット内のファイルやディレクトリの確認。
- データ整理のためのディレクトリ構造の確認。

## 5. gsutil rsync
`gsutil rsync` コマンドは、ソースとデスティネーションの内容を同期するために使用されます。

**使い方**:
```sh
gsutil rsync [SOURCE] [DESTINATION]
```
**ユースケース**:
- 定期的なバックアップのためのデータ同期。
- 異なる環境間でのデータ一致を確保。

## 6. gsutil du
`gsutil du` コマンドは、バケットやディレクトリ内のストレージ使用量を表示するために使用されます。

**使い方**:
```sh
gsutil du [DIRECTORY_PATH]
```
**ユースケース**:
- ストレージ使用量の監視。
- コスト管理のための使用量確認。

## 7. gsutil mb
`gsutil mb` コマンドは、新しいバケットを作成するために使用されます。

**使い方**:
```sh
gsutil mb gs://[BUCKET_NAME]/
```
**ユースケース**:
- 新しいプロジェクト用のバケット作成。
- データの分類や管理のためのバケット作成。

## 8. gsutil rb
`gsutil rb` コマンドは、既存のバケットを削除するために使用されます。

**使い方**:
```sh
gsutil rb gs://[BUCKET_NAME]/
```
**ユースケース**:
- 使わなくなったバケットの削除。
- 不要なリソースのクリーンアップ。

## まとめ
Google Cloud の `gsutil` コマンドは、データ転送と管理において非常に便利なツールです。このガイドで紹介したコマンドとその使い方、ユースケースを参考にして、あなたのデータ管理ワークフローを最適化しましょう。各コマンドの具体的なオプションや詳細な使用例については、公式ドキュメントを参照してください。

このガイドが、Google Cloud の `gsutil` コマンドを利用する際の助けとなれば幸いです。
gcc/g++ Tips

# 共有ライブラリ
```
/usr/lib/
├── libexample.so.1.0       # 実体ファイル
├── libexample.so.1         # バージョンリンク -> libexample.so.1.0
└── libexample.so           # 開発用リンク -> libexample.so.1
```

## 共有ライブラリの作り方
以下でlibshared.soを出力
```bash
$ g++ -fPIC -c liba.cpp
$ g++ -fPIC -c libb.cpp
$ g++ -shared liba.o libb.o -o libshared.so.1.0
```

# gccオプション
## リンカオプション
### -l（小文字のエル） 
リンク対象のライブラリを指定

```bash
# libexample.so or libexample.aの場合、以下のように先頭のlibや拡張子は不要
$ gcc -lexample
```

## ディレクトリオプション
### -I（大文字のアイ）
指定パスから先のヘッダーファイルを参照

```bash
$ gcc -I<directory path>
```

### -L
指定パスから、-l（小文字のエル）で指定したライブラリを検索
<font color="Salmon">※実行時、このパス先の共有ライブラリが使われるとは言ってない</font>

```bash
gcc -L<directory path>
```

### -rpath
実行時、指定したパス先の共有ライブラリを動的リンクする

```bash
$ gcc -rpath=<directory path>
```

# 環境変数
## LD_LIBRARY_PATH
<font color="Salmon">rpathが設定されていない場合</font>、実行時、この変数で指定したパス群の<font color="Salmon">左から順番</font>に共有ライブラリを探し、最初に見つかったものを動的リンク

# 参考
* [16.5. GCC での動的ライブラリーの使用](https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/7/html/developer_guide/gcc-using-libraries_using-dynamic-library-gcc)

* [Linux の共有ライブラリを作るとき PIC でコンパイルするのはなぜか](http://0xcc.net/blog/archives/000107.html)
ESP32 OTA メモ

sz_x:  OTAのイメージファイルのサイズ
x_path： OTAのイメージファイルのパス

esp_ota_get_next_update_partition()
↓
esp_ota_begin()
↓
esp_ota_write()
↓
esp_ota_end()
↓
esp_ota_set_boot_partition
↓
ESP.restart()


```
#include <esp_ota_ops.h>

void ota_test(void)
{
    esp_err_t r = ESP_OK;
    const esp_partition_t *part;
    esp_ota_handle_t handle;
    part = esp_ota_get_next_update_partition(NULL);
    FILE *fp_x = fopen(x_path,"rb");
    r = ((fp_x == NULL) ? ESP_FAIL : ESP_OK);
    if (r == ESP_OK) r = esp_ota_begin(part, OTA_SIZE_UNKNOWN, &handle);
    if (r == ESP_OK)
    {
        for (int i=0; i < (sz_x / 512); i++)
        {
            size_t rsz = fread(buf,sizeof(uint8_t),512,fp_x);
            if (rsz != 512)
            {
                Serial.println("Read error (ota)");
                r = ESP_FAIL;
                break;
            }
            else
            {
                r = esp_ota_write(handle, (const void*)buf, 512);
            }
        }
        if (r == ESP_OK && (sz_x % 512) > 0)
        {
            size_t rsz = fread(buf,sizeof(uint8_t),(sz_x % 512),fp_x);
            if (rsz != (sz_x % 512))
            {
                Serial.println("Read error (ota)");
                r = ESP_FAIL;
            }
            else
            {
                r = esp_ota_write(handle, (const void*)buf,(sz_x % 512));
            }
        }
    }
    if (r == ESP_OK) r = esp_ota_end(handle);
    if (r == ESP_OK) r = esp_ota_set_boot_partition(part);    
    
    ESP.restart();
}
```
デモ環境HPにだけ表示したい、デモ環境リボン


# 結論　以下のコードをコピペでOK

```html
<div class="demo-ribbon-top">デモ環境</div>
<div class="demo-ribbon-bottom">デモ環境</div>
<style>
    /* リボンのスタイル */
    .demo-ribbon-top {
        position: fixed;
        left: -100px;
        top: 40px;
        z-index: 1000;
        transform: rotate(-45deg);
        background-color: red;
        color: white;
        padding: 20px 100px;
        font-size: 40px;
        font-weight: bold;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
        text-transform: uppercase;
    }

    .demo-ribbon-bottom {
        position: fixed;
        right: -100px;
        bottom: 40px;
        z-index: 1000;
        transform: rotate(-45deg);
        background-color: red;
        color: white;
        padding: 20px 100px;
        font-size: 40px;
        font-weight: bold;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
        text-transform: uppercase;
    }

    /* モバイルではリボンサイズを半分にする */
    @media (max-width: 768px) {
        .demo-ribbon-top {
            left: -50px;
            top: 20px;
            padding: 10px 50px;
            font-size: 20px;
        }

        .demo-ribbon-bottom {
            right: -50px;
            bottom: 20px;
            padding: 10px 50px;
            font-size: 20px;
        }
    }
</style>
```

## こんな感じになります。

（デスクトップ）
![demo-ribbon-pc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605776/eed273df-5e89-4a1d-0f66-ff6bfe4d278d.png)

（モバイル）
![demo-ribbon-mobile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1605776/eed76a9b-5f23-9cea-06bc-0df7bf80b9b4.png)

## おわり

本番環境とデモ環境（ステージング環境、テスト環境）の混同による操作ミスを防ぐため、目立つ形で画面の右下・左上に固定されたリボンを作る必要がありました。

あとはこのコードを、条件分岐でデモ環境でのみ有効になるようにするだけです。

上記の画像でばれてしまいましたが、ChatGPTのコピペです。ほぼ一発でした。
ググってもそれっぽいのが出てこなかったので作りましたが、5分もかかりませんでした。便利ですね。
Cannot find module 'XXX' or its corresponding type declarations.

## 問題

VsCodeの拡張機能Veturが有効になっている環境で既存プロジェクトに参画した。
vueファイルのimportのうちフレームワーク以外のすべてに以下のようなエラーが出現した。

```
Cannot find module 'XXX' or its corresponding type declarations.Vetur(2307)
```

## 状況

- 既存プロジェクトへの参画なので、「存在しません」とエラーの出ているファイルはきちんとあるべき場所に存在する
- `package.json`での定義も間違っていない
- エラーが出現していてもfrontendのbuildは問題なく実施できる（import先のファイルは認識できている様子）

## 解決策

[この記事](https://qiita.com/TakuTaku04/items/d3a54218ece59e83e764)を読んだところ、`Vetur`いらなくねってなったので、アンインストールしました。
それだけでなにもコード変えてないけどエラー0。
プロジェクトの先輩にこの話をしたところ、今は[Volar](https://blog.vuejs.org/posts/volar-a-new-beginning)の方がおすすめとのことでした。
python version 変更

#仮想環境からの抜け方（condaなし)

```
pyenv versions
```
インストールしてあるpyenvの一覧を表示する。

いきたいバージョンへ移動する
```
pyenv local 3.7.0
```



# python version 変更
```
pyenv install -l
```
インストールできるversionの一覧を表示

```
pyenv install 3.7.1
```
インストールしたバージョン指定

```
pyenv local 3.7
python --version
```
【DAY3】IDEについて

# IDE(Integrated Development Environment)とは
IDEは、統合開発環境とも呼ばれ、プログラミングをする際に必要なソフトウェアを統合して、1つの画面で操作できるようにしたものです。
プログラミングをするには、下記のようなソフトフェアが必要になります。
* コードを書くテキストエディタ
* 人がわかる言葉から機械が分かる言葉に変換してくれるコンパイラ
* テストを支援してくれるデバッガ
* コードのバージョン管理

統合開発環境がなければ、これらを一つ一つ別々で入手し、別々に起動して操作しなければなりません。しかし統合開発環境があれば、この手間を大きく削減することができます。

## テキストエディタとは
テキストエディタとは、**文字情報の入力・編集・保存を可能とするソフトウェア**です。

## コンパイラとは
コンパイラとは、**高水準言語で書かれたプログラムをコンピュータが理解可能な形に変換する処理を行う言語プロセッサ**のことです。
コンピュータの処理は全て0と1だけで行われています。しかし、人が0と1だけでコンピュータの処理内容を記述するのは現実的ではありません。
そこで、人間にとって理解しやすい構文で書くことができる高水準言語が作られ、高水準言語によりコンピュータの処理内容を記述するようになりました。
しかし、当然高水準言語で記載された内容をコンピュータは理解できません。従って、高水準言語で記載された内容をコンピュータが理解できるように変換するのがコンパイラの役目です。

## デバッガとは
デバッガとは、**バグと呼ばれる、コンピュータにおけるプログラムやソフトウェアの誤りや不具合(エラー)を発見・修正するソフトウェア**のことです。
もう少し具体的に書くと、動いているプログラムを一時的に止めたり、実行途中のデータの中身を好きな値に書き換えたり、プログラムの不具合の原因を探す上で便利な機能を提供してくれるソフトのことです。

## IDEの例
IDEには、以下のようなものがあります。
* Visual Studio Code
* Eclipse
* Xcode
* Android Studio

VScodeは広く一般的に使われている印象です。私はVScodeとEclipseを使ったことがあります。
Functionから呼び出しているAzure OpenAI ServiceのAPIをGPT3.5から画像入力可能なGPT4oに変えてみた

# はじめに
Azure Functionsを使って開発した関数で、Azure OpenAI ServiceのGPT3.5のAPIを呼び出して利用していましたが、先月末GPT4oがGAしたのでこっちに移行したいと思います

関数のベースは以前作成した下記の記事のものを修正する形で使います

https://qiita.com/t-sho/items/4f8df04216111205f53b

# 米国東部リージョンでAzure OpenAIのリソースを作成する
GPT4oは日本リージョンでは利用できないので米国東部リージョンを利用します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/3c593afa-ca4a-bb89-af4e-0f9b239b0a7d.png)

リソース作成後、Azure OpenAI Studioでモデルをデプロイします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/055a8f21-ea3d-5fe5-45f5-1bcfa9482db2.png)

# Functionで画像データがあった場合の処理を追加
HTTPリクエストの要求本文の形としては下記のイメージです
ユーザの入力に相当する"type"="human"のところに、imagesのリストを入れるようにします。
画像が複数入ってきてもいいようにリスト形式にしています。
画像データはbase64でエンコードされたものを受け取ります。
```json
{
    "messagelist":[
        {"type":"system","message":"あなたは優秀なアシスタントです。日本語で回答してください。"},
        {"type":"human","message":"こんにちは","images":[]},
        {"type":"ai","message":"こんにちは！今日はどんなお手伝いができますか？"},
        {"type":"human","message":"なんて書いてある？","images":["data:image/png;base64,<エンコードした文字列>","data:image/png;base64,<エンコードした文字列>"]}
    ]
}
```

imagesのリストに要素があった場合は、画像データがついてるものと判断しHumanMessageのContentに含めるように処理を修正します。
```python
import azure.functions as func
import logging
import os
from langchain_core.messages import HumanMessage,SystemMessage,AIMessage
from langchain_openai import AzureChatOpenAI

app = func.FunctionApp(http_auth_level=func.AuthLevel.FUNCTION)

@app.route(route="simplechat")
def simplechat(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')
    model = AzureChatOpenAI(
        openai_api_version=os.environ["AZURE_OPENAI_API_VERSION"],
        azure_deployment=os.environ["AZURE_OPENAI_CHAT_DEPLOYMENT_NAME"],
    )

    data = req.get_json()
    message_lists = []
    for item in data['messagelist']:
        if item['type'] == 'system':
            message_lists.append(SystemMessage(content=item['message']))
        elif item['type'] == 'human':
            message_content = [{"type": "text", "text": item['message']}]
            if 'images' in item and len(item['images']) > 0:
                for image_url in item['images']:
                    message_content.append({"type": "image_url", "image_url": {"url": image_url}})
            message_lists.append(HumanMessage(content=message_content))
            
        elif item['type'] == 'ai':
            message_lists.append(AIMessage(content=item['message']))
    
    response = model.invoke(message_lists)

    if response.content:
        return func.HttpResponse(response.content)
    else :
        return func.HttpResponse(
            "This HTTP triggered function executed successfully. But an unexpected error occurred with the Azure OpenAI Service API.",
            status_code=200
        )
```

AzureにデプロイしたらFunctionの環境変数の値をGPT4oのものに変更しておきましょう。


# 実行
実際Functionに対して画像を送ってみて、画像認識された回答が返ってくることを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261327/bf6783d9-edd6-d8bf-572b-d9b22b420d0c.png)

単価の高いGPT4は飛ばしてよいので、GPT4oが早く日本リージョンで使えるようになると良いですね
vueCompilerOptionsのexperimentalDisableTemplateSupportが使えなくなっていた

## 問題

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1211125/5768aba1-fab9-9664-8ec4-03bda78f983e.png)

気づいたら`tsconfig.json`の`vueCompilerOptions`に定義していた`experimentalDisableTemplateSupport`プロパティに警告が出ていた。

## 原因

`1.0.0-alpha.4(2022/9/24)`にアップデートした際、破壊的な変更があった様子。（今更気づいた）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1211125/7fea5fe1-dbdf-5c59-7320-c109483e8921.png)

- [参考リンク](https://github.com/vuejs/language-tools/blob/master/CHANGELOG.md#100-alpha4-2022924)

## 対処

プロパティ名を`skipTemplateCodegen`に変更した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1211125/841e3ea9-0cd8-53a2-be1b-1e7de14e6a01.png)
【UiPath】非構造化データと構造化データについて

# UiPath AI-Powered Automation Summit Tokyo
6/18(火) 六本木の東京ミッドタウンでUiPathのカンファレンスに行ってきました。
すべての講演を聞くことはできませんでしたが、今回のテーマはAIでしたが、本質は **「AIによって、非構造化データの取り扱いが容易になった」** ことだと思いました。
まずは、非構造化データとはどのようなデータなのか説明します。

# 非構造化データと構造化データの違い

#### ・非構造化データ
PDFファイルや画像ファイルといったデータで、特定の情報を狙って取得することが困難なデータを指します。
具体的な例
例えば、以下は出張申請書のPDFとなりますが、赤枠部分の情報をUiPathで取得するには困難でした。セレクターで選択してもうまく取得できなかったり、仮に取得できたとしても、書式が変わっていることで、エラーとなったりと、デリケートで自動化には向きません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/4477469a-8716-5fab-eb61-66f8aa1fc066.png)

#### ・構造化データ
そこで、ロボットが読みやすい形で申請書をExcelなど、機械に命令して取得しやすい形のデータに変更して運用していたと思います。
以下のように、申請日の記載セルをH6の定数とすることで、ロボットへH6セルの情報を取得するように指示することで、ロボット起動が安定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/dd780cfe-c614-e1da-cf5b-89655bb849f6.png)

# DCUが自動化にもたらすインパクト
ここからが今回の本題となりますが、DCU（Document Understanding)を使ことで何ができるようになるのか、というと、上記で説明した非構造化データの必要なデータを取得することが容易に行えるようになりました。
DCUができることを列挙すると以下の通りです。

|  できること  |  説明 |
| ---- | ---- |
| ドキュメントの分類 | ドキュメントの種類（請求書、契約書、注文書など）を自動的に識別し、分類することができます。 | 
| 情報の抽出 | ドキュメントから特定のデータ（名前、日付、金額、住所など）を抽出し、構造化データとして保存します。 | 
| 手書き文字の認識 | OCR（光学文字認識）技術を活用して、手書きのテキストをデジタルデータに変換することができます。 | 
| テンプレートフリーのデータ抽出 | テンプレートに依存せずに、異なる形式のドキュメントから必要な情報を抽出できます。 | 
| 自然言語処理 | テキストの意味を理解し、重要な情報を抽出したり、内容を要約したりすることができます。 | 
| ドキュメントのレビューと修正 | 自動抽出されたデータを人間が確認し、必要に応じて修正するためのインターフェースを提供します。 | 
| ワークフローの自動化 | 抽出されたデータを基に、請求書処理や契約書管理などのビジネスプロセスを自動化します。 | 
| スケーラビリティ | 大量のドキュメントを迅速に処理し、大規模なドキュメント処理業務にも対応可能です。

# まとめ
今回のUiPath AI-Powered Automation Summit Tokyoでは、AIの進化がビジネスプロセスの自動化に与える大きな影響を実感しました。特に、非構造化データの取り扱いが飛躍的に向上したことが印象的でした。従来、非構造化データの処理は非常に困難であり、多くの手間とコストがかかるものでした。しかし、UiPathのDCUを活用することで、これらの課題が大幅に解消されました。

DCUの導入により、以下のようなメリットが得られます：

|  メリット  |  説明 |
| ---- | ---- |
| 非構造化データの効率的な処理 | PDFや画像から必要な情報を抽出する作業が自動化され、時間と労力を大幅に削減。 | 
| 業務の正確性と一貫性の向上 | 手動によるデータ入力ミスが減り、業務の品質が向上。 | 
| スケーラビリティ | 大量のドキュメントを短時間で処理でき、大規模な業務にも対応可能。 | 
| 柔軟な適用 | テンプレートに依存せず、多様な形式のドキュメントからデータを抽出できるため、さまざまなビジネスシナリオに適用可能。 | 

このように、DCUを活用することで、企業はより効率的で信頼性の高い業務プロセスを構築することができます。AI技術の進化は今後も続き、さらに多くのビジネス課題が解決されることが期待されます。UiPathの取り組みは、AIによる業務自動化の未来を切り開く一歩であり、その可能性を強く感じることができました。
次回はDCUを使用して、非構造化データから構造化データへ変換する事例を試したいと思います。
記事：[【UiPath】DCU活用事例](URL)
USBチェッカーをレビュー

## はじめに
こんにちは、やっとUSBテスターを購入したbockringです。今までは(何故か家に転がっていた)USB C-Cの延長と秋月電子で売っている小型電圧計を組み合わせたものを使っていました。しかし、電流は測定できませんし何Aまで耐えられるのかすら不明です。騙し騙し使っていましたが今度こそ、と購入しました。

## 今回購入した物
この度、2点を購入しました。どちらもRoute-R(ルートアール)ブランドのものです。企業の理念(？)てきなものが「中国と日本の架け橋」なのでRouter(ルーター/経由地)と掛けているのでしょう。

購入したものはこちらです。
[USB Type-Aチェッカー](https://route-r.co.jp/?p=2233)と[USB Type-Cチェッカー](https://route-r.co.jp/?p=4238)の2点です。

https://amzn.to/3F065dj

https://amzn.to/3Z8jiHM

Aの方は5V専用です。私はQCユーザーではないのでこちらにしましたが、[QC2.0/3.0/データ通信対応版](https://route-r.co.jp/?p=3224)の方がおすすめです。というか、これを買った方が良かったですね…(買ってから気づきました)

そしてCの方はしれっとPD3.1(30V8A 240W)に対応しています。

ちなみに、選定基準は
・電圧/電流/積算電流量の同時表示
・なるべく小型なもの
です。あと、Cの方については「金属筐体であること」も条件です。Cの方は大電力を流すので放熱の問題もありますし、純粋にチェッカーのCってモゲやすい傾向にあるので、その気休めですね。

## 使用テスト
ここからはただひたすら意味の分からないことをします。それは、接続のことなのですが、なんと

**ﾓﾊﾞｲﾙﾊﾞｯﾃﾘｰ→ﾁｪｯｶｰ(A)→USBｹｰﾌﾞﾙ(A-C)→ﾁｪｯｶｰ(C)→ﾁｪｯｶｰ(自作C)→ｽﾏﾎ**

です。訳がわからないですね。試験は5Vで行います。結果として
全て同じぐらいの電圧になれば問題ないですね。電流もAとCの物でほとんど同じになれば問題ないものとします。


## 負荷試験
ここでは充電容量11%のiPadを使用して少々の電流を流していきましょう。

:::note info
いきなり余談ですが、AppleのUSB-C↔︎Lightningケーブルは実は常に5Vのトリガーをかけています。

その証拠に、PD対応の端子にチェッカーを繋ぎ、普通のPDケーブルのみを繋いでみましょう。画面は付きませんね。しかしAppleのケーブルを繋ぐと画面がつきます。

これは、CC検知に対応していないLightningのiPhoneやiPadなどにも電気を供給する工夫ですね。さすがはAppleです。
:::

## モバイルバッテリーの容量チェック
USBチェッカーと負荷装置といえばこれですよね。その前にモバイルバッテリーを意味もなく5Wの低速充電器に接続して一晩かけて満充電にします。満充電になったらバッテリーにチェッカーとUSBケーブル(A-Lightning)を接続しますが、ここで注意が必要です。接続する前にチェッカーを別の充電器に接続して積算電流量をリセットします。0mAhにして、充電器から外したらオス端子を負荷装置に繋ぎます。

試験を開始します。負荷装置のスイッチはOFFにしてケーブルとチェッカーを接続します。そして1Aにして正常に流れたらそのまま2Aモードにして待ちましょう。(別に1Aのままでも良いんですが待つの面倒なので)
![IMG_1426.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3777721/92a9cb2b-b8c0-5a4e-4bd9-97f7760782ac.jpeg)
すでに雲行きが怪しいです。長いこと使っているので仕方ないですが、凄く劣化してますね… 単純計算で2970mAhになってしまいます… まぁ続けましょう。

0%が近づいたら0%で点滅するまで待ち、結果を読み取ります。放電は`0.93A`で推移、放電時間は`3:08.10`、そして積算電流は`2890mAh`でした… 昇圧効率は大体70~80%なことが多いですので、ここでは75％として計算します。電圧はセル公称値の3.7Vで計算します。
```
(2890mAh / 1000) * 5V = 14.45Wh //出力した容量
14.45Wh / 3.7V * 1000 ≒ 3905.4mAh //出力容量(セル)

3905.4mAh(出力分) / 75% = 5207.2mAh //バッテリセルの実容量(理論値)
```
全然大丈夫じゃ無さそうです、というか替え時をとうの昔に過ぎていますね… 今度SMARTCOBY Pro Slimを買っておきます。

ちなみに、0.93A放電(なんで2A近く出ないの?)で1時間5分ちょっとが過ぎた時に1000mAh(1Ah)を記録したので、それなりに精度は高そうな雰囲気です。安心して使えますね。

## おわりに
USBチェッカー(特にAの方)をレビューしてきました。純粋な容量なチェックのはずが買い替え時を過ぎていることがわかったりと色々ありましたが、良かったと思います。

しかしRoute-Rさんの製品は中国からのOEMなこともあって初期不良品(常に0.5Aのトリガーがかかっちゃうとかw)が来ることもあるようです。しかし輸入代理のRoute-Rさんは6ヶ月の保証はあるようなので、直輸入よりは安心ですね。

それではまた〜
Open SSLとは？


## opensslとは？

SSLやTLSの機能が実装されているオープンソースの通信暗号プロトコルライブラリ

SSLやTLSについて詳しくはこちら↓

https://qiita.com/mayobimu/items/5ac78a48cd9ae30b6577


## 現在のバージョン
### サポート
- バージョン3.2
    - 2025年11月23日まで
- バージョン3.1
    - 2025年3月14日まで
- バージョン 3.0
    - 2026年9月7日 (LTS) まで

### サポート外
- バージョン 1.1.0、1.0.1、1.0.0、0.9.8

> With regards to current and future releases the OpenSSL project has adopted the following policy:
Version 3.2 will be supported until 2025-11-23
Version 3.1 will be supported until 2025-03-14
Version 3.0 will be supported until 2026-09-07 (LTS).
Versions 1.1.1 and 1.0.2 are no longer supported. Extended support for 1.1.1 and 1.0.2 to gain access to security fixes for those versions is available.
Versions 1.1.0, 1.0.1, 1.0.0 and 0.9.8 are no longer supported.



https://www.openssl.org/policies/releasestrat.html
Rubyにおけるrequire、require_relative、loadの違いと使い方

## はじめに

Rubyでプログラミングを行う際、ファイル間でコードを共有し再利用することは非常に重要です。これを実現するための主要なキーワードは `require`、`require_relative`、および `load` です。しかし、多くの初心者プログラマーはそれらの違いに混乱することがあります。この記事では、`require`、`require_relative`、`load` について詳しく説明し、それらを効率的に使用する方法を具体的な例を交えて紹介します。

この記事では、以下のようなディレクトリとファイル構成を仮定します：

```zsh
- project/
  - main.rb
  - lib/
    - foo.rb
```

```ruby:lib/foo.rb
class Foo
  def message
    puts "Hello world!"
  end
end
```

## Rubyにおけるrequire

`require` は、ライブラリやモジュールを現在のプログラムにロードするために使用されるRubyのキーワードです。`require` の特徴は、プログラムの実行中に一度だけファイルをロードすることです。これにより、不要な再ロードを避け、システムリソースを節約できます。

`require` は指定されたファイルを読み込み、メモリに保存します。次回以降、そのファイルにアクセスする際には、メモリに保存された内容を使用するため、再度ファイルを読み込む必要がなくなり、パフォーマンスが向上します。しかし、`require` されたファイルに後で変更が加えられた場合、その変更は反映されません。

`require` を使用する際、Rubyはグローバル変数 `$LOAD_PATH` にリストされているパスでファイルを検索します。ファイル名の指定時に `.rb` 拡張子を省略することができます。

### requireの例

次のような内容の `main.rb` ファイルがあるとします：

```ruby:project/main.rb
require './lib/foo'

foo = Foo.new
foo.message
```

この `main.rb` を実行すると、次のような結果が得られます：

```zsh
Hello world!
```

## Rubyにおけるrequire_relative

`require_relative` は `require` と同様にファイルを一度だけロードしますが、**現在のファイルの位置からの相対パス**を使用してファイルをロードします。これにより、プロジェクト内のファイルをフルパスを指定せずにロードすることができ、便利です。

### require_relativeの例

次のような内容の `main.rb` ファイルがあり、フォルダ `project` がフォルダ `work` 内にあるとします：

```ruby:project/main.rb
require_relative './lib/foo'

foo = Foo.new
foo.message
```

プロジェクトのルートフォルダから `main.rb` を実行すると、期待通りの結果が得られます。

```zsh:work/project/
# work/project/
ruby main.rb => Hello world!
```

```zsh:work/
# work/
ruby project/main.rb => Hello world!
```

## Rubyにおけるload

`load` は現在のプログラムにソースファイルをロードするために使用されるRubyのキーワードです。しかし、`require` とは異なり、`load` は呼び出されるたびにファイルを再ロードします。これは、実行中にファイルの内容が変更された場合、その変更が反映されることを意味します。

### loadの例

次のような内容の `main.rb` ファイルがあるとします：

```ruby:project/main.rb
load './lib/foo.rb'

foo = Foo.new
foo.message
```

この `main.rb` を実行すると、結果が表示されます。

## requireとloadの比較

これらのキーワードはすべて、現在のファイルに必要なコードをロードするために使用されます。基本的な違いは次のとおりです：

- `require` はプログラムの実行中に一度だけファイルを読み込みます。
- `load` はファイルが呼び出されるたびにそのファイルを再読み込みします。

そのため、`load` は開発環境（development）での作業に役立ちます。この環境では、ソースコードの変更が頻繁に発生します。逆に、`require` は、ソースコードが安定していて頻繁に変更されない本番環境（production）での使用に適しています。

## まとめ

以下は、Rubyにおける `require`、`require_relative`、および `load` の違いを比較した表です：

| **メソッド**         | **パス**                                    | **ロード回数**          | **拡張子の省略** |
|---------------------|--------------------------------------------|-----------------------|-----------------|
| require           | Rubyの実行パス（$LOAD_PATH）からの相対パス   | 一度だけ               | 可              |
| require_relative  | `require_relative` が呼び出された位置からの相対パス | 一度だけ               | 可              |
| load              | Rubyの実行パス（$LOAD_PATH）からの相対パス   | 呼び出されるたびに再ロード | 不可            |

これらの違いを明確に理解することで、`require`、`require_relative`、および `load` を効果的に使用し、Rubyプロジェクトをより効率的に管理することができます。
Rubyのクラスメソッドとインスタンスメソッドの概念と違い

**クラスメソッド**と**インスタンスメソッド**はオブジェクト指向プログラミングにおいて重要な概念です。この記事では、Rubyプログラミング言語におけるクラスメソッドとインスタンスメソッドについて説明します。

## クラスメソッドとは？

クラスメソッドはクラス上に定義され、クラスのインスタンスではなく、クラス自体に対して直接呼び出すことができるメソッドです。これらはクラス全体に使用されることが多いです。

### クラスメソッドの定義方法

Rubyではクラスメソッドの定義方法は非常に柔軟です。以下にクラスメソッドを定義するための3つの一般的な方法を示します。

```ruby
# 方法1
class Car
  def self.total
    10
  end
end

puts Car.total # => 10

# 方法2
class Car
  class << self
    def total
      10
    end
  end
end

puts Car.total # => 10

# 方法3
class Car; end

def Car.total
  10
end

puts Car.total # => 10
```

- 方法1: 最も一般的な定義方法で、`self`を用いてクラスメソッドを定義
- 方法2: クラス全体に適用する複数のメソッドを定義する場合に便利な方法で、`class << self`を用いてクラスメソッドを定義
- 方法3: クラス外部でクラスメソッドを定義する特殊な方法

## インスタンスメソッドとは？

インスタンスメソッドはクラス内に定義され、そのクラスのインスタンスに対して呼び出すことができるメソッドです。これにより、特定のインスタンスのデータにアクセスし、変更することができます。

### インスタンスメソッドの定義方法

```ruby
# 方法1
class Car
  def name
    'Toyota'
  end
end

puts Car.new.name # "Toyota"

# 方法2
class Car
  attr_accessor :name
end

car = Car.new
car.name = 'Toyota'

puts car.name # "Toyota"

# 方法3
class Car; end

car = Car.new
def car.name
  'Toyota'
end

puts car.name # "Toyota"
```

- 方法1: これは最も一般的なインスタンスメソッドの定義方法で、そのクラスのすべてのインスタンスに適用される
- 方法2: `attr_accessor`は、`name`属性の`getter`および`setter`メソッドを作成し、そのクラスのすべてのインスタンスに適用される
- 方法3: これは特定のオブジェクトにのみ適用されるメソッドの定義方法で、他のインスタンスには影響しない

## クラスメソッドとインスタンスメソッドの違い

### クラスメソッド:

- クラス上で呼び出される
- クラスメソッドは、クラス全体に関連する操作が必要なときに使用される。例えば、サンプルオブジェクトの作成、データの統計、検索の実行など
- 例: `User.create_sample_users`

### インスタンスメソッド:

- 特定のオブジェクト上で呼び出される
- インスタンスメソッドは、特定のオブジェクトのデータにアクセスしたり、変更したりする必要があるときに使用される
- 例: `user.profile`

---

クラスメソッドとインスタンスメソッドの違いは、Rubyプログラミングにおいて重要な側面です。正しく理解し適用することで、強力で保守しやすく、効率的なプログラムを作成することができます。
【Pyhon】venvを使って別のパソコンでも数年後でも動くスクリプトを作っておく

# venvを使っていないとき

俺：いろいろな事情で**Excelファイルを読み込んでCSVにしてさらにExcelの形式にしてさらにCSVにするツール**が必要になってしまった…。

俺：どうしてわざわざExcelファイルを経由するんだ…！？　まあいっかー。

俺：Excelファイルを扱うとなると、`Pandas`がいいかなあ。`pip install`っと……。

通りすがりの先輩：Pythonを使うときは、venvを使うと便利だぞ！

俺：`venv`……？
venvを使うと、仮想環境を作ってそこで動かせるのかー。
いや、**Excelファイルを読み込んでCSVにしてさらにExcelの形式にしてさらにCSVにするツール**なんてもう二度と触る気はないし、別に使わなくてもいいか。

～数年後～

俺：まさかExcelファイルを読み込んでCSVにしてさらにExcelの形式にしてさらにCSVにする機会が再び来るとは……。
前作った便利ツールなかったっけ？
あっ、Pythonのバージョンが上がってるせいで動かせない。
このとき使ってたバージョンっていくつだっけ？
一瞬だけ動いてほしいだけなんだけどな……。

あのときvenvをやっておいたら……。

# Pythonを使うときは、venvを使うと便利だぞ！

というわけで、ちゃんとvenvやrequirements.txtを使用して動く環境を作っておくと、便利です。
（使用しなくても開発はできますが、便利）。
個人的には、 **「あとあとでも確実に動かせる環境が手に入る」** という便利さが、あとから効いてくる機会が多かったです。人に提供するときも便利です。

# venvとは

venvは軽めの仮想環境を作るための仕組みです。
Python3.3から追加された機能です。

https://docs.python.org/ja/3/library/venv.html

Pythonの最新版は今（2024/6/20)、3.12.4なので結構前です。

仮想環境を作る仕組みはほかにもありますが、標準の機能なのでお手軽で便利です。

# 使い方

- Pythonの仮想環境を作成
まず、プロジェクトのディレクトリを作成し、そのディレクトリに移動します。
以下の例ではmy_projectという名前でフォルダを作っています。

```sh
mkdir my_project
cd my_project
python -m venv venv
```

フォルダをのぞいてみると、venv用にいろいろできています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/f26ac213-5344-d99c-5512-d600c016b277.png)


- 仮想環境を有効化
作成した仮想環境を有効化します。

Windowsの場合:
```sh
venv\Scripts\activate
```

macOS/Linuxの場合:
```sh
source venv/bin/activate
```

前の手順で作成されたScripts内のactivate.batを起動するのと同じです。

仮想環境が有効化されると、コマンドプロンプトが (venv) で始まるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439672/9dde3c04-e183-6862-2d97-482643d347f6.png)

タイポでmaiiiiiin.pyになっている気がするがまあいいや。

- 必要なパッケージをインストール
仮想環境が有効化された状態で、必要なパッケージをインストールします。

```sh
pip install パッケージ
```

と、ひとつひとつやってもいいのですが、
`requirements.txt`にパッケージを記述しておいて、一コマンドでインストールできるようにすると便利です。

```sh
pip install -r requirements.txt
```

あとはmain.pyなど適当なファイルを作って仮想環境内で実行していきます。

# うれしい点

Pythonでは、なんかしようと思ったとき、だいたいやりたいことをやらせてくれるパッケージがあります。
（C#でもNugetで便利なものをインストールして使用する機会はありますが、Pythonではやりたいことすべてにあるので衝撃的でした。ライセンスには注意しましょう）。

例えばCSVやExcelを扱おうと思ったとき、画像を加工しようとしたとき、音声や動画ファイルを扱おうと思ったとき、「このパッケージを入れたら便利だなあ～」というのに出くわします。

    pip install パッケージ名

で入れるかと思います。

このパッケージはかなり便利ですが、**新しいPythonのバージョンには対応してなかったり、古い関数をやめたので新しい関数にしてほしいとか** 、使っているといろいろなトラブルが襲い掛かってきます。

メインマシンでPythonのバージョンを下げたり、あえて古いバージョンのパッケージを入れたりしないとならなくなってくると本当に大変です。
あっちのスクリプトはバージョン下げないと動かないけどこっちは最新版が入ってるとか、管理しきれません。

仮想環境の中だったら気にせず使用することができるため便利。

# その他

※本記事はQmonus Value Streamの投稿キャンペーン記事です。

https://qiita.com/official-events/3648bc4e6cedb674491c
計算統計力学　森北出版株式会社　Wm.G.Hoover

```r
#p.9　ばねの運動方程式 d^2x/dt^2=-k*x/m
#2次差分を用いた場合(精度が悪い)

x=1 #初期置
xvec=c(x) #閾値ベクトル
tvec=c(0) #時間軸
ite=30 #計算回数
dt=1.2　#時間幅
k=5 #ばね定数
m=10 #質量

for(l in 1:ite){
if(l==1){
x=2*x-k*(dt^2)*x/m  
}else{
x=2*xvec[l]-k*(dt^2)*xvec[l]/m-xvec[l-1]  
}  
xvec=c(xvec,x)
tvec=c(tvec,l*dt)
}


plot(tvec,xvec,xlim=c(min(tvec),max(tvec)),ylim=c(min(xvec),max(xvec)),xlab="t",ylab="",col=2,type="o")

par(new=T)

plot(tvec,cos(sqrt(k/m)*tvec),xlim=c(min(tvec),max(tvec)),ylim=c(min(xvec),max(xvec)),xlab="t",ylab="",col=3,type="o")


```

```r
#p.9 ばねの運動方程式 d^2x/dt^2=-k*x/m
#オイラー法

x=1 #初期置
y=0 #xの勾配の初期値
xvec=c(x) #閾値ベクトル
yvec=c(y)
tvec=c(0) #時間軸
ite=50 #計算回数
dt=0.1　#時間幅
k=5 #ばね定数
m=10 #質量

for(l in 1:ite){
x=x+dt*y
y=y-dt*k*x/m
xvec=c(xvec,x)
yvec=c(yvec,y)
tvec=c(tvec,l*dt)
}


plot(tvec,xvec,xlim=c(min(tvec),max(tvec)),ylim=c(min(xvec),max(xvec)),xlab="t",ylab="",col=2,type="o")

par(new=T)

plot(tvec,cos(sqrt(k/m)*tvec),xlim=c(min(tvec),max(tvec)),ylim=c(min(xvec),max(xvec)),xlab="t",ylab="",col=3,type="o")


```

```r

#p.16 最小作用の原理
#円上を動く座標でラグランジアンを最小にするx,yの軌跡を求める
#オイラー法

x=1 #初期値x
y=0 #初期値y
X=0 #初期値xの勾配
Y=1 #初期値yの勾配
t=0 #初期時刻
lam=1 #初期値
r=2 #動く円上の半径

xvec=c(x) #閾値ベクトル
yvec=c(y) #閾値ベクトル
tvec=c(t) #時間軸

ite=1000
m=10 #質量
dt=0.01
Lvec=c() #ラグランジアン

for(l in 1:ite){
x=x+dt*X
y=y+dt*Y
x=r*round(x/sqrt(x^2+y^2),digit=4) #半径rの円上の運動に限定
y=r*round(y/sqrt(x^2+y^2),digit=4) #半径rの円上の運動に限定

X_pre=X
Y_pre=Y
X=X+lam*dt*x/m
Y=Y+lam*dt*y/m
dX=(X-X_pre)/dt
dY=(Y-Y_pre)/dt
lam=m*(dX+dY)/(x+y)
t=t+dt
L=m*(dX^2+dY^2)/2+lam*(x^2+y^2-r^2)/2

xvec=c(xvec,x)
yvec=c(yvec,y)
tvec=c(tvec,t)
Lvec=c(Lvec,L)
}

#ラグランジュ乗数の確認
m*dX/x
m*dY/y


plot(xvec,yvec)

```
オンライン日付カウンターで時間管理を最適化

今日のデジタル時代では、オンライン ツールの使用が普及し、日常生活に欠かせないものになりました。最も便利で広く使用されているツールの 1 つは、オンライン日付カウンターです。このツールは、さまざまな分野のユーザーにとって、多くの重要で役立つ効果をもたらします。オンライン日付カウンターを使用する主な利点は次のとおりです。
1. 効果的な時間管理
オンライン デイ カウンター ツールは、ユーザーが効率的に時間を管理するのに役立ちます。重要なプロジェクト、計画、イベントを簡単に追跡および管理します。特定のイベントまであと何日残っているかを正確に知ることで、科学的に仕事を計画して整理することができ、怠惰や消極的な姿勢を避けることができます。
2. 重要なイベントのリマインダー
オンライン日付カウンターを使用すると、誕生日、記念日、約束などの重要なイベントを忘れることはありません。このツールを使用すると、各イベントの前にリマインダーを設定できるため、徹底的に準備してイベントを見逃すことがなくなります。
3. 長期計画のサポート
オンライン デイカウンターの使用は、長期的な計画を立てるのに非常に役立ちます。試験の準備、旅行の計画、仕事のプロジェクトの管理など、このツールを使用すると、残り時間を計算してタスクを適切に分割し、すべての作業を時間通りに完了することができます。
4. 時間と労力を節約
2 つの日付の間の日数を手動で計算する代わりに、オンライン日数カウンターを使用すると、時間と労力を節約できます。必要な情報を入力するだけで、ツールが自動的に計算し、正確な結果を即座に提供します。これにより、時間を気にせずに他の重要なタスクに集中できます。
詳細はこちらをご覧ください : https://lichduongam.com/dem-ngay-online.html
Databricks生成AIクックブック - 2. RAGの基礎

[2\. RAG fundamentals — Databricks Generative AI Cookbook](https://ai-cookbook.io/nbs/2-fundamentals-unstructured.html) [2024/6/20時点]の翻訳です。

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

> [Databricks生成AIクックブック](https://qiita.com/taka_yayoi/items/36c51bce8f33a70cf204)のコンテンツです。


このガイドのセクション1では、RAGを紹介し、機能をハイレベルで説明し、LLM単体に対する利点をハイライトしました。

このセクションでは、非構造化データに対するRAGアプリケーションを開発する際のキーコンポーネントや原則をご紹介します。特に以下を議論します:

1. [**データパイプライン**](https://qiita.com/taka_yayoi/items/8b5845c4c3e22e2bdd20): RAGアプリケーションの**データパイプライン**を用いて、PDFのコレクションのような非構造化文書を収集に適したフォーマットに変換します。
1. [**収集、拡張、生成\(RAGチェーン\)**](https://qiita.com/taka_yayoi/items/03bfe87bb2c0c21dde09): ステップのシリーズ(**チェーン**)は以下を実行するために呼び出されます:
    1. ユーザーの質問の理解
    1. サポートデータの収集
    1. ユーザーの質問とサポートデータに基づいたレスポンスを生成するためのLLMの呼び出し
1. [**評価**](https://qiita.com/taka_yayoi/items/e4344fddbf3f1cea1f79): あなたのビジネス要件を満たすように、RAGアプリケーションの品質/コスト/レーテンシーを評価します。
1. [**ガバナンス & LLMOps**](https://qiita.com/taka_yayoi/items/741420c779118fae1114): データリネージとガバナンス(アクセスコントロール)を含む、それぞれのコンポーネントのライフサイクルを追跡、管理します。

![](https://ai-cookbook.io/_images/1_img1.png)

- [目次](https://qiita.com/taka_yayoi/items/36c51bce8f33a70cf204#%E7%9B%AE%E6%AC%A1)
- 前のセクション: [1. RAGの概要](https://qiita.com/taka_yayoi/items/ad36e09639a95b6eae69)
- 次のセクション: [2\.1\. データパイプライン](https://qiita.com/taka_yayoi/items/8b5845c4c3e22e2bdd20)

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
【ChatGPT＋DALL-E3】【Dream Machine】の動画を１秒ごとに分割する方法。


　どうも、カーブミラーです。

　今回は、Dream Machineの動画を１秒ごとに分割します。おそらく、ほかの動画でもできるかと（未確認）

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はありません。あしからず。
:::

　Luma AIのコンテストに
　　登録しました、と
　　　以前書きましたけど、
　　　　登録方法が間違っていました😅

　とりあえず
　　登録し直しました。

　ごらんになりたい方は
　　こちらからどうぞ。
　　　20秒あります。音なし。
　　　　[登録作品](https://x.com/kabumira862571/status/1803414936426598892?t=YRYTsQpeboqIOYEQxeI9GA&s=19)
***
　さて、本題です。

　動画の分割なんて
　　使うときが来るのか？

　そう思うかもしれませんが、
　　意外とあります。

　特に動画生成AIは
　　生成する時間が
　　　固定されています。
　　　　Dream Machineなら
　　　　　5秒ですね。

　“ここで次のシーンに行きたい”
　　そう思っても、何かしらの
　　　動画編集ツールを
　　　　使わねばなりません。

　もちろん、
　　それを生業にするのなら
　　　そんなツールを導入しても
　　　　構いませんけど、
　　　　　素人の私には
　　　　　　ちと縁遠い😅

　ですが、
　　私にはChatGPTさんがいます。

　これまで
　　・動画から最後のフレームを取得
　　・動画同士の連結
　　・動画の逆再生の動画化
　とやってきました。

　分割だって、
　　できる！……よね？

　とりあえず、
　　尋ねたら、“できません”と
　　　言われてしまいました😅

　でもこれは
　　ChatGPT自体ができないだけの話。

　Code Interpreterを使えば、
　　できるできる。

　いろいろと
　　やってみて
　　　やり方がわかりました。

　動画をアップロードして
　　次のPromptを入力、
　　　送信すれば行なえます。
```Text:動画の分割Prompt
この動画をMoviePyを使って、1秒ごとに分割してください。
```

　これで、
　　1秒ごとにカットされた
　　　動画が作成され、
　　　　そのリンクが表示されます。
　　　　　あとはダウンロードだけ。

　このMoviePyというのは
　　Pythonのライブラリで、
　　　強力なビデオ編集ライブラリ
　　　　だそうです。

　ChatGPTさんに
　　教えてもらいました😸

　なお、
　　今回は
　　　1秒ごとに分割しましたが、
　　　　お好みの秒数を指定すれば
　　　　　ほどよい長さの動画を
　　　　　　作成できることでしょう。
　　　　　　　やってないけど😅

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
【AtCoder】中学生の自分が沼りながらも入緑しました！！！

## 記事の内容を単刀直入に

**入緑しました！**

それだけです。

## 今までの道のり

![rate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3740518/d36c7815-8129-dd38-49a2-64e1a6b63777.png)

自分は灰色コーダーのころは順調にレートを伸ばしていきました。

そこまではよかったのですが、茶色になったころ、さっそくつまづきました。

詳しくはこの記事に書いてあります。

https://qiita.com/while-true-if/items/7d6e5b98473c2a205ce3

そのころ様々なことを精進しました。そして、ついに努力が報われて、緑になれました。

## これからの目標

### 運ゲーをなくしたい

自分の武器は「速さ」です。簡単な問題は速く解くため、いつもは3完でもたいてい緑パフォをとっていました。しかし、C問題で難しい問題が出されると、たまに、2完ということもありました。これでは、パフォーマンスが600程度となってしまいます。つまり、**落茶もありえます**。さらに、自分は問題を自作するのが好きであるため、たまに類似する問題も出てきます。自分はABC357のD問題とほぼ同じ問題を作っていたため、D問題を速く解くことができました。それも入緑の要因だと思います。しかし、それはただ問題が当たったという運ゲーです。

### 緑Coderで停滞をしたくない

自分は茶Coderのとき、グラフを見て分かる通り、かなり停滞ぎみであることがわかります。

今のパフォーマンスはたいてい1100くらいであるため、緑Coderの上の方で停滞してしまいます。

そのため、**どんどん精進して、使える解放を増やしていきたい**と思います。そして**あと20回のコンテストで入水**しようと思います。

### AB問題を安定的に速く解く

自分の武器は「速さ」と言いましたが、逆にAB問題を速く解けないとかえって焦ってしまうので、より、AB問題を解く時間が遅くなってしまいます。たまに、AB問題合計で15分ということもありました。原因はA問題で5分をかけてしまい、B問題で焦ってスペルミスをしたことです。その時のコンテストでは運良くC問題を5分くらいで解けたので、レートはあまり冷えずにすみました。

目標はA問題を1分、B問題を2分以内に解くこと、つまり、AB問題を3分以内に解きたいです。

### 自分の身につけている解放と身につけたい解放

- 全探索
→これは基本の解放なので完璧だと思います。
- DP
→基本的なことは知っていまいますが、応用となるとできません。これは精進をして、身につけようと思います。
- DFS・BFS
→基本的な問題は解けますが、応用となるとできません。ちなみに、自分の苦手分野はグリッド関連の問題なので、精進をする優先順位は高いです。
- セグ木
→理論は知っていますが、あまり使いこなせません。
- 二分探索
→自分はPythonで書くことがほとんどなので、`bisect`というものに頼っていることが多いです。ただし、`bisect`ではかけない二分探索を使う問題を精進しようと思います。

## C++について

:::note warn
今から書くことは自分の意見です。
:::

最近は競プロerの知っている通り、ChatGPTの性能が大きく上がったので、Pythonを使っている人はもし`TLE`になったらChatGPTでC++に翻訳してもらえばいいと思います。しかし、気をつけてほしいのは情報オリンピックでは今のところChatGPTの使用が禁じられています。C++を覚えておくことは情報オリンピックで上位を目指す人にとっては重要でしょう。ただ、情報オリンピックをそんなに意識していない人は、Rustのほうが良いと思います。Rustはまだ若い言語なので、そのうち伸びると思います。さらに、C++と同程度の速さがあるうえ、構文がわかりやすいので、おすすめです。

RustやC++を使うなら自分のテンプレを作ることがおすすめです。

---
最後まで見てくれてありがとうございます。ぜひ、「いいね」と「フォロー」をお願いします。
きれいなコードを書くために意識していること

私がきれいで読みやすいコードを書くために、個人的に意識していることです。

### 1. 1つのメソッドを50行以内に収める

1画面で表示できる50行以内を目標にしています。

### 2. 同じ処理をメソッドにする

例え1行で書ける処理だとしても、同じ処理はメソッドにします。

1行なら全部書けばいいじゃん、と思いがちですが、ちりつもですし、万が一修正が発生した場合など、1か所を修正すればいいありがたさが分かります。

### 3. if文、for文の中身をメソッドにする

これについては、必ずではないですが。
1.の50行以内に収める、を達成するために、どこかしらの処理をメソッドにする場合、まずif文、for文の中身を別メソッドにすることを考えます。

### 4. 引数に副作用を与えるメソッドは避ける

これは過去にコードレビューで指摘されたことがあり。
Listを引数で渡してメソッド内でListに追加したり、インスタンスを引数で渡してメソッド内で値をセットするようなことは極力しないようにしています。
引数の値は参照するだけ！

基本的には、追加・セットする値単位にメソッドを用意して、返却されたものをセットする以下のような形にしています。
```java
ClassSample data = new ClassSample();
data.setHoge(getHoge(foo, bar));
```

もしくは、以下のようにList、インスタンスの作成単位をメソッドにしています。
```java
List<String> list = getList(hoge);
```

（どうしても、メソッド内で追加・セットしたい場合（同じ処理の場合など）は、セット専用のメソッドにしています。）

### 5. コメントを書く

特にメソッド呼び出しのところには必ずコメントを書きます。
何をしているメソッドなのか、書かないと中身を参照しないと分からなくなってしまうので。

あとは、if文、for文のところにも必ずコメントを書きます。
コードを読むより、コメントを読む方が早いと思われる場所には、コメントを書くようにしています。

### 6. その他

- 変数名･関数名をわかりやすくする
- プロジェクトのコーディング規約を読む

### さいごに

私がきれいで読みやすいコードを書くために意識していることに、難しいことはありません。
ですが、意識していないころより、見返したときに読みやすくなりました。

自分で読みやすくなったということは、たぶん他の人から見ても読みやすくなったかと思うので、今後もさらに精進してきれいで読みやすいコードを目指していきたいと思います！
AzureとAWSにおけるPrivate Linkの登場人物

Private Link はアプリケーションや PaaS サービスへのセキュアな接続を行うために必要不可欠な仕組みです。

Azure でも AWS でも使えますが、出てくる要素が異なるので整理してみました。

## PaaS に対する Private Link

### Azure の場合

下記のように接続します。

VNet の Subnet → Private Endpoint → Private Link → PaaS

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/896e14f5-e995-e40b-0b18-724a82c096db.png)

Private Endpoint が IP アドレスを提供し、Private Link により Private Endpoint と PaaS の間を繋ぎます。

Private Endpoint の IP アドレスの名前解決には、Private DNS Zone を使用します。
例えば NoSQL の Cosmos DB と接続する場合は、`privatelink.documents.azure.com` という感じで、頭に `privatelink` とついた Private DNS Zone を用意します。

https://learn.microsoft.com/ja-jp/azure/private-link/private-endpoint-overview

### AWS の場合

下記のように接続します。

VPC の Subnet → VPC Endpoint → PaaS
(VPC Endpoint はインターフェース型)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/aa4e27dd-d087-6512-5644-f104f180c1be.png)

IP アドレスの提供と PaaS への紐付けは VPC Endpoint が実施してくれます。
VPC Endpoint の設定でプライベート DNS を有効にしていれば、非表示の AWS 管理のプライベートホストゾーンが作成されて名前解決できます。

https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-access-aws-services.html

## アプリケーションに対する Private Link

### Azure の場合

下記のように接続します。

VNET の Subnet → Private Endpoint → Private Link Service → Azure Load Balancer → アプリケーション

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/5830f591-b2af-5f42-f1d3-071852e8830f.png)

Private Endpoint が IP アドレスを提供し、Private Link Service が Private Endpoint と Load Balancer の間を接続してくれます。
Load Balancer からアプリケーションへリクエストを流します。

https://learn.microsoft.com/ja-jp/azure/private-link/private-link-service-overview

### AWS の場合

下記のように接続します。

VPC の Subnet → VPC Endpoint → VPC Endpoint Service → Network Load Balancer → アプリケーション

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3769407/d1837cdc-83f4-bebe-93d5-cd1494031f6f.png)

VPC Endpoint が IP アドレスを提供し、VPC Endpoint Service が VPC Endpoint と Network Load Balancer の間を接続してくれます。
Network Load Balancer からアプリケーションへリクエストを流します。

https://docs.aws.amazon.com/vpc/latest/privatelink/privatelink-share-your-services.html