OmniAICreator/Qiita-1.07M huggingface dataset:
AWS OpsWorksでIAMユーザをEC2インスタンスに作成しSSHログインする

### IAMユーザ作成
「IAM」を開き「ユーザーを追加」をクリックする。
![WS000040.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/cd0c6514-1e59-afcf-d7e3-8b6d82ef83f1.jpeg)

任意のユーザー名を入力し「次のステップ」をクリックする。
![WS000041.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/8629ac7a-b4d0-27fb-fb5b-045e03314149.jpeg)

任意の権限を設定し「次のステップ」をクリックする。（OpsWorksの権限の付与も不要）
![WS000042.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/b1aa5a1d-2ae2-6c58-817a-963cef7dfbe3.jpeg)

任意のタグ設定を行い「次のステップ」をクリックする。
![WS000043.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/7cf23cc8-3ba3-0581-e3ba-523bad46ed2d.jpeg)

設定に問題がないことを確認し「ユーザーの作成」をクリックする。
![WS000044.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/e8cf99b1-05ee-adde-e8a8-fe9d2f7391df.jpeg)

ユーザーの作成に成功したことを確認し「閉じる」をクリックする。
![WS000045.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/21a6297a-4b20-5ba7-19bd-f7cb6f0f495e.jpeg)

### OpsWorks設定
OpsWorksを開き「Users」を選択し「Import IAM users to Asia Pacific(Tokyo)」をクリックする。
![WS000046.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/18955eff-e255-488f-4404-cd93fc7cd0c7.jpeg)

IAMで作成したユーザを選択し「Import to OpsWorks」をクリックする。
![WS000047.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/f5a29486-46cb-84f0-197e-5848a79a79cb.jpeg)

Importされたユーザの「edit」をクリックする。
![WS000048.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/67b514ba-caf9-c3bc-8b50-baf269f35f52.jpeg)

秘密鍵・公開鍵を作成し公開鍵を「Public SSH key」に設定し「SSH/RDP」にチェックを入れ「Save」をクリックする。
![WS000051.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/4005d9c9-68e5-3dd7-02e5-1dfc45d4af44.jpeg)

公開鍵が設定されたことを確認する。
![WS000052.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/c3869722-fd22-7e06-11a3-cbac2eca08c5.jpeg)

公開鍵に対応する秘密鍵で、Stackに含まれるEC2インスタンスにログインする。
![WS000049.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314837/2c5f8544-0c63-16ef-8124-dcad0ebb10b9.jpeg)
【初心者用】<PHP編>API利用法　DarkSkyで天気を自動取得、WEBページに組み込む方法

こんにちは。
表題の通り、初心者向けのAPI利用法を記載します。

##はじめに
以前、[こちらの記事](https://qiita.com/masuraoProg/items/41d57671bc1ba89489bb)にてjQueryを用いた表現方法を用いたのですが、
CORSにより、利用が表現されていました。
本題では無いので、CORSについてはググって確認していただきたいのですが、
ざっくりいうと、
　・サーバーから許可されていなければ使えない
　・サーバーサイドからコンタクトすれば問題ない
ということを学んだので、ここに記載します。

##ここでやらないこと
CORSの細かい解説
PHPを使うための環境設定

##APIを利用しよう
さて、早速ですがPHPにて「DarkSky」のAPIを利用してみたいと思います。

重ねていいますが、DarkSkyの登録方法等は、この[稚拙な記事](https://qiita.com/masuraoProg/items/41d57671bc1ba89489bb)をご確認ください。
API Key の取得までお願いいたします。
API Key の取得まで済んだら、あとはコードを書くだけです。

##コードを書こう。
PHPにて下記のように記載します。
**あなたのAPI Keyという記載部分にはそのとおりあなたのAPIを記載してください。**

```PHP:dark_sly_test.rb

<?php
//↓API　URLを変数に格納
$url = "https://api.darksky.net/forecast/"あなたのAPI Key"/36.0658,139.5221?units=si&lang=ja&exclude=alerts,flags";

//↓格納したURLをjsonにチェンジ！
$json = file_get_contents($url);
$json = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');

//↓JSONデータを連想配列に!!
$arr = json_decode($json,true);

//配列から１時間後の体感気温を取得！
$nextOneHourTemperature = $arr["currently"]["apparentTemperature"];

//表示事項をまとめる
echo("<h1>darksky.netからAPIで情報取得っ！</h1><br><p>１時間後の体感気温は？</p>".$nextOneHourTemperature."℃だよ！");
```

これで、こんな感じに表示されます。

<img width="638" alt="スクリーンショット 2019-09-02 23.17.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307585/8cf6707c-0d5a-1f60-f9cc-85f7680bada8.png">


はいできました。

連想配列である、$arrだけを表示してみると、
色々なものが格納されていますので、必要に応じて内容を確認してみてください。

##まとめ
以上、
CORSってなんやねんと思っていたら、サーバーサイドから接続すれば簡単に内容を知ることができたというお話でした。
JetBrains IDEのVCSで複数のコミットログを一つにまとめる

普段のコーディングでPRを出す前、乱雑に細分化したコミットログをある程度まとめたいときに使うJetBrains IDEの機能。


1. "Version Control" - "Log" タブのソースツリーから、まとめたい対象の一番古いcommitを右クリック
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392349/c5fcf444-3229-fc08-d2a2-3cdfd40c7669.png)

2. "Interactively Rebase from Here"をクリック
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392349/5effd9b5-1f33-9304-77f0-bab78682caaf.png)

3. 編集対象に対して"Action"を選んでいく(commitの順番は⇅で入れ替えられる)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392349/db8edc01-60ae-6b96-d84d-69e35578eed9.png)

4. 今回はcommitを結合したいので"Squash"を選択(一つ上のcommitに統合される)
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392349/7872ee7d-8583-0ea3-4f19-57bae44b4a19.png)

5. コメントを編集して"Resume Rabasing"を押す。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392349/e72741d2-ffb0-178a-6368-f99e7cb41551.png)


コンフリクトした場合は途中でマージモードに切り替わるので乱用は注意が必要。

Actionの種類はこんな感じ。
基本的に"Fixup"しか使わない。

| Action | Right align |
|-----------|------------|
| Pick | 選択したcommitをそのまま適用 |
| Edit | このcommitの影響を受けるファイルを編集してから適用 |
| Skip | commitを無視して、なかったことにする|
| Squash | 選択したcommitを前のcommitと結合。<br>コメントも結合される。|
| Reword | commitのcommentを編集してから適用 |
| Fixup | "Squash"のコメント破棄する版 |

公式
https://www.jetbrains.com/help/phpstorm/edit-project-history.html#interactive-rebase
【Rails】Devise機能を使用したユーザー登録後のリダイレクト先を変更する

# 前提
以下コマンドにてdevise用のusersコントローラを作成しています。

```ターミナル.
$ rails g devise:controllers users

Running via Spring preloader in process 1829
      create  app/controllers/users/confirmations_controller.rb
      create  app/controllers/users/passwords_controller.rb
      create  app/controllers/users/registrations_controller.rb
      create  app/controllers/users/sessions_controller.rb
      create  app/controllers/users/unlocks_controller.rb
      create  app/controllers/users/omniauth_callbacks_controller.rb
```

# やりたいこと
ユーザーの新規登録完了後、指定したパスにリダイレクトさせたい。
今回は、以下の「user_path」にリダレクトさせます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389470/a811f36a-bb52-15bd-291f-82334ea3ee37.png)

# ユーザー新規登録後にリダイレクトするパスを変更する
registrations_controller.rbの下の方にある「after_inactive_sign_up_path_for」メソッドをコメントアウトを外し修正します。
今回は、

```【before】registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController

~~省略~~
  # The path used after sign up for inactive accounts.
  # def after_inactive_sign_up_path_for(resource)
  #   super(resource)
  # end
```

```【after】registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController

~~省略~~
  # The path used after sign up for inactive accounts.
  def after_inactive_sign_up_path_for(resource)
    user_path(resource)                    #ここを修正する
  end
```
※今回リダイレクトさせたいパスには「user_id」が必要なので、user_pathに対して"resource"を渡しています。

# 最後に
備忘のために投稿しました。意外と簡単に遷移できました。
考える時間を増やそう！SAPショートカット集

<h2>概要</h2>
今回は業務効率化のために現場で使えるSAPのショートカットを紹介します。

<h2>SAPとは？</h2>
「SAP社」が開発するERPパッケージのひとつです。ERPパッケージとは、企業の業務を統合して一括管理するソフトウェアのことを指します。
詳しくはググってみてください！

<h2>SAPショートカット</h2>
|機能|コマンド|
|---|---|
|コマンドフィールドへジャンプ|ctrl + /|
|開いているトランザクションを閉じて別のトランザクションを開く|/n + (開きたいトラン)|
|別ウィンドウを開いてトランザクションを開く|/o + (開きたいトラン)|
|新しいセッションの開始|Ctrl + Shift + ;|
|開いているセッションを削除|/i|
|SAPの画面を全て閉じてログオフ|/nex|
|照会、変換の互換|ctrl + F1|

<h2>まとめ</h2>
というわけでまとめてみましたが、まっだまだありそうですね。。。
今後も追加していくようにします！それでは！

他の記事もぜひぜひ
https://qiita.com/harumaki_dayo
RailsのSlimでフォームに(form_with)Bootstrapを適用させる

ぐぐってもすぐに分からなかったので、メモ。
今は、form_withを使ってフォームを作るといいらしい。
フォームにclassを書くには、キーワード引数？ classに文字列でクラス名を渡すといいらしい。

Railsの中身読んでも引数の指定の仕方がよくわかりませんでした。
Rails難しい。

```ruby:app/views/blogs/new.html.slim
= form_with url: blogs_create_path, model: @blog, locale: true do |f|
  .form-group.col-md-6
    = f.label :name
    = f.text_field :title, class: 'form-control'
  .form-group.col-md-6
    = f.label :article
    = f.text_area :article, class: 'form-control'
    = f.submit '新規登録', class: 'btn btn-primary'
```


参考にさせていただきました。

[一日一吉
Ruby学習日記6：Slimを少々]
(http://baikichiz.hatenablog.com/entry/2018/12/29/045901)

[slimで書くformサンプル]
(https://qiita.com/shigeru10/items/ebcd3e639ae41f460143)

[【Rails 5】(新) form_with と (旧) form_tag, form_for の違い]
(https://qiita.com/hmmrjn/items/24f3b8eade206ace17e2)

[Bootstrap
Forms]
(https://getbootstrap.com/docs/4.3/components/forms/)
facerig対応Live2Dモデルを作成するときのレイヤー構成

基本的なレイヤー構成

```
<フォルダ>
├<髪>
│├揺らしたい前髪
│├その他の前髪
│├右横髪
│└左横髪
│
├<顔>
│├右眉毛
│├左眉毛
│├鼻
│├頬
││
│├<右目>
││├まつ毛
││├眉毛_上の方
││├眉毛_右の方
││├ハイライト
││├瞳
││└白目
││
│├<左目>
││├まつ毛
││├眉毛_上の方
││├眉毛_左の方
││├ハイライト
││├瞳
││└白目
││
│├<口>
││├上唇
││├下唇
││└口の中
││
│├顔(肌の部分)
│├右耳
│└左耳
│
└<体>
│├襟部分
│├服
│├首
│├<右腕>
││├二の腕
││├腕
││└手
││
│├<左腕>
││├二の腕
││├腕
││└手
││
│└<足>
│　├<右足>
│　│├太もも
│　│├ふくらはぎ
│　└靴
│　│
│　└<左足>
│　　├太もも
│　　├ふくらはぎ
│ 　　└靴
└後ろ髪
```

この他に動かしたい部分を想像してイラストを描いてみるといいかもしれない
例えば服をひらひらさせたかったら服の表と裏を描いて交互に表示させるとか。
考え方次第でどんな動きもできるのがLive2Dなので頑張って考えてみてください！
[備忘録]Rails開発環境でPostgreSQLを使用する方法

#環境
Ruby 2.5.1
Rails 5.2.3
PostgreSQL 11.5

#ロールの作成
以下のコマンドでロール(ユーザー)を作成する。

```
psql -U postgres
postgres=# create role [rolename] with superuser createdb login password '[password]';
```
このコマンドでスーパーユーザー、DB作成可の属性を持ったロールが作成される。
[rolename]はロールの名前、[password]はDBへログインするためのパスワードを入力する。

属性の付与理由は以下の通り

<dl>
  <dt>スーパーユーザー</dt>
    <dd>外部キー参照を行うテーブルを作る場合、これが無いとテストで「参照整合性を無効にできない」というエラーが発生するため。</dd>
    <dd>(スーパーユーザーはほぼ全ての権限を持つため、上記エラーを回避するための権限のみを持たせるべきだが方法が不明。)</dd>
  <dt>DB作成可</dt>
    <dd>データベースを作成できる権限を付与するため。</dd>
    <dd>(スーパーユーザーを持っていれば、この属性が無くてもデータベースは作成可能となるが、将来スーパーユーザーを削除した場合を考えて付与する。)</dd>
</dl>

#新規プロジェクトの作成
任意のフォルダに移動し以下のコマンドを実行する。

```
rails new [appname] -d postgresql
cd [appname]
```
[appname]はアプリ名称を入力する。

#設定の変更
config/database.ymlを以下のように変更する。(デフォルトのコメント部分は削除している。)

```config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  # 以下3行を追加
　username: [rolename] #作成したロールの名前
  password: [password] #作成したロールのパスワード
  host: localhost

development:
  <<: *default
  database: [appname]_development #[appname]はアプリ名称と同じ

test:
  <<: *default
  database: [appname]_test #[appname]はアプリ名称と同じ

production:
  <<: *default
  database: [appname]_production #[appname]はアプリ名称と同じ
  username: [appname] #[appname]はアプリ名称と同じ
  password: <%= ENV['TEST_APP_DATABASE_PASSWORD'] %>
```

#データベース作成
以下コマンドでデータベースを作成する。

```
rails db:create
```

config/database.ymlの設定により[appname]_developmentと[appname]_testという名称のデータベースが作成される。

#テーブルの作成
以下のコマンドでモデルを作成する。

```
rails generate model [modelname]
```
[modelname]はモデル名を入力する。
以下のコマンドでmigrateを行う。

```
rails db:migrate
```
以下のコマンドでテスト用のmigrateを行う。

```
rails db:migrate RAILS_ENV=test
```
テストを行う場合は、デフォルトでgemfileに書かれているテスト用gemの「chromedriver-helper」が非推奨となっておりエラーが発生するため、「webdrivers」に変更する。

#参考
[Ruby on Railsの開発環境でPostgreSQLを利用する](https://qiita.com/taKassi/items/8e43171aeda300b67213)
Vue v-html

# v-html
2重中括弧のmustachesは、データをHTMLではなく、プレーンなテキストとして扱います。実際のHTMLとして出力するためには、v-htmlディレクティブを使用する必要があります。

```html
<div id="msg">
        <p>Using mustaches: {{ rawHtml }} </p>
        <p>Using v-html directive: <span v-html="rawHtml"></span></p>
    </div>

    <script>
    var app = new Vue({
        el: '#msg',
        data: {
            rawHtml: '<span style="color:red">This should be red.</span>'
        }
    })
    </script>
```
インフラ系エンジニアが唯一覚えるべきPythonの使い方

ごめんなさい、タイトル盛りました。

他のインタプリタ系言語も大体同じようにコマンドをアドホックに実行できるけれど、Pythonも標準ライブラリを組み合わせることでかなり便利に使うことができます。

# TL;DR

Pythonを使ってコマンド1発でwebサーバを動作させます。

```console:Python3
$ python3 -m http.server 12345
```

あるいは

```console:Python2
$ python2 -m SimpleHTTPServer 12345
```

# 任意のポートでwebサーバを起動

## 何がうれしいのか？

VMやネットワークを構築して、まだDBやアプリケーションサーバなどが用意されていない状態で、`iptables`やネットワーク機器の各種ルーティングやポート毎のフィルタリング・ロードバランサ設定が正しく動作しているかの確認、どうしていますか？

Pythonがあれば単体(標準ライブラリ)でwebサーバを任意のポートで起動できるので、疑似サーバとして「リモートからのTCP疎通」を簡単に確認できます。(リモートからは使用するポートで`curl`すれば疎通確認できる)

Pythonと言っても、プログラミングする必要はありません。

- コーディング不要
- 設定ファイル不要
- 基本的に追加のパッケージインストール等は不要
    - Pythonインタプリタ(`python`コマンド)が有ればOK
- 現在主流の3.xか、少し古い2.x(2.xは2020年1月1日でサポート終了)のどちらでもOK
    - オプションが若干異なる
- 実行すると、カレントディレクトリをルートドキュメントとしてファイルリスト・ファイル内容をクライアントに応答
    - 簡易的にファイル配布サーバにも使える

デフォルトでリモートホストからの接続も受け付ける動作(0.0.0.0でLISTEN)するので、「ローカルからは`curl`が反応あるけど、リモートからだと接続できない」のであれば、ファイヤーウォールやロードバランサの設定が怪しいはずなので確認してみましょう。

## Python 3.x

```console
zaki@chaource:~$ python3 -m http.server 12345
Serving HTTP on 0.0.0.0 port 12345 (http://0.0.0.0:12345/) ...
```

停止は`Ctrl-c`

## Python 2.x

```console
zaki@chaource:~$ python2 -m SimpleHTTPServer 12345
Serving HTTP on 0.0.0.0 port 12345 ...
```

停止は`Ctrl-c`

## Pythonのバージョン確認方法

```console
zaki@chaource:~$ python --version
Python 2.7.15+
```

`--version`を付けて実行すればOK

# JSONの整形

一つと言いつつもう1件 :innocent:

何かのAPIサーバに`curl`したりすると、JSON形式のレスポンスが改行無しでドカンと振ってきて見づらいチクショウというとき、これもPythonで簡単に整形できます。

`| python -m json.tool`

これを付けるだけ。
制限(?)として、正しい書式になっていないナンチャッテJSONだとあっさりエラーになるので注意。
[jq](https://stedolan.github.io/jq/)使えたらそれでもいいけど。

```console
zaki@mascarpone% curl -s -H "Authorization: Bearer $(oc whoami -t)" "http://docker-registry-default.192.168.99.103.nip.io/v2/_catalog"
{"repositories":["openshift/dotnet","openshift/httpd","openshift/jenkins","openshift/mariadb","openshift/mongodb","openshift/mysql","openshift/nginx","openshift/nodejs","openshift/perl","openshift/php","openshift/postgresql","openshift/python","openshift/redis","openshift/ruby","openshift/wildfly"]}
```

このような、1行に出力されて見づらいJSONレスポンスも…

```console
zaki@mascarpone% curl -s -H "Authorization: Bearer $(oc whoami -t)" "http://docker-registry-default.192.168.99.103.nip.io/v2/_catalog" | python -m json.tool
{
    "repositories": [
        "openshift/dotnet",
        "openshift/httpd",
        "openshift/jenkins",
        "openshift/mariadb",
        "openshift/mongodb",
        "openshift/mysql",
        "openshift/nginx",
        "openshift/nodejs",
        "openshift/perl",
        "openshift/php",
        "openshift/postgresql",
        "openshift/python",
        "openshift/redis",
        "openshift/ruby",
        "openshift/wildfly"
    ]
}
```

`python -m json.tool`へパイプしてあげるとこのように整形される。
(ちなみに実行環境はminishift付属のdockre-registreyへ[Docker Registry API](https://docs.docker.com/registry/spec/api/)を実行)
fzf.vimでAgを用いた文字列検索をする際、ファイル名とのマッチングを除外する

`fzf.vim` にデフォルトで用意されている`Ag`コマンドでの文字列検索は、ファイル名と検索文字列のマッチングも表示される。

<img width="1440" alt="スクリーンショット 2019-09-02 22.44.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402968/8d09fade-c89d-ca8d-fca9-52ea0fcbeed2.png">

本文とのマッチングを見たいとき困る…

## 解決策
`Ag`コマンドにオプションを付けることで、ファイル名とのマッチングを除外することができる。
`.vimrc` で以下のコードを書くことでコマンドを再定義できる。

```vim:vimrc
command! -bang -nargs=* Ag call fzf#vim#ag(<q-args>, {'options': '--delimiter : --nth 4..'}, <bang>0)
```

<img width="1440" alt="スクリーンショット 2019-09-02 22.43.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402968/5a1a98e5-a962-b18d-119e-d84a3d5d9d77.png">

本文とのマッチングだけ表示されるようになった。

> 参考
https://github.com/junegunn/fzf.vim/issues/609
Face-data-serverを作っている



# Face-data-serverとは

https://github.com/Cj-bc/Face-data-server
LSPの発想を取り入れたfacerigバックエンドみたいなやつ。

# 概要
face-data-serverはその名の通り顔の情報をストリーム配信するサーバーです。
フェイストラッキングをして、そこからアバターを動作させるのに必要最低限(だと思われる)数値を抽出して配信します。
単体では動作せず、複数のフロントエンド(開発中)と組み合わせて使用します。
発想としては、facerigやLuppet等のアバターを操作するアプリケーションを表示部分と顔検出部分に分けたようなものになります。

# 作り始めたきっかけ

`facerig`という3D/2Dアバターに自分が入り込んで動かせるアプリケーションがあります。
これで遊びたかったのですが**実はmac非対応です**
なら...作るしかないですね、はい。


# なぜServerで配信する形態をとるのか

**複数のフロントエンド**を開発することができるからです。
実は、facerigを使わずに同様のことをする取り組みはずっと以前からあり、Unity+live2Dを使えばサクッと作れたりします。([この記事](https://qiita.com/nkjzm/items/1ba5dfc0575ed6ddd8ff)がわかりやすい)
しかしこれでは2D,3D両方対応させたりするのに厄介です。それでいて[私のプロジェクト](https://github.com/Cj-bc/Yozakura-project)では**CLIからVtuberしたい**とかいうぶっ飛んだ計画があったため、それぞれ別のものとして作成するのはコストが大きすぎました。
なので、表示部分の差でしかないフロントエンド側とフェイストラッキングの情報を取得するバックエンド部分を切り分けるに至りました。

# 現状

現状はまだ`v0.7.1`で、サーバーとしての機能を追加途中といったところです。
- [x] 頭の角度
- [ ] 目の開き具合
- [ ] 口の開き具合

# 技術的内容

## 使用言語、ライブラリ等
カメラ接続・顔検出に`OpenCV`と`dlib`を使用しています。その双方が使える言語という観点でpythonが使われています。
又、サーバーとして機能させるために`gRPC`を使用しています。詳しいことは割愛しますが、APIを`*.proto`というファイルに一括して書け、そこからそれに対応するコードを複数言語で出力できるため採用しました。あとは技術的好奇心です。

## 顔の傾き検出
現在は純粋に三角関数を用いて測定しています。ここら辺についてはいつか詳しくまとめます。
例えば、正面から見た目と目の間の距離の推移から顔を水平方向に振る動きの角度が検出できます。
床と水平方向の平面を考えて正面を0度としたとき、正面を向いているときの目と目の距離を1とすると、90度で目の距離が(理論上)0になるのでこれはcosと同じ値の推移になります。
dockerの基本コマンドとエトセトラ【初学者の備忘録】


##dockerイメージの作り方
```bash
#オプションはキャッシュが残らないように。慣れないうちはこれでやる。
docker build --no-cache -t deploy_test2:タグ名 .
```

##dockerコンテナの作り方
```bash
#ruby:1.0イメージから、rails_testコンテナを作成し、デタッチドモードで起動する。
$ docker run -it --name rails_test -d ruby:1.0

#コンテナとホスト側の動作、バインドマウントまでさせる方法
$ docker run -it --name コンテナ名 -d -v ホスト側絶対パス:コンテナ側絶対パス:パーミッション イメージ名
```
	 
```bash
#alpineイメージのコンテナにsshログインする方法
#debian系のイメージなら/bin/bashとする
$ docker exec -it コンテナ名 /bin/ash
```

##docker-machineの作り方(dockerリモコンぐらいに考えるとわかりやすいかも)
```bash
#dockerをどこに作成するか、その名前（default）
#--driverはdockerを建てる場所。デフォルトではvirtualboxなので、指定しなくても良い。
$ docker-machine create --driver virtualbox default

#defaultのIPアドレスを確認する
$ docker-machine ip default 
```

##dockerイメージの削除方法
```bash
$ docker rmi -f イメージ名か、イメージID
```

##dockerコンテナの削除方法
```bash
$ docker rm -f コンテナ名か、コンテナID
```

##docker-machineで作成したホストの削除方法
```bash
$ docker-machine rm ホスト名
```

##確認コマンド
```bash
#docker-machineの一覧表示
$ docker-machine ls

#docker-machineで管理するdockerを対象に、dockerコマンドの操作対象を切り替える
$ eval $(docker-machine env docker-machineの名前)

#dockerコマンドの操作対象をローカルに戻す
$ eval $(docker-machine env -u)

#動作中のコンテナを表示
$ docker ps
```

##dockerfileの奥義
絶対に互換性に泣く。まずは下記からスタートする。
というか、まずは本を読んだ方が良い。
ググりながらやったら詰みました。

###・ベースイメージを決める。
###・アプリケーションのrootディレクトリを作成する。
###・それをワーキングディレクトリとする(HOMEではない)

```docker
#このレベルからスタートしてコンテナ上でいろいろ試す。
FROM ruby:2.5.1-alpine

ENV APP_ROOT /usr/src/myapp

WORKDIR $APP_ROOT

COPY Gemfile Gemfile.lock ./
```

・aptやapkのupdateを行う。必要なら、パッケージリストにURLを追記した上で。
・apt-getなどで必要なパッケージを導入する。
・GemfileとGemfile.lockをコピーする。
・Rubyならbundlerでupdateとinstallする。
・不要なキャッシュやリスト、データを削除する。
・コンテナ起動時に実行したいコマンドを記述する。
Amazon VPCのサイズを後から変更するには

- Q:VPC のサイズは変更できますか?
 - A:はい。既存の VPC を拡張するには、4 つのセカンダリ IPv4 IP 範囲 (CIDR) を VPC に追加します。
 VPC を縮小するには、VPC に追加したセカンダリ CIDR ブロックを削除します。ただし、VPC の IPv6 アドレス範囲のサイズは変更できません。


「アクション」-「CIDRの編集」から行える。
![スクリーンショット 2019-09-02 22.39.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/91f35365-ea9c-1d71-666d-ff5d815ace9c.png)

ちなみに5つ目を作成使用とすると怒られる。
![スクリーンショット 2019-09-02 22.41.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/0ecb0c4a-c162-1949-eea7-1bd48acf9cc8.png)

また、プライマリCIDRは削除することはできない。
![スクリーンショット 2019-09-02 22.44.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/e94002f6-adf1-c0da-03e3-445fe8807ebc.png)
【AWS】AWS Auroraには再起動しても何しても消えないキャッシュが存在します【Aurora】

MySQL、使ってますか？
AWSのAurora、使ってますか？？
SQLのクエリチューニング、してますか？？？


弊社も常々WEBサイトのページ表示速度とは戦い続けていて、日々クエリチューニングをしています。

そんなある日、スロークエリログにて重たいクエリを発見したので早速EXPLAINなどを使って確認しようとしたところ・・・
１回目→激重
２回目→爆速
で返ってきて「？？？」となりました。
キャッシュだろうと思い「RESET QUERY CACHE」を打ってその後何回も実行してみましたが、結果は常に爆速。

一体１回目の実施は何だったの？まさか…と思い確認したところ、Auroraではバッファプールキャッシュやページキャッシュといったキャッシュが使われこれらのキャッシュはDB再起動しても消えないしすべてのキャッシュを削除しても消えないとのことでした。

つまり、初回時の速度を再現したいのであればDBインスタンスを新しく作成して実効するしかな、とのことです。

詳しくはこちらの「存続できるキャッシュのウォームアップ」あたりをご覧ください。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.Overview.StorageReliability.html
算数のあの表現，英語で何ていうの？

## 算数のあの表現，英語で何ていうの？

英語でエンジニアと話す際，忘れがちなので書いておきます
もっと必要なものがあれば教えて下さい

|演算方法|式|英文|
|------|------|------|
|足し算| X + Y = Z | X plus Y is Z, X added to Y makes Z|
|引き算| X - Y = Z | X minus Y is Z, Y subtracted from X makes Z |
|掛け算| X * Y = Z | X multiplied by Y is Z, X times Y equals Z |
|割り算| X / Y = Z | X divided by Y is Z |
|余り| X % Y = Z | X modulo Y is Z. Z is the remainder from the division of X by Y |
|冪乗| X ^ Y = Z | X to the power of Y is Z |

|実例|英文|
|---|---|
| 1/2  | A half|
| 2/3  | Two over three, two thirds|
| 3^2  | The square of three|
| 2^3  | The cube of two|
| 6^-3 | 6 to the power of negative three|
| √16  | The square root of 16|
| 5以上| More than 5|
| 5以下 | 5 or less(under, below) |
| 5未満 | Under 5 |
|5より大きい| Above 5|
| a < b | a is less than b |
| a > b | a is greater than b |
| a <= b | a is not greater than b|
| a >= b | a is not less than b|
  
### 用語

* 和    Summation
* 差    Difference
* 積    Product
* 商    Quotient
* 余り  Remainder
* 冪    Power
* 分数    Fraction
* 分母    Denominator
* 分子    Numerator
* 階乗    Factorial
* 平均  Average
* 組み合わせ    Combination
* 順列    Permutation
* 直積    Direct product
* 内積    Inner product
* 微分    Differential
* 偏微分    Partial differential
* 積分    Integral
* 奇数    Odd number
* 偶数    Even number
* 素数    Prime number

### 参考文献

- [算数、数学の英語表現](http://yamamoto-english.info/%E7%AE%97%E6%95%B0%E3%80%81%E6%95%B0%E5%AD%A6%E3%81%AE%E8%8B%B1%E8%AA%9E%E8%A1%A8%E7%8F%BE/)
- [かけ算って英語でなんて言うの？](https://eikaiwa.dmm.com/uknow/questions/4093/)
- [この英語表現できる？　「未満」「以下」「以上」はどういうの？](https://juken.oricon.co.jp/rank_english/news/2071623/)
nanoエディター設定のメモ

以下のオプションは、すべてのユーザーに適用するときは/etcのnanorcというファイル、1つのユーザーに適用する場合はそのユーザーのホームディレクトリに.nanorcというファイルを作って書き込んでください。
#行数を表示
set linenumbers
#Tab幅を指定
set tabsize X(Xに値を指定)
#自動改行を禁止
set nowrap
一説によるとハンバーガーメニューはもう遅いらしい

ナビゲーションメニューのレスポンシブ対応と言えば、ハンバーガーメニューという一種のお決まりのような風潮があったりする。
確かに見た目としてコンパクトで良い感じだった。

でも
**ハンバーガーメニューはあまり見ない。**
そうだろう？

一般的に必要な情報はスクロールすればわかるようにしてある。
スクロールする事に慣れた現代人にとってもはやハンバーガーメニューはないも同然である。

だから、これからの時代は見せるナビゲーションでいこう。

## 見本
https://codepen.io/engineerhikaru/pen/JjPNRwo
https://getbootstrap.com/docs/4.3/examples/blog/
こんな感じのものを作っていく。

## コード
まずはHTMLから
なお今回使用するCSSの書き方は、現在開発中のCSSフレームワークinstant.css(仮)に準ずるものです。(つまり、instant.css(仮)を読み込めば同じHTMLコードで実装可能)

```html:HTML
<ul class="fbox nowrap nav">
  <li><a href="#">HOME</a></li>
  <li><a href="#">PAGE1</a></li>
  <li><a href="#">PAGE2</a></li>
  <li><a href="#">PAGE3</a></li>
  <li><a href="#">PAGE4</a></li>
  <li><a href="#">PAGE5</a></li>
</ul>
```

```css:CSS
/* 横に並べる(折り返しあり) */
.fbox{
  display: flex;
  flex-wrap: wrap;
}
/* 折り返しをなくし、はみ出たらスクロールさせる */
.nowrap{
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  overflow-x: scroll;
  flex-wrap: nowrap;
}
```

ひとまずこれで、実装が完了。ただ見た目が悪すぎて、よく分からなくなってると思うので、下記のコードを書くと良い。

```css:CSS
.nav{
  background:#eee;
}
.nav li{
  list-style: none;
  text-align: center;
  flex: 1;
}
.nav a{
  display: block;
  padding: 10px;
  white-space: nowrap;
}
.nav a:hover{
  background: #d90000;
  color: #ffffff;
}
```

## 解説
見た目の部分は長くなるので省略するが、上の部分は解説したいと思う。

```css:CSS
.fbox{
  display: flex;
  flex-wrap: wrap;
}
```
display: flex;はご存知かと思うが、レイアウトを自在に出来るやつ。
子要素を横に並べる事が出来ます。(今回でいうとli要素)
flex-wrap: wrap;は要素が右端までいったら下に折り返させるやつ。

```css:CSS
.nowrap{
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  overflow-x: scroll;
  flex-wrap: nowrap;
}
```
この部分はすごく分かりづらいが1つ1つ説明すると、
scroll-snap-type: x mandatory;は実は今回のこの部分では必要ないコード。なぜ書いたかというと現在開発中のinstant.css(仮)に必要なコードだから。(要は書かないで良いです。)
-webkit-overflow-scrolling: touch;は、スマホで活躍します。スマホでスクロールしてパッと指を離した時に、スーッと惰性でスクロールが止まるようになります。そうする事でより自然なスクロールにする事が出来ます。
overflow-x: scroll;は要素が右端までいったらスクロールするようにさせます。
flex-wrap: nowrap;は先ほどflex-wrap: wrap;で折り返しにさせていたものを再度折り返しなしの状態にさせる為のコードです。(なので、.fboxの前に.nowrapを書くとうまく行かないかも)

という感じです。
いかかでしたでしょうか？
でも、あくまでもう遅いらしいというのは一説によるもの+私の主観的なものなので、ハンバーガーメニューが良いという事もあったりします。(デザイン的になど)

先ほども少し書いていましたが、今回使用したコードを混ぜつつ、爆速で爆速なサイトを作れるCSSフレームワークinstant.css(仮)を開発中です。
出来たらまた記事書いたりして宣伝します。よろしくです。
Laravel(5.8)をHerokuにデプロイする

## 概要
Herokuにリリースした際にやった事を記録として残しておく

## App周りの設定
### Appの作成

```
$ heroku create app-name
```

### buildpackの追加
これを設定する事でcomposerやnodejsがライブラリを追加してくれるようになります。

```
$ heroku buildpacks:add heroku/php 
$ heroku buildpacks:add heroku/nodejs
````

## DB周りの設定
### AppにDBを追加
```
$ heroku addons:create heroku-postgresql:hobby-dev -a app-name
```

### DBの情報の確認
DB情報はHeroku側で自動で決めてくれるため、下記のコマンドで確認して後ほど環境変数にセットする

```
$ heroku pg:credentials:url -a app-name
```

## 環境変数の設定
.envだと環境毎に値が変わって不便なため、Herokuにリリースする場合はサーバに環境変数をセットするとよい。

### 環境変数設定コマンド
```
$ heroku config:set TZ=Asia/Tokyo -a app-name
```

### 一般的に使うであろう環境変数
- APP_NAME=Laravel
- APP_ENV=production
- APP_KEY=
- APP_DEBUG=false
- APP_URL=
- LOG_CHANNEL=stderr
- DB_CONNECTION=pgsql
- DB_HOST=
- DB_PORT=5432
- DB_DATABASE=
- DB_USERNAME=
- DB_PASSWORD=

## Deploy周りの設定
### Procfileの作成
このファイルを作成する事でミドルウェアの設定や、デプロイ時にコマンドを走らせたりできるようになる。

```Procfile
release: ./heroku-entrypoint.sh 
web: vendor/bin/heroku-php-nginx -C .heroku/nginx/nginx.conf public/
```
- heroku-entrypoint.sh(名前はなんでもよい)はデプロイ時に実行する内容をシェルに書いています。
- webにはnginxの設定ファイルの場所を記載します。個人的にインフラ系のファイルはドットディレクトリにまとめているので上記の場所にしてありますが、実際はどこでも大丈夫です。

### nginxの設定ファイル
```.heroku/nginx/nginx.conf
location / {
    try_files $uri @rewriteapp;
}

location @rewriteapp {
    rewrite ^(.*)$ /index.php$1 last;
}
```

### Deploy時のBuild設定
HerokuにDeployする時にフロントエンド周りのbuildをしたい場合はpackage.jsonに下記の項目を書き足す事で実行してくれるようになります。

```package.json
"postinstall": "npm run prod"
```

## HerokuにDeploy
### Deploy
masterブランチをherokuにpushする事でリリースされます

```
$ git push heroku master
```

### 確認
```
$ heroku open
```
Rubyで深層学習のスタイル変換を動かす

![mymontage.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/c40e9e03-c423-0b66-981a-3806ec29bd00.jpeg)

### 準備するもの

* [ONNXRuntime](https://github.com/ankane/onnxruntime)
* [Magro](https://github.com/yoshoku/magro)[^3]
* [Fast Neural Style Transfer Model](https://github.com/onnx/models/tree/master/vision/style_transfer/fast_neural_style) からモデルをダウンロード

`st.rb`

```ruby
require 'magro'
require 'onnxruntime'

model = OnnxRuntime::Model.new('mosaic.onnx')

input = Magro::IO.imread(ARGV[0])
                 .transpose(2, 0, 1)
                 .expand_dims(0)
                 .to_a

output = model.predict(input1: input)

result = Numo::Int32.cast(*output['output1'])
                    .clip(0, 255)
                    .transpose(1, 2, 0)
                    .cast_to(Numo::UInt8)

Magro::IO.imsave(ARGV[1], result)
```

### 実行[^2]

```bash
ruby st.rb in.jpg out.jpg # pngも可
```

### 生成された画像
https://commons.wikimedia.org/wiki/File:Arimatsushibori.JPG [^1] を 1200x900に変換

![Arimatsushibori.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/8be31e70-117f-2ab6-6601-6581cd2aef49.jpeg)

imagemagickによるmontage
![mymontage.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/c2f51e4d-2ff7-ed41-4dbf-14a474026027.jpeg)

candy
![candy.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/271cb8b9-d7b0-17c0-5d06-83efef942fac.jpeg)

mosaic
![mosaic.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/259fafa3-ab19-ad86-cee1-6cdd57a45413.jpeg)

pointilism
![pointilism.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/6e5368be-d77d-c2a4-ca02-3763830aac40.jpeg)

rain_princess
![rain_princess.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/5a96315b-21f9-7a6d-00f7-b9c0186eee30.jpeg)

udnie
![udnie.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/144608/e79cd2fe-9f6e-ce6a-bf2e-bed468001dc0.jpeg)

美しい絵が出力されました。

[^1]: Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0) 
[^2]: 画像のサイズによってはエラーが出る。4の倍数じゃないとエラーが出るとか？
[^3]: created by @yoshoku
【メモ】HTMLの基本構造

#HTMLタグの整理

###ブロックレベル要素
- 見出し・段落・表など、文書を構成する基本となる要素
- 一般的なブラウザでは前後に改行が入る
- ボックスの概念が適用される（後に説明）

```
<div>
<form>
<h1>-<h6>
<ul>
<p>
etc...
```

###インライン要素
- ブロックレベル要素のコンテンツ（中身）として用いられる要素
- 前後に改行が入らず、文章の一部として表示される

```
<a>
<br>
<code>
<i>
<img>
<input>
<label>
<select>、
<span>
<strong>
etc...
```

#ボックスの概念について
- ボックスはデフォルトで、左から右まで矩形の領域を確保
- ブロック要素はすべて「ボックス（領域）」という四角のエリアを持っている
- ボックス領域はマージン、ボーダー（枠線）、パディングとコンテンツから成り立っている

<img width="179" alt="screenshot 1.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339259/f4a0f6c6-a490-e30a-3c0a-f9743119a114.jpeg">
論文実装のtips

論文実装においては実験を早く回すことが大事です。
コードを見やすくしたり、後々の運用を考えて作り上げることも大事ですが、論文実装がうまく行かなかったら全ておじゃんになるということを考えると、そのあたりの整形は最後でいいと言えるでしょう。
また、パッケージ化などの作業は慣れてくるとほとんど時間がかからなくなります。

論文実装で作るべきもの
train.py
---
- init_model
- load_weight
- train
- tensorboard
- evaluate

dataloader.py
---
- train_val_test_split

preprocess.py
---
ここはその論文の前処理を行って学習データを作る

model.py
---
モデルの定義
自作キーボードデビュー！ErgoDash作りからMacでキーマップの書き換えまで

# はじめに
前々からエルゴノミクスキーボードに興味があり，インターンで関東滞在の機会を得たので週末に[遊舎工房さん](https://yushakobo.jp/)を知人と訪れてErgoDashを購入しました！[(こんな感じのやつ)](https://www.google.com/search?q=Ergodash&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjbzNGDj7LkAhXPy4sBHRixCK4Q_AUIESgB&cshid=1567426793002590&biw=1680&bih=916)

ただ，デフォルトのキーマップではなく自分でカスタマイズしたキーマップにしてみたかったので，Macにその環境を作って焼くまでの手順をメモ程度に残します．

電子工作やハードウェアよりの知識は豊富でないので，間違っていたり回りくどいことをしていたらごめんなさい．

# 手順1: ErgoDashを手に入れる
「男は黙ってはんだ付け」という感じでした．

インターンでマンスリーに滞在中のため半田付けができないので遊舎工房さんの作業スペースで組み立てました．
はんだ付けは高専のときにやったきりで不安でしたが時間をかければどうにかなります．

ここら辺は自作大好きな人が写真付きでブログ書いていたり，お店に行けばスタッフさんに助けてもらえるので割愛です．

[ここ](https://github.com/omkbd/ErgoDash/blob/master/Doc/build.md)の言う通りにやれば失敗しません．

強いて言うと，友人と片手分ずつやって14時に作業開始して閉店ギリギリまで店にいたのでチャレンジしたい人は早めの時間から行くことをオススメします．

# 手順2: QMK Firmware を手に入れる
Githubのリポジトリ[(https://github.com/qmk/qmk_firmware)](https://github.com/qmk/qmk_firmware)をcloneしてインストールを走らせる．

```bash
$ git clone https://github.com/qmk/qmk_firmware.git
$ cd qmk_firmware
$ util/qmk_install.sh
```
ここで`lib/lufa`のもろもろがちゃんとあるか確認しておくといいです．
Github辿るとすぐ見つかるので必要であれば別途zipか何かで落とすといいと思います．
（僕の場合上手く引っ張ってこれておらずディレクトリが空になっていてbuildのときに`No such file or directory`と怒られたので）

# 手順3: Defaultのキーマップからカスタム用のファイルをコピー・キーマップの作成

```bash
$ cp -r keyboards/ergodash/rev1/keymaps/default/ keyboards/ergodash/rev1/keymap
s/[YOUR_ORIGINAL_KEYMAP_NAME]
```

コピーしておくことでデフォルトに戻したくなったりしたときやファイルを壊してエラーに遭遇したときに安心です．
ここの`keymap.c`とかを好きな形に書き換えます．

# 手順4: HEXファイルの作成

フォーマットは`[キーボード名]:[キーマップ名]`のような形です．

```bash
$ make ergodash/rev1:[YOUR_ORIGINAL_KEYMAP_NAME]
```
これで`qmk_firmware`のところにhexファイルができていると思います．

# 手順5: QMK Toolboxのインストール・焼く

自分のキーマップを焼くためのツールです．
Github[(https://github.com/qmk/qmk_toolbox)](https://github.com/qmk/qmk_toolbox)見れば書いてありますがbrewで簡単にいけます．

```bash
$ brew tap homebrew/cask-drivers
$ brew cask install qmk-toolbox
```

QMK Toolbox Applicationを開いて`Local File`にさきほど作った`hexファイル`を設定します．
`Keyboard from qmk.fm`を`ergodash/rev1`に設定します．
後はキーボードを繋いでリセットボタンを押して数秒以内に`Flash`を押せば`avrdude`が走って書き込みが動く(人は動く)．

# 手順5で詰む人用
僕はWebを頼りにやって手順5で詰みました．
遊舎工房のスタッフさんに「Macだとシリアル通信のドライバーがいるかも」（？）云々と助言をいただいていたのを思い出して[ここ](https://www.ftdichip.com/Drivers/VCP.htm)とか色々漁ってみても上手くいきませんでした．

```bash
ls /dev/tty*
```

を叩いてもキーボードを認識してる反応もなく，QMK Toolboxでも上手くポートを識別してくれませんでした．

色々自分のわかる範囲で見ていくと，キーボードのリセットボタンを押してから数秒の間上記コマンドを叩くと`/dev/ttyusbmodem...`とキーボードが認識されていることが確認できました．

ので，QMK Toolboxが走らせている`avrdude`コマンドをキーボードのリセットボタンを押してすぐ叩くことで書き込みに成功しました．

高い買い物だったのでヒヤヒヤしながら調べました．

# おわりに
まだまだ慣れずにMacBookのキーボードに逃げてしまいがちですが，肩こりがひどい人なので使いこなしてできるエンジニアオーラをガンガン出していきたいと思います．

俺の考えた最強キーマップなどお持ちの方がいらっしゃればぜひコメント欄に掲載くださいm(_ _)m

# キーマップアレンジのメモ
ここのページがわかりやすい
https://qiita.com/ReSTARTR/items/970354940f49c67fb9fd

# 参考文献等
・[QMK](https://github.com/qmk)
・[Virtual COM Port Drivers](https://www.ftdichip.com/Drivers/VCP.htm)
・[macで自作キーボードのキーマップ設定](https://sfender.hatenablog.com/entry/2019/02/11/182340)
・[Macでもシリアル接続できるぞー！](https://www.vincentina.net/?p=5025)
・[最高に使える自作キーボード（ErgoDash)を目指してキーマップをイジってみた](https://qiita.com/keita69sawada/items/ddc054e6631f3a06b0ba)
0.1ぐらいから始めるProjectEuler@python　Problem 7

どもども、最近帰るのが遅くてお疲れなとある学生です。
というわけで、7問目書いていきましょう。

```python:Problem_7.py
#素数を小さい方から6つ並べると2、3、5、7、11、13であり、6番目の素数は13である。
#10 001番目の素数を求めよ。
sosuu = []
k = 0
n = 1
while k != 10001:
    n = n + 1
    p = True
    for i in range(2,n):
        if n % i == 0:
            p = False
            break
    if p == True:
        sosuu.append(n)
        k = k + 1
print(sosuu[-1])
```
解　104743
はい、私はこう書きました。
圧倒的脳筋です。
####解き方の解説をしていきます。
nとn未満のiを割って割り切れたらpをFalseにしてbreakでifを切る。割り切れなかったらsosuuに値を代入してkの値を＋1する。この流れをkが10001になるまで繰り返し、kが10001になったらsosuuの最後の値を出力って感じです。

圧倒的計算量。圧倒的無駄！！ただ、これ以外に解法は1つ思いついたのですが、プログラムにできなかったです悲しみ。
でもまぁひとまずは、こんな感じですかね？もしわからないことやアドバイス等あればコメントしていただければと思います。
というわけで気が向いたら次も見ていってください。よろしくお願いします。
RHEL8+nginxイメージの作成

### 概要
CentOS7にDockerをインストールしたサーバで、
RHEL8+NGINXのイメージをDockerfileで作成して、コンテナ起動するところまで記事にしたいと思います。

### 実行環境
実行環境は以下の通りです。

サーバ：1台
OS：CentOS Linux release 7.6.1810 (Core)
docker：19.03.1

また、RHEL8のベースイメージは、Red Hat社が公式に提供しているユニバーサルベースイメージ(UBI)として入手できるので、これを活用してイメージを作成したいと思います。UBIとして提供されている各種ベースイメージは全て無料で入手と再配布が可能です。詳細は以下のRed Hat公式マニュアルがありますので、興味のある方はご参照ください。

[■RHEL8-コンテナーの構築、実行、および管理](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html-single/building_running_and_managing_containers/index)

「第4章 Red Hat Universal Base イメージの使用 (標準、最小、ランタイム)」から読むといいと思います。

### Dockerfileによるイメージ作成
さっそくDockerfileを紹介します。

```bash:Dockerfile
FROM registry.access.redhat.com/ubi8/ubi:latest

# Install of NGINX
RUN yum update --disableplugin=subscription-manager -y \
 && rm -fr /var/cache/yum
RUN yum install --disableplugin=subscription-manager nginx -y \
 && rm -fr /var/cache/yum
CMD ["-g","daemon off;"]
ENTRYPOINT ["nginx"]
```

UBIイメージに追加でソフトウェアを追加する場合、サブスクリプション管理を無効にしておくと、確実に再配布することができます。`subscription-manager`プラグインを無効にすると、ソフトウェアを追加する時、無料で入手可能なリポジトリのパッケージのみが使用できる状態になります。

では、Dockerfileでイメージ作成します。

```bash:Dockerfileでイメージ作成
# docker build -f Dockerfile -t rhel8-ubi/nginx .
Sending build context to Docker daemon  29.81MB
Step 1/5 : FROM registry.access.redhat.com/ubi8/ubi:latest
(略)
Successfully built 7399ce96786e
Successfully tagged rhel8-ubi/nginx:latest
# docker images
REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
rhel8-ubi/nginx                            latest              7399ce96786e        18 seconds ago      276MB
```
### コンテナを起動してNGINXへアクセスする
最後に`docker run`コマンドでコンテナを起動して、NGINXへアクセスします。

```bash:コンテナを起動
# docker run --name nginx0001 -h nginx0001 -p 8000:80 -d rhel8-ubi/nginx
d9a05d5e8f283d27a6db210018ddd76129dbade56b94993460b2fd490b65ed59
# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
d9a05d5e8f28        rhel8-ubi/nginx     "nginx -g 'daemon of…"   10 seconds ago      Up 9 seconds        0.0.0.0:8000->80/tcp   nginx0001
```

あとは、Webブラウザを開いて、以下のURLへアクセスすると、
NGINXのTOP画面が表示されます。

http://＜DockerホストのIPアドレス＞:8000

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198785/45fa914e-020d-bf2b-a2aa-9bee9da05033.png)


以上で終わりです。

### 引用元
以下を参考に本記事を作成させていただきました。

[コンテナーの構築、実行、および管理](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/8/html-single/building_running_and_managing_containers/index#using_red_hat_universal_base_images_standard_minimal_and_runtimes)
[CentOS 7とPodmanで触ってみようRed Hat UBI - ビルド編](https://rheb.hatenablog.com/entry/podman_build_with_dockerfile)
[Docker入門 CentOSとNginxでWebサーバー構築](https://qiita.com/sbut_sug/items/b7c92ca5c7215d294355)

最後ですが、上記引用元の「CentOS7とPodmanで触ってみようRed Hat UBI - ビルド編」では、CentOS7+Podmanの組み合わせによるDockerfile作成やコンテナ起動の記事ですが、本記事で紹介した通り、CentOS7+Dockerの組み合わせでも、registry.access.redhat.comにアクセスすることができます。

これによりRHEL8ベースイメージを`docker pull`することができますので、ぜひRHEL8を手軽に触りたい方は、これでコンテナ起動して操作してみては如何でしょうか。
※たしか記事の執筆者の方がツイートされてるのを拝見して利用させてもらいました。ありがとうございました。


以上です。
【Swift】Bluetoothの設定(ON/OFF)を確認する

## CBCentralManager()を使用する
初期化処理時にdelegateを行う。

```Swift
let manager = CBCentralManager()
manager.delegate = self
```

## Bluetoothのステータス変更を受け取る
CBCentralManagerDelegateを利用

```Swift
extension 〇〇Manager: CBCentralManagerDelegate {
  func centralManagerDidUpdateState(_ central: CBCentralManager) {
    if central.state != .poweredOn {
      //ここにOFFのときの処理を記載（アラートを表示など）
    }
  }
}
```

## 特定処理の実行前にステータスを確認

```Swift
  func confirmBLEStatus() -> Bool {
    if manager.state != .poweredOn {
      //ここにOFFのときの処理を記載（アラートを表示など）
      return false
    } else {
      return true
    }
  }
```
[Linux] ls -lhでファイルサイズをわかりやすく表示する



普通にls -lを打つとバイト単位で表示されてわかりにくい

```
[root@localhost ~]# ls -l /
合計 32
lrwxrwxrwx.   1 root root     7  5月 11 23:40 bin -> usr/bin
dr-xr-xr-x.   5 root root  4096  8月 27 21:42 boot
drwxr-xr-x.  20 root root  3160  9月  2 21:33 dev
drwxr-xr-x. 152 root root 12288  9月  2 21:33 etc
drwxr-xr-x.   4 root root    30  8月 27 21:28 home
lrwxrwxrwx.   1 root root     7  5月 11 23:40 lib -> usr/lib
lrwxrwxrwx.   1 root root     9  5月 11 23:40 lib64 -> usr/lib64
drwxr-xr-x.   2 root root     6  4月 11  2018 media
drwxr-xr-x.   2 root root     6  4月 11  2018 mnt
drwxr-xr-x.   3 root root    16  5月 11 23:42 opt
dr-xr-xr-x. 137 root root     0  9月  2 21:33 proc
dr-xr-x---.  14 root root  4096  7月 17 23:00 root
drwxr-xr-x.  41 root root  1300  9月  2 21:33 run
lrwxrwxrwx.   1 root root     8  5月 11 23:40 sbin -> usr/sbin
drwxr-xr-x.   2 root root     6  4月 11  2018 srv
dr-xr-xr-x.  13 root root     0  9月  2 21:33 sys
drwxrwxrwt.  12 root root  4096  9月  2 21:34 tmp
drwxr-xr-x.  13 root root   155  5月 11 23:40 usr
drwxr-xr-x.  23 root root  4096  7月 13 18:57 var
```

ls -lhオプションをつければgood

```
[root@localhost ~]# ls -lh /
合計 32K
lrwxrwxrwx.   1 root root    7  5月 11 23:40 bin -> usr/bin
dr-xr-xr-x.   5 root root 4.0K  8月 27 21:42 boot
drwxr-xr-x.  20 root root 3.1K  9月  2 21:33 dev
drwxr-xr-x. 152 root root  12K  9月  2 21:33 etc
drwxr-xr-x.   4 root root   30  8月 27 21:28 home
lrwxrwxrwx.   1 root root    7  5月 11 23:40 lib -> usr/lib
lrwxrwxrwx.   1 root root    9  5月 11 23:40 lib64 -> usr/lib64
drwxr-xr-x.   2 root root    6  4月 11  2018 media
drwxr-xr-x.   2 root root    6  4月 11  2018 mnt
drwxr-xr-x.   3 root root   16  5月 11 23:42 opt
dr-xr-xr-x. 134 root root    0  9月  2 21:33 proc
dr-xr-x---.  14 root root 4.0K  7月 17 23:00 root
drwxr-xr-x.  41 root root 1.3K  9月  2 21:33 run
lrwxrwxrwx.   1 root root    8  5月 11 23:40 sbin -> usr/sbin
drwxr-xr-x.   2 root root    6  4月 11  2018 srv
dr-xr-xr-x.  13 root root    0  9月  2 21:33 sys
drwxrwxrwt.  10 root root 4.0K  9月  2 21:35 tmp
drwxr-xr-x.  13 root root  155  5月 11 23:40 usr
drwxr-xr-x.  23 root root 4.0K  7月 13 18:57 var
```
apollo-clientを使っていてデータが変に重複してる（キャッシュが変）？と思った時に見てみる事

# 例

例えばこういう感じの`id`が重複するパターンのデータをapolloを使って受け取った場合、

```json
{
  "data": {
    "results": [
      {
        "id": 1,
        "className": "ClassA",
        "value": 42
      },
      {
        "id": 1,
        "className": "ClassB",
        "value": 24
      }
      
    ]
  }
}
```

通常通りこういう感じで表示すると

```tsx
const client = useApolloClient()
client.query({
  query: QUERY,
})
.then(({ data }) => {
  console.log(JSON.stringify(data, null, 2))
})
```

こんな感じになってしまう。（*ClassAがClassBのデータに上書きされてる*）

```json
{
  "results": [
    {
      "id": 1,
      "className": "ClassB",
      "value": 24
    },
    {
      "id": 1,
      "className": "ClassB",
      "value": 24
    }
  ]
}
```

# 原因

ApolloClientを作る時に特段事情がなければ[InMemoryCache][1]をこういう風にデフォルトのままで使ってると思う。

```tsx
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import { ApolloClient } from 'apollo-client';

const cache = new InMemoryCache();

const client = new ApolloClient({
  link: new HttpLink(),
  cache
});
```

このままだと、GraphQLで返ってくるデータに`id`(もしくは`_id`)があると、これをキーとしてキャッシュしてしまう。この為、1つの問い合わせの中に複数テーブルのデータが混ざる場合、`id`が重複してしまう可能性があり、これによりGraphQL自体は正しいが（Networkタブでは期待通りのデータが返ってきてる）、ApolloClientで取れるデータが期待通りにならない。

> https://www.apollographql.com/docs/react/advanced/caching/#normalization
> By default, InMemoryCache will attempt to use the commonly found primary keys of id and  __id for the unique identifier if they exist along with __typename on an object.

# 解決方法

1. uuidを使う
1. ulidを使う
1. [InMemoryCache][1]で[normalization][2]をする
1. `id`を架空のランダムな物にして（例えばその場でuuidをつくって使う）、`_id`に本来入れるプリマリーキーを入れる


**1**の場合、グローバルにユニークになるのでこのcachingと相性が良くなるが、新規プロジェクトじゃないとかなりやっかい。その上uuidは基本ソート出来ないのでRailsなどで使う`Model.first`みたいな物が期待した物にはならない。（idが登録順序にならないので）

**2**の場合、cachingとの相性、ソート可と便利だが、やはり新規プロジェクトじゃないとかなりやっかい。

**3**の場合、面倒。上の例だとApolloClientを作る際にこのような形で`InMemoryCache`を設定する必要がある。似たようなクエリーがあればその数ほどやらないといけない。

```tsx
import { InMemoryCache, defaultDataIdFromObject } from 'apollo-cache-inmemory';

...
...

const cache = new InMemoryCache({
  dataIdFromObject: object => {
    switch (object.__typename) {
      case 'Result': return `${object.className}-${object.id}`;
      default: return defaultDataIdFromObject(object);
    }
}});

...
```

**4**の場合、React側で`id`は使い物にならないが、とりあえず期待と違うキャッシングはされない。React側では`id`の代わりに`_id`を使う（`_id`にこだわる必要は無く名前は何でも良いが...）。

```graphql
query {
  results{
    id
    _id
    className
    value
  }
}
```

```rb
# 例えばRuby側がサーバーで、データを返すとして
def ...
  class_a = ClassA.find(id)

  results = [
    {
      id: SecureRandom.uuid, # 例えばuuidを使う
      _id: class_a.id, # React側ではこちらを使う
      ...
      ...
    }
    ...
  ]

  { results: results }
end

```




[1]: https://www.apollographql.com/docs/react/advanced/caching/
[2]: https://www.apollographql.com/docs/react/advanced/caching/#normalization
gitでpushやpullができなくなったときに対処した方法

先日、急にリモートリポジトリへの`push`や`pull`ができなくなってしまいました。
原因は特定できなかったものの、なんとか対処することができたので、その方法を書いていきます。

## 権限を外されたのではないか
リモートリポジトリを管理している人が私ではなかったので、リモートリポジトリを管理している人に直接聞いてみました。
しかし、権限を外したような設定はしていないとのことで、これが原因ではなさそうです。

## 色々調べる
まず、`git remote -v`で remote のリポジトリのアドレスを調べてみます。

```zsh
$ git remote -v
origin [URL] (fetch)
origin [URL] (push)
```

次に、`git config --list`で調べます。

```zsh
$ git config --list
credential.helper=osxkeychain
filter.lfs.clean=git-lfs clean -- %f
filter.lfs.smudge=git-lfs smudge -- %f
filter.lfs.process=git-lfs filter-process
filter.lfs.required=true
user.name=KenAra
user.email=xxxxx@gmail.com
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
remote.origin.url=git@github.com:xxxxx/xxxxx.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master
```

## 最終的な解決方法
色々試しましたが結局のところ、もう一度`git remote add`を行うことで復活させることができました！

```console
$ git remote add origin https://[username]:[password]@/github.com:xxxxx/xxxxx.git
```

原因は特定できませんでしたが、なんとか`push`や`pull`をできるようになったのでよかったです。
【C#】C#言語仕様を翻訳してみた 〜 Hello World 〜

# はじめに
この記事はC#言語仕様を翻訳してみたシリーズの第2項である。
他の項の翻訳も見たい場合は以下のリンクから確認できる。

1. [はじめに](https://qiita.com/TomoProg/items/20699ef4e9ae807596f8)
1. [Hello World]()

また、この記事を書く経緯や翻訳方針についての説明は第1項 [はじめに]  (https://qiita.com/TomoProg/items/20699ef4e9ae807596f8) を参照していただきたい。

# この記事の翻訳対象
この記事では[**Hello world**](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/language-specification/introduction#hello-world)を翻訳する。

# 翻訳文
### Hello World

“Hello, World”プログラムはプログラミング言語の紹介に伝統的に使われています。
これはC#のHello Worldプログラムです。

```cs
using System;

class Hello
{
    static void Main() {
        Console.WriteLine("Hello, World");
    }
}
```

通常、C#のソースファイルの拡張子は`.cs`です。
この"Hello, World"プログラムが`hello.cs`というファイルに保存されているとすると、マイクロソフトのC#コンパイラで以下のコマンドでコンパイルすることができます。

```sh
csc hello.cs
```

`hello.exe`という実行可能なアセンブリが生成されます。

このアプリケーションを実行した時の出力は以下の通りです。

```sh
Hello, World
```

この"Hello, World"プログラムは`using`ディレクティブで始まっており、`System`名前空間を参照しています。

名前空間はC#のプログラムとライブラリを階層的に整理するための手段です。

名前空間は型と他の名前空間を含みます。
例えば、`System`名前空間はプログラムで参照されている`Console`クラスや`IO`、`Collections`といった名前空間を含んでいます。
特定の名前空間を参照する`using`ディレクティブを使用すると、その名前空間のメンバーである型を修飾せずに使用できます。
`using`ディレクティブのおかげで、`System.Console.WriteLine`を`Console.WriteLine`と省略できます。

"Hello, World"プログラムで宣言された`Hello`クラスは`Main`と名付けられたメソッドを一つ持っています。
`Main`メソッドは`static`修飾子で宣言されています。
インスタンスメソッドが`this`を使って特定のインスタンスオブジェクトを参照できるのに対し、スタティックメソッドは特定のオブジェクトを参照せずに使用できます。
決まりごととして、`Main`と名付けられたスタティックメソッドはエントリーポイントとして機能します。

プログラムの出力は`System`名前空間の`Console`クラスの`WriteLine`メソッドによって生成されます。
このクラスはデフォルトではマイクロソフトのC#コンパイラによって自動的に参照される.NET Frameworkのクラスライブラリによって提供されます。
C#自身は個別のランタイムライブラリを持たないことに注意してください。
その代わり、.NET FrameworkはC#のランタイムライブラリです。

# 次回
[Program structure](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/language-specification/introduction#program-structure)を翻訳予定。

それではまた。
TomoProg
Rails ログファイルを削除する

# はじめに
こんにちは！
この記事では、Railsのログを削除する方法をご紹介します。
ログを削除、というとログファイルごと消してしまうイメージなように思いますので、**ログファイルを空にする**という言い方のほうが正しいかもしれませんね。。

コマンドを使ってファイルを空にしたいと思います。

**前提：Railsの環境構築, 簡単なターミナルの知識**

# Railsにおけるログの場所
Railsのログの場所は、アプリケーションのrootパスの直下にある**logフォルダ**になります。アプリケーションのrootパスとは`rails new アプリ名`コマンドを打った時の、そのアプリフォルダの直下になります^^

具体的には、

```
log/development.log
log/production.log
```

があると思います。
productionモードでこのアプリを起動したことがない場合、production.logはなく、`development.log`だけ存在するかもしれません！

# コマンド
次にターミナルで、アプリケーションのrootパスにいってください！
そして、下記のコマンドをターミナルから打ちます！

```
$ echo '' > log/development.log 
```

これで`ls -la log/development.log`コマンドを打ってみるとfile-sizeが1になっていると思います。(0にはならないのですね。。。)

# 終わりに
今回はターミナルのコマンドを使って、ログファイルを空にする方法をご紹介しました。
ですが、実は手っ取り早くログファイルのサイズを0にするのは、development.logを削除するのがいいかもしれません。。。試したことはないです^^;
初心者プログラマーの僕が、テスト駆動開発を愛する5つの理由

# 最初に
テスト駆動開発（以後TDD）の存在を知って、自分で取り入れてみてから、自分の開発は良くなったと思っています。

TDDを人におすすめしよう！　と思って本を読んだり色々と調べていたりするうちに、
[TDDは死んだ](https://yattom.hatenablog.com/entries/2014/04/24) とか、テスト全部書かなくても...と言われていることを知りました。
それでも自分はTDDで開発するのが好きだし、自分には合っていると思うので、自分がTDDを愛する理由を書いてみたのがこの記事です。
若干ポエム寄りになっているかもしれませんが、ご容赦いただけると幸いです。

# 前提としていること

- TDDの基本的な流れとして、タスク細分化→Red/Green/Refactoringのループを回す、であること
- 実践者は初心者であり、実装にまだ不慣れであること（内容についての言い訳ではなく、そういう人がTDDを実践した事で感じた事を書いたという意味）
- TDDではなく自動テストによる恩恵も含む。TDDを実践すれば自動テストの恩恵を受ける事ができるから。

# TDDを愛する理由たち

## 1.目の前のタスクに集中するリズムを作ってくれる

### 解決すべき問題

プログラマーが仕様書を受け取った時点で、詳細設計まで網羅されている事はあまりないと考えています。
必ず、ある程度ざっくりと決まった仕様から、コードを書ける程度のToDoに分解せねばなりません。
まずどこまで分解すればコードを書きやすくなるのか、初心者にはこの時点でハードルがあります。
また首尾よくタスクを分解できても、今度は複数のタスクが見えていることで、同時に複数の事が気になってしまい、生産性が下がってしまいます。

### TDDによる解決

TDDではテストを書くと言われていますが、それより前にまず、**仕様をざっくりToDoリストに落とし込みます。**
その後に、よく知られているようなRed/Green/Refactoringが始まります。

これによって、上記の問題2つが解決されます。

>まずどこまで分解すればコードを書きやすくなるのか、初心者にはこの時点でハードルがあります。

テストケースが書きやすくなるまで分解します。シンプルです。

>今度は複数のタスクが見えていることで、同時に複数の事が気になってしまい、生産性が下がってしまいます。

Red/Green/Refactoringの各ステージで、もし行き詰まった場合に修正すべき対象は何なのか？　が明白です。
同時に考える問題は、（初心者でなくとも）少ないほうが良いに決まっています。TDDのリズムは、目の前の事に集中する補助線となってくれます。

## 2.安心と共に修正できる
### 解決すべき問題

レビューを受けると多くの修正すべき問題点を指摘されます。
レビュー体制が整っている事は喜ばしい事である反面、沢山の指摘事項に怯む事もよくあります。
そして指摘事項を修正している間に、問題なく動いていたコードが破壊されていない保証はありません。

### TDDによる解決

自動テストがあれば、既存コードを破壊してしまう可能性は大きく減じられます。
また、テストコードを書きやすいようにToDoが細分化されているので、どのToDoにおいて問題があったのかが分かりやすくなります。

## 3.設計の問題に早期に気付く事ができ、手戻りが減る

### 解決すべき問題

私が現在最も苦労しているのは、コードの詳細設計です。
どのように処理を分割すべきか？　分割した処理はどこに書くべきか？　そういった概念は現在進行系で勉強している所です。
設計の問題において最も苦しい事は、設計に問題があっても、プロダクションコードだけ書いている間はなかなか気付かないという事です。
問題に気付けなければ相談しに行くこともできず、結果としてレビューの段階で大きく手を入れざるをえなくなります。

### TDDによる解決

TDDは、特に設計になにか問題が起こると、**テストが書き辛くなります。**これが設計を見直す指標になります。
ToDoが大きすぎたり、特定の実装に依存し過ぎていたりすると、どうしてもテストが綺麗に書けません。
こうした時には実装の手を止めて、実装方法を相談しに行くようにしています。

## 4.歩幅を調節しながら進んでいける

### 解決すべき問題

TDDを批判する言葉の中に、「そんなに細かい粒度でテストを書く必要は無い」というものがあります。
具体的にその現場を見たわけではありませんが、その批判は的を射ているのかもしれません。
ベテランプログラマーでなくとも、「このToDoくらいはテスト書かずとも良いな...」と思う事もあります。

### TDDによる解決

TDDには「歩幅の調節」という言葉があります。TDDは小さなToDoでテストを書いていく事を推奨はしていますが、必須ではありません。
Kent Beckの「テスト駆動開発」の中で、**テストしなくてよいものはあるか** という問いが投げ掛けられています。

>シンプルに答えるなら、本書レビュアーのPhlipが言うところの「不安が退屈に変わるまでテストを書く」となる。これは一種のフィードバックループだ。ということは、答えは皆さん自身で見つけなければならない。
ＫｅｎｔＢｅｃｋ. テスト駆動開発 (Japanese Edition) (Kindle の位置No.4559-4561). Kindle 版. 

既に十二分に熟知している場所においては、少なくとも個人の不安を解消するためのテストコードは不要です。
**うちではTDDを実践しているから、必ず最初にテストを書いてね** という現場がもしあれば、それはTDDを実践しているとは言えないとすら思います。

## 5.（他の開発手法に比べて）比較的すぐに実践できる、すぐに効果を発揮する

### 解決すべき問題

プログラマーがコードを洗練させていく方法はTDDだけではありません。
動く綺麗なコードを生み出すために、DDDだったり、Clean Architectureだったり、他の勉強をすることも良いでしょう。
しかしそれらの勉強が生きるまでに、あるいは普段のコードに馴染むまでには、ある程度時間が掛かります。

### TDDによる解決

**テストを書くことが楽だとは言いません。** むしろテストを書くのは大変です。
モック作成のような、プロダクションコードを書く上では必要の無い知識を身につける必要もあります。
しかしTDDの導入自体は明日からやってみる事は可能です。
そしてその恩恵は、意外なほどすぐに現れます。

# 最後に

私がTDDを取り入れてみて、感じている恩恵についてまとめました。
まだまだ勉強すべきことは多いながら、TDDが死んだと言われるのは寂しい気持ちがあってこの記事を書くに至りました。

これから実践を重ねた結果、いつか私もTDDを放り投げるかもしれません。
しかしそういう日が来ても、TDDを勉強、実践する事で得たものは今後糧になっていくと思っています。
scp コマンドでディレクトリを転送しつつ統合する

# 目的

- ファイルサイズなどの関係で CI の artifacts を CI の外で管理したい
- 送信側 (Docker image) に手を加えずに解決したい （rsync などを入れない）

# 結果

## シンプル

```
scp -pr srcdir user@host:~/destdir
```

- `~/destdir` が存在しない： `srcdir/file` は `~/destdir/file` へ
- `~/destdir` が存在する： `srcdir/file` は `~/destdir/srcdir/file` へ
- `srcdir/` にしても変わらない （参考：[scpとrsyncでパスのケツスラッシュのありなしの挙動を毎回迷うのでメモ - 俺たちのブログ](http://oretachino.hatenablog.com/entry/2014/12/11/003815)）

結論： 統合後のパスに `srcdir` を含めたくないので使えない

## ワイルドカード

```
scp -pr srcdir/* user@host:~/destdir
```

- `~/destdir` の有無に関わらず `srcdir/file` は `~/destdir/file` へ
- `srcdir/.dotfile` はコピーされない場合が多い（シェルの設定による）

結論： 悪くはないが完全ではない

## スラッシュドット

```
scp -pr srcdir/. user@host:~/destdir
```

- `~/destdir` の有無に関わらず `srcdir/file` は `~/destdir/file` へ
- `srcdir/.dotfile` も `~/destdir/.dotfile` にコピーされる
- `cd srcdir; scp -pr . user@host:~/destdir` と等価のはず

結論： 使える

# その他

- 転送先のディレクトリは1階層しか作ってくれないので、深いところに直接コピーする場合は `ssh user@host mkdir -p ~/destdir/path/to/target` などが必要
- rsync なら `rsync -avz srcdir/ user@host:destdir` が正義 （参考：[地雷だらけのrsyncを理解する。 - こせきの技術日記](http://koseki.hatenablog.com/entry/20090424/rsync)）
- tar と ssh を組み合わせる方法もある （参考：[sshだけでファイル・ディレクトリ転送(scp, sftpなし) - Qiita](https://qiita.com/takaakikasai/items/4e9b2a67fd2a932f4756)）