OmniAICreator/Qiita-1.07M huggingface dataset:
PHPのディレクティブとは

## そもそもディレクティブとは
コンパイル時にコンパイラーに与える補足情報

## phpのディレクティブとは
PHPの動作や挙動を制御するための設定項目

`php.ini` などの設定ファイルに記述され、PHP本体や拡張モジュールの動作パラメータを指定・調整ができる。
ディレクティブは、メモリ使用量やエラーレポートの挙動、拡張モジュールの有効化ができる。

動作のカスタマイズ: PHP環境全体や特定のスクリプト・ディレクトリ単位での挙動を変更することができる

## どのようなことができるのか

- 各種PHP設定値（`memory_limit`, `display_errors`, `include_path`など）の指定
- 拡張モジュールごとの設定変更
- サーバー設定（Apacheのphp_value/php_flagなど）を通じたディレクトリ単位や仮想ホスト単位での動作調整
- スクリプト内で ini_set() 関数を用いた動的な設定変更

## ディレクティブの設定場所と変更方法

最初に読み込まれるのは主設定ファイル `php.ini` で、PHP起動時に読み込まれてから、スキャンディレクトリ内の拡張設定ファイル（`.ini` ファイル）や各ディレクトリの `.user.ini` を読み込んで設定を上書き・追加できるようになる。

Apache設定ファイルや`.htaccess`Apacheモジュールとして動作する場合、`.htaccess` や `httpd.conf` を用いてPHP設定を変更可能。具体的には `php_value`, `php_flag`, `php_admin_value`, `php_admin_flag` などのディレクティブを使用。

## ディレクティブの種類と変更可能な範囲 
ディレクティブには、それぞれ設定可能な範囲やタイミングが定められていて、「``INIモード``」と呼ばれ、以下のように分類分けされる

- INI_USER: スクリプト内（ini_set()）やユーザー定義ファイル（.user.ini）で変更可能
- INI_PERDIR: php.ini、.htaccess、httpd.conf、.user.ini などで設定可能
- INI_SYSTEM: システム全体の設定ファイル（php.ini、httpd.conf）でのみ設定可能
- INI_ALL: どこからでも変更可能（スクリプト内も含む）

## 参考
https://www.php.net/manual/ja/configuration.php
https://www.php.net/manual/ja/configuration.file.php
https://www.php.net/manual/ja/configuration.file.per-user.php
https://www.php.net/manual/ja/configuration.changes.modes.php
https://www.php.net/manual/ja/configuration.changes.php
JSONとXMLの違い、特徴と比較

現代のデータ交換において、JSONやXMLは一番予想されるデータフォーマットです。この記事では、JSONとXMLの違いや、それぞれがなぜ「半構造化データ」と呼ばれるのかについて解説します。
※この記事は、ChatGPTの出力を基に作成しています。

---

### 半構造化データとは何か？

半構造化データとは、データを一定の構造で表する中でも、構造が完全に固定されず、柔軟な存在のことを指します。

- **構造化データ**: スキーマが定義されたデータ。例：リレーショナルデータベースの表。
- **半構造化データ**: 構造があるが固定ではない。例：JSONやXML。
- **非構造化データ**: 構造やルールがない。例：テキストデータや画像データ。

---

### JSONはなぜ半構造化データと呼ばれるのか

#### 1. 構造があるが固定されない
JSONは、キーと値のペアでデータを表現しますが、一緒に出現する項目や構造はデータによって異なることがあります。これが柔軟性を持たせ、「半構造化」と言われる理由です。

#### 2. スキーマレスの柔軟性
JSONは、データの構造を事前に定義しなくても利用できます。このため、データの追加や変更が容易です。

#### 3. 階層構造を持つ
JSONはオブジェクトや配列を利用して、階層的なデータ構造を表現しやすいのが特徴です。

#### 例
```json
{
  "name": "太郎",
  "age": 25,
  "hobbies": ["読書", "ランニング"]
}
```

---

### XMLはなぜ半構造化データと呼ばれるのか

#### 1. 構造があるが柔軟なタグ構造
XMLはタグを自由に定義できるため、データの構造を単純に許されます。しかし、構造化データのように一定のスキーマを要求しません。

#### 2. 非端なネストが可能
XMLは要素を入れ子にすることで、複雑な階層構造を表現できます。

#### 3. スキーマを利用した構造定義も可能
スキーマを使うことで、構造を定義してデータを正しく表現させることも可能です。

#### 例
```xml
<person>
  <name>太郎</name>
  <age>25</age>
  <hobbies>
    <hobby>読書</hobby>
    <hobby>ランニング</hobby>
  </hobbies>
</person>
```

---

### JSONとXMLの比較

| イメージ・解説              | JSON                                | XML                                |
|------------------------------------|-----------------------------------|-----------------------------------|
| 構造                         | キー・値ペアを基本として柔軟   | タグを基本として完全な構造も可能 |
| 文法の単純さ               | 簡潔で読みやすい             | タグが多いためやや出力量が大きい |
| データ型のサポート     | 数値、文字列、配列、オブジェクト、真偽値、null | すべて文字列として表現            |
| スキーマの必要性         | 一般的に不要                 | XML SchemaやDTDを利用可能 |
| 使用例                        | RESTful APIなど              | SOAPプロトコルや文書構造化 |

---

### まとめ
JSONもXMLも半構造化データとして、構造と柔軟性を共有しています。しかし、JSONは軽量で簡潔なデータ交換に優れ、XMLはスキーマを使ったデータ構造の規範化や文書構造化に適しています。用途に対して、これらを正しく使い分けることが大切です。
Creating an Automatically Resizing Textarea for User Input


# What We Want to Achieve

We want the text area where users input text, such as in a search box, to automatically resize itself when the amount of text exceeds the initial size.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/3e7c5e35-ea38-2d70-8e80-e8861620f740.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/683850ec-522b-54dc-6235-66fead0f3634.png)

# Code

※ Feel free to change the versions of Bootstrap and jQuery to your preference.

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hello Resizable Textarea</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">

<!-- jQuery 3.5.1 -->
<script src="https://code.jquery.com/jquery-3.5.1.js"
	integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
	crossorigin="anonymous"></script>

<!-- bootstrap 5 -->
<link
	href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
	rel="stylesheet"
	integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
	crossorigin="anonymous">

<!-- Bootstrap Icons -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">

<script type="text/javascript" class="init">
$(document).ready(function() {
    const textarea = document.querySelector('.input-group textarea');
    function autoResize() {
    	textarea.style.height = 'auto';
    	textarea.style.height = this.scrollHeight + 'px'; // Set to scroll height
    }
    textarea.addEventListener('input', autoResize); // Adjust size on input
    autoResize();
});
</script>

</head>

<body class="m-3">
    <div class="container mt-5">
        <div class="row">
            <div class="col">
                <div class="input-group mb-3">
                    <textarea class="form-control" placeholder="Search criteria" aria-label="Search" rows="1" ></textarea>
                    <button id="btn_search" type="submit" class="btn btn-primary"><i class="bi bi-search"></i></button>
                </div>
            </div>
        </div>
    </div>
</body>
</html>
```

Comment: It would be great if this becomes standard in HTML.

---
Bootstrap でテキストボックスのサイズが大きくなったときに自動でリサイズしたい（令和７年版）

# やりたいこと

検索などのテキストボックス（正確にはテキストエリア）に入力された文字列が長くなったときに、自動でサイズを変更したい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/3e7c5e35-ea38-2d70-8e80-e8861620f740.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110265/683850ec-522b-54dc-6235-66fead0f3634.png)

# コード

※ bootstrap, jQuery のバージョンはお好みのものに変更してください。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Hello Resizable Textarea</title>
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon">

<!-- jQuery 3.5.1 -->
<script src="https://code.jquery.com/jquery-3.5.1.js"
	integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
	crossorigin="anonymous"></script>

<!-- bootstrap 5 -->
<link
	href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"
	rel="stylesheet"
	integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC"
	crossorigin="anonymous">

<!-- Bootstrap Icons -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet">

<script type="text/javascript" class="init">
$(document).ready(function() {
    const textarea = document.querySelector('.input-group textarea');
    function autoResize() {
    	textarea.style.height = 'auto';
    	textarea.style.height = this.scrollHeight + 'px'; // スクロール高さに設定
    }
    textarea.addEventListener('input', autoResize); // 入力ごとにサイズ調整
    autoResize();
});
</script>

</head>

<body class="m-3">
    <div class="container mt-5">
        <div class="row">
            <div class="col">
                <div class="input-group mb-3">
                    <textarea class="form-control" placeholder="検索条件" aria-label="Search" rows="1" ></textarea>
                    <button id="btn_search" type="submit" class="btn btn-primary"><i class="bi bi-search"></i></button>
                </div>
            </div>
        </div>
    </div>
</body>
</html>
```

コメント：HTMLの標準規格になってくれるとうれしい

---

以上.
コミュニティユーザーがサイトでTodoを作成できるようにする

## ナビゲーションメニューでTodoメニューを表示するには「活動にアクセス」権限が必要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/fe3fbdc7-a19c-d5f3-b470-f31125126998.png)


## 新規Todo(Task)ボタンを表示するには「ToDo の編集」権限が必要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/7c6fa0ed-bf6a-f1d5-761f-24766d2968f2.png)

## 「行動の編集」権限もある、これはカレンダーで編集権限かも
印刷プレビューの注意点

# 印刷プレビューの表示の仕方について
印刷時の表示しない範囲は以下のように設定しなければ基本、ページ全体が表示されます。

```
<style>
@media print {
  .クラス名 {
    display: none;
  }
}

</style>
```

最近、Vueのページにトーストのメッセージを実装したところ
1度も使用しなければ問題ないのだが、1度でも使用するとトーストを使用して非表示になった後にも以下のタグがページの下に残ってしまう

これが原因になって空白の1ページがプレビューに追加されるバグが発生してしまう可能性があります。

[トーストの作成方法のURL](https://qiita.com/studyhiminato1107/items/a6d8a005a080d91cf395 "トーストの作成方法のURL")

```
<div class="v-toast v-toast--top"></div>
<div class="v-toast v-toast--bottom"></div>
```

# トーストを印刷プレビューから排除する
Vue.jsのトーストを印刷プレビューから排除するスタイル
```
<style>
@media print {
  .v-toast {
    display: none !important;
  }
}

</style>
```

上記のスタイルを指定しておくとトーストを印刷プレビューから排除できました
【Anthropic】Model Context Protocolを知る

## 概要
### 「Model Context Protocol」とは
コンテンツ リポジトリ、ビジネス ツール、開発環境など、データが存在するシステムに AIアシスタントを接続するための新しい標準規格

https://www.anthropic.com/news/model-context-protocol


### AIアシスタントの課題
- 優秀なAIモデルでさえ、情報サイロとレガシーシステムに閉じ込められたデータへのアクセスができない
- AIモデルごとにデータ形式や接続方法などの調整が必要となる

### MCPによる解決
AIシステムとデータソースを接続するための共通の規格を提供し、独自の規格を単一のプロトコルに置き換えます。

## Model Context Protocol

### アーキテクチャ

- **MCPホスト**: Claude Desktop、IDE、または MCP を介してデータにアクセスする AI ツールなどのプログラム
- **MCPクライアント**: サーバーとの 1:1 接続を維持するプロトコル クライアント
- **MCPサーバー**: 標準化されたモデル コンテキスト プロトコルを通じて特定の機能を公開する軽量プログラム
- **ローカルデータソース**: MCP サーバーが安全にアクセスできるコンピューターのファイル、データベース、サービス
- **リモートサービス**: MCP サーバーが接続できるインターネット経由 (API 経由など) で利用可能な外部システム

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654759/14276926-78fd-2941-c4af-1c0f8fbe993e.png)


## Getting Start 〜Claudeデスクトップユーザ向け for Mac〜 

https://modelcontextprotocol.io/quickstart/user

#### [1] デスクトップ版Claudeをダウンロード

https://claude.ai/download

#### [2] 設定の編集

「Claude」→「Settings」→「Developer」→「Edit Config」の順で押していくと設定ファイルが作成される
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654759/f75223a6-b9f1-90d9-c64a-3e6fb08efe06.png)

> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654759/9f9e3f3c-dd5e-3c23-e285-89eb87ef6e3d.png)

設定ファイルの内容を以下に書き換える
※usernameは自分のコンピュータのユーザ名に置き換える
```
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/Desktop",
        "/Users/username/Downloads"
      ]
    }
  }
}

```

#### [3] Node.jsがインストールされているか確認する or インストールする、

Node.js がインストールされているか確認
```
node --version
```

されていなければインストール（以下を参考）

https://qiita.com/ffggss/items/94f1c4c5d311db2ec71a

#### [4] Claude Desktopを再起動

再起動後に、入力ボックスの右下にハンマーアイコンが表示される
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654759/92a5af05-5913-8715-88c0-4ce9945a8f01.png)


#### [5] 試してみる

できた！すごい！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654759/5ccd6ff9-6c6f-27ff-178d-2ed0ba4048e2.png)

## 次回
次は、「サーバー開発者向け」と「クライアント開発者向け」のGetting Startをやっていきたい

https://modelcontextprotocol.io/quickstart/server

https://modelcontextprotocol.io/quickstart/client
y = 1.5 x に従う人工データの作り方

# 目標
次のような散布図を人工データを用いて作成する
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957867/18163caf-de0c-a103-1174-24972e2447b1.png)

# 実行環境
Google Colaboratory

#パッケージのインストール
```python:sample.py
!pip install mplcyberpunk
!pip install watermark
```
```python:sample.py
import mplcyberpunk
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import warnings
warnings.simplefilter('ignore')#プログラム実行中の警告をすべて無視するための設定
```

# 実行コード
```python:sample.py
x = np.array([3, 0])
y = np.array([0, 3])

# 各ベクトルを並べて行列を作成
V = np.array([x, y])
# 各ベクトルの原点を行列で指定
origin = np.array([[0, 0],[0, 0]])
plt.style.use("cyberpunk") #グラフのスタイルの設定

rng = np.random.RandomState(3) #乱数生成のルール設定（これは標準正規分布）
sample = rng.randn(500, 2) #2次元のサンプルを500個生成する
sample[:, 1] += 0.5 * sample[:, 0] #生成した乱数のx成分にy成分を足す（0列目の数値を0.5倍したものを1列目に足す）
colors = sample[:, 0] #x成分の大きさに応じて色が変化する

 #グラフのサイズの設定
plt.rcParams["figure.figsize"] = (5,5)
#グラフのスタイルの設定
plt.scatter(sample[:, 0], sample[:, 1], c=colors, s=10) 

#散布図の各点が光るように設定
mplcyberpunk.make_scatter_glow() 

#矢印を描く関数
plt.quiver(origin[0,:], origin[1,:], V[:,0], V[:,1], angles='xy', scale_units='xy',color=['cyan','magenta'], scale=1) 

plt.plot(0, 0, 'ok') #原点が黒丸で表示されるようにして散布図を描画
plt.grid(visible=True, which='major') #グリッドを表示してxとyの範囲を設定
plt.xlim(-4, 4)
plt.ylim(-4, 4)
```
このコードではプロット上にx軸・y軸を描くためにベクトルを利用しています。最初の４行がそれに対応しています。

# 結果
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957867/86e6ef09-a677-712b-7669-7831052bffac.png)


今回は、単に散布図の描画方法だけでなく、視覚化する際のアレンジも紹介しました。サイバーパンク風にするだけでも面白いので様々な描画に使ってみてください！
circuitjsの作法 その53

# 概要
circuitjsを調査してみた。
練習問題やってみた。

# 練習問題
elixirで論理回路アセンブラをコンパイルして、ネットリストを高位合成せよ。
半加算器を書け。

# 投入したソース

```
make 4
in 0 1
out 2 3
and 0 1 2
xor 0 1 3
```

# 生成したネットリスト

```
$ 1 0.000005 10.20027730826997 50 5 50 5e-11
L 128 160 80 160 2 0 false 5 0
L 128 224 80 224 2 0 false 5 0
w 128 224 160 224 0
w 160 224 160 128 0
w 160 128 224 128 0
w 160 224 224 224 0
w 128 160 192 160 0
w 192 160 192 256 0
w 192 256 224 256 0
w 192 160 224 160 0
M 368 144 416 144 2 2.5
M 368 240 416 240 2 2.5
150 224 144 368 144 0 2 0 5
154 224 240 368 240 0 2 0 5
```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/0e39afe0-ad60-55ca-0c01-a7f61a1493fc.png)


成果物

https://paiza.io/projects/3-Iiq8xZl_vaR7vlx8EwmQ?language=elixir


# サンプルコード

```

defmodule Asm do
	def start_link do
		Agent.start_link(fn ->
			%{in0: "", in1: "", make0: "", u: ""}
		end, name: __MODULE__)
	end
    def make0(a) do
	end
    def in0(a, b) do
    end
    def out0(a, b) do
    end
    def and0(a, b, c) do
		Agent.update(__MODULE__, fn v ->
            str = "150 224 144 368 144 0 2 0 5\n"
            %{v | u: v.u <> str}
		end)
    end
    def xor0(a, b, c) do
		Agent.update(__MODULE__, fn v ->
            str = "154 224 240 368 240 0 2 0 5\n"
            %{v | u: v.u <> str}
		end)
    end
    def or0(a, b, c) do
		Agent.update(__MODULE__, fn v ->
            str = "152 224 144 368 144 0 2 0 5"
            %{v | u: v.u <> str}
		end)
    end
    def print() do
		Agent.get(__MODULE__, fn v ->
            IO.puts "$ 1 0.000005 10.20027730826997 50 5 50 5e-11"
            IO.puts "L 128 160 80 160 2 0 false 5 0"
            IO.puts "L 128 224 80 224 2 0 false 5 0"
            IO.puts "w 128 224 160 224 0"
            IO.puts "w 160 224 160 128 0"
            IO.puts "w 160 128 224 128 0"
            IO.puts "w 160 224 224 224 0"
            IO.puts "w 128 160 192 160 0"
            IO.puts "w 192 160 192 256 0"
            IO.puts "w 192 256 224 256 0"
            IO.puts "w 192 160 224 160 0"
            IO.puts "M 368 144 416 144 2 2.5"
            IO.puts "M 368 240 416 240 2 2.5"
            IO.puts v.u
		end)
	end
end

defmodule Main do
	def run(str) do
    	Enum.map(String.split(str, "\n"), fn l ->
		    #IO.puts l
		    s = String.split(l, " ")
		    #IO.puts Enum.at(s, 0)
		    cond do
			Enum.at(s, 0) == "make" ->
				Asm.make0(Enum.at(s, 1))
			Enum.at(s, 0) == "in" ->
				Asm.in0(Enum.at(s, 1), Enum.at(s, 2))
			Enum.at(s, 0) == "out" ->
				Asm.out0(Enum.at(s, 1), Enum.at(s, 2))
			Enum.at(s, 0) == "and" ->
				Asm.and0(Enum.at(s, 1), Enum.at(s, 2), Enum.at(s, 3))
			Enum.at(s, 0) == "nand" ->
				Asm.nand0(Enum.at(s, 1), Enum.at(s, 2), Enum.at(s, 3))
			Enum.at(s, 0) == "nor" ->
				Asm.nor0(Enum.at(s, 1), Enum.at(s, 2), Enum.at(s, 3))
			Enum.at(s, 0) == "xor" ->
				Asm.xor0(Enum.at(s, 1), Enum.at(s, 2), Enum.at(s, 3))
			Enum.at(s, 0) == "or" ->
				Asm.or0(Enum.at(s, 1), Enum.at(s, 2), Enum.at(s, 3))
			true ->
				IO.puts ""
			end
	    end)
	    Asm.print
	end
end

Asm.start_link

Main.run("""
make 4
in 0 1
out 2 3
and 0 1 2
xor 0 1 3
""")



```


以上。
FlutterでJavaScriptのモデルを定義してdartからメソッドを呼ぶ

## パッケージのインストール
- jsパッケージ
- freezedパッケージとその関連パッケージ

https://pub.dev/packages/js

https://pub.dev/packages/freezed

https://pub.dev/packages/freezed_annotation

https://pub.dev/packages/build_runner

```pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  js:
  freezed_annotation: 
  json_annotation: 

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner:
  freezed: 
  json_serializable: 
  
```
## 今回使用するクラス
- StorageManger

https://developer.mozilla.org/ja/docs/Web/API/StorageManager
## やりたいこと
dart側から`fetchStorageEstimate()`を呼ぶとjsの`navigator.storage.estimate()`を呼ぶ形にしたい

### Storage Manager用のWrapperを作成
```dart
import 'dart:js_util';
import 'package:js/js.dart';

@JS('navigator.storage')
external StorageManager get storageManager;

@JS()
@anonymous
class StorageManager {
  // jsのメソッドを呼ぶ
  external dynamic estimate();
}

@JS()
@anonymous
class StorageEstimate {
  external num get quota;
  external num get usage;

  external factory StorageEstimate({
    num quota,
    num usage,
  });

  factory StorageEstimate.fromJsObject(Object jsObject) {
    return StorageEstimate(
      quota: getProperty(jsObject, 'quota'),
      usage: getProperty(jsObject, 'usage'),
    );
  }
}

Future<StorageEstimate> fetchStorageEstimate() async {
  final jsEstimate = await promiseToFuture(storageManager.estimate());

  return StorageEstimate.fromJsObject(jsEstimate);
}
```
### StorageEstimateクラスをfreezedを使用してimmutableにする

```dart
import 'dart:js_util';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:js/js.dart';

part 'storage_estimate.freezed.dart';


@JS('navigator.storage')
external StorageManager get storageManager;

@JS()
@anonymous
class StorageManager {
  external dynamic estimate();
}

@freezed
class StorageEstimate with _$StorageEstimate {
  const factory StorageEstimate({
    required num quota,
    required num usage,
  }) = _StorageEstimate;

  factory StorageEstimate.fromJsObject(Object jsObject) {
    return StorageEstimate(
      quota: getProperty(jsObject, 'quota') as num,
      usage: getProperty(jsObject, 'usage') as num,
    );
  }
}

Future<StorageEstimate> fetchStorageEstimate() async {
  // promiseToFutureメソッドでdartのFutureに変換する
  final jsEstimate = await promiseToFuture(storageManager.estimate());
  // Dartで定義した型にして返す
  return StorageEstimate.fromJsObject(jsEstimate);
}
```

### 使用
```dart
  final estimate = await fetchStorageEstimate();
  print('${estimate.quota}');
  print('${estimate.usage}');
```

## 参考
https://zenn.dev/heyhey1028/articles/abd818ca760e33
初めてWebページを公開するならGithubPages

どうもAtsu1209です。
今回は「初めてWebページを公開するならGithubPages」という話をします。

# なんでGithubPages
初めてWebページを公開するときは大体の方は静的サイトだと思います。
PHPなどをしする人は少ないでしょう。
そのため、ファイルをアップロード&デプロイという簡単な方法で公開できる
GithubPagesがおすすめだと私は考えます。

# GithubPagesやりかた

https://prog-8.com/docs/github-pages

私が最初に公開したときに参考にしたやつを乗せておきます。

# 最後に
あくまで私(中学生)の考えなのであまり深くは考えないようにしてください。

**お わ り**
クエリパラメータについて

# はじめに
railsで実装しているときに、検索機能を作成していたのですが、そこで躓いたので備忘録として記録しておきます。
そもそも、`params`についての理解が浅いのでこちらも同時に理解していきたいと思います。

# 手順
#### １ 現状把握
![スクリーンショット 2025-01-18 9.32.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3952789/4584f233-e090-3e6b-c4c1-3da9df7b19c8.png)
このようにURLに`?category=腹筋`などが追記されている状態。
+ なぜこれができるのか
+ これで何ができるのか etc...

上記のことを記録していきます。

#### ２ クエリパラメータとは
`?category=腹筋`の部分をクエリパラメータと呼びます。そして、これらはURLの最後に追記される`キー`と`値`の組み合わせのことです。上記の例では`categoryがキー`で`腹筋が値`です。

#### ３ クエリパラメータの作成方法
今回私は`link_to`で作成したので、こちらを確認してください。
```php:index.html.erb
<div class="categories">
  <% @categories.each do |category| %>
    <%= link_to videos_path(category: category.name) do %>
      <div><%= image_tag category.image_path %></div>
    <% end %>
  <% end %>
</div>
```
`@categories`には腹筋や背筋などの筋トレ部位のデータを初期データとして入れております。それをeachで要素を１つずつ以下の処理に入れています。今回はクエリパラメータの備忘録なので、以下のコードの部分が大切になります。
```php
<%= link_to videos_path(category: category.name) do %>
```
link_toでパスを指定した後にカッコ内にキーと値を入れます。ここでのキーは何でも良いのですが、誰が見ても分かるようにする方が良いです。これにより、クエリパラメータが作成されます。

#### ３ 何ができるのか
まずは先ほどのビューで作成したデータをコントローラーで受け取る方法です。`params[:category]`このように記述することで、`category`というキーの値を取得してくれます。ここで理解できたのですが、クエリパラメータにおける`params`はユーザーがリクエストした内容（今回では`category=腹筋`）を保持してくれる役割でした。

それらをうまく活用することで、検索機能なども作成することができます。
以下に検索機能の参考例を記載しておきます。
```php:index.html.erb
<%= form_with url: videos_path, method: :get, local: true do |f| %>
  <%= f.text_field :query, placeholder: '検索キーワードを入力' %>
  <%= f.submit '検索' %>
<% end %>
```
```php:controller.rb
if params[:query].present?
```
上記のように検索フォームに入力した内容が`query`というキーに値として保持され、それを活用してコントローラーで、もしparamsにデータがあればという形にしています。`if文`以降はそれぞれが必要な記述を記載してください。

# おわりに
少しずつ理解できてきていますが、まだまだわからないことだらけです。こつこつと諦めずに勉強していき、将来の自分に自己投資をしていきたいと思います。
シェルスクリプトでの数値比較

# はじめに

シェルスクリプトでの数値による条件分岐を調べてみました。
変数に数値を入れて、if 条件分の中は[]を使います。

# 数値による条件分岐

記載すると以下のようになります。
```
#!/bin/bash

a="残留"
b="降格"

zyuni=16

if [ $zyuni -lt 17 ]; then
	echo $a
else
	echo $b
fi
```

-ltを使用しているので、17より数値が大きければ降格、17未満なら残留と表示されます。
今回はzyuniが16で17より小さいです。
なお、[]の最初と最後はスペースを入れないとエラーが出るので注意です。
zyuniという変数には数値を入れます。
条件分の中では変数の前に「$」をつけます。つけないと中身が参照されません。


実行結果は以下の通りになります。

```
残留
```
Dockerコマンドメモ

# 内容

Dockerコマンドの例を記載しています。

# container コマンド

## コンテナの作成・実行
```
docker container run --name apache01 -p 8080:80 -d httpd
```

## コンテナの停止
```
docker container stop apache01
```

## コンテナの削除
```
docker container rm apache01
```

## 実行中のコンテナを表示
```
docker container ls
```

## 全コンテナの表示
```
docker container ls -a
```

# compose コマンド

## コンテナの作成・実行
```
docker compose up -d
```

## コンテナを停止
```
docker compose stop
```

## 既存コンテナの起動
```
docker compose start
```

## プロジェクトの表示
```
docker compose ls
```

## コンテナからマシンへコピー
```
docker compose cp web:/usr/local/apache2/htdocs/index.html .
```

## マシンからコンテナへコピー
```
docker compose cp index.html web:/usr/local/apache2/htdocs/index.html
```

## コンテナの削除
```
docker compose down
```

## イメージの削除
```
docker compose down --rmi all
```

## 実行中コンテナでコマンドを実行
```
docker compose exec db mariadb --version
```

## 停止中コンテナでコマンドを実行
```
docker compose run db mariadb --version
```

## コンテナのシェルを起動
```
docker compose exec db /bin/bash
```

## ログ確認
```
docker compose logs web
```

## イメージのビルド
```
docker compose build
```

## イメージのビルド(キャッシュ無し)
```
docker compose build -no-cache
```

## ビルド・コンテナ実行
```
docker compose up -d --build
```

# image コマンド

## イメージの表示
```
docker image ls
```

# network コマンド

## ネットワーク確認
```
docker network ls
```
個人的な備忘録：『.gitignore』が全くわからなかったので、理解を深めるために記事としてアウトプットしてみた

## はじめに
今回は、あまり使ったことがなく、自分でもよく理解していない `.gitignore` について、少し背伸びしながらアウトプットしてみました。

:::note info
**`.gitignore` は、Gitでバージョン管理を行う際に、追跡対象から除外するファイルやディレクトリを指定するための設定ファイルです。**
:::

この記事は、ほぼ自分の備忘録として整理した内容です。***その点はあらかじめご了承ください。***

## 書こうと思ったきっかけ
`.gitignore` ファイルについてはその存在を認識していたものの、具体的に何をしているのか、どのような役割があるのかはよく分かりませんでした。

しかし、実際に使用している場面を見ると、「**こんなことができるんだ**」「**こういう使い方をするんだ**」と驚くことが多くありました。そのため、今回記事としてまとめてみることにしました。

この先、自分がどれだけ使いこなせるようになるかは分かりませんが、とりあえずアウトプットすることで、知識を整理し、自分の学びを深めていきたいと思います。

## そもそも、`.gitignore`とは？

`.gitignore` は、Gitでバージョン管理を行う際に 追跡対象から除外するファイルやディレクトリを指定するための設定ファイル です。

**基本的な使用例**

以下のように `.gitignore` ファイルに除外したいパターンを記述することで、特定のファイルやフォルダを管理対象から除外できます。

```.gitignore
node_modules/
```

このファイルに記述されたパターンに一致するファイルやフォルダは、Gitのインデックス（ステージングエリア）に追加されず、リポジトリにコミットされることがありません。

## 主な用途

### 機密情報の保護
APIキーやパスワードが記載された設定ファイルをリポジトリに含めないようにします。  
**例**: `.env`

---

### 無駄なファイルを除外
一時ファイルやキャッシュファイル、OSが自動生成する不要なファイルを除外します。  
**例**: `*.log`, `*.tmp`

---

### プラットフォーム依存のファイルの除外
開発環境ごとに生成されるファイルやIDE関連の設定ファイルを管理対象から外します。  
**例**: `.DS_Store` (macOS), `Thumbs.db` (Windows)

---

### ビルドや生成物の除外
ソースコードから生成されるバイナリや中間ファイルなど、バージョン管理の必要がないものを除外します。  
**例**: `dist/`, `node_modules/`

## `.gitignore` の基本的な使い方

**`.gitignore` ファイルを作成**

リポジトリのルートディレクトリに `.gitignore` ファイルを作成します。

**除外したいパターンを記述**

`.gitignore` に以下のようなルールを記述します。

```.gitignore
# 一時ファイルを除外
*.tmp
*.log

# ディレクトリを除外
node_modules/

# 環境依存ファイルを除外
.DS_Store
Thumbs.db

# 特定ファイルを除外
secret_config.json
```

**すでに追跡されているファイルの除外**

`.gitignore` を設定する前に追跡されているファイルはそのまま管理対象となります。

追跡を解除するには以下のコマンドを使用します。

```.gitignore
git rm --cached ファイル名
```

**使用する流れ**

`.gitignore` を設定した後、Gitのステージングエリアに追加してコミットします。

```bash
git add .gitignore
git commit -m "Add .gitignore"
```

以降、`.gitignore` に記述されたファイルやフォルダは追跡対象から除外されます。

### `.gitignore` の利便性

`.gitignore` は、リポジトリ内に不要なファイルを含めないための便利なツールです。正しく設定することで、プロジェクトを効率的かつ安全に管理することができます。

## まとめ
ここまでお読みいただき、ありがとうございました。
今回の内容は、私自身が `.gitignore` の使い方を学びながらアウトプットした備忘録です。

:::note info 
***わからないことを積極的にアウトプットすることで、自分の知識として管理しやすくなると改めて感じました。***
:::

内容に不備がある可能性もございますが、その点はご容赦ください。

## おまけ: README.md の重要性
今回のおまけでは、リポジトリに `README.md` を作成することの大切さを改めて実感したことを共有します。

以前の私は、`README.md` を適当に記述することが多く、使いこなせている自信がありませんでした。

:::note warn
**しかし、リポジトリに詳しい使い方の手順や注意点をまとめることで、チーム開発において非常に重要な役割を果たすと感じました。**
:::

***これからは、こうした細かい部分にも力を入れ、プロジェクトの利便性やわかりやすさを向上させていきたいと思います。***
互いに素な数をつないだ整数ネットワーク

## はじめに
ノードを整数、リンクを互いに素な組、としてネットワークをかいたら面白いことになるんじゃないか！と、ふと思ってやってみました。
差が1の数の組は互いに素なので、ネットワークは必ず連結になります。せっかくなので差が1のリンクは目立たせてみました。タンパク質のフォールディングみたいに鎖がどんな形になるのか見てたら楽しそう。

## 互いに素な整数ネットワーク
以下のコードでネットワークを描画できます。pythonでかきました。
<details open><summary>コード</summary>

```python
import networkx as nx
import matplotlib.pyplot as plt
import math

# 互いに素かどうかを判定する関数
def are_coprime(a, b):
    return math.gcd(a, b) == 1

# ノードの範囲（例2〜9の整数）
nodes = range(2, 10)

# グラフの作成
G = nx.Graph()

# ノードをグラフに追加
G.add_nodes_from(nodes)

# ノード間にエッジを追加（互いに素なペア）
edges = []
highlight_edges = []  # 連続する数のエッジを保存するリスト
for i in nodes:
    for j in nodes:
        if i < j:
            if are_coprime(i, j):
                edges.append((i, j))
            # 連続する数を特定
            if j == i + 1:
                highlight_edges.append((i, j))

# グラフにエッジを追加
G.add_edges_from(edges)

# 配置方法の指定
pos_grid = nx.kamada_kawai_layout(G)
plt.figure(figsize=(8, 6))

# 通常のエッジを描画
nx.draw_networkx_edges(G, pos=pos_grid, edgelist=edges, edge_color='gray', alpha=0.5)

# 連続する数のエッジを目立たせる（太さと色を変更）
nx.draw_networkx_edges(G, pos=pos_grid, edgelist=highlight_edges, edge_color='red', width=2)

# ノードを描画
nx.draw_networkx_nodes(G, pos=pos_grid, node_size=700, node_color='skyblue')

# ラベルを描画
nx.draw_networkx_labels(G, pos=pos_grid, font_size=12, font_weight='bold')

# 出力
plt.show()


```

</details>


実際のネットワークは以下です。

<details open><summary>ノード：２～９</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900848/4306d569-48cb-de06-e180-f6eb8925c4fc.png)

</details>

<details open><summary>ノード：10～19</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900848/3542c9af-734b-2150-7b8a-8a0ee8ae76c1.png)

</details>

<details open><summary>ノード：20～29</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900848/461b8b4b-5e3f-bf0f-0314-488e2e48a26d.png)

</details>

<details open><summary>ノード：30～49</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900848/c1140bdb-6f80-0879-5a42-707fc610c275.png)

</details>

<details open><summary>ノード：2～49</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900848/821d3fe3-a830-846f-ed62-a40f1dcda040.png)

</details>

## おわりに
うーん。なんだかよくわからないですね！私が気づいてないだけで、面白い性質はたくさんあるのかしら？
ノード2~49の図でいくつかのかたまりができていますが、何か意味があるんだろうか...？。中央には大きめな素数が固まっています。
素数がリンクを持ちやすいので、素数を外してみても面白いのかも。あと、逆に共通因数を持つものにリンクをはるとか。ノードのポジションの決め方もいろいろかえてみるとまた発見があるかもしれません。距離とかクラスター係数とかのネットワーク特徴量を見てもいいのかしら。
もしここから何かおもしろいことをひらめいた人は好きに研究してください！では！
Youtube がやめられない？だったらこうしよう。

# はじめに
**Youtubeは最高です。**

でも、怠ける理由には少し弱いのです。

でも、面白いのです。

でも、妻も怖いのです。

でも、私はプログラミングが出来るんだぜ？

# コーディング
解説は、コメントで行います。
```javascript:Code
/**
 * メイン関数 - YouTube購読チャンネルの新規動画をチェックしてメール通知する
 */
function main()
{
    // YouTubeの購読チャンネル一覧を取得（最大50件）
    const registered_channels = YouTube.Subscriptions.list('snippet', {
        mine: true,
        maxResults: 50
    });

    var message = "";
    // 各チャンネルの新規動画情報を取得してメッセージを作成
    registered_channels.items.forEach((channel) => {
        message += getNewVideo(channel.snippet.resourceId.channelId);
    });

    // 新規動画の有無に応じてメッセージを設定
    if (message === "") {
        message = "今日のyoutubeの新しい投稿はない!\n明日に期待して生きろ!\n\n"
    } else {
        message = "今日のyoutubeの新しい投稿はこんな感じだよ!\n今日も頑張って生きよ～♪\n\n\n" + message;
    }

    // メール送信を実行
    sendEmail(message);
}

/**
 * 指定されたチャンネルの新規動画情報を取得する関数
 * @param {string} channel_id - チャンネルID
 * @return {string} 新規動画の情報を含むメッセージ
 */
function getNewVideo(channel_id)
{
    const yesterday = new Date();
    yesterday.setHours(yesterday.getHours() - 24);
    
    // 指定チャンネルの動画を検索（今日投稿されたもののみ）
    const response = YouTube.Search.list('snippet', {
        channelId: channel_id,
        order: 'date',
        type: 'video',
        publishedAfter: yesterday.toISOString()
    });

    var message = "";
    // 新規動画がある場合、各動画の情報をメッセージに追加
    if (response.items.length > 0) {
        message += response.items[0].snippet.channelTitle + "の動画：\n\n";
        response.items.forEach((item) => {
            message += "Title : " + item.snippet.title + "\n" + 
                      "Description : " + item.snippet.description + "\n" + 
                      "Link : " + "https://youtube.com/watch?v=" + item.id.videoId + "\n\n";
        });
        message += "\n";
    } else {
        message = "";
    }
    return message;
}

/**
 * メール送信を行う関数
 * @param {string} message - 送信するメッセージ本文
 */
 const MAIL = [Your e-mail address];  // string でメールアドレスを
function sendEmail(message)
{
    // 指定されたメールアドレスに新規動画情報を送信
    MailApp.sendEmail(
        MAIL,
        "今日投稿された動画",
        message
    );
}
````
# 終末に
:::note info
「終わりに」より「終末に」のほうがかっこいいのです。
:::
最終的に、以下のようなメール文をいただけます：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674822/84c8754d-fde8-9dc3-d61e-f668ec0fac6b.png)

作成したGASプロジェクトに「トリガ」を指定するすことで、指定時刻にメールをいただけるようになります。

では、また。

<details><summary></summary>

:::note info
去り際の言葉は、シンプルな方がかっこいいのです。
:::

</details>
初めてOSSにプルリクエストしてみた

# はじめに
私は2年目のエンジニアです。チーム開発はしていますが、Gitをうまく活用できている自信はないです。また、私はOSSの開発に興味があったので、Gitの勉強も兼ねて、Pull requestを送ってみようと思いました。

# プロジェクトの選定
プロジェクトの選定は以下記事を参考にしました。
[OSS未経験「なにから始めたらいいかわからない…」←これを一気に解決する神リポジトリ](https://qiita.com/Naughty1029/items/cf8750f375fa99bce9bb)

参考にというよりは、完全に真似させていただき、以下リポジトリを選択しました。

[awesome-resources](https://github.com/shahednasser/awesome-resources)

# プルリクエストまでの流れ
具体的には以下の流れでプルリクエストまでを行いました。

* 上記リポジトリをfork
* ローカルにクローン
* ブランチの作成
* ローカルのワークツリーを変更
* ステージに追加、コミット、push
* プルリクエストの作成
→[Added technical writing(#588) #772](https://github.com/shahednasser/awesome-resources/pull/772)

最終のコミットの履歴が2023年とかだったので、おそらく変更がマージされることはないと思いますが、勉強にはなったと感じています。

以上。
【敗北】mvコマンドは移動先が存在しないとリネームになるぞ

## はじめに
先日CIジョブを書いており、mvコマンドを使う機会がありました。
mv == move やろ？？　ファイル・フォルダの移動やろ？？という理解だけで挑み、一瞬ハマりかけたので、反省文を残します。

## mvは、移動**またはリネーム**を行うコマンド
manを見てみます。
```
$　man mv
>>>
(略)
DESCRIPTION
     In its first form, the mv utility renames the file named by the source operand to the destination path named by the target operand.  This form is
     assumed when the last operand does not name an already existing directory.

     In its second form, mv moves each file named by a source operand to a destination file in the existing directory named by the directory operand.
     The destination path for each operand is the pathname produced by the concatenation of the last operand, a slash, and the final pathname component
     of the named file.

(略)
```
なんとなく訳します。
> 1つ目の挙動としては、mvユーティリティはsourceオペランドで指定されたfileをtargetオペランドで指定されたpathにリネームします。この挙動は最後のオペランド（targetオペランド）が存在しないときに実行されます。
２つ目の挙動としては、mvはsourceオペランドで指定された各ファイルを、directoryオペランドで指定された、存在するディレクトリへと移動します。各オペランドの移動先パスについては、`directoryオペランド/元のファイル（フォルダ)名`となります。

ちゃんと書いてありました。
つまり、「移動先のパスが存在しないとき、mvコマンドはリネームをするぞ」ということになります。

## 試してみる1

こんなディレクトリを用意しました。
```
.
├── baz
│   └── hoge.txt
└── foo
    └── bar
```

```zsh
$ mv baz/hoge.txt foo/bar
```
とすると、、、
```
.
├── baz
└── foo
    └── bar
        └── hoge.txt
```

これはいいですよね。

## 試してみる2
次が問題です。
```
.
├── baz
│   └── hoge.txt
└── foo
    └── bar
```
このディレクトリ構造に対して、
```
$ mv baz/hoge.txt foo/banana
```
を実行するとどうなるでしょう。
先ほどの説明に照らし合わせると、`foo/banana`というフォルダは存在しないので、リネームの挙動になります。
つまり、「`baz/hoge.txt`というファイルを`foo/banana`というファイルにリネームする」挙動になるので、こうなります。
```
.
├── baz
└── foo
    ├── banana
    └── bar
```
初見だと何が起こってるのかわかりませんが、先ほどの説明を読んだ後だと納得できますね。






最後まで読んでいただきありがとうございました。
弱小プログラマー、個人開発1年勝負：初挑戦で気づいた現実と課題

# 初動

今回は、私が個人開発の第一歩としてどのように進めたかを反省の意味を込めて、振り返ってみたいとおもいます。

## 技術スタックの選定
個人開発のアイデアを思い立ったとき、まず頭に浮かんだのは「Webアプリ」か「ネイティブアプリ」のどちらかを作るという選択肢でした。

これまでの経験から、Webアプリのほうが取り組みやすいと感じ、いったんそちらを選択。
加えて、初めての個人開発では、とにかくインフラやドメイン関連などわからないことが多く、とりあえず完了させることを目的に選定。

ざっくり以下のような構成で実装を開始。
- インフラ: Firebase Hosting（最初はまともにwebサーバを立てようとしていましたが、簡単にデプロイできるので選択）
- フロントエンド: Angular（以前少し触れたことがあり、慣れているため）
- バックエンド: 当初は検討していましたが、スピード重視で一旦なしに。

とにかく早く形にすることを優先し、最低限の構成でスタートしました。

## 初めてのアイデア

育児中という自分の環境を活かせないかと考え、「育児グッズ系のWebサイトでアフィリエイト収益を得る」というアイデアを思いつきました。というよりそれ以外思いつかなったです。（笑）

## 実際に進めてみて分かったこと

アイデアを実現するために進めていく中で、いくつかの壁に直面しました。

### アフィリエイト審査
そもそも審査を通過するには、まずサイトのアクセス数を増やす必要があることが判明。

### アクセス数を集めることの難しさ
なんとなくやれば少しは集まるだろうなんてどこかで思っていたと思いますが、本当にまったくアクセスをとれないこと。

### 時間の無駄遣い

データを集めるロジックなど、必要以上に時間を費やしてしまいました。

# 踏まえて反省点
- ビジネス的な観点で
    - 作ったものをどう宣伝するか考えられなかったこと。（そもそも宣伝する価値が有ると自分で思えなかったかのも有るかもしれませんが、、
    - アイデアがあまり出ないので、競合分析を怠った上で正当化して進めたこと。後で調べると同じようなものがバカみたいに出てきました（泣）
- 技術的な観点で
    - SEO関連の知識があまりになかったこと
    - データを集めるロジックなどに注力して、ユーザにどのような価値を与えるか意識できていなかったこと
    - まともな作業記録をつけていないので、ふわっとした反省しかできないこと

# 感想
このプロジェクトには、記録をしっかり残していなかったため正確ではありませんが、およそ2週間弱を費やしました。
結果として、妄想で終わらせないために一旦Webサイトを公開するところまでは行けました。しかし、アクセス数はほぼゼロ。アフィリエイト審査にいたるまでもなく。。
覚悟はしていましたが、ショックを受けたのが正直なところです。
マークダウンファイルをchrome上でプレビューする方法

# はじめに
READMEなどのマークダウンファイルをVScode以外でプレビューしたい時ありませんか？
私はあります。そんな時の方法を紹介します。

# 手順
[markdown viewer](https://chromewebstore.google.com/detail/markdown-viewer/ckkdlimhmcjmikdlpkmbgfkaikojcbjk?hl=ja)という拡張機能を使います。
リンク先からインストールしてください。

私の設定は以下ダンプに載せています。参考にしてみてください。
![スクリーンショット 2025-01-18 9.18.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693671/212e816b-3696-a589-9816-661ec27a914e.png)


![スクリーンショット 2025-01-18 9.19.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693671/ee67b061-e7f4-110f-cf87-60fc934483d9.png)

![スクリーンショット 2025-01-18 9.19.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693671/e050eafa-72a4-97ea-7b16-734dcef4d277.png)

以上。
C#のタプル型についてのアウトプット

:::note info
C#のタプル型について学んだことをアウトプットしていきます。
:::
:::note info
動作の確認は.NET9で行っています。
:::


## タプル型とは
タプル型は複数のデータをグループ化できます。
グループ化という意味では配列も同様ですが、タプル型は異なる型を混在させることが可能です。
また、タプル型はデータ構造的に参照型に見えなくもないですが、値型です。


## 宣言方法
タプル型は`()`を使用して宣言します。
以下のコードが基本的な宣言方法です。

```cs:C#
(string, int) name = ("紫咲シオン", 1208);
Console.WriteLine(name);

// (紫咲シオン, 1208)
```

タプル型もvarを使用して型を省略できます。
```cs:C#
var name2 = ("紫咲シオン", 1208);
Console.WriteLine(name2);

// (紫咲シオン, 1208)
```

## データへのアクセス方法

個々のデータには`変数名.Item位置`でアクセスします。
この際、位置は配列とは違い、1から始まります。
```cs:C#
var name3 = ("紫咲シオン", 1208, 'S');
Console.WriteLine($"名前：{name3.Item1} 誕生日：{name3.Item2} イニシャル：{name3.Item3}");

// 名前：紫咲シオン 誕生日：1208 イニシャル：S
```

C#のタプルはフィールド名を付けることができます。
各データの前に`フィールド名: `を付与します。
フィールド名を付けることで、`変数名.Item位置`の他に`変数名.フィールド名`でもアクセスできるようになります。

```cs:C#
var name4 = (Name: "紫咲シオン", Birth: 1208);
Console.WriteLine($"名前：{name4.Name}　誕生日：{name4.Birth}");

// 名前：紫咲シオン　誕生日：1208
```

また、事前に宣言した変数を設定することで、その変数名がフィールドとなりアクセスすることも可能になります。
```cs:C#
var name = "紫咲シオン";
var birth = 1208;
var name5 = (name, birth);
Console.WriteLine($"名前：{name5.name}　誕生日：{name5.birth}");

// 名前：紫咲シオン　誕生日：1208
```
## 分割代入
タプル型はフィールド毎にデータを分けて代入することが可能です。
`(型 変数名, ...) = タプル型の変数`でそれぞれのデータが分割されて代入されます。
```cs:C#
var data = ("紫咲シオン", 1208);
(string name6, int birth2) = data;
Console.WriteLine($"名前：{name6}　誕生日：{birth2}");

// 名前：紫咲シオン　誕生日：1208
```

`var`を付けることで型を省略することも可能です。
```cs:C#
var data2 = ("紫咲シオン", 1208);
var (name7, birth3) = data2;
Console.WriteLine($"名前：{name7}　誕生日：{birth3}");

// 名前：紫咲シオン　誕生日：1208
````
【PowerApps】コンボボックスから、選択した値を取り出す方法

##動画でも解説しました。
<iframe width="560" height="400" src="https://www.youtube.com/embed/V18BK8m4S6E?si=itC0O_03awPSStSK" 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>

## コンボボックスの特徴
今回はコンボボックスから、選択した値を取り出す方法について解説します。
コンボボックスには、アイテムの検索機能や複数選択が可能などといった、 ドロップダウンにはない特徴があります。


## 使用するリスト
![testlist1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/c0edafab-e9c2-462a-0988-379b37697afe.png)

このようなリストを用意しました。 このリストのuser_mail列とmemo列の値を使用していきます。

## コンボボックスの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/e798ce60-c066-569d-5001-d1dae74d34af.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/32db9dd9-e96a-ff13-93c7-e99d9249db8e.png)

通常はコンボボックスを配置した際には、 プロパティのディスプレイタブから データソースを選択し、 フィールドの編集から表示する列を選択します。

アイテムの検索で使用する列を選択します。

## コンボボックスの選択した値をコレクションに入れて見てみます

```JAVA
//コンボボックスの選択したアイテムをコレクション化
ClearCollect(col_cb,Self.SelectedItems);
```
こちらはコンボボックスのOnChangeプロパティです。
選択肢を変更した際に、選択アイテムをコレクションに格納しています。
選択したアイテムを格納したコレクション、 col_cbを見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/5961aa1d-4146-b4d0-27c1-b0b84f59bcea.png)

このように選択したアイテムがテーブル形式で格納されています。

## .Selectedで１つだけ値を取り出す
それでは、コンボボックスから値を取り出してみます。
まずはテキストラベルのTextプロパティを```ComboBox2.Selected.user_mail```にすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/41473148-425e-ca68-a5f3-7f235309a06b.png)
取り出せるのは選択した最後の1件だけとなり、 レコード形式ですので Selected. に続けて列名を入れると、その列の値を取り出すことができます。

目的が1件だけの取得であれば、複数選択をオフにして、
アイテム検索付きのドロップダウンとして使用しても良いかもしれません。

## 複数の値を取り出す？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/ee2844f8-79c4-1783-a661-5ef2aa662480.png)

それではこちらのリストボックスを見てみます。 Itemsプロパティに
ComboBox2.SelectedItemsを指定し、Valueで列名を指定しています。
一見成功していますが、コンボボックスで選択しているのは、 複数の単一レコードなので、
選択したレコードの値１つずつしか出てきません。

コンボボックスで選択した値に合致する全てのレコードの値を
リストから取得するには、やり方は様々ですが工夫が必要となります。

```
//リストボックス用のコレクションを準備
Clear(col_list);

//col_cbを繰り返し処理
ForAll(col_cb,
    With({mail:user_mail},
        //コレクションにフィルターをかけたmemo列の値を追加
        Collect(col_list,Filter(test_list1,user_mail=mail).memo
        )
    )
);

Reset(ListBox1)

```
こちらは先ほどもお見せした、コンボボックスのOnChangeプロパティです。 後半部分でリストボックス用のコレクションを作成しています。
Clear関数で一度コレクションを初期化して、
ForAll関数でコンボボックスのレコードの数分繰り返し処理を行います。
With関数でメールアドレスを取得して、 user_mail列でメールアドレスが 合致するレコードのmemo列の値をコレクションに追加しています。

これで選択したメールアドレスに合致する 全てのレコードのmemo列の値がリストボックスに表示されますが
重複する値を削除するため、 リストボックスのItemsプロパティで Distinct 関数を使用してコレクションから一意の値を取り出しています。
```
//コレクションからmemo列の一意の値を取り出す
Distinct(col_list,memo)
```
いかがだったでしょうか?
今回はコンボボックスから、選択した値を取り出す方法について解説しました。
Javaで「ラベルに文字列と画像の両方を表示した場合の位置関係を設定する」の動作を確認してみた。

# 概要

Javaで「ラベルに文字列と画像の両方を表示した場合の位置関係を設定する」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/tutorial/jlabel/index9.html

# 実装

以下のファイルを作成しました。

```Sample.java
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
import java.awt.Color;
import java.awt.BorderLayout;
import java.awt.Dimension;

class Sample extends JFrame{
  public static void main(String args[]){
    Sample frame = new Sample("MyTitle");
    frame.setVisible(true);
  }

  Sample(String title){
    setTitle(title);
    setBounds(100, 100, 728, 400);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    ImageIcon icon1 = new ImageIcon("./check.png");
    ImageIcon icon2 = new ImageIcon("./batsu.png");
    ImageIcon icon3 = new ImageIcon("./star.png");

    JLabel label1 = new JLabel("Hello!", icon1, JLabel.CENTER);
    label1.setOpaque(true);
    label1.setBackground(Color.YELLOW);
    label1.setPreferredSize(new Dimension(180, 100));
    label1.setHorizontalTextPosition(JLabel.LEFT);

    JLabel label2 = new JLabel("Good!", icon2, JLabel.CENTER);
    label2.setOpaque(true);
    label2.setBackground(Color.GREEN);
    label2.setPreferredSize(new Dimension(180, 100));
    label2.setHorizontalTextPosition(JLabel.CENTER);

    JLabel label3 = new JLabel("Sorry!", icon3, JLabel.CENTER);
    label3.setOpaque(true);
    label3.setBackground(Color.RED);
    label3.setPreferredSize(new Dimension(180, 100));
    label3.setHorizontalTextPosition(JLabel.RIGHT);

    JPanel p = new JPanel();
    p.add(label1);
    p.add(label2);
    p.add(label3);

    add(p, BorderLayout.CENTER);
  }
}
```

以下のコマンドを実行しました。

```
$ javac Sample.java 
$ java Sample
```

実行結果は以下の通りでした。

![Screenshot from 2025-01-18 08-38-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/ea86db1e-006b-ebb8-1afd-95ed20f656a5.png)

# まとめ

何かの役に立てばと。
今年楽しみな「Notion mail」の公開について（サボり）  

# 今年楽しみな「Notion mail」の公開について  

## 1. Notion mailとは  
これがまた面白い話なんですが、「Notion mail」という機能が今年登場するらしいんです。Notionって、タスク管理とかメモとか、仕事を何でもまとめちゃう便利ツールなんですけど、「いやいや、メールだけは別だから」っていう、ある種の線引きがありました。でも、その線をとうとう越える時が来た、と。つまり、メールすらもNotionの中に組み込まれちゃうらしいんです。こう聞くと、「それって便利なの？」と思うかもしれませんが、意外と奥が深いんです。  

---

## 2. Notion mailの可能性  

### (1) タスクとの統合  
まず注目したいのは、メールをそのままタスク化できるところです。「締め切りが～」とか「これ急ぎで対応してね」とか、メールで来るあれこれを、ワンクリックでタスクに変換できちゃうって話です。これなら、メールを見て「あー、これ後でやらないとな」と頭の片隅でモヤモヤする必要もなくなりそうです。Notionのページにタスクとして載っければ、それだけで「後回し」から「やることリスト」に早変わりです。  

### (2) ドキュメントとのリンク  
もう一つの目玉は、ドキュメントとの連動です。例えば、メールに添付された資料とか、ちょっと重要そうな内容をNotionのプロジェクトページにペタッと貼り付けられる。そうすれば、「あのメールどこ行ったっけ？」と受信ボックスを探し回る時間がなくなります。なんなら、メール本文をそのままNotionのページに埋め込めたら、さらにスマートですよね。  

### (3) チームコラボレーションの向上  
Notion mailの魅力は、それだけじゃありません。チームで使う場合、メールの内容をそのまま共有できるっていう機能も期待されています。例えば、「これ、どう思う？」みたいなメールを、プロジェクトメンバー全員がリアルタイムでチェックできる。わざわざ転送しなくてもいいし、「見逃した」なんて言い訳も通用しなくなりそうです。  

---

## 3. Notion mailの実装が解決する課題  

### (1) 複数ツールの利用による非効率性  
これまで、メール、タスク管理ツール、ドキュメント作成ツールといった感じで、いくつものツールを行き来するのが普通でした。でも、Notion mailの登場で、その非効率が解消される可能性があります。一つのプラットフォームで全部管理できるって、便利なようでちょっと怖いですよね。でも、便利な方が強いです。  

### (2) 情報の一元化  
メールの情報がNotion内に統合されることで、「情報の迷子問題」が解決されます。受信ボックスが散らかるのは避けられないですが、Notionなら一箇所にまとめられる。これだけでも、仕事の見通しが良くなるんじゃないでしょうか。  

### (3) コミュニケーションの履歴管理  
さらに期待されるのが、メールの履歴を追いやすくなる点です。Notion内でやり取りの記録が整理されていれば、必要なときにパッと振り返ることができる。「これ、誰が言い出したんだっけ？」みたいな会議での疑問も、一瞬で解決できるかもしれません。  

---

## 4. 期待される新機能の例  

### (1) フィルタリング機能  
「重要なメール」だけをピックアップする機能なんかがあったら便利ですよね。タグ付けや条件設定で、受信ボックスの整理整頓が簡単にできるようになる可能性があります。  

### (2) AIによるメールの分析  
NotionのAI機能と連動して、メール内容を要約したり、返信案を提案したりする機能も期待されています。たまに面倒くさい長文メールをAIが一瞬でまとめてくれると、心の中でガッツポーズしちゃいそうです。  

### (3) モバイルアプリとの連携  
スマホで受信したメールをNotionに簡単に取り込めるようになれば、移動中でも効率的に作業が進むでしょう。電車の中でサクサク整理しておいて、オフィスに着いたらすぐ動ける、なんて未来も近そうです。  

---

## 5. Notion mailの影響と可能性  
Notion mailは、個人の効率化だけでなく、企業や組織にも大きな影響を与えそうです。特に、複数チームが絡むプロジェクトでは、メールを起点とした情報共有が一元化されるだけで、仕事がどれだけスムーズになるか計り知れません。情報の渋滞が解消される未来が、すぐそこにあるように感じます。  

---  

# まとめ  
「Notion mail」は、ただのメール機能以上のものを提供する予感がします。メール、タスク、ドキュメントが一体化することで、作業効率が一気に向上する可能性を秘めています。新機能の登場を待つ間に、今のNotionをしっかり使いこなしておくのも良い準備になるかもしれません。さて、今年の楽しみがまた一つ増えましたね。
個人的な備忘録：ハッカソンで学んだDockerを使ったフロントエンド環境構築をローカルで動かしてみた

## はじめに
今回は、現在受講しているITスクールのハッカソン活動に基づく内容です。

:::note info
**チームメンバーの方にフロントエンドのDocker関連ファイルを準備していただいたので、それを私のローカル環境でも試してみようと思いました。**
:::

***これは個人的な備忘録としての走り書きメモになりますが、温かい目で見ていただければ幸いです。***

## 書こうと思ったきっかけ
私自身、フロントエンドのDocker関連ファイルを作成する経験はこれまでほとんどありませんでした。

:::note warn
**今回、勉強する機会があったため、記事として整理してみることにしました。**
:::

***チームのリポジトリにアップしていただいたものを、自分のローカル環境にクローンし、正常に動作するかどうかを確認していきます。***

## 補足事項
今回は、Dockerファイルやフロントエンド部分の詳細な説明は割愛します。

:::note alert
**主に、リポジトリをローカル環境でクローンし、正常に動作するかどうかを確認することが目的です。**
:::

***その点、あらかじめご了承ください。***

## ローカルに`git clone`してみた
まずは、リポジトリをローカル環境にダウンロードする必要があります。

:::note info
***そのため、`git clone`コマンドを使用してリポジトリをクローンします。***
:::

### 手順

-  ターミナルを開きます。
-  任意のディレクトリに移動します。  
   例えば、以下のように`projects`ディレクトリに移動します:

```bash
cd ~/projects
```

-  クローンしたいリポジトリのURLを用意します。
-  以下のコマンドを実行してリポジトリをクローンします:

```bash
git clone <リポジトリのURL>
```

**例:**

```bash
git clone https://github.com/example/frontend-docker.git
```

-  コマンド実行後の確認:

   クローンが正常に完了すると、以下のようにクローン先のディレクトリが作成されます。

```bash
cd xxx
ls
```

**出力例:**

```bash
Dockerfile
docker-compose.yml
src/
package.json
```

## 実際に動かしてみた
ここでは、動作確認の手順がリポジトリ内のREADMEに記載されていたため、その手順に沿って作業を進めました。

### ローカル開発構築手順
以下は、ローカル環境での開発環境構築手順です。

**コンテナを立ち上げる**

Docker Composeを使用して、必要なコンテナを起動します。

```bash
docker-compose up -d
```

**コンテナの中に入る**

起動したコンテナ内で作業を行うため、appコンテナに入ります。

```bash
docker-compose exec app bash
```

**プロジェクトディレクトリに移動**

プロジェクトのディレクトリに移動します。

```bash
$ cd xxx
```

**モジュールのインストール（初回およびモジュール追加時のみ必要）**

必要なモジュールをインストールします。

```bash
$ npm install
```

**開発用サーバーを起動**

開発環境用のサーバーを起動します。

```bash
npm run dev
```

**ブラウザで確認**

開発サーバーが起動したら、以下のURLにアクセスして、ブラウザ上で表示を確認します。

```bash
http://localhost:5173
```

ブラウザからアクセスした結果、問題なくReactのルートページが表示されることを確認できました。

![Screenshot 2025-01-18 at 8.24.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3662571/d5618446-a5ff-8917-7151-e0510448cc52.png)

***この確認が無事に完了したことで、ローカル環境での動作確認は成功と言えます。***

## まとめ
最後までお読みいただき、ありがとうございました。

:::note warn
**今回は、自分用の備忘録として、ローカル環境でのフロントエンド動作確認を中心にまとめましたが、非常に良い学びの機会となりました。**
:::

***今後は、自分一人でもフロントエンド関連のDocker関連周りのファイルを作成できるよう、さらに勉強を進めていきたいと思います。***
スクロールするテーブル(bootstrap 5.3)

bootstrap 5.3 を使ったスクロールするテーブル。

https://codepen.io/okadabasso/pen/LEPBWpP

thead に `position: sticky` を指定して thead を固定するやり方はいろいろ解説があるが、少なくとも chromium の現在のバージョンでは親要素と table 要素の間に微妙な隙間ができてしまい、スクロールすると thead の上に tbody の中身が表示されてしまう。
まあ 1px 程度なので無視することもできるがさすがに気になる。

なのでこの隙間を隠すために

```html
                    <div class="position-sticky w-100 scrollable-table-shim">
                    </div>
```

のようにダミーの要素を配置する。

あとは枠線が二重になるのを `margin: -1px` とかで隠したりする。
paizaラーニングレベルアップ問題集の「2つの数値を出力」をやってみた。

paizaラーニングレベルアップ問題集の[2つの数値を出力](https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__stdout_boss)をやってみました。
- - -
###### 問題
https://paiza.jp/works/mondai/d_rank_level_up_problems/d_rank_level_up_problems__stdout_boss
- - -
###### 方針
`1 1`という文字列を出力してもよいのですが、今回は改行なし出力と改行あり出力の関数・メソッドを使ってみました。
- - -
###### C
```c
#include <stdio.h>

int main() {
	printf("%d", 1);
	putchar(' ');
	printf("%d", 1);
	puts("");
	return 0;
}
```
- - -
###### C++
```cpp
#include <iostream>
using namespace std;

int main() {
	cout << 1 << ' ' << 1 << endl;
	return 0;
}
```
- - -
###### C#
```cs
using System;

class Program
{
	public static void Main()
	{
		Console.Write(1);
		Console.Write(' ');
		Console.Write(1);
		Console.WriteLine();
	}
}
```
- - -
###### Go
```go
package main
import "fmt"

func main() {
	fmt.Print(1)
	fmt.Print(" ")
	fmt.Print(1)
	fmt.Println()
}
```
- - -
###### Java
```java
public class Main {
	public static void main(String[] args) {
		System.out.print(1);
		System.out.print(' ');
		System.out.print(1);
		System.out.println();
	}
}
```
- - -
###### JavaScript
```js
console.log(1, 1);
```
- - -
###### Kotlin
```kotlin
fun main() {
	print(1)
	print(' ')
	print(1)
	println()
}
```
- - -
###### PHP
```php
<?php
	echo 1, ' ', 1, PHP_EOL;
?>
```
- - -
###### Perl
```pl
print 1, ' ', 1, $/;
```
- - -
###### Python3
```py
print(1, 1)
```
- - -
###### Ruby
```rb
print 1, ' ', 1
puts
```
- - -
###### Scala
```scala
object Main extends App{
	print(1)
	print(' ')
	print(1)
	println()
}
```
- - -
###### Swift
```swift
print(1, 1)
```
Goチュートリアル コマンド用語解説①：go mod initからlog.SetFlags(0)まで

## はじめに
Go言語を学ぶ中で登場する重要なコマンドや設定について、具体的な使い方とその意味を詳しく解説します。この記事では、以下の内容を扱います：

1. `go mod init example/hello`
2. `import "rsc.io/quote"`
3. `go mod tidy`
4. `go mod edit -replace example.com/greetings=../greetings`
5. `log.SetPrefix("greetings: ")`
6. `log.SetFlags(0)`

---

## 1. `go mod init example/hello`
このコマンドは、新しいGoモジュールを初期化するために使用します。

### **ポイント**
- `go.mod`ファイルを生成します。このファイルはモジュールの依存関係を管理するために使用されます。
- `example/hello`はモジュールパスを表します。本番環境ではリポジトリのURL（例: `github.com/username/project`）を指定します。

### **例**
モジュールを初期化すると、以下のような内容が`go.mod`に記録されます：

```
module example/hello

go 1.21
```

## 2. `import "rsc.io/quote"`
外部モジュールをコードに取り込むための記述です。

### **ポイント**
- `rsc.io/quote`はGo言語で利用可能な公開モジュールの一例です。
- このモジュールには、名言を返す便利な関数が含まれています（例: `quote.Go()`）。

### **使い方**
コード内で`quote.Go()`関数を呼び出すと、"Don't communicate by sharing memory, share memory by communicating."のようなメッセージを返します。

## 3. `go mod tidy`
このコマンドは、モジュールの依存関係を整理し、`go.mod`と`go.sum`を更新します。

### **ポイント**
- コード内で使用しているすべての依存関係を確認し、それらをダウンロードします。
- 不要な依存関係を削除します。

### **例**
`import "rsc.io/quote"`を追加した後に`go mod tidy`を実行すると、以下が自動的に行われます：
- `go.mod`に`require rsc.io/quote v1.5.2`が追加されます。
- `go.sum`に依存関係の検証情報が記録されます。


## 4. `go mod edit -replace example.com/greetings=../greetings`
モジュールの参照先をローカルパスに置き換えるためのコマンドです。

### **ポイント**
- 開発中のモジュールをローカルディレクトリから読み込むために使用します。
- `example.com/greetings`を`../greetings`に置き換える指定をしています。

### **用途**
外部リポジトリに公開する前に、ローカルで開発中のモジュールをテストする際に便利です。


## 5. `log.SetPrefix("greetings: ")`
ログメッセージの先頭にプレフィックスを追加します。

### **ポイント**
- `"greetings: "`という文字列がすべてのログメッセージの前に付与されます。
- ログの出力元を簡単に識別できるようになります。

### **例**
`log.Println("This is a log message.")`が以下のように出力されます：

```
greetings: This is a log message.
```


## 6. `log.SetFlags(0)`
ログ出力のフォーマットを変更します。

### **ポイント**
- `0`を指定することで、タイムスタンプやソースコード情報を含まないシンプルなログ出力にします。

### **フラグの種類**
| フラグ           | 説明                                  |
|------------------|---------------------------------------|
| `log.Ldate`      | 日付を追加 (`YYYY/MM/DD`)             |
| `log.Ltime`      | 時刻を追加 (`HH:MM:SS`)               |
| `log.Lmicroseconds` | マイクロ秒を追加 (`HH:MM:SS.uuuuuu`) |
| `log.Llongfile`  | フルパスのファイル名と行番号を追加    |
| `log.Lshortfile` | ファイル名のみと行番号を追加          |


## まとめ
この記事では、Goモジュールを初期化し、外部モジュールをインポートし、依存関係を管理する基本的な方法を解説しました。また、ログ出力をカスタマイズする`log.SetPrefix`と`log.SetFlags`の活用方法も紹介しました。

Goの開発でこれらを活用することで、より効率的なモジュール管理とデバッグが可能になります！