OmniAICreator/Qiita-1.07M huggingface dataset:
【syncfusion】DiagramComponentでパンツールをミドルクリックで有効にする

## 背景
syncfusionの描写ツール（DiagramComponent）で、マウスのミドルボタン（ミドルクリック）・ホイールボタンを押すことで、パンツールを有効にし、そのまま長押し&ドラッグで、画面を掴んで移動できるような挙動を実装したい。

使っているプログラミング言語は、ReactjsとTypescriptです。

今回はsyncfusionを使っているが、マウスのミドルボタンでパンツールを有効にする実装が必要な場合は、応用ができると思います。

## やること

![image-236.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256394/df87ef6f-e303-ad56-d2cd-b50005d7676f.png)

上図のような画面で、ミドルボタンを押すとパンツールが有効になり、カーソルが手のアイコンみたいなものに変化し、描写画面を掴んで移動させることができるようにする。伝わるかな……

## Syncfusionとは？
Syncfusionは、2001年にアメリカ・ノースカロライナ州で設立されたソフトウェア企業です。同社の代表的な製品は、ビジネス用途を中心に、さまざまなアプリケーションにリッチなユーザーインターフェースを提供するコンポーネントライブラリです。
今回使用するのも、このSyncfusionの有償ライブラリで、幅広い用途に対応できる強力なツールセットを提供しています。


## 実装例

```react:pantool.tsx
useEffect(() => {
    const handleMouseDown = (event: MouseEvent) => {
      if (event.button === 1 && diagramInstance.current) {
        // ミドルボタンを押したときに、パンツールを有効にする
        diagramInstance.current.tool = DiagramTools.ZoomPan;
        // ミドルボタンで左クリックの動作をシミュレートする
        const mouseDownEvent = new MouseEvent('mousedown', {
          clientX: event.clientX,
          clientY: event.clientY,
          button: 0, // 左クリックを意味する
        });
        diagramInstance.current.diagramCanvas.dispatchEvent(mouseDownEvent);
        event.preventDefault();
      }
    };

    const handleMouseUp = (event: MouseEvent) => {
      if (event.button === 1 && diagramInstance.current) {
        // ミドルボタンを離したときに、パンツールを無効にする（デフォルトツールに戻す）
        const mouseUpEvent = new MouseEvent('mouseup', {
          clientX: event.clientX,
          clientY: event.clientY,
          button: 0, // 左クリックを意味する
        });
        diagramInstance.current.diagramCanvas.dispatchEvent(mouseUpEvent);
        diagramInstance.current.tool = DiagramTools.Default;
      }
    };

    window.addEventListener('mousedown', handleMouseDown);
    window.addEventListener('mouseup', handleMouseUp);

    return () => {
      window.removeEventListener('mousedown', handleMouseDown);
      window.removeEventListener('mouseup', handleMouseUp);
    };
  }, []);
```


## ミドルクリックによるパンツールの実装解説

### useEffectフックの利用
useEffectは、Reactのライフサイクルメソッドに相当し、コンポーネントのマウントやアンマウント時に副作用（イベントリスナーの追加・削除）を実行するために使います。
このコードでは、マウスのmousedownおよびmouseupイベントに対するリスナーを追加しています。

### handleMouseDown関数
この関数は、マウスのmousedownイベント（ボタンが押されたとき）を処理します。

`event.button === 1`は、ミドルボタン（ホイールボタン）が押されたことを意味します。

`diagramInstance.current.tool = DiagramTools.ZoomPan`
で、パンツールを有効にしています。DiagramTools.ZoomPanはsyncfusion特有なので、syncfusionを使っていない場合は、この部分をuseStateのState更新とかに置き換えて、パンルールを有効にするような実装を施せばいけそうな気がする。
この設定により、ミドルクリックで画面を移動できるようになります。

ミドルボタンで左クリックの動作をシミュレートするために、MouseEventオブジェクトを生成し、`button: 0`として左クリック相当のイベントを作成します。このイベントをdiagramCanvasに対して発火し、実際のクリック動作をシミュレートしています。

### handleMouseUp関数
この関数は、マウスのmouseupイベント（ボタンが離されたとき）を処理します。
ミドルボタンを離したら、元のマウス操作に戻って欲しいので、マウスのmouseupイベントを拾いたいのです。

同じく`event.button === 1`でミドルボタンが離された場合に、左クリック相当のmouseupイベントをシミュレートします。
diagramInstance.current.tool = DiagramTools.Defaultで、パンツールを無効にし、通常のツールに戻す動作を行います。


### イベントリスナーの追加と削除
window.addEventListenerを使用して、mousedownとmouseupのイベントリスナーをウィンドウに追加しています。
これにより、どこでマウス操作が行われても、パン機能が働くようになります。

## お疲れ様でした。
わからないところ、間違っているところ、もっといい方法がある場合は、コメントでもDMでも教えてください。
AtCoder 勉強記録[C++] その62

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## A - Raise Both Hands
[A - Raise Both Hands](https://atcoder.jp/contests/abc370/tasks/abc370_a)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define mod 998244353

int main() {
  int l, r;
  cin >> l >> r;
  if(l==1 && r==0){
    cout << "Yes" << endl;
  } else if(r==1 && l==0){
    cout << "No" << endl;
  } else {
    cout << "Invalid" << endl;
  }
}
```
### 解法
`L=1, R=0`の場合、`L=0, R=1`の場合、それ以外の場合で分けて考えることで結果がもとまる。
## B - Binary Alchemy
[B - Binary Alchemy](https://atcoder.jp/contests/abc370/tasks/abc370_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define mod 998244353

int main() {
  int n;
  cin >> n;
  vector<vector<int>> a(n, vector<int>(0));
  for(int i = 0; i < n; i++){
    for(int j = 0; j <= i; j++){
      int x;
      cin >> x;
      a[i].push_back(x);
    }
  }
  int ele = 1;
  for(int i = 0; i < n; i++){
    if(ele-1 >= i){
      ele = a[ele-1][i];
    } else {
      ele = a[i][ele-1];
    }
  }
  cout << ele << endl;
}
```
### 解法
生成した元素と1からNまでの元素を合成し続けることで結果がもとまる。
## C - Word Ladder
[C - Word Ladder](https://atcoder.jp/contests/abc370/tasks/abc370_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define mod 998244353

int main() {
  string s, t;
  cin >> s >> t;
  int sz = s.size();
  vector<string> res;
  while(t != s) {
    string nex(sz, 'z');
    for(int i = 0; i < sz; i++){
      if(t[i] != s[i]){
        string tmp = s;
        tmp[i] = t[i];
        nex = min(tmp, nex);
      }
    }
    res.push_back(nex);
    s = nex;
  }
  sz = res.size();
  cout << sz << endl;
  rep(i, sz) cout << res[i] << endl;
}
```
### 解法
`T[i]!=S[i]`となる`S[i]`を全て`T[i]`に変換することで結果がもとまる。その際に操作後の文字列が辞書順で最小であるかを判定する。
たった5分でできる！Bazelを使ってHello World.ccをビルドする方法

## Google生まれの優等生なビルドツール<br> 速く、きれいに、どの言語でも

Bazelは、Googleが開発したビルドツールで、大規模なプロジェクトでも高速かつ再現性のあるビルドを実現します。

具体的には以下の特徴があります。
- 多言語・マルチプラットフォーム対応
- 高速で並列ビルドが可能
- クリーンなビルド（ディレクトリを汚染しない）
- 人が読める高レベルのビルド言語

今回はこんな素敵なツール、Bazelを使って簡単なC++プログラムをビルドする方法を紹介します。

## 1. Bazelのインストール

まず、Bazelをインストールします。macOSの場合は以下のコマンドでインストールできます：

```sh
brew install bazel
```

Ubuntuの場合は、[公式ドキュメント](https://bazel.build/install/ubuntu)を参照してください。

## 2. プロジェクト構造の作成

以下のような構造でプロジェクトを作成します：

```
WORKSPACE
main/
├── BUILD
└── hello-world.cc
```

## 3. WORKSPACEファイルの作成

ルートディレクトリに`WORKSPACE`ファイルを作成し、以下の内容を記述します：

```python
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

http_archive(
    name = "aspect_gcc_toolchain",
    sha256 = "3341394b1376fb96a87ac3ca01c582f7f18e7dc5e16e8cf40880a31dd7ac0e1e",
    strip_prefix = "gcc-toolchain-0.4.2",
    urls = [
        "https://github.com/aspect-build/gcc-toolchain/archive/refs/tags/0.4.2.tar.gz",
    ],
)

load("@aspect_gcc_toolchain//toolchain:repositories.bzl", "gcc_toolchain_dependencies")

gcc_toolchain_dependencies()

load("@aspect_gcc_toolchain//toolchain:defs.bzl", "gcc_register_toolchain", "ARCHS")

gcc_register_toolchain(
    name = "gcc_toolchain_x86_64",
    target_arch = ARCHS.x86_64,
)
```

## 4. ソースコードの作成

`main/hello-world.cc`ファイルを作成し、以下のコードを記述します：

```cpp
#include <ctime>
#include <string>
#include <iostream>

std::string get_greet(const std::string& who) {
  return "Hello " + who;
}

void print_localtime() {
  std::time_t result = std::time(nullptr);
  std::cout << std::asctime(std::localtime(&result));
}

int main(int argc, char** argv) {
  std::string who = "world";
  if (argc > 1) {
    who = argv[1];
  }
  std::cout << get_greet(who) << std::endl;
  print_localtime();
  return 0;
}
```

## 5. BUILDファイルの作成

`main/BUILD`ファイルを作成し、以下の内容を記述します：

```python
load("@rules_cc//cc:defs.bzl", "cc_binary")

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
)
```

## 6. ビルドと実行

以下のコマンドでプログラムをビルドします：

```sh
bazel build //main:hello-world
```

ビルドが成功したら、以下のコマンドで実行できます：

```sh
./bazel-bin/main/hello-world meithon
```

出力例：

```
Hello meithon
Wed Sep 11 21:03:22 2024
```

以上で、Bazelを使ってC++プログラムをビルドする方法を紹介しました。簡単でしたね！

## What's next ✨

Bazelを使って他の言語のプログラムをビルドする方法も同じようにできます。公式ドキュメントを参照することで、TypeScriptやGo、Rustなどの言語での使用方法も学ぶことができます。

https://github.com/bazelbuild/rules_go

https://github.com/aspect-build/rules_ts

また、Bazelを使ったビルドの高速化や便利な機能なども公式ドキュメントで紹介されています。さらに詳しく知りたい方は以下のページを参照してください

https://bazel.build/extending

---

実際のプロジェクトにおける、Bazelの活用方法などもあれば記事にしていきたいと思います！

ここまで読んでいただき、ありがとうございます。
いいねやシェアはとても励みになりますので、ぜひ宜しくお願いいたします！
【AWS】セキュリティグループとネットワークACLの使い分け

# 背景
先日、後輩からAWSについてのヘルプを求められました。あるIPアドレスからの通信を許可したいが、うまく設定できていないのか、リクエストに対してレスポンスを確認できない、とのこと。イメージは以下の通り（相談時と内容を少し改変しています）。

![スクリーンショット 2024-09-11 11.02.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448259/65bd60e2-8b2d-db86-6220-0bb07a90340b.png)

どうも、**ネットワークACLを用いて送信元を制限しようとしていた**らしいが、うまくいかないらしい。レスポンスの通信でポートを443にすると上手くいかず、全ポート許可するとレスポンスが返せているとのこと。ただ、それではセキュリティ上良くないのでは？とのことで相談を受けた。とりあえず動くけど、良くないのでは？と考える姿が素晴らしい。

# セキュリティグループとネットワークACLの違い
本題に入っていく前に、セキュリティグループとネットワークACLの違いについておさらい。後輩にはこのあたりの違いを改めて説明しました。細かい違いもありますが、ざっくり記載します。
| セキュリティグループ | ネットワークACL |
|:-:|:-:|
| **ステートフル**であり、リクエストに対するレスポンスは自動で許可される | **ステートレス**であり、リクエストだけではなくレスポンスに対しても明示的な許可が必要 |
| **AWSリソース**に対して関連付けをする | **サブネット**に対して関連付けをする |
| 通信の**許可**のみ可能 | 通信の**許可**及び**拒否**が可能 |

セキュリティグループで特定のセキュリティグループを許可できるというのも特徴ですね。

# 解決編
さて、私のこれまでの知識&経験上、ネットワークACLを使うケースはほぼありませんでした。セキュリティグループで満たせない要件がある場合はネットワークACLを使っていくという感じです。

そのため、まずは「セキュリティグループを使って制御したら？」と回答しました。後輩曰く、「社内のものなので、可能な限りセキュリティは厳しめの方が良いのではと思った」とのこと。

それ対して、「セキュリティグループでもIPとPortで制限掛けられるから問題ない」と返しました。その後、セキュリティグループを使うように修正したところ、上手くいったと連絡を受けました。

めでたしめでたし…なんですが、ちょっと回答として不十分だったなと後から思い、少し追加で調査&補足しました。

# なぜセキュリティグループではないといけなかったのか
そもそも、ネットワークACLでポートを全許可したら上手くいく、というところが一つのポイントでした。リクエストのプロトコルはHTTPで、443を許可すれば良いというのは当然の感覚ですが、レスポンスのポートは443なのでしょうか？

HTTPでは、**レスポンス時のポートはエフェメラルポートから割り当て**されます。つまり、レスポンス時のポートは事前には分からないということになります。そのため、ネットワークACLでポート全許可をすればレスポンス可能だが、あるポートだけ許可してもレスポンスはできなかった（許可されたポートではなかったため）ということになります。

セキュリティグループではステートフルであり、レスポンスの通信は自動で許可されるため、レスポンスのポート番号を意識しなくても良いという点で、今回のケースではセキュリティグループを採用した方が良かったということです。

# セキュリティグループとネットワークACLの使い分け
じゃあ基本セキュリティグループでいいじゃん！ネットワークACLはどこで使うの？という話になります。あくまで個人の感覚になりますが、ネットワークACLの方はデフォルトの全許可にし、セキュリティグループで制御することを第一に考えればOKだと思います。ネットワークACLはリクエストとレスポンス両方で設定が必要になるため、管理が煩雑になることが懸念されます。

また、ネットワークACLでは「拒否」ルールが設定できるので、特定サーバへの通信または特定サーバからの通信を制限したい場合に利用するのが良いかなと思います。例えば、VPC内部からウイルス感染の恐れがあるサーバへのアクセスを拒否したい場合であったり、外部から不正アクセスの恐れがある送信元を拒否したい場合などでしょうか。

# まとめ
* 特定の通信を「許可」したい場合はセキュリティグループで対応(基本はこちらで十分)
* 特定の通信を「拒否」したい or 厳しいセキュリティ要件がある場合はネットワークACLで対応

最後まで記事をご覧いただきありがとうございました！もし私はこういう使い分けしているよ、みたいな話があれば教えていただきたいです！
【VirtualBox】VirtualBox上にCentOS9をインストールしようとするとカーネルパニックになった話

◆環境
　・VirtualBox-7.0.20
　・CentOS 9

◆症状
　仮想マシン作成後、isoイメージをマウントして仮想マシンを起動すると以下の状態に。
 
 ![スクリーンショット 2024-09-11 213000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761139/1fabf682-ab05-d4c3-69dd-e02304495598.png)

◆原因
　メモリ容量をデフォルト値で仮想マシンを作成したこと。
 
◆解決策
　デフォルト値の「2048MB」→「4096MB」に変更したところカーネルパニックが解消され、無事インストールに進みました。

　![スクリーンショット 2024-09-11 215538.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761139/7d59e802-9032-6e80-1d2e-8838a41c3e3b.png)
![スクリーンショット 2024-09-11 215505.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3761139/1047eeb4-ef59-1ef9-1820-14646ef66b8f.png)
[Industrial Engineering] 最適発注量 

# 式
``年間需要量``: R
``1回あたりの発注量``: Q
``1回あたりの発注費用``: C 
``1個あたりの年間保管費用``: H 




|Title||Answer|
|:--|:--|:--|
|発注回数|``年間需要量`` / ``1回あたりの発注量``|R / Q|
|②発注費用|``発注回数`` * ``1回あたりの発注費用``|(R / Q)*C|
|①保管費用|``平均発注量``(=``1回あたりの発注量``/2) * ``1個あたりの年間保管費用``|(Q / 2)*H|
|③経済的発注量|(R / Q)*C = (Q / 2)*H|Q = |√(2RC / H)|
|④総費用|① + ②|(R / Q)*C + (Q / 2)*H|


# Image
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/754ffba6-91f6-7c81-9047-d7462e9cb072.png)


# 参考リンク
- [令和2秋75](https://www.ap-siken.com/kakomon/02_aki/q75.html)
社内業務システムの引継ぎにおいて本当に必要なドキュメントとは何か？

筆者の様な、社内業務システムの開発者にとっては悩みの種である、開発システムのドキュメント整備。
SES等の委託系のシステム開発方法と違い、
- 同じオフィスでシステムユーザーと直接やり取りできる影響で、厳密な仕様書を書かず口頭で仕様を決める事が良くある
- 小規模システムだと設計者と開発者が同じ人になる事が多々あり、設計書が頭の中にあっても問題ない
- 保守業務も開発者が流れでやる事が多く、不在時に他のメンバーが対応できない

といったように、キチンとした部署でない限り、こういった業務改善系のシステム開発は必要なプロセスがなぁなぁで済まされる事があります。
我が部署もそのような状態であったのですが、対象システムの量と規模感的に大規模サービスレベルのドキュメント類を整備するのは正直オーバーワークでした。

そのため、コスパよくドキュメント整備と引継ぎを行うにはどのようにすればいいのか、検討して理論化してみたというだけの記事です。

Qiitaではあまり見かけない業務改善系のエンジニアに向けた記事で、
あまり参考にならない記事だとは思いますがメモ書きとして残しておきます。

# 引き継ぎ項目
1.	概要説明。システムが使われている業務の概要、システムの立ち位置・目的を知る
2.	業務フロー(システム内部仕様は除く)
3.	システムの実物を見せながら、使い方・正しい挙動を説明
4.	システム設計の概要説明。(仕様技術やアーキテクチャ、ざっくりとした仕組み説明)
5.	業務フローを再び追いながら、システム内部仕様を説明
6.	UML、ER図等の細かい仕様書を各自でインプットしてもらう
7. システムの不具合が起こりやすい部分や、過去に頻発した問題、対策方法等の説明

基本的にこの順序通りに進めると理解しやすい。
また、これらは資料＋実際の説明中の録画データとして残っていると一番良い。
筆者の部署は、Teamsで説明し、録画データを無期限保存する事で対応

# 解説
6番はよくある「設計書」として用意される資料だが、これだけ作っていてもシステムの実際の使い方が良く分かっていない状態であるため、理解するのにかなりの労力がいる。
また、ユーザーからの「この機能を使っていたらエラーが出た」と言うような連絡について、システムの詳細設計だけを知っていても実際の使い方との紐づけが出来ていない状態なので、どうすればいいか分からない。
１番のみを行っていた場合も同様で、実際の使い方との紐づけが出来ておらず対応できない。
業務アプリ等であれば、最低限業務フロー図は作らなければいけないだろう。

# どこまで用意すればいいか？

### ■マクロ(データ加工系)
ExcelシートをDBにINSERTするだけのマクロや、シートを加工するだけのマクロ、ＤＢから少しデータを持ってくるだけのマクロであれば、システムの概要説明を数行でするだけで役割が理解できる。前後の業務フローを理解していなくても、インプットイメージとアウトプットイメージさえ分かっていれば問題ない。
後は中身を見るだけで、基本的な技術者であれば改修が可能と思われる。
引き継ぎ項目1と3を行う。

### ■RPA
概要説明を行い、業務フローを説明する事で、システム仕様を説明したのと基本的に同義になる。バックグラウンドでのDB処理等、業務フローに書かれない所だけを追記すればよい。
引き継ぎ項目1と2、余裕があれば自動化前の画面で3を行う。

### ■マクロ(システム系)、Access
複数のマクロを組み合わせたExcelシステムの場合、ほぼアプリと同義であるため、
概要資料、業務フロー、使い方だけでなく、実際にこのマクロを起動するとどのような処理が行われるのかを順を追って説明する必要があると思われる。
Accessについても同じ。
引き継ぎ項目1,2,3,4,5を行う。
6のUML等に関しては、マクロやAccessだと表現するのに適さない場合もあるので、これは任意。

### ■アプリ
アプリに関しては、内部構造が複雑であることが殆どなので、基本的に引き継ぎ項目1~6全て用意するのが望ましい。業務での使用目的、業務の中でどう使われるのか、業務で使ってる機能の内部構造の概要等は割と知っておかないと保守が難しいレベル。

# 休暇対応
連休等で居なくなる場合は、全てを行うのは時間的に足りない場面が殆どであるため、トラブル頻度、トラブル時のリスクの大きさを考慮して引き継ぎ範囲を限定するのが望ましい。また、引継ぎ内容は、基本的に業務停止につながる重大なトラブル事例と、その対処法について教える事に重きを置く。
pictureタグ sourceタグの使い方

## アジェンダ
`<picture>`タグと`<source>`タグを使用して、異なる画面サイズに応じた画像の表示を切り替えることができます。
今回は、画像を`SP`、`Tablet`、`PC`のサイズによって切り替えるというものを例にしながら簡単にまとめます。

## HTML例
```html
<section>
  <picture>
    <!-- スマホ用の画像 -->
    <source srcset="path-to-mobile-image.jpg" media="(max-width: 599px)" />
    <!-- タブレット用の画像 -->
    <source srcset="path-to-tablet-image.jpg" media="(min-width: 600px) and (max-width: 1023px)" />
    <!-- PC用の画像 -->
    <source srcset="path-to-desktop-image.jpg" media="(min-width: 1024px)" />
    <!-- PCの画像（対応しないブラウザ用） -->
    <img src="path-to-default-image.jpg" alt="Key Visual" />
  </picture>
</section>
```

## ポイント
1. `<picture>`タグを使用して、異なる画像を提供することで、デバイスに合わせた画像の切り替えができます。
2. `<source>`タグの`media`属性を使って、画面幅（ブレークポイント）に応じて画像を切り替えます。
   - `(max-width: 599px)`：599px以下の画面（スマホ）
   - `(min-width: 600px) and (max-width: 1023px)`：600px〜1023pxの画面（タブレット）
   - `(min-width: 1024px)`：1024px以上の画面（デスクトップ）
3. `<img>`タグはデフォルトの画像を表示するため、対応していないブラウザでも表示されます。

## 注意: pictureタグ内にimgタグは必ず必要
pictureタグには必ずimgタグを入れる必要があります。
```html
<section>
  <picture>
    <source srcset="path-to-mobile-image.jpg" media="(max-width: 599px)" />
    <source srcset="path-to-tablet-image.jpg" media="(min-width: 600px) and (max-width: 1023px)" />
    <source srcset="path-to-desktop-image.jpg" media="(min-width: 1024px)" />
  </picture>
</section>
```

## 参考
- [HTMLのpictureタグの基本的な使い方と表示されない原因の対策 | Designup](https://designup.jp/html-picture.html)
Python実践データ分析１００本ノック第２版トライ中

# ノック２５とノック２７でエラー出現
google colaboratoryでやってますが、ノック２５と２７でエラー出現。
## まずノック２５
ノック２５は辞書を使って以下の様に書き換えたら、何とかエラーが消えました。

```python
# 'count'列を数値型に変換する
uselog_months['count'] = pd.to_numeric(uselog_months['count'], errors='coerce')

# 'customer_id'ごとに集計（教科書の答えではエラーが出て上手くrunできないので、辞書を使ってみた。）
uselog_customer = uselog_months.groupby('customer_id').agg({'count': ['mean', 'median', 'max', 'min']})
uselog_customer = uselog_customer.reset_index(drop=False)
uselog_customer.head()
```

## 次はノック２７
教科書通りだとエラーが出て実行できない。
どうやらpandasのバージョンが違うみたいで、先に以下のコードでpandasを指定すると上手く動きました。
```python
!pip install pandas==1.3.5
```
でもpandasバージョンだいぶ違うし、補足でもいいから新しいコードをネットに上げて欲しいです。
（表記法も少し変わってるのかな？）

## PS
結局anaconda3でpandas等のバージョンを指定して環境を作成し、秀和システム実践データ分析１００本ノック第２版を続けることにしました。変なエラーが今のところ出現しないので精神衛生上好ましいです。でも文法とか変わってたら勉強したこと無駄になりそうです。それにしてもgoogle colaboratoryの補完機能素晴らしかったです。
[備忘録]　C言語を学習していく上で改めて分かった用語について

# はじめに
　こんにちは，Umamusume22です．最近，会社の研修でC言語を勉強しています．ポインタや構造体などはやっぱり難しいです，，，，そこで，C言語の醍醐味であるメモリやアドレスについて分かったことを忘れないようにアウトプットします．

# 備忘録[1,2]
- malloc関数：動的メモリを確保する関数のこと
- memset関数：メモリを初期化するときに使う
- リンク：プログラムを動かす上で必要なオブジェクトコードを全てくっつけて実行ファイルを生成すること
- オブジェクトコード：0110，，，のように0と1が沢山書かれたファイルのこと
- プリプロセス：#で始まる命令を実行すること

# 最後に
　記事の内容が短くて申し訳ありません．C言語を学習していく上で分からない用語が沢山出てきます．リンク？プリプロセス？状態になります．そこで，備忘録として学んだ用語をまとめました．頑張ってアウトプットを続けていきます．

 ここまで記事を読んでいただきありがとうございました




※ウマ娘の声をフーリエ変換した記事や水栓の開閉判定をLineに通知する記事も書いています．suzuが私です．興味がある方はぜひご覧ください！
https://vigne-cla.com/31-1/#toc5

※noteも始めました．
https://note.com/madoka235/n/nbba2153326e1

ぜひフォローよろしくお願いします!

# 参考文献
[1]"【C言語入門】mallocの使い方(memset, memcpy, free, memcmp)"
https://www.sejuku.net/blog/25002

[2]"C/C++のビルド入門"
https://qiita.com/deltaMASH/items/317a347204e1d5ff0a9f#:~:text=%E3%83%AA%E3%83%B3%E3%82%AF%20(link),(link)%E3%81%A8%E3%81%84%E3%81%84%E3%81%BE%E3%81%99%E3%80%82
NSSMを用いたNode-REDのWindowsサービス化

# はじめに
Windows上でNode-RED稼働は、Windowsログイン後にコマンドプロンプトからNode-RED起動が原則必要です。
しかしWindows Update等により意図せず再起動することがあり、気が付くとNode-REDが起動していないことがあります。また、企業管理下PCでは再起動をコントロールできないことがあります。
この記事ではNSSM(Non-Sucking Service Manager)を用いてNode-REDをWindowsサービス化することで、Windows起動後にログインしなくともNode-REDが使える環境を作ります。

# 環境
- Windows 11 (23H2 Build: 22631.4037)
- インターネット接続あり
- npmを用いてNode-REDを導入していること
- C:\temp フォルダが作成されていること

# 主な手順
1. NSSMをダウンロード後、任意の場所に配置する
2. NSSMの設定を行う
3. Windowsサービス登録されたことを確認する

# 1. NSSMをダウンロード後、任意の場所に配置する
ダウンロード先 | NSSM - the Non-Sucking Service Manager

https://nssm.cc/

NSSMをダウンロードします。
1. Download メニューをクリックします
2. 「nssm 2.24-101-g897c7ad」をクリックしファイルをダウンロードします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/59a3d8e7-cfab-981e-71d6-ba2d6a0fc095.png)

ダウンロードしたファイルを任意の場所に配置します
1. ダウンロードしたファイル(nssm-2.24-101-g897c7ad.zip)を展開します
2. 任意の場所に配置します。例ではC:\Program Filesに配置しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/72bc61f9-9199-126c-effb-2590ff066edc.png)


# 2. NSSMの設定を行う
コマンドプロンプトからNSSMの設定を行います。例ではC:\Program Filesにファイルを配置しています。
1. Windowsスタートボタンをクリックします
2. コマンドプロンプト と入力します
3. 「管理者として実行」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/a09cdf2c-8698-60d4-41b4-ccd55ca4bbf5.png)

NSSMの設定を行います
1. NSSM(正確にはnssm.exe)を配置した場所へ移動します
2. NSSMで使用するサービス名とNode-RED実行ファイルを設定します
　※NSSMが日本語を考慮していない可能性があるため半角英数字で記載することを推奨します
3. 作成したサービスに対しディレクトリ(AppDirectory)を設定します
4. 作成したサービスに対しパラメーター(AppParameters)を設定しC:\tempへログ出力します
  ※C:\tempフォルダが無い場合は事前に作成してください
5. 作成したサービスに対しサービスの説明(Description)を設定します。
　※NSSMが日本語を考慮していない可能性があるため半角英数字で記載することを推奨します

```
1.
cd C:\Program Files\nssm-2.24-101-g897c7ad\win64
2.
nssm install 任意の名前 "C:\Users\\"%USERNAME%"\AppData\Roaming\npm\node-red.cmd"
3.
nssm set 任意の名前 AppDirectory "C:\Users\\"%USERNAME%"\.node-red"
4.
nssm set 任意の名前 AppParameters "-u C:\Users\\"%USERNAME%"\.node-red > C:\temp\node-red.log"
5.
nssm set 任意の名前 Description "サービスの説明"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/39f3b578-43fe-a7c0-7eab-d134d6b01359.png)

# 3. Windowsサービス登録されたことを確認する
Windowsサービス管理画面を表示します
1. Windowsスタートボタンをクリックします
2. サービス と入力します
3. 「開く」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/d3e3e29f-87a6-e001-8f59-46759ed4b4b0.png)
4. サービスが登録されていることを確認します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520636/b80b7f15-a074-baac-57aa-870a19c5e7c7.png)

5. Windowsを再起動し、ログインする前にNode-REDが使用できることを確認します

以上で完了です。

# 参考
Running Node-RED as a service on Windows using NSSM
https://gist.github.com/dceejay/576b4847f0a17dc066db
【プログラミング初心者】0から始めるReact学習 #6 ~Web開発の基本編~

# 1-2.GitHubの学習
## 9月8日
本日は時間を取れるのが23時からだったこともあり、
30分だけ学習に充てました。

GitHubについて理解を深める動画を見たのですが、
「ローカルリポジトリ」と「リモートリポジトリ」を使ってチーム開発をするということを
理解しました。

今はまだ使わないと思うので流し見だけしましたが、
将来的に利用することになると思うので都度見直そうと思います。

## まとめ
明日からはReactで課題に取り組みます！
最初に立てた勉強計画では、9月15日までに1番を完了することになっているため、
残り5日で完成させることを目標に取り組んでいこうと思います！

遂にインプットからアウトプットへ移行するというワクワクと
ちゃんとできるかなといった不安が混ざってます。。！（笑）
上手く作れると良いな～！楽しむぞー！！
sympyの三角形に関するあれこれ

# 基本的な使い方
ほとんどが三角形あるいは多角形のプロパティとして用意されている。英単語が分かれば楽勝。

## 定義
次のように、3つの頂点を指定することでインスタンスを生成できる。

```python
from sympy import *
t = Triangle((0, 0),  (1, 0), (1, 1))
```

## 面積など

```python
t.area # 面積
t.perimeter # 周長
```

## 五心と九点円

```python
t.circumcenter # 外心
t.incenter # 内心
t.centroid # 重心
t.orthocenter # 垂心
t.excenters # 傍心
t.nine_point_circle # 九点円
```

## 内接円と外接円

```python
t.incircle # 内接円
t.circumcircle # 外接円
```

## ドキュメント

https://docs.sympy.org/latest/modules/geometry/polygons.html

# 代数計算をさせてみる

sympyで三角形のあれこれが計算できるが、最も嬉しいのは代数的に計算できることだろう。例えば、三角形$(x, 0),  (1, y), (z, 1)$の重心は次のようになる。

```python
var('x:z')
t = Triangle((x, 0),  (1, y), (z, 1))
print(t.centroid)
```

```python
Point2D(x/3 + z/3 + 1/3, y/3 + 1/3)
```

重心は三頂点の座標の算術平均になることを思い出せば、sympyの力を借りなくとも分かる気もする。では、外心はどうだろうか？

```python
print(t.circumcenter)
```

```python
Point2D((x**2*y - x**2 + y**2 - y*z**2 - y + 1)/(2*(x*y - x - y*z + 1)), (y*(x*y - x - y*z + 1)/2 + (x - 1)*(x*z - x + y - z**2 + z - 1)/2)/(x*y - x - y*z + 1))
```

というように、合っているのかぱっと見て分からないけれど、代数的に求めてくれていることが分かる。
[Strategy] 技術経営

# 技術経営の課題

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/34b0d315-265c-226d-b406-74d27f17cecb.png)


# 参考リンク
- [平成27秋70](https://www.ap-siken.com/kakomon/28_aki/q70.html)
[Next.js]App Routerにおける動的ルーティング

# App Routerでの動的ルーティング方法
以下の構成で`/test/[id]`の形式で動的ルーティングが可能
## ディレクトリ構造
```
ルートディレクトリ
└apps
  └test
    └[id]
      ├page.tsx
      └layout.tsx
```
## page.tsx
```
export default function Home() {
  return (
    <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <main>
        動的ルーティング可能
      </main>
    </div>
  );
}

```
## layout.tsx
```
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body>
        {children}
      </body>
    </html>
  );
}

```

## /test/1にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618167/ab9c4dcb-29c8-5b6c-7478-faa1354e519a.png)

# 動的ルーティングを活用したページ表示
pages.tsxの`Home()`関数の引数にparamsを追加し、関数内でidを使うよう修正
## page.tsx
```
export default function Home({params}: {params: {id: string}}) {
  const { id } = params
  return (
    <div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)]">
      <main>
        id毎にページの要素を変更<br />
        id:{id}
      </main>
    </div>
  );
}
```

## /test/1にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618167/aa90afc4-d843-fb7a-73a5-cf7cd8b29782.png)

## /test/2にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/618167/be6ceca5-8ce1-c07b-acd4-1d9a8c9321d0.png)
Streamlitの環境でPython3勉強の記録

StreamlitのPython3を勉強して自分用としてメモを残す 

1. 環境設定
Python3 と Streamlit の環境を整える手順を説明する。
今回のOSはWindows11とする。

    * Python3のインストール（未インストールの場合）
    ・リンク：https://www.python.org/downloads/
     ・もしくは、Windows11の既存アプリ：Mincrosoft storeでPython3ダウンロード
    * 環境変数を設定する。
    ・リンクからダウンロードした場合は、環境変数に設定する必要がある。
     ・Mincrosoft storeでダウンロードした場合は省く
    * コマンドプロンプトを起動しPython3のバージョンを確認
        ```
        python -V
        //Python 3.1x.xが出れば環境設定完了
        ```
    * 必要なパッケージのインストール
        以下のコマンドを実行する。
        ```
         pip install streamlit
        ```

        すると、streamlitのインストールが実行される。
        
    
2. Streamlit helloの実行確認
Streamlitが正しくインストールされたか確認するために、streamlit helloコマンドを実行し、初期デモアプリが動くか確認します。コマンドラインに以下を入力します:
    ```        
    streamlit hello
    ```
ブラウザが開き、以下のような画面が出れば成功。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3085752/32ac597a-154f-527c-4b59-6da141798960.png)

:::note warn
※もし、コマンドプロンプトでエラーメッセージが出れば、環境設定がしっかりと反映されていない可能性が高いので、コマンドプロンプトの再起動か、パソコンの再起動を試すこと。
:::
Markdown にメタデータを追加してGitHub Pages に一覧表示させるまで

## やったこと
Markdown にメタデータ（作者、作成日、タグ）を追加し、そのデータを元に作成済みのGitHub Pages のサイトに一覧表示させた。


## 前提
- GitHub Pages にメディアサイト？は作成済み
- 記事一覧ページには最初の100文字だけ仮に表示させてて分かりにくい！！
詳しくは前々回記事参照

https://qiita.com/magurouhiru/items/5aa7a2dd70d7ea56a081

## 1. Markdown にメタデータを追加する方法
### 最初のイメージ
Markdown にコメントだったりhtml のヘッダーだったりをつけるイメージ。
表示はされないけど、存在はしていて生ファイル見たら読めるみたいなやつ。

### メタデータのつけ方
ざっと調べたらいくつか見つかった。
- コメント的な奴（ファイルのどこに書いてもOK）
  - `[](ここに書く)`
    - 複数行も末尾に\を入れれば行けるらしい。（私の環境ではダメだったけど。）
  - `<!-- ここに書く -->`
    - htmlと同じ書き方。複数行もOK。
- html のヘッダー的な奴（ファイルの頭に書く）
  - `---`で上下からはさむ。
    - 複数行もOK。

参考

https://qiita.com/yu0819ki/items/e1e1d20cedc68706ba23

https://dev.classmethod.jp/articles/parse-md-markdown-meta-data/

いくつかあるんだなあ3番目が雰囲気好きだなあ。
と思ったけど少し気になって、いくつかの環境で書いてみた結果。

| `[](ここに書く)`                              | `<!-- ここに書く -->` | ---<br>ここに書く<br>---                   |
|------------------------------------------|------------------|---------------------------------------|
| ngx-markdown：△1<br>私のエディタ：△2<br>Qiita：△3 | ngx-markdown：▲<br>私のエディタ：〇<br>Qiita：〇 | ngx-markdown：×<br>私のエディタ：〇<br>Qiita：× |

※ △1は末に\をつけても複数行はNGだった。あとスペースがあったらダメだった。
※ △2は末に\をつけても複数行はNGだった。
※ △3は末に\をつけても複数行はNGだった。あと全角スペースがあったらダメだった。
※ ▲は消えたけどwarningがでてた。

ということで結構ばらつきがあった。
ngx-markdown（Angular で使用しているMarkdown →htmlにしてくれるいいやつ）の優先度が一番高い。
したがって消去法的に`[](ここに書く)`の書き方を使うしかないが...

### ほんとに`[](ここに書く)`を使っていいの？
なんだか怪しく思えてきた。これってどこかで見た気がするんだよなー
そもそもMarkdown ってだれが仕様を決めてるの？
調べてもよくわからなかったのでウィキペディアさんに聞きました。
どうやら↓のサイトが公式の仕様を決めてるっぽい。

https://daringfireball.net/projects/markdown/

斜め見だけどコメントとかメタデータとかの記載がなかった。
加えてngx-markdown の出力したhtml 見るとアンカータグがあった。
![1-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/4ec3762e-d14c-658c-1ae1-0030aff51dfc.png)

つまり、もともとの仕様的には`[](ここに書く)`はコメントではなくアンカータグであり、見えないのは`[]`内に何もかいてないからである。
だとすると今回の目的ではつかいたくないな。
悪さする気はしないけど、一般公開する場所に乗せるのは気乗りしない。

ということは...全滅ですね！

### じゃあどうするの？
ファイルの先頭にJSON でメタデータ書く。
ngx-markdown に食べさせるときはJSON を除外する。

まあ決まりがないなら好き勝手やっていいってことじゃない！

## 2. Angular アプリの改修
JSON は特にひねりとかなく↓の形でやる。
`{"author":"作者名","date":"yyyy/mm/dd",tags":["タグ1","タグ2"...]}`
ファイルの頭につけて、最初の行だけ抜き出して、パースして、ちょっといじって表示するだけ。
あとはあまり書くことはないかな？

ということで、今回の成果です！
![2-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/99201114-46d8-9672-de5f-1e0e97d19f36.png)

うーん、まだましになったかな？
この後きっと見た目整えるから、とりあえずOK

### おまけ
前回GitHub Actions にlint と prettier のチェックを入れた動作確認です。

https://github.com/magurouhiru/mysite/actions

![3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/822099/04de2ef6-1c14-5ca1-7879-f6beacadbd15.png)

今回の記事は以上です。

前回の記事はこちら

https://qiita.com/magurouhiru/items/d368d3cbedd1a76df53b

詳細見たい人はこちら

https://github.com/magurouhiru/mysite/pull/19

https://magurouhiru.github.io/mysite/
Tomcatのデフォルトはリクエストパスに%2fを含むと400を返す

> encodedSolidusHandling	
> When set to reject request paths containing a %2f sequence will be rejected with a 400 response.
> 
> https://tomcat.apache.org/tomcat-10.0-doc/config/http.html より抜粋

よって、```http://localhost:8080/hoge/%2F``` のようなURLにアクセスすると`@RestController`に辿り着かずTomcatが400を返す。

`http://localhost:8080/foo?hoge=%2F` とかクエリで渡す分にはOK。
Swooshを使ってメール送信

- Elixirでできるだけ簡単にメール送信します
- Swoosh.Adapters.Localを使ってローカル内でテストします

# プロジェクト作成
```
$ mix phx.new mail_experiment --no-ecto
$ cd mail_experiment
```

# ソースを書く

#### 送信画面

```elixir:lib/mail_experiment_web/live/mail_live/index.ex
defmodule MailExperimentWeb.MailLive.Index do
  use MailExperimentWeb, :live_view
  alias MailExperiment.Email
  alias MailExperiment.Mailer

  @impl true
  def mount(_params, _session, socket) do
    socket
    |> assign(:logs, [])
    |> then(&{:ok, &1})
  end

  @impl true
  def handle_event("send", _params, %{assigns: %{logs: logs}} = socket) do
    send_mail()

    socket
    |> assign(:logs, logs ++ ["送信しました #{DateTime.utc_now()}"])
    |> then(&{:noreply, &1})
  end

  def send_mail do
    Email.create_email()
    |> Mailer.deliver()
  end
end
```

```heex:lib/mail_experiment_web/live/mail_live/index.html.heex
<p class="text-2xl mb-10">メール送信</p>

<div class="flex flex-row">
  <button phx-click="send" class="rounded-lg bg-violet-600 w-12 px-2 text-white mr-3">送信</button>
  <a href="/dev/mailbox" target="_blank" class="rounded-lg bg-red-600 w-32 px-2 text-white">
    メールボックス
  </a>
</div>
<hr class="mt-10" />
<div class="">
  <%= for log <- @logs do %>
    <p><%= log %></p>
  <% end %>
</div>
```

#### ルーターの設定

```diff_elixir:lib/mail_experiment_web/router.ex
defmodule MailExperimentWeb.Router do
  # 〜省略〜
  scope "/", MailExperimentWeb do
    pipe_through :browser

+    live "/", MailLive.Index, :index

-     get "/", PageController, :home
+    # get "/", PageController, :home
  end
  # 〜省略〜
end
```

#### メール送信部分

```elixir:lib/mail_experiment/email.ex
defmodule MailExperiment.Email do
  import Swoosh.Email

  def create_email() do
    new()
    |> to({"hoge", "hoge@local.local"})
    |> from({"YMN test", "ymn@local.local"})
    |> subject("Test mail")
    |> html_body("<h1>こんにちはhogeさん</h1>")
    |> text_body("こんにちはhogeさん\n")
  end
end
```

# メールadapterの確認（今回は変更しません）
Swoosh.Adapters.Localであることを確認しました

```elixir:config/config.exs
import Config
# 〜省略〜
config :mail_experiment, MailExperiment.Mailer, adapter: Swoosh.Adapters.Local
# 〜省略〜
```
# 実行
```
$ mix phx.server
```


`http://localhost:4000`にアクセス
- 「送信」をクリック
- 「メールボックス」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/d0057fbd-8c32-99bc-da73-667863e1e465.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295814/36fba3d8-bd05-4d84-aca6-d976d7a6b0f0.png)

メール送信が確認でました

# ソース(github)

https://github.com/ymn-t-yamanashi/mail_experiment/releases/tag/v0.02
【Atcoder解法検討】ABC130 A~D Python

## A - Rounding
#### 問題ページ : [A - Rounding](https://atcoder.jp/contests/abc130/tasks/abc130_a)
### 考察 
標準入力、if文による条件分岐、出力でとおります。
### コード
```python
X, A = map(int, input().split())

if X < A:
    print(0)
else:
    print(10)
```

## B - Bounding
#### 問題ページ : [B - Bounding](https://atcoder.jp/contests/abc130/tasks/abc130_b)
### 考察
　一見するとわかりづらい問題ですが、ボールが跳ねる座標は漸化式から順次求めることができます。その跳ねる座標がX以下ならカウントしていくだけです。
### コード
```python
N, X = map(int, input().split())
L = list(map(int, input().split()))

pos = 0     # ボールが跳ねる座標
ans = 1     # 座標X以下でボールが跳ねる回数

# ボールが跳ねる座標を順次求め、X以下ならカウントする
for i in range(N):
    pos += L[i]
    if pos <= X:
        ans += 1

print(ans)
```

## C - Rectangle Cutting
#### 問題ページ : [C - Rectangle Cutting](https://atcoder.jp/contests/abc130/tasks/abc130_c)
### 考察
　数学または算数の問題（長方形 二等分でググる）。対角線の交点を通る直線で必ず二等分できます。よって面積は長方形面積の半分。
 　また$(x,y)$が対角線の交点と一致する場合は無数の直線で二等分可能ですが、それ以外の場合は単数となります（二点を通る直線は一意に決定されます）。
### コード
```python
W, H, x, y = map(int, input().split())

# 面積は必ず長方形の半分
S = W * H / 2

# (x,y)が対角線の交点にあれば複数、その他は単数
if x * 2 == W and y * 2 == H:
    num = 1
else:
    num = 0

print(S, num)
```

## D - Enough Array
#### 問題ページ : [D - Enough Array](https://atcoder.jp/contests/abc130/tasks/abc130_d)
### 考察
　まず連続する部分列の和を計算する必要があるので累積和の適用が考えられます。ただし累積和を使用しても起点と終点の両方を探索すると$O(N^2)$となってTLEとなります。
　このような場合、起点か終点どちらかを固定して考えるとうまくいく場合があります。起点を固定して考えると、累積和に対する二分法で部分列の和がKを超える個数を数えることができます。この時計算量は$O(N 
 \log N)$となります。
 
### コード
```python
from bisect import bisect_left

N, K = map(int,input().split())
A = list(map(int, input().split()))

# 累積和
S = [0] * (N+1)
for i in range(N):
    S[i + 1] = S[i] + A[i]

# 部分列の起点をふって各起点に対し累積和への二分法で和がK以上となる個数を数える
ans = 0
for l in range(N):
    pos = bisect_left(S,K+S[l])
    ans += N - pos + 1

print(ans)
```

## E - Common Subsequence
#### 問題ページ : [E - Common Subsequence](https://atcoder.jp/contests/abc130/tasks/abc130_e)

## F - Minimum Bounding Box
#### 問題ページ : [F - Minimum Bounding Box](https://atcoder.jp/contests/abc130/tasks/abc130_f)

青色diff以上は後日挑戦
Workato：数値を特定の桁数で先頭0埋めしたい

# はじめに

1,2,3という数字を、001,002,003のような特定の桁数で先頭0埋めしたい場合は、Formulaを利用すると簡単に先頭0埋めを実現することができます。

# 手順

先頭0埋めしたいフィールドをFormulaモードへ切り替え、次の通り入力します。

```ruby
"%03d" % <<値（データピル）>>.to_i
```

上記の場合、3桁の先頭0埋めで結果が出力されます。また、0埋めの桁数を5桁にしたい場合は、 `%03d` を `%05d` に変更することで5桁の先頭0埋めが可能です。

具体的な手順については、以下の図を参照ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/afa03cbf-d8f5-a16f-6a4a-7d649e51d9f0.png)

# 関連情報

本設定は、sprintfフォーマットに準じます。

https://docs.ruby-lang.org/ja/latest/class/String.html#I_--25
VscodeのAll Changesが表示されなくなる

## 問題
vscodeのソース管理(Source Control)にて受信/送信(Incomming/Outgoing)タブが表示されない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706631/760ca744-f014-21ca-ef79-367c9351982c.png)


## 原因
vscodeのバージョンを`1.92.2`から`1.93.0`にあげてしまったことが原因でした

2024年8月のアップデート内容にソース管理の内容をソース管理グラフに移動との記載あり

https://code.visualstudio.com/updates/v1_93#_accessibility

`v1.92`に上げた際にも`All Changes`が見れなくなる問題があったが、この際はvscodeのsettings.jsonに`"scm.showHistoryGraph": false,`を記載することで対応できた

しかし`v1.93`ではこのoptionが無効になっている

https://github.com/microsoft/vscode/issues/224616

commit

https://github.com/microsoft/vscode/commit/cd360e031846694c62da57abe3f991dafea33766

## 対応
一時的な対応として以前のバージョンにロールバックすることで解決した

https://code.visualstudio.com/updates/v1_92

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706631/49f8a598-9393-b3ce-ffff-127b652eb694.png)

とはいえ最新バージョンを使いたいので、このissueをSubscribeしておく

https://github.com/microsoft/vscode/issues/224616
golangci-lintとgolangci-lint-actionを使った開発メモ　

# 概要

ローカルの `golangci-lint` のバージョンとCIの `golangci-lint-action` による `golangci-lint` のバージョンの違いでたびたび詰まることを観測したのでざっと調べたメモ

# 背景

チーム共通のアクションに `golangci-lint-action` を組み込んでおり、golangのプロジェクトでは `.golangci.yaml` を直近のプロジェクトからコピペして使い回す運用になっていた。

`golangci-lint-action` はversionの指定ができるが、チーム内であまり認識されていなく、CIの設定でも"stable"を固定にしていることが多い。

基本は最新を使っていくと安全なはずなので、"stable"は良いが、 `.golangci.yaml` の使い回しが良くない。

この辺りどう運用していくのが良いのかざっくり考えてみる

# 公式のドキュメント確認

> IMPORTANT: It's highly recommended installing a specific version of golangci-lint available on the releases page.

公式では特定のバージョンを使うことを強く推奨している

## Configuration

https://golangci-lint.run/usage/configuration/

- `golangci-lint linters` で有効になっているlinterのリストが確認できる
- 設定ファイル `.golangci.{yaml, toml, json}` がカレントディレクトリにあるとそれを読み込んでくれる

カスタムしたい項目が上記ドキュメントにあれば設定ファイルを書いて挙動を制御する、ということなのでカスタムしたい項目がない（そこまでできていない）なら特に設定ファイルはおかず最新の設定そのままでlintかけていく方針が良さそう？

# 考えたこと

- 理想
    - チームで話し合って必要なlintersや他設定を込めて `.golangci.yaml` を作る
    - CIは"stable"で最新の状態に追従していく
    - ローカル開発でこけたところは直す
    - バージョン依存のところも気づけるのでローカルを最新に追従させていく
- ボツ案
    - チームで話し合って必要なlintersや他設定を込めた `.golangci.yaml` のメンテの手が回らない
    - `.golangci.yaml` にコメントで対応バージョンを書いてまずはそれを通すことを目標にする
    - 余力があればCIのバージョンを"stable"にして通すようにする
    - （ローカルでlintを通すようにデバッグするためにローカルのバージョンを上げる必要がありこの辺りのバージョン管理が少し手間そうなのでボツ）
- 当座の方針
    - 使い回している `.golangci.yaml` はチーム内で一度それぞれのlinterを整理済みのものなので使っていく
    - CIは"stable"、ローカルも追従する
    - こけたら直す
    - `.golangci.yaml` のドキュメントも修正する
    - 上記方針でドキュメントに知見をためてもらう、困ったらそこをみるような習慣にする


以下のような方針もあり本当はやりたいが、リポジトリの管理状況や担当者の状況を考えると現状導入は難しそう

https://zenn.dev/otakakot/articles/172ac34ee62582
【Error】Gitが正しく処理できない恐れも！！日本語や特殊文字はだめ

# はじめに
Githubにプルリクエストをあげるより前に気づかなければいけなかったこと。おそらく初めの方で学習した内容。ですが、すっかり忘れていてError？注意の表記が出るまでちゃんと認識していませんでした。これからの為にも記事に残しておきたいと思います

## 環境
- Windows, WSL
- Docker
- Ruby 3.2.3
- Rails 7.1.3


## 1：Githubにて気づいたエラー

[![Image from Gyazo](https://i.gyazo.com/35ba5783d07249d0e100d2ce5b76b8f8.png)](https://gyazo.com/35ba5783d07249d0e100d2ce5b76b8f8)

英文は下記になります👇
```ruby
The head ref may contain hidden characters: "05\u30DD\u30B9\u30C8\u8A73\u7D30"
```
#### これが何を意味しているのか

> このメッセージは、Git での操作中にリファレンス（参照）名に隠れた文字が含まれている可能性があることを示しています。隠れた文字（例: 特殊文字、制御文字、または非表示文字）がリファレンス名に含まれていると、Git がそれを正しく処理できないことがあります。


### 2：この問題に対処するためのステップはいくつかありました

1. **リファレンス名の確認**
    - 隠れた文字が含まれている可能性があるリファレンス名を確認します。リファレンス名には、ブランチ名、タグ名、リモートのリファレンスなどがあります。
    - 下記コマンドで、リファレンス名に不審な文字が含まれていないか確認します。
    
      ```bash
      git branch -a
      git tag
      git remote show origin
      ```
    

    
2. **リファレンスの修正または削除**
    - 隠れた文字が含まれているリファレンス名を修正または削除する必要があります。以下はリファレンスの名前変更や削除のコマンドです。
    - **ブランチ名の変更**:
        
        ```bash
        git branch -m old-branch-name new-branch-name
        ```
        
    - **タグ名の変更**:
        
        ```bash
        git tag new-tag-name old-tag-name
        git tag -d old-tag-name
        ```
        
    - **リモートのブランチやタグの削除**:
        
        ```bash
        git push origin --delete branch-name
        git push origin :refs/tags/tag-name
        ```
        
3. **リファレンスのクリーンアップ**
    - 隠れた文字が含まれているリファレンスが正しく修正または削除されたら、Git のリポジトリをクリーンアップするために、次のコマンドを実行します。
    
    ```bash
    git fetch --prune
    git remote prune origin
    ```
    
4. **リポジトリの整合性チェック**
    - Git リポジトリの整合性をチェックし、問題がないか確認します。
    
    ```bash
    git fsck
    ```

## 3:私が行ったこと
👇私が実際にした流れになります

##### 1:リファレンス名の確認
```ruby
$ git branch -a
  01readme
  02fig
  03ER
  04_create_post
* 05ポスト詳細
  main
  remotes/origin/01readme
  remotes/origin/02fig
  remotes/origin/03ER
  remotes/origin/04_create_post
  remotes/origin/05ポスト詳細
  remotes/origin/main
```
`05ポスト詳細` というブランチ名に日本語が含まれているのがわかります。よく調べると、日本語や特殊文字が含まれるリファレンス名が問題を引き起こすことがあるため、これが原因でエラーが発生している可能性があるという事がわかりました


##### 2:ブランチ名の変更～整合性の✅チェックまで
さっそく、
日本語を含むブランチ名を英数字に変更してみます。    
```bash
git branch -m 05ポスト詳細 05-post-details
```
    
つぎに、一度`git add .`と`git commit -m 'コメント'`そして`git push --set-upstream origin 05ポスト詳細`を実行してしまっているので、リモートブランチも変更していきます
    
```bash
# ローカルブランチの名前変更
git branch -m 05ポスト詳細 05-post-details
    
# リモートブランチの削除とプッシュ
git push origin :refs/heads/05ポスト詳細
git push origin 05-post-details
    
# リモートトラッキング情報の更新。不要なリファレンスを削除
git fetch origin --prune

# リポジトリの整合性を確認し、問題がないか確認
git fsck
```
    

# さいごに、まとめ
リファレンス名に日本語や特殊文字が含まれている場合、Git が正しく処理できないことがあるという事を、今回のエラーから学びました。
日本語になってるくらい大丈夫でしょ？という思い込みだけでその先に進まず、一度エラー内容をよく調べて少しずつ進めていきたいと思います
今回の記事が何か参考になれば幸いです。
Rails サーバーランチャーが見つかりません

# RubyMineでデバッグしようとしたら「Rails サーバーランチャーが見つかりません」って怒られた話

こんにちは！今日は、RubyMineでRailsプロジェクトをデバッグしようとしたときに遭遇した問題と、その解決方法について共有したいと思います。

## こんな困ったことが…

デバックやりやすいと聞いたのでRubyMineに乗り換えたのにこんなエラーが出てきました！

```
エラー: Rails サーバーランチャー '/プロジェクトの名前/bin/rails' がプロジェクトに見つかりませんでした
```

「えっ、なんで？昨日まで普通に動いてたのに…」って感じで、ちょっと焦りました。

## 原因はこれだった

調べてみると、どうやらプロジェクトの`bin/rails`ファイルがどこかに消えちゃったか、うまく設定されてないみたいなんです。

このファイル、実はRailsアプリを動かすのに超重要な役割を果たしているんですよ。これがないと、RubyMineさんが「Rails、どこ〜？」って感じで迷子になっちゃうわけです。

## 解決方法はこれ！

さて、問題が分かったところで、解決方法です。意外と簡単でした！

1. まずは、ターミナルを開いて、プロジェクトのルートディレクトリに移動します。

2. そして、このコマンドを打ち込みます：

   ```bash
   bundle exec rails app:update:bin
   ```

3. 最後に、RubyMineでプロジェクトを再読み込み。

これだけで、あら不思議。デバッグが動くようになりました！「えっ、こんな簡単でいいの？」って感じですよね（笑）

## ちょっとした豆知識

- この問題、実はよくあるんです。特に、プロジェクトを最初にセットアップしたときや、Railsをアップグレードした後によく起こります。
- `bin/rails`ファイルは、Railsアプリケーションの実行に必要な重要なファイルです。これがないと、色々と困ったことが起きちゃいます。

## まとめ

エラーメッセージを見て最初は焦りましたが、原因が分かれば解決方法はシンプル。こういうちょっとしたつまずきも、解決できたときの喜びは大きいですよね。

みなさんも同じような問題にぶつかったら、ぜひこの方法を試してみてください。「動かない…」ってなったときの救世主になるかもしれません！

それでは、ハッピーコーディング！
[Security] セキュリティ対策製品

# 一覧
|製品名|詳細|
|:--|:--|
|IDS|Intrusion Detection System<br>不正パケット監視<br>``対象``: ネットワーク全体（ネットワーク層、トランスポート層）|
|IPS|Intrusion Prevention System<br>不正なパケット監視・遮断<br>``対象``: ネットワーク全体（ネットワーク層、トランスポート層）|
|WAF|Web Application Firewall<br>WebアプリケーションへのHTTP/HTTPSトラフィック監視・遮断<br>``対象``: Webアプリケーション|
|SIEM|Security Information and Event Management<br>ファイアウォール、IDS、IPS、Webサーバなどの**ログデータ**を一元管理・監視・分析<br>``対象``: エンドポイント（PC・モバイルデバイス・サーバ）、ネットワーク全体|
|UTM|Unified Threat Management<br>ファイアウォール、IDS、IPS、マルウェア対策などを統合したネットワーク監視装置（分析はできない）<br>``対象``: ネットワーク全体|
|EDR|Endpoint Detection and Response<br>エンドポイントの挙動を監視・警告、不審なプロセスの終了<br>``対象``: エンドポイント（PC・モバイルデバイス・サーバ）|
|ハニーポット|ダミーとして設置したサーバやネットワーク<br>|
|TPM|PCに搭載されたセキュリティチップ|

# 参考リンク
- [R2F44_TPM](https://www.ap-siken.com/kakomon/02_aki/q44.html)
- [R4S1_PM_WAF](https://www.ap-siken.com/kakomon/04_haru/pm01.html)
ファイルの内容を確認したい時に使えるLinuxコマンドたち

## 概要
ファイルの中身を確認したいときに使えるLinuxコマンドについてまとめておく。
自分が使用するものだけ。

## catコマンド
これは、ファイルの内容を全て表示したいときに使用できる。
```
$ cat docker-compose.yml
```

## lessコマンド
lessコマンドに関しては、ファイルの内容を1行づつ確認したい時に使用できる。
```
$ less docker-compose.yml
```
lessコマンドを実行した直後は、ターミナルの枠内で表示できる行まで表示されている。もしも、さらに下の行の内容を確認したい場合は``↓カーソル``を押下していけば1行ずつ確認して行くことができる。そして、ターミナルでコマンドを打てる状態に戻すには、``q``を押下すれば良い。

lessコマンドは決行応用が効きvimのようにファイルを編集したりすることも可能。がんばろう。

## headコマンド
headコマンドは何も指定をしなければファイルの先頭10行までを表示してくれる。
```
$ head docker-comppose.yml
```
もしも、先頭の何行目かまでを指定して表示したい場合は以下のような形で実行すればよい。
```
$ head 7 -n docker-compose.yml
```
こんな感じで行数を指定すれば、ファイルの先頭から7行目までの内容が表示される。
Pixel 8aでデュアルeSIMを試してみた

## Pixel 8aでデュアルeSIMを試してみた

最近、Pixel 8aのデュアルeSIMについて気になったので調べてみました。Googleで検索してみると、いくつかの記事がヒットし、その中で特に気になったのがこちらの記事でした：  
**[Pixel 8aのデュアルeSIMについて](https://applipo.ne.jp/app/pixel8a-dual-sim-esim/)**

この記事では、デュアルeSIMについて「通話用とデータ用のSIMをそれぞれ別々に設定できない」と説明されています。  
当初、eSIMが2つ使えないのは本当かな？と思いつつ、実際に試してみることにしました。

Googleで検索すると以下のように出てきましたので、実際には使えるかもしれない思いがありました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3352980/f5848935-12fb-8c46-bf48-8488b2cb03b0.png)
### 使用したSIM

今回使用したSIMは次の2つです：

- **Povo 2.0の音声SIM**（eSIM）
- **iijmioのeSIM**（ドコモのデータ通信専用SIM）

もともと、iijmioのeSIMはPixel 8aに入っており、Povo 2.0の音声SIMは物理SIMで使っていました。  
データ通信については、家族とシェアしているため、データ容量が不足することを恐れ、別の物理SIMを使いたいと考えました。

そのため、今回はeSIMの活用に挑戦。別の物理SIMは、iPhoneで使用していた**楽天モバイルのSIM**です。

### 実際に試してみた

そもそも音声SIMは端末ごとに割り当てられるため、物理SIMである必要はないと考えていました。  
デュアルeSIMの実装が可能かどうか、記事の内容が正しいかも検証したかったので、実際に試してみました。

### 結果

結果として、問題なく**デュアルeSIMが使えました！**  
今のところ、特にトラブルもなく、快適に利用できています。

これから同様にデュアルeSIMを試したい方も、ぜひ参考にしてみてください！
駅すぱあと VBA SDKを使って経路探索を行う

**本記事はヴァル研究所の支援として作成された記事です**

[駅すぱあとはAPIを公開](https://api-info.ekispert.com/)しており、駅情報や経路探索などをAPI経由で行えます。メソッドはすべてGETメソッドで、情報取得系のみです。レスポンスはJSONまたはXMLで返ってきます。

この駅すぱあと APIを利用しやすくするSDKを開発しはじめました。SDKはVBAで作っており、Excelなどから利用できます（Windowsのみ、macOSでは利用できません）。

今回は、スタンダードプランで提供されている経路探索APIに対応したので、その使い方を解説します。

## 必要な情報

SDKを利用する際にはAPIキーが必要です。[無料トライアルがあるので、こちらから取得](https://api-info.ekispert.com/form/trial/)してください。

## 注意点

- SDKはWindowsでのみ動作します
- SDKは非公式です。公式サポートへの問い合わせはご遠慮ください

## ファイルのインポート

[こちらのリポジトリ](https://github.com/EkispertAPIMania/VBA-SDK)にある `*.cls` と `*.bas` ファイルをすべてインポートします。これらは以下のライブラリを含んでいます。

- [VBA-tools/VBA-Dictionary](https://github.com/VBA-tools/VBA-Dictionary)
- [VBA-tools/VBA-Web: VBA-Web](https://github.com/VBA-tools/VBA-Web)
- [VBA-tools/VBA-JSON](https://github.com/VBA-tools/VBA-JSON)

## 初期化

先ほど取得したAPIキーを使ってSDKを初期化します。

```vb
Dim client As Ekispert
Set client = New Ekispert
client.ApiKey = "YOUR_API_KEY"
```

## 経路探索の探索条件の設定

経路探索は `CourseExtremeQuery` を使います。このオブジェクトを取得し、探索条件を設定します。

```vb
Dim Query As CourseExtremeQuery
Set Query = client.CourseExtremeQuery()

' 出発地、目的地の設定
Query.ViaList(0) = "高円寺"
Query.ViaList(1) = "東京"

' 日付の設定
Query.DateProp = Now

' 探索種別を平均待ち時間探索に設定
Query.SearchType = Plain
```

探索条件は [経路探索 - 駅すぱあと API Documents 駅データ・経路探索のWebAPI](https://docs.ekispert.com/v1/api/search/course/extreme.html) にあるものを指定できます。`Date` はVBAの予約語なので、日時（ `date` または `time`）については、 `DateProp` プロパティへ設定してください。

## 探索の実行

探索条件を設定したら、探索処理を実行します。結果は `ResultSet` クラスになります。探索がうまくいったかどうかは `ResultSet.Success` の値で判定してください。

```vb
Dim Result As ResultSet
Result = Query.Find()

Debug.Print Result.Success ' True または False
```

### エラーだった場合

もし探索がエラーだった場合は `ResultSet.Error` の中にエラー情報があります（駅すぱあと APIからのエラーの場合）。

```vb
If Not Result.Success Then
    MsgBox Result.Error.Message
    Exit Sub
End If
```

### 成功した場合

処理が成功した場合、 `ResultSet.Courses` の中に経路情報が入っています。各経路には `Prices` （金額情報） や `Route` （ルート） プロパティなどがあります。

```vb
Debug.Print Result.Courses(0).Prices(0).Oneway ' 片道運賃。460など
```

## ソースコード

SDKのコードは以下のリポジトリにて公開しています。ライセンスはMIT Licenseです。

[EkispertAPIMania/VBA-SDK: Excel VBAなどで動作する駅すぱあと VBA SDKです（Windowsのみ）](https://github.com/EkispertAPIMania/VBA-SDK/tree/main)

## まとめ

経路探索は今回紹介したものの他、前後のダイヤ探索や平均待ち時間探索などさまざまな種類があります。今後のSDKのアップデートにて対応する予定なので、ぜひご利用ください。

何か不具合があれば、Issueにて連絡いただければ対応します（macOSでは動かないので注意してください）。

[EkispertAPIMania/VBA-SDK: Excel VBAなどで動作する駅すぱあと VBA SDKです（Windowsのみ）](https://github.com/EkispertAPIMania/VBA-SDK)
iRocket、BitKraftとの戦略的提携で成長とイノベーションを加速

暗号通貨とブロックチェーン技術の分野を再編成する動きとして、iRocketがゲームとインタラクティブメディアに特化したベンチャーキャピタル企業、BitKraftとの戦略的提携を発表しました。この提携には、iRocketの運営、研究開発、そして成長を後押しするための6,500万ドルの資金が注入される予定です。

![irocket1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784576/35e991c9-814f-9e09-6779-d83e2eb3550c.jpeg)

## 成功に向けた提携
iRocketとBitKraftの提携は、ブロックチェーンゲームのエコシステムを革新するという共通のビジョンに基づいています。BitKraftのゲーム業界における豊富なリソースと、iRocketの革新的な技術を活用することで、ユーザー体験を向上させ、ゲームにおけるブロックチェーンアプリケーションのさらなる普及を目指す強力なシナジーが生まれることが期待されています。

「BitKraftと提携できることを大変嬉しく思います」とiRocketのCEOであるトム・ピエール氏は述べています。「彼らのインタラクティブメディア分野における深い理解は、iRocketのビジョンと完全に一致しています。この投資により、当社の成長を加速し、コミュニティの進化するニーズに応える新しいソリューションを開発することが可能になります。」
## iRocketとFUELトークンへの影響
この提携は、iRocketにとって、特にその主要なトークンであるFUELにとって重要な転換点となります。資金の流入により、iRocketの運営拡大が進み、より充実した製品提供や革新的な機能の開発が可能になります。iRocketがインフラを強化し、サービスを拡大することで、FUELトークンの需要が大幅に増加する可能性が高まります。

FUELトークンの投資家や保有者は、より強固なエコシステムの恩恵を受けることが予想されます。この提携により、トークンの新しいユースケースやユーティリティが増え、BitKraftの支援を受けて、iRocketは市場でのポジションを強化し、より幅広いオーディエンスにトークンの魅力をアピールできるようになります。これにより、トークンの価値向上が期待されます。
## 未来へのビジョン
BitKraftとの提携は、単なる資金提供にとどまらず、ブロックチェーンゲームエコシステムを革新するという共通のコミットメントを象徴しています。両社は、技術の進化、市場の存在感の向上、ゲームやエンターテインメント業界との戦略的提携など、新たな成長の可能性を模索していく予定です。

iRocketがこの野心的な旅に乗り出す中で、提携は革新的な開発をもたらし、関係企業だけでなく、ゲームにおけるブロックチェーン技術とのユーザーの関わり方をも革命的に変えることが期待されます。リソース、知識、ネットワークを結集することで、iRocketとBitKraftは、ブロックチェーンゲームの未来をより統合され、ダイナミックなものにするリーダーとしての地位を確立する準備が整っています。
## 結論
BitKraftの多額の投資と戦略的提携により、iRocketはブロックチェーン分野での成長とイノベーションを加速させる準備が整っています。同社が運営を拡大し、FUELトークンのユーティリティを強化する中で、この協力関係は投資家やユーザーに新たな機会をもたらすでしょう。iRocketとBitKraftが協力して、ゲームにおけるブロックチェーン革命の次なる章を形作る未来は、非常に明るいものとなっています。
[Docker][CircleCI]備忘録: Dockerの動作の仕組みとCircleCIのリモートDocker環境

# 経緯
CircleCI上でローカルマシンで実行しているのと同じ`docker-compose.yml`を使って`docker-compose up`コマンドでローカルと環境を統一した状態で自動テストできるようにしたろ！とCircleCIの公式ドキュメント[Run Docker commands](https://circleci.com/docs/building-docker-images/)を読んでいると

「Docker実行環境内でDockerイメージをビルドするためには、リモートDocker環境を使ってください。」

とか

「dockerコマンド・docker-composeコマンドを使ってDockerイメージをビルドするためには、ジョブ内で`setup_remote_docker`キーを設定する必要があります。」

という記述が出てきた。

「リモートDocker？よう知らんけど、とりあえず言われて通りやってみるか！」とjobを設定してパイプライン実行させると失敗。ログを確認すると、バインドマウントの設定部分で「ホストマシン側にそんなファイルねぇわ」的なエラーが発生していた。

エラーメッセージ的にとりあえず「リモート」Dockerがあやしすぎるということで調べてみると、「Dockerの動作の仕組み」の理解が足りてないことに気づいた。

この記事はそれらの備忘録。

# Dockerの動作の仕組み
|![architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/ba9e08f7-886b-4efe-5ec2-e353fb367f73.png)|
|:--|
|出典: [Docker architecture](https://github.com/docker/docs/blob/v17.06-release/engine/docker-overview.md#docker-architecture)|

[Docker architecture](https://github.com/docker/docs/blob/v17.06-release/engine/docker-overview.md#docker-architecture)に書かれていることをまとめると、

- Dockerはクライアント・サーバーアーキテクチャである。
- サーバーの構成要素は、Dockerデーモン・イメージ群・コンテナ群
- Dockerクライアントは、実行されたdockerコマンド(イメージのビルド、コンテナの作成・起動、イメージのpush, pull etc.)に対する具体的な処理をDockerデーモンにお願いする(Docker APIのリクエストで)。
- Dockerデーモンは、Dockerクライアントからのリクエストに対する具体的な処理をする。
- Dockerデーモンはクライアントと同じシステム上で動作させることもできるし、リモートで動作しているDockerデーモンにクライアントが接続するといった構成でもいける

# リモートのDockerデーモンの利用
[How to deploy on remote Docker hosts with docker-compose](https://www.docker.com/blog/how-to-deploy-on-remote-docker-hosts-with-docker-compose/) によると、環境変数`DOCKER_HOST`でDockerデーモンが動作しているリモート環境を設定している、または`-H`(--host)オプションで直接リモート環境を指定しつつ`docker-compose up`を実行することでリモートのDockerデーモンを使って各種dockerコマンドを実行できる模様。
他にもcontextを設定しての方法もある模様。

# CircleCIでのdockerコマンド実行
[Run Docker commands](https://circleci.com/docs/building-docker-images/)には他にも以下のような記述がある。

「リモートDocker環境に使用されるリソースクラスは、ジョブのプライマリコンテナをどのように設定するかによって決定される。」

つまり、プライマリコンテナのVMとリモートDocker環境のVMは異なるということだろう。
先述の情報を合わせると、CircleCIでは`setup_remote_docker`によって、おそらく以下のような形で動作しているのだろう。

![DockerとDockerCompose-CircleCIのリモートDocker.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59542/a05b1f5c-068d-ed7c-babb-79d03ff24375.png)

これなら、バインドマウントの設定でホスト側のファイルないわエラー が出るのも納得できる。
だってリモートDocker側の環境にバインドマウント対象のファイルがごそっとコピーされてるわけじゃないんだもの。イメージビルド時にプライマリコンテナ側にあったファイルはイメージ内にコンテキストとして引き渡されてはいるけれども。

# 謎な点
[Run Docker commands](https://circleci.com/docs/building-docker-images/)には以下の記述もある。

「`setup_remote_docker`を使用することで、全てのdockerコマンドはプライマリコンテナの起動に使われたのと同じVM上で実行される」


ちょっとよくわかんないけど、今のところは重要でなさそうなので、また問題にぶち当たったら考えることにする。










# 参考
[Docker architecture](https://github.com/docker/docs/blob/v17.06-release/engine/docker-overview.md#docker-architecture)
[リモートホストで動作しているDockerデーモンを使用する](https://kazuhira-r.hatenablog.com/entry/2020/06/30/223609)
[Docker Engineを立ててクライアントからいじる](https://qiita.com/murata-tomohide/items/526cadd39bf415264af9)
[How to deploy on remote Docker hosts with docker-compose](https://www.docker.com/blog/how-to-deploy-on-remote-docker-hosts-with-docker-compose/)