OmniAICreator/Qiita-1.07M huggingface dataset:
Macにpipenv環境作ってみた

# 前提

- Homebrewがインストールされていること
- Xcode Command Line Toolsがインストールされていること

# pipenvの準備

pipenvをインストール

```bash
$ brew install pipenv

# インストール確認
$ pipenv --version
pipenv, version 2018.7.1
```
# pipenvを使ってみる

```bash
# 任意のフォルダを作成
$ mkdir pipenv-example
$ cd pipenv-example

# 開発フォルダ内で仮想環境フォルダを作成する設定
$ export PIPENV_VENV_IN_PROJECT=1

# pythonのバージョン指定
$ pipenv --python 3.7
Creating a virtualenv for this project...

# 成功するとPipfileが作成される
$ cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[packages]

[dev-packages

[requires]
python_version = "3.6"

$ pipenv shell
Launching subshell in virtual environment…
bash-3.2$   . /XXXX/pipenv-example/.venv/bin/activate

# バージョン確認
(pipenv-example-edEeQ5ra) bash-3.2$  python --version
Python 3.7 # pipenvで指定したバージョン
```

# パッケージインストール

原因は不明ですが、pip 18.1を使用すると以下のエラーが発生しました。

```bash
Pipfile.lock (662286) out of date, updating to (7fbb99)...
Locking [dev-packages] dependencies...
lib/python3.7/site-packages/pipenv/utils.py", line 402, in resolve_deps
    req_dir=req_dir
  File "/usr/local/Cellar/pipenv/2018.7.1/libexec/lib/python3.7/site-packages/pipenv/utils.py", line 250, in actually_resolve_deps
    req = Requirement.from_line(dep)
  File "/usr/local/Cellar/pipenv/2018.7.1/libexec/lib/python3.7/site-packages/pipenv/vendor/requirementslib/models/requirements.py", line 704, in from_line
    line, extras = _strip_extras(line)
TypeError: 'module' object is not callable
```

Github Issueを漁っているうちにバージョンを変更することで回避できることが分かったので、
回避方法を記載します。

## pipenv内のpipバージョン変更

```bash
# 18.0のpipをインストールするだけ
pipenv install pip==18.0

# 確認
$ pipenv shell

# バージョンチェック
(pipenv-example-edEeQ5ra) bash-3.2$ pip --version
pip 18.0 from /XXXX/pipenv-example/.venv/lib/python3.7/site-packages/pip (python 3.7)
```

## パッケージインストール

```bash
$ pipenv install Flask
```

## 追記(2019/01/14)

pipenvをアップデートしたところ、pipを18にしなくてもエラーにならなくなりました。

```bash
$ brew update
$ brew upgrade pipenv
$ pipenv --version
pipenv, version 2018.11.26

$ pipenv install Flask
```

以上です。
Selenium で クリックしたページを保存 (python3)

SPA のページで、クリックして出てきた情報を取り込む時の方法です。

```py:click_save.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#	click_save.py
#
#					Aug/25/2018
#
# ------------------------------------------------------------------
import sys
from selenium.webdriver import Firefox
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support.wait import WebDriverWait

# ------------------------------------------------------------------
def file_write_proc(file_name,str_out):
	fp_out = open(file_name,mode='w',encoding='utf-8')
	fp_out.write(str_out)
	fp_out.close()
#
# ------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")
url_target = sys.argv[1]
idx = sys.argv[2]
file_html = sys.argv[3]
#
#
options = Options()
options.add_argument('-headless')
driver = Firefox(executable_path='/usr/bin/geckodriver', firefox_options=options)
ttx = 100
wait = WebDriverWait(driver, timeout=ttx)
driver.get(url_target)
button = driver.find_element_by_id(idx)
button.click()
driver.save_screenshot("out.png")
html = driver.page_source
#
driver.quit()
file_write_proc(file_html,html)
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

使用例

```bash
./click_save.py https://ekzemplaro.org/audio mpg321 mpg321.html
```

上記の例でクリック前のページ
![click_aug2501.png](https://qiita-image-store.s3.amazonaws.com/0/179446/84989467-2e54-9d3d-9ce9-30d2b8662904.png)

クリック後のページ
![click_aug2502.png](https://qiita-image-store.s3.amazonaws.com/0/179446/8890577e-dfd6-c095-11a5-4ba61a8c0488.png)

このクリック後のページが保存されます。
draw.ioでAWSのシステム構成図を描いてみる

# 何をするか
- WebサービスのAWSシステム構成図を作成する
- どうせなので、なるべく爆速なシステム構成にする
- どうせなので、なるべく安いシステム構成にする

# 事前準備
[draw.io](https://www.draw.io/) にアクセス
<img src="https://qiita-image-store.s3.amazonaws.com/0/217144/8bca57a1-c249-adbd-3164-a1a691547373.png" width="50%">

Create New Diagram => Network でAWSのテンプレートを選択
<img src="https://qiita-image-store.s3.amazonaws.com/0/217144/0df54d1c-f4fe-eed5-95dc-10bf9ce5e86e.png" width="50%">

# 作成したシステム構成図
![image.png](https://qiita-image-store.s3.amazonaws.com/0/217144/0fe586d1-bbfe-a13c-5333-72713afb9489.png)

## こだわりポイント
- 静的ページ（HTML/javascript/css/画像）は CloudFront + S3 で爆速に
- データ登録はAPIGateway + Lambda + DynamoDB　でまあまあの速度に
- 登録されたデータはAPIGatewayのCache（別料金） or Lambdaの再利用キャッシュを使用してキャッシングする
- レコメンドやランキングなどのデータはバックエンドで作成してS3に配置し、CloudFront経由で取得する
- Lambda＋APIGatewayの開発はCode３兄弟を使ってDevOps化する

# 次回予告
これを作ってみる
HTMLで部分的にイタリックにする方法

#なんのための記事か？
知らないことはすげー怖い。
て思ったから備忘録も兼ねてシェア。

#HTMLで記述される文字を部分的にイタリック体にするには？

##方法1(超簡単)
```:HTML
<p>前部分<i>イタリック部分</i>後部分</p>
```
参考URL 文中のイタリック体の「性欲」に注目。
https://storage.googleapis.com/edd-homepage/IntroductionEdD/index.html

##方法2(すげー力技)
bootstrapを利用。

```HTML:
<p class="forItalic"></p>前部分<p class="forItalic">イタリック部分</p><p class="forItalic">後部分</p>

```
```CSS:
.forItalic{
 display:inline;
}
```

#最後に
ほんのちょっとしたことなんだけど、
知っているのと知らないのでラクしてトクする具合が大きく変わってくるから、
もっと簡単な方法があるんじゃないか？って常に疑問を持つ心を持とう！
CentOS7にdocker-ceをインストールする

## 目的

* CentOSにdocker-ceをインストール
* サービス起動設定

## 公式

https://docs.docker.com/install/linux/docker-ce/centos/#os-requirements

## 手順

事前にdockerが入っている場合は削除する

```
[root@localhost ~]# sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine
```

yumリポジトリを追加するために依存関係モジュールをインストール

```
[root@localhost ~]# sudo yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2
```

docker-ceをインストールできるようにするためyum追加

```
[root@localhost docker]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
読み込んだプラグイン:fastestmirror
adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
grabbing file https://download.docker.com/linux/centos/docker-ce.repo to /etc/yum.repos.d/docker-ce.repo
repo saved to /etc/yum.repos.d/docker-ce.repo
```

docker-ceインストール(最新)

```
[root@localhost ~]# sudo yum install docker-ce
```

サービス起動

```
[root@localhost ~]# systemctl start docker
```

サービス自動起動設定

```
[root@localhost ~]# systemctl enable docker
```

インストールされたか確認

```
[root@localhost ~]# docker --version
Docker version 18.06.1-ce, build e68fc7a
```
【Swift4】まだ、そんなだせえ方法でArray初期化してるの？


Swiftでテストデータなどを作成する時に、Arrayに同じ値を複数個入れて初期化したい時があります。

そういう時に、つい、こういうやり方をしてしまいがちです。

```swift
// 直書きで入れる
var array = [0,0,0,0,0]
```

```swift
// クロージャーでfor文を使う
var array: [Int] = {
    var array = [Int]()
    for _ in 0 ..< 5 {
        array.append(0)
    }
    return array
}()
```

#もっと便利に書く方法
SwiftのArrayには、以下のようなイニシャライズがあります。

```swift
public init(repeating repeatedValue: Array.Element, count: Int)
```

これは、repeatedValueに渡された値を、countの数だけ格納して初期化してくれるので、最初にあげたようなやり方を、スマートに書くことができます。

```swift
var array = [Int](repeating: 0, count: 5)
```

#注意点
classオブジェクトをrepeatedValueに指定した場合、参照を複製してしまうため、Arrayの中身の値を書き換えた時に、初期化時の値全てに反映されてしまうので注意が必要です。

```swift
class TestClass {
    var value = 0
}

var array = [TestClass](repeating: TestClass(), count: 5)
// 0番目を書き換えてログに出力する。
array[0].value = 100
array.forEach { print($0.value) }

// 0番目以外も変わってしまう!
/*
 出力結果
 100
 100
 100
 100
 100
 */
```

もちろんstructなどの値渡しオブジェクトを使用する際は、この注意点を気にする必要はありません。

```swift
struct TestStruct {
    var value = 0
}

var array = [TestStruct](repeating: TestStruct(), count: 5)
array[0].value = 100
array.forEach { print($0.value) }

// 0番目だけが変わる!
/*
 出力結果
 100
 0
 0
 0
 0
 */
```

#おまけ

##Extension
どうしてもクラスでやりたいけれど、参照が複製されたら困る場合に使うArrayのExtensionです。

```swift
extension Array {
    
    init(count: Int, repeating closure: () -> Element) {
        var array = [Element]()
        for _ in 0 ..< count {
            array.append(closure())
        }
        self = array
    }
}
```

##使い方
```swift
var array = [TestClass](count: 5) { TestClass() }
array[0].value = 100
array.forEach { print($0.value) }

// 0番目だけが変わる!
/*
 出力結果
 100
 0
 0
 0
 0
 */
```
WLC がAPを認識しない

#事象

以下のようなエラーメッセージが出力され、WLC(WIRELESS LAN CONTROLLER 4400) が　AP(Aironet 1250)を認識せず、JOINできない

```ruby:APのコンソールに出力されるエラーメッセージ
*Aug  8 06:25:24.000: %CAPWAP-5-DTLSREQSEND: DTLS connection request sent peer_ip: 172.16.0.2 peer_port: 5246
*Aug  8 06:25:24.387: %DTLS-5-ALERT: Received FATAL : Certificate unknown alert from 172.16.0.2
*Aug  8 06:25:24.387: %DTLS-5-SEND_ALERT: Send FATAL : Close notify Alert to 172.16.0.2:5246
```




#原因
APの証明書の有効期限が切れていた（２００８年〜２０１８年）

```ruby:証明書の確認コマンド
(AP)> show crypto pki certificates
```

```ruby:中身
Certificate

 (略）

　　　　　Validity Date: 
 　　　   start date: 14:15:31 UTC Apr 3 2008
 　　　   end   date: 11:25:31 UTC Apr 3 2018
```
現在は2018年７月なので、期限切れ。

#解決方法


WLCで有効期限を無視するコマンドが用意されているので、実行する


```ruby:version　7.0.252.0
(WLC)>config ap lifetime-check {mic|ssc}  enable
```

```ruby:version　7.4.140.0
(WLC)>config ap cert-expiry-ignore {mic|ssc} enable
```

コマンドがなければ、WLCのバージョンをアップデートする。

#参考
[Lightweight AP - Fail to create CAPWAP/LWAPP connection due to certificate expiration](https://community.cisco.com/t5/wireless-mobility-documents/lightweight-ap-fail-to-create-capwap-lwapp-connection-due-to/ta-p/3155111)
[python] 指定ページの表示速度を計測、そしてレポートをまとめる

# ページの表示速度をrequests を使って
python のバージョンは3.6.5 です。

```python
# -*- coding: utf-8 -*-
import requests

def test1():
    print ("この記事")
    r = requests.get('https://qiita.com/sasajidegozaimath/items/e4e401b3de41360376c2') 

    # elapsed を用いて以下の通り計測します。
    print (r.elapsed.total_seconds())

    # 404の場合はテストがFailuredであることを確認するために、assertion を入れます
    assert '200' in str(r.status_code)

```

実行には pytest--html → https://pypi.org/project/pytest-html/ のコマンドを用います。
インストールしていない場合はインストールしておくとレポートの作成が捗ると思います。

<pre>
pytest ***.py --html=report.html
</pre>

report の箇所は、好きなファイル名にしてください。
結果ファイルは以下のようにhtml形式で出力されます。
成功・失敗がひとめでわかるので嬉しいです。
<img width="1227" alt="20180825.png" src="https://qiita-image-store.s3.amazonaws.com/0/266495/a8f0362e-377d-2b6f-22fb-6937c7c239c7.png">
【将棋AI】「将棋AIで学ぶディープラーニング」を読む♪～対戦してみる

<img width="200" style="float: left;" alt="将棋AIで学ぶディープラーニング" src="https://qiita-image-store.s3.amazonaws.com/0/233744/ded117b9-37c7-1b41-033d-960e63ca5fe1.jpeg">
第六夜は、将棋所をダウンロードして昨夜のtrain_policyで学習したパラメータを使って対戦するところまで記述します。
###説明したいこと
（１）将棋所のダウンロード
（２）とにかく対戦してみる
（３）対戦する
###（１）将棋所のダウンロード
【参考】
[ホーム＞ダウンロード](http://shogidokoro.starfree.jp/download.html)
[ホーム＞将棋所の使い方](http://shogidokoro.starfree.jp/usage.html)
参考からShogidokoro.zipをダウンロードします。
やり方は将棋所の使い方のDownloadを見てください。
普通にダウンロードして、解凍すれば以下のフォルダーが出てきます。
![shogidokoro.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/834459de-8f7b-5719-a85f-eaa8a40c63ec.jpeg)
ここでShogidokoro.exeをダブルクリックすると以下のようなアプリが起動します。
![shougidokoro_kido.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/e70c627e-94d9-849e-2906-cfaa602b7450.jpeg)
上記ではエンジン管理を選ぶところですが、ここから作成した自前のエンジンを登録していきます。
ちなみに、当初はLesserkai1.4.2というアプリが登録できます。
登録すると自分自身とも対戦できるので対局を選んで対戦させるのもなれるという意味でいいと思います。
###（２）とにかく対戦してみる
実は昨夜のTrain_policy.pyで学習したパラメータを使って対戦しようとしてもすぐにはできません。そこで将棋所に登録するための作業がありますが、ここでは山岡さんが作成したアプリの構成をダウンロードしてそれを利用することとします。
※内容の説明は次回以降で実施する予定です
まずは、ディレクトリ構成は以下のようにしましょう。

```
PJのディレクトリ
| setup.py
| ...
| kiflist_train_1000.txt
| kiflist_test_100.txt
├── model
|     model_policy
|── pydlshogi
|   |common.py
|   |features.py
|   |read_kifu.py
|   └── network 　 
|   |      policy.py
|   └── usi 　 
|   |      usi.py
|   |      usi_policy_player_.py
|   └── player 　 
|          base_player.py
|          policy_player.py
└── utils            
|      filter_csa.py
|      ...
└── bat            
      policy_player.bat
```
もちろん、以下のサイトからそれぞれダウンロードして保存してください。
[TadaoYamaoka/python-dlshogi ](https://github.com/TadaoYamaoka/python-dlshogi)
ここで一つだけ注意です。
policy_player.pyの以下のディレクトリはたぶん異なるので自分の環境に合わせて変更してください。

```policy_player.py
class PolicyPlayer(BasePlayer):
    def __init__(self):
        super().__init__()
        #self.modelfile = r'H:\src\python-dlshogi\model\model_policy'
        self.modelfile = r'C:\Users\tosio\fastText\path\to\corpus\AB\KerasExample\dlshogi\model\model_policy'
        
        self.model = None

```

###（３）対戦する
ここまでの流れの通り、ファイル名等を同じ名称でやってくるとエンジン登録から対戦までできると思います。
一応、エンジン登録のやり方は上記のエンジン管理を選んで
![engineReg.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/a02081a3-8256-42ed-1ffa-540379a59b71.jpeg)
で登録されます。

いよいよ対戦です。ウワンと対戦してみようと思います。

![taisen.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/469fa4b1-97a8-4434-4323-45ea47b0a42e.jpeg)
あれ？？負けてしまいました。
![muauanvspolicy.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/a1280d49-4939-81c3-b1df-db3b886c127e.jpeg)
まだまだ方策ネットワークだけなんだけど、。。
そして、この方策ネットワークは以下のように比較的強くLesserkai 1.4.2となかなかいい勝負をして、以下のように勝つこともあります。
※この先が楽しみ
![policy_win.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/9fdbf00e-fff1-ba1d-9532-bd415ff1a139.jpeg)
###まとめ
・将棋所をダウンロードしてインストールする
・自分のエンジンを将棋所で使えるように環境整備する
・実際戦ってみると方策ネットワークが意外に強い
・将棋AIの指し手が思っていたより早い

・この辺り将棋AIを動かす環境及びアプリ作成が難易度高いので先送りにした
AWS CodeStarのCodeBuild設定でどハマりした話

Pythonでサクッとlambdaを作ろうとしてAWS CodeStarってものを見つけて使ってみたらハマったことのメモ。

色々コードを実装していざlambdaに配置したら謎のエラー。ローカルでは全く問題がない。

CodeBuildでもエラーは出ていない、のだが...

原因はlambdaのランタイムはpython3.xを指定していたのにCodeStarが設定したCodeBuildのイメージがなぜかpythonですらなくnodeのイメージだった。で、たまたま？そのイメージにもpythonが入ってたがバージョンが2.xだったのでpipでインストールしていたライブラリで、「python2系のリソースがあるけど、python3系で実行してるよ？」っていうエラーを出してlambdaの実行時に異常終了してた。。。

そりゃね、CodeStarでプロジェクト作るときにはpythonのバージョンまでは指定してなかったしねぇ...でもnodeのイメージってどうなのよ。

ということで、CodeStarを使って新しいプロジェクトを作ったらCodeBuildのコンソールに行って、buildに使われるイメージを確認しましょう。

以上です。
ansibleで遊んだplaybookメモ

用途としては違うだろうけど、複数のEC2でのファイル同期をS3を介してansibleでもできそうだなあ

```playbook.yaml
- hosts: all
  remote_user: ec2-user
  gather_facts: no
  tasks:
    - name: yum install net tools
      become: yes
      become_user: root
      yum: name="net-tools" state=present

    - name: install pip
      become: yes
      become_user: root
      shell: easy_install pip && easy_install --upgrade pip

    - name: install boto3
      become: yes
      become_user: root
      shell: pip install boto3
      register: result

    - name: config dir
      become: yes
      become_user: ec2-user
      file:
        path: ~/.aws
        state: directory

    - name: setup region for boto3
      shell: echo "[default]" > ~/.aws/config
    - name: setup region for boto3
      shell: echo "region = ap-northeast-1" >> ~/.aws/config

    - name: sync s3
      shell: aws s3 sync s3://bucket ~/s3
```

ansible面白かった。

```shell
$ ansible-playbook playbook.yaml  --private-key ~/AWS/secret/private-aws.pem

PLAY [all] ******************************************************************************************

TASK [yum install net tools] ************************************************************************
ok: [54.250.161.68]

TASK [install pip] **********************************************************************************
changed: [54.250.161.68]

TASK [install boto3] ********************************************************************************
changed: [54.250.161.68]

TASK [config dir] ***********************************************************************************
ok: [54.250.161.68]

TASK [setup region for boto3] ***********************************************************************
changed: [54.250.161.68]

TASK [setup region for boto3] ***********************************************************************
changed: [54.250.161.68]

TASK [sync s3] **************************************************************************************
changed: [54.250.161.68]

PLAY RECAP ******************************************************************************************
54.250.161.68              : ok=7    changed=5    unreachable=0    failed=0
```
AOLでPHPは使えない？どうしてもPresentation Errorが出てしまうときの対処法 

"Hello World"と出力するだけのシンプルなコード。一見問題ないようだが・・
![スクリーンショット 2018-08-25 15.11.48.png](https://qiita-image-store.s3.amazonaws.com/0/247390/dd129b32-9059-9147-1ab7-ee5a48fc7d10.png)

エラーが出る。なぜ？？
![スクリーンショット 2018-08-25 15.13.18.png](https://qiita-image-store.s3.amazonaws.com/0/247390/18bb91b9-5de3-af78-de52-c8eea81b5f0b.png)

同様のコードをpython3で書いて見る
![スクリーンショット 2018-08-25 15.15.27.png](https://qiita-image-store.s3.amazonaws.com/0/247390/eeb35962-5771-1909-1053-d73fe0fd69b8.png)

これは通る。PHPに起因する現象か？
![スクリーンショット 2018-08-25 15.15.40.png](https://qiita-image-store.s3.amazonaws.com/0/247390/13e065ac-65fb-1503-9a39-3837b650aa8d.png)

どうしてもわからない・・AOL(Aizu Online Judge)のバグなのかな？
# 問い合わせてみた

会津大学の○○と申します。
いつもＡＯＪをご利用頂きありがとうございます。

ご連絡を頂きありがとうございました。
ジャッジでは、必要な改行・空白がない、あるいは不必要な改行・空白を出力すると、
表示エラーとしてPresentation Error となってしまいます。
この問題の場合は
<?php
print "Hello World\n";
?>
のように最後に改行が必要になります。

どうぞ宜しくお願い致します。



## 結論：末尾に改行が必要
確かに通る。そういえばpythonのprint文は、デフォで改行してくれるんでしたっけ。
![スクリーンショット 2018-08-25 15.21.24.png](https://qiita-image-store.s3.amazonaws.com/0/247390/f0c4464d-96ac-f3d4-9266-57cd0a53de15.png)

![スクリーンショット 2018-08-25 15.19.53.png](https://qiita-image-store.s3.amazonaws.com/0/247390/55dc1e25-bf55-4717-6e80-e5ea7ce67ec3.png)
VS Code on Windows10の統合ターミナルからRuby on WSL(Ubuntu 18.04)を開けなかった

# 概要

- Windows 10上のVS Codeの統合ターミナル(wsl)で、WSL(Ubuntu 18.04)上にインストールしたrubyを呼び出そうとしたところ、コマンドが見つからず実行できなかった。
    - ただし、WindowsアプリからUbuntu 18.04のターミナルを開いたときは正しくrubyコマンドが使える。
- 原因はWSLの既定ディストリビューションがLegacyになっていたせいだった。`wslconfig`で既定ディストリビューションを変更したら解決した。

# やりたかったこと

- WindowsとWSL Ubuntuで別々にRubyをインストールしたくない。
- Windows上でRubyのバージョン管理をするのは何かと面倒なので、WSL Ubuntu上でrbenvを使って管理したい。
- VS CodeはWindowsから起動したいが、統合ターミナルはwslを使いたい。
- 起動時の統合ターミナルのカレントディレクトリはVS Codeで開いているディレクトリにしてほしい。

# 困ったときの環境

- OSはWindows 10 Home。最初期のバージョン10.0から使い始め、2018年8月25日現在のバージョンは最新の1803だった。
- 過去、バージョン1703のときにbeta版のWSL (Bash on Ubuntu on Windows)をインストールしていた。
- 今回新たにバージョン1803でWindowsストアからUbuntu 18.04をインストールした。
- このUbuntu 18.04上で、rbenvを使ってrubyをインストールした。
    - このとき`ruby -v`できちんとパスが通っていることを確認した。
- その後、Windows上で別途VS Code(バージョン1.26.1)をインストールした。
- `既定のシェルの選択`でwslを選択した。(デフォルトはpowershellだったと思う)
- 再起動し、統合ターミナルから`ruby -v`したら`ruby: コマンドが見つかりません`。なんで！？

# 解決

コマンドプロンプトから`wslconfig`で既定のWSLディストリビューションを調べたところ、以下のようにLegacyが既定になっていた。

```shell-session
> wslconfig /l /all
Windows Subsystem for Linux ディストリビューション:
Legacy (既定)
Ubuntu-18.04
```

以下のコマンドを実行し、既定のディストリビューションを変更した。

```shell-session
> wslconfig /setdefault Ubuntu-18.04

> wslconfig /l /all
Windows Subsystem for Linux ディストリビューション:
Ubuntu-18.04 (既定)
Legacy
```

引用元：https://linuxfan.info/wslconfig

VS Code上で`Terminal: Select Default Shell`からwslを選択した。これにより以下の記述がユーザー設定に追加された。

```json:settings.json
{
    "terminal.integrated.shell.windows": "C:\\WINDOWS\\System32\\wsl.exe",
}
```

最後にVS Codeを再起動して統合ターミナルを開くと、Ubuntu 18.04の環境に導入しておいたrubyを動かせた。やったぜ。

```shell-session
$ pwd
/mnt/c/Users/asami/workspace
$ ls
hello.rb
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
$ ruby hello.rb
Hello world!
```

# 解決に至るまでに調べたこと

- VS Code (バージョン1.26.1)ではデフォルトで以下の4つが選べるようだ。
    - Command Prompt
    - Windows PowerShell
    - Git Bash
    - WSL Bash
- このうちのWSL Bashはインストールしている**既定の**WSLのshellを使うらしい。([参考](https://qiita.com/kn1cht/items/5813b6ae273d2f22404e))
- インストールしているアプリ版のWSLは`C:\\Users\\<ユーザ名>\\AppData\\Local\\Microsoft\\WindowsApps\\<WSLバイナリ名>.exe`に存在する。([参考](https://qiita.com/m_zuma/items/6b2ee25001109a6506c4))
    - ただし、アプリ版WSLのバイナリを直接指定した場合、統合ターミナルを開いたときのカレントディレクトリがホームに固定されてしまうようだ。
- 私のように「開発環境(コンパイラなど)はWSLで、エディタやファイル管理はWindowsで」と使い分けたい場合、既定としたいWSLに標準shellを含めた環境設定を行った上で、VS Codeの統合ターミナルのシェルにwsl.exeを選択すればよい。
- wslに関する設定はCommand PromptまたはWindows PowerShellから行う。具体的には`wslconfig`を使う。

# まとめ

LegacyなBash on Ubuntu on Windowsはトラブルのもとになるので、普通に使うなら設定等をアプリ版に移行した上で削除してしまったほうがよさそう。
削除は`wslconfig /u <ディストリビューション名>`。(あっさり全消しされるので実行時は要注意)

# 参考

- [Qiita(@kn1cht) - VSCodeの統合ターミナルでWSLのzsh(など)をデフォルトで使う](https://qiita.com/kn1cht/items/5813b6ae273d2f22404e)
- [Qiita(@m_zuma) - VSCode の統合ターミナルで Bash on Ubuntu を利用するための設定](https://qiita.com/m_zuma/items/6b2ee25001109a6506c4)
- [@IT - Windows 10でLinuxプログラムを利用可能にするWSL（Windows Subsystem for Linux）をインストールする（バージョン1803対応版）](http://www.atmarkit.co.jp/ait/articles/1608/08/news039.html)
- [Linux Fan - WSLで複数のLinuxディストリビューションを管理する](https://linuxfan.info/wslconfig)
【JavaScript】「配列」と「オブジェクト」のデータ型について学ぶ - データの操作編

前回に引き続き、「配列」と「オブジェクト」の違いについてまとめていく。

__「ノンプログラマのためのJavaScript はじめの一歩」 第2章 JavaScriptの文法 より__

## 値の取得


### 配列

- `変数名[インデックス]` で取得できる
- インデックスとは、要素に対して `0` から順番に振られた番号みたいなもの

```JavaScript
var dog = [
  'Chihuahua',
  'Shiba',
  'Pug'
];

console.log(dog[1]); //-> Shiba
```

### オブジェクト

- `変数名.プロパティ名` で取得できる
  - 基本的にはこの記法を使用する
- 配列のように `[]` を使って、 `変数名['プロパティ名']` でも取得できる
  - __プロパティ名を変数にして呼び出したい場合__ は `[]` で指定しなければいけない

```JavaScript
var dog = {
  'name': 'Doc',
  'profile': {
    'breed': 'Chihuahua',
    'sex': 'Male',
    'age': 7
  }
};

console.log(dog.name); //-> Doc
console.log(dog['name']); //-> Doc
console.log(dog.profile.age); //-> 7

var key = 'name';
console.log(dog[key]); //-> Doc
```

### 入れ子になっているデータの値を取得する場合は

どちらも `[インデックス]` や `.プロパティ名` をつないで指定することで取得できる。

## 値の更新

配列もオブジェクトも「値の取得方法」で変更したい値を指定して代入する。

## 【配列のみ】要素数の取得

オブジェクトのプロパティ数を取得する方法は記載されていなかった。

`配列の変数名.length` で取得できる。

```JavaScript
var a = [
  [
    1, 2, 3, 4, 5
  ],
  [
    1, 2, 3
  ]
]

console.log(a.length) //-> 2
console.log(a[0].length) //-> 5
```

## 【オブジェクトのみ】プロパティの追加

この章では配列の更新方法は記載されていなかったので、オブジェクトのみ。

```JavaScript
var dog = {
  'name': 'Doc'
};

dog.coat = 'smooth';
console.log(dog); //-> {name: "Doc", coat: "smooth"}
```

## まとめ

理解はできたけど書いてあるコードを読み解くには、値の取得方法からデータがどのような構造になっているかイメージしなければ難しそう。

- `[インデックス]` になっているところは配列
- `.プロパティ名` になっているところはオブジェクト
映画のハッカー気分を味わえる hollywood

ハッカーがターミナル越しにプログラミングしていくシーンが出てくる映画は面白いですよね。僕はソーシャルネットワークとか MATRIX なんかが好きです。

そんな映画に出てくるハッカーの気分を味わえる <a href="https://github.com/dustinkirkland/hollywood" target="_blank" rel="nofollow noopener">hollywood</a> というフェイクアプリを見つけたので、紹介します。

## hollywood とは

<a href="https://github.com/dustinkirkland/hollywood" target="_blank" rel="nofollow noopener">GitHub - dustinkirkland/hollywood</a>

hollywoodは、起動するとランダムにペインを分割し、それぞれのペインで hollywood で定義してあるコマンドをランダムに起動することができます。
その画面上では特に作業はできないフェイクアプリですが、目まぐるしく画面が切り替わっていく様は圧巻です。

## 画面イメージ

hollywood を実行すると、このように数秒ごとに十数枚のペインが何度も切り替わります…！

![hollywood.gif](https://qiita-image-store.s3.amazonaws.com/0/222030/da50ad0a-e2d3-39d2-379b-9a563ffd729f.gif)

また、hollywood 作者の Dustin Kirkland さんの YouTube 動画を観るのもイメージが湧きやすいと思います。

<a href="https://www.youtube.com/watch?v=rVMn3xk5mcY" target="_blank" rel="nofollow noopener">Hollywood Technical Melodrama -- There's an app for that on Ubuntu in Byobu! - YouTube</a>

## インストール・利用方法

hollywood のインストール方法を調べたところ、大きく分けて Ubuntu を使う場合、 Docker を使う場合という2パターンありました。

### Ubuntu

hollywood はもともと Ubuntu 向けの仮想端末である Byobu 上で動くアプリということで、Ubuntu であれば apt でインストールできます。

```bash
$ sudo apt install hollywood
```

上記コマンドでインストールできない場合は、リポジトリ登録してからインストールします。

```bash
$ sudo apt-add-repository ppa:hollywood/ppa
$ sudo apt-get update
$ sudo apt-get install byobu hollywood
```

起動は下記コマンド一発でOKです。

```
$ hollywood
```

停止は ```CTRL+C``` でできます。

### Docker 

Ubuntu 以外の OS の場合は、<a href="https://github.com/dustinkirkland/hollywood/issues/18#issuecomment-356824341" target="_blank" rel="nofollow noopener">hollywood 用の Docker を準備してくだった方がいる</a>ようなので、そちらを使うのがお手軽です。

docker をインストールした状態で、下記コマンドを実行します。

```
$ docker run -it jess/hollywood
```

同じく停止は ```CTRL+C``` でできます。

## hollywood で使われているコマンド

hollywood で実行されているコマンドは下記で確認できます。

https://github.com/dustinkirkland/hollywood/tree/master/lib/hollywood

それぞれのコマンドをざっと調べてみました。そのままコマンドを実行しているのもあれば、すこし加工したコマンドもあって面白いです。
個人的には ```cmatrix``` というコマンドが存在するんだ…！とワクワクしました。

コマンド|概要
:--|:--
apg| パスワードジェネレーター
bmon| 送受信パケット状況を表示
cmatrix| 映画 MATRIX のエフェクト
code| ```/usr``` 以下のプログラムファイル内容を出力
errno| 直近に発生したエラー番号
hexdump| バイナリデータを出力
htop| プロセスビューアー
jp2a| jpg画像をアスキーアートに変換する
logs| ```/var/log``` 配下のログを出力
man| コマンドマニュアル
mplayer| 音楽プレイヤー
speedometer| ネットワークトラフィックをグラフ表示
sshart| ssh公開鍵作成をアート表示
stat| ファイルの属性や日付を表示
tree| ディレクトリ構造をツリー表示

## 終わりに

直接作業が便利になるわけではないかもしれないですが、気分転換にこんなフェイクアプリも触ってみると面白いなと思いました。知らないコマンドにも出会えてよかったです。

## 参考

* <a href="https://itsfoss.com/hollywood-hacker-screen/" target="_blank" rel="nofollow noopener">Fake A Hollywood Hacker Screen in Linux Terminal | It's FOSS</a>
【JavaScript】「配列」と「オブジェクト」のデータ型について学ぶ - 定義と特徴編

今回は「配列」と「オブジェクト」の共通している部分と異なる部分を意識するため、いくつかのトピックごとに分けてまとめてみる。

__「ノンプログラマのためのJavaScript はじめの一歩」 第2章 JavaScriptの文法 より__

## データ型「配列」と「オブジェクト」の定義と特徴

どちらも以下の点で共通している。

- 複数のデータを `,` で区切り、1つにまとめることができる
- 「値」には、変数同様に色んなデータ型を入れることができる

### 配列

- `[ ... ]` で囲われている部分
- `,` で区切られたそれぞれの値を __要素__ と言う

```Javascript
var foo = [
  '値A', // <- 要素
  '値B'
];
```

### オブジェクト

- `{ ... }` で囲われている部分
- __`プロパティ名: 値` のペアで記述する__
- `,` で区切られたそれぞれのペアを __プロパティ__ と言う

```JavaScript
var foo = {
  'プロパティ名1': '値A', // <- プロパティ
  'プロパティ名2': '値B'
};
```

## まとめ

配列とオプジェクトの大きく異なるポイントは __`プロパティ名: 値` のペアで記述する__ の有無だと思った。
実際の用途ケースがどう違ってくるのか、 `dog` という変数名があったとして〜というケースで少しイメージしてみた。

### 配列を使うなら

ある種類において共通した名称の値を入れる時によさそう。

```JavaScript
var dog = [
  'Chihuahua',
  'Shiba',
  'Pug'
];
```

### オブジェクトを使うなら

1つのデータに付随する様々なデータを入れる時によさそう。

```JavaScript
var dog = {
  'breed': 'Chihuahua',
  'name': 'Doc',
  'sex': 'Male',
  'age': 7
};
```

今回はここまで。
次は「配列」と「オブジェクト」のデータ操作についてまとめていく。
【JavaScript】「文字列」と「数値」のデータ型と「四則演算」について学ぶ

今回は個人的にうっかり抜けてしまってた部分や重要だと思ったポイントを、後で思い出しやすくするためにまとめておく。

__「ノンプログラマのためのJavaScript はじめの一歩」 第2章 JavaScriptの文法 より__

## データ型「文字列」と「数値」の定義と特徴

### 文字列

- `'xxx'` もしくは `"xxx"` など、 __クォーテーションで囲われている部分__
- `+` で文字列の連結ができる

### 数値

- `'xxx'` もしくは `"xxx"` など、 __クォーテーションで囲われていない半角数字__
- 四則演算ができる

## 四則演算

- データ型が数値の場合、足し算・引き算・掛け算・割り算の計算ができる
- 足し算・引き算と掛け算・割り算の優先順位は算数と同じ
- 割り算には「商」を算出する `/` と「あまり」を算出する `%` の2つがある

### インクリメントとデクリメント

（数値を代入した）変数自身の数に1を足したり引いたりして、値を更新する処理は `変数名++` や `変数名--` の書き方に置き換えることができる。
それぞれの処理を「インクリメント」「デクリメント」と言う。

下の2つは同じ処理になる。

```JavaScript
var a = 5;
a = a + 1;
console.log(a); //-> 6
```

```JavaScript
var a = 5;
a++;
console.log(a); //-> 6
```

### 数値と文字列の違い

数値と文字列の違いは `+` で連結するとわかりやすい。

- 数値のみ：足し算
- 文字列のみ：文字列の連結
- 数値と文字列：文字列の連結
dockerでGitLab導入時に「Operation not permitted」と言われた話

## はじめに
GitLabをできるだけ手軽に導入したいと思い、Dockerを使った導入方法を試してみることにした。
しかし、自分のDockerに関する知識が不足しており、はまったところがあったので、メモがてらに投稿。

## エラー内容
[公式の手順](https://github.com/sameersbn/docker-gitlab#quick-start)どおり、

```sh
$ wget https://raw.githubusercontent.com/sameersbn/docker-gitlab/master/docker-compose.yml
$ docker-compose up
```

してみると、

```
gitlab_1 | chmod: changing permissions of '/home/git/data': Operation not permitted
```

こんなエラーが何個も出ている。 …という状況。

## 解決方法
まず、前提として、`/home/git/data`はコンテナ側のパスであり、これに結び付けられているホスト側でのパスは`/srv/docker/gitlab`である。（公式がこのように指定している）

が、`/srv`ディレクトリ配下を編集する権限がないために、 `Operation not permitted`と言われているわけである。

したがって、適切な権限を付与すれば動くはず。
だがしかし、めんどくさがりな僕は
`/srv`配下ではなく、`/Users/（ユーザ名）`配下で作業することで、今回のエラーを回避。

つまり、`docker-compose.yml`を以下のとおり3箇所修正しました。
（今回はテスト的に導入してみたため、`Desktop`配下に設置しています。）

```
version: '2'

services:
  redis:
    restart: always
    image: sameersbn/redis:4.0.9-1
    command:
    - --loglevel warning
    volumes:
    # - /srv/docker/gitlab/redis:/var/lib/redis:Z    # 本来左記のようになっているのを
    - /Users/(ユーザ名)/Desktop/gitlab/redis:/var/lib/redis:Z    # Users配下に変更

  postgresql:
    restart: always
    image: sameersbn/postgresql:10
    volumes:
    # - /srv/docker/gitlab/postgresql:/var/lib/postgresql:Z    #ここも同様
    - /Users/(ユーザ名)/Desktop/gitlab/postgresql:/var/lib/postgresql:Z
    environment:
    - DB_USER=gitlab
    - DB_PASS=password
    - DB_NAME=gitlabhq_production
    - DB_EXTENSION=pg_trgm

  gitlab:
    restart: always
    image: sameersbn/gitlab:11.1.4
    depends_on:
    - redis
    - postgresql
    ports:
    - "10080:80"
    - "10022:22"
    volumes:
    # - /srv/docker/gitlab/gitlab:/home/git/data:Z    # ここも同様
    - /Users/(ユーザ名)/gitlab/gitlab:/home/git/data:Z
    environment:
    - DEBUG=false

    ~以下省略~
```

## 結果
<img width="1280" alt="スクリーンショット 2018-08-25 15.05.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/119088/328c09f3-b629-ccb7-d6b9-dff5ae1409db.png">

はい、表示されました😊

## 追記（2018/11/18）
[個人ブログ](https://yyh-gl.hatenablog.com)始めました。
よかったらこちらもどうぞ！
[初心者] [メモ] 「退屈なことはPythonにやらせよう」をやってみたメモ　５章演習プロジェクト

## はじめに
「退屈なことはPythonにやらせよう」をやって見て演習プロジェクトの答えがなかったため、自分なりに考えた答えを公開してみようと思います。

フィードバックがいただけたり、すこしでも他の学習者の手助けになれば幸いです。

以下の内容を見てわからない方は書籍の購入をお勧めします！
とてもわかりやすく参考になる書籍だと思います。

## ファンタジーゲームの持ち物リスト

### 問題
{'ロープ': 1, 'たいまつ': 6, '金貨': 42, '手裏剣': 1, '矢': 12}のような辞書を引数として受け取って次のように表示する関数display_invetory(invetory)を書く

持ち物リスト:
1 ロープ
6 たいまつ
42 金貨
1 手裏剣
12 矢
アイテム総数: 62

### 回答
```python

def display_invetory(invetory):
    print('持ち物リスト:')
    total_items = 0
    for k, v in invetory.items():
        print(str(v) + ' ' + k)
        total_items += v
    print('アイテム総数: ' + str(total_items))


stuff = {'ロープ': 1, 'たいまつ': 6, '金貨': 42, '手裏剣': 1, '矢': 12}
display_invetory(stuff)
```

## 持ち物リストにアイテムを追加する

### 問題
dragon_loot = ['金貨', '手裏剣', '金貨', '金貨', 'ルピー']
以上のようなリストを受け取り持ち物リストにアイテムを追加するadd_to_invetory(invetory, added_items)を書く

### 回答

```python

def add_to_invetory(invetory, added_items):
    for i in added_items:
        invetory.setdefault(i, 0)
        invetory[i] += 1
    return invetory

inv = {'金貨': 42, 'ロープ': 1}
dragon_loot = ['金貨', '手裏剣', '金貨', '金貨', 'ルピー']
inv = add_to_invetory(inv, dragon_loot)
display_invetory(inv)
```
printf チェッカー

私の C コンパイラのテスト環境は、ほとんどが printf を使ったものでして、当初これらのテストを作成したとき、printf の書式文字列に無頓着でした。

    unsigned int ui;
    long int li;
    ...
    printf("ui = %d li = %x\n", ui, li);

のようなコードを多数書いてしまったのです。最近、このようなテストを修正しなければならないはめになってしまいました。本来なら

    printf("ui = %u li = %lx\n", ui, li);

とでもして %d や %x ではなく %u や %lx とするべきでした。

そこで、printf の書式文字列に対して、引数が妥当かどうかをチェックする簡単なツールがあったらどうかと考えてみたのです。

例えば, 上のようなコードに対しては

    %d に unsigned int が指定されている
    %x に long int が指定されている

といった警告メッセージを出力するものです。
【JavaScript】「変数」について学ぶ

__「ノンプログラマのためのJavaScript はじめの一歩」 第2章 JavaScriptの文法 より__

- 変数とは、データを保存しておく箱
- どんなデータでも入れることができる

### 試してみたこと

> 変数にはどんなデータでも入れることができます。
> P.24より

入れる値によってどんなデータ型が返ってくるか、`typeof` を使って確認してみる。

```JavaScript
var a;
typeof a //-> "undefined"
a = 1;
typeof a //-> "number"
a = '1';
typeof a //-> "string"
a = [ 1, 2, 3 ];
typeof a //-> "object"
a = { b: 1 }
typeof a //-> "object"
```

配列もオブジェクトも `object` らしい。
データの種類については、本を読み進めていく方が理解できそうだったので、今はこれを疑問に持ちながら先に進んでいこうと思う。

-----

###### 参考サイト

- [typeof 演算子 - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/typeof)
【JavaScript】「セミコロン」について学ぶ

__「ノンプログラマのためのJavaScript はじめの一歩」 第2章 JavaScriptの文法 より__

- `;` は文章の終わりを明示する
- 改行をする場合に限り、文末の `;` を省略できる

### 気になったこと

> しかし、セミコロンを省略すると意図しない動作になることがあるので、必ずセミコロンを付けましょう。
> P.20より引用

「意図しない動作」とは…？
改行とセミコロンの省略の関係を軽く調べてみた。

JavaScriptは、セミコロンを省略しても __特定の条件で自動でセミコロンを挿入__ して解釈してくれる仕様になっている。
この「特定の条件」に当てはまらない場合に「意図しない動作になる」らしい。

例えば、、、

```JavaScript
var a = 1;
(function() {
  console.log(a);
})(); //-> 1
```

このコードからセミコロンを省略すると

```JavaScript
var a = 1
(function() {
  console.log(a)
})() //-> Uncaught TypeError: 1 is not a function

// このように認識されている
var a = 1 (function() {
  console.log(a);
})();
```

今の知識力では、「特定の条件」を全て理解するのは難しいけれど、「必ずセミコロンを付けましょう」の理由を理解することはできた。

-----

###### 参考サイト

- [JavaScriptのセミコロンを省くと起こること](https://qiita.com/IganinTea/items/ac48b7e12890351ee55a)
- [JavaScriptの行末セミコロンは省略すべきか | blog.tai2.net](https://blog.tai2.net/automatic_semilocon_insertion.html)
「ノンプログラマのためのJavaScriptはじめの一歩 (WEB+DB PRESS plus) 」を読んで、個人的なメモを残していきます

本に書かれているコードを色々試し、自分なりに理解したことや残しておきたいと思ったことを記していきます。

## この本にしようと思った理由

JavaScriptの入門書がいっぱいある中で、この本は1冊を通して1つのコードを体系的に学ぶ構成になっていました。
自分のスキルにちょうどいい本を探している中で、難易度的にちょうどよさそうと思えたことも買う決め手になりました。

## なぜやるのか

jQueryの文法はある程度理解できるけど、JavaScriptそのもの知識が浅いので、基礎的な知識からしっかり理解したい。
そしてゆくゆくはVue.jsを理解できるようになりたい。

### JavaScriptに対して課題だと思っていること

- パフォーマンスを考慮したコードなど、"もっといい書き方"があるのかもしれないけどわからない
- 配列を扱っているコードは読めるけど使いこなせない
- スコープとクロージャを理解するのに時間がかかる

まずはこの課題を解決できるようになりたいと思います。

## 学習メモ（随時追加）

1. [【JavaScript】「セミコロン」について学ぶ](https://qiita.com/otthi/items/ceec62d5a117678649e9)
2. [【JavaScript】「変数」について学ぶ](https://qiita.com/otthi/items/74c4b396be242e9443c0)
3. [【JavaScript】「文字列」と「数値」のデータ型と「四則演算」について学ぶ](https://qiita.com/otthi/items/1229b11093929708e10d)
4. [【JavaScript】「配列」と「オブジェクト」のデータ型について学ぶ - 定義と特徴編](https://qiita.com/otthi/items/387ee53202ff319b3cf5)
5. [【JavaScript】「配列」と「オブジェクト」のデータ型について学ぶ - データの操作編](https://qiita.com/otthi/items/0baa5ae2bf2b62b64810)
6. [【JavaScript】条件判定 true と false について学ぶ](https://qiita.com/otthi/items/239babddcb0c481fe2e9)
7. [【JavaScript】繰り返しの処理 while文 と for文 について学ぶ](https://qiita.com/otthi/items/1981811b251efbd17dca)
動画のサムネイルから視聴回数を予測するAI

# 概要
動画のサムネイルから視聴回数を予測してみました。ようするに、どんなサムネイルを作れば、視聴回数が上がるか事前に分かるようになるかもしれません。

# はじめに
AutoMLを使うにあたって試したいと思いやってみました。

# 準備
今回は **MEGWIN TV** さんと **マックスむらい** さんのチャンネルを使用しました。(動画数が多いため)
ソースコードは、 https://github.com/GitHub30/predict_yt_views にあります。(糞コード)

### 1. チャンネルの動画一覧をすべて取得する。
チャンネルの動画一覧を取得しようとすると、APIの制限に引っかかるので、代わりにチャンネルのplaylistを使って動画一覧を取得します。

```python:print_video_ids.py
playlistId = 'UUp_RW49IudjKEw_yal7tfFw'
def print_video_ids(next_page_token=''):
    response = build('youtube', 'v3', developerKey=DEVELOPER_KEY).playlistItems().list(
        part="snippet",
        playlistId=playlistId,
        maxResults=50,
        pageToken=next_page_token
    ).execute()

    for item in response.get('items', []):
        print(item['snippet']['resourceId']['videoId'])

    if 'nextPageToken' in response:
        print_video_ids(response['nextPageToken'])

print_video_ids()
```

### 2. サムネイルをダウンロードする。
```bash
for video_id in `python print_video_ids.py`
do
    wget https://img.youtube.com/vi/${video_id}/mqdefault.jpg -O $video_id.jpg
done
```

### 3. 視聴回数を取得する。
```python
response = build('youtube', 'v3', developerKey=DEVELOPER_KEY).videos().list(
    part="statistics",
    id=video_id
).execute()

for item in response.get('items', []):
    if 'viewCount' in item['statistics']:
        print(item['statistics']['viewCount'])
```

### 4. zipファイルを作成する。
今回は、視聴回数が **MEGWIN TV** は100000回を超えているかいないか、 **マックスむらい** は200000回を超えているかいないかでデータセットを作成しました。

```
megwin/
  ├ a_0/
  │   └ 2mBRwwNA8zw.jpg
  │   └ r29uWKBm67I.jpg
  │          ︙
  │   └ 6s56MRsGk6k.jpg
  └ a_100000/
      └ kNyTatPkSbM.jpg
      └ ghgbFMZgZP8.jpg
             ︙
      └ B4kZl_UBsgY.jpg
megwin.zip
maxmurai/
  ├ a_0/
  │   └ y88JG09nXYM.jpg
  │   └ u9fqddk61o0.jpg
  │          ︙
  │   └ v5eG3Gb0Bzo.jpg
  └ a_200000/
      └ ntnOdOsOjBI.jpg
      └ 7gUS4IF3sY4.jpg
             ︙
      └ NmBCbUVPcAU.jpg
maxmurai.zip
```

### 5. データセットの作成
先程、作ったzipファイルを選択してください。
![beta-dot-custom-vision.appspot.com_vision_datasets_create_project=automl-mnist (1).png](https://qiita-image-store.s3.amazonaws.com/0/208363/fa066f8c-fdaf-01ae-6e7d-16c52c207f49.png)

### 6. 学習
無料で学習できます。
![beta-dot-custom-vision.appspot.com_vision_datasets_train_dataset=ICN3734265783997282363&model=ICN3119082969681404154&project=automl-mnist.png](https://qiita-image-store.s3.amazonaws.com/0/208363/44d2a342-309f-2fcb-76c9-e323cce681cb.png)

# 結果
**MEGWIN TV** は80%の精度で10万再生できるサムネイルかどうか識別できることがわかりました。
![beta-dot-custom-vision.appspot.com_vision_datasets_evaluate_dataset=ICN3734265783997282363&model=ICN3119082969681404154&project=automl-mnist.png](https://qiita-image-store.s3.amazonaws.com/0/208363/8664f415-e7e4-a492-2bcd-59c1986b452d.png)

**マックスむらい** は81%の精度で20万再生できるサムネイルかどうか識別できることがわかりました。
![beta-dot-custom-vision.appspot.com_vision_datasets_evaluate_dataset=ICN6072659906232381245&model=ICN1468243788934747461&project=automl-mnist.png](https://qiita-image-store.s3.amazonaws.com/0/208363/97e2c866-742b-5894-2347-11cab52a9f59.png)



# おわりに
投稿時からいいサムネを作れば、より多くのひとに見てもらえるようになるかもしれないですね。
サムネイルが視聴回数に影響することがわかったので、次はどんなサムネイルを作ればYouTubeの急上昇にのるのかや高評価や低評価の割合を予測してみたいです。今回は画像だけだったので、タイトルも解析してアンサンブルしたら精度が上がるか検証してみたいです。
MacでReactNativeの環境構築

## 手順
公式の[Getting Started](https://facebook.github.io/react-native/docs/getting-started.html)に、エラー対処なども含めて詳しく記載されていました。

### Node, Watchmanのインストール
```
$ brew install node
$ brew install watchman
```

### Watchmanのインストール時のエラー
Watchmenのインストール時に下記エラーが発生しました。
手動でディレクトリを作成することで回避しました。
ユーザー名はwhoamiで読み替えてください。

```
# エラー内容
Error: An unexpected error occurred during the `brew link` step
The formula built, but is not symlinked into /usr/local
Permission denied @ dir_s_mkdir - /usr/local/Frameworks
Error: Permission denied @ dir_s_mkdir - /usr/local/Frameworks

# 回避方法
$ sudo mkdir /usr/local/Frameworks
$ sudo chown your_user:admin /usr/local/Frameworks/
```

### react-native-cliのインストール
```
$ npm install -g react-native-cli
```

### サンプルプロジェクトの作成
```
$ react-native init SampleProject
$ cd SampleProject/
```

### iOSのエミュレーターで確認
```
$ react-native run-ios
```

### Androidのエミュレーターで確認
SDKのバージョンが古かったため、アップデートを行いました。

```
$ react-native run-android
```
あるファイルを削除するだけでディスク使用率が100％になる理由

# ディスク容量が100％！
サーバーをメンテしていたところ、最近になってディスク使用率があっという間に100％になってしまうとい現象が起きました。
こういうときは、`du -m` や `find . -mmin -60 -ls` などで容量の大きいファイルを見つけて削除すれば空きます。[ncdu](https://dev.yorhel.nl/ncdu)を使うとより楽に容量の重たいファイルを見つけることができるようです。

# 見つからない容量の大きいファイル
ところが、一週間くらいかけて少しずつ容量の大きいファイルを探しては削除や空で上書き(`echo "" > xxx.log`)してもみるみるうちにディスクは圧迫されすぐに100％になってしまいました・・・。
容量が空いていないと実行できないコマンドもいくつかあるため、少し空けてはメンテを行いということを繰り返す。
ついには `tune2fs` でファイルシステム中の予約ブロックを減らすまでに至り、もうこれ以上減らせるものがないと悟りました。

# プロセスによって掴み続けられているファイル
プロセスがファイル(ファイルのinode)を掴んでいると、プロセスがファイルを開放するかプロセスが終了するまでそのファイルがどんな姿形になっていようが書き込み続けるという挙動をします。
こういったプロセスは `lsof`で特定することができました。

[sort - How to find the largest open files? - Unix &amp; Linux Stack Exchange](https://unix.stackexchange.com/questions/382693/how-to-find-the-largest-open-files)

こちらのリンクに書き込まれている以下のコマンドにより、lsofを使ってプロセスが掴んでいるファイルを容量順にソートしてくれるのですぐに見つけることができました。

```
lsof \
| grep REG \
| grep -v "stat: No such file or directory" \
| grep -v DEL \
| awk '{if ($NF=="(deleted)") {x=3;y=1} else {x=2;y=0}; {print $(NF-x) "  " $(NF-y) } }'  \
| sort -n -u  \
| numfmt  --field=1 --to=iec
```

その結果がこれです。

```
39G  /var/log/ufw.log
42G  /var/log/kern.log
42G  /var/log/syslog
```

エッッッッッッッッッ

しかし、そこにはファイルが存在していません。ファイルが存在していないけど書き込まれ続けているという現象。
そこで思い出しました。ログを整理しようとして `echo "" > /var/log/ufw.log` ではなく `rm` したあの日の事を。

こちらは `rsyslogd` を再起動するだけで簡単に解決しました。

# なぜ肥大化したのか

そもそもなぜ肥大化したのか、そしてファイルは見つからなかったのか。
logrorateも正常に動いているのにもかかわらず肥大化した理由は、単にそこにファイルがないからlogrorateしようにもできないということでした。
本来、logrotateの中でrsyslogdを再起動しています。しかし、rsyslogdが管理しているファイルをすべて`rm`してしまったことにより、rsyslogdが再起動する機会を人の手によってすべて奪ってしまったのです。

そうやってlogrotateで削除や圧縮、再起動もされることもなく、duやfindでも見つからない巨大ファイルが出来上がります。


# 対策

log系ファイルは削除ではなく、空で上書きするに徹すればいいというわけではありますが何らかのオペレーションでファイルが開いているプロセスを削除してしまうかもしれません。そうなったら気づけない。

簡単な対策として定期的にrsyslogdなどのプロセスをcronで再起動するようにするだけでもいいのかもしれません。
一番シンプルなWordpressテーマ

#Wordpressで一番シンプルな構造とは？
　これからWordpressについて知りたいと思ってまずは簡単なシステムは何なのか？ということでメモ
#必要なファイル
- index.php
- functions.php
- screenshot.png
- style.css


　必要最小限のファイルはこの４つのファイルになる。
　それぞれの中身は下記に記載

```index.php
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
	  xml:lang="ja"
	  lang="ja">
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=<?php bloginfo('charset'); ?>" />
		<title><?php bloginfo('name'); ?><?php wp_title(' : '); ?></title>
		<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" />
	</head>
	<body <?php body_class(); ?>>
		
	</body>
</html>
```

```functions.php
// なし
```

```style.css
/*
Theme Name: ThemaMin
Theme URI: https://wordpress.org/themes/twentyfifteen/
Author: the my name
Author URI: https://wordpress.org/
Description: オリジナルテーマ（日本語は文字化け）
Version: 1.0
License: GNU General Public License v2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
Tags: blog, two-columns, left-sidebar, accessibility-ready, custom-background, custom-colors, custom-header, custom-logo, custom-menu, editor-style, featured-images, microformats, post-formats, rtl-language-support, sticky-post, threaded-comments, translation-ready
Text Domain: ThemaMin
*/
```

これらのファイルからいろいろ追加していく必要があるけども、関数はすでに用意されているものを引用していけば問題ないかと思うのでいろいろ試してみようと思う。

サンプルのデータはこちら↓
https://github.com/chibadai/ThemaMin
Pythonランチャ（Windows版のみ）




# はじめに

[Pythonの複数バージョンの扱い方（Windowsの場合） | ガンマソフト株式会社](https://gammasoft.jp/python/python-version-management/)

[3. Windows で Python を使う — Python 3.7.0 ドキュメント](https://docs.python.org/ja/3.7/using/windows.html#launcher)

恥ずかしながらPythonランチャというのを初めて知りました。

Python 3.3 から、Windows版のPythonをインストールすると、Pythonランチャが一緒にインストールされます。

C:\Windows\py.exe が実行ファイルです。

Pythonランチャを使うと、インストールされたPythonのうち最新版を自動で選択して実行してくれ、さらに古いバージョンのPythonもインストール済みならバージョン指定して実行させることも出来ます。



# 試してみた

```sh
E:\projects>py -V
Python 3.7.0
```

`py` コマンドは新しくインストールした3.7.0が動いています。


```sh
E:\projects>py -m pip -V
pip 10.0.1 from E:\app\create\Python370\lib\site-packages\pip (python 3.7)
```

`py` コマンドから `pip` を呼び出すと、3.7.0のpipが動きます。


```sh
E:\projects>python -V
Python 3.6.5
```

環境変数に古いPythonのパスが登録されていると、 `python` コマンドでそっちが動いてしまいます。


```sh
E:\projects>pip -V
pip 10.0.1 from e:\app\create\python365\lib\site-packages\pip (python 3.6)
```

`pip` コマンドも同様です。


```sh
E:\projects>py -3.6 -V
Python 3.6.5
```

環境変数から古いPythonのパスを削除しても、`py` コマンドでバージョンを指定して実行が可能です。
（古いPython自体をアンインストールしてしまうと、これは実行できません）
（`python` コマンド、`pip` コマンドはパスが通らなくなるので実行できなくなります）



# 感想

何も考えずにPythonをほいほいインストールしていっても、ランチャーが自動で管理してくれるので便利で助かりますね。
Bashの入出力リダイレクトまとめ

# チートシート

```bash
# 入力
command < file   # ファイルの内容をコマンドの標準入力に渡す

#-----------------------------------------------------------
# 出力
command >&2      # 標準出力を標準エラー出力にリダイレクト

command > file   # ファイル作成 or 上書き
command >> file  # 追加出力。ファイルがなければ作成
command 2> file  # 標準エラー出力をファイルにリダイレクト(作成 or 上書き)

command &> file      # 標準出力/エラー出力を同一ファイルにリダイレクト
command > file 2>&1  # 同上
command &>> file     # 標準出力/エラー出力を同一ファイルに追加書き込み
command >> file 2>&1 # 同上

command > file1 2> file2   # 標準出力,エラー出力を別々のファイルにリダイレクト
command >> file1 2>> file2 # 標準出力,エラー出力を別々のファイルに追加書き込み
```

NOTE:

- `&>` は `>&` に置き換え可能だが、[Man page of BASH](http://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html)によれば好ましいのは前者らしい。
- 同様に、`&>>` は `>>&` に置き換え可能。
- `&>`, `&>>` 辺りはBash以外のシェルでは動かないことがあったと思う。



# 参考

- [bash: 標準出力、標準エラー出力をファイル、画面それぞれに出力する方法 - Qiita](https://qiita.com/laikuaut/items/e1cc312ffc7ec2c872fc)
エラー対処：Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted

Ansibleをインストールしようとして出たエラーの対処法メモ

```shell
$ sudo pip3 install ansible
...
Collecting MarkupSafe>=0.23 (from jinja2->ansible)
Collecting pycparser (from cffi!=1.11.3,>=1.7->cryptography->ansible)
Installing collected packages: pycparser, cffi, six, idna, asn1crypto, cryptography, bcrypt, pynacl, pyasn1, paramiko, PyYAML, MarkupSafe, jinja2, ansible
Could not install packages due to an EnvironmentError: [Errno 1] Operation not permitted: '/bin/ansible-console'
```

どうやら `/bin` 以下にはsudoでもファイルが置けない模様。
そこでpipに `--user` オプションをつけてインストール場所をかえる。

```
pip3 install ansible --user
```
私のMac環境だと`/Users/paper2/Library/Python/3.7/bin`にインストールされていたのでパスを通してインストール完了。

ちなみにパスの確認方法は以下

```sh
$ pip3 show ansible
Name: ansible
Version: 2.6.3
Summary: Radically simple IT automation
Home-page: https://ansible.com/
Author: Ansible, Inc.
Author-email: info@ansible.com
License: GPLv3+
Location: /Users/XXXX/Library/Python/3.7/lib/python/site-packages
Requires: paramiko, setuptools, cryptography, jinja2, PyYAML
Required-by:
```
Atcoder ABC 105 D by Python3 (累積和、modをキーとする辞書の利用)


[Atcoder Beginner Contest 105 D](https://beta.atcoder.jp/contests/abc105/tasks/abc105_d)　のPython3による解答例。
##学んだこと
- ずらっとならんだ数字のうち一定区間の合計を考えるときは、累積和を利用する。
- 「差が割り切れるかどうか」←→「mod n に関して等しい」と換言する。
 
辞書検索の計算量オーダーについていまいち理解できていない。O(1)なのだろうか？

##コード
```
# coding: utf-8

n,m = list(map(int,input().split()))
A = list(map(int,input().split()))

#（↓）累積和を別のリストに格納する必要はなく、modmという変数を1つ用意して、modmにその時点での累積和のmod mを格納すればよい
modm = 0

#（↓）{x:y}:Aの各要素を順に処理していくとき、mod mがxである要素が現時点までにy個見つかっていることを表す
dic = {0:1}

cnt = 0
for a in A:
    modm = (modm+a) %m
    cnt += dic.get(modm,0)
    dic[modm] = dic.get(modm,0) + 1
#（↑）c[b]では、bをキーとする要素が見つからなかった場合エラーが発生してしまう。
#（↑）c.get(b,default)なら、bをキーとする要素が見つからなかった場合デフォルト値を返してくれる。

print(cnt)
```
System.Net.WebException - App Transport Security policy requiresが出た時の対処

Xamarin.iOSでHttpClinetを使った時に、System.Net.WebExceptionが発生するようになってしまった。前はhttpでもいけたと思ったんだけど、httpsじゃないとダメみたい。
![System.Net.WebException.png](https://qiita-image-store.s3.amazonaws.com/0/77444/fb37348c-9224-a593-28e9-85929dfdbb89.png)

# stack overflowにXcode用の解決方法があった
[The resource could not be loaded because the App Transport Security policy requires the use of a secure connection]
(https://stackoverflow.com/questions/32631184/the-resource-could-not-be-loaded-because-the-app-transport-security-policy-requi)

# Xamarinで試したところうまくいった
1. Visual Studio＞プロジェクトツリー＞info.plist＞ソースを開く
1. 新しいエントリの追加で、NSAppTransportSecurity（辞書型）を追加
1. 追加されたエントリの下に、NSAllowsArbitraryLoads（ブール値）を追加し、値を「Yes」にする。

- 設定例 - Visual Studio for Mac v7.6.1(build 9)
![info-plist.png](https://qiita-image-store.s3.amazonaws.com/0/77444/738b592e-7c9e-4e89-4b66-be3eb912be27.png)


リビルドして実行すれば、httpsで通信できるようになる。
React Router v4とReduxを繋げるにはconnected-react-routerを使うのがおすすめだよ！

今、Railsをバックエンド、ReactをフロントエンドにWebサービスを作っています。
Reactでは、ステート管理に`Redux`、ルーターに`React Router v4`を使っています。
そこで、`React Router v4`のステートをReduxで管理したいのです。

# どうやって`React Router v4`のステートをReduxで管理するか
## よくみんなが使ってるライブラリ `react-router-redux`
現在、react-router-reduxは、最新版のはReact Router v4に対応しておらず、alpha版の5系にReact Router v4は対応してるようです。　
しかし、[React RouterのGithubリポジトリ](https://github.com/reacttraining/react-router/tree/master/packages/react-router-redux)をみて見ると、react-router-reduxは、メンテナンスされていなく、非推奨であるそうです。
### ということで`react-router-redux`　を使うのはやめた



そして、[React RouterのGithubリポジトリ](https://github.com/reacttraining/react-router/tree/master/packages/react-router-redux)では、ReduxとReactを同期させるためのライブラリはとして、　[connected-react-router](https://github.com/supasate/connected-react-router)が紹介されています。

# React Router推奨の[connected-react-router](https://github.com/supasate/connected-react-router)を使うことにした
使い方は[connected-react-router](https://github.com/supasate/connected-react-router)のREADMEで紹介されています。

## [connected-react-router](https://github.com/supasate/connected-react-router)のいいところ

- `react-router v4`をサポートしてる
- ステートを維持しながらホットリロードすることをサポートしてる
- `redux-thunk`,`redux-saga`で`history`メゾットのdispatchが機能する
- TypeScriptをサポートしてる

## [connected-react-router](https://github.com/supasate/connected-react-router)の使い方

### Step1

- `history`オブジェクトを作る
- ルートレデューサーを`connectRouter`でラップし、`history`オブジェクトを指定して新しいルートレデューサーを取得する
- `history`アクションを送出する場合`（push('/path/to/somewhere')`など）にURLを変更する場合は、 `routerMiddleware(history)`を使う。

```jsx
...
import { createBrowserHistory } from 'history'
import { applyMiddleware, compose, createStore } from 'redux'
import { connectRouter, routerMiddleware } from 'connected-react-router'
...
const history = createBrowserHistory()

const store = createStore(
  connectRouter(history)(rootReducer), // new root reducer with router state
  initialState,
  compose(
    applyMiddleware(
      routerMiddleware(history), // for dispatching history actions
      // ... other middlewares ...
    ),
  ),
)
```
### Step2

- React Routerv4のルーティングを`ConnectedRouter`でラップし、`history`オブジェクトをpropsとして渡す
- `ConnectedRouter`をreact-reduxの`Provider`の子として配置する

```jsx
...
import { Provider } from 'react-redux'
import { Route, Switch } from 'react-router' // react-router v4
import { ConnectedRouter } from 'connected-react-router'
...
ReactDOM.render(
  <Provider store={store}>
    <ConnectedRouter history={history}> { /* place ConnectedRouter under Provider */ }
      <div> { /* your usual react-router v4 routing */ }
        <Switch>
          <Route exact path="/" render={() => (<div>Match</div>)} />
          <Route render={() => (<div>Miss</div>)} />
        </Switch>
      </div>
    </ConnectedRouter>
  </Provider>,
  document.getElementById('react-root')
)
```