OmniAICreator/Qiita-1.07M huggingface dataset:
ASK で Pod を動かす Node を明示的に設定する

前回までの記事で、ACR/AKS デプロイ、リソースの作成、アプリケーションの実行、Pods への Label の割り当てを行いました。基本的に Pods の作成は マニフェストファイルの適用で実施しますが、実際に AKS アプリケーションをデプロイしていくと、Pod を動かす Node を明示的に設定するということが必要です。今回の記事は、その方法を見ていきます。

#クラスター内の Node を確認する
まずは、`kubectl get node` コマンドを実行して、現在動いている Node を確認します。

```
$ kubectl get node
NAME                                STATUS   ROLES   AGE   VERSION
aks-nodepool1-XXXXXXXX-vmss000000   Ready    agent   44h   v1.13.12
aks-nodepool1-XXXXXXXX-vmss000001   Ready    agent   44h   v1.13.12
aks-nodepool1-XXXXXXXX-vmss000002   Ready    agent   44h   v1.13.12
```

上記のコマンドを実行した際に、`NAME` の列に表示されているものが、Node の名前です。今回は明示的に `aks-nodepool1-XXXXXXXX-vmss000002` に Pod を作成したいと思います。

#Node にラベルを割り当てる
`kubectl label node aks-nodepool1-XXXXXXXX-vmss000002 server=webapp` を実行して、一台の Node にラベルを割り振ります。上記コマンドを実行したあとに、`kubectl get node --show-labels` を実行することで、Node に割り振られている Label を確認することが可能です。

```
$ kubectl get node --show-labels
NAME                                STATUS   ROLES   AGE   VERSION    LABELS
aks-nodepool1-20426113-vmss000000   Ready    agent   44h   v1.13.12   XXXXXXXXXXXXXXXXXX
aks-nodepool1-20426113-vmss000001   Ready    agent   44h   v1.13.12   XXXXXXXXXXXXXXXXXX
aks-nodepool1-20426113-vmss000002   Ready    agent   44h   v1.13.12   XXXXXXXXXXXXXX,server=webapp,XXXXXXX
```
これで Node 側の準備は整いました。あとはマニュフェストファイルを編集して、指定したラベルが張られている Node に Pods を作成します。

#指定したラベルの付いた Node に Pod を作成する
まずは、マニフェストファイルを編集します。Pods を起動する node は `spec:nodeSelector:server` の部分で設定します。今回は `webapp` というラベルをしています。

```labelsample.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: stage

spec:
  containers:
  - name: nginx
    image: nginx
  nodeSelector:
    server: webapp  # webappというラベルの付いた Node に割り当てる
```

上記マニュフェスファイルを作成したら、`kubectl apply -f labelsample.yaml` を実行し、 Pod を作成します。実行後、`kubectl get pod --output=wide` で実行されている Pod を確認します。

```
$ kubectl get pods -o=wide
NAME    READY   STATUS    RESTARTS   AGE     IP            NODE                                NOMINATED NODE   READINESS GATES
nginx   1/1     Running   0          3m48s   XX.XXX.X.XX   aks-nodepool1-XXXXXXXX-vmss000002   <none>           <none>
```

これで指定した Node に Pod が割り振られているのが確認できました。
次回はより深いところで、Pod に必要なメモリ / CPU を割り当てる方法についてみていきたいと思います。

#参考 URL
Assigning Pods to Nodes
https://kubernetes.io/docs/concepts/configuration/assign-pod-node/
Pythonで競技プログラミングする際の入力チートシート

## はじめに
Pythonで競技プログラミングを始めたので、入力部分の実装時間を短縮するための入力のテンプレートを作成しました。自分用の備忘録のようなものです。

## 環境 
Python 3.5.x(AtCoderで動作したのを確認)

## 本編

### 基本となる入力用のクラス
```python

class Scan():

    def intarr(self):
        line = input()
        array = line.split(' ')
        num_array = [int(n) for n in array]
        return num_array

    def strarr(self):
        line = input()
        return line.split(' ')
```
### 入力する行数が決まっている場合(整数)
```python
def main():
    sc = Scan()
    n = sc.intarr()
    print(n)

# 入力例
10 4 0
# 出力
[10, 4, 0]
```

### 入力する行数が決まっていない場合(整数)
```python
def main():
    sc = Scan()
    array = []
    while True:
        try:
            array.append(sc.intarr())
        except ValueError:
            break

    print(array)

# 入力例
3 5 7
1 2 3 4 5
2 3
#出力
[[3, 5, 7], [1, 2, 3, 4, 5], [2, 3]]
```

### 文字列
```python
def main():
    sc = Scan()
    n = sc.strarr()
    print(n)

# 入力例
Hello World
# 出力
['Hello', 'World']
```

## 終わりに
こうした方が実行速度が早いなどのアドバイスがありましたらお願いします。
爆速でyamllintを.yml形式以外のファイルにも適用する

# `.yml`形式以外のファイルにも、yamllintを適用する方法

1. yamllintを実行するディレクトリに下記内容の`.yamllint`を置く

※yamllintのデフォルト設定では、`.yaml`、 `.yml` 、 `.yamlint`の3形式しかサポートしていないため、追加で拡張子を指定する必要があります。

```yaml
---
extends: default

yaml-files:
  - '*.dig' # 今回追加したいファイル形式
  - '*.yaml'
  - '*.yml'
  - '.yamllint'

```



2. `$ yamllint  . ` で動作確認する
Promiseのresolveとrejectの両方を呼び出したらどうなってしまうのか？

`Promise`は次のサンプルコードように、失敗したら`reject`を、成功したら`resolve`を呼び出すような書き方をする。

```js
new Promise((resolve, reject) => {
  // ...
  if (err) {
    reject(err)
  } else {
    resolve()
  }
})
```

このサンプルコードは、正常系と異常系でif分岐されており、`resolve`と`reject`が両方呼ばれる可能性はない。

もしも、`resolve`と`reject`の両方を呼び出したらどうなるのだろうか？

```js
new Promise((resolve, reject) => {
  reject()
  resolve()
})
```

普通はこんなことはしないだろうが、`Promise`の仕様を知っておくのは良さそうだ。

## 実験1: `resolve`→`reject`の順で呼んでみる

実験してみよう。まずは、`resolve`→`reject`の順で呼び出してみよう。

```js
new Promise((resolve, reject) => {
	resolve()
	reject()
}).then(value => console.log('success'))
  .catch(reason => console.log('failure'))
//=> success
```

この実行結果は、「success」になり、`resolve`が尊重されたかたちになった。

## 実験2: `reject`→`resolve`の順で呼んでみる

今度は逆に、`reject`のほうを先に呼び出してみることにする。

```js
new Promise((resolve, reject) => {
	reject()
	resolve()
}).then(value => console.log('success'))
  .catch(reason => console.log('failure'))
//=> failure
```

今度の結果は「failure」になった。`reject`のほうが採用されたことが分かる。

## 結論: 先に呼ばれたほうが採用される

「Promiseの`resolve`と`reject`の両方を呼び出したらどうなってしまうのか？」の疑問への答えとしては、「先に呼ばれたほうが採用される」ということになりそうだ。

## 余談: 先勝ちと言っても、処理が中断されるわけではない

ちなみに、`resolve`と`reject`どちらかが採用されるとは言え、`Promise`に渡したexecuterの処理が中断されるわけではない。例えば、下記のコードでは、①で`resolve`が採用されるが、そのあとの②③の行も実行される。

```js
new Promise((resolve, reject) => {
	resolve() // ①
	console.log('after resolve') // ②
	reject() // ③
}).then(value => console.log('success'))
```

## Learn more

* [非同期処理:コールバック/Promise/Async Function · JavaScript Primer #jsprimer](https://jsprimer.net/basic/async/#promise-status)
プロジェクトファイルについて

# はじめに
e2studioでのプロジェクト内に生成されるファイルについての記述．

# プロジェクト内のファイル
### generateフォルダ
ファイル名 > 内容：備考

- dbsct.c > セクションの初期化処理(テーブル)
- hwsetup.c > ハードウェア初期化：初期化の内容をコーディング
- intprg.c > ベクタ関数の定義
- iodefine.h > レジスタ一覧
- resetprg.c > 初期設定ルーチン (リセットベクタ関数)：リセット直後に呼ばれる関数
- sbrk.c > 低水準インタフェースルーチン(sbrk関数)
- sbrk.h > 低水準インタフェースルーチン(sbrk関数のヘッダ)
- stacksct.h > スタックサイズの設定
- typedefine.h > 型定義ヘッダ
- vect.h > ベクタ関数のヘッダ
- vecttbl.c > 固定ベクタテーブル

### srcフォルダ

- *.c > main関数

### HardwareDebugフォルダ

- *.mot > 書き込み用ファイル

# resetprg.c

パワーオンリセットで、初期設定ルーチン`PowerON_Reset_PC`関数が呼び出される．この関数は，`main`関数を実行する前、および実行した後に必要な手続きを記述する関数でresetprg.c にある．`PowerON_Reset_PC`関数内には，main関数と`HardwareSetup`関数がある．ユーザーが取り扱うのは主にこの2つであり，`HardwareSetup`関数に初期化プログラムを書けるようにhwsetup.cが自動生成されている．が，main関数内で初期化しても良い．hwsetup.cにある`HardwareSetup`関数に初期化プログラムを書く場合は`PowerON_Reset_PC`関数のコメントを外す．

```resetprg.c                                                               

void PowerON_Reset_PC(void)
{ 

=== ここのコメントを外す↓ ====		
//	HardwareSetup();				// Use Hardware Setup


	main();

}
```

# 参考文献

- ファイルの構成 | CS+ V4.01.00 http://tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V4.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx08c0200y.html
- スタートアッププログラム | CS+ V4.01.00 http://tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V4.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx08c0300y.html
- RX631開発 プロジェクトファイルの確認と書き込み https://ccwo.hatenablog.jp/entry/2016/08/17/193731
【ActiveRecord】タブ区切りtsvをデータベーステーブルに登録する

#概要
アウトプット用に、学習した内容を紹介していきます。
本日はActiveRecordを用いて、タブ区切りtsvファイルのデータをローカルデータベースにあるテーブルに登録してみます。

#環境
Mac OS Mojave 10.14.6
Ruby 2.5.3
MySQL 5.7.28
ActiveRecord 6.0.1

#テーブル

以下のタブ区切りtsvで保存された表を、ActiveRecordでローカルデータベース内のテーブルに保存する事を考えます。

```posts.txt
user_id	content
1		Hello
1		World
2		I'm Paul.
4		😀
5		😂
```

最終的に以下の形でDBに登録されて欲しいです。

**postsテーブル**

|  id  |  user_id  |  content  |
|:---:|:---:|:---:|
| 1 |  1  |  Hello  |
| 2 |  1  |  World  |
| 3 |  2  |  I'm Paul.  |
| 4 |  4  |  😀  |
| 5 |  5  |  😂  |

#登録の流れ

それではまずtrainingというデータベースにpostsテーブルを作成します。
`use training;`でデータベースを選択しておきます。
また登録データに絵文字があるので、`ALTER DATABASE training CHARACTER SET utf8mb4;`などであらかじめ文字コードを変更しておきましょう。

postsテーブルを作成するのは以下のコードで作成します。

```
mysql> create table posts
    -> (id int auto_increment not null primary key,user_id int,content text);
```

```:出力
Query OK, 0 rows affected (0.01 sec)
```

idをauto_increment(自動的に番号を割り当て)のNULLを許さない主キーに設定し、user_idをint型、contentをtext型に設定します。


念の為テーブルを以下のコマンドで確認しておきます。

```
mysql> show columns from posts;
```
```:出力
+---------+---------+------+-----+---------+----------------+
| Field   | Type    | Null | Key | Default | Extra          |
+---------+---------+------+-----+---------+----------------+
| id      | int(11) | NO   | PRI | NULL    | auto_increment |
| user_id | int(11) | YES  |     | NULL    |                |
| content | text    | YES  |     | NULL    |                |
+---------+---------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
```
```
mysql> select * from posts;
```
```:出力
Empty set (0.00 sec)
```

無事設定したカラムで空のテーブルが作成されています。

それではここに、ActiveRecordを用いて先ほどのtsvデータを登録してみましょう。

```ruby:regist_to_posts.rb
require 'active_record'
FILE_PATH = './posts.txt'

# DB接続
ActiveRecord::Base.establish_connection(
  adapter: 'mysql2',
  host: 'localhost',
  username: 'root',
  password: 'password',
  database: 'training',
  encoding: 'utf8mb4'
)

# Postクラスーpostsテーブルの対応
class Post < ActiveRecord::Base
end

# posts.txtを開く
file = File.open(FILE_PATH)
# 一行目はカラム名なので飛ばす
file.readline
# 一行ずつpostsに追加
file.each do |line|
  post = line.chomp.split("\t")
  Post.create(
    user_id: post[0],
    content: post[1]
  )
end
```

`#DB接続`の部分が、DBに接続するための呪文です。

そこから下でActiveRecord::Baseクラスを継承したPostクラスを用意しています。これでActiveRecord::Baseを継承したPostのクラスメソッドを通じてpostsテーブルへアクセスできるようになります。命名規則に従っているため、postsというテーブル名がコードに出てくることなくpostsテーブルへのレコードが登録できます。

そこから下は、postsテーブルにデータを追加していくコードです。
ちなみに`require 'CSV'`しておくと、

```ruby:
table = CSV.table(FILE_PATH, col_sep: "\t")
table.each do |line|
  Post.create(line.to_hash)
end
```

といったスッキリしたコードで書くことができます。

それでは実行してみましょう。

```
$ ruby regist_to_posts.rb
```
```:出力
```

ターミナルには何も出力されませんが、テーブルには書き込まれています。
コード中に`ActiveRecord::Base.logger = Logger.new(STDERR)`を記述しておくとログが見れるのでおすすめです。

本当に登録できているのかテーブルを確認しに行きます。

```
mysql> select * from posts;
```

```:出力
+----+---------+-----------+
| id | user_id | content   |
+----+---------+-----------+
|  1 |       1 | Hello     |
|  2 |       1 | World     |
|  3 |       2 | I'm Paul. |
|  4 |       4 | 😀          |
|  5 |       5 | 😂          |
+----+---------+-----------+
5 rows in set (0.00 sec)
```

無事に登録できたようです。
【クラウド初心者向け】AWSアカウント作成後にやった方が良い初期設定（改善提案）

# 改善提案の確認
- TrustedAdvisorは、運用実績から学んだベストプラクティスを活用しています。
- AWS環境を検査し、システムの可用性とパフォーマンスを向上させたりセキュリティギャップを埋める機会がある場合には、推奨事項を提案する。

## 使用ユーザー
- IAMユーザー

## 手順
1. AWSにサインインします。
    1. アカウント、ユーザー名、パスワードを入力してサインインします。  
     [アカウント内（IAM）で作成したユーザーを使用してコンソールにサインインする](https://qiita.com/echolimitless/items/129495c920217916a14f#%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E5%86%85iam%E3%81%A7%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9F%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%81%AB%E3%82%B5%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%B3%E3%81%99%E3%82%8B)

1. 『AWSマネジメントコンソール』画面にある「サービスを検索」にTrustedAdvisorと入力し、検索結果から《TrustedAdvisor》をクリックし、TrustedAdvisorコンソール[（https://console.aws.amazon.com/trustedadvisor/）](https://console.aws.amazon.com/trustedadvisor/)を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/af54deea-9334-c1e2-66ca-ebff7ea181fa.png)

1. 『trustedadvisorコンソール』画面に各種改善提案が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/3098b429-b932-5a0f-082c-cf05e1a6b531.png)

# 参考サイト
- [AWS Trusted Advisor](https://docs.aws.amazon.com/ja_jp/awssupport/latest/user/getting-started.html#trusted-advisor)

# 目次に戻る
- [【クラウド初心者向け】Amazon Connectでコールセンターを作る](https://qiita.com/echolimitless/items/e5044c73656f8ae29f93#%E7%9B%AE%E6%AC%A1)
【クラウド初心者向け】AWSアカウント作成後にやった方が良い初期設定（脅威監視）

# 脅威監視の設定
- GuardDutyは、CloudTrailイベントログ、VPCフローログ、DNSログを分析し、疑わしいアクティビティーを検知するサービスです。

## 使用ユーザー
-  IAMユーザー

## 手順
1. AWSにサインインします。
    1. アカウント、ユーザー名、パスワードを入力してサインインします。  
     [アカウント内（IAM）で作成したユーザーを使用してコンソールにサインインする](https://qiita.com/echolimitless/items/129495c920217916a14f#%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E5%86%85iam%E3%81%A7%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9F%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%81%AB%E3%82%B5%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%B3%E3%81%99%E3%82%8B)

1. 『AWSマネジメントコンソール』画面にある「サービスを検索」にGuardDutyと入力し、検索結果から《GuardDuty》をクリックし、GuardDutyコンソール[（https://console.aws.amazon.com/guardduty/）](https://console.aws.amazon.com/guardduty/)を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/b11c866b-c07e-ace7-6fbd-3b1b94f94bbf.png)

1. AWS Configコンソールを初めて開く場合や新しいリージョンで開く場合に、次のページが表示されるので《今すぐ始める》をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/42fc1305-f822-5b5f-ceae-bcbbab0b3933.png)

1. 《GuardDutyの有効化》をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/af3e2a36-25e0-a8f0-0ffa-a57e3eaaa116.png)

1. 『GuardDutyコンソール』画面に脅威監視の結果が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/1aa609de-e6cc-c872-4162-19ae8affdebc.png)

# 参考サイト
- [Amazon GuardDuty とは](https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/what-is-guardduty.html)
- [GuardDuty のセットアップ](https://docs.aws.amazon.com/ja_jp/guardduty/latest/ug/guardduty_settingup.html)

# 目次に戻る
- [【クラウド初心者向け】Amazon Connectでコールセンターを作る](https://qiita.com/echolimitless/items/e5044c73656f8ae29f93#%E7%9B%AE%E6%AC%A1)
[Kotlin] Android Studioで簡単に非同期処理

# はじめに
AndroidアプリでHTTPリクエストをしようとするとメインスレッドでやるなと言われるので、手っ取り早く解決する方法を一応メモ。

# 環境
- Android Studio
    - 3.5.1
- Kotlin
    - 1.3.50

HTTPリクエストするならインターネット通信のパーミッションを取るのを忘れずに！

```xml:AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
```

# コード
メインスレッドでやらなければいいので、Threadクラスで別スレッドを作成すればOK。
今回はとりあえずHTTPリクエストをしてみる。

```kotlin:sample.kt
Thread {
    // ここは非同期処理
    val url = URL("https://www.google.com")
    val httpCone = url.openConnection() as HttpURLConnection
    httpCone.requestMethod = "GET"
    httpCone.connect()
    if (httpCone.responseCode in 200 .. 299) {
        val resIS = httpCone.inputStream
        val resReader = BufferedInputStream(resIS).bufferedReader()
        Log.d("LOG", resReader.readLine())
    }

}.start()
```

# まとめ
とりあえず非同期処理を行いたい場合は、`Thread`を使えばいいと思う。
本格的に使うのであれば、`AsyncTask`や`AsyncTaskLoader`を使うべきなのかな？
なぜ開発環境をVM＋Dockerで構築するのか

業務で仮想マシン（VM：VirtualBOX）上でdocker-composeを動かして開発を行っているので、そのメリット／デメリットについて書いてみようと思います。


# メリット①：インフラが可視化できる

VMおよびシステムの構成が以下に集約されるため、どんなソフトを使っているか、どんなアーキテクチャ構成になっているかが分かりやすいです。
また、バージョンを指定してインストールしておけば、バージョン違いによる動作不良なんかも防げます。

- VMの構成：`Vagrantfile`
- システム構成：`docker-compose.yml`


# メリット②：バージョン管理できる

`Vagrantfile`も`docker-compose.yml`もテキストファイルのため、Git等のバージョン管理ツールで管理することができます。



# メリット③：環境の複製が容易

VirtualBOXとVagrantをインストールしておけば開発環境を簡単に複製することができます。
1時間もあれば環境が作れてしまいます。

メンバーが増える場合などに、環境構築に1日以上かけるなんてことがなくなります。

## 構築手順（例）

- VT-xの有効化（BIOSの設定が必要です）
- VirtualBOXとvagrant、Gitのインストール
- Vagrantfileをクローン
- `vagrant up`を実行

この時点で開発環境の構築は完了

- `vagrant ssh`でVMにssh接続
- `git clone xxxxxx`でプロジェクトをクローン
    - docker-compose.ymlが入っているものとする
- `cd xxx && docker-compose up`でプロジェクト起動


これだけで環境構築＆プロジェクトの起動が完了します。



# メリット④：本番環境に近い環境で開発ができる

Windows上で開発する場合、本番や検証環境へデプロイした後にOS依存の不具合が発生することがあります。
開発時から本番と同じOSを使うことでOS依存の不具合を早い段階で回避することができます。


# その他のメリット

- プロジェクトが終わったらVMを破棄するだけで、ホストOSはクリーンな状態を保てる
- 動かなくなったらVMを破棄して作り直せば良い


# デメリット

## 最初に作る人が大変

最初に環境を作る人は結構大変です。
慣れてる人であればスラスラかけるかもしれませんが、ナレッジのないチームで1から作る場合は結構時間がかかると思います。

最初は単純なVMを立ち上げて、VM内でプロジェクトに必要なツールを`yum install`して、それらのコマンドをVagrantfileに書いていけばよいと思います。

## なんかよくわかんないけど、動いてる状態になる

Vagrantfileを作った人以外は、なんかよくわかんないけど環境出来たという状況になりがち。
有識者がいなくなるとメンテできなくなる可能性が高い。。





# 最後に

Vagrantfileができあがるまでは大変ですが、一度できてしまえば楽なのでおススメです。
今後メンバーが増えることが確定している場合などは特に良いですね！

時間があればVagrantfileのプラクティスなんかも書いてみたいと思います。
データ構造の破棄の仕方

今回はコードはナシです。

#データ構造について
データ構造を考えるのは楽しい作業ですね。
ヘンな構造作って、ムフフっていうのも一興です。
プログラミングなんてそこらに落ちてる構造使えばできないということはないですし、ちょっと手数が増える程度で可読性を考えたほうが後々良いでしょう。

#データ構造とは。
データを持つときにどういうつながりで所持すると、うまく問題を解くことができるかという問題です。
ツリーとかグラフとか線形とか色々すでに出ています。

#データ構造の破棄。
意外とノウハウが無いのはデータ構造の破棄じゃないでしょうか。
個人的には端を作って端から構造内のデータ等を吸い上げて収束させることを考えます。
特にツリーなんかは一番端の葉から潰していきます。

#概念図
えーっと、構造はたくさんありますが、今回は二つの潰し方を図示してみました。
![EJBclR6U8AIC53m[2].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509227/8b02833b-d421-db06-07b2-c9dcab1bc0c2.png)
![EJBPlbQUYAAnh2p[1].png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509227/382360fe-1385-7bb5-69f1-44821cb55845.png)

#終わりに。
今回の概念図は自分のツイッターにあげてあるのをパクってきました。なので、どこかで見たことあるかもしれません。
とりあえず、破棄は末端から情報を吸い上げつつ中央へ潰していきましょう。

以上。
canvas要素の描画を任意のタイミングで切り替えたい



##はじめに
canvas要素を最前面に配置したかったが、アプリ起動時からcanvasを展開すると裏の要素の操作ができなくなってしまいます。
なお描画するエフェクト（紙吹雪）は[jsdo.it](http://jsdo.it/)にあったものを利用しました。
（現在は閉鎖されてしまっているようです）

##環境
- Mac OS X EL Capitan 10.14.5


##解決策
紙吹雪を描画する関数内では`setInterval`関数が用いられおり、それによって継続的な動作が行われていました。以下が実際のコードです。

`setInterval(draw, 20);`

20msごとにdraw関数を呼び出す処理が行われています。この処理を止めるためには、`setInterval`に対応する`clearInterval`を用いました。

描画を停止することでcanvasを消し、下の要素への操作が可能になりました。

##実装例

今回はアプリ内で任意の箇所をクリックした時に描画を停止できるよう、外部の関数として停止処理を実装しました。

```js
var carryout;


function celebrate() {


  function draw{
/*
    描画処理は省略
*/
  }

//20msごとに描画繰り返し
    carryout = setInterval(draw, 20);


}

//呼び出された時にIntervalを破棄
function stopDraw() {
    clearInterval(carryout);
}

```

この関数をクリック時に呼び出すことで停止処理を実現することができた。

##デモ

以下のように任意のタイミングでcanvasのオンオフを切り替えることができます。

![canpas.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/516709/91d2a4ec-c2ee-4bb4-a911-b1a6a846fcee.gif)


##終わりに
他にも実装方法がありそうだと思ったが、Interval関数が使われている場合これが一番簡単に実装できそう。
止まり方が少し不自然かも？
カリー化関数と部分適用の使いどころを考える

複数の引数を取る関数が、以下のように特定の変数だけ変わる偏った呼ばれ方をすることが想定される場合、

``` javascript
someFunc(hoge,piyo,1);
someFunc(hoge,piyo,2);
someFunc(hoge,piyo,3);
someFunc(hoge,piyo,4);
someFunc(hoge,piyo,5);
```

こんな感じにカリー化した関数があると、
部分適用した関数を利用してすっきりと書ける。

``` javascript
const curriedSomeFunc = (hoge,piyo) => (num) => {
  someFunc(hoge,piyo,num);  
}
const partiallyApplied = curriedSomeFunc(hoge,piyo);
partiallyApplied(1);
partiallyApplied(2);
partiallyApplied(3);
partiallyApplied(4);
partiallyApplied(5);

```

普通は通常の関数のみを外部に公開するけれども、
ユースケースが明らかに偏りそうな場合はカリー化関数も併せて出してあげると親切かもしれない。
GitLab(無料版)を使ったDevOps環境を考えてみる

業務でGitLabを使い始めて数か月たちますが、思いのほか良かったのでメモがてら運用ルールを残しておこうかと思います。
（GitLabの回し者ではないです。。）

# GitLabとは

元々はGitHubのオンプレ版のような認識をされていたようですが、独自進化して今やDevOpsツールとして成長を遂げています。

DevOpsに必要な機能はGitLabに備わってるよ！的なことが書いてありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/32ebf0e2-a2bc-a978-f52e-8e46ab0e4055.png)
引用：https://www.gitlab.jp/comparison/

また、このページでは各ツールとGitLabを比較し、GitLabでできること／できないことを一覧で見れるので導入時に必要な機能があるか確認できるのも良いところですね。


# GitLabの良いところ
- オンプレで構築できる
- いつまでも無料で利用できる
- 無料プランで結構やれる
- 小規模くらいのプロジェクトであればGitLabだけで完結できる（と思う）



# GitLabの使い方

## Wiki

README.mdに書くようなことではないけど、残しておいたほうが良さそうな資料をここに書いておくと良いかも。


## リポジトリ

よくあるGitのホスティングサービスですね。

### ブランチルール

GitLab Flowの「[Production branch with GitLab flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html#production-branch-with-gitlab-flow)」がシンプルで良いと思います。

|ブランチ名|用途|備考|
|---|---|---|
|production|本番環境用ブランチ|直接のマージ、プッシュ禁止|
|master|ステージング環境用ブランチ|直接のマージ、プッシュ禁止|
|feature/xxx|作業ブランチ||

- リポジトリ設定にて、productionとmasterは直接編集を禁止にしておきます
    - 少人数なら運用でカバーでも良いかもしれないですが、念のため。。。


## Issue

Issueでタスク管理を行います。
Issueは実作業レベル（1日～長くて1週間程度）の粒度に分割して作成します。

Issueのコメントで`/estimate 2d`のように入力すると、見積もり工数を入れることもできるので、ストーリーポイント的に使ってもよいかもしれません。

### ラベル

有料プランでないとEpic機能がつかえないので、アジャイル開発の場合はラベルでどうにかする必要があります。
以下のような分け方をすると良いかも？


|種別|ラベル名|色|
|---|---|---|
|Epic|EP -XXXXX-|紫|
|User Story|US -XXXXX-|緑|

※いちいちラベルつけるの結構めんどくさいので、かなり付け忘れます。。。


### Board

カンバンボードです。
タスクの見える化に、大いに役立ちます。

デフォルトではOpenとCloseの2つしかリストがないので、以下のようなリスト構成にします

|リスト名|内容|
|---|---|
|open|バックログ|
|List -対応予定-|スプリントバックログとして使用|
|List -対応中-|対応中のIssue|
|close|完了済みのIssue|


### Milestone

スプリントとして利用します。
IssueにMilestoneを設定することができます。
スプリント（1～2週間程度）ごとにMilestoneを作成し、その週に対応するIssueにMilestoneを設定します。


## Merge Request

GitHubで言うところのプルリクエストです。
コードレビューはここで実施します。
~~※無料版の場合は承認者を設定できないため、問題なければイイネする等のルール決めが必要です~~
（2021/07/02追記）
最新版ではReviewer機能も無料で使えるようになりました

なお、masterやproductionへのマージの際は必ずマージリクエストを介して行うようにします。
また、マージリクエストの前後でGitLab CIを動かすこともできます


## GitLab CI

いわゆるCIツールです。
テストや各環境へのデプロイの自動化を行うことができます。

※オンプレの場合はGitLab-Runnerを自分で作成する必要があるため注意が必要です。
（ハマった時のメモを[コチラ](https://qiita.com/teracy55/items/2f9ecaafc0a042c1f6df)に残してますので、ハマったら参考にしてください。。）

- Herokuでステージング／本番環境を構築する場合は[コチラ](https://qiita.com/teracy55/items/2f9ecaafc0a042c1f6df#heroku%E3%81%B8%E3%81%AE%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4)をご覧ください。
- マージリクエスト作成時（マージ前）にパイプラインを動かしたい場合は[コチラ](https://qiita.com/teracy55/items/41f65100fc534a5a750f)をご覧ください。



# 作業フロー（例）

スクラム＋チケット駆動を意識した運用を考えます。


## 1スプリントごと

- 次のスプリント用のMilestoneを作成
- そのスプリントで対応するIssueに作成したMilestoneを設定
- Boardで対象Issueを`List-対応予定-`（スプリントバックログ）に入れます

※前スプリント（Milestone）のIssueが残っている場合はMilestoneを更新する
　

## 日々の作業

- 対応するIssueから「Create Merge Request」押下し、以下を作成
    - 作業ブランチ（feature/xxxxという名前で作っておく）
    - WIP状態のマージリクエスト
- ローカルで作業ブランチに切り替え、作業
    - コミットする際は`#123 xxxxxxx`のようにコメント内にIssueIDをつけるとGitLabのコミット一覧から直接Issueに飛べるので便利です
- 作業完了後、リモートへプッシュし、IssueのWIPをはずす（`Resolve WIP status`ボタンを押下する）
- レビューアに連絡
    - 補足事項等はIssueかマージリクエストに記載する 
- 問題なければマージ
- GitLab CIにより、自動でテスト⇒デプロイ












# 最後に

無料版のGitLabでも結構やれるな～という印象を受けました。
すべての機能を使ったわけではないですが、小規模なプロジェクトであれば十分すぎる機能を備えていると思います。
データ抽出時につい調べてしまうSQL構文

##■やりたいこと
1．抽出したデータをそのままエクセル等に貼り付けした際に、文字列に改行が入っていると行がずれてしまうことがあるので、改行コードを削除して抽出。

2．特定の区切文字を含んだ文字列を、区切文字で分割して抽出。（例：A|B|C）


##■利用している環境
Microsoft SQLServer 2014

##■解決方法
#####1．改行コードの削除
削除したい改行コードは以下となります。
    - CR：CHAR(13)
    - LF：CHAR(10)
Replace関数を2度利用し、改行コードを削除していきます。
	
```SQL
Select  REPLACE(REPLACE(Column1, CHAR(13), ''), CHAR(10), '') From Table1 
```


#####2.文字列を特定の区切文字で分割

1. CHARINDEX関数でColumn1の文字列に存在する区切文字を検索して、最初に見つかった位置を取得します。
2. SUBSTRING関数でColumn1の区切文字以前を取得します。
※区切文字以降の文字を取得したい場合は最初の区切文字以降を指定することで取得はできます。

```SQL
Select SUBSTRING( Column1, 1, CHARINDEX( 区切文字 , Column1 ) - 1 ) From Table1 
```

##■試してみる
普通に抽出した場合(before)と関数を使って抽出した場合(after)でテストしてみます。

```SQL
Select 
	REPLACE
		(REPLACE(
		'ABC
		DEF
		GHI'
		,CHAR(13), '')
	,CHAR(10), '') 
```

結果
![SnapCrab_NoName_2019-10-25_20-11-7_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439865/8d40d64b-2500-d431-228f-6442fe49d799.png)



↓今回は縦線「｜」を区切文字として文字列を分割しました。

```SQL
Select SUBSTRING( 'ABC|DEF', 1, CHARINDEX( '|', 'ABC|DEF' ) - 1 ) 
```

結果
![SnapCrab_NoName_2019-10-25_20-11-23_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439865/f44f94b1-a54f-e4b6-2b7a-5586b9c07b61.png)


##■補足
文字列区切りに関して、今回は配列として扱うほどではない文字列であったが、
配列として分割したい場合は関数がないので、SQL文を自作して実装が必要になります。
※Microsoft SQLServer 2016以降であれば、STRING_SPLIT という関数が利用可能となっているようです。
ROS2をアンインストールする

#概要
ROS2をアンインストールする。

#環境
- ubuntu 18.04 LTS
- ROS2(ros-dashing-desktop)

#手順

###1.パッケージ消去
今回はdashingで行いましたが、おそらくバージョン名を書き換えることで他のバージョンでも利用可能です。また、purgeコマンドで設定ファイルも消しています。

```bash:terminal
sudo apt purge -y ros-dashing-*
sudo apt -y autoremove
```

###2.bashの設定ファイルの記述を消去
以下の記述を消去します。

```diff:.bashrc
source /opt/ros/dashing/setup.bash
```

###3.再起動
```bash:terminal
sudo reboot
```

#参考文献
- https://answers.ros.org/question/57213/how-i-completely-remove-all-ros-from-my-system/
IBM CloudのDelivery PipelineでPHPUnitを実行する方法

CI/CDを考える上で、外せないのがテストの自動化ですよね。
自身が更新したアプリケーションを、デプロイする前に最低限のチェックをかけたい、というのは誰もが抱く思いでしょう。
`IBM Cloud`でも、CI/CDを一瞬で構築できるの仕組みがあり非常に重宝します。
今回の記事では、私がよく使っている`PHPUnit`を使って自動でテストする方法をご紹介します。

### 自動テストを実現する２つの方法
1. 外部CI/CDサービスを使って実現する 
    `Github`と`Travis CI`等の外部CI/CDツールを使って、`Pull Request`がマージされる前にテストを実行して確認しよう！というものです。
実は既に、[PHP アプリケーションを自動的にテストして IBM Cloud にデプロイする](https://www.ibm.com/developerworks/jp/cloud/library/cl-bluemix-test-deploy-php-apps-automatically/index.html)という記事があります。割とオーソドックスなのはこちらの方法かと思いますので、ぜひ、ご一読ください。

2. Delivery Pipeline内で直接テスト環境を用意してテストを実行する
`Delivery Pipeline`では、自分でシェルを書くことができます。テストステップを追加して、中に下記のシェルを書くだけで、phpunitをDeployする前に実行することができます。
何らかの事情により、外部サービスが使えない時などに、役にたつ**かもしれない**テクニックですね！
もちろん、他の言語でもシェルの中でプログラムの実行環境をセットアップすれば:ok:です。

### PHPUnit環境構築シェル
```bash
#!/bin/bash
#まずはPHPと関連するextentionをinstall
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install -y php7.2 php7.2-fpm php7.2-mysql php7.2-mbstring php7.2-zip php7.2-xml
#composerをinstall
curl -sS https://getcomposer.org/installer | php
#必要なパッケージをinstall
php composer.phar install
#ここでテストを起動します
php vendor/phpunit/phpunit/phpunit tests/StackTest.php
```

### テストに成功した場合
<img width="1117" alt="スクリーンショット 2019-11-12 18.45.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/8b896cc0-6cae-97a5-fbe1-e1f528b97665.png">

### テストに失敗した場合
<img width="1139" alt="スクリーンショット 2019-11-12 18.53.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154110/907f7621-c63b-8dcc-d4f3-2ae26c2bce03.png">

#### 上記シェルの実行Log(抜粋)
きちんと`PHP Unit`が実行されている事がわかります。

```
There was 1 failure:

1) StackTest::testPushAndPop
Failed asserting that 0 is identical to 1.

/home/pipeline/c7703b7e-15e2-47fd-ba16-ef57ecd30f0f/tests/StackTest.php:9

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.
WARNING: No file found for the pattern: tests/TEST-*.xml . Not uploading test results.
WARNING: No file found for the pattern: target/site/jacoco/jacoco.xml . Not uploading test results.

Finished: FAILED
```
geocoderで緯度と経度が登録されない問題

# バージョン

```ruby:Gemfile.lock
geocoder (1.5.2)
```

# 起きたこと

[README](https://github.com/alexreisner/geocoder)を読んだ通りにやったのに、いくら住所を登録しても`latitude`と`longitude`がnullのままで登録される気配がない。

確認してみたこと

- `address`や`latitude`、`longitude`のカラム名をTypoしてないか？
-  `latitude`と`longitude`をfloat型で定義したか？
-  モデルに`geocoded_by :address`と`after_validation :geocode`を記述したか？
-  そもそもGemをInstallした？

で上記は全部ちゃんとできていました。

# 原因

`bin/rails c`で色々叩いてみてそれとなく原因が分かりました。

```irb
[1] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12-5渋谷マークシティ")
=> nil
[2] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12-5")
=> nil
[3] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12")
=> nil
[4] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1")
=> nil
[5] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂")
=> [35.6588903, 139.6975169]
[6] pry(main)> Geocoder.coordinates("東京都渋谷区")
=> [35.6645956, 139.6987107]
```

railsのアプリ上では「東京都渋谷区道玄坂1-12-5渋谷マークシティ」で登録しようとしていたのですが、そもそもその住所だと緯度と経度を取得できていないことが分かりました。

# 解決策

`geocoder`のデフォルトのgeocoding serviceはnominatimを使用しており
このAPIの精度だと上記の結果になるようです。
これをgoogleのAPIに変更することにより精度を上げることができます。
以下の手順で使用サービスをgoogleに変更してあげましょう。

- configファイルを作成する

```sh
$ bin/rails g geocoder:config
```

- configの設定

`config/initializers/geocoder.rb`が作成されるので編集する。
(※googleのAPI KEYを取得しておく必要があります)

```ruby
Geocoder.configure(
  # Geocoding options
  # timeout: 3,                 # geocoding service timeout (secs)
  lookup: :google,              # name of geocoding service (symbol)
  # ip_lookup: :ipinfo_io,      # name of IP address geocoding service (symbol)
  # language: :en,              # ISO-639 language code
  use_https: true,              # use HTTPS for lookup requests? (if supported)
  # http_proxy: nil,            # HTTP proxy server (user:pass@host:port)
  # https_proxy: nil,           # HTTPS proxy server (user:pass@host:port)
  api_key: {your google api key},
  # cache: nil,                 # cache object (must respond to #[], #[]=, and #del)
  # cache_prefix: 'geocoder:',  # prefix (string) to use for all cache keys

  # Exceptions that should not be rescued by default
  # (if you want to implement custom error handling);
  # supports SocketError and Timeout::Error
  # always_raise: [],

  # Calculation options
  # units: :mi,                 # :km for kilometers or :mi for miles
  # distances: :linear          # :spherical or :linear
)
```

これで、再度コンソール上で叩くと…

```irb
[1] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12-5渋谷マークシティ")
=> [35.6581487, 139.6979397]
[2] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12-5")
=> [35.6577383, 139.6973389]
[3] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1-12")
=> [35.6579443, 139.6979978]
[4] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂1")
=> [35.65751710000001, 139.6994338]
[5] pry(main)> Geocoder.coordinates("東京都渋谷区道玄坂")
=> [35.6581518, 139.6981574]
[6] pry(main)> Geocoder.coordinates("東京都渋谷区")
=> [35.6619707, 139.703795]
```
となり、しっかり緯度と経度が取得できていることが分かります。
【クラウド初心者向け】AWSアカウント作成後にやった方が良い初期設定（準拠法、管轄裁判所設定）

# 準拠法と管轄裁判所の変更
- 準拠する法律を日本の法律に変更する。
- 第一審裁判所を東京地方裁判所に変更する。

## 使用ユーザー
-  ルートユーザー

## 手順
1. AWSにサインインします。
    1. Eメールアドレスとパスワードを入力してサインインします。  
     [ルートユーザーを使用してコンソールにサインインする](https://qiita.com/echolimitless/items/129495c920217916a14f#%E3%83%AB%E3%83%BC%E3%83%88%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%A6%E3%82%B3%E3%83%B3%E3%82%BD%E3%83%BC%E3%83%AB%E3%81%AB%E3%82%B5%E3%82%A4%E3%83%B3%E3%82%A4%E3%83%B3%E3%81%99%E3%82%8B)

1. 『AWSマネジメントコンソール』画面にある「サービスを検索」にartifactと入力し、検索結果から《AWS Artifact》をクリックし、AWS Artifact コンソール（https://console.aws.amazon.com/artifact/）を開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/f3737c00-1fd8-62e9-9b0f-925154ecff33.png)

1. 『AWS Artifactコンソール』画面のメニューから《契約》をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/cb130b87-11ed-4e79-4210-0cc3a5ce3e0a.png)

1. 《日本準拠法に関するAWSカスタマーアグリーメント変更契約 をダウンロードして確認する》をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/e156a368-6414-d84c-bea9-02400315e799.png)

1. 説明が表示されるので内容を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/c10a91ae-571e-726c-a20f-9eec3693a834.png)

1. 内容確認後、「NDA を確認済みで、同意する場合はここをチェックしてください」のチェックボックスをチェックし、《NDA に同意し、日本準拠法に関するAWSカスタマーアグリーメント変更契約 をダウンロードする》をクリックします。PDFファイルがダウンロードされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/eaf36fc0-5706-1cd3-4e1c-831fbd08e0a7.png)

1. 「本変更契約の条件をダウンロードし確認した。」、「本変更契約の条件に同意する」、「本変更契約の条件は機密事項であること並びにAWS Artifact NDA秘密保持契約に服することを了解し、これに同意する。」のチェックボックスをチェックし、《このアカウントの日本準拠法に関するAWSカスタマーアグリーメント変更契約に同意する》をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/c12c232c-2cda-d1ee-344f-13947b41c50c.png)

1. 契約状態がアクティブになり準拠法と管轄裁判所の変更ができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520689/341855e0-fb61-042f-aeeb-2eee54f1dec3.png)

# 参考サイト
- [AWS Artifact とは](https://docs.aws.amazon.com/ja_jp/artifact/latest/ug/what-is-aws-artifact.html)

# 目次に戻る
- [【クラウド初心者向け】Amazon Connectでコールセンターを作る](https://qiita.com/echolimitless/items/e5044c73656f8ae29f93#%E7%9B%AE%E6%AC%A1)
DDD+CQRSで、クエリでも使う業務知識はロールにしてみる(DCI的な)

#はじめに
[DDD+CQRSで実装すると業務知識がドメインサービスにばかりいってしまう(気がする)][]で悩んでいた時に、
[境界づけられたコンテキストをDCIで考えてみる](https://qiita.com/kwhrkzk/items/0f0af84a51d3a6173946)でDCIについて勉強したところ、
クエリで取得したDTOにロールを与えれば良いんじゃないの？と思ったので投稿してみます。

#前提
[DDD+CQRSで実装すると業務知識がドメインサービスにばかりいってしまう(気がする)][]で話していた利益率計算についての続きです。

ざっくり書くと
![a.png](https://camo.qiitausercontent.com/2de00d99d4b57183e96a7ce8c7a364cc2bf277c9/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3130393330322f37646432636264662d653638652d313132622d316535322d3261356666326464356634312e706e67)
のように利益率計算に関するメソッドをエンティティに入れちゃうとクエリ側で使用するの大変だよねって話です。なのでドメインサービスに置くしかないかなと思ってました。
![b.png](https://camo.qiitausercontent.com/561764b7017f3a9379f4769bb0615b16df6e91a1/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3130393330322f39333134656431652d643165622d313433652d343863302d6336653437333335626664332e706e67)

けど利益率に関するメソッドが増えてきたら何を使えば良いかわからなくなりそうな気がしていました。


#ドメインサービスに散らばっていた利益率に関する知識をロールにまとめる

そこで出会ったのがDCIという考え方。自分の中ではデータクラスにロール(役割)を与えるイメージです。文脈によってロールを切り替えてユースケースを実現します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/54f2fd1e-b9c1-f3f9-d9d5-11e31ee5d6e2.png)
[](
@startuml
abstract class 値オブジェクト
class 商品ID << (V,#FF7700) >> {
+ Create(GUID): 商品ID {static}
}
class 原価 << (V,#FF7700) >> {
+ Create(double): 原価 {static}
}
class 利益率 << (V,#FF7700) >> {
+ Create(double): 利益率 {static}
}
class 売値 << (V,#FF7700) >> {
+ Create(double): 売値 {static}
}
商品ID --|> 値オブジェクト
原価 --|> 値オブジェクト
利益率 --|> 値オブジェクト
売値 --|> 値オブジェクト
interface I利益率を計算するロール {
+ 原価
+ 利益率
+ 売値
+ 売値を計算する(): 売値
+ 売値を計算する(原価, 利益率): 売値
+ 原価を計算する(): 原価
+ 原価を計算する(売値, 利益率): 原価
+ 利益率を計算する(原価, 売値): 利益率
+ 利益率を取得する(商品ID): 利益率
}
note bottom of I利益率を計算するロール : メソッドはデフォルト実装する
class 商品 <<Aggrigate>> {
- 商品ID
- 原価
- 利益率
- 売値
+ Get原価
+ Get利益率
+ Get売値
+ Create(商品ID, 原価): 商品 {static}
}
商品ID -down-o 商品
原価 -down-o 商品
利益率 -down-o 商品
売値 -down-o 商品
商品 --|> I利益率を計算するロール
@enduml
)


こんな感じで**I利益率を取得する**とか**I利益率計算**とか利益率に関する業務知識がドメインサービスに散らばっていたのを**I利益率を計算するロール**という役割としてまとめちゃいます。

そうすれば[DDD+CQRSで実装すると業務知識がドメインサービスにばかりいってしまう(気がする)][]で問題にしていた

> しかしエンティティ内に記述してしまうと、別の場所で利益率計算をしたくなったときに困ります。
> たとえば利益率がn%だったときの原価と売値の一覧を画面に表示したいといった場合、
> CQRS的なクエリでエンティティを介さずDTOに包んで値を取得したときに利益率計算をしようと思っても出来ません。

もDTOを定義する際に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109302/efc35d69-2dbf-552f-d705-476aa648f52c.png)
[](
@startuml
interface I利益率を計算するロール {
+ 原価
+ 利益率
+ 売値
+ 売値を計算する(): 売値
+ 売値を計算する(原価, 利益率): 売値
+ 原価を計算する(): 原価
+ 原価を計算する(売値, 利益率): 原価
+ 利益率を計算する(原価, 売値): 利益率
+ 利益率を取得する(商品ID): 利益率
}
note bottom of I利益率を計算するロール : メソッドはデフォルト実装する
class DTO {
+ 原価
+ 利益率
+ 売値
}
DTO --|> I利益率を計算するロール
@enduml
)

のように**I利益率を計算するロール**を継承してしまえばクエリ側でも業務知識を無理なく使える気がします。

#まとめ

* エンティティでしか使わない業務知識はエンティティに実装する
* クエリ(CQRS的な)でも使用する業務知識はドメインサービスとして実装する
* 業務知識としてロール(役割)としてまとめることができるのならばロールを用意する

と思ったんですけどどうでしょうか。


[DDD+CQRSで実装すると業務知識がドメインサービスにばかりいってしまう(気がする)]:https://qiita.com/kwhrkzk/items/905c1ea277260f453fff
GCEのメモリ使用状況をモニタする

GCP/GCEはドキュメントが整備されており、たいていの必要な情報はきっちりドキュメント化されている。

しかし膨大なドキュメントの、どこに欲しい情報があるのか、意外に見つけられない/見つけるまで時間がかかることがよくある。

# メトリクスの監視

インスタンス詳細画面の「モニタリング」タブでは、デフォルトでCPU、ネットワーク、ディスクI/Oなどいくつかのメトリクスの監視ができる。

メモリの使用状況など、その他のメトリクスを監視しようと、Stackdriverを開き、メトリクスを追加するも、グラフ上に「`No data is available for the selected time frame`」と表示されてしまう。

# Monitoringエージェントのインストール

実は、GCEのデフォルトの状態だと、まだメモリ等の監視はできない。「Monitoringエージェント」を追加でインストールする必要がある。

> Monitoring エージェントの使用は必須ではありませんが、使用することをおすすめします。Monitoring は、Monitoring エージェントがなくても、CPU 使用率、一部のディスク トラフィック指標、ネットワーク トラフィック、稼働時間情報などのいくつかの指標にアクセスできます。Monitoring エージェントを使用すると、Monitoring から仮想マシン（VM）インスタンス上のその他のシステム リソースやアプリケーション サービスにアクセス可能になります。これらの追加機能が必要な場合は、Monitoring エージェントをインストールする必要があります。

[Monitoring エージェントの概要](https://cloud.google.com/monitoring/agent/)より

そこで、次のドキュメントに従い、Monitoringエージェントをインストールする。

- [Monitoring エージェントのインストール](https://cloud.google.com/monitoring/agent/install-agent)


# メトリクスの追加

Stackdriverの画面を開き、チャートの追加などの操作で、次のようにメトリクスを選択する。

|項目|値|備考|
|---|---|---|
|Resource type|`GCE VM Instance`||
|Metric|`Memory utilization`|識別子は`agent.googleapis.com/memory/percent_used`|

こんな感じで表示されればOK。

<img width="559" alt="screenshot.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/66742/cbcf2a4d-7994-ec7d-b582-5f1fb6945fd5.png">

# トラブルシュート

Stackdriverをインストールしたのに、メトリクスの監視ができないことがある。公式ドキュメントでトラブルシュートが公開されている。

- [エージェントのインストールのトラブルシューティング](https://cloud.google.com/monitoring/agent/troubleshooting)

以下のQiitaの記事も参考になる。

- [GCP Stackdriver Agent 起動が失敗するケース Marketplace 経由で作成したVMは注意](https://qiita.com/koshilife/items/9eea5b5e073cf96a077a)
CI/CDの基本

CI/CDという言葉も色々なところで耳にするが、バズワードになっているのではないだろうかという気もしています。
とっかかりの方を対象に、なるべく簡単にまとめたいと思います。
また、AWSにはCI/CDを実現するための複数のサービスがリリースされていますが、それぞれどのような役割を担っているのか、合わせて整理したいと思います。

インターネット上に同じようなサイトはありますが、一応。


# CI/CDの種類

そもそも、CI/CDは、開発からデプロイまでにおける一連のプロセスに関する、自動化についての設計種別になります。
継続的デプロイとかの言葉を耳にされたことがあるかもですが、以下の３種の総称になります。
- Continuous Integration
- Continuous Delivery
- Continuous Deployment
（なので、厳密に言えば、CI/CD/CDや、CI/CDsって表記してもいいようにも思います）

下に行くほどカバーする自動化フェーズが広くなります。
図で表すと以下のようになります。

![CI_CD.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51320/d8cb43bd-d301-4896-5b4a-7510760cba66.png)

個人的には、Continuous DeliveryからContinuous Deploymentの心理的ハードルが高い気がします。


# CI/CDのツール

CI/CDは上記のようにプロセスのため、ツールは必須ではないですが、現実的にツールを使わないと辛いと思います。
Travics CI、Circle CIやJenkins、GitLabいろいろあり、それぞれに特徴がありますので、要件から選んでもらえれば。

機会があれば、別の投稿にてツールの紹介もしたいと思います。
SQL~少し詳しく~

#はじめに
以前、SQLとはなんぞやという記事を書いたので、
この記事では、１歩だけ進んだ、具体的な操作を紹介します。

##データの追加
INSERTでデータを追加挿入することができます。

例)
```
INSERT INTO students(id, name, course)
VALUES(4, "Kate", "java");
```
idカルムのようなAUTO INCREMENTの部分は、
省略することができます。

##データの削除
```
DELETE FROM テーブル名
WHERE id=7;
```
のように、WHEREで指定してあげることで、
特定のレコードを削除できます。

WHEREで指定し忘れてしまうと、
すべてのレコードが削除されてしまうので、
気をつけましょう。

##データの更新
UPDATEも用いて、
```
UPDATE　テーブル名
SET name="Jordan", course="HTML"
WHERE id=6;
```
というように、
更新するレコードをWHEREで指定することができます。
WHEREで指定しないと、カルム内の全データが更新されてしまします。

UPDATE実行後はデータを戻すことができないので、
実行前に一度SELECEを実行して、
操作するデータを確認することが大切です。

##GROUP BYを用いる場合のSELECT
SELECTで使えるのは、
GROUP BYに指定しているカラム名と、集計関数のみです。

##書く順番
テーブルの指定　FROM
結合　ON JOIN
取得条件　WHERE
グループ化　GROUP BY
関数　演算因子
HAVING
検索 SELECT, DISTINCT
順序 ORDER BY
LIMIT lIMIT

です。

##複数のテーブルを結合する
テーブルAとテーブルBを結合する場合、
```
SELECT *
FROM テーブルA
JOIN テーブルB
ON 結合条件
```

と記載します。

結合条件は、
```ON テーブル名.カルム名=テーブル名.カルム名```
です。

LEFT JOIN とすると、
NULLのレコードのものも取得することができます。

##参考
progate　SQL
特定のディレクトリ配下のファイル一覧を作成する方法【フルパス＆ファイル名のみ】

参照：
https://yumeyame.com/filelist_command

####方法：コマンドプロンプトで取得する
以下の方法で指定したディレクトリ配下のファイル一覧を作成できます。
コマンド
dir c:\work /b /s /a-d
オプションの意味
b：ファイル名だけを表示する
s：サブディレクトリも対象にする
a-d：フォルダ以外を表示する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3783/586a6821-120c-68ee-f7b5-13e1dca9dd2a.png)
sort_byを使用してみて


あるタブ区切りのtxtが存在した時に最後のカラムである年齢順に並べたい時にsort_byメソッドを使いました。
その中で詰まってしまった部分も紹介します。

```ruby:meibo.txt
john	m	18
paul	m	20
alice	f	15
dabid	m	17
jasmin	f	17
```
```ruby:sort_by.rb
personal_data = []

File.foreach("meibo.txt"){|line|
  personal_data << line.split(" ")
}
personal_data.sort_by!{|person| 
  person[2]
}
personal_data.each {|output|
  puts output.join("\t")
}

```

このように出した場合はうまくいくが、配列のpaulの年齢を2にした場合

```
alice	f	15
dabid	m	17
jasmin	f	17
john	m	18
paul	m	2
```
という結果になりました。
これは配列の値をsort_byの時点では文字列でしか捉えていないので整数値としなければならないので

```ruby:sort_by.rb
personal_data = []

File.foreach("meibo.txt"){|line|
  personal_data << line.split(" ")
}
personal_data.sort_by!{|person| 
  person[2].to_i
}
personal_data.each {|output|
  puts output.join("\t")
}

```
として整数値にしてから年齢順にするためにsort_byを使用した結果

```
paul	m	2
alice	f	15
dabid	m	17
jasmin	f	17
john	m	18
```
欲しい結果が得られました。
文字列、整数値は今後も気をつけていきたいと感じました。
VisualStudioでAntを使ってNativeなAPKを作ってみる

<font color="DeepPink">※2019/11/13 Gradle版の記事もアップいたしました。詳しくは [こちら](https://qiita.com/furui/items/59b5a290b2539bd0c8c3) をご御覧ください。</font>

# はじめに
CEDEC2019 の「[玄人向けAndroid/iOS対応エンジン 開発レポート](https://cedec.cesa.or.jp/2019/session/detail/s5c9877b2970eb)」というセッションにて VisualStudioでもGradleを使ったNativeアプリが作れるという話を聞きました。
かなり前から私がやりたかったことでしたので早速試してみました。

# ブレイクポイントが止まらない
VisualStudioとGradleで色々試しNativeアプリは作れましたが、どうやってもブレイクポイントが止まりませんでした。
これではVisualStudioの旨味がかなり減ってしまいます。
ということで違う方法を模索しました。

# VisualStudioとAnt
NativeActivityも試してみましたが、Android向けの広告などがJavaのライブラリの物が多くC++オンリーでの開発はかなり不向きな環境でした。
複数のプラットフォームに対応する上でVisualStudioで開発できることが私の環境では望ましかったため、VisualStudio上のAntで開発する方向で落ち着きました。

# 開発環境
- OS : Windows 10
- Visual Studio 2017 Professional

# プロジェクトの準備

### 1. Antプロジェクトの作成
「**Android**」という名前でプロジェクトを作っています。
![00.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75533/04872078-ac2e-6e49-4400-ad6c9b8e601f.gif)

### 2. Sharedライブラリ用のプロジェクトの作成
「**Shared**」という名前でプロジェクトを作っています。
![01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75533/1e962020-d690-e729-827d-ec506ddd1018.gif)

### 3. Sharedライブラリをantプロジェクトに紐付ける
![02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75533/fd0212db-c4c7-dc46-7a74-9b11ddd5a6f0.gif)

この段階でソリューションのビルドを行い、ビルドが通れば設定完了です。

# JNIで繫いで動作確認

ここからはJavaとNativeを繫いでブレイクポイントが止まるか確認してみます。
2つのファイルに下記コードを追記します。

``` Android.java
public class Android extends Activity
{
    // 追記
    static {
        System.loadLibrary("SharedProject");
    }
    native void NativeTest(int value);

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        /* Create a TextView and set its text to "Hello world" */
        TextView  tv = new TextView(this);
        tv.setText("Hello World!");
        setContentView(tv);

        // 追記
        NativeTest(123);
    }
}
```

``` Shared.cpp
extern "C" {
    // 追記
    JNIEXPORT void JNICALL Java_com_Android_Android_NativeTest(JNIEnv* env, jobject, jint value)
    {
        LOGI("test [%d]", value);
    }
}
```

# 動作確認
上記を追記したらAndroid端末とPCを繋ぎ、実行してみます。
![03.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75533/fe944cc8-fabe-697f-5019-42f69e742a6a.gif)

ブレイクポイントを貼ったところで止まり、変数の中身が見えていることが確認できました。

# まとめ
VisualStudio & Gradle で開発ができるのが理想ですが、どうしても難しい場合は VisualStudio & Ant でも行けそうです。
VisualStudio & Gradle でもブレイクポイントがうまく止まったらまた記事にしてあげようと思います。
VisualStudioでAndroidのNative開発している文献があまりにも少ないのでもう少し世の中に増えていくといいなと思いました。
Qwiklabs(Google CloudとAWSのラボ環境)について

# Qwiklabsとは

これ
https://www.qwiklabs.com/?locale=ja

GoogleCloudとAWSのラボ環境を一時的に払い出してくれて、ハンズオンができるサービス。

# ラボ

[ラボのカタログ](https://www.qwiklabs.com/catalog)
 
 - レベルや長さ、料金、言語などでフィルターかけられる
 - 無料のラボもある 例: [Introduction to AWS Lambda](https://www.qwiklabs.com/focuses/6431?parent=catalog)
 - 日本語に対応しているラボもある
 - 全サービスあるわけじゃない(例えばCognito関連のラボ探したけどなかった)
 - クエストっていう「テーマに沿っていくつかラボを集めたやつ」もある。

# クレジットの仕組み

https://support.google.com/qwiklabs/answer/9139480?hl=ja

チャージしたクレジットの有効期限は6ヵ月

クレジットはグループ間で共有できるらしい
https://support.google.com/qwiklabs/answer/9120705

$55で１ヶ月ラボやり放題(Advantage Subscription)
$495で1年間ラボやり放題とかもある
**サブスクリプションで自動更新される点は注意**

見た感じ、1ラボ 0〜35クレジットぐらい(1クレジット=$1 まとめて購入でディスカウントあり)


# やってみた感想

むかし何かのトレーニングで初めてQWIKLABSを触ったとき、時間に追われ焦りながら終わらせたときはあんまり有用に思えなかったが、あとで再度理解するために能動的に自分でやるラボ決めてやったり、じっくり手順理解しながらやると、だいぶ理解の助けになった。

ドキュメントベースで学んだ後、さぁ手を動かすぞという時に１から自分でやるのもいいがラボ活用するのもありだなぁと思った。リソース消し忘れとか気にしなくていいし。

リソースのクリーンナップや料金を気にするのは必要なことなので、そこ気にする必要がないのはメリットでもありデメリットでもある。

## アウトプット

あまり触れたことのなかった「GCPの触り」と「AWSのビッグデータ周り」はQwiklabsも活用して学び、以下の資格もとることができました。

 - [Google Cloud Associate Cloud Engineer](https://cloud.google.com/certification/cloud-engineer?hl=ja)
 - [AWS Big Data Specialty](https://aws.amazon.com/jp/certification/certified-big-data-specialty/)


# メンバー加入時のトレーニングとして

英語が苦手じゃなければ、稟議でAdvantage Subscriptionを買って適したクエストやってみてもらって
ラボのあと内容説明してもらったり、少しカスタムしたものを自分で検証アカウントに１から構築してもらうのもいいかも。

ラボ繰り返しやったり、他にも気になるラボあればできるので Advantage Subscriptionがいいと思う。
Subscriptionは自動更新される点は注意(2回目)


# 参考リンク
[Qwiklabsヘルプ](https://support.google.com/qwiklabs/?hl=ja#topic=9114857)
GitHub Actionsで一定間隔ごとにAtCoderのレーティングのグラフを撮ってみた

## はじめに
先日AtCoderを始めた[@wawawatataru](https://twitter.com/wawawatataru)と申します。
レートはまだ茶色にすら到達していませんが楽しく参加しています。
![screenshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23369/2bb11d6c-411d-3e5e-aec2-64b305d51920.png)
と、AtCoder参加者の方には上図のようなレーティングの画像をTwitterなどで投稿している方も多いと思います。

今回はこの作業を今後やらなくてもいいように自動化したいと考え以下の対応をおこないました。

* GitHub Actionsを利用し、一定間隔ごとにAtCoderのレーティング画像を取得
* GitHub Pagesで上記の画像をOGPに設定したページを作成
* OGPを設定したページのURLをTwitterに投稿し固定ツイートにする

上記対応を行うと、下のツイートのようにOGPが自動で更新される（はず）ツイートを行うことができるので、
固定ツイートに設定するだけで、何度もツイートせずに自分のレートを表示することができます。

**実際のツイート**
https://twitter.com/wawawatataru/status/1194150708099964928
<img src="https://github.com/wawawatataru/atcoder_ogp/blob/master/docs/image/sample.png?raw=true" width="400px">

**できていないこと**
OGPの更新方法を完全に理解できていません。
[Card validator](https://cards-dev.twitter.com/validator)でOGPのキャッシュが削除されるという記載を見たのですが、画像更新後、OGPがすぐに更新されることもあれば、Card validatorを使用しても更新されないこともありました……。
詳しい方、教えてください。

### 実際のコード
[atcoder_ogp](https://github.com/wawawatataru/atcoder_ogp)

### レーティング画像の取得
レーティング画像はPythonでSeleniumを用いて行っています。
[capture_rate.py](https://github.com/wawawatataru/atcoder_ogp/blob/master/capture_rate.py)

```
def capture_atcoder_rating():
    …
    driver.get("https://atcoder.jp/users/wawawatataru")
    driver.set_window_size(1920, 1080)
    driver.find_element_by_id("rating-graph-expand").click()
    png = driver.find_element_by_class_name("mt-2").screenshot_as_png
    …
```
AtCoderでは`https://atcoder.jp/users/user_name`で`user_name`のプロフィールページなので、そのページのCSSクラスが`.mt-2`の部分のスクリーンショットを保存しています。
そうするとページ上部のレーティングの画像が保存できます。

TwitterのOGPは1.91:1の割合の画像のため、コード内では`resize_image()`で1.91:1になるように白で塗りつぶしています。

### OGPの設定
GitHub Pagesに設定している`index.html`内で行っています。

```
<head>
    …
    <meta property="og:title" content="AtCoderRating">
    <meta property="og:type" content="website">
    <meta property="og:url" content="https://wawawatataru.github.io/atcoder_ogp">
    <meta property="og:image" content="https://wawawatataru.github.io/atcoder_ogp/image/screenshot.png">
    <meta property="og:site_name" content="">
    <meta property="og:description" content="AtCoderのレーティングです。">

    <meta name="twitter:card" content="summary_large_image">
    …
</head>
```

### GitHub Actionsの設定
基本的には参考記事の通りに行いました。
一定時間ごとにActionsを実行したかったため、`.github/workflows/capture.yml`で実行間隔を設定しています。

```
on:
  schedule:
    - cron: "0 1 * * *"
```

ワークフローをトリガーするイベントに関しては公式の[ヘルプ](https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows#scheduled-events)にも記載があるため、そちらをもとに、毎日実行されるように設定しています。

### 参考にさせていただいた記事
[【GitHub Actions】自作Actionsのリリースを自動化する](https://qiita.com/homines22/items/92ee4efe4317bb5a30ad)
[Github Actionsで遊んでみた](https://qiita.com/sirotosiko/items/011a4d3af160ca90e30d)
[Dockerを使ってHeadless Chromeを動かしてみる](https://qiita.com/dd511805/items/dfe03c5486bf1421875a)
[Dockerでheadless-chromeを使ったスクレイピング環境を整える](https://qiita.com/rotelstift/items/7dafcdcae3ca18b65b26)
ホームボタンがスクロールしてもついてくるように。 ❏CSS❏

#【結論】 position: fixed;

縦長のページで、下にスクロールしてもヘッダーやボタンなどを追従させたい時。

例）

```scss:index.scss
.home_button {
  position: fixed;
  top: 10px;
  right: 10px;
  略
}
```

これだけで勝手に追従してくれます。
top,right,left,bottomで固定させたい位置を指定できます。
今回の例ではホームボタンを左上に固定させました。

<br>
CSSだけで簡単に実装できるので非常に便利です！
初めてのRegex（正規表現）

未来電子テクノロジーでインターンをしているtokky08です。
初めてRegexについて勉強したのでアウトプットとして書いていきます。

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#Regexって何？
情報系の学部ですがRegexについて初めて勉強しました。聞いたこともないし、見たこともありませんでした。では、Regexとは何かということで、「いくつかの文字列を一つの形式で表現するための表現方法」のことを指します。とりあえず例を見ていった方が早いと思います。

#正規表現の書き方

| 文字 | 説明 |
|:---:|:---:|
| \t  | タブ |
| \r  | 改行 |
| \n  | 改行 |
| \d  | 数字（0-9）|
| \D  | 数字意外|
| \s  | 空白文字|
| \S  | 空白文字以外|
| \w  | アルファベット・アンダーバー・数字|
| \W  | アルファベット・アンダーバー・数字意外|
| .   | 任意の一文字|
| +   | 直前の文字を1回以上繰り返す|
| *   | 直前の文字を0回以上繰り返す|
| ?   | 直前の文字を0または、1回繰り返す|
| {n} | 直前の文字をn回繰り返す|
|{x,y}| 直前の文字をx以上y以下繰り返す|
|{x,} | 直前の文字をx以上繰り返す|
|{,y} | 直前の文字をy以下繰り返す|
| ^   | 行の先頭|
| $   | 行の末尾|
|[a,b,c]|aまたはbまたはc|
|[^a,b,c]|a,b,c以外|

ざっとこのような書き方があります。

#具体的な例

```
[0-9]{3}-[0-9]{4}
```
>一致結果例
123-4567
098-1234
412-5237


`home/desktop/regex/index.txt`
上記ディレクトリパスのみに一致するように指定を行う。

```
^.*/
```


#まとめ

正規表現は膨大なデータを扱うときに便利なことが分かりました。
覚えることは多いですが、実際に実践的に使っていきたいですね。
WordPressを使ったサイト制作でよくやるカスタマイズ

前回は「[WordPressを使ったサイト制作標準フロー](https://qiita.com/koji-yamauchi/items/394c8e111dcd14a5d311)」として環境周りのことをご紹介しましたが、今回はWordPressをベースとしたよくやるカスタマイズの一例をご紹介します。

## 不要なウィジェット削除

WordPressは汎用性を重視して作られていますが、一般的なコーポレートサイトやオウンドメディアを構築するにあたって、すぐには必要としない機能も多くあります。
クライアントが管理画面を操作するときになるべくわかりやすくするために不要なものは無効化しましょう。

不要なデフォルトウィジェットは `unregister_widget` によって削除出来ます。

```
function my_widgets_init() {
	unregister_widget( 'WP_Widget_Pages' );            // 固定ページ
	unregister_widget( 'WP_Widget_Calendar' );         // カレンダー
	unregister_widget( 'WP_Widget_Archives' );         // アーカイブ
	unregister_widget( 'WP_Widget_Meta' );             // メタ情報
	unregister_widget( 'WP_Widget_Search' );           // 検索
	unregister_widget( 'WP_Widget_Text' );             // テキスト
	unregister_widget( 'WP_Widget_Categories' );       // カテゴリー
	unregister_widget( 'WP_Widget_Recent_Posts' );     // 最近の投稿
	unregister_widget( 'WP_Widget_Recent_Comments' );  // 最近のコメント
	unregister_widget( 'WP_Widget_RSS' );              // RSS
	unregister_widget( 'WP_Widget_Tag_Cloud' );        // タグクラウド
	unregister_widget( 'WP_Nav_Menu_Widget' );         // カスタムメニュー
	unregister_widget( 'WP_Widget_Media_Video' );      // 動画
	unregister_widget( 'WP_Widget_Media_Image' );      // 画像
	unregister_widget( 'WP_Widget_Media_Audio' );      // 音声
	unregister_widget( 'WP_Widget_Media_Gallery' );    // ギャラリー
}
add_action( 'widgets_init', 'my_widgets_init' );
```

# ビジュアルモードエディタでのタグ自動削除回避

投稿画面でビジュアルモードに切り替えると `<span>` タグなどが自動的に削除されますが、下記の記述で回避可能です。

```
function my_tiny_mce_before_init( $init_array ) {
    $init_array['valid_elements']          = '*[*]';
    $init_array['extended_valid_elements'] = '*[*]';
    return $init_array;
}
add_filter( 'tiny_mce_before_init' , 'my_tiny_mce_before_init' );
```

# 投稿画面のカテゴリ階層表示

投稿画面でカテゴリの階層構造を保って表示するようにします。

```
function my_wp_terms_checklist_args( $args, $post_id = null ) {
  $args['checked_ontop'] = false;
  return $args;
}
add_action( 'wp_terms_checklist_args', 'my_wp_terms_checklist_args' );
```

# RSSフィールドでの複数ページ結合

`<!--nextpage-->` により記事を複数分割している場合でもRSSには全文表示する必要がある場合は下記のようにします。

```
add_filter( 'content_pagination', function ( $pages, $post ) {
	if ( is_feed() && 1 < count( $pages ) ) {
		$content = implode( "\n\n", $pages );
		$pages   = array( $content );
	}
	return $pages;
}, 10, 2 );
```