OmniAICreator/Qiita-1.07M huggingface dataset:
MacでLaravel開発環境を構築する

# MacでLaravel開発環境を整備するまでの手順
macOS11.2でPHPフレームワークのLaravelの開発環境を調えるための手順を自身の備忘録も兼ねて書き留めておきます。初心者で知識も不足しているので間違っている所があれば、ご指摘頂けると幸いです。
## Laravelとは

## Homebrewのインストール
Homebewが入っていない場合はインストールしておきます。執筆時点では次のコマンドでインストールできます。
ターミナルにコピペしてください。


```zsh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)
```

なお、インストールコマンドはバージョンによって変わっている事があるので、ホームページで最新版を確認する事をオススメします。

https://brew.sh/index_ja
##Composerのインストール
ComposerはPHPのパッケージ管理ソフトです。
Hombrewでインストールします。

### Homebrewのアップデート

はじめにHomebrewをアップデートしておきます。
この処理には時間がかかる事があるので気長に待ちましょう。


```zsh
brew update
```

### インストール

アップデートが完了したらComposerをインストールします。

```zsh
brew install composer
```

### インストールの確認
インストールが完了したら次のコマンドで正しくインストール出来ているか確認します。

```zsh
composer -v
```

次のように表示されればOKです。

```zsh
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 2.0.12 2021-04-01 10:14:59
```

## Laravelのインストール
次はいよいよLaravelのインストールです。
（正確にはLaravelインストーラーのダウンロードですが、今は細かい事は気にしないでください！）

### インストール
次のコマンドを実行します。

```zsh
composer global require laravel/installer
```

### パスを通す
インストールは完了しましたが、今の状態ではまだパスが通っておらず、
laravelコマンドが使用出来ないので、パスを通す必要があります。
laravelは `＄HOME.composer/vendor/laravel/installer/bin` にあるので
ここにパスを通してやれば良いです。
つまり、次のようにします。

```zsh
export PATH=$HOME/.composer/vendor/laravel/installer/bin:$PATH
```

これでパスが通りました。試しに次のコマンドを打ってみてください。

```zsh
laravel -V
```

次のように表示されれば完了です！
おつかれ様でした！（※バージョンはインストールされて時期によって異なります）

```zsh
Laravel Installer 4.2.4
```


##参考サイト
https://readouble.com/laravel/4.2/ja/quick.html
初学者のプログラミング　ActiveRecord::RecordNotFound (Couldn't find User with 'id'=:id):

##ユーザー詳細ページを実装しようとしたときのエラー
```ruby
<%= link_to "点数入力", user_path %>
```
上記のようにパスを設定し、ユーザー詳細ページに遷移させようとしたところエラーが発生した。エラー文としては、`ActionView::Template::Error (No route matches {:action=>"show", :controller=>"users"}, missing required keys: [:id]):`
ずっとこのエラーが出て心折れそうだった。
##/user/:idのURLにはidを指定する
```ruby
<%= link_to "点数入力", user_path(@user.id) %>
```
link_toメソッドでパスを利用するとき、idが必要になる際は、上記のようにインスタンスのidをしてする必要がある。そうすることで、特定のidが指定され、URLが生成される。

##参考
https://programming-beginner-zeroichi.jp/articles/45

確認点１「pathの設定へidが設定されているか」を参考にし、記述を変更したところエラーが修正できた。
お世話になりました！本当にありがとうございました！

##まとめ
解決方法を探していた時に、railsのバージョン違いの情報に悩まされた。今後、自身の記事を誰かが見てくれていることを考えて、必ずrails6というバージョンを記載することを意識していこうと思った。

## さいごに
プログラミングの初学者です。その日に学んだことを学習の一環としてアウトプットしています。より深く学習していきたいと考えておりますので、内容に誤りがございまいたらご指摘等いただけますと幸いです。

参考図書：パーフェクト Ruby on Rails【増補改訂版】すがわらまさのり/前島真一/橋立友宏/後藤優一/五十嵐邦明
【GoogleAppsScript】スプレッドシートのフィルタを開くたびに更新する【GAS】

# スプレッドシートのフィルタが更新されない！
スプレッドシートのフィルタを使用してる時に`TODAY()`等の日付関数でフィルタをかけたり、GAS（GoogleAppsScript）により裏側で表のデータが変更されるとフィルタが最新状態に更新されずに古いデータが残ってしまいます。

<img width="250" alt="フィルタ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1186542/09691929-034c-8424-dceb-56a9c68b73a8.png">

たとえば今月以降のデータでフィルタをかけても

<img width="500" alt="表_3月" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1186542/c37372d6-db7b-a778-a81e-ab9af77f2fe0.png">

翌月になると…

<img width="500" alt="表_4月" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1186542/ed638d4f-1346-a8c8-5010-c753dc13ba90.png">

更新されてない！

再度フィルタのOKボタンを押せば更新されますが、非常に面倒で毎回そんなことをしているほど暇ではないですし、OKボタンを押す度に「なんでこんなことしているんだろう…」と後悔ばかりが押し寄せます。

# GASで開くたびにフィルタを更新すれば解決！
そこでGASです。
スプレッドシートが開かれるタイミングでフィルタのOKボタンを押すのと同じことをしてあげれば解決します。

```main.js
// onOpenでスプレッドシートが開かれる度に実行
function onOpen() {
  // すべてのシートを取得
  const sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
  for (const sheet of sheets) {
    // フィルタ取得
    const filter = sheet.getFilter();
    if (!filter) {
      continue;
    }
    // フィルタを同じ内容で更新
    const col = filter.getRange().getColumn();
    const criteria = filter.getColumnFilterCriteria(col);
    filter.setColumnFilterCriteria(col, criteria); 
  }
}
```
やっていることは至極単純で、`getFilter()`でフィルタを取得して、全く同じ内容でセットし直してあげてます。
フィルタの内容を取得したり設定したりするには`columnPosition（列）`を指定してあげないとダメなので、`getRange().getColumn()`で列を取得してます。

`onOpen`で実行しているためシートを開きっぱなしにしていると更新されませんが、フィルタのOKボタンの時とは違い、心晴れやかな気持ちでF5を押せるはずです。
【本当は教えたくない…】ノンデザイナーだからこそ知っておきたかった7のサイト


みなさん、こんちには

【[watnowテックカレンダー](https://bit.ly/watnowTechCal2021_4)の13日目】
今日は[watnow](http://www.watnow.jp/)の[しゅい](https://twitter.com/shuidayotehehe)が担当します
よろしくお願いします!


##はじめに
前回はデザインの参考サイト,フリーのイラストサイト,配色のサイトを紹介させていただきましたが、
今回はフリーのイラストサイトに特化して紹介させていただきます

[前回の記事はコチラから](https://qiita.com/bo_zu_/items/88f45b132c8293dcd9b1)

社内資料制作の際や営業資料を制作する際に役立てていだけたらなと思います…
これを使うだけで資料の素人感が一気になくなるんです
私はこれを使い始めてから誉められることが多くなった気がします。。。

では早速紹介していきます！

なお今回も**紹介するサイトは全て無料で利用**できます

##イラストサイト

###1,manypixels
![スクリーンショット 2021-04-13 14.11.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360221/5f279021-a791-d1e4-fae3-c14ee79b1b3e.png)


URL:https://www.manypixels.co/gallery

###2,storyset

![スクリーンショット 2021-04-13 14.12.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360221/7d7e394f-edc8-22cc-94a6-ae3458326b35.png)

URL:https://storyset.com/

###3,ITG.digital
![スクリーンショット 2021-04-13 14.20.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360221/15d363e4-86f1-1d7a-9df2-14ec8d4b6d28.png)

URL:https://app.itg.digital/

###4,loosedrawing

![スクリーンショット 2021-04-13 14.13.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360221/f77e9ce1-d320-82f1-3c40-162a9a6ae8a8.png)

URL:https://loosedrawing.com/

###5,illlustrations
![スクリーンショット 2021-04-13 0.28.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360221/997bcf28-e825-ea4d-b451-271f0f4b46c1.png)

URL:https://illlustrations.co/

###6,Streamline Lab

![スクリーンショット 2021-04-13 0.30.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360221/4e5f185c-9b24-7f5b-db41-4c743919dacd.png)

URL:https://lab.streamlinehq.com/

###7,DESIGNS.Ai
![スクリーンショット 2021-04-13 14.17.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360221/fb90bf7f-3d2f-4684-ca31-002dd2c3c618.png)

URL:https://designs.ai/graphicmaker/illustrations/Duotone_Cartoon_Set


##おまけ
これを使うだけでパワポをベタ褒めしてもらえる秘密パワポサイトをおまけで紹介します。
【google slide】,【PowerPoint】の両方でダウンロードできるからぜひ試してみてください…

###8,slidesgo

![スクリーンショット 2021-04-13 14.12.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360221/1202782c-8044-94ff-2afe-a96b0add792d.png)



URL:https://slidesgo.com/

##おわりに

どうだったでしょうか。今回のまとめがみなさんの資料作りする際などに役立てたら幸いです
watnowでは、チャレンジ精神旺盛な仲間を募集しています
興味を持たれた方はぜひ[@watnows](http://bit.ly/watnow_twitter)をフォロー,DMお願いします🤲
PHP5上級試験/準上級試験の上級合格に挑戦(21) プログラミングPHP第3版 16章~17章

# 16章 デバッグ
黒本だと１１章のアプリケーションに関するテクニックの、エラーの箇所が対応する。
PHP開発の場合開発環境、ステージング環境、本番環境の３つがある

## 16.1 開発環境
開発環境はエラー報告をできる限り設定しておく
Gitなどでバージョン管理するべきだが、そうでないならlocalhost環境を用意する方法がある
localhost環境構築にはZend Server CEやApache Web Server,MicorosoftのIISなどを手動でインストールする方法がある
他にも、ビルドインウェブサーバーを使う方法、クラウド環境を利用する方法がある

ビルドインウェブサーバー
http://php.net/manual/ja/features.commandline.webserver.php

Zend社の開発・テスト用のクラウド環境
http://www.phpcloud.com/

## 16.2 ステージング環境
自分のコードがどのように動くのかを本番環境をシミュレートした保護された環境で試すことができ、
また、エンドユーザ・クライアントが新機能を試す場でもある。
つまり、開発者用と、クライアント用の２種類用意するとよい（リソースがあれば）

## 16.3 本番環境
エラー報告の制御は厳しくする
404のページリダイレクトやtry~catch構文でエラーをうまく回避し、ログファイルに書き出すようにする

## 16.4 php.ini設定

+ `display_errors`　→本番環境では0
+ `error_reporting` → いろいろな設定がある（黒本１１章参照）

→ ステージング環境でのおすすめ設定として

動きが怪しいファイルが有る時、そのファイルにだけ頭に記載すると、エラーを吐き出す。

```index.php
error_report(E_ALL);
ini_set("display_errors", 1);
```
## 16.5 手動でのデバッグ

Zend Studio for EclipseやKomodoといった統合開発環境を使う
→変数の内容に依存する論理的エラーも捕捉可

・var_dump()、print()、pritn_r()がある
　→print_rの場合、データ型表示はなし


## 16.6 エラーログ
ログの置き場所は、
Ubuntuの場合デフォルトは/var/logs/apache2.jogになる

## 16.7 IDEをつかったデバッグ

複雑な問題はIDEを使ったデバッグが一番
Zend Studio for Eclipse　をつかったデバッグもある（これはJSもデバッグできる）
他にもKomodoやPhpEDがある

実行しているコードがブラウザに表示する内容を表示する
Debug OutputビューとBrowser Output ビューで、
コードを実行したところまでしか表示しないことが良い点。
つまりブレークポイントだと、そこまでしか表示しない。
ウォッチ式とかもある

## 16.8　その他の応用テクニック
プロファイリング・ユニットテストなどがある
→大規模なウェブシステムを作っていて大量のサーバーリソースを必要とする場合は、調べたほうがいい

# 17章 日付と時刻

黒本だと第１４章が対応する

今までの日付・時刻関数群は、1970年1月1日より前、2036年1月19日より後の日付を扱えなかった
（32ビット符号付き整数値で管理していたから）
今後のことを考えると、DateTimeクラス群を使うほうが良い

DateTimeZoneクラスで、設定をphp.iniファイルから抜き出す場合`ini_get（）`をつかう
そしてもっと詳しい情報をゲットするにはgetLocation()を使う

```index.php
$tz = ini_get('date.timezone');
$dtz = new DateTimeZone($tz);
echo "サーバーのタイムゾーン： {$tz}<br>";

foreach  ($dtz->getLocation() as Key => $value){
 echo "{$key} {$value}<br/>";
}
```
Runge–Kutta法でLorenzアトラクタを描く

#0. 初めまして
初めての投稿なので温かい目で見てください．
3つの常微分方程式をRunge–Kutta法で連立させて解き，Lorenzアトラクタを描いてみました．

#1. Lorenz方程式
E N. LorenzによってNavier–Stokes方程式から導かれた3つの常微分方程式です．太陽熱で暖められる地表と，上層で冷やされる大気の対流を記述するモデルです．

```math
\begin{align}
\frac{dx}{dt}&=-px+py \\
\frac{dy}{dt}&=-xz+rx-y \\
\frac{dz}{dt}&=xy-bz \\
\end{align}
```

パラメターを$p=10$，$r=28$，$b=8/3$として，3次元相空間の軌道をプロットします．初期座標は$\(x, y, z\)=\(0.0, 1.0, 2.0\)$としています． 

#2. ソースコード
CでRunge-Kutta法のプログラムを書きました．特に捻りのないシンプルなコードです．

```c:attLorenz.c
#include <stdio.h>
#include <math.h>

const double p = 10.0;
const double r = 28.0;
const double b = 8.0 / 3.0;

double f(double t, double x, double y, double z) {
	return (p * y - p * x);	//dx/dt = -px + py
}

double g(double t, double x, double y, double z) {
	return (r * x - x * z - y);	//dy/dt = -xz + rx - y
}

double h(double t, double x, double y, double z) {
	return (x * y - b * z);	//dz/dt = xy -bz
}

int main(void) {
double t;
double x = 0.0;
double y = 1.0;
double z = 2.0;
double dt = 0.02;
double tmax = 100.0;
double k1, k2, k3, k4;
double l1, l2, l3, l4;
double m1, m2, m3, m4;

	for (t = 0.0; t <= tmax; t += dt) {
		k1 = dt * f(t, x, y, z);
		l1 = dt * g(t ,x, y, z);
		m1 = dt * h(t ,x, y, z);		
		k2 = dt * f(t + dt / 2.0, x + k1 / 2.0, y + l1 / 2.0, z + m1 / 2.0);
		l2 = dt * g(t + dt / 2.0, x + k1 / 2.0, y + l1 / 2.0, z + m1 / 2.0);
		m2 = dt * h(t + dt / 2.0, x + k1 / 2.0, y + l1 / 2.0, z + m1 / 2.0);
		k3 = dt * f(t + dt / 2.0, x + k2 / 2.0, y + l2 / 2.0, z + m2 / 2.0);
		l3 = dt * g(t + dt / 2.0, x + k2 / 2.0, y + l2 / 2.0, z + m2 / 2.0);
		m3 = dt * h(t + dt / 2.0, x + k2 / 2.0, y + l2 / 2.0, z + m2 / 2.0);
		k4 = dt * f(t + dt, x + k3, y + l3, z + m3);
		l4 = dt * g(t + dt, x + k3, y + l3, z + m3);
		m4 = dt * h(t + dt, x + k3, y + l3, z + m3);
		x += (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0;
		y += (l1 + 2.0 * l2 + 2.0 * l3 + l4) / 6.0;
		z += (m1 + 2.0 * m2 + 2.0 * m3 + m4) / 6.0;
	}
	
return(0);
}
```

#3. Lorenzアトラクタ
gnuplotでプロットしてみました．
蝶のように綺麗な軌道が描けました．3次元の相空間内で軌道同士は交差せず，自己相似な構造（フラクタル構造）を示します．
Lorenzアトラクタは曲線でも曲面でもない，2と3の間の非整数のフラクタル次元をもつフラクタル集合です．

![la.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/673389/d12d1a28-96ac-e2a2-6d93-4cac5ddf06a2.jpeg)


#4. カオス理論
Lorenz方程式は決定論的な常微分方程式ですが，その軌道は非周期的で初期値によって結果が大きく変化するカオス的な性質を示します．この初期値鋭敏性によって，気象の正確な長期予測は非常に困難であると結論されます．これが有名なバタフライ効果です．

#参考文献
●決定論的非周期な流れ（Deterministic Nonperiodic Flow）：Edward N. Lorenz, Journal of Atmospheric Sciences, Vol.20, pp.130-141, 1963.
●ストロガッツ 非線形ダイナミクスとカオス　数学的基礎から物理・生物・化学・工学への応用まで（丸善出版）
reactjs-popupはオートフォーカスされる

[reactjs-popup](https://www.npmjs.com/package/reactjs-popup) を使ってポップアップを作成した
ポップアップの中のエレメントにモーダル、ツールチップの中にinputタグ、buttonタグを配置していた
モーダル、ツールチップを開いたときに、オートフォーカスされた

オートフォーカスされたくない！

## なぜオートフォーカスされたのか
そういう仕様だったから。
それをコントロールするpropsもない！
https://github.com/yjose/reactjs-popup/blob/655ea28b90b7bb1c1c7902b162e56f6823550361/src/index.tsx#L141

## 解決方法
これをreactjs-popupにわたす`children`の先頭に入れる

```jsx
<input type="hidden"></input>
```
【就活用】就活テクニックを爆発的に磨く方法、それは先人に訊く

#はじめに
私は内定10社様から内定をいただき、就活を始めて1週間で自社開発の企業1社から内定をもらいました。

私が1週間で内定までいけたのは、就活テクニックを先人に聞けて、それを実践できたからだと思います。

中には周りにエンジニアなんていないし、誰に聞けばいいと思った方がいると思います。
私もその１人でした（泣）

そこで私が先人から就活テクニックを聞く方法を共有し、ぜひ皆さんにも爆速で、納得いく就活を進めて欲しいと思い記事を作成しました。

なお、就活はテクニック、攻略方法を知っていて実行できれば、内定はもらいやすいです。
（ゲームの攻略本のようなイメージ）

#先人に訊く方法
connpassを利用して、個人等で就活懇談会が開かれているので、そこに参加して、テクニックを聞く方法です。

以下よりアクセスできます。

https://connpass.com/

無料で参加でき、就活懇談会以外にも技術的な勉強会等も開かれているので、興味ある方はぜひご利用ください。

他には知り合いにエンジニアの方がもしいれば、ぜひ転職活動前に就活テクニックを聞いてみてください。

知っていると知らないでは雲泥の差かと思います。

#それ以外にないかと言われますと・・・私の記事をぜひ見てください！！！m(＿ ＿)m

以下よりご覧になれます。

https://qiita.com/narimiya/items/b59db099b923b0b88330

就活ライフを楽しみましょう！！

以上です。
Ubuntu 20.04 で NVIDIA GPGPU 計算クラスタを作るメモ

## 背景

Ubuntu 20.04 で GPGPU(CUDA, OpenCL)計算クラスタを作りたい.
(AMD の場合は取り上げないが, 基本ドライバ関連だけ変えればいけるはず)

## Ubuntu install

USB メモリに ISO いれてインストールします.

## ssh ログイン

Desktop 版では標準では sshd が入っていないので,

```
$ sudo apt install openssh-server
```

で sshd 動かして ssh ログインできるようにしておきます.

## Suspend, sleep の off

Ubuntu 20.04 から(?) 裏でなにか CPU, GPU 使っていたとしても問答無用で数分たつと suspend するようになってしまっているので(Desktop 版の場合), suspend, sleep を off にします.

Ubuntu 20.04 + lightdm + NVIDIA driver で一定時間ログインしないと suspend する(解決策あり)
https://qiita.com/syoyo/items/55aeb57074a2bc8a47be

(↑ GPU 関係なくデフォルトでは suspend/sleep しました)

## ビルド環境

`build-essential` では cmake, git など入らないので適宜いれる.

```
$ sudo apt install build-essential
$ sudo apt install cmake git
```

## x11 の設定(nvidia-settings で制御するもの)

GPU のファン量などコントロールしたい場合は, nvidia-settings を使う必要がありますが, これには X11 を入れる必要があります.
(headless 環境では動かない)

NVIDIA GPU の X11 headless setup + X11VNC/RDP 接続のメモ
https://qiita.com/syoyo/items/a14fa891b80bb82a4485

あたりを参考にして x11vnc を headless(物理画面出力なし)で動かせるようにします.

## GPU ドライバ, CUDA

CUDA SDK 入れればドライバも入るので, CUDA SDK 入れるのが手っ取り早いでしょうか.

## MPI

OpenMPI, MPICH お好みで.
とりあえずは OpenMPI がよいでしょうか.

Xubuntu16.04でOpenMPIを使って並列処理をしてみる
https://qiita.com/pochiMasahiro/items/3c0c2828234b3c6a5a44

apt で入れます.

MPICH, OpenMPI 混在させるばあいは, update-alternatives あたりで切り替え, もしくは MPICC など環境変数で mpich 側のコンパイラを指定, でしょうか.

## InfiniBand

apt でドライバやパッケージ入ります.

## 共有ストレージ

NFS or CIFS(Samba) で接続でしょうか.

CIFS の場合は, ユーザー権限で接続できます.

Ubuntu 16.04 or 18.04 で gvfs で samba(cifs) をコマンドラインでユーザ権限でマウントする
https://qiita.com/syoyo/items/8f9cb366c7abe476ad7d


## TODO

* [ ] 複数ノードをセットアップする場合, Ubuntu MAAS あたりで OS イメージを作って一括デプロイできる環境をつくる
[Rails6] Bootstrapが適用されない時の解決方法

##前提・使用環境
AWS Cloud9 (Ubuntu)
Ruby 2.6.6
Rails 6.1.2.1
##エラー内容
以下を元に設定するも、自環境ではBootstrapのドロップダウンのリンクが表示されなかった。
[Rails 6にjQueryとBootstrapを入れる](https://qiita.com/kazutosato/items/d47b7705ee545de4cb1a)(webpackerで入れる場合で進めた)

・実行したコマンド

```shell:Terminal
yarn add bootstrap@next jquery popper.js
```

※ Bootstrapに関してはリンク先と異なるコマンドを実行している[^1]

・ブラウザーに表示されたエラー

```:Browser
Uncaught Error: Cannot find module '@popperjs/core'
```




##解決策

```shell:Teminal
yarn add @popperjs/core
```

##エラーの原因・背景など
###エラー認識の経緯
Bootstrapのドロップダウンが表示されなかったので、ブラウザの検証で確認。以下のエラーが発生していた。

```:Browser
Uncaught Error: Cannot find module '@popperjs/core'
```

意訳："@popperjs/core moduleが見つけられないよ"
ということだったのでYarnで上記モジュールをインストールした。([popperjs/popper-core - GitHub](https://github.com/popperjs/popper-core))

###参照先
[Bootstrap 5.0 - Download - Yarn](https://getbootstrap.com/docs/5.0/getting-started/download/)

###あとがき
今回がQiita初投稿です。至らぬ点・ご指摘ございましたらコメントいただけますと幸いです。

[^1]: Bootstrapのバージョンによって変わるらしい。導入予定のBootstrapのバージョンのドキュメントに合わせた。
Djangoで既存のPostgreSQLを利用

# はじめに

[Djangoチュートリアル③（モデルの作成、Django Admin）](https://qiita.com/honda28/items/04bc74c28b816aa10e2c)ではデフォルトの SQLite データベースの設定を行った。本記事では、PostgreSQL の設定を試してみる。あらかじめ存在している AWS 上に構築されている PostgreSQL を利用するため、①データベースの設定、②データベースからモデルを定義、③マイグレーションまで行う。[Integrating Django with a legacy database](https://docs.djangoproject.com/en/3.2/howto/legacy-databases/) を参考にした。

# ①データベースの設定

まず config/settings.py におけるデフォルト設定（SQLite）を以下に示す。SQLite の 'NAME' は使用するファイルの絶対パスを指定している。

```python:config/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}
```

上記を以下のように変更する。

```python:config/settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': [database_name],
        'USER': [user_name],
        'PASSWORD': [password],
        'HOST': ***.amazonaws.com,
        'PORT': '5432'
    }
}
```

SQLite では 'ENGINE' として 'django.db.backends.sqlite3' としていたのを、'django.db.backends.postgresql' に変更しており、あとは　DB の設定で必要とされるものを順に指定している。

さらに以下コマンドで PostgreSQL のドライバとして paycopg2-binary をインストールする。

```
$ pip install psycopg2-binary
```

上記で行ってきたデータベースの設定で正しく接続できているかは以下コマンドで確認できる。

```
$ python manage.py dbshell
```

# ②データベースからモデルを定義

既存のデータベースを使用しているため、当然モデルの定義がされておらず、Django ORM を使用することができない。Django ではデータベースからモデルを自動生成する `inspectdb` コマンドが準備されているので、それを利用してモデルを定義する。以下コマンドでは、出力結果をそのまま [app_name]/models.py に保存している。

```
$ python manage.py inspectdb > [app_name]/models.py
```

各モデルクラス内のサブクラスである class Meta の項目が意味するものは以下。
- managed：各テーブルの作成、変更、および削除を管理するかどうか。デフォルトでは False。
- db_table：テーブル名。

モデルを定義できたので、有効化するために config/settings.py の INSTALLED_APPS に登録しておく。登録する方法は[Djangoチュートリアル③（モデルの作成、Django Admin）](https://qiita.com/honda28/items/04bc74c28b816aa10e2c)のモデルの有効化と同様。

# ③マイグレーション

以下コマンドでマイグレーションを行う。

```
$ python manage.py makemigrations [app_name]
$ python manage.py migrate
```

テーブルのアクセスは以下コマンドなどで確認できる。

```
$ python manage.py shell
>>> from [app_name].models import [model_name]
>>> [model_name].objects.all()
```

# おわりに

既存のデータベースからモデルを自動作成でき、非常に便利なことがわかった。新規データベースでも、モデルを定義するよりデータベースを先に作ってそれからモデルの自動作成をした方が楽なのかも。わかったことがあれば、追記していきたい。
AWS ELB(Elastic Load Balancing)

##概要
エラスティック ロード バランサーの説明
RDS[(★)](https://qiita.com/tr76aquarius/private/3f7aee917a174c0989d4#%E7%89%B9%E5%BE%B4)と同じ要領でEC2を複製していた(Webサーバーを複製した)場合に起きる問題
・インターネットゲートウェイのアクセスポイントが分かれてしまう
・サーバーが正常化チェックする問題
・直接Webサーバーにアクセスさせるのはセキュリティ的に良くない。セキュリティに伴う処理の負荷の問題
　→ 本来コンテンツを提供する役割のWebサーバーに、通信の複合サーバーリソースの効率的な使い方とはいえない

ELBは複数のAZにリクエストを振り分けることができます。ターゲットグループに登録されているリソースに通信を振り分け、インスタンスID,IPアドレス,Lambda関数を設定できます

https://aws.amazon.com/jp/elasticloadbalancing/?elb-whats-new.sort-by=item.additionalFields.postDateTime&elb-whats-new.sort-order=desc

##負荷分散
ロードバランサにはDNS名のアクセスポイントが付与される
　→ アクセスポイントを一つにし、負荷を分散させる
片方のEC2が忙しそうなら別のEC2に自動でリクエストを流す
##ヘルスチェック
ヘルスチェック機能がある
　→ 異常なインスタンスを認識し、通信をストップさせ、正しい動きをしているインスタンスのみに通信を流す(ロードバランサーから切り離すと言われる)

##SSLターミネーション
セキュリティが高いが、暗号化された通信の処理が重い
・ELBに証明書を付与することでSSL通信の終端となる + ELBより先はHTTP通信となる
　→ HTTPS通信を複合する処理を担う
　→ セキュリティが高いまま、HTTP通信が可能なので処理が軽くなる

##ELBの種類
###ALB
アプリケーション ロード バランサー
HTTPやHTTPSのリクエストの負荷分散に使える
その他特徴
・レイヤー 7 に対応、HTTP/HTTPS リクエストの負荷分散。
・クライアントとロードバランサーの間の HTTPS ターミネーションをサポート。（NLBもリスナーにTLSを選択することで、HTTPSターミネーションが可） 
・セキュリティグループによるアクセス制限が可能。
・スティッキーセッションを使って、同一のクライアントからのリクエストを同一のターゲットにルーティングが可能。 

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/introduction.html

###NLB
ネットワーク
TCP,TLS,UDPのトラフィックの負荷分散に使える

https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/network/introduction.html

###CLB
クラシック
古いタイプのモノ
積極的に使用する必要はない

##主な構成
###ELBのみパブリックサブネットに配置
それ以外をプライベートサブネットに配置することが多い
※メンテナンス時はメンテナンス用のEC2を用意してそこからメンテナンスをする踏み台サーバーを準備するケースがある
###3階層アーキテクチャ
ELB作成時に内部向けか、外部向けか選択することができる

**外部接続時はALB、内部の接続時はNLBを使用するのが良い**

##参考
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
冗長性のあるブログサービス(冗長構成)を構築してみる

#実装デモ
障害を想定した試験として
　①メインのEC2を手動で停止してブログが見れるか確認
　②メインのRDSを停止してもブログが見れるか確認

**注意**
RDSのDBインスタンスを削除しないと
実装デモ終了時は9~10円/時間かかります。
RDS<アクション<削除でOK
最終スナップショットを作成すると、いつでも復旧可能になる

##準備
・同じリージョンの別AZにメインとサブそれぞれにEC2とRDSを作成。
・ELBを配置して2台のEC2にhttp通信が振り分けられる様に設定しておく。
・どちらのEC2が起動しているか見分けがつきやすいように、htmlファイルに見分けがつきやすい様に変化をつけておく

##ロードバランサー作成
EC2のダッシュボードページ<ロードバランシング<ロードバランサーを選択

ロードバランサーの作成をクリック<ALB作成をクリック

1,
ロードバランサーの設定
名前(任意),スキームはインターネット向け,IPアドレスタイプはipv4,リスナーはHTTPの80番ポートのまま,AZはVPCとAZを選択、パブリックサブネットを選択

2,セキュリティ設定の追加を選択

**(※注意※)HTTPSプロトコルを使用する様警告がでますが、デモだとHTTP接続で進める**

3,新しいセキュリティグループを作成するを選択、セキュリティグループ名(任意)を入力

4,ルーティングの設定<ターゲットグループ
名前(任意),ターゲットの種類をインスタンス,プロトコルをHTTPの80番ポート,プロトコルバージョンはHTTP1を選択

ヘルスチェック
HTTPの/でも良いが/readme.htmlを指定
詳細設定でEC2インスタンスのヘルスチェック間隔を設定できる
正常のしきい値を２、間隔を10秒に変更(10秒毎にヘルスチェック通信を飛ばして2回OKならそのインスタンスは正常とみなす設定になる)

5,ターゲットの登録
どのインスタンスをターゲットグループに追加するか選択できる
準備した2つのインスタンスを選択、登録済みに追加をクリック
これで2つのインスタンスに通信が振り分けられる設定になる

確認、作成をクリックし完了

↑の確認でEC2のダッシュボードページ<ロードバランシング<ターゲットグループを選択
今回作成したロードバランサーを選択、targetsを選択すると、どのWebサーバーに対してヘルスチェックの状態を確認できます。

##RDSの中に設定されているサイトアドレスをロードバランサーのDNS名に書き換える
どちらかのウェブサーバーにログインして下のコマンドでRDSに接続します

```console
mysql -h database-1.xxxxxxxxxxxxxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u wordpress -p

解説
mysql -h RDSのエンドポイント) -u wordpress -p
-uでwordpressインストール時に設定したユーザー名に-pオプションをつける
```
実行してパスワードを入力

```
(※)wordpressのテーブルを使用する宣言)
USE wordpress

(※)↓テーブルの名前やオプションを表示
SELECT * FROM wp_options WHERE option_name IN ('siteurl', 'home');

(※)option_value欄がサーバーのパブリックIPアドレスと同じという点を確認しておく

UPDATE wp_options SET option_value = 'ロードバランサーのDNS名' WHERE option_name IN ('siteurl', 'home');

(※)上のSELECT文を実行後、書き変わっているか確認
```

**<確認>**
・このDNS名をブラウザに打ち込んで正常にブログが開くか
・更新を何度か繰り返してみて、区別できるように準備編でhtmlファイルの違いがみられるか



##セキュリティグループの設定変更
今の状態だと全て接続元からの80番ポートからの通信が許可されている
→ ロードバランサーからのセキュリティグループからのアクセスのみに許可するよう設定を変更する

---
EC2<セキュリティグループ<適切なセキュリティグループを選択<インバウンドルール<インバウンドルールを編集
↓ 
80番ポートの0.0.0.0/0を削除
↓ 
同じく80番ポートにロードバランサーで作成したセキュリティグループを選択<ルールを保存

表示に問題ないか確認

##障害テスト(EC2)
障害を想定したテストを実施するため、EC2インスタンス片方だけシャットダウンする

EC2のページ<インスタンスの状態<インスタンスを停止

**<確認>**
振り分けが行われず、更新しても停止していないサイトのみが表示し続けられる

##RDSも冗長化構成
Amazon RDS<データベースを選択<該当するDBを選択して変更をクリック

DBインスタンスの設定<可用性と耐久性<マルチAZ配置<スタンバイインスタンスを作成するにチェックをつける
続行→ 変更スケジューリング(デモなので今すぐ変更を選択)

##障害テスト(RDS)
先程冗長構成を選択肢たDBを選択<アクション<再起動
DBインスタンスをフェイルオーバーで再起動

**<確認>**
・Webサイトが正常に動作するか
・DB<ログとイベントの最近のイベントに〇〇 instance failover startedや
〇〇 instance failover completedログが残っているか


##参考
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました
https://aws-cloud-tech.com
CloudWatchとは

##概要
サービス形態　ー　[SaaS](https://ja.wikipedia.org/wiki/SaaS#%E6%A6%82%E8%A6%81)

・AWSの監視マネージドサービス
・AWSリソースの状態を監視する
・条件に合致した場合、アラームで通知を行う
　→ (例)EC2のCPU使用率が90％など高負荷まで上がったら通知を出すなど
・条件に合致した場合、アクションを設定できる

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html

##全体像
収集、監視、アクション、分析といった機能がある

###収集
AWSのリソースの状態(EC2やRDSなど各種サービスのCPU使用率)をはじめとした様々な情報を収集する。
ログファイルなども収集できる
この収集する情報のことを **メトリクス** と言う

###監視
CloudWatchのエージェントをインストールすれば、オンプレのサーバーも同じ仕組みで監視できる
CPU使用料が90%(しきい値)を超えるとサービスが安定稼働できない
→ 監視条件を設定するのがAlarmの役目

###アクション
Alarmが起動したら様々なアクションを設定できる
条件の設定ができて、それぞれの場面、重要度に応じた設定も作成できる
・メール通知、[AWS Lambda](https://aws.amazon.com/jp/lambda/)を自動的に発動
・EC2のAuto Scalingを発動
・EC2アクションの停止、削除、再起動も設定で発動できる

###分析
収集した情報をグラフなどで可視化したものをダッシュボードで表示

##使用すべき理由
**・自動でメトリクスを収集する**
AWSリソースを作成した時点でデフォルトのメトリクスが収集される
EC2ならCPU使用率やディスクの読み書きのパフォーマンス、ネットワークの流入出の量もデフォルトで収集される

**・従量課金性**
メトリクスを補完しすぎると補完使用料金が別途かかる(課金対象となる可能性あり)
独自で監視システムを構築するというスタートダッシュ時の料金がオンプレ[(★)](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%B3%E3%83%97%E3%83%AC%E3%83%9F%E3%82%B9)で構築する監視システムの場合と比べてメリットがある

https://aws.amazon.com/jp/premiumsupport/knowledge-center/cloudwatch-understand-and-reduce-charges/

**・高解像度の監視可能**
基本は5分感覚でメトリクスを取得するのは**無料**だが、
**詳細モニタリング**といった1分間や、1秒間といった高解像度の監視も可能(追加料金)

**・オンプレも監視可能**
サーバーにCloudWatchのエージェントを入れることにより、一元管理(クラウドもオンプレも)できる
既にオンプレで監視システムを動かしている場合移行は難しいケースも多い可能性もあるが、検討してみる価値あり

##メトリクス
CloudWatchで収集した情報のこと

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/working_with_metrics.html

###標準メトリクス
あらかじめAWSが用意したメトリクス
(例)CPU使用率、NWパフォーマンス,Disk I/Oなど

###カスタムメトリクス
ユーザーが独自に設定したメトリクス
自分でCloudWatchに送る設定を行う必要がある
(例)メモリ使用率、ディスク使用率など

###(補足)CloudWatchエージェント
・CloudWatchエージェントをEC2にインストールする
・EC2にIAMロールをアタッチする
・適切なネットワークルートを設定する

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/Install-CloudWatch-Agent.html

##アラーム評価
###評価軸
設定には3つの評価軸がある

1,Period・・・評価感覚
2,Evaluation Period・・・直近、何個のPeriodを評価対象とするか(評価期間)
3,Datapoints to Alarm・・・評価対象のうち、何個のPeriodがしきい値を超過したか

**(例)**
しきい値 - CPU使用率が30%以上
Period - 1分間隔
Evaluation Period - 3個
Datapoints to Alarm - 3個

1分間隔(Period)でCPU使用率を計測し、評価期間中(Evaluation Period)に何回越えたか(Datapoints to Alarm)という設定となる

###アラームのステータス
OK・・・しきい値内の値
ARARM・・・しきい値外の値
INSUFFICIENT・・・収集し始めた場合などの理由により、アラームの状態を判断するのには不十分な値

###欠落データの取扱
欠落データ・・・CloudWatchになぜか１分感覚で設定されているのに、データが送信されてこない状態のこと
この時CloudWatchがどのように振る舞うのか設定できる

Missing・・・見つかりません→ 直近のアラームの状態が保持される
Good・・・適正→ 欠落データはしきい値内である
Ignore・・・無視→ 過去のデータポイントに遡る
Bad・・・不正→ 欠落データはしきい値外である

**サーバーがダウンしてメトリクスが全て欠落した場合**

Missing・・・見つかりません→ INSUFFCIENT(OKでもNGでもなく判断できない状況)
Good・・・適正→ OK状態
Ignore・・・無視→ 現在のステータスを保持
Bad・・・不正→ アラーム状態

**(例1)**
CPU使用率ならBadを設定するのが良い
→ なんらかの不具合によってメトリクス自体を送信できていない可能性があるのでそこを検知するため

**(例2)**
エラーが発生した場合のみにメトリクスが作成される場合
→ 欠落データをGood(適正)するのが良い

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html

#参考
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
AutoScalingとは

##概要
期間限定のキャンペーンなどで負荷が増加した際、EC2インスタンスを増設して一時的な処理の増加に対応したり、逆に負荷が低下した状態ならEC2インスタンスを減らしたりできる

https://aws.amazon.com/jp/autoscaling/

スケールアウトは複数のアベイラビリティゾーンで均等のサーバー数になるようにスケールアウトされます。 数が均等な場合は、ランダムにスケールアウトされます。
##起動テンプレート
EC2を起動するテンプレートのようなもので、何のAMIを使うか、インスタンスタイプは何か、キーペアはどれか、セキュリティグループなど通常EC2を手動で設定する内容をひとまとめにした機能

何のインスタンスを動かすか、起動テンプレートを作成する

**※起動設定(旧版)**
起動テンプレートは、内容を更新する際にバージョン管理ができる点に対して
起動設定は別のファイルとして管理しなければならない

**AWSは起動テンプレートの使用を推奨しています**
##AutoScalingグループ
起動テンプレート作成後に設定する
どの起動テンプレートを使用するかを設定するため、先に使用する起動テンプレートと紐付ける
他にELBのターゲットグループと紐付けできる
EC2をどれくらい作成していくかを指定する。
設定内容は**最小、希望、最大**

**希望**とはAutoScalingグループ作成直後のEC2インスタンスの作成される数

Auto Scalingグループを作成するときは、起動設定を指定する必要があります。複数のAuto Scalingグループに同じ起動設定を指定することができます。ただし、Auto Scalingグループに対して１つの起動設定のみを指定でき、作成後に起動設定を変更することは出来ません。 したがって、Auto Scalingグループの起動設定を変更する場合は、起動設定を作成してから、Auto Scalingグループを新しい起動設定で更新する必要がある。

##スケーリングポリシー
CloudWatchでメトリクスが発行され、設定したアラームと紐づけることで、EC2を追加したり削除したりできるルールのことで、一つのAutoScalingに対し、複数条件を設定できる

**(例)アクセス数の増減により↓** 
・負荷が70%を越えた状態ならEC2を１つ追加(限度は最大まで)
・負荷が30%を切っていたらEC2を1つ削除(限度は最小まで)

![AutoScaling1.017.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207512/999fdad5-f177-d796-7f8b-c0db8b5f0f82.jpeg)


##運用について
AutoScalingにはスケジュールに基づくスケーリングを設定することができます。例えば毎朝午前 8:30 に業務を開始する場合、処理の増加を予め見越して8:00 からスケーリングを開始すると十分余裕が得られます。 **定期的に処理が集中するシステムの運用はスケジュールを利用したスケーリングを設定すべきです。** ネットワークトラフィックの増加を検知してからスケールアウトを行うと業務に間に合わない可能性があります。 また、リザーブドインスタンスやスポットインスタンスを利用する方法も予測に対するアプローチとしては間違いです。

##実装の流れ

https://qiita.com/tr76aquarius/items/b48d3d9b8f8e31adf872



##参考
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
AutoScaling 起動テンプレート作成　ハンズオン

##作成方法
EC2<インスタンス<テンプレートの起動を選択
起動テンプレートを作成をクリック
**(注意)**
(=〇〇)→ 作成したテンプレートに実際に設定した内容をメモしています。

**起動テンプレート名と説明**

起動テンプレート名前を入力、
テンプレートのバージョン説明ではバージョン番号を指定できる(=1.0.0)、
AutoScalingのガイダンスとは、AutoScalingでこのテンプレートを使用する場合にチェックボックスを選択
テンプレートタグ→ このテンプレート自体にタグを追加する。必要に応じてタグを追加(コストタグ)
ソーステンプレート→ 既にテンプレートを作成している場合元となるテンプレートを指定して作成し、1から設定する手間を省ける。

---
続いて
AMI(=自分のAMI)、
インスタンスタイプ(=t2.micro)、
キーペア(=既存のキーペア)、

ネットワーク設定
ネットワーキングプラットフォーム(=VPC)、
セキュリティグループはENI(EC2インスタンスにアタッチするIPアドレス)に対してセキュリティグループを設定したいので空欄にしておく、
ストレージも指定できる(=ここではそのまま)
リソースタグ(この起動テンプレートを元に立ち上げたEC２インスタンスに対して、アタッチされるタグを指定できる。)


**ネットワークインターフェース**
セキュリティグループをENIと紐付ける(既存のEC2インスタンスと同じように設定)
パブリックIPアドレスの自動割り当てを有効化に変更(このEC2が立ち上がった際ssh接続、つまり外からこのEC2インスタンスにログインできる設定)


**高度な詳細**
EC2インスタンスを作成する際に色々な整備機能を指定できる。(今回はデフォルト)

<起動テンプレートを作成>

##起動テンプレートの特徴

起動テンプレートを変更した際、テンプレートのバージョンを指定して更新することができる。

##既存のEC2インスタンスから作成する方法
EC2<インスタンス<アクション<イメージとテンプレート<インスタンスからテンプレートを作成を選択

実際のEC2インスタンスの設定を反映した状態の起動テンプレート作成画面になり、自動的にソーステンプレートにソースインスタンスが表示される

##参考
この記事はAWS初学者を導く体系的な動画学習サービス
「AWS CloudTech」の課題カリキュラムで作成しました。
https://aws-cloud-tech.com
memo: node.jsを使った古いプロジェクト

# 前提として
nodenv などでnode.jsのバージョンを合わせた上で作業する。
.node-version がない場合は、当時のnode.jsのバージョンをなんとかして調べる。

また、正しい挙動・想定される挙動 を事前に把握しておく。　

Gitで管理するなど、試行錯誤ができる状況を作っておく。


## package-lock.json の内容でnode_moduleをinstallする
`npm install` ではなく `npm ci` を使えば package-lock.json の内容でモジュールをインストールできる。
パッケージに脆弱性がある場合も多いので頼りすぎ注意。
（やっぱり package-lock.json のGit管理は大事ですよね）

### npmのバージョンが足らなくて `npm ci` できないとき
とりあえず `npm install` を試す方が正攻法な気がします。
その上で npm installがこけてしまった場合、、、

`npm outdated -g` して、npmが 5.7以上に上げられるかを確認して、
npmをアップデートできる場合、 `npm update -g npm` して、
`npm ci` する。


## npm ciでもダメなら頑張ってnpm installする
腰を据えて `npm install` する。
エラーログを読んで、一つ一つ対応する。

脆弱性エラーが出たときは、`npm audit fix` してみる。
脆弱性解消しきれない場合は、`npm audit fix --force` してみる。
それでも脆弱性解消しきれない場合は、`npm audit` してみて、パッケージの一つ一つに対応していく。

ログ読めば大体なんとかなる。

# 参考記事
https://qiita.com/masatakaaaa/items/22669ab7d53c8c7e09a1

https://engineering.mobalab.net/2019/08/08/package-json%E3%81%A8package-lock-json%E3%81%AE%E9%81%8B%E7%94%A8%E6%96%B9%E6%B3%95%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/
Your bundle is locked to mimemagic (0.3.5), but that version could not be foundでbundle installが上手くいかない時の対処法


##Railsのmimemagicが原因でbundle installが動かない

```
Your bundle is locked to mimemagic (0.3.5), but that version could not be found
```


Railsと間接的に依存関係にあるmimemagicがソフトウェアのライセンスの問題で、公開停止をしているため、該当するGemが見つからない状態になっていた。

##解決方法

mimemagicをアップデートさせることにより、対応が可能

```
$ bundle update mimemagic 	
```


##今回のライセンス問題で出てきたライセンスの種類と概要

mimemagic自体はは`MIT`というライセンス、mimemagicの一部コードで`GPL`というライセンスが使用されているとのこと。

###MITとは
`Massachusetts Institute of Technology License`の略で、マサチューセッツ工科大学で作成された寛容型オープンソースライセンスの一つとのことです。

###特徴
MITライセンスを用いて公開されたプログラムを改変したり、自らのプログラムに組み込んだ派生的な著作物は、ソースコードを公開せずに販売・配布が可能になるとのことです。
ライセンスの制限が少ないため、他のライセンスと組み合わせて共存することも多いとのこと。


###GPL2.0とは
`GNU General Public License`の略で、OSSやフリーソフトウェアでも採用されているもの

###特徴
ソースコードの公開を原則として、誰でも入手、使用、改変再配布することを認めているとのこと。
GPLで公開されているプログラムを改変したり、自らのプログラムの一部として組み込んだ場合など、派生的・二次的な著作物を作成した場合には、これにもGPLを適用して公開しなければならないと定めているらしい。


###個人的な感想
今回のmimemagicの件は、ライセンスの特徴の違いによって発生した問題だったとのことで、こういった法律関係に関しては完全に専門外ですので、概要を掴むことがギリギリでした。
どの業種においても、ルールや法律は存在するので、今回のRails開発をする際に、システムに関する法律に対する興味を持ついいきっかけになりました。



※本ページ記載の内容は、あくまで私の理解になります。。ライセンス関連は、解釈の仕方や見解の相違によってトラブルになることが多いため、不利益を被っても保証や責任を取れません。詳しくは法律の専門家に相談してください。


##参考
https://wa3.i-3-i.info/word13200.html
https://yamory.io/blog/about-mit-License/
https://yamory.io/blog/about-gpl-license/
https://e-words.jp/w/GPL.html
https://licenses.opensource.jp/GPL-2.0/GPL-2.0.html

####原文
https://opensource.org/licenses/GPL-2.0
https://opensource.org/licenses/MIT
springframeworkのJavaMailSenderでメールを送る際の送信主に名前を付与する

たまたま、JavaのプロジェクトとKotlinのプロジェクトの両方で送信主に名前を付与して送信する処理を作成したので、備忘録として投稿します。


##Java開発環境

|  |version  |
|---|---|
|java  |11  |
|SpringBoot  |2.1.0.RELEASE |

既存のSimpleMailMessageを用いた処理の場合、`InternetAddress`を使用することが出来なかったので、`MimeMessage`を用いた処理に変更

```PHP:変更前
SimpleMailMessage message = new SimpleMailMessage();
            message.setFrom("hoge@.com");
            message.setTo("hoge");
            message.setSubject("subject");
            message.setText("body");
```

InternetAddressクラスを用いて、personalと形式を設定

```PHP:InternetAddressクラス
InternetAddress(StringSE address, StringSE personal, StringSE charset)
```

```PHP:変更後
MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true , "UTF-8");
            helper.setFrom(new InternetAddress( "hoge@.com" ,"不動産SHOPナカジツ", "UTF-8"));
            helper.setTo("hoge");
            helper.setSubject("subject");
            helper.setText("body");
```



##Kotlinでの設定
こちらはJavaで設定した変更後の処理と同様の処理

|  |version  |
|---|---|
|Kotlin  |1.3.70  |
|SpringBoot  |2.3.4.RELEASE  |

```PHP: 
val message = javaMailSender!!.createMimeMessage()
val helper = MimeMessageHelper(message, true)
helper.setFrom(InternetAddress("hoge@.com", "不動産SHOPナカジツ", "utf-8"))
helper.setTo("hoge")
helper.setSubject("subject")
helper.setText("body")
```



###参考
https://spring.pleiades.io/specifications/platform/8/apidocs/javax/mail/internet/internetaddress
中華圏のエンジニア動画

#UPDATE

とりあえず動画をMP3に落として、ウォークマンで聞き始める。

* 発音は確かにうまい
 文法はネイティブではないが、やはり学校教育の差なのか、言いたいことを伝える能力が高い
 →　日本人はこういう自己主張が下手である。

* エンジニアなので、ISSUEとかDOCUMENT書いていたら、英文法は出来そうな気がしてきた。
 →　ちなみに、辞書を使わずに書いた、自分のくそ英語

https://github.com/chanmoto/japanese-karaoke-song
https://github.com/chanmoto/multi-language-dict

#背景
最近、中華圏のエンジニアが動画で登場している



おなじみVUE.JS開発者のドキュメンタリー

https://www.youtube.com/watch?v=OrxmtDw4pVI

中国でのオープンソースコミュニティ

https://www.youtube.com/watch?v=RFjIBM0TR7U

最近、話題のオードリータン　→　お笑いの方ではない

https://www.youtube.com/watch?v=aamQHqtXTn0

総じて驚かされるのは、みんなすごく英語が達者ということである。

##英語の勉強

ここからが本題であるが、やはりIT方面の情報交換において英語が最重要である。
ちなみに、こないだ受けたTOEICが450点程度で、危機感を覚える。

これまで人生長く英語は学んできたが、一向に向上しないのは何故なのか？

##日本人の英語ができない理由

日本人が総じて英語がダメな理由を書いてみる

* カタカナ英語などの登場で、英語脳を遮断されている
* 日本人は学校教育により、間違った英語教育を受けてしまっている
* 英語ができなくても何も一生困らない

#これからの目標設定

少なくともＩＴエンジニアとしては、以下のレベルにはなるべきだと思う。

* Youtubeの動画を字幕なしで理解出来るレベル
* ＩＴエンジニアとしては、人前で英語プレゼンや情報発信ができるレベル
* IT用語の正しい発音はマナーとして最低限は学ぶこと

ちなみに私の場合は中国語の勉強に取り組んでおり、とある学習方法で一定の成果を上げている。

##カラオケの日本語ルビ

中国語は日本語と違い、そもそもの発音や音節が違う
→　日本語に聞こえるように要約すると、案外、脳は素直に言うことを聞いてくれる。

https://motochan1969.hatenablog.com/entry/2019/04/12/071100

ポイント
・中国語　→　ピンイン読み　→　音節を変える　→　日本語の当て字

* 我爱你 →　wo ai ni　→ wo aini →　魚会いに（うおあいに）   
* 怎么样 →　zen me yang →　zenme yang →　座間やん（ざまやん）
* 喜欢你 → xi huan ni →　xi　huan　ni →　強い不安兄（しいふあんにい）
* 我喜欢你 →　wo xi huan ni →　woxi huan ni →　 魚氏ファンに（うおしふぁんに） 

同様に英語の場合も、これは可能である。

洋楽カラオケの例を示す。

https://motochan1969.hatenablog.com/entry/2019/04/14/002121
https://motochan1969.hatenablog.com/entry/20210329/1617027028
https://motochan1969.hatenablog.com/entry/2019/07/14/110200


こういうのをやっていると、
ネタ？
なのかと思ってしまうが・・・

少なくとも、Githubをジットハブと読んで恥ずかしい思いをすることがないようにしたい。


余談であるが、日本語ルビを付与するタスクは
Deepleaningのトランスフォーマーそのままだと思う

すごい技術はこういう遊び心から、生まれてくるのではないかと思う。
laravel カラムを削除するマイグレーションの書き方

# 目的

- カラムを削除する際のマイグレーションファイルの記載方法をまとめる

# 情報

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| PHP バージョン | 7.4.8 | Homebrewを用いてこちらの方法で導入→[Mac HomebrewでPHPをインストールする](https://qiita.com/miriwo/items/cd54077aad7e139cf518) |
| Laravel バージョン | 6.X | commposerを用いてこちらの方法で導入→[Mac Laravelの環境構築を行う](https://qiita.com/miriwo/items/adaaaeecae69d6392e08) |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |
| Node.jsバージョン | v12.14.1 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでNode.jsをインストールする](https://qiita.com/miriwo/items/73d1546220f1c091a7d5) |

# 方法

1. 「delete_flag」というカラムを削除したい場合下記のように記載する。

    ```php
    $table->dropColumn('delete_flag');
    ```

# 例

1. 下記にマイグレーションファイルの例を記載する。下記のマイグレーションファイルはtasksテーブルに「delete_flag」カラムを追加するup処理と追加されている「delete_flag」カラムを削除するdown処理が記載されている。

    ```2021_04_12_213724_add_delete_flag_columns_to_task_table.php
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    class AddDeleteFlagColumnsToTaskTable extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::table('tasks', function (Blueprint $table) {
                $table->tinyInteger('delete_flag')->after('statut_id')->nullable()->comment('削除フラグ');
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::table('tasks', function (Blueprint $table) {
                $table->dropColumn('delete_flag');
            });
        }
    }
    ```
GitHub Actionsでの機密情報の参照

# はじめに
`GitHub Actions` 皆様お使いでしょうか。
正式リリースされて一年ちょっと経っておりますので、大分利用されている方も増えてきている印象があります。
(無料枠ありますし。)
弊社でも `GitHub Actions` を活用しておりますが、各種キー情報など、機密情報をどのように扱うのかまとめてみました。
手順としては

```
1. GitHubのproject > setting > secrets
2. １で登録したsecretキーを、GitHubActions上から参照
```

といった流れになります。

# GitHub Actionsへの登録
GitHub上の、下記ページで設定を行います。
`https://github.com/${account_name}/${project_name}/settings/secrets/actions`
※ `account_name` , `project_name` は環境によって異なります。


ここでは、 `SECRET_SAMPLE` という名前で作成します。
![スクリーンショット 2021-04-13 14.08.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66330/092a876d-5e9c-7906-12af-b31d91276f07.png)

# GitHub Actionsからの利用
https://docs.github.com/ja/actions/reference/encrypted-secrets

```yml
name: CI
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]
jobs:
  plan:
    name: test-workflow
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v1
        with:
          aws-access-key-id: ${{ secrets.SECRET_SAMPLE }}

      - name: command run 
        run: | 
          aws sts get-caller-identity
```

# 参考情報
* https://qiita.com/inouet/items/c7d39ac4641c05eec4a0
* https://www.ikkitang1211.site/entry/github-actions-secrets
* https://dev.classmethod.jp/articles/github-organization-level-secrets/
Unityにおけるオブジェクト破棄のタイミング

# 概要
シングルトンオブジェクトのデストラクタでゲーム設定の保存処理を行うようにしたところ、エディタ終了時にクラッシュする現象が発生しました。原因を調査すると、Unityエディタではプレイ中に生成されたオブジェクトが少し変わったタイミングで破棄されていました。

# 結論
Unityエディタでプレイ中に生成されたオブジェクトは__次回のプレイ開始時__及び__エディタの終了時__に破棄されます。直感的にはプレイ停止時に破棄されていそうですが、次のプレイ、もしくはエディタの終了時までオブジェクトは保持されているようです。

# 実験
以下のコードでデストラクタの実行タイミングを確かめます。

```c#:SingletonDestractor.cs

using UnityEngine;
public class SingletonDestractor
{
    static SingletonDestractor instance;
    static public SingletonDestractor Instance
	{
		get
		{
			if(instance == null)
			{
				instance = new SingletonDestractor();
			}
			return instance;
		}
	}

	public void Call()
	{
		Debug.Log("Call");
	}

	~SingletonDestractor()
	{
		Debug.Log("Destract");
	}
}
```

デストラクタでDebug.Logを呼び出すシングルトンオブジェクトです。
以下のコンポーネントでこれを生成します。

```c#:Caller.cs
using UnityEngine;

public class Caller : MonoBehaviour
{
    void Start()
    {
        SingletonDestractor.Instance.Call();   
    }
}
```

実行、停止したところ、コンソールは以下のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526299/43f802e3-187a-738e-2971-4d9377c8e8a4.png)

デストラクタ内で呼び出しているはずのDebug.Log("Destract");が実行されていません。
この状態で再度実行、停止したところ、コンソールは以下のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526299/959c34b7-9d4f-c8a6-f2ec-a7aba7261bfd.png)
このことから、前のプレイ時のSingletonDestractorオブジェクトが今回のプレイ開始時に破棄されたことが分かります。間が2秒ほど空いていることから、恐らくプレイボタンを押してから実行が開始されるまでの間に破棄されていると思われます。

また、しばらく別の作業をしていた所、以下のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526299/1737fd4c-78f9-8f04-d83e-fdafd58e8db3.png)
時間経過、もしくは何らかのタイミングでも破棄されるようです。いずれにせよデストラクタの実行タイミングはコントロールしづらく、使用は避けたほうがいいでしょう。

# 解決策
オブジェクト破棄時に何か処理をしたい場合は、MonoBehaviourを継承して、[OnDestroy関数](https://docs.unity3d.com/ja/2018.4/ScriptReference/MonoBehaviour.OnDestroy.html)を使うべきです。具体的には以下のようにします。

```c#:SingletonDestractor.cs
using UnityEngine;

public class SingletonDestractor : MonoBehaviour
{
    static SingletonDestractor instance;
    static public SingletonDestractor Instance
	{
		get
		{
			if(instance == null)
			{
				var go = new GameObject();
				instance = go.AddComponent<SingletonDestractor>();
				DontDestroyOnLoad(go);
			}
			return instance;
		}
	}

	public void Call()
	{
		Debug.Log("Call");
	}

	void OnDestroy()
	{
		Debug.Log("Destract");
	}
}
```

このようにすると、先程のシングルトンクラスと同様に扱うことができ、なおかつゲームオブジェクトの破棄はプレイ終了時に行われるので、意図したタイミングでデストラクタ相当の処理を行うことができます。実際にこちらのクラスでプレイ、停止したところ、コンソールは以下のようになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526299/4ca6460d-523b-a5a1-6ee7-105e60ae99f7.png)
正しく終了時に破棄が行われていることが確認できます。
完全に理解した Slack 絵文字を作った

メガ文字でやり方わからなかったので作った。
> https://zk-phi.github.io/MEGAMOJI/

こんなの
![scroll.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/7b402fb4-7dc2-7d13-8a03-508bc249c772.gif)
![kanzen.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/f9c12979-54e7-2017-e40e-a8ed47a0026e.gif)
![完全に理解した！-#FFFFFF-#00FFFF.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/270c052c-0d40-8d14-8e0f-32b0c6a78f67.gif)


> 出典
https://yingtongli.me/blog/2018/05/12/marquee.html

1. `brew install ffmpeg gifsicle`
1. FONT_PATH を合わせる
1. 実行

slackのemojiが130KBあたりに制限があるらしいので、大きすぎる場合は 32x32くらいにするといいかも。

自分の環境だとFILL色が効いてないです。

```sh
#!/bin/bash

IMWIDTH=48
IMHEIGHT=48
STEP=5 #pixels per frame
FRAMERATE=50 #frames per second

FONT_PATH="/System/Library/Fonts/ヒラギノ角ゴシック W4.ttc"

MESSAGE="完全に理解した"

BACKGROUND="#FFFFFF"
FILL="#00FFFF"

# Make a "unique" prefix for this run
PREFIX="$(head -c 32 /dev/urandom  | shasum | cut -b 1-10)"
OUTPUT="${PREFIX}.gif"
OUTPUT="scroll.gif"

# Generate image from text input
convert -background "$BACKGROUND" -fill "$FILL" -font "$FONT_PATH" -density 200 -pointsize 100 "label:${MESSAGE}" "/tmp/${PREFIX}_label.png"

# Resize to 128px high
convert -resize x${IMHEIGHT} "/tmp/${PREFIX}_label.png" "/tmp/${PREFIX}_sized.png"

# Add white space to front and back for empty frames
WIDTH="$(identify -format "%[fx:w]" "/tmp/${PREFIX}_sized.png")"
CANVAS_SIZE=$(($WIDTH + $IMWIDTH + $IMWIDTH))
echo width=$WIDTH
echo CANVAS_SIZE=$CANVAS_SIZE
convert -size ${CANVAS_SIZE}x${IMHEIGHT} "xc:$BACKGROUND" "/tmp/${PREFIX}_canvas.png"
convert "/tmp/${PREFIX}_canvas.png" "/tmp/${PREFIX}_sized.png" -geometry +${IMWIDTH}+0 -composite "/tmp/${PREFIX}_padded.png"

# Generate individual frames
OFFSET=0
I=0
LIMIT=$(($CANVAS_SIZE - $IMWIDTH))
while [ $OFFSET -lt $LIMIT ]; do
  echo ${OFFSET}/${LIMIT}
  convert "/tmp/${PREFIX}_padded.png" -crop "${IMWIDTH}x${IMHEIGHT}+${OFFSET}+0!" "PNG32:$(printf "/tmp/${PREFIX}_frame_%05d.png" $I)"
  I=$(($I + 1))
  OFFSET=$(($OFFSET + $STEP))
done

# Compile to gif
ffmpeg -y -f image2 -i "/tmp/${PREFIX}_frame_%05d.png" -vf palettegen "/tmp/${PREFIX}_frame_palette.png"
ffmpeg -y -f image2 -framerate $FRAMERATE -i "/tmp/${PREFIX}_frame_%05d.png" -i "/tmp/${PREFIX}_frame_palette.png" -filter_complex "[0:v][1:v]paletteuse" "$OUTPUT"

# Compress it
# gifsicle -bO --dither --colors 8 "$OUTPUT"

# Clean up!
rm /tmp/${PREFIX}_*.png
```
Fakersでダミーの注文データを作る（Ruby on Rails、seeds）

# やりたいこと
社内研修で、ウォーターサーバーの替えのボトルの在庫を見張って自動発注するというプチIoTシステムをRailsで開発しています。

Railsで注文データのダミーを作りたかったのですが、調べても意外にそれっぽいハウツーに出会えなかったのでメモ。（自分のぐぐり力不足？）

ちなみに、注文モデル（order.rb）には以下のカラムがあります。

| カラム | データ型 | |
|:-----------|:-----------|:-----------|
|delivery_date|date|納品日|
|qty|integer|注文数|
|order_date|date|注文した日付|
|status|integer|0: 注文済み、1: 納品済み|
|created_at|datetime|
|updated_at|datetime|
|item_id|bigint|注文アイテムの外部キー|
|user_id|bigint|注文したユーザーの外部キー|

ちなみに、環境。
Rails6.0.3, macOS Catalina 10.15.7

# 実装！
今回はFakerというgemを活用して、ダミーの注文データを30個生成します。
（gemとは？=>Railsをさらに便利にしてくれるライブラリ（＝拡張機能＝オプション機能＝カスタマイズ機能）みたいなやつ）
Fakerそのもののインストールの仕方に関してはネットにたくさん記事があるので割愛します。

```ruby:seeds.rb
# 最新の注文は個別で作る
order_date = Faker::Date.between(from: 5.days.ago, to: Date.today)
Order.create(
  order_date: order_date,
  qty: Faker::Number.between(from: 1, to: 10),
  delivery_date: order_date + 3, # 納品日は注文日の３日後としておく。下に詳述。
  status: 0,
  user_id: 2,
  item_id: 1)

# 残り29個はランダムで生成してもらう
29.times do
  order_date = Faker::Date.between(from: 1.year.ago, to: 10.days.ago)
  Order.create(
    order_date: order_date,
    qty: Faker::Number.between(from: 1, to: 10),
    delivery_date: order_date + 3,
    status: 1,
    user_id: Faker::Number.between(from: 1, to: 2),
    item_id: Faker::Number.between(from: 1, to: 3)
  )
end
```
↑コードを見れば何をしたいか大体わかると思うので、解説は加えません。
これ以外の実装がしたい場合は、Fakerはその辺のチュートリアル記事よりも、本家に当たるのが吉でしたのでこちらを参照すると良いと思います。
Fakerドキュメント　https://github.com/faker-ruby/faker#faker
Faker::Date　https://github.com/faker-ruby/faker/blob/master/doc/default/date.md#fakerdate

ちなみに、当初、delivery_dateもFakerしようと思ったのですが、そうすると、delivery_date（納期）がorder_date（注文日）よりも前になってしまうなど整合性が取れないデータが発生することを懸念し、`order_date + 3` という計算にしました。

余談ながら、この計算方法（文法）で合っているかは、ターミナルで`rails db:seed`する前に、rails consoleで確認できることを発見！↓

```terminal
% rails console   
Running via Spring preloader in process 48085
Loading development environment (Rails 6.0.3)
irb(main):001:0> order_date =  Faker::Date.between(from: 1.year.ago, to: 10.days.ago)
=> Tue, 09 Jun 2020
irb(main):002:0> order_date + 15
=> Wed, 24 Jun 2020
irb(main):003:0> 
```

## 生成！
ターミナルで`rails db:seed`すると下記のようにデータが生成されました！↓

![スクリーンショット 2021-04-13 13.10.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/1589d488-e557-1072-4ba7-29a0a55032d1.png)

# 最後に
何かご指摘やもっといい方法などあればぜひ教えてください。
ありがとうございます。
データ構造とアルゴリズム Vol.8

#Vol.8: Counting Sort

Counting Sortの原理を理解し、これをC言語で実現することができます。

#Counting Sortとは？
👌 Counting Sortは大きさを基準にデータ数を数える整列アルゴリズムです。 各データをすぐにサイズを基準に分類するため、O(N)の時間複雑度を持ちます。

#Counting Sort実現
例）実行するコードの例

```C

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MAX_VALUE 10001 //Counting Sortは、データサイズを基準として整列するため、配列のインデックスを超える元素が入力されると整列できません。

int n, m;
int a[MAX_VALUE] //メモリが非常に消耗しているため、大きさの制限が必ず必要です。

int main(){
    scanf("%d", &n);
    for (int i =0; i < n; i++) { scanf("%d", &m); a[m]++; }
    for (int i =0; i < MAX_VALUE; i++) {
        while (a[i] != 0) { printf("%d", i); a[i]--; }
    }
    system("pause");
}

```

🤔 結果は？
`input1->` 5
`input2->` 7 8 9 10 392
`result->` 7 8 9 10 392


#まとめ
📌Counting Sortは、時間複雑度がO(N)の整列アルゴリズムです。
📌Counting Sortは、データのサイズが限定的な時に使用することができます。

📚参考講義：コンピューター工学専攻必須オールインワンパッケージOnline
👆 上記の講義はCとC++を言語を前提に説明しています。
データ構造とアルゴリズム Vol.7

#Vol.7: クイックソート
クイック整列の原理を理解し、これをC言語で実現することができます。

#クイックソートとは？
👌 クイックソートとは、ピボットを基準に、大きな値と小さい値を交換するソート技法です。 
👌 値を交換するのにN 番、異なる場合は、交換した後に元素が半分に分けられるため、全体元素を分割するのに平均的にlog N 番が必要となるため、平均的に O(Nlog N) の時間の複雑さを持ちます。
👌 元素を半分づつに分ける時に、logNの時間の複雑度が出てくる代表的な例は、完全二進ツリーです。 このような完全二進ツリー形態は、コンピュータ工学で最も好む理想的な形態です。

#クイックソートを実現
###例）実行するコードの例
```C
//クソートの配列宣言
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <limits.h>
#define SIZE 5

int a[SIZE] = {9, 8, 1, 7, 4};

int swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

void quickSort(int start, int end) {
    if (start >= end) return;
    int key = start, i = start + 1, j = end, temp;
    while(i <= j) {//ずれるまで繰り返します。
        while (i <= end && a[i] <= a[key]) i++;
        while (j > start && a[j] >= a[key]) j--;
        if(i > j) swap(&a[key], &a[j]);
        else swap(&a[i], &a[j]);
    }
    quickSort(start, j - 1);
    quickSort(j + 1, end);
}

int main(void) {
	quickSort(0, SIZE - 1);
	for (int i = 0; i < SIZE; i++) printf("%d\n", a[i]);
    return 0;
```

🤔 結果は？
`result->` 1 4 7 8 9

まとめ
📌 クイックソートは、偏向した分割が発生した場合の演算の量がO(N^2)です。 そのため、実際に並べ替えを行う場合は、クイック並べ替えを直接実現しません。 代わりにC++のAlgorithmライブラリを使用します。 Algorithmライブラリのsort()関数は、クイックソート基盤とし、O(NlogN)を保障します。
📌 クイックソートは平均的な時間複雑度がO(Nlog N)である最も普遍的な整列アルゴリズムです。

📚参考講義：コンピューター工学専攻必須オールインワンパッケージOnline
👆 上記の講義はCとC++を言語を前提に説明しています。
サーバ内の不要ユーザ追い出し


# きっかけ
EC2で通信が遮断された際にSSHのプロセスが残っているのが気になりやってみました。
ですので、ただの備忘録です:tea:

# TODO

```zsh:クライアント
% ssh hoge-server
```

```bash:サーバ
$ w
 12:00:00 up 1 days,  1:23,  1 user,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
fuga     pts/0    xxxxxxxxxx.a 12:30    4.00s  0.05s  0.00s sshd: fuga [priv] 
hoge     pts/1    xxxxxxxxxx.a 12:50    4.00s  0.05s  0.00s w
$ ps ax | grep sshd
 3336 ?        Ss     0:00 /usr/sbin/sshd -D
22221 ?        Ss     0:00 sshd: fuga [priv]
22223 ?        S      0:00 sshd: fuga@pts/0
22228 ?        Ss     0:00 sshd: hoge [priv]
22229 ?        S      0:00 sshd: hoge@pts/1
$ kill -9 22223
```

## 解説

* <code>w</code>
	* ログインユーザの確認
	* <code>who</code>でも確認可能
* <code>ps ax | grep sshd</code>
	* sshdのプロセスIDを確認
* <code>kill -9</code>
	* プロセス強制終了コマンド

# 参考
https://eng-entrance.com/linux-command-kill
https://www.atmarkit.co.jp/ait/articles/1807/26/news009.html
https://uxmilk.jp/50638