OmniAICreator/Qiita-1.07M huggingface dataset:
Azure Linux VMのディスク使用率を監視する

Virtual Machineのメトリックを取得する場合、ホストVMメトリックとゲストVMメトリックの2種類があります。
詳細は以下の記事参照

[Azureメトリック](https://qiita.com/shingo_kawahara/items/c218ab36f6dd53a8b6a4#%E3%83%A1%E3%83%88%E3%83%AA%E3%83%83%E3%82%AF)

WindowsのゲストVMメトリックでは、ディスク使用率は「% Free Space」カウンターで取得されますが、Linuxでは同じような項目がありませんでした。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/9a153072-0ea5-5ac6-b811-ea7891cae9eb.png)
<br>

どうやらパフォーマンス関連のものしかなさそうですね。
Linux VMのディスク使用率を監視したいと思います。

# Log Analyticsでパフォーマンスカウンターを収集する
* OMSワークスペースに仮想マシンを登録します。手順はこちらを参考にしてください。

[Azure Log Analyticsへイベントログ収集](https://qiita.com/shingo_kawahara/items/c218ab36f6dd53a8b6a4#log-analytics%E3%81%B8%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%83%AD%E3%82%B0%E5%8F%8E%E9%9B%86)

* 仮想マシンを登録したら次にLinuxパフォーマンスカウンターを収集します。OMSページから[詳細設定]→[Linuxパフォーマンスカウンター]の順に選択し、収集を適用してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/ba594e8b-de7b-6379-98a3-976a6a33d732.png)
<br>

* OMSページから[ログ検索]を選択し、以下のようなクエリを発行します。ここではルートボリュームの空き容量を取得しています。

```
Perf | where CounterName == "% Used Space" and InstanceName == "/" and Computer == "[Your VM Hostname]"
```

* こんな感じでボリューム毎のディスク使用率が表示されてます。この例ではルートボリュームが12%使われてるということですね。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/7ffd16f3-96d6-333e-70c6-6432baa7e6cb.png)
<br>

# アラート設定
せっかくなので、ディスク使用率が80%を越えたらアラートが飛んでくるようにします。

* まずはログ検索で以下のクエリを発行します。ディスク使用率が80%以上のデータを表示するという意味です。1回でも80%を超えると1レコード表示されます。

```
Perf | where CounterName == "% Used Space" and InstanceName == "/" and Computer == "[Your VM Hostname]" and CounterValue >= 80
```

* 検索結果はヒットしなくていいので、このまま[New Alert Rule]を選択します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/9a1b4295-9cf1-3b3d-87fe-87ea4b2b79b5.png)
<br>

* [アラート条件]を選択します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/1a90aa56-2321-dd72-f928-a727b968285a.png)
<br>

* 1回でも80%を越えたら通知したい場合は、しきい値を「0」にします。チェック頻度も選択できるので、ここは要件次第で決めます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/a6383b21-ae14-c132-f253-683c23207adb.png)
<br>

* 他Log Analyticsのアラート設定項目は以下の記事を参考にしてください
[Log Analyticsアラート設定](https://qiita.com/shingo_kawahara/items/c218ab36f6dd53a8b6a4#log-analytics%E3%82%A2%E3%83%A9%E3%83%BC%E3%83%88%E8%A8%AD%E5%AE%9A)
<br>

* ディスク使用率は性質上、何時間も閾値を越えた状態のままとなることがあるかと思います。Log Analyticsアラートでは指定したクエリ発行頻度に従ってクエリを発行し続けます。つまり、例えば5分毎にクエリ発行する定義とした場合、5分毎に通知が飛んできます。うざいですね。
* それを回避するために、アラート設定するところで「アラートを表示しない」にチェックを付けます。そうすると再度通知するまでどれくらい待機するかを定義することができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/2f300570-e0fe-2e45-9620-f81fe907a114.png)
<br>

以上
Rで単語の出現頻度を求める。

##はじめに
Rで単語の全文書中の出現頻度を計算しました。
今回はあくまで備忘録です。


何か良いライブラリがありそうですが、見つかりませんでした。
（知っている人がいれば、教えてください・・）

##やりたいこと
簡単です。

```R

[["lemon", "apple", "banana", "lemon"], ["orange", "banana"]]
```

の全文書中の出現頻度を求めるだけです。

ただし、

| apple | banana | lemon | orange|
|:-:|:-:|:-:|:-:|
|  1 |  2 | 2  |1|

ではなく、

| apple | banana | lemon | orange|
|:-:|:-:|:-:|:-:|
|  1 |  2 | 1  |1|

として計算したいです。（１文書につき１カウント）

##やってみた
大したことはしていません。
（Rはそこまで詳しくないので、もっと良い方法があれば教えてください・・）

まず、普通に<code>table</code>で集計すると、

```R
xxx <- list(c("lemon", "apple", "banana", "lemon"),c("orange", "banana"))
table(unlist(xxx))

 apple banana  lemon orange 
     1      2      2      1 
```
となってしまいます。

今回は、文書ごとに<code>unique</code>関数を適用してから集計することで対応しました。

```R
xxx.distinct <- lapply(xxx, function(p){unlist(unique(p))})
table(unlist(xxx.distinct))

 apple banana  lemon orange 
     1      2      1      1

```

##おわりに
とりあえずやってみましたが、素敵なライブラリがあると嬉しいです。
自然言語処理用の良いライブラリ等があれば教えて頂けると幸いです。
EC2でホスト名の名前解決ができず困った件

参考にさせていただきました。ありがとうございます。

- [【AWS】VPC内でPrivate DNSによる名前解決](https://qiita.com/y_takeshita/items/2eb5e6abb5eb5516d1de)
- [Route 53のPrivate DNS対応を試してみた](https://dev.classmethod.jp/cloud/aws/route53-private-dns/)

# 結論

- EC2でプライベートなホスト名の名前解決を行う場合は、Route53のプライベートホストゾーンを作成する。
- インスタンス同士の通信はセキュリティグループの許可が必要。

# 困っていたこと
AWS上にEIPを設定したEC2開発環境AとBを用意しました。
それぞれのホスト名の名前解決を行いたいのですが、それができず困っていました。

```bash
ubuntu@ldap_srv:$ hostname
ldap_srv
ubuntu@ldap_srv:$
```


```bash:/etc/hosts
127.0.0.1 localhost
127.0.0.1 ldap_srv ldap_srv.localdomain

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
```

```bash
ubuntu@ldap_srv:~$ nslookup localhost
Server:		127.0.0.1
Address:	127.0.0.1#53

Name:	localhost
Address: 127.0.0.1

ubuntu@ldap_srv:~$ 
```


```bash
ubuntu@ldap_srv:~$ nslookup ldap_srv
Server:         127.0.0.1
Address:        127.0.0.1#53

** server can't find ldap_srv: NXDOMAIN

ubuntu@ldap_srv:~$
```


```bash
ubuntu@ldap_srv:~$ dig ldap_srv

; <<>> DiG 9.10.3-P4-Ubuntu <<>> ldap_srv
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 30144
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ldap_srv.			IN	A

;; AUTHORITY SECTION:
.			2803	IN	SOA	a.root-servers.net. nstld.verisign-grs.com. 2018031301 1800 900 604800 86400

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Wed Mar 14 13:07:32 JST 2018
;; MSG SIZE  rcvd: 112

ubuntu@ldap_srv:~$
```



# プライベートホストゾーンの設定
AWSコンソールにて、[Route53] → [Create Hosted Zone]

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235642/fa8e99aa-1a47-931b-e886-731406dc6501.png)

Hosted Zone作成後、Aレコードを登録する。
[Create Record Set]

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235642/d9cbf14e-c96b-1977-1695-67cd5abca1e2.png)




ネットワーク再起動。

```bash
ubuntu@ldap_srv:$ sudo /etc/init.d/networking restart
[ ok ] Restarting networking (via systemctl): networking.service.
ubuntu@ldap_srv:$
```


```bash
ubuntu@ldap_srv:~$ dig ldap_srv

; <<>> DiG 9.10.3-P4-Ubuntu <<>> ldap_srv
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 762
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ldap_srv.                      IN      A

;; ANSWER SECTION:
ldap_srv.               60      IN      A       13.115.xxx.xxx

;; Query time: 2 msec
;; SERVER: 172.31.0.2#53(172.31.0.2)
;; WHEN: Wed Mar 14 13:42:41 JST 2018
;; MSG SIZE  rcvd: 53

ubuntu@ldap_srv:~$
```

名前解決出来るようになりました。
source(.)の使い方

# 検証手順

前提：
①現シェル環境でnumberを1に設定
②子プロセスでnumberを確認してから2に変更
※スクリプトは下記ファイルを使用

```bash:sub.sh
[pirlo@minidns ~]$ cat sub.sh
echo number=$number  //numberが定義されているかを確認
number=2    　　　　　//サブシェル環境でnumberを2に変更
echo number=$number  //更新後のnumberを表示
[pirlo@minidns ~]$
```

確認開始

```bash
//現シェル環境のnumberを確認
[pirlo@minidns ~]$ echo $number
1

//子プロセスのシェル環境でnumberが定義されていないことを確認でき、2に設定
[pirlo@minidns ~]$ ./sub.sh
number=
number=2

//現シェル環境に戻ってから再度numberを確認し、子プロセスの影響がないことを確認
[pirlo@minidns ~]$ echo $number
1

//bashではなくsourceでスクリプトを実行。bashと異なり、最初の確認ではnumberが取得できた
[pirlo@minidns ~]$ source sub.sh
number=1
number=2

//再度numberを取得して、変更されていることを確認
[pirlo@minidns ~]$ echo $number
2
[pirlo@minidns ~]$
```

# 結論
・sourceでの実行は、実行されたスクリプトの中身を現シェル環境にコピーして実行すると考えて良さそう
・bashでの実行は、新規のシェル環境でスクリプトが実行され、独自のシェル変数を持ち、親シェル環境からシェル変数を継承せず、自分のシェル変数も親シェル環境へ反映しないらしい。
Kubernetes始めたい人のためのチュートリアルまとめ

# 概要
Kubernetesを始めたいって思って、Webで初心者向けのサイトとか情報を集めても、クラスタを作って、yaml食わして、ブラウザで見れました・・・以上。みたいなものが多くて、次何したらいいの・・・ ってなりませんか？

そういう人はチュートリアルをあるので、それを順番にやってみればいいかと思います。

# 本家のチュートリアル

Kubernetesの本家にもチュートリアルがあります。
https://kubernetes.io/docs/tutorials/

ただこれ、英語だし、クラスタを自分で作らないといけない、ローカル環境もつくらないといけない、っていうのでなかなか手を出しにくいのではないかと思います。

一部簡単なものはブラウザでできるものもありますが・・・
https://kubernetes.io/docs/tutorials/kubernetes-basics/


なので、本家以外のチュートリアルを色々触ってみたのでまとめてみました。

# その他のチュートリアル

## 自由にできるインフラがない、とりあえずやってみたいって人向け
https://www.katacoda.com/courses/kubernetes

- 英語
- クラスタ構築
    - 不要
    - ブラウザ上ですべて実施できる
- 料金
    - 無料
- はまり度
    - 特に問題はなく最後までできた

## GCPでやりたい人
https://cloud.google.com/kubernetes-engine/docs/tutorials/

- 日本語
- クラスタ構築
    - GKEで構築
    - 手順もある
    - CloudShellでの手順もあるので、ローカル環境の構築も不要
- 費用
    - Node用インスタンス利用料
    - g1-small×2くらいで大体いける
    - 後半のJenkinsあたりはもう1台くらいいる
- はまり度
    - 大体問題なくできる
    - 自分はJenkinsの認証のところがうまくいかなかった

## AWSでやりたい人
https://github.com/aws-samples/aws-workshop-for-kubernetes

- 英語
- クラスタ構築
    - 用意されているCloudFormationでCloud9環境をつくって、Cloud9上のコンソールからkopsを使ってクラスタを構築する
- 費用
    - EC2インスタンス利用料
    - マネージド・サービスではないので、Master、Nodeの両方のインスタンスが起動する
    - Single-Masterの構成で3台(Master1台、Node2台)、Multi-Masterだと8台(Master3台、Node5台 Nodeの台数は変更可能) + Cloud9用1台のインスタンスが起動するので割とお金がかかるかも
- はまり度
    - 書いてるとおりにやってもいまくいかないことも多い気が・・・
    
## Azureでやりたい人(未実施)
https://docs.microsoft.com/ja-jp/azure/aks/

- 日本語
- クラスタ構築
    - AKEで構築
    - 手順もある
    - CloudShellでローカル環境の構築も不要(っぽい)
- 費用
    - 知らない
- はまり度
    - やってないので不明

## ちゃんと理解したい、説明欲しいって人
入門Kubernetes
https://www.amazon.co.jp/dp/4873118409

- 日本語
- クラスタ構築
    - 自前
- 費用
  - ¥3,024(書籍費用) + インフラ
- はまり度
    - GKEでやってみたけど、ほぼ問題なく完了

# 個人的な所感
あくまで個人的な所感ですが・・・

|                |Katacoda|GCP  |AWS  |Azure|本   |
|:---------------|:------:|:---:|:---:|:---:|:---:|
| **言語**        |英語    |日本語|英語  |日本語|日本語|
| **お手軽度**     | ◯      | △   | △  | △   | ☓   |
| **費用**        | ◯      | △   | ☓  | ?   | ☓    |  
| **サクサク度**    | ◯      | △   | ☓  | ?   | △   |
| **理解度**      |☓       | △   | ☓   | ?   | ◯   |


# まとめ
個人的はおすすめは、

- 環境がない人  →  Katacode
- もう少し現実的な環境で、はまらずにサクサク進めたい人  →  GCP(GKE)
- ちゃんと理解したい人  →  本 + GKE

がいいんではないかと思います。
WPS > NCL > geo_em.d01.ncデータの地図上表示

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
GeForce GT 730 1GB GDDR5
CentOS 6.9 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

WRF(Weather Research and Forecasting Model)とその前処理であるWPS関連。

### 処理内容

WPSで作成されるgeo_em.d01.ncファイルを表示したい。

### NCLでの表示

http://www2.mmm.ucar.edu/wrf/OnLineTutorial/Graphics/NCL/Examples/BASIC/basic_plot_setup.htm
の1つ目のサンプルで表示できる。

以下は実際の処理データで実行した結果。
(スクリプト名は: `CODE_170613/plot_wps_180511.ncl`とした)。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/aacaa03e-88d1-62e1-8404-6359f1e0f6dc.png)


### 運用上のコスト

NCL自体を詳しくないため、Jupyter NotebookやSalemやCartopyなどで可視化しようと試していた。

結局、NCLでの実行が運用上手間がかからないことが分かった。
[Swift] Resultの処理を簡単に


## Resultが面倒くさい

Resultを処理する時Swift5では以下のようになるとおもいます。

```swift
let result = Result(100)

switch result {

case let .success(value): print(value * 5)

case let .failure(error): print(error)

}
```

長い。面倒くさい。
ScalaやRustがうらやましい！！

## こうなった

Future&lt;T&gt; のように処理できるようにしました。

```swift
let result = Result(100)

result
  .ifSuccess { print($0 * 5) }
  .ifError { print($0) }
```

短い！ わかりやすい！（個人の感想です）

## やりかた
以下、extensionです。 

```swift
extension Result {

  @discardableResult
  func ifSuccess(_ f: (Success) -> Void) -> Result {
  
    if case let .success(value) = self {
      
      f(value)
    }
    
    return self
  }
  
  @discardableResult
  func ifFailure(_ f: (Failure) -> Void) -> Result {
  
    if case let .failure(error) = self {
    
      f(error)
    }
    
    return self
  }
}
```
@vue/cli 3 に flow を導入する

2系の時は [こちら](https://alligator.io/vuejs/components-flow/)の記事を参考にさせて頂いたのですが
3.0.0-beta.10 の場合を調査したので備忘録で残しておきます。

## 前提

- @vue/cli 3.0.0-beta.10

以下の構成で動作確認をしました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61513/177718e0-e01d-c64c-84f2-882bf8afcf7b.png)

## 参照記事

- [Flow導入時に最初にやることまとめ](https://qiita.com/zaki-yama/items/3567b316f0fb62986809)
- [Flowの速い環境変化](http://mk.hatenablog.com/entry/2017/09/03/081508)

## 追加するパッケージ

- [flow-typed](https://github.com/flowtype/flow-typed)
- [@babel/preset-flow](https://github.com/babel/babel/tree/master/packages/babel-preset-flow)
- [eslint-plugin-flowtype](https://github.com/gajus/eslint-plugin-flowtype)
- [eslint-plugin-flowtype-errors](https://github.com/amilajack/eslint-plugin-flowtype-errors)
- [flow-bin](https://flow.org/en/docs/install/)

```
# flow-typed
npm install -g flow-typed

# 各パッケージ
npm install --save-dev @babel/preset-flow eslint-plugin-flowtype eslint-plugin-flowtype-errors flow-bin
```

## .flowconfig

package.json の `scripts` に `flow` を追加してください。

```diff:package.json
   "scripts": {
+    "flow": "flow",
     "serve": "vue-cli-service serve --open",
```

`flow init` を実行します。

```shell
npm run flow init
```
作成した .flowconfig ファイルに以下のオプションを追加します。

```.flowconfig:.flowconfig
[options]
include_warnings=true
module.file_ext=.js
module.file_ext=.vue
```

`[ignore]` には `node_modules` や `flow-typed` を追加しておいたほうがよいです。

## flow-typed

型定義ファイルをインストールします。

```
flow-typed install
```

## babel

`@babel/preset-flow` を追加します。

```diff:package.json
   "babel": {
     "presets": [
-      "@vue/app"
+      "@vue/app",
+      "@babel/preset-flow"
     ]
   },
```

## eslint

`eslintConfig` 内に plugins と rules を追加します。
また、任意で [eslint-plugin-flowtype の rules](https://github.com/gajus/eslint-plugin-flowtype#eslint-plugin-flowtype-rules) も追加します。

```package.json
"plugins": [
  "flowtype",
  "flowtype-errors"
],
"rules": {
  "flowtype-errors/show-errors": 2,
  "flowtype-errors/show-warnings": 1
}
```

## 確認方法

任意のファイルに `// @flow` を追加し、

```shell
npm run lint
```

を実行すると、以下のようなエラーが出ます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/61513/7f4e5039-31df-23c4-ac90-955b1c92c7e5.png)
docker + capistrano で deploy の動作確認をする


# ssh接続サーバーをdockerで構成

公式チュートリアルを参考に ssh 接続可能なサーバーを立てておく。
この例ではrootユーザーでパスワード認証する。


```:Dockerfile
FROM ubuntu:16.04

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
```

https://docs.docker.com/engine/examples/running_ssh_service/#build-an-eg_sshd-image

## イメージ作成

```
$ docker image build . -t ssh_server
```

## port を指定してコンテナ実行

```
$ docker run -d -p 10000:22 ssh_server
```

## docker コンテナから Github に接続できるように、秘密鍵を置いておく。

Githubには手元から公開鍵でssh接続できる前提。

方法は何でも良い。この例では docker cp コマンドで、直接手元からコピーする。

```
$ docker cp ~/.ssh/id_rsa_github_aiming コンテナID:/root/.ssh
```

# capstrano を インストール

```
$ gem install capistrano
```

```
$ cap install
```

# capistrano の設定変更

適当なレポジトリを指定する。
この例では https://github.com/github/hub を使う。

ちなみにレポジトリの中身は何でも良い。
(レポジトリ側にcapistrano関係のファイルは必要ない)


```deploy.rb
set :repo_url, "git@github.com:github/hub.git"
```

手元からサーバー ( docker コンテナ ) に繋ぐための設定を書く。

```deploy/production.rb
# The server-based syntax can be used to override options:
# ------------------------------------
server "localhost",
  user: "root",
  roles: %w{web app},
  ssh_options: {
    forward_agent: false,
    auth_methods: %w(password),
    port: 10000,
    password: "screencast"
  }
```

# デプロイを実行

```
$ cap production deploy
```


# dockerコンテナに deploy されているのを確認

```
root@8af7b375dc67:/# ls -la /var/www/my_app_name/
total 24
drwxr-xr-x 5 root root 4096 May 11 06:52 .
drwxr-xr-x 3 root root 4096 May 11 06:52 ..
lrwxrwxrwx 1 root root   44 May 11 06:52 current -> /var/www/my_app_name/releases/20180511065207
drwxr-xr-x 3 root root 4096 May 11 06:52 releases
drwxr-xr-x 7 root root 4096 May 11 06:52 repo
-rw-r--r-- 1 root root  106 May 11 06:52 revisions.log
drwxr-xr-x 2 root root 4096 May 11 06:52 shared
```

# 環境

- Capistrano Version: 3.10.2 (Rake Version: 12.0.0)
- Mac OS X Sierra
- Docker version 18.03.0-ce, build 0520e24








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
【Rails】メソッドをModelとDecoratorのどちらに実装するか？

Railsにおいて、「**Modelのデータを少し加工して返すメソッドを実装したい場合、ModelとDecoratorのどちらに実装するか？**」と悩むことがあります。

大雑把な基準として以下のように決めました[^1]。

[^1]: 自分ひとりで決めたわけではなく、会社の上司や先輩に相談はしています

* データ自体の取得：Model
 * DBのデータをそのまま返すものでなくてよい
* 表示用のデータ加工：Decorator
 * 戻り値はほぼStringになる

「実際にどのように表示するか？」はViewに移管し、適宜Helperでまとめます。

あくまで自分の中の基準ですが、迷ったときの指針の一つにでも使ってください。
Pythonによるスクレイピング&機械学習[6-4]

##MLPでテキスト分類してみよう
6章で、テキスト分類をするコードがkerasで書かれていたので、tensorflowで書き直しました。(p290)

####コード
```python
import tensorflow as tf
import json
from sklearn.model_selection import train_test_split
from keras.utils import np_utils
from sklearn.utils import shuffle

nb_classes = 9

batch_size = 64
epochs = 20

def weight_variable(name, shape):
    W_init = tf.truncated_normal(shape, stddev=0.01)
    W = tf.Variable(W_init, name="W_"+name)
    return W

def bias_variable(name, size):
    b_init = tf.constant(0.1, shape=[size])
    b = tf.Variable(b_init, name="b_"+name)
    return b

# data = json.load(open("./newstext/data-mini.json"))
data = json.load(open("./newstext/data.json"))
X = data["X"]
Y = data["Y"]
max_words = len(X[0])

X_train, X_test, Y_train, Y_test = train_test_split(X, Y)
Y_train = np_utils.to_categorical(Y_train, nb_classes)
Y_test = np_utils.to_categorical(Y_test, nb_classes)
print(len(X_train), len(Y_train))

x = tf.placeholder(tf.float32, shape=[None, max_words])
y_ = tf.placeholder(tf.float32, shape=[None, nb_classes])

W = weight_variable("num1",[max_words, 512])
b = bias_variable("num1", 512)
h = tf.nn.relu(tf.matmul(x, W) + b)

keep_prob = tf.placeholder(tf.float32)
h_drop = tf.nn.dropout(h, keep_prob)

W2 = weight_variable("num2", [512, nb_classes])
b2 = bias_variable("num2", nb_classes)
y = tf.nn.softmax(tf.matmul(h_drop, W2) + b2)

cross_entoropy = -tf.reduce_sum(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))

optimizer = tf.train.AdamOptimizer(1e-4)
train_step = optimizer.minimize(cross_entoropy)

predict_step = tf.equal(tf.argmax(y_, 1), tf.argmax(y, 1))
accuracy_step = tf.reduce_mean(tf.cast(predict_step, tf.float32))

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    N_train = len(X_train)
    n_batches = N_train // batch_size
    for epoch in range(epochs):
        X_, Y_ = shuffle(X_train, Y_train)
        for i in range(n_batches):
            start = i * batch_size
            end = start + batch_size

            sess.run(train_step, feed_dict={
                x: X_[start:end],
                y_:Y_[start:end],
                keep_prob:0.5
            })

        loss = sess.run(cross_entoropy, feed_dict={
            x: X_test,
            y_: Y_test,
            keep_prob:1
        })
        print(loss)

        accuracy = sess.run(accuracy_step, feed_dict={
            x: X_test,
            y_: Y_test,
            keep_prob:1
        })
        print(accuracy)

    acc = sess.run(accuracy_step, feed_dict={
        x: X_test,
        y_:Y_test,
        keep_prob:1.0
    })
    print(acc)
```

####結果
```
2323.9214
0.83821934
1160.6143
0.9082519
747.41626
0.92508143
572.6161
0.9391965
427.56378
0.9457112
397.68292
0.94679695
371.37494
0.95222586
353.74292
0.95222586
340.4296
0.95222586
331.1926
0.95222586
326.9084
0.9533116
320.22305
0.9538545
313.026
0.95276874
311.2329
0.9533116
306.23077
0.9516829
307.86145
0.9533116
305.60995
0.95222586
303.2419
0.9533116
300.61127
0.9516829
```

##参照
Pythonによるスクレイピング＆機械学習　開発テクニック BeautifulSoup、scikit-learn、TensorFlowを使ってみよう(著者:クジラ飛行机、出版社:ソシム株式会社)
http://www.socym.co.jp/book/1079
PowerShellでArcGIS Web Adaptorのインストールを自動化してみた


インストーラーの解凍だけはGUI必須だけど他は自動化した.

自動化した処理

- ArcGIS Web Adaptor 10.5をインストールする
- Web Adaptorを構成する


## インストーラーを解凍する

Web_Adaptor_for_Microsoft_IIS_105_ja_155426.exeを実行する.
解凍先を適宜設定する.
「今すぐプログラムを実行」のチェックを外すこと.


## インストーラーを実行する

- VDIR_NAMEにArcGISのWeb Adaptorの名前を設定する.
- VDIR_NAMEに「arcgis」を指定した場合, Web Adaptorには「 http://\<gis_server_name\>/arcgis/webadaptor 」で接続できる.

``` powershell
$arcGISWebAdaptorName = "arcgis"
$arcGISWebAdaptorSetupExe = "E:\ArcGISInstaller\WebAdaptorIIS_Japanese\setup.exe"
$arcGISWebAdaptorSetupArg = "/qn VDIR_NAME={0}" -f $arcGISWebAdaptorName

Start-Process -FilePath $arcGISWebAdaptorSetupExe -ArgumentList $arcGISWebAdaptorSetupArg -Verb runas -Wait
```

## Web Adaptorを構成する

- Web Adaptorを構成することで「 http://\<gis_server_name\>/\<webadaptor_name\>/rest/services 」からArcGIS Serverのサービスを呼び出すことが出来るようになる.

``` powershell
$arcGISWebAdaptorName = "arcgis"
$webAdaptorURL = "http://<gis_server_name>/{0}/webadaptor" -f $arcGISWebAdaptorName
$serverURL = "http://<gis_server_name>:6443"
$admin_userName = "someone"
$admin_password = "pass"
$configureWebAdaptorExe = "C:\Program Files (x86)\Common Files\ArcGIS\WebAdaptor\IIS\Tools\ConfigureWebAdaptor.exe"
$configureWebAdaptorArg = "/m server /w {0} /g {1} /u {2} /p {3} /a true" -f $webAdaptorURL, $serverURL, $admin_userName, $admin_password

Start-Process -FilePath $configureWebAdaptorExe -ArgumentList $configureWebAdaptorArg -Verb runas -Wait
```



### 参考

- https://enterprise.arcgis.com/ja/web-adaptor/10.5/install/iis/silently-install-arcgis-web-adaptor-server.htm
【Firefox Safari IE】日付のオプション指定でdatepickerが動作しない

##はじめに
Chrome基準で開発していると、他のブラウザで動作しないことがいろいろありますよね。本記事はChromeの恩恵を受けてしまったためにdatepickerが動かなかった問題をメモとして残します。

##Chrome, Edge
``` maxDate: '+2018-8-10' ```
``` + ```があっても動作する。 
が、この記述だと他のブラウザで動作しません。
(Edgeは動作しました..！)

##Firefox
``` maxDate: '2018-8-10' ```
``` + ```があると表記エラーのようで動作しません。

##Safari, IE
``` maxDate: '2018-08-10' ```
YYYY-MM-DD表記じゃないと動作しません。

##おわりに
Chromeに拍手:clap::clap:
findでファイルの検索や、ファイル名のみを取得する方法

ちょいちょい忘れてしまうのでメモ

## 作業ディレクトリからの相対パスで表示

`find . -type f`

## ファイル名のみを表示

`find . -type f | awk -F/ '{print $NF}'`



MACではこれでいけました。
競技プログラミングを Python 3 で解く

# はじめに
`Python` 大好きおじさんなので競プロも `Python` で解きたいです.
`Python` 触り始めて少ししか経っていないので訂正等ありましたらご指摘ください.

#チートシート
## 標準入力
### 1行から入力
#### 文字
##### `>> ABC`
```input.py
S = input()
print(S) # ABC
```
##### `>> ABC`
```input.py
S = list(input())
print(S) # ['A', 'B', 'C']
```
##### `>> A B C`
```input.py
S = input().split()
print(S) # ['A', 'B', 'C']
```
#### 数字
##### `>> 1`
```input.py
N = int(input())
print(N) # 1
```
##### `>> 1 2 3`
```input.py
A, B, C = map(int, input().split())
print(A) # 1
```
##### `>> 1 2 3`
```input.py
L = [int(i) for i in input().split()]
print(L) # [1, 2, 3]
```
##### `>> 1 2 3`  (上と同じ)
```input.py
L = list(map(int, input().split()))
print(L) # [1, 2, 3]
```
### 複数行から入力
#### 文字
##### 1次元
```input.txt
3
ABC
DEF
GHI
```
```input.py
N = int(input())
S = [input() for _ in range(N)]
print(S) # ['ABC', 'DEF', 'GHI']
```
##### 2次元
```input.txt
3 3
ABC
DEF
GHI
```
```input.py
H, W = map(int, input().split())
S = []
for _ in range(H):
    S.append(list(input()))
print(S) # [['A', 'B', 'C'], ['D', 'E', 'F'], ['G', 'H', 'I']]
```
```input.txt
3 3
A B C
D E F
G H I
```
```input.py
H, W = map(int, input().split())
A = [input().split() for _ in range(H)]
print(A) # [['A', 'B', 'C'], ['D', 'E', 'F'], ['G', 'H', 'I']]
```
#### 数字
##### 1次元
```input.txt
3
123
456
789
```
```input.py
N = int(input())
A = [int(input()) for _ in range(N)]
print(A) # [123, 456, 789]
```
##### 2次元
```input.txt
3 3
1 2 3
4 5 6
7 8 9
```
```input.py
H, W = map(int, input().split())
A = [list(map(int, input().split())) for _ in range(H)]
print(A) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```


## その他の関数
### 素数判定
```prime_judge.py
def prime_judge(p):
    p = abs(p)
    if p == 2:
        return True
    if p < 2 or p & 1 == 0:
        return False
    return pow(2, p-1, p) == 1
```
素数判定をします.
素数なら `True`, 素数でないなら `False` を返します.
>http://d.hatena.ne.jp/pashango_p/20090704/1246692091

# 更新
新しいフレーズに出会ったら随時更新していきます.
2018/05/11 16:40 文字の2次元配列の入力コードを変更しました.
WordPressの記事ページに更新日を追加

```php
<div>
最終更新日：<time datetime="<?php the_modified_date( 'Y-m-d' ); ?>"><?php the_modified_date( 'Y年m月d日' ); ?></time>
</div>
```

※WordPressのthe_modified_date()という関数で、かっこの中に日付のフォーマットを指定可能。
参考：https://wpdocs.osdn.jp/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%82%BF%E3%82%B0/the_modified_date

※<time>タグを使うときには、機械可読にする（クローラー...Googleなどのロボット型検索エンジンが読める）ように、datetime属性を追加する。
参考：https://developer.mozilla.org/ja/docs/Web/HTML/Element/time


### 参考にさせていただいたサイト
https://www.nxworld.net/wordpress/wp-modified-date.html
Ubuntu Server 18.04 LTSのインストールUSBの作成

#はじめに
Ubuntu ServerのUSBメモリを使ったインストールメディアを作成する。

#必要なのもの
- Ubuntu Server 18.04 LTS
- 16GB以上のUSBメモリ(できるだけ高速なもの) //1GBなので、十分すぎる
- クライアントマシン //MacBook Airを使用

#手順
##1. ダウンロード
1-1: ubuntu.comから[Ubuntu Server](https://www.ubuntu.com/server)のisoイメージのダウンロードします。イメージの種類は、『Ubuntu 18.04 LTS』使用します。

1-2:『Download Ubuntu Server』ボタンをクリックする。
![スクリーンショット 2018-05-11 14.36.10.png](https://qiita-image-store.s3.amazonaws.com/0/54439/47f19d41-ac5b-2666-8c1d-8e2678718ddc.png)


1-3: Ubuntu Server 18.04 LTSの『Download』ボタンをクリックする。
![スクリーンショット 2018-05-11 14.37.56.png](https://qiita-image-store.s3.amazonaws.com/0/54439/26eed268-e1f5-5119-62f5-b4291b873cc3.png)


1-4: ダウンロードが開始され、次のページにリダイレクトされる。
![スクリーンショット 2018-05-11 14.55.16.png](https://qiita-image-store.s3.amazonaws.com/0/54439/95b267eb-5c7c-ee73-01cd-63fb270b3286.png)



1-5: 『ubuntu-18.04-live-server-amd64.iso』がダウンロードされる。




##2. OSインストールメディアの作成
<font color="Red">重要: この作業は、書き込むディスクを間違えるとデータロストに繋がりますので慎重に作業してください。誤り避ける為、起動ディスク以外は接続をはずしてください。</font>
クライアントマシンにダウンロードした『ubuntu-18.04-live-server-amd64.iso』ファイルをUSBメモリに書き込みします。ターミナル.aapを使って、次のコマンドを入力して作業を進めます。

- diskutil: ディスクの管理
- sudo: 管理者権限でコマンドを実行
- dd: isoイメージをそのままUSBに書き込み

カレントディレクトリは、Desktopし、『ubuntu-18.04-live-server-amd64.iso』ファイルもDesktopに移動します。

2-1: diskutilコマンドで現在のディスクの接続状況を確認する。


```
$ diskutil list
```

(例)ここでは、内蔵SSDが/dev/disk1でマウントされている。『THEBE_HD』と言う名前のボリュームがある。
![スクリーンショット 2018-05-11 15.27.27.png](https://qiita-image-store.s3.amazonaws.com/0/54439/eb0027a8-72e5-5c3b-be77-766b746d0dde.png)


2-2: USBメモリを接続して、diskutilコマンドで現在のディスクの接続状況を再確認する。


```
$ diskutil list
```

(例)ここでは、USBメモリが/dev/disk2でマウントされている。『Untitled』と言う名前のボリュームがある。

![スクリーンショット 2018-05-11 15.31.48.png](https://qiita-image-store.s3.amazonaws.com/0/54439/cdddd3ed-f825-2c78-1664-82d5f231cc8c.png)



2-3: USBメモリをアンマウントする。

```
$ diskutil unmountDisk /dev/diskN #Nは数字
```

(例)ここでは、USBメモリを『diskutil unmountDisk /dev/disk2』でアンマウントされた。アイコンも消える。

![スクリーンショット 2018-05-11 15.35.19.png](https://qiita-image-store.s3.amazonaws.com/0/54439/2e12d57f-dc06-a979-68d3-a63818da62a7.png)



2-4: ddコマンドでファイルをコピーする。完成したらイジェクトする。

```
$ sudo dd if=ubuntu-18.04-live-server-amd64.iso of=/dev/rdiskN bs=1m
#Nは数字
```

(例)ここでは、USBメモリを『sudo dd if=ubuntu-18.04-live-server-amd64.iso of=/dev/rdisk2 bs=1m』でファイルコピーした。ダイアログからイジェクトした。イメージもサイズもコピーしたサイズもまったく同じの845,152,256バイトなので、正しく作成できた。ちなみに/dev/diskと/dev/rdiskは同じディスクを指して、ランダムアクセスかシーケンシャルアクセスかの違いです。


![スクリーンショット 2018-05-11 15.40.40.png](https://qiita-image-store.s3.amazonaws.com/0/54439/83d92712-277d-9728-a13a-7a4d327f40a8.png)


![スクリーンショット 2018-05-11 15.42.05.png](https://qiita-image-store.s3.amazonaws.com/0/54439/6bd8568b-8420-0fe2-7a91-7dfba516ba19.png)


#リファレンス
「ファイル名を指定して実行」を改造する

# ファイル名を指定して実行

「ファイル名を指定して実行」ってよく使う方いますでしょうか？
最近では常駐メモリも気にせずランチャーツール導入する方が早いでしょう。
キーボード慣れている人でも、「フォルダやファイルを規定アプリで開く」想定で使ってみると**使いづらい**イメージがあります。

![wr.png](https://qiita-image-store.s3.amazonaws.com/0/65983/d0ea7ed7-a717-0da5-dc9b-9629dfdc3b2d.png)

- 横幅もうちょっとほしい
- せっかくサジェストしてくれるのにホームポジションから遠い`↑` `↓`キーで移動しなければならない
- `\`キーが遠い・・
- UNIX系触っていて 「`TAB` ＝サジェスト」「`/`＝ディレクトリ区切り 」が染みついている

といったフラストレーションが・・
なのにこの機能、Windows2000～Windows10の現アップデート(2018/05)に至って全くと言っていい程仕様が変わっていません。

だったら**使いやすく改造しよう**というロマン企画です。
（※ MSさんがこの機能へのテコ入れに入ると、たちまち動かなくなる可能性があるのであくまでロマン企画です。）

Win-R-EXT
https://github.com/RAWSEQ/wrext

**AutoHotKey**なら１枚のスクリプトファイルで改造できます。
https://github.com/RAWSEQ/wrext/blob/master/wrext.ahk
久しぶりに使ってみたら、意外といろんなことがでるという事が分かって楽しいです。詳細は後述。

# Win-R-EXT

![wr01_1.gif](https://qiita-image-store.s3.amazonaws.com/0/65983/5d02eb2f-f2ba-5c03-c0f0-c74da333de6a.gif)

- `/` で変身
- `/` : パス区切り（実質は `\` ですが・・）
- `TAB` : サジェスト
- `TAB` + `Shift` : サジェスト戻り
- `Ctrl` + `BackSpace` : 上の階層　←ポジションから離れてますが・・

最低限のキーストロークでたどり着けます。
その他ムダ機能も完備しています。

## ショートカット機能

**ショートカットをたどる** 機能

![wr03.gif](https://qiita-image-store.s3.amazonaws.com/0/65983/7ea2e903-5b4e-5b61-d93f-9b080ca1486c.gif)

ショートカットファイル(.lnk)で `/` キーを押すと、文字通り「ショートカット」する機能。これは意外と便利。

## フォルダ作成機能

**年月日時分秒の入力**　**再帰的フォルダを作成**　の組み合わせで固有フォルダの作成

![wr02.gif](https://qiita-image-store.s3.amazonaws.com/0/65983/f0e06f9e-a58b-7cc4-bd86-8094c37b5b1c.gif)

キーアサイン変えてるだけなので、キーストローク表示がちょっとおかしいですが気にしないでください。

- `Ctrl` + `s` : 「年月日時分秒」の数字形式の文字入力
- `Ctrl` + `d` : フォルダを作成（途中のフォルダが無い場合はそれも作成する）

## AutoHotKeyとは

公式：https://autohotkey.com/
日本語ドキュメント：http://ahkwiki.net/Top

キー入力からいろんな事をスクリプトを用いて命令することができる、いわゆるマクロツールです。
単体で動作する「.exe」も出力できるので、配布も比較的しやすいです。
本体は英語ですが、かなり充実した日本語ドキュメントサイトがあるので、理解に困ることは、ほぼないと思います。

## 使い方
https://github.com/RAWSEQ/wrext
Clone or Download (緑のボタン) からDownload Zip (クローンでも良し）
Zipを展開する。

### AutoHotKey持ってない人

「wrext.exe」を起動する。
（※SmartScreen(水色のウィンドウ)が表示される場合があります。その場合は「詳細情報」から続行できます。）

### AutoHotKey持ってる人

「wrext.ahk」を開く。


`Win` ＋ `R` キーで「ファイル名を指定して実行」を開き、そのまま`/`キーを押す。
Safari Technology Preview WebDriverで"An unknown server-side error occured while ..."エラーが出たときに試すべきこと

# 症例

通常のSeleniumの使用法として，

```python
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('http://google.co.jp')
```

などと実行する分には動作します．しかし，そのあと

```python
driver.save_screenshot('image_path.png')
driver.get('http://yahoo.co.jp')
```

などと処理を続けたり特定の処理を行うと

```
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command.
```

や

```
selenium.common.exceptions.WebDriverException: Message: A session with id = 'hogehogehoge' was not found.
```

などと例外を発生して動作が停止してしまうことがあります．

どの処理が悪いのかは完全には分かっていませんが，`save_screenshot()`はエラーを起こす黒い操作であると思っています．


# 結論
**Mac OSのバージョンにあったSafari Technology Previewを入れ直しましょう．**

# Safari Technology Previewとは
[Safari Technology Preview](https://developer.apple.com/safari/technology-preview/)は，今後Mac OSやiOSのSafariに組み込まれるかもしれないWebテクノロジーを試してみるためのブラウザです．

筆者は，Webページ全体のスクリーンショットを撮るために使っています．

# 環境

| 名前                       |   バージョン         |
|---------------------------|---------------------|
| Selenium with Python      | 3.12.0         |
| Safari Technology Preview | 11.2           |
| Mac OS                    | High Sierra 10.13.4 |
| Python                    | 3.6.4          |

# よくある発症ケース
## 1. Mac OSをアップデートした時
Mac OSをSierraからHigh Sierraにアップデートする場合（もしくは他のバージョンからHigh Sierraなどにアップデートする場合），最初の数回の動作は**OSのバージョン違いのようなエラーを吐くことなく**機能します．  
ただ，少し操作を続けたりある特定の動作を行うと上記の症例のように`An unknown server-side error`という情報量≒0なエラーを起こします．

## 2. テキトーなバージョンのSafari Technology Previewをインストールした場合
実行中は，1.の場合と同じように，OSのバージョンが違うといった警告を出すことなく動作しますが，いきなり動作を停止します．

（インストール時にエラーを出してくれるかどうかは未確認です．）

# 解決策
いまインストールしてあるSafari Technology Previewをアンインストールして，正しいバージョンのSafari Technology Previewをインストールし直します．

## 1. いまあるSafari Technology Previewのアンインストール
「Finder」→「アプリケーション」→「Safari Technology Preview」を選択し，「（右クリック）」→「ゴミ箱に入れる」（→「ゴミ箱を空にする」）と操作を行うと簡単にアンインストールできます．

## 2. 正しいバージョンのSafari Technology Previewのインストール
[Safari Technology Previewのダウンロードページ](https://developer.apple.com/safari/download/)から，正しいバージョンのインストーラをダウンロードしてきて，ダブルクリック&実行をします．

# おまけ
OSのバージョン違い以外にも`An unknown server-side error`が出た場合は，Webdriverが壊れたというような原因もありえるのでSafari Technology Previewの再インストールは有効な場合もあると考えられます．



<!-- selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command.
<class 'selenium.common.exceptions.WebDriverException'>, WebDriverException("A session with id = '7F8E63DE-63F3-4A03-9E6F-B959E2F8DE00' was not found.",), <traceback object at 0x10af445c8>
-->
【SpatiaLite】平面や直線の重心を求めるCentroid関数の例

正方形の重心を出せます。

```sql
SELECT
	AsText(
		Centroid(
			GeomFromText(
				'POLYGON((0 0, 0 1, 1 1, 1 0, 0 0))',
				0
			)
		)
	)
;
-- POINT(0.5 0.5)
```

線分の中点も出せます。

``` sql
SELECT
	AsText(
		Centroid(
			GeomFromText(
				'LINESTRING(0 0, 1 1)',
				0
			)
		)
	)
;
-- POINT(0.5 0.5)
```
Ruby 開発環境を rbenv で整える

# Ruby 開発環境を rbenv で整える

# 前提

- macOS Sierra(10.12.6)

# インストール

## rbenv インストール
```shell
$ brew install rbenv
```

## rbenv 設定
```shell:.zshrc
+ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.zshrc
+ eval "$(rbenv init -)"
```

# インストール出来る Ruby のバージョンを確認する
```shell
$ rbenv install -l
```

# Ruby をインストールする
```shell
$ rbenv install 2.5.1
```

# インストールされている Ruby のバージョンを確認する
```shell
$ rbenv versions
  system
* 2.5.1 (set by /Users/moritake/.rbenv/version)
```

# Ruby　のバージョンを切り替える
```shell
$ rbenv global 2.5.1
```

# Ruby のバージョンを確認する
```shell
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
```
React Native Android Studio 3.1 系で @hoge/hoge となっている npmモジュールが存在すると gradle sync に失敗する

とあるアプリを React Native で開発していて、Android 3.1 系統にアップグレードしたら、gradle sync が通らなくなってしまって修正しました。

次の2つのことが同時に発生したことが原因でした。

* gradle 4.2 を適用したこと
* @hoge/ と スコープを限定している npm モジュールを利用してる

https://docs.gradle.org/4.2/release-notes.html#path-separator-characters-in-names-are-deprecated

によると、gradle4.2 で、path-separator-characters ( /, \\, :, <, >, ", ?, * )を使用したパスの指定は deprecated になったようです。

アプリでは、@terrylinla/react-native-sketch-canvas を下記のコマンドでインストールしていました。

```
$npm i -s @terrylinla/react-native-sketch-canvas
$react-native link
```

こうすると、settings.gradle と app/build.gradle にそれぞれ次のような行が追加されます。

* settings.gradle

```
include ':@terrylinla/react-native-sketch-canvas'
project(':@terrylinla/react-native-sketch-canvas').projectDir = new File(rootProject.projectDir, '../node_modules/@terrylinla/react-native-sketch-canvas/android')
```

* app/build.gradle

```
compile project(':@terrylinla/react-native-sketch-canvas')
```

これらのファイルの、 `@terrylinna/` のうち `/` の文字が原因です。

Hotfix になるのですが、 `@terrylinla/` を削除しても動作に支障はないので次のように修正して解決しました。

* settings.gradle

```
include ':@terrylinla/react-native-sketch-canvas'
project(':@terrylinla/react-native-sketch-canvas').projectDir = new File(rootProject.projectDir, '../node_modules/@terrylinla/react-native-sketch-canvas/android')
```

↓

```
include ':react-native-sketch-canvas'
project(':react-native-sketch-canvas').projectDir = new File(rootProject.projectDir, '../node_modules/@terrylinla/react-native-sketch-canvas/android')
```

* app/build.gradle

```
compile project(':@terrylinla/react-native-sketch-canvas')
```

↓

```
compile project(':react-native-sketch-canvas')
```
【ECサイト事業者必見】EU一般データ保護規則（GDPR）について【GoogleAnalytics】

GoogleAnalyticsのデータ消失騒動を踏まえて、
日本のEC事業者が最低限やるべきことは何か？に関する
オンラインセミナーがありました。備忘録的メモです。

#セミナー概要
日時：2018年5月9日15時〜16時
場所：オンラインセミナー
主催：JASEC（一般社団法人日本イーコマース学会）
講師：宮松利博様（株式会社ISSUN 代表取締役）

# EU一般データ保護規則（GDPR）とは
* 一言で言うと、個人情報保護の取り決め。
* 2018/5/25施行開始、20年ぶりに改正。
* [wikipedia](https://ja.wikipedia.org/wiki/EU一般データ保護規則)

# 対象
住所やEメールアドレスはもちろんのこと、IPアドレスやCookie情報、GPS移動データ、IPアドレス、セッションIDも保護の対象になる。
そのため、「ウチは関係なさそう」という日本のEC業者も、たとえば以下の場合はGDPRの対象になる。

* 現地ローカルにサービスを提供しているEC業者
* Paypal/AmazonPay/ApplePayに対応しているEC業者
* EEA域（欧州31ヶ国）が配送可能地域に含まれている
* EEA域（欧州31ヶ国）の国・言語にサイトが対応している
* 中小・零細企業も例外なく適用
* 欧州からのIPをブロックしたとしても例外なく適用
 
#抵触した場合、どうなるか
* 72時間以内の通達義務発生
* 高額な罰金の可能性も

#日本のEC事業者が最低限やるべきこと
GoogleAnalytics上での「IPアドレスの匿名化」と「データ処理修正条項」の確認

#基本情報の収集
* [実務ハンドブック入門編]
(https://www.jetro.go.jp/ext_images/_Reports/01/dcfcebc8265a8943/20160084.pdf)
* [実務ハンドブック実践編](https://www.jetro.go.jp/ext_images/_Reports/01/76b450c94650862a/20170058.pdf)
* [一般データ保護規則（仮日本語訳）](https://www.jipdec.or.jp/library/archives/gdpr.html)
* 有識者：杉本武重弁護士

#わかりやすいまとめ
[いよいよ施行のEU「一般データ保護規則（GDPR）」貴社のアナリティクス設定は本当に「永続的に保持」で良い？](http://www.issun.com/blog/いよいよ施工のeu「一般データ保護規則（gdpr）」貴/)
Chrome の強制終了Ctrl+Qを事実上封印する小技


# 解決する問題
Chromeの特定のショートカットキー動作を事実上封印する

## 今回の例
以下のコマンドが非常に打ち間違いやすいのに対して事故った時のリスクが大きい。

```
Ctrl+W：開いているタブを閉じる
Ctrl+Q：Chromeの終了
```

Chromeをまるごと終了することが稀の上，終了前にはタブの数が少なくなっているためCtrl+Wの連打で済むことも多い。**`Ctrl+Q`を封印することにする。**

# 使用する手法と原理
- 拡張機能へのキーボードショートカット割当を行う

拡張機能へとショートカットを割り当てるとそちらが優先されるので動作してほしくないコマンドを適当な拡張機能に当てはめて事実上無効化出来る。

## 手順
右上の3点リード？のメニューから「拡張機能」を選択，左上から「キーボードショートカット」を選択。
適当な拡張機能の欄を選択し`Ctrl+Q`を押して設定完了。

こんなかんじ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/188863/14ade025-6f4d-e89b-67ea-7a9f5c7f8e82.png)

以上。

# 関連手法

## Warn Before Quittingを使用
閉じる前に確認させるアレ。
https://dotstud.io/blog/chrome-stop-quit-error/#chrome%E3%81%AE%E6%A8%99%E6%BA%96%E6%A9%9F%E8%83%BD-warn-before-quitting

## 外部アプリケーションでキーコマンドを編集
keyhacとかいうのが良いらしい
https://support.google.com/chrome/forum/AAAAG2AdvocB1BSwGSCZXI?hl=ja
RedmineでActiveDirectory連携を行う

RedmineでActiveDirectory(以下AD)連携が出来たので事細かく残しておく。

# 設定する
管理 -> LDAP認証 -> 新しい認証方式 から、ADを登録する。
![AD01.png](https://qiita-image-store.s3.amazonaws.com/0/13972/9a800ef4-2e65-31b6-c93a-01c5fde18946.png)

|項目|内容|
|-------------------|-----|
|名称               |自由|
|ホスト             |ADのIPアドレス|
|ポート             |389|
|アカウント          |ADに管理されているユーザー名@ドメイン名|
|パスワード           |ユーザーのパスワード|
|ベースDN             |ドメイン名|
|あわせてユーザーを作成|チェックする|
|ログインIDの属性     |sAMAccountName|
|名の属性             |givenName|
|姓の属性             |sN|
|メールアドレスの属性  |mail|

ドメインの設定状態が以下の時、アカウント、ベースDNは以下の通りになる。
【ドメイン】
sample.local
　└ Users
　　　└ Administrator

【設定値】

|項目|内容|
|-------------------|-----|
|アカウント          |Administrator&#64;sample.local|
|ベースDN            |DC=sample,DC=local|

『あわせてユーザーを作成』のチェックをしないと、予めRedmine側でユーザー登録しないといけない。
しかもAD側のパスワードが変わっても連動しないので、あまり意味がない様子。
チェックしていると、初回ログインでユーザー登録が行われるし、AD側のパスワードが変わっても追随する。
姓、名、メールアドレスのいずれかがADから取得できない場合は、入力しろ画面が出る。

# テストする
テストリンクをクリックして、『接続しました』と出ればOK。
![AD02.png](https://qiita-image-store.s3.amazonaws.com/0/13972/b314824a-e4e9-1743-2885-8246e450b675.png)
【初心者】就活のためにJavaの勉強を始めてみた話〜3ヶ月目〜

こんにちは。
地方の無名文系大学に通う3年生です。

私は就活のために３ヶ月程前からプログラミングの勉強をしています。
勉強を始めたきっかけなどについて気になる方は1ヶ月目の記事を見て頂ければと思います。

[【初心者】就活のためにJavaの勉強を始めてみた話〜1ヶ月目〜]
(https://qiita.com/ayumitani611/items/8da091cb0f0447b509eb)

３ヶ月目では、先月取り組んでいたドットインストールの復習に取り組みました。
今回は2巡目という事もあって１巡目よりもエラーが出る回数が減り、エラーの修正も自力でできる回数が増えました。

しかし、この１ヶ月で成長を感じたのはエラー修正に関してくらいで、それ以外の技術や知識については勉強時間に対してあまり身に付いていないという結果になってしまいました。

なので今回は3ヶ月目の学習における反省点について書いていきます。

## **3ヶ月目の反省点**

私が反省している点は

- 内容の理解よりも短時間で終わらせるを優先してしまった事
- 勉強をする日としない日が出来てしまった事

の2点です。

今月は春休みが終わったので学校の勉強にも時間を使わなければならないなどの事情もありました。
その為もあり、ドットインストールでの勉強を早く終わらそうとして、書き写すだけの作業のようになってしまっていました。
また、課題提出日の前日にはそちらに集中してしまった為、プログラミングの勉強の時間を取れていませんでした。

時間が取りにくい事情もありましたが、もう少し時間を上手に使えば勉強時間を捻出する事が出来たはずですし、もっと効率の良い勉強を出来たと思います。
もし１日の勉強時間をあと10分ずつでも増やしていれば、内容理解の為に考える時間が確保でき 結果的には短時間で技術や知識を身につける事に繋がったのだろうとも思います。
また、課題をしなければならない日でも勉強を全くしないのではなく、動画1つ分だけでも進めておけばよかったと思います。

６月の上旬に１学期が終わるので、4ヶ月目では3ヶ月目よりも課題やテスト勉強で時間が必要になると考えられます。
ですが4ヶ月目では今回の失敗を踏まえて、学校の課題も疎かにならないようにしながら 時間を効率的に使って勉強したいと思います。

## 最後に

最後まで読んでくださってありがとうございました。
今月のような反省はもうしなくても良いように、これからもっと頑張って行きたいです。
次は６月の上旬に４ヶ月目の進捗を書きたいと思いますので、ご覧いただければ幸いです。
CakePHP2でvirtualFieldでpaginateしたいときの解決法

virtualFieldの使い方。
基本
Modelで定義する場合

    public $virtualFields =[
	    'hoge' => 'COUNT(Model.huga_id)'];
    //hogeにfuga.idの合計を定義する
動的に定義

    $this->Model->virtualFields =['hoge' =>'COUNT(Model.huga_id)'];
    $this->Model->find('all'[
	    'fields' =>['hoge']
    ]);
またバーチャルフィールドには制限があり、関連モデルのcondition等に用いることができない。
https://book.cakephp.org/2.0/ja/models/virtual-fields.html#id6
Model1はModel2に対してhasManyの関係
動的にModel1でModel2のカラムからvirtualFieldsを作成し,paginateを利用しソートしたい時に困った
ex)Model1をModel2を持ってる数の多い順にする

    $this->Model1->virtualFields = ['hoge'=>'count(Model2.model1_id)'];

    $this->paginate =[
	'limit' => 10,
	'order' => 'Model1.hoge DESC',
	'group' => ['Model1.id'],
	'joins' => [[
	    'table' => 'model2',
	    'alias'  => 'Model2',
	    'type'  => 'left',
	    'conditions' => ['Model1.id'=>'Model2.model1_id']
    ]]
    ];
新卒用のネットワーク課題でおきた悲劇 ~自作DHCPサーバーの恐怖~

#はじめに
もう、あるあるだと思うので、タイトルを見て内容が予測できるかと思いますが、新卒用のネットワーク課題を作成中におきてしまった悲劇を書き記したいと思います。

#背景
今年は新卒用の課題として、RaspberryPIを使ってネットワークを構築させてみようという試みで課題を作成することになりました。
内容は、クローズドなネットワークを作成し、そのなかでDHCPサーバーとDNSサーバーを自作して、実際に通信してみようというもの。

構成としてはこんな感じで、すごく簡単な構成。
<img src=https://qiita-image-store.s3.amazonaws.com/0/93763/819d78aa-2fb2-aa20-64ea-ec832c4bc2e6.png width=60%">


#起きた悲劇
課題を作成した後は、実際に他の人に課題をやってもらうわけですが、そこで悲劇はおきました。
このクローズドネットワークのHUBに社内LANを繋いでしまい、影響を受けた偉い人のPCがインターネットに繋がらないという事態に。。。

#起きた悲劇 (技術的な内容)
なぜこんなことになっるのかというと、同じネットワーク内にDHCPサーバーが複数あると、クライアントからの「IPアドレスくださ〜い」というリクエスト(DHCPディスカバー) に対して、早いもの勝ちでリクエストを受け取ったDHCPサーバーが返事をしてしまいます。
そうすると、自作DHCPサーバーに取り込まれてしまったクライアントは、クローズドネットワークに引き込まれて外部と通信ができなくなってしまうわけです。

#なぜ悲劇が起きたのか
では、なぜクローズドネットワークに対して社内LANを繋いでしまったのでしょうか。
それはもちろん課題の構成に原因があります。

## 課題をやる人間はネットワークに詳しくない
前提として、課題をやる人間は課題を通してネットワークを学ぶわけなので、DHCPをよく知らない人が対象となり、もちろんDHCPの脅威もわからないのです。
そのため、やってはいけない事もわかるわけがないのです。
課題をやってもらう前に、徹底して注意事項を伝えておくことが大切でした。

## ググれない環境
社内PCをクライアントとして使用していたため、ググる手段がなくなってしまっていました。
無線に切り替えるか、社内LANに差し替えるかすればいいのですが、HUBに社内LANをさせばネットワーク構成も崩さずにインターネットに繋がることができると考えてしまったようです。

## 簡単に社内LANと繋ぐことができる環境
何と言ってもこれですね。
もっと徹底して隔離するべきだったのです。
そもそも、インターネットに接続する手段が社内LANだったというのがよくなかったのです。

#解決策
徹底して社内LANに繋がない様にします。

## 会社のPCは使わない
構成の中で会社のPCをクライアントとして使用していたのが間違いでした。
こういった危ない研修には社内機材は巻き込まない。
そうすることで、ググりたい時は通常通り会社のPCでググってもらうことができます。

## インターネットに繋ぐ
インターネットに繋ぎたい？
じゃあ、別の回線を用意しなさい！
そう、まずは社内ネットワークを使わなくても良い環境を用意することにしました。
会社のPCを構成から外したことで、検索などは会社のPCで行える様になりましたが、ミドルウェアのインストールなどにインターネット接続は必要です。

そのために下記の様な構成に変更し、インターネットに繋ぎたい時は4G回線を使用し、かつRaspberryPIで無線の設定は一切触らせないように、有線で接続するようにします。
![qiita用 (3).png](https://qiita-image-store.s3.amazonaws.com/0/93763/5dc288d5-8122-bd7b-3037-53991cd9075c.png)


##注意事項は徹底して書いておく
当たり前のことなのですが、注意すべき事項は課題の資料に目立つ様に書いて起きます。
なぜダメなのか、どういったことが起きるのかを記載しておきます。
そうすることで、課題を終えた時に「あーだからダメだったのか」と納得してもらえれば、それもまた理解が深まります。
口頭で伝えるのは、伝え漏れが発生するのでNG。

#最後に
課題作りって難しいですね。
成長してほしい一心で作ってるはずなのに、新卒研修でこんな地雷を踏んでしまった日には、その人に恐怖心を植えつけてしまい、逆に成長の妨げになるかもしれません。
今回の様に特にネットワークを作成するような課題は危険が伴うことを身を以て学びました^^;
ReactNavigationのTabNavigatorで切替時に毎回イベントさせる方法


- [ReactNavigation](https://reactnavigation.org/)

### v2
- 参考: https://stackoverflow.com/questions/50961321/createbottomtabnavigator-how-do-i-reload-refresh-a-tab-screen-on-tab-on-the-tab#

```jsx
import React from 'react'
import { createBottomTabNavigator } from 'react-navigation'
import { View, Text } from 'react-native'

class Home extends React.Component {
  componentDidMount() {
    this.subs = [
      this.props.navigation.addListener('didFocus', () => this._onFocus())
    ]
  }

  componentWillUnmount() {
    this.subs.forEach(sub => sub.remove())
  }

  _onFocus = () => {
    console.log('home on focus')
  }

  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Home!</Text>
      </View>
    )
  }
}

class Test extends React.Component {
  componentDidMount() {
    this.subs = [
      this.props.navigation.addListener('didFocus', () => this._onFocus())
    ]
  }

  componentWillUnmount() {
    this.subs.forEach(sub => sub.remove())
  }

  _onFocus = () => {
    console.log('test on focus')
  }

  render() {
    return (
      <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
        <Text>Test!</Text>
      </View>
    )
  }
}

export default createBottomTabNavigator(
  {
    Home,
    Test
  }
)
```


### v1
- 参考： https://github.com/react-navigation/react-navigation/issues/2725#issuecomment-385216286

```jsx

  static navigationOptions = ({ navigation }) => {
    return {
      tabBarOnPress: ({ scene: { index }, jumpToIndex }) => {
        jumpToIndex(index)
        navigation.state.params.onFocus()
      }
    }
  }

  componentDidMount() {
    this.props.navigation.setParams({
      onFocus: this._onFocus.bind(this)
    })
  }

  _onFocus = () => {
    // do something
  }
```
ndenvにパスが通らない

# 結論
`$HOME/.anyenv/bin`にパスを通せばいいとあったけど通しても呼べなかったのでもう直接pathを通した。

`set -U fish_user_paths $fish_user_paths $HOME/.anyenv/envs/ndenv/bin/`

fish全然わからん

追記
anyenvにパスを通してもだめだった(evel ndenvとevel anyenv両方やったせい？anyenvの方にnodeが入ってない)

とりあえずbrewで入れたnodeを削除して
ndenv installすると$HOME/.ndenv配下に入っていたので
`$HOME/.ndenv/shims`にパスを通して解決した

> 参考
> https://qiita.com/tonkotsuboy_com/items/5322d226b6783d25b5df
プラグインが原因でsketchが立ち上がらずに落ちてしまう時の解決方法

**This plugin is incompatible with Sketch 50**とわざわざ警告してくれているのにアップデートしてSketchが起動しなくなりました :angel_tone1:

![スクリーンショット 2018-05-11 12.53.36.png](https://qiita-image-store.s3.amazonaws.com/0/252629/e85061fb-863d-5ebe-c064-970328083662.png)

## 試したこと
立ち上がった瞬間にPluginsメニューを開きUninstallしようとしたが、落ちるタイミングが早すぎて出来なかった。

## 解決方法
ファインダーから直接sketchのPluginが入っているフォルダに移動し、犯人をPluginsフォルダから移動させる :coffee:


## SketchのPluginsフォルダの場所
/Users/ユーザ名/Library/Application\ Support/com.bohemiancoding.sketch3/Plugins 

＊Libraryフォルダが見当たらない場合
optionを押しながらファインダーメニューの移動をクリックするとLibraryが出てきます。

警告を無視してはいけませんね。。。
【Unity2018】ShaderGraphのプロパティパネルが消えた！？時の対応策

# 環境
エディタバージョン : Unity2018.1.0f2
OS : Windows10
ShaderGraphのバージョン : 1.1.4-Preview

# はじめに
Unity2018で**ShaderGraph**が追加されました。
ノードベースでシェーダーを組めるツールです。
<img src = "https://qiita-image-store.s3.amazonaws.com/0/44288/3873e7c8-35f2-bfe3-496c-967ca1c03deb.png" width = 400>

直感的で分かりやすくて楽しい。

# 消えるプロパティパネル
ShaderGraphのウィンドウの左上にプロパティパネルがあります。
<img src = "https://qiita-image-store.s3.amazonaws.com/0/44288/bd54cc4c-e637-bbfc-b12c-3be3a76abcd3.png" width = 300>

なんとこのプロパティパネル、ウィンドウサイズを**変えると消えてしまいます** 。
<img src = "https://qiita-image-store.s3.amazonaws.com/0/44288/4b1ed21c-6e3a-5419-ebd1-cbb577d3fa63.png" width = 300>

ウィンドウを開きなおしても、Unity再起動してもプロパティパネルが出てきてくれません。(泣)

ShaderGraphのバグですね。

# Libraryフォルダを消すと直るらしい。
困ったときのGoogle頼み。 
「unity shader graph properties disappear」でググってみたら解決方法が載ったAnswerが見つかりました。

Properties Panel missing in Shader Graph
https://answers.unity.com/questions/1501592/properties-panel-missing-in-shader-graphproperties.html

**Libraryフォルダを消したところ、プロパティパネルが表示されるようになりました。**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/44288/37771763-f10e-1053-c6e1-7fdfc0c87a21.png)
WRF | WPS > difference > ARW coreとNMM core > ARW: Advanced Research WRF と NMM:Non-hydrostatic Mesoscale Model

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
GeForce GT 730 1GB GDDR5
CentOS 6.9 (64bit)
NCAR Command Language Version 6.3.0
for WRF3.7.1, WPS3.7.1
  openmpi-1.8.x86_64 とその-devel
  mpich.x86_64 3.1-5.el6とその-devel
  gcc version 4.4.7 (とgfortran)
for WRF3.9, WPS3.9
  Open MPI v2.1.1
  gcc version 4.9.2 (とgfortran; devtoolset-3使用)
　NetCDF v4.4.1.1, NetCDF (Fortran API) v4.4.4
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(2)-release (x86_64-redhat-linux-gnu)
date (GNU coreutils) 8.4 
tmux 1.6-3.el6
```

WRF(Weather Research and Forecasting Model)とその前処理であるWPS関連。

### ARWとNMM

Geogridに関する資料を読んでいる。
http://www2.mmm.ucar.edu/wrf/users/tutorial/200907/Basic/WPS-general.pdf

p14とp15に2つのドメインでの定義図がある。

- Geogrid: Defining ARW Domains
- Geogrid: Defining NMM Domains

ARWとNMMについては検索して以下を見つけた。
https://ams.confex.com/ams/pdfpapers/153552.pdf

> The Weather Research and Forecasting (WRF) model contains two dynamic cores: the Non-hydrostatic Mesoscale Model (NMM – Janjic 2003) core (developed at the National Centers for Environmental Prediction (NCEP) and the Advanced Research WRF (ARW – Skamarock et al. 2005) core, 

dynamic coreが2種類あり、使っている方のcoreに関してgrid定義をすればいい。
Ripple (XRP) のアドレスを作成

# ripple-lib をインストール
```
$ npm install ripple-lib
```

# サンプルコード
- オフラインでも動作します。

```js
const RippleAPI = require('ripple-lib').RippleAPI;
const api = new RippleAPI();
const address = api.generateAddress();
console.log('address', address.address);
console.log('secret', address.secret);
```
debパッケージをソースコードで落として自分でビルドして中身を見てみる

## パッケージ

```
$ sudo apt install build-essential -y
```

gccやmakeなどの基礎開発ツール郡はこのパッケージに含まれています。

```
$ sudo apt install install devscripts -y
```

debuildコマンドはこのパッケージに含まれています。

その他

```
$ sudo apt install git-buildpackage quilt pbuilder debootstrap dput debhelper -y
```

## apt sourceを使えるようにする

[apt sourceを使えるようにする](https://qiita.com/miyagaw61/items/7789e7e5b14101cb9c38)

## ソースコード取得

```
$ sudo apt source unzip
```

## ソースコードをビルドするための関連パッケージをすべてインストール

```
$ sudo apt build-dep unzip -y
```

## debuildコマンドでパッケージをビルド

```
$ cd unzip-6.0
$ debuild -uc -us -b
```

## 一時ファイルを削除

```
$ fakeroot debian/rules clean
```

## 各ファイルの説明

### unzip_6.0-16+deb8u2.debian.tar.xz

Debian固有のファイル群（パッチなど）

### unzip_6.0-16+deb8u2.dsc

パッケージに関する設定情報ファイル群

### unzip_6.0.orig.tar.gz

大本のオリジナルなアーカイブ

### unzip-6.0

Debian固有のものを含め全てのものが展開されているソースディレクトリ
この中の「debian」というディレクトリの中にパッケージ作成のための「レシピ」が収まっている。

## rules

このファイルは実行可能な makefile で、ソースからパッケージをコンパイルしバイナリパッケージを構築するためのパッケージ特有のレシピを含んでいます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/132486/d07be560-1c13-695f-6eea-4608a050b66a.png)

## control

debian/control ファイルは、ソースパッケージとそれから生成されるバイナリパッケージについての最も重要な (バージョン非依存の) 詳細を含みます。

## changelog

Debian 版のパッケージの変更は全て簡潔に Debian changelog ファイル debian/changelog に記載すべきです。 これには上流の版に加えた Debian パッケージ向けの変更、 およびパッケージに対するそれ以外の修正や更新を記載します。

## copyrightもしくはcopyright.in

パッケージの著作権情報が記述されます。

## 次は自分でパッケージを作ってみましょう

[debパッケージ開発 メモ](https://qiita.com/miyagaw61/private/79de57a279928790189b)