OmniAICreator/Qiita-1.07M huggingface dataset:
運用保守で即戦力になりたい自己紹介

## 自己紹介
事後ですが自己紹介の記事を作成してみました。

自分自身を振り返りたいと思い今回記事を作成しました。

金融と流通系と様々な派遣先で運用保守メインで働いてきました。
2014年から運用保守メイン働いています。今では8年以上経験を積むことが出来ました。
**経験年数の長さが強みです。**
経験年数は当てにならないという厳しい意見はありますが、
**経験が長い分、辛い時期はありましたが辞めずに継続して様々な現場で働いてきました。**

第一希望の現職Sierに内定をいただけたのは、面接の受け答えが良かったのと運用メインでの経験年数が長かったためです。
面接の受け答えはキャリアアドバイザー利用してとても良かったです。


## インフラエンジニアになったきっかけ
新卒から働いていた派遣先は半導体業界のエンジニアの仕事でしたが、私がしていたお仕事内容が汎用的ではなかったため、IT業界へキャリアチェンジを視野に考えていましたが、SESメインでIT系企業を沢山受けましたが書類で全て落ちました。面接ではコミュニケーション能力が低いと指摘されたこともあります。
IT業界は技術よりコミュニケーション能力が問われると伺いました。
未経験で採用させるのは難しいと改めて感じました。

その後、なんとか前職の経験からエンジニアリングの特定派遣社員として内定を頂き、
様々な派遣先で2年半は頑張って働きました。
何かのタイミングでITの部署に異動になり、前職はlinuxのスクリプト作成経験があったため
2014年10月から金融系の運用保守の現場に働く機会を頂くことが出来ました。

## 過去振り返って
※職歴はIT業界以外の部分は省いて記載しております。

1~3社は客先常駐で働きました。
### 1社目 特定派遣 在籍期間 4年半弱
4年半弱のうちのインフラエンジニアの経験は1年半です。
運用保守は半年間働きました。
仮想化のサーバーの構築の手伝いを一年間しました。
金融系でjp1 AJSとlinuxを使った業務になります。
**運用保守の基本的な気を付ける点を学びました**
以下の記事にまとめています。
https://qiita.com/gama1234/items/5a6fb54194f687ab9f4a


**取得した資格 LPICレベル1、VBAの一番簡単な資格取得**
資格のlinuxコマンドの知識が大変役に立ちました。
VBAは業務の自動化に役に立ちました。

### 2社目 特定派遣 在籍期間 3年弱
1年半は主にいろんな派遣先でJP1 AJSとlinuxを使用する業務をしていました。
Bashのスクリプト経験の知識が大変役に立ちました。

流通系で1年半はクラウドの運用の現場で電話対応 8割　定型作業 8割の業務をしていました。
技術スキルというよりはコミュニケーションスキルの現場でした。
新人を指導して業務をしました。期限が短い依頼が複数ありマルチタスクに運用作業を対応することを学びました。

**取得した資格 LPICレベル2 MTAネットワークの基礎、MTAセキュリティ ITパスポート
ネットワークの基本知識、ITパスポートでITの基本を学びなおしました。
LPICレベル2は有料の講座を受けました。サーバーの構築の知識を付けることが出来ました。**

### 3社名 SES 在籍期間 10ヶ月
AWSの保守の業務をしました。
VBAで自動化したりBashのスクリプトを500行ぐらい作成していました。
nginxのサーバー構築と技術調査があったため、構築と同じぐらいの難易度はあったと思いますが、不明点が多く体調不良で現場を抜けました。

**取得した資格 AWS クラウドプラクティショナーを取得**

休職中での転職活動のため、なかなか内定が貰えず苦労しました。

### 5社目 Sier  現在 在籍期間 4年目
現在AWSの運用保守を担当しています。相談しやすい環境で気づいたら3年間働いていました。
AWSとlinuxを9割の環境でした。案件を4つ経験を積む事が出来ました。
何かあれば午前3時ごろでもお電話があって障害対応していました。
**辛い時期もありましたが、障害対応含めて一人で対応できるようになったため、一人前の運用保守になれたと思います**
今が即戦力のため、現職に貢献できるように頑張ります

**取得した資格 AWS SAA SOA DVA SAP DBS SCS取得　GCPはCDL ACEを取得**
人生の中で一番資格を取得しました。

AWS資格取得の記事にまとめました
https://qiita.com/gama1234/items/8ca518a13750a78baedf


## 現在学び中の資格
現在はLPICレベル1とLPICレベル2の再取得に向けて学んでいます。
**AWSにしてもlinuxの基本知識は必要になります。**

AWSの資格取得に向けても学習継続しています。
運用保守で必要な知識をまとめました。
https://qiita.com/gama1234/items/44d9ab15f85c7f6881b4

# まとめ
コミュニケーション能力が低いとIT業界に入る前に面接で指摘がありましたが、
一年半電話対応がメインの運用保守で活躍することが出来ました。
**慣れないことは最初は上手くいきませんが、繰り返し経験積む事である程度の事は出来ると個人的には思いました。**

資格取得は意味がないなど意見はありますが、8年半インフラエンジニアをしてみて個人的な感想ですが、
**資格は必要な基礎知識です。実務でどのように活かすかは自分次第です　資格の知識が役に立たなかったことは今まで一度もありませんでした。**

また、長く働けるかは個人的には仕事で困ったときに現場で相談しやすい環境が大事だと思いました。
**人間関係や働く環境はとても大きいです。**
同じ仕事内容でも短期離職を経験したため、短期離職になったからその仕事が向いていないということではないと思いました。**短期離職した場合は、どういった環境が自分にあっているか長く働けた環境を振り返ってみることが必要かもしれません。**

エンジニアの方であたりがきつい方や自分より優秀な若い方もたくさんいます。
他人と比較したり、人から言われたことを気にしてしまう時は**自分が今まで歩いていた道を振り返って成長した部分に目を向けた方が良いです。
中途になると実務経験は人それぞれです。そのため、全く同じ経験の人がいないかぎり比較は出来ません。**

**インフラエンジニアは学ぶことが好きな方は技術スキルはアップすると思います。**
今は40歳ですが現役で活躍出来る様に日々資格の勉強と記事のアウトプットを頑張っています。
Microsoft - AzureChatGPTをCloneしてオリジナルChatgptを作っちゃおう - ④失敗していたGithubのログイン実現

# はじめに
皆さんこんにちは。
Kazuyaです。
Microsoftから、github にて、chatgptの内部構成までを公開するような形で公開されました。
https://github.com/microsoft/azurechatgpt

*************************************************************
### この投稿は、以下の連載です。
①でDevOpsを用いて楽に環境をと思ったところ、Pipelineにミスがあるようで（多分Envilonment系）、デプロイ後に動確すると、AppServiceのURLをたたいてもエラー。
②では、ローカルで実行するとうまくいきました👌

【連載】

https://qiita.com/kazuya-ho2/items/b45054a33c2981b2b79d

https://qiita.com/kazuya-ho2/items/0d03d2fed8fa389faeb7

https://qiita.com/kazuya-ho2/items/78371596a202eda07319

*************************************************************

今回はこれまでのシリーズで失敗していた「Github」アカウントでのログインの実現です。
ではでは行ってみたいと思います。

# 前提
①～③の連載を見て失敗と挫折と成功を味わった後。

# Githubのアプリ作成のやり直し

①？②？のどちらかでやったと思いますが、今一度。
自分のGithubにアプリを作っていきます。
今回は本番環境なので以下にアクセス。

https://github.com/settings/applications/new

以下の画像を参考に設定を埋めていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/63008376-d540-c1b1-7d49-496ff74a3671.png)

※Homepage URLは、端的に、Azure AppServiceのURIです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/c45dcd68-b9b1-7bce-5677-b0e8970ae23a.png)

こんな感じですね。
これで「Register application」をクリック。


遷移後の画面で、「Client ID」と、「Generate a new client secret」をクリックして生成されたシークレットをメモする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/5b295eeb-55ff-c6ac-dd82-189d67861ff3.png)

# Azure App serviceの環境変数に入れていく。
③の作業の時はこの値はブランクにしておきました。
以下の環境変数に、上記で取得したＩＤとシークレットを設定するだけでＯＫ。

AUTH_GITHUB_ID：上記で取得した「Client ID」
AUTH_GITHUB_SECRET：上記で生成した「シークレット」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/b3741d36-6d7c-67ab-b1b1-2df31cd49666.png)

これで「Save」をクリックして、再度「App Service」のURIをクリック！
※ログアウトが実装されていないので、Azure ADでログイン済みだと、ログイン画面が表示されません。
　ので、シークレットウィンドウで開くとよいです。

# いざ、出陣🔥
まずはログイン画面。
今回はここで、「GitHub」を選んでいく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/523c2dd2-f48f-1337-e286-d875cabc70b7.png)

作成したオーナーのGithubアカウントではなくて、違うGithubアカウントを用意したので、そのアカウントでログインできるか試していく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/0311fc4f-4117-ddb7-1c13-bfe26b5c9348.png)

お、作ったGithubへ、ログインしたいアカウントの情報の認証情報を入れてよいかのメッセージが出た🔥
「Authorize」を押してログイン🔥

ＯＫ！いい感じ～🔥🔥

そして・・・・
無事接続完了🔥🔥🔥

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2242133/27162b71-2bd7-f95d-9413-9547cf11e131.png)

いいですねー。複数のIdPの実装が完了しました👌👌

こんな感じで使っていけそうなので、やっていきましょう！

それでは皆様またお会いしましょう👌

# 免責事項
本記事は、著者が独自で調査・検証を行った内容で、所属企業やいずれかの企業の公式見解に基づきません。
また、本記事を参考にして行った作業に関して発生するすべての損害、問題、課題について、当方では一切の責任を負えませんのであらかじめご了承ください。
Intellijでマウスオーバーしてもクイックドキュメントのツールチップが出ない時の対処法

普段、あらゆる言語でIntelliJを使って開発しています。
IntelliJでは、変数名などにマウスカーソルをホバーしたら、クイックドキュメントのツールチップが表示されると思います。
こういうやつ↓
![スクリーンショット 2023-08-06 17.58.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274517/3c813141-0b65-4bee-5753-76151b61ea59.png)
Intellijのバージョンを上げた時（たぶん）、マウスオーバーしても出なくなってしまいました。

軽く検索した限りは日本語情報がなかったのと、自分がPCをリプレイスするたびとかにこれになりそうなので、ここにメモを置いておきます。

## 環境

MacBook Air 13inch (2022)
macOS 13.4.1
IntelliJ IDEA 2023.2 (Ultimate Edition)

## 症状と原因

IntelliJ内のめぼしい設定（tooltipだとかmouse hoverだとかで検索して出る項目など）をonにしても反映されません。
OSレベルのスクリーンリーダーの設定をIntelliJが勝手に読んで、設定が反映されないみたいです[^1]。

## 対処法

スクリーンリーダーの設定をオフにします。
`Appearance & Behavior -> Appearance -> Accessibility -> Support screen readers` のチェックを外します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274517/51afdaf9-1a54-8a25-88cd-6be7b8a02f2e.png)
設定の横に「Required restart」とあるように、IntelliJの再起動が必要です。

[^1]: https://intellij-support.jetbrains.com/hc/en-us/community/posts/4414191199634-Missing-quick-documentation-on-mouse-hover
【TypeScript】Utility TypesのPartial型を理解する

## Utility Typesとは
Utility Types（ユーティリティ型）は、既存の型を元に新しい型を生成することができる型です。

## Partial型とは
Partial型（パーシャル型）は、特定の型の全てのプロパティをオプショナル（任意）にすることができます。

### Partial型の使用例

```TypeScript:TypeScript（Partial型未使用の場合）
type UserProfile = {
  name: string;
  age: number;
  address: string;
};
```

この`UserProfile`型のプロパティは、現状全て必須です。
なので、`UserProfile`型のオブジェクトを作成する時には、`name`・`age`・`address`の全てのプロパティを渡す必要があります。

そこで、もし一部のプロパティだけを扱いたい場合や、全てのプロパティが必ずしも存在しない場合に、Partial型を使用します。

```TypeScript:TypeScript（Partial型使用の場合）
type PartialUserProfile = Partial<UserProfile>;

/*PartialUserProfileの型は以下のようになります
type PartialUserProfile = {
  name?: string;
  age?: number;
  address?: string;
*/
};
```
`?`記号は、そのプロパティが存在しても存在していなくても良いことを示しています。
つまり、各プロパティはオプショナル（任意）となります。

なので、`Partial<UserProfile>`を用いてオブジェクトを作成する際には、`UserProfile`の全てのプロパティが含まれていないくても問題ありません。

例えば以下のように、`Partial<UserProfile>`を用います。

```TypeScript:TypeScript
const tanaka: PartialUserProfile = {
  name: 'Tanaka',
}

console.log(tanaka) //=>{ name: 'Tanaka' }
```

`tanaka`オブジェクトは、`name`・`age`・`address`の全てのプロパティを含んでいないですが、`Partial<UserProfile>`によってオプショナルになっているため、問題ありません。

## まとめ

Partial型（パーシャル型）を用いることで、特定の型の全てのプロパティをオプショナル（任意）にすることができました。

わかりやすい実例は今後追記していきたいと思います。
【型変換】あれ？int?Integer?【初心者】

# はじめに
お久しぶりです！絶賛転職活動中のミツクマです🐻
関東の夏は故郷の夏と違う暑さでここ数日体調を崩していました（転職活動中でよかった。。）
さて、今回はプログラミングを久しぶりにしていて
初歩的なミスに陥ってしまったので戒めとともに備忘録として記事にしようと思いました。

# ことの発端
簡単なプログラミングをしているときに
「入力を受け付けた文字列を数字型に変換してメソッドの引数として扱う」といったものでした。
```
"1,2,3,4"
```
といった文字列を受け取り
```java
Scanner scanner = scanner.nextLine();
String[] testStrArray = scannerl.split(",");
int[] testNumArray = new int[testStrArray.length];
```
といった風に書き実行したところ
```
I@5b6f7412
```
と出てきました。
ポンコツな僕は、「？？？？」となってしまい
色々調べました。
あれ？文字列から数字型への変換間違えているっけ？
あれ？数字以外を変換しようとしている訳じゃないのに．．．？
と随分と変に考え込んでしまいました。

# 解決はあっさり
解決法というか、答えというか
単純にオブジェクト型の変換になるため、
#### intではなくInteger
というなんというか初歩中の初歩のミスをしていました。
しかし、業務では意識してたり設計書通り実装していたから。。（言い訳
改めて基礎を固め忘れないことの大事さを思い出しました。

# 最後に
あほっぽい話であり、投稿するのも恥ずかしいと思いましたが
プログラミング上のケアレスミスってアルゴリズム上のミスを真っ先に探しがちだと思うので
そんな方の少しでも役に立てたらと思い、投稿させていただきました。
これからも、記事を投稿していきます。
いいねやフォローお願いします！
見ていただきありがとうございました！🐻
CSVをMySQLに入れるPythonをChatGPTに書かせてみた

```py
import sys

import pandas as pd
import mysql.connector

from pathlib import Path

# MySQLデータベースへの接続情報
db_config = {
    'host': 'localhost',
    'user': 'username',
    'password': 'password',
    'database': 'database'
}

# CSVファイルをデータフレームに読み込む
p = Path(sys.argv[1])
df = pd.read_csv(p)

# MySQLデータベースに接続
db_connection = mysql.connector.connect(**db_config)
db_cursor = db_connection.cursor()

# テーブル名を指定
table_name = p.stem

# テーブルのカラム定義を生成
column_definitions = []
for column_name, dtype in zip(df.columns, df.dtypes):
    if dtype == 'int64':
        column_type = 'INT'
    elif dtype == 'float64':
        column_type = 'DOUBLE'
    else:
        column_type = 'VARCHAR(255)'  # 文字列型のデフォルト
    column_definitions.append(f'`{column_name}` {column_type}')

# テーブルを作成
create_table_query = f'''
    CREATE TABLE IF NOT EXISTS `{table_name}` (
        id INT AUTO_INCREMENT PRIMARY KEY,
        {', '.join(column_definitions)}
    )
'''
# print(create_table_query)

db_cursor.execute(create_table_query)
db_connection.commit()

columns = [f"`{i}`" for i in df.columns]
insert_query = f'''
    INSERT INTO `{table_name}` ({', '.join(columns)})
    VALUES ({', '.join(['%s'] * len(columns))})
'''
# print(insert_query)

valuesList = []

# データをテーブルに挿入
for index, row in df.iterrows():
    values = [None if pd.isna(v) else v for v in row]
    valuesList.append(values)

db_cursor.executemany(insert_query, valuesList)
db_connection.commit()

# 接続を閉じる
db_cursor.close()
db_connection.close()

# print(p)
```

いくつか修正を入れています。
GolangのTest入門(Step2：複数ケースのテストケース実行)

##　はじめに
[前回](https://qiita.com/kouji0705/items/abe2ec6d002194f34d67)の続きです。今回は1つの関数で複数のテストケースを実行するプログラムを書きたいと思います。

## 実装
```go:product/product.go
package product

func Add(a, b int) int {
	return a + b
}
``` 

```go:test/sample/sample_test.go
package sample

import (
	"fmt"
	"testing"

	pr "github.com/kouji0705/go-test/product"
)

func TestAdd(t *testing.T) {
	type args struct {
		a int
		b int
	}
	tests := []struct {
		name string
		args args
		expected int
	}{
		{
			name: "1+1(成功)",
			args: args{1, 1},
			expected: 2,
		},
		{
			name: "1+1(失敗)",
			args: args{1, 1},
			expected: 3,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if actual := pr.Add(tt.args.a, tt.args.b); actual != tt.expected {
				fmt.Println("テスト失敗", tt.name)
				t.Errorf("実行値と期待値が異なります。実行値: %v, 期待値: %v", actual, tt.expected)
			}else {
				fmt.Println("テスト成功", tt.name)
			}
		})
	}
}
```

## 実行結果
```shell:実行結果
~/go/src/go_test$ go test -v ~/go/src/go_test/test/sample
=== RUN   TestAdd
=== RUN   TestAdd/1+1(成功)
テスト成功 1+1(成功)
=== RUN   TestAdd/1+1(失敗)
テスト失敗 1+1(失敗)
    sample_test.go:36: 実行値と期待値が異なります。実行値: 2, 期待値: 3
--- FAIL: TestAdd (0.00s)
    --- PASS: TestAdd/1+1(成功) (0.00s)
    --- FAIL: TestAdd/1+1(失敗) (0.00s)
FAIL
FAIL    github.com/kouji0705/go-test/test/sample        0.433s
FAIL
```

## NextStep
今回は複数ケースのテストケース実行をしました。次回はMockを利用したテストケースの実装方法を紹介したいと思います。
GolangのTest入門(Step1：テストコード実装、実行)

## はじめに
Go言語のテスト実装を1から学び直そうと思い、記事にしています。

## ディレクトリ
```
~/go/src/go_test$ tree 
.
├── go.mod
├── product
│   └── product.go
└── test
    └── sample
        └── sample_test.go

4 directories, 3 files
```

## 環境作成
①go.mod initの作成
```shell:go.mod init
go mod init github.com/kouji0705/sample_test  
```

②プロダクトコード実装
productディレクトリにコードを記載。
初回なので可能な限りシンプルな実装にしようと、引数の和を算出するコードです。
```go:product/product.go
package product

func Add(a, b int) int {
	return a + b
}
```

③テストコード実装
プロダクトコードで書いたコードをテストします。
```go:test/sample/sample_test.go
package sample

import (
	"testing"

	pr "github.com/kouji0705/go-test/product"
)

func TestAdd(t *testing.T) {
	type args struct {
		a int
		b int
	}
	tests := []struct {
		name string
		args args
		expected int
	}{
		{
			name: "1+1",
			args: args{1, 1},
			expected: 2,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			if actual := pr.Add(tt.args.a, tt.args.b); actual != tt.expected {
				t.Errorf("実行値と期待値が異なります。実行値: %v, 期待値: %v", actual, tt.expected)
			}
		})
	}
}
```

## 実行結果
```shell:成功時(引数が1,1：期待値：2)
~/go/src/go_test$ go test -v ~/go/src/go_test/test/sample                       
=== RUN   TestAdd
=== RUN   TestAdd/1+1
--- PASS: TestAdd (0.00s)
    --- PASS: TestAdd/1+1 (0.00s)
PASS
ok      github.com/kouji0705/go-test/test/sample        (cached)
```
→成功時はPASSが出ます。

```shell:失敗時(引数が1,1：期待値：3)
~/go/src/go_test$ go test -v ~/go/src/go_test/test/sample
=== RUN   TestAdd
=== RUN   TestAdd/1+1
    sample_test.go:29: 実行値と期待値が異なります。実行値: 2, 期待値: 3
--- FAIL: TestAdd (0.00s)
    --- FAIL: TestAdd/1+1 (0.00s)
FAIL
FAIL    github.com/kouji0705/go-test/test/sample        0.904s
FAIL
```
→失敗時はFAILが出ます。

## NextStep
今回は関数1件で1ケースのテストを実施しました。次回は関数1つで複数件のテストを実装するテストコードを書きたいと思います。
【ざっくり解説】Linuxとは？Unixとは？WindowsやMacはどう関係してるの？

UnixとLinuxの違い、Windows OSやMac OSとの関係性など、分かっているようで、うまく言語化できていないなぁと思ったので、こちらに備忘録としてまとめていきます。

プログラミング初学者の方はぜひ参考にしてみてください。


# そもそもUnixやLinuxって何？
- UnixとLinux、どちらもOSの種類のことである。
- OSとはオペレーティングシステムの略称である。
- OSは、基本的な機能を制御しているソフトウェアの1種である。
- 例えば、パソコンでキーボードを叩けば画面に文字が現れたり、マウスでクリックしたら選択項目が出てきたり、といった、コンピュータの基本的な機能を制御している。
- ※ソフトウェアとは「コンピュータに対して命令を出すプログラム」のことを指す。
- ※ソフウェアと対をなす言葉としてハードウェアがある。ハードウェアはパソコンやスマートフォンなどの物理的な機器を指している。
- ※OSが脳みそだとすれば、パソコンは体といった比較ができる。


# Unixとは？
- Unix（ユニックス）とは、現存するOSの中で最も古いと言われているOSである。
- Unixは1969年にアメリカの研究所によって開発されたと言われている。
- 後のLinuxの開発の元になったと言われている。
- 開発当初はアセンブリ言語と呼ばれる言語で構成されていた。
- のちにC言語で書き換えられてから、ハードウェアの機種依存性が低くなり、広く普及した。
- サーバー向けOS（サーバーOS）としては、Unix系OSが大きなシェアを持っている。


# Linuxとは？
- LinuxもOSの一種である。
- Unixをベースとして開発されたUnix系OSである。
- Linuxは、1991年にフィンランドのヘルシンキ大学の学生（当時）によって開発された。
- 例としては、スマートフォンのOS「Android」はLinuxカーネルの上に構築されている。
- ※カーネルとは、OSの中核を担う部分であり、アプリケーションとハードウェアの架け橋とも言われている。
- 特徴としては、オープンソースであること。
- ※オープンソースとは、世界中に公開されている無料のソースコードのことである。

> WindowsやMac OSを組み込む際は、OSを購入する必要があります。一方、Linuxは無料で公開・配布されているため、誰でも手軽に使えます。新たなOSの導入を検討している場合、経済性に優れる理由でLinuxを選択肢に加えるのもおすすめです。

引用：<a href="https://hnavi.co.jp/knowledge/blog/linux-merit/">Linuxとは？初心者でもわかる基本情報とメリットを紹介</a>

# WindowsはUnix・Linuxどっちなの？Windows誕生の流れ
- WindowsはMicrosoft社が開発したOSである。
- Windows OSは、UnixやLinuxとは別物（どちらでもない）、と考えて良い。
- なので、WindowsがUnix・Linuxどちらなのか？という考え自体が違う。
- Microsoftは、はじめ、「MS-DOS」というCUIのOSを開発・販売していた。
- ※CUIとは、「Character User Interface」の略称で、すべての操作をキーボードを用いて行うインターフェースのことである。
- そこに割って入ったのがスティーブ・ジョブズ率いるAppleが開発した「2代目Macintosh（1984年）」である。
- 2代目Macintoshは、GUI（Graphical User Interface）と呼ばれる、マウスやタッチパネルなどの直感的な操作を実現したコンピュータである。
- 遅れをとったMicrosoftだったが、その後開発・発売した「Windows95」などが大ヒット。
- 現在パソコン市場はWindows OSがトップシェアを誇るに至った。


# MacはUnixとLinuxどっちなの？
- 現在のMacパソコンは、「Mac OS X」名称のOSが使われている。
- MacのOSである「Mac OS X」は、Unix系である。
- なぜなら、Mac OSはBSD系Unixをベースに開発されたOSだから。
- そういった意味で、Mac OSはUnixの親戚関係と言える。
- 元々、Appleは独自OSの開発を進めていたが、諦めて、UnixをベースとしたOS開発に移行した。
- 2001年にAppleは「Mac OS X」の名称で最初の製品を販売した。


# サーバーOSにおけるUnixとWindows
- OSと一口に言ってもさまざまな種類がある。
- 複数のユーザーからのアクセスを捌くサーバー向けOS（サーバーOS）という言葉がある。
- 一方、パソコンなどのコンピュータに導入されるOSをデスクトップOSなどと呼んだりする。
- デスクトップOSで世界シェアのトップは、MicrosoftのWindows OSである。
- WindowsはサーバーOSとしてのWindows OSもある。
- だが、サーバーOSにおける市場で利用されているのは、Unix系OSが多い。


# Linux・Unixが似ている点

> ・ CUIベースのOS
・ 高い信頼性と安定性
・ 低コスト（Linuxにいたっては無料）
・ 企業のサーバーOSとして活用されている

引用：<a href="https://tech-camp.in/note/technology/14821/">Unixとは？Linuxとの違いやWindows・Mac OSとの関係性を徹底解説</a>



# 引用・参考サイト

https://tech-camp.in/note/technology/14821/

https://hnavi.co.jp/knowledge/blog/software-description/#title1

https://hnavi.co.jp/knowledge/blog/linux-merit/

https://mid-works.com/columns/engineer/infrastructure/1138060

https://ja.wikipedia.org/wiki/Linux

https://ja.wikipedia.org/wiki/%E3%82%AB%E3%83%BC%E3%83%8D%E3%83%AB
PythonとBokehを使用して画像付きの散布図を作成する

## はじめに
この記事では、PythonとBokehライブラリを使って、画像付きのインタラクティブな散布図を作成する手法を紹介します。
Bokehを使用することで、データポイントにマウスをオーバーした際に画像を重畳して表示する効果を実現します。また、OpenCVを利用して適当な色で塗りつぶした画像を生成し、ダミーデータとして利用します。本記事では、コードの詳細な説明やサンプルコードを提供するとともに、最終的な可視化結果も示します。画像を用いた機械学習で、結果を可視化したい方におすすめです。
![Animation_20230806172311.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134714/5f3c4c8c-7fb7-45e4-643f-1e27a11204ae.gif)

## 実行環境
Python 3.11.3
bokeh  3.2.1
numpy  1.25.2

## 目次
1. [Bokehとは？](#1-bokehとは)
2. [画像付き散布図の構築手順](#2-ダミーデータの作成手順)
    2.1. [ダミーデータ(画像)の作成](#21-ダミーデータ画像の作成)
    2.2. [ダミーデータ(画像+座標)の作成](#22-ダミーデータ画像座標の作成)
3. [Bokehを使った可視化](#3-bokehを使った可視化)
4. [実行と結果](#4-実行と結果)
5. [まとめ](#5-まとめ)


## 1. Bokehとは？
pythonでデータ可視化を行うためのライブラリです。
データ可視化のライブラリとしてはその他にも matplotlib や seaborn などのライブラリがありますが、
今回はインタラクティブな可視化に向いているBokehを使用しました。

https://docs.bokeh.org/en/latest/

## 2. ダミーデータの作成手順
今回は、5点のダミーデータを用意しました。
### 2.1. ダミーデータ(画像)の作成
適当な色の画像5枚を生成し、openCVを用いてjpgとして保存します。

~~~python
import numpy as np
import cv2

# ダミーデータに適当な色の画像を作成
colors = [(0, 0, 0), (0, 255, 0), (255, 0, 0), (255, 255, 0), (127, 127, 127)]

# 適当な色で画像を生成し保存
for i,color in enumerate(colors):
    size=(100, 100)
    image = np.ones((size[1], size[0], 3), dtype=np.uint8) * color
    # 画像を保存
    cv2.imwrite(f'test{i}.jpg',image)
~~~

### 2.2. ダミーデータ(画像+座標)の作成
dict型でダミーデータを作成します。画像名(image_url)は[2.1](#21-ダミーデータ画像の作成)で作成した画像のパスを指定しています。

~~~python
# ダミーデータ（例としてランダムな座標と画像を用意します）
data = {
    'x': [1, 2, 3, 4, 5],
    'y': [5, 4, 3, 2, 1],
    'image_url': [
        'test0.jpg',
        'test1.jpg',
        'test2.jpg',
        'test3.jpg',
        'test4.jpg'
    ]
}
~~~

## 3. Bokehを使った可視化
Bokehを使用してHTMLに画像と画像名を描画します。

~~~python
from bokeh.plotting import figure, show
from bokeh.models import HoverTool, ColumnDataSource

# ColumnDataSourceを作成
source = ColumnDataSource(data)
plot = figure(width=600, height=400)

# 散布図をプロット
scatter = plot.scatter(x='x', y='y', size=15, source=source)

# 画像を重畳して表示
hover = HoverTool(renderers=[scatter], tooltips=None)
hover.tooltips = """
    <div>
        <img src="@image_url" height="100"></img>
    </div>
    <div>
        <span style="font-size: 12px">@image_url</span>
    </div>
"""
plot.add_tools(hover)
# 出力
show(plot)
~~~

## 4. 実行と結果

上記コードを実行することで、ブラウザ上で画像付きの散布図をインタラクティブに操作することができます。
![Animation_20230806172311.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134714/859fdb7e-87ac-3975-9a93-4f87c05829d7.gif)


また、`show(plot)`で、htmlファイルが作られるので、一度実行してしまえばスクリプトを再実行しなくてもhtmlで結果を確認することが可能です。

## 5. まとめ
PythonとBokehライブラリを使って、画像付きのインタラクティブな散布図を作成する手法を紹介しました。
本記事内で書かれたプログラムはほとんどchat-GPT先生に作ってもらいました。もし不備などありましたら、一報いただけると幸いです。

また、matplotlibにて同様のことをしている偉大な先人の方の記事はこちら
https://qiita.com/sage-git/items/00fc33722d68627c467d
[備忘録] AWS CDK プロジェクトの作成

AWS CDKを学習していく過程を記録する。

# はじめに
[AWS CDK(Cloud Development Kit)](https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/home.html) とは、プログライミング言語でインフラを定義し、AWS CloudFormationを通してデプロイできる開発フレームワークである。

AWS CloudFormationはJSONやYAMLといったテキストファイルでリソースが定義される一方、AWS CDKは馴染みのあるプログラミング言語(JavaScript、TypeScript、Python、Java、C#など)で書くことができる。
また、アプリケーションとインフラをまとめて管理できるメリットもある。

# 実施したこと
1. AWS CDK TypeScriptプロジェクトの作成
1. デプロイ
1. 実行結果確認 

### 1. AWS CDK TypeScriptプロジェクトの作成
cdk はあらかじめインストールしてある。
```
% cdk --version
2.40.0 (build 56ba2ab)
```

プロジェクト用のフォルダを作成し、プロジェクトを立ち上げる。
```
% cdk init app --language typescript
```

下記構成でフォルダおよびファイルが作成された。
```
├── README.md		
├── lib
     └── app-stack.ts			
├── test
     └── app.test.ts
├── bin
     └── app.ts			
├── node_modules		
├── tsconfig.json
├── cdk.json		
├── package-lock.json
├── jest.config.js		
├── package.json
```

#### エントリポイント 
/bin/app.tsがCDKアプリケーションのエントリポイントであり、/lib/app-stack.tsからAppStackクラスをインスタンス化する。
```
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import { AppStack } from '../lib/app-stack';

const app = new cdk.App();
new AppStack(app, 'AppStack', {　});
```

#### メインスタック
/lib/app-stack.tsでは、AWSリソースの集まりであるスタックが定義されており、/bin/app.tsでロードされる。
```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';

export class AppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    });
  }
}
```

### 2. デプロイ

#### CLIの設定
コンソールからIAMユーザー作成後、下記コマンドを入力。
```
% aws configure
```
対話形式で、Access Key, Secret Access Key, Default region name, Default output format を設定した。
設定内容は下記より確認できる。
```
% aws configure list  
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ******************＊＊ shared-credentials-file    
secret_key     ******************** shared-credentials-file    
    region           ap-northeast-1      config-file    ~/.aws/config
```

#### cdk bootstrap
cdk bootstrap コマンドで、デプロイに必要なIAMロールやS3などを作成する。
```
% cdk bootstrap
```

#### ビルド
ビルド、コンパイルするために npm run build コマンドを実行する。
ただし、libフォルダ下のアプリケーションスタックのみの修正であれば、後述のデプロイコマンド実行時に自動的にビルド、コンパイルされるため、このコマンドは不要である。
```
% npm run build
```
※ここで TypeScript のエラーに遭遇したが、回避方法については[[備忘録] error TS1005, TS1011, TS1128 の解消](https://qiita.com/m-chan/items/48fcc2e4f9bfeb22e525)にまとめた。

#### デプロイ
最後に cdk deploy コマンドでアプリケーションスタックをデプロイする。
```
% cdk deploy
```

### 3. 実行結果確認
cloudformationから、デプロイしたスタックが確認できる。
![スクショ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280374/cafada39-d6da-88e1-d93c-403d5d80c49a.png)


# 最後に
AWS CDK TypeScriptプロジェクトの作成、デプロイまで確認できた。 
次は、API Gateway, Lambdaを構築していきたい。

参考にした文献を記す。  
- https://zenn.dev/ufoo68/books/3fbd1969bd4b21c5454b/viewer/cdkinit  
- https://docs.aws.amazon.com/ja_jp/cdk/v2/guide/home.html
npm install したときに、high severity vulnerabilitiesの対応備忘

# 概要

npm install したときに、high severity vulnerabilitiesが発生

`npm audit fix`で解消せず

`npm-force-resolutions`を活用して解決を目指す


```bash
> npm install

...

10 high severity vulnerabilities

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.
```

# 原因

とあるパッケージの依存関係にあるパッケージが古いバージョンやなんらかの原因により、脆弱性があると判断されている様子

# 一般的な対応

`npm audit fix`
or
`npm audit fix --force`

で対応可能らしい

今回のケースでは上記のコマンドで対応不可だったので
詳しく調べてみる

# 対応

## 何が起こっているか確認する

`npm audit`を試す

```bash
> npm audit
# npm audit report

glob-parent  <5.1.2
Severity: high
glob-parent before 5.1.2 vulnerable to Regular Expression Denial of Service in enclosure regex - https://github.com/advisories/GHSA-ww39-953v-wcq6
No fix available
node_modules/babel-cli/node_modules/glob-parent
node_modules/glob-base/node_modules/glob-parent
  chokidar  1.0.0-rc1 - 2.1.8
  Depends on vulnerable versions of anymatch
  Depends on vulnerable versions of glob-parent
  node_modules/babel-cli/node_modules/chokidar
    babel-cli  *
    Depends on vulnerable versions of babel-register
    Depends on vulnerable versions of chokidar
    node_modules/babel-cli
  glob-base  *
  Depends on vulnerable versions of glob-parent
  node_modules/glob-base
    parse-glob  >=2.1.0
    Depends on vulnerable versions of glob-base
    node_modules/parse-glob
      micromatch  1.6.2 - 2.3.11
      Depends on vulnerable versions of parse-glob
      node_modules/babel-cli/node_modules/micromatch
        anymatch  1.2.0 - 1.3.2
        Depends on vulnerable versions of micromatch
        node_modules/babel-cli/node_modules/anymatch
```

`glob-parent`の`5.1.2`未満は脆弱性があるようで、これが原因になっている様子

## 現在の状態を確認

`npm ls`で確認してみる

```
 npm ls glob-parent
app@0.1.0 ...
├─┬ babel-cli@6.26.0
│ └─┬ chokidar@1.7.0
│   ├─┬ anymatch@1.3.2
│   │ └─┬ micromatch@2.3.11
│   │   └─┬ parse-glob@3.0.4
│   │     └─┬ glob-base@0.3.0
│   │       └── glob-parent@2.0.0
│   └── glob-parent@2.0.0
└─┬ webpack-dev-server@4.15.1
  └─┬ chokidar@3.5.3
    └── glob-parent@5.1.2
```

`glob-parent@2.0.0`が解消されれば良さそうと見立てる

## 解決方法

`npm-force-resolutions`を使います


```bash
> npm i npm-force-resolutions
```

`package.json'にどこまでバージョンを上げるか書き加えます
今回は5.1.2まで上げてみます

```json:package.json
"resolutions": {
    "glob-parent": "^5.1.2"
  }
```

実行します
```bash
> npx npm-force-resolutions
```

clean install します

```
npm ci
...

found 0 vulnerabilities
```

脆弱性はなさそうですね


# 最後に

無事バージョンを上げることが出来、脆弱性は解消できました
改めて'npm ls'にてバージョンを確認したところpackage.lock.json的には違和感の残る結果の様でした

また今後、別の方法も模索出来ればと...


```
> npm ls glob-parent

app@0.1.0 ...
├─┬ babel-cli@6.26.0
│ └─┬ chokidar@1.7.0
│   ├─┬ anymatch@1.3.2
│   │ └─┬ micromatch@2.3.11
│   │   └─┬ parse-glob@3.0.4
│   │     └─┬ glob-base@0.3.0
│   │       └── glob-parent@^5.1.2 invalid: "^2.0.0" from node_modules/glob-base
│   └── glob-parent@^5.1.2 invalid: "^2.0.0" from node_modules/babel-cli/node_modules/chokidar
└─┬ webpack-dev-server@4.15.1
  └─┬ chokidar@3.5.3
    └── glob-parent@^5.1.2 invalid: "~5.1.2" from node_modules/chokidar
```
【TypeScript】型アサーション（as~）の使い方

# 型アサーションとは
TypeScriptで**推論された型を上書きする**機能のこと。
「アサーション(Assertion)」は日本語で「**主張、断言**」、つまり「**この変数の型は⚪︎⚪︎ですよ！**」とコンパイラに明示的に伝えるような機能のことです。
基本的な使い方は以下のようになります。

```
変数名 as 型名
```

TypeScriptには型推論と呼ばれる「変数に代入した値に基づいてコンパイラが自動で型を推論する機能」が元々備わっています。
これによって、全ての変数や引数に型の定義を書く必要がなくなるためコードの記述量が減るというメリットがあります。

一方で、型推論ばかりに頼ってしまうと、知らずのうちに開発者の意図しない型に推論されてしまうことがあります。その結果、別の型の値を変数に代入してしまうとコンパイラエラーに繋がります。
以下は簡単な例です。

```TypeScript
let hoge = {}; // ここで{}型のhogeと推論される
hoge.name = "Yamada"; // Err「プロパティ 'name' は型 '{}' に存在しません。」
hoge.age = 20; // Err「プロパティ 'age' は型 '{}' に存在しません。」
```

上記は変数定義時に、{}型と推論された変数hogeに対してname, ageというプロパティを追加したためコンパイルエラーになります。

これを型アサーションで解決すると以下のようになります。
```TypeScript
type User = {
    name: string,
    age: number,
}
let hoge = {} as User;
hoge.name = "Yamada";
hoge.age = 20;
```
まず、型エイリアスと呼ばれる機能で、name、ageというプロパティを持つオブジェクトの型を「User」という型名で定義します。
その後、「let hoge = {} as User」と書くことで、「**変数hogeをUser型で推論してください！**」とコンパイラに伝えることができるのでエラーは解消されます。

# as以外の書き方
asを用いた記法以外にも、アングルブラケット（<>）を用いた記法が存在します。
使い方は以下の通りです。
```
変数名<型名>
```
しかし、こちらのアングルブラケット構文は、JSXの<>と混在してコードが読みにくくなるのであまり使用されないようです。

# 型アサーションの使用は極力避ける
型の推論を上書きしてくれるという機能は非常に強力が故に便利に感じてしまいます。しかし、型アサーション後の型に何か問題があったときコンパイルエラーとして検知されないので実行時になってエラーに気づくということが発生してしまいます。
型アサーションの使用を避けるためにも、コンパイラの型推論に全面的に頼らずに、変数定義の際に予め型宣言を行なうことも重要なのかと思います。

しかし、一般的に、JavaScriptからTypeScriptへコードを移植する際、発生するコンパイルエラーを一時的に解消したいという目的では、型アサーションが使われるようです。それ以外の目的では極力使用は避けたほうがよさそうですね。
【JasperReports】エラーメッセージEdge browser engine is not setup対策

# 概要

Jaspersoft Studioを使ってプレビュー表示をするときに、「Edge browser engine is not setup. HTML and JRIO Preview will not work fine」というエラーメッセージが表示される場合があります。当記事ではこの問題を解決する方法を紹介します。

# 対処方法

まず、WebView2のサイトを表示し、固定バージョン(修正済みバージョンと書かれているところを選択)をダウンロードします。アーキテクチャが選択できるバージョンを選択します。

https://developer.microsoft.com/ja-jp/microsoft-edge/webview2/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333194/5aa3b052-70c9-538c-aaae-2b73957eb6e0.png)

cab形式のファイルがダウンロードされる為、以下のコマンドで任意の場所に展開します。
ここでは、C:\webview2フォルダに展開します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333194/7fa47d03-6ab4-5b3c-9307-cc71b86db547.png)


次に、Jaspersoft Studio v6.20.5を利用している場合は、以下のファイルをテキストエディタで開きます。

C:\Program Files\Jaspersoft\Jaspersoft Studio-6.20.5\Jaspersoft Studio.ini

そのファイルの一番最後に、以下の行を追記します。

```
-Dorg.eclipse.swt.browser.DefaultType=edge
-Dorg.eclipse.swt.browser.EdgeDir=C:\\webview2
```

最後に、Jaspersoft Studioを再起動するとエラーメッセージが消え、プレビューが正常に行われるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/333194/0a35f804-8ddb-8a6e-5915-7b8a0cf15c51.png)

# 参考

- Jaspersoft Studioユーザガイド
https://community.jaspersoft.com/sites/default/files/docs/js-jss_8.2.0_user-guide_0.pdf
メモ: Promiseについて調べたまとめ

Node.jswを勉強していたらPromiseに出会ったので少し調べてみたまとめ。

# Promiseとはざっくり何

JavaScriptやNode.jsでの非同期処理の結果。


# Promiseを使って嬉しいこと

Promiseを使った非同期処理のコールバック処理が書きやすくなる。


# 使ってみる

```node.js
'use strict';

// fetch Promiseを返す
// HTTPリクエストを実行
fetch('https://api.football-data.org/v4/competitions/PL/matches')
// thenでコールバック処理を記述
.then((response) => response.json())
.then((data) => console.log(data));
```

# 参考文献

- https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises
- https://www.tohoho-web.com/ex/promise.html#timing-problem

以上
はじめましてQiita　

<h1>なるほど。こうやって使うのか</h1>

どうも皆さん、たそまると申します。

これまでこういったものに触れたことが無かったため、マークアップできるんだという感動をすでに感じています。

私は、今年から社会人になったペーペーの端くれエンジニアです。

今回は、初投稿ということで、軽い自己紹介でもしていこうと思います。

<h3><font color="Crimson">特に何も期待しないでいただけると助かり・・・!</font></h3>

***
はい、ということで。ここからは具体的にね。

長々と書くとめんどくさいので、ざっくりとまとめてますね。

* 2023年1月より未経験から客先常駐で運用保守
* 諸事情により大学中退のため中途入社
* 鹿児島→福岡（2023年8月現在）
* 資格はFEのみ保持
* HTMLやCSS、JS等は読み書きできる程度
* AWS勉強中　SAAは近々取る予定

近況含めてそんな感じです。めちゃめちゃ優秀な訳でも、特化しているわけでもないので、面白みのない人生ではあります。

がしかし、さすがに何かしらの日記的な、日々のアウトプットはしといたほうがいいよな・・・

ということで、 **Qiita** はじめました！　

今後は当たりまえだろってことや、そんなことも知らなかったんかってこともありますが、成長過程を残せたらと思います。

各SNSについては、下に乗せておきますね。　

それでは。ほなまた✋

 ***

Twitter (X) [@Ts3rX](https://twitter.com/Ts3rx)
GitHub [たそ丸](https://github.com/tasomaru)
Mastdon [@tasomaru](https://best-friends.chat/@tasomaru)
(BizRobo!)ロボットからcurlコマンドでTeamsに通知してみました

社内で利用しているロボットで、メールではなくTeamsで通知させたいことがありましたので、試してみました。
せっかくなのでどのように実装したのか簡単に記事にします。

# 通知方法

通知にあたっては、Teamsに用意されているIncoming Webhookを利用することにしました。
また、ロボットから通知させる際のアクションは[コマンドライン実行(Execute Command Line)]を利用し、curlコマンドを実行しています。
API関連でよく使う[Rest Webサービス呼出]ではないです。

Incoming Webhookやcurlコマンドについてはこちらの記事を参考にしました。
参考記事：Microsoft TeamsのWebhookによる通知
https://qiita.com/SDN/items/3754ae1e8960df01cc11
この場を借りて筆者の方に感謝します。

なお、参考記事では、bashを利用していたようなのでLinuxかUnix前提だと思いますが、Windowsでもcurlコマンドは使えます。
Windws10からは標準搭載されるようになったらしいです。
Windowsのはオリジナルとは完全に同じものではないっぽいですが、詳しくないのでここではあれこれ言いません。
使いこなせると便利だとは思います。

# 事前準備
事前準備は先ほどの記事の通り、Teams上の任意のチーム上でコネクタの設定をし、Webフックができるようにします。
また、ロボットで打つコマンドやメッセージ内容を設定用のファイルに記載しておくと後で楽かと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/e8e0e100-afc7-342a-66ca-85ffe0d4623a.png)
URLについては、これが分かると誰でもメッセージが送信できてしまうので、なるべくMCのパスワードストアに記録するようにした方がセキュリティ上良いと思います。

今回は以下のように、＜メッセージ＞と＜URL＞部分をロボット内で変数値と置換できるようにしています。
```コマンド
curl -H "Content-Type: application/json" -d "{\"text\": \"＜メッセージ＞\"}" ＜URL＞
```

# 実装
ロボットで実装していきます。
事前に定義していた設定ファイルを読み込み、各値を変数に読み込みます。
その後、コマンド実行するためのコマンド内容を作成するため、
[変数の割当]ステップで各値を置換します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/fad14fa8-0370-ba4b-661f-79abd8ef7e0a.png)

コンバータの[パターンを置き換え]で置換すべき文字列を指定して置き換えていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/54689849-ae01-570b-2af1-455915772bab.png)
あらかじめ、置換用の文字列も定数としてタイプの初期値に記録しておくと便利です。
こうすると、やっぱり文字列変えたい、となったときも、ステップ内で直接記載していないのであちこちステップの設定をひとつひとつ探す必要がありません。

そして、作成できたコマンドをコマンド実行用の変数として割り当て、コマンドライン実行で利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/cf450dd8-973e-bb6a-a420-295e7541b79f.png)

そして、こちらを実行すると、Teamsにメッセージが送信されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736479/9b3ec79f-48e2-064d-6822-d0ea69359e61.png)

# まとめ
事前準備さえできてしまえば、それほど多くの手順は必要ありません。
メールでの通知もいいですが、メールだと埋もれてしまうとか、エラーの発生と概要だけでもTeamsで確認できるようにしたいとか、そういうニーズもあるかもしれません。

また、以前私が作成した以下の方法でエラー内容を抽出し、その内容をインシデント対応のためのチームに送信し、インシデント対応を行うのもありかもしれません。
(BizRobo)MC上でスケジュール実行したロボットエラー情報をログデータベースから抽出する方法
https://qiita.com/YG_10_04/items/eb4c652c1ec2b7540cf8

例えば、DBからエラー内容を抽出し、それをkintoneに転記してインシデント対応記録を起票し、
エラー概要とkintoneの起票No、URLを記載してTeams通知、というような使い方もできると思います。
これは以前、Slack通知でもそういうことをしているというのは上記記事にも書いた通りですが、Teamsでも似たようなことはできます。
皆さまもよろしければお試しあれ
せんせー、ハイパースペクトラルイメージングってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、ハイパースペクトラルイメージングってなに？

# ハイパースペクトラルイメージングとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

ハイパースペクトラルイメージングというのは、
色をすごくたくさんのパーツに分けて見る特別なカメラのことです。

君が虹を見たことがありますよね？
虹はたくさんの色が重なってできていますよね。
でも、虹には赤、橙、黄、緑、青、藍、紫の7色だけが見えます。

でも、ハイパースペクトラルイメージングのカメラは、もっとたくさんの色を見ることができます。
虹の色をもっと細かく分けると、たくさんの色が見えてきます。

例えば、このカメラを使うと、植物が健康かどうか、または空気や水がきれいかどうかを調べることができます。
それは、物や場所が反射する色を詳しく見ることで、その状態を判断できるからです。

だから、ハイパースペクトラルイメージングとは、
たくさんの色を見て物事を理解するための特別なカメラのことなんです。

# まとめ

ハイパースペクトラルイメージングというのは、
色をすごくたくさんのパーツに分けて見る特別なカメラのこと
React + React Routerを使用したプロジェクトで404エラーを解消する方法！


React RouterでSPA（シングルページアプリケーション）を開発している際、リンクをクリックすると問題なく遷移するのに、URLを直接叩くと404エラーになってしまう…そんな経験はありませんか？この記事では、その問題を解消する方法を紹介します。

## 目次
1. [問題の概要](#問題の概要)
2. [原因と解決策の理解](#原因と解決策の理解)
3. [Apacheサーバーの設定](#Apacheサーバーの設定)
4. [Nginxサーバーの場合](#Nginxサーバーの場合)
5. [まとめ](#まとめ)

## 問題の概要
React Routerを使用しているプロジェクトで、リンクをクリックして遷移すると問題ないのに、URLを直接入力すると404エラーが発生する現象について説明します。

### サンプルコード
```jsx
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';

function App() {
  return (
    <Router>
      <div>
        <Link to="/">Home</Link>
        <Link to="/about">About</Link>
        
        <Route exact path="/" component={Home} />
        <Route path="/about" component={About} />
      </div>
    </Router>
  );
}
```

## 原因と解決策の理解
この現象の原因と、Apacheサーバーでの解決策を見ていきましょう。

### クライアントサイドルーティングとサーバーサイドルーティング
React Routerはクライアントサイドでルーティングを行うため、サーバーはURLに対応する物理的なファイルを探しに行きます。その結果、404エラーが発生します。

## Apacheサーバーの設定
Apacheサーバーの設定を変更して問題を解決しましょう。

### .htaccessファイルの変更
以下のコードを既存の`.htaccess`ファイルに追加します。

```htaccess
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule . /index.html [L]
```

## Nginxサーバーの場合
Nginxサーバーの場合は以下のように設定します。

```nginx
location / {
    try_files $uri $uri/ /index.html;
}
```

## まとめ
React + React Routerで404エラーに悩まされることがあれば、この記事の方法で解決できるかもしれません。クライアントサイドルーティングの挙動を理解し、サーバーの設定を適切に行うことで、スムーズなページ遷移が実現できます。

---

この記事は、具体的な問題とその解決策を明確に提供しており、Qiitaのフォーマットに従っています。いいねや共有を頂ける内容になっていると思います。
さくっとthree.jsを使って3D描画する

three.jsをインストールして、立方体を表示することを目標にします。
アプリケーションフレームワークには、Svelteを使用します！

# 特徴
WebGL APIをラッピングしているので、簡単な設定で3D体験が可能になります。
プリミティブ図形の表示や、DCCツール(BlenderやMaya)で制作した3DCGを読み込ませて表示できます。


# 準備するもの
- MacOS
- Nodeの最新バージョン
- VSCode
- Svelte(インストール方法は[こちら](https://qiita.com/penta-design-system/items/c9a2cc2dd496ae397a5b)にまとめています)

# Nodeの最新バージョン
※以前の記事でNodeのバージョン管理ツールからインストールする方法を記載しています！

# three.jsをインストール
```
# three.jsインストール
npm install three

# TypeScript用の型定義(ts使うなら必須)
npm install -D @types/three
```

# 3DCGの構成
大きく分けて、カメラ、シーン、ライト、メッシュ、ジオメトリ、マテリアルで構成されています。
最終的に、キャンバスにレンダリングされて、Webブラウザで見れるようになります。

メッシュにジオメトリ、マテリアルを入れて、ライトで照らす。それをシーンとしてグループ化します。
カメラでシーンを撮影し、キャンバスに描画(レンダリング)する流れとなります。


<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522989/a72ab32d-c4e9-71ca-3d94-3c6259fa5c4e.png">


# フォルダ構成
svelteのフォルダ構成になります。lib配下にthree用のクラスを作成し、+page.svelteでimportします。


```:フォルダ構成
svelte-app
└── src
    ├── app.d.ts
    ├── app.html
    ├── index.test.ts
    ├── lib
    │   ├── index.ts
    │   └── three
    │       └── App.js
    └── routes
        ├── +page.svelte
        └── three
            └── +page.svelte

```



```html:three/+page.svelte
<script lang="ts">
	import { onMount } from 'svelte';
	import { App } from '$lib/three/App';

	let threeApp: App;

	// https://svelte.jp/tutorial/onmount
	onMount(async () => {
		threeApp = new App();
	});
</script>

<div>
	<canvas id="canvas" />
</div>

```
注意としては、サーバーサイド処理では、Windowオブジェクトが参照できないため、画面描画後に３DCGを描画するよう`onMount`内に記述します。

```javascript:App.js
import * as THREE from 'three';

class App {
	constructor() {
		// 縦横のサイズをウィンドウから取得
		const width = window.innerWidth / 2;
		const height = window.innerHeight / 1.5;
		// キャンバスを指定
		const canvas = document.getElementById('canvas') || undefined;
		const renderer = new THREE.WebGLRenderer({
			canvas,
			antialias: true
		});
		renderer.setSize(width, height);
		renderer.setPixelRatio(window.devicePixelRatio);
		renderer.setClearColor('#000'); // 背景黒

		// カメラを作成
		const fov = 45; // カメラの垂直視野角
		const aspect = width / height;
		const camera = new THREE.PerspectiveCamera(fov, aspect, 1, 1000);
		camera.position.z = 3;

		// メッシュを作成
		const geometry = new THREE.BoxGeometry(1, 1, 1);
		const material = new THREE.MeshPhongMaterial({
			color: '#fff' // オブジェクト白
		});
		const mesh = new THREE.Mesh(geometry, material);
		mesh.rotation.x = Math.PI * 0.15; // x軸の回転角(ラジアン)
		mesh.rotation.y = Math.PI * 0.25; // y軸の回転角(ラジアン)

		// ライトを作成
		const light = new THREE.PointLight();
		// ライトを手前右上に移動
		light.position.x = 0.5;
		light.position.y = 0.5;
		light.position.z = 3.5;

		// シーンを作成
		const scene = new THREE.Scene();
		// メッシュとライトを追加
		scene.add(mesh);
		scene.add(light);
		// カメラで撮影したシーンをcanvas要素に描画
		renderer.render(scene, camera);
	}
}
export { App };
```
描画するcanvasを指定し、3DCGの構成通りに設定していきます。

# 結果
localhost:5173/threeにアクセスして、立方体が表示されたら完成です！

![立方体.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3522989/4902236e-77bd-03c6-8333-18cef5208120.png)
Spring bootでBootstrap&jQueryを使用する

# 本記事の概要
Spring bootを使うときにUIを良くするためのBootstrapとjQuery。
Spring bootで開発中に使用したくなった場合にはどうしたらいいかを備忘録としてまとめました。
(まだ編集中で、お試しがてらの投稿になるのでご了承ください）

# そもそもBootStrapとjQueryとは何ぞや
下記の記事に記載しています。

* Bootstrap
編集中
* jQuery
編集中

# Spring bootで使用したい時にどうすれば良いか

### ◾️手順1：pom.xmlへの定義(Mavenを使っているとき限定)
【Question】
BootstrapとjQueryのメリットは分かった。実際にSpring bootでWebアプリ開発するときに使ってみたい。
**...でどうしたら使えるようになるんですか？**

【Answer】
ビルドツールがMavenの場合、pom.xmlファイルのdependenciesタグの中で以下の依存関係を追加する。
こうすることでMavenが必要なファイルを入手してきてくれるのだ。

```pom.xml
<dependencies>

    <!-- ①Bootstrapを使いたい！！ Maven君必要なファイル取ってきて！！ -->
	<dependency>
		<groupId>org.webjars</groupId>
		<artifactId>bootstrap</artifactId>
		<version>5.3.1</version>
	</dependency>

    <!-- ②jQueryを使いたい!! Maven君必要なファイル取ってきて!! -->
	<dependency>
		<groupId>org.webjars</groupId>
		<artifactId>jquery</artifactId>
		<version>3.7.0</version>
	</dependency>

    <!-- ③実際にBootstrapとjQueryを使用するときに、HTMLにバージョン番号を書かなくて済むようにしたい!! -->
    <!-- Maven君!!そのためのファイル取ってきて!! -->
	<dependency>
		<groupId>org.webjars</groupId>
		<artifactId>webjars-locator-core</artifactId>
	</dependency>

</dependencies>
```
<補足1:なぜこの方法でやったのか>
上記のようにMavenに依存関係を追加する以外のやり方もあるが、なぜこの方法でやったかと言うと、
以下の2つの理由から。
* とりあえず簡単にできるから
* Mavenに必要なファイルを入手してもらったあとは、ネットが繋がってない状況でも使用できるから

<補足2:バージョンについて>
Mavenリポジトリで色んなバージョンが使用できる。今回は執筆時点での最新版を
\<verison>タグ内に記入した。

*Bootstrap
https://mvnrepository.com/artifact/org.webjars/bootstrap
*jQuery
https://mvnrepository.com/artifact/org.webjars/jquery

なぜweb-jars-locator-coreにはversionを書かなかったのかというと、書くと
「バージョンが重複しているよ！」と警告が出てしまったから(詳細がまだ分かってない)

### ◾️手順2：htmlへの定義(Thymeleafを使用している前提)
【Question】
Mavenが必要な依存関係を解消してくれたのは分かった。
**...でどうしたら<font color="Red">それぞれのHTMLで</font>使えるようになるんですか？**

【Answer】
htmlファイルの\<head>タグ内に、以下のようにBootstrapを使用する宣言を記述すればよい。

```test.html
...省略
<head>
    <meta http-equiv="Content-type" content="text/html; charset=UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">

    <!-- ここでBootstrap(css)を使用することを宣言している -->
    <link rel="stylesheet" th:href="@{/webjars/bootstrap/css/bootstrap.min.css}">
    <!-- ここでBootstrap(javascript)を使用することを宣言している -->
    <script th:src="@{/webjars/bootstrap/js/bootstrap.min.js}" defer></script>

    <!-- ここでjQueryを使用することを宣言している -->
    <script th:src="@{/webjars/jquery/jquery.min.js}" defer></script>

    <title>ウェルカムページ</title>
</head>
...省略
```

<補足1:deferとは?>
HTMLとjavascriptの読み込みを並列に実施するように指示するオプションで、
これをつけるとjavascript読み込みの際に画面表示が高速化される。

### ◾️手順３：実際にBootstrapとjQueryを使用してみる
編集中
せんせー、バイオメトリクスってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、バイオメトリクスってなに？

# バイオメトリクスとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

バイオメトリクスとは、人それぞれが持つ特別な特徴を認識する科学のことです。

君が友だちと一緒に遊んでいて、誰が誰だかわかるのはなぜです？ 
それは君が友だちの顔を見て、「あ、これはゆうきくんだ！」とか「これはさきちゃんだ！」と認識できるからですよね。

バイオメトリクスも同じようなことをします。
でも、それは人の目ではなく、コンピュータがやります。
コンピュータは、人の指紋や顔、声、目の形など、人それぞれが違う特徴を見て、
誰が誰だかを認識することができるんです。

これは、スマートフォンで顔認証や指紋認証を使ってロックを解除したり、
空港でパスポートをチェックするときに使われるような、とても重要な技術なんです。

だから、バイオメトリクスとは、君が友だちを見分けるのと同じように、
コンピュータが人を見分けるための特別な科学なんです。
これが大きくなったら、もっと詳しく学ぶことができます

# まとめ

バイオメトリクスとは、人それぞれが持つ特別な特徴を認識する科学のこと
GitHub Cli入門

## 参考記事
- GitHub CLIで始める快適GitHub生活

https://qiita.com/ryo2132/items/2a29dd7b1627af064d7b

- GitHub公式ドキュメント

https://docs.github.com/ja/github-cli

https://cli.github.com/manual/gh

## 今回の構築環境

- Ubuntu 22.04.2 LTS

Ubuntu上では`lsb_release -a`コマンドを実行すると、ディストリビューションのバージョンやコードネームを確認することができます。
```
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.2 LTS
Release:        22.04
Codename:       jammy
```
[Linux環境バージョン確認方法について](https://dev.classmethod.jp/articles/linux-os-version/)

## インストール手順

https://github.com/cli/cli#installation

- GitCliをLinux環境にインストール
```
sudo apt install gh
```

## 認証

https://cli.github.com/manual/gh_auth_login

GitHub Cliを利用する前に自分のGitHubアカウントと連携するための認証が必要。  
`gh auth login`コマンドを実行して、認証を済ませてください。
※自分は下記内容で認証しました。
```
$ gh auth login
# どのアカウントにログインしますか？
What account do you want to log into? => GitHub.com
# Git操作に優先するプロトコルはなんですか？
What is your preferred protocol for Git operations? => SSH
# SSH 公開キーを GitHub アカウントにアップロードしますか？
Upload your SSH public key to your GitHub account? => 自身のSSH公開鍵
# GitHub CLI をどのように認証しますか？
How would you like to authenticate GitHub CLI? => Login with a web browser
```

https://github.com/login/device にアクセスし、ワンタイムパスワードでログイン後、認証を行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711955/a0919314-ab7b-e234-83d9-f4a07734ab39.png)

## GitCliを使ってリモートリポジトリを作成

https://cli.github.com/manual/gh_repo_create

- ローカルディレクトリの情報をリモートリポジトリに追加する場合
  1. `cd`コマンドでプッシュしたいディレクトリへ移動
  1. `git init`コマンドを実行
  1. `gh repo create リポジトリ名(任意) --private --source=pushするディレクトリパス(任意) --remote=upstream`を実行
  ```
  	# 現在のカレントディレクトリからリモートリポジトリを作成する
  	gh repo create test-cli --private --source=. --remote=upstream
  ```

なぜ、`gh repo create test-cli --private --source=. --remote=upstream`を実行することで、リモートリポジトリにローカルディレクトリを追加することができるのかはわからない。
公式の `gh repo create` のオプション説明を見ても `--source`と`--remote=upstream`の十分な説明を見つけることができなかったため、知っている方がいれば教えてください。

- リモートリポジトリが追加されているか確認  
```
git remote -v
upstream        git@github.com:ユーザー名/リポジトリ名.git (fetch)
upstream        git@github.com:ユーザー名/リポジトリ名.git (push)
```

- リモートリポジトリをブラウザで表示  

https://cli.github.com/manual/gh_browse

```
gh browse
せんせー、ナノフォトニクスってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、ナノフォトニクスってなに？

# サナノフォトニクスとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

ナノフォトニクスというのは、すごく小さい世界で光を使って遊ぶ科学のことです。

「ナノ」はとても小さいことを意味していて、
「フォトニクス」は光を使うことを意味しています。
だから、ナノフォトニクスはとても小さいスケールで光を使って色々なことをする科学なんです。

君が指でピンポン玉を押すと、ピンポン玉は動きますよね。
でも、もしピンポン玉がすごく小さくて、君の目には見えないくらい小さかったら、どうなりますか？ 
それを想像するのが、ナノフォトニクスの一部です。

この科学を使えば、光をコントロールして、色々なことができるようになるんです。
例えば、光を使って情報を送ったり、病気を見つけるのを手伝ったりすることができます。

ナノフォトニクスは難しそうだけど、光で遊んで、
そしてそれを利用して新しい発見をする、とても面白い科学なんです。

# まとめ

ナノフォトニクスというのは、すごく小さい世界で光を使って遊ぶ科学のこと
せんせー、メタマテリアルってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、メタマテリアルってなに？

# メタマテリアルとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

メタマテリアルというのは、とても特別な材料のことです。
この材料は、普通の物質ではできない驚きのことができます。

君がおもちゃのブロックで遊んだことがありますよね？
そのブロックは、君がどう組み合わせるかによって、様々な形の塔や家を作ることができますよね。

メタマテリアルもそのようなものです。
とても小さな「ブロック」を特別な方法で組み合わせることで、
普通の材料ではできないような特別な性質を持つ材料を作ることができるんです。

例えば、光や音、電磁波などを特別な方法で反射したり、曲げたり、吸収したりする材料を作ることができます。

# まとめ

メタマテリアルというのは、とても特別な材料のこと
せんせー、スピントロニクスってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、スピントロニクスってなに？

# スピントロニクスとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

スピントロニクスというのは、電子の「回転」を利用する新しい科学のことです。

電子というのは、とても小さい粒子で、私たちが見ることができないくらい小さいんです。
この電子が持っている特別な力を「スピン」と呼んでいるんです。

君が遊んでいるおもちゃの回転するトップを想像してみてください。
トップは自分の軸でくるくると回りますよね。
電子も同じようにくるくると回転しているんです。

スピントロニクスでは、この電子の「スピン」、
つまり回転を使って、新しいタイプのコンピュータを作ることができるんです。
それによって、コンピュータはもっと速く、もっと少ないエネルギーで働くことができるようになるです。

だから、スピントロニクスは、電子の回転を使ってコンピュータをもっと良くするための特別な科学なんです。

# まとめ

スピントロニクスというのは、電子の「回転」を利用する新しい科学のこと
せんせー、オプティカルコンピューティングってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/7f59d21b-0564-377b-a326-47169950dc66.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/319ddbbb-e9dd-5833-688d-5808a705af9b.png)

せんせー、オプティカルコンピューティングってなに？

# オプティカルコンピューティングとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/754ad1db-cf66-be94-8f33-137d3e28f1cc.png)

オプティカルコンピューティングは、ちょっと難しそうだけど、
楽しく考えると、光で遊ぶ新しいコンピュータの作り方と言えます。

君が遊んだことのあるコンピュータやゲーム機は、電気を使って動いているんです。
でも、オプティカルコンピューティングは、電気の代わりに光を使ってコンピュータが動くように考える方法なんです。

光は、とても早く動くから、光を使ったコンピュータはとても速くなることができるです。
だから、もっとたくさんのことを同時にやることができます。

例えば、もし君が光のスピードで動けたら、秒速で地球を7.5周することができるんです。
それぐらい、光は早いんです。

だから、オプティカルコンピューティングは、光の速さを利用して、
もっと早く、もっと賢く働くコンピュータを作るための科学なんです。

# まとめ

オプティカルコンピューティングは、電気の代わりに光を使ってコンピュータが動くように考える方法
ABC313 - C - Approximate Equalization 2 自己解法

# 問題

https://atcoder.jp/contests/abc313/tasks/abc313_c

# 考察
数列の最大値と最小値の差を1以下にするために最低限必要となる操作の回数を求めてくださいという問題です。
## 結論
結論としては、下記の手続きに沿ったコードを作成すればACできます。

:::note info
- 次の2つの値を求める。
  - 数列$A$の平均値。小数切り捨て。(${Ave}_1$とする。)
  - 数列$A$の平均値。小数切り上げ。(${Ave}_2$とする。)
- 次の2つの値を求める。
  - 数列$A$で、「${Ave}_1$より小さい値」に該当する各項の「${Ave}_1$との差の絶対値」を合計した値。($d_1$とする。)
  - 数列$A$で、「${Ave}_2$より大きい値」に該当する各項の「${Ave}_2$との差の絶対値」を合計した値。($d_2$とする。)
- $d_1$と$d_2$のうち、より大きい値が答え。
:::

なぜACできるかを説明していきます。

## 数列の各項の値は何になるか
数列の最大値と最小値の差を1以下にするとき、数列の各項の値は何になるかを考えます。まず、今回の問題で行う操作では、1つの項の値を1増やし、1つの項の値を1減らします。この操作で、各項の和が変わることはありません。そのため、数列の各項の最終的な値は各項の和を項数で割った値、すなわち平均値の近くになりそうです。

平均値は、小数を含む可能性があります。しかし、今回の問題では最大値と最小値の差を1にすればいいです。そのため、各項の値は「平均値の小数を切り捨てた値(${Ave}_1$)」か「平均値の小数を切り上げた値(${Ave}_2$)」のどちらかとなります。各項が平均値の小数を切り捨てた値(${Ave}_1$)」か「平均値の小数を切り上げた値(${Ave}_2$)」のどちらかなった形を「理想形」ということにします。

## 操作の対象となる2項を選び方を考える。
数列の各項の値が「平均値の小数を切り捨てた値(${Ave}_1$)」か「平均値の小数を切り上げた値(${Ave}_2$)」になるはずということが分かりました。あとは理想形になるのに必要な操作の回数を調べていきます。そのために操作対象となる2つの項は毎回どれを選べば良いかを考えます。通常、${Ave}_1 ≦ {Ave}_2$ですから、数列の各項に対して下記の事実があることは分かるかと思います。
- ${Ave}_1$より小さい値→$({Ave}_1との差の絶対値) ≦ ({Ave}_2との差の絶対値)$
- ${Ave}_2$より大きい値→$({Ave}_1との差の絶対値) ≧ ({Ave}_2との差の絶対値)$

上記の事実から、${Ave}_1$より小さい値は${Ave}_1$になるように、${Ave}_2$より大きい値は${Ave}_2$になるように操作対象を選んでいけば少ない回数で理想形になります。

この事実を踏まえた上で、操作対象となる2つの項の選び方を考えます。

### case1. 数列に「Ave1より小さい値」の項と「Ave2より大きい値」の項の両方が存在する場合
この場合、「${Ave}_1$より小さい値」の項と「${Ave}_2$より大きい値」の項を選べば理想形に近づいていきます。

### case2. 数列に「Ave1より小さい値」の項が存在するが、「Ave2より大きい値」の項が存在しない場合
この場合、一方は「${Ave}_1$より小さい値」の項を選べば良いことは分かるかと思います。もう一方は数列内に既に存在している、「値が${Ave}_2$」の項を選べば良いです。近づけるのは平均値ですから、Ave1より小さい値」の項が存在するが、「Ave2より大きい値」の項が存在しない状況では、「値が${Ave}_2$」の項は確実に存在するといえるためです。

### case3. 数列に「Ave2より大きい値」の項が存在するが、「Ave1より小さい値」の項が存在しない場合
この場合、一方は「${Ave}_2$より大きい値」の項。もう一方は数列内に既に存在している、「値が${Ave}_1$」の項を選べば良いです。先程と同様の理由で、この条件を満たす場合は「値が${Ave}_1$」の項は確実に存在するといえます。

以上のことから、操作対象となる2つの項は毎回どれを選べばいいか分かりました。

## 操作回数は何回になるか
先程のcase1～3から、次のような考え方で操作を繰り返すことになります。
-  最初は「Ave1より小さい値」の項と「Ave2より大きい値」の項の両方が存在する
    - case1に該当する。そこで、「Ave1より小さい値」の項と「Ave2より大きい値」の項を選んでどちらかが存在しなくなるまでcase1の操作を繰り返す。

- 「Ave1より小さい値」の項と「Ave2より大きい値」の項のどちらかが存在しなくなった
    - case2かcase3のどちらかに該当するため、理想形になるまで該当するcaseの操作を繰り返す。

あとは操作回数を求めていくわけですが、1つめの操作回数は『「${Ave}_1$より小さい値」に該当する各項と「${Ave}_1$との差の絶対値」の合計値』と『${Ave}_2$より大きい値」に該当する各項と「${Ave}_2$との差の絶対値」の合計値』のうちの小さい方になります。そして2つめの操作回数は、先程の値の大きい方の値から、小さい方の値を引いた回数になります。結局のところ、必要な回数は2つの値のうちの大きい方を求めれば良いとことになります。

これで、計算用$O(N)$と、十分に間に合う時間で求めることができます。

# 提出コード(コンテスト後)

https://atcoder.jp/contests/abc313/submissions/44323042

ご不明点などがあれば教えていただけると幸いです。