OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonを使ってOutlookのカレンダーに予定を追加する(9時間補正)

Pythonを使ってOutlookのカレンダーに予定を追加するとき、9時間ずれるの直せなかったので、

９時間の時間補正をしたメモ

Outlook デスクトップアプリです。

***

### Pythonを使ってOutlookのカレンダーに予定を追加する

#### 終日の予定を追加する例

まず、「野球」の予定として追加する例から始めましょう。ここでのポイントは、予定の開始時間に日本標準時（JST）から世界協定時（UTC）への9時間の補正を加えることです。

```python
import win32com.client
import datetime

# Outlookのインスタンスを作成
outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")

# 予定表フォルダーを取得
calendar_folder = namespace.GetDefaultFolder(9) # 9はカレンダーフォルダー

# 追加したい日付のリスト
dates = [
    "2024-04-29", "2024-05-03", "2024-05-06", "2024-07-15", "2024-08-12",
    "2024-08-13", "2024-08-14", "2024-08-15", "2024-09-16", "2024-09-23",
    "2024-10-14", "2024-11-04", "2024-12-30", "2024-12-31", "2025-01-01",
    "2025-01-02", "2025-01-03", "2025-01-13", "2025-02-11", "2025-02-24", "2025-03-20"
]

# 各日付に対して終日の予定を追加、9時間の補正を加える
for date_str in dates:
    date = datetime.datetime.strptime(date_str, "%Y-%m-%d")
    start_date = date + datetime.timedelta(hours=9)
    end_date = start_date + datetime.timedelta(days=1)

    appointment = calendar_folder.Items.Add("IPM.Appointment")
    appointment.Subject = "野球"
    appointment.AllDayEvent = True
    appointment.Start = start_date
    appointment.End = end_date
    appointment.Save()

    print(f"野球の予定が追加されました：{date_str}")
```

#### 特定時間の予定を追加する例

次に、「なんかの予定」として特定の時間帯（8:30から17:00）に設定される予定を追加する例を見てみましょう。こちらも同様に、9時間の補正を加えています。

```python
import win32com.client
import datetime

# Outlookのインスタンスを作成
outlook = win32com.client.Dispatch("Outlook.Application")
namespace = outlook.GetNamespace("MAPI")

# 予定表フォルダーを取得
calendar_folder = namespace.GetDefaultFolder(9)

# 追加したい予定の日付リスト
dates = [
    (4, 13), (4, 27),
    (5, 11), (5, 25),
    (6, 8), (6, 22),
    (7, 6), (7, 20),
    (8, 3), (8, 17)
]

# 各日付に対して特定時間の

予定を追加、9時間の補正を加える
for month, day in dates:
    start_time = datetime.datetime(2024, month, day, 8, 30) + datetime.timedelta(hours=9)
    end_time = datetime.datetime(2024, month, day, 17, 0) + datetime.timedelta(hours=9)

    appointment = calendar_folder.Items.Add("IPM.Appointment")
    appointment.Subject = "なんかの予定"
    appointment.Start = start_time
    appointment.End = end_time
    appointment.Save()

    print(f"なんかの予定が追加されました：{month}/{day} 8:30 - 17:00")
```

### まとめ

Pythonを使ってOutlookの予定を追加することで、日々のタスク管理がより効率的になります。日本で働く私たちにとって、時間の補正は国際的なコミュニケーションをスムーズに行う上で非常に重要です。この記事で紹介した方法を活用して、時間管理の精度を高めましょう。

と、ChatGPTさんは言っています。

***

# 補足 pip

PythonでOutlookの予定を操作するために、特に`win32com.client`モジュールを使用している場合、`pywin32`パッケージをインストールする必要があります。`pywin32`は、PythonからWindowsのCOM（Component Object Model）技術を利用するためのパッケージです。OutlookのようなWindowsアプリケーションを操作する際に必要となります。

`pywin32`をインストールするには、以下のコマンドを使用します：

    pip install pywin32

このコマンドは、Pythonのパッケージマネージャーであるpipを使用して、`pywin32`パッケージをインストールします。インストール後は、Pythonスクリプト内で`win32com.client`をインポートして、OutlookなどのWindowsアプリケーションとのインタラクションが可能になります。

なお、`pywin32`はWindows環境専用のパッケージであり、LinuxやmacOSでは使用できません。Pythonスクリプトを実行する環境がWindowsであることを確認してください。

***
初めてTailwind CSSを使ってみた

# 初めてTailwind CSSを使ってみた

## 背景
これまでの個人プロジェクト(React)ではstyled-componentsをメインに使ってきていたが、ViteやNext.jsの学習の際にTailwind CSSを目にする機会が増え、ぜひ使ってみようとなった。またServer Componentを使う上でスタイルにはPostCSSやTailwind CSSが推奨されているらしいため。

## Tailwind CSSとは
フロントエンドで用いられるUIにスタイルを適用するためのCSSライブラリ。

### 特徴
Utility Classesという既にスタイルが設定されたクラスが用意されている。そのクラス再利用しスタイルしていく。

例:
|Utility Class|Property|
|:-----------:|:------------:|
|font-bold|font-weight: 700|
|text-red-500|color: rgb(239 68 68)|

### 使い方
htmlタグのclass属性(ReactではclassName)に必要なUtility Classを羅列する。

```
<form className="flex flex-col gap-4">
```

## インストール方法
開発環境毎のインストール方法が公式ドキュメントに記載されてます。
https://tailwindcss.com/docs/installation

## 利用中のミス
動的にクラス名を作成して使用すること

### 背景
Reactのプロップスにカラー名を渡し、そのカラー名をクラス用のストリングと繋げてクラスに埋め込んだところ、そのスタイルが適用されていなかった。

コードイメージ:
```
export default function Test({color}) {
  return (
    <div className={`text-${color}`}>...</div>
  )
}
```

### 問題
[Tailwindでは動的にクラス名を作成することができない](https://tailwindcss.com/docs/content-configuration#dynamic-class-names)

### 解決
カラー名に対応したフルクラス名をマッピングして、フルクラス名をクラスに埋め込む

```
export default function Test({color}) {
  const colorMap = {
    red: "text-primary-red"
  }

  return (
    <div className={colorMap[color]}>...</div>
  )
}
```

## カスタマイズ
Tailwind.config.jsにプロジェクトに合わせた独自のクラスカスタマイズが行える。以下のような設定が可能。

- フォントカラー
- メディアクエリ
- Webフォント

またデフォルトのクラスを上書きすることも出来る。

## 便利なツール
VSCodeの拡張機能やPrettierとの連携でTailwindをより便利に使うことができる

### VSCode拡張機能
[Tailwind CSS IntelliSense](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss)

コードエディターでクラス名の補完入力をしてくれたり様々な機能がある

### Prettierプラグイン
[Automatic Class Sorting with Prettier](https://tailwindcss.com/blog/automatic-class-sorting-with-prettier)

羅列されたクラス名を自動で並び替えてくれる

## 感想
これまでの個人プロジェクトではsytled-componentsを主に使っていた。Tailwindをしばらく使ってみると、こっちの方が直感的かつ早くスタイル描けるので使いやすいと思った。styled-componentsやピュアなCSSを書くときにクラス名やコンポーネント名を考えるのが大変だったが、Tailwindではその必要がないので楽だと感じた。ただ、どうしてもクラス名を書く量が増えてしまうので、使用するのが最適かどうかはプロジェクトによって変わりそう。

またデフォルト設定を上書きして使用できるクラスを絞ることで、チーム開発であってもスタイルが一貫したUIを作成することができそう。

## 疑問点
Tailwindインストール時についてくるPostCSSがあまりよく分からなかった。CSS版のBabelのようなものという認識だが、それが実際にはどういうものかは理解できていない。

## おわりに
ここまで読んでいただきありがとうございました。
まだまだ知識不足・認識齟齬があると思いますので、見つけた際にはぜひご指摘ください！
【Kotlin】Sequenceを返す関数を再帰で実装する

下記のようにすることで、`Sequence` を返す関数を再帰で実装できる。

再帰だが、suspend 関数（コルーチン）で実装されているので処理が平坦化され、
スタックオーバーフローは起こらない。
（末尾再帰の最適化が行われているのではない。）

```Kotlin:フィボナッチ数列を表す Sequence を返す関数を再帰で実装した例
/**
 * フィボナッチ数列を返す。
 *
 * ```
 * fibonacciSequence().take(10).toList() // -> [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
 * ```
 */
fun fibonacciSequence(): Sequence<Long> {
    return sequence {
        val a = 0L
        val b = 1L

        yield(a)
        yield(b)

        yieldFibonacciSequenceAfter(a, b)
    }
}

/**
 * [a], [b] 以降のフィボナッチ数を [SequenceScope.yield] する。
 */
private suspend fun SequenceScope<Long>.yieldFibonacciSequenceAfter(a: Long, b: Long) {
    val c = a + b

    yield(c)

    yieldFibonacciSequenceAfter(b, c)
}
```

／以上
Googleカレンダーに特定のイベントを一括で追加する方法 (GAS)

Google Apps Script (GAS) を使用して Google カレンダーに特定のイベントを一括で追加する方法

かぜひいてから、全てが面倒くさくて自動化

***

## Googleカレンダーに特定のイベントを一括で追加する方法

### はじめに

Google Apps Script（GAS）は、Googleのサービスを自動化したり拡張したりするための強力なツールです。この記事では、GASを使用してGoogleカレンダーに特定のイベントを一括で追加する方法をご紹介します。

### Google Apps Scriptとは？

Google Apps Scriptは、クラウド上で実行されるJavaScriptベースのスクリプト言語です。Googleドキュメント、スプレッドシート、カレンダーなど、Googleのさまざまなサービスと連携して動作します。

GASの詳細については、[公式ドキュメント](https://developers.google.com/apps-script)を参照してください。

### GASの基本的な使い方

1.  **Googleドライブにアクセス**します。
2.  **新規 > その他 > Google Apps Script**を選択して新しいスクリプトプロジェクトを作成します。
3.  スクリプトエディタが開いたら、必要なコードを貼り付けます。
4.  **保存**ボタンをクリックしてスクリプトに名前を付けます。
5.  スクリプトを実行するには、関数名の左にある▶︎（実行）ボタンをクリックします。
6.  初回実行時には、Googleからアクセス許可を求められるので、指示に従って承認します。

### ケーススタディ: Googleカレンダーにイベントを一括追加

#### ケース1: 「野球」イベントの一括追加

以下のスクリプトは、2024年に特定の日に「野球」というイベントを追加する例です。

今回は、9:00-18:00

your_calendar_id@example.com　は、gmailのアドレスとか

```javascript
function addBaseballEventsToCalendar() {
  var calendarId = 'your_calendar_id@example.com';
  var calendar = CalendarApp.getCalendarById(calendarId);
  var dates = [
    '2024-04-13', '2024-04-27', '2024-05-11', '2024-05-25',
    '2024-06-08', '2024-06-22', '2024-07-06', '2024-07-20',
    '2024-08-03', '2024-08-17',
  ];

  dates.forEach(function(date) {
    var startDate = new Date(date + 'T09:00:00');
    var endDate = new Date(date + 'T18:00:00');
    calendar.createEvent('野球', startDate, endDate);
  });
}
```

#### ケース2: 「なんかの予定」イベントの一括追加

別の例として、「なんかの予定」という全日イベントを2024年と2025年に追加するスクリプトです。

```javascript
function addSomeEventsToCalendar() {
  var calendarId = 'your_calendar_id@example.com';
  var calendar = CalendarApp.getCalendarById(calendarId);
  var dates = [
    '2024-04-29', '2024-05-03', '2024-05-06', '2024-07-15', '2024-08-12',
    '2024-08-13', '2024-08-14', '2024-08-15', '2024-09-16', '2024-09-23',
    '2024-10-14', '2024-11-04', '2024-12-30', '2024-12-31',
    '2025-01-01', '2025-01-02', '2025-01-03', '2025-01-13', '2025-02-11',
    '2025-02-24', '2025-03-20'
  ];

  dates.forEach(function(date) {
    var day = new Date(date);
    calendar.createAllDayEvent('なんかの予定', day);
  });
}
```

### まとめ

Google Apps Scriptを活用すれば、Googleカレンダーに特定のイベントを一括で追加することが簡単にできます。これにより、手動でイベントを一つずつ追加する手間を省くことができます。GASを使用することで、日常業務を効率化し、より生産的な時間を確保することができるでしょう。

***

って、感じ
MacでLinux環境をサクッとつくる

Linux OSについての基礎知識を、実践を通して身につけたい。

でも、
・UTM(仮想化ソフト)は、重すぎて使えなかった
・新しいPCを用意するのは、ハードルが高い

どうにか手元にあるMac PCでLinux環境を簡単に作れないものか...

という悩みを、Dockerを使用してUbuntu(Linuxの一種)の仮想環境を構築することで解決しました。
この記事では、その方法についてシェアします。

# はじめに
## この記事の想定読者
- インフラ(特にOS)の初学者
- Linuxの環境を簡単に作って触りたい人

## この記事で書くこと
Ubuntuの仮想環境の構築手順

## この記事で書かないこと
- Dockerそのものについての詳細な説明
- Dockerのインストール方法([こちら](https://matsuand.github.io/docs.docker.jp.onthefly/desktop/mac/install/)を参照)


## 環境条件
- MacBook Air
    - チップ：　M1
    - OS：　 Ventura 13.5.1
- Dockerバージョン：　23.0.5

# MacでLinux環境を構築する方法
以下の３ステップで作れます
1. Dockerファイルを作成する
1. ビルドする
1. 起動する

## 1.　Dockerファイルを作成する
今回はLinuxの環境を作るのがゴールなので、以下のようにOSとコマンドを1つ設定したファイルを使用します。
```dockerfile:dockerfile
# 最新のUbuntuイメージを使用
FROM ubuntu:latest

# コンテナ起動時に実行されるコマンド
CMD ["bash"]
```

<details><summary>クリックしてDockerファイルの説明を見る</summary>

<table>
  <thead>
    <tr>
      <th>要素</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td>　FROM　</td> 
    <td>どのOSを動かしたいか　</td>
  </tr>
  <tr>
    <td>　CMD　</td>
    <td>「CMD ["bash"]」 で、コンテナ起動直後にubuntu内で操作できる</td>
  </tr>
</table>
</details>

## 2.　ビルドする
以下のコマンドを実行します。
```
docker build -t my_ubuntu .
```
<details><summary>クリックしてビルドコマンドについて説明を見る</summary>

<table>
  <thead>
    <tr>
      <th>要素</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td>　-t　</td> 
    <td>イメージ名を指定する
        <br>※「ubuntu」以外の名前に指定すること　
    </td>
  </tr>
  <tr>
    <td>　.　</td>
    <td>Dockerfileを作成したディレクトリ
        <br>※上記コマンドの場合は、現在のディレクトリ
    </td>
  </tr>
</table>
</details>

<br>
以下のように表示されれば、正常にビルド完了です。

```
[+] Building 112.2s (9/9) FINISHED
```

## 3.　起動する
以下のコマンドを実行します。
```
docker run -it --name my_container my_ubuntu bash
```
<details><summary>クリックして起動マンドについて説明を見る</summary>

<table>
  <thead>
    <tr>
      <th>要素</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td>　-it　</td> 
    <td>コンテナ内に入り、コマンドラインで操作したい時に指定する</td>
  </tr>
  <tr>
    <td>　--name　</td>
    <td>任意のコンテナ名を指定する</td>
  </tr>
  <tr>
    <td>　bash　</td> 
    <td>どのシェルを使用してコマンドライン操作するかを指定する
        <br>※今回はbashを使用
    </td>
  </tr>
</table>
</details>

<br>
以下のようにプロンプトが表示されれば、Ubuntuの環境を起動完了です。　

```
root@0c01adbb637f:/myapp#
```

使用後は`docker stop コンテナ名`でコンテナを停止します（起動したまま放置するとリソース食うので）。

---
最後に1点補足です。
以下のように、Dockerファイルを作成しなくても、コマンドでもっと簡単にUbuntuの環境を構築する方法はあります。
```
docker run -it ubuntu:latest
```

ただ、Dockerfileを作成する方法も自分でカスタマイズできて便利なので、こちらの方法を紹介しました。

「カスタマイズできる」というのは、たとえば、上記コマンドで構築したUbuntu環境では、`sudo`や`python`が使えません。
```
$ docker run -it ubuntu:latest
(中略)
Status: Downloaded newer image for ubuntu:latest
root@e03a5cdbd2f9:/# sudo ls
bash: sudo: command not found　　　　　　　　　　　　　　　　　　　　　　　　　　　　//sudoコマンドがない
root@e03a5cdbd2f9:/# python --version
bash: python: command not found　　　　　　　　　　　　　　　　　　　　　　　　//pythonがない
```
これらを使用したいとなった場合、起動後に、逐一`apt-get install -y パッケージ名`を実行してインストールする必要があります。
一方で、Dockerfileに以下のように記述・起動することで、上記操作の手間を省けます。
```dockerfile:dockerfile(sudoとpythonを導入する例)
# 最新のUbuntuイメージを使用
FROM ubuntu:latest

# 以下のように記述することで、起動時に各パッケージが利用できる状態になる
RUN apt-get update && apt-get install -y \
    python3 \ 
    sudo

# コンテナ起動時に実行されるコマンド
CMD ["bash"]
```

最後までお読みいただき、ありがとうございました。
ProtoPediaのプロフページで投稿作品数などのバッジを追加する

ProtoPediaのプロフィールページの自己紹介枠がマークダウン対応された（2024/2/26）。
マークダウン対応されたので、是非みんなにやってもらいたいことがある。

それは、ProtoPediaの「投稿作品数」「投稿作品の総PV」「投稿作品のいいね数」のバッジを追加すること。
こんな感じでバッジを追加できます。

![スクリーンショット 2024-02-24 13.46.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2863747/82b73b5b-0890-73c1-ff2f-8710586c844a.png)

バッジ部分を拡大
![スクリーンショット 2024-02-24 14.14.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2863747/eef3c19b-d926-a5f1-012c-2565f2531031.png)

ただこの機能、公式ではサポートしておりません（すいません）


でもでもでも、こちら↓を使うとあら不思議。バッジ追加できてしまうのです。

https://protopedia.net/prototype/3701

実はこの作品、「ProtoPedia Advent Calendar 2022」で @yamaccu さんが作成してくれたもの。その記事がこちら。

https://qiita.com/yamaccu/items/b192399a90047f51f331

是非みんなも、「[設定画面](https://protopedia.net/settings)」からやってみてねー！
世界一流エンジニアの思考法　第2章「アメリカで見つけたマインドセット」２

# 世界一流エンジニアの思考法(前回の続き)

## 第2章「アメリカで見つけたマインドセット」ー日本にいるときは気づかなかったことー
**-「検討をやめて検証する」-**　時間をかけずにさっさと「検証」の段階に進み、フィードバックを得るようにしよう。
⇨何を選ぶかの選択のかを比較検討に過大な時間をかけることは無駄(決して全てが無駄とは言わない)で、それよりも早く前に進むことが大切である。実務経験を積み重ねる方が圧倒的に重要である。そこには **「失敗」** がつきもので、早く失敗することはそれ自体に価値がある。

**-「不確実性を受け入れよう」-**
変化に柔軟に対応する必要なソフトウェア開発の分野では特に必要な習慣だ。この考えなしに新しいモダンな開発スタイルのマネジメントは不可能と言っても過言ではない。

* マネジメントは詳細までは細かく練られた計画を期待しない
* 予算と報告のプロセスは精密な結果の予測を要求しない
* 内部プロセスは計画や優先順位の変更に柔軟である
* 事前に全ての問題分析が完了せずとも新しいことに挑戦する姿勢をもつ
* システムとプロセスは柔軟で、複数の頻繁な変更を受け入れられる
* 学びに基づいて、変化を精力的に行う

## 気付きなど
**-「検討をやめて検証する」-**　である「早めに検証して、早めに失敗しよう」点において、私はある程度基礎の力を持ったうえで、机の上で「検討」することより「検証」を行い、失敗しFBを得る。ここでは、何もプログラミングのスキルなしで考えず真っ直ぐ進むということではなく（逆に時間を無駄にする可能性がある）、マネジメントを行う方に向けた分野かなと思いました。
Windowsで自動的にごみ箱を空にする方法 (python&bat)

かぜひいてから、全てが面倒くさくなってきたので、自動化

***


***

### Windowsで自動的にごみ箱を空にする方法

Windowsを使っていると、時にはごみ箱が溜まってしまうことがあります。定期的にごみ箱を空にすることは、ディスクスペースを確保し、システムをスムーズに保つために役立ちます。このブログでは、Pythonスクリプトとバッチファイルを使用して、Windowsのスタートアップ時に自動的にごみ箱を空にする方法を紹介します。

#### Step 1: Pythonスクリプトの作成

まず、以下のPythonスクリプトを作成します。このスクリプトは、WindowsのAPIを呼び出してごみ箱を空にするものです。テキストエディタを開き、以下のコードをコピーしてください。

```python
import ctypes

# ごみ箱を空にする関数
def empty_trash():
    # SHEmptyRecycleBinを呼び出してごみ箱を空にする
    # 0 = ごみ箱のハンドル, None = すべてのごみ箱, 0x0003 = フラグ（空にする＋確認なし）
    ctypes.windll.shell32.SHEmptyRecycleBinW(0, None, 0x0003)

# ごみ箱を空にする
empty_trash()
```

このスクリプトを`ゴミ箱を空にする.py`という名前で保存します。保存場所は、例えば`C:\Users\*****\Documents\Python\`など、任意の場所で構いません。

#### Step 2: バッチファイルの作成

次に、Pythonスクリプトを実行するバッチファイルを作成します。新しいテキストファイルを開き、以下の内容を入力してください。

```bat
@echo off
python "C:\Users\*****\Documents\Python\ゴミ箱を空にする.py"
```

このファイルを`EmptyTrash.bat`という名前で保存します。ファイルの保存時には、文字コードをANSIとして保存してください。これは、特に日本語のWindowsシステムで重要です。

#### Step 3: スタートアップへの追加

最後に、作成したバッチファイルをWindowsのスタートアップフォルダに追加します。これにより、Windowsが起動するたびに自動的にごみ箱が空にされます。

1.  `Win + R` キーを押して「実行」ダイアログを開きます。
2.  `shell:startup` を入力し、「OK」をクリックします。
3.  開いたスタートアップフォルダに、`EmptyTrash.bat`ファイルをコピーまたは移動します。

これで設定は完了です。次回のWindows起動時から、ごみ箱が自動的に空になるようになります。

***

って、感じ
[Python] solanaのウォレットの残高を取得する

# SOLのウォレットの残高を取得してみた。

今回は、SOLの開発をpythonでちょこっとやってみようと思い、pythonから始めてみました。最近、tsとかgoとかいじってた人間のため、pythonを久々に書いたらちょっと違和感あったけど、なんとかかけました〜

### 対象ウォレット
検証用でメインネットにウォレットがあるので、それを使ってその残高を取得してみます。
```
EDuVpfE29Rb7S9q1bM5Db8WwtqMAPbZb8bqrfNcNt24c
```
https://explorer.solana.com/address/EDuVpfE29Rb7S9q1bM5Db8WwtqMAPbZb8bqrfNcNt24c

→ ウォレットを晒しただけでは、なにもできないので安心してください。（秘密鍵は公開しないよ！！）

![Screenshot 2024-02-24 at 13.59.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556108/6e145c41-2495-6872-8929-2a491d642e44.png)

残高：0.002267881
となっているので、この数値が取れればいいわけです！ちなみに、桁数は違う可能性があります。explorerはちょっと短い。

## コード書いてみた

### 必要なモジュール

```
requests
asyncio
solana
```
上記のものになるので、下のコマンドを叩いてみてください。バージョンで拒否られたら頑張ってください笑

```
$ pip install requests asyncio solana
```

これらをしたら、以下のコードを書いてください！

```python: balance.py
from operator import truediv
import requests
import asyncio
from solana.rpc.async_api import AsyncClient

SOLANA_ENDPOINT = 'https://api.mainnet-beta.solana.com'
SOL_PROGRAM_ID  = 'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'
# 今回は、このウォレットアドレスにしていますが、自分のがあれば書き換えてください！
SOL_WALLET = 'EDuVpfE29Rb7S9q1bM5Db8WwtqMAPbZb8bqrfNcNt24c' 

# connection api server
async def main():
    async with AsyncClient(SOLANA_ENDPOINT) as client:
        res: bool = await client.is_connected()
    if res == 1:
        print("connection success")  # True
    elif res == 0:
        print("connection failed") # False
    
    payload = {
        'jsonrpc': '2.0',
        'id': 1,
        'method': 'getTokenAccountsByOwner',
        'params': [
            f'{SOL_WALLET}',
            {
                'programId': f'{SOL_PROGRAM_ID}'
            },
            {
                'encoding': 'jsonParsed'
            }
        ]
    }
    r = requests.post(SOLANA_ENDPOINT, json = payload)
    j = r.json()
    
    print(j)
    
    await client.close()

asyncio.run(main())
```

意外とpythonでも同期処理をするようにasync/awaitの操作が必要になるので、気をつけてくださいね！

## ちなみに

### progeram id

Solanaのブロックチェーンにおいて、"Token Program ID" は、SPLトークン（Solana Program Libraryトークン）の作成や管理に関わるプログラムの識別子のことで、SPLトークン標準は、ERC-20トークンというものに相当するSolana用のものであり、トークンの作成、転送、および管理を可能にするスマートコントラクトのセットのことをさしています。

Token Program ID
基本的に以下の固定値になっているようなので、これをうめこみました！
```
TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
```
このトークンの詳細についてはexplorerを見てみてください！

https://explorer.solana.com/address/TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA

![Screenshot 2024-02-24 at 14.07.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556108/c5fa5668-256f-1d4f-6a32-474c4d340846.png)

さらにちょっと覗きたい方はこちら！

https://solanacookbook.com/ja/guides/get-program-accounts.html#%E6%A6%82%E8%A6%81


今回はここまで！
PDFにまとめた古い図面さん、各ページを分割、図番でファイル名とする (Tesseract OCR)

Tesseract OCR メモの続きです。

Tesseract OCR メモ<br><https://hide.ac/articles/MAg5H2KlK>

***

古い図面データをまとめてスキャナーでPDFにしたいときなど

例えば、右下の図面番号を拾って、各ページを分割、ファイル名にすることを想定しています。

***

# Pythonを使用したPDFからのテキスト抽出とページ別PDFの保存

## 導入

この記事では、Pythonを用いてPDFファイルから特定の領域のテキストを抽出し、そのテキストを基に新しいPDFファイルの名前を生成する方法を紹介します。この技術は、文書管理システムにおける自動ファイリングや、大量のPDFファイルを扱う際の作業効率化に役立ちます。

## 必要なツール

*   **Python**: プログラミング言語
*   **Tesseract OCR**: テキスト抽出のためのオープンソースOCRエンジン
*   **PikePDF & PDF2Image**: PDFファイルの処理と画像変換に使用
*   **Pillow (PIL)**: 画像処理ライブラリ

## ステップバイステップのガイド

1.  **環境設定**: 必要なライブラリのインストールとTesseract OCRのセットアップ。
2.  **PDFから画像への変換**: `pdf2image`を使用してPDFファイルを画像に変換します。
3.  **テキスト抽出**: `Tesseract OCR`と`Pillow`を使用して、変換された画像から特定領域のテキストを抽出します。
4.  **新しいPDFの生成と保存**: 抽出したテキストをファイル名に使用し、`PikePDF`で元のPDFのページを新しいPDFとして保存します。

### コードの詳細解説

このスクリプトは、Pythonを使用してPDFファイルから特定の領域のテキストを抽出し、そのテキストをもとにして各ページを個別のPDFファイルとして保存するプロセスを自動化します。以下、コードの主要部分を順に説明します。

#### 必要なライブラリのインポート

```python
from pdf2image import convert_from_path
import pytesseract
from PIL import Image
import os
import re
import pikepdf
```

*   `pdf2image`: PDFを画像に変換するためのライブラリ。
*   `pytesseract`: Tesseract OCRをPythonから利用するためのラッパー。
*   `Pillow (PIL)`: 画像処理ライブラリ。ここでは、画像の特定の領域をクロップするために使用します。
*   `os`: ファイルパスの操作やディレクトリの作成に使用します。
*   `re`: 正規表現を使ってファイル名から不適切な文字を除去します。
*   `pikepdf`: PDFファイルの操作に使用します。

#### Tesseract OCRのパス設定

```python
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'
```

Tesseract OCRがインストールされているパスを指定します。これにより、`pytesseract`がTesseract OCRを呼び出す際に正しい場所を参照できるようになります。

#### PDFから画像への変換

```python
pdf_path = r"C:\Users\******\Desktop\OCRtest\your_pdf_file.pdf"
output_dir = r"C:\Users\******\Desktop\OCRtest\output"
images = convert_from_path(pdf_path)
```

*   `pdf_path`: 処理するPDFファイルのパス。
*   `output_dir`: 生成されるPDFファイルを保存するディレクトリのパス。
*   `images`: `convert_from_path`関数を使用して、PDFファイルを画像のリストに変換します。

#### テキストの抽出とPDFファイルの保存

area = (width \* 0.82, height \* 0.93, width, height)

右下の図面番号を拾って、ファイル名にすることを想定しています。

```python
with pikepdf.open(pdf_path) as pdf:
    for i, image in enumerate(images):
        width, height = image.size
        area = (width * 0.82, height * 0.93, width, height)
        cropped_image = image.crop(area)
        text = pytesseract.image_to_string(cropped_image, lang='eng').strip()

        if text:
            filename = re.sub(r'[\\/*?:"<>|]', "", text.splitlines()[0])[:15]
        else:
            filename = "no_text"

        unique_filename = f"{i + 1}_{filename}.pdf"
        file_path = os.path.join(output_dir, unique_filename)

        new_pdf = pikepdf.new()
        new_pdf.pages.append(pdf.pages[i])
        new_pdf.save(file_path)
        print(f"PDF saved as {file_path}")
```

*   各ページをループ処理し、画像の特定領域からテキストを抽出します。
*   抽出したテキストをファイル名に使用し、それぞれのページを新しいPDFファイルとして保存します。テキストが抽出されなかった場合は、デフォルトのファイル名を使用します。
*   `pikepdf.new()`で新しいPDFを作成し、`pdf.pages[i]`で元のPDFから特定のページを新しいPDFに追加します。そして、指定されたパスにPDFを保存します。

## 使用例と応用

古い図面を複数枚まとめてスキャナーでPDFにしたとき、それぞれのページを図番を振って保存したいときなど

今回は、右下の図面番号を拾って、ファイル名にすることを想定しています。

## まとめ

この方法を使えば、大量のPDFファイルを効率的に管理し、必要な情報に迅速にアクセスするための作業を自動化できます。

***

という感じ
フリーランスエンジニアの時給に対して社員換算の年収価値は何円なのか計算してみた

フリーランスエンジニアの時給に対して社員換算の年収価値は何円なのか計算してみた

# 概要

フリーランスエンジニアの時給が何円の場合に、年収価値は何円になるのかを計算したい。

ここで言う年収価値とは、フリーランスの時給を社員年収に換算するならば、何円の価値があるかということだ。

# 計算してみた感想


どんなシナリオを描くかによってかなり結果額が違ってくる。
時給が税込6000円の場合、だいたい538万円 から961万円ぐらいの価値がありそうだ。

一概には言えないが、やはり一般論通り「社員に比べて3分の2程度の価値」というのが実態なのではないかと思った。
( 718万円程度 )

その理由は

- 社員ならば会社が負担する社会保険料の15%程度を自分でまかなう必要がある 
- 特別休暇、福利厚生がない
- 仕事が途切れる場合がある
- 消費税の支払いがある ( 時給を税抜金額で試算する場合は無視して良いが、税込で計算する場合は考慮が必要 )

# 時給6000円の場合の年収価値

## 前提

以下全てのシナリオにおいて

- 時給は税込額とする 
- 社員に比べて、社会保険料の負担が15%多いものとする ( 年金は社員相当分を自分で積み立てるものとする )
- 細かな所得税率などの計算はしないものとする
- ITエンジニアはほとんど経費がかからない場合が多いため、経費は無視するものとする
- 事業税の支払いはないものとする
- 1日の稼働時間は8時間とする

## 楽観的なシナリオ

このシナリオでは、フリーランス時給が税込6000円の場合に、社員換算で年収961万円程度の価値がある

- 仕事は1日も途切れないものとする
- 消費税はみなし仕入れ率を考慮して5%の負担とする
- カレンダー通りに休日を取り、祝日は休むものとする ( 年間平日247日 )
- 社員と比べると年末年始休暇・有給休暇などの特別休暇はないが、その違いは無視するものとする

計算式

```
6000*8*247*(105/110)*(85/100) ＝ 9619527.27273
```

## 悲観的なシナリオ

このシナリオでは、フリーランス時給が税込6000円の場合に、社員換算で年収767万円程度の価値がある

- 年に平均で1ヶ月ほど仕事が途切れるものとする
- 消費税は預かり分のまま10%納めるものとする
- 休日祝日に加えて、社員同等の特別休暇の日数分だけ休むものとする ( ここでは年間20日間とする )

計算式 

```
6000*8*(247-20-20)*(100/110)*(85/100) = 7677818.18182
```
## 一般論によるシナリオ (妥当そうなパターン)

このシナリオでは、フリーランス時給が税込6000円の場合に、社員換算で年収718万円程度の価値がある

- 消費税を預かり分のまま10%納めるものとする
- カレンダー通りに休日を取り、祝日は休むものとする ( 年間平日247日 )
- フリーランスの収入は社員に比べて3分の2の価値とする (ここに特別休暇・福利厚生・仕事が途切れた場合など全てが含まれるものとする )

計算式

```
6000*8*247*(100/110)*2/3 = 7185454.54545
```

## 一般論によるシナリオ (悲観的なパターン)

このシナリオでは、フリーランス時給が税込6000円の場合に、社員換算で年収538万円程度の価値がある

- 消費税を預かり分のまま10%納めるものとする
- カレンダー通りに休日を取り、祝日は休むものとする ( 年間平日247日 )
- フリーランスの収入は社員に比べて2分の1の価値とする (ここに特別休暇・福利厚生・仕事が途切れた場合など全てが含まれるものとする )

計算式

```
6000*8*247*(100/110)*1/2 = 5389090.90909
```

# 他の時給で計算する


上に書いた計算式で時給部分を変えてGoogleに入力するなどすればOK


```
税込の時給額*8*247*(100/110)*2/3
```


以下は、社員に比べて3分の2の価値とした時の例。

たとえば年収価値を1000万円にしようと思ったら、税込時給は8500円程度は稼ぐ必要がありそうだ。

## 時給 税込3000円の場合

年収価値 359万円程度

## 時給 税込4000円の場合

年収価値 479万円程度

## 時給 税込5000円の場合

年収価値 598万円程度

## 時給 税込6000円の場合

年収価値 718万円程度

## 時給 税込7000円の場合

年収価値 838万円程度

## 時給 税込8000円の場合

年収価値 958万円程度

## 時給 税込9000円の場合

年収価値 1077万円程度

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
【Next.js/React】パスは正しいのにコンポーネントがimportできない時に確認すべきこと

## はじめに

とあるNext.jsのサンプルコードを写経していて、Headerコンポーネントをimportしようとしたところ、VSCodeに怒られてimportできませんでした。

![スクリーンショット 2024-02-24 12.03.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/820e8487-e2aa-0420-9cc6-99b702b7b12b.png)

こういう時は十中八九、パスのtypoや階層構造のミスなので、入念にチェックしましたが、解決できませんでした。

## 原因

まず赤波線にhoverしてエラーメッセージを確認しました。

> ファイル '{省略}/src/app/components/Header.tsx' はモジュールではありません。


ん？ `モジュールではない`ってどういうこと？？

Headerコンポーネントを確認します。

```react
const Header = () => {
  return (
    <header>
      <div>
        <h1>テスト</h1>
      </div>
    </header>
  )
}
```

あ、exportしてない...

exportしてないのにimportできるはずがありません。

## 修正

末尾に`export default Header;`を追加しました。

```react
const Header = () => {
  return (
    <header>
      <div>
        <h1>テスト</h1>
      </div>
    </header>
  )
}
// 以下を追加
export default Header;
```

これで無事にimportできるようになりました。

## ミスの原因

そもそもなぜ`export default Header;`を書き落としてしまったのか。

筆者が普段以下のように、関数宣言と同時にエクスポートしているためです。

```react
export const Header = () => {
  return (
    <header>
      <div>
        <h1>テスト</h1>
      </div>
    </header>
  )
}
```

これは**名前付きエクスポート**という書き方です。

デフォルトエクスポートと異なり、名前付きエクスポートは複数の関数や変数をエクスポートできます。
したがって、importするときも`{}`をつける必要があります。

```react
import { Header } from "./components/Header";
```

ちなみに、ここで`{}`を忘れるとRuntime Errorになります。

> Unhandled Runtime Error
Error: Unsupported Server Component type: undefined

:::note info
デフォルトエクスポート・名前付きエクスポートは、上記以外の書き方も可能です。
詳細は以下をご参照ください。

- [【React/Next.js】「export default」と「export」の違い](https://zenn.dev/seetsuko/articles/f378bf513d6231)
- [JavaScript Primer ECMAScriptモジュール](https://jsprimer.net/basic/module/)
:::

## 終わりに

色々試していて`Runtime Error`になったときは、学習し始めたばかりのNext.jsに原因があると思いましたが、結局はJavaScriptの知識不足によるものでした。

フレームワークを扱っていると原因がどこにあるのか把握するのが大変ですが、このように根本にあるJavaScriptについて誤解しているせい、ということが多い感じです。

## 参考

https://zenn.dev/joeee/articles/36e15e4260eeec
Juliaで音声ファイルを再生する

Juliaで音声ファイル（WAV）を再生する方法についてまとめてみます。

# 環境
OS：Windows 11
Julia：v1.10.1（v1.8.5でも動作を確認）

# パッケージの追加
```julia:必要なパッケージ
add FileIO
add LibSndFile
add PortAudio
```

# プログラム
### WAV形式の再生
```julia:WAV形式の再生
using FileIO: load, save
import LibSndFile
using PortAudio

snd = load("audio.wav")
stream = PortAudioStream(0, 2, samplerate=Int(snd[2]))
write(stream, snd[1])
close(stream)
```
上記のコードはデフォルトのデバイスで再生されますが、うまくいかない場合は次のようにデバイス名やsamplerateなどを指定してみるといいかもしれません。

### WAV形式の再生２
```julia:WAV形式の再生２
using FileIO: load, save
import LibSndFile
using PortAudio

snd = load("audio.wav")
stream = PortAudioStream("デバイス名", 0, 2, samplerate=48000)
write(stream, snd[1])
close(stream)
```
:::note info
```julia:再生デバイス名を調べる
using PortAudio
PortAudio.devices()
```
:::

# まとめ
`Warning: libportaudio: Output underflowed`が出ますが再生自体はできるようです。

# 参考記事
https://qiita.com/0x20FE/items/068416a5565683cd828a

# 更新履歴
- **2024/02/24**
・投稿
【Googleフォト】の消しゴムマジックを使ってみた。


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

　今回は、Googleフォトの一機能、消しゴムマジックを使ってみました。

:::note info
本記事は、Googleフォトの消し
ゴムマジックのお試しです。
画像はありません。あしからず。
:::

　まずは、ニュースから。

　X-Twitterの
　　OpenAI社の開発者アカウントから
　　　公式な発表がありました。

　以下が
　　そのポスト内容です。
***
GPTs are the best way to customize ChatGPT, with more features and strong adoption from users and developers. We’re winding down the plugins beta on April 9, as GPTs offer a better way to reach ChatGPT users.

DeepL翻訳（GPTsのsが消され、追加）
「GPTsはChatGPTをカスタマイズする最良の方法であり、より多くの機能とユーザーや開発者からの強力な採用があります。 GPTsはChatGPTユーザーにより良い方法を提供するため、4月9日にプラグインベータを終了します」
***

　なるほどねぇ。

　まぁ、GPTs普及のためには、
　　仕方ない処置でしょうね。

　プラグインを
　　使ってきた人は、
　　　すぐに対策を
　　　　こうじることを
　　　　　オススメします。
***
　本題に
　　しましょう。

　私は、
　　スマホで、
　　　ChatGPTを使っています。

　スマホは、
　　Androidです。

　Androidスマホであれば、
　　たいていの機種には
　　　Googleのアプリが
　　　　インストールされています。

　その中で、
　　Googleフォトを
　　　よく使います。

　フォト、つまり画像の管理に
　　使うアプリですね。

　私の使い方は、基本的に、
　　画像の整理が主になります。
　　　ほかには、画像の編集。

　書籍のスクショの
　　上下左右の余分な部分を
　　　カットする、なんてことですね。
***
　そんなGoogleフォトですが、
　　とある機能を
　　　今日まで見逃していました。

　それが
　　消しゴムマジック
　　　です。

　前からあったのは
　　目にしていたのですが、
　　　“ふぅん”とスルーして
　　　　いたのです。
　　　　　用がありませんでしたから。

　今回は、別に用があったわけでなく、
　　“使い方くらいは”という感じで
　　　使ってみたわけです。
***
　使い方は簡単です。

　まずはタップして起動。

　編集する画像を選択。

　“編集”をタップ。

　メニューが出てくるので、
　　その中から、“ツール”を選択。

　“ぼかし”
　“消しゴムマジック”
　“空”
　　の三つが出てきます。

　“消しゴムマジック”を選択。

　（少し時間がかかる）

　対象をなぞるか
　　輪で囲むと、
　　　少しの時間を待って、
　　　　それで消されます。

　それを
　　繰り返して、
　　　最終的にセーブするわけです。
***
　ここまで
　　書いてきて
　　　私はセーブできないことを
　　　　知りました。

　Google Oneに
　　加入しなければ
　　　ならないのです。

　まぁ、
　　そこまでの
　　　利用をするつもりも
　　　　ありませんので、
　　　　　ここまでです。

　ただ、
　　これはこれで
　　　使い場所次第で
　　　　有効かな、とは思いました。

　写真撮影して
　　余計なものが
　　　写り込んでいて消したい、
　　　　という場面でしょうか。

　あまり、
　　参考には
　　　なりませんでしたかね？

　今回は、ここまで。
LeetCode 201. Bitwise AND of Numbers Range の解き方メモ

https://leetcode.com/problems/bitwise-and-of-numbers-range/description/

LeetCode 201. Bitwise AND of Numbers Range の解き方メモです。問題は「LeftからRightの範囲にある整数すべてをAND演算した結果を求めなさい」とたいへんシンプルなのですが、結構てこずっちゃったので、考えた過程を残しておきたいと思います。

LeftからRightの範囲にある整数すべてをAND演算した結果をAとします。Aの右からNビット目が1である条件は、LeftからRightの範囲にある整数すべてについて、右からNビット目が1であることです (N>=1)。この条件を満たすのはどのような場合でしょうか? これを見極めるため、0から15までの2進数を観察します。

|10進数|2進数 |1ビット目|2ビット目|3ビット目|4ビット目|
|:-----|:-----|:--------|:--------|:--------|:--------|
|0     |0000  |0        |0        |0        |0        |
|1     |0001  |1        |0        |0        |0        |
|2     |0010  |0        |1        |0        |0        |
|3     |0011  |1        |1        |0        |0        |
|4     |0100  |0        |0        |1        |0        |
|5     |0101  |1        |0        |1        |0        |
|6     |0110  |0        |1        |1        |0        |
|7     |0111  |1        |1        |1        |0        |
|8     |1000  |0        |0        |0        |1        |
|9     |1001  |1        |0        |0        |1        |
|10    |1010  |0        |1        |0        |1        |
|11    |1011  |1        |1        |0        |1        |
|12    |1100  |0        |0        |1        |1        |
|13    |1101  |1        |0        |1        |1        |
|14    |1110  |0        |1        |1        |1        |
|15    |1111  |1        |1        |1        |1        |



この表をながめていると、ある整数Xの右からNビット目が1である条件は「Xを2^nでわったあまりが2^(n-1)以上であること」だとわかります。

(例: N=3の場合) 2^3=8でわったあまりが2^(3-1)=4以上の整数について、右から3ビット目が1。上表を見ると、8でわったあまりが4になる4と12、あまりが5になる5,13、あまりが6になる6と14、あまりが7になる7と15について、右から3ビット目が1になっていることがわかる。

したがって、Aの右からNビット目が1になるのは以下の条件を満たす場合であるとわかります。

1. LeftとRightを2^Nでわったときの商が同じ
2. LeftとRightを2^Nでわったときのあまりがどちらも2^(n-1)以上

(1.の条件が必要な理由 … LeftとRightを2^Nでわったときの商が違う場合、2^Nでわったときのあまりが0になる整数がLeftとRightの範囲に出現する)

あとは実装するだけ。すべてのNについて上記の条件を満たすかどうかチェックすればよいです。

```rust
impl Solution {
    pub fn range_bitwise_and(left: i32, right: i32) -> i32 {
        let left = left as u128;
        let right = right as u128;

        let mut ret = 0u128;
        for n in 1..=32 {
            let p = 2u128.pow(n-1);
            let q = 2u128.pow(n);
            if left/q==right/q && p<=left%q && p<=left%q {
                ret |= 1<<(n-1);
            }
        }

        ret as i32
    }
}
```
機能ライセンスの「フローユーザー」

現状(2024年2月23日)ではユーザの設定の中の「フローユーザー」もあるし、プロファイル、権限セットにも同じような設定がある。

+ [ユーザの設定画面から設定できる機能ライセンスの中に「フローユーザー」というものがあるかと思うのですが、こちらは「フローユーザー」でないとプロファイル等でフローの実行権限を付与していたとしても動かせないということなのでしょうか。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007YvwCm)

2019年の質問と回答では、機能ライセンスだけが言及されている。

Your users would only need a flow licence if they need to run the flow. So for example if you had a screen flow then users would need this feature licence to be able to run it.  As here it is an automated flow based on the process builder criteria the user's won't need the flow user feature licence.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8YbRSAV

最近の解説でも機能ライセンスは説明されていますね。

Examples of Common Feature Licenses

1. Marketing User: This is for users needing advanced marketing tools.
2. Flow User: Grants access to Salesforce’s workflow and automation features.
3. Knowledge User: Ideal for those managing knowledge bases within Salesforce.
4. Service Cloud User: Tailored for users requiring advanced customer service tools.

https://redresscompliance.com/salesforce-feature-licenses-how-do-they-work/


以下の解説を読むとwinter20からプロファイルや権限セットで制御できるようになったみたいです。


以前は、「フローを実行」、「フローの管理」、または「フローユーザ」権限を持つユーザは、すべてのフローを実行できました。このリリースでは、有効にされたプロファイルや権限セットへのアクセスを制限することで、ユーザが実行できるフローを制御できるようになりました。

https://help.salesforce.com/s/articleView?id=release-notes.rn_forcecom_flow_mgmnt_access.htm&release=222&type=5


Winter 24のリーリース更新ではフローを細かく指定できる（いやいや指定しないといけない。Apexクラスみたいなるんだろう）みたいですね。Winter '25 で強制適用かな？

フローを実行するためのユーザーアクセスの制限 (リリース更新)
https://help.salesforce.com/s/articleView?id=release-notes.rn_automate_flow_release_update_restrict_user_access.htm&release=246&type=5
Microsoft Copilot Studioを使って、石川県能登町災害支援情報を回答する会話型生成AIチャットボットを爆速で作る

Microsoft Copilot Studioを使って、石川県能登町災害支援情報を回答する会話型生成AIチャットボットを爆速で作ります。作成時間は約1時間程度です。ちなみに、この記事を書くのにはその倍ぐらい掛かっています。

**作成したサイトはこちらです**

https://notocho-chat.studio.site/

<br>
会話型で問い合わせることが出来ます。必要な情報を能登町役場のホームページより取得して、会話ベースで回答してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/30fae2a5-b1fb-1733-7115-93f847b5012e.png)


# 会話型生成AIチャットボットを作ろうと思い立った
石川県能登町役場のホームページを見れば、必要な情報は掲載されているのですが、「いま自分が欲しい情報のみ」に特化して探せるかというと、なかなかそういう訳には行きません。もちろん、ホームページの検索機能はあるので、検索することは出来るのですが、複数ページがヒットするので、それぞれのページを確認した上で、自分が必要な情報を自分で探す手間が残ります。

そこで、今回着目したのが、**Microsoft Copilot Studio**です。会話形式で問合せし、会話形式で生成AIが応答してくれるので、必要な情報にたどり着きやすくなります。また、参考にしている情報は能登町役場のホームページの情報であり、参照している情報のURLも合わせて教えてくれるので、最終的にはそちらを確認することで正確な情報を得ることができます。

# 現地の情報がなかなか得にくい人の役に立てば
石川県能登町では、他の地域と同様で空き家の課題などがあり、令和6年能登半島地震でも空き家も多くの被害が受けていると思われます。しかしながら、なかなか現地に行くことが出来なかったり、その手続きをどうしたら良いのかという課題もあると考え、そういった方が、まずはちょっと対応方法を調べてみるといった情報源になれば良いと思っています。

# Microsoft Copilot Studioとは

https://www.microsoft.com/ja-jp/microsoft-copilot/microsoft-copilot-studio

CopilotStudioとは、Microsoftが提供するエンドツーエンドの会話型AIプラットフォームです。自然言語またはグラフィカルインターフェイスを使用して、強力で接続されたコパイロットを作成およびカスタマイズできます。CopilotStudioを使用すると、業界、部署、役割の枠を超えて、さまざまなリクエストに対応するチャットボットを簡単に構築できます。

### Microsoft Copilot Studioの設定画面
このような画面で設定することが出来ます。いろいろ設定する必要はなく、チャットボットの名前やアイコンなどを設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/b187ecb6-5c2a-3c08-a4a3-caa652ca5123.png)

### 生成AIのデータソースの設定
「設定」メニューより、生成AIが参照するデータソースを指定することが出来ます。
Copilot Studioでは、公開WEBサイトの参照も可能なので、能登町役場のURLを入力しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/f21b1e3f-2402-0407-3ad1-30cdd2f8698d.png)

能登町役場のホームページはこちら

https://www.town.noto.lg.jp/www/normal_top.jsp

# STUDIOとは

https://studio.design/ja

STUDIOは、ノーコードでWEBサイトを構築できるツールで、コードを書く必要がなく、ドラッグ＆ドロップでサイトレイアウトや要素の配置が可能です。また、デザインテンプレートも数多くあるので、オシャレなサイト構築なども行うことが出来ます。また、作成したサイトは１クリックで公開まで出来ます。

今回は、埋め込みコードが使用できるサイトを素早く構築でき、かつ、公開までシームレスで実装できると考えて、STUDIOでサイト構築をしました。とは言っても、空のページを作成して、埋め込みコードにMicrosoft Copilot Studioで生成した埋め込みコードを埋め込んだだけです。

Micosoft Copilot Studioの連携先としては、Slack/LINE/Facebook/Teamsなどが利用できるのですが、今回は早く作ることを目標として、STUDIOを使用することに決めました。

# サイト公開にあたって

Microsoft Copilot Studioで会話側AIチャットボットを作成して、STUDIOで公開するまでにかかった時間は約１時間程度です。これで誰もが使いやすくという状況ではまだまだないとは思いますが、ちょっとでも助かる人がいたり、これが出来るならもっとこれも出来ないか？といった次の発想に繋がっていくサイクルも大切だと思っています。

知りたいことがある程度決まっているならチャットボット経由で問合せするのも良いと思いますし、幅広い情報をとにかく知りたいというのであれば、直接ホームページをいろいろ見てみるのも良いと思いますし。目的や使い方に合ったインターフェイスが用意されていくのが良いと思うので、ケースバイケースで利用してもらえたらと思います。

# 運用コスト
Microsoft Copilot Studioは有料サービスで、基本料金は、25,000円／月から利用可能です(2024年2月24日現在）。今回は、無料デモ版で作成しているので、約60日程度で利用がストップしてしまいますが、それまでにはもう少し状況も変わってくるかなと思うので、とりあえずプロトタイプとして公開しています。

# 最後に
開発に至った経緯や実際に作ってみた過程や想いなどはこちらにも記載しています。良かったら読んでください。

https://note.com/yukima77/n/nfb92ef8e59f1
MQL4、MQL5のファイルをGitHubで差分表示する方法

## やりたいこと
掲題の通り、MQL4,MQL5のファイルをGit(GitHub)管理するときに差分を表示するようにしたい。
デフォルトだと.mq4/5のどちらもバイナリファイルとしてgitに認識されてしまう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713320/718bdae8-22e7-6c1e-7576-8ab4eccc9810.png)


## 解決策
.gitattributesファイルに以下URLの適当なリポジトリからファイルを拾ってきて
ちょちょっと修正して利用しました。

https://github.com/orgs/EA31337/repositories

コメントは削除しております。
mq4/5ファイルに対してのみの設定で良い場合、無駄な記述も多いので適宜修正が必要かなと思います。

```
[attr]utf8 text eol=lf whitespace=blank-at-eol,-blank-at-eof,-space-before-tab,tab-in-indent,tabwidth=2
[attr]utf16 encoding=UTF-16LE-BOM working-tree-encoding=UTF-16LE-BOM diff merge eol=CRLF
[attr]binary  -text diff
*.ex?     binary
*.h       utf8 diff=c
*.json    utf8 diff=c
*.mq?     utf8 diff=c
*.mqproj  utf16 diff=c
*.txt     utf8 diff=c
```


### 結果
ちゃんと差分が表示されるようになります。
(お見せできる範囲が狭くて申し訳ないです)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3713320/6a0b2cb5-b246-756c-e71f-0dadd446a231.png)


## 注意点
私はWindowsユーザーなので`eol=lf`オプション(プロパティ？)は不要だったので削除しました。
Google Colabで韓国語を形態素解析

韓国語の勉強を始め、例文など集めていると、動詞の活用が不規則で困ります。たとえば「見た人」を意味する韓国語「온 사람」は、「見る  오다)」の語幹「오」に過去連体形を示す「ㄴ」が付いて「온」になるのですが、一文字の中で変化があるので検索しにくいですね。

というわけで日本語の形態素解析のように韓国語でも形態素解析できないか探してみました。

今回、試してみたのはkonlpyというライブラリ。このライブラリ自体はmecabを含む５つの[tag Package](https://konlpy.org/en/latest/api/konlpy.tag/)を選べるのですが、このうちkkmaがGoogle Colabでも動かせましたので、こちらを使っていくことにします。（他のパッケージは動かせませんでした。誰か動かせたという情報あれば教えてください）

https://konlpy.org/en/latest/

まず、関連パッケージをインストールします。ipywidgetsを入れておくと、入力する文字列をいちいちコードに貼らなくてもインタラクティブに入力できるので、おすすめです。

```py
!pip install konlpy
!pip install mecab-python3

from konlpy.tag import Kkma
from konlpy.utils import pprint

!pip install ipywidgets
from ipywidgets import interact
```

本体のコードはこちら。ipywidgetsでインタラクティブに使いたいので、適当な関数名を付けています。

```py
s = "기억이 돌아온 거야?"
def func(s):
  for line in s.split('\n'):
    print(line)
    poslist = Kkma().pos(line,flatten=False, join=False)
    for tags in poslist:
      if tags[0][1] == "VV" or tags[0][1] == "VA" : # 動詞または形容詞
        word = ""
        part = ""
        for tag in tags:
          word = word + " "+ tag[0]
          part = part + " "+ tag[1]
        print(word+" / "+part)
interact(func,s=s)
```
postlistをpprintすると、名詞などすべての品詞が出てきますが、今回は動詞(VV)の活用だけを見たいので絞り込んでいます。

実行すると、このように動詞を品詞ごとに分解した結果が出てきます。
```
기억이 돌아온 거야?
 돌아오 ㄴ /  VV ETD
```

文字列を入力する欄がありますので、そこにコピペすると何度でも解析できて便利ですね。
プロセスの自動化設定



+ [ 自動化プロセスユーザのメールアドレスが無効であるため、このフローでアクションまたはエラーのメールを送信できません。[設定] の [プロセスの自動化設定] ページの [自動化プロセスユーザのメールアドレス] でシステム管理者プロファイルの組織のメールアドレスを指定する必要があります。](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007ZBv99)

:::note
過去の回答では　組織のメールアドレスに変更したいメールアドレスを追加し再度お試しください　とありますね。

https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000C5uWMSAZ
:::

# Utility Bar

+ [ユーティリティバーに追加した画面フローが表示されない](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007UtJkl)

:::note
フローの実行権限が必要みたいです。

URL または [設定] から起動されるフローでは、Classic ランタイム環境ではなく Lightning ランタイム環境が使用されます。Lightning ランタイムでのみ 2 列フロー画面、カスタム画面コンポーネント、ローカルアクションがサポートされます。

フローの Lightning ランタイムを有効化
設定 --> プロセスの自動化設定


And the answer is ...

+ If the only item in the Utility Bar is a Flow, and ...
+ The running user is not a Flow User (in user record) or does not have Manage Flows or Run Flows permission (in either profile or Permission Set)


Then, even if the specific flow in the Utility Bar has been granted to a Profile or Permission Set assigned to the running user, the absence of the Flow User/Manage Flows/Run Flows will prevent the Utility Bar from even displaying (as empty or with the flow).

In my use case, I needed to add the Run Flows permission to the Permission Set that granted access to the flow - thus encapsulating all the required permissions for the flow in one place. 

https://salesforce.stackexchange.com/questions/300831/utility-bar-doesnt-appear-in-lightning-app-for-certain-users
:::

# プロセスの自動化設定

プロセスまたはフローインタビューが失敗した場合、Salesforce は、実行されたすべての処理および何が失敗したかについての詳細を含むメールを送信します。この詳細には、ユーザーが入力したデータなど、プロセスまたはフローに関与したデータが含まれます。

ここで以下の設定のメールにエラーを返すことができる

+ [Apex 例外メール通知の設定](https://help.salesforce.com/s/articleView?id=000385876&type=1)
Evolotionary alogrithm

## 3.2 Evolotionary alogrithm
## 概要
3.2章では、Cartesian genetic programming (CGP)という直接符号化方式を用いてCNNの構造と接続性を表現する方法について説明しています。CGPは、計算ノードの二次元グリッドでプログラムを有向非巡回グラフとして定義します。各ノードには、ConvBlock, ResBlock, max pooling, average pooling, concatenation, summationなどの高機能モジュールをノード関数として採用しています。これらのノード関数は、CNNでよく使われる処理をまとめたもので、探索空間を削減する効果があります。CGPで表現されたCNNの構造は、訓練データセットで学習した後、バリデーションデータセットでの精度を適応度として評価します。その適応度に基づいて、進化的アルゴリズムがCNNの構造を最適化します。具体的には、強制突然変異と中立突然変異を組み合わせた(1+λ)進化戦略を用いています。強制突然変異は、少なくとも一つの有効ノードを変化させるように突然変異を適用することで、並列計算を効率的に利用します。中立突然変異は、有効ノードを変化させずに無効ノードのみを変化させることで、CGPの進化に有効な中立ドリフトを維持します。このようにして、CGPはCNNの構造を柔軟に表現し、適応的に探索することができます。

## 強制突然変異について
強制的な突然変異とは、個体の遺伝子を変化させる際に、少なくとも一つの有効ノード（出力ノードにつながっているノード）が変化するまで突然変異を繰り返すことである。
強制的な突然変異は、適応度の改善が見られない場合に、親個体に対して中立的な突然変異（有効ノードを変化させない突然変異）を適用することで、中立的な探索を維持しながら、個体の多様性を高めることができる。
強制的な突然変異は、CNNのアーキテクチャの探索において、有効ノードの数や深さに制約を設けることなく、適切な構造を見つけることができる。
強制的な突然変異を用いた遺伝的アルゴリズムは、CIFAR-10データセットにおいて、手作りのCNNや強化学習によるCNNの設計法と競合する性能を示した。
## 中立突然変異
この論文では、中立突然変異という手法を用いて、CNNのアーキテクチャを効率的に探索する方法を提案しています。中立突然変異とは、CGPの表現において、表現型に影響を与えないように遺伝子を変化させることです。この手法の利点は、中立な探索によって、局所最適解から脱出しやすくなることや、フィットネス評価の回数を減らすことができることです。論文では、中立突然変異を親個体に適用することで、(1+λ)進化戦略を改良したアルゴリズムを提案しています。実験の結果、中立突然変異を用いた方が、用いない場合よりも高い分類精度のCNNアーキテクチャを見つけることができたと報告しています。
## CGPについて

CGP（Cartesian Genetic Programming）は、遺伝的プログラミングの一種であり、プログラムを二次元グリッド上のノードとして表現します。この手法は、異なるノード関数を組み合わせてプログラムを構築することができ、変数長のネットワーク構造やスキップ接続を柔軟に表現できます。CGPは、畳み込みニューラルネットワーク（CNN）のアーキテクチャを自動的に構築するためにも利用されています。

具体的には、CGPを用いてCNNのアーキテクチャを進化的に最適化する際に、異なるノード関数（畳み込みブロック、レジューダルブロック、プーリング、結合、和など）を組み合わせて遺伝子プログラムを生成します。このプログラムは、学習データセットで訓練され、バリデーションデータセットでの分類精度を適応度として評価されます。CGPは、CNNのアーキテクチャの柔軟な探索と最適化に貢献しています。
Quail-UI: 超シンプルなVue3のUIライブラリ

元々は[Quaily](https://quaily.com)用に作られましたが、後に独立させることにしました。

- リポジトリ: https://github.com/quailyquaily/quail-ui
- デモ: https://quailyquaily.github.io/quail-ui

UIライブラリは数多くありますが、新たに作成した理由は、不必要な依存関係を減らしたい、まだ遭遇していない問題を解決したくない、というものです。唯二の依存関係であるdays.jsも、実際には削除可能で、そのうち削除する予定です。

目的：シンプルさと、私が少し芸を楽しめること（例：Switchコンポーネント）

Vueに依存しているのは、多くのフロントエンドツールに頼らずに済むため、そしてビルドが完了すればすぐに使用できるためです。これは私のような怠け者にとって非常に重要です：

```html
<script type="importmap">
{
  "imports": {
    "vue": "https://cdn.jsdelivr.net/npm/vue@3.3.9/dist/vue.esm-browser.prod.js",
    "quailui": "https://static.quail.ink/assets/quail-ui/0.2.45/index.js",
  }
}
</script>
<script type="module">
  import * as Vue from "vue";
  import QuailUI from "quailui";
  
  const { createApp, ref, onMounted } = Vue;
  const app = createApp({
    // ...     
  });

  app.use(QuailUI, {debug: true});
  app.mount("#app");
</script>
```
FreeBSDでstan

# cmdstan

cmdstanはstanに、stanはstanmathに、stanmathはTBBに依存していて、サブモジュールとしてツリーの中に持っています。
```zsh
%ls stan/lib/stan_math/lib/tbb_2020.3
```
pkgのonetbbはバージョンが新しく、うまく行かなかったので、tbb_2020.3をコンパイルして別の場所にインストールすることにします。また、stanのソースをC++にコンパイルするstancはバイナリをダウンロードしていますが、FreeBSD用のバイナリは提供されていませんので、ソースからコンパイルします。

まずは、リポジトリから依存関係を含めてソースを取得します。
```zsh
git clone --recursive https://github.com/stan-dev/cmdstan.git
```

FreeBSDを認識するように`make/stanc`を編集します。
```zsh
% git diff make/stanc
diff --git a/make/stanc b/make/stanc
index e860ac5..b0c3c1c 100644
--- a/make/stanc
+++ b/make/stanc
@@ -36,7 +36,8 @@ else ifeq ($(OS),Linux)
 	ARCH_TAG := -armhf
   endif
  endif
-
+else ifeq ($(OS),FreeBSD)
+  OS_TAG := FreeBSD
 else
   $(error  Cannot detect OS properly. $n This will impede automatically downloading the correct stanc. $n Please visit https://github.com/stan-dev/stanc3/releases and download a stanc binary for your OS and place it in ./bin/stanc. $n )
 endif
```

stancのソースとTBBのインストール先を指定します。
```zsh
% cat make/local
CXX = c++
TBB_CXX_TYPE = clang
TBB_LIB = ${HOME}/.local/lib 
STANC3 = ${HOME}/src/stanc3
```

## stanc3

既定ではstancはバイナリをダウンロードします。FreeBSD用はないので、Not Foundと書かれたファイルができてしまいます。[getting_started](https://mc-stan.org/stanc3/stanc/getting_started.html)を参考にソースからコンパイルします。stanc3は[OCaml](https://www.ocaml.org/)で書かれていますので、OCamlのインストールも必要です。

cmdstanのmake/localに指定したパス（上の例では${HOME}/src/stanc3）に取得します。
```zsh
git clone https://github.com/stan-dev/stanc3.git
```

OCamlのインストールには、GNU patch必要なので、インストールします。
```
# pkg install patch
``
[Install OCaml](https://www.ocaml.org/install)の通りにインストールします。
```
bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"
opam install ocaml-lsp-server odoc ocamlformat utop
```

新しいターミナルを立ち上げて、stancをビルドします。
```zsh
opam update; opam install --deps-only --with-test .
```
バイナリは`_build/default/src/stanc/stanc.exe`
にできます。

## tbb_2020.3

tbbのディレクトリに移動して、ビルドします。pkgのonetbbとコンフリクトしないように、`${HOME}/.local`にライブラリとヘッダをインストールしました。

```zsh
% cd stan/lib/stan_math/lib/tbb_2020.3
% gmake
% cp build/FreeBSD_intel64_clang_cc16.0.6_kernel14.0_release/libtbb.so ~/.local/lib
% cp build/FreeBSD_intel64_clang_cc16.0.6_kernel14.0_release/libtbbmalloc.so ~/.local/lib
% cd ~/.local/include
% ln -s ${OLDPWD}/include/tbb .
```

最後にcmdstanをインストールして、例をビルド、実行して動作確認をします。
```
gmake build
gmake examples/bernoulli/bernoulli
```

## rstan

FreeBSDでは~/.R/Makevarsに2行追加する必要があります。
* TBBのインターフェースが変更され、古いヘッダは削除されたので、プリプロセッサフラグで新しいものを使うことを指定します。
* `libtbb.so`だけでなく`libtbbmalloc.so`もリンクする必要があります。
[gist](https://gist.github.com/tenomoto/65f43286aa6966bbbf2a8e6dca4c3699)にも`Makevar`のサンプルを置きましたが、ここにも書いておきます。

```Make
CPPFLAGS+= -DTBB_INTERFACE_NEW=true
LDFLAGS+= -ltbb -ltbbmalloc
```

以上の変更をすれば、Rから`install.packages("rstan")`でコンパイルはうまくいきます。
【kintone】複数のレコードの更新-kintone Rest API(初心者/入門)

# はじめに
[前回](https://qiita.com/pomo/items/623baa1a1e037990366a "複数のレコード取得")はRESTAPIを使用した`複数のレコードの取得`を試しました。

今回は`複数のレコードの更新`のサンプルになります。

## 手順
1. アプリの設定は前回と同じとします。前回の記事と同じように`数値`フィールドを設定してください。
1. 下記コードをコピペ保存してアプリ更新
1. 一覧でボタンを押下して実行

## 説明
今回は`数値が1`という値を持つレコード全てを取得し、`数値を２`という値に書き換えるだけのサンプルです。
- putBodyにappと更新するrecordsを記述します
- recordsは,`{id:レコードのID, record:{フィールドコード:{value:値}}}`という各レコードの更新するデータの配列を入れてあげることで、各レコードの指定したフィールドの値を更新できます

処理として今回は、
1. 取得してきたレコードをmapでレコード数分回っていき、全て2という値に書き換える
1. putBodyのrecordsに`records.map`を使用するとreturnで返ってきた内容が**配列で作成**されます。シンプルに配列を作成するに使える関数です




# コード
```test.js
(() => {
  "use strict";

  // ボタン押下時に書きかえる
  const testFunction = async () => {
    const appId = kintone.app.getId();

    const body = {
      app: appId,
      query:
        '数値 = "1"',
    };
    const res = await kintone.api(
      kintone.api.url("/k/v1/records.json", true),
      "GET",
      body
    );
    const records = res.records;
    if(records.length === 0){
      alert("recordsの取得ができませんでした。数値が1のレコードがありません")
      return
    }

    // 取得したrecordsの数値の合計
    records.map((record) => {
      // 取得した対象のレコードを2という値に書き換える
      record["数値"].value = 2;
    });

    // 書き換えたレコードをmapでまわしながら対象のフィールドだけ更新
    const putBody = {
      app: appId,
      records: records.map((record) => {
        return {
          id: record["レコード番号"].value,
          record: {
            数値: {
              value: record["数値"].value,
            },
          },
        };
      }),
    };

    console.log(putBody);

    await kintone.api(
      kintone.api.url("/k/v1/records.json", true),
      "PUT",
      putBody
    );

    // 画面の更新
    location.reload();
  };

  // レコードの一覧画面で実行していきます
  kintone.events.on("app.record.index.show", (event) => {
    // ボタンの設置と作成
    const button = document.createElement("button");
    button.innerText = "実行";
    button.addEventListener("click", testFunction);

    // kintoneに表示する要素（位置）を取得して、ボタンを設置。
    const el = kintone.app.getHeaderMenuSpaceElement();
    el.appendChild(button);

    // 必ずeventを返してあげる
    return event;
  });
})();
```

## おわりに
今回は`複数のレコードの更新`をRESTAPIを使って行いました。
取得してきたレコードを一気に書き換える際に便利ですね。

それでは
 ### 楽しいkintoneライフを:relaxed:

また参考は下記に貼っておきます。


## 参考
https://cybozu.dev/ja/kintone/docs/rest-api/records/update-records/
スタックとキュー（LIFOとFIFO）【Algorithm-Data構造入門Ⅲ】

# LIFOとFIFOとは
## LIFO
**LIFO**(Last In, First Out)は、最後に追加された要素が最初に取り出されるデータ構造です。これは、例えば本棚に本を積み重ねるようなイメージです。新しい本を最後に追加し、必要なときには一番上の本から取り出します。

## FIFO
**FIFO**(First In, First Out)は、最初に追加された要素が最初に取り出されるデータ構造です。これは、例えば列に並ぶ人々や食料品のレジの待ち行列などのイメージです。最初に並んだ人や商品が最初に処理されるという原則です。

# スタックとキュー
## スタック
### スタックとは
スタックは、**LIFO**のデータ構造であり、新しい要素がスタックの一番上に追加され、最も新しい要素が最初に取り出されます。

### 自作関数を使用した例
```python
class Stack:
	def __init__(self):
		self.items = []

	# 	タックの先頭に要素を追加
	def push(self, item):
		self.items.append(item)

	# 	タックの先頭から要素を削除
	def pop(self):
		return self.items.pop()

	# 	タックの先頭の要素を取得
	def peek(self):
		return self.items[-1]

	# 	タックのサイズを取得
	def size(self):
		return len(self.items)

# スタックの使用例
s = Stack()
s.push("A") # スタック: ["A"]
s.push("B") # スタック: ["A", "B"]
s.push("C") # スタック: ["A", "B", "C"]
print("スタックのサイズ:", s.size())  # 出力: 3
print("スタックのトップ:", s.peek())  # 出力: C
print("ポップされた要素:", s.pop())  # 出力: C
```
### collectionsモジュールを使用した例
```python
from collections import deque

# dequeを使用したスタックの例
stack = deque()
stack.append("A")
stack.append("B")
stack.append("C")
print("スタックのサイズ:", len(stack))  # 出力: 3
print("スタックのトップ:", stack[-1])  # 出力: C
print("ポップされた要素:", stack.pop())  # 出力: C
```

## キュー
### キューとは
キューは、FIFO（First In, First Out）のデータ構造であり、新しい要素がキューの末尾に追加され、最も古い要素が最初に取り出されます。

### 自作関数を使用した例
```python
class Queue:
	def __init__(self):
		self.items = []

	# キューの末尾に要素を追加
	def enqueue(self, item):
		self.items.append(item)

	# キューの先頭から要素を削除
	def dequeue(self):
		return self.items.pop(0)

	# キューの先頭の要素を取得
	def size(self):
		return len(self.items)

# キューの使用例
q = Queue()
q.enqueue("A") # キュー: ["A"]
q.enqueue("B") # キュー: ["A", "B"]
q.enqueue("C") # キュー: ["A", "B", "C"]
print("キューのサイズ:", q.size())  # 出力: 3
print("キューの先頭:", q.dequeue())  # 出力: A キュー: ["B", "C"]
print("キューの先頭:", q.dequeue())  # 出力: B キュー: ["C"]
```

### collectionsモジュールを使用した例
```python
from collections import deque

Queue = deque()

# キューの末尾に要素を追加
def enqueue(item):
	Queue.append(item)

# キューの先頭から要素を削除
def dequeue():
	return Queue.popleft()

# キューのサイズを取得
def size():
	return len(Queue)

# キューの使用例
enqueue("A")
enqueue("B")
enqueue("C")
print("キューのサイズ:", size())  # 出力: 3
print("キューの先頭:", dequeue())  # 出力: A
print("キューの先頭:", dequeue())  # 出力: B
```

# まとめ
スタックとキューは、データを一時的に保存し、処理順序を制御するための重要なデータ構造です。Pythonでは、リストやcollectionsモジュールを使用して簡単に実装できます。これらのデータ構造を理解し、適切に活用することで、効率的なアルゴリズムとデータ処理が可能となります。