OmniAICreator/Qiita-1.07M huggingface dataset:
モダン言語に慣れたらC++の配列アクセスが気になる

## 配列の領域外のアクセス時のエラー（Go言語）

普段はGo言語を使っているのですが、以下のようなコードを書いて、０〜９以外の値を入力するとアクセスエラーが発生します。

例えば、以下のようなプログラムを書いて実行してみます。

```golang
package main

import "fmt"

func main() {
	a := make([]int, 10)
	var x int
	fmt.Print("x = ")
	fmt.Scan(&x)
	a[x] = 1
}
```

ここで、`10`を入力すると配列外参照になるので、当然エラーが発生してくれます。

```txt
x = 10
panic: runtime error: index out of range [10] with length 10
```

## C++の場合
### 配列の場合
配列の場合は、エラーが発生しないのはC言語と同じなので知っていました。

例えば、以下のようなプログラムを書いた場合、`10`を入力してもエラーが発生しません。この場合、領域外が書き換えられてしまします。

```c++
#include <iostream>

int main()
{
    int a[10];
    int x;
    std::cout << "x = ";
    std::cin >> x;
    a[x] = 1;

    return 0;
}
```

### std::array, std::vectorの場合

ここを勘違いしていました。**vectorなどを使った場合は領域外参照でエラーが発生してくれるものと考えいました**。

例えば、以下のようなプログラムを書いて`10`を入力するとGoと同じようにindexエラーが発生すると考えいましたが、実際に書いて動かしてみると**エラーは発生しません**。

```c++
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> a(10);
    int x;
    std::cout << "x = ";
    std::cin >> x;
    a[x] = 1;

    return 0;
}
```

リファレンスを見ると、以下のよう`at`をつかって書けばに書けば領域外参照のエラーが発生するようです。

```c++
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> a(10);
    int x;
    std::cout << "x = ";
    std::cin >> x;
    a.at(x) = 1;

    return 0;
}
```

```txt
x = 10
libc++abi: terminating due to uncaught exception of type std::out_of_range: vector
```

ググってみると、以下のような記事がありました。

[コピペすると(たぶん)どこでvectorを範囲外参照しているかがわかるソースコード(を作りたい)](https://fplusfplusf.hatenablog.com/entry/2023/11/23/192416)

C++20以降であればこの記事のコードを貼り付けると一応チェックできるようです(自分の環境では`no type named 'source_location' in namespace 'std'`となり、チェックできず)。

最近モダン言語に慣れてしまったせいで、領域外参照は当然のようにチェックしてくれると思っていました。久しぶりにC++を使って気をつけなきゃいけないと思い記事にしました。

まぁ、チェックしていたら速度面で不利になるので当然といえば当然の実装なんですけど・・・

（追記）
思ったより、色々コメントをいただいています。私もC言語、C++言語をメインでずっと使ってきていたので、C/C++の言語のポリシーはある程度理解しているつもりです。ただ、久しぶりにC++を使うと、プログラマ側の負担が大きな言語だと感じました（スキルが必要と言い換えることも可能かも）。
良くも悪くも、そこがC言語なのですが。
ホントにSESはやめとけ!?客先常駐歴8年の私が教えます

私は客先常駐の機械エンジニアとして新卒から約5年半、SES会社でITエンジニアとして3年ほど働いた経験があります。<strong>客先常駐のエンジニアというと「客先常駐はやめとけ」って意見が多くあり、あまりいい噂は聞かないですよね。</strong>ただしこう言った主張の中には、「この人客先常駐で働いたことないだろうな」ってものも結構見受けられます。

そこで今回はわりと長い期間、客先常駐エンジニアをしてきた私が体験に基づいて、ぶっちゃけどうなのか？おすすめできるのか？について紹介したいと思います。客先常駐という働き方に興味がある方、ぜひ最後まで読んでいってください！


<iframe width="560" height="315" src="https://www.youtube.com/embed/_Yn3dnGXvo0?si=WYeivITOwLiVH-pn" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## SESってなに？
**SESは自分が所属している会社とは別の会社に出社して、別の会社（客先）で与えられた業務に従事する働き方**です。IT業界では客先常駐のことをSES（System Engineering Service）と言ったりしますが、同様の意味となります。

客先と所属している会社とで合意した時間単価で契約を結び、エンジニアはそこで決められた期間働きます。期間は短期仕事の場合は1〜2ヶ月という場合もありますが、基本的に3ヶ月単位で結ばれることが多いです。3ヶ月ごとに客先とエンジニア双方に契約を継続するか確認をして、お互いに合意が取れればさらに3ヶ月延長というように契約をしていきます。

## SESのメリット・デメリット
実際に客先常駐エンジニアとして働いてきて、私が感じたメリット・デメリットについて以下にまとめます。

【メリット】

- 未経験でも実務経験を積みやすい
- 仕事内容を簡単に変えられる
- いろいろな開発現場を中から見ることができる

【デメリット】

- 案件ガチャ
- 人間関係が難しい
- 契約が不安定

## 【結論】SESはやめとくべき？
![Conclusion-that-SES-should-not.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784196/e52a2a58-3f22-282b-4fa6-265aa6dbaee5.jpeg)

最初に結論から申し上げると、<strong>「やめとけってほどではないが、特別おすすめはしない。やるなら3年くらいと、期間を決めてやるのが吉」</strong>です。なぜこの結論に至ったか、解説します。

### なぜやめとけではないのか？
私がやめとけってほどではないと考える理由として、未経験でもとりあえずエンジニアとして働ける点があります。上記メリットでも述べましたが、客先常駐であれば比較的簡単に未経験からでもエンジニアとなることができます。

未経験からのエンジニア転職の場合、まず**エンジニアとして働いた経験の有無**がこれからのキャリアにとても重要となります。ただ**自社開発をやっているような企業は、狭き門で採用されるのが難しくまず経験を積むのが難しい**です。

自社開発企業に固執して二の足を踏み続けるのは時間がもったいないので、それだったら比較的入社が容易なSES企業などに入ってとりあえず経験を積むのがおすすめです。ただ才能があって自社開発で働けるような人であれば、自社開発に入ったほうが良いと思います。

### なぜおすすめはしないのか？
これはできる仕事の範囲に制限があり、**中級者程度でスキルが頭打ち**してしまうからです。やはり客先常駐は他社のエンジニアのため、上流の設計工程のような責任ある業務を行うことができないことが多いです。重要な仕事は社員が行い、客先常駐のエンジニアは人が代わってもできる仕事をやることが多いので、レベルもそれなりのものとなってしまうためスキルが伸び悩みが起こります。

私の体感としては最初はスキルが全くない状態のため成長を実感できていましたが、3年くらいを境に成長が鈍化を感じるようになりました。そのため**3年くらいを目処**に期間を決めて、転職などの次のキャリアを考えましょう。3年の実務経験があると、未経験のときの求職活動とは打って変わって多くの企業から転職のお誘いがかかると思います。

## まとめ
これから客先常駐をやってみようか迷われている方に向けて、私が客先常駐エンジニアとして働いてみて感じたことをまとめてみました。よく「客先常駐はやめておけ」なんて意見をよく見ますし、たしかに嫌な思いをしたことも今までにありました。

ただ**エンジニアになるため、再現性の高い方法**でもあります。今まで経験してきたことをこの記事に込めたので、これからのキャリアをお考えの方に参考になると幸いです。

<br>

SESがおすすめできる人など、より詳しい内容は以下にあります。もっと詳しく知りたい方は、こちらをご覧ください:bangbang:

https://taishi-official.com/2020/03/22/75/


### おまけ

https://qiita.com/taishi_will_be/items/70a8ce8938944286b487

[>> 未経験からエンジニア転職を目指す際に知っておくべき情報](https://taishi-official.com/first-engineering-career-change/)
[>> 失敗しないエンジニア転職完全ガイド(履歴書・職務経歴書の書き方や面接対策)](https://taishi-official.com/changing-engineer/)

<br>

<strong>＼Follow me／</strong>

- X（旧Twitter）：https://x.com/taishi_it_blog
- Instagram：https://www.instagram.com/taishi_will_be/
- YouTube：https://www.youtube.com/@Engineer_ILLBE
- TikTok：https://www.tiktok.com/@taishi_will_be
- note：https://note.com/taishi_wii_be/

<br>

最後に良かったら「いいね」お願いします:thumbsup:
Docker Docs AIアシスタントが日本語での質問・回答にも対応


# 概要


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/76f83f4c-9fdb-6d64-ffa0-cd4728f44628.png)


Docker 公式ドキュメント（ https://docs.docker.com/ ）の「Ask AI」は、**日本語で** Docker に関係する質問ができるようになっています。（Ask AI に関しては[公式ブログ](https://www.docker.com/blog/docker-documentation-ai-powered-assistant/)での言及、[日本語訳「DockerのドキュメントにAI搭載のアシスタントが登場」](https://www.docker.com/ja-jp/blog/docker-documentation-ai-powered-assistant/)を参照ください）。

質問に対する回答は、Docker の公式ドキュメント等のソースに従って回答し、回答中でソースのURLも示せます。そのため、他の生成AI（チャットボット）等と比べると、公式ドキュメントに基づいた正確な情報を提供しますので、dockerコマンドの使い方や、用語の意味を効率的に調べるのに役立ちます。

# 使い方

公式ドキュメント https://docs.docker.com/ をウェブブラウザで開きます。画面右下に「 Ask AI 」（AIに質問する）ボタンがありますので、こちらをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/d80bd1f9-9f72-1a37-92c7-3ebdba2ae8ad.png)

次に、入力欄が表示されます。そこに、日本語で質問を入れ、エンターキーを押すか、「→」ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/a0a5ce62-827e-0866-470d-4943bd3124da.png)

あとは、自動的に内容が表示してくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/5e40181e-5290-5fe2-f92f-26bbc84a226f.png)

あとは、引き続き質問を続けられます。

回答内容が明らかに期待しない内容の場合や、出力を止めたい場合は、「Stop Generating」（生成を停止）のチェックボックスをクリックし、チェックを入れると直ちに出力が止まります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/d7bb5362-9d51-052c-ad98-fd79f448b1ad.png)


# 日本語を使うコツ

このAI（チャットボット）は、いわゆる生成AIでいうところのRAG(retrieval augmented generation system)を提供する [kapa](kapa.ai) という SaaS を使っている模様です。おそらく GPT か何かの言語モデルが後ろで動いていると考えられます。

そのため、そのまま日本語で入力しても、質問の意図が理解できない場合があります。例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/f83915f0-d6e1-cbde-d30f-3cc73ccfcab5.png)

このような場合は、ChatGPT等と同じように、質問条件を変えると望ましい回答が出る場合があります。例えば、先の「Docker ボリューム」を英語の「Docker Volume」とすると、より詳しい回答になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/a1fc4437-7f7d-2018-337d-133eb83413b0.png)

あるいは、次のように入力内容を英語に変換し、回答を日本語で求める方法も使えます。例：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/ed23d51b-4441-c7dd-2baf-1c30ddbde994.png)


# ドキュメントの翻訳や解説にも使えます

公式ドキュメントは英語ですが、翻訳が難しい技術的な内容も翻訳でき、背景も教えてくれます。例えば、次の例はドキュメントの本文を引用し、その意味と背景を訊ねる内容です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13002/f1367293-b558-515e-5221-ec367135dd1c.png)


# エラーが出たら

英語でエラーメッセージが出て、出力が止まる場合があります。その場合は、ウェブブラウザでページそのものを読み込み直してください。

# 注意点や感想

ざっくりと使ってみたところ、回答内容は学習・訓練された印象を受けます。注意点としては、一般的な言語モデルによる回答同様、100%最新の情報かつ完全な回答ではないかもしれません。ですが、回答内容にソースを示していますので、内容の妥当性を利用者自身で検証・確認できます。ドキュメントを隅々読むような時間が無いときや、細かなコマンドや技術要素について深く考えたいときに、役立つのではないでしょうか。


Enjoy!


# 参考

- [Docker Documentation Gets an AI-powered Assistant | Docker](https://www.docker.com/blog/docker-documentation-ai-powered-assistant/)
- [DockerのドキュメントにAI搭載のアシスタントが登場 | Docker](https://www.docker.com/ja-jp/blog/docker-documentation-ai-powered-assistant/)
RustのSledを使ってとにかくかんたんにキーバリューストアしてみた


たまたま急にオクテット列とオクテット列を対応させたくなったので、
今回は、Rustで使えるシンプルで高性能なキーバリューストアのSledというのを試してみました。

## Sledについて

https://docs.rs/sled/latest/sled/

Sledは高性能な埋め込みデータベースです。

- スレッドセーフでアトミックな操作
- 複数の独立したキー空間を持つツリー
- ACIDトランザクションやキーの更新監視
- 効率的にデータを統合

## とにかく使ってみる

`Cargo.toml`はこんな感じです。

```toml:Cargo.toml
[package]
name="handson-sled-sync"
version="0.0.0"
edition="2021"

[dependencies.sled]
version="^0.34.7"
```

今回は`sled`だけに依存します。たいへんシンプル。

### 開く・閉じる

まずはここからです。

```rust:src/main.rs
use std::error::Error;

fn main(
)->Result<(),Box<dyn Error>>{
	let db=sled::open("db")?;
	db.flush()?;
	Ok(())
}
```

`sled::open("db")`で開きます。
閉じる前には`db.flush()`が（生成AI的には）おすすめのようですが、今回は無くても同じようなフォルダの構造はできていました。 でもやっぱり ~~生成AIに期待して、~~ 心配なので、今回はちゃんと`db.flush()`することにします……。だって見た感じ`std::ops::Drop`を実装している気配がなくて怖いんだもん。

ちなみにこんな構造のフォルダができました。

```
db/
|-- blobs/
|-- conf
`-- db
```

### 挿入・取得・削除

まずは基礎の基礎として、挿入、取得、削除をやってみます。

```rust:src/main.rs
use std::error::Error;

fn main(
)->Result<(),Box<dyn Error>>{
	let db=sled::open("db")?;
	dbg!(db.get(b"")?);
	db.insert(
		b"",
		b"",
	)?;
	dbg!(db.get(b"")?);
	db.remove(b"")?;
	dbg!(db.get(b"")?);
	db.flush()?;
	Ok(())
}
```

これを実行するとこうなりました。

```
[src/main.rs:7:2] db.get(b"")? = None
[src/main.rs:12:2] db.get(b"")? = Some(
    [],
)
[src/main.rs:14:2] db.get(b"")? = None
```

キーとして空のオクテット列`b""`を使います。

最初に`db.get`で取得してみると、キーになにもないことが確認できました。
次に`db.insert`でキーに空のオクテット列`b""`を対応させます。
今度は`db.get`で取得してみると、キーに空のオクテット列`b""`があることを確認できました。
次に`db.remove`でキーを削除してみます。
今度は`db.get`で取得してみると、キーには再び何もないことが確認できました。

### トランザクション

途中でやめたりやめなかったりできます。

```rust:main.rs
use std::error::Error;
use sled::transaction::ConflictableTransactionError;
use sled::transaction::TransactionError;

fn main(
)->Result<(),Box<dyn Error>>{
	let db=sled::open("db")?;
	dbg!(db.get(b"")?);
	let _:Result<(),TransactionError<&str>>=db.transaction(
		|tree|{
			tree.insert(
				b"",
				b"",
			)?;
			Err(ConflictableTransactionError::Abort("something wrong"))
		}
	);
	dbg!(db.get(b"")?);
	let _:Result<(),TransactionError<&str>>=db.transaction(
		|tree|{
			tree.insert(
				b"",
				b"",
			)?;
			Ok(())
		}
	);
	dbg!(db.get(b"")?);
	db.flush()?;
	Ok(())
}
```

これを実行するとこうなりました。

```
[src/main.rs:8:2] db.get(b"")? = None
[src/main.rs:18:2] db.get(b"")? = None
[src/main.rs:28:2] db.get(b"")? = Some(
    [],
)
```

まずはトランザクションを途中でやめてみます。ただやめたいというだけでやめられます。

```rust
let _:Result<(),TransactionError<&str>>=db.transaction(
    |tree|{
        tree.insert(
            b"",
            b"",
        )?;
        Err(ConflictableTransactionError::Abort("something wrong"))
    }
);
```

このとき、中の`tree.insert`は起こってほしくないですが、ちゃんと起こってないことが確認できています。

次はほぼ同じクロージャーで`Ok(())`を返してみます。今度はちゃんと反映されていることが確認できました。

## 結論

ご覧の通り、オクテット列をオクテット列に対応させる程度の目的で、ちょっと使うだけなら記事一枚に収まる簡単さです。

これなら急にオクテット列とオクテット列を対応させたくなってもすぐになんとかできますね✨


## 付録

### 閉じる前の`db.flush`本当に必要か問題

結論としてはわからなかったです。

やっぱり生成AIにの主張は検証すべきというのが正論なのでちょっと調べてみました。

一応ちゃんとソースコードを`grep`してみてはいるんですけど`Db`は`std::ops::Drop`を直接は実装していないようです。（`db.flush`が必要だと思う根拠）

`Config`のところに書いてある例では`flush_every_ms`という設定があったようです（`db.flush`が必要ないと思う根拠）、が、今はなさそうです（`db.flush`が必要だと思う根拠）。
データベースのバージョン管理ツール調べてみた

# 背景
社内で使っているCRMアプリケーションを社外に売り出していこうという方針になり、となるとDBもクライアントの数用意しないと、となり、アプリケーションコードの管理はGitでしてるけど、DBも同じことしないと大変では？というのが発端
# 見つけたのは下記の5つ
| サービス名 | 料金 | 備考 |
|:-----------|------------:|:------------:|
| [liquibase](https://www.liquibase.com) | 無料版あり。料金非公開 | ー   |
| [Flyway(Redgate)](https://flywaydb.org/)     | 無料版あり。チームエディションが年597USD/ユーザ | JAVAベース？ |
| [SQL Server Data Tools (SSDT)](https://visualstudio.microsoft.com/vs/features/ssdt/)       | ツール自体は無料        | VS用ツール？ |
| [dbForge Source Control](https://www.devart.com/dbforge/sql/source-control/)         | 約200ドル          | ー           |
| [ApexSQL Source Control](https://www.apexsql.com/sql-tools-source-control/)       | 年508CAD/ユーザ       | SSMSアドイン       |
【Next.js エラー対応】"Image with src "/images/[image-file-name.png]" has either width or height modified, but not the other..."

Next.js の next/image で画像の縦横比を設定しろと怒られた場合の対処法。
（公式マニュアルをちゃんと読んでおけば遭遇しないやつ）

### エラーメッセージ

```
"Image with src "/images/[image-file-name.png]" has either width or height modified, but not the other. If you use CSS to change the size of your image, also include the styles 'width: "auto"' or 'height: "auto"' to maintain the aspect ratio."
```

直訳：「[画像名]は幅か高さのどちらかが変更されていますが、もう一方は変更されていません。CSSを使って画像のサイズを変更する場合は、縦横比を維持するために「width: "auto"」または「height: "auto"」スタイルも含めてください。」

### 元のコード

```reacttypescript
<Image
    className='mx-auto hover:opacity-80'
    src='/images/bannd'
    width={180}
    height={48}
    priority
/>
```

### 解決策

CSS で画像の width か height のいずれかに auto を指定し、縦横比を維持してやることで解決。

```reacttypescript
<Image
    className='mx-auto hover:opacity-80'
    src='/images/banner.png'
    alt='d'
    width={180}
    height={48}
    style={{ // 追加
        width: '100%',
        height: 'auto',
    }}
    priority
/>
```

### ボツ案

Next.js 12 以前の方法：
`layout="responsive"` を追加。これにより、画像は親要素に対してレスポンシブになり、指定した幅と高さを基にアスペクト比が維持される。

```reacttypescript
<Image
    className='mx-auto hover:opacity-80'
    src='/images/banner.png'
    alt='代替テキスト'
    width={180}
    height={48}
    layout='responsive' // 追加
    priority
/>
```
Javaで「ラッパークラスの利用」の動作を確認してみた

# 概要

Javaで「ラッパークラスの利用」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/var/index13.html

# 実装

以下のファイルを作成しました。
```JSample13_1.java
class JSample13_1{
  public static void main(String[] args){
    Integer i = Integer.valueOf(10);
    int val = i.intValue();

    System.out.println("i = " + val);
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample13_1.java 
$ java JSample13_1 
i = 10
```

# まとめ

何かの役に立てばと。
セキュリティ対策

情報の漏えいや不正な利用から守るために開発者が行う対策をまとめる




## **:point_up:パラメータ改ざん**
GetとPostの送信方法のうち、
アドレスバーからURLパラメータを直接改ざんし不正利用する攻撃

対策➡Getではなくセキュリティのさらに強いPostを使う




## **:point_up:SQLインジェクション**
クエリ※を操作して不正にデータベースを操作する、
SQL文の脆弱部分を不正利用した攻撃

対策➡正しいセミコロン、シングルクォーテーションを心掛け、
　　　エスケープ処理をする
対策➡SQLよりPHPのプリペアドステートメント※を利用する


###### クエリとは
データベースに対する命令文のこと



###### プリペアドステートメント（prepared statement）とは
プログラム上で動的にSQL文を生成する必要があるとき、
可変部分を変数のようにしたSQL文をあらかじめ作成しておき、
値の挿入は処理系に行わせる方式。
実行効率を向上させ、SQLインジェクションを防止する効果がある。
https://e-words.jp/w/%E3%83%97%E3%83%AA%E3%83%9A%E3%82%A2%E3%83%89%E3%82%B9%E3%83%86%E3%83%BC%E3%83%88%E3%83%A1%E3%83%B3%E3%83%88.html



## **:point_up:クロスサイトスクリプティング(XSS)**
SNSなどのユーザー入力サイトで悪質なスクリプトを表示すること

対策➡勝手なコードをうたせないように入力値を制限する
対策➡スクリプトの構成に必要な記号(<>など)を置換させる

⇒htmlspecialchars関数が担ってくれる
　記述方法：
 ```
 htmlspecialchars( 変換対象, 変換パターン, 文字コード )
 ```
 https://techplay.jp/column/600




## **:point_up:クロスサイトリクエストフォージェリ(CSRF)**
気づかない間に自分が悪者にされてしまうような、
意図しないリクエストを強要して攻撃手法

対策➡トークン※を使って、
正しいフォームから遷移された正しいデータであることを確かめる

##### トークンの作成方法
トークンはセッションIDをハッシュ化して作成される⇒hash関数が担ってくれる
記述例（バージョンごとに異なる方法）：
```
hash('sha512', 'テスト', false)
```
https://asaoka.site/blog/php-hash/


## **:point_up:セッションハイジャック**
他人のセッションIDを盗んで本人になりすます。例としてクレジットカードの不正利用が挙げられる

対策➡画面遷移するたびにセッションIDを再作成する⇒session_regeneraite_id関数が担ってくれる
記述方法：

``` 
session_regenerate_id(true) 
```
マルチスレッド

プロセス内に```複数の流れ```を持ちます。
...
一つのスレッドしか持たないプログラムをシングルスレッドプログラム、２つ以上のスレッドを持つプログラムをマルチスレッドプログラムと呼びます。

### 長所
* ページテーブルのコピーが不要なため、```生成時間が短い```
* 様々なリソースを同じプロセス内の全スレッド噛んで共有するため、メモリをはじめとした```リソース消費量が少ない```。
* 全スレッド間でメモリを共有するため、見かけ上の協調動作がしやすい。
#### 気づき
協調動作とはなんだろう
### 短所
* ```一つのスレッドの障害が全スレッドに影響```する。例えば一つのスレッドが不正なアドレスを参照して以上終了すると、プロセス全体が以上終了する
* 各スレッドが呼び出す処理が```マルチスレッドプログラムから呼び出し良いかどうかを熟知しておく必要```がある。例えば内部的にグローバル変数を排他制御なしにアクセスしている処理は、スレッドセーフではい。この場合は、```同時に一つのスレッドからしか当該処理を　呼ばないようにプログラマが制御しないければならない```。

#### 気づき
スレッドを意識したプログラムをしたことがないのでいつか触れるのだろう。

# 出典
https://gihyo.jp/book/2022/978-4-297-13148-7

# 感想
この後のカーネルスレッド、ユーザスレッドに違いがいまいち理解できないので飛ばす
robloxでassistant その66

# 概要
robloxでassistantやってみた。
練習問題やってみた。

# 練習問題
Quaternionを、見つけたので、使え。

# 手順
- ServerScriptServiceに、scriptを追加。
- スクリプトを書く。

```
local Quaternion = {}
Quaternion.__index = Quaternion
function Quaternion.new(w, x, y, z)
	local invLength = 1 / math.sqrt(w * w + x * x + y * y + z * z)
	local self = setmetatable({
		W = w * invLength,
		X = x * invLength,
		Y = y * invLength,
		Z = z * invLength,
	}, Quaternion)
	return self
end
function Quaternion.fromAxisAngle(axis, angle)
	local sin = math.sin(angle / 2)
	return Quaternion.new(math.cos(angle / 2), sin * axis.X, sin * axis.Y, sin * axis.Z)
end
function Quaternion:Conjugate()
	return Quaternion.new(self.W, -self.X, -self.Y, -self.Z)
end
function Quaternion.__mul(self, other)
	local w = self.W * other.W - self.X * other.X - self.Y * other.Y - self.Z * other.Z
	local x = self.X * other.W + self.W * other.X - self.Z * other.Y + self.Y * other.Z
	local y = self.Y * other.W + self.Z * other.X + self.W * other.Y - self.X * other.Z
	local z = self.Z * other.W - self.Y * other.X + self.X * other.Y + self.W * other.Z
	return Quaternion.new(w, x, y, z)
end
function Quaternion:ToAxisAngle()
	local angle = math.acos(self.W) * 2
	local sin = math.sin(angle / 2)
	local axis = Vector3.new(self.X, self.Y, self.Z) / sin
	return axis, angle
end
function Quaternion:ToCFrame()
	local nx = self * Quaternion.new(0, 1, 0, 0) * self:Conjugate()
	local ny = self * Quaternion.new(0, 0, 1, 0) * self:Conjugate()
	local nz = self * Quaternion.new(0, 0, 0, 1) * self:Conjugate()
	nx = Vector3.new(nx.X, nx.Y, nx.Z)
	ny = Vector3.new(ny.X, ny.Y, ny.Z)
	nz = Vector3.new(nz.X, nz.Y, nz.Z)
	return CFrame.fromMatrix(Vector3.zero, nx, ny, nz)
end
function Quaternion:Slerp(other, t)
	local rel = other * self:Conjugate()
	local axis, angle = rel:ToAxisAngle()
	angle *= t
	return Quaternion.fromAxisAngle(axis, angle)
end


local part = Instance.new("Part", game.Workspace)
part.Position = Vector3.new(-10, 1, -10)
part.Anchored = false
local p = part
local s, positive = 0, true
local origin = p.CFrame
local speedMultiplier = 100
game:GetService("RunService").PostSimulation:Connect(function(DeltaTime)
	local rot = math.pi / 8
	local identity = Quaternion.new(1, 0, 0, 0)
	local up = Quaternion.new(math.cos(rot / 2), 0, 0, math.sin(rot / 2))
	local right = Quaternion.new(math.cos(rot / 2), math.sin(rot / 2), 0, 0)
	local final = up:Slerp(identity, math.sin(math.rad(s))) * right:Slerp(identity, math.cos(math.rad(s)))
	p.CFrame = origin * final:ToCFrame()
	s += DeltaTime * speedMultiplier
end)

```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/ba7ed375-d590-cf10-d099-09d224266081.png)


以上。
面接官「0.1 + 0.2 == 0.3 が成立しない理由を説明せよ」

## 面接官「0.1 + 0.2 == 0.3 が成立しない理由を説明せよ」

という質問がきたらどう答えるだろうか。


## 0.3にはならない

### Javascript
適当なブラウザから以下のようなJavascript実行した。結果「0.1+0.2==0.3」は「false」となった。

```js
0.1+0.2==0.3
//false
0.1+0.2===0.3
//false
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552182/e0a4c538-1729-487b-503c-e1f632b2a7c6.png)


ちなみに以下のような先頭に0をつけなくても、小数点として解釈される。
```js
.1+.2==.3
//false
```

### Python
バージョン3.10.11で検証する。同様に「0.1+0.2==0.3」は「false」となった。

```py
>>> 0.1+0.2==0.3
False
```

## なぜか

これは、計算機が浮動小数点数を2進数で表現する際に、特定の小数は正確に表現できず、誤差が発生するためです。10進数の0.1や0.2は、2進数では無限に続く循環小数となるため、これらの数値を正確に表現することができません。その結果、0.1 + 0.2 は 0.3 と等しくならないことがあります。


### 小数点以下の数値→2進数へ変換する方法

CSを修めていればご存知方と思いますが、復習します。

1. 小数点以下の数値を2倍する
1. 結果の整数部分を取り出し、それを2進数の桁として記録する
1. 小数部分だけを次のステップに持ち越す
1. 小数部分が0になるか、所定の精度に達するまで1〜3を繰り返す



`0.1 × 2 = 0.2`
整数部分: 0
小数部分: 0.2

`0.2 × 2 = 0.4`
整数部分: 0
小数部分: 0.4

`0.4 × 2 = 0.8`
整数部分: 0
小数部分: 0.8

`0.8 × 2 = 1.6`
整数部分: 1
小数部分: 0.6

（以下省略）

最終的に0.1は`0.0001100110011001100110011....`となる。


## まとめ

この問題の本質は、コンピュータが浮動小数点数を扱う際の誤差にあります。浮動小数点数の精度と表現方法を理解しておくことが重要です。


（追記）
言語仕様によるよ！
どういった仕様で実装されているか本質的な部分にも関心向ける機会ってあんまりなですよね。
robloxでassistant その65

# 概要
robloxでassistantやってみた。
練習問題やってみた。

# 練習問題
VehicleSeatを、使え。

# 手順
- workspaceに、VehicleSeatを追加。
- VehicleSeatに、scriptを追加。
- スクリプトを書く。
```
local Players = game:GetService("Players")
local seat = script.Parent
local currentPlayer = nil
local function onOccupantChanged()
	local humanoid = seat.Occupant
	if humanoid then
		local character = humanoid.Parent
		local player = Players:GetPlayerFromCharacter(character)
		if player then
			print(player.Name .. " has sat down")
			local me = game.Workspace:WaitForChild(player.Name)
			currentPlayer = player
			seat.Position += Vector3.new(0, 0, -10)
			me.HumanoidRootPart.Position += Vector3.new(0, 0, -10)
			return
		end
	end
	if currentPlayer then
		print(currentPlayer.Name .. " has got up")
		currentPlayer = nil
	end
end
seat:GetPropertyChangedSignal("Occupant"):Connect(onOccupantChanged)


```

以上。
M1 MacでVSCodeを用いてCloud RunにFlaskのHello Worldアプリケーションをデプロイする方法

このドキュメントでは、M1 Macを使用してVSCodeでFlaskのHello WorldアプリケーションをGoogle Cloud Runにデプロイする手順を説明します。

# 前提条件

1. M1 Macを使用していること
2. Google Cloudアカウントを持っていること
3. Dockerとgcloud CLIがインストールされていること
4. VSCodeがインストールされていること

# 手順

## 1. Google Cloudプロジェクトの作成

1. [Google Cloud Console](https://console.cloud.google.com/)にアクセスし、新しいプロジェクトを作成します。
2. プロジェクトIDをメモしておきます。ここでは例として`helloworld-project`とします。

## 2. Google Cloud SDKの設定

1. Google Cloud SDKをインストールしていない場合は、[インストール手順](https://cloud.google.com/sdk/docs/install)に従ってインストールします。
2. ターミナルで以下のコマンドを実行して認証します。

```sh
gcloud auth login
gcloud config set project helloworld-project
```

## 3. Flaskアプリケーションの作成

1. VSCodeを開き、新しいディレクトリを作成します。

```sh
mkdir flask-hello-world
cd flask-hello-world
```

2. 必要なファイルを作成します。

```app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)
```

```requirements.text
Flask==2.0.3
gunicorn==20.1.0
Werkzeug==2.0.3
```

```.dockerfile
# Use the official Python image from the Docker Hub
FROM python:3.9-slim

# Set the working directory
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

# Install any needed packages specified in requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

# Make port 8080 available to the world outside this container
EXPOSE 8080

# Run gunicorn when the container launches
CMD ["gunicorn", "--bind", "0.0.0.0:8080", "app:app"]
```

## 4. Dockerイメージのビルドとテスト

ターミナルで以下のコマンドを実行してDockerイメージをビルドします。
注意点として、M1MacではDockerイメージが、Cloud RunのLinux x86_64環境と互換性がないため、以下のコマンドを用いてビルドする必要があります。

```sh
docker buildx build --platform linux/amd64 -t flask-hello-world .
```

Dockerイメージをローカルでテストします。

```sh
docker run -p 8080:8080 flask-hello-world
```

ブラウザで [http://localhost:8080](http://localhost:8080) にアクセスし、"Hello, World!"が表示されることを確認します。

## 5. Dockerイメージのタグ付けとプッシュ

DockerイメージをGoogle Container Registryにタグ付けします。

```
docker tag flask-hello-world gcr.io/helloworld-project/helloworld
```

DockerイメージをGoogle Container Registryにプッシュします。

```
docker push gcr.io/helloworld-project/helloworld
```

## 6. Cloud Runにデプロイ

以下のコマンドを実行してCloud Runにデプロイします。

```sh
gcloud run deploy helloworld \
  --image gcr.io/helloworld-project/helloworld \
  --platform managed \
  --region us-central1 \
  --allow-unauthenticated
```

デプロイが成功したら、表示されたURLにアクセスしてアプリケーションが動作していることを確認します。

# まとめ

これで、M1 Macを使用してVSCodeで作成したFlaskのHello WorldアプリケーションをGoogle Cloud Runにデプロイする手順は完了です。デプロイされたアプリケーションは、指定されたURLで公開されています。お疲れ様でした！

# 参考リンク

- [GCP 初心者の M1 Mac ユーザーが Cloud Run にデプロイするときにドツボにはまったこと](https://zenn.dev/msksgm/scraps/d667e2b2eecf4e)
Form I-9 Compliance Insights: Common Mistakes, Alternative Procedure, Audits, E-Verify & Electronic Solutions

About

Nine months into the new version of Form I-9: Are you up to date? This webinar dives deep, exploring updates to the latest Form I-9 and unpacking the alternative procedure. We’ll address potential audit concerns and the importance of internal audits for ongoing compliance. Is paper I-9 chaos holding you back? Learn how E-Verify and electronic I-9 software streamline verification, saving you time and resources.

Limited seats available! Register now to gain valuable insights and master I-9 compliance strategies.

When

Thursday, May 23, 2024 · 11:30 p.m. IST (GMT +5:30)

Agenda

Understand key changes and address common questions surrounding the new Form I-9
Comprehend the Form I-9 Alternative Procedure and the Requirement of Form I-9 Policy
Discover E-Verify enrollment advantages and streamlined verification with E-Verify Web Services.
Overcome the major challenges associated with completing paper-based Form I-9s.
See how electronic I-9 software simplifies the process, mitigates risks, and ensures ongoing compliance.
Address concerns about potential audit spikes following the implementation of the alternative procedure.
Witness the power of electronic I-9 software firsthand through a live demonstration of I-9 Assist and its features.![form i.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3678143/05aa7725-97d0-197f-9f15-cd8c0df6d12c.png)
[Tableau] 点数をドーナツチャートで表現したいよ

これを作った記録です！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/b3be24ea-7931-23a3-51a3-4282967149df.png)

こちら参考にさせて頂きました。先人に大感謝。
[【Tableau Tips】ドーナツチャートの作成方法](
https://blog.truestar.co.jp/tableau/20210506/43977/)


# 考え方

やってみた結果、まとめるとこんなイメージです。
* スコアを表現する円グラフと、真ん中の穴を表現する円グラフを用意して重ねる
* スコアを表現する円グラフには``スコア``と、``100-スコア`` を角度に用いる

# ドーナツをつくっていく
### 1. 計算フィールド ``100-スコア`` を作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/8c9fc262-e91e-1a5f-01ac-26b2e262be18.png)


### 2. 計算フィールド ``1`` をつくる
なんで？はうまく説明できないので、冒頭の参考ページを読んでください。
わたしみたいな面倒くさがりさんは、おまじないだと思ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/19bb3adc-6f67-64d4-9898-3cb8ff24bc78.png)


### 3. ふたつの円グラフをつくる

行シェルフに``1``を"最小値"で配置し複製。
マークは「円グラフ」を選択。

::: note info
Tips1：右クリックしながらドラッグ＆ドロップでスマートに集計の種類を選択
Tips2：Ctrl押しながらドラッグ＆ドロップで複製
:::

円グラフが２つ表示されるので、右側のフィールドを右クリックで「二重軸」
ヘッダーも非表示にしておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/bfe57813-4d8d-5d1e-0b41-e09545a272f7.png)


### 4. 円を上下に分かつ線（ゼロライン）を消す

背景右クリック　「書式設定」-「線の書式設定」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/10efa03e-2356-b28d-713a-203d1207eeab.png)


### 5. ドーナツの穴をつくる

マークの中、２つ目の円グラフ（ (2)となっている方）の色とサイズを編集する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/613a147f-521f-a0c8-0667-1b5e1b516e99.png)


### 6. スコアを割合っぽく表現する

１つ目の円グラフ（(1)となっている方）の「角度」に ``メジャーバリュー``を配置する。
※データエリアの一番下にあるよ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/5a7772ca-b001-519d-6af5-d143ebd21c3b.png)



配置すると、「マーク」の下に「メジャーバリュー」エリアが出現する。

ありとあらゆるメジャーが入ってくるんで必要な項目のみ残す。足りないものがあれば追加する。

今回は``睡眠スコア``と``100-[睡眠スコア]``を角度で表現したいから配置。
平均点を表示するようにしたいから集計の種類も「平均」に変更。

するとこんな感じになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/0ef601a1-5ae9-3fca-556c-ae985d4cb7fa.png)

「角度」に``メジャーバリュー``が、「詳細」に``メジャーネーム``が設定されました。

まだ見た目に変化はありませんね。
なぜかって？色分けする指標を設定していないからです。

### 7. 色で割合を表現する

「詳細」に設定されていたこの``メジャーネーム``を、「色」までドラッグ＆ドロップ。
すると割合が一目でわかるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/e730ed42-0093-eb2d-a6f6-a055a5f2ee64.png)



### 8. 思いやりをもって整える
* 色
* ラベル
* ツールヒント（カーソルあてたときに出てくるやつ）
* フォント

など。**このあたりが丁寧に処理されていると洗練された感じがでる**と思っています。


## ドーナツ完成！

これこれ～！こういうのが欲しかったんだよ～！というのが出来ました。
きれいなものができるとTableauはどんどん楽しくなりますね。
進捗率などを表現するのにおすすめです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798299/f28b716c-d2ae-1128-7510-c095ecabfb85.png)
【Docker】VSCodeのショートカットを上書きせずにデタッチする

# 結論
### 1. Dockerの設定ファイルにアクセス
※Windowsをお使いの方は別途調べてみてください
```zsh
vim ~/.docker/config.json
```

### 2. デタッチに指定したいコマンドを設定
今回は`ctrl + [`を２回入力するとデタッチが発火するようにしました。
```zsh
{
　　　　... 色々な設定,
  # 以下を追加
  "detachKeys": "ctrl-[,ctrl-["
}
```

### 3. 以上！！！

# 経緯・まとめ
Dockerでコンテナを立ち上げている時に、`attach`をするとコンテナ内で記録されたログを確認することができます。
API開発などをしている場合に非常に有用です。

しかし、
「一旦コンテナから抜けて別の作業しよう〜」って
**`ctrl + c`をタイプするとコンテナが落ちてしまうんですよね。。。**


それでどうにかならないかなと調べてみると、`ctrl + p, ctrl + q`をタイプすると、コンテナを落とさない状態で抜けることができるとのことでした。
しかし、VSCodeのデフォルトショートカットと上記のコマンドが競合してしまうことから、**VSCodeのショートカットを上書きしないといけないっぽいらしいのです。**

https://qiita.com/Statham/items/c204e85067ea4dca2724

https://tech.withsin.net/2015/09/30/docker-container-detach/

な~んか抵抗感があったので、どうにかならんかと調べていたところ、、、

「Dockerの設定ファイル自体を編集しちゃえばいいんじゃない？」

ってことに気づいて公式ドキュメントを確認してみたら、なんと専用の設定項目ありました。

https://docs.docker.com/engine/reference/commandline/cli/

やっぱ、第一に公式ドキュメントを確認するのが、バグ？を解決する近道だと気付かされた今日この頃でした。。

この記事を最後まで見ていただき、ありがとうございます！
もし記事が参考になりましたら、ハート・ストックを押していただけますと記事を書く励みになるのでお願いします！

ではでは！！
PNG⇛JPEG変換メモ（Python）

### やりたかったこと

PNG⇛JPEGをする。
今回問題となったのは、PNG画像の拡張子をJPEGに変えてるだけで、内部情報はPNGのままで怒られてしまった。
そのため、JPEGにしっかり変換する（新卒並感）



### 解決
以下OpencvでJPEG変換するコード。今回エラーとなっていたのは、imwriteする時に保存先をしている第一引数を変数でhogehoge.pngを指定し、無限ループが起きていた。（for文で第四引数のクオリティを下げて画像サイズを小さくしていた。）

第一引数の拡張子は.jpgにしよう（戒め）

```
# 該当PNG画像
image = cv2.imread('hoge.png')

# JPG画像として保存する
cv2.imwrite('hoge.jpg', image, [int(cv2.IMWRITE_JPEG_QUALITY), 95])
```



しかし、これでちゃんと中身までJPEGに変換されているかは確認できない。怪しいし、動作確認でのエビデンスはどうしよう・・・・

というわけで下記サイトに出会った。どうやらバイナリの先頭部分（シグネチャ）で判定できるらしい。

https://xaro.hatenablog.jp/entry/2017/05/17/103000



```
# ファイル読み込み
with open(image_file_path, mode='rb') as f:
    image = f.read()

# バイナリ変換した画像ファイルをターミナルに表示してみる
print("hoge.jpeg =>" + str(image[:8]))
```


先頭が「\xff\xd8」であればJPEG、「\x89PNG\r\n\x1a\n」であればPNGとなっているようなので、そちらをコンソールで確認。






以下の記事が詳しそうだったので後々読みたい。

https://qiita.com/spc_ehara/items/e425b6dcc0398299c40d#%E7%9B%AE%E6%AC%A1
Go言語とは

# はじめに
こんにちは！WebエンジニアになりたいK.Yです!
今回はGo言語について学んだことを書きたいと思います。
※認識が間違ってたら、コメントしてくれると嬉しいです:grinning:

# Goとは
Go言語とは、2009年にGoogleによって作られたオープンソースの静的付けプログラミング言語です。
Go言語は、コマンドツールライン、Webアプリケーション、クラウドやコンテナ技術などに使われています。
YouTubeやメルカリ、クックパッドなど、大規模なユーザー数を誇るサービスの開発に使用されています。

# Go言語のメリット
- シンプルで可読性の高いコードを書きやすい。
<p>Goはコードを書く自由度が高くない。
<br>そのため、誰が書いても同じ様なコードになりやすい。
<br>複数人でコードを書いても、作業効率は落ちにくい。
</p>

---
- 実行速度が速い
<p>
コンパイル速度が早く、コンパイル済みのプログラム実行速度もC言語に迫る速さ。
<br>処理が高速なので、プロダクトのパフォーマンス改善にも大きく期待できる。
</p>

---
- エラーがわかりやすい。
<p>
Goはコンパイル言語なのですが、コンパイルとはプログラミング(ソースコード)を
<br>すべて機械語に翻訳されてから実行されます。
<br>コンパイル言語は翻訳時に文法エラーが出るため、実行する前にバグを見つけやすい。
</p>

# 最後
これからGoを勉強していくので、Goについてのアウトプットを増やしていけたらと思います。
読んでいただきありがとうございました。
データ分析で3Dプロットを第三角法で使う

中学校の技術で立体で何か設計する時にキャビネット図や等角図など色々やりましたが、その中でデータサイエンスにも昇華できると思うのが三角投影図です。
今は三角投影図ではなく第三角法と言われているそうですが(自分が中学校の時は三角投影図と習いましたゆとり世代です)。

# 第三角法
第三角法では立体図形を右上に置いて左上に上から見た図、左下に横(左)から見た図、右下に正面から見た図を作ります。
イメージ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/90b5408c-7d34-a6e7-df82-7890f6c6e9e2.png)
これを基に、3Dでのプロットで三次元でのプロットだけでは分からない詳細な部分を他の三面図で表します。

# 関数
```Python3
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
def factor_plot3D(x, y, z, c=None, cmap=None):
    fig = plt.figure(figsize=(16,10))
    ax1 = fig.add_subplot(2, 2, 1)
    ax1.scatter(x, y, cmap=cmap, c=c)
    ax2 = fig.add_subplot(2, 2, 2, projection='3d')
    ax2.scatter(x, y, z, cmap=cmap, c=c)
    ax3 = fig.add_subplot(2, 2, 3)
    ax3.scatter(z, y, cmap=cmap, c=c)
    ax4 = fig.add_subplot(2, 2, 4)
    ax4.scatter(x, z, cmap=cmap, c=c)
    plt.show()
```

## 使用例
ここではScikit-Learnのwineデータに対して主成分分析で三次元にしたデータを第三角法の観点からプロットしてみようと思います。
```Python3
from sklearn.decomposition import PCA
import pandas as pd

df = pd.read_csv("wine.csv")

y = df["Wine"]
x = df.drop("Wine", axis=1)
for col in x.columns:
    x[col] = (x[col] - x[col].mean())/x[col].std()
pca = PCA()
pca.fit(x)
tx = pca.transform(x)
factor_plot3D(tx[:, 0], tx[:, 1], tx[:, 2], c=y, cmap="brg")
```
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/75cdba38-da90-d4f9-1310-2fa751549238.png)
このように3Dのプロットでは右上から観察されているため左から見た図が非常に重要になります。

# まとめ
中学校で習ったことも使い方次第では役に立つ。
Splunk - SPLを読みやすくする

## 検証環境
Splunk Enterprise 9.2.1

## はじめに
SPLはパイプ（|）が出てきたからといって別に改行しなくてもいいんだけど、改行した方が見やすいし、何より理解しやすい。１行でずらーーーーっと書かれたSPLは読む気が失せる。手動で改行していくのも面倒臭い。そんな方向けの話です。

## [1] 自らがSPLを書く時
パイプ（|）を入力したら勝手に改行してくれたら嬉しい。それ、出来ます。

1. Splunk Webにログイン
1. ログインしたユーザ名をクリック
1. 「基本設定」をクリック
1. 「SPLエディター」タブをクリック
1. 「詳細エディター」がOFFの場合はONに変更
1. 「全体」タブの「サーチオートフォーマット」をONに変更

これでパイプ（|）を入力すると自動で改行してくれます。

## [2] 誰かが作成したSPLを読む時
１行にずらーーーーっと書かれたSPLを綺麗に整形してくれると嬉しい。これも出来ます。

1. Splunk Webにログイン
1. 「Apps」から「Search & Reporting」をクリック
1. １行にずらーーーーっと書かれたSPLをサーチ欄に未整形のままコピペ
1. Command(⌘)+shift(⇧)+F を同時に押す（Macの場合)

これでパイプ（|）やサブサーチに合わせて整形してくれます。

## どう変わるのか
画面上のようなサーチではなく、画面下のようなサーチになる。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3310888/aff1c5f7-f2e9-30b4-b600-a30dcff54dad.png)

## 終わりに
見やすいのが良いよね。整形するためのショートカットは他にも色々あって便利なものがありそう。
数理最適化で、つぼを積んでみよう

## 問題

特大、大、中、小のつぼが3つずつ、合計12本あります。
それぞれの高さは100cm、80cm、60cm、40cmです。
つぼを縦に重ねると上のつぼが下のつぼに20cmだけ入って低くなります。
たとえば、小の上に大を重ねると`40 + 80 - 20`で100cmになります。
ただし、下のつぼが大きいときは、上のつぼがほぼ入りますが、10cmだけ入り切りません。
たとえば、大の上に小を重ねると`80 + 10`で90cmになります。
3つのつぼをおける場所があります。つぼを重ねて高さを130cmに収めるにはどうすればよいでしょうか？

## 考え方

各つぼを頂点とし、重ねることを辺とすると、[運搬経路(配送最適化)問題](https://qiita.com/SaitoTsutomu/items/1126e1493ff601a858c9)（VRP）として解くことができます。

デポを1つ用意し、デポからすべてのつぼに距離0でつなげます。つぼ間は、重ねたことで高くなる分が距離になります。

## Pythonで解いてみる

VRPを解くためのPyVRPを使って解いてみましょう。PyVRPは、`pip install pyvrp`でインストールできます。

https://pyvrp.org/

デポは、`add_depot()`で1つ用意します。
置く場所は車両になります。ここでは`add_vehicle_type()`で3台用意します。
つぼに相当する拠点は、`add_client()`で追加します。
辺は、`add_edge()`で追加します。

```py
from pyvrp import Model
from pyvrp.stop import MaxIterations

size = [40, 60, 80, 100]  # 小、中、大、特大の高さ
over = [  # 行の上に列を積んだときの増える高さ
    [20, 40, 60, 80],
    [10, 20, 40, 60],
    [10, 10, 20, 40],
    [10, 10, 10, 20],
]
# 12個のつぼの種類
vases = [0] * 3 + [1] * 3 + [2] * 3 + [3] * 3

m = Model()
depot = m.add_depot(0, 0)
m.add_vehicle_type(3, depot=depot, max_distance=130)
for index in vases:
    nd = m.add_client(0, 0)
    m.add_edge(depot, nd, size[index])
    m.add_edge(nd, depot, 0)
for ifr, fr in zip(vases, m.locations[1:]):
    for ito, to in zip(vases, m.locations[1:]):
        d = 0 if fr == to else over[ifr][ito]
        m.add_edge(fr, to, d)
result = m.solve(MaxIterations(100), display=False)
print(result)
```

**出力**

```
Solution results
================
    # routes: 3
   # clients: 12
   objective: 390.00
# iterations: 100
    run-time: 0.18 seconds

Routes
------
Route #1: 12 8 5 3 
Route #2: 10 9 6 2 
Route #3: 11 7 4 1 
```

出力のRouteは重ねたつぼを意味し、左が下で右が上です。Routeの番号は各つぼで、数字の小さい方から、小、中、大、特大です。数字を見ると下から、特大、大、中、小になっています。

## 補足

高さを最小化したい場合は、高さを二分探索で求めるとよいでしょう。

以上
ポケモンで学ぶ"状態"の英訳

# これってStatus？State？
こんな疑問から考えてみた
以下はあくまで浅い個人の解釈


# ポケモンでの"Status"
いわゆるステータスなのでイメージがしやすい
・レベル
・HP
・こうげき
・すばやさ

などが挙げられる。
「このポケモンの状態は〇〇だ。」と言い換えられるものが該当しそう


# ポケモンの"State"は？
上で述べた
「このポケモンの状態は〇〇だ。」
と対称させて考えるのであれば
「このポケモンは〇〇な状態だ。」
と解釈するのがしっくりきやすいように思う

「Statusはレベル100だ。」に比べると
「レベル100のStateだ。」には若干違和感がある

「健康な状態だ。」から考えると、少し変化するが
「もうどくの状態」、「ひんしの状態」なんかもStateなのだろう

「状態はもうどくだ」には違和感のないことが、
このStatus/Stateの使い分けのややこしいところだと思う
英語でもある程度は交換可能らしいので完全な切り分けは無理


# 排他的か、そうでないか

「状態は〇〇だ」、「〇〇な状態」だけでは区別できない部分を切り分けるため
もう一つの視点として"排他性の有無"を提案する

`Status.IsPoisoned = true/false (どく状態)は Status で
`State = Poisoned なら State というのが個人的な解釈

`Status.IsPoisoned` の場合、Status のメンバは複数あることが予想される
`Status.IsBurned` (やけど)
`Status.IsFainted` (ひんし)
などは同じクラス内のメンバとして常に存在する。

一方で `State = Poisoned` は他の要素を排除している
`State = Burned`, `State = Fainted` はそれぞれ排他的に存在する状態だ

一般にポケモンはまひしながらどくをあびながらひんし…のような状態になることはない
なのでいわゆる「状態異常」の"状態"は State になる、と思っている


# 結論
### Status
・「状態は〇〇だ。」で表せる
・非排他的

### State
・「〇〇な状態だ。」で表せる
・排他的

### おまけ
statusか、stateか、というテーマを書こうとしたときにぱっと思い浮かんだのは
`switch(state)`
`if(status.IsError)`

という使い分けだが、これだけだとあまり展開させられる感じがしなかったので
著名タイトルの力を借りることにした
GitLabのssh登録にpbcopyが便利すぎた

## 結論

```bash
cat ~/.ssh/id_rsa.pub | pbcopy
```

上記のコマンドを実行すれば、生成した公開鍵の中身をクリップボードにコピーすることができます。そして、コピーした内容をGitLabのsshの公開鍵の登録テキストフィールドにペーストすれば簡単にできます。

## ssh公開鍵生成

```bash
ssh-keygen -t ed25519 -C "<comment>"
```

上記のコメントの部分には任意のテキストを入力してください。

今回は公式のページによるとRSAよりセキュリティが高いと言われているED25519を生成する想定でいます。

## 参考記事

[SSHキーを使ってGitLabと通信します。 | GitLab](https://gitlab-docs.creationline.com/ee/user/ssh.html#ed25519-ssh-keys)

[Macな人は pbcopy が便利 - Qiita](https://qiita.com/mktakuya/items/c57a12b5b072a658acd0)

[macOSのターミナルでのクリップボード操作(pbcopy/pbpaste)](https://zenn.dev/notakaos/articles/20220921-macos-pbcopy-pbpaste)
【Mac】Icebergを用いてターミナルをいい感じにする

久しぶりにMacを買い替えて、ターミナルの初期設定に地味に時間がか
思い出しがてら備忘録として残します。

## 設定後のターミナル
![スクリーンショット 2024-05-22 23.11.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010278/9a70cafb-aa87-980c-5876-104a44bce1cf.png)


## Icebergとは
https://cocopon.github.io/iceberg.vim/
目に優しいダークブルーの配色のテーマ。


## 1. icebergのテーマをインポートする
1. 公式サイト（ https://cocopon.github.io/iceberg.vim/ ）を開く

2. `Iceberg for macOS`の真下にあるDownloadボタンをクリックする
![スクリーンショット 2024-05-22 21.54.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010278/30ca4330-4d3c-b5b9-4c03-6f9fcd378147.png)

3. ターミナルを起動し、設定を開く
![スクリーンショット 2024-05-22 21.51.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010278/cca11d4a-76de-fe26-4fc8-11b9e1724fcb.png)

4. 3点リーダーの箇所をクリックし、読み込むを選択。ダウンロードしたファイルを開く

![スクリーンショット 2024-05-22 22.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1010278/dc8e6c77-d9df-341f-6875-6a5bd1352602.png)


5. `Iceberg`が読み込めたら、`Iceberg`を選択した状態で、三点リーダーの隣にある`デフォルト`をクリックする（これをしないと反映されない）

## 2. フォントを変更する
- フォント：Menlo
- サイズ：18

## 3. 背景色を変更する
「カラーとエフェクト」をクリックし、不透明度を91%に設定する
ここはお好きな透明度に.....

## 4. プロンプトを変更する
Macのデフォルトのままではみにくいので、変更していきます。

1.`.zshrcプロファイル`を作成

```sh
 touch ~/.zshrc
```

2.以下コマンドを実行する。
```sh
vim ~/.zshrc
```
3.以下内容をコピー&ペーストする
```sh
# git
autoload -Uz vcs_info
setopt prompt_subst
zstyle ':vcs_info:git:*' check-for-changes true
zstyle ':vcs_info:git:*' stagedstr "%F{magenta}!"
zstyle ':vcs_info:git:*' unstagedstr "%F{yellow}+"
zstyle ':vcs_info:*' formats "%F{cyan}%c%u[%b]%f"
zstyle ':vcs_info:*' actionformats '[%b|%a]'
precmd () { vcs_info }

# プロンプトカスタマイズ
PROMPT='
[%B%F{red}%n%f%b:%F{green}%~%f]%F{cyan}$vcs_info_msg_0_%f
%F{yellow}$%f '
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion

```

| コマンド | 説明 | 例 |
| ---- | ---- |---- |
| %n | ユーザー名 |piyopiyo|
| %m | ホスト名 |piyopiyonoMacBook-Pro|

もしホスト名も入れたかったら、以下のような形に変更する。
`PROMPT='
[%B%F{red}%n@%m%f%b:%F{green}%~%f]%F{cyan}$vcs_info_msg_0_%f
%F{yellow}$%f '`


4.`esc`を押して、続けて`:wq`と入力する
5.設定を反映する
```
source .zshrc
```

6.反映されてたらヨシ！
（反映されない場合は、ターミナルを再起動等してみる。）



## 参考記事
https://medium.com/@kjmczk/mac-terminal-53a3d4ac06c7

https://hirlab.net/nblog/category/macbook/art_911/#%E8%A6%8B%E3%81%9F%E7%9B%AE%E3%81%8C%E3%83%80%E3%82%B5%E3%81%84%E3%81%AE%E3%81%A7%E3%81%A9%E3%81%86%E3%81%AB%E3%81%8B%E3%81%99%E3%82%8B
ターミナル環境をWarpでもなんでもiTermっぽくする

# きっかけ

コマンドラインツールに悩んでいた頃に、iTermを使っている人がショートカットキーでパカパカアプリを切り替えているのが羨ましかった。

当時Warpが流行っていたのでWarpでそういうことができないかなぁと思って調べた。

# ショートカットキーで任意のアプリをパカパカする

まず、HammerSpoonをインストールします。

```
brew install hammerspoon
```

init.luaに以下のコードを書いて再読み込みさせます。

```
hs.hotkey.bind({'ctrl'}, 'q', function()
  local warp = hs.application.find('Warp')
  if warp:isFrontmost() then
    warp:hide()
  else
    hs.application.launchOrFocus('/Applications/Warp.app')
  end
end
```

# 動作

`Ctrl+q`で任意のアプリがパカパカします。

# 余談

同じ要領でWindowsライクにFinder(Explorer)をパカパカできるようにしてます。

```
hs.hotkey.bind({'ctrl'}, 'e', function()
  local finder = hs.application.find('Finder')
  if finder:isFrontmost() then
    finder:hide()
  else
    hs.application.launchOrFocus('/System/Library/CoreServices/Finder.app')
  end
end
```

# 参考

https://qiita.com/senth/items/4c7dc7f97e6607bcd112
僕とGitとエイリアス

## Gitのエイリアスを設定しよう！
SourcetreeのようなGUIを使ってる方も多いと思うのですが、私の環境だと動作が重たいことが多く使い勝手がイマイチでした。
また、そもそも操作はIDE上（ターミナル上）で完結したいというのがあります。
かといって急に慣れないコマンドを打とうとすると、あれ、このコマンドどう打つんだっけ？と毎回ググる羽目になって生産性が悪いなと。

そんな中、エイリアス設定をすれば自分が覚えやすいようにコマンドを短く設定できます。また、エイリアスを設定しておくファイルがある種コマンドのメモ代わりになるのでそこもチョコっと便利です。


## 設定方法

`.gitconfig`に以下のようにエイリアスを追記するだけで設定完了です！

```
[alias]
    co = checkout
    cob = checkout -b
```


## 私が設定してるエイリアス
### `git co`
`git checkout`
ブランチの切り替えです。

### `git cob`
`git checkout -b`
新しいブランチを作ってそのブランチに切り替えます。
    
### `git br`
`git branch`
ブランチの一覧を表示します。

### `git cu`
`git branch --show-current`
現在のブランチ名を表示します。
cuはcurrentの略のつもりです。


### `git pl`
`git pull origin $(git branch --show-current)`
現在のブランチをプルします。

この場合、複数コマンドを使ってるのでエイリアスの設定は以下のようになります。
```
[alias]
    pl = !git pull origin $(git branch --show-current)
```


### `git ps`
`git push origin HEAD`
現在のブランチをプッシュします。

※ 誤ってプッシュしてしまうのが怖いのでもしかしたら設定しないほうが良いかもしれません。


### `git mg`
`git merge`
ブランチのマージをします。


### `git logo`
`git log --oneline`
1行ずつコミットログを出力します。


### `git undo`
`git reset --soft HEAD^`
直前のコミットを取り消します。
softなので作業内容は消えません。

### `git save`
`git stash save`
コミットされてない変更を一時的に退避させます。

ブランチを切り替えるときに、コミットしてない分が競合してしまうのを防ぐのに便利です。

### `git ap`
`git stash apply stash@{0}`
退避した作業を元に戻します。


### `git edit`
`git config --edit --global`

`vi ~/.gitconfig`と同じです。
`.gitconfig`の存在をいつも忘れてしまうでこれを設定してます。
また、設定してたエイリアスを忘れてしまった時（本末転倒な気もする）はこのコマンドでカンニングしてます。


## まとめ
以上、Gitエイリアスの設定方法と私が設定してるエイリアス一覧でした！
他にも「こんなGitのエイリアス便利だよー」というのがあれば是非教えてください！
【jquery】もっとも簡単なモーダルの設置方法（複数設置可）

<p>プラグイン不要で複数設置可能なモーダルウィンドウの実装方法をご紹介します。</p>

<p>【実装のポイント】</p>
<ul>
<li>ボタンとモーダルコンテンツをidで紐づけて複数対応を可能にしています。</li>
<li>モーダルを開いた後どこをクリックしても閉じるようにしています。</li>
</ul>

<p>CSSやhtmlの構造はお好みで調整ください。</p>

<br>
<p><b>【最低限のサンプル】</b></p>
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="JjqYzjJ" data-pen-title="easy modal" data-user="abiwvsjx-the-builder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/abiwvsjx-the-builder/pen/JjqYzjJ">
  easy modal</a> by H M (<a href="https://codepen.io/abiwvsjx-the-builder">@abiwvsjx-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

<br>

<p><b>【ちょっと整えたサンプル】</b></p>
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="wvbKOGZ" data-pen-title="easy modal deco" data-user="abiwvsjx-the-builder" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/abiwvsjx-the-builder/pen/wvbKOGZ">
  easy modal deco</a> by H M (<a href="https://codepen.io/abiwvsjx-the-builder">@abiwvsjx-the-builder</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>
[過去記事]AWS Lambda コード書き換えた時の反映とテストの流れ

## 概要

今回はLambdaのコードを書き換えた時の流れをまとめます。ようはコード書き換え後のルーティン手順です。この手順を行わないとせっかく書き換えたコードが反映されないこともありますのでしっかり抑えておきましょう！

また、今回の説明には下記の記事で構築した内容を使います。詳細は下記をご確認ください。（当該の環境を構築していなくても本記事の内容はご理解いただけると思います！）

https://qiita.com/miriwo/items/7470659f070504e0fafe

## 方法

### 場所の確認

まずはコードが記載されている場所を確認しましょう。
AWSにログイン後、Lambdaにアクセスし、サイドバーの「関数」をクリックします。

![Cursor_と_Lambda-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/fdffa3c0-feba-536c-9a5d-7297e2f991cb.png)

関数名をクリックします。

![Cursor_と_関数_-_Lambda-1024x221.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/9b0b2a5c-744c-533a-0b4a-006edd1c9349.png)

開いたページの「コード」の「lambda_function」タブにコードが記載されています。

![Cursor_と_test_function_-_Lambda-5-1024x572.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/4142c161-2eca-9c82-74f0-c53ca7d71d0c.png)

### コードの保存とデプロイとテスト

コードの記載されている場所が分かったところで早速本題です。
コードを編集した際には下記のステップを経る必要があります！

1. コードの保存
1. 最新状態のデプロイ
1. テスト

Lambdaのエディタは一般的なエディタ（VScode）などと違って自動保存機能がありません。。！（おそらく設定でもそのような項目は無いはず、、！素人が探した限りですが、、！）
なので必ず手動で保存する必要があります。
Macなら「cmd」+「s」などのショートカットで保存する事ができます。
これを忘れるといくらその次の動作をしたところで古いコードのままなので注意です！

さらに、変更を加えたコードをデプロイする必要もあります。コード変更後、保存し差分があると「Deploy」のボタンがクリッカブルになるのでクリックしてデプロイしましょう！

![Cursor_と_test_function_-_ラムダ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b7d2c6e6-0945-25b8-682d-87e23adba6eb.png)

最後にテストです。これはデプロイされた内容の妥当性を確認します。これも同様にデプロイ後に実施しないとあまり意味がないのでご注意ください。

## さいごに

保存、デプロイを行わないとコードが最新になりません、、！さらに妥当性のテストはAPIでエラーを発生させないために大切です。
WSL2のUbuntu 22.04にKotlin入れてHello, World!した2024春

基本的に下記記事と同じです。いえ、むしろ何も変わりませんので悪しからず。
https://qiita.com/n0bisuke/items/686c1717a894713fdd06

## 環境

- Windows 11 Pro
- WSL2
- Ubuntu 22.04
```bash
$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04.2 LTS"
```

## sdkman のインストール

zip と sdkman をインストールします。
sdkman は SDK マネージャーです。特に JDK 管理に使われるようです。

まずは zip です。
```bash
$ sudo apt install zip
...
...
Processing triggers for man-db (2.10.2-1) ...
```

次に sdkman です。公式の手順通りです。

https://sdkman.io/install

```bash
$ curl -s "https://get.sdkman.io" | bash
...
Enjoy!!!
```



最後に `Enjoy!!!` って言われるとちょっと元気出ますね。
ちなみにコマンド実行結果の冒頭に sdkman のアスキーアートが表示されます。お楽しみに。

初期化スクリプトの読み込み
```
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
```

バージョン確認
```bash
$ sdk version

SDKMAN!
script: 5.18.2
native: 0.4.6
```

これで OK です。

## Kotlin のインストール

sdkman を使ってインストールします。

```bash
$ sdk install kotlin

Downloading: kotlin 2.0.0

In progress...

##################################################################################################################################################### 100.0%

Installing: kotlin 2.0.0
Done installing!


Setting kotlin 2.0.0 as default.
```

Java をインストールします。
第三引数にバージョンを指定できます。指定しなかった場合、最新の安定バージョンがインストールされます。
```bash
$ sdk install java

Downloading: java 21.0.3-tem

In progress...

##################################################################################################################################################### 100.0%

Repackaging Java 21.0.3-tem...

Done repackaging...

Installing: java 21.0.3-tem
Done installing!


Setting java 21.0.3-tem as default.
```

バージョンを確認します。
```bash
$ kotlin -version
Kotlin version 2.0.0-release-341 (JRE 21.0.3+9-LTS)
$ java -version
openjdk version "21.0.3" 2024-04-16 LTS
OpenJDK Runtime Environment Temurin-21.0.3+9 (build 21.0.3+9-LTS)
OpenJDK 64-Bit Server VM Temurin-21.0.3+9 (build 21.0.3+9-LTS, mixed mode, sharing)
```

インストール完了です。

## Hello, World!する

私は[リッチー＆カーニハンのプログラミング言語C](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9EC-%E7%AC%AC2%E7%89%88-ANSI%E8%A6%8F%E6%A0%BC%E6%BA%96%E6%8B%A0-B-W-%E3%82%AB%E3%83%BC%E3%83%8B%E3%83%8F%E3%83%B3/dp/4320026926)から入ったので `Hello, World!` です。

Kotlin ファイルの拡張子は `.kt` です。hello.kt を作成します。
```Kotlin:hello.kt
fun main(args: Array<String>) {
    println("Hello, World!")
}
```

ソースをコンパイルします。少し時間がかかります。コンパイラのクラスをロードするのに時間がかかるそうです。オプションの意味は[公式](https://kotlinlang.org/docs/command-line.html#create-and-run-an-application)に詳しいです。
```bash
$ kotlinc hello.kt -include-runtime -d hello.jar
```

`-include-runtime` は `.jar` ファイルに Kotlin のランタイムライブラリを含めることを意味します。
`-d` はクラスファイルを出力するディレクトリを意味します。

実行します。
```bash
$ kotlin hello.jar 
Hello, World!
```

なお、Tips として、Kotlin scripting を使えば、コンパイル→実行という2コマンドを経ず、1コマンドで実行できます。

```Kotlin:hello.kts
println("Hello, World!")
```
```bash
$ kotlinc -script hello.kts
Hello, World!
```

最後に無理矢理元記事との差別化を図ったのでした。終了。
Ubuntuのデータ飛んだオワタ／(^o^)＼

# はじめに

マジで迂闊でした。

WindowsUpdateでUbuntuが起動しなくなったので色々調べて失敗したので供養。

# 問題

突然下記のエラーが発生してUbuntuが起動しない。

色々調べて参考記事のコマンドをよく考えずにコピペ実行したらダメだった。

wsl --unregister Ubuntu

# 解決方法

腹水盆に帰らず。
オワコンです。

鍵データが一部吹き飛びました。
それと、ここ1週間で作成中のWordPressはDockerのDBに保存されていたので、そのデータも吹き飛びました。

あーあ。

# おわりに

今朝の出来事。
頭真っ白になりました。

即、問い合わせ送って修正してもらったので、今後同じミスはなくなるかと思います。

誰かのミスが1つ消えたと思えば、価値ある失敗だったと思います。

# 参考

https://www.rk-k.com/archives/6873