OmniAICreator/Qiita-1.07M huggingface dataset:
DataFrameでmulti columnsをsingle columnに戻す関数

## 関数の機能
このようなmulti columnsのデータフレームを
![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/50ae3b7d-63a5-4c0e-6541-2dbc2ea87a0c.jpeg)

single columnsのデータフレームに変換します。
![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/01d6935f-cedf-94a7-1a2f-ab198d9867b8.jpeg)


## 役に立つシーン
- pythonのmulti columnsをsingle columnになおす。
- mergeするときにmulti columnsはちょっと不便。
- df.groupby("hoge").agg("A":{"sum","mean"]}) で集計した値がmulti columnsになってしまうので、結合するときに使用しました。
- 既存の関数がありそうな気がしたが探しても見つからなかった...有識者の方教えて下さい。


## マルチカラムの参考
- pandasのMultiIndexから任意の行・列を選択、抽出: https://note.nkmk.me/python-pandas-multiindex-indexing/
- pandasのマルチカラムをいい感じに処理するtips: https://qiita.com/tenajima/items/55bb8b5843690d464225

## 実際のコード
``` python:
#dfの1行目、2行目の列名を連結した列名に変換する関数
def rename_multicol(df):
    df_col=df.columns #列名をコピー
    df = df.T.reset_index(drop=False).T #一回列名をリセット
    for  i in range(df.shape[1]): #列名を新たに定義
        rename_col = {i:"".join(df_col[i])}
        df = df.rename(columns = rename_col)     
    df = df.drop(["level_0","level_1"],axis=0)
    return df
```
実際にこの関数を使った例がこちら。

``` python:
company_list =["A","B","C","D","E","F","G"]
pref_list = ["東京","沖縄", "東京", "神奈川", "神奈川", "東京", "沖縄"]
num_list = [10,3,6,4,5,7,2]

df = pd.DataFrame({"会社名":company_list,
                   "都道府県":pref_list,
                   "人数":num_list})

#人数の合計と平均を計算
number_df = df.groupby("都道府県",as_index=False).agg({"人数":["sum","mean"]})

#シングルカラムに変換する
number_df_rename = rename_multicol(number_df)
```

dfから都道府県ごとの人数の合計と平均を集計したいとします。
'df.groupby("都道府県",as_index=False).agg({"人数":["sum","mean"]})'で同時に集計かのうです。
![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/a36b55db-0aa4-ee93-5ddd-cc4d19a29bf1.jpeg)

集計後のnumber_df。人数とsum,meanがmulti columnsになっている。
![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/e67bfa6c-5188-4075-6e11-234f84be169f.jpeg)

rename_multicolの関数をつかってsingle columnsに変換したnumber_df_rename。
これで都道府県をkeyとして別のdataframeと結合できます。
![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533584/876235bf-b5f0-da94-8081-d77755930bc5.jpeg)

## 終わりに
そもそもmulticolumnsっていうのも知らずに「複数列 解除」とかで検索してました...。
テーブル単体でいうと便利ですけど結合を考えると取りあつかいずらかったです。
【C#】テキストファイルを任意の行を読み込む


##自己紹介
こんにちは。tetraです。
最近C#の学習を始めました。C#歴3ヶ月目の新卒エンジニアです。
任意の行で表示したくてもテキストファイルを上から順に読む処理が出てムカついたので新しく作成します。

##ファイル読み込み
さっそく書いていきます。
１行目を出力しています。

```sample.cs
using System;
using System.IO;
using System.Linq;

class sample
{
    static void Main()
    {
        // skipのパラメーターをいじると任意の行を指定できる
        int n = 0;
        string line = File.ReadLines("./sample.txt").Skip(n).First();
        Console.WriteLine(line);
    }
}
```




##いかがでしょうか？
いかがでしょうか。経験が浅いため至らぬところがまだまだあります。
もし間違い等に気がつきましたら、コメント又は[tetra](https://twitter.com/_T_E_T_R_A_)までお知らせください。
MacのVisual Studio Codeが日本語化しなくなって、再インストールしても治らない場合の対処

# はじめに
MacのVisual Studio Codeが急に英語表示になり、Visual Studio Codeを再インストールしても日本語化できなかったときの対処です。
こちらの<a href="https://daeudaeu.com/programming/python/development-environment/visual-studio-code-%E3%81%AE-mac-%E3%81%8B%E3%82%89%E3%81%AE%E3%82%A2%E3%83%B3%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/" target="_blank">Visual Studio Code の Mac からのアンインストール
</a>を試した後、**Japanese Language Pack for Visual Studio Code**拡張をインストールし、コマンドパレットの**>Configure Display Language**からjaを選択し、再起動しても言語が英語のままで困っている人は、この対処が使えると思います。

# Visual Studio Codeのアンインストール
アプリケーションフォルダのVisual Studio Codeを削除し、上記の<a href="https://daeudaeu.com/programming/python/development-environment/visual-studio-code-%E3%81%AE-mac-%E3%81%8B%E3%82%89%E3%81%AE%E3%82%A2%E3%83%B3%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/" target="_blank">Visual Studio Code の Mac からのアンインストール
</a>を行ます。

# Application SupportからCodeの削除
ターミナルから、Library/Application Supportを開きます。

```
cd Library/Application\ Support/
```

Application Supportの中の`Code`を削除します。

```
sudo rm -rf Code
```

# Visual Studio Codeの再インストール
Visual Studio Codeをインストールし、日本語拡張を入れ、コマンドパレットから、Display Languageをenからjpに変更します。再起動後、Visual Studio Codeの言語設定が日本語になっていることを確認します。
Windows Server 2019 Hyper-V を HP Z800 にインストールする

Windows Server 2019 Hyper-V を HP Z800 にインストールする手順です。

# 構成

* Windows Server 2019 Hyper-V
* HP Z800 WorkStation


# 手順
インストールISOからインストールUSBメモリを作成し、USBメモリからWindowsインストーラーを起動します。

## ISOダウンロードとUSBメモリ作成
RufusでUSBメモリ作った。

## インストール

1. F9でBootSelect画面に行き、USB Storageを選択します
1. 画面の指示に従ってインストールを行います

## Windows Admin Centerインストール
Windows Server 2019 Hyper-V にはGUIが無く、リモートデスクトップを行っても表示されるのはコマンドプロンプトだけです。
GUIの管理画面としてWindows Admin Centerをインストールします。

>Windows Admin Center は、追加コストなしで使用できる Windows Server 用リモート管理ツールです。物理、仮想、オンプレミス、Azure、ホスティングといった、Windows Server を実行できるあらゆる環境に対応します。
https://www.microsoft.com/ja-jp/windows-server/windows-admin-center


[How to install and configure Windows Admin Center on Windows Server Core [part1]](https://www.markou.me/2019/09/how-to-install-and-configure-windows-admin-center-on-windows-server-core-part1/)に記載の手順通り実施する。

```
New-Item -Path C:\Downloads -ItemType directory
wget "http://aka.ms/WACDownload" -outfile "C:\Downloads\WindowsAdminCenterCurrent.msi"
cd C:\Downloads ; msiexec /i WindowsAdminCenterCurrent.msi /qn /L*v log.txt SME_PORT=443 SSL_CERTIFICATE_OPTION=generate
```

## Hyper-V
AdminCenterからはHyer-Vのコンソールが見えないので、次のURLにある手順にしたがっての設定を行う。
[Hyper-V マネージャーで資格情報を指定して Hyper-V に接続する](https://www.vwnet.jp/Windows/WS16TP2/HVMan/Credential.htm)



```
Unhandled Promise rejection: RPC: 'msft.sme.hyperv:virtualMachines#1590830391921+3' から 'msft.sme.shell:##' への送信の期限が切れました
 'Log/0'。 ; Zone: <root> ; Task: setTimeout ; Value: RPC: 'msft.sme.hyperv:virtualMachines#1590830391921+3' から 'msft.sme.shell:##' への送信の期限が切れました 'Log/0'。 undefined
```
safe Rust でスタックオーバーフローする方法

safe Rust は安全な言語と言われますが, 残念ながらスタックオーバーフローをコンパイル時に検出し防ぐことはできません. あるコードがスタックオーバーフローを起こすかどうかは環境に依存する話なので当然といえば当然ですが. 

# 大きなデータを持つ

スタックサイズは OS 等にもよりますが数 MB 程度なので, それより大きな array をスタックに確保しようとすれば一発でオーバーフローします.

```rust
fn main() {
    let _ = [ 0f64; 4_000_000 ];
}
```

解決策: 大きなデータはヒープに持つようにする.


# 関数の再帰呼び出し

スタックオーバーフローの一番多いと思われるパターンは関数の再帰呼び出しです. が, rustc は関数の再帰呼び出しが終了しないことに気づくと警告を出してくれます. 

```rust
fn main() {
    fn tmp() -> i32 { tmp() }

    tmp();
}
```

これをコンパイルすると `function cannot return without recursing` というメッセージとともに警告が表示されます. が, コンパイル自体は成功してバイナリを実行するとスタックオーバーフローします.

ただ, これよりちょっとだけ複雑な再帰呼び出しではコンパイラが気づかないこともあります.

```rust
fn main() {
    fn a() -> i32 { b() }
    fn b() -> i32 { a() }

    a();
}
```

また, 再帰は理論上終了するものの, 終了するまでに必要な関数の呼び出し回数が多すぎるためスタックオーバーフローする, というケースもあります. これは末尾最適化により解決する可能性があります.

解決策: 設計ミスなので見直す. または末尾再帰最適化をする.


# 参考文献

* [スタックオーバーフロー - Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B9%E3%82%BF%E3%83%83%E3%82%AF%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%83%95%E3%83%AD%E3%83%BC)
tkinterで簡単なファイル選択アプリケーション

#tkinterで簡単なファイル選択アプリケーション

##選択したファイルをタプル形式で返します．

```Python:FileChoice.py
import os
from tkinter import Tk
from tkinter import StringVar
from tkinter import LEFT
from tkinter import ttk
from tkinter import filedialog
from tkinter import messagebox

def App():
    # 参照ボタンのイベント
    # button1クリック時の処理
    def button1_clicked():
        fTyp = [("",".csv")]
        iDir = os.path.abspath(os.getcwd())
        filepath = filedialog.askopenfilenames(filetypes = fTyp,initialdir = iDir)
        file1.set(filepath)

    # button2クリック時の処理
    def button2_clicked():
        messagebox.showinfo('FileReference Tool', u'Reference Files ↓↓\n' + file1.get())
        print(file1.get())
    #Exit時の処理
    def on_closing():
        if messagebox.askokcancel("Quit", "Do you want to quit?"):
            root.destroy()

    # rootの作成
    root = Tk()
    root.title('FileReference Tool')
    root.resizable(False, False)

    # Frame1の作成
    frame1 = ttk.Frame(root, padding=10)
    frame1.grid()

    # 参照ボタンの作成
    button1 = ttk.Button(root, text=u'Reference', command=button1_clicked)
    button1.grid(row=0, column=3)

    # ラベルの作成
    # 「ファイル」ラベルの作成
    s = StringVar()
    s.set('ファイル>>')
    label1 = ttk.Label(frame1, textvariable=s)
    label1.grid(row=0, column=0)

    # 参照ファイルパス表示ラベルの作成
    file1 = StringVar()
    file1_entry = ttk.Entry(frame1, textvariable=file1, width=50)
    file1_entry.grid(row=0, column=2)

    # Frame2の作成
    frame2 = ttk.Frame(root, padding=(0,5))
    frame2.grid(row=1)

    # 参照確認の作成
    button2 = ttk.Button(frame2, text='Check', command=button2_clicked)
    button2.pack(side=LEFT)

    # Exitボタンの作成
    button3 = ttk.Button(frame2, text='Exit', command=on_closing)
    button3.pack(side=LEFT)
    #return file1
    
    root.mainloop()

    return eval(file1.get())
```

```Python:Running
fileparh = App()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/886510d0-2f20-5614-d2f2-c5322fcc5976.png)
Reference ---エクスプローラーを開きファイルを選択します
Check--------Referenceで選択したファイルを確認します
Exit---------アプリケーションを閉じます

```Python:Running
print(filepath)
# 結果)選択したファイルがタプル形式で返されます
```

もっとクールで早くなる書き方があったら訂正するのでご指摘ください！
【AWS SAP】S3エトセトラ【頻出】

##S3にまつわるエトセトラ
AWS SAP取得にあたり、憶えて良かったエトセトラをまとめる。

##EC2とS3とCloudFrontと

例えば、
WEBサーバとしてEC2を利用。
静的コンテンツをS3で提供。
静的コンテンツへのアクセスが集中するたびにHTTPエラーが発生。
といったケースがあるとする。

そんな時に回避策として利用すると良いのが、CloudFront。(CDN)
CloudFrontで静的コンテンツをキャッシュすることでS3の負荷を軽減し、アクセス集中に対応。

##S3に個人情報を保存する
S3に個人情報を保存するのはいいが、安全性が不安。通信は暗号化したい場合にどうするか。

大丈夫です。S3の通信はデフォルトでSSL暗号化されます。

##S3の保存期間
S3のライフサイクルで、有効期限を決めることで保存したデータを任意の期間保管したら削除といったことができる。

追加で、任意の期間経過したらデータをGLACIERに移行するといったこともできる。

利用イメージとしては、
・ログ保存のためにS3を利用する。
・半年間のログは頻繁に利用するが、半年以上経過したログはほとんど利用しない。
・ただ、半年以上経過したログも保管しておきたい。
・コストは最小限に抑えたい。

そんなときは、S3のライフサイクルを利用して、半年経過したらGLACIERに移行する。

※GLACIERはS3に比べると安価だが、データ取り出しに時間がかかる。

すぐに使わないよーというデータを保管しておく分には問題ない。
アウトプット勉強。第0回

#自己紹介
初めまして！
未経験から第二新卒(当時23歳)でこの業界に飛び込み現在インフラエンジニアとして3年目に突入しました。
現在はネットワークのオンプレ運用を中心にエンジニアとして揉まれる日々を過ごしています。

保有する資格
CCNP
LinuC 2
VBA basic
ITパスポート
TOEIC 780


##この二年間の経歴
未経験でこの業界に入り、最初は24H365Dの監視現場に配属されました。そこでITエンジニアの洗礼とでもいうのでしょうか？
職人気質な先輩に怒られ、なじられ、かつこのままずっとここにいるのは嫌だと思い、必死にLinuC201を取得し、CCENT(※1)を勉強し、前向きな姿勢が認められて、日勤のNW運用現場へ異動となりました。そこから約1年半、日々勉強し資格を取得し**とにかく早く実力をつける！**このマインド一本でがむしゃらに頑張りました。その頑張りが実を結び入社して1年半後、構築現場へキャリアアップを果たしました!!
しかし。。。。。

※1 CCENT 
現在のCCNAより前に存在した資格。旧CCNAはCCENT(100-105J)とCCNA(200-105J)の２つを取得するか、範囲がとてつもなく広いCCNA(200-125J)試験を突破しなければ、正式にCCNAホルダーとして認定されませんでした。
初めて黒本を購入した人は、英単語ターゲットよりも分厚い、あの試験範囲の広さに絶望感を味わった方も多いはず。。

#なぜブログを始めようと思ったのか??

今までの考え方(資格＝実力)
資格も持ってるし、知識もあるんだから構築でもすぐに戦力になるだろうと自信をもって現場に配属されましたが、何故か知識はあっても仕事に活かすことができず
挙げ句の果て、知っているはずの知識もリーダーに怒られて思い出す羽目に、、
　　
**あれ、、、あんなに勉強したのになんで資格の知識がすぐに活用できていないのか。。。？**
　　　
いままでテストでは勉強したことが頭の引き出しから引っ張ってこれたけど
なんで実務では通用しないのか？この時はまだ
・もしかしたら、まだまだ現場で求められている知識が足りないのかな・・？
・前の現場と違ってAWSなどクラウドの用語も設計書に乗ってるしな。。
　よし！クラウドの免許も取得してもっと知識を増やすぞ！
つまり勉強し、知識を増やし資格を取得さえすれば何とかなると考えていました。。

##気が付いたらまた資格取得に走り、同じ過ちをすると気が付いた
"Amazon Web Services パターン別構築・運用ガイド "(通称オレンジ本)を購入し、早速クラムメディアを契約し、2ヶ月でAWS SAA取ろう！と意気込みました。。　　　
しかし問題の答えや知識が増えていくにつれて思いました。
**あ、、、俺また目先の資格に頼ってるかも、、そもそも苦労して暗記してCCNPとってそこからクラウドにも適応すれば市場価値を上げられるって考えたけど、これじゃまた同じこと引き起こすかも、、、**

#再発防止として暗記中心でなくアウトプット勉強法に切り替える
と、そこで初めて気が付きました。
####持っている資格数や保有資格の難易度＝市場価値じゃないんだな。。
でも、今までping-tを覚えて乗り切る勉強が中心だったし、どうすればいいのかな、、と
その時、会社にエンジニアメンター制度がありブログを発信してアウトプットしている方がメンターとして支援する制度を見つけました。
勉強したことを発信することで、自分の言葉で理解し、かつ他人にも情報を提示するからこそ責任が伴う。
このアウトプット勉強法を今後は取り込んで、ネットワークでの教訓を絶対に活かすぞ！と誓いました。

#今後どのような感じで情報発信していくのか

月3回を目標にインフラ関係の内容でブログをアップしていきます。

#次回予告
記念すべき技術ブログの第一回目は現在ネットワークの現場にいるので関連した技術のVPCを中心に記事をアップする予定です
Git「マージする前に、変更をコミットするか、それらを隠してください」と出たら...

チーム開発をしていて、Macのターミナルに

**error: Your local changes to the following files would be overwritten by merge: Please commit your changes or stash them before you merge.**

と出たので、対処してみた。

##エラーが起きたタイミング

チームで開発しているので、まず

```
$ cd checkout master
```

でMacのターミナルにて、マスターへ移動。

次にチーム開発で使っているGithubより

```
$ git pull origin master
```

でmasterブランチを最新に更新。そこでエラー文が登場！

```
error: Your local changes to the following files would be overwritten by merge:
	//ここは関係するファイル名が表示される
Please commit your changes or stash them before you merge.
```

何でだろうと考えつつ、対処法をまとめてみました。

##対処法

エラー文をそのまま、グーグル翻訳してみると、以下のようになりますね。

>エラー：次のファイルに対するローカルの変更はマージによって上書きされます：マージする前に、変更をコミットするか、それらを隠してください。

ふむふむ。

コンフリクト、つまり「競合」「衝突」となっているみたい。

対処法として

- 対象ファイルを削除する
- 指摘されたファイルを退避させる
- 強制的にマージさせる

という方法があるようです。

私としては「削除」でもいいかなと思ったのですが、初心者ゆえに不安もあったため、二番目の「一時退避」を選びました。

```
$ git stash
```
これで、現在の作業を一時退避させます。stashというコマンドで。

コンフリクトがなくなったと思うので、再度以下のコマンドです。

```
git pull origin master
```

はい、エラー文がなくなりました！
わーい！

##まとめ

初学者の場合、エラーが出ると恐怖に陥りますよね...

でも嬉しいことに、先駆者がエラーが出た時の対処法をまとめてWeb上に投稿してくださっています。感謝でしかないですね。

今回ご紹介した方法以外に、良い対処法があるかと思いますので、どうぞご教授ください。


>【参考にさせていただいたサイト】
[本番環境でpullしたらコンフリクト？解決法３パターン！【Please commit your changes or stash them before you merge】](https://qiita.com/15grmr/items/433ee3b47828aaad32a8)
コードやアイディアの個人的な保存と再利用を支援してもらうサービス： 結局どれがベストか？


teratailの次の記事を見て考えたことを書き残しておきます。

* [自分で書いたコードを蓄積するための仕組み作り](https://teratail.com/questions/256854)

これまでいろいろなツールやサービスを試してみましたが、全面的に完璧な手法はないですね。以下、あくまで個人的な印象です。

* **Evernote** --
 メモ帳/スクラップブックとしてアイディアをテキストとして蓄えておくにはそれなりに使える。コードの再利用という点では特段の旨味は見当たらない。
* **Dropbox** -- 
 いろいろ放り込んでおいて複数のマシン間でやり取りするのは便利だけど、容量制限が面倒。カネを払って制限を撤廃するまでのメリットがあるかと言うと…。
* **Google Drive** --
 データ共有の面の使い勝手はdropboxとだいたい同じ。容量制限がgmailと共有なのでメールが溜まってくると保存用の空きも無くなっていく。スプレッドシートなどgoogleアプリとの親和性は良くて便利だが、表記の課題に関しては可もなく不可もなくといったところか。
* **GitHub** -- 
よくもわるくもコードの保存と共有に特化したサービス。gitコマンドで更新できるシステムは、馴染めればこの上もなく便利だろうとは思うが、私個人は限定的にしか使いこなせていない。ここは異論があるだろうけど、都度コミットしない情報は管理できないので、思いつき情報の保存と再利用という点では使いやすいとは感じられない。複数人のプロジェクトならともかく、個人で完結しているプロジェクトではそこまでのアドバンテージはないのでは。

どのツールにも今ひとつ物足りないところがあるのが実情で、かといってそれを埋めようと補助ツールを用意したりいろいろプロトコールを考えても、結局自分の中でそれが馴染むことはまれでした。だいたい、そうした「工夫」に時間を取られる事自体なにか本末転倒な印象が拭えませんね。

# で？ 結論は？

私自身が結局どうしているかといえば、次の２つに集約されました。

## Gmailで「保存」

* 広く応用できそうなコーディング上のtipsや有用なウェブサイトの情報など、これはという情報はとりあえず**自分のgmailアドレスに向けてメールする**。

あとで情報を探す作業は、gmailの背後に控えるgoogle先生が手伝ってくれるので安心です。

## 日付をつけてプロジェクトごとにローカルに保存

* あるプロジェクトの内容に深く関わる情報やコードは「その場から動かさない」。

試行錯誤の痕跡、捨てたコードやデバッグ用の使い捨て補助スクリプトや検算用データや、それら一切とともに丸ごと保存用HDDに保全しておく。

あまりに普通すぎて、わざわざqiitaで紹介するほどのことかと言われそう。しかし、長年の試行錯誤の結論はこれだと言わざるを得ません。

「この貴重な情報はとっとこう」と思って、下手に「特別な場所」に集めて保存しようとしないことです。それはたいていうまく行きません。なぜかというと、「特別な場所」に移した瞬間、そのメモなりコードなりの背景情報との関係が切れてしまうのです。

タグ付け？ 役に立ちません。そのときに良いと思った「タグ」は１週間後の自分が連想する「適切なタグ」とはまず一致しません。

ただ、その情報には必ず「日付」をつけておくことが重要。最終的に「タグ」の代わりになる唯一信頼できる手がかりとして、日付以上のものはありません。日付さえついていれば、結構記憶を辿って当時の思考を再生できるものです。

これを念頭に、コマンドラインですぐできる作業もできるだけスクリプトファイル化してスクリプトファイルを通して実行するよう日頃から心がけておきます。このスクリプトファイル以上に信頼できるログはありません。また、類似の作業を後日改めて行いたいとなったとき、そこからサルベージしてコードを書くことができます。結局これが一番直接的で時間が無駄にならないようです。

我ながらすごくつまらない結論だな。ここまで読んでくれた皆様、申し訳ない。
MacでCUDAが使えなくなることを誰も不満に思ってないの？

https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#title-new-features

家で機械学習やる人は自作してUbuntu使うのかな。

業務で機械学習やる人はGoogleやAmazonに金を積むのかな

研究室では大学のスパコンや研究室のサーバー使うのかな。



50万ぐらい払ってもいいからMacで機械学習したい人っていると思うんだけどなぁ。
JavaによるWebアプリケーション構造とプレゼンテーション層における処理の流れ

##はじめに
新入社員研修において、Javaを用いたWebアプリケーションの開発を行ったので、そこで学んだことを簡単にまとめていきたいと思います。
間違い等も多くあると思いますので、ご指摘してくださると嬉しいです。

Webアプリケーションのサーバーサイドにおける処理の流れを中心に取り上げていきます。想定しているサンプルとしては、簡単な１件検索のサンプルになります。

##サーバ間のやりとり
動的なWebページを実装する場合のクライアントとサーバー間における動的な情報のやりとりについて簡単に説明します。

まず、クライアントからWebサーバーにリクエストを送信します。このクライアントとWebサーバー間の送受信はHTTPプロトコルによって行われております。動的なWebページを表示する場合、Webサーバー側で何らかの処理(プログラム)を行う必要があります。その処理がWebアプリケーションであり、それをJavaやPHPなどのサーバーサイド言語で実装していくことになります。
今回はJavaでの実装を想定としています。

そのアプリケーションを実行するためには、Webサーバーとは別にアプリケーションサーバーを用意する必要があります。
( JavaのアプリケーションサーバーではTomcatが有名です。)
アプリケーションサーバーも、クライアントとWebサーバーの送受信と同様に、Webアプリケーションと送受信を行うには、あるプロトコルが必要になります。上記のようにアプリケーションサーバーにはTomcatを使用して、WebサーバーにはApatchを使用する場合、Apatchにmod_jkという連携用モジュールを拡張機能として実装します。
そのmod_jkのajp13というプロトコルを使用してアプリケーションサーバーとWebサーバーは送受信を行うことができます。
Tomcatは簡易的なWebサーバーを保有しているため、特に連携しなくても送受信は可能です。

##Webアプリケーションの構造
では、そのサーバーサイドでどのようにWebアプリケーションが処理されているのかを見ていきます。

WebアプリケーションはMVCアーキテクチャをモデルとして設計されており、大きく分けて次の３つの階層に分けて設計されています。

・プレゼンテーション層
・ビジネス層
・インテグレーション層

それぞれの層に含まれるプログラムの役割は明確に分けられています。

次に、クライアントからのリクエスト情報を元にどのように処理がなされているのかを記します。

###サーバーサイドにおけるアプリケーションの処理の流れ

<img width="948" alt="スクリーンショット 2020-06-04 20.05.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/644352/0fd9375e-9ece-1eff-6f0a-dab44d399e43.png">

リクエスト情報は、まずFrontControllerに渡されます。このFrontControllerはサーブレットであり、Webアプリケーションの処理を一元管理しています。

そのFrontControllerはリクエスト情報に応じて処理を振り分けます。(switch-case文が有効)
その中でActionを呼び出し、そのActionが入力値のチェックやセッション管理(セッションオブジェクトの生成や解放)、ビジネス層の業務Logicへの処理依頼を行います。
（余談ですが、セッション管理ではサーバリソースを有効に活用するために一定時間アクセスが途絶えたらセッションを無効化するなど、出来るだけ早く解放するほうが良いそうです）

そして、肝となる業務Logicでは業務処理を制御します。
業務処理に必要な情報は、データベースへのアクセスによって取得します。
データベースへアクセスするためにはConnectionManagerを用います。具体的には、ConnectionManagerのgetConnectionメソッドを用いてConnectionオブジェクト(データベースへの接続)を取得します。

そのConnectionオブジェクトをDAOのコンストラクタの引数に渡して、DAOオブジェクトを生成します。
そして、DAOのメソッドを呼び出し、Entityを用いて戻り値を受け取ります。

`DAO内の戻り値の設定処理方法(１件検索の場合)`
`while(res.next())で検索結果がある場合に{}内の処理を行う。{}内ではres.get~を用いて戻り値を設定する`

業務LogicがEntityのオブジェクトを受けとった後、定義したオブジェクトに格納し、戻り値に設定します。

Actionにおいて業務Logicを生成し、メソッドを呼び出します。その結果をスコープなどに設定します。
戻り値としては遷移ページ先を設定します。

FrontControllerにおいてActionから遷移ページ先を受け取り、フォワードします。



##プレゼンテーション層におけるアプリケーションの動作

###サーブレットとJSP
Webページを表示するHTMLファイルを生成するためにはサーブレットというプログラムが必要になります。サーブレットはTomcatなどのWebアプリケーションサーバーによって実行されます。

このサーブレット単体でもWebページは表示させることは可能なのですが、プログラムの記述が煩雑になってしまい、綺麗なプログラムではなくなってしまうので、HTMLにJavaコードを埋め込んだJSPにWebページの表示を依頼することになります。

また、Webページを遷移させていくためには、クライアントが送信したリクエストにパラメータを付加させる必要があります。
そのリクエストの送信方法としてはGETとPOSTの二種類があります。

###GETとPOST
GETとPOSTのどちらの方法でも、任意の値をパラメータとして設定する必要があります。

GETオペレーションでは、パラメータに設定した任意の値がURLに組み込まれる形でWebサーバーに送信されます。
ゆえに、Webページを再度閲覧したいという場合は簡単にアクセスすることができます。
つまり、ブックマークはパラメータごとに保存がされているという状況になります。
デメリットとしてはパラメータの長さに制限があることや、上記のようにセキュリティ面が低いことが挙げられます。

一方、POSTオペレーションはパラメータに設定した任意の値はURLに組み込まれず、リクエストのメッセージボディに格納される形でWebサーバーに送信されます。
ゆえに、セキュリティ面ではGETオペレーションより高いです。また、パラメータの長さにも制限がなく、大量のデータを送信することができます。

アプリケーションでの処理ではユーザー定義サーブレットで、HttpServletにおいて定義されているdoGetメソッドとdoPostメソッドをオーバーライドする形で記述します。そのことによりHTTPの機能を使用することができます。

##まとめ
今回はサーバーサイドにおけるWebアプリケーションの動作についてとプレゼンテーション層におけるアプリケーションの動作について簡単に解説しました。
これ以上は長くなってしまうので、ビジネス層とインテグレーション層に関しては別記事で解説できたらと思います。
HashMap の値を取り出し，value の値でソートした結果をリストで返す

javaでMap（HashMap）をvalueを使ってソートする際のやり方をまとめておきます．
ここでは，B_arrayを使ってA_arrayの値も同時にソートしたい状況を考えています．
HashMapのentry型を持つリストをソートする形なので，TreeMapなど，他のMapでも使えます．


#####コード

```java:Solution.java
import java.util.*;

class Solution {
    public static void main(String[] args) {
        int[] A_array = {1,6,3,10,5};
        int[] B_array = {8,21,13,4,5};
        tryComperator(A_array, B_array);
    }
    public static void tryComperator(int[] a, int[] b){
        Map<Integer, Integer> map = new HashMap<Integer, Integer>();
        //配列の要素をhashmapに格納．
        for (int i = 0; i < a.length; i++){
            map.put(a[i], b[i]);
        }
        //Hashmapの各要素をリストに格納．
        List<Map.Entry> mapValuesList = new ArrayList<Map.Entry>(map.entrySet());
        //mapValuesList を出力してみる．(10=4 のような形で出力されるらしい．)
        for (Map.Entry v: mapValuesList){
            System.out.println("map>> "+v+",key>> "+v.getKey()+"value>> "+v.getValue());
        }
        //Comparatorクラスをインスタンス化
        Comparator<Map.Entry> comparator = new Comparator<Map.Entry>() {
            public int compare(Map.Entry entry1, Map.Entry entry2) {
                return ((Integer) entry1.getValue()).compareTo((Integer) entry2.getValue());
            }
        };
        //comparator を使ってソートする．
        Collections.sort(mapValuesList, comparator);
        //確認のための出力
        for (Map.Entry s : mapValuesList) {
            System.out.println(s);
        }
    }
}
```

#####出力

```
map>> 1=8,key>> 1value>> 8
map>> 3=13,key>> 3value>> 13
map>> 5=5,key>> 5value>> 5
map>> 6=21,key>> 6value>> 21
map>> 10=4,key>> 10value>> 4
10=4
5=5
1=8
3=13
6=21
```

valueの昇順に出力されました．


参考: http://kevin3sei.blog95.fc2.com/blog-entry-159.html
docmute で簡単にTeX を分割


自分で書いた記事を簡略に書いただけという記事です．

> [分割TeX ファイルをdocmute を用いて単体/統合 コンパイルする - Qiita](https://qiita.com/Yarakashi_Kikohshi/items/b3a84f23022393208aab)

# ○ `docmute` の仕様

- 子ファイルの`\begin{document}` から`\end{documetn}` の間を`\input{file name}` で挿入することが出来る．（プリアンブルは無視される）

- 子ファイルは同じフォルダにある必要がある．

# ○ 親ファイルと子ファイルの取り込むパッケージ

どちらも同じパッケージを取り込んでいるのが望ましい．これらのパッケージをまとめて`texファイル` に保存し`\input{hoge}` しても良いが，プロジェクトごとに同じパッケージをまとめた`texファイル` をそれぞれのフォルダに入れておく必要が出てくる．

それを避けるために`styファイル` にしておき，`\usepackage{hoge}` にする．これをTeX ツリーのローカルに保存することで，どのプロジェクトでも同じパッケージを使うことが出来る．

# ○ 親ファイルの例

`mypackage.sty` には必要なパッケージが入っている．

````tex:master.tex
\documentclass[a4paper,10pt,uplatex]{jsarticle}
\usepackage{docmute}
\usepackage{mypackage}
\begin{document}
    \input{MainBody1}
    \input{MainBody2}
    \input{MainBody3}
    ...
    \input{MainBodyN}
\end{document}
````

# ○ 子ファイルの例

````tex:MainBody1.tex
\documentclass[a4paper,10pt,uplatex]{jsarticle}
\usepackage{mypackage}
\begin{document}
    hogehogehogehoge
\end{document}
````

子ファイルには行番号を表示するパッケージなど，編集段階では欲しいけれど提出段階では必要のないパッケージを含んでコンパイルすることが出来る．

# ○ メリット

1. 子ファイルを単独でコンパイルすることもできる．
2. プリアンブルの内容を子ファイルと親ファイルで少しだけ変更することが出来る．
3. パッケージをプロジェクトの外に出しているため，複数のプロジェクトに対して対応することが出来る．

これは，パッケージを`\input` で取り込んだり，`subfiles.sty` を用いたりすることでは出来ないだろう．
【メモ】はじめてSpringBootでSpockを書いたとき

# はじめに
現場でSpockを書く機会があったが？？？になった為
ざっくり流れだけ書く


# テストするサンプルソース

```java:ServiceImpl
public String send(Stiring to, String hash) {
        String url = "https://test" + "/send/" + hash;
        String strBody = createBody(url);
        return sendMail(to, strBody, hash);
    }
```
メールを送信するメソッド
urlを作成
メール本文を作成
宛先と本文とハッシュをがっちゃんこしてメールを送信している
returnで文字列を返す

# テストするソースコードを理解する
このクラスは何をしているのか
どんなメソッドがあるのかざっくり理解しておく
後でがっつりソースコードとにらめっこすると思うのでここでウォーミングアップも兼ねて

# メソッドごとにテストコード書いていく
だいたい登場するのが
setup:
when:
then:
where:
この4つ

```groovy:ServiceImplTest
package demo;

import demo

@RunWith(Sputnik.class)
class ServiceImplTest extends Specification {

    def setup() {
        Service service
    }

    @Unroll
    def "正常テスト1"() {
        setup:
        service = (ServiceImpl) Spy(ServiceImpl.class, constructorArgs: [test1])
        service.createBody(_ as String) >> "dummyBody"
        service.sendMaiil(_ as String, _ as String, _ as String) >> "test"

        when:
        String testString = service.send(to, hash)

        then:
        testString == "test"

        where:
        testcase   | to          | hash
        "testCode" | "aaa@co.jp" | "testhash"

    }
}
```


# when
まずはじめに書くのは`when:`
`service.send(to, hash)`を本実装と同じように実装する
ただtoとhashには事前に文字列が必要なので用意しておく※`where:`参照

実行後にreturnで文字列を返すため`testString`という変数に格納

※`where:`の使い方は他にもあるためこれは一例

**ここではメソッドを実行するだけ**
と覚えておく

# then
次に`then:`に着目
testString == "test"
`testString`の変数には文字列のtestが入ってるよね？の確認
**実行結果を検証する**

# setup
最後に`setup:`を実装していく
when: then: where:でテストの**入口**と**出口**を作成した
あとは中身の実装を偽装実装？していくだけ
サンプルソースのsendクラスには2つのメソッドが呼び出されている
それをMock化していく※詳しくはMock・Spyで調べてください
`createBody(url)`
`sendMail(to, strBody, hash)`


そして `>> "dummyBody"`のように本番同様か、都合の良い結果を自分で書いてしまいましょう
`_ as XXXX`と記載すればやり過ごしてくれます。引数がないとエラーを起こすから
とりあえず何か入ってるてことにしといてくれる

※`_ as XXXX`と記載しないとMock化しないので引数などは入れないでください
前まではtoを`service.createBody(to)`といれてて動作しなかった
Intellijだと`_ as XXXX`のXXXXを勝手に保管してくれるから便利

**自身のメソッドのみの試験を行いため、他のクラス、メソッドを呼び出しにいかないように偽装する**
不可能な場合もたくさんあるのでその時は適宜現場の人と相談していく

# おわり
だいたいの流れはこんな感じ
技術的というかどこからやればいいか
手も足もでない状態のときはこうしてコツを掴んでいった。
follow_redirect!って何をfollowしてるの?: Railsチュートリアル備忘録 - 7章

ユーザー登録作成時のテストを書いております

```ruby:/sample_app/test/integration/users_signup_test.rb
require 'test_helper'

class UsersSignupTest < ActionDispatch::IntegrationTest
.
.
.

  test "valid signup information" do
    get signup_path
    assert_difference 'User.count', 1 do
      post users_path, params: { user: { name:  "Example User",
                                         email: "user@example.com",
                                         password:              "password",
                                         password_confirmation: "password" } }
    end
    follow_redirect!
    assert_template 'users/show'
  end
```

`follow_redirect!`とはなんぞ!

>このメソッドは、POSTリクエストを送信した結果を見て、指定されたリダイレクト先に移動するメソッドです。(Railsチュートリアル)

なんとなく挙動は想像できる

##わからないこと
指定されたリダイレクト先ってなんぞ?

##検証
このままテストを実行してみると
`rails test` > Green

`post users_path`に対応するコントローラーの挙動を参照すると

```rails:/sample_app/app/controllers/users_controller.rb
.
.
.
  def create
    @user = User.new(user_params)
    if @user.save
      flash[:success] = "Welcome to the Sample App!"
      redirect_to @user
    else
      render 'new'
    end
  end

```
この中の`redirect_to @user` > `redirect_to root_path`に変更してみると

`rails test` > Red

```
 FAIL["test_valid_signup_information", #<Minitest::Reporters::Suite:0x000055e3f2c61b10 @name="UsersSignupTest">, 1.4677946789997804]
 test_valid_signup_information#UsersSignupTest (1.47s)
        expecting <"users/show"> but rendering with <["static_pages/home", 
...
```

リダイレクト先が"static_pages/home"になってるよと

##結論
`follow_redirect!`は、
"POSTリクエストを送信した結果を見て"、
つまり対応するコントローラ内で明示されたリダイレクトの挙動に従っているようだ
C# 値型(boolとchar)

##bool

bool型キーワードは**ブール値(true、false）**を表す。
**.NET System.Boolean構造体のエイリアス**です。

bool型の値を使って論理演算を実行するには、ブール論理演算子を使用。
bool型は比較及び、等値演算子の結果の型。
bool式は、if,do,while及びforステートメント及び条件演算子?:で制御条件式にすることが出来る。

**bool型の既定値はfalse**です。

**リテラル**
true 及び falseリテラルを使用して、bool変数を初期化したり、bool血を渡したりすることが出来る。

```

C#
bool check = true;
Console.WriteLine(check ? "Checked" : "Not checked"); // output: Checked

Console.WriteLine(false ? "Checked" : "Not checked"); // output: Not checked

```

**3値ブール型ロジック**
3値ロジックをサポートする必要がある場合は、NULL許容型のbool？を使用。
例えば、3値ブール型をサポートするデータベースを操作する場合など。
bool?オペランドの場合、ていっぎ済みの＆演算子と｜演算子は3値ロジックを
サポートする。

**コンバージョン**
**bool型が関係する変換が2つのみ用意。**
対応するNULL許容型のbool？への暗黙的な変換とbool?がたからの明示的な変換。
但し、.NETには、bool型との間の変換に使用できる追加のメソッドが用意されて入る。

##char
char型のキーワードは、**UnicodeUTF-16文字**を表す。 **.NET System.Char構造体のエイリアス**。
**範囲(U+0000～U+FFFF)**

char型では、**比較演算子、等価演算子、インクリメント演算子、およびデクリメント演算子がサポート**。
charオペランドの場合、算術演算子及びビット論理演算子によって、対応する文字コードに対する演算が実行され、
int型の結果が生成されます。
string型では、char値のシーケンスとしてテキストを表します。

**リテラル**
char値は以下で指定できる。
・文字リテラル
・Unicodeエスケープシーケンス。これは\uの後に文字個0度の16進数表現（4つの記号）を続けた者になります。
・16進数エスケープシーケンス。これは\xの後に文字コードの16進数表現を続けた物。

```
C#
var chars = new[]
{
	'j',
	'\u006A',
	'\x006A',
	(char)106,
};


Console.WriteLine(string.Join(" ", chars)); // output: j j j j
```

文字コードの値をそれに対応するchar値に型変換も可能。
※Unicodeエスケープシーケンスは４つの16進数をすべて指定する必要がある！！
※16進数エスケープシーケンスの場合は、先頭のゼロを省略可能。

**変換**
char型は、**整数型（ushort,int,uint,long,ulong）に暗黙的に変換可能**。
また組み込みの**浮動小数点数値型（float,double,decimal)に暗黙的に変換可能**。
**sbyte,byte,short整数型には明示的に変換**する。

**他の型からchar型への暗黙的に変換は不可。**
しかし、整数または浮動小数点の数値型はcharに明示的に変換可能になっている。
参考資料：
・Microsoft C#リファレンス
PocketMine-MP4.0を構築する

~~**現在PMMP4.0は安定版ではありません。通常のPMMPを使いたい方は3.xを使用してください。**~~
11/15追記: 現在4.0のベータバージョンが公開されており、12/1に安定版のリリースが予定されているため、この記事のような使い方は必要ない(はず)です。

# 環境
- Ubuntu 18.04.4

# 作業用ディレクトリを作る
ディレクトリ名はなんでも大丈夫です。ここではpmmp4とします。

```shell
$ mkdir pmmp4
$ cd pmmp4
```

# バイナリをコンパイルする
[php-build-scriptsのmasterブランチ](https://github.com/pmmp/php-build-scripts/tree/master)を使います。compile.sh実行後はかなり時間がかかるので気長に待ちましょう。

```shell
$ git clone --branch=master https://github.com/pmmp/php-build-scripts
$ cd php-build-scripts
$ ./compile.sh
```

エラーが出た場合はインストールするよう表示されたものをインストール後、再度compile.shを実行してください。

```shell
$ mv bin ../
$ cd ../
$ rm -rf php-build-scripts
```

# PMMPをダウンロードする
PMMP用のディレクトリを作り、GitHubから[PMMPのmasterブランチ](https://github.com/pmmp/PocketMine-MP/tree/master)をcloneした後、必要な物だけを取り出します。

```shell
$ git clone --recursive --branch=master https://github.com/pmmp/PocketMine-MP
$ cd PocketMine-MP
$ mv src resources composer.json start.sh ../
$ cd ../
$ rm -rf PocketMine-MP
```

# 依存ライブラリをインストール
まずcomposer.pharをダウンロードします。

```shell
$ curl -sS https://getcomposer.org/installer | php
```

composer.pharを用いてインストールします。

```shell
$ bin/php7/bin/php composer.phar install
```

# PMMPを起動する

```shell
$ ./start.sh -f src/PocketMine.php
```

成功すると次のように表示されるため、指示に従って設定を行います。

```shell-session
[*] PocketMine-MP set-up wizard
[*] Please select a language
...
```

設定後、初回では開発中のバージョンで起動できない設定になっているため、自動でPMMPが停止します。
そこで、pocketmine.ymlを編集して起動できるように設定します。

```yaml:pocketmine.yml
settings:
...
  enable-dev-builds: true
```

23行目のenable-dev-buildsをfalseからtrueに変更し、保存後再度start.shを実行すると起動できます。

# おわりに
何か間違い等あれば連絡ください！
良きPMMPライフを！
【AWS SAP】ELBの3タイプ【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第19弾
以下の違いについて覚えておいて損はありません。

ELBの3つのタイプ
・Classic Load Balancer
・Application Load balancer
・Network Load Balancer

##Classic Load Balancerとは

トランスポートレイヤー (TCP/SSL) またはアプリケーションレイヤー (HTTP/HTTPS) のいずれかでルーティングを決定する。

リバースプロキシのため、行きも帰りもロードバランサを経由する。

##Application Load balancerとは
HTTP / HTTPS トラフィックの負荷分散を行う。アプリケーションレイヤーでルーティングを決定する。

リバースプロキシのため、行きも帰りもロードバランサを経由する。

##Network Load Balancerとは
TCPトラフィックなどネットワーク系の負荷分散
を行う。トランスポートレイヤー (TCP/SSL) でルーティングを決定する。
行きだけロードバランサーを経由する。帰りは経由しない。
【AWS SAP】EC2のインスタンス課金タイプ【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第18弾
以下の違いについて覚えておいて損はありません。

・オンデマンドインスタンス
・リザーブドインスタンス
・スポットインスタンス

##オンデマンドインスタンスとは
従量課金。使った分だけ支払うタイプ。

##リザーブドインスタンスとは
事前に予約して利用。(1年契約か3年契約)
オンデマンドインスタンスに比べて、最大72%安くなる。
当分使うことが想定される場合などはリザーブドインスタンスを利用することでコスト削減が可能。ただ、一度購入すると途中で利用しなくなってもコストは同じ。

##スポットインスタンスとは
AWSで使われていないEC2を入札制で利用する。
サーバー価格が入札金額を上回ると、サーバーを利用できなくなる。
突然停止するリスクを許容しても安く使いたい！という場合に利用する。
Raspberry Piに64bit版OS(beta)をインストール

先日[Raspberry Pi4に8GB版](https://amzn.to/3d4ncXx)が発売されたのに伴いOSも64bit版(beta)が公開されました。
今回は64bit版OSをインストールしてみます。

## 環境
- Windows 10を使用
- RaspberryPi3+にインストール(4を未所持のため)
- Etcherで64GBのmicroSDカードにインストール
- ヘッドレスで設定、運用

## 目次
- [ダウンロード](#ダウンロード)
- [インストール](#インストール)
- [初期設定](#初期設定)
- [ネットワーク設定](#ネットワーク設定)
    - [SSHの有効化](#sshの有効化)
    - [Wi-Fi設定](#wi-fi設定)
    - [SSH接続](#ssh接続)
- [初期設定](#初期設定)
    - [raspi-config](#raspi-config)
    - [パスワード変更](#パスワード変更)
    - [ローケルの変更](#ローケルの変更)
    - [タイムゾーンの変更](#タイムゾーンの変更)
    - [アップデート](#アップデート)
    - [raspi-configの終了](#raspi-configの終了)
    - [パッケージの更新](#パッケージの更新)
- [終わりに](#終わりに)

## ダウンロード
[こちら](https://www.raspberrypi.org/forums/viewtopic.php?f=117&t=275370)のページから`Download here`をクリックしてzipファイルをダウンロードしてください。
## インストール
- ダウンロードしたファイルをmicroSDカードに書き込みます。  
- 今回はEtcherを使用します。[こちら](https://www.balena.io/etcher/)からダウンロードしてインストールしてください。
- Etcherを起動したら`Flash from File`をクリックしダウンロードOSのzipファイルを選択します。  
- 真ん中のインストール先を確認し、違う場合は`Change`で変更してください。
- 正しいインストール先が選択された状態で`Flash`をクリックしてください。
- しばらく待ってインストールが完了したらEtcherを閉じてください。

## ネットワーク設定
### SSHの有効化
- インストール直後おそらくWindowsがmicroSDカードを認識していないと思うので一度microSDカードを指し直してください。  
- microSDカード(boot)が表示されたら開きsshファイルを作成せてください。(ssh.txtにならないように注意)

### Wi-Fi設定  
イーサネットに繋いで運用する場合は飛ばしてください。

- microSDカード(boot)にwpa_supplicant.confを作成し内容は以下にします

```
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="接続先のSSID"
    psk="接続先のパスワード"
}
```

パスワードは平文で保存されます。後でハッシュ化できますが今回は割愛します。

### SSH接続
- microSDをRaspberryPiに指し電源をつなげ起動ま完了するまでしばらく待ちます。
- コマンドプロンプトかpowershellを起動し以下のコマンドでRaspberryPiと接続します。

```
ssh pi@raspberrypi
```

- yes/no?と聞かれるのでyesと入力します。
- もう一度`ssh pi@raspberrypi`を入力するとRasPiとSSH接続されパスワードを聞かれるので、初期パスワードの`raspberry`と入力するとログインできます。

## 初期設定
### raspi-config

- 以下のコマンド入力するとraspi-configが表示されます。

```
sudo raspi-config
```

### パスワード変更
- 1を選択してパスワード変更してください

### ローケルの変更
- 4を選択
- I1を選択
- `ja_JP.UTF-8 UTF-8`に合わせてスペースキーで選択しエンターを押して確定します。
- システムのロケールを聞かれるので`ja_JP.UTF-8`を選択します。

### タイムゾーンの変更
- 4を選択
- I2を選択
- Asiaを選択
- Tokyoを選択

### アップデート
- 8を選択するとアップデートが開始されます。

### raspi-configの終了
- 右キーを押して`Finish`を選択しraspi-configを終了します。
- 再起動するか聞かれたら再起動します。
### パッケージの更新
以下のコマンドでパッケージを更新します。

```
sudo apt update
sudo apt upgrade -y
sudo apt dist-upgrade -y
```

## 終わりに
OSのインストールと簡単な初期設定は以上になります。
RaspberryPi3+を64bitにして意味があるのかは __知らん!__
書き終わってから気づいたけどコレは64bitとか関係ない記事になってしまった。

## 関連記事

- [RaspberryPiにSambaをイントールしてファイルサーバを作成](https://qiita.com/loach/items/36825623bc9277b08b71?utm_source=Qiita&utm_medium=referral&utm_campaign=analytics)

## My Accounts
<a href="https://github.com/mao2009"><img src="https://mao2009.github.io/qiita_template/GitHub-Mark-64px.png" width="50px"></a><a href="https://twitter.com/loach_mao"> <img src="https://mao2009.github.io/qiita_template/Twitter_Social_Icon_Circle_Color.png" width="50px" ></a>
data structure Python push pop

```python
#データがの一番上に値を入れる:push(n)
#nは入れる値
#データの一番上から値を取り除く＋表示する　:pop()

push(5)
push(6)
pop()
>>6

#emptyからpop()しようとすると、'stuck underflow'エラーとなり、
上限以上にpush(n)しようとすると、'stuck overflow'エラーとなる。

push(7)
pop()
pop()
>>stuck underflow

#peekを使うと、削除せずに一番上から値を表示できる。
push(5)
peek()
>>5


```
Risizeの謎   

画像認識機械学習エンジニアは，前処理で画像のリサイズをすることが多いだろう．
224や，608などは，界隈では見慣れた数字になっていると思う．

それ故に，~~無意識に色々リサイズしてしまうのだが~~，今回，苦しめられたので皆さんのお役に立つかは分かりませんが共有します

# 起きたこと
あるクラス分類の画像認識Pで，モデルが吐くクラス事後確率と，画像を並列して表示するUIを作成して時のこと．
以下の作業を同時に行っていた．

1,学習済みモデルに対して定性評価するために，**リサイズ済み画像**で推論を行い，事後確率をグラフにまとめていた．
２，一方でUIに焼き込む際には，**リサイズ前の画像**に事後確率を焼き込んで，ビデオにするという突貫工事を行なっていた．（こちらはスクリプト内でリサイズしていた）

この際に，事後確率を観察していると，
*「んっ？？，全然違う値を出力している...」*
となった．
モデルも同じで，前処理も同じだ．
試しに入力画像も保存してみるがほぼ同じ...（と思っていた）

# 原因
原因は，リサイズの手法が異なっていたことだった．
関係ないだろうと思っていたのだが，
**1の作業の画像はffmpeg,
2の作業では,opencv**
でリサイズしてたのが原因だった．
そして，見た目では同じ画像も，numpy_arrayで出力してみると微妙な違いがあった！



それぞれのリサイズは以下のようにしていた．単純だ...
### opencvでのリサイズ

```resize.py
img_resized = cv2.resize(img,(224,224))
```
### ffmpegでのリサイズ
```split_video.py
command = f'ffmpeg -i {INPUT} -vodec png -vf scale={size}:{size} -r {FRAME_RATE} {OUTPUT}'  

subprocess.call(command,shell=True)
```

ここで原因となったのは，Interpolateを指定していなかったことだ．

# Interpolateとは
画像の補完方式だ．
要は，画像を圧縮するわけだからなくなってしまう情報がある．そこを保管する方式は色々あるのだ．
Opencv の公式ページには以下のように手法が書かれている．

> INTER_NEAREST - a nearest-neighbor interpolation
INTER_LINEAR - a bilinear interpolation (used by default)
INTER_AREA - resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire’-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.
INTER_CUBIC - a bicubic interpolation over 4x4 pixel neighborhood
INTER_LANCZOS4 - a Lanczos interpolation over 8x8 pixel neighborhood


ちなみにdefaultは`INTER_LINEAR`
これが，[ffmpegでは，`CUBIC`であるのが原因だった．](https://ffmpeg.org/ffmpeg-all.html)

# まとめ
もちろんプロの方だと，自分のようなことは起こさないと思いますが，自分はここで少し苦戦したのでまとめました．
【Python】matplotlib3.2の日本語フォント設定方法【公式遵守】

# :star: はじめに
- `matplotlib` (https://matplotlib.org/) はPythonでグラフなどを描画するための有名なライブラリです
- ただし、グラフ内のラベルなどで日本語を使いたい場合、デフォルトだと文字化け（◻︎◻︎◻︎◻︎◻︎となるので豆腐と呼ばれているよう）が発生してしまいます
- 自分が `matplotlib 日本語` で調べた時に出てきた記事が結構力技の方法（インストールしたmatplotlibの中身を直接書き換えるようなやつ等）ばかりで困ったので、公式で紹介されている方法を書いておきます

# :question: 日本語化ライブラリは使わないの?
- `japanize-matplotlib` (https://github.com/uehara1414/japanize-matplotlib) というmatpotlibの日本語化ライブラリを作ってくれている親切な方がいます
- これを使うこともできるのですが、このライブラリで使われている `font_manager.createFontList` というメソッドがmatpotlibの`3.2.0`より非推奨になりました
  - https://matplotlib.org/api/prev_api_changes/api_changes_3.2.0.html

>font_manager.createFontList is deprecated. font_manager.FontManager.addfont is now available to register a font at a given path.

- よって、matpotlibを3.2.0以上で使用している場合、次のような警告が表示されるようになりました

```
MatplotlibDeprecationWarning: 
The createFontList function was deprecated in Matplotlib 3.2 and will be removed two minor releases later. Use FontManager.addfont instead.
```

- `japanize-matplotlib` のソースコードを読めば分かるように複雑なことはしていないので、今回は自前で同等の実装を`FontManager.addfont`に置き換えて行います

# :pencil: FontManager.addfont で日本語フォントを追加する
- 日本語フォント（今回はIPAexゴシック）をダウンロード&解凍する
  - IPAexフォント: https://ipafont.ipa.go.jp/node193
- 使用するリポジトリにダウンロードした`.ttf`ファイルを置く
  - 例えばfontsディレクトリを作って `/fonts/ipag.ttf` のように置く
- [fontManager.addfont](https://matplotlib.org/api/font_manager_api.html?highlight=addfont#matplotlib.font_manager.FontManager.addfont) で読み込むだけ
  - ~~自分はclassmethodだと思い込んで時間を無駄にした...~~

```py
from matplotlib import font_manager

font_manager.fontManager.addfont("/fonts/ipag.ttf")
matplotlib.rc('font', family="IPAGothic")
```

- フォントが複数がある場合は次のようにすればOK

```py
from matplotlib import font_manager

font_files = font_manager.findSystemFonts(fontpaths=["/fonts"])

for font_file in font_files:
    font_manager.fontManager.addfont(font_file)

matplotlib.rc('font', family="IPAGothic")
```


# :tada: おまけ
- ちなみにバージョンが3.2未満の場合は次のように対応できます
  - `japanize-matplotlib` でやってることとほぼ同じ

```py
from matplotlib import font_manager

font_files = font_manager.findSystemFonts(fontpaths=["/fonts"])
font_list = font_manager.createFontList(font_files) # 3.2以上の場合は警告が出る
font_manager.fontManager.ttflist.extend(font_list)
matplotlib.rc('font', family="IPAGothic")
```

# :star: 終わりに
- なにも大したことはしてないのですが他の人が調べた時に惑わされないように書き残します
GitHubでCloneでもForkでもなくリポジトリの複製が欲しい

GitHubでCloneでもForkでもなくリポジトリの複製が欲しい。
そんな時の方法。

## 1. GitHub上で新規リポジトリを作成

普通に `New Repository` から作っちゃってOK。
仮にこれを `user/new-repository` とする。

## 2. ベアリポジトリの作成

ターミナルでコピー元のリポジトリ（仮に `user/old-repository` とする）をベアクローンする。
（ベアとは作業ディレクトリを持たないリポジトリのこと）

```bash
git clone --bare https://github.com/user/old-repository.git
```

（SSH使ってる方は `https://github.com` を `git@github.com:` に変えてください）

## 3. 新しいリポジトリにミラープッシュする

```bash

cd old-repository.git
git push --mirror https://github.com/user/new-repository.git
```

## 4. 確認&ベアリポジトリの削除

GitHubで新しいリポジトリにファイルが複製されているのを確認したら、ベアリポジトリを削除する。

```bash
cd ../
rm -rf old-repository.git
```

以上。
備忘録: Rails APIアプリ作成時のチートシート

#app作成コマンド
```
rails バージョン new アプリ名 -d mysql --webpacker=(vue or react) --skip-turbolinks
```

#追加するgem list
```
gem 'devise'
gem 'devise-i18n'
gem 'rails-i18n'

gem 'faker'
gem 'factory_bot_rails'

gem 'rubocop', require: false
gem 'rubocop-rails', require: false
gem 'pry'
gem 'pry-doc'
gem 'pry-rails'
gem 'pry-byebug'
gem 'foreman'

gem 'rspec-rails', '~> 4.0.0'
gem 'rubocop-rspec', require: false
```

#実行コマンド
```
$ rails webpacker:install

$ rails webpacker:install:vue

$ yarn add axios

$ yarn add vue-router

$ rails g rspec:install

$ rails g devise:install
```

#rubocopの設定
```..rubocop.yml
require: rubocop-rails

AllCops:
  # Rubyのバージョンを指定
  TargetRubyVersion: 2.6.5
  # 除外するファイル
  Exclude:
    - vendor/bundle/**/*
    - bin/*
    - db/**/*
    - config/**/*
    - Gemfile
    - node_modules/**/*

# Missing magic comment # frozen_string_literal: true. を無視
Style/FrozenStringLiteralComment:
  Enabled: false

# Missing top-level class documentation comment. を無視
Style/Documentation:
  Enabled: false

# Line is too long を無視
Metrics/LineLength:
  Enabled: false

# Use nested module/class definitions instead of compact style. を無視
Style/ClassAndModuleChildren:
  Enabled: false
```

#rspecの設定
```ruby:.rspec
--require spec_helper
--format documentation
```
#foremanの設定
```ruby:Profile.dev
web: bundle exec rails s
# watcher: ./bin/webpack-watcher
hot: ./bin/webpack-dev-server
```
```ruby:bin/server
# /bin/bash -i
bundle install --path vendor/bundle
bundle exec foreman start -f Procfile.dev
```
```
$ chmod 777 bin/server
```

#日本語対応といらないファイルを作成しない設定
```ruby:config/application.rb
config.i18n.default_locale = :ja
config.time_zone = "Tokyo"

config.generators do |g|
  g.template_engine false 
  g.assets false
  g.helper false
  g.test_framework :rspec,
                    fixtures: false,
                    view_specs: false,
                    helper_specs: false,
                    routing_specs: false
end
```

#よく使う作成コマンド
```
$ rails g devise:install
$ rails g devise user
$ rails g model モデル名 title:string likable:references{polymorphic}

# rails generate migration クラス名 カラム名:データ型( カラム名:データ型)
$ rails g migration AddDetailsToTitles price:integer author:string
$ rails g migration RemoveAuthorFromTitles author:string

$ rails g controller api/v1/コントローラー名 index create

$ rails g factory_bot:model モデル名

$ rails g rspec:request api/v1/portfolios/post

```
#PULL_REQUEST_TEMPLATE
```
## 前提プルリク

先にレビュー/マージする必要があるPRがある場合は記載。
なければ「なし」と記載。

## Issue番号

関連するIssueがある場合は記載。
なければ「なし」と記載。

## 概要

目的、変更内容など。必須。
タイトルで十分に伝わる場合は「表題の通り」と記入。

## 参考記事など

ない場合は省略可。

## 注意点

ない場合は省略可。

## スクリーンショット

画面がない場合は省略可。

## チェックリスト
- [ ] rubocopが警告やエラーを出さないこと
- [ ] rspecが全てパスしていること
```

#Can't verify CSRF token authenticity(都度調べてるエラー)

上記エラーに関する参考URL:　https://7me.nobiki.com/2018/07/30/rails-vue-axios-csrf-token/

XXS(クロスサイトスクリプティング)とCSRF(クロスサイトリクエストフォージェリ)の違い
参考URL: https://qiita.com/wanko5296/items/142b5b82485b0196a2da

```
const token = document.getElementsByName("csrf-token")[0].getAttribute("content");
axios.defaults.headers.common["X-CSRF-Token"] = token;
```
【python】＃で階段を作るプログラム

#【python】＃で階段を作るプログラム
hackerrankの自分用メモです。


与えられた整数の段を持つ＃の階段を作る。

```:n=6の場合
     #
    ##
   ###
  ####
 #####
######
```

▼my answer

```python:
def staircase(n):
    for i in range(n):
        i += 1
        a = " "*(n-i)+"#"*i
        print(a)


if __name__ == '__main__':
    n = int(input())

    staircase(n)
```


<br>
・`文字列`*数値
数値分文字列を繰り返す

```python:
"#"*6

#出力
'######'
```

```python:
"abc"*6

#出力
'abcabcabcabcabcabc'
```


<br>
・指定した数だけ、1から整数を取り出す。

`range(n)`：0からの数字になる。
　→ nに1を足す。

```python:
n=3
for i in range(n):
   i += 1
   print(i)

#出力
1
2
3
```
Python基礎：Socket、Dnspython

#はじめに
nslookup、ドメインからIP取得、IPからドメイン取得などの処理がしたい場合があります。

socket、dnspythonを使って処理できます。

#socket
doc：https://docs.python.org/ja/3/library/socket.html

##ドメインからIPを取得
```python
import socket

print(socket.gethostbyname("google.com"))
```

>172.217.161.78

##ドメインからIPアドレス情報を取得
```python
import socket

print(socket.getaddrinfo("yahoo.co.jp", 443))
```

>[(<AddressFamily.AF_INET: 2>, 0, 0, '', ('182.22.59.229', 443)), (<AddressFamily.AF_INET: 2>, 0, 0, '', ('183.79.135.206', 443))]

##IPからFQDNを取得
```python
import socket

print(socket.getfqdn("182.22.59.229"))
```

>f1.top.vip.ssk.yahoo.co.jp

などなど。

#dnspython
doc: http://www.dnspython.org/docs/1.16.0/
##インストール
`pip install dnspython`

##nslookup
###nslookupコマンド
`nslookup yahoo.co.jp`
>名前:    yahoo.co.jp
Addresses:  182.22.59.229
          183.79.135.206

###dnspythonでnslookupコマンドと同じ結果を取る

```python
import dns.resolver

print(dns.resolver.query("yahoo.co.jp", "A").response.answer[0])
```

>yahoo.co.jp. 0 IN A 182.22.59.229
yahoo.co.jp. 0 IN A 183.79.135.206

など。

以上
linked list

linked listは、access timeはO(n)でよくないが、
insertion timeがO(1)で優れている。

linked listのnodeには、データと次のリンクを指すnextが格納されている。nextにはnullが格納されている。


```python
Node1.data = "G"
Node1.next = Node2
Node2.data = "R"
Node2.next = Node3
Node3.data = "O"
Node3.next = Node4
Node4.data = "W"
Node4.next = null
#Node1.next.nextは、Node3を意味する。
``` 

また、bi-directionalと呼ばれる双方型のlinked listも存在する。

```python
Node2.data = "5"
Node1.next = Node2
Node2.previous = Node1
#1から２と、２から１の両方が定義されている。
```
Ruby ハッシュについて（続）

[前回のハッシュに関する記事](https://qiita.com/mofuko0213/items/aca2b7d2a34874ac6945)

# ハッシュの同値比較
== でハッシュ同士を比較すると、同じハッシュかどうかをチェックできます。
このときすべてのキーと値が同じであれば、trueが返ります。
たとえ並び順が異なっていたとしても、キーと値がすべて同じであれば、trueとなります。

(例)

```ruby
x = { 'a' => 1, 'b' => 2, 'c' => 3}
y = { 'b' => 2, 'c' => 3, 'a' => 1}
x == y # => true
```

# 要素数の取得
sizeメソッド（= length）を使うと、ハッシュの要素の個数を調べることができます。

```ruby
{ 'a' => 1, 'b' => 2, 'c' => 3 }.size # => 3
```

# 要素の削除
deleteメソッドで指定したキーに対応する要素を削除できます。
最後に、ハッシュを出力させると、要素が削除されていることがわかります。

```ruby
menus = { 'food' => 'rice', 'drink' => 'water', 'dessert' => 'cake' }
menus.delete('food') # => "rice" 削除された要素の値が戻り値となります
puts menus                             # => {"drink" => "water", "dessert" => "cake"}
```

## 参考にした文献

[プロを目指す人のためのRuby入門](https://www.amazon.co.jp/dp/4774193976/ref=cm_sw_em_r_mt_dp_U_shaUEbXSFD416)
Xcodeで画面外に描画されたものを見る方法

Debug View Hierarchyでデバッグするとき、画面外に描画されて見えないことがあります。

下の丸で囲ってるところをクリックすると、画面外に描画されてるものが見えるようになります。
![スクリーンショット 2020-06-04 17.54.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59336/9148694f-8ba7-5873-fbf4-009aef0481bb.png)

便利！！
【AWS SAP】S3における暗号化【頻出】

##AWS SAP取得に向けて勉強する中で覚えてよかったもの 第17弾

・SSE-C
・SSE-KMS
・SSE-S3

##SSE-C
Server-Side Encryption with Customer-Provided Keys (SSE-C)の略称。
ユーザー側でキーを準備し管理する。

##SSE-KMS
Server-Side Encryption with AWS KMS-Managed Keys (SSE-KMS)の略称。
ユーザー側でKMSでキーを生成して管理する。


##SSE-S3
Server-Side Encryption with Amazon S3-Managed Keys (SSE-S3)の略称。

Amazon S3 がキーを管理。キー自体を定期的に更新することで安全性を担保。

##ポイント
会社のポリシーによっては、暗号化キーを自社で管理したいといったケースがある。
その場合は、SSE-Cを利用。
PHPの便利Tips備忘録(時々更新)

## 改行
`"\n"`が使えなかったら`"<br/>"`

## エラー表示
「ブラウザでPHPの処理したいんだけど何も表示されない!!」
「でも、レンタルサーバー使ってるから`php.ini`とかの編集の仕方わからないし…」
そんな時は↓

```php
ini_set("display_errors", "on");
error_reporting(E_ALL);
```

`ini_set` で`php.ini`を編集しなくてもファイルからエラーを確認できるようになる。
`error_reporting`で出力するエラーのレベルを設定、`E_ALL`でほとんどのエラーが検出される。

## var_dumpを見やすく
データの確認をするのに便利な`var_dump`
少量のデータなら良いけど、大量のデータを確認するとなると、ブラウザ上で区切られて表示されないから見づらい。
そんな時は↓

```php
echo "<pre>";
var_dump(確認したいデータ);
echo "</pre>";
```
htmlの`<pre>`タグで`var_dump()`の出力の際に使用されている改行などがそのままブラウザに反映されるようになる。
【Git】『ブランチをまたいだコミットの差分ファイルのみ』をZIPファイルにまとめて取得する。

メモとして残します。


#■やり方
```shell
 git archive ブランチ名 --format=zip -o ./diff-files.zip  `git diff --name-only --diff-filter=d コミット1Rev コミット2Rev`
```
##注意！
**ブランチ名は未来の方のブランチを指定すること。**
masterとdevelopでの比較の場合は、基本的にはdevelopが未来のリリースのため、欲しいのは未来のリソースになります。
`git archive master...`にすると、masterブランチ基準の差分になるため、古いリソースでの差分ファイルが取得されてしまいます。
Ansibleで変数で定義されたリストを文字列に変換

## 概要

with_itemsだと同じコマンドをループしてしまうのでリストを文字列結合してtaskで利用したかった。

e.g.)

```yaml
vars:
  list:
   - foo
   - bar
   - baz

shell: command --option foo bar baz
```


## 結論

- [set_fact](https://docs.ansible.com/ansible/latest/modules/set_fact_module.html)にJinja2的な出力の仕方で変数化してしまう。
- ここではdebugで出力しているが `shell: echo{{ str }}` のような形で利用できる。

### 定義

```yaml
- name: concat strings
  set_fact:
    str: " {{ names | join(' ') }}"
  vars:
    - names:
        - foo
        - bar
        - baz

- name: view var
  debug:
    var: str
```


### 実行結果

```text
TASK [debug : concat strings] *******************************************************************************************************************************************************************************************************************************************
ok: [host]

TASK [debug : view var] *************************************************************************************************************************************************************************************************************************************************
ok: [host] => {
    "str": " foo bar baz"
}

```

---

もっと良い方法があれば教えてほしいです。
GCEでNestedVirtualization対応のUbuntuインスタンスを立てる

# はじめに
## 対象読者
* ネストされた仮想化 ( Nested Virtualization ) 環境を、なるべく安価にクラウドで触りたい
    * 具体例としては Android Studio でのエミュレータをクラウドで動かしたい
    * 今回は GCP - GCE でおこなう

## 各ベンダーのコストと選定
* GCP ( Google Cloud Platform )
    * GCE ( Google Compute Engine ) の N1 プランで月額最低 3,000 円程度からインスタンスを立てられる
        * とはいえ Android エミュレータ動かすなら vCPU * 2 + メモリ 3.75 GB 環境くらいは必要になってくるので 5,000 円以上はかかる
* Microsoft Azure
    * fvs2 で月額最低 8,000 円程度から
* さくら
    * 専有サーバで対応している。月額 20 万円ほど……
* DigitalOcean
    * コスト的には一番安く月額最低 2,000 円程度からいけるらしい（未検証）
    * ただし日本リージョンが存在していないため、遅延が大きいのがネックとなる


# Nested Virtualization 対応のイメージ作成
## 自作インスタンスのイメージを用意する
### インスタンスを用意しておく
* Nested Virtualization 対応させたい OS ( ここでは Ubuntu 20.04 ) のインスタンスを一つ作成します
* ここで指定したイメージ名は後で使います
* スペックも、以後使いたいものと同等にしておくと、後が楽です
* インスタンス作成後、ログインしてパッケージ更新など済ませておくと、これまた後が楽です

```sh
apt update
apt upgrade
```

### インスタンスを停止
* 準備ができたら、管理画面でインスタンスを停止

## Nested Virtualization 対応のイメージ作成
### cloud shell でコマンド実行
* --project
    * project_name のところに、自身の環境におけるプロジェクト名を指定
* images create
    * create_image_name のところに、自身の作成したイメージ名を指定
* --source-disk
    * source_image_name のところに、自身の作成したイメージ名を指定
* --source-disk-zone
    * zone_name のところに、インスタンスを作成した時に自身で設定した zone を指定

```sh
gcloud compute --project=project_name images create create_image_name --source-disk=source_image_name --source-disk-zone=zone_name --licenses "https://www.googleapis.com/compute/v1/projects/vm-options/global/licenses/enable-vmx"
```

* 実行後、以下のように表示されたら成功です

```sh
Created [https://www.googleapis.com/compute/v1/projects/project_name/global/images/create_image_name].
NAME               PROJECT            FAMILY  DEPRECATED  STATUS
create_image_name  project_name                           READY
```

### イメージが作成されていることを確認
* 左メニューの「イメージ」を選ぶと、その中に create_image_name が存在していることが確認できます
    * 「マシンイメージ」ではなく単なる「イメージ」の方です

### インスタンス作成
* 「イメージ」の中にある create_image_name を選択して「インスタンス作成」実行
* 通常通りにインスタンス作成を進めていく
    * リージョンは「イメージ」が置いてあるところと異なるリージョンでも、指定できます
    * ブートディスクのところが create_image_name になっているはずです


# 対応したインスタンスへの接続と確認
## 接続
* ターミナル等から ssh 接続してください

## 確認
* 以下コマンドを打って vmx が flags 内にあれば OK です

```sh
cat /proc/cpuinfo
```

```sh
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology nonstop_tsc cpuid tsc_known_freq pni pclmulqdq vmx ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti ssbd ibrs ibpb stibp tpr_shadow flexpriority ept vpid fsgsbase tsc_adjust bmi1 hle avx2 smep bmi2 erms invpcid rtm rdseed adx smap xsaveopt arat md_clear arch_capabilities
```


# おわりに
## 感想
* ここまで辿り着くのに時間かかった……！　日本語での情報少ないというか、まず公式ドキュメントが日本語だとよくわからなくて、まだ英語の方が理解しやすい
* GCE のインスタンス、やっぱりそこそこのスペック積まないと Android エミュレータはしっかり動いてくれないなあ……

## 参考
* [Enabling nested virtualization for VM instances](https://cloud.google.com/compute/docs/instances/enable-nested-virtualization-vm-instances)
* [eve-ngをGCE(GCP)に導入してみた](https://qiita.com/aoi96/items/9c3d3040a50eb5dd053e)