OmniAICreator/Qiita-1.07M huggingface dataset:
Git for Windows(Git Bash)にコピペした際「01~」が末尾に付いてくる場合の対処法

# 困った

vscodeでGit Bashをデフォルトターミナルにして使っていると、
文字をターミナルにコピペした際末尾に **「01~」** が付いてきてしまう問題が発生。

# 対処法

調査してみるとどうやら`~/.bashrc`に以下を追記すれば良いらしい

```bash
# setting for git bash bug on vscode
bind 'set enable-bracketed-paste off'
```

無事解決しました！

# 他の症状

今回の「01~」が付いてきてしまう問題の他に、
文字数によって **「~」** だったり **「[201~」** が付いてきてしまうケースもあるらしい。

以上。この記事がどなたかのお役に立てれば幸いです。
SoledJSでGoogleの拡張を作ったらReactでできたページにもHTMLが表示されてしまう

# はじめに

ReactでGoogleの拡張が作れることを最近知ったので試しに作ろうとしたところ問題が起きて解決にすこし手間取ってしまったのでまとめていきます。

この機会にSolidJSで拡張機能を作成したので、何が問題なのかつかみづらかったので時間がかかりました

# 問題

以下のリポジトリを利用して拡張機能を追加しました
特に手などは加えずにデフォルトのまま実行しました

https://github.com/fuyutarow/solid-chrome-extension-template

するとReactで以前作成したページ(デプロイしたもの)を表示すると下に以下のような文字が表示されるようになりました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/810513/f596738a-66bc-ea54-c580-2686fdcc5a6e.png)

拡張機能を削除すると消えるので、拡張機能のどこかが悪さしているようでした

# 解決方法

`/src/pages/content/components/Demo/index.tsx`に問題がありました

```tsx:/src/pages/content/components/Demo/index.tsx
import App from "@src/pages/content/components/Demo/app";
import { render } from "solid-js/web";

const root = document.createElement("div");
root.id = "extension-root";
document.body.append(root);

render(App, root);
```

ポイントは`document.createElement("div")`のところです。これはページの`div`属性に対して拡張機能でかかれたものを子要素として追加しています。

今回はポップアップに子要素を追加すればよいので(ブラウザのポップアップ属性)、以下のように変更しました

```tsx:/src/pages/content/components/Demo/index.tsx
import App from "@src/pages/content/components/Demo/app";
import { render } from "solid-js/web";

const root = document.createElement("popup");
root.id = "extension-root";
document.body.append(root);

render(App, root);
```

無事消えました！ちなみにあの文字は`/src/pages/content/components/Demo/app.tsx`の文字が表示されていました

# おわりに

やっと拡張機能の開発がスムーズにできそうで色々わくわくしています。
SolidJSもこの機会に試して記事にできたらと思っています

# 参考

https://github.com/fuyutarow/solid-chrome-extension-template
AWS Certified Cloud Practitioner合格体験記

# はじめに
AWSの資格を初めて取得したので簡単に記録を残しておきます。

# AWS Certified Cloud Practitionerとは
https://aws.amazon.com/jp/certification/certified-cloud-practitioner/

言わずと知れたAWSの入門資格。
内容は以下の構成。
- クラウドのコンセプト(26%)
- セキュリティとコンプライアンス(25%)
- テクノロジー(33%)
- 請求と料金設定(16%)

他のクラウド資格と比較すると、「請求と料金設定」、即ち料金プランなどに関しての問題がある程度の比重を占めているのが特徴かも知れません。

# 個人的バックグラウンド
[OCIの記事](https://qiita.com/tkuribayashi/items/f17dc8a321766caa0e4d)、[GCPの記事](https://qiita.com/tkuribayashi/items/573f675b78be67bda549)、[Azureの記事](https://qiita.com/tkuribayashi/items/484588a27f1f16200a7d)で書いた通り。

- AWS
    - 実務経験なし
    - 趣味や社内研修で多少触ったことがある程度
- GCP
    - 2年ほど実務で使用
        - アプリケーション開発者ロールしかやっていないので、触ったことのない機能の方が多い
    - Cloud Digital Leader取得
- Azure
    - 1年半ほど実務で使用
        - アプリケーション開発者ロールしかやっていないので以下同文
    - AZ-900取得
- Oracle Cloud
    - 経験なし、Oracle Cloud Infrastructure Foundations 2021 Associate取得

# 学習方法
- APNのトレーニング(https://aws.amazon.com/jp/partners/training/)
    - 会社のトレーニングコースとして提供されていたもの。一通りの説明資料と簡単な模擬問題。
- A Cloud Guru
    - 無料で受けられる講義のみ受講。ラボ・模擬試験は有料だったためパス。

# 試験
AZ-900のときと同様に、Pearson VUEを利用し近所のテストセンターにて受験しました。
試験会場には15分前には着いて、本人確認や写真撮影などを受付で行い、その後入室して受験という形です。
身分証明書を忘れたりしなければ、自宅などの遠隔試験よりも楽に受けられると思います。(AZ-900のときと同じ感想)

# 結果&所感
65問90分の試験で700点が合格点のところ、815点で合格。所要時間は25分程度でした。
合否は試験終了後にすぐ画面上で確認できましたが、点数は後日メールにて受け取るスコアレポートにて分かります。
パブリッククラウドサービスに関する一般的な知識を持っている前提においては、AWSのサービス名を覚えておけばある程度簡単に合格点に達することができるレベルだと感じました。
問題内容に関しては、半分くらいは確信を持って回答できるもの、残りは少々迷いつつも、例えば複数の問題の選択肢を見比べると自ずと答えが見えてくるものなどがあったりしました。
1-2割の問題に関しては、問題自体が少々曖昧で、細かい知識を持っていないと回答しづらいものもありました。

# 今後
AZ-900の記事で書いた、情報処理安全確保支援士の講習をまだ受けていなかったのでとりあえずそれをこなした後、GCP ACE(or PCA)/AZ-104/AWS SAAのどれを受けるか迷っているところです。
カバレッジについて

## はじめに
テストについて勉強していると、***カバレッジ***という単語が出てきましたがなんのこっちゃという感じでした。そこでカバレッジの概要を掴むために調べた記事をまとめてみました。

## カバレッジとは
以下記事によるとカバレッジとは ***『対象範囲に対して、全体の内どれくらい網羅しているかを示す指標のことです。ソフトの品質を担保するための一つの指標として使われます。』*** とのこと。ソフトウェアの動作やプログラムのパスなどがとり得る状態の全体に対して、どのくらい網羅してテストするかということのようです。記事では論理構造の全体に対してどれほど実行できたかということを尺度としていました。

参考ウェブサイト
[【徹底解説】カバレッジ（網羅率）とは？ソフトウェア開発における意味と3つの基準について解説](https://service.shiftinc.jp/column/4547/)

## C0,C1,CDC,MC/DC,MCCカバレッジとは
カバレッジには段階があり、基本的に以下の順で網羅率の高さが異なっています。カバレッジが高ければその分ソフトの品質は担保されますが、テスト工程が増えるため予算や期間に応じてどの程度テストするのかは考えたほうが良いでしょう。

***カバレッジ低***&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;→&nbsp;&nbsp;&nbsp;&nbsp;***カバレッジ高***
C0→C1→CDC→MC/DC→MCC 

それぞれの詳細については以下の記事が分かりやすかったです。

参考ウェブサイト
[ホワイトボックステストにおけるカバレッジとテストケース(C0, C1, C2, CDC, MC/DC, MCC)](https://dlrecord.hatenablog.com/entry/2020/04/29/201223)
 [猫でも使えるソフトウェアのテスト網羅（4）：C1カバレッジの弱点とエンジニアの信念](https://monoist.itmedia.co.jp/mn/articles/1609/07/news006_2.html)

## nスイッチカバレッジとは
nスイッチカバレッジという単語は、ホワイトボックステストで主に用いられる上記のC0などとは異なる文脈で使われるようでした。この単語はブラックボックステストの一つである***状態遷移テスト***の文脈で使われます。１つの状態を１つのスイッチに例え、n個の状態を経由した遷移をテストするという意味で使用されます。これもnの値を上げるとソフトの品質は保証されますが、テスト工数が大幅に増えるため、予算や期間に応じてどの程度テストするのかは考えたほうが良いでしょう。

### そもそも状態遷移テストとは
通常、入力条件が同じならば同じ出力結果になるという前提に立ってテストケースを設計します。しかしプログラムによっては、現在の状態や過去の履歴によって、同じ入力データを用いても異なる振る舞いをすることがあります。
こういった場合を網羅するために複数の手順を組み合わせたテストを行うのですが、それを設計する際に用いるのが状態遷移テストです。
具体的には、状態と状態を変化させるイベントを「状態遷移図」「状態遷移表」にまとめてテストケースを作成します。
詳細は以下のページで分かりやすく説明されていました。

参考ウェブサイト
[Jasst Tohoku 状態遷移テスト](https://www.jasst.jp/symposium/jasst19tohoku/pdf/S5-2.pdf)
[状態遷移テストと1スイッチカバレッジ](https://note.com/yumotsuyo/n/nd3099b40dc1f)

## さいごに
テストについて少し勉強してまとめてみました。基本的に詳細は他記事に書いてあるので、それぞれ気になった方はそちらを見てください。開発時間が限られている中で、いかに重要な所にフォーカスしてテストを設計できるかが大事なんじゃないかなと思いました。
go のわかりにくい型推論

# これは何？

go の型推論が思いがけない動作をしたのでその記録。

# 普通の例

```go:go1.19
func main() {
	f := func(i int) uint8 {
		return uint8((1 << i) % 10)
	}
	fmt.Println("f(5) =", f(5)) //=> f(5) = 2
}
```

$2^n$ を 10で割った余りを `uint8` で返すという普通の関数。

2の5乗 は 32 なので、 `f(5)` は 2 になる。順当。

# 思いがけなかった例

上記の関数 `f` に 10 を入れると

```go:go1.19
	fmt.Println("f(10) =", f(10)) //=> f(10) = 0
```

$2^{10}$ は 1024 なので `f(10) = 4` となるかと思いきや、ゼロになる。

私は意外だった。

# いろいろ試した

## 一回変数で受ける

```go:go1.19
f := func(i int) uint8 {
	n := 1 << i
	return uint8(n % 10)
}
fmt.Println("f(10) =", f(10)) //=> f(10) = 4
```

一回受けた変数 `n` は `int` になるらしく、ちゃんと 4 を返す。

## `1` ではなく `one` にする

```go:go1.19
f := func(i int) uint8 {
	const one = 1
	return uint8((one << i) % 10)
}
fmt.Println("f(10) =", f(10)) //=> f(10) = 0
```

`one` にしても untyped int のままなので、やはり即値を書くのとおなじになる。

## `const one int = 1`

```go:go1.19
f := func(i int) uint8 {
	const one int = 1
	return uint8((one << i) % 10)
}
fmt.Println("f(10) =", f(10)) //=> f(10) = 4
```

`one` が `int` なら、オーバーフローしない。

## むだに `int(0)` を足す

```go:go1.19
f := func(i int) uint8 {
	return uint8(int(0) + (1<<i)%10)
}
fmt.Println("f(10) =", f(10)) //=> f(10) = 4
```

`int(0)` を足すと `1<<i` の `1` が `int` だと推論される。

## `1` ではなく `'\x01'` にする

```go:go1.19
f := func(i int) uint8 {
	return uint8(('\x01' << i) % 10)
}
fmt.Println("f(10) =", f(10)) //=> f(10) = 0
```

untyped rune でも untyped int と同様。


## 式の途中に負を入れる

負の値なら `uint8` だと推論されないだろうと思うと

```go:go1.19
f := func(i int) uint8 {
	return uint8(-1 + 1 + (1<<i)%10)
}
fmt.Println("f(10) =", f(10)) //=> f(10) = 0
```

そうでもない。
ならばと順序を変えると

```go:go1.19
f := func(i int) uint8 {
	return uint8(-1 + (1<<i)%10 + 1) //=> -1 (untyped int constant) overflows uint8
}
fmt.Println("f(10) =", f(10))
```

オーバーフローでエラーになる。

## 関数に渡す場合も同様

```go:go1.19
func main() {
	u8 := func(x uint8) { fmt.Println("x =", x) }
	u32 := func(x uint32) { fmt.Println("x =", x) }

	i := 10
	u8((1 << i) % 10)  //=> x = 0
	u32((1 << i) % 10) //=> x = 4

	const ci = 10
	u8((1 << ci) % 10)  //=> x = 4
	u32((1 << ci) % 10) //=> x = 4
}
```

関数に渡す場合でも同様に、引数の型によって untyped int の型が推論され、計算結果に影響を与える。

ただし、 シフトする前に型を推論するのは untyped ではない値に遭遇した場合のみ。

上記コードの `i` は untyped ではないので `1 << i` にある 1 の型を推論する必要が生じる（しかし、推論に `i` の型は使わない）。
上記コードの `ci` は untyped なので、 `1 << ci` にある 1 の型を推論する必要がなく、untyped のまま `(1 << ci) % 10` を計算できる。

# まとめ

というわけで go 言語は

```go:go1.19
uint8((1 << i) % 10)
```

のような式がある場合、`uint8` の部分に書かれる型によって `1` の型が推論され、推論の結果オーバーフローになったりならなかったりするという仕様っぽい。

私は
`(1<<i) % 10` の部分は `uint8` の部分とは無関係に計算され、その結果を `uint8` にキャストするんだと思っていたんだけど、そうではない。

また。

`(式A) + (式B)` のような式があると、式A の型は 式B の中にある untyped な型の推論に影響を与えるので 式A の型が 式B の計算結果に影響を与える。

関数呼び出しでも同様で `関数(式X)` のように書く場合、関数の引数の型が 式X の中にある untyped な型の推論に影響を与えるので 関数の引数の型が 式X の計算結果に影響を与える。

大変わかりにくく、トラブルの原因になりやすい仕様だと思うけど、変わらないと思う。気をつけよう。

# おまけ: zig の場合

ビット長不定の定数があるもう一つの言語ということで zig の場合を見てみる。

zig で似たようなことを試みると、

```zig:zig0.10
fn f(a: i32) u8 {
    return @intCast(u8, (1 <<| a) % 10);
    // ↑ error: LHS of shift must be a fixed-width integer type, or RHS must be comptime-known
}
```

zig は、ビット長不定の値をシフトできないことがわかる。（エラーメッセージにある通りシフト量がコンパイル時にわかっているのであればOK）

いろいろ考えたんだけど、今の所 go で起きているようなわかりにくい状況を引き起こす方法は思いついていない。

よくできていると思う。
A-FrameとGoogle BlocklyでAR表示するサイトを作ってみた

# 「ARを作ろう」
A-FrameとGoogle Blocklyを利用してAR表示する「ARを作ろう」はこちら。
https://kaihatuiinkai.jp/nesopuro2/ar/

中学校　技術科「ネットワークを利用した双方向性のあるコンテンツのプログラミング」を学習するための教材として開発しました。
![ar_earth.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509199/2e197c1e-5fbf-3a84-b68f-214b801ca3d0.jpeg)


# ARを簡単に表示できるA-Frame
カメラで撮影している現実の画像にデジタルコンテンツを重ねるAR（拡張現実、以下AR）の作成が難しいと思っていました。そう、A-Frameに出会う前までは。A-Frameを使うとブラウザ上でARが簡単に表示できます。

```JavaScript:ar_test1.html
<!DOCTYPE html>
<html>
<head>
  <meta charset='UTF-8'>
  <script src='https://aframe.io/releases/1.3.0/aframe.min.js'></script>
  <script src='https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar-nft.js'></script>
</head>
<body>
  <a-scene>
    <a-marker preset='hiro'>
      <a-box position='0 0 0' scale='1 1 1' color='blue' ></a-box>
    </a-marker>
    <a-entity camera></a-entity>
  </a-scene>
</body>
</html>

```
テストサイトはこちら
https://kaihatuiinkai.jp/ar/ar_test1.html

# Google Blocklyでタグを編集
Google BlocklyのブロックでA-Frameのタグを組み込んで、ARサイトを編集できるようにしました。
![ar01.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509199/83e72bd4-8af1-eaeb-10c6-cb35f13bbcfa.png)


![ar02.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509199/bc3d0671-93ac-c955-1718-090c03ccd09c.png)

画像をアップロードして、テクスチャとして立体表面に張り付けることもできます。
どうぞご活用ください。
Xcodeでのローカライズがうまくいかないときの対処法


結論からお伝えするとキャッシュをクリアすれば多分直ります。

上部メニューからProduct→Clean Build Folderをタップ

![スクリーンショット 2022-11-16 22.12.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/494487/d23baeba-3469-9759-d8ac-cf02186c5040.png)

もしかしたらバージョンによっては名前が違うかもですが、Cleanという名前の物があればそれを押せばいけると思います。

シミュレーターで起動してて、端末をiPad ProからiPad Airに変えた際にこの現象が起きて何が原因なのか調べたらキャッシュが問題らしいという記事を見つけ対処しました。

参考記事はこちら。
https://nackpan.net/blog/blog/2014/05/28/xcode-localize-trouble/
【OpenLayers】ベクトルタイルを表示する

## はじめに
この記事は#30DayMapChallenge2022 16日目の記事です。
テーマはMinimalです。
OpenLayersを使って国土地理院のベクトルタイルを表示してみます。

![image](https://raw.githubusercontent.com/tjukanovt/30DayMapChallenge/main/images/flyers/30dmc-2022.png)

https://30daymapchallenge.com/

## OpenLayersとは
簡単にダイナミックなマップを設置することができるJavaScriptライブラリ
地図タイル、ベクトルデータ、マーカーを表示することができる
フリーかつオープンソースで、2条項のBSDライセンス（FreeBSDとしても知られています）の下でリリースされている
執筆時の最新バージョンはv7.1.0でした

## ベクトルタイルを表示する
国土地理院のベクトルタイルを表示してみます。

```index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="utf-8" />
        <title>サンプル</title>
        <meta name="description" content="サンプルです" />
        <link href="style.css" rel="stylesheet" />
        <!-- OpenLayers -->
        <script src="https://cdn.jsdelivr.net/npm/ol@v7.1.0/dist/ol.js"></script>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v7.1.0/ol.css" />
    </head>
    <body>
        <div id="map"></div>
        <script src="main.js"></script>
    </body>
</html>
```

```style.css
body {
    margin: 0;
    padding: 0;
}
#map {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 100%;
}
```

```main.js
const vectorLayer = new ol.layer.VectorTile({
    declutter: true,
    source: new ol.source.VectorTile({
        minzoom: 4,
        maxZoom: 16,
        format: new ol.format.MVT(),
        url: 'https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf',
        attributions: "出典：<a href='https://www.gsi.go.jp/' target='_blank'>国土地理院ベクトルタイル提供実験</a>",
    }),
});

const map = new ol.Map({
    layers: [vectorLayer],
    view: new ol.View({
        center: ol.proj.transform([138.68786, 38.68355], 'EPSG:4326', 'EPSG:3857'),
        zoom: 6,
    }),
    target: 'map',
});
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2667439/64fa6c5c-2ed8-a3c5-8377-a70eb107a289.png)

ベクトルタイルといえばMapbox GL JS/MapLibre GL JSでしたが、OpenLayersでも表示できるんですね～



# 参考文献
https://openlayers.org/en/latest/examples/vector-tile-selection.html

https://github.com/gsi-cyberjapan/gsimaps-vector-experiment

https://qiita.com/cieloazul310/items/8999c88f1acf79632cd3
デイトラ「Web制作コース」　受講内容をアウトプット 7日目

学んだことをアウトプットしています。完全に自己満足ですので悪しからず。
以下の点を確実にアウトプット
①何で学んでるか
②日々の学習内容
③学びのポイント
④制作物
⑤+αで参考にした記事
⑥+αでやってみたこと

①デイトラ「Web制作コース初級編」
②ゼロからサイトを作ってみよう③
③今日得た新しい知識
　・<br>タグを入れると改行が入る
　・メディアクエリでスマホ用の表示を作る際は最大767pxにすることが多い。これは最も普及しているタブレットのipadの
　　大きさが768pxのため。
　・flex-wrap:wrap;で親要素の幅に入らなくなった子要素が自動的に改行される。
　・flexを使用した際にafterが残っているとこれも見えないが要素としてみなしてしまうので無効にする。
④練習ｻｲﾄの完成
⑤なし
⑥なし
初心者向けJava学習動画

https://www.youtube.com/channel/UC42DlV-0RDb6fJ8A3IbAang

https://www.youtube.com/watch?v=5p_3OudszfA&t=5s

https://www.youtube.com/watch?v=2bJmY0XOMMs


https://www.youtube.com/watch?v=Ec9RE_2MYp0&t=6s


https://www.youtube.com/playlist?list=PLru8-xuz0Yvzm33wBZHfK6uILYW23LJi5




https://www.youtube.com/watch?v=q4wy3hSCcdk&t=1167s


https://www.youtube.com/watch?v=kjxetd5ylzI&t=9s

https://www.youtube.com/watch?v=z51UcYdiCZM&list=PLXXalsdlzX-IuXHRLIrw9G55Hw6oiXQGS
HTML（チートシート）

# html
## 参考記事
- アイコン
<a herf = "https://fontawesome.com/search"> Font Awesome </a>

- ログインの画像
<a herf = "https://ja.gravatar.com/"> Gravatar  </a>

# javascript
## 参考記事
### JQUERY
- 入力補完 
<a herf = "https://tarekraafat.github.io/autoComplete.js/#/"> autoComplete.js </a>

 - プッシュ通知
<a herf = "https://www.casleyconsulting.co.jp/blog/engineer/293/"> ブラウザでプッシュ通知を実装してみた </a>
#7 Bootstrapを利用して画面の作成[1. 環境設定]

# #7 Bootstrapを利用して画面の作成[1. 環境設定]
この記事ではBootstrapを利用した画面デザインの作成をしていきます。
画面デザインはアプリケーション作成で重要視され、画面デザインではBootstrapというフレームワークがよく使われます。
また、スマートフォンにも対応した画面を作ることもできます。

# 前回まで
前回はOracleデータベースとの接続を行いました。今回の記事では前回使用したプロジェクトを継続して用います。

https://qiita.com/Jackoguro/items/808d9fff90f39962c3cd

# 構築環境
1. 各バージョン
- Spring Boot ver 2.7.5
- jquery ver 3.5.1
- bootstrap ver 4.5.3
- webjars-locator ver 0.40 

2. 依存関係
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/659bbe6b-9e92-99cb-2ca3-5ba3c02d240f.png)

# 今回行うこと
今回は以下の流れに沿って進めていきます。
1. pom.xmlにwebjarを使用するためのコードを追加
1. login.htmlにwebjarsでダウンロードしたライブラリを使用するためのコードを追加 

## 1. pom.xmlにwebjarを使用するためのコードを追加
webjarsとはBootstarpを使うためのライブラリです。webjarsを使用するとライブラのダウンロードや読込などを簡単に行うことができます。
```xml:pom.xml
	<dependencies>
		<!-- jquery -->
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>jquery</artifactId>
			<version>3.5.1</version>
		</dependency>
		<!-- bootstrap -->
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>bootstrap</artifactId>
			<version>4.5.3</version>
		</dependency>
		<!-- webjars-locator -->
		<dependency>
			<groupId>org.webjars</groupId>
			<artifactId>webjars-locator</artifactId>
			<version>0.40</version>
		</dependency>
        <!-- 省略 -->
	<dependencies>
```

:::note
webjars-locator：webjarsで使用するライブラリのバージョンを意識せずコードを書けるようになる
jquery：Bootstrapを使用するためにはjqueryというJavaScriptのライブラリが必要
:::

## 2. login.htmlにwebjarsでダウンロードしたライブラリを使用するためのコードを追加
HTMLファイルのヘッダーに下記内容を書き込みます。
```html:login.html
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- CSS読込 -->
<link rel="stylesheet" th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">
<!-- JS読込 -->
<script th:src="@{/webjars/jquery/jquery.min.js}" defer></script>
<script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}" defer></script>
<title>ログイン</title>
</head>
```
:::note
- webjarsでダウンロードしたライブラリは@{/webjars/･･･}という形で呼び出すことができます。「Maven依存関係」フォルダー内にMavenでダウンロードしたライブラリのjarファイルが入っています。
- defer：JavaScriptを読み込む際にdefer属性を付けることで画面表示の性能が改善される。また、defer属性を付けることでHTML、JavaScriptの読込を平行で実施してくれます。これにより処理が速くなります。
:::

下記画像のMETA-INF/resourcesより下のパスを@{/webjars/･･･}に指定します。
本来はバージョン番号を含めたパスを記載しなければいけないですが、webjars-locationを入れることでバージョン番号を省略することができます。下記画像はjqueryのjarファイルですが、bootstrapのjarファイルでも同様です。

![スクリーンショット_20221116_210228.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/7c50731e-56a5-b873-afd0-98b2739a8da1.png)

# 最後に
Bootstarpの設定は以上になります。
次回はHTMLに内容を記載し、Bootstrapを用いてデザインを作成します。
文字列の連結、if文、比較演算子、真偽値、else文、elseif文

### ドット「.」を用いた文字の連結

文字列、変数の間に.を入力することで
文字列同士、変数同士、文字列と変数を連結することが出来る。

\$name&thinsp;``=``&thinsp;\'東方';
echo&thinsp;\$name.\'仗助';

→東方仗助と表示

「.=」を用いると省略した書き方が可能

\$name&thinsp;``=``&thinsp;\'東方';
\$name&thinsp;.``=``&thinsp;\'仗助';
echo \$name;

→東方仗助と出力

### 変数展開

ダブルクォーテーションで文字列を囲んだ場合に中の変数を
\{}で囲むとその部分が変数に入っている値に置き換えられる(変数展開)。
シングルクォーテーションで文字列を囲んだ場合は変数展開されず
\{}も含めそのまま文字列としてみなされる。

\$name&thinsp;\=&thinsp;\'東方仗助';
echo&thinsp;\"こんにちは、``{$name}``さん";

→ダブルクォーテーションで囲んでいるため\$nameの値(東方仗助)が出力される。

\$name&thinsp;\=&thinsp;\'東方仗助';
echo&thinsp;\'こんにちは、``{$name}``さん';

→シングルクォーテーションで囲んでいるため\{\$name}をそのまま
 連結した値(こんにちは、\{name}さん)が表示される。

### if文

if文を使うと、条件に応じて処理を分岐することが出来る。
\()の中に条件を定義して、変数の値が条件を満たしている場合
{}内の処理が実行される。

\$i&thinsp;``=``&thinsp;10;
if(\$i&thinsp;\>&thinsp;5)&thinsp;``{``
&emsp;echo&thinsp;'\$iは5より大きい';
}

→\\$iは5より大きいため、\\$iは5より大きいと出力される。
 条件が成り立たない場合(\$iが5未満の場合)は処理が実行されないため
 何も出力されない。

### 数値の比較

\>などの数値を比較するための記号は**比較演算子**と呼ぶ。
比較した結果は真「true」か偽「false」のどちらかになる。

< →右辺の方が大きい時true
<= →右辺の方が大きいまたは等しい時true
\> →右辺の方が小さい時true
\>= →右辺の方が小さいまたは等しい時true
== →右辺と左辺が等しい時true
!= →等しくないときtrue

### 真偽値

trueとfalseは真偽値と呼ばれる。
真偽値は文字列や数値といったデータの種類の1つであり、
真偽値はtrueとfalseの2つしかない。
if文は。条件式がtrueの場合if文の中身が実行され、
falseの場合は実行されない。

### else文

ifと組み合わせてelseを使うと、条件を分岐させることが出来る。
if文の条件がfalseであった場合、elseの処理が実行される。

\\$i&thinsp;\=&thinsp;10;
if(\\$i&thinsp;\==&thinsp;5)&thinsp;\{
&emsp;echo&thinsp;'\\$iは5です';
}else&thinsp;{
&emsp;echo&thinsp;'\$iは5ではありません';
}

→if文の条件式がfalseであったためif文の処理は実行されず
 elseの処理\(echo&thinsp;'\\$iは5ではありません';)が
 実行され、\$iは5ではありませんが出力される。

### elseif文

elseif文を用いることで条件の多岐分岐が可能になる。
※elseifは必要な分岐の数だけ並べることができるが、
複数の条件に合致した場合、実行されるのは最初に合致したブロックだけとなる。

\\$i&thinsp;\=&thinsp;10;
if(\\$i&thinsp;\>=&thinsp;20)&thinsp;\{
&emsp;echo&thinsp;'\\$iは20より大きい';
}elseif(\\$i>=20)&thinsp;\{
&emsp;echo&thinsp;`\\$iは20以下10以上';
}else&thinsp;{
&emsp;echo&thinsp;'\$iは5ではありません';
}

→if文の条件式がfalseであったためif文の処理は実行されず
 elseifの処理\(echo&thinsp;'\\$iは20以下10以上';)が実行され
 \$iは20以下10以上が出力される。
【Perl初学者】無名サブルーチン

本日は備忘録のための、本当に忘れないためにメモしておく。。程度の感覚で投稿します。
テキトーでごめんなさい。

# 無名サブルーチンとは
その関数自体には名前のない関数
複雑なるデータ構造を作る際に便利
例）

```;hello.pl
my $func = sub {
  my $num = shift;
  return 5 * $num;
};
print $func->(2);
#結果 10
```

引数はshiftで受け取っています。
`my $func`には無名サブルーチンのリファレンスが入り、デリファレンスしてサブルーチン呼び出し、そして戻り値を返す。

# まとめ

リファレンスについては[リファレンスについて]()を参照
【シェルスクリプト】ファイルやディレクトリの有無を判定する

## ファイル

以下のようにするとファイルが存在する場合に`true`となります。  

```zsh
if [ -e ファイル ]; then
  コマンド
fi
```

また以下のようにするとファイルが存在しない場合に`true`となります。  

```zsh
if [ ! -e ファイル ]; then
  コマンド
fi
```

## ディレクトリ

以下のようにするとディレクトリが存在する場合に`true`となります。  

```zsh
if [ -d ディレクトリ ]; then
  コマンド
fi
```

また以下のようにするとディレクトリが存在しない場合に`true`となります。  

```zsh
if [ ! -d ディレクトリ ]; then
  コマンド
fi
```
[ケモインフォマティクス] smilesから分子構造を描画してExcelに入れる。

分子のデータをsmilesで管理することは多くあると思います。
一方、smilesは分子構造について他人に説明したいときや可読性についてはなかなか悪いため、構造が一目でわかる形で管理したいことはよくあるでしょう。

そこで、今回はsmilesのデータから構造を描画しExcelで管理する方法をまとめます。

ライブラリにはExcelを操作するopenpyxlと安定のrdkitを使います！

# 準備
まず、適当なsmilesを準備します。
```python
import pandas as pd
import pubchempy as pcp

properties = ['CanonicalSMILES', 'IUPACName']
benzene = pcp.get_properties(properties, 'benzene', 'name', as_dataframe=True)
toluene = pcp.get_properties(properties, 'toluene', 'name', as_dataframe=True)
df = pd.concat([benzene,toluene])
display(df)
```
![スクリーンショット 2022-11-16 19.52.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787586/26c8237b-ab4b-a338-6fdc-d781cebba031.png)

### 画像に変換する関数
画像に変換し、保存してくれる関数を作ります
```python
from rdkit import Chem
from rdkit.Chem import Draw
import openpyxl

def toImgFromSmiles(smiles, name):
    mol = Chem.MolFromSmiles(smiles)
    Draw.MolToFile(mol, f'{name}.png', size=(300, 300))
```

### 画像をエクセルのカラムに挿入する関数
```python
from openpyxl.drawing.image import Image as XLImage

def add_image(worksheet, smiles_column, image_column):
    ws = worksheet
    # 行数を取得
    R_NUM = len(list(ws.rows))

    for i in range(1, R_NUM):
        idx = i + 1
        # smilesが入ってるカラム名(ex. A1, C5)
        smiles_col_name = smiles_column + str(idx)
        image_col_name = image_column + str(idx)

        smiles = ws[smiles_col_name].value
        if smiles == None: continue
        print(smiles)

        try:
            # 画像作成
            toImgFromSmiles(smiles, smiles_col_name)
            img = XLImage(f'{smiles_col_name}.png')
            img.width = 200
            img.height = 200

            # 画像を貼り付ける
            ws.add_image(img, image_col_name)

            # セルの高さを調整
            ws.row_dimensions[idx].height = img.height
        except FileNotFoundError as e:
            print('error ', e)
            break
```

### いざ実行
```python
import openpyxl

df.insert(2, 'img', '')
file_name = 'dataset.xlsx'

df.to_excel(file_name, index=False)
wb = openpyxl.load_workbook(file_name)
ws = wb.active

# Excelは左からA列,B列,C列,,,
add_image(ws, 'A', 'C')

# 保存
wb.save(file_name)
```
### dataset.xlsx
ちゃんと出力されていますね！
![スクリーンショット 2022-11-16 21.02.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/787586/119c69df-c5f6-2e4e-8159-92ba97f5ecc7.png)
TypeScriptでもRubyのように複数の引数を配列でまとめて指定したい

## やりたいこと

Rubyでは、配列の頭に*をつけると配列が展開され、各要素を一つずつmethodの引数として渡すことができる。
```ruby
def method1(arg1, arg2, arg3)
  puts "一つ目の引数: #{arg1}"
  puts "二つ目の引数: #{arg2}"
  puts "三つ目の引数: #{arg3}"
end

args = ["hoge", 1, true]

method1(*args)
#  => "一つ目の引数: hoge"
#     "二つ目の引数: 1"
#     "三つ目の引数: true"
```

TypeScriptでも同じことがしたい。

## 方法

spread演算子を使えば実現できる。
その際、展開する配列の型が**要素数が引数の個数と同じ**で、**引数の型を順番通りにもつ**配列型となっている必要がある。

まずはありがちな失敗例を一つ挙げる。

### 失敗例

```typescript
const method1 = (arg1: string, arg2: number, arg3: boolean) => {
  console.log(`一つ目の引数: ${arg1}`)
  console.log(`二つ目の引数: ${arg2}`)
  console.log(`三つ目の引数: ${arg3}`)
}

type Args = string | number | boolean

const args:Args[] = ["hoge", 1, true]

method1(...args)
// => ...argsに対し警告がでる
```
この場合、
```spread 引数には、組の種類を指定するか、rest パラメーターに渡す必要があります```
という警告が出てコンパイルが通らない。
```Args[]```は個数の情報を持たないし、どの位置にどの型があるのかもわからないためである。

繰り返すが引数の型が異なる場合は、
展開する配列の型が**要素数が引数の個数と同じ**で、**引数の型を順番通りにもつ配列型**となっている必要がある。

そのように配列の型を指定するには下記二つの方法がある。


- [方法1: 配列の要素の型を明示する](#方法1-配列の要素の型を明示する)
- [方法2: as constを使用する](#方法2-as-constを使用する)

### 方法1: 配列の要素の型を明示する

```typescript
const method1 = (arg1: string, arg2: number, arg3: boolean) => {
  // 省略
}

const args:[string, number, boolean] = ["hoge", 1, true]

method1(...args)
//  => 一つ目の引数: hoge
//     二つ目の引数: 1
//     三つ目の引数: true
```

重要なのは```args```に指定している```[string, number, boolean]```の部分である。
このように要素の個数と特定の位置に含まれる型を明示している配列の型を**タプル型**という。

タプル型を使用することで、
1. 引数の数と同じだけ要素が存在すること、
2. 配列を展開した時に確実に引数の型と一致すること

が保証されるため、警告は解消される。

### 方法2: as constを使用する

配列の要素を明示する以外にも```as const```を使用する方法がある。
配列に対して、```as const```を使用して型アサーションを行うと、指定された配列は**readonlyなタプル型**となる。

```typescript
const method1 = (arg1: string, arg2: number, arg3: boolean) => {
  // 省略
}

// argsの型は　readonly ["hoge", 1, true]
const args = ["hoge", 1, true] as const

method1(...args)
//  => 一つ目の引数: hoge
//     二つ目の引数: 1
//     三つ目の引数: true
```

この場合も方法1と同様、要素の数と特定の位置に含まれる要素の型が保証されるため、警告は解消される。

## まとめ

- TypescriptでRubyのように複数の引数を配列でまとめて指定するためにはSpread演算子を使う
- Spread演算子で引数を渡す場合は**配列の要素の型**を明示するか**as const**を使用してタプル型を指定する

## 参考元

[スプレッド演算子-TypesScript Deep Dive 日本語版](https://typescript-jp.gitbook.io/deep-dive/future-javascript/spread-operator#henoapply)


[Tuple Types-TypeScript: Documentation](https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types)


[readonly Tuple Types-Typescript: Documentation](https://www.typescriptlang.org/docs/handbook/2/objects.html#readonly-tuple-types)
picoCTF Writeup picoGym Practice Challenges Python Wrangling (注意<spoiler>)

とりあえず3つのファイルをダウンロード。

ende.py -- 複合スクリプト

flag.txt.en -- 暗号化文

pw.txt -- 秘密鍵

となっていることがわかる。

スクリプトende.pyを実行するのに-d[Fileとしてflag.txt.en]をつけてあげればよい。

\>python ende.py -d .\flag.txt.en
Please enter the password:aa821c16aa821c16aa821c16aa821c16
picoCTF{\<spoiler>}
[Unreal Engine 4] レベルを遷移しても、BGMを継続して再生する方法

# 目次
<!-- タイトルとアンカー名を編集 -->
1. [BGMを継続して再生する方法](#bgmを継続して再生する方法)
1. [参考文献](#参考文献)
1. [その他](#その他)

# BGMを継続して再生する方法

※Unreal Engine 4.14以前のバージョンについては、Spawn Sound 2Dに「Persist Across Level Transition」の項目がないため、本記事の方法を利用できません。

Game Instanceに、Audio Componentの変数を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572997/7c713724-cd0f-a6d8-d0b9-3a14df06ee84.png)

レベルブループリントなど、BGMを再生・停止したいところで以下の処理を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572997/5f73d41d-5984-50bb-a6ca-cd657c0b521c.png)

# 参考文献
- [おかずさんのコメント](http://meganeo.blog.shinobi.jp/ue4/%E3%80%90ue4%E3%80%91%E9%9F%B3%E3%82%92%E5%86%8D%E7%94%9F%E3%81%99%E3%82%8B%E4%BB%B6-persistentlev)

# その他
Unreal Engineのバージョン：4.26
Googleで検索していた際に、「パーシスタントレベル・サブレベルを設定しなければならない」といった情報がありましたが、そのような設定をせずに、本記事の方法で解決できると思います。
何か質問などありましたらコメントしていただけると助かります。m(_ _)m
pandasまとめ

irisデータを用いてpandasの基礎操作をまとめていきます

# irisデータ読み込み
irisデータについて　
ディクショナリー型変数で
{'data': array([[5.1, 3.5, 1.4, 0.2], , , , , , , , [5.9, 3. , 5.1, 1.8]]), 
'target': array([0, 0, 0, 0, 0, , , , , , , , , 2, 2, 2, 2, 2]), 
'frame': None, 'target_names': array(['setosa', 'versicolor', 'virginica'], dtype='<U10'),
'DESCR': '.. _iris_dataset:\n\
 , , , , , , - Many, many more ...',
'feature_names': ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'], 'filename': 'iris.csv', 'data_module': 'sklearn.datasets.data'} 
のように構成されている(print_irisの中身)
shapeで形状が出力できるのは謎

```.py
import pandas as pd
from sklearn.datasets import load_iris
import matplotlib.pyplot as plt

iris = load_iris()
print(iris.data)
print(iris.target)
print(iris.data.shape)#(150,4)
print(iris.target.shape)#(150,)




```
# Pandasを使う
pandasのデータフレームを使用することでデータを扱いやすくする
そのままだとデータ処理がdata.shapeくらいしかできないが、pandasの機能を使うことで統計的に処理ができるようになる

```.py
#これでデータフレーム作成
df_iris = pd.DataFrame(iris.data,columns = iris.feature_names)
df_iris.describe()#合計数、平均、標準偏差、最大値、最小値をまとめて計算してくれる

```
相関を散布図で図示する


```.py
import seaborn as sns
df_temp = df_iris.copy()
sns.pairplot(df_temp)
plt.show();

```
k-meanを使用
手順　モデルを用意しデータをフィットさせる　→　分類実行
```.py
from sklearn.cluster import KMeans
model = KMeans(n_clusters= 3,random_state=0,init="random")
model.fit(df_temp)
cluster = model.predict(df_temp)
print(cluster)
```
[0,0,2,0,1,,,,,,,2,2]
のように各データがラベリングされる
picoCTF Writeup picoGym Practice Challenges Wave a flag (注意<spoiler>)

~~~:picoCTF
Description
Can you invoke help flags for a tool or binary? This program has extraordinarily helpful information...
~~~

プログラムをダウンロードして、elfファイルが実行可能環境であれば実行すればよい(./warm)

その他の環境であればghidra等を利用すれば元となるコード(c)からフラグが見つけられる。
Cisco Aironet (自律型) でNTP (SNTP) を使って時刻を合わせる

# はじめに
先日、Cisco の Aironet シリーズ アクセスポイント (Autonomous OS 搭載) を中古で購入しました。
手動で時刻を設定するのは現実的ではないため，NTP を利用しようと思いましたが，うまくいかなかったので，記録を残しておきます。

なお，今回は事前に以下の設定を投入しています。

```
clock timezone JST 9 0
```

# うまくいかなかった方法
とりあえず，Cisco のルータやスイッチなどと同じような設定を試してみました。
設定の投入自体はできているようですが，動作はしないようでした。

```
> enable
# conf t
(config)# ntp server ntp.jst.mfeed.ad.jp
(config)# end

# show clock
(正しくない日時が表示される)

# show ntp associations
        ^
% Invalid input detected at '^' marker.
```

# うまくいった方法
NTPではなく，**SNTP**を使用します。
SNTPはNTPの簡易版ですが，互換性があるため，サーバのアドレスは同じものをそのまま使用できました。

```
> enable
# conf t
(config)# sntp server ntp.jst.mfeed.ad.jp
(config)# end

# show sntp
SNTP server                Stratum   Version    Last Received
ntp.jst.mfeed.ad.jp         2           4        00:00:28      Synced

# show clock
16:36:35.452 JST Wed Nov 16 2022
```

## 参考
- https://www.cisco.com/c/ja_jp/td/docs/wireless/access_point/atnms-ap-82/configuration/guide/cg-82-book/cg-chap5-admin.html
Vite + Express のボイラープレート 

ふぁーです。先日 "東京Web3ハッカソン" というイベントに参加してきました！


2週間でブロックチェーンアプリを開発して公開して提出、かつ説明動画や資料の用意も必要だったのでかなり痺れる２週間でした

（実際には平日仕事で開発出来ないのと土日は子育てもあり、実質土日に数時間ずつしか時間が取れませんでした）

https://tokyo.akindo.io/

そんな短期間での開発をなんとかやりとげたのですが、もっと効率的に開発したいという思いが強くなった為、ハッカソンの際に開発した開発環境をチューニングして公開する事にしました。

もし私以外にも同じような構成のアプリケーションをぱぱっと作ってみたいという方がいましたら是非利用頂ければ幸いです。


# 構成

* フロントエンド
  * Vite
  * React, React-router-dom
  * Mui-material, emotion
  * Recoil
  * i18n
* バックエンド
  * Express
  * mysql
* その他
  * Open API
  * Docker
  * eslint
  * prettier

# レポジトリ

以下に公開致しました。是非もっと良い構成やアイディアがあれば遠慮なく issue or pull request して頂けると嬉しいです

https://github.com/ymuichiro/vite-mui-react-express-template

# 使い方

各操作方法を説明します

## 初期設定

※ コマンドをまとめる為に makefile を用いています。 導入していない方は先にそちらをインストール下さい

以下の通り実行して、依存ライブラリをインストールしてください

```
make install
```

## 開発用サーバー起動

以下の通りに実行するだけです

```
make start
```

終了する場合は `ctrl + c` でとまります。起動していたコンテナが止まるだけなので一旦コンテナを削除してしまいたい場合は以下の通りに実行して下さい

```
make down
```


## デプロイ

ビルドしてサーバーにデプロイする際には以下を実行して下さい

```
make deploy
```

# その他

その他、よく使いそうなコマンドをまとめておきます

## 一旦環境をきれいにしたい

インストールした node_modules や dist、docker を綺麗にしたい場合は以下を実行して下さい

```
make clean
```

## 一旦コンテナ化してしまいたい

`make deploy` のケースは VM 等での利用に向いていますが、 Google Cloud run 等で使いたい際には以下の手順を踏んでください

1. 開発したソースを一式ご自身の GitHub レポジトリにpushして下さい
2. push 後、 レポジトリ内の GitHub Actions タブを確認頂ければビルドが自動で開始されていることが確認されます
3. 終わるのを待ちます
4. 完了マークになりましたらコンテナ完成です



# まとめ

上記のような操作で開発を進めていけます。もし宜しければ活用下さい！

なお当方はハッカソンにて以下の作品を提出しました。Blockchain には `Symbol` というパブリックブロックチェーンを活用しています。

https://github.com/ymuichiro/decentralized-guild

Symbol は 難しいコントラクトの開発方法を覚えなくとも Javascript の sdk や API を経由して簡単にブロックチェーンアプリを開発する事が出来ます。

もしブロックチェーンアプリ開発に興味のある方は以下を参照下さい

**サイト**
https://symbol-community.com/ja-JP

**入門サイト**
https://github.com/xembook/quick_learning_symbol

**お問い合わせ**
https://discord.gg/A8MRq5Vuvt


他、ハッカソンのインフラ構築には今回 Alibaba Cloud を使いました
中国...？と思う方もいるかもしれませんが、今回以下の理由にて選定しています。
こちらももし宜しければ触ってみてもいいかもしれません！

* ちゃんと東京リージョンもある
* 他クラウド事業者よりも大抵一回り安い
* 管理コンソールがとてもシンプル。余計なものがなく知識がなくとも使いやすい
* お勧めは Simple Application Server。定額で安価なサーバーを設置出来ます

もしハッカソンの際にどういった構成でインフラを用意したか気になった方はレポジトリの方に記載しておりますのでご確認下さい

https://www.alibabacloud.com/ja


2022/11/26 更新

* コンテナへの依存を軽減しました
https://github.com/ymuichiro/vite-mui-react-express-template/releases/tag/0.0.2
EAFPとLBYLについて解説(学習まとめ)

今更ですが、「EAFP」と「LBYL」について解説していきたいと思います。
プログラミングする上で大事なことなので、筆者自身が忘れないように書き留めておきます。


「EAFP」は、「Easier to Ask Forgiveness than Permission」「許可を得るよりも、許しを請うほうが簡単」という格言です。
「EAFP」は、例外処理機構を用いることから、コード中にtry/except文が頻繁に出てくる方式であり、安全なエラー処理が可能な反面、実行時のオーバーヘッドが大きいというデメリットがあります。


「LBYL」は、「Look Before You Leap」「飛ぶ前に見ろ/転ばぬ先の杖」という格言です。
「LBYL」は、オブジェクト指向以前の手続き型言語で採用されていました。例えば、関数の戻り値や、関数に渡すポインタ引数を用いて、関数側で結果コード(＝ステータスコード)を書き込んでもらい、呼出し元でチェックをするという方式です。コード中にif文が頻繁に出てくる方式です。前段の「EAFP」に比べると若干コードの可読性が下がる一方で、実行時のオーバーヘッドが小さいというメリットがあります。


以上が、「EAFP」と「LBYL」についての解説でした。
また懲りずに記事を書いていこうと思います。
それではまた～。
『システム運用アンチパターン』輪読会 8章「業務時間外のデプロイ」

### まずは参考文献
[システム運用アンチパターン](https://www.oreilly.co.jp/books/9784873119847/ "システム運用アンチパターン")
システムの開発・運用範囲が異なるエンジニア間でも、共通して会話ができる社内輪読会にはよい書籍

---
## 本章のまとめ
・ デプロイが大ごと ＝ デプロイ戦略に何か深刻な問題がある
・ 業務時間外のデプロイ = 組織を守るためとして正当化されがちなアンチパターン(対症療法でしかない）

---
### 8.1 苦労話

---
### 簡単にリリースができず、リリースとリリースの間が長期間で運用しているケース
・在庫をもっっている状態
　保管、トレースのコストが発生、価値を生まない状態

---
遅いリリースプロセスの悪影響
**リリースの詰め込み**
+ リリース規模が大きくなり、リリースのリスクを増大させる

**大急ぎの機能**
+ 次のリリースタイミングまでに急いで機能を開発

**重厚な変更管理プロセス**
+ リリースが大きくなるとリスクが増大、リスクが増大すると失敗の影響も増大。その結果承認、変更管理の層、つまりゲートキーパーが増加して、プロセスがさらに複雑に

---
### 所感
レガシーかつ、商品において、こういう状態のものを苦々しく思い出した。
それ以外にも多くの課題を抱えていたシステムだったけれど、**「デプロイを簡単にするためにはどうしていけば実現できるか」**
という視点から立て直しの計画を立てる方法がよかったのかもしれないと気付かされた。
一番重かったのはリリース作業だったのだけれど、インシデント、セキュリティインシデントが多く、とりあえず穴を塞ぎにいって、先の見えない戦いをしていた。

---
### 8.2 デプロイのレイヤ

---
![untitled.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2444381/37dc0243-3f34-4ab0-ad99-334b8edb336d.jpeg)

**データベースデプロイ**
+ 新しいコードのデプロイの一環としてデータベースに必要な変更を行うプロセス

**アーティファクトデプロイ**
+ 1台のサーバに新しいコードをインストールするプロセス

**フリートデプロイ**
+ 複数のサーバにアーティファクトをデプロイするプロセス

**機能デプロイ**
+ アプリケーション全体で新機能を有効にするプロセス

---
### 所感
機能デプロイといわゆるコードデプロイ（アーティファクトデプロイ、フリートデプロイ）を分けるアプローチはあまりしたことがなかったが、
リリース日とデプロイを分けられるので、エンジニアとしては心配事から解放される期間が設けられるのでユースケースによっては有効かもしれない。
実装（テストも)がその分複雑になることと、あとで必要に応じて、機能スイッチを削除する必要があることとのトレードオフで判断が必要

---
### 8.3 デプロイを日常的に行う
+ 8.3.1 正確な本番前環境
+ 8.3.2 ステージング環境は本番環境とまったく同じにはならない

---
・本番前環境はアーキテクチャ/トポロジー的に本番環境と同じ環境を実現すること
+ 物理サーバー台数、ファイルサーバ、ネットワーク境界

・ただ、本番環境と完全には同じにはできない
+ ユーザー数（並行実行性）、想定外の操作

---
### 所感
・完全に同じにできない。でも同じにできるところを同じにしていないことは、特に昔のシステムにおいてはよくある話。
・アーキテクチャ以前にミドルウェアのバージョンが違っていたりすることもあった

---
### 8.4 頻繁に行うことで恐怖心を減らす

---
慣れが大事。恐怖心が軽減される。なので頻繁にデプロイすることが良いこととなる
逆に、抵抗感と恐怖心で負のフィードバックループが発生する

![untitled.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2444381/feb9af7f-c912-3fb2-ceaa-56875a977172.jpeg)

---
### 8.5 リスクを減らして恐怖心を減らす

---
**自動テスト**から始めよう

:::note warn
[よくある誤解]
自動テストは**すべて**のバグを発見できなければ何の価値もない
:::

:::note
[正]
テストするケースやシナリオを継続的に追加することで、継続的に価値を生み出し続けます。
リリースに関する不確実性を完全に取り除くことはできません。
しかし、その不確実性をあなたや組織が許容できる範囲まで減らすことは可能です。
デプロイ頻度を上げるには、テストの実行頻度を上げることから始めなければいけません。
:::

---
### 8.6 デプロイプロセスの各レイヤでの失敗への対応

---
各レイヤでロールバックできるようにしましょう

![untitled.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2444381/37dc0243-3f34-4ab0-ad99-334b8edb336d.jpeg)

---
### 8.6.1 機能フラグ
### 8.6.2 いつ機能フラグをオフにするか
---

・リリースする機能をオン/オフするスイッチを設置することで機能単位で戻しができる。
・機能の効果を計測し、OK/NG判断をできるようにしましょう
・OKであれば、スイッチは適宜削除リリースするようにしましょう。

---
### 8.6.3 フリートのロールバック

---
ブルーグリーンデプロイでいつでも切り替えできるように。

注意点
1. DBスキーマがアプリケーションのバージョン間での互換性があるか
1. バックグラウンド処理が同居してないか
1. アプリケーションサーバがローカルディスクに状態を保存していないか

---
### 8.6.4 デプロイアーティファクトのロールバック
パッケージ管理システムは使いましょう
ロールバック時にuninstallもできるので、ブルーグリーンで違うサーバー群との環境差が広がらない

---
### 8.6.5 データストアレベルのロールバック

データベースの変更のルール

:::note 
常に追加的変更を加えること！！
既存のものを変更するのは避ける
:::

---
### 8章の所感

複雑に絡み合った問題をそのまま闇雲に解決するのでなく、
レイヤ分けして、課題を分解して、順序づけて解決していく
って当たり前だけれど、大事。
プログラミング完全未経験者に教えて分かった。伸びる人の特徴。

# 結論
✅ __とりあえずやってみようという考えの人が伸びる__
✅ __原因をよく考える人が伸びる (結果がダメなときでも)__

# 解説
それぞれ解説します。

## とりあえずやってみようという考えの人が伸びる
大前提として、__技術というものは、見たり読んだりしているだけで習得できません😤__

伸びる人は理解できていない部分があったとしても、とりあえずやってみようという考えで着手しています。
そのような状態で着手しているので、バグやエラーが多発するのですが、__できる限り手が止まらないように行動しています。__

伸び悩んでいる人は、「とりあえずやってみる」までが遅い ⇒ 試行回数が少ない ⇒ 得られる情報が少ない ⇒ 習得速度が落ちるという負の連鎖に陥っているように見えます😥

## 原因をよく考える人が伸びる
ひとまず着手してみることが大事ということは前述した通りです。
ただし、闇雲にやっていてもダメで、__何らかの考えを持って取り組まないと時間を浪費します。__

伸びる人は「～～と書いたら～～という結果になった。これは～～だからだろう。」といったように原因をよく考えて作業しています。修正するときもその仮説を元に進めているため素早く対応することができていました。(学習を始めたばかりの時点では仮説が間違っていることもありましたが時間とともに改善されていました)

# 要するに
__試行錯誤と仮説検証が大事__ ということです😎

作業中にエラーが出たりバグったりすることもあると思いますが、「～～と書いたらエラー/バグが起こる」ということも重要な知識の1つであり、それを直すことも重要な経験になります。

よく分からないときこそ手を動かして知識と経験を増やしていきましょう。
自然言語処理で引用文献を楽したい人向けの論文一覧(形態素解析、wrod2vecからBERTまで)


参考文献を書くのって意外と手間がかかりめんどくさい…
自然言語処理を勉強している学生、社会人の方に向けて、形態素解析ツールと言語モデル論文の一部をまとめました。

2022/11/19　コメントを受けて形態素解析の引用文献を改善

# 形態素解析
## Mecab
Taku Kudo, Kaoru Yamamoto, Yuji Matsumoto: Applying Conditional Random Fields to Japanese Morphological Analysis, Proceedings of the 2004 Conference on Empirical Methods in Natural Language Processing (July 2004), pp.230-237. 
<br>(https://aclanthology.org/W04-3230)

## Juman＋＋
Arseny Tolmachev, Daisuke Kawahara, Sadao Kurohashi: Juman++: A Morphological Analysis Toolkit for Scriptio Continua, Proceedings of the 2018 Conference on Empirical Methods in Natural Language Processing (November 2018): System Demonstrations, pp.54-59. 
<br>(https://dx.doi.org/10.18653/v1/D18-2010)

## Sudachi
Kazuma Takaoka, Sorami Hisamoto, Noriko Kawahara, Miho Sakamoto, Yoshitaka Uchida, Yuji Matsumoto: Sudachi: a Japanese Tokenizer for Business, LREC 2018: Eleventh International Conference on Language Resources and Evaluation (May 2018), pp.2246-2249. 
<br>(https://aclanthology.org/L18-1355)

## GINZA
松田寛: GiNZA - Universal Dependenciesによる実用的日本語解析, 自然言語処理, Vol.27, No.3 (2020年9月), pp.695-701.　
<br>(https://doi.org/10.5715/jnlp.27.695)

## Stanza
Peng Qi, Yuhao Zhang, Yuhui Zhang, Jason Bolton, Christopher D. Manning: Stanza: A Python Natural Language Processing Toolkit for Many Human Languages, 58th Annual Meeting of the Association for Computational Linguistics: Proceedings of the System Demonstration (July 2020), pp.101-108. <br>(https://dx.doi.org/10.18653/v1/2020.acl-demos.14)








# 言語モデル
## Word2Vec
Mikolov, T., Chen, K., Corrado, G., and Dean, J. (2013). Efficient Estimation of Word Representations in Vector Space. arXiv:1301.3781.

## RNN
J. L. Elman. (1990). Finding structure in time, Cognitive science, 14(2), 179-211 

## LSTM
S. Hochreiter and J. Schmidhuber. (1997). Long short-term memory, Neural computation, 9(8), 1735-1780.

## ELMo
Matthew E. Peters, Mark Neumann, Mohit Iyyer, Matt Gardner, Christopher Clark, Kenton Lee, Luke Zettlemoyer. (2018). Deep contextualized word representations, arXiv:1301.05365v2.

## Transformer
Ashish Vaswani, Noam Shazeer, Niki Parmar, Jakob Uszkoreit, Llion Jones, Aidan N. Gomez, Lukasz Kaiser, and Illia Polosukhin. (2017). Attention is all you need. arXiv:1706.03762.

## BERT
Jacob Devlin, Ming-Wei Chang, Kenton Lee, Kristina Toutanova. (2018). BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding. arXiv:1810.04805.
forEachとmapの違い

結論、**戻り値を持つかどうか**です。

```
const arr = [本田, 香川, 岡崎, 内田, 長友];

// forEachの場合
arr.forEach(value => {
  console.log(value);
});
// 本田
// 香川
// 岡崎
// 内田
// 長友


// mapの場合
arr.map(value => {
  console.log(value)
});
// 本田
// 香川
// 岡崎
// 内田
// 長友
```


forEachもmapも得られる結果は同じ。

大きく異なる点は、**戻り値を持つかどうか**。

```
const arr = [本田, 香川, 岡崎, 内田, 長友];

// forEachの場合
const forEachResult = arr.forEach(value => {
  return value;
});
console.log(forEachResult); 
// undefined

// mapの場合
const mapResult = arr.map(value => {
  return value;
});
console.log(mapResult);
// [本田, 香川, 岡崎, 内田, 長友]
```
picoCTF Writeup picoGym Practice Challenges Mod 26 (注意<spoiler>)

~~~:picoCTF
Description
Cryptography can be easy, do you know what ROT13 is? cvpbPGS{arkg_gvzr_V'yy_gel_2_ebhaqf_bs_ebg13_MAZyqFQj}
~~~

rot13をエンコードしてやればいい

https://dencode.com/ja/cipher/rot13

このサイトで入力しrot13で出力した文字がフラグとなる
pdfコピペで邪魔な半角スペースを消したり改行を削除したりテキスト置換するChrome拡張

# TL;DR

https://github.com/kentoak/replace-text

`Alt+M`でポップアップのページを呼び出し、テキストボックスにペーストした瞬間に全角に挟まれた半角スペースを削除したり、ピリオドカンマと句読点を正しくしてくれたりｍテキスト置換をしてくれるChrome拡張。

* 全角に挟まれた半角スペースを削除（テキストボックスにペーストすると自動で半角スペースが削除される。）
* 改行などの削除
* テキスト置換する（2つまで）

`Alt+M`で呼び出す。Macだと`Option+M`。

# 機能

### 全角に挟まれた半角スペースを削除

   日本語pdfをコピーすると、このように半角スペースが挟まってしまうことがある。テキストボックスに文字列を入力したら、即座に全角に挟まれた半角スペースを削除する。
    
e.g.)
    日本語pdfについて、日本語間に空白ができることがある。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/ddc600c0-d21d-e575-1bab-f8d8107f6aa4.png)
    改行が半角スペースとなっており、邪魔。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/d65d4a40-5709-8133-0091-74c728ba2ccc.png)
    ↓
    テキストボックスにペーストすると半角スペースが削除される。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/2a643039-6ce8-c02e-5fd6-ca39ecb461e3.png)

### 改行などの削除
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/f871ddaf-7e28-17ac-590a-fb726e0f3ee7.png)



* `NL`
    改行→半角スペースにする。Altを押してもこれが実行され、さらにクリップボードにコピーされる。
    e.g.) 
    ```
    I have a pen.
    I have an apple.
    ```
    ↓
    ```
    I have a pen. I have an apple.
    ```

* `BL`
    空白となっている行を消去する。
    e.g.) 
    ```
    I have a pen.
    
    I have an apple.
    ```
    ↓
    ```
    I have a pen.
    I have an apple.
    ```


* `NL&Spc`
    改行のみを削除する。
    e.g.) 
    ```
    I have a pinea
    pple
    ```
    ↓
    ```
    I have a pineapple
    ```

* `Copy`
    クリップボードにコピーする。

* `~Spc~`
    文字列の先頭(前方/左側)及び末尾(後方/右側)にある空白文字を一括削除

* `ALL`
    すべての半角スペースを一括削除

* `Cmd`
    ネットでコマンドラインをコピーするときに邪魔な、`$`+`半角スペース`、`%`+`半角スペース`、`>`+`半角スペース`、`+`+`半角スペース`を削除する。
    e.g.)
    ```
    $ cd Desktop
    $ ls
    ```
    ↓
    ```
    cd Desktop
    ls
    ```
* `cnt`
    文字数カウントする。右下に文字数が表示される。

* etc
    * テキストボックスにペーストすると自動で全角に囲まれた半角スペースが削除されるが、何回かフォーカスしないと途中までしかやってくれないかもしれないので注意。
    * 履歴が3つまで残る。（History1~3）
    * 下段のテキストボックスはなにもしないので元のテキストの保存用に。Memoは履歴には残らないただのテキストボックス。

### 文字列置換
置換前wordに置換したいと思っている文字列を入力し、置換後wordに変換する文字列を入力。Beforeの欄に、テキストを入れると、Afterに置換後のテキストがリアルタイムで出力される。`クリア`でテキストボックスがクリアされ、`変換`を押すとクリップボードにコピーされる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/a95e6562-1aac-cbc9-b693-b8bdbcc4023b.png)

↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316390/9a90efc5-3131-c311-0de9-0d916be9ca0e.png)




# Chrome拡張の導入方法
1. [リポジトリ](https://github.com/kentoak/replace-text)をGitHubからクローンするかzipファイルをダウンロードしてunzip。
2. Chromeを起動しの拡張機能の管理ページ(chrome://extensions)で、画面右上のトグルボタンをクリックしてChromeのデベロッパーモードをオンにする。
3. デベロッパーモードを起動すると表示されるバーの一番左の「パッケージ化されていない拡張機能を読み込む」というボタンを押し、先程このリポジトリをダウンロードしたフォルダを選択する。
【SwiftUI】iOS16からシェアの実装がめっちゃ簡単になってた

# はじめに
iOS16からSWiftUIに新しいUIコンポーネントが追加されました。
その中に`ShareLink`というものがあったので使ってみたら驚きの簡単さだったので紹介します。

# 以前の実装方法
https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034

このようにUIKitをうまく使わないと使用できませんでした。
```swift
import SwiftUI

struct ContentView: View {
    @State var isSharePopover: Bool = false
    var body: some View {
        Button("シェア") {
            share()
        }
        .popover(isPresented: $isSharePopover) {
            ShareView()
        }
    }
    // iPhone: ハーフモーダル
    // iPad: ポップアップ
    func share() {
        if UIDevice.current.userInterfaceIdiom == .pad {
            isSharePopover = true
        } else {
            let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
            let activityViewController = UIActivityViewController(activityItems: [link], applicationActivities: nil)
            let scene = UIApplication.shared.connectedScenes.first(where: { $0.activationState == .foregroundActive }) as? UIWindowScene
            let viewController = scene?.keyWindow?.rootViewController
            viewController?.present(activityViewController, animated: true, completion: nil)
        }
    }
}

struct ShareView: UIViewControllerRepresentable {
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let link = URL(string: "https://qiita.com/SNQ-2001/items/86646b661ccc4a7a9034")!
        let activityViewController = UIActivityViewController( activityItems: [link], applicationActivities: nil)
        return activityViewController
    }
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}
```

# ShareLinkを使用すると...
1行で書くことができました！
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ShareLink(item: URL(string: "https://qiita.com/SNQ-2001/items/45f30b8b757e3e4fae5a")!)
    }
}
```
![スクリーンショット 2022-11-16 19.25.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4f8649a9-7562-39e3-8c79-e82344fef1ee.png)

### ラベルをカスタマイズする
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ShareLink(item: URL(string: "https://qiita.com/SNQ-2001/items/45f30b8b757e3e4fae5a")!) {
            Text("シェアボタン")
        }
    }
}
```
![スクリーンショット 2022-11-16 19.29.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/406e1cf0-e8c1-4b9b-d026-ce0ea3e67f5e.png)

### SharePreviewをカスタマイズする
![スクリーンショット 2022-11-16 19.33.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2207b3b9-8d99-872e-c2e4-d1120bb33a2e.png)
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        ShareLink(item: URL(string: "https://qiita.com/SNQ-2001/items/45f30b8b757e3e4fae5a")!, preview: SharePreview("ここがシェアプレビューです", icon: Image(systemName: "wind.snow")))
    }
}
```
![スクリーンショット 2022-11-16 19.35.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/a3b74b1b-a2ce-61d9-e1f2-99f87bf76c50.png)

# おわり
SwiftUIがどんどん便利になってますね
次はWebViewあたりを対応して欲しいですね〜
【RSpec】validate_uniqueness_ofでテストが落ちるときの対処

## 環境
Rails 6.1.3.1
ruby 2.7.1
mysql Ver 8.0.26

## 

```shoulda-matchers```というGemを使ってテストを書くとき、下記のエラーでテストが通らない。

```ruby
it { is_expected.to validate_uniqueness_of(:number) }
```

```
Expected Employee to validate that :number is unique, but this could not
be proved.
After taking the given Employee, whose :number is ‹0›, and saving it
as the existing record, then making a new Employee and setting its
:number to ‹0› as well, the matcher expected the new Employee to be
invalid, but it was valid instead.
```


## 解決法
https://github.com/thoughtbot/shoulda-matchers/blob/3e9d69ba7b6cc37251deb08f1a8866c97cf2bc0c/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb

> This matcher works a bit differently than other matchers. As noted before, it will create an instance of your model if one doesn't already exist. Sometimes this step fails, especially if you have database-level restrictions on any attributes other than the one which is unique. In this case, the solution is to populate these attributes with values  before you call `validate_uniqueness_of`.

ドキュメントにも書いてあるが、```validate_uniqueness_of```はモデルのインスタンスがまだ存在しない場合インスタンスを作成する。このときに今回でいうと```number```が一意でなかったためテストが落ちてしまった。
Factoryでインスタンスを生成しておくとテストが通るようになる。

```ruby
subject { build(:employee) }
it { is_expected.to validate_uniqueness_of(:number).ignoring_case_sensitivity }
```
WSL2上でKubernetes学習環境を構築 (minikube)

# はじめに
minikube を用いた Kubernets 学習環境の構築方法です。WSL2のインストールについては、過去に方法でインストールしていたため本記事のやり方については試していません。

# 想定環境
- OS： Windows 10 (64bit)
    - __hyper-vを使う場合はPro版が必要です__
- WSL2必須

# WSL2のインストール
注意事項
1. WSL2をインストールするにはWindows 10 のバージョンが2004以降である必要があります。
満たしていなければOSをアップデートしてください。
1. WSL2のインストールにはVT-x等の仮想化支援技術を有効にする必要があります。
タスクマネージャー等で確認できますので無効になっている場合は有効にしてください。
(BIOSの設定を変更する必要があります。)

OSのバージョンに問題がなければ、PowerShellを開いて以下のコマンドを実行します。
```
wsl install -d Ubuntu
```
上記のコマンドを実行するとWindows上にLinuxサブシステムがインストールされるので、
スタートからインストールしたUbuntuを起動しUbuntuの初期設定を行う。（ユーザ名，パスワード等）

Ubuntu以外のLinuxディストリビューションがインストールしたい人は、
以下のコマンドでインストール可能なディストリビューションを調べることができるので適宜変更してください。
```
wsl --list --online
```

- 参考
 
https://learn.microsoft.com/ja-jp/windows/wsl/install

# Dockerのインストール
Windows上に「Docker Desktop」をインストールします。
これにより、先ほどインストールしたWSL2上でもDocker使用できるようになります。

以下からインストーラをダウンロードしインストールしてください。
- 注意
WSL2上でもDockerを使えるようにするために、Enable WSL 2 Features（WSL 2 機能を有効にする）のオプションが設定ページで選択されているかどうかを確認してください。

- インストーラ

https://docs.docker.com/desktop/install/windows-install/

- 参考
 
https://docs.docker.jp/docker-for-windows/install-windows-home.html

# Kubernetes 及び kubectl のインストール
1. 先ほどインストールしたDocker Desktopを起動してください。
1. 右上の歯車ボタンを押してSettingを開きます。
1. 左のメニューの中からKubernetesを選択します。
1. 「Enable Kubernetes」にチェックを入れ、右下の「Apply & restart」を押すと
Kubernetes 及び kubectl のインストールが始まります。

# minikubeのインストール
先ほどの段階で Kubernetes が使用できるようになりますが、私の環境だとプロキシが原因なのかKubernetesが起動できなかったので minikube のインストールを行います。今回は、WSL2上に minikube をインストールしますが、Windows上にPowerShellを使って minikube をインストールすることも出来ます。ただ、PowerShellを使ってインストールした環境だと minikube のチュートリアルでサービスのURLが表示されず動作確認ができませんでした。WSL2上では問題なかったため、今回はWSL2上にインストールします。

Ubuntuを起動し以下のコマンドを実行することで minikube をインストール出来ます。
パッケージをダウウンロードし、
```
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
```
インストールします。
```
sudo dpkg -i minikube_latest_amd64.deb
```
インストールが完了したらPowerShell上で以下のコマンドを実行し minikube が起動するかチェックしてください。プロキシ環境では、Docker Desktop 及び minikube にプロキシの設定をする必要があります。
```
minikube start
```
以下のコマンドで minikube の停止及び削除ができます。
```
minikube delete
```

- 参考

https://minikube.sigs.k8s.io/docs/start/

# 動作確認
WSL2上にインストールしたminikubeで公式のチュートリアルを実行できました。

- 公式チュートリアル

https://kubernetes.io/ja/docs/setup/learning-environment/minikube/

# 追記
確認の仕方が間違ってただけでPowerShellで動かしたminikubeでもチュートリアルの動作確認ができました。また、hyper-vでの動作確認もしたので追加しておきます。

- Hyper-vで起動（管理者モードでPowerShellを起動する必要あり）
```
minikube start --vm-driver="hyperv"
```
Redmine APIでチケットを登録しようとしたが題名がありませんとエラーになる

# はじめに

仕事でRedmineを利用することが多いですが、やはり手作業で色々やる工程が多いので不便なところが多く自動化しようとして詰まった箇所がありましたのでまとめます。

# 問題

Redmineのチケットを作成するためにPostmanを利用して以下のJSONをPOSTしました。

```
{ 
    "project_id": "676",
    "tracker_id":"4",
    "subject": "新規チケット",
    "description": "APIで作成しました",
    "status_id": "1",
    "priority_id": "4",
    "custom_fields":[{
        "id":10,
        "name":"Project No", 
         "value":"100"
    }] 
}
```

すると「題名がありません」というエラーが発生しました。

調べたところAPIがうまく叩けておらず、最初のバリデーションエラーが返ってきているようでした。

「題名」というエラーがあるのでAPI自体は叩けていることがわかります。

# 解決方法

以下のようにJSONを設定することでうまく動きました。

```
{ 
    "issue": { 
        "project_id": "676",
        "tracker_id":"4",
        "subject": "新規チケット",
        "description": "APIで作成しました",
        "status_id": "1",
        "priority_id": "4",
        "custom_fields":[{
            "id":10,
            "name":"Project No", 
             "value":"100"
        }] 
}}
```

issueというキーに書く必要があるようでした

# おわりに

調べたところすぐにわからず、割と時間をとってしまったので誰かのためになればと思います。

Redmineの自動化は割と楽しそうな気配がしています。