OmniAICreator/Qiita-1.07M huggingface dataset:
【Python】二次元リストの初期化にはリスト内包表記を使う

paizaを触って1か月、レート2000に到達しました。
実装言語にはPythonを使っていたのですがこの機会にいくつか備忘録を残します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194558/e7a074f2-0a61-149e-d680-56a51d72956e.png)

:::note info
使用言語：Python 3.11.2
:::



# 結論
多次元リストの初期化にはリスト内包表記を活用する
```python3
[[0]*3 for _ in range(4)]
```
:::note info
Python Documentation contents にて同内容の説明が掲載されている
https://docs.python.org/ja/3/faq/programming.html#how-do-i-create-a-multidimensional-list

※ コメントにてご教示いただきました。ありがとうございます。
:::

また明確な意図がない限り下記表現は使わない
```python3
[[0]*3] * 4
```

## サンプル（OKパターン）
4×3サイズの0埋めリストを初期化する場合
```python3:test.py
# 二次元リストnizi_listの初期化
ROWS,COLUMNS=4,3
nizi_list = [[0]*ROWS for _ in range(COLUMNS)]
print("■nizi_listの初期化後の中身");print(*nizi_list, sep='\n');print()

# 各リストのオブジェクトIDの確認
print("■nizi_listの各リストのオブジェクトIDの確認")
for i in range(COLUMNS):
    print("nizi_list[%d]のオブジェクトID: %d"%(i,id(nizi_list[i])))
print()

# 二次元リストnizi_listの要素の変更
nizi_list[0][1] = 1
print("■nizi_list[0][1]の値変更後の中身");print(*nizi_list, sep='\n');print()
```
```:実行結果
■nizi_listの初期化後の中身
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]

■nizi_listの各リストのオブジェクトIDの確認
nizi_list[0]のオブジェクトID: 1936982372288
nizi_list[1]のオブジェクトID: 1936982416256
nizi_list[2]のオブジェクトID: 1936982411712

■nizi_list[0][1]の値変更後の中身
[0, 1, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]
```


## サンプル（NGパターン）
4×3サイズの0埋めリストを初期化する場合
```python3:test.py
#二次元リストnizi_listの初期化
ROWS,COLUMNS=4,3
nizi_list = [[0]*ROWS] * COLUMNS
print("■nizi_listの初期化後の中身");print(*nizi_list, sep='\n');print()

#（以下略）
```
```:test.py実行結果のログ
■nizi_listの初期化後の中身
[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 0, 0, 0]

■nizi_listの各リストのオブジェクトIDの確認
nizi_list[0]のオブジェクトID: 2893548518592
nizi_list[1]のオブジェクトID: 2893548518592
nizi_list[2]のオブジェクトID: 2893548518592

■nizi_list[0][1]の値変更後の中身
[0, 1, 0, 0]
[0, 1, 0, 0]
[0, 1, 0, 0]
```

:::note warn
- <font color="#ff3030">`nizi_list[0][1]` のみ代入したつもりが `nizi_list[1][1]`と`nizi_list[2][1]` にも反映された</font>
  - これは `nizi_list[0]` ～ `nizi_list[2]` が全て<b>同オブジェクト</b>として定義されたため
  - オブジェクトIDはid関数を用いることで参照可能
:::
【ES Modules】Cloud Functionsでrequire()ではなくimportを使う【index.mjs】

# `type: module`を使う場合
```json:package.json
{
  "name": "sample-http",
  "type": "module",
  "version": "0.0.1"
}
```

```javascript:index.js
/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
export const helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!'
  res.status(200).send(message)
}
```

# `index.mjs`を使う場合

コンソールエディタでシンタックスハイライトがきかないので、あまりオススメはしません

```json:package.json
{
  "name": "sample-http",
  "main": "index.mjs",
  "version": "0.0.1"
}
```

```javascript:index.mjs
/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
export const helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!'
  res.status(200).send(message)
}
```

# Puppeteerを使った例

Node.js 16を選択し、メモリを2GB以上にしましょう

https://qiita.com/7mpy/items/3ffc7974a46a82ec1f8e

```json:package.json
{
  "name": "sample-http",
  "main": "index.mjs",
  "version": "0.0.1",
  "dependencies": {
    "puppeteer": "^19.7.5"
  }
}
```

```javascript:index.mjs
import puppeteer from 'puppeteer'

/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
export const helloWorld = async (req, res) => {
  await puppeteer.createBrowserFetcher().download(puppeteer.defaultBrowserRevision)
  const browser = await puppeteer.launch()
  const page = await browser.newPage()
  await page.goto('https://example.com/')
  res.send(await page.content())
  await browser.close()
}
```
Render.comにRailsアプリをデプロイした時のビルドエラー＆解決方法集

# はじめに
本記事はメモ置き場なのであてにならないことが多い。
そのうちきれいにまとめたい。

# エラーの探し方
Render.comでビルドを開始するとビルドログが表示される。
最終的に失敗すると"Build Failed"が出力され、ビルドに失敗したことを通知してくれる。
あとは長いビルドログを遡ってどこでコケてるか探す。

#解決方法
ビルドエラーログの箇所をコピぺでググる。エラーによってはログに解決方法書いておいてくれてあるのでとても親切。


# ビルドエラー＆解決方法集

## Your bundle only supports platforms...
```
Bundler Output: Your bundle only supports platforms ["x86_64-darwin-20"] but your local platform
remote:        is x86_64-linux. Add the current platform to the lockfile with `bundle lock
remote:        --add-platform x86_64-linux` and try again.
```
解決方法がそのまま書いてある。
「bundle lock --add-platform x86_64-linux」を実行して解決。

## ArgumentError: key must be 16 bytes
キーの長さが足りないよ！っていうエラー。
Renderキーに「config/master.key」を指定していたがうまくいかなかったのでmaster.keyに記述されているキーをそのままコピペしたらうまくいった。
多分あまりよろしくない気がするので別解を探す予定。

# おわりに
他にもあった気がするけどメモし忘れた。
またエラー起こったら追記します。
Goでテストコードを書く

書きます

今回はA Tour of Goのフィボナッチにテストを書く

```go:main.go
package main
import "fmt"
func fibonacci() func() int {
	a, b := 1, 0
	return func() int {
		a, b = b, a+b
		return a
	}
}
func main() {
	f := fibonacci()
	for i := 0; i < 10; i++ {
		fmt.Println(f())
	}
}
```

```sh
$ go run main.go
0
1
1
2
3
5
8
13
21
34
```

テストを書く

```go:main_test.go
package main
import "testing"
var Debug bool = false
func TestFibonacci(t *testing.T) {
	if Debug {
		t.Skip("skip")
	}
	f := fibonacci()
	if f() != 0 {
		t.Errorf("err")
	}
	if f() != 1 {
		t.Errorf("err")
	}
	if f() != 1 {
		t.Errorf("err")
	}
	if f() != 2 {
		t.Errorf("err")
	}
	if f() != 3 {
		t.Errorf("err")
	}
}
```

テスト実行

```sh
$ go test
PASS
ok  	example/user/hello	0.227s
```

今回は変数をクロージャのような形で保持して呼び出すたびにカウントアップするような実装になっているのでテストもそれに沿った形で書いています。リファクタリングもできますが挙動を理解しました。
【競プロ/Swift】まよコン 2023/03/16

# 注意事項
本記事は復習のための日記的なものであり、丁寧な解説を求めている方には不十分かと思われますので、ご了承のほどお願いいたします。

# 正解済み問題
## B - Base K
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc220/tasks/abc220_b)

**解答**
入力値を10進法に直して、掛け算して出力。
標準APIにまじ感謝。

```swift
let k = Int(readLine()!)!
let ab = readLine()!.split(separator: " ")
 
print(Int(ab[0], radix: k)! * Int(ab[1], radix: k)!)
```

## C - Multiplication 3
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc169/tasks/abc169_c)

**解答**
結構苦戦した。。
少数を扱う場合は誤差が出る可能性があるので、こんな感じで切り分けて解くのが良さそう。
直接計算したら意外と不正値が割と出る。。笑

```swift
import Foundation
 
let input = readLine()!.split(separator: " ").map{ String($0) }
let A = Int(input[0])!
let B = Int(input[1].split(separator: ".").reduce("") { $0 + $1})!
 
print( A * B / 100)
```

# 誤答及び、未解答問題
## B - Ruined Square
**問題文**
[こちら問題ページ](https://atcoder.jp/contests/abc108/tasks/abc108_b)

**未解答**
一発正解かなと思ったが、条件が網羅できておらずWA。
そこからは解法が思いつからずに終了。

```swift
let positons = readLine()!.split(separator: " ").map{Int($0)!}
let distance = [abs(positons[0] - positons[2]), abs(positons[1] - positons[3])]

print("\(positons[2] - distance[1]) \(positons[3] + distance[0]) \(positons[0] - distance[1]) \(positons[1] + distance[0])")
```
**正答**
考え方はあってたぽい。
もっと落ち着いて、整理してコード書いて行ったら解けたかも。

```swift
let xy = readLine()!.split(separator: " ").map{ Int($0)! }
let x1 = xy[0]
let y1 = xy[1]
let x2 = xy[2]
let y2 = xy[3]
let x3 = x2-(y2-y1)
let y3 = y2+x2-x1
let x4 = x1-(y2-y1)
let y4 = y1+x2-x1
print(x3,y3,x4,y4)
```
# 参考
https://kenkoooo.com/atcoder/#/contest/show/3f8d9193-3ab2-46dd-92e6-60bf13e17e7b?activeTab=Problems
【Git】用語まとめ

## はじめに
Git、GitHubの基礎を理解するために必要な用語をまとめました。

## 用語集
|用語 |説明 |
|---|---|
|gitignoreファイル |Gitで管理したくないファイルやディレクトリを設定する。記載するとコミット対象から外れる |
|GitHubフロー |GitとGitHubを使って作業する方法として、GitHubが推奨してる一連の流れ |
|Gitディレクトリ |コミットを格納する場所 |
|masterブランチ |Gitのリポジトリを作成する際に自動的に作られるブランチ|
|Issue |GitHubでリポジトリのバグ報告や問い合わせなどを投稿する機能 |
|LGTM |「Looks Good To Me」の略。レビュー内容がOKだと判断した時に使うことが多い |
|mainブランチ |masterブランチと同じ役割のブランチ。GitHubでリポジトリを作成すると自動的に作られる |
|modified |「最後にコミットした状態」から変更済みのファイルを表す |
|origin |クローン元のリモートリポジトリを表す名前 |
|READMEファイル |リポジトリの基本情報を記載するファイル。GitHubではリポジトリのトップページに表示される |
|unmodified |「最後にコミットした状態」から変更されてないファイルを表す |
|untracked |追跡されていないファイルを表す。まだ一度もコミットされておらず、Gitの管理下にない |
|クローン |GitHub上のリポジトリを丸ごとパソコンに取得すること。はじめに1回だけ行う |
|コミット |任意のタイミングで記録を保存する操作。その記録自体のことも「コミット」と呼ぶ |
|コンフリクト |複数のブランチで（複数人で）同じファイルの同じ箇所を編集した後に怒る衝突。必要な内容を勝手に上書きしないための機能 |
|スカッシュ |複数のコミットをまとめること。GitHubでマージの際に使うと、ブランチに加えた変更履歴が１つになる |
|ステージングエリア |コミットするファイルを登録する場所。「インデックス」とも呼ぶ |
|チェックアウト |操作対象のブランチに切り替えること。特定のバージョンをワークツリーに反映する働きをもつ |
|トピックブランチ |短期的に使う作業用のブランチ |
|バージョン管理 |バックアップや履歴の把握などに役立てるため、ファイルの変更をすべて記録すること |
|プッシュ |ローカルリポジトリからリモートリポジトリに反映すること |
|フェッチ |リモートリポジトリの内容をローカルリポジトリに取得すること |
|フォーク |リポジトリを複製するGitHubの機能 |
|ブランチ |Gitで記録する履歴を枝分かれさせるための機能。複数の作業を並行して進めるときに使用する |
|プル |リモートリポジトリの内容をローカルリポジトリに取得し、ワークツリーに反映すること |
|プルリクエスト |ブランチの取り込みを依頼するGitHubの機能 |
|ベースブランチ |プルリクエストでのマージ先のブランチ |
|マージ |枝分かれさせたブランチを統合すること |
|リベース |ブランチを統合する方法のひとつ。まるで履歴が枝分かれしていなかったかのように一直線に統合する |
|リポジトリ |コミットを貯めていく場所 |
|リモートリポジトリ |インターネットなどのネットワーク上に存在するリポジトリ |
|ローカルリポジトリ |手元で使っているパソコン内に作成する自分専用のリポジトリ |
|ワークツリー |変更するファイルを保持する場所。「ワーキングツリー」「作業ディレクトリ」とも呼ぶ |

## 参考
https://www.amazon.co.jp/%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84Git-GitHub%E3%81%AE%E6%95%99%E6%9C%AC-%E4%BA%BA%E6%B0%97%E8%AC%9B%E5%B8%AB%E3%81%8C%E6%95%99%E3%81%88%E3%82%8B%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86-%E5%85%B1%E6%9C%89%E5%85%A5%E9%96%80-%E3%80%8C%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84%E6%95%99%E6%9C%AC%E3%80%8D%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4295013617/ref=sr_1_1?keywords=git+github&qid=1678935341&sprefix=git+%2Caps%2C192&sr=8-1
なぜクラウドストレージを利用すべきなのか

  近年、クラウドストレージはすごく人気があるサービスになってきました。ユーザーのパソコン上にデータを保存する代わりに、インターネットでファイルを格納することができるからです。さらに、クラウドストレージは、場所や時間に縛られることなくオンラインでファイルの共有が行えます。この便利なサービスは、主にビジネスや個人ユーザーに利用されていますが、この記事では、なぜクラウドストレージを使用すべきなのかについて説明していきたいと思います。

  アクセス可能性は、クラウドストレージを利用することで大きなメリットとなります。これは、データをインターネットで保存するため、ユーザーはいつでもどんな場所でもファイルにアクセスができます。このようなアクセス性は、ビジネスにとっては、出張先や遠隔地での仕事などで必要なデータにアクセスすることができるというメリットをもたらします。また、個人ユーザーにとっては、自宅や外出先などでファイルや思い出にアクセスすることができるというメリットもあります。一般的に、クラウドにデータを使用にはインターネットしか必要ではありませんが、クラウドストレージプロバイダの一部はオフラインでもストレージにアクセス可能です。クラウドストレージを利用することで、データのセキュリティが向上します。安全性は、デジタルデータを保存・管理する上で重要な要素です。

  [最適なクラウドストレージ](https://www.cloudstoragenews.jp/best-cloud-storage-providers/)サービスプロバイダーは、高度なセキュリティシステムを提供しています。これには、データ暗号化、認証、アクセス管理などが含まれます。これらのセキュリティ施策により、データを保存することができる環境が安全になり、データの漏洩や破壊などが防止されます。また、クラウドストレージは、複数のデバイスからアクセスすることができるため、データのバックアップも簡単に行えます。このようなバックアップにより、データの数値や品質などが保証され、データの損失などが防止されます。
![pcloudapp4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784576/9d4571cc-f692-d57f-e835-2982b69699fe.jpeg)
  データ保存に関しては、クラウドストレージを利用することで、より効率的かつ安全なデータ保存が可能となります。例えば、コンピュータやハードドライブなどのローカルストレージに保存したデータは、ハードウェアの故障や破損などの原因で失われる可能性があります。しかし、クラウドストレージを利用することで、これらのリスクを回避することができます。また、クラウドストレージを利用することで、データを保存することができる場所が増えるというメリットもあります。このような書類を保存メリットは、ビジネスや個人にとっても重要です。
github pagesで躓いた点


初投稿です
超初心者です
自分用のメモに書いてみます 
## そもそもgithubにpushする際のterminalの知識がない
同じファイルを編集して新たにpushしようとするとreomteの段階で
```diff_c
remote origin exists
```
との表示が
```diff_c
git remote rm origin
```
で一度ブランチを削除する
その後
```diff_c
git remote origin url
```
でうまくいくことがわかった

## repositoryに追加したけどページに反映させるやり方がわからない
1.　Settingsからpagesを開く
2.　branchの選択　mainからrootsを選ぶ
3.　しばらくしてcodeを開くとオレンジのランプが灯火
4.　detailsを開くとビルドの様子が分かる
5.　最後にurlが出てくるのでリンクに飛ぶと完成

## 注意点
・メインのファイルはindex.htmlにリネイムしないとNOT FOUNDになっちゃう
・repository名は<user名>.github.ioにするといい感じになる(違う名前にするとスラッシュが入りドメインが長くなる)
***
なんやかんやでwebページを公開することが出来ました
まだ見出しとかインラインとか慣れてないです、、
次は自己紹介とかしようかな
これからどんどん更新するので温かい目で見守って下さい笑
デプロイした EventGrid Trigger の Azure Function を手動で発火させるメモ

## 経緯

ローカルで実行した EventGrid Trigger の Function に対して、直接 Http Request を送ることで処理を走らせることができます。

これは公式ドキュメント: [How to work with Event Grid triggers and bindings in Azure Functions: Manually post the request](https://learn.microsoft.com/en-us/azure/azure-functions/event-grid-how-tos?tabs=v2%2Cportal#manually-post-the-request) に手順がまとめられています。

同様に Azure にデプロイした後も Http リクエストを投げれば手動で走らせられると動作確認などで何かと便利だと思って試したのですが、ドキュメントの手順から単に URL をデプロイ先のものに置き換えたのみでは HttpStatusCode 401 の応答が返ってきてしまい、期待通りに動きません。

そのため手動で走らせることは無理なのではないかと思っていたのですが、試行錯誤する中で実際には可能であることに気づいたので、方法をメモします。

## 試した環境

* C# (.NET6) 
* Azure Function v4

私が個人的に慣れている構成で試してうまくいくことのみ確認していますが、恐らくは言語などを問わず同じ方法で可能なのではないかと思っています。(もしほかの環境でうまくいったということがあれば教えていただけると大変ありがたいです。)

## 方法

以下のように単に Function Key をクエリパラメーターに付与してあげるだけで期待通り処理が走ります。

```
@RESOURCE_NAME=<functionのリソース名>
@FUNCTION_NAME=<実行するFunctionの名前>
@CODE=<function の App Keys>

POST https://{{RESOURCE_NAME}}.azurewebsites.net/runtime/webhooks/EventGrid?functionName={{FUNCTION_NAME}}&code={{CODE}}
Content-Type: application/json
aeg-event-type: Notification

{
  "id": "1",
  "eventType": "aaaa",
  "subject": "aaaa",
  "eventTime": "1111-12-15T14:21:12+00:00",
  "data": {
    "tekitou": "atai",
  },
  "dataVersion": "1.0"
}
```
YOLOv8で物体検出モデルを試してみた

# はじめに
YOLOv8で物体検出してみます。
また検出時にクラスやconfidenceの指定方法、モデルサイズによる推論速度の比較なども検証してみます。

# 環境
Python-3.8.12
torch-1.7.1+cu110
NVIDIA GeForce RTX 3090

# 試してみた
### YOLOv8のインストール
``` sh
pip install ultralytics
```

### データセットの準備
こちらからデータを拝借
https://cocodataset.org/#download

1000枚の画像で試していきます。

### まずはディテクション
``` python
from ultralytics import YOLO

# モデルの生成。モデルは自動でダウンロードされます。
model = YOLO("yolov8s.pt") 
# 推論実行
results = model("./datasets/test2014/COCO_test2014_000000139819.jpg")
```
推論実行時に渡す引数はファイルパス、URL、cv2などで読み込んだ配列など様々なデータに対応しています。渡せるデータは[こちら](https://docs.ultralytics.com/modes/predict/)から確認できます。
cv2で読み込んだ場合は、BGRからRGBに変換してから利用するように注意が必要です。

結果はリストで返ってきます。
推論時に複数のデータを渡せば、結果もそれに応じて複数返ってきます。
中身は以下のようにして確認できます。
``` python
results[0].cpu().boxes.numpy().boxes
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802936/8f507e40-7b44-acbf-69f8-4c2309d72447.png)
インスタンス毎に情報を持ち、左から順にバウンディングBOXの4座標、confidence score、クラスになります。

クラスは results[0].names から確認することもできます。
0はperson、38はtennis racketです。

推論時にクラスやconfidenceを指定することも可能です。
指定しない場合は、学習された全クラス、スコア0.25以上の物体が検出されるようです。

今度はperson、スコア0.6以上で推論実行してみます。
``` python
results = model(
    "./datasets/test2014/COCO_test2014_000000139819.jpg",
    classes = [0],
    conf = 0.6
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802936/2618c3c1-6072-1716-56a2-939d1431cc39.png)
先ほどよりも結果が絞られました。
結果を元の画像に描画します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802936/51fda519-c72b-8c57-ea80-7bea82693453.png)

# モデルサイズ別に推論速度を比較する
物体検出モデルはサイズ別に５つのバリエーションが用意されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802936/35942f7d-f0e1-6346-2e30-c6b788da1ee4.png)

今回は1000枚の画像を使って、推論速度と物体の検出数を比較してみました。
先ほど同様、クラスはperson、スコアは0.6とします。
``` python
model_paths = [
    "./model_data/yolov8n.pt",
    "./model_data/yolov8s.pt",
    "./model_data/yolov8m.pt",
    "./model_data/yolov8l.pt",
    "./model_data/yolov8x.pt",
]

performance_info = {}
img_files = glob.glob("./datasets/test2014/*.jpg")
for model_path in model_paths:
    predict_time = 0
    bbox_cnt = 0
    model = YOLO(model_path)
    for img_file in img_files[:1000]:
        img = cv2.imread(img_file)
        start = time.perf_counter()
        results = model(
            img[:,:,::-1],
            classes = [0],
            conf = 0.6,
        )
        predict_time += time.perf_counter() - start

        result = results[0].cpu().boxes.numpy()
        boxes = result.xyxy.astype(int)    
        bbox_cnt += len(boxes)

    performance_info[os.path.basename(model_path)] = {
        "time":predict_time,
        "bbox_cnt":bbox_cnt,
    }
```
結果はこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2802936/06da4d64-8fe3-3608-8bab-7f4ae6a5292b.png)
一番小さいNサイズと一番大きいXサイズを比べると速度が1.5倍かかってますが、検出数も1.5倍多い結果となりました。
今回は単純に速度と検出数で比較しましたが、いずれしっかりと精度を出して比べてみたいと思いました。

以上になります。
最後まで読んでいただき、ありがとうございました。
OCI IPSec VPN接続例一覧

## 概要
NW機器を使用してOCIにInternet IPSecVPN接続する設定例です。
## 検証済機器
- [Cisco Router Cisco892](https://qiita.com/tktk2712/items/b3e7522482f09795107f)
- YAMAHA RTX830
    - [IKEv1](https://qiita.com/tktk2712/items/03c3360173135e0a702b)
    - [IKEv2](https://qiita.com/tktk2712/items/365ce1eacef543bcf476)
- [FortiGate 50E](https://qiita.com/tktk2712/items/766440e490a18687701f)
- [FortiGate 50E(BGP)](https://qiita.com/tktk2712/items/576ae1f5401e69e212bb)
- [Palo Alto VM-Series Next-Generation Firewall Bundle 1](https://qiita.com/tktk2712/items/1e506a37458616465b30)
- [Juniper vSRX Next Generation Firewall](https://qiita.com/tktk2712/items/e1ca0ff239466a0fd48c)
- [Cisco ASAv Virtual](https://qiita.com/tktk2712/items/5cfcd7d26cd01d0ec417)
- [Check Point Security Management, NGFW](https://qiita.com/tktk2712/items/df297166058503c7a04b)
- [NEC IX2105](https://qiita.com/tktk2712/items/9bb1de36e8fd8c1fa0f4)
- FUJITSU Si-R G100
    - [IKEv1](https://qiita.com/tktk2712/items/a4e92dd442c842db0e57) 
    - [IKEv2](https://qiita.com/tktk2712/items/b47a8929fd02fcb1d048)
- [VyoS](https://qiita.com/tktk2712/items/8a78669c1c813c383e9d)

## 参考情報
[OCIサイト間VPN CPE構成 検証済CPEデバイス](https://docs.oracle.com/ja-jp/iaas/Content/Network/Reference/CPElist.htm)
数学再挑戦！AIと一緒に楽しく学ぶエンジニアのためのChatGPT活用法

※タイトルはChatGPTに考えさせてます。

# きっかけ
gpt4に数学の問題を作成させて、それを解かせるという動画を見かけた。
https://www.youtube.com/watch?v=riP_P01e_Ms

「数学はそのうちやってみたい。でもなかなか触る気になれない・・・」
が何年も続いているが、ChatGPTと絡めてやると楽しそうだ。

そしてせっかくならPythonコードも書かせてみたら、数学の教科書を読むより楽しいのでは？
と思った。

# 試しに問題を用意させた
>高校3年生レベルの数学問題を３問ほど出して。また、それを解くPythonコードも用意して。

以下の結果が返ってきた。

>問題1:
二次関数 y = ax^2 + bx + c の頂点を求める。
ここで、a = 2, b = -4, c = 3 とする。

>問題2:
二つの点 A(3, 4) と B(7, 8) の間の距離を求める。

>問題3:
角度θが 30 度の場合、sinθ と cosθ の値を求める。

# コード作成
そしてそして。コーディングもセットでついてくる。
>以下に、それぞれの問題を解くPythonコードを示します。
```math_test.py
import math

# 問題1: 二次関数の頂点を求める
def quadratic_vertex(a, b, c):
    x_vertex = -b / (2 * a)
    y_vertex = a * x_vertex ** 2 + b * x_vertex + c
    return x_vertex, y_vertex

a, b, c = 2, -4, 3
x_vertex, y_vertex = quadratic_vertex(a, b, c)
print(f"問題1: 頂点座標: ({x_vertex}, {y_vertex})")

# 問題2: 二点間の距離を求める
def distance_between_points(x1, y1, x2, y2):
    return math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)

x1, y1 = 3, 4
x2, y2 = 7, 8
distance = distance_between_points(x1, y1, x2, y2)
print(f"問題2: 点Aと点Bの距離: {distance}")

# 問題3: sinθ と cosθ の値を求める
def sin_cos_of_angle(degrees):
    radians = math.radians(degrees)
    sin_theta = math.sin(radians)
    cos_theta = math.cos(radians)
    return sin_theta, cos_theta

degrees = 30
sin_theta, cos_theta = sin_cos_of_angle(degrees)
print(f"問題3: sinθ = {sin_theta}, cosθ = {cos_theta}")
```

ええやん。

「学び直ししたいけど、教科書読めない・・・」という人にお勧め。
Cloud Functionsでres.status(200).send(message);しなかったら？

いつものコードです。`res.status()`や`res.send()`や`res.end()`しなかったらどうなるでしょうか？
```javascript
/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
exports.helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!'
  res.status(200).send(message) // この行を削除
}
```

# タイムアウトになります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435735/f11b8d64-be4e-c84e-8dcb-39b5214bbbd8.png)

returnしてもタイムアウトになります。気をつけましょう

```javascript
/**
 * Responds to any HTTP request.
 *
 * @param {!express:Request} req HTTP request context.
 * @param {!express:Response} res HTTP response context.
 */
exports.helloWorld = (req, res) => {
  let message = req.query.message || req.body.message || 'Hello World!'
  return message
}
```

# まとめ

`res.end()`などで終了するように心がけましょう
【Linux】ファイルの内容を末尾から出力する方法


## `tac`コマンド

`tac`コマンドはファイルの行を逆にして出力します。  

```terminal
$ cat sample.txt
1 abcde
2 abcde
3 abcde
4 abcde
5 abcde

$ tac sample.txt
5 abcde
4 abcde
3 abcde
2 abcde
1 abcde
```

複数のファイルのそれぞれの行を逆にして連結する場合には次のように実行します。  

```sample.txt
$ cat sample.txt example.txt
1 abcde
2 abcde
3 abcde
4 abcde
5 abcde
a 12345
b 12345
c 12345
d 12345
e 12345

$ tac sample.txt example.txt
5 abcde
4 abcde
3 abcde
2 abcde
1 abcde
e 12345
d 12345
c 12345
b 12345
a 12345
```

複数のファイルを連結したうえで行を逆にして出力するには次のようにします。  

```terminal
$ cat sample.txt example.txt | tac
e 12345
d 12345
c 12345
b 12345
a 12345
5 abcde
4 abcde
3 abcde
2 abcde
1 abcde
```

## `rev`コマンド

`rev`コマンドはファイルの行の文字列を逆にして出力します。  

```terminal
$ rev sample.txt
edcba 1
edcba 2
edcba 3
edcba 4
edcba 5
```

ファイル全体を末尾から先頭に向かって出力するには次のようにします。  

```terminal
$ tac sample.txt | rev
edcba 5
edcba 4
edcba 3
edcba 2
edcba 1
```
form_withの使い方について

# はじめに
オリジナルアプリ実装中にform_withについてほぼ理解できていなかった為、沼にハマりました。form_withを何となく使っていた方やあまり理解できていない方が、この記事を読んで頂いて、少しでも理解が深まれば幸いです。

# 1. ``form_with``(ヘルパーメソッド）とは？？

viewにHTMLタグを出現させたりテキストを加工するために使用するメソッドの総称。
また投稿ページ・編集ページなどにおけるフォームを実装する為のヘルパーメソッドの事です。
ヘルパーメソッドは、他にもlink_toなどその他色々あります。

# 2.記述方法
```ruby:form_withの基本構文 [model.ver]
 <%=　form_with model: モデルクラスのインスタンス do |form| %>　　
    formの内容
 <% end %>
```

```ruby:form_withの基本構文 [url.ver]
 <%= form_with url:　　path do |form| %>
    formの内容
 <% end %>
```
```ruby:form_withの基本構文 [scope.ver]
 <%= form_with scope: :name属性の値, url:path, local: true do |f| %>
   formの内容
 <% end %>
```

上記が**form_with**の基本形です。
**do~end**の間にformの記述を行い、処理が行われます。

# 3 form_withの特徴

* インスタンス変数の中が、newアクションで新規作成されたインスタンスの場合はcreateアクションが実行
* インスタンス変数の中に、既に存在するレコードがある場合はupdateアクションが実行

この２つの条件で自動的にcreate・updateの処理の分岐を行なってくれます。
具体例を以下のコードに記述します。


# ４.解説
```ruby:birthdays_controller.rb
  def new
    @birthday = Birthday.new
  end
```

```ruby:new.html.erb
<%= form_with model: @birthday, local: true do |f|%>
   <div class="field">
   #〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜 省略
   <div class="actions">
   <%= f.submit "登録する", class: :form_btn  %>
   </div>
<% end %>
```
新規登録ページで登録するをクリックすると、 birthdays_controllerで定義した変数@birthdayの中身は新規作成されたモデルのインスタンスが入っており、このインスタンスがsaveされると、保存されたモデルのインスタンスとなり、createアクションが動きます。

```ruby:birthdays_controller.rb
   def edit
     @birthday = Birthday.find(params[:id])
   end
```

```ruby:edit.html.erb
<%= form_with model: @birthday, local: true do |f|%>
   <div class="field">
  # 〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜　 省略
   <div class="actions">
   <%= f.submit "更新する", class: :form_btn  %>
  　　</div>
<% end %>
```
編集ページで更新するをクリックすると、birthdays_controllerの@birthdayの中身に情報（レコード）は入っているので、updateアクションが動きます。

# ５、少し余談
edit.html.erb（編集ページ）でインスタンス変数の記述を@birthdayではなく@Birthdayと定義してしまい、受け渡しができず、ずっとルーティングエラーがでていました。
タイポミスで膨大な時間を費やしてしまうので、必ず一旦、冷静になり、現状を言語化しながら紙に書き出す事をしていきたいですね。
また皆さんは、タイポを無くすために工夫されていることはありますでしょうか？？
コメント頂けたら幸いです。

ここまで、見ていただきありがとうございます。
【Rails】部分テンプレート

# 【Rails】部分テンプレート作成方法
複数のviewページで共通して使われている部分を共有（部分テンプレート）することが出来ます！



## メリットは...？
・同じ記述を何度も書く必要がなくなる
・修正が必要な場合、修正箇所が減る
・記述するコードが減る
・ファイルサイズを小さくすることが出来る



## 部分テンプレート作成手順
①部分テンプレートファイル作成
②共通のコードを切り取る
③①で作成したファイルに②を記述する
④部分テンプレート用のコードに書き換える
⑤部分テンプレートファイルを呼び出す

## ①部分テンプレートファイル作成

今回はspotsのnew・index・show・editページに部分テンプレートを付けたいと思います。
部分テンプレートのファイルは「_(アンダーバー)」を必ず最初に付ける決まりがあります。
`_new.html.erb`というファイルを作ります。
![スクリーンショット 2023-03-16 224120.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3111780/d395e996-b9ee-b836-7323-6230efe43499.png)

## ②共通コードを切り取る

共通するコードを切り取ります。

```php:view/admin/spots/new.html.erb
---<ここから✂>---
<% @spots.each do |spot| %>
<div>
  <%= link_to spots_path(spot.id) do %>
    <%= image_tag spot.get_image %>
  <% end %>
---<ここまで切り取る✂>---

<p><%= link_to "プロフィール編集", 〇〇_path(@〇〇) %></p>
  <% end %>
</div>

```

## ③　①で作成したファイルに②に記述（貼り付け）
①で作成した`_new.html.erb`ファイルに②で切り取りしたコードを貼り付けます。

```php:view/admin/spots/_new.html.erb

<% @spots.each do |spot| %>
<div>
  <%= link_to spots_path(spot.id) do %>
    <%= image_tag spot.get_image %>
  <% end %>

```

## ④部分テンプレート用のコードに書き換える

部分テンプレート内でインスタンス変数を使用すと、コントローラを変更した際に、部分テンプレート内も変更の必要が出てきてしまい面倒になります。
そこで、部分テンプレート内のインスタンス変数をローカル変数に変更します！
その方法とは...　`「@」を取るだけです`


```php
<% @spots.each do |spot| %>
<div>
  <%= link_to spots_path(spot.id) do %>
    <%= image_tag spot.get_image %>
  <% end %>
```
@これを外します！


```php
<% spots.each do |spot| %>
<div>
  <%= link_to spots_path(spot.id) do %>
    <%= image_tag spot.get_image %>
  <% end %>
```





## ⑤部分テンプレートファイルを呼び出す
newのviewファイルに`<%= render 'new', spots: @spots %>`を記述する。

```php:view/admin/spots/new.html.erb

<%= render 'new', spots: @spots %> #これを記述すると部分テンプレートファイルを呼び出せる

<p><%= link_to "プロフィール編集", 〇〇_path(@〇〇) %></p>
  <% end %>
</div>
        .
        .
        .
```

new以外のviewファイルには下記のように記述する。
`admin/spots/new`を使う

```php:view/admin/spots/index.html.erb

<%= render 'admin/spots/new', spots: @spots %> #このように記述する

<h1>投稿一覧</h1>

<% @spots.each do |spot| %>
        .
        .
        .

```

これで部分テンプレート使えました:relaxed:
[TypeScript]安全なグローバルステータス管理

<h2>始めに</h2>
アクセスするデータは全域空間に置くと便利ですが、<br>
便利だという点で最も不安な空間でもあります。<br>
もし、あるコードでミスをして間違ったデータをセットしたり、別の種類のデータで上書きしたりした場合、
深刻な問題が発生する可能性があります。<br>
アプリケーションの規模が相当な時には、このようなバグがどこで発生するのかを探すことさえ非常に難しいことだ。
だから、みんながアクセスできる全域空間はできれば使わない方が一番いいけど、仕方ない時！

<h2>globalを使ったグローバルステータス</h2>
declare global ブロック内に宣言したタイプは、全域entityのプロパティタイプと定義されます。
storeは全域空間に定義されており、外部により間違ったデータにセットされる可能性があります。

```typescript:app.ts
const store: Store = {
    currentPage: 1,
    feeds: [],
}

declare global {
    interface Window {
        store: Store;
    }
}

window.store = store;
```

<h2>classを使った安全なグローバルステータス管理</h2>
app.tsでscriptにてグローバルデータを定義しましたが、それよりもclassを作成し
グローバルデータを管理する方が安全です。classの中で、属性をprivateにして外部からアクセスできないようにします。
<br>
currentpageは属性です。<br>
そのため、getCurrentPage()を作って提供する方法があります。<br>
しかし、数字一つを持ってくるのにgetCurrentPage()のようにメソッドを呼び出してそんな形式にすると面倒！<br>
typescriptでは、内部では関数として動作するが、外部では属性のように見えるgetter setterという文法があります。
setter中で防護コードを作成して、ミスを防ぐ対策ができます。

```typescript
class store {
    // privateと定義して外部からアクセスできなくすること。
    private feeds: NewsDeed[];
    private _currentPage: number;

    constructor() {
        this.feeds = [];
        this._currentPage = 1;
    }

    //属性と関数の名前が同じであればいけないこと!
    //それで内部で使用するものは__をつけたこと
    get currentPage() {
        return  this._currentPage;
    }

    set currentPage(page: number) {
        if (/*防護コードを作成*/)
        this._currentPage = page;
    }
}
```
こうしておけば、クラス外部では、まるで属性のように見えるため代入文でセットでき、プロパティ値のように参照することができます。
setがなければ一種のreadonly属性になります。
<br>

```typescript:外部でstoreクラスのデータにアクセスする方法
// storeのset currentPage(page: number) に相応
this.store.currentPage = 1

// storeのget currentPage() に相応
this.setTemplateData('currentPage', this.store.currentPage.toString());

```
[node.js] flash messageを表示させる

# はじめに
node.jsでflash messageを表示させたかったが、大変苦労した。


# install
```terminal
$ npm install express-session --save
$ npm install express-flash --save
$ npm install express-handlebars --save
```

# Code
```javascript:app.js
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var flash = require('connect-flash');
var session = require('express-session')
var sessionStore = new session.MemoryStore;

var app = express();

app.use(session({
  secret: 'keyboard cat',
  resave: true,
  store: sessionStore,
  saveUninitialized: true,
  cookie: { maxAge: 60000 },
}))

app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(flash());

app.set('views', path.join(__dirname, 'views'));

app.get('/', function (req, res) {
  res.render('home.ejs', {
    message: req.flash('info')
  })
});

app.get('/flash', function (req, res) {
  req.flash('info', 'Flash is back!')
  res.redirect('/');
});
```


```html:home.ejs
<h1>main page</h1>

<% if (message) { %>
    <div>Flash:<%= message %></div>
<% } %>
```

```json:package.json
{
  "name": "myapp",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "connect-flash": "^0.1.1",
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "dotenv": "^16.0.3",
    "ejs": "^3.1.8",
    "express": "^4.18.2",
    "express-flash": "^0.0.2",
    "express-flash-notification": "^0.5.0",
    "express-handlebars": "^7.0.2",
    "express-session": "^1.17.3",
    "http-errors": "~1.6.3",
    "morgan": "~1.9.1",
    "mysql": "^2.18.1",
    "pug": "^3.0.2"
  },
  "devDependencies": {
    "nodemon": "^2.0.21"
  }
}
```


# 操作画面
![2023-03-16 23;21;03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/af2573fc-6c5b-ec27-38e9-91c620f3e391.gif)
ページを更新すると、`flash message`は消える
これを応用してログイン時にエラーメッセージなどを表示することができる。




# 参考
https://qiita.com/MahoTakara/items/0a88d05ff93328035ad8
PHP基本構文『foreach文』

# 前提の基本知識
## 配列
- イメージはタンス
    - [0,1,2] 0番から数字が振られていく。
    - 下記、バナナを取り出したかったら、0を指定する。
```
$fruits = ['バナナ', 'リンゴ', 'スイカ'];
echo $fruits[0];
```
![スクリーンショット 2023-03-16 23.14.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/3857af87-38f6-fb30-ea8e-ebd79947be7e.png)
## 連想配列
- イメージは鍵付きのタンス
    - キーとバリュー（タンスの鍵と中身をセットで記載）
    - 'キー'=>'バリュー'
        - キーを入力して、バリューを取り出す。
        - dogを取り出したかったら、キー犬を入力する。
```
$animals = ['犬'=>'dog', '猫'=>'cat', '馬'=>'horse', '牛'=>'bull'];
echo $animals['犬'] . '<br>';
```
![スクリーンショット 2023-03-16 23.18.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/4e8898c7-760c-d35a-8383-e106af72341e.png)
# foreach文
- 配列の中身を一覧で取り出す
```
$students = ['ゴン', 'キルア', 'ズシ'];
foreach($students as $student){
echo $student . '<br>';
}
```
![スクリーンショット 2023-03-16 23.20.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3193952/2c0f322d-521a-9eab-e33a-27975fa4db64.png)
Windows11にRuby On Railsをインストールしてからアプリの立ち上げまでを解説

Windows11にRuby On Railsの環境構築からアプリの立ち上げまでを解説します。

# Rubyのインストーラをダウンロードする
Rubyインストーラーのダウンロードはこちらの公式サイトからです。↓
【公式サイト Ruby Installer for Windows】
URL:https://rubyinstaller.org/

公式サイトの「Download」ボタンをクリックします。
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/7073332a-f317-50c0-53e5-5e880d2ad745.png)

ドキュメントの記載にあるように使用するバージョンを決めていない場合は、ハイライトされているバージョンを選択すると良いでしょう。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/73ae4597-48b7-9036-cea4-73d55a674124.png)

インストーラを起動すると下記の画面が表示されますので、デフォルトのまま「install」ボタンをクリックします。
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/80a3ac8d-ca30-68ad-a3d8-215002f47054.png)

こちらもデフォルトのまま「Next」ボタンをクリックします。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/4cfa402d-d967-6d2b-7147-990dd19a07a6.png)

インストールが完了するまで少し待ちます。(約1GBくらいなのでだいたい40秒くらい)
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/4bf694a7-a560-74f1-2cbc-0d8e2b7c6df0.png)

インストールが完了すると、下記の画面が表示されますので「Finish」ボタンをクリックします。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/9ca33e4f-24c3-674f-7822-538374786659.png)

「Finish」ボタンをクリックしたあと、下記のコンソール画面が自動で起動します。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/578ee2a4-d535-c9bf-0275-34c93cb16e77.png)

ツールMSYS2のバージョン1,3をインストールするためコンソール画面に「1,3」を入力してEnterキーを押します。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/4b5b6574-c6ff-b9ba-50b4-0aaf72f63039.png)

MSYS2がインストールされます。
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/ce38e08e-b427-ca02-46ca-2cec1ca1eb38.png)

次にBundlerをインストールします。下記のコマンドを入力しましょう。
以降の各ツールをインストールするのコマンド画面は、「Start Command Prompt with Ruby」を使います。Windowsのスタートメニューから起動しておきましょう。
![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/88eb5171-7f98-ba8d-9aa1-8249a33ca35c.png)


```コマンド
gem install bundler
```
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/26f0fde8-b203-e8c9-ed5e-3caea52d9417.png)

最後にRailsをインストールしましょう。下記のコマンドを入力してください。
```コマンド
gem install rails
```
Railsアプリに必要なツールがインストールされますので少し待ちます。
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/26cf0a66-0a5f-ccd8-3b1c-5d65bb640203.png)

インストール完了後の画面です。
![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/9de57805-8e9e-7a22-f9ef-e4fce2ecaa92.png)

さて、いよいよRailsアプリケーションの作成です。
下記のコマンドを入力しましょう。※コマンドの最後についているのはGitをインストールするためです。これがないとアプリは作成できません。
```
rails new アプリケーション名 -G
```

![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1169664/d4612a73-7cad-f024-e8a7-2274071ea4ba.png)

以上でWindows11でのRuby On Railsのアプリ作成は完了です。
クリップボードにある会社を転職口コミサイトで開くプログラムをPythonで作成した

## 背景

転職活動を始めた。
いろんなサイトで求人情報を見て、気になった会社を検索して、登録している口コミサイトのページを探す・・・

<b>地味にめんどくさい</b>

ということでササッと自動化してみた。

## 機能

気になった会社名をコピーしてプログラムを起動するとOpenWorkでその会社のページを開く。だけ。

## 使用したPythonライブラリ
##### pyperclip
クリップボードを操作できる。
今回はクリップボードの内容を取得するのに利用。

##### selenium
Webブラウザの操作を自動化できる。
これでOpenWorkのURLを取得する。

##### webbrowser
URLを開くのに使用した。
他の機能は知らない。


## プログラムの流れ

1\. クリップボードの内容を取得する
2\. "openwork 会社名"で検索
3\. 検索結果の一番最初のURLを取得する
4\. 取得したURLを開く

## 実際のプログラム
```open_in_openwork.py
import pyperclip
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
import webbrowser

def main():
    # クリップボードから会社名を取得
    company = pyperclip.paste()

    # スクレイピング時にブラウザを開かないように設定
    options = Options()
    options.add_argument('--headless')

    # Chromeドライバーの読み込み
    driver_path = r"D:\Program Files\chromedriver.exe"

    # 検索
    search_url = f"https://www.google.com/search?q=openwork+{company}"
    browser = webdriver.Chrome(driver_path,options=options)
    browser.get(search_url)

    # 一番上の検索結果のURLを取得
    target_url = browser.find_element(By.CLASS_NAME,"MjjYud").find_element(By.TAG_NAME,"a").get_attribute("href")

    # 取得したURLを開く
    webbrowser.open(target_url)

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

## 最後に
プログラムを実行するのも手間をかけたくないので、
バッチファイルを作ってClaunchに登録してホットキーを設定したらラクチン。
Python Flask *locals()の使い方

**ChatGPT:**
Flaskの`render_template()`関数には、引数を辞書形式で指定する方法以外にも、引数を`*args`として渡すことができます。以下は、`*args`を使用して引数を渡す方法の例です。
```python
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    name = "Alice"
    age = 25
    return render_template('index.html', *locals())

```
上記の例では、`*locals()`を使用して、`index()`関数のローカル変数を全て引数として渡しています。`locals()`関数は、現在のスコープに存在する変数を辞書形式で返す関数です。
テンプレート中では、引数を通常通り参照することができます。
```html
<!DOCTYPE html>
<html>
  <head>
    <title>Flask Template Example</title>
  </head>
  <body>
    <h1>Hello, {{ name }}!</h1>
    <p>You are {{ age }} years old.</p>
  </body>
</html>

```
上記の例では、`{{ name }}`と`{{ age }}`が`index()`関数のローカル変数である`name`と`age`に置き換えられ、`Hello, Alice!`と`You are 25 years old.`という出力が得られます。
ただし、`*args`を使用する場合、引数の順序に注意する必要があります。`*args`を使用すると、引数をタプルとしてまとめたものが`render_template()`関数に渡されます。そのため、渡された引数をテンプレート内で参照するには、引数の順序を正確に把握する必要があります。


 --------
FreeBSDタッチパッドをoffにする


xinput listで、タッチパッドのidを調べます。

```
$ xinput list
⎡ Virtual core pointer                    	id=2	[master pointer  (3)]
⎜   ↳ Virtual core XTEST pointer              	id=4	[slave  pointer  (2)]
⎜   ↳ System mouse                            	id=6	[slave  pointer  (2)]
⎜   ↳ GlidePoint                              	id=11	[slave  pointer  (2)]
⎜   ↳ Logitech USB Receiver                   	id=13	[slave  pointer  (2)]
⎣ Virtual core keyboard                   	id=3	[master keyboard (2)]
    ↳ Virtual core XTEST keyboard             	id=5	[slave  keyboard (3)]
    ↳ System keyboard multiplexer             	id=7	[slave  keyboard (3)]
    ↳ Power Button                            	id=8	[slave  keyboard (3)]
    ↳ Sleep Button                            	id=9	[slave  keyboard (3)]
    ↳ AT keyboard                             	id=10	[slave  keyboard (3)]
    ↳ Logitech USB Receiver
```

ここでは、11番につながっているので、11番をoffにします

```
$ xinput set-prop 11 "Device Enabled" 0
```
ACM（AWS Certificate Manager)とは何か？

最近、ACMを複数利用する事を考える機会があったので、ACM（AWS Certificate Manager）とは、何か？について、まとめました。
--

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/8caefe93-5be8-4ef6-8930-b46fbc7dd435.png)
https://aws.amazon.com/jp/certificate-manager/

ACM（AWS Certificate Manager）は、AWSが提供するSSL/TLS証明書の発行、管理、および自動化を行うフルマネージドサービスです。ACMを使用することで、AWSリソース（ELB、CloudFrontなど）に証明書を適用し、Webサイトやアプリケーションのセキュリティを向上することができます。

ACM（AWS Certificate Manager）では、DNS validationによるドメイン名の所有権確認が可能です。DNS validationを使用する場合、ACMは自動的にCSRに基づいてTXTレコードを生成し、ドメイン名の所有者に指示を出します。所有者は、指示されたTXTレコードをDNSに追加することで、ドメイン名の所有権を確認します。ACMは、TXTレコードが正常に追加されたことを確認することで、ドメイン名の所有権を確認し、SSL/TLS証明書を発行します。

__ACMでは、以下のような機能が提供されています。__

__1.SSL/TLS証明書の発行__
ACMを使用することで、無料でSSL/TLS証明書を発行することができます。また、証明書の有効期限が切れる前に自動的に更新する機能も提供されます。

__2.マネージドサービス__
ACMは、フルマネージドサービスであり、証明書の発行、管理、更新、および削除を自動的に処理します。これにより、証明書の管理に必要な手間や費用を削減できます。

__3.AWSサービスとの統合__
ACMは、Amazon Elastic Load Balancer（ELB）、Amazon CloudFront、Amazon API Gateway、AWS Elastic BeanstalkなどのAWSサービスと統合されています。これにより、証明書の適用を簡素化し、Webサイトやアプリケーションのセキュリティを向上できます。

__4.多要素証明書のサポート__
ACMは、SAN（Subject Alternative Name）証明書をサポートしており、1つの証明書で複数のドメイン名を保護することができます。

__5.セキュリティの向上__
ACMは、証明書のプライベートキーをKMS（Key Management Service）で保護することで、高度なセキュリティを提供します。また、自動的な証明書の更新機能により、セキュリティを保つことができます。

__6.ACMでは、パブリック証明書とプライベート証明書の2種類の証明書を発行することができます。__
パブリック証明書は、Webサイトやアプリケーションの公開部分に使用されます。
一方、プライベート証明書は、VPC内のリソース間の通信などのように、内部的に使用されます。

__7.注意点__
__ELB に証明書をインポートする場合は、その ELB があるリージョンで証明書を作る必要がある。__
東京リージョンのElastic Load Balancer（ELB）に、バージニアリージョンで発行したACM証明書を適用することはできません。
ただ、CloudFront に証明書をインポートする場合は、バージニア北部で証明書を作る必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2920213/0accdb0c-632c-8fa2-1fc4-c65ba50b691e.png)
https://aws.amazon.com/jp/certificate-manager/faqs/

__ACM (AWS Certificate Manager) で取得した証明書の形式は、通常PEM形式です。__
PEM (Privacy Enhanced Mail) は、データの暗号化、署名、または認証に使用されるX.509証明書の一般的な形式です。
ACMで証明書を取得すると、PEM形式の証明書、中間証明書、およびルート証明書を含むzipファイルをダウンロードできます。PEM形式の証明書は、通常、Webサーバー、ロードバランサー、または他のサービスにインポート出来ます。
PEM形式の証明書は、テキストファイルで、BEGIN CERTIFICATEとEND CERTIFICATEで囲まれたASCIIテキストで構成されます。例えば、以下のような形式です。
~~~
-----BEGIN CERTIFICATE-----
ABCDEFGHIJKLMNOPQRSTU123vxxxxxxxxxxxxxxx
-----END CERTIFICATE-----
~~~
PEM形式の証明書をインポートする際には、通常、Webサーバーの設定や、ロードバランサーのリスナーの設定などで、ファイルをアップロードして指定する必要があります。

少しでも、学習の参考にして頂ければ、と思います。
--
FreeBSD インストールノート


## 基本システムのインストール

まず、FreeBSDのインストールメディアを作り、基本システムをインストールします。英語なので少し読みにくいのですが、FreeBSDはシステムがきれいなので、インストールはやりやすいでしょう。僕のマシンは古いマシンで、ディスクの容量も小さいので、ファイルシステムはUFSでインストールしました。

#### sudo,suを許可

userをwheelグループに追加します。

```
# visudo
%wheel ALL=(ALL:ALL) ALL # コメントアウトを外す
# vi /etc/group
wheel:*:0:root,user      # userをwheelグループに追加
```

## xorg、Desktop Environmentのインストール。

#### xorgのインストール

グラフィカルインターフェースのために、xorgをインストールします。

```
# pkg install xorg
```

```/usr/local/etc/X11/xorg.conf
Section    "Module"
    Load   "freetype"
EndSection
```

```/usr/local/etc/X11/xorg.conf.d/input.conf
Section    "Files"
    FontPath    "/usr/local/share/fonts/dejavu"
EndSection
Section "InputClass"
        Identifier      "libinput keyboard catchall"
        MatchIsKeyboard "on"
        MatchDevicePath "/dev/input/event*"
        Driver          "libinput"
        Option          "XkbRules" "evdev"
        Option          "XkbModel" "jp106"
        Option          "XkbLayout" "jp"
EndSection
```
#### DEのインストール

DEはxfce,display managerはlightdmにしました。

```
# pkg install xfce xfce4-goodies lightdm lightdm-gtk-greeter
```

```/etc/rc.confに追加
dbus_enable="YES"
lightdm_enable="YES"
```
これで、次回起動したらlightdmが動き、ログイン画面になります。

#### 日本語環境

```$HOME/.xprofile
#!/bin/sh
export LANG=ja_JP.UTF-8
export LC_ALL=ja_JP.UTF-8
export LC_CTYPE=ja_JP.UTF-8
 
export DefaultIMModule=fcitx
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
export XMODIFIER=@im=fcitx
/usr/local/bin/mozc start
fcitx -r -d
````

```
# pkg install ja-font-std ja-font-vlgothic ja-font-takao
# pkg install ja-fcitx-mozc ja-mozc-server ja-mozc-tool zh-fcitx zh-fcitx-configtool
```

#### ブラウザのインストール

```
# pkg install firefox
```
RFC4180に準拠しないCSVを考える

# RFC4180に準拠しないCSVを考える
RFC4180を実装したくないので独自仕様を考えます。嫌いな人はBBしてください。

## そもそもRFC4180とは？

https://www.ietf.org/rfc/rfc4180.txt

有志による翻訳

http://www.kasai.fm/wiki/rfc4180jp

フォーマットについて抜粋したものが以下です
- カラム名を示すヘッダ行の有無は自由
- 値をカンマで区切る
- 値がカンマを持つ場合は""で囲む
- 改行(CRLF)で次のレコード
- 値が改行を持つ場合も""で囲む
- 値がダブルクォーテーションを持つ場合はダブルクォーテーションを2つ重ねてエスケープする
- ファイル末尾の改行の有無は自由
- 「Infomational(情報提供)」なので必ず従う必要はない

## RFC4180に対する評価

筆者個人の評価になりますが、あまり良いものではないです
理由としては以下が挙げられます
- 値に改行を持つ場合はテキストエディタで開くとフォーマットが崩れているように見える
- 多くのファイル入出力では行ごとに読み込むがこの仕様では前の行の状態を見なければならない
- 完全に対応できているライブラリは多くはない
- CSVを安易に採用する現場で外部ライブラリやOSSの使用が許可されていない事が多い

## 独自仕様の要点

上記の通り、従う必要はなく、送信側と受信側で形式に合意があれば何の問題もない。よって独自仕様を考える
独自仕様を考えるにあたって以下に注意する必要がある
- 値にカンマを持つ場合
- 値に改行を持つ場合
- エスケープ文字が値に含まれている場合
- エスケープ文字が何もエスケープしていない場合

### その他考慮する点

- 行ごとにフィールド数が異なる場合の扱い
- コメント行

# 筆者の独自仕様

プログラミング言語に倣う

- 値がカンマを持つ場合はカンマの前にバックスラッシュを付与する
- 値が改行を持つ場合は改行を\r\n、\r、\nのいずれかで示す
- 値がバックスラッシュを持つ場合はバックスラッシュを2つ重ねる
- バックスラッシュが単体で存在している場合は無視する

文字コードやヘッダ行については送受信間で応相談

## 感想

ここまで書いといてなんですが、更に外部に展開する可能性を考えると最初から標準仕様に従って車輪を再再再発明するほうが楽です。逆にその場対応なら改行を扱わないとするので十分です

誰かちゃんとした標準仕様作ってくれないかな
Ubuntu 22.04でSTM32 VSCode Extensionを導入してみる

# STM32 VSCode Extensionとは
参照 : https://newsroom.st.com/media-center/press-item.html/t4536.html
CubeMX, CubeIDEで生成したプロジェクトをVisual studio codeで扱えるようにする公式の拡張機能のようです。
今までは非公式の拡張機能しかなく、環境構築や設定にそこそこ苦労する印象が有りましたが、公式のものですのでそのへんの面倒さはかなり改善されるのではないかと期待しています。

# 環境
- NUCLEO-F767ZI
- Ubuntu 22.04

# 導入
まずは以下のツールのインストールが必要です。
- STM32CubeCLT
- STM32CubeIDE
- Embedded Tools

STM32CubeIDEはプロジェクトの生成に必要ですが、導入記事が多いのでここでは省略します。

- STM32CubeCLT
サードパーティ製IDEでCubeIDEのような機能を使えるようにするツールみたいです。（今までこんなのあったっけ）

https://www.st.com/en/development-tools/stm32cubeclt.html からダウンロードします。
Ubuntu22.04なのでSTM32CubeCLT-DEBをダウンロードすればいいんですが、STM32CubeCLT-Lnxのほうがアンインストールが楽そうなのでそちらを選びました。Ubuntuの場合はどちらを使っても大丈夫みたいです。

ダウンロードしてzipファイルを解凍したら、
```
sudo sh st-stm32cubeclt_1.12.0_14980_20230301_1550_amd64.sh
```
と入力するとこんな感じの画面が出てきます。
![Screenshot from 2023-03-16 18-22-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017430/e7256384-3a06-4952-b48c-becd39c17945.png)
下ボタンをおしてスクロールするとACCEPT / I DO NOT ACCEPTが出てくるのyを押してインストールします。

![Screenshot from 2023-03-16 18-22-36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017430/d0120e23-475c-7889-4412-a392f114ff50.png)

これでインストール完了です。

- Embedded Tools
STM32 VSCode Extensionが依存してるVScode拡張機能です。Vscodeの拡張機能欄でEmbedded Toolsと入力してインストールしましょう。

- STM32 VS Code Extension
上と同様にVscodeの拡張機能欄でSTM32 VS Code Extensionと入力してインストールしましょう。


# 使ってみる
まずはCubeIDEで適当にプロジェクトを作って保存します。
次に、vscodeを開いて左下のSTM32と書いてある蝶のマークをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017430/92782d46-2b90-fe1c-877f-cc6092451e87.png)

Import a local projectをクリックして、CubeIDEで作ったプロジェクトをimportします。 .cprojectファイルをクリックしてOpen projectします。（隠しファイルを表示する設定にしないと.cprojectは現れません）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017430/781c036f-d553-fac0-42c5-74eadf4de0c8.png)

その後、vscodeで開発する用にいくつかファイルが自動生成されます。intellisenseやデバッグの設定もここで自動で生成されます。

これで設定は完了のはずなんですが、このままだと僕の環境だとデバッグでエラーが出ました。
```
Could not find the path to "ST-Link_gdbserver". Ensure STM32CubeIDE is installed.
```
ST-Link_gdbserverがうまいこと認識されていないっぽいので、無理やり認識させます。.vscode/launch.jsonを開いて、"debugServerPath"の値を
```
which ST-LINK_gdbserver
```
で出力されたパスに書き換えます。
```launch.json
 "debugServerPath": "/opt/st/stm32cubeclt_1.12.0/STLink-gdb-server/bin/ST-LINK_gdbserver",
```

これでデバッグを行うことができます。

右上の三角ボタンを押すとデバッグ構成を選択するという画面が出るので、Launchを選びます。
ここでbuildとflashが行われ、デバッグができるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017430/b15c5bca-cf1f-997e-eb69-cf0dcb3373c2.png)

あとはブレークポイントなど設定していい感じにしてください。
![Screencast-from-03-16-2023-06_28_11-PM.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2017430/4ce96f96-b72d-b0cd-bd45-b5f769e5cfea.gif)

# 参考

https://marketplace.visualstudio.com/items?itemName=stmicroelectronics.stm32-vscode-extension
UILabelの背景をグラデーションさせる

## 概要
`UILabel`の背景にグラデーションを設定する時のメモです。


## 実装
カスタムのUILabelを作成しました。
以下のコードでラベルにグラデーションを設定できます。
画像のような感じになります。

また、ラベルの周りに適当なサイズの余白を加えました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/9027f153-779e-ff75-1524-79400fb744af.png" width="300" />

```swift:GradationLabel.swift
class GradientLabel: UILabel {
    override class var layerClass: AnyClass {
        return CAGradientLayer.self
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        translatesAutoresizingMaskIntoConstraints = false
        textAlignment = .center
        textColor = .white
        text = "hoge"
        
        if let gradientLayer = layer as? CAGradientLayer {
            gradientLayer.colors = [
                UIColor.systemPurple.cgColor,
                UIColor.systemPink.cgColor,
            ]
            gradientLayer.startPoint = CGPoint(x: 0, y: 0)
            gradientLayer.endPoint = CGPoint(x: 1, y: 1)
        }
        
        layer.cornerRadius = 2
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override var intrinsicContentSize: CGSize {
        var intrinsicContentSize = super.intrinsicContentSize
        intrinsicContentSize.height += 4
        intrinsicContentSize.width += 4
        return intrinsicContentSize
    }
}

```
ssh-keygenを作ってSSH接続をできるようにする

# ssh-keygenとは
ssh-keygenは、SSH（Secure Shell）プロトコル用の鍵ペアを生成するコマンドラインツールです。
公開鍵認証方式を使用してリモートマシンへの接続をセキュアに行うために使用されます。

# ssh-keygenを使って鍵を作成する方法
### 鍵ペアの生成
- 実行すると、キーペア（公開鍵と秘密鍵）の保存先やパスフレーズの入力が求められます。
- デフォルトの保存先は、ホームディレクトリの .ssh フォルダ内です。


```
ssh-keygen
```





### 保存先の指定や生成される鍵ペアの名前を変更する
- 特定のファイル名やディレクトリで鍵ペアを保存したい場合は、-f オプションを使用してファイル名を指定できます。


```
ssh-keygen -f /path/to/your/custom-key
```
### 鍵のタイプとサイズの指定
- デフォルトでは、RSAアルゴリズムを使用した2048ビットの鍵ペアが生成されます。
- 異なるアルゴリズム（例：ed25519）や鍵サイズを使用したい場合は、-t（タイプ）オプションと-b（ビット数）オプションを指定できます。

```
ssh-keygen -t ed25519 -b 256
```
### パスフレーズの設定
- 鍵ペアにパスフレーズを設定することで、秘密鍵の安全性を高めることができます。
- パスフレーズが設定されている場合、SSH接続時にパスフレーズの入力が求められます。
- パスフレーズは、鍵生成時に対話式で設定するか、-N オプションを使用して設定できます。

```
ssh-keygen -t rsa -b 4096 -N "your-passphrase"
```
生成された鍵ペアは、デフォルトでは次のファイルに保存されます。
```
公開鍵: ~/.ssh/id_rsa.pub
秘密鍵: ~/.ssh/id_rsa
```
公開鍵をリモートサーバーの ~/.ssh/authorized_keys ファイルに追加することで、対応する秘密鍵を持つユーザーがパスワードなしでSSH接続できるようになります。
Laravel リクエスト時の形式でLocalファイルを取得する方法

## はじめに
業務の中で、リクエスト時の形式でLocalファイルを取得する必要があり、この先も頻繁に使用すると感じたのでメモを残します。

## 取得方法
ローカルのファイルは、以下のように「**UploadedFile**」を使用すると、リクエストでファイルを取得してくる時と同じ形式で取得できます。

``` php:code
Illuminate\Http\UploadedFile

$file = new UploadedFile(storage_path("app/public/test.pdf"), "test.pdf");

```
リクエスト時の形式で取得できることによって以下のように「**getClientOriginalExtension**」を使用して拡張などの取得も可能になります。
``` php:code
$extension = $file->getClientOriginalExtension();
```
[AWS Q&A 365][Redshift]AWSのよくある問題の毎日5選 #6

# 1. Amazon Redshiftとは何ですか？それはどのように機能しますか？
回答：Amazon Redshiftは、Amazon Web Services（AWS）が提供するデータウェアハウスサービスで、ユーザーが大量のデータをコスト効果的かつスケーラブルな方法で格納および分析できるようにします。列指向ストレージ技術と大規模並列処理（MPP）を使用して、大規模データセットに対する高速なクエリ性能を提供します。

# 2. Amazon Redshiftを使い始めるにはどうすればいいですか？
回答：Amazon Redshiftを始めるには、AWSアカウントに登録し、Redshiftクラスタを作成する必要があります。これは、AWS Management ConsoleまたはRedshift APIを使用して行うことができます。クラスタが稼働していると、データをロードしてSQLを使用してクエリを開始できます。

# 3. Amazon Redshiftについてもっと学ぶためのリソースは何ですか？
回答：Amazon Redshiftについて学ぶための多くのリソースがあります。これには、Amazon Redshift Management Guide、Amazon Redshift Database Developer Guide、SQLリファレンス、システムテーブルとビュー、チュートリアル、機能ビデオ、およびAmazon Redshift Getting Started Guide自体が含まれます。

# 4. Amazon Redshift Getting Started Guideの最新バージョンの新機能とアップデートは何ですか？
回答：Amazon Redshift Getting Started Guideの最新バージョン（2021年6月30日更新）には、一般的なデータベースタスクの開始、データレイクのクエリ、リモートソース上のデータのクエリ、データの共有、およびAmazon Redshiftデータを使用した機械学習モデルのトレーニングについての新しいセクションが含まれています。また、新しいサンプルロード手順が含まれています。

# 5. Amazon Redshiftを使用してリモートソース上のデータを照会する方法は？
回答: Amazon Redshiftを使用してリモートソース上のデータを照会するには、Amazon Redshift Spectrum機能を使用できます。これにより、標準SQLを使用してAmazon S3、Hadoop、または他のデータストアに保存されているデータを照会できます。また、Amazon Redshift連携クエリ機能を使用して、1つのSQLステートメントを使用して複数のデータソース間のデータを照会することもできます。