OmniAICreator/Qiita-1.07M huggingface dataset:
formオブジェクトでの中間テーブルを利用した複数選択できるチェックボックス機能の実装

## 初めに

疑問に思ったことや上手くいかなかったことのアウトプットをしています。
自分なりの理解でアウトプットしていきます。初学者なので誤りもあると思います。
その際はご指摘いただけると幸いです。


>開発環境：
Rails7.1.3
ruby3.3.6

### 目的
formオブジェクトを通して多対多の関係のモデルを使用して複数のチェックボックスで保存できるようにする。

### 前準備（モデルのリレーション、初期データ）

```:モデルのリレーション
class Example < ApplicationRecord
  has_many :example_colors, dependent: :destroy
  has_many :colors, through: :example_color
end

class ExampleColor < ApplicationRecord
  belongs_to :color
  belongs_to :example
end

class Color < ApplicationRecord
  has_many :example_colors
  has_many :examples, through: :example_colors
end
```

```db/seeds.rb
# ここでcolorの初期データを作成します。

names = %w[赤 黄 黒 白]
names.each do |color_name|
  Color.find_or_create_by(name: color_name)
end
```
db:seedをして、準備完了です！

### formオブジェクトのファイル作成
```app/forms/example_form.rb
class ExampleForm
　include ActiveModel::Model
  include ActiveModel::Attributes

  attr_accessor :title, :body, :color_ids

  delegate :persisted?, to: :example

  def initialize(attributes = nil, example: Example.new)
    @example = example
    attributes ||= default_attributes
    Rails.logger.debug "Initializing ExampleForm with: #{attributes.inspect}"
    super(attributes)
  end

  def to_model
    example
  end

  def save
    ActiveRecord::Base.transaction do
      example.update!(title: title, body: body, color_ids: color_ids.reject(&:blank?))
    end
  end

  praivate

    attr_reader :example

    def default_attributes
      {
        title: example.title,
        body: example.body,
        color_ids: example.color_ids
      }
    end
end 
```

idsモデルを使うと、関連オブジェクトのidの取得、追加・削除を行えます。
関連自体の操作で楽にデータ管理できるわけですね。

## コントローラ作成

```
class ExamplesController < ApplicationController

  def new
    @form = ExampleForm.new
  end

  def create
    @form = ExampleForm.new(example_params)

    if @form.valid?
      @form.save
    end
  end

  praivate

  def example_params
      params.require(:example).permit(:title, :body, color_ids:[])
  end
end  
```
### formの作成

```
<%= form_with model: @form, local: true |f| %>
  <div class="mb-3">
    <%= f.label :タイトル %>
    <%= f.text_field :title %>
  </div>
  <div class="mb-3">
    <%= f.label :本文 %>
    <%= f.text_field :body %>
  </div>
  <div>色</div>
  <%= f.collection_check_boxes :color_ids, Color.all, :id, :name do |b| %>
    <div>
      <%= b.label { b.check_box + b.text } %>
    </div>
  <% end %>
  <%= f.submit '登録' %>
<% end %>  
```
collection_check_boxesメソッドを使用してチェックボックスを作成します。
form_withの中なので第一引数は省略しています。
第二引数にcolor_idsをセット。メソッド名を指定しています。
第三引数にColor.allをセット。チェックボックス作成の際どこからデータを取るか指定します。
第四引数にidをセット。valueを指定しています。
第五引数にnameをセット。こちらはチェックボックスのtextを指定していますね。

これでformオブジェクトを使用しながら複数のチェックボックスで、複数のチェックを入れられるフォームの完成です！



### 参考記事
[Railsのデザインパターン: Formオブジェクト](https://applis.io/posts/rails-design-pattern-form-objects)
[1.5. 多対多の関連を持つオブジェクトをチェックボックスで編集可能なフォーム](https://rails.densan-labs.net/form/many_to_many_checkbox_form.html)
[collection_check_boxesメソッドの構造確認](https://qiita.com/sho012b/items/3a595fde14516081dff5)
TypeScriptの環境構築をWebpackでする際のメモ

バックエンドも含めて、JSの勢いが凄いなと思っていたら、
新しい技術やライブラリはJSから出てくることがよくわかった。
AWSとか、OpenAIとかで、JSしかSDKが出ていないものが割と多い。


そんなこともあり、TypeScriptをかじってみることにした。
Webpackで環境構築をしたので、
そのメモとして、package.jsonは以下の通り
```
{
  "name": "typescript_prac",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "ts-loader": "^9.5.2",
    "typescript": "^5.7.3",
    "webpack": "^5.97.1",
    "webpack-cli": "^6.0.1",
    "webpack-dev-server": "^5.2.0"
  }
}
```
特に手間がかかり、今回メモにしておこうと思ったのが、
webpack.config.js ですね。

```
module.exports = {
  entry: {
    bundle: "./src/index.ts",
  },
  output: {
    path: `${__dirname}/dist`,
    filename: "[name].js",
  },
  mode: "development",
  resolve: {
    extensions: [".ts", ".js"],
  },
  devServer: {
    static: {
      directory: `${__dirname/dist}`,
    },
    //ブラウザを自動で開く
    open: true,
  },
  module: {
    rule: [
      {
        test: /\.ts$/,
        loarder: "ts-loader",
      },
    ],
  },
};
```
個人的には、Viteの方が好きだけど、
複雑な依存関係があった場合は、Webpackのが安定するらしい。


余談として、TSでコンパイルエラーが出ても、
JSファイルが出力されて、
それを実行した時にエラー出ないのは、仕様上、仕方ないけれど、
ちょっと安全性の担保が微妙だなと。


ただ、TSは汎用性が半端なく、
クラウドやAIとの相性も抜群なので、
練習しなきゃ新時代に置いてかれるらしいです。
MongoDBのソート挙動に起因するReactの無限スクロールでの重複キー問題の解決

## はじめに

ReactとMongoDBを使用した無限スクロールの実装中、ページネーションの境界でデータが重複して表示される問題に遭遇した。
この記事では、MongoDBのソート挙動に起因する問題の原因と、`_id`を用いた具体的な解決策について解説する。

## 想定読者
- ReactとMongoDBを使用したアプリケーションを開発している方
- 無限スクロール・ページネーションをを実装している、もしくは実装予定の方
- データベースのソート挙動について知りたい方

## 結論から
MongoDBのソート挙動により、同一ソート値を持つドキュメントの順序が一貫性を欠く場合がある。
これにより、Reactの無限スクロール実装時にキー重複警告が発生する。
`_id`フィールドを補助的なソートキーとして追加することで問題を解決できる。

## 開発環境
- React 18.x
- MongoDB 8.0.0
- MongoDB Node.js Driver 6.9.0
- TypeScript 5.x
- Node.js 23.5.0

## 問題の詳細

大量のデータが存在するMongoDBのCollectionに対してあるクエリでフィルターした結果を、無限スクロールで表示されるデータがダブった。
具体的には無限スクロールの1回目に取得した最後のデータと２回目に取得した最初のデータが重複した。

### 発生した警告
```
Warning: Encountered two children with the same key, `.$xxxxxxxxxxxx`. 
Keys should be unique so that components maintain their identity across updates. 
Non-unique keys may cause children to be duplicated and/or omitted — the behavior 
is unsupported and could change in a future version.
```

### 問題の再現条件
以下の条件が揃った場合に発生:
- フィルター条件を含むMongoDBクエリ
- 昇順でのソート
- 2ページ目以降のデータ取得

### 問題のあるコード
```typescript
// Backend: MongoDB query
const sortObject = {
  [sortBy]: order === "asc" ? 1 : -1
};

const items = await Collection.find(query)
  .sort(sortObject)
  .skip(skip)
  .limit(limit)
  .lean()
  .exec();

// Frontend: React component
const loadMore = async (page: number) => {
  const response = await fetchItems(page);
  setState((prev) => ({
    items: [...prev.items, ...response.items], // appending returned items
    page,
  }));
};
```

実際は`page === 1`かどうかでitemsのappendなど調整しているが、詳細は一部省略する。（本題ではないので）

## 原因の特定

### MongoDBのソート挙動の特徴
1. 同一のソート値を持つドキュメントが存在する場合、その順序は必ずしも一貫性を持たない
2. ページネーション（`skip`と`limit`）と組み合わさると、同一ドキュメントが異なるページに出現する可能性がある
3. これにより、React側で同一キーを持つアイテムが重複して表示される

## 解決策

補助的なソートキーとして_idを追加.
(参考) [MongoDB Documentation: sort()](https://www.mongodb.com/docs/manual/reference/method/cursor.sort/)

### MongoDBクエリの修正
```typescript
const sortObject = {
  [sortBy]: order === "asc" ? 1 : -1,
  _id: 1  // 補助的なソートキーとして_idを追加
};

const items = await Collection.find(query)
  .sort(sortObject)
  .skip(skip)
  .limit(limit)
  .lean()
  .exec();
```

### なぜ解決するのか
1. `_id`フィールドはMongoDBにおいて一意性が保証されている
2. 主ソートキーが同値の場合でも、`_id`による順序付けで一貫性のある結果が得られる
3. これにより、ページネーション時の重複が防止される

## 技術的考察

### MongoDBのソート挙動
- デフォルトでは、同一ソート値を持つドキュメントの順序は不定
- 分散システムやシャーディングの場合、この挙動はより顕著になる
- 安定したソートには必ず一意な値をソートキーに含める必要がある

## まとめ

MongoDBを使用した無限スクロールの実装において、ソート挙動に起因する問題と遭遇した。
以下のケースで発生しうる。

1. ソート対象フィールドに重複値が存在
2. 大量データのページネーション処理のページ境界
3. 複数のフィルター条件の組み合わせ

`_id`フィールドを補助的なソートキーとして活用することで、安定したソート結果とクリーンな無限スクロールの実装が可能となる。

## 参考文献
- [MongoDB Documentation: sort()](https://www.mongodb.com/docs/manual/reference/method/cursor.sort/)
- [React Documentation: Lists and Keys](https://reactjs.org/docs/lists-and-keys.html)
dnfをProxy環境下で使う

今回はVirtualBox上に構築したOracle Linux での設定です。
社内環境下などで、Proxyの設定が必要で`dnf`エラーとなってしまう場合は試してみてください。

## 設定ファイルを修正する
`/etc/dnf/dnf.conf`こちらのファイルを修正します。
`[main]`の最下部に以下を追記
```
proxy=http://<ユーザ名>:<パスワード>@<proxy_ip>:<proxy_port>
proxy=https://<ユーザ名>:<パスワード>@<proxy_ip>:<proxy_port>
// 例
proxy=http://user_name:user_password@192.168.xx.xx:8080
```

## おわりに
意外と簡単。ただ簡単には気付けない。
場数を経験して、だいたいProxyだろうなと分かるようになっていきたい。
NumPyの基本＆応用


## NumPyとは？
NumPy（Numerical Python）は、Pythonで数値計算を高速に処理するためのライブラリ。
大量のデータを効率的に扱え、データ分析や機械学習で必須！
## 1. NumPy配列の作成  
🔹 PythonのリストをNumPy配列（ndarray）に変換  
🔹 計算が高速＆多次元配列が扱える  
```:python
import numpy as np

# PythonリストからNumPy配列を作成
arr = np.array([1, 2, 3, 4, 5])
print(arr)  # 出力: [1 2 3 4 5]
print(type(arr))  # 出力: <class 'numpy.ndarray'>

# 2次元配列（行列）
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print(matrix)
```

## 2. 特殊な配列の作成  
🔹 すべて0 or 1 の配列を簡単に作れる  
🔹 ランダムな値の配列も生成可能  
```:python
# すべて0の配列（3×3）
zeros = np.zeros((3,3))
print(zeros)

# すべて1の配列（2×4）
ones = np.ones((2,4))
print(ones)

# ランダムな数値（0〜1の間, 4×4）
random_arr = np.random.rand(4,4)
print(random_arr)

# 整数のランダムな配列（0〜10の間, 3×3）
rand_ints = np.random.randint(0, 10, (3,3))
print(rand_ints)
```
## 3. 配列の演算  
🔹 配列の足し算・引き算・掛け算などを要素ごとに実行  
```:python

a = np.array([10, 20, 30])
b = np.array([1, 2, 3])

print(a + b)  # [11 22 33] (各要素ごとに加算)
print(a - b)  # [9 18 27] (各要素ごとに減算)
print(a * b)  # [10 40 90] (各要素ごとに乗算)
print(a / b)  # [10. 10. 10.] (各要素ごとに除算)
print(a ** 2) # [100 400 900] (各要素の2乗)
```
## 4. 配列の形状操作（リシェイプ）  
🔹 配列の形を変更（reshape）し、2D・3Dに変換可能  
```:python
arr = np.arange(1, 10)  # 1〜9の配列
print(arr)

# 1D → 2D（3行3列）
reshaped = arr.reshape(3,3)
print(reshaped)
```
## 5. 統計計算  
🔹 平均値・中央値・標準偏差などの統計処理が簡単に  
```:python

data = np.array([10, 20, 30, 40, 50])

print(np.mean(data))   # 平均: 30.0
print(np.median(data)) # 中央値: 30.0
print(np.std(data))    # 標準偏差
print(np.max(data))    # 最大値
print(np.min(data))    # 最小値
```
## 6. 条件に合うデータの抽出  
🔹 条件を指定してデータをフィルタリング  
```:python
numbers = np.array([5, 10, 15, 20, 25, 30])

# 15以上の要素を抽出
filtered = numbers[numbers >= 15]
print(filtered)  # 出力: [15 20 25 30]
```
## 7. ブロードキャスト（異なる形の配列の計算）
🔹 異なる形の配列同士の演算ができる
```:python
matrix = np.array([[1, 2, 3], [4, 5, 6]])
vector = np.array([10, 20, 30])

# 各行に [10, 20, 30] を加算
result = matrix + vector
print(result)
```

## まとめ
##### NumPyはPythonで高速な数値計算ができるライブラリ  
・1D, 2D, 多次元の配列を簡単に作成＆操作  
・特殊な配列（ゼロ, ワン, ランダム）を簡単に生成  
・高速な数値演算（+,-,*,/,** など）に対応  
・統計計算（平均,中央値,標準偏差,最大・最小 など）が一発でできる  
・条件に合うデータをフィルタリング可能  
・異なる形の配列同士の計算（ブロードキャスト）ができる  
##### NumPyの活用シーン
✅ データ分析・統計処理を高速化したい
✅ 大量の数値データを処理したい
✅ 機械学習・AIの前処理に使いたい
✅ 行列演算を手軽に実行したい
ざっくりDB正規化・正規形

正規化って聞くとなんだか難しそうだけど、そんな難しいことはしていない。
DB を使いやすい状態にしているだけ。

## 正規化と正規形の違い
正規化・・・テーブルをさらに分割すること
正規形・・・正規化した結果できた形

## 第一正規形

- 各行が一意な状態
- 列に重複がない状態

次のような状態は、第一正規形ではない

```
// 列が重複している
受注テーブル
| 受注ID | 商品1 | 価格1 | 商品2 | 価格2 |
|--------|--------|--------|--------|--------|
| 1      | りんご | 100    | みかん | 80     |
| 2      | バナナ | 150    |       |        |
```

第一正規形に直すと次のような状態になる

```
| 受注ID | 明細番号 | 商品   | 価格 |
|--------|----------|--------|------|
| 1      | 1        | りんご | 100  |
| 1      | 2        | みかん | 80   |
| 2      | 1        | バナナ | 150  |
```

## 第二正規形

対象：複合キーのテーブル
- 第一正規形を満たしている状態
- 主キーの一部でさらに分けることができない状態

次のような状態は、第二正規形ではない

```
// 複合キーの一部である商品IDで商品名と価格が特定できる

受注明細テーブル（複合キー：受注ID + 商品ID）
| 受注ID* | 商品ID* | 商品名 | 価格 | 数量 |
|---------|---------|--------|------|------|
| 1       | A001    | りんご | 100  | 2    |
| 1       | A002    | みかん | 80   | 3    |
*がついている列が複合キー
```

第二正規形に直すと次のような状態になる

```
受注明細テーブル
| 受注ID* | 商品ID* | 数量 |
|--------|--------|------|
| 1      | A001   | 2    |
| 1      | A002   | 3    |

商品テーブル
| 商品ID | 商品名 | 価格 |
|--------|--------|------|
| A001   | りんご | 100  |
| A002   | みかん | 80   |
```

## 第三正規形

- 第二正規形を満たしている状態
- 主キー以外の項目でさらに分けることができない状態

次のような状態は、第三正規形ではない

```
// 顧客情報が注文ごとに重複している（山田、東京）
受注テーブル
| 受注ID* | 顧客名 | 顧客住所 | 商品ID |
|--------|--------|----------|---------|
| 1      | 山田   | 東京     | A001    |
| 2      | 山田   | 東京     | A002    |
*がついている列が主キー
```

第三正規形に直すと次のような状態になる

```
// 山田と東京が1回しか出てこなくなった
受注テーブル
| 受注ID* | 顧客ID | 商品ID |
|--------|--------|---------|
| 1      | C001   | A001    |
| 2      | C001   | A002    |

顧客テーブル
| 顧客ID* | 顧客名 | 顧客住所 |
|--------|-------|---------|
| C001   | 山田   | 東京     |
```

## 正規化のメリット
- データの重複が減り、DB の容量的に無駄がない
- データの更新をするときに、複数箇所を変更しなくて良い
Google Colaboで簡単グラフ作成＋Gemini AI

# Google Colaboでグラフ作成

Pythonはそれなりに使っていたつもりですが、Matplotlibには一切触れて来ず、急にグラフを作成することになり困ったことになりました。

しかしGoogle Colaboを使えばあっさりグラフが作れたのでやり方を紹介します。

※データ自体はDataFrameで用意しておく必要があることご留意ください

## 準備

Google Colaboratoryにアクセスして[ノートブック新規作成]
https://colab.research.google.com/?hl=ja

グラフの日本語がおかしくなるのでjapanize_matplotlibのインストールだけしておいてください。

```python
!pip install japanize_matplotlib
```

## サンプルデータセット

今回はサンプルデータとしてyahoo-financeから1ヵ月分の日経平均データをDataFrameに入れます。

```python:yahoo-financeインストール
!pip install yahoo-finance
```

```python:サンプルデータセット
import yfinance as yf

code = "^N225"  # 日経225

nikkei = yf.Ticker(code)

# "1mo"で1ヵ月分取得
df_nikkei = nikkei.history(period="1mo")
```
## グラフの自動作成

DataFrameが出来たら出力してください。※printを使わず変数名だけで出力
これだけでデータが表示されます。

```python:データ表示
df_nikkei
```

<br>

ここまででこのような感じになります。

![スクリーンショット 2025-02-05 212535.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/95b4670a-d68c-f93d-b754-d0fc2253e637.png)

<br>

それではグラフを作成します。出力されたデータのグラフマークをクリックして下さい。

![スクリーンショット 2025-02-05 212600.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/c7bfb568-deac-c80b-826f-44bd69ffa8cf.png)

<br>

色々なグラフが出てきました。この中で好きな形式を選んで下さい。
（無かったらごめんなさい）

![スクリーンショット 2025-02-05 212651.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/77631973-4d72-d66d-9981-4ee915a0cde1.png)

ポップアップが出るので[セルを追加]を選んで下さい。

![スクリーンショット 2025-02-05 212722.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/fd8ca7b0-5cf4-0ad5-8661-29b9be77c793.png)

実行するだけでとグラフが出来ます。

![スクリーンショット 2025-02-05 212833.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/994302cb-c96f-490a-c435-c15f12dff9c5.png)


<br>

## Geminiによる修正

これだけではちょっと物足りないのでGeminiを使って修正したいと思います。
グラフを実行したセルを選択した状態（クリックで選択できます）で右上のダイヤのようなマークをクリック。「コードを説明する」をクリックします。

![スクリーンショット 2025-02-05 212912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/965fb307-6736-1a2a-4025-5128414f93dd.png)

<br>

そうしますとGeminiがコードを説明してくれますので、それに返信する形でやりたいことをお願いします。今回は最大値に矢印を付けてもらいます。（入力後に紙飛行機マークで送信）

![スクリーンショット 2025-02-05 213143.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/8d3e4096-e44b-1f27-a04f-88c123bef7ae.png)

<br>

Geminiが修正したコードを生成してくれたら、右上の「コードセルに追加」ボタンをクリックします。

![スクリーンショット 2025-02-05 213253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/4ef5488a-a272-b1fd-a6ff-abebf050bf85.png)

<br>

最大値へ矢印が追加できました。

![スクリーンショット 2025-02-05 213431.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/4a240e18-ddc3-36b8-f3fb-b1d1a138be16.png)

<br>

ちょっとタイトルと被ってるので改行してもらったり、タイトルを修正してもらったり、そういった指示にも応えてくれます。出来上がったのはこちらです。

![スクリーンショット 2025-02-05 213756.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3549938/5f56d298-9346-623a-e51b-437983ad0402.png)


**※タイトルなどが日本語だと文字化けするので"import japanize_matplotlib"はコードに追加して下さい。**


# おわりに

細かい指示などはまだ上手く行かない場合も多いですが、ざっとしたグラフをつくるならあっさりとできてしまいます。Google Colaboは勝手に色々進化しているので勉強しがいがありそうです！
競プロerの私がS問題を解く時に考えたこと

## 問題（要約）
> マンハッタン距離で半径を表される円がたくさんある。それらに被らないように最大の円を作れ。
> \- 電脳少女プログラミング2088 S問題


## 考えたこと
### 1つ目の思いつき
まず初めに思いついたのは、
**2次元bool配列を用意してそこに出し、中心と半径を全探索する** 方法。

さっそく計算量を考えてみる。

まず前処理としてマップを埋める。だいたい $O(HW)$ ぐらいじゃね、と思った。
次に探索する。これは中心1個ごとにおおよそ$O(HW)$かかり、中心を全探索するには$HW$回かかるから、合計で$O(H^2W^2)$かかる。
よって全体の[時間計算量](https://atcoder.jp/contests/apg4b/tasks/APG4b_w?lang=ja)は明らかに$O(H^2W^2)$である。

$H,W<=200$より、最大$O(1,600,000,000)$で、コンピュータの限界だと考えられている秒あたり$O(10^9)$を超えている。
よっておそらくTLE(実行時間超過)が出る。
~~あとは多分S問題でゴリ押し解法が通るわけない~~

### 2つ目の思いつき
でもまだ全探索を諦めたくない。
ここで、$M(縄張りの個数)<=200$に着目する。
どうにかして縄張り1つに対する半径の最大値を$O(1)$で求めることができれば、すべてのマスを全探索しても$O(HWM)$、つまり$O(8,000,000)<10^9$で、十分間に合う解法であることがわかる。

ではどうやって半径の最大値を$O(1)$で求めるか。(~~多分$O(logN)$の二分探索でも間に合うケド~~)
ここで**半径がマンハッタン距離で表される**ことを利用する。
円の中心間のマンハッタン距離は、$(x_1,y_1),(x_2, y_2)$とおくと、$d=|x_1-x_2|+|y_1-y_2|$で求められる。
ここで、マンハッタン距離である事を忘れて普通の距離のように扱うと、$max(-1, 中心間の距離-片方の半径)$は最大の半径になる。
だから、これを実装してあげればAC。
※ちなみに、$max()$の左辺を0にしてないのは、そのマス自体が他の円の中に入っている状態をより楽に区別できるようにするため。

### 伝えたいこと
 - 楽な解法がダメそうでもちょっと粘ってみよう！
 - まずは無理そうでも計算量を出してみる！いろいろひねってみてそれを改善していこう！
 - (競技)プログラミングは、最高のコードを書くことが目的**なのではなく**、**最低限ACできる**コードを書くという競技。ACすればOK！これめっちゃ重要！

## 実装例(AC)
```C++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vl = vector<ll>;
#define rep(i,n) for(ll i=0;i<(n);i++)
#define chmin(a,b) a=min(a,b)
#define chmax(a,b) a=max(a,b)

int main() {
    ll h, w, m;
    cin >> h >> w >> m;

    vl x(m), y(m), r(m);

    rep(i, m) cin >> x[i] >> y[i] >> r[i];

    for (auto& i : x) i--;
    for (auto& i : y) i--;

    ll res = -INF;
    rep(i, h) {
        rep(j, w) {
            ll now = INF;
            rep(k, m) {
                ll dist = abs(i - x[k]) + abs(j - y[k]);
                ll remain = dist - r[k] - 1;
                chmin(now, remain);
            }

            chmax(res, now);
        }
    }

    chmax(res, -1LL);

    cout << res << endl;
}
```

## さいごに
なにか質問、疑問、感想とかあればコメントへお気軽に。投稿の励みになります。
【Excel】指定範囲で〇〇グループの〇〇位の値を一発抽出！

## `要件`
##### 範囲の中で検索条件内で順位付けした値を探す
例えば表の中の「りんご」の中で一番安い店

## `例`
このような表があったとする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287842/c8ead5f5-39a6-03b8-fa5b-faa07d0df407.png)

ここではリンゴが2番目に安い店を例にしてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287842/321429f0-c23c-0dc9-192c-c7b9eead68ed.png)

H3セルに以下の関数を入力

:::note info
=INDEX(B:B, INDEX(ROW(D:D), MATCH(SMALL(IF(C:C=F3, D:D), G3), IF(C:C=F3, D:D), 0)))
:::
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287842/1791a9a6-3f54-1902-3371-c3509a76b859.png)
Python pandasまとめ

## 概要
pandas は、Pythonで 表形式のデータ（ExcelやCSVなど）を扱うためのライブラリ で、以下のようなことができる。
***
### 1. データの読み書き
🔹 様々なファイル形式に対応
	•	CSV, Excel, JSON, SQL などを読み書きできる。
```:python
import pandas as pd

# CSVの読み込み
df = pd.read_csv('data.csv')

# CSVへの書き出し
df.to_csv('output.csv', index=False)

# Excelの読み込み（openpyxlが必要）
df = pd.read_excel('data.xlsx')

# JSONの読み込み
df = pd.read_json('data.json')
```
***
### 2. データの確認・探索

🔹 データの内容を素早くチェックできる
```:python
print(df.head())  # 最初の5行を表示
print(df.tail())  # 最後の5行を表示
print(df.info())  # データの型や欠損値の確認
print(df.describe())  # 数値データの統計情報
```
***
### 3. データの抽出・フィルタリング

🔹 条件に合うデータを取り出せる
```:python
# "点数" が 80 以上の行を取得
high_scores = df[df['点数'] >= 80]

# "名前" だけ取得
names = df['名前']
```
***
### 4. データの加工・変換

🔹 列の追加・削除、データの変換
```:python
# 新しい列を追加（例: 合格判定）
df['合格'] = df['点数'] >= 80

# 列の削除
df = df.drop(columns=['不要な列'])

# データの型を変換
df['年齢'] = df['年齢'].astype(float)
```
***
### 5. データの集計

🔹 グループごとの集計や統計
```:python
# 平均値の計算
print(df['点数'].mean())

# 学年ごとに平均点を出す
print(df.groupby('学年')['点数'].mean())

# 値のカウント（頻度集計）
print(df['学年'].value_counts())
```
***
### 6. 欠損値の処理

🔹 データの抜け（NaN）を処理
```:python
# 欠損値の確認
print(df.isnull().sum())

# 欠損値を削除
df = df.dropna()

# 欠損値を平均値で埋める
df['点数'] = df['点数'].fillna(df['点数'].mean())
```
***
### 7. データの並び替え

🔹 特定の列でソート
```:python
# "点数" の降順に並び替え
df = df.sort_values(by='点数', ascending=False)
```
***
### 8. データの可視化

🔹 グラフを作成
```:python
import matplotlib.pyplot as plt

df['点数'].plot(kind='hist')  # ヒストグラム
plt.show()

df.plot(x='名前', y='点数', kind='bar')  # 棒グラフ
plt.show()
```
***
### 🔍 pandas の使用タイミング
•	CSVやExcelのデータを処理・分析したい
•	Webスクレイピングしたデータを整理したい
•	データを集計・加工してレポートを作りたい
•	グラフを作ってデータを可視化したい
ClineでGitHub Copilotを使用する方法

# はじめに
生成AI系のサービスの進化は激しく，最近ではDeepSeekやOpenAIからo3が登場するなど，感激とエンジニアの仕事がなくなるのではないかという恐怖が同時に押し寄せております． また，AIが自律的に考え，実行するAI-Agentも身近となり，コーディングではClineという拡張機能が有名だと思います．ClineはAPI経由での利用となるため，API料金が発生し，庶民にとっては少し手が出しづらい状況でした． しかし，Clineのアップデートにより，GitHub Copilotも対応したため，個人プランは10ドルで，また学生なら無料で利用可能となりました！
そこで，本記事では，ClineでGitHub Copilotを使う手順について解説いたします．

# GitHub Copilot
まずは，ClineでGitHub Copilotを利用するために，GitHub Copilotの拡張機能をインストールしてください．  

https://marketplace.visualstudio.com/items?itemName=GitHub.copilot

GitHub Copilotは無料枠も用意されておりますが，学生ならGitHub Copilot Proが無料で利用できます． 申請方法は以下を参照してください．  

https://docs.GitHub.com/ja/copilot/managing-copilot/managing-copilot-as-an-individual-subscriber/managing-your-GitHub-copilot-pro-subscription/getting-free-access-to-copilot-pro-as-a-student-teacher-or-maintainer

# Clineのインストール
次に， Clineをインストールします．  

https://marketplace.visualstudio.com/items?itemName=saoudrizwan.claude-dev

# Clineの設定
インストールが終わったら，VScodeでClineの設定をしていきます．
## API Provierの設定
まず，API Provierの設定をします．Clineの設定画面に移動し，下記の画像のように「VS Code LM API」を選択してください．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734306/531cdb03-69d6-8390-e4df-e4b5897e7a91.png)

## Language Modeの設定
Language Modelを選択します． 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734306/c11fab1c-9e8f-8cb0-b69c-59cdc36d8e06.png)

[Artificial Analysis](https://artificialanalysis.ai/)によると，Coding (HumanEval)の評価では，o1とo3-miniが高得点で，また処理速度も考慮するとo3-miniが早いため，言語モデルはo3-miniがおすすめです． ただ，使用感はClaude Sonnetがよかったりするので，一度いろいろと試してみると良いです．ここではo3-miniを選択します．

## Custom Instrcutionの設定
次に，Custom Instructionの設定です．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734306/d645b341-e298-1ca5-4045-bcb4af7a28b7.png)
AIの動作をカスタマイズできます．「応答を日本語にする」，「技術的内容を詳しく説明する」，「特定のフォーマットで返答する」など，お好みに合わせてください．今回は空欄でいきます． 


設定後は右上の「Done」を押して確定してください．

## Auto approveの設定
Clineが実行中に，特定の操作を実行する際には，ユーザーの手動承認を求めることがあります． 毎回承認を許可するのはめんどうなので，Auto approveの設定を変更することで，自動承認を許可し，コード編集やファイル操作をスムーズに行えるようにしましょう．下の画像のように各操作にチェックマークを付けてください．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734306/9e0e478a-51fd-0c56-744f-257c4def363f.png)
ただし，この設定は危険なコマンドを実行してしまうリスクため，注意が必要です．

### 自動承認可能な操作
1. **Read files and directories**  
   PC上の任意のファイルやディレクトリを読み取る権限を許可します．

2. **Edit files**  
   ClineがPC上のファイルを変更できるようにします．

3. **Execute safe commands**  
   安全と判断されたターミナルコマンドの実行を許可します． ただし，破壊的なコマンドは引き続き手動承認が必要です．

4. **Use the browser**  
   ヘッドレスブラウザを用いて，ウェブサイトの自動操作を可能にします．

5. **Use MCP servers**  
   設定済みのMCPサーバーを利用し，ファイルシステムの変更やAPIとのやり取りを実現します．

### その他
- **Max Requests: 20**  
  Clineは最大20回まで自動でAPIリクエストを実行します． これを超える場合は，再度承認が求められます．

- **Enable Notifications**  
  タスク完了時や手動承認が必要な場合に通知を送信し，進捗確認を容易にします．

# 実験
それでは，実際にタスクを設定して動作を確認してみましょう．  例として，「モダンなホームページを作ってください」と入力します．

![無題の動画 ‐ Clipchampで作成 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2734306/9890f18c-6c9b-1a1b-51b6-2876f1b97496.gif)
しばらく待つと自動生成されたエンジニア企業っぽいホームページができあがりました．


少し味気ない，ホームページではありますが，タスクを設定するだけで，全く手を加えずにここまでできました．

# おわり
以上，ClineでGitHub Copilotを使う手順について解説いたしました．  
導入は非常にシンプルですので，ぜひ積極的にご活用して，生産性を向上させていきましょう！
コンテナ間通信でハマった話

## 1.はじめに
GoとReactを使ったアプリケーションをdockerで作成しているとき、GoとReactの通信が上手くいかず数時間ハマったので原因と解決策を備忘録としてまとめます。

## 2.何が起こったのか
下記のdocker-compose.ymlでGo,React,DB用のコンテナを三つ立てていました。
``` docker:docker-compose.yml
volumes:
  postgres-data:


services:
  reactapp:
    build: ./front
    tty: true
    working_dir: /app
    volumes:
      - ./front:/app
    command: sh -c "npm start"
    ports:
      - "3000:3000"
    networks:
      - net_test
    env_file:
      - .env
  goapp:
    build: ./backend
    volumes:
      - ./backend:/app
    # command: sleep infinity
    command: air
    # network_mode: service:db
    ports:
      - "8080:8080"
    networks:
      - net_test
    env_file:
      - .env
  db:
    image: postgres:latest
    restart: unless-stopped
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - net_test
    ports:
      - "5432:5432"
    env_file:
      - .env
networks:
  net_test:
    external: true

```
異なるコンテナ間の通信はサービス名で名前解決できるとのことだったので、http://${サービス名}:${ポート名}という感じでReactからバックエンド(Go)にアクセスを行うようにしました。
``` .env
REACT_APP_GO_BASE_URL=http://goapp:8080
```
``` react:login.jsx
try {
    const response = await axios.post("`${process.env.REACT_APP_GO_BASE_URL}/registerPhoto", {
                username,
                likedPhotoStatus: photosArray})
} catch (error) {
    console.error("CannotRegisterLikedPhoto", error)
}
```
すると、net::ERR_NAME_NOT_RESOLVEDというエラーが出ました。どうやら、名前解決ができていないようです。
？？？？？サービス名で名前解決できるんじゃないの！？
## 3 原因と解決策
色々調べてみると、Reactは当然ですがブラウザ上で動いています。なので、Reactはコンテナの上で動いているのではなくあくまでもブラウザの上で動いているということなのです。
そのため、http://${サービス名}:${ポート名}でアクセスするのではなくhttp://localhost:${ポート名}でアクセスする必要があるとのことでした。
localhostに変更したら無事バックエンドへのアクセスができました！！
``` .env
REACT_APP_GO_BASE_URL=http://localhost:8080
```
## 参考
https://qiita.com/pappy/items/95edbb644ac12a35e259

https://qiita.com/Mayumi_Pythonista/items/11b412e59e045a2c5eb3
USB接続したreCameraをブリッジ接続でインターネットにアクセスできるようにする

# 1. はじめに

switch-scienceから[reCamera](https://www.switch-science.com/products/10092)を購入したのですが、Wi-Fi搭載モデルの **reCamera 2002w** は2025.2.5時点で技適未認証のためか、日本国内ではWi-Fi非搭載モデルの **reCamera 2002** しか購入できません。
このモデルは公式にはインターネット接続には付属のイーサネットケーブルで有線Ethernet接続が必要になるのですが、Node-REDのノードのインストールやEthernetを使用する外部機器との通信のためにいちいち有線接続するのは面倒なので、PCと接続しているUSBでブリッジ接続することでインターネットにアクセスできるようにします。

なお、この方法についてはX(旧twitter)にて@matsujirushi さんに多大なアドバイスをいただきました。
この場を借りてお礼申し上げます。

# 2. Windows側の設定

https://qiita.com/nkojima/items/4056d749328d4512c53f

を参照ください。
ネットワーク接続にてネットワークブリッジを作成すればいいのですが、「有線+無線での2回線構成の場合、起動時に無線が自動で接続されない」設定の無効化も必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360166/8e1441b7-cf28-6a5b-e3d0-24f338246d42.png)


# 3. reCamera側の設定

はじめに、念のため[公式](https://wiki.seeedstudio.com/recamera_getting_started/#os-upgrade-guideline)で紹介されている
* Manually update the latest OTA firmware
と
* Manually restore factory settings
を実施しておきます。

ファームウェアのzipファイルは[teraterm](https://teratermproject.github.io/)ならSSH SCPでreCameraに送信することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360166/0f5ce744-b2dd-4247-2258-47a02bd62123.png)


そのあと、
* /etc/init.d/S70hardware
* /etc/dhcpcd.conf
* /etc/resolv.conf

の3つのファイルを次のように書き換えます。

なお、前提として下記のIPアドレスであるものとします。
* DHCPサーバー(ルーター)のIPアドレス：192.168.11.1
* reCameraのIPアドレス：192.168.11.100


```bash:bash
sudo vi /etc/init.d/S70hardware

```

```diff:vi
~~~ 中略 ~~~

    sleep 0.5

    setup_wlan1
    config_ip wlan1 192.168.16.1
-   config_ip usb0 192.168.42.1
+   config_ip usb0 192.168.11.1
  ;;

  stop)
  
~~~ 中略 ~~~

```


```bash:bash
sudo vi /etc/dhcpcd.conf
```

```diff:vi
~~~ 中略 ~~~

# denyinterfaces usb0
interface usb0
metric 9997
- static ip_address=192.168.42.1/24
- static routers=192.168.42.1
- static domain_name_servers=192.168.42.1
+ static ip_address=192.168.11.100/24
+ static routers=192.168.11.1
+ static domain_name_servers=192.168.11.1

interface wlan1
metric 9998
static ip_address=192.168.16.1/24
static routers=192.168.16.1
static domain_name_servers=192.168.16.1
nohook wpa_supplicant

```

```bash:bash
sudo vi /etc/resolv.conf
```

```diff:vi
# Generated by dhcpcd from usb0.dhcp
# /etc/resolv.conf.head can replace this line
- nameserver 192.168.42.1
+ nameserver 192.168.11.1
# /etc/resolv.conf.tail can replace this line
```

ここまで設定できれば、```sudo reboot```で再起動したあとに```recamera.local```もしくは```192.168.11.100```でreCameraにアクセスすることができ、reCameraはインターネットに接続できていると思います。
※reCameraのブラウザコンソール上では```Not Connected```のためインターネットにアクセスできていないように見えますが、```ping www.google.com```などでpingを打つと応答が帰ってくるのでインターネットにアクセスできていると分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360166/dfb28331-5725-fc21-6d28-5958cd18bb36.png)


おわり
【ポエム】EQってなんだ

下記のリンクを読んでのかるーいメモです．
https://amzn.asia/d/6FSXfRB

中古でめっちゃ安くなってますね．

しっかり読んでから，まとめなおそうと思います．

# EQ（Emotional Intelligence）ってなんだ
自分自身と他者の心の動きに気づき，それを理解する力をEQという．
また，その気付きを使って自分の行動や人間関係をうまくマネジメントする力でもある．

EQはIQと異なり，後天的に身に着けられるスキル．
個性やIQとも独立している要素．


# EQが高いと何がいい？何が良さそう？
本の帯には，「EQの高い人は，お金に振り回されづらく，失敗や逆境にもうまく対処できることがわかっている」と書かれていた．

EQスキルが上がるにつれて，今の自分の感情が何に起因するものなのかが気付けるように，その感情に前向きに反応できるようになる．

「行動をコントロールできる」部分に影響するからEQは大事なのだと考えられる．

時間管理や意思決定やコミュニケーション力に含まれるほとんどのスキルはEQと関連性が強く，仕事の成功に「ものすごく」いい影響を与える．


# EQが低いとどうなる？
他人といるより，一人でいることを好む傾向が強くなる．

EQではなく，スペシャリスト的なスキルや経験ベースでのし上がった人たちは，EQが低い傾向にあるので，自身もここは注意が必要である．（トップ層でEQが高い人は減るそうだが，その中でもEQが高い人たちは特にパフォーマンスが高いとのこと）


# EQを高めるには？
本書の大部分を使って解説されている．

自身の行動のコントロールや，他者理解の部分が自身に欠けている部分と認識しているので，これから隙間時間で読み進めていこうと思う．
感情と行動のコントロールが伸ばすことのできるスキルとして体系化されていることが分かっただけでも収穫だった．

ざっくり目次を読んで今からやっていけそうなのは
- 自分の感情を俯瞰する癖をつける（自己認識力）
- 行動が思い通りでないときは，感情と理性の状況を書き出してから，行動計画に移す（自己管理力）
- 集まりに前もってそなえる＆他人の立場に立つ（社会的認識力）
- 心を開いて好奇心を持つ（人間関係管理力）
Mac Tips

# VNC接続

windowsからMacへ接続後、画面を拡大すると、固まる。
その場合は、Macで「システム設定＞アクセシビリティ＞ディスプレイ＞視差効果を減らす」にチェックし、拡大時のアニメーションを抑制する。

# XcodeとAppleWatch連携
AppleWatchが切断されたら、接続中のiPhoneをUnpairし（切断ではない）、再度接続する。
事前に、AppleWatchも同じネットワークに参入させとく

これでうまくいく。とりあえずこの方法で一旦様子見。

# 参考
* [Macで画面上の動きを抑制または減らす](https://support.apple.com/ja-jp/guide/mac-help/mchlc03f57a1/mac)
インターネットの仕組み

## はじめに
こんにちは、小林です。
今回はインターネットの仕組みについて記事を書いていこうと思います。

## インターネットとは
インターネットは、世界中のコンピュータなどの情報機器を接続するネットワークです。1990年ごろから、世界的に広く使われ始め、近年はその利活用が目覚しく進展してきました。現在では、私たちの生活や仕事などのさまざまな場面で使われる、不可欠な社会基盤となっています。
インターネットを利用するためには、さまざまな方法があります。家庭や学校、職場で利用する場合には、インターネットサービスプロバイダ（光回線、ケーブルテレビ回線などを通じて、インターネットに接続してくれるサービス事業者）と契約することによって、インターネットに接続できるようになります。携帯電話会社と契約することで、携帯電話回線を通じてインターネットを利用することもできます。

## インターネットの仕組みについて
複数のコンピュータを、ケーブルや無線などを使ってつなぎ、お互いに情報をやりとりできるようにした仕組みをネットワークと呼びます。
ネットワーク上で、情報やサービスを他のコンピュータに提供するコンピュータをサーバ、サーバから提供された情報やサービスを利用するコンピュータをクライアントと呼びます。私たちが普段使うパソコンやスマートフォン、タブレットなどは、クライアントにあたります。
### インターネット通信の流れ
インターネット通信の流れについてWebサイトが表示までの流れを例に説明していこうと思います。
Webサイトが表示されるまでの流れは、以下の通りです。

1．DNSサーバーにWebサーバーのIPアドレスを問い合わせる

2．DNSサーバーからアクセス先のIPアドレスが送られてくる

3．受け取ったIPアドレスのWebサーバーにページデータを要求する

4．Webサーバーから送られてきたページデータをブラウザで表示する
まずは、ユーザーが各種のブラウザでWebサイトのURLを入力し、Webサーバーにアクセスします。URLにはドメイン名が含まれていますが、インターネット通信ではドメイン名をIPアドレスに変換する作業が必要です。そこでDNSサーバーがこの作業を行い、IPアドレスを取得します。
そして、取得したIPアドレスのWebサーバーにデータをリクエストすると、Webサーバーはリクエストされたデータをブラウザ上で表示します。


# おわりに
インターネットの定義や仕組みなどを解説しました。データの送受信やWebサイトの利用は一般的なことですが、実際にはさまざまなソフトウェアが動いています。
また、今後はIoTやAIなどの発展で、モノとインターネットが繋がったり、インターネットを取り巻く環境が大きく変化したりする可能性があります。
以上、小林でした。
Windows11について

## はじめに
こんにちは小林と申します。
2025/10/25にWindows10のサポートが終了してしまう為、今後はWindows11へ移行していく必要があります。
今回はアップデート後のWindows11がどんなものかまとめてみようと思います。

## Windows11とWindows10の違い
### ①デザインの変更
Windows 11では、Windows 10の標識のように簡易化された「Metro（メトロ）デザイン」が廃止され、親しみやすさや落ち着きを感じられる「Fluent（フルーエント）デザイン」が導入されました。Fluentデザインでは、次のような5つのコンセプトに基づいて設計されています。

### ②タスクバーの機能とデザイン
タスクバーでは、スタートボタンとピン留めされたアイコンがセンタリングされ、操作性が向上しました。［ニュースと関心事項］は［ウィジェット］に集約され、［タスクビュー］ではタイムラインが廃止されるなど機能がシンプルになる一方、テレワークのニーズに応えるべくビジネスコミュニケーションアプリ［Teams］のアイコンが追加されています。

### ③ウィンドウのスナップ
開かれている複数のウィンドウを並べて表示するスナップ機能が強化されました。ウィンドウの［最大化］ボタンにマウスポインタを合わせると表示されるポップアップでスナップのレイアウトとウィンドウの表示位置を指定します。

### ④タッチキーボードが進化
Windows 11では、タッチパネルでの操作が身近になったことから、タッチキーボードがカスタマイズできるようになりました。キーボードにテーマを指定したり、キーの大きさを調節したりして、オリジナルのタッチキーボードを設定できます。

### ⑤Androidアプリに対応
Windows 11では、Android端末で利用できるアプリを利用できるようになります。Androidスマートフォンやタブレットで利用しているアプリをWindows上で利用できるようになると、利用可能なアプリの数が増えるだけでなく、スマートフォンやタブレットとの連携もスムーズになります。

## Windows11のメリット、デメリット
### メリットについて
- 豊富な機能が追加
- 動作性の向上

### デメリットについて
- Windows 11 へアップグレードできないケースがある
- 削除される機能がある

## Windows11へアップグレードする必要性
ここまでWindows11の特徴とメリット、デメリットについて説明してきましたが
実際にWindows11へアップグレードする必要性について自分なりの考えをまとめて
みようと思います。
結論から言うとWindows11へのアップグレードは必要であると思います。
まだまだWindows10比べて使用しずらい部分はあると思いますが、サポートが終了してしまう事を考えるとやはりアップグレードしておく必要があります。
PCがシステム要件を満たしているのであれば、早めのアップグレードしておく事がいいと思います。

## おわりに
Windows10のサポートが終了してしまう期限まで１年を切っていしまっています。
Windowsのサポートが終了しているものを使用し続けるリスクはセキュリティ面においても
危険性があります。皆さんもアップグレードしてみてはいかがでしょうか。
以上、小林でした。
個人的な備忘録：Sidecar コンテナの基本からメリットまで、自分なりに体系的にまとめてみた

## はじめに

近年、コンテナ技術の発展により、マイクロサービスアーキテクチャが一般的になっています。***その中で、特定の機能を分離し、独立して管理できる **Sidecar コンテナ** の設計パターンが注目されています。***

特に AWS ECS（Elastic Container Service）などのコンテナオーケストレーション環境では、Sidecar コンテナを活用することで、ログ収集やセキュリティ強化、データ同期などを効率的に実装できます。

本記事では、Sidecar コンテナの概念や用途、メリット・デメリットについて整理し、AWS ECS における設定例についても触れていきます。

## 書こうと思ったきっかけ

コンテナを活用したシステム開発において、**アプリケーションのロギングやモニタリングの実装方法に悩むことが多い** という課題がありました。

:::note warn
**また、セキュリティ強化やデータのキャッシュ管理など、**主コンテナとは別に特定の機能を持たせる設計を考える機会が増えた** ため、Sidecar コンテナの活用方法を整理することにしました。**
:::

特に、**AWS ECS のタスク定義における Sidecar コンテナの設定方法が分かりにくい** という声もあり、実際の導入例を含めて、わかりやすく解説することを目的としています。

## Sidecar コンテナとは？

Sidecar コンテナは、主コンテナ（アプリケーションコンテナ）の補助的な役割を担うコンテナであり、同じタスク内で動作することで特定の機能を提供します。

このパターンは、AWS ECS（Elastic Container Service）のようなコンテナオーケストレーション環境でよく使用されます。

## Sidecar コンテナの用途

Sidecar コンテナは、以下のような用途で活用されます。

**ログ収集とモニタリング**

- FireLens（Fluent Bit や Fluentd）を使用して、アプリケーションのログを CloudWatch Logs や Elasticsearch に送信する。
- AWS X-Ray を用いた分散トレーシングの実装。

**プロキシやセキュリティ強化**

- Envoy や AWS App Mesh を用いたサービスメッシュの実装。
- TLS 証明書の管理とリクエストの暗号化。

**データ同期やキャッシュ管理**

- Redis や Memcached を Sidecar として配置し、アプリケーションのキャッシュ機能を補助する。
- S3 や DynamoDB へのデータ転送の管理。

**ジョブのスケジューリングやタスクの実行**

- 定期的なデータ処理タスクを実行するスクリプトの管理。
- アプリケーションのリクエストに応じたデータ変換。

## Sidecar コンテナのメリット

- **分離性の向上**  
主コンテナのコードを変更せずに新しい機能を追加できる。

- **スケーラビリティ**  
Sidecar を独立してデプロイ・管理できるため、アプリケーションの拡張が容易。

- **再利用性**  
複数のアプリケーションで同じ Sidecar コンテナを使い回せる。

- **可観測性の向上**  
ロギングやモニタリングを独立して管理できる。

## Sidecar コンテナのデメリット

- **リソース消費**  
追加のコンテナが動作するため、メモリや CPU の使用量が増加。

- **複雑性の増大**  
コンテナ間の通信や設定が増えることで、管理の難易度が上がる。

- **デプロイの影響**  
Sidecar コンテナのバージョン管理や更新が必要。

## AWS ECS における Sidecar コンテナの設定例

AWS ECS では、タスク定義の `containerDefinitions` に複数のコンテナを定義することで、Sidecar コンテナを追加できます。

```json
{
  "family": "sidecar-example",
  "containerDefinitions": [
    {
      "name": "main-app",
      "image": "my-app:latest",
      "memory": 512,
      "cpu": 256,
      "portMappings": [
        {
          "containerPort": 8080,
          "hostPort": 8080
        }
      ]
    },
    {
      "name": "sidecar-logger",
      "image": "amazon/aws-for-fluent-bit:latest",
      "memory": 256,
      "cpu": 128,
      "logConfiguration": {
        "logDriver": "awslogs",
        "options": {
          "awslogs-group": "/ecs/sidecar-example",
          "awslogs-region": "us-east-1",
          "awslogs-stream-prefix": "sidecar"
        }
      }
    }
  ]
}
```

この例では、`main-app` がアプリケーションのコンテナであり、`sidecar-logger` がFluent Bitを使用してログをCloudWatch Logsへ送信するSidecar コンテナとして動作します。

## まとめ

Sidecar コンテナは、アプリケーションの補助的な機能を提供することで、可観測性やセキュリティを向上させる重要な技術です。

:::note info
**適切に活用することで、マイクロサービスアーキテクチャの拡張性や運用の効率化を図ることができます。**
:::

ただし、リソース管理や運用の複雑性も増すため、用途に応じて慎重に設計することが求められます。
【Excel】VLOOKUPの限界突破！INDEX関数とMATCH関数で複数条件検索

## `要件`
##### 範囲の中から特定条件に対する値を探すにはVLOOKUPを使うと思うが、複数条件で探す場合にはEXCELで用意された一つの関数では難しい。そこでINDEX関数とMATCH関数を組合すことで実現させる

## `例`
左の表から「AM店」かつ「みかん」の値段を出したい場合
H3セルに以下の関数を入力

:::note info
=INDEX(D:D,MATCH(F3&G3,B:B&C:C,0),1)
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287842/6db15b1a-0580-4368-a13a-01e222e03004.png)

:::note info
説明
=INDEX(「表の値段の列」,MATCH(「探したい店名」&「探したい品物」,「表の店名の列」&「表の品物の列」,0),「表の値段の列番号」)

＝MATCH(**「A」&「B」&「C」,「A」&「B」&「C」**
＆で対象を増やすことも可能
:::
【kintone標準機能】「こんなときどうする？」アクション、関連レコードで解決する方法をまとめてみた。

# はじめに

ノベルワークスのつつみん（[@tsutsumin_38](https://x.com/tsutsumin_38)）です。
　前回に引き続き、実践型研修で学んだことをアウトプットしたいと思います。お客様との打ち合わせを想定した研修の中で、kintoneの標準機能で要望に応える場面もありました。「こんなときどうする？」をまとめてみようと思います。

 ## こんなときどうする？その１
 
 ### 前提
 - 顧客管理アプリと案件管理アプリがある
 - 顧客管理アプリにアクションの設定があり、案件管理アプリに「企業名」を転記している
 - 案件管理アプリの「企業名」（ルックアップフィールド）、ほかのフィールドのコピーで「部署名」「担当者名」「社内営業担当」を転記している

![プレゼンテーション1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957410/2c1ce35f-58bc-41a4-a72c-b2f64359ea44.jpeg)





 ### 要望
営業担当フィールドだけは編集できるようにしたい。
→社内営業担当は顧客ごとに決まっているけど、案件によっては変更になったり2人で担当することもあるので。

 ### 解決方法
 - 案件管理アプリの「企業名」（ルックアップフィールド）の設定で→ほかのフィールドのコピー「社内営業担当」をはずす
 - アプリアクションの設定に「社内営業担当」を追加
 ![スライド2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957410/c1d049d9-fbcc-6b07-6408-4da300d9b690.jpeg)
 
この方法で、顧客管理アプリの「社内営業担当」が転記され、なおかつ編集できる！
 
:::note info
ポイント
ルックアップでほかのフィールドのコピーに設置したフィールドは編集できないが、アクションで転記したフィールドは編集できる
:::

 ## こんなときどうする？その２
### 前提
- 顧客管理アプリと案件管理アプリがある
- 案件管理アプリに「企業名」（ルックアップフィールド）を設定、ほかのフィールドのコピーで「部署名」「担当者名」を転記している
- **社内営業担当フィールドは、編集したいのでほかのフィールドのコピーに設定していない**
 <img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957410/ac9f634e-fecb-aa18-2232-65b848ac0d30.png">

### 要望
案件管理アプリで入力（新規、編集する）ときに、顧客管理アプリの社内営業担当を参照しながら、案件管理アプリの社内営業担当を入力したい。

### 解決方法
- 関連レコードを設定する
    （ルックアップの取得ボタンを押すと、関連レコードが表示される）
    
![スライド2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3957410/49f7c826-7bb0-2652-b542-ace50e100407.jpeg)

この方法で、顧客管理アプリの企業「F」の「社内営業担当」を参照しながら、案件の「社内営業担当」を入力できる！

:::note info
ポイント
関連レコードは、すぐに表示されるので参照しながら入力を進められる
:::

# まとめ
　kintoneの標準機能についてまだまだ勉強不足だと思ったので、「こんなときどうする？」をまとめてみました。いろんな事案を経験して、すぐに解決方法を提案できるようになりたいと思っています！
24時間365日運用可能なビットコイン自動裁定取引システム

### 1. 環境構築

#### 1.1 Pythonのインストール
まず、Pythonをインストールします。Windows 11では、以下の手順でインストールできます。

1. [Python公式サイト](https://www.python.org/downloads/)から最新版をダウンロードし、インストールします。
2. インストール時に「Add Python to PATH」にチェックを入れることを忘れないでください。

#### 1.2 必要なライブラリのインストール
次に、必要なPythonライブラリをインストールします。コマンドプロンプトまたはPowerShellを開き、以下のコマンドを実行します。

```bash
pip install ccxt pandas numpy requests
```

- `ccxt`: 取引所APIの統合ライブラリ
- `pandas`: データ分析ライブラリ
- `numpy`: 数値計算ライブラリ
- `requests`: HTTPリクエストを行うライブラリ

### 2. APIキーの取得

使用する取引所（例: Binance）のAPIキーを取得します。取引所のアカウントにログインし、API管理ページからキーを生成します。APIキーとシークレットキーを安全に保管してください。

### 3. 自動裁定取引システムの作成

以下は、Binanceと別の取引所（例: Kraken）間でアービトラージを行うための基本的なPythonコードです。

```python
import ccxt
import time
import pandas as pd

# APIキーの設定
binance_api_key = 'your_binance_api_key'
binance_secret = 'your_binance_secret'

kraken_api_key = 'your_kraken_api_key'
kraken_secret = 'your_kraken_secret'

# 取引所の初期化
binance = ccxt.binance({
    'apiKey': binance_api_key,
    'secret': binance_secret,
})

kraken = ccxt.kraken({
    'apiKey': kraken_api_key,
    'secret': kraken_secret,
})

# 通貨ペアの設定
symbol = 'BTC/USDT'

def get_price(exchange, symbol):
    ticker = exchange.fetch_ticker(symbol)
    return ticker['last']

def arbitrage_opportunity(price1, price2):
    spread = abs(price1 - price2)
    return spread > 0.01  # スプレッドが1%以上の場合にアービトラージ機会とみなす

def execute_trade(exchange, symbol, side, amount):
    order = exchange.create_order(symbol, 'market', side, amount)
    return order

def main():
    while True:
        binance_price = get_price(binance, symbol)
        kraken_price = get_price(kraken, symbol)

        if arbitrage_opportunity(binance_price, kraken_price):
            if binance_price < kraken_price:
                # Binanceで買い、Krakenで売る
                execute_trade(binance, symbol, 'buy', 0.001)
                execute_trade(kraken, symbol, 'sell', 0.001)
            else:
                # Krakenで買い、Binanceで売る
                execute_trade(kraken, symbol, 'buy', 0.001)
                execute_trade(binance, symbol, 'sell', 0.001)
            print(f"Arbitrage executed: Binance {binance_price}, Kraken {kraken_price}")
        else:
            print(f"No arbitrage opportunity: Binance {binance_price}, Kraken {kraken_price}")

        time.sleep(10)  # 10秒ごとにチェック

if __name__ == "__main__":
    main()
```

### 4. コードの説明

- **APIキーの設定**: BinanceとKrakenのAPIキーを設定します。
- **取引所の初期化**: `ccxt`ライブラリを使って取引所を初期化します。
- **価格取得関数**: `get_price`関数で指定した通貨ペアの最新価格を取得します。
- **アービトラージ機会の検出**: `arbitrage_opportunity`関数で価格差をチェックし、アービトラージ機会があるかどうかを判断します。
- **取引実行関数**: `execute_trade`関数で市場注文を実行します。
- **メインループ**: `main`関数で定期的に価格をチェックし、アービトラージ機会があれば取引を実行します。

### 5. 注意点

- **API制限**: 取引所のAPIにはリクエスト制限があるため、過剰なリクエストを避けるようにしてください。
- **セキュリティ**: APIキーやシークレットキーをコードに直接書かず、環境変数や設定ファイルから読み込むようにしてください。
- **バックテスト**: 実際の資金を投入する前に、過去のデータを使ってバックテストを行い、ボットの性能を確認してください。

### 6. 次のステップ

- **ログの追加**: 取引の記録をログファイルに保存し、後で分析できるようにします。
- **リスク管理**: 損失を最小限に抑えるためのストップロスやテイクプロフィットの機能を追加します。
- **最適化**: アルゴリズムを最適化し、より効率的にアービトラージを行うための改善を続けます。

このコードは基本的な例であり、実際の運用にはさらに多くの機能と改善が必要です。特に、目標とする高いリターンを達成するためには、市場の深い理解と高度なアルゴリズムが必要です。
Snowflakeを使用する際によく使うSQLまとめ①

# 書いたきっかけ

３月末にSnowflakeの資格取得するための自身のアウトプットの場でもあるのですが、
自分の辞書代わりや、みなさまにも共有して便利になれたら一石N鳥だと思い投稿しました。


# CREATE FUNCTION

UDFを作成することが可能となっております。
以下はSnoflakeの組み込み関数を使用して、UDFを作成しております。

```sql
CREATE OR REPLACE FUNCTION DAY_NAME_ON(NUM_OF_DAYS INT)
    RETURNS STRING
        AS
        $$
        SELECT 'IN' || CAST(NUM_OF_DAYS AS STRING) || ' DAYS IT WILL BE A ' || DAYNAME(DATEADD(DAY,NUM_OF_DAYS,CURRENT_DATE()))
        $$;


SELECT DAY_NAME_ON(100);
```

LANGUAGEを指定することで、
以下の高級言語も使用することができます。
デフォルトでは、上のクエリの通り、sqlになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/30086f58-8e3c-46df-b341-81b2ea806bec.png)


# CREATE EXTERNAL FUNCTION

もし仮に、既にAWSのLambdaなどに関数が用意されていて、それを用いりたい場合は、
これを使用します。

API GatewayなどとAPI連携することで、Snowflakeからクラウドリソースを使用することで
実行することができます。

一例をこちらに記載します

```sql
CREATE OR REPLACE API INTEGRATION DEMONSTRATION_EXTERNAL_API_INTEGRATION_01
    API_PROVIDER = AWS_API_GATEWAY
    -- API GATEWAY を正常に動作することができるロールを付与
    API_AWS_ROLE_ARN = 'ARN'
    -- エンドポイントURLを記載
    API_ALLOWED_PREFIXES = ('API GATEWAY URL')
    ENABLED = TRUE;


CREATE OR REPLACE EXTERNAL FUNCTION LOCAL_ECHO(STRING_COL VARCHAR)
    RETURNS VARIANT
    API_INTEGRATION = DEMONSTRATION_EXTERNAL_API_INTEGRATION_01
    AS 'PROXY SERVICE URL'


SELECT LOCAL_ECHO('test')

```

メリットとして、
そのままある既存の関数を使用することができること
開発コストが少なくなる

デメリットとしては、
通信の関係で、レスポンスが遅れることです。

基本的にはUDFを使用することが推奨されていますが、
snowflakeではサポートされていない言語が使用されていることだったり、
やむを得ない場合は使用することを検討すると言ったところでしょうか。

https://docs.snowflake.com/ja/sql-reference/external-functions-introduction


# CREATE SEQUENCE
テーブルをINSERTする際など、レコードごとに一意な値を情報として欲しい場合が
実務においてほしいタイミングがかなりあります。

その際にレコードごとにシーケンス番号をつけることができるのが、
CREATE SEQUENCEです

以下に一覧を記載します

```sql

CREATE SEQUENCE TRANSACTION_SEQ

START = 1001

INCREMENT = 1;

CREATE OR REPLACE TABLE TRANSACTIONS(
ID INTEGER DEFAULT TRANSACTION_SEQ.NEXTVAL,
AMOUNT DOUBLE
);

INSERT INTO TRANSACTIONS(AMOUNT)
VALUES(1000.0);

SELECT * FROM TRANSACTIONS;

```
結果は以下のようになります。
INSERTにはAMOUNTしか追加していませんが、前列取得してみると、IDに値が入っていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526914/da83ed06-6878-a4f2-25e1-77628ebca311.png)

私自身、当初実務でこの機能を知らずに、あるテーブルのシーケンス番号を作成する際に、
PKキーを使用して、クエリを作成してシーケンス番号を作成していました。

# CRETE TASK
日々のクエリを自動化させたい場合に、使用するSQLになります。
よく使用されるのは、COPY INTOと合わせて、データレイクからSnowflakeにロードする場面などです。

簡単な一例を作成しました。
SCHEDULEについては、cronを使用することも可能です。

```SQL
CREATE TASK T1
    WAREHOUSE = COMPUTE_WH
    SCHEDULE = '30 MINUTE'
AS
    SELECT 1;
    
```

また、DAGで定義することも可能です。
TASK3を参照すると、AFTERというものが追加されていることがわかります。
あるタスクが終了したら次のタスクを開始させることができます。

これはかなりの場面で使用されるので、とても便利です
```sql
CREATE TASK T1
    WAREHOUSE = COMPUTE_WH
    SCHEDULE = '30 MINUTE'
AS
    SELECT 1;

CREATE TASK T2
    WAREHOUSE = COMPUTE_WH
    SCHEDULE = '30 MINUTE'
AS
    SELECT 1;


CREATE TASK T3
    WAREHOUSE = COMPUTE_WH
    AFTER T1,T2
AS
    SELECT 1;
```
Xcode SwiftUIでHot Reloadを行う

### はじめに

SwiftUIで階層が深い箇所のデザイン適応などをしていると
ある程度はプレビューでも出来るのですが実際の表示も確認したくなった時にビルド→画面遷移のコストがバカになりません。

Flutterみたいにホットリロードしたいなと思っていたのですが、[InjectionIII](https://github.com/johnno1962/InjectionIII)を活用することで実現できました。

導入したXcodeのバージョンは16.2です。2025/02/05時点で動作を確認しています。

### 環境構築

1\. [InjectionIIIのReleases](https://github.com/johnno1962/InjectionIII/releases)からInjectionIIIアプリをダウンロードして起動します。

![スクリーンショット 2025-02-05 20.21.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618958/ca9aeb08-f3ce-8f15-1303-1a735ecd36c0.png)

起動するとメニューバーに表示されます。

![スクリーンショット 2025-02-05 20.23.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618958/f39aa5b7-00b4-041c-26da-540dd90c4474.png)


2\. ホットリロードしたいプロジェクトを開きAdd Package Dependencies...から`https://github.com/krzysztofzablocki/Inject.git`を追加します。

![スクリーンショット 2025-02-05 20.10.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618958/0cb469cc-a5ba-93e8-9eee-deb86cca4bd7.png)

3\. 忘れずにFrameworksに追加します。

![スクリーンショット 2025-02-05 20.25.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618958/44792f1d-06eb-6bb2-6e2b-e6e38ce17bc0.png)

4\. Other Linker FlagsのDebugに`-Xlinker`と`-interposable`を追加します。

 ![スクリーンショット 2025-02-05 20.10.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618958/66ca2798-29ad-afa3-314b-1d0a5650438e.png)

5\. Hot reloadしたいViewにコードを追加します。

```swift
import Inject // 追加

struct LargeTextListView: View {
    @ObserveInjection var inject // 追加
```

```swift
    var body: some View {
        List(self.dataList) { textData in
            LargeLineTextView(textData.text)
        }
        .enableInjection() // 追加
    }
```

6\. InjectionIIIアプリの`Open Project`から、Xcodeプロジェクトがあるディレクトリを選択します。

![スクリーンショット 2025-02-05 20.22.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618958/fbe9b9ca-7728-08ae-6489-62106f30e628.png) ![スクリーンショット 2025-02-05 20.33.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618958/c779ff21-a5e1-47d2-2a1c-8703206fcd38.png)

7\. Xcodeでアプリを実行します。(Command + R)

実行時にうまく出来ていればと以下のようなXcodeのログが表示されます。

```
💉 InjectionIII connected /path/to/SmallUIs/SmallUIs.xcodeproj
💉 Watching files under the directory /path/to/SmallUIs
```

8\. 5で追加したViewを表示した状態で、コードを変更し保存すると以下のようなログが表示されて、数秒で変更が反映されます！

```
💉 Compiling /path/to/SmallUIs/SmallUIs/LargeTextListView.swift
💉 Selecting Xcode /Applications/Xcode16.2.app/Contents/Developer
💉 Loading .dylib ...
💉 Interposed 8 function references.
💉 Injected type #1 'SmallUIs.LargeTextListView'
💉 Injected type #2 'SmallUIs.LargeTextListView.TextData'
```

### 最後に

以上です。
XcodeだけではなくVSCodeやCursorでの開発でも使えるらしいです。こういうのをうまく活用して効率化していきたいと思います！
コマンドを使用したグローバルIPの確認方法いろいろ


調べてみたらいろいろあったのでメモ。

```sh:
# https://github.com/mpolden/echoip
# Star 3k
$ curl ifconfig.co
xxx.xxx.xxx.xxx
```

```sh:
# https://ipinfo.io/about
$ curl ipinfo.io
{
  "ip": "xxx.xx.xx.xx",
  "hostname": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "city": "xxxxxxxx",
  "region": "xxxxxxxx",
  "country": "JP",
  "loc": "xxxxxxxxxxxxxxxx",
  "org": "xxxxxxxxxxxxxxxxxxxxxx",
  "postal": "xxxxxxx",
  "timezone": "Asia/Tokyo",
  "readme": "https://ipinfo.io/missingauth"
}

# グローバルIPのみ取得
$ curl ipinfo.io/ip
xxx.xxx.xxx.xxx
```

```sh:
# IPv6でアクセスするとIPv6で帰ってくる
$ curl ifconfig.io

# 明示的にIPv4を指定するには -4 をつける
$ curl ifconfig.io -4
xxx.xxx.xxx.xxx
```

```sh:
# IPv4のみに対応
$ curl ifconfig.me
xxx.xxx.xxx.xxx
```

```sh:
# https://github.com/masahide/inet-ip.info
$ curl inet-ip.info
xxx.xxx.xxx.xxx
```

```sh:
# https://github.com/masahide/inet-ip.info
$ curl ipecho.net/plain
xxx.xxx.xxx.xxx
```

```sh:
# 応答がはやい
$ ipaddr.show
xxx.xxx.xxx.xxx
```

```sh:
# Google
$ curl https://domains.google.com/checkip
xxx.xxx.xxx.xxx
```

```sh:
# AWS
$ curl checkip.amazonaws.com
xxx.xxx.xxx.xxx
```

# まとめ

AWSにもグローバルIPを確認できるサービスがあった。
以下が覚えやすく使いやすかった。
- ipinfo.io 
- checkip.amazonaws.com
CSSを画面に反映させる方法

CSSを画面に反映させる方法は2つ

今回の例では、
①画面にあるすべてのテーブルに対して反映
②1つのテーブル（設定した特定の要素）に対して反映

### ①HTMLタグをStyle Sheet Editorに追加する
`画面にあるすべてのテーブルに対して反映`

テーブルウィジェットを画面にドラッグした時のデフォルト
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691264/b73c0cda-f8ad-26a2-15da-394170fd1c43.png)

Style Sheet Editorを開く
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691264/a4ee1fba-0f21-d2a0-c3ea-1dfedabd7c37.png)

"table｛｝"のようにHTMLタグを記載する
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691264/6b69c886-9e43-a323-ead7-7b1dfd3bb76d.png)

```
table {
    border-collapse: collapse;
    border: 2px solid cornflowerblue !important;
}

table th {
    border: 2px solid cornflowerblue;
}

table td{
    border: 2px solid cornflowerblue;
}
```
2つのテーブルの枠の色が変わりました
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691264/86bf0e2c-ad14-78a7-add9-233f8a42696d.png)


### ②クラスを定義する
`設定した特定の要素に反映される`

クラスを定義した上で、ウィジェットのPropertiesのAttributeのclassに.を除いた文字列を設定
①との違いは先頭に .があるかどうか

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691264/206bb42b-4b60-5056-cc84-15119d2ae0ff.png)

```
.table-container{
border-collapse: collapse;
border: 2px solid cornflowerblue 
}
.table-container th {
    border: 2px solid cornflowerblue;
}
.table-container td{
    border: 2px solid cornflowerblue;
}
```
上のテーブルの枠の色が変わりました
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691264/688f620e-4161-d2fd-e699-ee4fc684a90e.png)
【OrbStack】ローカルでファイル更新したらdockerコンテナ内で更新されないんだが...

# この記事の意図
個人備忘録の範疇の記事です。
OrbStackの技術記事がまだ少ないので、もしヒントになったりしたら嬉しいです。
＊写真とかコマンドとか何も載せてなくてすみません...メモ的な記事なので...ご了承ください

# こんな質問が...
Docker Desktop (DockerHub)→OrbStackに移行しました。
いやー[この記事](https://qiita.com/Hiroshi_Sakai_flat/items/2a3836ac5f09731fa63a)見てもらうとわかりますが、結構すんなりうまくいったなー
と思っていました...

＊とあるチャットツールにて...
「あのーすみません。ファイルの更新がされなくて...」
「え？どうゆう状況だ？」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699389/7278ecc5-cba4-5452-bb60-e85bcf12c673.png)


# というわけで状況調査...
どうやら
ローカルでファイルを新しく作成したり、mv, cp等のコマンドでファイル移したりしても、dockerコンテナ内で更新されない問題が起きている！
ということがわかりました。

## とりあえず、公式やら記事やら調査...
OrbStackの記事はかなり少ない印象で、同じようなファイル更新されないような問題やトラブルに遭遇した方はいらっしゃらなかったです。（わい調べ）

公式か〜
と思い、調査！

お！Volume周りがおかしくなっているというIssueを発見！
https://github.com/orbstack/orbstack/issues/1374

わからんが解説した？らしい...
利用者のversionも確認！
→全然新しいversionを利用してくれていた...

OrbStackのアプリ自体を立ち上げ直したりしても直らず...(再起動で直るとかもどっかで書かれていたのをみたけど...)
dockerコンテナを立ち上げ直すと再度マウントしてくれるので、ファイルは更新されます...

## 原因がわからない...
試行錯誤、ファイルキャッシュとかなんかやってたかなーと思い、諸々開発環境を調査。
しかも、問題が起きる人と起きない人がいて、謎が謎を生んでました...

# 結論なんだった？
原因かどうかはわからないが、トラブルが起きていた方の環境で試してみたら直ったのが、
docker-syncを利用しないで環境を構築する！
でした。(ファイル周りだとdocker-sync関係あるかもなーからの発想)

## docker-syncって？
[docker-sync](http://docker-sync.io/)
詳細は、控えますが、
ローカル(ホスト側)のディレクトリをマウントしてdockerコンテナ内とローカルのディレクトリを同期？させて利用することが多いかと思います。
ただ、dockerの初期とかは、それだと猛烈に遅くなるらしいです。
速度改善のために使うイメージです。
＊ただ、今はPCスペックとかdocker自体の速度も速くなっていると思うので、使わなくても大丈夫なイメージです...(個人的意見)

## docker-syncはなくても大丈夫...
docker-syncはなくても大丈夫！
だと思い、docker-syncを利用しない方法で諸々調整！

## そして...
直りました！

touchコマンドでファイル作成すると、dockerコンテナ内に同様のファイルができます。
mvコマンドでファイル名を変更すると、dockerコンテナ内も同期します。
cpコマンドでコピーすると、dockerコンテナ内も新たにコピーしたファイルができます。

よかったー

# というわけで...
Docker Desktopでは、起きなかったが、OrbStack環境に移行後、docker-syncと相性？が良くなくて、ファイル更新がされなかった
という個人的な結論に至りました。

これが本当に原因でファイルが更新されなかったのかはわかりませんが、OrbStack周りの記事はあまりなさそうだったので、備忘録として残します！