OmniAICreator/Qiita-1.07M huggingface dataset:
Rust の leaflet クレートの描画部分の使い方

Hi, there！ SAmmysだよ！
Yewで作成中のアプリに地図を使う部分があって、その部分をleaflet使って実装したよ。
leaflet クレートを使った Example もあるけど、その中の記述のままだと最新バージョンではエラーが出ちゃうから、せっかくだしここでザッと最描画部分のコンポーネントの最小限な部分だけ書いちゃうね。
キミならこれ見れば実装できちゃうよ💡

Map型の変数`map`とTileLayerは各自で好きなように作ってね。
以下、上記`map`変数の使い方とか記載。

◆任意の緯度・経度の座標にピンを立てる場合
```rust
let marker = leaflet::Marker::new(&LatLng::new(35.861683,139.645676));
marker.add_to(&map);
```
はい、愛するさいたま市の市役所にピンが経ちました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057373/847286b0-8483-18db-5486-6aebe8c7ba62.png)

◆任意の緯度・経度にコメントも立てる場合
```rust
let marker = leaflet::Marker::new(&LatLng::new(35.861683,139.645676));
let popup_options = leaflet::PopupOptions::new();
// popup_options.set_max_width(10.0); // もし横幅に制限つけたければ
// popup_options.set_max_height(30.0);  // もし高さに制限つけたければ
// popup_options.set_keep_in_view(true); // ユーザー操作時に画面移動させても描画内に必ずPopupを表示させたければ
let popup: leaflet::Popup = leaflet::Popup::new_with_lat_lng(
    &LatLng::new(35.861683,139.645676),
    &popup_options
);
popup.set_content(&wasm_bindgen::JsValue::from("さいたま市の市役所です"));
marker.add_to(&map).bind_popup(&popup).open_popup();
```
はい、ご覧のとおりです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057373/b1244698-9708-7fdb-e218-05f221be6df4.png)

◆任意の緯度・経度を中心に円を描く場合
```rust
let circle_option = leaflet::CircleOptions::new();
circle_option.set_radius(17.0);
let circle = leaflet::Circle::new_with_options(
    &LatLng::new(35.861683,139.645676),
    &circle_option
);
circle.add_to(map);
```
市役所内に円形の結界が張られました（笑）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057373/9b129d17-65ea-4a8b-abfa-68a9aca65f0d.png)
▲ もし色を変えたければ、すぐ下の線の色指定を参考にしてね。

◆任意の２点間を線で結ぶ場合（色と太さ指定付き）
```rust
let mut latlngs = js_sys::Array::new();
for item in [LatLng::new(35.861683,139.645676), LatLng::new(35.62416667,135.0611111)].iter() {
    latlngs.push(&wasm_bindgen::JsValue::from(item));
}
let polyline_option = leaflet::PolylineOptions::new();
polyline_option.set_color("#1DFFD0".to_string()); // ここで色指定してるよ！
polyline_option.set_weight(8.0); // ここで太さ指定してるよ！
let polyline = leaflet::Polyline::new_with_options(
    &latlngs,
    &polyline_option
);
polyline.add_to(map);
```
愛する京丹後市とさいたま市が太い絆で結ばれました。
（ヘリコプターで行くと一度日本海またぎそう！）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1057373/21e2d798-4d9f-7acc-6b13-3f6bd82e09bd.png)

ということで、地図関連は色々なアプリでも使えるから参考にしてみてね。
ちなみに、GoogleMap は API Key 使ったリクエスト回数でコストかかっちゃうから僕は見送ったよ。
See ya!
FlexboxとGridの得意なこと

CSSをあまり触らない同僚からFlexbox（以下flex）とGrid（以下grid）について聞かれたので、そのとき話した個人的な意見をまとめてみました。

## flexとgridの共通点
- 垂直方向の中央揃えが簡単にできる
- 「余ったスペースを埋める」が簡単にできる
- 要素の間に一定の余白を設定できる
- 特定の要素を任意の位置に移動・並び替えできる
- 高さ不定の要素を横並びにしたときに1行の高さを揃えられる

最近コーディングを始めた人にはあまりピンとこないかもしれませんが、`flex`と`grid`がなかった頃からのコーダーにとっては上記が簡単にできるようになったのは画期的なことでした。

それまでは`display:table-cell`を使ったり、`float`を駆使して回り込み解除に`.clearfix`なる専用クラスを作ったり、jsで高さ不定の要素が並ぶ行の高さを揃えたり（今でもまだ必要な場面はありますが）、色々ひと手間かけないといけなかったのです。

## flexとgridの違い
![スクリーンショット 2024-02-17 20.17.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3686558/a211f599-21da-e79e-4fd4-7684794bc4f4.png)

- `flex`は要素一定方向に並べる　（`float`に近い）
- `grid`は要素を決まったマス目の中で一定のルールに従って配置する　（`table`に近い）
- `flex`は`grid`より先にすべてのブラウザで利用できるようになった
    - 古くからコーディングしている人にとっては`flex`の方が`grid`より付き合いが少し長い
    - 古いサイトやライブラリ、フレームワークは`flex`を使っていることが多い

## flexの得意なこと
- 不定のサイズ・不定数の要素を一定方向に並べられる
- タグ一覧やパンくずリスト、アイコン＋テキストのボタン、表示する要素が状況によって異なるセクションの行列揃えなどに便利
-  「とりあえず２つ以上の要素を並べる」を`grid`より直感的に設定できる
    - `grid`は最初にルールを考える必要がある
- `flex`に慣れているとFigmaのオートレイアウトを直感的に理解しやすくなる
    - Figmaのオートレイアウトに慣れていると`flex`にとっつきやすい

## gridの得意なこと
- 縦と横２軸の一定のルールで要素を並べられる
- ページ全体のヘッダー・メイン・フッターの設定、サムネイルギャラリーやタイル状のナビのようなレイアウトなどに便利
- `flex`でできることを`flex`より少ない記述で表現できるケースがある
- `subgrid`を使うことでjsを頼らずに親要素が異っているサイズ不定の子要素同士のサイズを揃えられる
- `auto-fit`や`minmax（）`を駆使することでメディアクエリーを頼らずにレスポンシブデザインを組みやすい

## flexとgridの比較

### 上下左右中央寄せ
水平・垂直で中央寄せしたい要素の親要素に設定する時のそれぞれの記述。
とにかく「中央に配置する」をやりたいだけなら2行で済むgridの方を選びます。
#### flex
```
.parent{
  display: flex;
  justify-content: center;
  align-items: center;
}
```
#### grid
```
.parent{
  display: grid;
  place-content: center;
}
```
### 複数行の中の要素を左下から右上に向けて並べる

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="abPjELW" data-user="mazereeta" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mazereeta/pen/abPjELW">
  Grid : Bottom Right to Top Left</a> by AyaOki (<a href="https://codepen.io/mazereeta">@mazereeta</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

#### flex
```
.parent{
  display: flex;
  direction: rtl;
  flex-wrap: wrap;
  flex-flow: wrap-reverse;
  justify-content: flex-start;
}
```
#### grid
```
.parent{
  display: grid;
  grid-template-columns: repeat(4, 1fr);　/* 任意のテンプレート */
  transform: rotate(180deg);
  
  > .item{
    transform: rotate(180deg);
  }
}
```
めったにやらない処理ですが、ふとこれを`grid`でやりたい時どうするんだ？と思ってやってみたらなかなかできなくて、X（Twitter）でその事をつぶやいてたら上記の親を反転＋子要素をさらに反転させるアイデアをいただきました。
`grid`も「右から開始する」だけなら`direction: rtl;` でいけます。
RaspberryPiでUnityエディタの起動確認

# RaspberryPiとは
RaspberryPiは、ラズベリーパイ財団が開発及び販売するシングルボードコンピュータです。
今回はそのモデル4BのRAM8GBモデルを使用します。
OSはArm版Windows11を使用します。

以下より購入可能です。
[Raspberry Pi Shop by KSY](https://raspberry-pi.ksyic.com/main/index)

先日、国内版のRaspberryPi5が販売開始しましたが、まだ手元に用意できていないので4を使用します。

# Unity2023.3
Unity2023.3よりArm版WindowsマシンでUnityEditorが使用可能になりました。
記事作成時点ではベータ版となっており、2023.3.0b5を使用します。
[Unityリリース](https://unity.com/releases/editor/beta/2023.3.0b1)

# 動作確認
公式サンプルである[URP3DSampleScenes](https://github.com/Unity-Technologies/URP3DSampleScenes)を使用します。
このプロジェクトは2022.3.7f1で作成されているので起動時にバージョン不一致の確認ダイアログが出ますが、2023.3で開きます。

アセットのImportに非常に時間がかかりました。
まずは空のシーンを作ってエディタを実行してみます、特にエラーは出てなさそうです。
Statsを確認すると2.9FPSと表示されました。
空のシーンでこれは苦しいですね。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878081/5d832432-5a83-2327-e59d-38a933dcc5ff.png" alt="UnityEmptyScene.png" width="512">

続いてGardenSceneを開いて実行してみます。
Statsを確認すると0.6FPSと表示されました。
このシーンで何が起こっているのか把握が難しいレベルだと感じました。
とはいえ最低限動作してそうです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878081/fb952f1a-2f08-e691-187e-83c798658f99.png" alt="UnityGardenScene.png" width="512">

# まとめ
Arm版Windows環境のRaspberryPi4で、Unity2023.3が最低限動作することを確認しました。

URP3DSampleScenesプロジェクトはエラーなく実行可能でしたが、動作は非常に重かったです。
また新規で作成したプロジェクトでも動作確認しましたが、快適に実用可能とは言えないと感じました。

初学者用の簡単なパズルゲーム開発くらいであれば使用できるかと思いましたが、流石に難しそうです。
RaspberryPi5を入手できたら、また試してみようと思います。
【Swift】2つの値がほぼ同じであることを判定したい

# はじめに
Swiftで同じであることを知りたいのであれば、`==`を使えばわかります。
しかし、今回知りたいのは「**ほぼ**同じである」ことです。

「ある基準値より差が小さければ同じものであるとする」ということがしたいです。

どういうことかというと、

値A: 5.55550
値B: 5.55555

基準値を0.0001だとすると、上の例では値Aと値Bはほぼ同じであると言えます。

テストを書く際にこういうケースは割と発生すると思います。

実際、Nimbleにも`beCloseTo`という機能があり、「ほぼ同じ」が再現できます。

どのように実装すれば最もスマートでしょうか？

# Nimbleのコードを見てみる
値Aと値Bの差の絶対値を求めて、基準値より小さいかを見ているようです。
```swift
internal func isCloseTo(
    _ actualValue: NMBDoubleConvertible?,
    expectedValue: NMBDoubleConvertible,
    delta: Double
) -> PredicateResult {
    let errorMessage = "be close to <\(stringify(expectedValue))> (within \(stringify(delta)))"
    return PredicateResult(
        bool: actualValue != nil &&
            abs(actualValue!.doubleValue - expectedValue.doubleValue) < delta,
        message: .expectedCustomValueTo(errorMessage, actual: "<\(stringify(actualValue))>")
    )
}
```

Nimbleではほぼ同じの基準値をデフォルトで`0.0001`に設定しているようです。
```swift
public func defaultDelta<F: FloatingPoint>() -> F { 1/10000 /* 0.0001 */ }
```

# 実装
イコールのように、ニアリーイコールを定義してみました。
基準値はNimbleを参考に`0.0001`に設定しました。
```swift
import Foundation

infix operator ≒≒ : ComparisonPrecedence

func ≒≒(left: Double, right: Double) -> Bool {
    return abs(left - right) < 0.0001
}
```

# 使い方
`a`と`b`の差が0.00005の時は`true`を返します。
```swift
let a: Double = 5.55550
let b: Double = 5.55555

print(a ≒≒ b) // true
```

`a`と`b`の差が0.00015の時は`false`を返します。
```swift
let a: Double = 5.55550
let b: Double = 5.55565

print(a ≒≒ b) // false
```

# おわり
かなり勉強になりました

# 参考記事
https://qiita.com/Se1getsu/items/e950e9d06b775b84bf68

https://zenn.dev/kyome/articles/48f551222b339c
Gmail :  GASを使ってメール自動削除

Gmailで一部メールが消すのも面倒になってきたので、定期的に自動で削除させる。

GASを使って、定期的に自動削除させる。

***

# 流れ

Google Apps Script（GAS）を使用して定期的に特定のメールを削除するには、GmailApp クラスを使用したスクリプトを作成し、トリガーを設定して定期実行します。以下はその基本的な手順です。

1.  **Google Apps Scriptプロジェクトの作成**:
    *   Google Drive にアクセスし、「新規」>「その他」>「Google Apps Script」を選択して新しいプロジェクトを作成します。
    *   プロジェクトに名前を付けます。

2.  **スクリプトの作成**:
    *   あとで記載

3.  **トリガーの設定**:
    *   スクリプトエディタの画面で「トリガー」アイコン（時計のアイコン）をクリックします。
    *   右下の「トリガーを追加」をクリックします。
    *   実行する関数として、コードに記載のものを選択。例えば「deleteSpecificEmails」を選択します。
    *   イベントのソースとして「時間主導型」を選択し、どのくらいの頻度でスクリプトを実行するかを設定します（例: 毎時、毎日、週1回など）。

4.  **保存して実行**:
    *   トリガーの設定が完了したら、「保存」をクリックします。
    *   初めてスクリプトを実行する場合、Googleから権限の承認を求められます。指示に従って承認してください。

これで、設定した条件に一致するメールが定期的に削除されるようになります。安全のため、重要なメールが誤って削除されないよう、実行前に条件をよく確認してください。

***

# スクリプト&トリガー

指定された条件に基づいて、Gmailから特定のメールを2日に一度削除するためのGoogle Apps Script（GAS）のコードは以下のようになります。各メールアドレスと題名の条件を考慮に入れたスクリプトを作成します。

```javascript
function deleteSpecificEmailsPeriodically() {
  // 検索クエリのリスト
  var queries = [
    'from:"dマーケット" <message_r@mail2.apl01.spmode.ne.jp>',
    'from:"dショッピング" <message_r@mail2.apl01.spmode.ne.jp>',
    'from:"Google" <no-reply@accounts.google.com> subject:"セキュリティ通知"',
    'from:"no-reply@bitflyer.com" subject:"【bitFlyer】ログイン確認メール"'
  ];
  
  queries.forEach(function(query) {
    var threads = GmailApp.search(query);
    for (var i = 0; i < threads.length; i++) {
      GmailApp.moveThreadToTrash(threads[i]);
    }
  });
}
```

このスクリプトは、指定したメールアドレスと題名の条件に基づいてメールを検索し、見つかったメールをゴミ箱に移動します。

### トリガーの設定（2日に一度実行）

1.  スクリプトエディタの画面で「トリガー」アイコン（時計のアイコン）をクリックします。
2.  右下の「トリガーを追加」をクリックします。
3.  実行する関数として「deleteSpecificEmailsPeriodically」を選択します。
4.  イベントのソースとして「時間主導型」を選択します。
5.  「時間ベースのトリガーのタイプを選択」で「日タイマー」を選び、「間隔」で「2日ごと」を選択します。

以上で、指定された条件に一致するメールが2日に一度削除されるように設定されます。設定する際は、重要なメールが誤って削除されないように注意してください。また、初めてスクリプトを実行する際には、Googleから権限の承認を求められますので、指示に従って承認してください。

***

# GASリンク

Google Apps Script（GAS）にアクセスするには、以下のURLを使用できます:

[Google Apps Script](https://script.google.com/)

このリンクを開くと、Google Apps Scriptのダッシュボードが表示され、新しいプロジェクトを作成したり、既存のプロジェクトにアクセスしたりすることができます。Googleアカウントでログインしている必要があります。

***

こんな感じで勝手に消してもらおうと思う。

書いてあるのは、あくまで例。
【Linux標準教科書】4, 5章の補足事項

## これはなに？

Linux標準教科書を元に学習中です。

テキストを進める上で、「この場合はどうなの？」と疑問に思ったこととその答えをまとめます。

## 4章: 正規表現とパイプ

### grep -i

> grepコマンドの`-i`オプションは大文字・小文字を区別せずに検索できる。
> てことは、grepってデフォルトでは大文字・小文字を区別するってこと？

その通り。
`-i`オプションは、大文字と小文字の区別が重要でない場合や、ユーザー入力などで大文字小文字が不確定な場合に特に便利です。

### grep -e

> grepコマンドの`-e`オプションってどんなときに使うの？
> 「文字列を検索パターンとして扱う。」と説明してるけど、それってgrepそのものの機能なのでは？
> 現に以下の出力結果は同じっぽいし。
> - `ls /etc/* | grep conf$`
> - `ls /etc/* | grep -e conf$`

`-e`は、検索条件が2つ以上あるときに使うと便利。
例えば以下のコマンドを使用することで`error`**もしくは**`warning`という単語を含む行を見つけることができる。

```
grep -e error -e warning filename
```

> 上の例はor条件で検索するんだね。
> and条件で検索する場合はどうすれば良いの？

and条件にする場合は、grepをパイプで繋ぐ。
上の例をand条件にする場合は、以下のコマンドを使用する。

```
grep "error" filename | grep "warning"
```

## 5章: 基本的なコマンド2

### tr

> `cat FILE | tr on ON`
> によってoとnがOとNに変換されるけど、"on"というかたまりの文字列を"ON"にしたい場合はどうすれば良いですか？

`sed`（もしくは`awk`）を使用する。
質問内容を実現するには、以下のコマンドを使用する。

```
cat FILE | sed 's/on/ON/g'
```

`sed`は正規表現をサポートしているので、より複雑なパターンや条件に基づく置換も可能
[Ruby] 名鉄津島線の駅名を上り方面、下り方面の順番で表示する

名鉄津島線の駅名を上り方面、下り方面の順番で表示するプログラムをRubyで実装しました

```Ruby
# 名鉄津島線の駅名表示

tsushima_line_data = ["須ヶ口","甚目寺","七宝","木田","青塚","勝幡","藤浪","津島"]
station_num = tsushima_line_data.length

def space()
  puts ""
end

# 名鉄津島線の上り方面の駅名を順に表示(津島から須ヶ口)
start_num = 0
i = station_num - 1
while i >= start_num
  puts tsushima_line_data[i]
  i -= 1
end

space

# 名鉄津島線の下り方面の駅名を順に表示(須ヶ口から津島)
j = start_num
while j < station_num
  puts tsushima_line_data[j]
  j += 1
end
```

結果
![title.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710584/650812c0-d5bc-65bb-19b0-b6f336826d67.jpeg)
Windowsタスクバーのアイコンを区分けする（mac版付き）

# 概要
Windowsのタスクバーにピン止めしたアプリはぴっちり敷き詰められていてアイコンが増えてくると区別しづらくなると思います。ジャンルごとにスペースで区分けする方法を共有します。

![スクリーンショット 2024-02-17 200805.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/c3c838c9-b209-8f6a-e9dc-50f66e527c88.png)

Windowsのタスクバーに何でも良いのでアイコン画像を設定したショートカットを差し込むことで区分けをしていきます。ですがショートカットそのままではタスクバーに登録することが出来ないのでそこでひと工夫が必要になります。

# 本文
## ショートカットを作成
まずは専用の作業用フォルダを適当な場所に作成します。そのフォルダに何でも良いのでショートカットを作成します。（これから作る区分け部分はクリックするとそのフォルダが開いてしまいます。どうせならよく使うドキュメントフォルダ、動画フォルダなどを登録しておけば一石二鳥になりそうですね）
今回はドキュメントフォルダを右ボタンで作成したフォルダへドラッグしてショートカットを作成しました。
![スクリーンショット 2024-02-17 201142.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/1724d599-24a0-0c35-cbc1-816ea8c90e31.png)
## アイコンファイルを用意する
区分けに使いたい絵柄のアイコンファイルを用意します。サイズは22*22で背景を透過したい時はアルファチャンネル付きの画像を拡張子icoで作成します。

（GIMPでアイコンを作る場合の作例）
①ファイル > 新しい画像で表示されたウィンドウから詳細設定をクリック > 塗りつぶし色を「透明」にしてサイズは22*22にします。
②区分け用の絵柄を描きます。（透過処理が上手くいかなかった場合はタスクバーの色をスポイト機能で吸い取って背景にするのでも良いと思います）
③ファイル > 名前を付けてエクスポート。ポップアップが表示されたら拡張子をicoにして最初に作成したフォルダへ出力します。

## ショートカットの準備
①ショートカットファイルを右クリック > プロパティ
②リンク先にショートカットのフォルダへのディレクトリが登録されていますがこの先頭に「explorer 」と追加します。これを追加することで冒頭に話していたタスクバーにはショートカットを登録することができない問題を解決することができます。続けてアイコンの変更をしたらOKを押してください。
![スクリーンショット 2024-02-17 203757.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/0eab1f62-588a-2f9a-fb81-ba880d26e0b3.png)

## タスクバーに登録する
ショートカットキーのファイルをタスクバーにドラッグすると無事登録されると思います。後は好きな位置に移動させたら完成です！
![スクリーンショット 2024-02-17 203010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/331c02b7-f470-4e22-8f29-749f785872ef.png)

:::note info
同じショートカットファイルはタスクバーに登録できないので複数区分けしたい時はショートカットを追加で作成してください。
:::


# macの場合
おまけでmacの場合の区切りを追加する方法です。
Terminalで以下のコードを入力します。（最初のコードでスペースを作成してkillall DockでDockerを再起動しています）

```terminal
defaults write com.apple.dock persistent-apps -array-add '{tile-type="spacer-tile";}'; killall Dock
```

Dockerに空欄が追加されるので好きな位置にドラッグで移動させてください。
必要なくなったら右クリックで「Dockから削除」でいつでも消せます。
![スクリーンショット 2024-02-17 21.02.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617265/639103bc-be1a-e572-ade4-a9e6dc6225aa.png)
WindowsのMicrosoftフォトのキャッシュを消す

# はじめに

Microsoftの画像表示管理アプリ「Microsoft フォト」及び「Microsoft フォト レガシ」で、特定のフォルダを認識できてないことがあったのでキャッシュを消して解決したので、メモとして残す。

環境はWindows10です。

# 方法

Windowsの設定からも消せるようだが、うまくいかず最終的にファイルエクスプローラーから削除しました。

## 設定から

1. Windowsの「設定」→「アプリ」→対象のアプリの「詳細オプション」を開く
2. 「リセット」でキャッシュが消える

## ファイルエクスプローラーから削除

各フォルダの中を削除する

Microsoft フォト

```
%LOCALAPPDATA%\Packages\Microsoft.Windows.Photos_8wekyb3d8bbwe\AC\Microsoft\CryptnetUrlCache\Content
```

```
%LOCALAPPDATA%\Packages\Microsoft.Windows.Photos_8wekyb3d8bbwe\AC\Microsoft\CryptnetUrlCache\MetaData
```

Microsoft フォト レガシ
``` 
%LOCALAPPDATA%\Packages\Microsoft.PhotosLegacy_8wekyb3d8bbwe\AC\Microsoft\CryptnetUrlCache\Content
```

```
%LOCALAPPDATA%\Packages\Microsoft.PhotosLegacy_8wekyb3d8bbwe\AC\Microsoft\CryptnetUrlCache\MetaData
```
:::note info
%LOCALAPPDATA% = C:\Users\ {UserName} \AppData\Local
:::
webp→jpg変換 _ python (chatGPT画像とか)

ChatGPTで画像生成すると"webp"ファイルになるので、まとめてjpgにするメモ

ChatGPTに聞いたら一発で教えてくれたけど備忘録で。

***

# pip

今回のコードを実行するには、以下の2つのパッケージが必要です。

1.  `Pillow` - 画像処理ライブラリ
2.  `os` - ファイルシステム操作用の組み込みライブラリ

`Pillow` パッケージは通常、`PIL` としてインストールされます。コード内で `from PIL import Image` としてインポートしています。

これらのパッケージをインストールするために、以下のコマンドを使用できます。

```bash
pip install Pillow
```

`os` ライブラリは Python の標準ライブラリに含まれており、追加のインストールは必要ありません。

また、このコードは Python 3.x 環境で動作します。Python 2.x では動作しないことに注意してください。

***

# コード

```python
import os
from PIL import Image

# 変換元のフォルダパス
source_folder = "変換元のフォルダのパス"
# 変換先のフォルダパス
destination_folder = "変換先のフォルダのパス"

# 変換元のフォルダ内のファイルを取得
files = os.listdir(source_folder)

# 変換元のフォルダ内のすべてのファイルについて処理
for file in files:
    # ファイルの絶対パス
    file_path = os.path.join(source_folder, file)
    # webpファイルかどうかを確認
    if file.lower().endswith('.webp'):
        # webp画像を開く
        img = Image.open(file_path)
        # 変換先のファイルパスを生成 (拡張子を.jpgに変更)
        destination_path = os.path.join(destination_folder, os.path.splitext(file)[0] + ".jpg")
        # jpg形式で保存
        img.save(destination_path, 'JPEG')
        # 画像を閉じる
        img.close()
```

このコードでは、Pillowライブラリを使用してwebp画像をjpgに変換しています。`source_folder`変数に変換元のフォルダパスを、`destination_folder`変数に変換後のフォルダパスを指定してください。また、フォルダ内のすべてのwebp画像を変換するので、注意してください。

***

とても便利でした。ありがとうございました。
Tera TermでSSHの接続設定を保存し自動ログインする方法

## はじめに
Tere Termを利用する際に、ホスト、ユーザー名、パスフレーズ、秘密鍵を毎回入力するのを手間だと思う方も多いのではないでしょうか。
今回は、Tera TermでのSSH接続の設定を保存し、自動ログインするためのショートカットをデスクトップ上に作成していきたいと思います。

## SSHの接続設定を保存する
**■ 前提の確認**
従来であれば、下記の画像のようにホスト名を入力した後、ユーザ名、パスフレーズを入力、秘密鍵のパスを通してSSHによる接続ができるようになると思います。
本記事では、これらの工程を省略し、ショートカットをクリックするだけで接続できるように設定をします。
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/180cbcc5-d974-356d-54a0-c0c0ffb8bb24.png)
![画像4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/738fabef-33bb-ae28-e80b-a1bca254e7ab.png)

 **1. デスクトップにTera Termのショートカットを作成する**
まずは、Tera Termがあるフォルダを開きます。
~~~
C:\Program Files (x86)\teraterm
~~~

そして、「ttermpro.exe」というファイルを右クリックして、「送る」⇒「デスクトップ（ショートカットを作成）」を選択します。
そうすると、デスクトップにTera Termのショートカットが作られていると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/efb7d911-e508-8031-3ce1-96a75f944b27.png)

 **2. SSHの接続内容を設定する**
 Tera Termのショートカットが作成されたら、右クリックして「プロパティ」を選択します。
![画像7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/64016b72-060a-076c-a042-ca7e05edfebf.png)

「プロパティ」が開けたら、「ショートカット」タブを選択し、「リンク先」に以下のパスを入力します。

* 秘密鍵での認証の場合
~~~
"C:\Program Files (x86)\teraterm\ttermpro.exe" <ipアドレス> /ssh /auth=publickey /user=<ユーザ名> /passwd=<パスフレーズ> /keyfile=<秘密鍵のファイルパス>
~~~
* パスワード認証の場合
~~~
”C:\Program Files (x86)\teraterm\ttermpro.exe” <ipアドレス> /ssh /auth=password /user=<ユーザ名> /passwd=<パスフレーズ>
~~~
入力後、「OK」をクリックし、プロパティを閉じます。
![画像11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/bc45077d-3bed-0e4f-f8d9-c28e0eb9da84.png)

 **3. ショートカットから自動ログインができるか確認する**
デスクトップ上に作成したショートカットをダブルクリックしてTera Termを起動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/efb7d911-e508-8031-3ce1-96a75f944b27.png)
自動的にログインができていたら成功です。
![画像13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072173/1692c565-d5d4-237b-12cb-96d5c67457fd.png)

※TeraTermの最新版5.2の場合、TeraTermのフォルダ名がteraterm5に変更されているため、パスも以下の通りに変更する必要があります。
・TeraTermがあるフォルダ：C:\Program Files (x86)\teraterm5
・リンク先のexeファイルパス：C:\Program Files (x86)\teraterm5\ttermpro.exe

## おわりに
Tera TermでのSSH接続の設定を保存し、自動ログインする方法について紹介しました。
しかし、デスクトップから誰でもサーバーへのログインが可能になってしまうので、セキュリティ面でのリスクは意識しなければなりません。
したがって、サーバーを操作する機会が減りましたら、ショートカットを削除するのをおすすめします。
Vimを覚える【VIMATE 中級】

# はじめに

使えるだけでかっこいい「Vim」を覚えていきます！

# 覚え方
| コマンド | 機能 | 覚え方 |
| ---- | ---- | ---- |
| `f` `F` `t` `T` | 左右検索移動 | find 見つけて移動<br>till 直前まで移動<br>`/` `?` とごっちゃにならないように |
| `;` `,` | `f` `t`の繰り返し | <font color="LightGreen">暗記するんだ！</font><br> |
| `m` | 現在の位置をマーク | mark<br>`ma`などと入れると位置を記憶<br>`:a`でその場所に戻れる |
| `D` | 現在の位置から行末まで削除 | `d$` と同じ意味<br>`dd` 一行削除、とごっちゃにならないように |
| `J` `gJ` | 下の行と結合 | join<br>g ありだと空白なしの結合。 |
| `.` | コマンド繰り返し | `shell` の `.` （現在位置）的な。「今のやつ」的な |
| `U` | 変更の取り消し（行全体） | Undo<br>保存前の変更を取り消す |
| `:qa` `:qa!` | vimの終了 | quit all |
| `s` `S` | 文字の置き換えインサート | substitute 置換する |
| `ge` `gE` | 直前の単語の末尾へ移動 | 応用 |
| `%` | 対応するかっこにアクセス<br>（カーソルがかっこ上にないと無効） | <font color="LightGreen">暗記する！</font> |
| `ciw` `caw` `cis` `cas` `cip` `cap` | 置き換え | change [`inner`/`all`]  [`words`/`sentenses`/`paragraphs`]<br>`i`と`a`の差は、空白を含むかどうか |
| `ci"` `ci'` `ca"` `ca'` `cib` `cab` `ciB` `caB` `cit` `ciT` | `""` `''` `()` `{}` `<tag>`内を置き換え | 上に同じ。`b`は block `t`は tag |
| `diw`  `di"` ... | 削除バージョン | `d` delete |
| `yiw` `yi"` ... | コピーバージョン | `y` yank |
| `g~iw` `g~i"` | 小文字・大文字切り替え | `g~` トグル（<font color="LightGreen">暗記する！</font>）<br>`i` inner<br>`w` word |

# おわりに

初級編はすぐいけたけど、中級編は難しいですね。
`w`と`b`が対で、`e`と`ge`が対で・・・などなど、ぶっちゃけアレな組み合わせも多く、頭がこんがらがる。
実務で使い始めると早いのかなあ・・・
今のところは、直感的ではないなという印象が強いです。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Vim中級編<br><br>結果は...<br><br>回答率 : 95%<br>タイム : 119秒でした！<a href="https://twitter.com/hashtag/Vim?src=hash&amp;ref_src=twsrc%5Etfw">#Vim</a> <a href="https://twitter.com/hashtag/VIMATE?src=hash&amp;ref_src=twsrc%5Etfw">#VIMATE</a><br> <a href="https://t.co/K810x9O2eg">https://t.co/K810x9O2eg</a> <br><br>悔しい～！！寝て起きたら完璧なはず😴</p>&mdash; たま / RUNTEQ53A (@SamuraiStats) <a href="https://twitter.com/SamuraiStats/status/1758816289580314624?ref_src=twsrc%5Etfw">February 17, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
ローカル作成したリポジトリをリモートに「Push」するまで　※cloneしない場合

## 既存のディレクトリをgitリポにし、GitHubへpushする方法

普段GitHubに作成済みのリモートリポをローカルにcloneしていたので、
すでにローカルで作成済みのフォルダーをGitHubに登録を始めて行ったので備忘禄



## 参照URL

https://qiita.com/Futo_Horio/items/4d669f695680bc13d5fa

## git init するとなぜかmainではなくmasterブランチができてしまうので、設定方法
https://zenn.dev/kimizuy/articles/master-to-main
RaspberryPi Zero Wの無線監視カメラ



環境構築
>sudo apt install -Y cmake libssl-dev

ソース取得＆ビルド
>cd ~
>git clone https://github.com/mpromonet/v4l2rtspserver.git
>cd v4l2rtspserver
>mkdir build; cd build
>sudo cmake ..
>sudo make install
>echo ~/.profile

VLCを起動
>rtsp://<raspi-ip-address>:8554/unicast
TomcatをHTTPS化する方法

### 前提条件
すでにTomcatがインストールされいる状態

### 自己証明書の作成

Powershellを開く

以下のコマンドを実行し、自己証明書を作成
```Powershell
New-SelfSignedCertificate `
  -Type SSLServerAuthentication `
  -Subject "localhost" `
  -DnsName "localhost" `
  -KeyLength "4096"`
  -KeyExportPolicy Exportable `
  -NotAfter (Get-Date).AddYears(1)
```

「コンピュータ証明書の管理」を開く

上記で作成した証明書を右クリックし、「すべてのタスク」＞「エクスポート」を押下

「証明書のエクスポートウィザード」画面にて「はい、秘密キーをエクスポートします」にチェックオンする
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/c9df19a1-6b7c-cd5a-e9b3-ae48397871af.png">

「証明書のエクスポートウィザード」画面にてパスワードを入力する
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/47c9abac-4b84-d2c4-a374-f97e27934d3f.png" >

「証明書のエクスポートウィザード」画面にて証明書のエクスポート先を「＜Tomcatインストールフォルダ＞\conf」に設定する
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/8b3deae4-2ebd-1254-6af0-352d3e8a1e3a.png" >

### 証明書のバインド
「＜Tomcatインストールフォルダ＞\conf\server.xml」を開く

「server.xml」に以下を記載する

```xml
    <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true">
        <SSLHostConfig>
            <Certificate certificateKeystoreFile="証明書のフルパス"
                         certificateKeystorePassword="証明書をエクスポートした際に設定したパスワード"
                         type="RSA" />
        </SSLHostConfig>
    </Connector>
```

Tomcatを再起動する

### 動作確認
「ユーザ証明書の管理」を開く

作成した証明書を「信頼されたルート証明書機関」＞「証明書」に配置する
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/16511d32-2d0c-9236-7cc5-b72e571d513a.png" >

以下でアクセスする
https://localhost:8443/

以下の画面が表示されれば完了
<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/f39abf2a-8ad1-b3be-eaa8-38a424701732.png" >
指定の回数だけサイコロを振る

inputに振りたい回数分の数値を入れると、全ての出た目とその目が出た回数を表示します。

```html
<input type="number" id="throw-dices" placeholder="投げる回数">
<button id="dice-switch">サイコロを振る</button>
```

```js
const diceSwitch = document.getElementById('dice-switch')

diceSwitch.addEventListener('click', throwDice)

function throwDice() {
  const numInput = document.getElementById('throw-dices')
  let str = ''
  const array = []
  const resultThrowDice = [
    { 'value': 1, 'count': 0 },
    { 'value': 2, 'count': 0 },
    { 'value': 3, 'count': 0 },
    { 'value': 4, 'count': 0 },
    { 'value': 5, 'count': 0 },
    { 'value': 6, 'count': 0 },
  ]

  for (let i = 0; i < numInput.value; i++) {
    array.push(Math.floor(Math.random() * 6) + 1)
  }

  array.forEach((diceRoll, index) => {
    if (index === 0) {
      str = diceRoll
    } else {
      str += ` , ${diceRoll}`
    }

    resultThrowDice.filter((diceNum) => {
      if(diceNum.value === diceRoll){
        diceNum.count++
      }
    })
  });

  console.log(str);
  console.log(resultThrowDice);
}

// サイコロを1万回振った時の結果
// {value: 1, count: 1689}
// {value: 2, count: 1649}
// {value: 3, count: 1657}
// {value: 4, count: 1671}
// {value: 5, count: 1685}
// {value: 6, count: 1649}
```

### 参考

https://janken.asotetu.work/js_saikoro/
Qiita記事の見出し記事フォーマット

## この記事を読む前に見ておくべき記事
https://qiita.com/darcy-it/items/0d92a6c51d650130ebc2

## この文書を使うタイミング
- Qiitaの記事を書くとき（新規作成時）

## この文書の使い方
- 下記の黒背景のマークアップをコピペして、項目数を先に作る。

## Qiita記事の見出しフォーマット
・見出し2：17項目
・コピーは黒背景の右上をクリックする。

    ## 1. a
    ## 2. b
    ## 3. c
    ## 4. d
    ## 5. e
    ## 6. f
    ## 7. g
    ## 8. h
    ## 9. i
    ## 10. j
    ## 11. k
    ## 12. l
    ## 13. m
    ## 14. n
    ## 15. o
    ## 16. p
    ## 17. q
RSpecの導入方法（準備まで）

# 環境構築の手順
### ① Gemの追加
```:Gemfile
group :development, :test do
  ...
  # 以下追加
  gem 'rspec-rails'
  gem 'factory_bot_rails'
end
```

### ② RSpec用の設定ファイルを生成する
```
bundle exec rails g rspec:install
```
下記のようにファイルが作成される
```
 create  .rspec
 create  spec
 create  spec/spec_helper.rb
 create  spec/rails_helper.rb
```

### ③ テストを実行してみる
```
bundle exec rspec 
```
以下のような結果になれば、RSpecを利用する準備は完了。
テストファイルをまだ作成していないため、このように表示される。
```
No examples found.

Finished in 0.00026 seconds (files took 0.05634 seconds to load)
0 examples, 0 failures
```
[Angular/Ionic/Capacitor]アプリで3rdpartylicenses.txtの内容を表示する

アプリケーション開発でOSSを利用する時、多くの場合ライセンス表示が必要になります。
Angularでは、ビルド時に生成される`3rdpartylicenses.txt`（以降、「~.txt」）を利用することで簡単にライセンス表示を実現できます。
Angularに加えてIonic・Capacitorフレームワークを利用してモバイルアプリを開発する場合にもこのファイルを利用したかったのですが、Webアプリとは異なる方法で実装する必要があったためまとめました。

## Webアプリにおける3rdpartylicenses.txtの使い方
そもそもブラウザでアクセスするWebアプリにおいては、大きく2通りの実装方法があります。

### 1. 直接~.txtファイルのパスにアクセスさせる
Angularでは、`ng build --prod`を実行すると`dist/[プロジェクト名]`ディレクトリに~.txtが生成されます。
この状態でアプリをデプロイするだけで、`[URL]/3rdpartylicenses.txt`のURLでライセンス表示を公開することができます。
ただし、txtファイルにアクセスしているだけなので、当然一切スタイルの無いプレーンテキストで表示されます。
こちらは[angular.io](https://angular.io)の`3rdpartylicenses.txt`の例です。

https://angular.io/3rdpartylicenses.txt

### 2. ~.txtファイルの内容を読み込んでComponentに表示する
1.の発展形として、HttpClientで`[URL]/3rdpartylicenses.txt`の内容を取得してComponentに表示することもできます。
1.とは異なりスタイルなどのカスタマイズも可能です。
この方法はこちらの記事で紹介されていました。

https://qiita.com/kyosho/items/4d321dc5bf3593a0fd1c

## Ionic・Capacitor環境での実装

Ionic・Capacitorを利用したモバイルアプリでは、通常のWebアプリとは仕組みが異なるため、1.の方法も2.の方法もそのまま使うことができません。
ではどうするかというと、以下の方法を取ることで解決できました。

1. スクリプトを用意して、ビルド時に~.txtファイルをassetsディレクトリにコピーする
1. assets配下の~.txtファイルの内容を読み込んでComponentに表示する

順番に解説していきます。

### assetsディレクトリへのコピースクリプト

Ionicでは、~.txtファイルはwwwディレクトリ配下に生成されます。
そのままではAngularのコードから参照できないため、assetsディレクトリなどにコピーする必要があります。
今回は、プロジェクトトップに以下のようなコピースクリプトを用意します。

```javascript:copy-licenses.js
fs = require('fs');
path = require('path');
// Ionicでは~.txtはwwwディレクトリ配下に生成される
srcPath = path.join(__dirname, './www/3rdpartylicenses.txt');
// assets配下にコピーする
destPath = path.join(__dirname, './src/assets/3rdpartylicenses.txt');
fs.copyFileSync(srcPath, destPath);
```

次に、`package.json`内のビルドコマンド部分を修正して、ビルドで~.txtが生成された直後にコピースクリプトが呼ばれるようにします。

```json:package.json
  "scripts": {
    "build": "ionic build && node copy-licenses.js",
    "buildprod": "ionic build --prod && node copy-licenses.js"
  }
```

何かライブラリを追加した時、ビルドすることによって~.txtファイルが再生成され、そのライブラリのライセンス表記も追加されます。
ビルドの度にコピースクリプトを走らせることで、ライセンス表記の追加漏れを防ぐことができます。

### Componentへの表示

ミニマムな実装で、ライセンスページにファイルの中身を表示していきます。
assets配下のリソースはHttpClientで読み込めるので、まず~.txtファイルの内容を変数に読み込みます。

```typescript:license.page.ts
export class LicensePage {
  private httpClient = inject(HttpClient);
  // ~.txtファイルの中身を変数に読み込む
  licenses$ = this.httpClient.get(
    'assets/3rdpartylicenses.txt',
    {responseType: 'text'}
  );
}
```

licenses$は`Observable<string>`型のため、`async`パイプをかませて`pre`タグの中に表示します。

```html:license.page.html
<!--ion-headerは省略-->
<ion-content [fullscreen]="true" class="ion-padding">
  <pre
  style="white-space: pre-wrap; word-wrap: break-word; overflow-wrap: break-word">
    {{ licenses$ | async }}
  </pre>
</ion-content>
```

`pre`タグに表示しているだけなのでシンプルな見た目ですが、これでライセンス表示を実装することができました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/732477/8a4dde2d-9705-cdef-32d0-ca6a76511c15.png" width="50%">

### おまけ
~.txtファイルの中身は一定の規則性に沿ってライセンス表記が並んでいるので、適宜パースして扱うことも可能です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/732477/8e365b67-a8e2-bc2c-cf47-252d778df064.png" width="50%>
Windows上に最新バージョンでないTomcatをインストールする方法

### 事前準備
以下のURLでJDKをダウンロードする
https://www.oracle.com/java/technologies/downloads/

上記でダウンロードしたファイルを使用し、JDKをインストールする

今回は以下のフォルダに置きます。
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/a979d85a-fe7f-311c-075e-37d7245b5c7f.png" >

### Tomcatのダウンロード
以下のURLからにアクセスする
https://tomcat.apache.org/


ナビゲーションウィンドウ＞「Download」＞「Archives」を押下
<img width=200 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/d1fe7409-2157-1ea0-c228-53b5499badcc.png" > 

今回は「9.0.54」が欲しいので「tomcat-9/」を押下
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/8317a258-252a-7aa6-68d1-31a5e426bf12.png" >

「v9.0.54/」を押下
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/3b568ade-c658-dce1-59a7-7f6d940a876b.png" >

「bin/」を押下
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/489df960-a009-d8ec-23cd-436ad8999778.png" >

「apache-tomcat-9.0.54.exe」を押下し、ダウンロード
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/ad5e999a-bd36-6b2e-2d2d-e53ab52b8440.png" >

### Tomcatのインストール
ダウンロードしファイルを開き、インストール

以下の画面にて、上記でインストールしたJDKのパスを設定する
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/1abfc86a-396e-bee2-85ee-7c8c8d95efad.png" >

今回はいかにTomcatを「C:\Program Files\Apache Software Foundation\Tomcat 9.0」に配置する
<img width=300 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/778d2f26-22e1-e3ff-5f40-d58430b207cb.png" >

### 動作確認
インストールが完了したら以下でアクセスする
http://localhost:8080/

以下の画面が表示されれば成功
<img width=400 src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3666448/da7b0bf5-4cc1-087f-5f6b-90e4d0cee933.png">
CloudFront FunctionsでBasic認証を行いアクセスを制限する

<h2>はじめに</h2>
CloudFront経由でS3に格納されているReactアプリにアクセスする際、<br>
Basic認証を行うように実装していきます！ 

<h2>Basic認証を行う関数の作成</h2>
まずはCloudFront FunctionsでBasic認証を行う関数を作成してきます。
CloudFrontから関数を選択して「関数を作成」をタップします。

![スクリーンショット 2024-02-17 17.26.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689588/857588e7-2774-032b-81ae-5c232627cd73.png)

続いて関数名を入力して以下のような設定で関数を作成します。
今回はBasic認証を行う関数と分かるように「Basic-Authentication」にしています。
関数名入力後は「関数を作成」をタップしたら関数が作成されます🎉

![スクリーンショット 2024-02-17 17.26.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689588/a48f896a-892a-fcbf-5525-4872a378dc8c.png)

<h2>Basic認証を実装する</h2>

CloudFront>関数>Basic-Authenticationの構築>関数コード で関数の処理を実装していきます。
Basic認証を行う処理は以下になります。

```ruby:Basic-Authentication
function handler(event) {
    var request = event.request;
    var headers = request.headers;

    // ID:Password の文字列をBasic64でエンコードした文字列を設定する
    var authString = "Basic dGVzdDp0ZXN0";
    
    if (
        typeof headers.authorization === "undefined" ||
        headers.authorization.value !== authString
    ) {
        return {
            statusCode: 401,
            statusDescription: "Unauthorized",
            headers: { "www-authenticate": { value: "Basic" } }
        };
    }
    return request;
}
```

Basic認証ではリクエストのAuthorizationヘッダの値に「Basic」の文字+スペース+「ユーザー名とパスワードから生成した認証情報」を設定する決まりになっています。
そのため関数の処理ではその決まりに則りAuthorizationヘッダの値が期待する値かどうかを判定する実装にする必要があります。
今回の実装では「ユーザー名とパスワードから生成した認証情報」は「ユーザー名:パスワード」の文字列をBase64でエンコードした文字列を設定するような想定で実装します。

今回はユーザー名とパスワードは両方「test」で認証しようと思うので、
authStringには「Basic」+スペース+「test:test」をBase64でエンコードした文字列が設定されています。

```
if (
    typeof headers.authorization === "undefined" ||
    headers.authorization.value !== authString
)
```
ではAuthorizationヘッダが存在しなかったりBasic認証を行った際にユーザー名とパスワードが両方「test」でなかった場合は401を返すようにしています。
上記に当てはまなければ問題ないため、requestを通すためにrequestをreturnしています。


<h2>CloudFrontへの紐付け、動作確認</h2>
関数作成後、作成した関数を公開していきます。
CloudFront>関数>Basic-Authentication の発行から「関数を発行」をタップして関数を公開してします。

![スクリーンショット 2024-02-17 17.35.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689588/0dae9213-32de-7087-5f22-18203b5629f8.png)

続いて作成した関数とCloudFrontのディストリビューションを紐付けます。
CloudFront>ディストリビューション からBasic認証を行いたいディストリビューションを選択します。
その後ビヘイビアを選択し、関数の関連付けで以下のように設定してください。
今回はリクエストに対して関数の処理を行いたいため、ビューワーリクエストに作成した関数を紐づけています。
![スクリーンショット 2024-02-17 18.21.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689588/13ed7c80-19b9-7d4e-7445-617ceda9dfc6.png)

最後にCloudFrontのURLへアクセスし、以下の表示になれば実装成功です🎉

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3689588/fc3995e6-f565-4880-1c50-b65b823b0662.png" width="300">
Qiita記事で見出し番号（項目数）を最大17までにする理由

## 1. a：最後までスクロールするとわかる
## 2. b
## 3. c
## 4. d
## 5. e
## 6. f
## 7. g
## 8. h
## 9. i
## 10. j
## 11. k
## 12. l
## 13. m
## 14. n
## 15. o
## 16. p
## 17. q
## 18. r
## 19. s
## 20. t
## 21. u
## 22. v
## 23. w
## 24. x
## 25. y
## 26. z
## 答え
- 17項目
## 理由
 - 右の目次が見れる最大数だから

![2024_0217_1827-s14-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632065/75e47087-a810-f935-796a-90dc2baecc62.png)

 - 目次にマウスポインタを合わせて、マウスのトグルボタンで上下移動できるが見る側にひと手間かかる。
 - その機能があるか知らない人もいる
ご挨拶

はじめまして、えごまと申します。
ご挨拶を兼ねて、初めて記事を作成しました。

Zennを少し使ってみましたが、Qiitaにも興味があったので。

# 自己紹介

学生時代にC++、C#、Javaでオブジェクト指向に触れました。
社会人になってからは、SI系企業、ネットメディア企業、ゲーム企業のエンジニアとして従事。

SI系企業ではオンプレ環境でサーバー構築、C++、Javaを経験させて頂きました。
Webエンジニアに転向してからはバックエンド、フロントエンド両方を担当しました。

バックエンドはPHPに偏ってしまいましたが、経験したPHPフレームワークはCodeigniter、FuelPHP、Laravelです。

フロントエンドはHTML、CSSを使用したデザインをはじめ、javascript、jQuery、Vue.jsを経験しました。

10年ほど前に、仕事外でローカルにLAMP環境を構築してWebエンジニアを目指しました。
今はWSL+DockerComposeをメインに使っています。

# 活動目的

技術的な守備範囲を広めることが主な目的です。

ローカルでの学習はモチベーションになりづらく。
アウトプットを意識せずにインプットを繰り返しても身になりづらいなと。
これまでも、そういった思いが錯綜していました。

どうせなら発信も兼ねて活動していこうと思い、立ち上げてみました。
Microsoft Power Platform(PL-900)に無料の教材で合格するための勉強法

PL-900の試験に無事に合格したので備忘録的に記事を投稿します。
本記事の内容は2024年2月時点での情報ですので今後改訂される場合があります。
(2023年12月17日改定済み)

# 結論
### [PL-900 : Microsoft Power Platform Fundamentals 試験対策](https://info.microsoft.com/JA-PowerApps-WBNR-FY21-05May-03-MKTOFY21PL900PrepSessionOndemandWebinar-SRDEM73329_LP02OnDemandRegistration-ForminBody.html)に登録して勉強しよう！
上記に登録すると登録したメールアドレス宛てにウェビナー形式のビデオ講座のリンクやスライド資料が送付されるのでそれを基に勉強しましょう。
模擬問題とほとんど同様の問題ばかり出るので最悪暗記しても良いです。
もちろん用語の意味や手法などを理解したほうが良いです。

# 本文
上記結論で物足りないという人は本文以下も見てもいいですが、蛇足です。
~~先人のパクリです~~

## 受験した経緯
弊社の社内での認定に向けて手っ取り早く取れそうなのがPL-900だったため
ちなみに筆者はAZ-900など他のMicrosoft系資格取ってません

## 試験概要
問題数 : 36問
時間 : 45分
合格点 : 700／1000

## 解答方法
選択問題（はい／いいえ）※１問の中で複数問題あり
複数選択問題（コンボボックス型／ラジオボタン型）
ドラッグアンドドロップ問題

## 試験範囲
Microsoft Power Platform のビジネス価値を説明する (20–25%)
Microsoft Power Platform の基本コンポーネントを特定する (10 - 15%)
Power BI の機能を実証する (10 - 15%)
Power Apps の機能を実証する (20 - 25%)
Power Automate の機能を実証する (15 - 20%)
補完的な Microsoft Power Platform ソリューションを説明する (15 - 20%)

## 受験に向けて筆者がやったこと
#### 0.PL-900の受験申込をする
https://learn.microsoft.com/ja-jp/credentials/certifications/exams/pl-900/
これは忘れないでやってください。ギャグのようですが真面目に書いています。
特にテストセンターでやる場合は空いている日にちが限られてくるので、試験の日にちを決めてから勉強するようにしましょう。
筆者はオンラインでの準備がめんどくさいと聞いたのでテストセンターで受けました。

#### 1. [PL-900 : Microsoft Power Platform Fundamentals 試験対策](https://info.microsoft.com/JA-PowerApps-WBNR-FY21-05May-03-MKTOFY21PL900PrepSessionOndemandWebinar-SRDEM73329_LP02OnDemandRegistration-ForminBody.html)に登録する
冒頭の結論部分でも記載しましたが、**これは必ずやりましょう。**
単純にPower Platform全体の知識を理解できるようになりますし、模擬問題による学習もできます。ビデオ講座は240分弱あるので急いでいる方やちょっとかじっている人はスライドでの学習でも十分かもしれません。
注意点として以下記載のものがあります
```
・Common Data Serviceでの記載になっている(現在はMicrosoft Dataverse)
・上記に伴って一部用語の変化
・模擬問題部分で解答が記載されていなかったり、問題と解答が同時に出ていたりする
```

#### 2.[PL-900のプラクティス評価](https://learn.microsoft.com/ja-jp/credentials/certifications/exams/pl-900/practice/assessment?assessmentId=34&assessment-type=practice)をひたすらやる
PL-900における模擬試験のようなものです。
上記リンクでうまくページにたどり着かない方は[PL-900のページ](https://learn.microsoft.com/ja-jp/credentials/certifications/exams/pl-900/)から**無料の練習用評価を受ける**というリンクをクリックしてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660314/fa5b9865-c704-392f-8ee6-fc8969d448ed.png)
内容としてはPL-900に関連するものがランダムに50問出題されます。
解答時に回答内容を確認することができ、Microsoft Learnのページなどをリンク付きで解説してくれるのでわかりやすいかと思います。
こちらはCommon Data Serviceではなく**Microsoft Dataverse**表記になっております。

## 試験当日
#### 問題について
問題文が長ったらしく書いてあったりしますが、下の方に機能要件などが書いてあるのでそんなに注意深く見る必要はないと思います。
機能要件や選択肢で引っかかったら見ても良いかもしれません。
急に知らない用語が出てきたりしても焦らずに解答しましょう。
消去法だったり用語の意味を考えれば案外いけます
問題を見直すでチェックができるので自信がない問題などはあとで確認しやすいようにチェックしておくのが良いかと思います。

#### その他
テストセンターの場合は身分証明書を持っていけばいいので手ぶらでも大丈夫です。
ティッシュの貸出もしているテストセンターもあるので借りたい人は借りましょう

## まとめ
試験対策講座は優秀なので基本はこれを軸にやっていきましょう。
勉強法について上記に記載したもの以外としてUdemyなどで学習するのも手だとは思います。~~(筆者はケチなのでやりませんでした)~~
会社から教材やお金を支給されているなら是非ともやったほうが良いと思います。

これから受験予定の方のお役に立てればと思います。
DXライブラリの初期化と終了

# はじめに
DXライブラリを導入してから最初に書くべきプログラムと注意点を紹介します。なお、DXライブラリの導入は[公式サイト](https://dxlib.xsrv.jp/)で詳しく解説されていますので、そちらをご覧ください。

# 開発環境
- Windows11
- Visual Studio 2022
- DXライブラリ Ver3.24d

# 最小限のプログラム
以下のプログラムが初期化から終了までのプログラムになります。このプログラムを入力してエラーが発生する場合、導入に不備がある可能性が高いので確認してください。

```cpp
#include "DxLib.h"
 
int WINAPI WinMain( _In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _In_ LPSTR lpcmdLine, _In_ int nCmdShow )
{
    // DXライブラリの初期化
    if( DxLib_Init() == -1 )
    {
        // -1ならエラーとしてゲーム終了
        return 0;
    }
 
    // DXライブラリの破棄
    DxLib_End();

    return 0;
}
```

## インクルード
```cpp
#include "DxLib.h"
```
`"DxLib.h"`はDXライブラリを使用するなら必須のインクルードになります。導入に不備があると、ここでエラーが発生することが多いので、戻って確認してみましょう。

## DXライブラリの初期化
```cpp
    // DXライブラリの初期化
    if( DxLib_Init() == -1 )
    {
        // -1ならエラーとしてゲーム終了
        return 0;
    }
```
`DxLib_Init`関数はDXライブラリを使用可能な状態にする関数で、プログラム中に１回は必ず呼び出さなければなりません。この関数を呼び出さないと他のDXライブラリの関数が使えない（失敗する）ので、なるべく早い段階で呼び出してください。

DxLib\_Init関数は失敗すると戻り値で -1 を返します。これに失敗した時点でゲームの起動は諦めたほうがよいのでエラーとして処理しましょう。

### DxLib_Init関数が失敗する
滅多にありませんが、DxLib\_Init関数で初期化に失敗することがあります。DXライブラリではこの失敗した原因を`GetLastErrorCode`関数で調べることができます。

```cpp
// DXライブラリの初期化
if( DxLib_Init() == -1 )
{
    // エラーの原因を調べる
    int error = GetLastErrorCode();

    // 戻り値で受け取ったエラーコードで分岐
    switch( error )
    {
        // 分岐例
        case DX_ERRORCODE_WIN_DESKTOP_24BIT_COLOR:
            // デスクトップが２４ビットカラーモードだった
            break;
    }

    return 0;
}
```
エラーの原因は以下の８パターンしかないそうです。

| エラーコード | 説明 |
|:-:|:-:|
| DX_ERRORCODE_WIN_DESKTOP_24BIT_COLOR | デスクトップが２４ビットカラーモードだった |
| DX_ERRORCODE_WIN_DOUBLE_START | 二重起動 |
| DX_ERRORCODE_WIN_FAILED_CREATEWINDOW | ウィンドウの作成に失敗 |
| DX_ERRORCODE_WIN_FAILED_ASYNCLOAD_CREATE_THREAD | 非同期読み込み処理を行うスレッドの立ち上げに失敗 |
| DX_ERRORCODE_WIN_FAILED_CREATE_DIRECTDRAW7 | DirectDraw7の取得に失敗 |
| DX_ERRORCODE_WIN_FAILED_INITIALIZE_DIRECTDRAW7 | DirectDraw7の初期化に失敗 |
| DX_ERRORCODE_WIN_NOT_COMPATIBLE_SCREEN_COLOR_MODE | 非対応の画面カラーモードが指定された |
| DX_ERRORCODE_WIN_FAILED_CHANGE_DISPLAY_SETTINGS | Win32API の ChangeDisplaySettings を使用した画面モードの変更に失敗 |

ほとんどの場合は二重起動が原因であることが多いので、特に理由がなければ詳細なチェックは省略してよいと思います。二重起動していないのに失敗するようなことがあれば確認してみてください。

## DXライブラリの終了
```cpp
// DXライブラリの使用を終了する
DxLib_End();
```
`DxLib_End`関数はDXライブラリの使用を終了するときに呼び出す関数で、基本的にはプログラム終了直前で呼び出します。呼び出さなくても見た目上問題がなさそうに見えますが、DXライブラリは内部で様々な処理を行っているため、潜在的な不具合が残る可能性があります。確実に呼び出すようにしましょう。

:::note
DxLib\_End関数にも戻り値があり、失敗すると -1 が返ってきます。ただし、失敗することはほぼないので、戻り値を無視しても通常は問題ありません。
:::

このプログラムを実行すると画面が一瞬暗転します。これはゲームがフルスクリーンモードで起動されるためで、現在は初期化を行ってすぐに終了しているため問題ない動作となります。

# 参考
- [DxLib_Initが失敗した理由](https://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4072)
Vscodeとdevcontainerで実現する簡単Python環境構築

サクッとPythonの実行環境を整えたい時、ありますよね。でも、ローカル環境をいじりたくないという気持ちも分かります。
「そんなときには、devcontainerを使ってみませんか？」
devcontainerは、環境の一貫性を保ちながら、チームメンバー間での開発環境の共有を容易にするツールです。
今回は、データ分析で頻繁に使用されるPandasライブラリを含むPythonの開発環境の構築方法をご紹介します。
## 開発環境
- WSL Ubuntu 22.04.3 LTS
- Visual Studio Code(Vscode)
- Docker Desktop

## 前提
Docker DesktopとVscodeが既にセットアップされていることが前提です。
まだの方は、公式サイトからダウンロードし、基本的な初期設定を行ってください。
また、VscodeでのRemote - Containers拡張機能のインストールが必要です。これにより、Vscodeから直接コンテナ内で作業を開始できます。

## 目標
Pandasライブラリを使用できるPythonの開発環境をDev Containersを通じて構築します。
## 手順
- Docker Desktopを起動する
- ローカルの任意のディレクトリに作業ディレクトリを作成する
- Vscodeのコマンドパレットからコンテナを作成する
- pandasのインポート

### Docker Desktopを起動する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/d3311687-5da7-3360-fe02-30b940ba40db.png)
### ローカルの任意のディレクトリに作業ディレクトリを作成する
今回は`workspace/`以下に作業ディレクトリを作成していきます。
```bash
mkdir python-playground
```
次に作成した作業ディレクトリに移動します。
```bash
cd python-playground
```
移動したらVscodeを起動しましょう。
```bash
code .
```
### Vscodeのコマンドパレットからコンテナを作成する
「Show and Run Commands」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/0270a163-ce4b-52ec-da68-381f54f4f2eb.png)
次に「Dev Containers: Open Folder in Container」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/1a32af47-bd38-23bc-d272-3bc880a0dad4.png)
現在のディレクトリが選択されていると思うので、そのまま「OK」を押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/d1b11685-d463-6f6a-19b8-8fe9a2812534.png)
次に言語の選択をしていきます。
言語としてPython3を、バージョンは3.12を選択します。ここで、特に追加機能は指定せずに進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/e480a7a3-8ee7-2866-c33f-e7aa6cc88061.png)
バージョンは今回3.12を使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/ef4dd67c-ae50-6d0d-22a5-a06d7d379594.png)
今回は追加機能を特に指定せず、そのまま「OK」を押します。
少し時間がかかりますが、コンテナが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/648a841e-2faa-3548-6d90-b82c8df3d688.png)
Vscode左下の表示が「開発コンテナー」となっていることを確認します。
ターミナルを開き、Pythonのバージョンを確認してみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/dd6ff7be-feb9-8a1c-29f4-fd9ce2d06af8.png)
これでPythonの環境構築完了です！
簡単ですね。
### Pandasのインポート
`devcontainer.json`に`"postCreateCommand": "pip install pandas"`を追加し、コンテナの再構築を行います。これで、Pandasがインストールされます。
```json:devcontainer.json
...
"postCreateCommand": "pip install pandas"
...
```
構成ファイルを編集したので、右下のボタンを押して「Rebuild」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/dd9e4594-c563-9d52-2823-76499e98fade.png)
最後に、Pandasを使ってCSVファイルを読み込む簡単なスクリプトを作成し、動作確認を行います。
`sample.csv`ファイルを準備し、以下のようなスクリプトで読み込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/642155/01048b3e-a148-a6b7-d844-2394ddb68818.png)
ちゃんと実行できていますね。
実行したスクリプトは以下です
```python:main.py
import pandas as pd

def read_and_print_csv(file_path):
    df = pd.read_csv(file_path)
    print(df)

if __name__ == "__main__":
    file_path = 'sample.csv'
    read_and_print_csv(file_path)
```
## まとめ
devcontainerを使用することで、Vscodeで数回クリックするだけで、必要な実行環境を素早く簡単に構築できます。
この方法は、Pythonだけでなく、他の言語やフレームワークにも適用可能です。
いろいろ試してみたいですね！
pandasのデータ構造について

# pandasのデータ構造について
### 慣れるべきふたつのデータ構造
シリーズ（Series）とデータフレーム(DataFrame）
---
## 1.Series
`obj = pd.Series([4,7,-5,3])`

```
0    4
1    7
2   -5
3    3
dtype: int64
```
値に関連づけられたインデックスというデータラベル配列が含まれる。
値にアクセスしたい場合は、values属性を使う。
`obj.values`

```
array([4, 7, -5, 3])
```
インデックス属性を使うと
`obj.index`

```
RangeIndex(start=0, stop=4, step=1)
```

のように返ってくる。そして、インデックスは指定できる。

```
obj2 = pd.Series([4,7,-5,3], index=['d', 'b', 'a', 'c'])
```

## 2.DataFrame
csvを読み込んだりするときに使う。

```
data = {'year':[2010, 2011, 2012, 2013],
        'month':['Jan', 'Fev', 'Mar', 'Apr']}
df = pd.DataFrame(data)
```
||||
|:--|:--|:--|
|| year | month |
| 0 | 2010 | Jan |
| 1 | 2011 | Fev |
| 2 | 2012 | Mar |
| 3 | 2013 | Apr |

こんな感じに配置される。
教師あり学習　分類と回帰

## データの前処理
### 二値化
##### 数値を0か1に変換すること。
- numpyをimport -> 配列を作成
- sklearnからpreprocessingをimport -> Binarizer()を使って、二値化
- 閾値はthresholdで設定

### 平均値
##### 特徴ベクトルから平均を引くと、特徴量の中心が原点になる。特徴ベクトルからバイアスを除去できる。
- メソッドmean()は平均値を表示
- メソッドstd()は標準偏差を表示

### スケーリング
##### 特徴量の値を訓練できる水準までスケーリングすることが大事。
- MinMaxScaler()オブジェクトを生成
- fit_transform()メソッドで最大値、最小値に収まるようにスケーリング

### 正規化
##### 特徴ベクトルを共通的な尺度に揃えること。
- L1正規化　要素の絶対値の和が1になるようにする。こちらがロバスト
- L2正規化　要素の自乗の和が1になるようにする

### ラベルのエンコーディング
##### ラベルを単語から数字に変換する。

- scikit-learnではラベルが数字である必要がある
- 単語ラベルを数字に変えるにはラベルのエンコーダを用いる
- LabelEncoder()オブジェクトを生成して訓練する
- transform()メソッドで数字変換、inverse_transform()メソッドで単語ラベルに戻る
ベクトル線図とフィードバック制御

# はじめに
ベクトル線図（ナイキスト線図）は制御対象が安定かどうかを判定するのに使用される。具体的には、角速度ωを変化させたときにおいて、周波数伝達関数の実部を横軸に、虚部を縦軸にしたものである。一方でフィードバック制御とは出力の信号を入力に反映させることにより対象物を制御するという方法である。今回は、電験3種令和4年度機械問15の問題をPythonを用いて解くことにより、フィードバック制御とベクトル線図の理解を深めることを目的とする。

# 問題設定
K=5,T=0.1として以下のような系のループを考える。

![feedback.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/d71918f1-f486-38c1-1510-91c2a1d1d417.jpeg)
# プログラム
この場合のベクトル線図を描写するプログラムは以下のように表すことができる。


```python seigixyo.py

import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
omega = np.arange(0.0, 10000.0, 0.001)

K=5
T=0.5
#伝達関数から周波数伝達関数への変換
s=1j*omega
#制御対象
G1=1/(s*T)

#伝達関数G（s）→G(jω)
#フィードバック制御
G=(K*G1)/(1+K*G1)
x=G.real
y=G.imag

plt.title("一次遅れ系のベクトル線図")
plt.xlabel('実軸')
plt.ylabel('虚軸')

plt.plot(x, y, 'b-')
plt.show()


```

これを実行した場合、以下のようなグラフが表示される。

![一次遅れ系のベクトル線図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/264ad55c-66b8-3d46-fa26-182a258fd70c.png)

このように、一次遅れ系のベクトル線図は半円状になる。これは導出も含めて押さえておいた方がいいだろう。
# 手計算による解析
この半円について手計算で伝達関数から導出してみよう。
まずは、負のフィードバックより周波数伝達関数は以下のように表すことができる。

```math
G(j\omega)=\frac{K\frac{1}{j\omega T}}{1+1\cdot K\cdot  \frac{1}{j\omega T}}=\frac{K}{K+j\omega T}
```
これを有理化する。

```math
G(j\omega)=\frac{K}{K+j\omega T}=\frac{K(K-j\omega T)}{(K+j\omega T)(K-j\omega T)}=\frac{K^2}{K^2+(\omega T)^2}-j\frac{\omega TK}{K^2+(\omega T)^2}
```

ここで、


```math
\begin{equation}
  \left\{ \,
      \begin{aligned}
      & X = \frac{K^2}{K^2+(\omega T)^2} (>0)\\
      & Y = -\frac{K\omega T}{K^2+(\omega T)^2}(<0)\\
      \end{aligned}
  \right.
  \end{equation}
```
ここで、Y/Xを求めると以下のようになる。
```math
\frac{Y}{X}=-\frac{\omega  K}{K}
```
ゆえに、
```math
(\omega T) =-\frac{Y}{X}K
```

この式をXの式に代入すると以下のようになる。
```math
X=\frac{K^2}{K^2+(\frac{Y}{X})^2 K^2}=\frac{1}{1+(\frac{Y}{X})^2}
```

これを整理すると以下のようになる。
```math
(X-\frac{1}{2}^2)+Y^2=(\frac{1}{2})^2
```

ゆえにこれは、半円を表すが、TとKの値に依存しないところが興味深いところである。

# まとめ
一次遅れ系の伝達関数のベクトル線図についてプログラミングを用いて描写することができるか今回は試みた。結果として、Pythonの複素数機能を用いれば上手く描写することができるということが分かった。なので、今回はある制御対象を負のフィードバックにした場合の特性を調べるために、ベクトル線図を用いた。このように、ベクトル線図は安定性や周波数特性を調べることができるので、電験を受ける方はぜひとも押さえておきたいところである。

# 参考文献
https://denken-ou.com/kikair4-1-15/
μT-Kernel3.0 BSP環境を Raspberry pi picoで構築した際の変更点

※あくまでも、自分が試した時の話
# 対象
https://github.com/tron-forum/mtk3_bsp/tree/master/docs/
uTK3bsp_pico_man_jp.pdf
※USER_NAMEは、現在ログイン中のユーザー名に置き換えること。

### ２．開発環境の準備
(1)https://xpack.github.io/dev-tools/arm-none-eabi-gcc/install/
Manual installを参照
展開先の例
C:\Users\USER_NAME\AppData\Roaming\xPacks\arm-none-eabi-gcc\xpack-arm-none-eabi-gcc-12.2.1-1.2

(2)https://xpack.github.io/dev-tools/windows-build-tools/install/
Manual installを参照
展開先の例
C:\Users\USER_NAME\AppData\Roaming\xPacks\windows-build-tools\xpack-windows-build-tools-4.4.0-1

### Eclipseでクロスコンパイラが見つからない場合の設定例
Arm Toolchains Paths
 C:\Users\USER_NAME\AppData\Roaming\xPacks\windows-build-tools\xpack-windows-build-tools-4.4.0-1\bin
 
Build Tools path
 C:\Users\USER_NAME\AppData\Roaming\xPacks\arm-none-eabi-gcc\xpack-arm-none-eabi-gcc-12.2.1-1.2\bin

### includeファイルが見つからない場合
ソースのフォルダをworkspace内にコピーしてからimportで以下を指定する。
C:\Users\USER_NAME\eclipse-workspace\mtk3_bsp-pico_rp2040

### デバッグ
Projectの欄で、Browse...を押して「mtk3bsp_pico_rp2040」を指定

### ビルドファイルの所在
C:\Users\USER_NAME\eclipse-workspace\mtk3_bsp-pico_rp2040\Debug\mtk3_bsp-pico_rp2040.elf

### OpenOCD
MSYS2で作成したOpenOCDのバイナリはeclipseから叩いても起動しない。そこで、Windows向けのバイナリのOpenOCDを導入する。
https://xpack.github.io/dev-tools/openocd/
Manual install
releaseのページから選ぶ。以下一例
https://github.com/xpack-dev-tools/openocd-xpack/releases/download/v0.12.0-3/xpack-openocd-0.12.0-3-win32-x64.zip

### run Configurationsの設定
・Executable Path のデフォルトで入っている環境変数は設定しても機能しないので、Browseで直接、実行ファイル(openocd.exe)のパスを設定する。
・オプションは、以下の様に設定する(下記pdfのAppendix.A)。
-f interface/cmsis-dap.cfg -c 'adapter speed 5000' -f target/rp2040.cfg　-s tcl

//旧 -f interface/cmsis-dap.cfg -c 'adapter speed 5000' -f target/rp2040.cfg -s ../share/openocd/scripts

### 参考
getting-started-with-pico.pdf　build-date: 2023-06-14