OmniAICreator/Qiita-1.07M huggingface dataset:
テストピラミッドについて

# はじめに
テストピラミッドについて、個人的な解釈のメモを書き残しておく。
どうも、私の周りの感覚と違うので。。。


# テストピラミッド

テスト自動化での文面でよく出てくる有名なテストピラミッド。

![1_6M7_pT_2HJR-o-AXgkHU0g-4294153157.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304109/3f8560f8-0744-8805-f3bb-aa6e931106e7.jpeg)

* 一番上は、UI や E2E というテスト
* 中盤は、結合テスト
* 一番下は、ユニットテスト

というものになっています。


# テストピラミッドの私の認識と他の人の差

テストピラミッドを表現している人で、以下のように表現されている人もいます。
https://test-hack.com/%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E3%83%94%E3%83%A9%E3%83%9F%E3%83%83%E3%83%89%E3%82%923%E5%88%86%E3%81%A7%E7%90%86%E8%A7%A3%E3%81%99%E3%82%8B/

E2E、UI のテストは以下のようにする
* 費用対効果が『低い』
* テストの量は『少なく』


コレに違和感を感じるのです。
そして、これがあるべき姿だとして『システムテスト』は非効率、ROI が悪いという主張だけが跋扈して独り歩きしている感じがしています。


テストピラミッドは『テスト自動化』の視点(文脈) だと認識しています。

『テスト戦略モデル図』と言われてますが、『テスト自動化戦略モデル図』と勘違いしていない？
と思うことがよくあります。(自動化どこ行った？)


私が認識しているのは、おおよそは、以下のほうです。
https://gihyo.jp/dev/serial/01/savanna-letter/0005


『単純』な機能のテストはE2E、UI の段階では少なくすべき、という認識をしています。

例えば、E2E のテストの段階で、入力チェックなどの単純なテストをするのは非常に効率が悪いということで、ユニットテストで実施せよ
システムテストになって、単純な入力ができない、設定が保存できないとかあると、再現性の特定、調査、修正で莫大なコストがかかるということです。

# E2E のテスト段階で単純な欠陥を出さない

E2E のテストは、様々な条件が重なってきて、かなりフレーキーな結果となり、その結果を吟味しながら保証できるかを判断していきます。
こんな状況で、単純な機能の欠陥のために、時間を大幅に費やすのはもったいないということです。

入力データ、環境を変更しながら、数日、欠陥の患部特定していた結果、「プログラムの条件式間違えてた、テヘペロ」とかで終わることもあります。

# テストピラミッドの土台 (底辺) は基礎工事なので手を抜くな

私の概念では、テストピラミッドの土台(底辺)は単機能の品質を保証するための重要なテスト。
これが崩れると、全ての保証が崩れるという認識です。

単機能ゆえに、自動化しやすく絨毯爆撃で全テストしやすいため、自然に量も増えるという認識をしています。


# テストピラミッドの頂点 E2E テストで重要なこと
テストピラミッドの頂点で、システム構成された状態での保証する重要なことは4つぐらいに絞られるかなと考えています。

* 俯瞰したシステムとしての整合性
* 保証できる代表例 (ユーザストーリー&ユースケース)
* 狙撃での欠陥発見(組み合わせの穴)
* 外部要因によるリスク把握

ピラミッドの頂点のテストで、絨毯爆撃は非効率で、テスト要求分析などを実施をしたうえでユーザーストーリーやリスクベースなどをあげて、保証しなければいけない状態・状況で欠陥を発見する(逆に、保証する)テスト活動することだと認識をしています。

昨今のアプリケーション、サービスは、ユニットテストだけで品質を保証できると全く思っていません。


# ピラミッドの土台と頂点での ROI について

1つ1つのテストは、土台の方がコストは安いです。
当然です。
だって、単機能のテストをするわけですから。

さらに、欠陥に気づいたとき調査・修正も開発担当者が見つけて修正するので情報ロスも少ないのでコストは低いです。

そして、この土台となるユニットテストは単一(単体)での機能を保証するものなので、これが動作しないと、他も全く動作しないということになります。
動作しないだけならいいけど、システムとして動作させると場合によっては、破壊的な挙動する可能性もあります。

よって、基礎工事となる土台は、非常に重要なのでユニットテストはおろそかにしてはいけません。

だからと言って、ピラミッドの土台、頂点で工数が変わらないとも考えています。

土台のテストは量が多くなる傾向ですが、「1つテスト時間 * テスト数」と考えると、保証活動時間としてはそこまで変わるか？と思っています。

よって、システムテストが ROI が悪いとも思っていません。
ユニットテストだけで、システムテストで保証する内容を包含すると、それこそ全組み合わせの実施になりかねないと思っています。


# 結論
テストピラミッドは自動化の文脈で使わないと、「システムテスト」は ROI が悪いから削減しようという使い方を間違い始めることになる

っという思いが強くなりました。
Ruby環境不要のRailsアプリジェネレータ rails-new

Railsプロジェクトを新規に作ろうと思った時、OSアップデートとかの影響で環境構築につまづいちゃうみたいなこと経験ありませんかね (Railsに限った話ではないんだけど)

そんなときに役立つのが、わりかし最近リリースされた`rails-new`ジェネレータです。

https://x.com/robzolkos/status/1842615591812690328


## `rails-new`とは？

[`rails-new`](https://github.com/rails/rails-new)はrust製のRailsアプリの雛形ジェネレータです。

このツールの最大の特徴は、ローカルマシンにRubyやRailsの環境がなくても、簡単に新しいRailsプロジェクトの雛形を作成できることです。

[リリースページ](https://github.com/rails/rails-new/releases)からバイナリをダウンロードして、パスの通ったディレクトリに配置するだけで `rails-new` コマンドが使用可能になります。

## 基本的な使い方

`rails-new`コマンドは、従来の`rails new`コマンドと同様のオプションをサポートしています。(というか移譲します。)

それに加えて、rubyのバージョンやrailsのバージョンも指定することができます。

```sh
➜  workspace rails-new help
A CLI tool to generate a new Rails project

Usage: rails-new [OPTIONS] <ARGS>...
       rails-new [OPTIONS] [ARGS]... <COMMAND>

Commands:
  rails-help  Prints `rails new --help`
  help        Print this message or the help of the given subcommand(s)

Arguments:
  <ARGS>...  arguments passed to `rails new`

Options:
  -u, --ruby-version <RUBY_VERSION>    [default: 3.3.4]
  -r, --rails-version <RAILS_VERSION>  [default: 7.2.0]
  -h, --help                           Print help
  -V, --version                        Print version
```

使用例:

```sh
rails-new myapp
```

これだけで、Ruby / Rails環境がない場所でも新しいRailsアプリケーションの雛形を生成できます。

## Dev Container対応

さらに便利なことに、Railsはバージョン7.2から[`devcontainer`](https://code.visualstudio.com/docs/devcontainers/containers)に対応しています。

以下のようにdevcontainerの設定ファイルを生成するオプションをつけて実行してみましょう。

```sh
rails-new myapp --devcontainer
```

生成されたプロジェクトをDevContainerプラグインを入れたVisual Studio Codeで開くと、「開発コンテナで開き直しますか？」と聞いてくるポップアップがでてきます。

![スクリーンショット 2024-10-10 17.56.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12806/4ab1f25c-6867-cbce-a11e-a19a5108882c.png)

これを許可すると必要なRubyやRailsの環境が整った開発コンテナが自動的に立ち上がりvscodeがコンテナ内の環境下で開き直されます。

(コンテナーでサイド開くを押した後、DevContainerが立ち上がってる過程の図)
![スクリーンショット 2024-10-10 17.58.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12806/576bf5d5-c561-b204-fc97-15c604376c43.png)

完了したらターミナルからサーバ起動コマンド( `bin/dev` )を実行します。
このターミナルはコンテナ内に接続されているのでローカルにruby環境がなくてももちろん実行できます。

サーバー起動後にlocalhost:3000にアクセスすれば普通にrailsアプリケーションの初期画面を見ることができます。

![スクリーンショット 2024-10-10 18.04.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12806/fe08bf58-6358-5be2-e40c-f11ab4e53d78.png)

これにより、ローカルの開発環境をクリーンに保ちながら、プロジェクト開発を迅速に開始できます。
言語処理100本ノックを始めるための（自分なりの）環境構築

https://nlp100.github.io/ja/

## 何をするのか
言語処理100本ノックを始めることにしたので環境構築をしていきます。
「あくまで個人の感想です。」なので他にいくらでもやり方はあるのですが、自分が思う最善の環境構築をします。
※ ここでは具体的なコードは載せません（自分で調べながら作った方が確実です）

## なぜいきなり言語処理？
ずばり...**研究室の課題**です！
と言っても、嫌々やるというわけではありません。

趣味でAtcoderをやっているせいか、プログラムで問題を解くことが好きなのでそこまで苦ではありません。（始める前なので何とでも言えます）

## 環境構築とかいらなくない？！
世の中にはGoogle Colabとかいう非常に便利なツールがあります。
コード補完もあるし、実行結果を残したままにできるし、何より、下手に環境構築しなくても使えます。めちゃくちゃ便利です。

**ただ、そういうことではないんです！
何が何でもvscodeでコーディングがしたいんです！**
（エンジニアの方ならわかってくれると信じてます）

ということでColabに頼らずに自前の環境構築をしていきます。

## 用意するもの
- vscode
- WSL（私はWindowsユーザなので）

## 環境について考える過程でのログ
まず大前提として、仮想環境を構築します。
Pythonの仮想環境を作るために、いくつか方法を思いつきました。

- venv（uv）
- anaconda
- Docker

<details><summary>こちら思考回路</summary>

<font color="LimeGreen">

---
うーん、Dockerつくるの面倒だな...。
あと、vscode拡張機能のdev container使うのもなんかな...。
やっぱりフォルダベースがいいなぁ。
anaconda使うのはなんか甘えな気がするな...。

</font>

<font color="Green">

**なんか最近Rust製のuvっていうのが出たらしい？！面白そう！（安直）**

</font>

---

</details>

ということで、uvを採用することにしました。

https://zenn.dev/turing_motors/articles/594fbef42a36ee

## 実行結果を残したい方
どうやらvscodeでもipynbファイルを扱えるらしい！
vscode拡張機能とか、jupyterとか諸々インストールしましょう

https://code.visualstudio.com/docs/datascience/jupyter-notebooks

## formatter入れたい
blackとかautopepとかいろいろありましたが、最近linterつきの**ruff**っていうのが出たらしいのでそれを使います。（これもRust製）
ruffには設定ファイル（ruff.toml）があり、そこで色々書くといいらしいです。
vscodeの設定で```Format On Save```があるので、それをTrueにしておくと作業がはかどります。

https://note.com/apollo132/n/nf8c9fe6598e0#b242d558-82c2-4c21-84b5-d3adbfcd1bec

## いざコーディング！
環境ができたらどんどんコーディングしていきましょう！

詰まったときはまず検索エンジンで調べましょう！
（答えが存在するのでChatGPTに聞けば一発で答えてくれますが、それは**甘え**です）

解説を見つけたので載せておきます。

https://qiita.com/Dukapan100knock/items/d418f2aa37b2b3d16428

## さいごに
コードを見たいのに！っていう方には申し訳ない記事になってしまいました。
すみません...。
環境構築の「答え」にはなりませんでしたが、「**ヒント**」にはなったと思います。

本記事に書いてあるキーワードで調べる
↓
記事を見つける
↓
その記事に載っているキーワードで再度調べる

こんな感じで進めてみてください。

### （余談）About me
地方大学の大学生
Web開発とデータ分析を勉強しています。
プログラミング歴は今年で３年目です。
（といっても、ちゃんとやっているのは１年前なので実質、プログラミング歴１年です）
自信をもってコードを見せられるわけではないのでこのような記事を書かせていただきました。
本記事が誰かの役に立てば幸いです。
HTTPとは

## HTTP (Hyper Text Transfer Protocol)
HTTPはTCP/IPをベースとしており、Web上でデータをやり取りするための通信プロトコルです。
HTMLやXML、画像、音声、動画、JavaScriptのプログラム、PDFなどコンピューターで扱える様々なデータを転送できます。
## TCP/IPとは
インターネットやその他のコンピューターネットワークにおいて、データ通信を行うための標準的なプロトコルスイート ( プロトコルをひとまとめにしてもの ) です。

インターネットのネットワークプロトコルは階層型になっています。
|アプリケーション層|
|:-------------:|
|HTTP, NTP, SSH, SMTP, DNS|
|トランスポート層|
|UDP, TCP|
|インターネット層|
|IP|
|ネットワークインターフェース層|
|イーサネット, Wi-Fi|

一番下から
<dl>
<dt>ネットワークインターフェース層</dt>
<dd>物理的なデータの送受信(ケーブルやネットワークアダプタに相当)をする役割</dd>
<dt>インターネット層</dt>
<dd>ネットワークでデータをやり取りする役割</dd>
<dt>トランスポート層</dt>
<dd>データの信頼性の高い送受信や通信の管理をする役割</dd>
<dt>アプリケーション層</dt>
<dd>ユーザーやアプリケーションが使用するプロトコルやサービスを提供する役割</dd>
</dl>

<strong>HTTPはアプリケーション層に位置するプロトコルになります。</strong>

## 主な特徴
<dl>
<dt>クライアント-サーバーモデル</dt>
<dd>クライアント: ユーザーが使用するウェブブラウザなどのアプリケーション。</dd>
<dd>サーバー: ウェブページやデータを提供するサーバーコンピュータ。</dd>
</dd>
<dt>リクエストとレスポンス</dt>
<dd>
    クライアント側がサーバーに対してデータやサービスをリクエストし、
    サーバー側がリクエストに応じてデータや結果をレエスポンスとして返す。
</dd>
<dt>ステートレスプロトコル</dt>
<dd>
各リクエストは独立しており、前後のリクエストとの関連性を持たない。
</dd>
</dl>

前回の記事

https://qiita.com/dsk-code/items/45daf961f6615514fde6
M5NanoC6でPWM(50Hz,0%...100%)で遊ぶ



x 過去ログを見よ!!


参考

![o_coq503.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7a4a047b-3409-c72d-95b9-21d1b7be60b9.jpeg)


https://logikara.blog/m5nanoc6-setting/


結果

わからないと思うけど　いろいろ、準備するのがめんどい


![o_coq505.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/ea8667f6-f197-c9e3-5fb8-d8d43b04624f.jpeg)



プログラム


```c++

//PWM_ledcWrite_test1_C6_1

#define PWM_PIN 1
#define FREQUENCY 50
#define RESOLUTION 12

//初期化
void setup() {

  //出力ピンの初期化
  pinMode(PWM_PIN, OUTPUT);

  // PWM設定（ピン番号, 周波数, 分解能）
  ledcAttach(PWM_PIN, FREQUENCY, RESOLUTION);
  
} //setup


//メインループ
void loop() {

  //4096回繰り返す
  for (int i = 0; i < 4096; i++) {

    // DUTY比を指定して、チャンネルに対して実行
    ledcWrite(PWM_PIN, i);

    delay(5); //5ms待つ

  } //for i

} //loop



```
頭がいいと「認められる」人になる

## 本の情報
**タイトル**
頭のいい人が話す前に考えていること

**著者**
安達 裕

## 本の内容(抜粋)
* 「頭がいい」とは？
頭がいいかどうかを決めるのは自分ではない。
かといって、頭の良さを決める基準があるわけでもない。
→他者から「頭がいい」と認識される人が、実際に「頭がいい」人と言える。

* 「頭がいい」人と認識されるには？
「相手が何を求めているのかを想像しながら生活する」ことが必要。
コミュニケーションの主体は自身ではなく、相手にある。
→相手が求めるものを伝えられることで、人から慕われるようになり、「頭がいい」と思ってもらえるようになる。

* 「頭がいい人」の考え方(相手が求めるものを伝えるための考え方)
1.相手の話を聞くこと
自分が何を話すかを考えながら相手の話を聞くのではなく、相手の話を聞いて「自分に言ってほしいこと」を考える。
→共感して欲しいのか、解決して欲しいのかなどを、相手の話から理解する。
2.反射的に話さないこと
人間には、「早い思考(=直観的な思考)」と「遅い思考(=論理的な思考)」があるとされる。
反射的に話そうとすると、早い思考が働いて内容を簡単で不正確なものに置き換えてしまう。
→一息置いて、事実と意見を分けてから離すようにする。

## 印象に残った点
* 話が浅い人
話が浅い人は、以下の特徴がある という記載があった。
    1.根拠が薄い
    2.言葉の「意味・定義」をよく知らない
    3.成り立ちを知らない
自分でも、話をしていると自信がなくなって尻すぼみになってしまうことが多々あり、上記の特徴が当てはまると感じた。
自分の話す言葉や内容を詳しく理解し、自信をもって話せるようにしたい。

## まとめ
会話の場で、何か話さないといけない・アイデアを出さないといけない と焦って考えてしまう人に読んでいただきたい本でした。
「コミュニケーションでは、自分が伝えたいことを伝えるのではなく、相手が言って欲しいことを伝える。」
私も自分の言いたいことに気を取られて反射的に話してしまうタイプなので、相手の話を理解できているか見直すことを意識付けたいと思います。
ありがとうございました。
IBM watsonx.ai で Meta Llama 3.2 Vision を動かしてcurlコマンドでAPI呼び出しする方法

# はじめに

タイトルの通りなんですが、IBM watsonx.ai で Meta Llama 3.2 Vision を動かしてcurlコマンドでAPI呼び出しする方法を記載します。
まだ情報が少ないので参考になればと思います。

## 参考
https://ai.meta.com/blog/llama-3-2-connect-2024-vision-edge-mobile-devices/

https://qiita.com/agumon/items/9f190e4c4dd6ab060520

# 実行

## コード
コードの処理はコメントに記載の通りです。画像データはBASE64にエンコードして渡します。

```zsh:test.sh
#!/bin/bash

# 環境変数準備
export API_KEY="xx"
export PROJECT_ID="yy"

# トークン取得
YOUR_ACCESS_TOKEN=$(curl -X POST "https://iam.cloud.ibm.com/identity/token" \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -H 'Accept: application/json' \
    -d 'grant_type=urn:ibm:params:oauth:grant-type:apikey' \
    -d "apikey=${API_KEY}" | jq -r '.access_token')

# test.jpgをbase64に変換 （同じフォルダにtest.jpgをおく）
BASE64_IMAGE=$(base64 -i ./test.jpg)

# visionのAPIを呼び出し
curl "https://us-south.ml.cloud.ibm.com/ml/v1/text/chat?version=2023-05-29" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -H "Authorization: Bearer ${YOUR_ACCESS_TOKEN}" \
    -d '{
	"messages": [
		{
			"role": "user",
			"content": [
				{
					"type": "text",
					"text": "これは何？"
				},
				{
					"type": "image_url",
					"image_url": {
						"url": "data:image/png;base64, '"${BASE64_IMAGE}"'"
					}
				}
			]
		}
	],
	"project_id": "'"${PROJECT_ID}"'",
	"model_id": "meta-llama/llama-3-2-90b-vision-instruct",
	"decoding_method": "greedy",
	"min_new_tokens": 0,
	"stop_sequences": [],
	"repetition_penalty": 1,
	"max_tokens": 900
}'
```

## 実行手順
1. IBM watsonx.ai インスタンスを準備して、プロジェクトを作成します。
1. APIキーとプロジェクトIDを取得して環境変数にセットします。
1. APIに渡したい画像（`test.jpg`）を準備します。（pngの場合は、-dで渡しているjsonの中に、`image/jpeg`を`image/png`にすると良いと思います。ただ、`image/jpeg`のままでも動きました。。。）
1. 上記コードを実行します。

## プロジェクトIDとAPIキー
プロジェクトIDとAPIキーの取得は下記が参考になるかと思います。

https://www.nicpartners.co.jp/report/142748/

サービスIDを使う場合は、下記が参考になるかと思います。
https://qiita.com/katahiro/items/3258cd42226ed82268ac


# おわりに
下記公式ドキュメントで情報を見つけられなかったのですが、そのうち追加されるかなとは思います。

https://cloud.ibm.com/apidocs/watsonx-ai

Pythonで呼び出す際は下記が参考になるかと思います。

https://www.ibm.com/think/tutorials/multimodal-ai-python-llama
【UE5/C++】Binaries とか消したらエディタのプロジェクトファイル消えておかしくなる

# 起こった事象
コンパイルが上手くいかずおかしくなったので、プロジェクトフォルダ内にある Binaries とか消したらエディタが正常に機能しなくなった。

# 解決策
プロジェクトフォルダ内の `.uproject` を右クリックし、`Generate Visual Studio project files` を選択すると、プロジェクトファイルを再生成でき、エディタが正常に動作するようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348896/1dd3d478-b18f-6f2c-a3a7-a0e174bbe3f4.png)


https://zenn.dev/piteki/articles/piteki-ue-generateprojectfiles_bat
CADとCGの違いは何ですか？

CAD（Computer-Aided Design）とCG（Computer Graphics）は、よく使われる用語ですが、応用分野や技術面で明確な違いがあります。近年では、3Dスキャナーの導入により、この二つの技術がより緊密に結びつき、設計の効率や精度がさらに向上しています。

CADとは？
CADはコンピューター支援設計のことで、主に精密なエンジニアリング設計や製造に使用されます。建築、機械設計、電子機器など、工業分野で広く活用されています。AutoCADやSolidWorksのようなCADソフトウェアは、精密なモデリングツールを提供し、2D図面や3Dモデルを作成して、製造や生産の実務に役立ちます。最近の設計プロセスでは、3Dスキャナーを用いて物体の幾何形状を捉え、実物を編集可能なCADモデルに変換することで、設計やリバースエンジニアリングが簡素化されます。

![6bf5894f11fce48de45ff40cc22c4dd6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/e35cd0be-f8fb-093d-1ca5-2bb02b23c021.png)
主な特徴：

精度：CADモデルは、製品の部品や建築構造の制作に使用されるため、非常に高い精度が必要です。3Dスキャナーを使うことで、複雑な物体の細部を正確に捉え、設計の正確性を大幅に向上させることができます。
パラメトリック設計：パラメーターに基づいて設計を容易に調整でき、最適化や変更が簡単です。3Dスキャナーで得たデータを基に、設計者は初期モデルを迅速に生成し、その後パラメトリックな修正を加えます。
工学志向：主に製造業、建築、工業デザインに使用されます。特に高精度な測定が必要な場合、3Dスキャナーはデータ取得ツールとして役立ち、後のCADモデリングを支援します。

CGとは？
CGはコンピューターグラフィックスの略で、コンピューターを使って画像を生成、レンダリング、処理するすべての技術を指します。CGは、アニメーション、映画の特殊効果、ゲームデザインなどのエンターテインメントや視覚効果の分野でよく使われます。MayaやBlenderなどのCGソフトウェアは、豊富なマテリアル、ライティング、レンダリングツールを提供し、視覚的にインパクトのある画像を生成します。3Dスキャナーを使えば、現実の物体のモデルを迅速に取得し、CG技術を使って細部を最適化したり、マテリアルを適用したり、シーンを構築したりして、モデリングや制作時間を短縮することが可能です。
![e9ad5bfa417355a7701cc29b8a03b250.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3824290/660fa9bd-9c0d-cfd6-d9a0-9435a45b10be.png)

主な特徴：

視覚効果：CGは視覚の美しさに重点を置き、主に映画、広告、ゲームなどの分野で使用されます。3Dスキャナーの応用により、デザイナーはリアルな物体を直接取得し、それをアニメーションやゲームのキャラクターの基礎として使用し、視覚効果のリアリティを強化することができます。
高い自由度：CGデザインは物理法則に厳密に従う必要はなく、デザイナーはさまざまな仮想シーンを作り出すことができます。3Dスキャナーを併用することで、現実の物体と仮想世界を融合させ、より多様な視覚体験を生み出すことが可能です。
レンダリング：CGは光と影、マテリアル、動的効果に重点を置き、デザインをより生き生きとさせます。3Dスキャナーで取得したモデルは、自然にCG作品に取り込むことができ、モデリング時間を短縮しつつ作品のリアリティを向上させます。

CADとCGの違い
応用分野の違い：CADはエンジニアリングや製造に焦点を当て、主に製品設計や工業製造に使用されます。一方、CGは映画、広告、ゲームなどのエンターテインメントやアートの分野で広く使用されます。3Dスキャナーは、これら両方の分野に実際の幾何学データを提供し、さまざまな応用を促進します。
精度要求：CADは非常に高い精度を必要とします。なぜなら、設計結果は製品の製造に直接影響するためです。一方で、CGは視覚効果に重点を置き、物理的なパラメータの精度はそれほど重要ではありません。3Dスキャナーは、両方のニーズに応え、精密なデータを取得できるだけでなく、CGにリアルな形状の基礎を提供します。
レンダリングと展示：CGは複雑なレンダリングアルゴリズムを使って、リアルな画像やアニメーションを生成しますが、CADの主な目標は、製造に役立つ操作可能なモデルや図面を生成することです。3Dスキャナーで取得した物体モデルは、CADでの製造指示やCGでの視覚的な表現の両方に使用できます。

二つの技術の融合
CADとCGは、一見異なる分野に見えますが、実際にはいくつかの交差点があります。たとえば、デザイナーはCADを使って精密な工業デザインモデルを作成し、その後CGソフトでリアルな製品のビジュアルをレンダリングし、クライアントにプレゼンテーションすることができます。3Dスキャナーは、この二つの技術の架け橋となり、実際の物体をスキャンして3Dモデルを作成し、それを必要に応じて正確な設計や視覚的な最適化に使用することができます。

https://www.revopoint3d.jp/
test

Sub DeleteRichTextBAttachments(doc As NotesDocument)

    ' リッチテキストフィールドBを取得
    Dim rtB As NotesRichTextItem
    Set rtB = doc.GetFirstItem("リッチテキストB") ' フィールド名に応じて変更

    ' リッチテキストB内のファイルを取得
    Dim object As NotesEmbeddedObject
    Set object = rtB.GetEmbeddedObject("添付ファイル名") ' ファイル名に応じて変更

    ' リッチテキストB内の添付ファイルを削除
    If Not object Is Nothing Then
        Call object.Remove
    End If

    ' ファイル名を取得して、$FILEフィールドから該当するエントリを削除
    Dim fileName As String
    fileName = object.Source

    ' $FILEフィールドを取得
    Dim fileField As Variant
    fileField = doc.GetItemValue("$FILE")
    
    ' 該当するファイルのエントリを削除
    Dim i As Integer
    For i = Lbound(fileField) To Ubound(fileField)
        If InStr(fileField(i), fileName) > 0 Then
            Call doc.RemoveItem("$FILE")
            Exit For
        End If
    Next

    ' 文書を保存
    Call doc.Save(True, False)
    
End Sub
M5NanoC6でPWM(1kHz,0%...100%)で遊ぶ


x 過去ログを見よ!!


参考

![o_coq503.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9dcb3d93-e606-4153-ecf2-7db0cf9ed34a.jpeg)


https://logikara.blog/m5nanoc6-setting/


●いろいろ
C6の応用、少ないし、ちょとつあれ・・・
きみ、きみだよ!!、自分で試すんだ。
なんの事?


結果

わからないと思うけど　いろいろ、準備するのがめんどい

![o_coq504.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/52617650-e214-09c8-70b1-dbc48b426a4e.jpeg)


プログラム


```c++

//PWM_ledcWrite_test1_C6_1

#define PWM_PIN 1
#define FREQUENCY 1000
#define RESOLUTION 8

//初期化
void setup() {

  //出力ピンの初期化
  pinMode(PWM_PIN, OUTPUT);

  // PWM設定（ピン番号, 周波数, 分解能）
  ledcAttach(PWM_PIN, FREQUENCY, RESOLUTION);
  
} //setup


//メインループ
void loop() {

  //256回繰り返す
  for (int i = 0; i < 256; i++) {

    // DUTY比を指定して、チャンネルに対して実行
    ledcWrite(PWM_PIN, i);

    delay(20); //20ms待つ

  } //for i

} //loop



```
Future vs Promise (in Scala)

こういうことらしい。

```
                    Future  <--read--- client
                      in
server ---write-->  Promise
```

Udemy [Scala Applied, Part 3](https://www.udemy.com/course/stairway-to-scala-applied-part-3/learn/lecture/12134198#overview) のスライドでは以下のように説明されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/534442/7ffdc9db-167e-5de9-ae68-4a2b5a438a7b.png)


## Ref

https://stackoverflow.com/a/28821051/10233141
【React備忘録】めっちゃ多用する演算子「&&」「??」のまとめ

Reactで使わない日はないといっても過言ではない演算子。
忘れないようにメモしておく。

## &&（論理AND演算子）
* 左側が`true`の場合、右側を評価し、結果を返す。
* 左側がfalsy（`false`、`null`、`undefiend`、`0`、`Nan`、`''`など）の場合、右側を評価せずに、左側を返す。
```react:App.tsx
const Test = () => {
  const array = ['1', '2', '3']

  return (
    <div>
      {array.length > 0 && <ArrayPanel />}
    </div>
  )
}
```
上記の例は、配列に値が1個以上ある場合にコンポーネントを表示させる処理になっている。
例えば、地図アプリで、地図上でクリックしたデータを配列に格納。データが格納されたら、初期状態では非表示だったArrayPanelコンポーネントを表示し、データを一覧で表示させる...といった処理など、コンポーネントの表示・非表示に活用できる。

## ??（Nullish Coalescing演算子）
* 左側が`null`または`undefiend`の場合に限り、右側を返す。
* 注意点として、左側がfalsyの場合は右側を返さない（`null`か`undefiend`の時だけ返す）。
```jsx
const Test = () => {
  const label = getLabel();

  return (
    <div>
      {label ?? '（ラベルなし）'}
    </div>
  )
}
```
すごく簡単な例だけれど、ラベルを取得する関数があったとして、値がある場合は表示し、ない場合（null or undefined）は「（ラベルなし）」と表示させる。

## 「評価する」と「返す」の違い
### 評価する
式や値を計算、または実行すること。
`&&（論理積）`の場合、左辺が`true`であれば右辺が評価（実行）され、その評価結果が返される。
```js
true && console.log('実行されました'); // コンソールに「実行されました」と表示される
```
上記の例では、`true`が左辺にあるため、右辺の`console.log('aaa')` が実行される。

### 返す
式全体としての値を返すこと。
`??（nullish coalescing operator）`の場合、左辺が`null`または`undefined`のときに右辺が評価され、その結果が返される。
```js
null ?? 'デフォルトの値'; // 結果は 'デフォルトの値'
```
上記の例では、左辺が`null`なので右辺の`'デフォルトの値'` がそのまま返される。
Windows11へVisual Studio 2022をインストール

# はじめに
この記事はWindows11にVisual Studio 2022をインストールし、GitHubを設定するまでの手順を記した記事です。事前にGitHubのアカウントとリポジトリを持っていることが前提になります。

# 導入環境
OS：Windows11
プロセッサ：AMD Ryzen 5 4500 6-Core Processor 3.60 GHz
RAM：32.0GB
システムの種類：64 ビット オペレーティング システム、x64 ベース プロセッサ
グラフィックボード：NVIDIA GeForce RTX 4060 8.0GB
Google Chrome：129.0.6668.90（Official Build） （64 ビット）

# Visual Studio 2022のダウンロード & インストール
以下のサイトをググって、見つける。

https://visualstudio.microsoft.com/ja/vs/features/net-development/

必要な種類のVisual Studio2022をダウンロードする。ここから先はCommunityをダウンロード（理由としては無料だからで、他は有料）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/0c142eec-48f0-86da-4924-346f933d8221.png)

以降、インストールする手順を踏むと、インストールが完了する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/c8701e04-0f74-324c-ea06-554da68e93e7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/00a82d2f-a3c3-191c-d748-2c023458a2ba.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/a6b017be-c468-bb57-ef4b-b0b840f09f62.png)


# 必要なアプリケーションをインストール
ここから先は.NETデスクトップ開発をインストールする例。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/5171a352-04be-175f-7778-44ae82af8aa6.png)

その後、Visual Studioを起動する。途中、サインインが求められるが、今回はスキップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/70bbd233-768c-1d4d-309a-6dc7aeaa8bae.png)

背景の設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/90510878-6f7d-7237-59a9-b9b0be149efd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/de9d223a-9f55-de72-a1b0-7730abceb0ad.png)

Visual Studioのプロジェクト選択画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/a6de1b41-b061-cd55-0151-51debda5c571.png)

# GitHubの設定
「リポジトリのクローン」を選択して、GitHubを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/efcf1c3f-53a5-371b-92ed-757ca93828d0.png)

アカウントを選択して連携する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/afc5588e-42ad-ed38-8837-cc61a9be570b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/f7214024-7d8d-e9cd-16dc-ee81fd2ef278.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/3a155fe3-d918-21e6-62f7-d7c081e3dafd.png)

プロジェクトを選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/d5cab2f5-2177-7868-84fd-a5888a33994b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/52097925-2a0b-e230-45b2-cba37c6bf22a.png)

Visual Studioが開けば、作業準備が完了する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/312621af-72ed-98df-3324-0e3376f7b0e6.png)
Docker環境でLiteLLMのcreate_views.pyスクリプトを実行する方法

こんにちは。今回は、Docker環境でLiteLLMの`create_views.py`スクリプトを実行する方法をご紹介します。この手順は、LiteLLMのデータベースビューを正しく設定するために重要です。

## なぜcreate_views.pyの実行が必要なのか？

LiteLLMのUsageダッシュボードで「relation "MonthlyGlobalSpend" does not exist」というエラーが表示される場合、`create_views.py`スクリプトの実行が必要です。このスクリプトは、必要なデータベースビューを作成し、Usageダッシュボードのデータを正しく表示するために不可欠です。

## 手順

以下の手順で、Docker環境内の`create_views.py`スクリプトを実行できます：

1. **Dockerコマンドの権限取得**
   まず、sudoを使用してDockerコマンドを実行する権限を取得します。

2. **実行中のコンテナの確認**
   ```
   sudo docker-compose ps
   ```
   このコマンドで、現在実行中のコンテナを確認します。

3. **litellmサービスのコンテナにアクセス**
   ```
   sudo docker-compose exec litellm /bin/bash
   ```
   litellmサービスのコンテナ内でbashシェルを起動します。

4. **スクリプトの実行**
   ```
   python db_scripts/create_views.py
   ```
   コンテナ内で`create_views.py`スクリプトを実行します。

5. **コンテナからの退出**
   ```
   exit
   ```
   スクリプトの実行が完了したら、exitコマンドでコンテナから抜けます。

6. **コンテナの状態確認**
   ```
   sudo docker-compose ps
   ```
   必要に応じて、再度コンテナの状態を確認します。

## 実行結果

この方法で`create_views.py`スクリプトを実行すると、必要なデータベースビューが正しく作成されます。スクリプトの実行中には、いくつかの警告メッセージが表示されることがありますが、これらは無視して構いません。

## トラブルシューティング

もし上記の手順でエラーが発生した場合は、以下の点を確認してください：

1. Dockerデーモンが実行中であることを確認する
2. docker-compose.ymlファイルが正しく設定されていることを確認する
3. ネットワーク接続に問題がないことを確認する

## まとめ

本記事では、Docker環境でLiteLLMの`create_views.py`スクリプトを実行する方法を詳しく解説しました。この手順を正しく実行することで、LiteLLMのUsageダッシュボードが正常に機能するようになります。

LiteLLMの運用やDocker環境の管理について、さらに詳しい情報が必要な場合は、公式ドキュメントを参照するか、コミュニティフォーラムで質問してみてください。

## 参考サイト

https://github.com/BerriAI/litellm/issues/5756
LeetCodeを1日1題解いてみる (day1)

今日から毎日１題ずつLeetCodeの問題を解いていきます！


# 1. Two Sum (Easy)

https://leetcode.com/problems/two-sum/

## 問題文
Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

# 僕の回答

```py
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        result = []
        for i in range(len(nums)):
            for j in range(i + 1, len(nums)):
                if nums[i] + nums[j] == target:
                    result.append(i)
                    result.append(j)
                    return result
```

# より効率の良い回答例

```py
class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        map = dict()  # 空の辞書を初期化

        for index, value in enumerate(nums):
            if target - value in map: # mapにvalueの相方がいる場合
                if index <= map[target-value]:
                    return index, map[target-value] 
                else:
                    return map[target-value], index 
            else:
                map[value] = index # mapにindex, valueを追加
```

### 次回はこちら!
https://qiita.com/h_y_s_d/items/de1fa3824a77bb5aa201
Raspberry Pi 5 の初期設定 インストールだったり起動だったり

## 独り言(飛ばしてダイジョーブ)
Raspberry Pi 5 を使い道も考えずに衝動買いしてしまいました。
懐が寒いことも忘れていました。

さて、購入したからには設定しましょうね〜。

## 必要なもの
- Raspberry Pi 5 　 (自分 8GB 買っちゃった)
- パソコン　　　　(自分は Macbook air)
- micro SDカード　(自分は 32GB)
- USB-C ケーブル と アダプタ
- Raspberry Pi Imager (入れ方は後述します)
- ハブ(自分はmicro SDが刺さるようなハブを使いました）

## Raspberry Pi 5 の初期設定

1. micro SDカードに OS を書き込む
以下のサイトから`Raspberry Pi Imager`をダウンロードしましょう。

https://www.raspberrypi.com/software/

MacでHomebrewが入っている場合は、以下のコマンドでもインストールできます。
```console
$ brew install --cask raspberry-pi-imager
```
ダウンロード出来たら、書き込むデバイス、OS、ストレージを指定します。
OSはDesktop版Bookworm(64-bit) 2024-07-04リリースを使用しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3802303/f19b3d92-c5bc-39d1-f030-9146332bb438.png)

次へを押すと`設定を編集する`を押して、このタイミングで色々設定しましょう。
ホスト名は指定しても大丈夫ですが、忘れないようにしましょう。
ユーザー名とパスワード、Wi-Fi、ロケール、SSHの設定をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3802303/15cc3e4c-731b-c530-b7b0-8647573563ee.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3802303/5302d1b5-7998-ecc2-4330-7b80ed8f8606.png)

micro SDカードに書き込めたら、次は起動してみましょう。

## 起動

起動する方法には色々あります。好きな方法で起動するといいと思います。

ここでは起動するために自分がした方法と、おまけを紹介します。他の方法が知りたい方は、個人でも調べてみて下さい。
### 1.SSHでの接続
Macの場合はターミナルから、Windowsの場合はコマンドプロンプトから以下のコマンドを実行して下さい。

```console
$ ssh ユーザー名@ホスト名もしくはIPアドレス
```

初めて接続する時は 
```
Are you sure you want to continue connecting (yes/no/[fingerprint])? 
```
（日本語訳：「本当に接続しますか？」）と聞かれますので、必ずキーボードでyesと打ち込んでEnterキーを押します。

ラズベリーパイのユーザーのパスワードを聞かれますので、入力してEnterキーを押します。この時、画面に＊＊＊＊などは表示されません。
```console
pi@raspberrypi: ~ $
```
ログインが完了すると以下のように ユーザー名@ホスト名: ~ $ などと表示されます。これが表示されれば、デスクトップ環境でターミナルを使用するのと同じように操作できます。

```console
sudo apt-get update
sudo apt-get upgrade
```
※コマンドの意味
update : 利用可能なソフトウェアリポジトリのパッケージリストを更新する。パッケージのインストールやアップグレードは行われない。
upgrade : パッケージ構成を変えない範囲でアップグレードする処理を実行。新しいパッケージのインストールや、既存パッケージの削除は行われない。

### おまけ(VNC Viewとか使う方法)
raspi-configから、ラズパイのデスクトップをパソコンに表示させる方法があります。
以下を実行すると、設定画面が表示されます。
```console
sudo raspi-config
```
`5 Interfacing Options` > `P3 VNC` > `Yes`を選択します。
これで、Raspberry Pi側の設定は完了です。


ラズパイにマウス、ディスプレイ、キーボード、SDカードを接続して電源を入れたら起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3802303/47687241-d721-4386-6987-8a1966ac88a2.png)

#### VNC Viewerを入れよう
以下のサイトから、VNC Viewerを入れよう！

https://www.realvnc.com/en/connect/download/viewer/ 

> 初回時は、`Use VNC Viewer without signing in`をクリックします。この時、匿名の使用状況データの送信が嫌な場合は、チェックボックスを外してからUse VNC Viewer without signing inをクリックします。

起動できましたら、画面上部のテキストボックスにラズパイのホスト名もしくはIPアドレスを入力して下さい。

> 初回接続時、確認メッセージが表示されますので、Continueボタンをクリックします。

ウィンドウが出てくると思うのですが、言われるがままにラズパイのUsernameとパスワードを入力し、OKボタンをクリックします。

おそらくこれで出来ると思います。知らんけど

### おまけ２
VNC Viewer入れたくない人向け

https://www.designet.co.jp/ossinfo/apacheguacamole/

こっちは全く別の話。(VNCじゃないよ)
Q)なんで書いたん？
A)それは言わないお約束。作者困っちゃう。(自己満だし)

https://webapp.telework.cyber.ipa.go.jp/
Rundeckのリモートノード実行ができなくなった話

# なにがおきたのか
　他環境の生死確認でrundeckからリモートノード実行で単純なコマンドを実行させるということをしています。このジョブがある日を境に動かなくなりました。ジョブのログには次のようなエラーが残っています。
 ```Failed: SSHProtocolFailure: invalid privatekey: [B@3774f82e```
 　SSHキーが無効になったようなので、とりあえずssh-keygenで再作成しましたが、症状は変わりません。興味深いことにコマンドラインからOpenSSHで実行すると別に問題ありません。どうやらrundeck側の問題のようです。
# 調べてみると
　検索してみると、この障害は割とポピュラーなもののようでした。
 [OpenSSH keys not accepted](https://github.com/rundeck/rundeck/issues/6312)
 [rundeck-ssh doesn't work with keys other than rsa?](https://groups.google.com/g/rundeck-discuss/c/an9OKLUfMD8)
 　どうやらrundeckで使われているライブラリがSSHの暗号タイプを扱えないらしく、デフォルトのSSHからSSHJライブラリに切り替えろ、ということのようです。
# 設定変更
　この変更はプロジェクト単位で行います。
 PROJECT SETTINGS →　EDIT CONFIGURATION → Default ノードエクズキュータ
　ここで、「SSH」を「SSHJ-SSH」に変更します。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696131/6a400716-19bb-4527-b6ef-0e75e81c8538.png)

　隣のタブには「Default ファイルコピー」がありますが、こちらもファイル転送を行うのであれば「SCP」から「SSHJ-SCP」に変更した方がよさそうです。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696131/5e058b1e-658c-13cf-7a16-612d38ded9c4.png)
# それはそれとして
　しかし、特にrundeckやJAVA関係のパッチを当てた覚えもないのでなぜ突然使えなくなったのかが不明で、そこは引っかかります。
C#でHTMLをWordに変換

HTMLは、ウェブページを作成するために使用されるマークアップ言語である。HTMLファイルを解析するには、ウェブブラウザが必要です。HTMLファイルをより読みやすくしたい場合は、HTMLファイルをWordに変換するのが良い方法です。この記事では、無料の.NETライブラリを使用して、シンプルなHTMLファイルをWord文書に変換する方法を紹介します。

## 無料.NETワードライブラリ
[**Free Spire.Doc for .NET**](https://www.e-iceblue.com/Introduce/free-doc-component.html)ライブラリをインストールするには2つの方法があります。1つはNuget経由でインストールする方法、もう1つは下記のリンクから製品パッケージをダウンロードし、ローカルパスから手動でプロジェクトにdllを追加する方法です。

https://www.e-iceblue.com/Download/download-word-for-net-free.html


## C# - HTMLをWordに変換
C#でHtmlファイルをWord文書にプログラム変換するのはとても簡単です。以下の2つのステップを踏むだけだ：
1\. **`Document.loadFromFile(String fileName, FileFormat fileFormat, XHTMLValidationType validationType)`** メソッドでHtmlファイルを読み込みます.
2\. **`Document.saveToFile(String fileName, FileFormat fileFormat)`** メソッドを使用して、HTMLファイルを.doc/.docxドキュメントに変換します。


>**C#のサンプルコードです：**
```csharp
using Spire.Doc;

namespace ConvertHTMLtoWord
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //HTMLファイルを読み込む
            Document document = new Document();
            document.LoadFromFile(@"E:\PythonDoc\input日.html");

            //HTMLファイルをWordとして保存する
            document.SaveToFile("HtmltoWord.docx", FileFormat.Docx2013);
        }
    }
}
```
![HTMLtoWord.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/3767cabb-520b-de1a-23ea-4a24d722e129.png)



この無料ライブラリは、[WordからHTML](https://www.e-iceblue.com/Tutorials/Spire.Doc/Spire.Doc-Program-Guide/Word-to-HTML-Convert-Word-to-HTML-with-C-VB.NET.html)、[WordからPDF](https://www.e-iceblue.com/Tutorials/Spire.Doc/Spire.Doc-Program-Guide/How-to-Convert-Word-to-PDF.html)、[WordからXML](https://www.e-iceblue.com/Tutorials/Spire.Doc/Spire.Doc-Program-Guide/How-to-Use-C-/VB.NET-to-Convert-Word-Doc-to-XML.html)などへの変換もサポートしています。

:::note info
注：無料APIには一定のページ制限があります。詳しくはこちらをご覧ください：https://www.e-iceblue.com/Introduce/free-doc-component.html
:::
PHP-クラス-インスタンス不要で利用できるクラス内の変数 

# はじめに
SLスタジオでPHP・WEB開発を独学中のアラフィフ主婦の忘備録です。

https://sls.ideal-growth.jp/12/lesson/312/learning

## プロパティの種類
PHPでは クラス変数 と インスタンス変数 という2種類のプロパティがあります。
1. インスタンス変数は、インスタンス生成後にアクセスが可能なプロパティです。**インスタンス毎に紐づけて値を保持する為、それぞれのオブジェクトで値が異なります。**
1. クラス変数はインスタンスを生成せずにアクセスが可能なプロパティです。**クラス自体に紐づけて値を保持する為、インスタンスに関わらず共通の値が適用されます。**

### サンプルソース
変数名など一部変更しています。

```PHP
class User
{
    // クラス変数はアクセス修飾子の記述に続けて、static キーワードを用いて定義
    public static $userCount = 0; // 変数には値をセットしておく必要あり

    public function countUp()
    {
        // クラス名とクラス変数の間に ::（スコープ演算子）を用いてアクセス
        self::$userCount++; // メソッド内(クラス内)では self キーワードを利用　$の記述は不要
    }
}

$user = new User(); // インスタンスを生成
$user->countUp();  // クラス内の関数（メソッド）を呼び出す
echo User::$userCount;  // クラス変数を出力
```

## 出力結果
```
1
```

## 遊んでみよう
```PHP
class User
{
    public static $userCount = 0;

    public function countUp()
    {
        self::$userCount++;
    }
}

$user = new User(); // 1度インスタンスを生成すれば
$user->countUp();   // クラス内の関数（メソッド）を呼び出すだけ
echo User::$userCount."\n"; // 出力結果は　1

$user->countUp(); // 2回目のクラス内の関数（メソッド）呼び出し
echo User::$userCount."\n"; // 出力結果は　2

$user->countUp(); // 3回目のクラス内の関数（メソッド）呼び出し
$user->countUp(); // 4回目のクラス内の関数（メソッド）呼び出し
$user->countUp(); // 5回目のクラス内の関数（メソッド）呼び出し
$user->countUp(); // 6回目のクラス内の関数（メソッド）呼び出し
echo User::$userCount."\n"; // 出力結果は　6
```

## 出力結果
```
1
2
6
```

## 最後に
問題を解くだけでなく、解説だけでわからないところを調べたり、コードを書き換えてみたりして遊んでみることで、より理解が深まりました。
GitList-2.0.0をUbuntu24.04で動かしてみる

# 概要

- GitList というのは、Linuxサーバー上にある プライベートなGitリポジトリをWebインターフェースを通してソースコードや差分、コミット履歴をブラウジングするCGIです。 
 https://github.com/klaussilveira/gitlist

- PHPで書かれています。

- 類似のものに GitWebとかWebSVNとかありましたけれど、それらは PerlのCGIです。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/28186/65b5b5e2-3536-141d-bdea-daff919bc9c6.png)


# 前提
- Ubuntu24.04 + Apache2 + PHP8.3 で動かしてみます。
- もちろん Gitはインストール済、Gitリポジトリはローカルファイルとして存在。

# 動かし方手順

- ソースコードリポジトリではなく、以下のURLから TarBallを取得します。

https://github.com/klaussilveira/gitlist/releases /gitlist-2.0.0.zip

- /var/www/html/gitlist/ ディレクトリを掘って、gitlist-2.0.0.zip を展開します
```
 $ cd /var/www/html/gitlist/
 $ unzip gitlist-2.0.0.zip
```
- /var/www/html/gitlist/var/log/ と
- /var/www/html/gitlist/var/cache/ ディレクトリを www-data:権限でr/w許可を与えます。

- apacheのsite 設定ファイル (000-defaultなど) にエイリアスを追加します。（別ファイルにして includeでも良い）

```
    #
    #  GitList::
    #
    Alias /gitlist /var/www/html/gitlist/public
    <Directory /var/www/html/gitlist/public>
           Options Indexes FollowSymLinks
           AllowOverride All
           Require all granted
    </Directory>
```
- apacheの mod_rewrite モジュールをa2enmodして、 .htaccess ファイルを作って URLの Rewriteルールを追加します。

```
#
<IfModule mod_rewrite.c>
    Options -MultiViews +SymLinksIfOwnerMatch
    RewriteEngine On
    RewriteBase /gitlist/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php/$1 [L,NC]
</ifmodule>
```
- 参照する Gitのリポジトリは /var/www/ 下に foo.git/ のようなディレクトリで作ります。
- ディレクトリの設定は gitlist/config/config.yaml 内に記述されているので、そこを触れば、別の場所に移動できます。
- 参照する Gitのリポジトリは safe.directory にしておく必要があるようです。
- （最近はセキュリティがいろいろ問題になるので・・・）
```
 $ git config --global --add safe.directory /var/www/foo.git 
```

- ・・・
- ここまでで、 Ubuntu22.04 (PHP8.1) では動作しますが、 Ubuntu24.04 (PHP8.3)では動きません。

# Ubuntu24.04 での動かし方

- TarBallのほうではなく、GitHubにある、GitListのリポジトリをクローンしてきます。
- gitlist/ 直下で、 composer init します。
- そうやって出来た gitlist/vendor/nesbot/ 以下のみを、TarBall のものと差し替えてください。
- ：  
- もしかしたら、本体ソースの中にまだ PHP8.3非対応部分が残っている可能性はありますが、とりあえず動いている感じです。
Dockerで動かすFessのインデックスバックアップ方法。

## 効果
バックアップを取得する→dockerコンテナ、dockerVolumeを全て削除する→コンテナ再立ち上げ→リストアする
→削除前に戻った！

## 前提
git
https://github.com/codelibs/docker-fess/blob/master/README.md
compose ファイル ファイル名：compose-opensearch2.yaml
C:\docker-fess-master\data\es　　このesというディレクトリを作成する。
```
services:
  search01:
    image: ghcr.io/codelibs/fess-opensearch:2.17.0
    container_name: search01
    environment:
      - node.name=search01
      - discovery.seed_hosts=search01
      - cluster.initial_cluster_manager_nodes=search01
      - cluster.name=fess-search
      - bootstrap.memory_lock=true
      - node.roles=cluster_manager,data,ingest,ml
      - "OPENSEARCH_JAVA_OPTS=-Xms1g -Xmx1g"
      - "DISABLE_INSTALL_DEMO_CONFIG=true"
      - "DISABLE_SECURITY_PLUGIN=true"
      - "FESS_DICTIONARY_PATH=/usr/share/opensearch/config/dictionary"
    ulimits:
      memlock:
        soft: -1
        hard: -1
      nofile:
        soft: 65535
        hard: 65535
    volumes:
      - C:/docker-fess-master/data/es:/usr/share/opensearch/data
      - C:/docker-fess-master/data/es/dictionary:/usr/share/opensearch/config/dictionary
    ports:
      - 9200:9200
    networks:
      - search_net
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "5"
    restart: unless-stopped

networks:
  search_net:
    driver: bridge

volumes:
  search01_data:
  search01_dictionary:
```
バックアップ先
C:\docker-fess-master\data\es

## 手動バックアップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/f2069a0f-0a08-2f99-2177-9aeba2f57cb1.png)

このファイルをコピー
どこかのバックアップ置場へペースト。




### リストア
コンテナ停止
どこかのバックアップ置場からバックアップをコピー。
C:\2docker-fess-master\data\es　へdictionaryとnodesをペースト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3882753/f2069a0f-0a08-2f99-2177-9aeba2f57cb1.png)
コンテナ再開


## まだ更新します

定期自動バックアップ方法
→うまくいったら追記
JAVA / Spring と Spring Boot の違いとは？

<br>

# ■ はじめに

Javaフレームワークの中でも、`Spring` と `Spring Boot` はよく使われています。
しかし、SpringとSpring Bootの違いをきちんと理解している人は意外と少ないかもしれません。
この記事では `Spring` と `Spring Boot` の違いを簡潔に解説し、どのような場面でどちらを使うべきかについても紹介します。

そもそものフレームワークとは何か？については以下の記事を作成していますので
こちらをご確認ください。

https://qiita.com/e-tak/private/3ad403b04bf79a9ead62

# ■ 目次
<br>

1. [Spring Frameworkとは？](#1-spring-frameworkとは)
2. [Spring Bootとは？](#2-spring-bootとは)
3. [SpringとSpring Bootの違い](#3-springとspring-bootの違い)
4. [どちらを使うべきか？](#4-どちらを使うべきか)
5. [まとめ](#5-まとめ)

## 1. Spring Frameworkとは？

Spring Frameworkは、エンタープライズJavaアプリケーションの開発を支援するフレームワークです。
特に依存性注入[^1]やAOP[^2]などの機能を提供し、
柔軟で保守性の高いアプリケーションを構築できるように設計されています。

そのようにSpringは非常に多機能にはなりますが、その分設定が多く複雑な部分があります。
また設定ファイルをXMLやJavaで作成する必要があり、難しいと思われることもあります。

## 2. Spring Bootとは？

Spring Bootは、Spring Frameworkの拡張版であり、Springの複雑な設定を簡略化するために作られたものです。<br>Spring Bootの大きな特徴は、**コンフィギュレーション[^3]の自動化**です。<br>
これにより設定ファイルをほとんど個人で作成することなく利用することができます。

### 主な特徴
- **自動設定**
    - 依存関係に基づいて、自動的に適切な設定が可能

- **組み込みサーバー**
    - Tomcatなどのサーバーが組み込まれており、アプリケーションを簡単に起動可能

- **シンプルなプロジェクト構成**
    - 最小限の設定で、すぐにプロジェクトを開始可能
<br>

## 3. SpringとSpring Bootの違い

Spring と Spring Boot の違いをもう少し詳しく見ていきましょう。

|**項目**|**Spring**|**Spring Boot**|
|:----------------:|:---------------------------------:|:--------------------------------:|
|**設定方法**| 複雑な設定が必要（XML/Javaベースの設定）|自動設定が中心|
|**アプリケーション起動** |別途サーバーをセットアップする必要あり|組み込みサーバーで、すぐに起動可能|
|**開発スピード**| 設定に時間がかかる|すぐに開発を開始可能|
|**使用ケース**| 複雑なエンタープライズシステムや大規模なアプリ|小〜中規模のアプリ開発に最適|
|**依存関係管理**|手動で追加|自動で追加・設定|

### 設定の違い

Springでは、XMLやJavaベースの設定を手動で行う必要がありますが、Spring Bootではほとんどの設定が自動化されています。<br>
以下は、Spring Bootを使った場合の`application.properties`[^4]ファイルの例です。

```properties
server.port=8080
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
```
このように、プロパティを設定するだけでデータベース接続やサーバーポートの設定が簡単に行えます。



## 4. どちらを使うべきか？
<br>

- **Springを使うべきケース**
エンタープライズ向けの大規模で複雑なシステムを開発する場合、Springが適しています。
特に設定を細かくカスタマイズしたい場合や、複数のシステムが連携するような複雑なプロジェクトではSpringの柔軟性が役立ちます。
<br>

 - **Spring Bootを使うべきケース**
小〜中規模のWebアプリケーションを作成したい場合にはSpring Bootが最適です。
設定の手間が少ないため、すぐに開発に着手することが可能です。

## 5. まとめ
 - Spring Frameworkは柔軟で多機能ですが、設定が複雑/エンタープライズ向けの大規模システムに適している。
 - Spring BootはSpringの設定を簡略化した拡張版で、素早く開発を始めたい場合に適している。
 - プロジェクトの規模や必要性に応じて、どちらを導入するかを検討する必要がある。

[^1]:Dependency Injection
[^2]:Aspect-Oriented Programming
[^3]:コンピュータやネットワーク機器、OS・ソフトウェアなどの設定のこと
[^4]:データベースの接続設定、サーバーポート、ログの設定などが含まれる設定ファイル
Javaのフレームワークとは？代表的なフレームワークの解説

<br>

# ■ はじめに
<br>

Javaには企業向けのものから小規模アプリケーションまで幅広いシステムを効率的に開発するために、
フレームワーク[^1]というものが多数存在します。
フレームワークを用いることで共通処理を簡単に実装でき、開発スピードや保守性が向上します。

この記事では、Javaの代表的なフレームワークについての概要とメリットを解説します。

# ■ 目次
<br>

1. [Java Frameworkとは？](#1-java-frameworkとは)
2. [代表的なJava Framework](#2-代表的なjava-framework)
3. [フレームワークを使うメリットとデメリット](#3-フレームワークを使うメリットとデメリット)
4. [まとめ](#4-まとめ)

# 1. Java Frameworkとは？
<br>
Javaフレームワークはアプリケーション開発においてよくある共通作業を自動化・簡略化するためのツールです。<br>
効率的な設計や保守が求められる現在の開発においてはフレームワークの利用は欠かせないものとなっています。

フレームワークを用いることで、以下のような開発タスクが簡単に実装可能です。
- **データベース接続**: フレームワークがデータベースとの接続やクエリ実行をサポート。
- **リクエスト処理**: HTTPリクエストの受信、ルーティング、レスポンスを簡単に行うことができる。
- **依存性管理**: 他のライブラリやサービス間の依存関係を自動的に解消。

Javaには数多くのフレームワークがありますが、それぞれのフレームワークは特定の目的に特化して設計されています。
そのため用途に応じて適切なフレームワークを選択することが重要です。

# 2. 代表的なJava Framework
<br>
Javaのフレームワークの中でも、以下が特に広く使われています。

- **Spring**  
  エンタープライズJavaアプリケーションの開発を効率化するためのフレームワークです。
  複雑なアプリケーションの開発をサポートするための機能が豊富に提供されています。
  コードのモジュール化や再利用性が向上し、保守しやすい設計が可能です。
<br>

- **Spring Boot**  
  上記のSpringの強力な機能を利用しつつ、煩雑な設定を簡略化したフレームワークです。
  組み込みサーバーで素早くWebアプリケーションを立ち上げることができ、特にプロトタイプや小規模のシステムに適しています。
<br>

- **Hibernate**  
  データベース操作をJavaオブジェクトとして扱うことが可能になるフレームワークです。
  そのためSQLの煩雑さが軽減され、Javaのコード内でデータベースの操作を行うことができます。
  複雑なクエリやデータベース設計が必要なシステムで便利です。
<br>

- **Struts**  
  Webアプリケーションフレームワークで、特に大規模なエンタープライズシステムで使用されています。
  古典的なフレームワークであるため、現在ではSpringやSpring Bootに取って代わられることが多いですが
  現在も一部のレガシーシステムで使用されています。
<br>

上記以外にも、非同期処理を簡単に扱えるのが特徴である **Play Framework** や、
JavaでUIを直接作成できる **Vaadin** といった用途に応じたフレームワークが多数存在します。
<br>
またSpring と Spring Boot の詳細な違いに関しては以下の記事を作成していますので
こちらをご確認ください。

https://qiita.com/e-tak/private/475e956103b1fdf05775

<br>

# 3. フレームワークを使うメリットとデメリット
<br>
Javaフレームワークを用いることには多くのメリットがありますが、勿論デメリットもあります。<br>
それぞれのポイントを押さえて、適切にフレームワークを選ぶことが大切です。

### メリット

- **開発の効率化**
    - 基本的な処理をフレームワークが自動化するため煩雑な設定やコードを書く必要がなくなる。（開発時間の削減）
  <br>
  
- **保守性の向上**
    - フレームワークが提供する標準的なコードや設計パターンに従うことで、実装者以外の開発者でも理解しやすくなる。
    チーム開発においてコードの一貫性が保たれやすくなることにも繋がる。
  <br>
  
- **セキュリティの向上**
    - 多くのフレームワークにはセキュリティ対策が組み込まれているため、
    開発者がセキュリティに関する複雑な処理を行わなくても安全なアプリケーションを構築できる。

### デメリット

- **学習コスト**
    - 新しいフレームワークを学ぶために時間と労力を要する。
    フレームワークの内部動作や設定に詳しくないと、問題が発生した際の解決が難しくなります。
<br>

- **依存性の増加**
    - フレームワークに依存しすぎてしまうと特定のバージョンや設計に縛られてしまい、
    バージョンのアップデートなどでコードが動かなくなるなど問題が生じることがあります。

# 4. まとめ

 - Javaフレームワークは、共通機能を自動化し、開発の効率を向上させる。
     - SpringやHibernateなど、用途に応じたさまざまなフレームワークがある。
     
 - Springはエンタープライズ向けに、Spring Bootは軽量なプロジェクトに最適。
     - また、Hibernateはデータベースとの連携を容易にする。
     
 - このようにSpringやHibernate を含むフレームワークの導入にはメリットとデメリットがあるため、プロジェクトの規模やニーズに合わせて選択を行う必要がある。

[^1]:Java言語でのアプリケーション開発を支援する枠組みで、効率的なシステム構築を可能にするもの。
2024/10/10_本日の勉強

## 概要
ポートフォリオサイトを作成した後、アプリケーション開発に必要なことを考え、
まず環境設定やGit/GitHubについて勉強しようと思いました。
以前、Progateか何かでGitHubの登録とリポジトリについて学んだことがありましたが、
復習も兼ねて再度学び直しました。(Progateではなく公式のGitHub の概要に関するドキュメントでした)

ただ覚えるだけでは苦手な部分もあるため、
不明点や調べたことについてはこちらに記載して整理していこうと思います。


## 本日学んだこと


* **commandline**
* catコマンドについて
cat（キャット）はUNIXの標準コマンドであり、ファイルを連結させたり表示したりするのに用いる。 catは連結することを意味する「catenate」の略である。

* **Git**
Git Bashをチュートリアルに沿って触っただけなので、まだこれを使って何ができるのか、具体的な用途がわかっていない状態です。。。
* **Github**
以前登録した後、公式チュートリアルで「Hello World」のリポジトリを作成し、マージまで行っていたことを忘れていたため、Progateの「Gitの環境構築をしよう！」で再度学び直しました。
ただ、公式チュートリアルを一通り行うのが良いかなと思いつつも、使用目的に応じて学ぶ内容を絞ることを考えています。

## 纏め
「cat」といえば猫しか思い浮かばないため、コマンドを略さずに単語としてしっかり認識することで、自分の勉強効率が上がると思っています。時間はかかるかもしれませんが、そのように進めていきたいと考えています。
そもそもの英語力なども鍛えないとな～・・・とも思いました。

学ぶことがたくさんあり、WEB検索をすれば解決策が見つかる環境であるため、他のエンジニアの方々には本当に頭が上がりません。
早く少しでも"ちょっと分かる"と言えるように頑張っていきます。


## 参考
https://docs.github.com/ja/get-started

https://ja.wikipedia.org/wiki/Cat_(UNIX)#:~:text=cat%EF%BC%88%E3%82%AD%E3%83%A3%E3%83%83%E3%83%88%EF%BC%89%E3%81%AFUNIX%E3%81%AE,catenate%E3%80%8D%E3%81%AE%E7%95%A5%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82

https://docs.github.com/ja/get-started/start-your-journey/hello-world
Gitコマンドまとめ（チートシート）

# はじめに
初学者向けにGitコマンドを一覧化してみました！

# Gitコマンド一覧
以下、Gitコマンドの一覧です。

## 基本的なGitコマンド

* 新しいGitリポジトリを作成します。
    ``` shell
    git init
    ```

* 既存のリポジトリをクローン（コピー）します。
    ``` shell
    git clone <クローンしたいリポジトリのURL>

    #例:
    git clone https://github.com/user/repo.git
    ```

* 作業ディレクトリの状態を表示します。変更されたファイルやコミットされていないファイルを確認できます。
    ``` shell
    git status
    ```


* 変更されたファイルをステージングエリアに追加します。

    ``` shell
    git add <ステージングしたい変更を指定>

    #例: すべての変更を追加
    git add . 
    #例: sample_dirの変更を追加
    git add sample_dir 
    ```

* ステージングエリアの変更をリポジトリにコミット（保存）します。
    ``` shell
    git commit -m "コミットメッセージ"
    ```

* ローカルリポジトリのコミットをリモートリポジトリにプッシュします。
    ``` shell
    git push <リモートリポジトリ名> <ブランチ名>

    #例: 
    git push origin main

    #以下とすることで、プッシュと同時に、以降ローカルブランチとリモートブランチが連携されるように設定できる
    git push --set-upstream <リモートリポジトリ名> <ブランチ名>
    ```

* リモートリポジトリから変更をプルして、ローカルリポジトリにマージしま*す。
    ``` shell
    git pull <リモートリポジトリ名> <ブランチ名>

    #例: 
    git pull origin main
    ```

## 特別なGitコマンド

* 新しいブランチを作成したり、現在のブランチを表示します。
    ```shell 
    #現在のブランチを表示
    git branch

    #新しいブランチを作成
    git branch new-branch
    ```

* ブランチを切り替えたり、特定のコミットに移動します。
    ```shell 
    #ブランチを切り替え
    git checkout new-
    
    # 特定のコミットに移動
    git checkout <commit-hash>
    ```

* 他のブランチを現在のブランチにマージします。
    ``` shell
    git merge <他のブランチ>

    #例
    git merge new-branch
    ```

* 一つのブランチの変更を別のブランチの先頭に移動します。よりクリーンな履歴を保つために使用されます。
    ``` shell
    git rebase <変更元ブランチ>

    #例: mainブランチの変更を現在のブランチに適用し、履歴を整理します。
    git rebase main 
    ```

## その他便利なコマンド

* リポジトリのコミット履歴を表示します。
    ``` shell
    git log
    ```

* 変更点を表示します。
    ``` shell
    git diff
    ```

* 作業中の変更を一時的に保存し、クリーンな作業ディレクトリに戻します。
    ``` shell
    git stash
    ```

* 一時的に保存した変更を再度適用します。
    ``` shell
    git stash pop
    ```
# まとめ
これらのコマンドを使いこなすことで、Gitの基本的な操作を理解し、効率的にバージョン管理ができるようになります。
チートシート的な用途で使っていだけると！
Minecraft ForgeのMixinセットアップ・使用メモ

# まえがき
よくMixinの書き方を忘れるのでメモしておきます。
# 環境
* Intellij IDEA
* Minecraft Development
* Minecraft Forge 1.16.5
# 準備
1\. build.gradleを以下のように変更
```diff_gradle:build.gradle
    plugins{
        ...
+       id 'org.spongepowered.mixin' version '0.7.+'
    }
+   mixin{
+       config 'modid.mixins.json'
+   }
```


2\. src/main/java/(package)/resourcesにmodid.mixins.jsonを作成し以下をコピペ
```json:modid.mixins.json
{
  "required": true,
  "package": "insert.your.package.mixins",
  "compatibilityLevel": "JAVA_8",
  "mixins": [
    "HelloMixin",
    "GoodbyeMixin",
    "NiceToMeetYouMixin"
  ]
}
```
:::note warn
modid、insert.your.package.mixin、HelloMixinなどの所は都度置換してください。
:::
# 使い方
まずmodid.mixins.jsonのmixinsにクラス名を追加しパッケージにもクラスを追加する
```java: HelloMixin.java
import org.spongepowered.asm.mixin.Mixin;
@Mixin(Hello.class)
public class HelloMixin{

}
```
### Inject
メソッド内などに処理を挿入したいとき。
```java: HelloMixin.java
@Inject(at = @At("HEAD"), method = "helloWorld", cancellable=true)
private void helloWorld(String argument,int argument, CallbackInfo ci){
    //@At("HEAD")の場合先頭に追加される
    
    //通常の処理をキャンセル(cancellable=trueが必要)
    ci.cancel();
    //新しい処理
    System.out.println("New Hello World");
}
```
### Redirect
メソッド内部の呼び出しなどの変更
```java: HelloMixin.java
@Redirect(at = @At(value = "FIELD", 
    target = "somethingsomething"/*ここはMinecraft Developmentで自動変換される*/),
    method = "helloWorld")
private String getUserName(Hello instance){
    return "taro";
}
```
Redirect後のコード
```diff_java: Hello.java
    public void helloWorld(){
-       System.out.println("Hello," + this.username); 
+       System.out.println("Hello," + getUserName(this)); 
    }

```
# 後書き
自分用に書いたので文章が汚い所もあるかもしれませんがご了承ください。
# 参考

https://qiita.com/Gorayan/items/5deaf65a23bdb3d44840


https://darkhax.net/2020/07/mixins
ViewSet actionsの種類 | Django REST Framework

Django REST FrameworkのViewSet、特にModelViewSetで自動的に提供しているlist, retrieve, create, update, partial_update, destroyなどのCRUDアクションの種類を整理します。

参考：公式ドキュメント[ViewSet actions](https://www.django-rest-framework.org/api-guide/viewsets/#viewset-actions)

# create
- HTTPリクエスト: POST
- 役割: 新しいレコードを作成します。通常、POSTリクエストを処理し、新しいインスタンスをデータベースに保存します。新規登録によく使われます。
```python
def create(self, request, *args, **kwargs)
```

# list
- HTTPリクエスト: GET (複数のオブジェクト)
- 役割: 全てのレコード、またはフィルタされたレコードのリストを取得します。通常は/api/resource/のようなリクエストに対応します。〇〇一覧とかのページを作るときに◎
```python
def list(self, request, *args, **kwargs)
```

# retrieve
- HTTPリクエスト: GET (単一のオブジェクト)
- 役割: 特定の１つのレコードを取得します。/api/resource/<pk>/のようなリクエストで、特定のpkに基づいてデータを取得します。詳細ページの表示とかに使います。
```python
def retrieve(self, request, *args, **kwargs)
```

# partial_update
- HTTPリクエスト: PATCH
- 役割: 特定のレコードを部分的に更新します。PATCHリクエストで送信されたフィールドのみを更新します。レコードのある特定のカラム(フィールド)だけ変更を加えたいという時に使います。フラグ変更、論理削除とかに使ったことがあります。
```python
def partial_update(self, request, *args, **kwargs)
```

# destroy
- HTTPリクエスト: DELETE
- 役割: 特定のレコードを削除します。通常、/api/resource/<pk>/のように特定のpkに対してDELETEリクエストを送信すると、そのリソースが削除されます。要は物理削除です。レコードを完全に消したい時に使います。
```python
def destroy(self, request, *args, **kwargs)
```

# update
- HTTPリクエスト: PUT
- 役割: 特定のレコードを完全に更新します。リクエストで送信された全フィールドで既存のリソースを置き換えます。レコードの全てのカラム(フィールド)に更新をかけたい時に使います。
```python
def update(self, request, *args, **kwargs):
```

# update と partial_update の違い
両者の違いは、特定のレコードのカラム(フィールド)の一部変更か、もしくは全カラム(フィールド)変更かという違いです。

- update: 一般的にはPUTリクエストに対応し、クライアントから全フィールドの値を送ることを期待します。欠けたフィールドはデフォルト値やnullで上書きされることが多いため、全フィールドの更新が前提です。
- partial_update: PATCHリクエストに対応し、送信された一部のフィールドだけを更新します。未送信のフィールドは変更されず、元の値が保持されます。

しかし、pertial_updateで全カラム(フィールド)の変更情報を送っても変更はできてしまいます。
また、updateメソッドでも全レコードの変更内容を送らず、PATCHに対応させるように書く方法もあります。

そのため、両者の違いがよくわからないですが、私は部分更新（フィールドの一部変更）が主流であれば、pertial_updateというふうに書いてみています。
TableViewで一部のcellだけdrag&drop無効化、cellの入れ替えをさせない(swift)

## はじめに
- 自分が調べたことを忘れないように記事に残しておくブログ的なものです
- 今回は一部のcellのdrag&drop無効化したかったのと、その無効化しているcellの入れ替えも禁止したかったという内容になります

## 一部のcellだけdrag&dropさせない・cellの入れ替えをさせない

```
// MARK: - UITableViewDragDelegate

func tableView(
    _ tableView: UITableView, 
    itemsForBeginning session: UIDragSession, 
    at indexPath: IndexPath
) -> [UIDragItem] {
    // ここで特定のcellのdragを無効化できる(ここでは3番目が無効化)
    if indexPath.row == 2 {
        return []
    }
    let item = self.data[indexPath.row]
    let itemProvider = NSItemProvider(object: item as NSString)
    let dragItem = UIDragItem(itemProvider: itemProvider)
    return [dragItem]
}

// MARK: - UITableViewDropDelegate

func tableView(_ tableView: UITableView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UITableViewDropProposal {
    guard let destinationIndexPath = destinationIndexPath else {
        return UITableViewDropProposal(operation: .cancel)
    }

    // ここで無効なセルへのドロップ禁止できる(ここでは3番目へのドロップを無効化)
    if destinationIndexPath.row == 2 {
        return UITableViewDropProposal(operation: .forbidden)
    }

    return UITableViewDropProposal(operation: .move)
}
```

## おまけ: drag&dropを無効化しているcellが動かないように固定する
- 別のcellをdragしている時にdrag&drop無効化しているcellにdrag中のcellを重ねた場合、drag&dropを無効化しているcellが移動してしまっていたので以下のコードで移動しないよう完全に固定化しました
```
// MARK: - UITableViewDelegate

func tableView(_ tableView: UITableView, targetIndexPathForMoveFromRowAt sourceIndexPath: IndexPath, toProposedIndexPath proposedDestinationIndexPath: IndexPath) -> IndexPath {
    // ここで指定したcellの動きを無効化できる(ここでは3番目のcellの動きを無効化)
    return proposedDestinationIndexPath.row == 2 ? sourceIndexPath : proposedDestinationIndexPath
}

```