OmniAICreator/Qiita-1.07M huggingface dataset:
Proxmox VE 5で仮想マシンのBIOS画面を入れ替える

Proxmoxの環境を最近、VE3からVE5にアップデートを検討中で、いろいろファイルを弄ったり仮想マシンで遊んでいたところ、KVMマシンを起動するときにBIOSがProxmoxオリジナルの起動画面だったので自分のものに変えてみた。

# SeaBIOS
KVMのBIOSには、「SeaBIOS」を採用しているようで「Legacy BIOS」と「UEFI」でファイルの場所が違うようです。今回は、「Legacy BIOS」しかやりません。

# ファイルの用意
Splashscreen本体は、Proxmox上の`/usr/share/qemu-server/bootsplash.jpg`からscpとかでローカルに持ってきます。

新しく画層を作成する場合は、「640x480」で画像を作成します。ちなみに、画像編集ソフトは、「**GIMP**」を使います。

作成または、元ファイルから好みの画像を作り終えたら、「Image」->「Mode」->「Index」を選択肢以下のように設定します。
<img width="484" alt="Screen-Shot-2019-04-28-at-9.37.51-PM.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136178/925d7b0b-f64d-e76a-8229-b2a701d0182a.png">

また、ファイルを出力する際、「Advanced Options」の部分を以下のように設定し出力しないと、ファイルを入れ替えても画像を認識しなくなるので注意しましょう。
![Screen-Shot-2019-04-28-at-9.39.26-PM-1024x1001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136178/d9e0291e-b9da-61f8-51da-7842603a7d15.png)

出力後、`/usr/share/qemu-server/bootsplash.jpg`を上書きし、仮想マシンを再起動させれば一瞬ですがオリジナルのSplashscreenが見れます。

![Screen-Shot-2019-04-28-at-2.32.11-PM-1024x603.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136178/17c01014-1fec-6b6f-2eac-92f418788ff1.png)

# 最後に
こんなに便利なものが無料で使えるなんていい時代ですね。LXCコンテナも使えるし、スペックの低いサーバーでも問題なく使えているので、OpenStackで挫折した方は、Proxmoxを検討しても良いかもしれませんね。あと、PCIやUSBパススルーも簡単に行えて超便利です。
メソッドの抽出(Extract Method)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/257568/fdaf5b9d-a029-52fa-35b6-44022684defa.png)


1つずつリファクタリング技法まとめ
個人的に簡単かつ取り入れ易いと思うものから

## 目的
すぐ引き出せるようにする

## 基本作業サイクル
- システムを動かして仕様を精査
- テストメソッドを作成
- テストの失敗を確認
- テストの成功を確認
- 小さい変更、随時テスト実行(失敗確認->成功確認)
- 最後テスト実行
- 最後動作確認

## メソッドの抽出(Extract Method)とは
コードの断片をメソッドにして、目的を説明するメソッド名にすること
 
## ポイント
- メソッド名とメソッドの中身の意味的な距離が近い、小さなメソッドを心がける
- **コメントは抽出できるメソッドを見分けるために使える**ことが多い
- **コメント自体がメソッドの名前の候補**になる
- 抽出したメソッドの中に**抽出元のローカル変数や引数が入っていないか**確認する
- 抽出したメソッドの中に一時変数が入っていないか、**抽出元の変数の値を書き換えていないか**確認する
- 一時変数が複数ある場合は「一時変数の分解」(Split Temporary Variable)を先に適用する
- 一時変数は「一時変数から問い合わせメソッドへ」(Replace Temp with Query)で削除もできる

## 例
- メソッド名とメソッドの中身の意味的な距離が近い、小さなメソッドを心がける
- **コメントは抽出できるメソッドを見分けるために使える**ことが多い
- **コメント自体がメソッドの名前の候補**になる

```

def scraiping
  # ログインする
  driver.navigate.to('https://サイト')
  driver.find_element(:id, 'id').send_keys('neko')
  driver.find_element(:id, 'password').send_keys('inu')
  driver.find_element(:css, 'li.loginBt > a').click

  # ダウンロードする
  driver.find_element(:css, 'input[value="ダウンロード（CSV）"]').click

  # ログアウトする
  driver.find_elements(:css, 'a').find { |element| element.text == 'ログアウト' }.click
end
```
　　　↓

```
def scraiping
  login
  download
  logout
end

def login
  driver.navigate.to('https://サイト')
  driver.find_element(:id, 'id').send_keys('neko')
  driver.find_element(:id, 'password').send_keys('inu')
  driver.find_element(:css, 'li.loginBt > a').click
end

def download
  driver.find_element(:css, 'input[value="ダウンロード（CSV）"]').click
end

def logout
  driver.find_elements(:css, 'a').find { |element| element.text == 'ログアウト' }.click
end
```  

- 抽出したメソッドの中に**抽出元のローカル変数や引数が入っていないか**確認する
- 抽出したメソッドの中に一時変数が入っていないか、**抽出元の変数の値を書き換えていないか**確認する

```
def scraiping
  # ログインする
  url = 'https://サイト'
  driver.navigate.to(url)
  driver.find_element(:id, 'id').send_keys('neko')
  driver.find_element(:id, 'password').send_keys('inu')
  driver.find_element(:css, 'li.loginBt > a').click

  download
  logout
end
```
　　　↓

```
def scraiping
  url = 'https://ふつうのサイト'
  # 単に抽出しない
  login(url)
  download
  logout
end

def login(url)
  # 仮に抽出元で後続で変数を使用していなければ引数なしで一時変数としておけば良い
  # url = 'https://サイト'

  driver.navigate.to(url)
  driver.find_element(:id, 'id').send_keys('neko')
  driver.find_element(:id, 'password').send_keys('inu')
  driver.find_element(:css, 'li.loginBt > a').click

  # 仮に抽出元で変数を書き換えたものを後続で使用する場合は引数を返す必要がある
  # url = 'https://サイト/1' if (driver.find_element(:id, 'next'))
end

```

## 関連パターン
- 一時変数の分解(Split Temporary Variable)
- 一時変数から問い合わせメソッドへ(Replace Temp with Query)
- メソッドからメソッドオブジェクトへ(Replace Method with Method Object)

## 書籍情報
Jay Fields (著), Shane Harvie (著), Martin Fowler (著), Kent Beck (著),
長尾 高弘(訳), リファクタリング:Rubyエディション
https://amzn.to/2VlyWML

## 雑感
最もよく使うリファクタリング
Microsoft Edge Dev（Chromium）でClickOnceは動作するか　※20190929時点のInsider

# 記事の対象者
- ClickOnce（WEB経由）を使っている
- Microsoft Edgeに多少の興味がある


# はじめに

URL欄に以下を打ち込むとClickOnceを有効化できます。
edge://flags/#edge-click-once
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124594/38f08c9c-d69b-a75a-f338-356b5e2bf159.png)
@mimita1026さんに教えていただきました。

　

ClickOnceという特別流行っているわけでもない技術を使っていると、
EdgeがChromiumベースで開発されるといった情報を目にするだけで
ClickOnce大丈夫かなぁと若干疑ってしまいます。

[Microsoft Edge preview builds: The next step in our OSS journey](https://blogs.windows.com/windowsexperience/2019/04/08/microsoft-edge-preview-builds-the-next-step-in-our-oss-journey/)

ClickOnceアプリの発行場所をWEBサイトにした場合、
基本的にはIEやEdgeでしかローダー（dfsvc.exe）が動作せず、
Chromeの場合は配置マニフェスト（.application）がダウンロードされてしまいます。
※拡張機能をインストールすることで起動は可能

Chromiumベースで開発された場合、
果たしてClickOnceはどういう動作をしてくれるんでしょうか。


# Microsoft Edge previewのインストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124594/e126bc73-c626-f1cd-6f5a-9a640823b0b3.png)
せっかくだし現時点の動きを試してみようということで
Insiderプレビュー版で実際に動かしてみました。

> Preview the next version of Microsoft Edge
[Let's build together!](https://www.microsoftedgeinsider.com/en-us/)

※現時点では英語のみ




# 配置マニフェスト(.application)にアクセスしてみた
HC取り損ねたので結論だけですが、
やっぱりダウンロードされました。
（ClickOnceローダーが起動しない）

Chromiumベースで作ってるんだから、少なくともInsider版ではそうなるよねといった感じですが、
こうなるとIEモードに期待するか、IE11を使うかといったことも考えないといけないんだろうか・・・。
（特定のURLはIEモードで動作させるとかできたらいいな）

Insider版の状況でアレコレ考えてもしょうがないので、
気にかけておく程度となります。


# 2019/09/29追記
ClickOnceの直接起動は対応済みとのことなので試してみました。
[*Updated* Dev channel build 77.0.211.3 is live](https://techcommunity.microsoft.com/t5/Discussions/Updated-Dev-channel-build-77-0-211-3-is-live/m-p/745801)
> Direct launch for ClickOnce applications has been enabled.
> ClickOnceアプリケーションの直接起動が有効になりました。

[Microsoft Edge Insider Channels](https://www.microsoftedgeinsider.com/ja-jp/download/)

BetaもDevインストールしましたが、
直接起動はできずにダウンロードされました・・・。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124594/f55ed4c3-c7d6-c298-e97e-d6058b87bbc5.png)


# 2019/10/03追記
コメントでもご指摘いただいておりますが、
設定変更で無事に起動できました。
npm pack/publishでファイルの更新日時が1985-10-26固定になっていた

#概要

作成したパッケージの中身が微妙な更新日時になった。何か壊れたのかと思ったが、1985-10-26 (日本では17:15)になっているのは意図された動作だった。
一年経った話だが検索しやすさに貢献して微妙に役に立つのではないかと思って書いた。環境は Windows 10 10.0.17763.475、node 10.15.3、npm 6.4.1。


#経緯

npmにパッケージを公開する際、`npm publish` の前に `npm pack` で tgz ファイルを作成して下記のことを確認していた。

* 余計なものが含まれていないか
* 公開用のファイルが古くないか

いちいち見るのは疑問があるけど、やっていると追加したテストやドキュメント等を同梱してしまったり、READMEが参照する画像がなかったりが発生するし、ミスして面倒くさくなるよりはいいのでそうした。

2019-05-09、作業してみるとファイルの更新日時が「1985-10-26 17:15」になっていて、従来のようにファイル更新日時確認ができない。
しかも「1970-01-01」ではないので何か壊れたのかと思った。

情報を探すと一年前のイシューが見つかった。

[2018-05-06 npm 5.7.1 pack/publish setting timestamp to epoch · Issue #19968 · npm/npm](https://github.com/npm/npm/issues/19968)

ハッシュ値がファイル日時だけで変わらないように「1970-01-01」にセットしたら問題があったので、都合悪くなくなるまでずらしたらしい(それでもトラブル発生した人がいるけど)。最近 npm を更新するまで気付かなかった。

これを書きながら「npm 5.7.1 pack/publish」で検索したらQiitaのエントリが見つかる。コメントまで読めば意図的な変更であることもわかる。

[`npm@5.7.[01]` で `npm pack` や `npm publish` して作成されるtgzのタイムスタンプがおかしいのでご注意ください - Qiita](https://qiita.com/abetomo/items/46568c6db3169da49c78)

さほど言及がないようで、目立ってメジャーな問題ではなかったのかな、と思った。


#結末

不具合ではなく意図的な動作なので、あとはこちらの問題しかない。
結局「提出されるパッケージが持つファイルの確認」はコマンド実行時のファイル一覧表示で済むし、
ファイルの日時は `scripts` の `prepublishOnly` でスクリプト実行させてチェックすればいい、というより別にやらなくていい(かつては気を付ける必要があった)ということになり、結果的に良くなった気がする。
mongodbの時間(ISODate)で〜以上を検索する

mongodbでcreatedやmodifiedの時間で「何時以上」と検索したいことがあると思います。

そのような時のクエリは以下のように記述します。

```sql
db.bonus_log.find({'created':{'$gte':ISODate("2019-05-08T18:05:23")}})
```

その他比較演算子は以下のようになります。

| sql記述 | mongodb記述 | 解釈 |
|:--|:--|:--|:--|
| >= | $gte | 以上 |
| > | $gt | より大きい |
| <= | $lte | 以下 |
| < | $lt | 未満 |
「コンピューターの開始時にページングファイル構成に問題が発生したため、一時ページングファイルが作成されました。全ディスクドライブの総ページングファイルサイズが指定したサイズよりも大きくなっている可能性があります。」

忘備録
まさかドライブレターをBにしたのが原因だったなんて…
Python(3)銘記その２

Python学習をやり直したので2.7と3.Xの文法上の違いを銘記します。

◆print文の書き方
Python2.7と3.Xで、括弧の有無に違いがあります。
例：a = 5　を出力するとき
 
Python2.7ではprint a
Python3.Xではprint(a)

◆整数の割り算の演算子
Python2.7と3.Xでは、結果が整数となる割り算の演算子が異なります。
例：a = 6　を2で割る
 
Python2.7ではprint a / 2 # 3と出力されます。
Python3.Xではprint(a // 2) # 3と出力されます。

Python2.7では整数の割り算に/を、Python3.Xでは整数の割り算に//を使用します。
他にも違いはありますが、ひとまず上記の2点を抑えれば大丈夫です。
Day007 webエンジニアへの道 - rails tutorial 第2章を完了 -

こんにちは。
webエンジニアを目指す[tomo](https://twitter.com/tomo_tech_)です。

エンジニアの勉強をしている日々の学びを記録しています。

私自身の頭の整理と今後迷った時のリファレンスも兼ねて書き連ねていきますが、同じようにエンジニア転職を考えている方の参考にもなればと考えています。
また、「ここ間違ってる！こっちが正しい！」といったご指摘もあれば頂けると嬉しいです🙏

#Day007のまとめ

**今日の気づき & 今後調べることなど**

- rails springとは何か？

- 第2章は大きくつまずくことなく完了できた。<br>（チュートリアルとscaffoldのおかげ...）

#特に学んだこと

###rails generateでエラーが発生した際の対応

rails generate scaffoldを実行したところ下記のエラーが発生。

```:commandline
/home/ec2-user/.rvm/rubies/ruby-2.6.0/lib/ruby/2.6.0/fileutils.rb:128:in `chdir': No such file or directory - getcwd (Errno::ENOENT)
```

どうやらRails Springというプロセスが起動していることが原因のよう。

`$ ps ax | grep spring` を実行して、表示されたプロセスIDを`$ kill -9 [プロセスID]`で削除。
その後にrails generate...とすればOK。

[参考]
[Rails generate error: No such file or directory - getcwd](https://stackoverflow.com/questions/28390149/rails-generate-error-no-such-file-or-directory-getcwd)

###ローカルサーバーのURLへアクセスができない場合の対処

![スクリーンショット 2019-05-09 23.50.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391565/8651612b-025d-2f3b-f963-45c307ee65a7.png)

画像右上の”pop out into new window”でページを開くとlivepreview（？）で表示されてしまい、そのまま末尾にURL(/user/newなど）を加えてもアクセスできないことがある。
その場合はURLの`/?_c9_id=livepreview...`を削除してからURLを付け加えればアクセス可能になる。

タブの `[B]` 以降をブラウザに直接入力してもOK。

##今日のひとこと

少しずつ順調に進められるようになってきたので、第3章以降もサクサク進めていきたいと思います。

---

twitterもやっているので、宜しければフォローお願いします！
[@tomo_tech_](https://twitter.com/tomo_tech_)
Pythonの都道府県のリスト

#生成コード
```prefec.py
import re
DATA = """
北海道
青森県
岩手県
宮城県
秋田県
山形県
福島県
茨城県
栃木県
群馬県
埼玉県
千葉県
東京都
神奈川県
新潟県
富山県
石川県
福井県
山梨県
長野県
岐阜県
静岡県
愛知県
三重県
滋賀県
京都府
大阪府
兵庫県
奈良県
和歌山県
鳥取県
島根県
岡山県
広島県
山口県
徳島県
香川県
愛媛県
高知県
福岡県
佐賀県
長崎県
熊本県
大分県
宮崎県
鹿児島県
沖縄県
"""

prefecture = re.findall(r'(\w+)\n',DATA)
print(prefecture)

```
#生成されたリスト
```['北海道', '青森県', '岩手県', '宮城県', '秋田県', '山形県', '福島県', '茨城県', '栃木県', '群馬県', '埼玉県', '千葉県', '東京都', '神奈川県', '新潟県', '富山県', '石川県', '福井県', '山梨県', '長野 '奈良県', '和歌山県', '鳥取県', '島根県', '岡山県', '広島県', '山口県', '徳島県', '香川県', '愛媛県', '高知県', '福岡県', '佐賀県', '長崎県', '熊本県', '大分県', '宮崎県', '鹿児島県', '沖縄県']
```
Surfingkeys で快適ネットサーフィン（前編）

# はじめに: この記事について

- キーボードでwebブラウジングしたい人向けの説明です
- キーバインドをカスタマイズ、便利な機能を追加して作業効率アップ

# Surfingkeys とは

- Chrome/Firefox の拡張です
  - キーバインドを設定したりコマンド入力ができるようになります
  - 極めればほぼマウスを触らずにブラウザの操作ができます
- JavaScript で設定を書くことができ、柔軟なカスタマイズが可能です
- インストールはこちらから
  - Chrome https://chrome.google.com/webstore/detail/surfingkeys/gfbliohnnapiefjpjlpjnehglfpaknnc
  - Firefox https://addons.mozilla.org/ja/firefox/addon/surfingkeys_ff/

※ 以降は Mac, Chrome を前提に書いていますが、他の環境でもおそらく動くと思います。

<!-- ## 動作イメージ

WIP -->

## 主な操作

デフォルトの動作です。好みにカスタマイズできます。

### スクロール

vimライクに移動できます

- `k` 上にスクロール
- `j` 下にスクロール
- `e` or `u` 画面半分上にスクロール
- `d` 画面半分下にスクロール
- `gg` ページの一番上にスクロール
- `G` ページの一番下にスクロール

### Omnibar

- `t` ブックマークと履歴を検索して開く
- `og` Google 検索
  - Open Google の略で覚える
  - もしくは `t` の後に `g` `スペース` で切り替え
- `oh` 履歴
- Omnibar内での操作
  - `↓` or `Tab` or `Ctrl-n`  次の候補へ
  - `↑` or `Shift-Tab` or `Ctrl-p` 前の候補へ
  - `Enter` 別タブで開く
  - `Ctrl-Enter` バックグラウンドの別タブで開く

### マウス操作の代わり

- `f` Follow links モードへ
  - 続けて出てくる文字を打つとリンクを開くことができる
    - input の場合はフォーカス
    - Shiftキーを押しながら打つと別タブで開く
- `cf` Follow links モードへ: バックグラウンドの別タブで開く
  - 例えばGoogleの検索結果のページを複数開きたいときなどに使えます
- `i` input要素にフォーカス
- Esc キー でやめる

### 検索

- `/` ページ内検索
  - vimと同じ
  - 単語を入力してEnterで確定
    - `n` で次の検索結果へジャンプ
    - `N` で前の検索結果へジャンプ
- Esc キー でやめる

### タブ操作

- `E` 左のタブへ
- `R` 右のタブへ
- `x` タブを閉じる
- `X` 最後に閉じたタブを開く

### ヒストリー操作

- `S` 戻る
- `D` 進む

### 他

- `yy` クリップボードにURLをコピー
- `?` すべてのショートカットキーを表示
- `Alt-s` 一時的にSurfingkeysを無効にする

## いろいろできるぞ Surfingkeys

機能が多すぎてあまり把握できていないですが便利そうと思ったものを紹介

詳しい説明は https://github.com/brookhong/Surfingkeys にあります。

- `T` で タブを切り替え
- `v` Visual mode
  - 更に `v` を押して Range mode（選択）
  - ※ 下記の操作はマウスで範囲選択してもできます
    - `y` でクリップボードにコピー
    - `sg` で ググる
    - `sG` で Omnibarを開く
  - 更に `v` で Normal mode に戻る
- `sm` Markdown preview
  - クリップボードにあるMarkdownテキストをプレビューできる
  - HTML コードをコピーできる
- `yg` 画面キャプチャ
  - マウス→右クリックで画像を保存する必要あり
- 2文字以上のコマンドは1文字目を打ったら右下にヘルプメッセージが表示される
  - 忘れても思い出しやすい
- PDFの閲覧も一部キーバインドが使える

## カスタマイズについて

[Surfingkeys で快適ネットサーフィン（後編） - Qiita](https://qiita.com/hush_in/items/653624cf5c516d3143a3) へ
Docker + nginx のベースイメージの書き方


## Dockerfile

```Dockerfile
FROM nginx:1.15.12-alpine

# Install gettext 
RUN apk --no-cache add bash libintl perl curl && \
    apk --no-cache add --virtual .build gettext && \
    cp /usr/bin/envsubst /usr/local/bin/envsubst && \
    apk del .build 

ENV NGX_PORT 80
ENV NGX_HOSTNAME _
ENV NGX_LOG_LEVEL warn
ENV NGX_ACCESS_LOG_ENABLED 0 

ADD nginx /etc/nginx/
ADD root /root/

CMD ["sh", "-c", "/root/scripts/docker_start"]
```

## `/root/scripts/docker_start`

```bash
#!/usr/bin/env bash 

# Inject EnvVars
files=`find /etc/nginx -type f -name "*.template"`

for file in $files; do
  envsubst "$(printf '${%s} ' ${!NGX_*})" < $file | tee $file.dist
done

# Replace configured settings
dists=`find /etc/nginx -type f -name "*.template.dist"`
for dist in $dists; do
  mv -v "$dist" "${dist/.template.dist/}";
done

nginx -g "daemon off;"
```

## `/etc/nginx/conf.d/default.conf.template`

```nginx
server {
    listen       ${NGX_PORT};
    server_name  ${NGX_HOSTNAME};

    access_log /var/log/nginx/access.log main if=${NGX_ACCESS_LOG_ENABLED};

    # For Healthcheck
    location /_status {
      access_log off;
      return 200 'ok';
    }

    location / {
      root   /usr/share/nginx/html;
      index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
}

```

## あとがき

- bashじゃないと `${!NGX_*}`とかできないので注意。
- `NGX_` じゃなくても大丈夫。
- bash + envsubstが快適
unityでrayをcollider裏面に当てる方法

Physics.queriesHitBackfaces = true;
↑このAPIを使えばいい！
5.5からのAPIです。



テスト結果：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403926/ac2df530-d97d-74ec-8124-e34fd3a721ae.png)


```C#:Shooter.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Shooter : MonoBehaviour
{
    public GameObject testBox;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        Physics.queriesHitBackfaces = true;
        RaycastHit hit;
        if(Physics.Raycast(transform.position,transform.forward,out hit,1000)){
            Instantiate(testBox,hit.transform.position,Quaternion.identity);
        }
    }
}

```
requireは実行ディレクトリからの相対パス

## 2019/5/14 追記
タイトルがガバガバなのでコメント欄でご指摘をいただきました。
ただただ感謝するとともに、そちらもご覧くださいませ〜。

## 環境

読んでる本：たのしいRuby 4版
Ruby : ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-darwin18]

## requireにハマる

別ファイルを「require」で読み込みたかった。
ファイル構成とサンプルコードはこんな感じ。

```terminal:tree
.
└── tanoshii_ruby
    ├── main.rb
    └── sub.rb
```

```Ruby:main.rb
require './sub'
goodnight()
```

```Ruby:sub.rb
def goodnight
  puts 'good night, world'
end
```

この状態で実行すると、

```terminal:termial
$ ruby tanoshii_ruby/main.rb
Traceback (most recent call last):
        2: from tanoshii_ruby/main.rb:1:in `<main>'
        1: from 
       (中略)
 `require': cannot load such file -- ./sub (LoadError)
```

あるぇ？？

## 「実行ディレクトリ + requireに指定された相対パス」が有効

もしや…と思いつつ、main.rbのディレクトリに移動してから再実行すると成功。

```terminal:terminal
$ cd tanoshii_ruby/
$ ruby chapter-03.rb
goodnight, world
```

ということで、requireは「実行ディレクトリ + requireに指定された相対パス」で評価してるみたい。
実行するときにハマらないよう気をつけよう。

## おまけ：ファイルからの相対パスはrequire_relative

ディレクトリ移動しなくても、requireをrequire_relativeにすることでファイルからの相対パスでイケる。
なんにも考えずに書きたければこっちの方が無難かな。

```Ruby:main.rb
# require './sub'         # => LoadError
require_relative './sub'  # => OK!
goodnight()
```
Greenの定理の証明

これが一番楽だと思います（多分）

##証明

任意の閉領域$\Omega$について、その境界を$\Gamma$とし、$\boldsymbol{n}$を$\Gamma$上の外向き法線ベクトルとする。この時、まず次のGaussの発散定理が成り立つ。

```math
  \int_\Omega \nabla \cdot \boldsymbol{A} d\Omega 
    = \int_\Gamma \boldsymbol{A} \cdot \boldsymbol{n} d\Gamma
```

また、$f$,$g$をスカラー関数とすると、ナブラの分配法則$\nabla(fg) = g\nabla f +f\nabla g$より、次式が成り立つ。

```math
  \int_\Omega \nabla \cdot [\nabla f(\boldsymbol{r}) g(\boldsymbol{r})] d\Omega
    =  \int_\Omega [\nabla^2 f(\boldsymbol{r})] g(\boldsymbol{r}) d\Omega
       +\int_\Omega \nabla f(\boldsymbol{r}) \cdot \nabla g(\boldsymbol{r}) d\Omega
```

上式の左辺にGaussの発散定理を適用すると、次のようになる。

```math
  \int_\Gamma [\nabla f(\boldsymbol{r}) g(\boldsymbol{r})] \cdot \boldsymbol{n} d\Gamma
    =  \int_\Omega [\nabla^2 f(\boldsymbol{r})] g(\boldsymbol{r}) d\Omega
       +\int_\Omega \nabla f(\boldsymbol{r}) \cdot \nabla g(\boldsymbol{r}) d\Omega
```

この式を、Greenの定理という。
Eulerの公式の証明

これが一番楽だと思います（多分）

##証明

複素数平面における単位円上の複素数$z$は、次のように書ける。

```math
  z  =  \cos \theta  +i \sin \theta
```

両辺を$\theta$で微分すると、

```math
  \frac{dz}{d \theta}  =  -\sin \theta  +i \cos \theta  =  iz
```

変数分離すると、

```math
  \frac{1}{z} \frac{dz}{d \theta}  =  i
```

両辺を$\theta$で積分すると、

```math
  \int \frac{1}{z} \frac{dz}{d \theta} d \theta  =  \int \frac{1}{z} dz  =  \int i d \theta
  \\
  \log_e z  =  i \theta
  \\
  z  =  e^{i \theta}
```

よって、

```math
  e^{i \theta}  =  \cos \theta  +i \sin \theta
```

この式を、オイラーの公式という。
ゲームサーバーで使われる暗号技術ってどんなの？


第三回は暗号に関するお話をします。
ゲームサーバーを設計する上でも暗号の知識は不可欠です。
Game Server Services では適切な箇所で適切な暗号技術を採用するよう努力をしています。

どういった暗号技術があり、どういう場面で使用できるのかを正しく把握して、安全なサーバーシステムを開発しましょう。

# 前回

[ゲームサーバーで使うデータベースってどんな種類があるの？](https://qiita.com/kazutomo/items/69a4900ae529b752342d)

# 暗号技術の種類

暗号技術には大きく3種類の用途が存在します。

* 暗号化
* ハッシュ化
* 署名

# 暗号化

暗号化はデータをスクランブルし、データの内容を隠す目的で使用します。
正しい手段を用いれば、データの復元ができるのが暗号化です。なお、復元処理を復号と呼びます。復号化と呼ぶと復号化警察によって鉄槌がくだされます。

暗号化には複数の方式があります。

１． 共通鍵暗号
２． 公開鍵暗号

## 共通鍵暗号

共通鍵暗号は暗号化するときと復号するときで同じ暗号鍵を使用します。
古くはビット演算のXORから、RC4、最近であればAESといったアルゴリズムが使用されます。

同じ暗号鍵を使用するということは、復号できる人は暗号化も出来るということになります。
つまり、ゲームのデータの改竄行為を回避するために暗号化したい。というニーズに対して、共通鍵暗号を使用するのは愚策です。
なぜなら、改ざんしたデータを再び暗号化すれば、ゲームからは改ざんされたデータなのか判断がつかないからです。

共通鍵暗号方式を使う場合は、暗号化する側と復号する側がお互いに信頼できる関係である必要があります。
主にサーバー間通信や、ゲームであればマルチプレイのプレイヤー間通信の保護に使用する。といった用途が適切です。

## 公開鍵暗号

公開鍵暗号は暗号化する暗号鍵と、復号する暗号鍵が別のものを使う。というのが特徴です。
暗号化に使用する暗号鍵を秘密鍵、復号に使用する暗号鍵を公開鍵と呼びます。このような仕組みから公開鍵暗号と呼ばれます。非対称鍵暗号とも呼ばれます。
つまり、復号できても暗号化することはできませんので、正しく復号できるデータを送信してくる相手は信頼に値する。ということになります。

## 暗号鍵の鍵長

暗号鍵には鍵長が存在します。
AES256 RSA1024 RSA2048 といったキーワードを見たことがあるかもしれません。これは前半が暗号アルゴリズム、後半が鍵長を表しています。
AES256 であれば AESアルゴリズムで 256bit の鍵長の暗号鍵を使用して暗号化している。という意味になります。

どの鍵長を使用するべきか。という方針は年々変化します。
これは時の流れでコンピューティングの速度が早くなり、暗号解読にかかるコストが安くなっていくためです。

## 暗号強度と鍵交換

共通鍵暗号に対して公開鍵暗号の方が鍵長が長くなります。なぜなら、公開鍵暗号の仕様を実現するために共通鍵と同じ鍵長であれば、暗号強度が弱くなってしまうためです。
また、暗号化・復号処理に要する計算量も公開鍵の方が多くなります。

そのため、時間経過やアクセスしてきたプレイヤーごとに異なる共通鍵を使用して通信するようにし、接続した際に共通鍵の暗号鍵を秘密鍵で暗号化したデータをサーバーから配布し、プレイヤーは受け取とったデータを公開鍵で復号した後に、出てきた共通鍵を用いて以降の通信を行う。というような使い分けをします。
みなさんがよく使うWebサイトの https から始まるサイトに接続する際にも同様の処理が行われています。

# ハッシュ化

ハッシュポテトを想像してもらえばわかるように、一定の法則に従ってデータをスクランブルして全く異なる値にしてしまいます。
ハッシュ化は暗号化とは異なり、データを元に戻すことはできません。
ハッシュドポテトを丸いじゃがいもに戻せないのと同じです。

この技術の使い所として、よくある例はパスワードの管理です。
よくパスワードが流出した。とニュースになりますが、正しくパスワードを取り扱っていれば、これは大した問題ではありません。

パスワードを保存するのに暗号化は不適切です。なぜなら元の形に戻せてしまうからです。
パスワードの保存には元に戻すことができないハッシュ化したデータを保存するようにするべきです。
パスワードを検証する場合には受け取ったパスワードを同じハッシュ関数を通して、保存した値と一致するかを検証すればいいわけです。

ここにも気をつけなければならない点があって、世の中には一般的な文字列や、流出したパスワードをハッシュ関数にかけた結果の一覧表が出回っているということです。これをレインボーテーブルと呼びますが、ただ一般的なハッシュ関数をかけただけでは、レインボーテーブルと突き合わせれば元のデータを特定される可能性があります。
このあたりは、何回もハッシュ関数にかける。ソルトをつける。など工夫がありますのでパスワードを取り扱う際にはよく調べた上で実装しましょう。
まちがえても平文（そのままのデータ）で保存しないように！

# 署名

暗号化やハッシュ化は元のデータを隠したり、不可逆な状態にすることが目的でした。
署名はデータ自体は読める状態を維持しつつ、改ざんされていないことを保証するための仕組みで、データ本体に追加して暗号鍵を使って検証できるデータ本体のハッシュ値をおくります。

署名は一般的に公開鍵暗号方式と組み合わせて使用します。
これは署名を検証するための暗号鍵と、署名を付与するための暗号鍵が同一になってしまうと署名の意味を成さないからです。
署名をつける側は秘密鍵を使ってデータに署名を付与し、署名を検証する側は公開鍵を使って署名を検証する。ということになります。

データ本体を改ざんするとハッシュ値が合わなくなるため、改ざんを検出できるうえに、改ざん後の値を元に署名を偽造しようと思っても秘密鍵を知らなければ作れない。というわけです。

ゲームサーバーではアセットを配布する際にアセットデータが改ざんされていないことを保証する署名を付けておき、クライアントは受け取ったアセットデータの署名を検証することで、悪意のあるアセットに差し替えられていないかを判定したりするのに使ったりします。

# GS2のご紹介

Game Server Services では ゲームサーバーのレンタルをおこなっています。

[個人からプロまで使えるゲームサーバー - Game Server Services(GS2)](https://gs2.io)

それでは、また。

# 次回予告

ゲームサーバーはなぜ落ちるのか
5/9 　勉強の記録　Ruby　アクセッサーメソッド

**アクセサメソッド**
インスタンス変数の値を読み書きするメソッドのこと。

**インスタンスメソッド**
メソッドは実行する一連の処理をまとめたもの。
ただし、通常のメソッドがプログラム中からいつでも呼び出せるのに対してクラス内に記述されたメソッドはクラスから作成されたオブジェクトしか呼び出すことが出来ない。このようなメソッドをインスタンスメソッドと呼ぶ（Let'sプログラミングより参照）

`Car.new`の`.new`はインスタンス変数ではない。クラスに対して実行するものなので、クラスメソッドと呼ばれる。

```rb

class Car
 def initialize(name)
  @name = name
 end
 
 def hello
  puts "Hello! I am #{@name}."
 end
 
 def name 
  @name
 end
 
 def name=(value)
  @name = value
 end
end


car = Car.new('Kitt')
puts car.name
car.name = 'hogehoge'
puts car.name
car.name = 'gehogeho'
puts car.name
```
インスタンス変数は外部からは書き換えられるようにできていないが、アクセッサーメソッドはそれをできるようにするもの。（だと今の所認識している）

上記を実行すると、
`Kitt
hogehoge
gehogeho`
と出力される。

```
 def name=(value)
  @name = value
 end
```
とすることで、のちに@nameを外部から変更することができる。


**アクセッサーメソッド**

```rb
def name 
  @name
 end
 
 def name=(value)
  @name = value
 end
```
ここでは`name`や`name=`がアクセッサーメソッド。


**attr_accessor**
`class Car` の下に
`attr_accessor :name`
と書き加えることで

```rb
def name 
  @name
 end
 
 def name=(value)
  @name = value
 end
```
を省略できる。(attr_accessorはアクセッサーメソッドではない。アクセッサーメソッドを定義してくれるメソッドである）
こっちの方が楽。

```rb
class Car
 attr_accessor :name
 #attr_reader :name
 #attr_writer :name
 def initialize(name)
  @name = name
 end
 
 def hello
  puts "Hello! I am #{@name}."
 end
 
 # def name 
 #  @name
 # end
 
 # def name=(value)
 #  @name = value
 # end
end

car = Car.new('Kitt')
puts car.name
car.name = 'hogehoge'
puts car.name
car.name = 'gehogeho'
puts car.name
```

他にも
`attr_reader :〇〇` ←　読む専門
`attr_writer :〇〇` ←　書く専門
といったものもある。
バージョン管理の方法

# バージョン管理（は大切らしい）
- 昨日購入した書籍には`/usr/local`配下に`go`ディレクトリを作成し、さらにバージョンごとにディレクトリを作成。必要応じてシンボリックリンクを切り替える事でバージョンを切り替えを行い管理出来ると書いてあった
- 前職の上司が「開発するバージョンによって動作がまったく違うので、バージョン管理は凄く大切！」と力説された事がある。エンジニアとして尊敬する人だったので、今でもそれははっきりと覚えている事からバージョン管理を調べてみた
- 今回インストールした`snap`という方法では簡単にバージョンを切替える事が出来るらしい。参照元は[ココ](https://hnakamur.github.io/blog/2018/05/06/install-latest-version-of-golang-using-snap-on-ubuntu/)です。（情報ありがとうございます）
- まず`go version`コマンドで既存バージョンを確認

```
$ go version
go version go1.12.2 linux/amd64
```

- 切り替えたいバージョンを`snap info go`で参照。なお、最終行に今インストールされているバージョンが表示されている（installedのところ）

```
name:      go
summary:   Go programming language compiler, linker, stdlib
publisher: Michael Hudson-Doyle (mwhudson)
contact:   michael.hudson@ubuntu.com
license:   unset
description: |
  This snap provides an assembler, compiler, linker, and compiled libraries for the Go programming
  language.
commands:
  - go
  - go.gofmt
snap-id:      Md1HBASHzP4i0bniScAjXGnOII9cEK6e
tracking:     stable
refresh-date: 5 days ago, at 20:49 JST
channels:
  stable:         1.12.5        2019-05-08 (3739) 92MB classic
  candidate:      ↑
  beta:           ↑
  edge:           devel-f766b68 2019-05-09 (3749) 92MB classic
  1.12/stable:    1.12.5        2019-05-08 (3739) 92MB classic
  1.12/candidate: ↑
  1.12/beta:      ↑
  1.12/edge:      ↑
  1.11/stable:    1.11.10       2019-05-08 (3730) 82MB classic
  1.11/candidate: ↑
  1.11/beta:      ↑
  1.11/edge:      ↑
  1.10/stable:    1.10.8        2019-01-24 (3133) 58MB classic
  1.10/candidate: ↑
  1.10/beta:      ↑
  1.10/edge:      ↑
  1.9/stable:     1.9.7         2018-06-13 (2117) 58MB classic
  1.9/candidate:  ↑
  1.9/beta:       ↑
  1.9/edge:       ↑
  1.8/stable:     1.8.7         2018-02-07 (1407) 51MB classic
  1.8/candidate:  ↑
  1.8/beta:       ↑
  1.8/edge:       ↑
  1.7/stable:     1.7.6         2017-06-02  (324) 48MB classic
  1.7/candidate:  ↑
  1.7/beta:       ↑
  1.7/edge:       ↑
  1.6/stable:     1.6.4         2017-05-17  (122) 49MB classic
  1.6/candidate:  ↑
  1.6/beta:       ↑
  1.6/edge:       ↑
installed:        1.12.2                   (3584) 92MB classic
```

- `sudo snap refresh --classic --channel=切り替えたいバージョン`で切り替えが出来る（切り替えたいバージョンはインストールされる）
- 余談だが最後に`go`を付けないと以下エラーが表示されて切り替え不可になるので注意

```
error: a single snap name is needed to specify mode or channel flags
```

- 切り替え実施

```
$ sudo snap refresh --classic --channel=1.10/stable go
go (1.10/stable) 1.10.8 from Michael Hudson-Doyle (mwhudson) refreshed
```

- インストール（切り替え）完了後にバージョンを見るとちゃんと指定したバージョンに切り替わっている。う〜ん凄いぜsnapコマンド！

```
$ go version
go version go1.10.8 linux/amd64`
```

- 余談だ`sudo snap refresh --classic --channel=stable`で最新の安定板にすると、再度DLが始まり最終的に最終バージョンがインストールされる

```
$ sudo snap refresh --classic --channel=stable go
go 1.12.5 from Michael Hudson-Doyle (mwhudson) refreshed
$ go version
go version go1.12.5 linux/amd64
```

# 【余談】クラウドでやりたい

- オンプレミス（あまり好きな表現ではない）でやると、設置場所にいないと出来ないのは21世紀には歯痒い
- なんやかんあるけど、結局クラウドでやればいいのでは？
- そんなこんなで明日はGCPでインスタンス構築してみようと思う
- 脱線しないように注意しましましょう
【Django】通勤中に書籍で学んだこと(デフォルトのDBトランザクション)

##経緯
最近通勤中に読んでる以下の書籍から学んだことをピックアップします。
https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Django-%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8%E3%80%8A%E5%9F%BA%E7%A4%8E%E7%B7%A8%E3%80%8B-%E6%A8%AA%E7%80%AC-%E6%98%8E%E4%BB%81/dp/4802094744

##DjangoのデフォルトのDBトランザクション
Djangoではモデルクラスのモデルマネージャ(objects)を経由してDBとクエリ(SQL文)をやり取りします。
そして、**モデルマネージャでクエリを実行した場合、発行されたSQLがDDLであったとしてもその時点でDBに反映(commit)される**とのことです。
これは存じておりませんでした。。

極端な例ですが、以下のようになるそうです。

```python:views.py
# import省略

def update(request):
    # 処理省略
    TableA.objects.save() # この時点でコミット
    TableB.objects.delete() # この時点でコミット 
    
    raise Exception # 例外発生 
    # ここまでに実行されたクエリはテーブルへ反映済み。ロールバックされない。
    # 処理省略
```

しかし、settings.pyの「DATABASES」にプロパティを追加すると挙動が変わるとのことです。

```python:settings.py
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mydb',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '127.0.0.1',
        'PORT': '3306',
        'ATOMIC_REQUESTS': True, # これを追加
    }
}
```

上記設定により1リクエスト単位でトランザクションが管理されるようになります。

```python:views.py
# import省略

def update(request):
    # 処理省略
    TableA.objects.save()
    TableB.objects.delete()
    # 処理省略
    # リクエスト内で例外が発生しなかった場合はトランザクションがcommitされる
```

##まとめ
今後、ログ出力機能を現在開発中のアプリケーションに埋め込んで実際に挙動が変化する旨を確認してみようと思います。
本日は書き溜めのみ。
Jakarta EE 開発者アンケート 2019

2019年3月に、Eclipse Foundationで実施した、Jakarta EE開発者アンケートの結果が公開されました。
https://jakarta.ee/documents/insights/2019-jakarta-ee-developer-survey.pdf


本稿では、生データをもとに、いくつかの質問と回答を紹介します。

#Q8 使用しているJava SEのバージョンは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139252/12ee5fca-179b-08cb-1463-190bbd3fbc95.png)


Java8が83.76%で１位。2018年もJava8が86.87%でした。
2018年との違いは、Java7が45.26%から24.51%にダウンした一方で、Java11が20.05%で３位に浮上。

#Q9 使用しているJava EEのバージョンは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139252/ab139ebe-6930-2345-90a2-ec49b726a48d.png)

Java EE 7が44%(2018年は56.29%)で１位は変わりませんが、Java EE 8が37%で２位に浮上。

#Q14 Jakarta EEをクラウドネイティブに適するためには？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139252/e60f3a90-43ac-dd21-dd16-eb74dd7d9c31.png)

2018年より選択肢が増えていましたが、
１位Better support for microserviceと、２位Native Integration with Kubernetsは変わらず。
３位にProduction quality reference implementationが、2018年の４位から浮上。


#Q16 クラウドネイティブで使用する言語・ランタイムは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139252/4ba4808b-7fe4-7b83-dd62-0abf371501d3.png)

傾向は、2018年とほぼ変わらず。


#Q17 クラウドネイティブで使用するフレームワークは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139252/bf87140a-6208-c04c-b6a1-5a0cf658cb20.png)

2018年は、「マイクロサービスで使用するフレームワーク」という質問でしたが、
１位Spring、２位Kubernetesはの順位は変わらず。
３位はMicroProfile(28%)で、2018年の7位(14.68%)から大きく浮上。


#Q20 クラウドネイティブ技術の重要なものは？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139252/5b7b1c6e-32fc-1950-f2e0-71be17af18aa.png)

重み付け平均では、ほぼ3から4くらいの幅に入っていますが、
「NEVER HEARD OF IT」と回答した人は、
Bootiqueで47.04%、Envoyで41.68%、Knativeで35.76%と、
Java開発者にはなじみがないのかもしれません。


#サマリ
クラウドネイティブが重要視されていることは、2018年と大きく変わっていません。
中でも、Spring/Spring Bootはクラウドネイティブのリーディングを維持する一方で、
MicroProfileの利用が大きく増えたて来たことが注目されます。
Java SEは、依然Java 8が主流ですが、Java 11が少しずつ普及してきたように見えます。
【Unity】ZenjectをImportするとエラーが出る

# 概要
ZenjectをAsset StoreからImportすると出現するエラーを、**強引**に解決する方法を書きました。

# 環境
Unity 2019.1.0f2 personal
Zenject 7.3.1

# 問題
ZenjectをAsset StoreからImportすると、以下のようなエラーが出ます。
> Assets/Plugins/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/Ship.cs(41,16): error CS0246: The type or namespace name 'ParticleEmitter' could not be found (are you missing a using directive or an assembly reference?)

> Assets/Plugins/Zenject/OptionalExtras/SampleGame1 (Beginner)/Scripts/Ship/Ship.cs(18,9): error CS0246: The type or namespace name 'ParticleEmitter' could not be found (are you missing a using directive or an assembly reference?)

<img width="716" alt="スクリーンショット 2019-05-09 午後2.39.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/164430/00458946-d9e6-41c9-9766-bca80ad3441a.png">

'ParticleEmitter'というnamespaceが見当たらない、という内容のエラーです。

# 原因
ParticleEmitterがUnity 2018.1 以降廃止されていることが原因です。

# 解決方法
強引な解決方法ですが、
Assets > Plugins > Zenject > OptionalExtras
を開き、SampleGame1(Beginner)を削除します。


# 参考文献
[UnityEngine.ParticleEmitter - Unity スクリプトリファレンス](https://docs.unity3d.com/ja/2017.1/ScriptReference/ParticleEmitter.html)

[Unity2018で旧来のパーティクルがエラーになる](https://dennou-note.blogspot.com/2018/09/unity2018.html)
【メモ】gemとbundler

<details>
<summary>前置き</summary>
本日はプログラミング初学者がRuby/Ruby on Railsの学習を進める上でのノートです。
もし「この表現は誤っている」、「理解の仕方がおかしい」などありましたらご教示いただけると幸いです。  
</details>

# gemとは？

rubyで使われるサードパティのライブラリ。
主に[rubygems.org](https://rubygems.org/)で公開されている。
他にも便利な検索サービスがあるみたい。
[参考：RubyGemsの探し方](https://qiita.com/vzvu3k6k/items/5317a822f58b0a6a1d70)

# RubyGemsとは？

> Ruby言語用のパッケージ管理システムであり、Rubyのプログラムと（"gem" と呼ばれる）
ライブラリの配布用標準フォーマットを提供している。gemを容易に管理でき、gemを配布するサーバの機能も持つ。
[wikipedia:RubyGems](https://ja.wikipedia.org/wiki/RubyGems)

gemコマンドのこと。
bundler、railsのinstall位でしか使ったことことがないので知りませんでした。
とはいえinstallは基本bundlerで行うので、gem作らないとあまり使う機会はなさそう。

# bundlerとは？

プロジェクト内で使うgemを管理するしくみ。
Gemfileというファイルを作成し、その中にgemを記述すると一括インストールできる。
またgem毎に使用するバージョンを指定[^1]できたり、導入環境を指定[^2]できたりする。


[^1]: 指定しない場合は最新のバージョンを利用する。
[^2]: 特定のステージ(test/development/production)のみに適用できる。
Route 53 の プライベートホストゾーンと外部の DNS を併用して使う場合の注意点

# やろうとしたこと

VPC 内の特定のインスタンスに対して、VPC 外部からも内部からも 設定した DNS で名前解決させたい

## 具体的な設定

- サーバの状態
    - EC2 (in VPC)
        - private ip 10.0.0.1
        - public ip 1.1.1.1
    - AWS外のサーバ
        - public ip 1.1.1.2

- パブリックな DNS (事情があり Route 53 ではない)
    - **example.com** の DNS サーバ
    - 設定レコード
        - hoge.example.com
            - A レコード 1.1.1.1
        - fuga.example.com
            - A レコード 1.1.1.2

- Route 53 (Private host zone in VPC)
    - **example.com** の DNS サーバ
    - 設定レコード
        - hoge.example.com
            - A レコード 10.0.0.1


# 問題となったこと

ここで問題となったのが、 `EC2 (in VPC)` から `fuga.example.com` への名前解決ができなくなりました。

パブリックゾーン プライベートホストゾーン が Route 53 であれば、名前空間が重複している場合、特に意識することなく `リクエストをパブリック DNS リゾルバーに転送` してくれるのですが、パブリックな DNS が Route 53 ではない DNS サーバを使っているのであれば、Route 53 からは外側に重複する名前空間があるか判定できないため、Route 53 から パブリックな DNS に問い合わせることもなく、名前解決に失敗します。

冷静に考えれば、そうなることに気づけるのですが、それによって焦った経験をしたので、メモとして残しておきます。

Route 53 と 外部の DNS を使う場合、重複した名前空間を使うのはやめておきましょう。

※ 参考記事 [プライベートホストゾーンを使用する場合の考慮事項](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/hosted-zone-private-considerations.html)
ASMのディスク使用量の確認

1. gridユーザーに切り替える
2. asmcmd lsdg
3. Usable_file_MBの値が残り使用できるディスク容量となる。

##マニュアルリンク
lsdg
https://docs.oracle.com/cd/E16338_01/server.112/b61035/asm_util004.htm#BABHHCBH`
Android Studio / IntelliJ IDEAにフォントを利用できるようにする(Windows 10)

Windows 10の環境で、「Myrica」、「SourceHanCodeJP」などプログラミング向けのフォントファイルに右クリックして、「Install for all users」を選択して、`%windir%/fonts`にインストールすれば、IDEのセッティングに選択できるようになります。

以前、フォントファイルをダブルクリックしただけはWindowsのUserのダイレクトリーにインストールしたので（例えば`C:\USERS\YOURNAME\APPDATA\LOCAL\MICROSOFT\WINDOWS\FONTS`）、IntelliJが認識できず、それを選択不可になっていました。

以上です。Hope this helps.
UnityのInputFieldのtextを取得する方法

## UnityのInputFieldのtextを取得する方法
onValueChangedや、onEndEditに関する情報が多く見られますが、次のように単純に取得することができます。

```c#
GameObject inputField = GameObject.Find("InputField");
InputField input = inputField.GetComponent<InputField>();
Debug.Log(input.text); //textが出力される
```
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
ありがとうございました。
はじめてのC++ 【46日目】

# はじめに
ブロック崩しとりあえず完成を目指す。でも今日はロベールするで。
## ロベールのC++
### クラスのテンプレート
関数のテンプレートは、 `int型` `double型`　などの制限を受けずに関数に値を入れる事ができる。という便利な機能のことであった。 
クラスのテンプレートは、どのような恩恵を受けることができるのであろうか？
とりあえず書いてみる。

```cpp:Array.h
#ifndef ARRAY_H
#define ARRAY_H

#include <iostream>
#include <algorithm>
#include <cstdlib>

template <typename TYPE>
  class Array {
public:
  //引数付きコンストラクタ
  Array( int size );
  //コンストラクタ
  Array( const Array& other );
  //operator関数 =　を定義
  void operator = ( const Array& other );
  //デストラクタ
  virtual ~Array();
public:
  TYPE Get( int i ) const;
  void Set( int i, TYPE value );

public:
  //配列のサイズを返す
  int Size() const;

private:
  //インデックスのチェック
  void CheckIndex( int i ) const;

private:
  //動的配列
  TYPE* m_array;
  //配列の要素数
  int m_size;

  };

  template <typename TYPE>
    Array<TYPE>::Array( int size )
  {
    m_array = new TYPE[ size ];
    m_size = size;
  }

  template <typename TYPE>
    Array<TYPE>::Array( const Array& other )
  {
    m_size = other.m_size;
    m_array = new TYPE[ m_array ];
    std::copy( other.m_array, other.m_array + m_size, m_array );
  }

  template <typename TYPE>
   void Array<TYPE>::operator = ( const Array& other )
  {
    TYPE* array = new TYPE[ other.m_size ];
    delete[] m_array;
    m_size = other.m_size;
    std::copy( other.m_array, other.m_array + m_size, m_array );
  }

  template <typename TYPE>
    Array<TYPE>::~Array()
  {
    delete[] m_array;
  }

  template <typename TYPE>
   TYPE Array<TYPE>::Get( int i ) const
  {
     CheckIndex( i );
     return m_array[ i ];
  }

  template <typename TYPE>
   void Array<TYPE>::Set( int i, TYPE value )
  {
     CheckIndex( i );
     m_array[ i ] = value;
  }

  template <typename TYPE>
   int Array<TYPE>::Size() const
  {
     return m_size;
  }

  template <typename TYPE>
   void Array<TYPE>::CheckIndex( int i ) const
  {
    if( 0 <= i && i < m_size ){
      //正常
    }else{
      std::cerr << "インデックスが不正" << std::endl
                << "値 : " << i << std::endl;
      std::exit(EXIT_FAILURE);
    }
  }

#endif
```
```cpp:classtemp.cpp
#include "Array.h"
#include <iostream>

int main() {
  Array<int> array(5);
  std::cout <<  array.Size() <<std::endl;


  for(int i = 0, size = array.Size(); i < size; ++i ) {
    array.Set(i, i * 2);
    std::cout <<  "あああ" <<std::endl;
  }

  for(int i = 0, size = array.Size(); i < size; ++i ) {
    std::cout << array.Get(i) << ' ';
  }

  std::cout << std::endl;
}
```
```:実行結果
エラーでないけどなにも出力されなかった。
どこかが間違ってるっぽい。また明日探す。
実際には↓のように表示される予定。
0 2 4 6 8
```
書いていて思ったのだが、 `<array>`　や `<vector>`　ってこうやって作られているのだなと思いました。
自分で、便利な機能を追加するためには、templete機能は必須だと感じた。
そういえば、ブロック崩しの `Vector2Dクラス`　のテンプレートを実装しようとしたが忘れていた。
明日時間がれば実装してみる。
# 終わりに
テンプレートってcppファイル書かないのね。
【Rails】assets:precompileは成功しているのにpumaを起動してもimageもjsもcssもNotFound（RAILS_SERVE_STATIC_FILESの話）

# この記事は
Railsのproduction環境では`rails assets:precompile`でアセット（imageやjsやcssなど）をコンパイルしておくことになっています。
何も気にせずに`rails assets:precompile`をすると`public`ディレクトリ配下に確かにコンパイルされたアセットが格納されるのですが、`puma`でアプリを起動してサイトを開いても反映されていないということがおきます。

それに困った時のメモです。

# 環境
一応、この記事は以下の環境で試しています。

- ruby 2.6.5
- rails 6.0.2

# 何が起きているのか
そもそもなんで僕らは`assets:precompile`をしているのだろう...

これはRailsガイドさんのサイトがわかりやすいのでそちらを参考に。=>[アセットパイプライン - Railsガイド](https://railsguides.jp/asset_pipeline.html)

で、面白いことが書いてあります。

> Sprocketsは、production環境では前述のフィンガープリントによるスキームを使用します。デフォルトでは、Railsのアセットはプリコンパイル済みかつ静的なアセットとして**Webサーバーから提供される**ことが前提になっています。

なんとこれ、Webサーバーから提供されることが前提になっている。
Webサーバーって言うのは代表的なものだと[Apache](https://httpd.apache.org/)とか[NGINX](https://www.nginx.com/)とかそういうやつです。
コンパイルしたファイルをWebサーバー自体に持たせたり、S3などのクラウドストレージに置いておきWebサーバーがそれを参照するように構成されているらしく、
Railsアプリの`public`ディレクトリを直接参照することはできないようにさせているようです。

で、この`public`ディレクトリを直接参照することをさせない設定は

```ruby:config/environments/production.rb
# 略
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
# 略
```
に書かれています。コメントアウトを読むと「`public`ディレクトリ（フォルダ）から静的なファイルを提供していない」とのこと。

# 対応
ここまでくれば対応は簡単です。`config.public_file_server.enabled`が`true`になるようにすればいいです。

## 対応１
単純に`config/environments/production.rb`を書き換えます。

```diff:config/environments/production.rb
- config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
+ config.public_file_server.enabled = true
```

## 対応2
もう一つの方法として、環境変数`RAILS_SERVE_STATIC_FILES`の存在性を検証していることがわかるので、環境変数を設定してあげる方法があります。

私はローカルではDocker Composeで開発をしているので、その場合はこんな感じ。（諸々省略）

```yaml:docker-compose.yml
services:
  rails:
    environment:
      - RAILS_SERVE_STATIC_FILES=true
```
もちろん`export`で設定したり、`Dockerfile`の`ENV`に設定したりしてもOK。また`true`でなくて適当な文字列`aaa`とかでも`present?`が`true`を返すような物であればなんでもOK。

# まとめ
公式（に近い）ドキュメントやコメントアウトを見れば、大体解決できるのがRailsのいいところ。
flaskでsubmit時にJSONデータを送信できなくてハマった時のメモ

flaskでSPAを作っていた時の話。
submit時にonsubmitにjavascript関数を動作させデータを送信しようとしてたが、２点ほどハマった部分があった。

## submit時に画面遷移を起こしている
submit時に画面遷移を起こしてしまうために上手くデータを送受信できなかった。
コードとしてはこんな感じ。

```html
<form name="input_from" onsubmit="foo();">
```

onsubmitの最後に`return false;`をつければ画面遷移を抑制できる。

```html
<form name="input_from" onsubmit="foo(); return false;">
```

## header指定がされていない
flask上で、POSTされたデータを受け取る際にこんなコードでデータをとり出そうとしていた。

```python
post_data = request.get_json()
```

この`request.get_json()`はheaderの`Content-Type`が `application/json`でないと上手く動作しないらしい。
Postmanだとデータを受け取れるのに
何故かこちらが作ったJavascriptからデータを送信できない事があるのはこれが原因の模様。
なのでこんな感じのコードを書いた。

```javascript
var data = JSON.stringify([
  {
    "foo": "bar",
  }
]);

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === 4) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "/api/test");
//↓ここが大事↓
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("cache-control", "no-cache");

xhr.send(data);
```
Julia その3 数値型と演算子

## 数値データ型
Juliaの数値データ型は、整数型と浮動小数点数型に分かれる。
整数型は符号付き、符号なしに、それぞれ1,2,4,8,16バイト長が用意されている。名前は`U?Int(8|16|32|64|128)`で、2x5=10通りある。直交性が美しい。

byte型はなくて、代わりにUInt8を用いる。真偽値を表す`Bool`型もある。実態は8ビット整数のようだ。

浮動小数点数は、`Float(16|32|64)`の3つが用意されている。

デフォルトとなる型は、システムによって変わる。64bitシステムでは、

```
julia> typeof(1)
Int64
julia> typeof(1.0)
Float64
```

となるが、32ビットシステムではそれぞれInt32, Float32になるそうだ。いまどきなかなか周りにないので確認のしようがないが。


## BigInt, BigFloat

数学者向けのシステムらしく、無限精度の整数、浮動小数点数もデフォルトで用意されている。これは、GNU のGMP, GPFRライブラリを内部で使っているそうだ。十分長い整数リテラルを書くと自然に`BigInt`になる。シームレスで素晴らしい。

```
julia> typeof(11111111111111111111111111111111111111111111)
BigInt
```

一方`BigFloat`のほうは明示的に作らないとできないようだ。しかも浮動小数点リテラルから作ろうとすると、リテラルの時点で`Float64`に丸められてしまうの意味がない。なので、parseを使って作るのが正解らしい。

```
julia> typeof(0.123456789123456789123456789123456789)
Float64

julia> a = BigFloat(0.123456789123456789123456789123456789)
0.1234567891234567837965840908509562723338603973388671875

julia> a = parse(BigFloat, "0.123456789123456789123456789123456789")
0.1234567891234567891234567891234567890000000000000000000000000000000000000000004

```

基本的な演算子はすべてBigIntをサポートしているようなので、ほとんど意識せずに利用できる。

```
julia> BigInt(111111111) ^ 5
16935087723754847838236041084523023336551
```

## 演算子

演算子は、割に普通だが、その１に書いたように`÷`演算子があったりする。ビット演算のxorは`^`で表現する言語が多い（C, Java, Pythonなど）のだが、Juliaではべき乗に使ってしまっているので、`⊻`というなんと読んだらいいのかわからない記号を導入している。これはREPLでは`\xor + tab` で出る。

```
julia> 0x01 ⊻ 0x02
0x03
```
CやJavaにあるインクリメント、デクリメント演算子`++`,`--` は無い。`+=`や`-=`はある。全ての２項演算子に用意されている。

```
julia> a = 1
1

julia> a += 1
2
```

## 演算子と関数
Juliaの演算子は基本的に関数で、関数としても利用できる。

```
julia> +(1, 2)
3
```

このとき`+`と`(`の間にスペースが入るとパースに失敗するので要注意。

## ユーザ定義演算子

Juliaではユーザが演算子を定義できる。といっても演算子として使える記号の種類や、そのパース時の優先順位は決まっている。ドキュメントを探しても見つからないのだけど、

https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm

ここのソースで定義されているようだ。schemeでパースしているのか？？びっくりだ。

演算子を定義する方法は関数の定義と同じ。演算子は関数だから当然だ。`∙`という演算子で２つ組のタプルを返すようにしてみよう。

```
julia> ∙(x, y) = x, y
∙ (generic function with 1 method)

julia> 1 ∙ 2
(1, 2)
```

ソースを見ると、本当にさまざまな記号が演算子として使えるようだ。ただこれらの記号には相互に見分けのつかないものも多いし、そもそもどう打ったらいいのかわからない。下手に多用すると、誰にも読めないメンテ不能のソースが爆誕しそうで恐ろしい。
flutter webを試してみる

Flutter完全初心者

# Install Flutter

https://flutter.dev/docs/get-started/install/macos

Run flutter doctor までできればOK

PATHの設定がちゃんとできれば詰まるところはなさそう

# Flutter webの準備
https://github.com/flutter/flutter_web#getting-started

# エディタ
Visual Studio Code を使うのが楽そう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39243/d7e06917-e5c6-b9ba-bd40-bf60d57607bc.png)


# プロジェクト作成
VSCodeの `Flutter: New Web Project` で作ってやるのが一番楽。

# ちょっといじってみる

MaterialButtonにはFlat, Raise, Outlineがあるっぽい。

```dart:lib/main.dart
<中略>

          children: <Widget>[
            Text(
              'Hello, World!',
            ),
            Text(
              'たむらまゆ'
            ),
            FlatButton(child: Text('flat button'), onPressed: () {},),
            RaisedButton(child: Text('raised button'), onPressed: () {},),
            OutlineButton(child: Text('outline button'), onPressed: () {},),
          ],
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

```

## こんな感じになる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/39243/fc822000-6d5d-f402-678c-21e6cda8d13f.png)
AppStoreの課金帯(Tier)について

## 概要
AppStoreの課金帯が記載された資料を探すのに苦労したのでメモ

## 資料リンク
https://www.equinux.com/us/appdevelopers/pricematrix.html

## Tips
- 低額課金帯は地域毎に細かな金額を調整できるように `AlternateTier` という課金帯が存在する
- 有料アプリ・課金アイテムの課金帯と定期購読(サブスクリプション)の課金帯は異なる
- 定期購読は1年以上課金し続けるとストア手数料が30%→15%に減少する(GooglePlayStoreも同様)
Java：ファイルをダウンロードしてダイアログで選択した場所に保存する[HttpClient使用]

## はじめに
さてさて、業務にてJavaのローカルアプリで以下の動きを実装することになりました。
1. 保存先を選択するダイアログを開く
2. 選択した保存先に指定のURLからダウンロードしたファイルを保存
結構よくありそうな処理なので、そのまま~~コピペ~~使えそうな記事が無いかなと調べてみたところ、`ダイアログを開く`、`URLからファイルをダウンロードして保存する`といった各々の処理についての記事はありましたが、まとまったものが見当たらず。
せっかくなので組み合わせて書いてみました。

## 以下サンプル
+ 今回はHttp通信にapache.httpComponentsを使用しています。

```xml:pom.xml
<!-- 省略 -->
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.5.2</version>
    </dependency>
<!-- 省略 -->
``` 

```java:DownloadSample.java
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.swing.JFileChooser;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class DownloadSample {
  // ダウンロード先のURL
  static String downloadUrl = "http://sample.com/hoge.txt";

  public static void main(String[] args) throws IOException {
    // デフォルトのファイル名をURLから取得します。
    URL url = new URL(downloadUrl);
    String fileName = Paths.get(url.getPath()).getFileName().toString();

    // 保存ダイアログの表示
    JFileChooser filechooser = new JFileChooser(fileName);
    // デフォルトのファイル名を指定
    filechooser.setSelectedFile(new File(fileName));
    // 保存ダイアログを表示
    if (filechooser.showSaveDialog(null) != JFileChooser.APPROVE_OPTION) {
      // 「保存」以外を押されたら終了
      return;
    }
    // 保存先を設定
    File saveFile = filechooser.getSelectedFile();
    try (
        // HttpClientを設定
        final CloseableHttpClient client = HttpClients.createDefault();
        // Get
        final CloseableHttpResponse response = client.execute(new HttpGet(downloadUrl))) {
      // statusを確認して通信成功したらファイル保存
      final int status = response.getStatusLine().getStatusCode();
      if (status >= 200 && status < 300) {
        final HttpEntity entity = response.getEntity();
        // ファイル保存
        Files.write(Paths.get(saveFile.toString()),
            entity == null ? new byte[0] : EntityUtils.toByteArray(entity));
      } else {
        throw new ClientProtocolException("Unexpected response status: " + status);
      }
    }
  }
}
```

本当にこれだけのサンプルなので不要かもしれませんが...[GitHub](https://github.com/h-ueno2/Java_file_download_sample)

## 参考文献
[[Java] ファイルをダウンロードして保存する（Apache HttpComponents HttpClient 4.5.2使用）](https://qiita.com/anqooqie/items/f591c49d6d4e7f0f6590)
 → Http通信とファイル保存については、ほとんどこちらの記事から流用させていただきました。ありがとうございます！
[「ファイルを保存する」ダイアログを表示する](https://www.javadrive.jp/tutorial/jfilechooser/index3.html)
[JFileChooserを便利に使うためのTips](https://konbu13.hatenablog.com/entry/2014/03/07/223805)
　→ 保存ダイアログの選択方法についてはこちらの記事を参考にさせていただきました。ありがとうございます！
[java.net.URLの使い方とちょっとNIO.2のメモ](https://torutk.hatenablog.jp/entry/20130104/p1)
　→URLからファイル名を取得する処理についてはこちらの記事を参考にさせていただきました。ありがとうございます！
MacOSXでRStudio1.2にアップグレードしたらawkがdyldでエラーを吐き出し、それ直そうとしたら起動しなくなったお話です。

##MacOSXでRStudio1.2にアップグレード
そうしたらawkがdyldでエラーを吐き出し、それ直そうとしたら起動しなくなったお話です。
## 環境
- MacOSX 10.13.6
- R ? -> 3.6.0
- Studio ? -> 1.2.0

## 経緯と対策
Rが3.6にあがっていたのでbrewを使ってupgradeしました。



```
brew upgrade R
```

ついでにRStudio1.2にアップグレードはこんな感じです。

```
brew cask install rstudio
```

このとき```/Application```に```RStudio```があるとインストールできないので念のためzipアーカイブして本体をゴミ箱に捨てておきます。

これで```RStudio```を起動するとなにやら```RStudio```の```Terminal```ウインドウにエラーが。

```
awk
"dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib"
```

それで
https://qiita.com/nwtgck/items/f5427c0d0f7827658bd5
を見つけて

```
$ brew switch readline 7.0.3_1
```
で入れ直しました。

そうすると、今度は```RStudio```が起動しなくなりました。```127.0.0.1```につながらないと。エラーも吐き出さないし、？状態でしたが、```R```を```Terminal```から起動すると

```
$ R
dyld: Library not loaded: /usr/local/opt/readline/lib/libreadline.8.dylib
  Referenced from: /usr/local/Cellar/r/3.6.0_2/lib/libR.dylib
  Reason: image not found
```

なるほど。こちらは```libreadline.8.dylib```を読んでるのですね。
それでもう一度

```
brew switch readline 8.0.0
```

と戻すと```RStudio```も起動しました。どういうわけか```awk```のエラーも消えています。

というわけで、ま、いいか。これまで書いたコードが```R 3.6.0```でも無事に動くといいのですが。

何かの参考になれば幸いでございます。
Gunicorn用のSystemdソケットとサービスファイルの作成

# Djangoで作成したアプリを動かすサーバー(Gunicorn)の起動および停止を堅牢な方法で行う。

- systemdサービスとソケットファイルを作成する
- Gunicornソケットは起動時に作成され、接続を待ち受ける。
    - 接続が発生すると、systemdは自動的にGunicornプロセスを起動して接続を処理する

## Gunicorn用のsystemdソケットファイルを作成する

`sudo`権限でGunicorn用のsystemdソケットファイルを作成する

```
$ sudo vim /etc/systemd/system/gunicorn.socket
```

```/etc/systemd/system/gunicorn.socket
[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn/socket

[Install]
WantedBy=sockets.target
```

## Gunicorn用のsystemdサービスファイルを`sudo`権限で作成する。
このとき、**サービスのファイル名は拡張子を除いてソケットのファイル名と一致する必要がある。**

- プロセスはすべての関連ファイルを所有しているため、プロセスの所有権を通常ユーザーアカウントに与える。
- NginxがGunicornと簡単に通信ができるように`www-data`グループにグループの所有権を与える。

```
$ sudo vim /etc/systemd/system/gunicorn.service
```

※`ExecStart=/home/ ubuntu / myprojectdir /bin/gunicorn`の`/home/ ubuntu / myprojectdir /bin/gunicorn`は`which gunicorn`で表示されたパスにする。

```/etc/systemd/system/gunicorn.service
[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ ubuntu / myprojectdir
ExecStart=/home/ ubuntu / myprojectdir /bin/gunicorn -- access-logfile - -- workers 3 --bind unix:/run/gunicorn/socket myproject.wsgi

[Install]
WantedBy=multi-user.target
```

## Gunicornソケットを起動して有効化する
これにより、起動時に`/run/gunicorn/socket`ファイルが作成される。そのソケットに接続するとsystemdはそれを処理するために`gunicorn.service`を自動的に起動する。

```
$ sudo systemctl start gunicorn.socket
$ sudo systemctl enable gunicorn.socket
```

プロセスが開始できたかどうかを確認する。

```
$ sudo systemctl status gunicorn.socket
```

## Nginxの設定

```/etc/nginx/sites-enabled/project
upstream app_server{
    server 127.0.0.1:8000 fail_timeout=0;
}
server{
    listern 80;
    server_name <yourIPadress> or <domain>
    
    location = /favicon.ico { access_log off; log_not_found off;}

    location /static/ {
        root /home/ ubuntu / myprojectdir;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn/socket;
    }
}
```

# 出典
- [Ubuntu 18.04でPostgres、Nginx、およびGunicornを使ってDjangoを設定する方法](https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04)
- [nginxとgunicornでDjangoの本番環境を構築する(2018年9月最新版)](https://qiita.com/takehiro_t59/items/bf4af2da35a4281f403f)
Leetcode #35: Search Insert Position

```swift
func searchInsert(_ nums: [Int], _ target: Int) -> Int {
    var start = 0
    var end = nums.count - 1
    while start <= end {
        let mid = (start + end)/2
        if nums[mid] == target {
            return mid
        } else if nums[mid] > target {
            end = mid - 1
        } else {
            start = mid + 1
        }
    }
    return end + 1
}
```