OmniAICreator/Qiita-1.07M huggingface dataset:
リスト内包表記の応用

リスト内包表記を使うと、かなり凝ったことをすることができます。
##条件に合ったデータのみアウトプットする
program1のように、for文の中でリストを作成するときに条件式を入れると、条件にあったデータのみを処理することができます。

```python:program1
"""
For文を使ってリストのうち偶数のデータのみ2倍して新たなリストを作成する
"""
num_list = [0,1,2,3,4,5,6,7,8]
num_plus = []
for num in num_list:
    if num % 2 == 0:
        num_plus.append(num * 2)
print(num_plus)
```

これをリスト内包表記では、program2のように記述します。

```python:program2
"""
リスト内包表記を使って、リストのうち偶数のデータのみ2倍して新たなリストを作成する
"""
num_list = [0,1,2,3,4,5,6,7,8]
num_plus = [num * 2 for num in num_list if num % 2 == 0]
print(num_plus)
```

このようにリスト内表表記の最後にif条件を入れることで簡単に書くことができます。
num_listの中で偶数の要素のみを2倍するというプログラムになるので、結果はいずれも次の通りになります。
[0, 4, 8, 12, 16]
となります。
なお、program3のようにif節を並記するとand条件になります。

```python:program3
"""
リスト内包表記を使って、リストのうち4以上偶数のデータのみ2倍して新たなリストを作成する（and条件）
"""
num_list = [0,1,2,3,4,5,6,7,8]
num_plus = [num * 2
            for num in num_list
            if num % 2 == 0
            if num >= 4]
print(num_plus)
```

結果は[8, 12, 16]になります。なお、このように長いリスト内包表記については、改行すると見やすくなるとのご指摘を頂きました。

##リスト内包表記でユーザ定義関数を使う
Program2の例では、引数を倍で与えられた数値を2倍にするという処理をしていますが、これをProgram4ではユーザー定義関数を使って表現しています。

```python:program4
"""
リスト内包表記でユーザー定義関数を使って新たなリストを作成する
"""

def double(num):
    return num * 2

num_list = [0,1,2,3,4]
num_plus = [double(num) for num in num_list]
print(num_plus)
```   
答えは、[0, 2, 4, 6, 8]になります。これは、少しまどろっこしい気もしますが、複雑な内容を簡潔に表現できるようになるのではと感じています。
tensorflow liteでmobilenet_quant_v1_224.tflite: No such file or directory

tensorflow/contrib/lite/examples/ios/camera/data/mobilenet_quant_v1_224.tflite: No such file or directory

一個上のフォルダにシェルスクリプトがあったので叩いて解決
tensorflow/contrib/lite/examples/ios/download_models.sh
CentOS 7 にGitLabをインストールする

# 前提
* CentOS 7のサーバを準備する
    * Memory 4GBが推奨されている。ここでは Azure MarketplaceのVM　`CentOS-7.3`, `D1v2`(1core/3.5GB)を使用

* 独自ドメインを使用する場合
  * 独自ドメインのDNSにGitLabサーバへのAレコード(またはCNAME)設定を追加しておく

* 今回使用したGitLabは`v10.8`

* （参考）GitLab EEを使用している。ライセンスをActivateするまでCEと同等の機能のみ利用可能。
    * [Community Edition or Enterprise Edition \| GitLab](https://about.gitlab.com/installation/ce-or-ee/)

# 手順
## GitLabのインストール
* CentOSサーバで以下のコマンドを実行してGitLabをインストールする

```bash:bash
# 依存パッケージのインストールと事前構成 --------------
sudo yum install -y curl policycoreutils-python openssh-server
sudo systemctl enable sshd
sudo systemctl start sshd

# firewalldを実行していない場合は警告がでるが、そのまま
sudo firewall-cmd --permanent --add-service=http
sudo systemctl reload firewalld

# Postfixのインストール -----------
sudo yum install postfix
sudo systemctl enable postfix
sudo systemctl start postfix

# GitLabパッケージの追加とインストール -----------
curl https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh | sudo bash

# URLは使用しているサーバーのFQDNに置き換えること
sudo EXTERNAL_URL="http://gitlab.example.com" yum install -y gitlab-ee

```

* ブラウザでGitlabにアクセスし、管理者の初期パスワードを設定する

* `root`ユーザで初期設定したパスワードを入力してログインする

## HTTPSの設定（Let's Encrypt統合を利用）
* （参考）Let's encrypt統合を使用しない場合は以下のページを参照
    * [NGINX settings \ Manually configuring HTTPS | GitLab](https://docs.gitlab.com/omnibus/settings/nginx.html#manually-configuring-https))

* `sudo vi /etc/gitlab/gitlab.rb`で以下の行を編集する。（コメントアウトされているので、#を外すこと）


```rb:/etc/gitlab/gitlab.rb
# HTTPSに変更する
external_url 'https://〜'

# Let's　Encrypt統合を有効にする
letsencrypt['enable'] = true 

# Let's Encryptに登録する自分のメールアドレスを指定する
letsencrypt['contact_emails'] = ['foo@email.com']

# (必要に応じて) HTTPリクエストをHTTPSへリダイレクトする設定にする
nginx['redirect_http_to_https'] = true

```

* NSGなどでインターネット側から80ポートへアクセスできない場合は、許可する

* 以下のコマンドを実行する

```bash:bash
# 設定変更を読み込む
sudo gitlab-ctl reconfigure

# 証明書が作成されていることを確認する
ls /opt/gitlab/embedded/ssl/certs/
```
* NSGを変更した場合は、元の設定に戻す。

## Email通知の設定
* 以下を参照
  [Azure上にGitlabを立てる \ メール送信設定 - Qiita](https://qiita.com/sunack/items/acd9412372c87714bfc1#%E3%83%A1%E3%83%BC%E3%83%AB%E9%80%81%E4%BF%A1%E8%A8%AD%E5%AE%9A)

# 参考
* [Installation methods for GitLab \| GitLab](https://about.gitlab.com/installation/#centos-7)

* [NGINX settings \ Enable HTTPS | GitLab](https://docs.gitlab.com/omnibus/settings/nginx.html#enable-https)

* [SSL settings \ Let's Encrypt Integration | GitLab](https://docs.gitlab.com/omnibus/settings/ssl.html#let-39-s-encrypt-integration)
JSONのモデルを自動生成してくれる！

#はじめに
最近GoogleのCloud Vision API　で遊ぶのにハマっているのですが，いつでも遊べるようにアプリを作っていてその時にAPI叩いた時に帰ってくるJSONのモデル作るのがっとってもダルいのでなんとかできないかとggりました．
#見つかったもの
タッタラッタッタッター♪
→[quicktype](https://app.quicktype.io/)←
これです．
使い方はめっちゃ簡単で，とりあえずAPI叩いてJSONをprintとかでコンソールで出してコピーします．
<img width="700" alt="スクリーンショット 2018-05-27 22.23.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/195267/fc91523b-ca3c-a56d-1cff-ec42a0133912.png">
配列になってたりで面倒（）

これをこのサイトの左側の所にJSONを選んでペーストしてあげると
<img width="1000" alt="スクリーンショット 2018-05-27 22.24.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/195267/bc4c2294-378b-f70b-6d29-52d89a305c1a.png">

はい，構造体になってできました．
すごい．

このサイトはSwift以外にC#，Go，C++．Java，TypeScript，Simple Types，Ruby，Kotlin，Rust等多くの言語に対応してるのでめっちゃ捗ります．

#おわり
とっても便利で，モデル作成なんて無駄な時間を取らなくて最高．
システム開発と契約と民法改正

[「システム開発 受託契約の教科書」](https://amzn.to/2kuApQB)を読んで契約の学習したので、その中で自分の基準で重要だと思った点をメモりました。契約について全然詳しくないので、間違っている点もあるかもしれません。

#契約とは
民法の規定だが民法上に契約の定義が明記されているわけではない
強行規定と任意規定があり、民法における契約の規定は基本的に任意規定。民法の強行規定、契約書記載事項、民法の任意規定の順に適用される。そのため、強行規定以外は自由に契約で契約当事者が決められる。
契約は口頭でも成立する
#契約書の目的
##債権・債務の明確化
どのようなシステムを作るのか、納期・金額はいくらか、といった項目。契約書にない場合には民法の規定が適用される。
##紛争発生時の拠り所
紛争発生時の契約解除や損害賠償について規定しておく。
##開発プロセスを規定して開発円滑化
体制、作成物、承認方法に関する条項規定して開発円滑化を図る。
##著作権の所在を明確化
特許権と違い、著作権は申請や登録なしに発生します。原則としては、プログラムを書いた人に帰属するため、契約に規定しないとプログラムを作成した会社が著作権を有する。

#契約基礎知識
##基本契約書
反復・継続して行われる取引に対する取引横断型と、導入プロジェクト全体に適用される基本的ルールを最初に決めるフェーズ横断型の2種類がある。取引横断型はベンダーの元請・下請間で使われることが多い。

#契約書体裁
標題はあったほうが望ましいが、法的な意味がなく必須ではない。

#知っておくべき法律上のポイント
##民法改正
民法の債権法改正法案が2017年6月に公布され3年以内に施行。債権を中心に改正され、システム開発関連として影響があるのは、瑕疵担保責任、解除、損害賠償、仕事ができなくなった場合の報酬です。
##請負と準委任
民法上、「請負は、当事者の一方が**ある仕事の完成をすることを約し**、相手方がその仕事の結果に対してその報酬を支払うことを約することによって、その効力を生ずる。」としています。請負とする場合、そのため、完成する仕事が明確である必要があります。
一方、準委任は事務の委託です。仕事の完成は目的としておらず、善良な注意者の管理義務(善管注意義務)を負って仕事を行います。

請負特徴

- 完成する仕事(システム)が具体的
- 完成したら代金を支払う
- 報酬が工数に関係なく決められている
- 瑕疵担保責任・検収の条項がある
- 契約書標題が「請負契約」

準委任特徴

- 完成する仕事(システム)が不明確
- システムベンダーが投入した人月に応じて代金が決まる
- システム完成ではなく作業実施有無によって支払が生じる
- 契約書標題が「業務委託契約書」

##債務不履行
簡単に言うと契約違反をすると債務不履行となり、履行不能・不完全履行・履行遅滞の3種類があります(ここでは会計の「債務」というより「責務」に近いです)。システムベンダーが請負契約で納期を守れない場合、ユーザーが代金未払いの場合などが債務不履行です。

##損害賠償
債務不履行の場合、債務不履行と因果関係がある損害について賠償請求することができます。
損害賠償額が大きくなるリスクが見込める場合(医療機器やユーティティ関連など)には、契約で上限を求めることがよく行われます。

##解除
契約を双方が合意して途中で無効にしたい場合は合意解除といいます。双方の合意がなくても、一定の事由に該当した場合法定解除ができます。
解除事由によって以下の解除があります。

- いきなり解除可能な**無催告解除**
- 催告をしても相手方が履行しない場合に解除可能な**催告解除**

民法で無催告解除可能な事由(債務履行ができない場合等)が定められていますが、それだけでは不足するので、相手の倒産危機などを契約に追加することが多いらしいです。
請負契約でシステム完成前の解除の場合でも、仕事結果が「可分」であれば、完成部分に相当する報酬を払う必要があります(民法改正により条文化された)。この**報酬額は投入原価に応じてではなく、注文者が受ける利益の割合に応じて**算定されます。

##瑕疵担保責任と契約不適合
瑕疵担保責任は請負契約で適用される欠陥に対する責任です。瑕疵担保責任に対するアクションとして追完請求(修補請求)、損害賠償、解除があります。
**民法改正によって瑕疵担保責任は契約不適合に置き換わります**。
契約不適合は、目的物が契約内容に適合しないことを示します。瑕疵担保責任と比べて当事者の合意、契約趣旨と性質が重視されています。契約不適合に対するアクションとして、追完請求(修補請求)、代金減額、損害賠償、解除の4種類があります(「代金減額」が民法改正により追加)。
期間制限の起算点は以下のように変更されています

|内容|瑕疵担保責任|契約不適合|
|:--|:--|:--|
|責任の期限|引渡から1年|注文者が不適合を知った時から1年|
|責任追及の方法|1年以内に瑕疵内容、損害額算定の根拠を示して請求|1年以内に契約不適合の種類と大体の範囲を通知。請求はその後でOK。|

##著作権
プログラムは「物」ではなくため、所有権ではなく著作権で管理します。システムに関係するものに限定した種類として以下の分類です。

- 著作財産権

 - 複製権:コピーすることをコントロールできる権利
 - 翻案権:既存の著作物の表現上の本質的な特徴の同一性を維持しつつ、具体的な表現形式を変更して新たな著作物を創作する権利

- 著作者人格権

 - 同一性保持権:著作物およびその著作者の意図に反して変更、切除その他の改変を禁止することができる権利

上記の定義があるのですが、著作権法の例外としてバックアップや不具合改修等のためのプログラムコピー・変更は著作権がなくても可能です。
原則的に、著作権は特許権と異なり申請不要で著作者(法人)に帰属します。しかし、契約書上でユーザに移転する規定を設けることも多いです(規定がない場合は、システムベンダー側に帰属)。著作人格権は著作権法の規定により譲渡できないため、著作人格権を行使しないことを契約書上に書いておくことが一般的です。
プログラムだけでなく、設計書等のドキュメントやマニュアルも著作権の対象となり得ます。

##再委託
民法上、準委任契約は再委託は委託者の許諾が必要で、請負契約は再委託は受託者の自由です。しかし、民法の規定より契約が優先されます。そのため、情報漏えいリスクやスキルなどを鑑みて契約書に再委託の可否・条件を記載します。

##協働と役割分担
システム開発を成功させるためにユーザとベンダーが協働作業することが必要です。また、システム開発が失敗した場合のリスクに備えて契約書に役割分担を明確にすること望ましいです。

##検収/検査
法的に請負契約における「検収」とは**「最後の工程まで完了したことを確認すること」**です。品質が問題ないかを検収することではありません。
ベンダー側からすれば、バグがあったからとりって検収が不合格で支払がなされないことは不都合ですし、ユーザ側からするとバグがないことのお墨付きを与えるわけではありません。
検収仕様書の作成と承認プロセスを契約書に明記することが望ましいです。
また、「みなし検収条項」を入れることがあります。検収不合格や検収遅滞の理由が非合理的な場合に検収合格とみなすことです。
spring-boot2系でspring.session.timeoutにserver.servlet.session.timeoutが設定される部分のコード

```xml:pom.xml
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.1.RELEASE</version>
	</parent>
```

色々ぐぐっていると、```spring.session.timeout```には```server.servlet.session.timeout```の値（1系では```server.session.timeout```）が設定される、と書いてある。これってどうやってるんだ？　と思ったんで該当部分のコードを読んだ。

```java:SessionProperties
package org.springframework.boot.autoconfigure.session;

@ConfigurationProperties(prefix = "spring.session")
public class SessionProperties {
	// （略）
	public SessionProperties(ObjectProvider<ServerProperties> serverProperties) {
		ServerProperties properties = serverProperties.getIfUnique();
		Session session = (properties == null ? null
				: properties.getServlet().getSession());
		this.timeout = (session == null ? null : session.getTimeout());
	}
```

なんのことはなく、```SessionProperties```のコンストラクタで```timeout```に```ServerPropertie.getServlet().getSession().getTimeout()```の値を設定しているだけであった。
IFSを再定義して、ロジックを見易くする。

# if文の入れ子のロジックは醜いよね。

関数型プログラミングをする為に、条件文を使いたくなかったので、IFC を定義したのですが、
以前に書いたDI,MIの拡張関数 TMI,TDI をIFC で書くと以下のようになります。
複雑な条件文になると括弧の対応がうざいですね。

```vb
Function TDI(A, T, Optional S = "")
    Dim I: I = Right(A, 1)
    Dim J: J = Val(A)
        
    S = IFC(I = "A", DI(Range(RCC("T01N_", T)), J) _
      , IFC(I = "a", DI(Range(RCC("M01N_", T)), J)) _
      , IFC(I = "B", DI(Range(RCC("T02N_", T)), J)))
    TDI = S
End Function

Function TMI(R, Optional S = "")
    Dim 年, 機械, 番号, W
    Call DR(R, MM(R), 年, 機械, 番号, W)
    
    S = IFC(機械 = 1 And W = 0, CC(MLOT(Range("T01N_"), R), "A") _
      , IFC(機械 = 1, CC(MLOW(Range("M01N_"), R), "a") _
      , IFC(機械 = 2, CC(MLOT(Range("T02N_"), R), "B"))))
    TMI = S
End Function

Function IFC(C, V, Optional S = "")     ' IF C THEN V ELSE S
    If C Then IFC = V Else IFC = S
End Function

```
# IFSの再定義

そこで、WorksheetFunction の IFS を VBS で再定義しました。

```vb
Function IFCS(ParamArray AR())
    Dim S: S = ""
    Dim I: For I = 0 To UBound(AR) Step 2
        If AR(I + 1) Then
            S = AR(I)
            Exit For
        End If
    Next I
    IFCS = S
End Function
```

条件式はperl流に後置きにしました。後置きの方が複雑な条件式を書き易く、見易いのです。


```vb
Function TDI(A, T, Optional S = "")
    Dim I: I = Right(A, 1)
    Dim J: J = Val(A)
        
    S = IFCS(DI(Range(RCC("T01N_", T)), J), I = "A" _
           , DI(Range(RCC("M01N_", T)), J), I = "a" _
           , DI(Range(RCC("T02N_", T)), J), I = "B")
    
    TDI = S
End Function

Function TMI(R, Optional S = "")
    Dim 年, 機械, 番号, W
    Call DR(R, MM(R), 年, 機械, 番号, W)
      
    S = IFCS(CC(MLOT(Range("T01N_"), R), "A"), 機械 = 1 And W = 0 _
           , CC(MLOW(Range("M01N_"), R), "a"), 機械 = 1 _
           , CC(MLOT(Range("T02N_"), R), "B"), 機械 = 2)
            
    TMI = S
End Function
```

以上
Zabbix3.XのMySQLテンプレート設定

# はじめに
Zabbix Serverで用意されているテンプレート「Template DB MySQL」(もしくは「Template App MySQL」)をDBサーバにそのまま設定しても、
ちゃんと監視をしてくれないため、必要となる設定をSimpleに記載しておきます。

# 前提
zabbix Server 3.4.9（OSはCentOS7）
Zabbix Agent ：MySQLもCentOSもバージョン関係なし！（おそらく）

# 設定
（Zabbixのポータル画面）
１． Zabbix Server に対象となるMySQLが搭載されているAgentを登録しましょ。
２． 対象となるAgentに Template DB MySQL を設定しましょ。
   ⇒ この時点で登録しても、ちゃんと監視できていないので、アラートが発生することはないです。

![zabbix02.png](https://qiita-image-store.s3.amazonaws.com/0/109620/f5caa588-6109-c850-db69-84a98d5a71de.png)



３．さていよいよここから本番です。
 MySQLのインストールされたZabbix Agent上で操作します。

（Zabbix AgentにSSHでログイン）
root ユーザになります。


４．Default では、ディレクトリが作成されていないので、作って必要な権限を与えます。

```
# mkdir /var/lib/zabbix
# vi /var/lib/zabbix/.my.cnf   (ファイル名の頭にはドットを付けます）
[client]
user=MySQLユーザ名　　　　　　　　　　　　　　　⇒ ★ user を指定してあげないとエラーになりました。（自分は）
password="MySQLユーザのパスワード"

sample)
[client]
user=root  
password="soresoregogo"

# chown -R zabbix. /var/lib/zabbix  　　　　　　 ⇒ ★ これをやらないとエラーになります。
# chmod -R 700 /var/lib/zabbix 　　　　　　　    ⇒ これは好き好きです。

```

５．最後に・・・

```
CentOS6の場合・・・
# service zabbix-agent restart

CentOS7の場合・・・
# systemctl restart zabbix-agent 

```

これで、監視ができるようになります。

#補足
５．を実行する際、ZabbixServer上で、tail をしておくことで監視が有効になったか確認できます。

```
# tail -f /var/log/zabbix/zabbix_server.log
(５．を実行するとサポートされたと言うログが表示されます）

  1293:20180527:215008.350 item "HOSTAAAAAA:mysql.status[Bytes_received]" became supported
  1294:20180527:215009.357 item "HOSTAAAAAA:mysql.status[Bytes_sent]" became supported
  1293:20180527:215010.360 item "HOSTAAAAAA:mysql.status[Com_begin]" became supported
  1294:20180527:215011.369 item "HOSTAAAAAA:mysql.status[Com_commit]" became supported
  1293:20180527:215012.370 item "HOSTAAAAAA:mysql.status[Com_delete]" became supported
  1297:20180527:215013.519 item "HOSTAAAAAA:mysql.status[Com_insert]" became supported
  1297:20180527:215014.530 item "HOSTAAAAAA:mysql.status[Com_rollback]" became supported
  1297:20180527:215015.544 item "HOSTAAAAAA:mysql.status[Com_select]" became supported
  1297:20180527:215016.557 item "HOSTAAAAAA:mysql.status[Com_update]" became supported
  1297:20180527:215017.567 item "HOSTAAAAAA:mysql.status[Questions]" became supported
  1297:20180527:215018.579 item "HOSTAAAAAA:mysql.status[Slow_queries]" became supported
  1297:20180527:215019.595 item "HOSTAAAAAA:mysql.status[Uptime]" became supported

```

以上になります。
kitematicとかGUIツールがあるならさっさと使っておけばよかった



今日は地元の草刈りを手伝ったあとで、自分のMacのメンテナンス兼Dockerの環境構築をしてました。

先に何か行っておくとGUIツールがあるのであれば使っておきべきだったという感想です。

## 仕事で使うとかリソースを節約したい以外であればKitematicを使おう

ほんとに便利ツールがあるのであれば積極的に使っておくべきだったなと思います。

ちなみにKitematicはDocker用の管理ツールでダッシュボード的に管理できます。

今回はMac版のKitematicをインストールして使いました。

## Kitematicをインストールしよう

Mac版のKitematicはdockerのアプリから選択できます。

現在公式サイトは、DockerToolboxの説明のところにいってしまうので、そこだけ注意が必要です。

![Screen Shot 2018-05-27 at 21.22.33.png](https://qiita-image-store.s3.amazonaws.com/0/89244/0a73e0ec-988e-c97a-6001-1284c9795426.png)


まずツールバーのDockerからKinematicを選択します。

<img width="714" alt="Screen Shot 2018-05-27 at 21.25.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/89244/67030714-acad-436d-6f96-66d2077dc77e.png">


選択するとこのような画面になると思うのでHereをクリック

特に何かのページに飛ぶわけでもないのでクリック後Downloadsを確認し圧縮ファイル”Kitematic-Mac.zip”が入っているかを確認してください。

![Screen Shot 2018-05-27 at 21.26.43.png](https://qiita-image-store.s3.amazonaws.com/0/89244/5c441df6-50a9-c68d-2da0-f0468802fe68.png)


解凍するとアプリのアイコンが出るのでこれをApplicationに入れれば完了です。


<img width="1061" alt="Screen Shot 2018-05-27 at 21.27.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/89244/d4a71da1-c3db-e8d6-5554-ed10f952a9f7.png">


ちなみにKitematic自体はこんな画面が表示されます。

## 使ってみた感想

いままでいちいちCLIでポチポチいじっていたのですが、超便利です。

Dockerhubにも勝手に接続される（ログインしているので）のでコンテナを立ち上げるのが非常に楽になりました。

僕はこれでローカルにGithubとJenkinsを立てて検証環境を作ってます。

せっかくメモリもCPUもいいやつを入れているのでね、このくらいはローカルで作っておかないといけないかなと言う謎の使命感

とにかく便利なのでおすすめです。
Web3 でノードがマイニングしているかどうかを確認

* `web3.eth.isMining` を使用します。
* マイニングしていれば `true` を、それ以外の場合は `false` を返します。

# サンプルコード

```js
web3.eth.isMining()
.then(console.log);
// => true
```

# 参考

* [https://scrapbox.io/web3-jp/web3.eth%23isMining](https://scrapbox.io/web3-jp/web3.eth%23isMining)

# Note
- Ethereum 関連の情報は https://scrapbox.io/sushiether/ に集約することにしました。
- この記事の内容に変更・更新がある場合は、以下の URL を更新します。
- https://scrapbox.io/sushiether/Web3_でノードがマイニングしているかどうかを確認
Xcode9.3のファイルを→Xcode9.2で"Failed to load Project"のエラー

#はじめに
たまたま別PCに入っていたXcode9.3をgitからプライベートのmacに落としてきてプロジェクトを開こうとすると
下記のポップアップが出てきて開かれなかった時の対処法

```
“Failed to load Project
```

Xcode9.3で開いて、左側のプロジェクトファイルをクリック→右側カラム内の、ファイルのアイコンをクリック
→`Project Document`の `ProjectFormat`を
`Xcode9.3-compatible`から`Xcode8.0-compatible`に変更した
<img width="1134" alt="screenshot.png" src="https://qiita-image-store.s3.amazonaws.com/0/176479/7a1f579b-cd1a-285a-6b6c-7abfc61fa2ec.png">

無事に`Xcode9.2`でも開けるようになった
ちなみにライブラリは`pod`で管理していて、開けない状態のときに`pod install`をして`xcworkspace`を作ってもうまく行かなかったので
`xcodeproject`が開けることを確認した後に`pod install`をやり直す必要がある

#参考文献
[“Failed to load Project , incompatible project version” pop up appears when i opens from code of xcode 9.3 in xcode 9.2](https://stackoverflow.com/questions/49622341/failed-to-load-project-incompatible-project-version-pop-up-appears-when-i-op)
[Docker]初心者向け よく使うコマンド一覧

基本的なコマンドをまとめました。
便利だと思ったコマンドはガンガン追加していきます。

# 基本コマンド

<pre>
・docker pull 検索
# docker search

・イメージ一覧取得
# docker images

・プル
# docker pull centos

・起動中のコンテナ確認
# docker ps

-l 最後に起動したコンテナを表示
-a 停止しているコンテナを含め表示
-q コンテナIDだけを出力

・ローカルディスクをマウントして起動
# docker run -v /Volumes/LOCAL:/mnt/cont -it centos /bin/bash
</pre>

# オプション付きコマンド

・コンテナ起動

<pre>
# docker run <repository:tag> <command>
</pre>

|オプション|説明|
|---|---|
|-t |擬似端末（pseudo-tty）|
|-i |インタラクティブ実行|
|-b |バックグラウンド
|-P |ポートフォワード（自動割り当てなので、任意のポート番号を指定したい場合は-p 0000）
|-v |ローカルディレクトリをマウント。絶対パスで<local path>:<container path>の形で指定。
|-u |ユーザを指定して実行

# 割と便利コマンド

<pre>
・コンテナ全停止
# docker stop $(docker ps -a -q) 

・コンテナ全削除
# docker rm $(docker ps -a -q) 

・イメージの全削除
# docker images -aq | xargs docker rmi

・全削除(コンテナ、イメージすべて消えます)
# docker system prune
</pre>

# 起動時系

<pre>
・タイムゾーンを指定して起動
# docker run -it -e TZ=Asia/Tokyo centos bash

・ホストネーム指定
# docker run --hostname host0001 -it centos /bin/bash

・コンテナ終了時に自動でコンテナを破棄
# docker run --rm -it centos /bin/bash
</pre>

ホスト名,IPなんかは下記のサイトが大変参考になります。
https://www.rootlinks.net/2017/04/19/dockerコンテナのホスト名とipを指定/
例外とエラーの違い

[&gt; to English Pages](https://kyowg.blogspot.jp/2018/04/exception-and-error.html)
## 1. 概要
あるプロジェクトでアプリケーションの<b>例外設計</b>について解説してた時、まず「例外とエラーの違い」についてプロジェクトメンバーに説明しなければならない事がありました。
この記事では、その時の説明の概要を投稿します。

## 2. はじめに
みなさんは、「<b>例外とエラーの違い</b>」について簡単に説明できますか？
つい先日も、あるプロジェクトで

>例外とエラーの違いは何か？

という質問を受けました。
この質問は以外に多い。
過去には、システム設計の話の中で、

>「想定内が例外」で「想定外がエラー」

と決め込むエンジニアもいました。
それに対して

>「目的が達成できれば例外」で「目的が達成できなければエラー」

と反論するエンジニアもいました。
さらに、

>「中断処理をしない例外処理は気持ち悪い」

と言い出すプログラマーもいました。
そしてついには、

>「例外という本来の言葉の意味とは...云々」

と語りはじめるエンジニアも現れました。
（私も昔は、例外の言葉の意味を考えたことのある一人です・・・）
この「エラーと例外の違いは何か？」の答えは、今どの領域について話をしているか次第です。
それをこれから例示します。

## 3. 例外とエラー
![exception_and_error.png](https://qiita-image-store.s3.amazonaws.com/0/260161/4e22da6a-fce7-2498-9451-96d931e90dac.png)
まず、我々エンジニアが最低限知っておかなければならないのは「例外とエラーの違いが普遍的に成立する概念は存在しない」ということです。
これを理解してないエンジニアさんは割と多い気がします。
したがって、冒頭のような誤解が生じるのだと思います。
要するに「普遍的な概念として両者を明確に定義することは不可能」ということです。
なぜなら、歴史的な背景もあり「例外とエラー」の定義は扱う領域によって異なるからです。
逆に、普遍的でなければ、その領域固有の定義は存在することもあります。
例えば Java は、他の言語に比べかなり明確になっていますが、C++ との差分は大きいです。
もし、特定の領域の「例外とエラー」の仕様に限定して議論してるなら、その領域の仕様に沿えばいいだけです。
もし、定義されてなければ？
定義されてないということは、「定義しない」ということを決めてるか、解釈の余地が残されているということかもしれません。

また、前述の「中断しない例外処理に対する賛否」についてですが、Ruby では、例外機構の中に retry という機構があります。
これは、例外処理中の再試行または復帰を意味します。
例えば、Python では、retry パッケージが配布されています。
Java や C++ では、retry 機構は公式サポートされていません。
でも、私は retry 機構を自前で実装している Java プロジェクトを知っています。
PHP でも goto 機構の制約に従えば、例外処理の再試行または復帰は可能です。
また、Java では、検査例外機構まで備わっています。
このように、ある特定言語の「例外とエラー」の仕様が、他のフィールドへ当てはまるとは限らないということです。

では、より広範囲なシステム設計の領域ではどう考えるべきか？
必要に応じて定義すれば良いのです。
冒頭のアプリケーションの例外設計の話も同じです。

## 4. まとめ
例外とエラーの違いは、普遍的に成立する概念は存在しません。
例外とエラーの定義は、それぞれのフィールドの定義に過ぎません。
定義があればそれに沿えばいい、なければ必要に応じて定義すればいい。
自分が新宿外側で家を探してみたいので機械学習以前に可視化してみる - どのサイトがいいのか探す

このあたりに触発されて

> http://www.analyze-world.com/entry/2017/10/09/062445

どのサイトが件数が多いのか解らないので、一旦以下の条件で絞り込んで件数比較してみた

* 荻窪駅徒歩10分以内
* 間取り指定無し（家賃で絞るため）
* 月額家賃[10万円,20万円]、共益費など含む
* マンション・アパート・一戸建てなどこだわらない、店舗・事務所は除けるなら除く

| Site Name        |    #Room | #Building|
|:-----------------|---------:|---------:|
| [SUUMO](https://suumo.jp/jj/chintai/ichiran/FR301FC001/?ar=030&bs=040&pc=30&smk=&po1=25&po2=99&shkr1=03&shkr2=03&shkr3=03&shkr4=03&rn=0015&ek=001506640&ra=013&cb=10.0&ct=20.0&ts=1&ts=2&ts=3&et=10&mb=0&mt=9999999&cn=9999999&fw2=)  |1,082        | 210|
| Homes（リンク作れず) |1,307|220|
| [いいへやねっと](http://www.eheya.net/search/line/search_new.jsp?search_flg=true&mode=line&area_type=city&sc_area_id=kanto&sc_prefecture_id=A130&region_id=&region_code=&sc_city_id=&line_id=CsdTEuCs&station_id=CsdTEuCsCsEuAq&price_from=100000&price_to=200000&price_and_cost=1&use_part_area_from=&use_part_area_to=&walk_from_station_x=&completion_date=&pageNum=1&sortType=priceCheap&sortDirect=&numPerPage=20&val_code=22573)|393|393?|
| [minimini](http://minimini.jp/list/line/tokyo/tokyochikatetsumarunouchisen/ogikubo/?lnkdiv=8&btn=3&route=0_2342_240&sc1=10.0&sc2=20&sc3=1&sc4=00000000000000&sc5=0&sc6=0&sc7=&sc8=&sc9=&sc10=000000000000000000000000000000000000000000000000000000000000&sc11=000000000000000&sc12=000000000000000&sc13=2&sc14=0&sc15=0&sc16=11111100) | 9 | 9?|
| [キャッシュバック賃貸](https://cbchintai.com/property/search/?utf8=%E2%9C%93&property_search_detail_type_id=2&gaq_cat=property_refine&p%5Brailroad_or_location%5D=false&p%5Bper_page%5D=&p%5Bfavorite%5D=&p%5Bbrowsed%5D=&p%5Bsorts%5D%5Bwith_photo%5D=desc&p%5Bsorts%5D%5Bscore%5D=&selected_pref_ids%5B%5D=13&p%5Brent_begin%5D=100000&p%5Brent_end%5D=200000&p%5Bwith_maintenance_fee%5D=0&p%5Bwith_maintenance_fee%5D=1&p%5Bno_deposit%5D=0&p%5Bno_key_money%5D=0&p%5Bfloor_area_begin%5D=&p%5Bfloor_area_end%5D=&p%5Bwalking_time%5D=&p%5Beffective_age%5D=&p%5Bquery%5D=%E8%8D%BB%E7%AA%AA%E9%A7%85&p%5Bline_ids%5D%5B%5D=28002&p%5Bstation_ids%5D%5B%5D=1131217)|42|42?|

こう見るとスクレイピングのしやすさでは SUUMO が圧倒的。。。
Youtube-Watch-History-Scraperを使って、YouTubeの全閲覧履歴（2年分）を出力してみた。

iTunesとかに再生回数っていう機能ありますよね？
僕は音楽をよく聞くので、この項目を見て「この曲100回くらい聞いてるのか〜」とか考えるのが好きなんです。
でも最近はapple musicとかよりよっぽどyoutubeで音楽を聞く回数が多いので、見た回数（≒再生回数）でランキングを作成したいなと。
ということで、とりあえず下記の記事を参考にして、youtubeの全閲覧履歴を出力してみました。

## 参考資料
https://blog.shumbo.org/youtube-watch-history-scraper%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6youtube%E3%81%AE%E5%B1%A5%E6%AD%B4%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%99%E3%82%8B-d1f48a4fd143

## 環境
- mac OS （High Sierra）
- google chrome
- pyenv 1.2.4
- python　3.6.5

## 手順

### Youtube-Watch-History-Scraperのダウンロード
下記リポジトリをクローンする。（もしくはzipファイルでダウンロードし、解凍する。）
https://github.com/zvodd/Youtube-Watch-History-Scraper

### EditThisCookieをダウンロード
下記サイト（chrome store）から拡張機能をダウンロードする。
https://chrome.google.com/webstore/detail/editthiscookie/fngmhnnpilhplaeedifhccceomclgfbg

### YouTubeのCookieを保存する。
[YouTubeのトップページ](https://www.youtube.com/)に行き、拡張機能のアイコンをクリック。
<img width="2564" alt="Monosnap 2018-05-27 20-49-38.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/259142/e7afd162-1e27-cebd-b396-1b19cc344bc8.jpeg">

エクスポートボタンをクリックし、クリップボードにCookieを保存する。
<img width="2560" alt="Monosnap 2018-05-27 20-47-38.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/259142/aa30e5c1-29c5-fbdb-f31f-f668c74050ef.jpeg">

テキストエディタを開いてペーストし、`youtube_cookies.json`という名前で、`./Youtube-Watch-History-Scraper`のディレクトリ直下に保存しておく。

<img width="504" alt="Youtube-Watch-History-Scraper-master 2018-05-27 20-54-53.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/259142/90dcf370-96cc-a7b4-29db-0682473532c0.jpeg">

これで下準備はおk。


### pipで必要なファイルをインストール（以下ターミナルの操作）

- scrapy（スクレイピング用のpythonフレームワーク）
- lxml（HTMLを扱うためのライブラリ）
- sqlalchemy（pythonでsqlを扱うためのライブラリ）

ディレクトリ直下に移動した後、上記３つをpip経由でインストール。

```terminal
$ cd ./Youtube-Watch-History-Scraper-master
$ pip install scrapy lxml sqlalchemy
```



### いざ実行

```terminal
$ scrapy crawl yth_spider
```

実行するとすごい勢いで閲覧履歴がログ出力されていくので、

**「うわ、1年前こんな動画見てたなあ...」**

など、情緒にふけりながらボーッと見ておく。

### 処理終了

```terminal
$ 2018-05-27 14:54:21 [scrapy.core.engine] INFO: Spider closed (finished)
```

5分くらい放置していたら処理が終わる。

### 出力結果
<img width="511" alt="Youtube-Watch-History-Scraper-master 2018-05-27 21-03-45.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/259142/c5134711-21ef-f576-d161-15bbe5d30d8b.jpeg">

ディレクトリを見てみると`youtube_history.db`というファイルが生成されており、そこに保存されています。
カラムは以下の通り。

|id|vid|author_id|title|description|time|
|:----------:|:----------:|:----------:|:----------:|:----------:|:----------:|

これをsqlite等で解析します。

ここで眠くなったため、ひとまずこの記事はこれにて...
Node.js内でNode.jsを実行する

# はじめに

メッセージアプリ内からNode.jsを実行できたら面白そうだなと思ったものの、ただ送られてきたソースコードを`eval()`するだけだとありきたりなので、REPL(対話的実行環境)をNode.js内から実行しようとしたときにハマったので、そのメモです。

# TL;DR

- child_process.spawnを使う
- 引数に `-i` をつける
- ~~わざわざこんなことする必要ない~~



# Node.jsを実行する

Node.js内から何かを実行するときは`child_process`というAPIを使うのでサンプルを見ながら以下のように書いたが反応してくれません

```js:動かない
const child_process = require('child_process')

const node = child_process.spawn('node')
node.stdout.setEncoding('utf8')

node.stdout.on('data', data => console.log(data))
node.stderr.on('data', data => console.log(data))

node.stdin.write('1 + 1\n')
```

何故動かないのか調べていると、Stack Overflowで[興味深い質問](https://stackoverflow.com/questions/27458502/how-to-run-interactive-shell-command-inside-node-js)を見つけました

この質問はnodeではなくpythonを対話的モードで実行する方法について聞いていますが、

stdinがターミナルでないと対話的モードで実行されないということなので、

もしかしたらnodeでも同じようなことが起きてるのでドキュメントを見てみたら[同じような引数](https://nodejs.org/docs/latest/api/cli.html#cli_i_interactive)があったので試しに追加してみたら無事に動作しました

# ソースコード

完成したソースとログも載せておく

```js:node.js
const child_process = require('child_process')

const node = child_process.spawn('node', ['-i'])
node.stdout.setEncoding('utf8')

node.stdout.on('data', data => console.log(data))
node.stderr.on('data', data => console.log(data))

node.stdin.write('1 + 1\n')

node.stdin.write('.exit\n')
```

```bash
$ node node.js
>

2

>
```

# 最後に

~~よく考えたらわざわざREPLを実行するほどでもないような...~~
KaoriYa - Vimの[:Tutorial]を再現してみる

Vimをメインエディタにし続けるために一念発起してキーボードをUSに買い替えました。[HHKBlite2](https://www.pfu.fujitsu.com/hhkeyboard/lite2/)から、ノートパソコンでずっとお世話になっていた[赤鼻のニクい奴](https://www3.lenovo.com/jp/ja/landingpage/accessories/thinkaccessories/thinkpad/02/04/)に変わりました。「もういいアイソレーションも出てるから大丈夫」と信じてたんですけど、やっぱりアイソレーション向いてません…

さておき、人生初のUSキーボードなので記号打ちに慣れてないし、ことvimにおいて記号に慣れるのは必須課題でもあるわけで、」じゃあvimtutorやっておくかー」ということでラクに起動できるようにKaoriYa版vimでコマンド化されていた`:Tutorial`を~~パク~~作ってみました。

## もうバッチでは`so /tutor/tutor.vim`あるんじゃねーの？

はい、基本それコピーして関数化すれば終わりっす。

```vim:vimtutor.vim
function! s:vimtutor(...) abort
	let s:ext = ""
	if a:0 > 0
	  let s:ext = "." . a:1
	else
	  let s:lang = ""
        :
        :
```

## おれは しょうきに もどった！

そもそもvimスクリプトなんだから関数化せんでも`source`で読み込んだらバッチ処理しませんか？

```vim:vimtutor.vim
function! s:vimtutor(...) abort
	let $TUTORCOPY = $VIMFILES.'/.tutor'
	if a:0 > 0
		let $xx = a:1
	endif
	new
	source $VIMRUNTIME/tutor/tutor.vim
	new $TUTORCOPY
endfunction

command! -nargs=? -bang Tutorial call s:vimtutor(<f-args>)
```

ちゃんとソース読むまで何やってるか分からなかったんですけど、tutor.vimってファイル作ってからもう一回`edit`で読み直してるんスね。で、そのときに保存するディレクトリを最初の方でガチャガチャやってるんですけど、なんかもうめんどくさくなってきたんで保存場所を$VIMFILESに固定しました。

### で、はじめてのUSキーボードはどうなのかというと…

`:`押せないです。（半ギレ）
【UiPath】似て非なるMonitor eventsとPick(Pick Branch)の違いを解説

UiPath Academyの最後の方にちょっとだけ登場したMonitor eventsとPick(Pick Branch)。
どちらも「いくつかの条件のうち、１つでもクリアしたら用意しておいたアクションを発動する」
という、イベントトリガー系のアクティビティだと思い込んでいて区別もあいまいだったのですが、
実際に使ってみると両者全く別物だとわかったので、ここで違いを整理しておきます。

#Monitor eventsとPickの比較

||Monitor Events|Pick(Pick Branch)|
|:---|:---|:---|
|条件部に設定できる<br>アクティビティの種類|Trigger系アクティビティ。<br>つまりマウスクリックやキー押下などの**人間の動作**がアクションのトリガーになる。|Trigger系 **じゃない方の** アクティビティ。<br>つまり人間の動作はトリガーにならない。|
|アクション発動の条件|複数のTriggerのうち、**１つでもクリアしたら**発動。ただし発動するアクションは**どのTriggerでも共通**|複数のPick Branchの条件部を一斉に実行し、**一番最初に終了したPick Branchのアクションを発動。**|
|アクション発動後の振る舞い|条件の監視に戻る＝エンドレスに繰り返し<br>※オプションで、１回の発動で終了するように変更可能|１回アクション発動したら終了|
|アクティビティの出自（小ネタ）|UiPath独自|Windows Workflow Foundationの[コンポーネント](https://docs.microsoft.com/ja-jp/dotnet/framework/windows-workflow-foundation/pick-activity)|
Pickはイベントトリガーではなく、「ビーチフラッグクイズ」みたいなイメージですね。
それぞれの回答者(Pick Branch)が一斉にフラッグに向かって走り出して、
一番にフラッグを取った人がクイズの回答権を得る、みたいな。
この後は、それぞれの実例を踏まえながら具体的な解説をしていきます。

# Monitor Eventsの解説
こんなイメージです。
![Monitor.png](https://qiita-image-store.s3.amazonaws.com/0/255097/f2147762-b6e5-5222-ba41-6b13058662d6.png)

実例として、10年以上前に「外人４コマ」としてネタに使われた画像で遊んでみます。
![gaijin.jpg](https://qiita-image-store.s3.amazonaws.com/0/255097/6f4f1508-1244-f5ed-e7f5-c7d19ea355a6.jpeg)

手前のピア・シュナイダー氏のどちらかの顔をクリック(Click Image Trigger)すると
メッセージ表示するワークフローを作ります。
![monitor.png](https://qiita-image-store.s3.amazonaws.com/0/255097/6b2fefb5-9707-64fb-52f4-85b7ffeae8bc.png)
実行して顔をクリック。はい出た。
![pia1.png](https://qiita-image-store.s3.amazonaws.com/0/255097/461756d7-3f6d-670b-7130-fd3532f54b8e.png)
オプションのRepeatForeverはデフォルトTrueなので、ワークフローは常に動き続け、
顔をクリックする度に何度でもメッセージ表示されます。
発動するアクションは共通なので、クリックした顔によってメッセージを変える事はできません。

# Pick (Pick Branch)の解説
こんなイメージです。
![Pick1.png](https://qiita-image-store.s3.amazonaws.com/0/255097/4bdefbbe-9d05-a2a7-a584-424a8751a0d3.png)

![Pick2.png](https://qiita-image-store.s3.amazonaws.com/0/255097/456e3f7b-acca-6353-1537-1c71ab4f88f5.png)

ここでも外人４コマで遊んでみます。
２つのPick Branchを使ってE3 2003と2004のシュナイダー氏それぞれの顔をImage Existsで検出させて、
先に検出した方のメッセージを表示させます。
Monitor Eventsのように「ユーザーがXXしたら」という条件は使えません。
トリガーを引くのはユーザーじゃないのです。
![pick.png](https://qiita-image-store.s3.amazonaws.com/0/255097/384e6fd5-2af7-ce07-1a38-9c03facf4d40.png)
実行結果。まあ面白くない。
![Pia2.png](https://qiita-image-store.s3.amazonaws.com/0/255097/c5f4758c-8f04-139f-febd-f56228fbbbe9.png)
### Pickの大事なポイント３点
1. 今回は顔の検出にImage Existsを使いましたが、とにかく早く検出して条件部を終了させればいいので、検出のアクティビティはImage ExistsでもFind Imageでもどっちでも良いです。
2. Pick Branchの条件部がSequenceになっています。という事は条件部に複数のアクティビティを設定できるということです。左のPick BranchはA→B→Cで発動、一方で右のPick BranchはDだけで発動、という全く異なる設定が可能です。
3. Pickは１回のアクション発動で終了してしまうので、
常駐プロセスとして繰り返し実行させたい場合は↓のようにループさせる必要があります。
![flowchart.png](https://qiita-image-store.s3.amazonaws.com/0/255097/4f187910-71ff-339f-46dd-54a3dc9d9f4e.png)

---
今回はここまで。
Pickの方は別の機会にもっと掘り下げて、面白い使い方を見つけたいと思います。
form_forでdate_selectをhiddenにしたい場合

フォームで、date_selectのinputをhiddenにしたいシチュエーションがある。
（例えば、登録(new)->確認(confirm)->(create)->完了(complete)となる画面の確認画面など）

このときに、hidden_filedにしてしまうと、

```confirm.html.erb
<%= form_for(@user, url: { action: 'create' }) do |form| %>
  <%# 省略 %>
  <div>
    <%= t '.birth_date' %>: <%= @user.birth_date %>
    <%= form.hidden_field :birth_date, id: :user_date, discard_year: true, discard_month: true, discard_day: true %>
  </div>
  <%# 省略 %>
<% end %>
```

`create` アクションに `birth_date"=>"{1=>2018, 2=>5, 3=>24}`のような形式で値が渡ってしまい、
モデル.newにparamsを渡したときに、勝手にDateにしてくれない。

なんでDateにして欲しいかというと、
hiddenじゃないときは、`"birth_date(1i)"=>"2018", "birth_date(2i)"=>"5", "birth_date(3i)"=>"24"`　の形式でパラメータが渡って、モデル.newにparamsを渡したときに、Dateになっているためそのままsaveできるが、
`birth_date"=>"{1=>2018, 2=>5, 3=>24}`の形式で渡ってきてしまうと、自分でDate型に整形して値をセットする必要が出てきてしまうから。

そういうときは、`discard_year: true, discard_month: true, discard_day: true`のoptionをつければよかった。


```confirm.html.erb
<%= form_for(@user, url: { action: 'create' }) do |form| %>
  <%# 省略 %>
  <div>
    <%= t '.birth_date' %>: <%= @user.birth_date %>
    <%= form.date_select :birth_date, id: :user_date, discard_year: true, discard_month: true, discard_day: true %>
  </div>
  <%# 省略 %>
<% end %>
```

参考:
https://apidock.com/rails/ActionView/Helpers/DateHelper/date_select
bashでCSVを読み込み1行ずつループ処理する

# 構文

```bash
while read ブロック変数; do
  処理
done < 読み込むファイル
```

# 使用例

以下の様なCSVがあったとする

```sample.csv
name,number,email
name1,0001,example1.com
name2,0002,example2.com
name3,0003,example3.com
```

このCSVを1行ずつループ処理する。
ここでは順番にname列とnumber列を標準出力させる。

```bash:sample.sh
#!/bin/bash

while read row; do
  column1=`echo ${row} | cut -d , -f 1`
  column2=`echo ${row} | cut -d , -f 2`

  echo "${column1}の番号は${column2}です。"
done < sample.csv
```

```bash
$ ./sample.sh

=> nameの番号はnumberです。
=> name1の番号は0001です。
=> name2の番号は0002です。
=> name3の番号は0003です。
```
bashでcsvカラムに条件を指定し行数をカウント

以下のCSVがあった場合

```sample.csv
id,name,status,email
1,name1,1,example1.com
2,name2,2,example2.com
3,name3,1,example3.com
4,name3,,example4.com
```

## status列の値が1の行数をカウント

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

CSV_FILE=$1

REGISTRATION_COUNT=`cat $CSV_FILE | awk -F , '$3 == 1' | wc -l`
echo $REGISTRATION_COUNT
```

### 実行
```
$ ./count.sh
=> 2
```

## status列の値が存在する行をカウント

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

CSV_FILE=$1

REGISTRATION_COUNT=`cat $CSV_FILE | awk -F , '$3 != NULL' | wc -l`
echo $REGISTRATION_COUNT
```

### 実行
```
$ ./count.sh
=> 3
```
Django備忘録~settings.py~

環境：Django2, Python3.6

###プロジェクト共通のstatic/templatesディレクトリ
#### templates
デフォルトでテンプレートの設定はあるはずなので、それのDIRSに追加
私はプロジェクト共通のbase.htmlとかを置いてます。
APP_DIRSがTrueの場合は各アプリの直下にあるtemplatesディレクトリも探しに行ってくれます。

~~~settings.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')], #ここに認識させたいディレクトリを書く
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
~~~
#### static
デフォルトだと記述されてないので追記する
Bootstrapをプロジェクト全体で使うときとか共通のcss/jsはここに置いてます。

~~~settings.py
STATICFILES_DIRS = (
    [os.path.join(BASE_DIR, 'static')]
)
~~~
sbt newでTransportExceptionが出る時

# sbt newでTransportExceptionが出る時

```
$ sbt new playframework/play-scala-seed.g8 --branch 2.5.x

=> [error] org.eclipse.jgit.api.errors.TransportException: git@github.com:playframework/play-scala-seed.g8.git: unknown host
   [error] Use 'last' for the full log.
```

gitへの接続でsshを使おうとして失敗してる

## 対応

httpsで接続する様に`https://github.com/`を加える

```
$ sbt new https://github.com/playframework/play-scala-seed.g8 --branch 2.5.x
```
Gitまとめ

#ブランチを作る

```
ブランチの作成

$ git branch ブランチ名
```

```
ブランチを作成してチェックアウト

$ git chechout -b ブランチ名
```

```
ブランチの削除
$ git branch --delete ブランチ名
```

#HEADとは
今いるブランチの最新コミットを指す。
.gitディレクトリにあるHEADファイルに書かれていた。

# git show

```
指定したハッシュ値のコミットを表示
$ git show ハッシュ値
```

```
今いるブランチの最新コミットを表示
$ git show HEAD
最新コミットの1つ前のコミット
$ git show HEAD^
2つ前のコミット
$ git show HEAD^^

```

# マージ

```
$ git merge ブランチ名
```

# コマンドを忘れた時

```
$ git help
```

```
add コマンドの詳細を確認
$ git help add
```

# リモートリポジトリ

```
リモートリポジトリを確認
$ git remote -v
```
Laravel5.5で未認証時にリダイレクトさせる処理

## 環境
- Laravel5.5
- multi auth

## やりたいこと
Multi auth を使っている前提で、未認証時にユーザ・管理者それぞれのログインページにリダイレクトさせたい。

## 5.4 までは app/Exceptions/Handler.php に直書きされていた

5.4 では、app/Exceptions/Handler.php に unauthenticated メソッドがありました。

```php
namespace App\Exceptions;

use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    .
    .
    .
    /**
     * Convert an authentication exception into an unauthenticated response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Illuminate\Auth\AuthenticationException  $exception
     * @return \Illuminate\Http\Response
     */
    protected function unauthenticated($request, AuthenticationException $exception)
    {
        if ($request->expectsJson()) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }

        return redirect()->guest(route('login'));
    }
}

```

これが、5.5 では初期状態では書かれていません。
vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php
こちらにあるようです。
どっちにしても、 app/Exceptions/Handler.php 内で unauthenticated をオーバーライドします。

```php
namespace App\Exceptions;

use Exception;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;

class Handler extends ExceptionHandler
{
    .
    .
    .
    /**
     * 認証していない場合にガードを見てそれぞれのログインページへ飛ばず
     *
     * @param \Illuminate\Http\Request $request
     * @param AuthenticationException $exception
     * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response
     */
    public function unauthenticated($request, AuthenticationException $exception)
    {
        if($request->expectsJson()){
            return response()->json(['message' => $exception->getMessage()], 401);
        }

        if (in_array('admin', $exception->guards())) {
            return redirect()->guest(route('admin.login'));
        }

        return redirect()->guest(route('user.login'));
    }
}
```

## 参考
▼Laravel 5.5 change unauthenticated login redirect url
https://stackoverflow.com/questions/45340855/laravel-5-5-change-unauthenticated-login-redirect-url
▼[Laravel] 5.3でMulti-Authを使う
http://www.84kure.com/blog/2016/06/06/laravel-5-3%E3%81%A7multi-auth%E3%82%92%E4%BD%BF%E3%81%86/
Go, ruby, pythonのカウンタプログラム

#Go, ruby, pythonのカウンタプログラム

##環境
ruby 2.4.1
Python 3.4.6
go version go1.9.4 
openSUSE Leap 42.3

##概要
土日に突発的に何か新しい事をやりたいと思ったので[A Tour of Go](https://go-tour-jp.appspot.com/list)でGo言語やってました。
そこでカウンタをとるプログラムの書き方が出てきて、他の言語では、どうやってたっけ？と思ったので備忘録としてここに残しておきます。

## カウンタプログラムの実装
### Goのカウンタ
[A Tour of Go](https://go-tour-jp.appspot.com/list)において、Go言語のカウンタは、クロージャを使っていました。それを真似て作成したのが以下のプログラムです。
pythonみたいにnonlocalとかは、書かないようです。

```go:test.go
package main

import(
	"fmt"
)

func counter() func() int{
	count := 0
	return func() int{
		count ++
		return count
	}
}

func main(){
	count := counter()
	fmt.Println(count())       => 1
	fmt.Println(count())       => 2
	fmt.Println(count())       => 3
}
```

### pythonのカウンタ
続いてPythonのカウンタ。こちらもクロージャを使用。

```python:test.py
def counter():
    count = 0
    def inc():
        nonlocal count 
        count += 1
        return count
    return inc

test = counter()
print(test())       => 1
print(test())       => 2
print(test())       => 3
```

### rubyのカウンタ
rubyでは、メタプログラミングで活躍するフラットスコープを使ってlambdaを使用。

```ruby:test.rb
count = 0
test = lambda{count += 1}
puts test.call       => 1
puts test.call       => 2
puts test.call       => 3
```

同じ処理をいろんなプログラムで書くと結構楽しい。
PandocMarkdownのdivとspan

最近のPandocはMarkdownでdivとspanを表現できて最強に思えます。
なので、紹介します。
日本語訳はこれ↓なんですが、ここに記載がなかったので。
http://sky-y.github.io/site-pandoc-jp/users-guide/

# span
spanタグを使いたいですね。
こうすればいいだけです。

```markdown
[hoge]{#foo .bar name=fuga}
```
{}の中にattributeを書き込みます。
これはこんな感じになります。

```html
<span id="foo" class="bar" name=fuga>hoge</span>
```
attributeの{}の中の書き方ですが、
idは#、classは.から書き始めます。
また、それ以外の属性は○○=○○という、HTMLと同じ書き方でいいです。
この辺はMarkdownExtraみたいな方言書き慣れている人はおなじみでしょうね。

## div
Markdownでdivタグを使いたいときは「:::」を使います。
「:::」は三つ以上ならいくつでも良いです。そして{}の中にattributeを書き込みます。
attributeがある場合はdivタグの始まり、
attributeがない場合はdivタグの終わりを意味します。

```markdown
:::{#hoge .fuga}
piyo
:::
```

これはこうなります。

```html
<div id="hoge" class="fuga">
piyo
</div>
```

## divの入れ子
入れ子の場合はこうします

```markdown
:::{#foo .bar}

:::{#hoge .fuga}

:::

:::
```

一見ちょっと難しそうにも見えます？(´・ω・｀)
これはこうなります

```html
<div id="foo" class="bar">
<div id="hoge" class="fuga">

</div>
</div>
```

# これ大丈夫なん？
所詮は方言です(´・ω・｀)
でも、僕はHTML辛いので使うことにしました。
Amazon Echoがホットワード検出時以外に通信しているかをWireSharkで覗いてみた


[例の事件](https://jp.techcrunch.com/2018/05/25/2018-05-24-family-claims-their-echo-sent-a-private-conversation-to-a-random-contact/)があったので、前から気になっていたEcho Dotの通信状況をWireSharkで調べてみました。



# WireSharkをインストール

「[Mac OS XでWiresharkを使う＆Wiresharkフィルタサンプル](https://qiita.com/isaoshimizu/items/da3e74d5a8e9b1d6b6a4)」を参考にさせていただいてインストール。

```

$ brew cask install wireshark
$ which wireshark
/usr/local/bin/wireshark
```

Finderで/usr/local/bin/を開き、wiresharkのexeをダブルクリックして起動。

### 自宅のWIFiのパケットをキャプチャ

![w1.png](https://qiita-image-store.s3.amazonaws.com/0/173392/a6669d79-bae5-e2c1-0219-39d972544355.png)

メニュー画面が開いたら、Wifiだけを選ぶ。
左上のサメの背びれをクリックすると、ネットワーク上に流れているパケットが見れる。

![w3.png](https://qiita-image-store.s3.amazonaws.com/0/173392/2ab4808e-d726-79a6-e112-54634c91b9d0.png)


### ログを採取しながらAlexaと会話し、終わってから1分放置する

- 30秒ごろ、 Alexaに天気を聞く
- 55秒ごろ 会話終了
- 120秒後、赤いボタンを押して停止



### Echo DotのMACアドレスを調べる

スマホのAmazon Alexaアプリ＞左上ハンバーガー＞Alexaデバイス＞EchoDotを選択＞一番下の「その他」＞MACアドレス

で確認できる。


### ログをcsvに出力する

ファイル＞パケット解析をエキスポート＞CSVとして
を実行

![w2.png](https://qiita-image-store.s3.amazonaws.com/0/173392/80ad496b-c0fb-3007-7845-43ed044ad1e1.png)

パケットの中身はWireSharkのほうで見た方が便利なので、まだ開いとく。

### ダウンロードしたcsvをGoogle スプレッドシートで開く
列は左から、
No.=ログ採取開始してからの行数、
Time=ログ採取開始してからの秒数、
Source=発信元
Distination=通信先
Length=バイト長
だと思われるので（みたまんま）、
Sourceをフィルタリングする。
さっきしらべたMACアドレスがついた「AmazonTe〜」というのがおそらくEcho Dotなので、これを指定する。

![w6.png](https://qiita-image-store.s3.amazonaws.com/0/173392/d8ee0bf5-1be1-2ee4-ee9e-79433c414c57.png)

そんで、適当にグラフを作ってみる。

### Alexa 1回目

- 30秒ごろ、 Alexaに天気を聞く
- 55秒ごろ 会話終了
- 120秒後、赤いボタンを押して停止

![w7.png](https://qiita-image-store.s3.amazonaws.com/0/173392/b077ee15-24b1-7918-2776-0121e0ebcf69.png)



なんかは通信してるけれども、明らかに通信量は少ない。
パケットの中まではちょっと見てないですが、盗聴というほどではなさそう。

### Alexa 2回目


10秒ごろ、独り言
39秒〜１分ごろ、会話
1分20秒ごろ、独り言いう


![スクリーンショット 2018-05-27 18.51.09.png](https://qiita-image-store.s3.amazonaws.com/0/173392/83dfb35b-b734-caee-3f52-4a6919cb81a2.png)

グラフにするまでもなく、1行しかヒットしてない。
会話の内容は、今の時間をおしえてというもの。
この後の独り言には全く反応してない。

これは「盗聴疑惑」についての安心材料になるかと。。




### Google Home

Google Homeについてもログを採取してみたが、
結論からいうと、なにか複雑なことをしてるようで、よくわからず。

- ホットワード検出時以外でも通信している
- Alexaより通信回数は多い（5秒に1回くらい、まんべんなく）
- ただし1回の通信あたりのパケットは短いので、私がマシンガンのようにしゃべった独り言を転送できるかというと、難しいのでは。



### 感想

Alexaは会話を全部送ったりはしてませんでした。

Google Homeについては[こういう記事](https://t.co/goNcJ5MWEs)もすでにでてるので、参考にしてみると良いかもと思います。

引用：

>上のグラフからわかるように、ホットワードとコマンドが送信された時代に送信されるデータの急激な増加があります。 期待どおりにGoogleホームが実行されました。 デバイスが起動されると、データ転送が行われました。それ以外の場合、ネットワークはコマンド間で比較的静かでした。 また、デバイスのマイクがミュートされているときに、ホットワードのトリガーや話しがネットワークトラフィックの増加を招かないことも証明しました。

うーん、大丈夫っぽいですね。。

とはいえもし高度な圧縮技術が存在するなら、認識はひっくり返ります。
あとこちらの記事は1年前ですので、その後どうなったのかはやっぱし調べないと。
背筋が寒くなったところで、今日は以上です。

おっと誰かきたようだ(ry
Angular Universal 入門1

Angular Universal。 Angularでサーバサイドレンダリングするためのライブラリ。

この記事では、Angular Universal を始める方へのイントロを書いておきます。

また、AngularUniversalを始める方用に最初のセットアップを済ませたコードを用意しました。

# はじめに。
まず、本家のサイトを見てみます。

https://github.com/angular/universal

本家Githubを見てもイミフでしかない。わからせる気がない。

https://universal.angular.io/

上記も本家にもかかわらず、 未だに `Angular2` とか書いてあって ( ﾟдﾟ)ﾎﾟｶｰﾝ

ということで、一番良いのは、Angularの [ServerSideRendering](https://angular.io/guide/universal) のページです。

ここに従ってやっていくのが一番良いです。
僕のように本家をいくつか回って混乱する被害者が出ないように祈ります。

# サンプルコード
上記のチュートリアルを済ませたコードをレポジトリにしました。
とりあえず動かしたい、という方は下記プロジェクトをクローンしてください。

https://github.com/seteen/angular-universal-sample
[Rails5.2] rspecの導入

railsの開発にrspecを導入しました。
導入手順を残しておこうと思います。

## 環境
|||
|:-:|:-:|
| Rails | 5.2.0 |
| ruby  | 2.5.1 |
| mysql | 5.7.20 |


## インストール
Gemfileを編集して「bundle install」
そして「bin/rails g rspec:install」
にて初期設定ファイル等を作成します。

```ruby:Gemfile
group :development, :test do
  (略)
  gem 'rspec-rails'
end
```

```
$ bundle install
$ bin/rails g rspec:install
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
```

## bin/rspecで実行できるように & 確認
しかしエラーが...。

```
$ bundle binstubs rspec-core
$ bin/rspec
Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.
```

## エラーメッセージの通りにコマンドを実行 & 確認
エラーメッセージにある通り「bundle binstubs bundler --force」
にて再度「bin/rspec」を実行したところ実行ができました。

```
$ bundle binstubs bundler --force
$ bin/rspec
No examples found.

Finished in 0.00038 seconds (files took 0.15095 seconds to load)
0 examples, 0 failures
```

## rails genarate コマンドを使った際にspecファイルも作成するように

```ruby:application.rb
config.generators do |g|
  g.test_framework :rspec,
  fixtures: false,
  view_specs: false,
  helper_specs: false,
  routing_specs: false,
  request_specs: false
end
```


## RSpecの出力を見やすくする
.rspecに以下を追加してください

```ruby:.rspec
+ --format documentation
```

## 参考
[Rails RSpecの基本 ~導入編~](https://qiita.com/shizuma/items/8221544601aa3d0770d2)
[Rails5へのRspec導入から実行確認まで](https://qiita.com/ryouzi/items/de7336e6175530723b30)
PhpStormのファイル名タブを縦並びにする

# こんなときに

ファイルを多めに開いた際に、エディタ上部で横並び表示していると見難い場合に効果的です。

![yoko.png](https://qiita-image-store.s3.amazonaws.com/0/165884/38529454-c768-f756-1eda-40f48b2fe5d6.png)

# やり方

- ファイル名のタブを右クリックしてメニューを表示
- "Tabs Placement" → "Left" を選択

![tate.png](https://qiita-image-store.s3.amazonaws.com/0/165884/33d4b513-de99-ca06-30c9-c108662fff92.png)

# 雑記

PyCharmとかAndroid Studio等のJetBrains系のIDEなら同じ操作で縦並び表示が出来ます。
pip3でJupyterが導入できなかった時の解決策

### 実行環境

- MacBook Pro
- macOS Sierra ver: 10.12.6
- homebrew導入済み
- Python3をインストーラで導入済み


### ※ terminalを誤って閉じてしまったのでメモだけ

pip3でJupyterを導入しようとしたところ、下のようなエラーが。

```
Could not find a version that satisfies the requirement ... (from versions: ) No matching distribution found for ...
```

どうも、「pip3が今のversionではJupyter見つからないけど？」というようなエラーのようでした。（正確な解釈はできていないと思いますが、ご容赦ください）

pip3やPython3をhomebrewで更新したものの、なぜかversionが変わらない…。Python3をインストーラから導入したことで、homebrewで導入したPython3が反映されていなかったようです。

そこで、https://blog.fkoji.com/2012/10022035.html の記事を参考にインストーラから導入したPython3を削除しました。以下、手順です。

1. アプリケーションフォルダから、Python3を削除
2. ```sudo rm -rf /Library/Frameworks/Python.framework```を実行
3. ```sudo rm -rf /usr/local/bin | grep Python```を実行
4. ```emacs ~/.bash_profile```で、.bash_profileからPython3に関する記述を削除して、ctrl+「x」+「c」（保存）　※ 「Frameworks/Python.framework」と書いてある文だった気がします。インストーラで導入すると、勝手に.bash_profileに書き込まれるようなのですが、コメントがついているのでわかると思います。
5. ```source ~/.bash_profile```で、.bash_profileの設定を更新
6. もう一度、homebrewからPython3やpip3を導入
ctf4b writeup

# **1. veni_vidi_vici**
 * 問題のzipファイルを解凍すると3つのファイルが出てくる。

  1. `Gur svefg cneg bs gur synt vf: pgs4o{a0zber`
  2. `Lzw kwugfv hsjl gx lzw xdsy ak: _uDskk!usd_u`
  3. `{ʎɥdɐɹɓ0ʇdʎᴚ :sı ɓɐlɟ ǝɥʇ ɟo ʇɹɐd pɹıɥʇ ǝɥ⊥`
 
<br>

 * 3番目のファイルの内容に注目すると`the third part of the flag is : Rypt0graphy}` となっている。
　このことから1番目と2番目のファイルの内容を`the first part of the flag is`と`the second part of the flag is`
　になるように文字をずらせばよいと予想をたてる。つまりrot13のこと。

　rot13のデコードは[このサイト](https://www.rot13.com/)を使用しました。

<br>

 * 1番目(`Gur svefg cneg bs gur synt vf: pgs4o{a0zber`)については**G**から**T**まで**13**文字ずらせばいいので**ROT13**を指定
   結果は`The first part of the flag is: ctf4b{n0more`です。
 
<br>

 * 2番目(`Lzw kwugfv hsjl gx lzw xdsy ak: _uDskk!usd_u`)については**L**から**T**まで**8**文字ずらせばいいので**ROT8**を指定しました。
 　結果は`The second part of the flag is: _cLass!cal_c`です。

<br>

 * よって`ctf4b{n0more_cLass!cal_cRypt0graphy}`が答えです。

<br>

* ちなみに問題文の意味は[こちら](https://ja.wikipedia.org/wiki/%E6%9D%A5%E3%81%9F%E3%80%81%E8%A6%8B%E3%81%9F%E3%80%81%E5%8B%9D%E3%81%A3%E3%81%9F)

<br>

# **2. RSA is Power**

問題文にもある通り**RSA暗号**に関する問題です。RSA暗号については[こちら](https://ja.wikipedia.org/wiki/RSA暗号)<br>
`N=97139961312384239075080721131188244842051515305572003521287545456189235939577`<br>
`E = 65537`<br>
`C = 77361455127455996572404451221401510145575776233122006907198858022042920987316`<br>
RSA暗号についてほとんど理解していなかったので、ひとまずWEBで調査しました。<br>
とりあえず分かったことは、<br>
 1. 公開鍵(ここではNのこと)=**P** x **Q**
 2. **E**は暗号化指数ということ
 3. **C**は暗号文(cipherの頭文字)
 4. 暗号文＝平文^**E** % **N**
 5. 平文＝暗号文^**D** % **N**
<br>

ここで**D**が何か調べました。すると復号化指数について[こちら](https://ist.ksc.kwansei.ac.jp/~nishitani/Lectures/2004/Maple/RSA.html)に説明がありました。<br>
**D**の値が欲しいので[こちら](https://tech.camph.net/rsa-public-key-encryption/)のサイトを参考にしてプログラムを組みました。<br>

また、**P**と**Q**の値も必要なので求めます。[こちらのサイト](http://factordb.com/)を使用しました。<br>
`P=299681192390656691733849646142066664329`
`Q=324144336644773773047359441106332937713`

処理終了時に出力される文字列を16進数に直して、ASCIに変換する処理も追加しています。

以上のすべてをまとめたコードがこちら

```python:rsa.py
# -*- coding: utf-8 -*-
import binascii
def ex_euclid(x, y):
    c0, c1 = x, y
    a0, a1 = 1, 0
    b0, b1 = 0, 1

    while c1 != 0:
        m = c0 % c1
        q = c0 // c1

        c0, c1 = c1, m
        a0, a1 = a1, (a0 - q * a1)
        b0, b1 = b1, (b0 - q * b1)

    return c0, a0, b0


def lcm(x, y):#最小公倍数
    return x * y // gcd(x, y)

def gcd(a,b):#最大公約数
    while b:
        a, b=b, (a%b)
    return a

cipher = 77361455127455996572404451221401510145575776233122006907198858022042920987316
p, q = 299681192390656691733849646142066664329, 324144336644773773047359441106332937713
n = p * q
e = 65537
λ = lcm(p-1, q-1)
c, a, b = ex_euclid(e, λ)
d = a % λ

plain = pow(cipher, d, n)
print(binascii.unhexlify(str(hex(plain))))

```

実行すると`ctf4b{5imple_rs4_1s_3asy_f0r_u}`が得られます。
resフォルダを細分化する

[material-components-android](https://github.com/material-components/material-components-android) の [catalog](https://github.com/material-components/material-components-android/tree/master/catalog) で、resフォルダが細分化されているのを見つけたので、どうやっているのかを調べました。

## sourceSetsを定義
appのbuild.gradleに対し、sourceSetsとresを置きたい場所を定義します。
srcDirsに書かれたフォルダをresフォルダに追加しています。

```build.gradle
def srcDirs = [
        'abc'
]

android {
    // 省略...

    sourceSets {
        main {
            res.srcDirs = ['src/main/res']
            srcDirs.forEach {
                res.srcDirs += 'src/main/java/com/kyaracter/myapplication/' + it + '/res'
            }
        }
    }
}
```

resフォルダとして認識されると、abcにあるresフォルダの見た目がリソースフォルダのものに変わります。

<img width="321" alt="Screen Shot 2018-05-27 at 18.12.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/9665/0939531e-0485-e218-5549-fd4ae29106c6.png">

## 使いみち
valuesだけでなく、layoutやmenuも同様に細分化できるので、ファイル数が多すぎて困った場合に使える感じです。
また、 abc/res/values/string.xml に定義する文字列は、この名前空間の外側でも参照できます。