OmniAICreator/Qiita-1.07M huggingface dataset:
Body-ParserがExpressにexpress.json()として標準搭載されている話

# 結論
`v4.16.0`以降のExpressを使用している場合は、`express.json()`が使える。

# はじめに

`Express`でクライアント経由からデータを会得する場合、`Body-Parser`をインストールして`req.body`経由でデータを会得するのが一般的でした。
しかし、現在のExpressには、Body-Parserの機能が標準で搭載されていることを知りました。それが`express.json()`です。

## `express.json()`とは

[Express 4.x - API リファレンス](http://expressjs.com/ja/api.html#express.json)

`Body-Parser`を基にExpressに組み込まれた機能です、クライアントから送信されたデータを、`req.body`経由で会得、操作できます。

> This middleware is available in Express v4.16.0 onwards.

4.16.0以降のバージョンに搭載しているので、それ以前のExpressでは使えないようです。</br>
（2019年6月20日現在npmからデフォルトでインストールできる最新版がv4.17.1、最新のバージョンを知りたい場合は[express - npm](https://www.npmjs.com/package/express)へ）


## 使い方

appに

```js

app.use(express.json())
app.use(express.urlencoded({ extended: true }));
```

を記述します。

# 作ってみた


[GitHub - atlansien/POST-processing-at-express_json](https://github.com/atlansien/POST-processing-at-express_json)

[コード部分](https://github.com/atlansien/POST-processing-at-express_json/blob/3535a5ffac0b0c7b1d6a38007deefc202d68010b/app.js#L10)


過去に作ったBody-Parserを利用したPOSTリクエスト処理を行うものですが、express.jsonに変更してもとくに問題なく動作しました（機能が少なすぎるのはありますが）

## Body-Parserとの違い

とくに差は見当たりませんでした。今後Expressの最新版が使える場合は、Body-Parserをインストールしなくても良さそうです。

## Express3でも標準搭載だった。

`Express3`でも、Body-Parserは`express.bodyParser`として使用できたみたいです。Express4になるに当たって外部ミドルウェアになって、それがまた搭載されたようですね。

[Express 4 への移行](https://expressjs.com/ja/guide/migrating-4.html)
JavaScriptでトランプをめくるアニメーションを作成してみた

# はじめに

カードをめくるアニメーションを作成してみました。

## 1. フォルダー構成
フォルダー構成は以下のようになります

```
.
 ├── card_turning.html
 ├── cardTurning.js
 ├── clover11.js　  
 └── backcard.png
```

## 2. 実装
コードは以下のようになります。

```card_turning.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>カードを捲るアニメーションプログラム</title>
</head>
<body>
    </div>
        <div>
            <img id='img' src='./backcard.png'/>
        </div>
        <div>
            <button id="button">めくる</button>
        </div>
    <div>
    <script src='./script.js'></script>
</body>
</html>
```

以下はJavaScriptのコードになります。

```cardTurning.js
const buttonElem = document.getElementById('button');
let isBack = true;

if(buttonElem !== null){
    buttonElem.addEventListener('click', () => {
        const element = document.getElementById('img');
        if(element !== null){
            let imagePath = isBack ? './clover11.png' : './backcard.png';
            rotationAnimationLoop(element, imagePath, 0);
            isBack = !isBack;
        }
    });
}
/* カードを捲る処理を指定された角度になるまでループさせる関数
* @param  {Object} element   imgタグのElement Object
* @param  {String} imagePath 画像のパス
* @return {Number} deg       カードの回転角度
*/
const rotationAnimationLoop = (element, imagePath, deg) =>{
    if( deg <= 180 ){
        rotationAnimation(element, imagePath, deg);
        setTimeout( 
            () => {
                rotationAnimationLoop(element, imagePath, deg+= 5 ) 
            }, 
        1 );
    }
}

/* カードを捲る処理
* @param  {Object} element   imgタグのElement Object
* @param  {String} imagePath 画像のパス
* @return {Number} deg       カードの回転角度
*/
const rotationAnimation = (element, imagePath, deg) =>{
    if ( 90 === deg ){
        element.src =  imagePath;
    }else {
        element.style.webkitTransform = 'rotateY(' + deg + 'deg)';
    }
}
```

## 3. 結果

結果は、こんな感じになります。


![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263738/8be347f0-e8f6-f313-e2ad-0b3b5bbd6573.gif)
PHPUnit 親クラスのメソッド呼び出しをモックする

## 問題：親クラスのメソッドを呼び出している処理をモックしたい。
```php
class Parent {
    function foo() {
        echo 'bar';
    }
}

class Child extends Parent {
    function foo() {
            $foo = parent::foo();
            return $foo;
    }
}
```
上のような処理をテストしようと、ChildのfooのテストでParentのfooが呼ばれることをmockで確認しようとしていたところ、親クラスのmockがうまくいかない。。。。（調べてみると、そもそも親のメソッドに依存している時点で、既に継承ではなく集約を使用するべき別クラスに処理を分ける必要があるのではないか？という回答もありました。https://stackoverflow.com/questions/6711647/in-phpunit-how-do-i-mock-parent-methods　
（今回は、別クラスに外出しするのではなく、親クラスのメソッド呼び出しをモックする方法を探しました。））


## 解決方法：親クラスメソッドの呼び出しtraitを展開
trait ParentCallTestable　を実装します。

```php
trait ParentCallTestable
{
    /**
     * Call parent methdod
     * @param  string $method  Method name to call
     * @return mixed
     */
    public function parent($method, ...$args)
    {
        return parent::$method(...$args);
    }
}
class Child extends Parent {
    use ParentCallTestable;
    function foo() {
            //$foo = parent::foo();
            $foo = $this->parent('foo');
            return $foo;
    }
}
```
これで、Childrenクラスのparent('foo')が呼ばれることをmockしてテストすることで、親クラスのメソッドの呼び出しをmockすることができました。

以上です。
TeraTermでトンネリングしてWinSCPでファイル転送する方法

**踏み台を介さないと通信できないサーバ**に対して
TeraTermでSSH転送(ポートフォワード)してから
WinSCPでファイルを転送する方法です。

A:ローカル
B:踏み台
C:リモートホスト

だとすると、

AからCにファイルを転送することができます。

僕自身、恥ずかしいことに、インフラに携わっていながらこのやり方を
知らなかった理由は
**2つのアプリが設定を共有するという事実が想定外だったからです。**

同じく知らない方のためにやり方をご説明します。

---

###◆手順
①TeraTermで設定を行う
②WinSCPで設定を行う
③ファイルを転送する

とっても簡単です！

図にするとこんな感じです▼
![ssh_port_forward.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442428/d53862ce-ba72-e453-1888-07462c2ead46.png)
`自分のPC: localhost
踏み台サーバ: 172.20.0.1
目的のサーバ: 124.68.0.1
`
この環境でSSH転送をしてローカルから目的のサーバ(124.68.0.1)に
WinSCPでファイル転送します。
**※尚、踏み台サーバと目的のサーバは同一セグメントのプライベートIPが
振られている必要がある、、、と思います。**

---

###◆設定方法

####①TerraTermでSSH転送設定する
`TeraTerm > 設定 > SSH転送 > 追加`
![teraterm_ssh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442428/cad83642-3e4e-87d3-175a-e2342b335755.png)
・ローカルのポート: `xx22(末尾22の任意の番号)`
・リモート側ホスト: `目的のサーバのグローバルIP`
・ポート: `22`

上記の様に設定を投入。
完了したらOKします。

**※TeraTermを複数開いている場合は、どのウィンドウで設定を行っても構いません。
ただし、セッションを終了あるいはxボタンでウィンドウを閉じると設定も消えます。
従って、設定を投入したウィンドウは、誤ってexitしてしまわないように
設定ダイアログもそのまま開いておくことをオススメします。**

####②WinSCPで設定を行う
続いてWinSCPでセッションとトンネル設定を行います。

**セッション設定**
![scp_session.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442428/426e68eb-d82b-4c9f-5c21-93b726003316.png)
・転送プロトコル: `SFTP`
・ホスト名: `踏み台サーバのプライベートIP`
・ポート番号: `22`
・ユーザ名: `踏み台サーバの管理ユーザ`
・パスワード: `踏み台サーバのパスワード`

**トンネル設定**
`設定 > 接続 > トンネル(バージョンによっては”詳細設定から”)`
![scp_tunnel.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442428/33c40ee8-8e8a-49e7-8768-0e957e169a65.png)
・「SSHトンネルを経由して接続」を選択
・ホスト名: `localhost`
・ポート番号: `6022`
・ユーザ名: `ローカルの管理者`
・パスワード: `ローカルのパスワード`

---
以上です。
これにより、TeraTermで指定した6022番ポートを使って
WinSCPもファイル転送ができるようになります。

WinSCPでも”トンネル”という設定があるため
「WinSCPで接続できない～！」という躓き方をした僕にとっては
実はTeraTermでの設定が必要だったというのは意表を突かれました。
僕だけなんでしょうか？？

※未熟な者で、何か間違いがあったら教えて頂けると幸甚です。
Leetcode #283: Move Zeroes

```swift
func moveZeroes(_ nums: inout [Int]) {
    var index = 0
    for num in nums {
        if num != 0 {
            nums[index] = num
            index += 1
        }
    }
    
    for i in stride(from: index, to: nums.count, by: 1) {
        nums[i] = 0
    }
}
```
【参考例】ソースコードのコメントにcopyrightを記載

# Oracle所有のJavaの例

```
/*
 * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

```
cl-sqlでlibmysql.dllが読み込めないときの対処法

windowsでcl-sqlを使うときに
```
Error opening shared library libmysql.dll
```
のエラーが出てきた。

system.lispに以下を追加することで解決。

```cl
(pushnew #p"c:/tools/mysql/current/lib/" cffi:*foreign-library-directories* :test #'equal)
 (cffi:load-foreign-library "libmysql.dll")
```

foreign-library-directoriesにどのフォルダから読み込むか
あらかじめ設定することで無事にファイルが読み込めた。

参照: https://masatoi.hateblo.jp/entry/20160805/1470385802
「今週」のデータを配列に代入したいとき

自分用のメモとして投稿します。
今週１週間のデータを配列に代入する方法を紹介します。

```ruby:
hoge = [*(Date.today.beginning_of_week..Date.today.end_of_week)]

=> [Mon, 17 Jun 2019, Tue, 18 Jun 2019, Wed, 19 Jun 2019, Thu, 20 Jun 2019, Fri, 21 Jun 2019, Sat, 22 Jun 2019, Sun, 23 Jun 2019]
```

下記を参考にしました。（助かりました。）
連続する値を配列に代入したいとき
https://qiita.com/ntakuya/items/c82bb6a9b3336ee77a87
"Warning: PATH set to RVM ruby but GEM_HOME and/or GEM_PATH not set, see" Railsチュートリアルでのエラー

今日も「Ruby on Rails チュートリアル」を始めようとしたらターミナルに
`Warning: PATH set to RVM ruby but GEM_HOME and/or GEM_PATH not set, see`の文字が・・・

1時間ほど調べたらなんとか解決しましたのでメモとして残したいと思います。

**参考ページ**
[Warning: PATH set to RVM ruby but GEM_HOME and/or GEM_PATH not set, see の解決方法（AWS Cloud9）](https://qiita.com/shyle/items/ab800c652d6952b7ba0c)

## 手順
1. `vi ~/.bashrc`をターミナルに入力
2. 開かれた.bashrcファイルの最終行に以下を追加 
> export PATH=$PATH':/path/to/add'
> export GEM_HOME=$HOME/.gem
> export GEM_PATH=$HOME/.gem

3. CTRL + C でコマンドモードへ(Type : quit < Enter > to exit vimが表示される)
4. ZZを入力(上書き保存して終了のコマンド)
5. Cloud9を再起動

<img width="1277" alt="スクリーンショット 2019-06-20 22.44.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437092/10551a80-59bc-8605-4486-6a0dc1c3f0b5.png">

画像の「Manage EC2 Instance」からインスタンスの管理画面へ行き
[アクション]→[インスタンスの状態]→[再起動]を実行しましょう

以上の手順実行後、起動すればエラーも解消され通常通り作業ができるでしょう！
.bashrcの編集完了やCloud9の再起動方法が分からなかったのでまとめてみました。
（再起動とか必要なくて即時反映できる手順があったら申し訳ないです！逆に教えてください！）

初めてのアウトプットですが、自分と同じ躓きをした方の力になればと思います。
ウィンドウとタブを渡り歩くコマンドを作ってみた

あったら便利かなと思って作りました。
別に無くてもいいかもと思いました。

### ソースコード

```VimScript
com! -nargs=1 Wintabmove call <SID>wintabmove(<f-args>)
fu! s:wintabmove(direction)
  "引数でr(ight)かl(eft)を指定する
  if !count(['r','l'], a:direction)>=1
    return
  endif

  let l:cur_winnr = winnr()
  let l:win_num = winnr("$")
  if a:direction=='r'
    "下または右側にウィンドウがある場合 
    if l:cur_winnr<l:win_num
      exe (l:cur_winnr+1)."winc w"
      return
    endif
  else
    "上または左側にウィンドウがある場合 
    if l:cur_winnr>1
      exe (l:cur_winnr-1)."winc w"
      return
    endif
  endif

  let l:cur_tabnr = tabpagenr()
  let l:tab_num = tabpagenr("$")
  if a:direction=='r'
    "右側にタブがある場合
    if l:cur_tabnr<l:tab_num
      exe "+tabn"
      exe "1winc w"
      return
    endif
  else
    "左側にタブがある場合
    if l:cur_tabnr>1
      exe "-tabn"
      exe winnr("$")."winc w"
      return
    endif
  endif

  if a:direction=='r'
    "これ以上右側に移動できない場合、
    "先頭のタブの先頭のウィンドウに戻る
    exe "1tabn"
    exe "1winc w"
  else
    "これ以上左側に移動できない場合、
    "最後のタブの最後のウィンドウに戻る
    exe "$tabn"
    exe winnr("$")."winc w"
  endif
endf

```
Vue.jsで遊んでみた　【STEP 1】Vue.js の導入

前回の記事
[Vue.jsで遊んでみた　【STEP 0】Node.jsでサーバーの構築](https://qiita.com/koujin/items/c288208a25536b635dae)

## 今回の内容
Vye.jsの初めのステップとして導入からちょっとしたことまで行っていきたいと思います。
範囲としては公式の初めにの途中までひとまず触っていきたいと思います。

基本的な環境に関しては前回記事通りです。

### 参考
[Vue.js はじめに](https://jp.vuejs.org/v2/guide/)

## 導入してみた
### ファイル構成

今回こんな感じのファイル構成にしてます。
ファイル名がダサいとかいう話は受け付けません。

~~~
localserver
 |-index.js
 |-public
   |-index.html
   |-js
     |-vue.js
     |-vue2.js
~~~

### Vue.jsを使う方法
対象のhtmlに次を書き加える。ただそれだけ。今回は開発バージョンを使ってます。

~~~html:index.html
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
~~~

### 使い方
index.htmlを公式にあるように以下のように書き換えます。

~~~html:index.html
<html>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
        <body>
                <div id="test">{{ message }}</div>
        </body>
        <script>
        var app = new Vue({
            el: '#test',
            data: {
                message: 'Hello Vue!'
            }
        })
        </script>
</html>
~~~

script側の`new Vue()`で新しいVueの要素を作成しています。その引数の`el`でDOMの対象となる要素と紐づけています。
`{{message}}`は紐づいているVueの`data`の`message`の内容を参照反映してます。

はい、そんなの見たらわかるわって話ですね。

上では直書きでjs部分を書きましたが、public配下にjsファイルを作成してそこに書いても大丈夫です。

はじめにに書いていることを用いて以下のように各ファイル実装してみました。

~~~html:index.html
<html>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <body>
        <h1>Index!!</h1>
        <div id="app">
            {{ message }}
        </div>
        <div id="app-2">
            <span v-bind:title="message">
                Hover your mouse over me for a few secondsto see my dynamically bound title!
            </span>
        </div>
        <div id="app-3">
            <span v-if="seen">Now you see me</span>
            <button v-on:click="changeState">changeState</button>
        </div>
        <div id="app-4">
            <ol>
                <li v-for="todo in todos">
                    {{ todo.text }}
                </li>
            </ol>
        </div>
    </body>
    <script src="js/vue.js"></script>
    <script src="js/vue2.js"></script>
</html>
~~~

~~~js:vue.js
var app = new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue'
  }
})

var app2 = new Vue({
  el: '#app-2',
  data: {
    message: 'You loaded this page on ' + new Date().toLocaleString()
  }
})
~~~

~~~js:vue2.js
var app3 = new Vue({
  el: '#app-3',
  data: {
    seen: true
  },
  methods:{
    changeState : function(){
      this.seen = !this.seen
    }
  }
})

var app4 = new Vue({
  el: '#app-4',
  data: {
    todos: [
      { text: 'Learn JavaScript' },
      { text: 'Learn Vue' },
      { text: 'Build something awesome' }
    ]
  }
})
~~~

だいたい公式にあるままですが、`app-3`に関してはボタンで見え隠れするように変更しています。
ここで`this`に関する注意ですが、よく言われれてるように関数を`function(){}`で宣言した時と`()=>{}`で宣言した時とで`this`の中身が変化します。

上の例では
`function(){}`の場合、`app3`を参照します。
`()=>{}`の場合は`Window`を参照します。
個人的な意見ですが、`this`はややこしくなってしまうのでできる限り使わず、明示的に`app3`とかいてあげた方がいいです。

## まとめ
次はいったんコンポーネントは置いておいて、APIたたいていろいろ試したいと思います。
Leetcode #844: Backspace String Compare

```swift
func backspaceCompare(_ S: String, _ T: String) -> Bool {
    var stackS = [Character]()
    var stackT = [Character]()
    for char in S {
        if char == "#" {
            stackS.popLast()
        } else {
            stackS.append(char)
        }
    }
    for char in T {
        if char == "#" {
            stackT.popLast()
        } else {
            stackT.append(char)
        }
    }
    if stackS.count != stackT.count {
        return false
    }
    
    for (index, char) in stackS.enumerated() {
        if char != stackT[index] {
            return false
        } 
    }
    return true
}
```
React.js 学習メモ　第5回

最近Reactの勉強を始めたので、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#Reactを書く際に気をつけるべきこと
####1:action typeは単語ごとに _ で区切る慣習になっている。

```jsx

//誤り
export const TEXTCHANGE = 'TEXTCHANGE';
//正しい
export const TEXT_CHANGE = 'TEXTCHANGE';
```

####2:props,stateの値をjsxの中で利用したい時は、↓みたいに書くことが多いです。
こうしておくと<div>文字数：{textLength}</div>って書けて、jsx内がスッキリするので。
この記法がよく分からなかったら[destructuring assignment](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment)でググりましょう。

```jsx
class App extends Component {
  render() {
    const props = this.props;
    //この記述↓
    const { textLength, textChange } = this.props;

    return (
      <>
        <div>文字数： {textLength}</div>
        <textarea
          type="text"
          onChange={e => props.textChange(e.target.value, e.target.value.length)}
        />
      </>
    );
  }
}
```

####3:return文しかないアロー関数は　() => ( return される中身 ) みたいな感じで省略してかける

```jsx

const mapStateToProps = state => ({
  textValue: state.text.textValue,
  textLength: state.text.textLength,
});
```

####4:Reduxはactionが発行される前のstateと変更のあったstateを合成して新しいstateを作って返却する、という哲学があります。もしstateにもっと複数のkey valueがあった時に、textValue textLength以外の情報が損なわれる恐れがあります。

ES6以降のJSだと、...[Object]のように書くことで、Objectの中身を全て取り出すことができます。
...stateはactionが発行される以前のstateの中身全部です。
なので、{ ...state } は、actionが発行される以前のstateを持った、新しいObjectということになります。
{ ...state, key: value} のように、カンマを使って変更したいkey valueを渡すと、元のstateの該当するkeyのvalueを書き換えたり、新たにstate treeにkey valueを追加することができます。

変更したいkey value以外を変更してしまう事故を防ぐための安全策みたいなものですね！

ちなみにですが...（ピリオド３つ）は[スプレッド演算子](https://qiita.com/Nossa/items/e6f503cbb95c8e6967f8)と言います！

```jsx
//誤り
return {textValue: action.textValue, textLength: action.textLength}
//正しくは
return { ...state, textValue: action.textValue, textLength: action.textLength}
```

#振り返り
今回は、React,Reduxを使って簡単にプログラムを書いた時に指摘された事をまとめてみました。
指摘されてこれがスプレッド演算子だったのかという事などを知る機会ができてコードをレビューしてもらえるのは改めて気づきの多いことだと感じました。
WSL + VSCode Remoteで.bash_profileの内容を反映させる

# 概要
[以前の記事](https://qiita.com/Developer_KanZG/items/f329dd3dd197b2005390)でRuby on Railsの開発環境をWSL上に作ったのは良かったんですが、
Rubyの警告が出るので.bash_profileにexportコマンドを記述し抑制していたのですが
なんとTerminalを立ち上げ直すたびに.bash_profileの中身を無視して警告を出してくるではありませんか！！！

ここではそれの対応策を紹介します

# 対策法
どうも`source ~/.bash_profile`や追加で`bash`した際に反映されることからVSCode RemoteのTerminalは起動時には.bash_profileを読み込んでくれないみたいです。
起動後bashを実行してやれば反映されるんですが毎回するのは面倒なので起動時に読み込まれるっぽい.bashrcに書き込むことにしました

```bash
# bash_profileの内容を.bashrcへ転機
cat ~/.bash_profile >> ~/.bashrc

# bash_profileがなんかの拍子で読み込まれるのを防ぐために名前変更
mv ~/.bash_profile ~/.bash_profile_bak

```

これで正常に.bashrcに書き込んだ内容がTerminal実行時に読み込まれるようになりました

# あとがき

~~これよく思えば.bash_profileは結果的に読み込まれてないのでタイトル詐欺ですね~~
【swift】 iPhone 8 以前と iPhone X 以降で UIToolBar の高さを変える。

![ToolBar.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193431/a2a4eac8-0f87-a864-3bbc-935da25104fd.gif)
#ホームボタンの有無でUIToolBarの高さを変えたい。
iPhone 8 以前のホームボタンがあるモデルと、iPhone X 以降のホームボタンがないモデルで UIToolBar の高さを変える方法を示します。
iPhone X 以降では画面下端に細いバーが入るので、若干 UIToolBarを高くして、BarButtonItemが細いバーにかぶらないようにします。
(Auto Layout は使わない設定です。）
##コード
UIToolBar を "myToolBar" とします。

```swift
import UIKit

class ViewController: UIViewController {
    
    @IBOutlet var myToolBar:UIToolbar!

    override func viewDidLoad() {
        super.viewDidLoad()
        let width = UIScreen.main.bounds.size.width
        let height = UIScreen.main.bounds.size.height
        //iPhone X 以降で、以下のコードが実行されます
        if height > 800.0 && height < 1000.0{
            myToolBar.frame = CGRect(x: 0, y: height * 0.92, width: width, height: height * 0.055)
        }
    }
}
```
「y: height * 0.92」や「height: height * 0.055」の数字は好みで微調整して下さい。

参考サイト
[iPhone画面サイズ早見表（図付き）](https://qiita.com/TD3P/items/b3b754bde584abc98f44)
firestore local emulator を docker-composeで動かす


[firestore-emulator-dokcer](https://github.com/perrystallings/firestore-emulator-docker)を使ってやろうとしたけどうまく行かなかったので下記の対応で済ませた話。


## Dockerfileの準備

Javaが必要なので`apk add --no-cache openjdk8-jre`でopenjdk8-jreを追加。

`npm i -g firebase-tools && firebase setup:emulators:firestore`でfirestore local emulatorを追加。

```dockerfile
FROM node:10-alpine

WORKDIR /usr/src/app

RUN apk add --no-cache openjdk8-jre

RUN npm i -g firebase-tools && firebase setup:emulators:firestore
```

## docker-composeの準備

```yaml
version: '3'

services:
  app:
    build: .
    volumes:
      - .:/usr/src/app:cached
      - node_modules-data:/usr/src/app/node_modules

volumes:
  node_modules-data:
    driver: local
```

## package.jsonに適当にscriptsを追記

自分は、下記のような感じにしました。

```json
  "scripts": {
    "start-firestore": "firebase serve --only firestore",
    "test": "npm run start-firestore & jest",
  }
```

## Let's TDD

```
$ docker-compose run --rm app npm test -- --watch 
```

## CI（CircleCI）

CircleCIの設定は下記のような形で対応

一部抜粋

```yaml
      - run:
          name: npm install
          command: docker-compose run --rm app npm install

      - run:
          name: test
          command: docker-compose exec app npm test
```
【Rails】Web APIを利用する時に使用するgem、Faradayを初めて触る

## 最初に

自分用にメモ。

Web APIを利用するとき
1. サーバー側から***リクエストパラメータ***をAPIに送信し
2. JSON形式やらで***レスポンス***が返ってくる。

それを行うミドルウェア(？)という理解。

## Faradayとは
- HTTPクライアントのgem ≒ Rackミドルウェア
- ミドルウェアを追加することで色々な機能を追加できるようになる。

> Faraday is an HTTP client library that provides a common interface over many adapters (such as Net::HTTP) and embraces the concept of Rack middleware when processing the request/response cycle.

Web APIコールに使ったりする。

> Faradayを使うと何が嬉しいの？
- HTTPリクエスト部分が宣言的に美しく書ける
- リクエスト/レスポンスが柔軟に設定できる

とか

> OAuth/OAuth2両方に対応しているので、APIによってgemを使い分けるみたいな面倒くさいことしなくても良い

## Rackミドルウェア
### Rackとは

> RackはHTTPリクエストとレスポンスを可能なかぎり簡単な方法でラッピングすることで、Webサーバー、Webフレームワーク、その間に位置するソフトウェア(ミドルウェアと呼ばれています)のAPIを1つのメソッド呼び出しの形にまとめます。 
 
言い換えると

> 指定したファイルを独自のRuby DSLとして読み込み、DSLで指定した様々なミドルウェア、アプリケーションを組み合わせてWebサーバーを立ち上げることができる `rackup` というコマンドを提供するライブラリである。

なるほど。

### Rails on Rack
#### Rails Application's Rack Object
> `Rails.application` is the primary Rack application object of a Rails application. Any Rack compliant web server should be using `Rails.application` object to serve a Rails application.

#### rails serverコマンド
> `rails server` コマンドは、 `Rack::Server` オブジェクトを作成し、Webサーバーを起動します。

```rb
Rails::Server.new.tap do |server|
  require APP_PATH
  Dir.chdir(Rails.application.root)
  server.start
end
```

> Rails::ServerクラスはRack::Serverクラスを継承しており、以下のように `Rack::Server#start` を呼び出します。

```rb
class Server < Rack::Server
  def start
    ...
    super
  end
end
```

#### rackupコマンド

> Railsの `rails server` コマンドの代わりに `rackup` コマンドを使うときは、以下の内容をconfig.ruに記述して、Railsアプリケーションのルートディレクトリに保存します。

```Rails.root/config.ru
require_relative 'config/environment'
run Rails.application
```

> 続いて、サーバーを起動します。

```
$ rack config.ru
```




## Usage

### GETリクエストの送信

```rb
Faraday.get("http://example.com")
```

### コネクション生成とリクエストの送信

```rb
connection = Faraday.new("http://example.com") # Faraday::Connection.new("http://example.com")
connection.get
```

### ミドルウェアの宣言

ミドルウェア機能を使って、いろんな機能を追加できる。

```rb
connection = Faraday::Connection.new(:url => 'http://example.com') do |builder|
  builder.use Faraday::Request::UrlEncoded  # リクエストパラメータをURLエンコードする
  builder.use Faraday::Response::Logger  # リクエストを標準出力に出力する
  builder.use Faraday::Adapter::NetHttp  # Net/HTTPアダプターに使う(NetHttpはデフォルト)
end

response = connection.get '/api/nyan.json'  # GET http://example.com/api/nyan.json
puts response.body
```

ミドルウェアの追加はクラスを使ってでなくシンボルを使っても書ける。

```rb
connection = Faraday::Connection.new('http://example.com') do |builder|
  builder.request :url_encode
  builder.response :logger
  builder.adapter :net_http
end
```

## 参考リンク
- [lostisland/faraday](https://github.com/lostisland/faraday)
- [lostisland/faraday_middleware](https://github.com/lostisland/faraday_middleware)
- [Faradayの使い方 59のレシピ -猫Rails](http://nekorails.hatenablog.com/entry/2018/09/28/152745)
- [Ruby の HTTP クライアントライブラリ Faraday が便利そう
](https://gist.github.com/mitukiii/2775321)
- [RailsとRack -Railsガイド](https://railsguides.jp/rails_on_rack.html)
- [Rackとは何か -Qiita](https://qiita.com/k0kubun/items/248395f68164b52aec4a)
- [HTTPとPOSTとGET](https://qiita.com/Sekky0905/items/dff3d0da059d6f5bfabf)
CorvusSKKの設定や辞書をオンラインストレージで共有する

# 前書き
CorvusSKKの辞書をオンラインストレージ上で共有したい。そもそもCourvusSKKのユーザー辞書はどこで管理されているのだろう？と思ったので調べてみた。なんとCorvusSKKの作者様が方法を説明したブログがあったので苦もなくできた。作者様の記事の紹介と自身の作業履歴を今後のために残しておく。

## CorvusSKK
Windowsで使用可能なSKK IME。SKKを使う人は僅かだと思うがこれに慣れてしまうと手放せない。もっと普及したらいいのに。
Githubで公開されている。
[@nathancorvussolisl](https://nathancorvussolis.github.io)
# 作者様の記事
ここを読めば終わり。
[Kaya: オンラインストレージとCorvusSKK](https://nathancorvussolis.blogspot.com/2016/07/onlinestorage-corvusskk.html)
プロセスは以下:
1. 辞書管理プロセスを止める。
2. 設定と辞書を管理しているディレクトリ(フォルダ)をオンラインストレージに移す。
3. 元のディレクトリにシンボリックリンク(ジャンクションでも可)を貼る。
4. 管理プロセス再起動。

# 自分の作業メモ
作者様の記事はcmdでの作業で書かれているようだ。Powershellで行うなら少し読み替えが必要になる。管理者権限が必要な作業もあることにも注意する。Powershell……使いやすいようで使いにくい。

## フォルダ操作
コピー
``Copy-Item -Recurse [コピー元] [コピー先]``
削除
``Remove-Item -Recurse [対象フォルダ]``

``-Recurse``をつけてフォルダの中身も再帰的にコピー、削除している。

## シンボリックリンク
シンボリックリンクを貼る``mklink``というコマンドはcmdのコマンドらしく、Powershellでは使えない。
### cmdから呼び出す
``cmd /c "mklink"``
とすればコマンドプロンプトで``mklink``としたのと同じ。ただし、管理者権限でPowershellを開いていないといけない。
### New-Itemを使う
Powershellでシンボリックリンクを貼る場合、以下のようにする。もちろん管理者権限が必要。
``New-Item -Type SymbolicLink -Path [リンク元] -Value [リンク先]``
ということだそうなのだが、うまくできなかった。上の方法で作業した。
### 管理者として実行
Powershellで管理者権限で実行するには
``Start-Process [コマンド] -Verb runas [引数]``
とするらしいのですが、これもよくわからなかった。``sudo``みたいにはならないのか？
[管理権限で実行: Windows にまつわる e.t.c.](https://www.vwnet.jp/Windows/PowerShell/runas.htm)
では関数``sudo``をつくっていますが、そこまでPowershell使いたくないし、いいか。

# 参考
[@nathancorvussolisl](https://nathancorvussolis.github.io)
[Kaya: オンラインストレージとCorvusSKK](https://nathancorvussolis.blogspot.com/2016/07/onlinestorage-corvusskk.html)
[PowerShellでファイルやフォルダーを操作する](https://www.atmarkit.co.jp/ait/articles/0809/05/news144.html)
[PowerShell で シンボリックリンクを 使えるようにしよう](https://tech.guitarrapc.com/entry/2014/08/19/022232)
[PowerShell v5の新機能と、実戦で使ってほしい機能](https://www.buildinsider.net/enterprise/powershelldsc/03)
[管理権限で実行: Windows にまつわる e.t.c.](https://www.vwnet.jp/Windows/PowerShell/runas.htm)
servlet ファイル送信

#コード
- 以下のように書くと複数のファイルを送信できる

```java:Upload.java
package fileUpload;

import java.io.File;
import java.io.IOException;
import java.util.Collection;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

@WebServlet("/fileUpload/Upload")
@MultipartConfig(maxFileSize = 20971520, maxRequestSize = 20971520, location = "/tmp/")
public class Upload extends HttpServlet {

	private static final long serialVersionUID = 1L;

	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");
		response.setContentType("text/html; charset=UTF-8");
		Collection<Part> parts = request.getParts();

		for (Part part : parts) {
			String name = getFileName(part);

			part.write(name);
			response.getWriter().append("アップロード:").append(name);
		}
	}

	private String getFileName(Part part) {
		for (String cd : part.getHeader("Content-Disposition").split(";")) {
			String str = cd.trim();
			if (str.startsWith("filename")) {
				String str2 = str.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
				File f = new File(str2);
				return f.getName();
			}
		}
		return "no_name";
	}
}
```
```jsp:upload.jsp
<%@ page language="java" contentType="text/html; charset=UTF8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>アップロード</title>
</head>
<body>
	<FORM action="fileUpload/Upload" enctype="multipart/form-data" method="POST">
		アップロード<BR />
		<INPUT type="file" name="uploadfile" multiple> <INPUT type="submit" />
	</FORM>
</body>
</html>
```
組み込みデータセットairqualityを使って重回帰

Rではlm関数を使って線形回帰を行うことができる。
今回はairqualityデータセットを使って
試しに使ってみる。

> head(airquality)
  Ozone Solar.R Wind Temp Month Day
1    41     190  7.4   67     5   1
2    36     118  8.0   72     5   2
3    12     149 12.6   74     5   3
4    18     313 11.5   62     5   4
5    NA      NA 14.3   56     5   5
6    28      NA 14.9   66     5   6
> Data=na.omit(airquality)
> Data=subset(airquality,select=c(Ozone,Wind,Temp))
> lm(Ozone~Wind+Temp,data=Data)

Call:
lm(formula = Ozone ~ Wind + Temp, data = Data)

Coefficients:
(Intercept)         Wind         Temp  
    -71.033       -3.055        1.840
NuxtのaxiosでbaseURLの設定が反映されない原因について

## NuxtのaxiosでbaseURLの設定が反映されない原因について
以下の設定だとbaseURLは設定できません。

```javascript:nuxt.config.js
  axios: {
    baseUrl: 'http://localhost:3000/api/v1' // 間違い
  }
```

正しくは`baseUrl`ではなくて`baseURL`だからです。以下が正しい設定になります。

```javascript:nuxt.config.js
  axios: {
    baseURL: 'http://localhost:3000/api/v1' // 正しい
  }
```

参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
いつも開くサイトを自動化する【python3】


PCを起動して、ブラウザを起動して、お気に入りから新しいタブで開いて....
よく開くサイトはブラウザがトップページなどに表示してくれたりもしますが、
めんどくさくなってきたので自動化することにしました。

#やってみる

まず開きたいURLをEXCELに張り付けます。

![0110.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/cd65ae8a-4724-e6e3-eea4-dd32d56b9239.png)

pythonに必要なライブラリをインストールします。

```python
pip install xlrd
pip install pandas
```

コードの中身はこうです。

```python
import pandas as pd
import subprocess
from time import sleep

URL = r'C:\Users\Desktop\urllist.xlsx'
df = pd.read_excel(URL, header=None)

for i in range(len(df)):
    URLS = df[0][i]
    subprocess.Popen([r'C:\Program Files\Mozilla Firefox\firefox.exe',URLS])
    sleep(5)

```

URLを書き込んだエクセルの場所を「URL」に入れ、
pandasでエクセルに読み込ませます。

書き込まれているURLを順番にひとつづつsubprocessを使って開いていきます。
firefoxでもchromeでも開きます。

timeのsleepを5秒入れているのはブラウザが重くなって接続エラーが出ることが多かったので入れています。

#以上
これで文字化しているURLを開くことができました。

・後で読もうと、どんどん新しいタブで開くけど、
　ブラウザが落ちて絶望する。←firefoxだとFoxyTabという
　タブのURLをすべてコピーしてくれるアドオンがあります

・webスクレイピングでフィルターを作ってニュースを選別し、
　URLを抽出したけれどアドレス枠にコピペして開くの面倒。

・職場でいつも開く退勤管理サイトを自動化したい。

そんなときに使える自動化スクリプトだと思います。
エクセルや内部の実行ファイルが操作できるので、他にも自動化が捗りそうです。

あとはdos画面からpythonとファイル名を指定して起動したら動きます。
ROSと外部のノード(ROS, Matlab等)で通信する時にIPアドレスを知るTips

##Tipsです、それ以上でも以下でもない
ROS⇔ROSとか、ROS⇔Matlabで通信する時にやり方一回忘れて死ぬほど苦労したのでメモ。
「ホスト　アドレス」とかで調べるんだけど、どれが本当に通信に使えるアドレスか全く分からなくて詰んだのホント最悪だった...
固定IPでやる方法もあるんだけど、使う時に手軽に分かれば別に良いよって人におすすめかな。
#方法
ターミナルで"hostname -I"って打って出てきた奴が今現在使えるIPアドレス。(ホスト名？ほんとよく分かんない...)
この中の一つが外部と通信出来るアドレスになる。
経験則的に「10.＊.＊.＊」って感じで頭が10の奴が通信で使えるアドレスだと思っている。理由は知らん。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246335/5c122694-0894-c3aa-e7c2-044868eaf32b.png)
#感想
最近ヒマがなくてまともな記事が書けん...
でもロボットアームのROS化と、Obnizとスマホを使ってAR内で自由にオブジェクトを動かす、みたいなのは出来たので適宜上げていきたいよね。ではまた。
ARMのUbuntu Server 18.04でBluetoothを使う(for Raspberry Pi)

## モチベーション
ROSロボット愛好家には欠かせない、[ARM版 Ubuntu Server 18.04。](https://ubuntu.com/download/iot/raspberry-pi-2-3)
一工夫しないとBluetoothが使えなかったので他の人が困らないように記録しておく。
（今回の実験対象はARM64版です。確認していませんが、ARMHF(32bit)でも同じ問題が起きているはずです。）

## Raspberry Pi用のUbuntu 18.04
[ARM/RaspberryPi \- Ubuntu Wiki](https://wiki.ubuntu.com/ARM/RaspberryPi)
SDカードイメージは、上記Ubuntu公式サイトよりダウンロード可能です。
なお、Ubuntu MateであればBluetoothの問題は発生しません。
ただ、Mateは重たいので、
ロボットに乗せるだけならば、「Ubuntu Server」の方がいいよね！ということです。

また、GUIが欲しくなったら、「xubuntu」「lubuntu」「kubuntu」が使えます。
最高ですね。

## オプショナルパッケージのインストール
```bash
$ sudo add-apt-repository ppa:ubuntu-raspi2/ppa
$ sudo apt update
$ sudo apt install libraspberrypi-bin libraspberrypi-dev
```

## Ubuntu PiフレーバーメーカーPPAの追加
* 有志が、Raspberry Pi用のUbuntuイメージに対して、公式イメージであるRaspbianにある各種パッケージをUbuntu用に提供してくださっています。
* Raspberry PiのBluetoothを動かす上で必要な`pi-bluetooth`を追加するために必要です。

```bash
$ sudo add-apt-repository ppa:ubuntu-pi-flavour-makers/ppa
$ sudo apt update
$ sudo groupadd -f --system gpio
$ sudo groupadd -f --system i2c
$ sudo groupadd -f --system input
$ sudo groupadd -f --system spi
```

## 必要なパッケージのインストール
* pi-bluetoothに加えて、bluetoothパッケージと、CLIから`bluetoothctl`コマンドの実行を可能にするためにbluezパッケージをインストール。
* 私の場合はこの時点では、Bluetoothデバイスが認識してくれなかったので再起動が必要でした。

```bash
$ sudo apt install pi-bluetooth bluetooth bluez 
$ sudo reboot
```

## 動作確認
```bash
$ sudo bluetoothctl 
[NEW] Controller xx:xx:xx:xx:xx:xx test01 [default]
[bluetooth]# list
Controller xx:xx:xx:xx:xx:xx test01 [default]
```

## 最後に
ROSやるならRaspbianよりUbuntuですね。
（最近はDockerばかり使ってますですが。）
JavaScript よくあるTodoアプリのfilterメソッドを用いた削除について

# Todoアプリでのタスク削除について（JavaScript）

JavaScriptのfilterメソッドの仕組みがよくわかっていなかったのでメモ。


JavaScriptのみならず、プログラミング言語の学習の際はTodoアプリを作りながら学ぶチュートリアルなどが数多くあるかと思います。

その中で、下記のようなコードがあります。

```javascript:index.js

const todos = [
  { id: 1, content: '買い物に行く' },
  { id: 2, content: '歯医者の予約をする' }
];


todos.filter(todo => {
  console.log(todo.id !== 1)
  return todo.id !== 1
})
```


「1」とある部分は、実際にはクリックイベントなどによって取得されるidです。
※Reactで、
`<Button onClick={() => {deleteTodo(id)}}>タスク削除</Button>`
で取得したidを「１」と仮定します。


この結果は下記の通り、id:2のタスクのみがリターンされます。

```terminal
=> [ { id: 2, content: '歯医者の予約をする' } ]
```

理解するととてもあたりまえのことですが、当初なぜtodosタスクのidと、選択したidが`！＝＝`だとfilterメソッドで取り除かれてしまうのかわかりませんでした。

ニュアンス的？にタスク内のidと、選択したidが同じ`===`の関係であれば取り除かれるような気がしていました。



[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)によると

> filter() メソッドは、引数として与えられたテスト関数を各配列要素に対して実行し、それに合格したすべての配列要素からなる新しい配列を生成します。

> この関数が true を返した要素は残され、false を返した要素は取り除かれます。

つまり`false`を返された要素は配列から取り除かれてしまうんですね。

**`！==`でtrueをfalseに変更する。
それによって配列から要素を取り除く。**

```javascript:index.js
const todos = [
  { id: 1, content: '買い物に行く' },
  { id: 2, content: '歯医者の予約をする' }
];

todos.filter(todo => {
  console.log(todo.id !== 1) // falseなので取り除かれる
  return todo.id !== 1
})

// => [ { id: 2, content: '歯医者の予約をする' } ]はtrueなので残る
```


[コードはこちら](https://repl.it/@Abbiscuit/CircularTwinModules)

---

### まとめ

今まで何となくメソッド名を覚えて使っていましたが、そのメソッドがどのような返り値を持っているか等を意識して練習すると、応用できそうだと感じました。

なので、しっかりとリファレンスを読みましょうw
CloudFront以外からのWebアクセスを拒否したい

#概要
CloudFront -> ELB -> EC2(Apache httpd) の構成で、インターネットから直接のELBへのアクセスを拒否したい。全てのウェブアクセスはCloudFront経由に限定したい。

##案0 ELBの待ち受けポートをデフォルト以外のものにする
CloudFrontとELBの設定さえ合致していれば、ELBは必ずしも443や80ポートでリッスンする必要はない。デフォルトでないポートに変えるだけでボットなどの変なアクセスがほとんど来なくなる。ただしこれはアクセス制限でも何でもないため、他の案と併用するのが良い。

##案1 ELBのセキュリティグループでCloudFrontのグローバルIPアドレスを指定する
CloudFrontのグローバルIPは[JSONで公開](https://docs.aws.amazon.com/ja_jp/general/latest/gr/aws-ip-ranges.html)されている。これをもとにCloudFrontのグローバルIPを許可するセキュリティグループをELBにアタッチすればアクセス制限が可能。ただしこのグローバルIPはわりと頻繁に変更が発生する。グローバルIPの変更イベントはSNSで受信することができるため、このイベントをトリガーにLambdaをキックしてセキュリティグループを動的に変更すれば対応できなくもないが、面倒だし変更イベント発生時のタイムラグも気になる。

##案2 CloudFrontのカスタムヘッダをapacheがチェックする
これ系の話題はクラスメソッドさんのブログですでに網羅されていますよね。。
CloudFront側でカスタムヘッダを付加し、apache側でカスタムヘッダの項目と値が一致することを確認。一致しなかったらアクセスを拒否する。

##案3 ELBのWAFがCloudFrontのカスタムヘッダをチェックする
案2と仕組みは同じ。WAFのちょっとした追加コストが許容されるのなら案2よりこちらが良い。案2だとec2までリクエストが届いた上で拒否するが、この案だとec2までリクエストは届かない。（細かい話をすると案3はelbまではリクエストが到達する。案1だとelbにも到達しない）
3行でわかるREST

初投稿してみます。

### 対象とする読者
ざっくり手短に「RESTとは」を理解したい方。

### RESTとは
RESTとは「**クライアントがWeb上に存在するリソースを操作する方法**」についての考え方である。では、どのように操作するのか。

1. RESTでは、クライアントが行う処理にURIが対応づくのではなく、**Web上のリソースにURIが対応づいている**。
2. クライアントは、操作したいリソースのURIにアクセスすることによって、リソースを操作する。
3. その際、**リソースに対して行う行動**を**HTTPメソッド（GET/POST/PUT/DELETE）によって規定**する。

### まとめ
RESTとはWebの設計思想のことで、**URI（モノ）とHTTPメソッド（行動）を上手く組み合わせて、Web上のリソースを扱おう**という考え方のこと。

### 参考リンク
- https://www.subthread.co.jp/blog/20160506/
- https://thinkit.co.jp/free/article/0609/8/4
- https://qiita.com/masato44gm/items/dffb8281536ad321fb08
Flatten―２題


# 前置き
構造がある要素に対して、構造を無視して列挙する処理が「ふらっとん」です。
今回は、`WinForm`内の`Control`の列挙と、ファイルの列挙を行ってみましょう。
実現方法は例によって`Extension`です。`Control`と`DirectoryInfo`のインスタンスに対して`Flatten`のメソッドが利用できるようになります。

# いきなり
コードです。

## Controlの列挙
```csharp
public static IEnumerable<T> FlattenControls<T>(this Control Me) where T : Control {
    if (Me is T) yield return (T)Me;
    foreach (Control ctrl in Me.Controls.Cast<Control>().SelectMany(ctrl => ctrl.FlattenControls<T>()))
        yield return (T)ctrl;
}
```
えーっと、`Control`の方は無闇に列挙ってのは余りありそうもないので、`Generic`にしてみました。

```csharp
    foreach(CheckBox cb in form.FlattenControls<CheckBox>().Where(c => c.Checked)) {
        Console.WriteLine(cb.Text);
    }
```
みたいな感じで、WinForm内にある全てのチェックボックスをその配置位置に係らず、チェックされているものを列挙できる感じ。

## ファイルの列挙
```csharp
public static IEnumerable<FileSystemInfo> FlattenFileSystemInfos(this DirectoryInfo Me) {
    yield return Me;
    foreach (FileInfo in Me.EnumerateFiles())
        yield return info;
    foreach (FileSystemInfo info in Me.EnumerateDirectories().SelectMany(dir => dir.FlattenFileSystemInfos()))
        yield return info;
}
```
ファイルの列挙と云いながら、フォルダも列挙されます。
一応、`EnumerateFileSystemInfos`に倣った感じなんですけど、唯一違うのは元のメソッドは自分自身を挙げないんですが、今回提供した`Extension`は自分も入ってきちゃうんですよね。
自分が要らない時は、適当に読み飛ばしちゃいましょう。

```csharp
	foreach(FileSystemInfo fs in new DirectoryInfo(@"c:\Users\00000000\Desktop").FlattenFileSystemInfos().skip(1)) {
        Console.Writeline($"{fs.GetTyep().Name}\t{fs.FullName}");
    }
```
で、デスクトップ上にある全てのフォルダとファイルがリストアップされます。

# 後書き
部分しか載せてません。
実際に使うときは、きちんと`Extension`の体裁を整えて下さいね。
iframeでロードごとにiframeで今表示しているurlを取得する（iframeはオリジンサイト）[js]

#はじめに
ライブラリ未使用です。
100記事ぐらい出てきそうな内容を100回ぐらい検索しました。(言い過ぎかもしれません…)
iframeはオリジンサイトと書いているのはクロスサイトだとセキュリティー的に引っかかるからです。

セキュリティーに関して知りたい場合、
[体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 ](https://www.sbcr.jp/product/4797393163/)
がおすすめです。
こんなに丁寧で情報が詰まっているのに3200円って買うしかないと思っています。

あとサイトでは、
[IPAのここら辺](https://www.ipa.go.jp/security/vuln/vuln_contents/sql.html)がおすすめです。

#code

```sample.html
<iframe id="example1" src="https://qiita.com" width="100%" height="100%"></iframe>

```


```sample.js
var element = document.getElementById("example1");

element.addEventListener("load", function(event) {
  let url = document.getElementById("example1").contentWindow.location.href
  console.log("現在のiframeのURLは", url);
});

```

#codeの解説
ifarmeに『example1』というidを指定します。
idを使ってiframeを取得します。
そのiframeにloadイベントを取得するように実装します。(これでiframeロードごとに呼んでいただける)
ロードされた時に新しいurlをGetします。
以上です。

#最後に
どうしてすぐにでなかったんだろう。
いや、本当は調べている時に頭が回ってなさすぎたのかもしれません…。
真相は闇の中…

#参考
https://developer.mozilla.org/ja/docs/Web/Events/load
https://stackoverflow.com/questions/12069102/i-want-to-get-url-from-iframe
React x TypeScript x Sass 環境を手に入れる最速の方法

## これだけ

```bash
# Windows環境
npx create-react-app my-app --typescript
cd my-app
echo SASS_PATH=./node_modules;./src > .env
npm i node-sass -D
```
あとは `.css` -> `.scss` に変換して終わり！

## 参考
- https://facebook.github.io/create-react-app/docs/adding-typescript
- https://facebook.github.io/create-react-app/docs/adding-a-sass-stylesheet
[Vue]WEBアプリのショートカット設定に、Vueに最適化されたプラグイン「Vue-ShortKey」が使いやすい件

# 今回のコード
今回はめちゃめちゃ簡単に使える、プラグイン「Vue-ShortKey」の紹介と、導入でハマったポイントの共有です。
## 今回してほしい挙動
WEBアプリを開いて、「a」キーを押すだけで、指定したインプットタグにフォーカスする。
## 準備
```vuejs:inputタグに仕込むこと
<input
    v-shortkey.focus="['a']"
>
```
以上。

…はい、これだけです。
簡単すぎて、やばいです。関数も、何もいりません。素晴らしい。
## 豊富なキーの種類に、メソッド実行機能なども
キーを指定する部分は、`['a']`←この部分でしているのですが、ctrlやalt、Functionキーからtab、space、矢印キーなど、大方なんでもいけます。
もちろん、複数キー同時押しの設定もできます。
さらに、このプラグインはコンポーネントごとではなく、グローバルに設定できるので、さらに便利。

また、フォーカスだけでなく、指定したメソッドの起動なども、`@v-shortkey="関数名"`って感じで指定してやれば、簡単に実現できます。
詳しくは、[公式サイト](https://www.npmjs.com/package/vue-shortkey)に分かりやすく書かれていますので、見てみてください。
# 導入時にハマったこと
こんな使いやすいプラグインですが、実は僕、導入までにめっちゃハマってしまいました。
戒めもかねて、共有させてもらいます。これから入れられる方は、ご注意ください。
## 1.Nuxt.jsで導入する場合、SSRをサポートしていないので注意
ここが、ズバリ導入の際、多くの人がハマるポイントかと思います。
このプラグイン、実はSSRモードに対応していません。
なので、導入の際はブラウザでしか動作しないよう、設定しておく必要があります。

公式ページにも、導入方法についてはあっさりとしか書いておらず、きっと多くの人が他のサイトを見ながら導入することになるかと思います。
その際、他のプラグインがSSRに対応していることが多いためか、ブラウザ動作オンリーの設定について書かれていないことが多かった印象があります。

[Nuxt.jsの公式ページ](https://nuxtjs.org/guide/plugins/#client-side-only)に書かれていますので、参考にしてみてください。
具体的には、

 - クライアント側動作オンリーですよというオプションをつける
 - 「.client.js」という名前にしたファイルにまとめておく

のどちらかのパターンになるかと思います。
ここさえ通過すれば、あとは全然難しくはないので、導入方法は割愛します。
## 2.良く似た名前のプラグインが多い
あとは全然難しくないと言いつつ、もう１つハマったポイントがありました。
そう、プラグイン間違え…!!

これは侮るなかれ、うまくいかずに再インストールする際に、誤って違うプラグインを入れてしまっていた…
または、情報を探していて途中から違うプラグインのものに変わっていた…なんてことも、結構あるものです。

僕は、こんな簡単なことにハマってしまい、1時間ほど使ってしまいました。
vue-shortkeyやvue-shortcutkey、vue-shortcuts等々、いくつかありました。
皆さんもご注意を。

以上です。最後までありがとうございました。
参考：[公式サイト](https://www.npmjs.com/package/vue-shortkey)
マビノギ：スクリーンショット等保存先をCドライブ以外にしてみた

#はじめに
オンラインゲーム「マビノギ」では、「ドキュメント」フォルダに「マビノギ」という名のフォルダが作成され、当フォルダにスクリーンショット（以下　スクショ）やキャッシュ等ファイルが保存される。

![画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173491/d5f59289-0090-6391-18f0-a7f3e2835872.png)

自分のコンピュータはCドライブ容量が少なく、しばしばスクショがドライブを圧迫してしまう。とはいえ、いちいち他ドライブにスクショを移すのが面倒くさい。
バッチとタスクスケジューラで定期的に移すことも考えたが、そもそもスクショ撮影時点で他ドライブに保存できれば？
と思いつき、やってみたらうまくいったのでメモ。

#使ったコマンド
Windowsには、[シンボリックリンク](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%83%AA%E3%83%B3%E3%82%AF)を作成する**mklink**コマンドが用意されている。
これを活用することで、Cドライブに「マビノギ」フォルダの存在を維持しつつ、中身は他ドライブへの保存を実現できた。

#実行手順
1. 現行の「マビノギ」フォルダを、中身ごと他ドライブに移動する。元フォルダは削除する。
2. コマンドプロンプトを「管理者として実行」で起動する。
3. コマンドプロンプトで、下記コマンドを実行する。

```shell
#各自のPC環境に合わせ、内容を適宜書き換えてください。
mklink /D "C:\Users\ユーザ名\Documents\マビノギ" "E:\マビノギ"
```

#実行結果
実行後のドキュメントフォルダ。「マビノギ」フォルダがシンボリックリンク化された。
![画像２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173491/3fb400a9-cdfe-3fff-a180-f84117cd4ba8.png)

シンボリックリンクのプロパティ画面
![画像3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173491/eb9d8826-133e-980e-363e-165849e006bb.png)

「ファイルの場所を開く」と、Eドライブの「マビノギ」フォルダに移動できた。
![画像４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173491/27e28632-64c0-3bb3-f18f-82072130e76d.png)


ゲーム上でスクショを撮影してみたが、Eドライブの「マビノギ」フォルダへ保存されるようになった。

#おわりに
マビノギに限らず、インストール時に一時ファイル等の保存先をCドライブに自動設定されるアプリケーションは少なくない。Cドライブの容量節約のため、他アプリケーションでも応用できる…

と思っていたら、他でも実践している事例を発見したのでご紹介します。

■**R-Y-OのIT備忘録 Ver2.0** [Windows] 楽天 Kobo デスクトップアプリの書籍データ保存場所を変更する 
[https://raspi.ryo.sc/kobo_desktop_save_data/](https://raspi.ryo.sc/kobo_desktop_save_data/)

やっぱり皆、似たようなこと思いつくのね。。。

おしまい(*'ω' *)
TyepScriptでBeforeInstallPromptEventの型

自分で型を書く必要がある。

```javascript
interface BeforeInstallPromptEvent extends Event {
  readonly platforms: Array<string>;

  readonly userChoice: Promise<{
      outcome: 'accepted' | 'dismissed',
      platform: string
  }>;

  prompt(): Promise<void>
}

window.addEventListener('beforeinstallprompt', (event:BeforeInstallPromptEvent) => {
    console.log(event.platforms);
}, false);
```

## 参考リンク

- [angular - Typescript type BeforeInstallPromptEvent - Stack Overflow](https://stackoverflow.com/questions/51503754/typescript-type-beforeinstallpromptevent)
ssh の許可されない接続先でファイルリストを見る

株式会社オズビジョンのユッコ (@terra_yucco) です。
今日も個人的な「ぷちっとしたメモ」になります。

# ssh の許可されない接続先

「ハピタス」の連携相手でも、普段 scp で連携しているので ssh を許可していない相手がいます。

>scp sftp

この 2 つしか許可されていないようです。

```
$ ssh -i /path/to/.ssh/user.pem -p 2222 user@hoge.example.com "ls -l /tmp"
Last login: Thu Jun 20 17:56:53 2019 from ec2-xx-xx-xxx-xxx.ap-northeast-1.compute.amazonaws.com

This account is restricted by rssh.
Allowed commands: scp sftp

If you believe this is in error, please contact your system administrator.

Connection to hoge.example.com closed.
```

## ファイルリストが見たい

実は先日、サーバリプレイスによるトラブルが発生し、その復旧のため、先方に転送済みのファイルを見たい、という状況になりました。
普段だったら ssh で `ls -l /path/to/files` などするのですが、ssh が許可されていない場合どうするのか。

## scp はどうか？

ssh と同じプロトコルだし、WinSCP を使うとファイルリストが取得できるので、scp コマンドでもコピーではなくてコマンド発行をする方法があるのか？と思ってずっと調べていました。
ただ、どうもうまい方法は見つからず。
よくよく見たら、WinSCP も scp コマンドで表示しているわけではなかったようです。

## 正解は sftp

WinSCP もプロトコルは sftp でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95030/daf58806-ec77-f833-a1b3-3c13a7cf3cdf.png)

ということで、sftp コマンドでファイルリストを取ってみます。
ssh オプションの指定方法が独特すぎる…。

```terminal
$ sftp -oIdentityFile=/path/to/.ssh/user.pem -oPort=2222 user@hoge.example.com
Connecting to hoge.example.com...
sftp> ls -l /tmp
-rw-r--r--    1 480      500         12977 Aug  8  2016 user-20160808.txt.gz
-rw-r--r--    1 480      500            59 Aug  8  2016 user-20160808.txt.ok.gz
sftp> exit
$
```

(∩´∀｀)∩
シェルスクリプト超入門~hello world!まで~

新規でshファイルを作成し以下の内容を記述する

```shell:hello.sh
#!/bin/bash

echo "Hello World !"
```

hello.shを置いているディレクトリに移動して以下のコマンドを実行するか、ファイルの絶対パスを指定して実行する

```
$ bash hello.sh
-> Hello World !
```
postfixのsmtpd_client_restrictionsを使って迷惑メールを拒否する

`postfix`でスパムメールの拒否設定を触る機会があったので覚え書きです。

## `smtpd_client_restrictions`による迷惑メールの拒否設定方法

以下の通り、`smtpd_client_restrictions`に`reject_rbl_client`と`PBL`を記載することで迷惑メールを拒否できます。

```main.cf
smtpd_client_restrictions =
    permit_mynetworks,
    reject_rbl_client bl.spamcop.net,
    reject_rbl_client zen.spamhaus.org,
    permit
```

## 設定に関する注意点

設定について調べたところ、`PBL`として`all.rbl.jp`を記載することを促す記事が多数存在しましたが、**`2017年9月末`をもって`PBL.JP`はサービスを終了している**ため注意が必要です。
`2019/06/20時点`でサービス提供状態を確認したところ、[spamcop](https://www.spamcop.net/)と[spamhaus](https://www.spamhaus.org/pbl/)が生きていたので設定として例示しています。

# 参考リンク

* [RBL.JP、運用終了](https://www.excite.co.jp/news/article/Slashdot_17_09_13_0649245/)
Kindle for PCで洋書がダウンロードできない問題に当たった時のTodo

#はじめに
- 今までKindleはAndroid/Ipadで読んでいたが、Win環境を導入したのでKindle for pcで読むことに。
- なぜか**洋書だけダウンロードできない**事態に見舞われたので、同じように悩んだ方向けに記事にしておきます。

#調査してみると...
- amazonレビューにこんなコメントが。
![2019-06-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303906/3fd28103-8788-7964-656d-323a37ba16ec.png)
...**多分違くね？**(ポンコツWebエンジニア並みの感想)
- ただOneDriveという点には引っ掛かりを覚えた。もしや、、、

#解決：やはりパスが問題でした
- My Kindle Contentsを/OneDrive/DocumentsからC直下に移動させたら普通に通った。
- やはりパスを解決できなかった模様
- 洋書だけで起きていたので何か理由がありそう？詳しい人いたら教えてください。

#まとめ
- これで一応使い物にはなりそう。
- そもそもKindle for PCは現状これにとどまらず色々と問題があるそう（レビューのひどさ参照）なので使うなという話は置いておく。
- そもそもKindleみたいな独自拡張子で配信するサービス使うからこういう羽目になるんだという話も置いておく。
- epubはいいぞ。
「報連相」の重要性を再認識しよう

#■はじめに
「報連相ぐらい出来ている」と感じるかと思っていても実は何かが抜けていたり
どうして大事かを理解出来ていないで行っている方が多いかと思うので
再度、復習の為にも学習し直し整理した。

#■内容
##・報連相の基本　体系立て
　　報連相とは、仕事で関わる人々との**コミュニケーション**のこと
　　1986年で生まれた言葉で、ある証券会社の社長が書いた本が基となる
　　[山崎富治　著：『ほうれんそうが会社を強くする』](https://www.amazon.co.jp/%E3%81%BB%E3%81%86%E3%82%8C%E3%82%93%E3%81%9D%E3%81%86%E3%81%8C%E4%BC%9A%E7%A4%BE%E3%82%92%E5%BC%B7%E3%81%8F%E3%81%99%E3%82%8B%E2%80%95%E5%A0%B1%E5%91%8A%E3%83%BB%E9%80%A3%E7%B5%A1%E3%83%BB%E7%9B%B8%E8%AB%87%E3%81%AE%E7%B5%8C%E5%96%B6%E5%AD%A6-%E5%B1%B1%E5%B4%8E-%E5%AF%8C%E6%B2%BB/dp/4341170112)
　　「下からの意見をどう吸い上げるか、みんなが働きやすい環境をどう作るか、暖かい人間関係をどう作るか、少数精鋭で社員一人一人に厚く報いるには…とつね日ごろから頭を悩ませていたとき思いついたのが”ほうれんそう”だった。」

###報告
　　主に上司や先輩へ（依頼事項や作業進捗など）
　　目的→判断をしてもらう情報材料の提供
###連絡
　　自分発信で上司、先輩・同僚、その他へ（納品の日付や量など→それを元にスケジューリング）
　　目的→事実の周知、ステークホルダー（利害関係者）の判断材料を提供する
　　　　　※ 自分の意見は含めないこと
###相談：
　　他の方の意見、考えを双方向で伺う
　　目的→助言などを貰うことで自分の判断材料を獲得する
　　　　　※ 事実＋自分の意見を伝えること

##・なぜ重要か
　　事実が伝わらず正しい判断が取れない組織となってしまう
　　　例）部下が報連相を行わない、連絡が途切れている人がいる→上司が正しい判断ができない→社長が会社の方針が定まらない、間違える　など

###報連相の不具合によるトラブル
####報告しないと…
1. 上司の判断の制度が低下する
2. 被害が拡大し上司が責任を問われる
3. 無駄な時間やコストが発生する

####連絡しないと…
1. 関係者の仕事の進行を狂わせる
2. 関係者に無駄な仕事をさせる
3. 関係者の時間を奪う

####相談しないと…
1. 仕事の質が上がらない
2. 仕事の手戻りや遅延が発生する
3. 最悪の場合は上司が責任を問われる

###なぜ報連相をしないのか
　　重要性を理解していない→大した事ないと思っている、一人でできると思っている
　　重要性を理解している→叱られたくない、評価を下げたくない、責任を取りたくない

##・ポイント
###共通のポイント
　　目的
　　　・事実の伝達
　　　・事実だけでなく意見も伝達
　　　・事実と意見に対する助言の獲得
　　　　共通しての目的は情報の共有化、なんのために情報を伝えるのかが大事
　　対象
　　　・相手（上司、同僚、取引先など）
　　　・場面（会議、対面、電話、メール）
　　　・タイミング（時間の余裕の有無など）
　　内容
　　　・事実と意見を分けること

###報告のポイント
　　　・中間報告…長期間に渡る仕事や、難易度の高い仕事を任された時は特に重要
　　　・トラブル報告…可及的速やかに報告する、隠したり一人で対処しない
　　　・完了報告…仕事を終えたことが完了ではなく報告し承認されて仕事の完了となる
###連絡のポイント
　　　・通常連絡…相手のことを考えで適切な手段で行う
　　　・緊急連絡…最も早く確実に伝えること
　　　・重要連絡…必ず伝わり、かつ記録に残ること
　　　　　　　　　相手に伝わった時点で連絡が完了する
　　　　　　　　　抜け漏れなく伝える
　　　　　　　　　客観的事実を伝える
###相談のポイント
　　　　・現状を伝える
　　　　・達成したい目標
　　　　・相談前に実施したこと
　　　　・目標に達成していない理由
　　　　　　手ぶらで相談に行かずに自分なりに考えていること、やっている内容を
　　　　　　相手にわかりやすい形でまとめておく
　　　　　　自分の都合を優先しないこと
　　　　　　相手の知恵をいただくことに感謝をし礼節を守ること

#■伝えるテクニック
##・ロジカルシンキング（論理的思考）の基本
###ロジカルシンキングとは
　　複雑なことをシンプルにまとめること
　　他人にわかりやすく伝えること

###ロジカルシンキングが行えていない報連相での典型的な症例
　　報告…何が言いたいのか分からないと叱られる
　　　　→伝えたいことをまとめ、話の構造化する
　　連絡…意図していない意味で伝わってしまう
　　　　→言葉の定義を明確にする
　　相談…何を相談すれば良いか整理できない
　　　　→検討すべき観点を「抜け」「漏れ」なく整理する

###ロジカルな報連相を身に着けるには、
1. 結論→理由の順に話す
2. 理由を複数用意する
3. 理由の制度を上げる

##・ピラミッド構造
###ピラミッド構造とは
　　理由を複数用意すること
　　メリットとして、
　　　結論がまとまる
　　　↓
　　　納得感が高まる

###伝わる報連相の口癖
　　論点（何の件なのか）
　　↓
　　結論
　　↓
　　複数の理由
　　↓
　　行動（何をして欲しいのか）

###言葉の定義
　　言葉の定義が違うことでのミスコミュニケーションが起きることを防ぐ
　　例）コミュニケーションの話題：利益率について
　　　　Aさんは利益率を「営業利益」と考えている
　　　　Bさんは利益率を「売上総利益」と考えている

　　　　利益は5種類…売上原価、営業費用、営業外損益、特別損益、法人税等
　　　　**しっかりとした言葉の定義をしないと会話が成立しない**

##・ＭＥＣＥ（ミーシー）
　　Mutually Exclusive and Collecti vely Exhaustiveの略
　　  Mutually（ 相互に）
　　  Exclusive（重複せず）
　　  and Collectively（全体として）
　　  Exhaustive（漏れがない）
　　　簡単に言うと…**モレなくダブりなく考えること**
　　　理由（根拠）にモレ・ダブりがあると結論の信頼性が低くなる

###ＭＥＣＥの切り口
1. Ａ／Not Ａ　　　　例）国内／国外、新規／既存
2. 要素　　　　　　　例）年齢別、地域別
3. プロセス　　　　　例）訪問→商談→見積→契約
4. 数式　　　　　　　例）売上＝客数×客単価
5. フレームワーク　　例）５Ｗ２Ｈ、ＱＣＤ

　複数の理由をＭＥＣＥ（種類別で）を使用すると**理由の制度が上がる**
　例）品質と利便性と価格

#■さいごに
「報連相」とは受ける側と渡す側のより**良い関係**や**風通しの良い環境**を作ることなのだということや
まず何の話なのか冒頭にして会話は始めるとよりよい「報連相」を行えると覚えておこう。
「伝えるテクニック」で書いた内容は、「報連相」以外でも活用できそうなので意識しようと思う。
いまどき設計書などのドキュメントをバージョン管理しないとか…

#■はじめに
現在、参画しているプロジェクトが設計書の管理をファイルサーバのみで行っており、
とても…**とても**不便に感じたので、この記事を残します。

##概要
###参画プロジェクト
・某Webサイト三期追加開発案件
一期開発中盤から参画をさせていただき、そのまま二期、三期と継続して着任している。

#■そもそもバージョン管理はなぜ必要か
以下のようなディレクトリを見たことがありますか？
![20190620.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223196/92bddb76-2f93-bf0e-5118-d97c3e75e762.png)

追加で開発案件が増えたり、段階リリースするようなプロジェクトだと
このようなディレクトリ構成になっているファイルサーバをよく見るかと思います。

「bk」フォルダとか「old」フォルダとかに過去資料入っているとか
改変履歴毎に見る度カラフルになっていく資料なども見たことある人もいるかと思います。
（そもそも本フォルダのファイル名に日付がある設計書なども見たことあります…）

##ファイルサーバ管理でのデメリット
・最新のドキュメントがどれだかわからなくなる
　　ユーザからの問合せで現在リリースしている仕様の確認や
　　次期開発の為に更新するドキュメントがどれなのか一目でわからない場合が発生しうる。
　　その為、無駄な時間のロスや誤って古い方のドキュメントを修正してしまう恐れもある。

・時系列でドキュメントを管理するのが難解
　　ローカルに落として更新している作業者や
　　障害対応でいつの間にか前期分のディレクトリにある資料が
　　更新されているなどで手戻りが起こってしまう。
　　また改変履歴に詳細に変更内容を記載していても、手作業による履歴管理では、
　　やはりミスや漏れにより十分には管理できない場合が少なくない。
　　誰からの指摘でどのような流れで変更が加わっていったかを
　　順を追っての確認がレビュー指摘一覧や議事録など
　　別の資料を見ながらでないと正確な所がわからない。

・無造作にコピーされサーバ容量を圧迫する
　　上の画像のようなディレクトリ構成だと今度は「2020年度」フォルダに
　　「2019年度」フォルダの資料をコピーして追加要望が発生した機能の設計書を直して…
　　っとファイルサーバを圧迫する。
　　しかし過去時点のドキュメントは残しておきたい為、
　　不要そうなフォルダを圧縮してサーバ容量をなんとか確保した経験もあります。

・見やすいですか？
![syousai01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223196/80a4c008-a3e9-e249-f81b-55484d29157a.png)
![syousai02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223196/9dcd3b6e-6d8b-247a-b74e-b1a9798fd21d.png)

#■バージョン管理ツール
追記予定