OmniAICreator/Qiita-1.07M huggingface dataset:
mackerelを用いたAWS EC2 リソースの監視とアラート発生時のSlack 通知

# はじめに
本記事では、SaaS型のサーバ監視サービスであるMackerelを用いて、EC2インスタンスのリソースを監視し、アラートをSlack通知する方法を記載します。

## Mackerelアカウントの作成
Mackerelのアカウントが未作成であれば、[ココ](https://mackerel.io/ja/)からアカウントを作成

## EC2インスタンスへのMackerelエージェントのインストール
1. MackerelのダッシュボードでHostsを選択し、「エージェントをインストール」をクリック
![mack1.png](https://qiita-image-store.s3.amazonaws.com/0/234000/d097a8e2-8a32-89bf-0587-e533a8aa9707.png)

2. インストール対象を選択すると、コマンド例(赤枠。API Keyは省略)が表示されるので、監視対象とするEC2インスタンス上でコマンドを実行。
これでエージェントのインストールは完了。
![aws.png](https://qiita-image-store.s3.amazonaws.com/0/234000/1129fb84-7cf8-d167-f304-e47fc1f66438.png)

## Slackでの通知設定
1.アラートを通知するSlackワークスペースのApp管理画面へ移動。(https://[your-workspace-name].slack.com/apps/manage)
2.「Appディレクトリを検索」のテキストボックスに-> 「Incoming Webhook」と入力し、設定を追加。
3. アラートを通知したい、Slackのチャネルを選択し、「Incoming Webhookインテグレーションの追加」をクリック。
![webhook.png](https://qiita-image-store.s3.amazonaws.com/0/234000/80b68ea0-3e67-04b8-0473-9fec01e590f2.png)
4. Mackerel上の設定で必要となるので、Webhook URL(赤枠)を控えておく
![hook2.png](https://qiita-image-store.s3.amazonaws.com/0/234000/2fc68e50-8a4b-16aa-4a6b-55430379e142.png)

## Mackerelでの通知設定
1. MackerelのダッシュボードでMonitorsを選択し、「チャンネル設定」->「通知チャンネルを追加」-> Slackを選択し、チャンネル名やアラートメッセージを入力。URL項目には、先ほど控えた Webhook URLをペーストし、「作成」をクリック。
![slack2.png](https://qiita-image-store.s3.amazonaws.com/0/234000/3a75c349-41e5-eb74-e87b-b18f4d36419d.png)

## Mackerelでの監視ルール作成
1. MackerelのダッシュボードでMonitorsを選択し、「監視ルール」を追加をクリック
2. 以下の画面の通り設定。加えて、任意の監視ルール名を入力し、「作成」ボタンをクリック

(**※今回はアラート通知を行うテストであるため、閾値や平均値監視はかなり低めに設定。運用時は適宜パラメータを見直す必要がある**)
![rule.png](https://qiita-image-store.s3.amazonaws.com/0/234000/02f58b78-f9cd-e3dc-bf33-c35fa56ae5aa.png)

## 通知の確認
上記の監視ルールに基づき、閾値を超えた場合、Slackに通知がくることを確認
![notification.png](https://qiita-image-store.s3.amazonaws.com/0/234000/cf9e5383-3d57-8e3d-ce81-b47050052f3f.png)
[Flutter] FlatButton 間の空白をなくす

## 結論
[materialTapTargetSize](https://docs.flutter.io/flutter/material/MaterialTapTargetSize-class.html) プロパティで、`shrinkWrap` を指定すればいける

```dart
FlatButton(
      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, // これ
      child: Text("sample"),
      color: Colors.red,
      onPressed: () => print("sample"),
    );
```

> padded → const MaterialTapTargetSize
Expands the minimum tap target size to 48px by 48px.
This is the default value of ThemeData.materialHitTestSize and the recommended size to conform to Android accessibility scanner recommendations.
GitHub - リポジトリの作成 #2

## GitHubを実際に使用してみる
### リポジトリの作成
「New repository」で、新規作成ページへ

- `Repository name`  
リポジトリの名前を入力
- `Description`  
リポジトリの説明を入力。任意。
- `Public,Private`<br>リポジトリを公開するか、非公開するかの設定。
- `Initialize this repository with a README`<br>リポジトリの初期化とREADMEファイルの設置が行われ、すぐにcloneできるようになる。ローカルの既存のGitリポジトリを登録する場合は、チェックを外して、手動でpushする。
- `Add.gitignore`<br>使用するフレームワークを選択することで、管理不要なファイルを.gitignoreファイルに記述してくれる。

「Create repository」で完成。

### その後の大まかな流れ
```terminal:ターミナル
// 作成したリポジトリを開発環境にクローンする
git clone {リポジトリのURL}

// 開発
// コミットする(ローカル側のリポジトリの更新)
git add {ファイル名 or .(すべて)}
git commit -m "コミットメッセージ"
// コミットの確認
git log

// pushする（GitHub側のリポジトリの更新)
git push
```
Ubuntu18.04にNVIDIAドライバーをインストール

Ubuntu18.04でNVIDIAドライバを入れるのがぐっとかんたんになった。

# 推奨ドライバ確認

まずはUbuntu大先生のおすすめのドライバを確認。

```bash
$ sudo ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd000013BBsv000010DEsd00001098bc03sc00i00
vendor   : NVIDIA Corporation
model    : GM107GL [Quadro K620]
driver   : nvidia-340 - distro non-free
driver   : nvidia-driver-390 - distro non-free recommended
driver   : xserver-xorg-video-nouveau - distro free builtin
```

自分のマシンのGPUの型番がmodelに正しく出力されていることを確認。

# インストール

以下のコマンドでUbuntu大先生おすすめのドライバをインストール。

```bash
$ sudo ubuntu-drivers autoinstall
```

# 動作確認

再起動して以下のコマンドを実行。

```bash
$ nvidia-smi 
Sun Mar  3 20:49:35 2019       
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 390.77                 Driver Version: 390.77                    |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  Quadro K620         Off  | 00000000:01:00.0  On |                  N/A |
| 34%   47C    P0     2W /  30W |    134MiB /  2000MiB |      0%      Default |
+-------------------------------+----------------------+----------------------+
                                                                               
+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1068      G   /usr/lib/xorg/Xorg                            65MiB |
|    0      1208      G   /usr/bin/gnome-shell                          66MiB |
+-----------------------------------------------------------------------------+
```

神かよ。

# 参考文献

https://linuxconfig.org/how-to-install-the-nvidia-drivers-on-ubuntu-18-04-bionic-beaver-linux
プロジェクトマネジメント観点で見るデイリースクラム

前回記事
[スクラム開発におけるプロジェクトマネジメント](https://qiita.com/purimaru/items/1a560923d2947dd17c2b)

## はじめに
1月1投稿という計画が早いものであっという間に2月も末になってしまったこともあり
今回は短めにデイリースクラムに関して、前回記事から引き続き読み解いてまとめていきます。

## デイリースクラム
デイリースクラムとは、開発チームのための 15 分間のタイムボックスのイベントである。
スプリントでは、毎日デイリースクラムを開催する。開発チームは、次の 24 時間の作業を計画する。
前回のデイリースクラムから行なった作業の検査と今後のスプリント作業の予想をすることで、
チームのコラボレーションやパフォーマンスを最適化するのである。
デイリースクラムは毎日、同じ時間・場所で開催し、複雑にならないようにする。

引用元 : [The Scrum Guide](https://www.scrumguides.org/docs/scrumguide/v2017/2017-Scrum-Guide-Japanese.pdf#zoom=100)

### プロジェクトマネジメントの観点に当てはめる

スクラムガイドに即して考えると以下でしょうか。
コストに関してはスプリントあたりのコストはおおよそ固定になるため不要かもしれません。
スプリントゴールの達成できる範囲の中でスコープのコントロールも追加になることもあるでしょう。

- 次の24時間の作業を計画する
  - スケジュールの作成(タイムマネジメント×計画)
- 前回のデイリースクラムから行った作業の検査
  - スケジュールのコントロール(タイムマネジメント×監視,統制)<br>->実際に行った作業と前回のデイリースクラムで行った計画との乖離からスケジュールの予測を立てる
  - コストのコントロール(コストマネジメント×監視,統制)<br>->実際に作業に要したコスト(時間)と作業に必要と予想したコストとの乖離からコストの予測を立てる

チームによっては議論や質問を行うケースもあり、スクラムガイドにも記載のある以下の例を使用したとする。
> 私や開発チームがスプリントゴールを達成する上で、障害となる物を目撃したか？

上記の質問を契機にリスク(顕在化したものを含む)の特定と分析、対応計画を立てることになるため
リスクマネジメントにおける計画と統制,監視の役割を持つこともあるでしょう。

単純にスクラムガイドの最低限の記述のみを当てはめると15分間の軽量なイベントということもあり多くの役割を持つものではないように見えます。
しかし、スプリント内の諸活動におけるモニタリングと最適化を担うことになるため
実際にはスケジュールやコストの検査から阻害要因やリスクを発見し、次の24時間に向けて適正化・対策を実施することが必要になり
その内容によっては上記で挙げた以上の知識エリアの統制を保つことになるかもしれません。

### まとめ
|知識エリア |立ち上げ |計画 |実行 |監視,統制 |終結 |
|---|---|---|---|---|---|
|統合||||||
|スコープ||**スプリントプランニング(topic1)**||||
|タイム||**スプリントプランニング(topic2)**<br>**デイリースクラム**||**デイリースクラム**||
|コスト||**スプリントプランニング(topic2)**||**デイリースクラム**||
|品質||||||
|人的資源||||||
|コミュニケーション||||||
|リスク||||**デイリースクラム**||
|調達||||||
|ステークホルダー||||||

### 最後に
今回は時間に追われてとりとめの無い文章になってしまったかもしれません。この記事を投稿した時点で2月31日(3月3日)なので3月分は充分に構成と考え校正してから投稿するよう反省です。

デイリースクラムは毎日同じ時間に開催し、同じ質問で構成されることが多いため最もマンネリ化しやすいイベントだと感じています。
しかし、アジャイルな開発において日々の検査・適応を行うことでアジャイルな計画作りをしていくは欠かせない活動でもあるため
スクラムガイドの例に固執し惰性でイベントを行うのではなく、イベントが持つ役割や意味をそれぞれのチームが考え
それを全うするために使う構成(質問)を作り、そのチームに合った形でイベント自体が最適化していきたいものです。
vscode-cfn-lintを入れてもUnable to start cfn-lintが表示されてうまくいかない

## 概要
[vscode-cfn-lint](https://github.com/awslabs/aws-cfn-lint-visual-studio-code)を入れたつもりが以下のエラーが出てうまく動かない！ちなみに環境は`windows 10`です。
![cfn-lint_error.jpg](https://qiita-image-store.s3.amazonaws.com/0/239750/9c1c6589-a520-5080-b129-376a8c087135.jpeg)


## 対応方法
１．ちゃんと`cfn-lint`を入れる。
[公式ドキュメンタリー](https://github.com/awslabs/aws-cfn-lint-visual-studio-code#requirements)を見てください。僕みたいに何も考えてないやつは、GUIでインストールした気になってここをちゃんと読んでいない。
>Requires cfn-lint to be installed: pip install cfn-lint


２．Pathを通す
`pip`してもエラーメッセージが出ちゃうときはPathを通します。
`setting.json`に以下追記するか、GUIの`settings`から[Extensions]-[CloudFormation Linter Configuration]-[Cfn Lint: Path]にcfn-lintのPathを記載します。

```json
"cfnLint.path": "[cfn-lint.exeのフルパス]"
```

私は、[chocolatey](https://chocolatey.org/) で、[anaconda](https://www.anaconda.com/) をインストールするとかしてたので、`C:\\tools\\Anaconda3\\Scripts\\cfn-lint.exe`になりました。


## まとめ
私みたいにちゃんと読まない読めない人のご助力になれば幸いです。入れたら超便利ですよね。

### 参考
[Cannot start cfn-lint in VSCode #21](https://github.com/awslabs/aws-cfn-lint-visual-studio-code/issues/21)
Githubpages(Users page)に独自ドメインでVueの環境構築するまで

# TL;DR

* GitbubpagesにVueでのサイトを構築したい
* ついでに独自ドメインも有効にしたい
* Githubpagesにはuser pageとproject pageがあるが、今回はuser pageを使いたい
* user pageだと、/docをルートとすることができない
* ↑これらの問題を解決した備忘録
* 多分あんまりよろしくない方式だが、とりあえず取り削ぎする必要があった

# 環境

* MacOS Mojave 1.14.2
* @vue/cli (version 3系)

# githubpagesを有効にする

* 通常、`username`というユーザが`portfolio`という名のリポジトリでgithubpagesを作成すると、URLは`https://username.github.io/portfolio/`というURLになる
<img width="735" alt="スクリーンショット 2019-03-03 20.09.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/341127/94f503a8-89eb-1c33-55f2-ec412a039913.png">

* `https://username.github.io`でアクセスできるようにするには、`username.github.io`という名のリポジトリを作成してgithubpagesにしなければいけない。
<img width="738" alt="スクリーンショット 2019-03-03 20.14.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/341127/913b5cac-eeb4-fb3a-e11b-3e693c4979f6.png">

# 問題

## その１

よく見ると、`Source`の所が変更できなくなっている... Vueのビルド先が`docs`だとそれを見に行ってくれない...
すなわち、gitのルートに直接ビルド結果を設置しなければいけない
そのために`vue.config.js`を編集してこのようにしても

```js:vue.config.js
module.exports = {
    publicPath: process.env.NODE_ENV === 'production'
        ? '/hoge/'
        : '/',
    outputDir: '../',
};
```

`build`するときに`outputDir`を一度削除するらしく、つまり

```
. <- gitのルート
├── ... <- ココにビルド結果を置く
└── project-name <- プロジェクトのルート
    ├── ...
    └── vue.config.js
```

なディレクトリ構成のため、すべてが削除されてしまう問題が発生した
そのため、`outputDir: '../docs'`として、

```
. <- gitのルート
├── docs
│   └── ... <- ココにビルド結果を置く
└── project-name <- プロジェクトのルート
    ├── ...
    └── vue.config.js
```

するしかなくなった、ただ前述したとおり`user page`はそこを見に行ってくれないため、masterにだけdocsの中身のみを押し込む必要がある
その点に関して、 [ココ](https://qiita.com/kwappa/items/03ffdeb89039a7249619)を参照させていただいた。
要約すると

```
git push -f --delete origin master
git subtree push --prefix docs/ origin master
```
のように、masterを削除して、masterにsubtreeとしてdocsの中身だけをpushしてやるというお話
というわけである程度自動化するためにgitルートに

```sh:deploy.sh
#!/bin/sh
git checkout source
git push -f --delete origin master
git subtree push --prefix docs/ origin master
```
みたいなシェルスクリプトを置いて、動かしていくといい感じにやってくれると思った。

## その2

動いたように見えた、が、独自ドメインを使用したい場合に、その設定がmasterのgitルートに保存されている事がわかり、デプロイするごとに設定が解除されてしまう問題が発生した
今回使いたいドメインは`gccc.dev`のため、deployするときに`CNAME`というファイルにドメイン名(gccc.dev)を記述する必要がある


```sh:deploy.sh
#!/bin/sh
git checkout source
echo "gccc.dev" > ./docs/CNAME
git add -A ./docs/CNAME
git commit -m "deploy"
git push -f --delete origin master
git subtree push --prefix docs/ origin master
```
とした、するといい感じに設定も反映されて、`./deploy.sh`するだけで全部やってくれるようになった

# 未だ解決していない問題

* ビルドするごとにdocsの内容が変更されるために、sourceのコミットログが汚れる
    * sourceブランチのみ、docsの変更を無視する設定を書く方法が見当たらない
* デプロイするごとにCNAMEを生成してコミットしているため、sourceも汚れる
    * masterにcheckoutしてからCNAMEを生成してsubtreeしても結局master側が汚れる
* 毎回masterを削除しているため、masterのコミットログが残らない
    * subtreeは最初にしか指定できないっぽい？


あたまわるいので上記問題が解決できない...
というより根本的にもっと賢い解決方法はあると思うが、やはりあたまがわるいのでできなかった。
【Java】【SQLServer】SQLServer用JDBCを利用してローカルのSQLServer2017に接続する

備忘用に残しています
※時間があったらまとめます。

<b>環境</b>

<table>
<tr>
<td>種別</td>
<td>ツール名</td>
<td>備考</td>
</tr>
<tr>
<td>OS</td>
<td>Windows 10 Pro</td>
<td></td>
</tr>
<tr>
<td>IDE</td>
<td>Pleiades 2018</td>
<td>Javaのフルエディションを使用</td>
</tr>
<tr>
<td>Java</td>
<td>Java8</td>
<td></td>
</tr>
<tr>
<td>DB</td>
<td>SQL Server 2017 Developer</td>
<td></td>
</tr>
</table>


<b>SQLServer のJDBCをJavaプロジェクトに追加する</b>

①該当のバージョンのJDBCをダウンロード
②「C:\Program Files」に解凍
　※Microsoftは上記プログラムフォルダに保存することを推奨している模様
　※解凍したJDBCにあるinstall.txtで明記されています
③Eclipseのプロジェクトにて任意のフォルダに該当のJDBCのJARファイルを移動する
　※私は「mssql-jdbc-7.2.1.jre8.jar」を使用し、ファイルはコピーせずに「ファイルへのリンク」にしました
プロジェクト・エクスプローラーでJDBCを追加したいプロジェクトでコンテキストメニュー（右クリック）でプロパティ―を選択
④Java のビルド・パスで「ライブラリー」タブを選択し、「JAR の追加」ボタン押下
⑤JDBCを入れたフォルダを選択し、「OK」ボタン押下
⑥「適用して閉じる」ボタンを押下する


<b>エラー内容</b>

`com.microsoft.sqlserver.jdbc.SQLServerException: ホスト [servername]、ポート 1433 への TCP/IP 接続が失敗しました。エラー: "Connection refused: connect。接続プロパティを調べて、SQL Server のインスタンスがホスト上で実行されていて、ポートへの TCP/IP 接続が許可されており、そのポートへの TCP 接続がファイアウォールにブロックされていないことを確認してください。"。`

<b>原因</b>

記載の通り。
自分の場合は、SQL Server のTCP/IP 通信を許可していなかったため、上記エラーが発生していました。

<b>解決策</b>
※他の原因は時間ができたら記載します。

①Windows ＋ R で表示されるファイル名を指定して実行ダイアログにて「SQLServerManager14.msc」 でSQL Server 構成 マネージャー を起動する
②SQL Server 構成マネージャー > SQL Server ネットワークの構成 > MSSQLSERVER のプロトコルを選択し、TCP/IPを選択、コンテキストメニュー（右クリック表示）で有効化を選択
③SQL Server 構成マネージャー > SQL Server のサービス でSQL Server(MSSQLSERVER) を選択し、コンテキストメニュー（右クリック表示）で「再起動」を選択しSQL Serverのサービスを起動し直す
④下記コードを実行



接続確認用のテストコード
※任意の値に変更してください

```java:ConnectURL.java

package testdbconnection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class ConnectURL {
    public static void main(String[] args) {

        // Create a variable for the connection string.
        String connectionUrl = "jdbc:sqlserver://[servername:[port];databaseName=[dbname];user=[username];password=[password]";

        try (Connection con = DriverManager.getConnection(connectionUrl); Statement stmt = con.createStatement();) {
            String SQL = "SELECT TOP 10 * FROM [tablename]";
            ResultSet rs = stmt.executeQuery(SQL);

            // Iterate through the data in the result set and display it.
            while (rs.next()) {
                System.out.println(rs.getString("[columnname1]") + " " + rs.getString("[columnname2]"));
            }
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
            System.out.println("can't connectioned");
        }
    }
}
```
vagrant boxが多いのでpowershellスクリプトでまとめて起動・停止する

# Vagrant up, Vagrant haltが面倒臭い
Vagrant、日々の勉強に重宝しています。
でも、環境で必要になるサーバーの数が増えてくると、各サーバの起動・停止が面倒ですよね。
ぼくは最近、勉強でOSSの認証システムOpenAMを触っています。
一応いろいろなサーバー構築の勉強からしようと思ったので
・OpenAMサーバー
・DBサーバー
・リバプロサーバー
・アプリサーバー
をVagrantを使って用意しました。
でも、
環境立ち上げるたびに「`vagrant global-status`実行して必要なサーバーのID取得してから`vagrant up <取得ID>`」とか、
「VagrantFIleがあるパスまで移動してから`vagrant up`打つ」とか、
正直面倒臭い。

そこで、実行するだけでリスト記載のマシンを起動・停止してくれるスクリプトを作成しました。
初めてpowershell書いたので慣習とか全然わからずノリで書いてます。
コメントなどあればお願いします。

# 環境
Windows 10 pro
Power Shell 5.1.17134.590

# ソース

```powershell:openam_box.csv
# box名を列挙
ldap01,wam01,rp01,app01
```



```powershell:openam_box.csv
# ロガー関数
Function Logger($script_name, $level, $message){
    Write-Host "[" (Get-Date) "]" ${script_name} ${level}, ${message}
}
```

```powershell:up_openam.ps1
# 環境変数を設定
$vagrant_dir = "C:\Users\banbo\vagrant"
#csvからbox名を読み込み
$box_list = Get-Content ${vagrant_dir}\openam_box.csv
$global_status = vagrant global-status
$my_name = $myInvocation.MyCommand.name
# ロガー関数を読みこみ
.${vagrant_dir}\logger.ps1

# box名からidを取得
Function Get-BoxId($box_name){
    $up_box =  $global_status | Select-String $box_name 
    $box_info = $up_box -split " "
    return $box_info[0]
}

# idを指定してマシンを起動
Logger($myname, "INFO", "Process start" )
$box_array = $box_list -split ","
foreach($box_name in $box_array){
   Logger($myname, "INFO", "Booting ${box_name}" )
   $box_id = Get-BoxId $box_name
   vagrant up $box_id > ${vagrant_dir}\vagrant.log
   if ($? -ne "True"){
       Logger($myname, "ERROR", "Booting ${box_name} failed" )
   }
}
Logger($myname, "INFO", "Process end" )
```
# 実行結果

```powershell:実行結果
PS C:\Users\banbo\vagrant> .\up_openam.ps1
[ 2019/03/03 20:28:57 ]  INFO Process start
[ 2019/03/03 20:28:57 ]  INFO Booting ldap01
[ 2019/03/03 20:29:47 ]  INFO Booting wam01
[ 2019/03/03 20:30:32 ]  INFO Booting rp01
[ 2019/03/03 20:31:17 ]  INFO Booting app01
[ 2019/03/03 20:32:02 ]  INFO Process end
PS C:\Users\banbo\vagrant>
PS C:\Users\banbo\vagrant> vagrant global-status
id       name    provider   state    directory
-------------------------------------------------------------------------
71a7ccb  default virtualbox poweroff C:/Users/banbo/vagrant/box
a7ea139  default virtualbox running  C:/Users/banbo/vagrant/wam01
9fb60e8  default virtualbox running  C:/Users/banbo/vagrant/ldap01
4319c7b  default virtualbox running  C:/Users/banbo/vagrant/rp01
08fb19e  default virtualbox running  C:/Users/banbo/vagrant/app01
```

ちなみに停止するには、スクリプト内で`vagrant up`しているところを`vagrant halt`に変えてやれば基本的にOKです。
あとはログメッセージを合わせてやれば、それっぽい動きになります。
CentOSにGitサーバー（Apache）を構築

##### 必要なパッケージをインストール
```
# yum install -y httpd git
```

##### httpd設定ファイル作成
```
# cd /etc/httpd/conf.d/
# vi git.conf
```

##### git.conf
```
SetEnv GIT_PROJECT_ROOT /var/lib/git
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAlias /git/ /usr/libexec/git-core/git-http-backend/
<LocationMatch "^/git/">
  Require all granted
</LocationMatch>
```

##### ファイアウォールの設定
```
# firewall-cmd --permanent --add-service=http
# firewall-cmd --reload
```

##### Gitリポジトリ作成
```
# mkdir /var/lib/git
# cd /var/lib/git
# git init --bare --shared test.git
# cd test.git
# git update-server-info
# git config http.receivepack true
# mv hooks/post-update.sample hooks/post-update
# chown -R apache.apache /var/lib/git
```

##### SELinux設定
```
# semanage fcontext -a -t httpd_var_lib_t '/var/lib/git(/.*)?'
# semanage fcontext -a -t httpd_sys_script_exec_t '/var/lib/git/[^/]+/hooks(/.*)?'
# restorecon -v -R /var/lib/git
```
SELinuxについて

- https://milestone-of-se.nesuke.com/sv-advanced/selinux/chcon-restorecon-semanage-fcontext/
- https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/6/html/managing_confined_services/sect-managing_confined_services-the_apache_http_server-types

##### サービス設定
```
# systemctl enable httpd
# systemctl start httpd
```

##### アクセス
```
# git remote add origin http://git-server/git/test.git
# git push --set-upstream origin master
# git clone http://git-server/git/test.git
```

##### 参考ページ
- http://www.torutk.com/projects/swe/wiki/CentOS_7%E3%81%A7apache%E7%B5%8C%E7%94%B1%E3%81%AEgit%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%82%92%E6%A7%8B%E7%AF%89
- http://d.hatena.ne.jp/ono51/20120619/p1
- https://httpd.apache.org/docs/2.4/ja/mod/quickreference.html
- https://git-scm.com/docs/git-http-backend
TypeScript + Node.js + Express + EJSでMVCをやってみる

# やること

ExpressでMVCをやってみようと思い立ったのでやってみようと思います。

# コード

https://github.com/yoshida-san/js-mvc

# 前提

* macOS Mojave
* Node.js v11.10.0
* npm 6.4.1

Expressは4系です。

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

* Express
* @types/express
* EJS
* typescript
* ts-node

# 準備

```json
// package.json
"scripts": {
  "ts-node": "./node_modules/.bin/ts-node"
}
```

# Hello worldしてみる

ディレクトリ構成は以下の通り。package.jsonやnode_modulesは省略。

```text
root
 └ src
    ├ controller
    ├ model
    ├ views
    └ app.ts
```

app.tsに以下を記述。

```ts
import Express from "express";
const app = Express();

app.get("/", (req, res) => {
    res.send("Hello world!");
});

app.listen(3000, () => {
    console.log("listening on port 3000!");
});
export default app;
```

実行（`npm run ts-node ./src/app.ts`）してブラウザで`localhost:3000`にアクセスしてHello worldが表示されればOK。

# controllerを経由して何か表示してみる

controllerディレクトリ配下にhogeController.tsを作成し、以下のコードを記述。

```ts
import * as Express from "express";
export default function hogeController(req: Express.Request, res: Express.Response, next: Express.NextFunction) {
    res.send("hogeController!!");
}
```

app.tsを以下のように修正。

```ts
import Express from "express";
import hogeController from "./controller/hogeController";
const app = Express();

app.get("/", (req, res) => {
    res.send("Hello world!");
});
app.get("/hoge", hogeController);

app.listen(3000, () => {
    console.log("listening on port 3000!");
});
export default app;
```

サーバを再起動して`localhost:3000/hoge`にアクセスしてhogeController!!と表示されればOK。

# Template engineを使って表示させてみる

viewsディレクトリ配下にhoge.ejsを作成して以下のコードを記述。

```html
<!DOCTYPE html>
<html>

<head>
    <title></title>
</head>

<body>
    hoge.ejs!!
</body>

</html>
```

hogeController.tsを以下のように修正。

```ts
import * as Express from "express";
export default function hogeController(req: Express.Request, res: Express.Response, next: Express.NextFunction) {
    res.render("./hoge.ejs");
}
```

app.tsを以下のように修正。

```ts
import express from "express";
import hogeController from "./controller/hogeController";
const app = express();

app.set("view engine", "ejs");
app.set('views', './src/views')

app.get("/", (req, res) => {
    res.send("Hello world!");
});
app.get("/hoge", hogeController);

app.listen(3000, () => {
    console.log("listening on port 3000!");
});
export default app;
```

サーバを起動してlocalhost:3000/hogeにアクセスしてhoge.ejs!!を表示されればOK。

## ejsにデータを表示してみる

ejsにデータを埋め込むにはrenderメソッドの第二パラメータに表示用のデータを渡す。
hogeController.tsを以下のように修正。

```ts
import * as Express from "express";
export default function hogeController(req: Express.Request, res: Express.Response, next: Express.NextFunction) {
    let data = {
        "title": "hogeController",
        "contents": "hoge text."
    }
    res.render("./hoge.ejs", data);
}
```

hoge.ejsを以下のように修正。

```html
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>
        <%= title %>
    </title>
</head>

<body>
    <%= contents %>
</body>

</html>
```

データクラスを作ってそれをejsに渡せるようにしておくと良さそうですね。

# 最後に

エラーとかログとかは置いといて大枠はそれっぽい感じになった気がします。
ejsに関しては色々とやれることが多そうなので、別で触ってみようと思います。

お疲れさまでした。
Rubyの%記号に関する小ネタ

[Ruby: パーセント記号 `%` の使い方まとめ ](https://techracho.bpsinc.jp/hachi8833/2019_03_01/71052)
を読んだところ思い出したの備忘録代わりに

---

## 剰余算の`%`は負値の時意外?な事になる

わりと有名ですが、Rubyの剰余算は負の値を考慮するとちょっと不思議な事になります。

例えば、C/C++の場合
5 % 3 = 2
-5 % 3 = -2
ですが

Rubyの場合は
5 % 3 = 2
-5 % 3 = 1
となります。

くわしくは、絶対値最小剰余や最小非負剰余で検索するとよいでしょう。
一応Rubyの方が一貫性ある感じではあるが、たまにハマりますので注意が必要です。

ちなみに、[ActiveSupport::Duration.build](https://github.com/rails/rails/blob/94b5cd3a20edadd6f6b8cf0bdf1a4d4919df86cb/activesupport/lib/active_support/duration.rb#L184)がこの罠を踏んでいます。


## %リテラルの区切り記号にNUL文字が使える

バグなのかそうでないのか微妙なのですが

```rb
STR = "%\0hoge!\0"

puts STR
puts eval(STR)
```
GitHub - 概要 #1

## GitHub とは
コードをシェアしやすい、Gitリポジトリのホスティングサービス
Pull Requestにより、ソースコードの差分を簡単に確認し、コードレビューを行える。

### GitHubとGitの違い
Gitでは、Gitリポジトリというデータの貯蔵庫にソースコードなどを入れて利用します。このGitリポジトリを置く場所をインターネット常に提供しているのがGitHubというサービス。

##GitHubが提供する主な機能
<dl>
 <dt>Gitリポジトリ</dt>
  <dd>基本的には無料で何個でもGitリポジトリを作成できる。</dd>
 <dt>Organization</dt>
  <dd>アカウントの権限の管理や支払いを統一できる。</dd>
 <dt>Issue</dt>
  <dd>一つのタスクを一つのIssueに割り当てて、トラッキングや管理を行える。</dd>
 <dt>Wiki</dt>
  <dd>開発ドキュメントやマニュアルなどの記載に使用する。</dd>
 <dt>Pull Request</dt>
  <dd>pushした変更や機能追加を他の人のリポジトリに取り込んでもらうための要求を出す。</dd>
</dl>

## Gitは分散型バージョン管理システム
### バージョン管理とは
ソースコードの変更履歴を記録し管理することで、特定の段階まで戻ったり、誤って消してしまったファイルを復活させたり開発の現場に必要な機能を提供する。
### 集中型と分散型
<dl>
<dt>集中型</dt>
<dd>リポジトリをサーバに集中させて配置するため、一つのリポジトリしか存在しない。<br>Subversionなどの集中型は、データが中央のサーバに集中されるので、管理がシンプルな反面、サーバの影響を受けやすい。
<dt>分散型</dt>
<dd>ユーザごとにリポジトリをForkし、Forkしたリポジトリは元とは異なるリポジトリとなり、自分の思うがまま編集できる。Forkとは、GitHub側にある特定のリポジトリを自分のアカウント以下のリポジトリに複製すること。
</dl>

## memo
* ＠ユーザ名と記述することによりNotificationsを相手に送れる。
* ＠組織名→Organizationに所属する全員
* ＠組織名/チーム→チームに所属する全員
* #番号→そのリポジトリのIssue番号のリング
* 興味のあるリポジトリをWatchに登録しておけば、関する情報がNews Feedに流れる。

## 用語
* Fork - GitHub側にある特定のリポジトリを自分のアカウント以下のリポジトリに複製すること。
Google スプレッドシートを curl で 代入・更新

次のようなスプレッドシートを作成します。
![spread_mar0303.png](https://qiita-image-store.s3.amazonaws.com/0/179446/8b28227c-c339-d275-4b20-d2a11b4cd9e3.png)

```bash:curl_create.sh
ACCESS_TOKEN="*****"
SPREADSHEET_ID="*****"
URL="https://sheets.googleapis.com/v4/spreadsheets/"
#
curl -H "Authorization: OAuth "$ACCESS_TOKEN \
        -X POST -H "Content-Type: application/json" \
        $URL$SPREADSHEET_ID:batchUpdate \
        -d@cities.json
```

```json:cities.json
{
  "requests": [
    {
      "updateCells": {
        "range": {
            "sheetId": 0,
            "startRowIndex": 0,
            "endRowIndex": 3,
            "startColumnIndex": 0,
            "endColumnIndex": 5
        },
        "rows": [
            {
              "values": [
                { "userEnteredValue": { "stringValue": "t2001"} },
                { "userEnteredValue": { "stringValue": "小山"} },
                { "userEnteredValue": { "numberValue": 82345} },
                { "userEnteredValue": { "boolValue": false} },
                { "userEnteredValue": { "stringValue": "2017-3-12"} }
            ]
          },
            {
              "values": [
                { "userEnteredValue": { "stringValue": "t2002"} },
                { "userEnteredValue": { "stringValue": "下野"} },
                { "userEnteredValue": { "numberValue": 31845} },
                { "userEnteredValue": { "boolValue": false} },
                { "userEnteredValue": { "stringValue": "2018-9-19"} }
            ]
          },
            {
              "values": [
                { "userEnteredValue": { "stringValue": "t2003"} },
                { "userEnteredValue": { "stringValue": "栃木"} },
                { "userEnteredValue": { "numberValue": 93726} },
                { "userEnteredValue": { "boolValue": false} },
                { "userEnteredValue": { "stringValue": "2014-3-22"} }
            ]
          }
        ],
        "fields": "userEnteredValue"
      }
    }
  ]
}
```

## 実行結果

```text
$ ./curl_create.sh 
{
  "spreadsheetId": "1D1hk5LH6O3BlFehaBgnzfGtbcr*******",
  "replies": [
    {}
  ]
}
```

## 参考

アクセストークンの作成方法はこちら
[Google スプレッドシートを curl で扱う](https://qiita.com/ekzemplaro/items/bbe4222544eb17110604)

シートを読む方法
[Google スプレッドシートを curl で読む](https://qiita.com/ekzemplaro/items/83f225b08bc4ee9739aa)
Alexa-sdk-v2でデータの永続化

#AlexaSDKは2種類ある
AlexaSDKは2018年4月に、バージョン2がリリースされており、ネットなどの情報を調べるときもV1の情報かV2の情報か注意が必要です。（現状は、ぐぐるとV2の情報が先にヒットするので特に問題ないかと思いますが）
V2への変更内容は下記の公式の動画がわかりやすいかと。
https://www.youtube.com/watch?v=tEhIthGVxyE&list=WL&index=14&t=1322s

今回AlexaスキルとiPhoneアプリを連携させようと思い、せっかくなのでV1のコードからV2に書き換え中に躓いたので、せっかくなので備忘録。


#DynamoDB にテーブルを作成できない
V2でもV1同様セッションをまたいだデータの永続化には、DynamoDB等のデータベースの使用が必要です。
詳しいコード等は以下のリンクを御覧いただければ問題ないかと思うのですが、何故かエラーハンドラへ落ちる。

https://dev.classmethod.jp/cloud/alexa-sdk-v2-fourth/

https://developer.amazon.com/ja/blogs/alexa/post/4144a8ea-7549-4c44-a4bd-e94cb93807ea/chapter4-jp


#Lambdaのロールを見直す
lambda関数のロールでDynamoDBのロールが許可されていないと、index.js上で、テーブル作成を許可していてもDynamoDBへアクセス出来ないので、ロールでDBへのアクセスが許可されているか確認する。

![dynamoDB.png](https://qiita-image-store.s3.amazonaws.com/0/47244/597d5312-d447-ba27-ab77-17dc1bf9f6ee.png)
古いDocker imageを柔軟に消す

`docker image ls`コマンドで表示される`CreatedSince`は、`2 weeks ago`とかざっくりした表現になっている。

```bash
$ docker image ls --format '{{.ID}}\t{{.CreatedSince}}' eiryu/q-text-as-data
67e7356ad630	41 hours ago
2fbfdfb6e5d8	43 hours ago
```

作られた日から15日経過したものを消すなど、もっと細かい指定がしたい場合は`CreatedAt`をparseして時刻判定をすれば良い。

ちなみにJavaだと`yyyy-MM-dd HH:mm:ss Z z`でparse出来る形式で出力される。

```bash
$ docker image ls --format '{{.CreatedAt}}' eiryu/q-text-as-data
2019-03-02 03:01:10 +0900 JST
2019-03-02 00:24:42 +0900 JST
```

結果は以下。`minusHours`の部分は`minusDays`等での調整も可。詳細は`java.time.LocalDateTime `のJavadocを参照。

```bash
$ docker image ls --format '{{.ID}}\t{{.CreatedAt}}' eiryu/q-text-as-data | groovy -npe "def createdAt = line.split('\t')[1]; def parsed = java.time.format.DateTimeFormatter.ofPattern('yyyy-MM-dd HH:mm:ss Z z').parse(createdAt); def time = java.time.LocalDateTime.from(parsed); if (time.isBefore(java.time.LocalDateTime.now().minusHours(42))) line"
2fbfdfb6e5d8	2019-03-02 00:24:42 +0900 JST
```

あとは`awk`なり`xargs`でIMAGE IDを`docker image rm`に渡せば良い。

DockerのGroovyで動かしても良いし便利。

```bash
$ docker image ls --format '{{.ID}}\t{{.CreatedAt}}' eiryu/q-text-as-data | docker container run --rm -i groovy:2.5.0-jdk8 groovy -npe "..."
```


### 環境

```bash
$ docker -v
Docker version 18.09.2, build 6247962

$ groovy -v
Groovy Version: 2.5.0 JVM: 1.8.0_181 Vendor: Azul Systems, Inc. OS: Mac OS X
```
Google Domains の DDNS を Raspberry Pi で利用する

# はじめに

2019年3月1日より、.dev ドメインの一般登録受付が始まったので、流行に乗って購入してみました。

- [Launch details for .dev](https://www.registry.google/announcements/launch-details-for-dev/#!/)
- [開発者に最適なドメイン、「.dev」の一般登録受付開始](https://prtimes.jp/main/html/rd/p/000000390.000006942.html)

これまでは「ムームードメイン」でドメインの取得・管理をしていたのですが、残念ながらムームードメインは .dev を取り扱っていなかったので、これを機に Google Domains を使ってみることにしました。

また、これまでは無料の DDNS サービス「MyDNS」で設定したドメインに、「ムームードメイン」で取得した独自ドメインからエイリアスを張るという少々厄介な運用をしていたのですが、Google Domains には DDNS 機能が用意されているようなので、これを使ってみることにします。

なお、今回は Raspberry Pi で DDNS の設定をする方法を紹介しますが、ほとんどの Debian 系 Linux システムでも同じ方法で設定することができるかと思います。

# Google Domains でドメインを取得する

[Google Domains](https://domains.google) で欲しいドメイン名を検索し、必要な情報を入力していくとドメインを購入することができます。

# DDNS の設定をする

## Google Domains 側の設定

ドメインを取得した後、以下のリンクからドメイン管理画面に飛ぶことができるようになります。

[Google Domains - ドメインの概要](https://domains.google.com/registrar)

1つしかドメインを持っていない場合には自動的にそのドメインの情報が表示されるようですが、もし複数のドメインを持っている場合にはDDNSを設定したいドメインを選択してください。

管理画面を開いたら、左のメニューから「DNS」の項目をクリックします。

![google-domains-001.png](https://qiita-image-store.s3.amazonaws.com/0/131110/1638932f-7148-1b0e-10a5-922a64c2dd5b.png)

「合成レコード」という項目までスクロールし、合成レコードタイプのリストから「ダイナミックDNS」を選択してください。

DDNSを設定するサブドメインを「サブドメイン」の欄に入力し、「追加」をクリックしてください。なお、ルートドメインにDDNSを設定する場合には「@」を入力します。

![google-domains-002.png](https://qiita-image-store.s3.amazonaws.com/0/131110/9b17f75c-955e-b1f4-eea6-3ae4fa87cbb4.png)

そうすると、ダイナミックDNSレコードが合成レコードのリストに作成されるので、レコードの左側にある「>」をクリックして値を表示します。

続いて、「認証情報を表示」をクリックして、このレコードのユーザー名とパスワードを表示します。このユーザー名とパスワードは Raspberry Pi 側の設定で使用します。

![google-domains-003.png](https://qiita-image-store.s3.amazonaws.com/0/131110/0d1c0b96-aeae-2775-f22b-8f4ed91a1c97.png)

## Raspberry Pi 側の設定

DDNS の更新には [ddclient](https://github.com/ddclient/ddclient) というソフトウェアを利用します。

まずは、以下のコマンドで ddclient をインストールします。

インストール完了時にセットアップウィザードが出てきますが、後から設定ファイルを直接編集するので空欄のまま適当に進めてください。（プロトコルは「others」等、適当なものを選択すれば大丈夫です。）

```sh
$ sudo apt update
$ sudo apt install ddclient -y
```

続いて、ddclient の設定ファイルを以下のように編集してください。

```/etc/ddclient.conf
ssl=yes
protocol=googledomains
use=web
login=<Google Domainsが生成したユーザー名>
password=<Google Domainsが生成したパスワード>
example.dev （DDNSを設定するドメイン名 ※サブドメイン込み、ルートの場合は「@」なし）
```

デフォルトではコンピュータが認識しているIPアドレス（`ipconfig`コマンド等で表示されるもの）をDDNSサーバーに通知しようとします。しかし、`use=web` とすることで、http://checkip.dyndns.com のCGIにアクセスしてIPアドレスを取得してくれるので、ポートフォワーディングを使ってサーバーを公開している環境でも問題なくグローバルIPアドレスを通知することができます。

以下のコマンドでちゃんと更新できるか試してみます。

```sh
$ sudo ddclient -daemon=0 -verbose
```

Google Domains の画面を更新して、以下のようにIPアドレスが表示されていたら成功です。

![google-domains-004.png](https://qiita-image-store.s3.amazonaws.com/0/131110/341d5eb1-077d-b2d0-e491-e4f417b5dc62.png)

デーモン起動している ddclient にも設定ファイルの変更を反映するため、以下のコマンドで再起動しておきましょう。

```sh
$ sudo service ddclient restart
```

# 参考URL

- [ダイナミック DNS - Google Domains ヘルプ](https://support.google.com/domains/answer/6147083)
- [Google Domain DDNS Raspberry Pi or Linux Systems - Affan's Blog](https://www.affan.info/google-domain-ddns-raspberry-pi-or-linux-systems/)
Google ColabでYOLOを動かす

# モチベーション
[Deep Learning基礎講座](https://deeplearning.jp/lectures/dlb2018/)で画像の分類、テキストの生成などは学んだので、もう少し他のことも試してみたい。以下やってみたいこと

* 物体検出（画像） <- 今回コレ
* 物体検出（動画）
* 画像の生成
* 強化学習

Kaggleにも取り組んでみたいし、TensorFlow2.0もやりたいし・・・。仕事してる暇がない:sob:

# 物体検出に使うアルゴリズム
物体検出には

* Faster R-CNN
* YOLO (You only Look Once)
* SSD (Single Shot Detector)

などいくつかのアルゴリズムがあるようですが、理論の違いはよくわかっていません。とりあえずよく名前を聞くYOLOを動かしてみることにしました。https://pjreddie.com/darknet/yolo/ によると他の方法よりも速くて正確だということです（サイトの色合いがアレですね・・・）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/337041/ebae8681-97d3-01b8-4c93-23d78fd32f6c.png)

# 実行環境
色々葛藤、試行錯誤した結果、いつものGoogle Colabに落ち着きました。

* どうもYOLOの実行はコマンドを叩けばいい（自分でPythonのコードを書く必要がない）みたいだから、ローカルマシンの方が楽そう（Google Colabではターミナルは使えない。!を付ければコマンド実行はできる）。あとGoogle Colabでは画像、動画の表示が難しそう
* ただ、Darknet（YOLOを実現するためのフレームワーク）はLinux前提だが、ローカルマシンはWindows
* 一応[Windows版](https://github.com/AlexeyAB/darknet)もあるが、自分でコンパイルする必要がある
* 面倒臭そうなのでGoogle Colabにした（正確にはWindowsでチャレンジしようとしたが、その過程でCUDAがうまくインストールできなかったり、Anacondaがいつの間にかアンインストールされたりで諦めた）

# 書いたコード
Darknetのダウンロードとインストール。簡単！

```Python
%%bash
git clone https://github.com/pjreddie/darknet
cd darknet
make
```

重みのダウンロード。簡単！

```Python
cd darknet
!wget https://pjreddie.com/media/files/yolov3.weights
```

物体検出。簡単！

```Python
!./darknet detect cfg/yolov3.cfg yolov3.weights data/dog.jpg
```

どうも通常はここで画像が表示されるようなのですが（標準ソフトが起動）、Google Colabなのでそれが実現できません。これに悩んでいましたが`predictions.jpg`というファイルが新たに生成されているようです。なので、

```Python
import cv2
import matplotlib.pyplot as plt
import os.path

# 座標軸の削除処理
fig,ax = plt.subplots()
ax.tick_params(labelbottom="off",bottom="off")
ax.tick_params(labelleft="off",left="off")
ax.set_xticklabels([]) 
ax.axis('off')

file = './predictions.jpg'
if os.path.exists(file):
  img = cv2.imread(file)
  show_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) 
  plt.imshow(show_img)
```

とすることで無事インラインに画像が表示できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/337041/3bcd0a3e-154d-9bb2-65df-213c160d3b60.png)

# 次回予告
Google ColabでYOLOの学習を行う

# 参考にさせて頂いたページ
* [Windows 10上のDarknetでYolo v3をトレーニングしOpenCVから使ってみる](https://nixeneko.hatenablog.com/entry/2018/08/15/000000)
* [Google Colab:darknet/YOLOを動かす](https://lsifrontend.hatenablog.com/entry/2018/06/05/224956)
* [Google Colaboratory上でYOLOv3のオリジナルデータ学習](https://qiita.com/emi-cd/items/60e8fe877dbedb2cfae7)
php-master-changes 2019-03-02

この日はコメント / ドキュメントの更新、ビルドシステムの不要コードの削除、phpize を通して拡張を configure した際にテストで依存する他拡張の動的読み込みがされない問題の修正があった！

# 2019-03-02
## c9s: Fix out-dated docs and typo
- https://github.com/php/php-src/commit/7c351ba65ca861470373dd1467138d668dcac5f3
- [7.4~]
- コメントの情報追加と古くなった情報の修正、typo の修正

## petk: Remove obsolescent AC_HEADER_STDC and memcpy check
- https://github.com/php/php-src/commit/a700451706b1a6da75f08a6a7e331635e17a6e99
- [7.4~]
- ビルドシステムで、autoconf の古いシステム向けマクロ AC_HEADER_STDC と HAVE_MEMCPY のチェック（c89 であるでしょ！っていう）を削除

## rhabacker: Fix [#77609](https://bugs.php.net/bug.php?id=77609): Tests from mailparse extension fails
- https://github.com/php/php-src/commit/3ead67239419632eecb83f0f101ead2021ee6c14
- [7.2~]
- phpize を通して php 拡張を configure する際にテスト用の php.ini が生成されるが、インストール済の他拡張を読み込む設定がないため、テストにこけたりする問題の修正
- 他拡張に依存する拡張のテストでかつ依存先を静的に処理系へ組み込んでない場合に困る、みたいな奴だった

## petk: Update NEWS
- https://github.com/php/php-src/commit/c39fb1fc4f1cf33e0d0c633f289c1c47f179e87a
- [7.2~]
- ↑の NEWS への追記

## petk: Remove LIBZEND_CHECK_INT_TYPE and PHP_CHECK_TYPES
- https://github.com/php/php-src/commit/7431eb72fe1593b75d87533abcd332ac404b7ea7
- [7.4~]
- ビルドシステムで、不要になった m4 マクロ LIBZEND_CHECK_INT_TYPE と PHP_CHECK_TYPES、_PHP_DEF_HAVE_FILE、PHP_HAVE_STDINT_TYPES の削除
【Java】Integer.parseInt()で負の2進数を扱う場合の考慮

# 動作環境
Java11

# 内容

大した内容じゃないのでいきなり本題に入ります。

Javaでは、負の数は内部的には2の補数で表現されています。Integer.toBinaryString()を使うと、内部的な表現の文字列を得ることができます。

2の補数は、2進数の場合は全てのビットを反転させてから1を足した数になります。10進数の15は2進数では1111なので、10進数の-15は下記の値になります。

```java
System.out.println(Integer.toBinaryString(-15))  // 11111111111111111111111111110001
```

しかし、Integer.parseInt()にこの値を渡すとエラーとなってしまいます。

```java
Integer.parseInt(Integer.toBinaryString(-15), 2)
//  例外java.lang.NumberFormatException: For input string: "11111111111111111111111111110001"
//        at NumberFormatException.forInputString (NumberFormatException.java:65)
//        at Integer.parseInt (Integer.java:652)
//        at (#9:1)
```

どうやらInteger.parseInt()には、内部的な2の補数表現の値ではなく、正の2進数に負の符号を付けた形で渡す必要があるようです。

```java
System.out.println(Integer.parseInt("-1111", 2))  // -15
```

以上です。

2019/3/4 追記
コメントにていくつかご指摘いただきました。

https://docs.oracle.com/javase/jp/8/docs/api/java/lang/Integer.html#toBinaryString-int-
> 整数引数の文字列表現を、基数2の符号なし整数として返します。
> 符号なしint値は、引数が負の数の場合は、引数に2^32を加算した値になります。

（そのままコピペすると232となる箇所を2^32に修正しています）

引数が負の値の場合は内部的な2の補数表現を返すと記述していましたが、公式ドキュメントでは上記のような記述になっているようです。
ただ、結果的には同じことになります。Rubyを使って検証しました。（Javaだとオーバーフローになったりしていろいろ面倒なため）

まずJavaのInteger.toBinaryString()の戻り値

````java
System.out.println(Integer.toBinaryString(-15));  // 11111111111111111111111111110001
````

引数の値（-15）に2^32を加算した値の二進数表現

````ruby
n = -15 + 2 ** 32
puts(n.to_s(2))   # 11111111111111111111111111110001
````
どちらも11111111111111111111111111110001になることが確認できました。

また、この内部的な二進数をそのままパースできるInteger.parseUnsignedInt()というメソッドがあるようです。

```java
System.out.println(Integer.parseUnsignedInt(Integer.toBinaryString(-15), 2));  // -15
```

ご指摘ありがとうございました。（そもそも公式ドキュメントを読めという話ですね…）
Vue.jsのアプリケーションを手早くHerokuで公開する


# これは何
Vue.jsのアプリケーションを素早くHerokuで公開することを目指します。
利用シーンとしては、プロトタイプを素早く作成して誰かに見せたり、何かやった感を得たい場合を想定しています。

# 開発環境の確認

以降の手順ではそれぞれ以下の環境を前提として進めていきます。
異なる場合はうまくいかないかもしれないのでご注意ください。

- Node.js (10.x)
- Yarn (1.13.0) ※npmを使用する場合は各所のコマンドを読み替えてください
- Vue CLI (3.x)
- Heroku CLI (7.x)
- Git


```
$ node -v
v10.15.0

$ yarn -v
1.13.0

$ vue -V
3.4.1

$ heroku -v
heroku/7.22.0 darwin-x64 node-v11.9.0
```

Vue CLIが無い場合は以下のコマンドでインストールできます（[詳しくは公式サイトをご参照ください](https://cli.vuejs.org/guide/installation.html)）。

```
$ yarn global add @vue/cli
```

# 手順

## アプリケーションの作成

`vue create` を実行するだけです。任意の作業ディレクトリで以下を実行しましょう。

```
$ vue create my-app
```

手元で動かすだけならこれで完了です。 `yarn serve` を実行するとアプリケーションが起動し、ブラウザでlocalhost:8080にアクセスすると確認することができます。

```
$ yarn serve
```

このような画面が表示されたでしょうか。

![スクリーンショット 2019-02-23 16.13.00.png](https://qiita-image-store.s3.amazonaws.com/0/19401/56e51425-12d7-bffe-1e9e-ae9e1bab52db.png)



## Webサーバーを用意する

Herokuで動作させるためにExpressを導入します。package.jsonにも自動的に記載されます。

```
$ yarn add express
```

Expressの設定ファイルを用意します。

```
$ touch server.js
```

`server.js`には以下のように記述します。

```server.js
const express = require('express');
const port = process.env.PORT || 8080;
const app = express();
app.use(express.static(__dirname + "/dist/"));
app.listen(port);
```

package.jsonに以下を追記します。
`start` はHerokuがにアプリケーション起動時に実行するコマンドです。
`build` は `start`の前にビルドしてもらうために記載します。

```package.json
"scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "postinstall": "yarn build",
    "start": "node server.js"
  }
```

Herokuにデプロイする準備はできました。
あとはHerokuにログインしてアプリケーションを作成し、デプロイしましょう。お疲れ様でした！！

```
$ heroku login
```

```
$ heroku create
```

```
$ git push heroku master
```

```
$heroku open
```

# 参考文献

- https://cli.vuejs.org/

- https://devcenter.heroku.com/articles/heroku-cli
[SQLServer]入れ子のカーソルを使って、件数が1件以上のテーブル名一覧を作る



## やりたいこと
レコードの件数が1件以上存在するテーブル名の一覧が作りたい。

## やっていること
対象にしたいテーブル名の一覧を作成して、その中の件数が1以上の場合に出力
※呼び出し側でログなどに出力してしまえば、リストが作れる

```
DECLARE @table_name NVARCHAR(128);
DECLARE @rec_count int;

DECLARE	CUR_TABLE CURSOR FOR
	select name from sys.tables where name like 'T\_%' ESCAPE '\'
	union all
	select name from sys.tables where name like 'D\_%' ESCAPE '\' 
	union all
	select name from sys.tables where name like 'M\_%' ESCAPE '\'
	union all
	select name from sys.tables where 
		name not like 'TMP\_%' ESCAPE '\' and
		name not like 'TT\_%' ESCAPE '\' and
		name not like 'PT\_%' ESCAPE '\' and
		name not like 'W\_%' ESCAPE '\' and
		name not like 'T\_%' ESCAPE '\' and
		name not like 'D\_%' ESCAPE '\' and
		name not like 'M\_%' ESCAPE '\' and
		name not like 'I\_%' ESCAPE '\' and
		name not like 'G\_%' ESCAPE '\' and
		name not like 'Z\_%' ESCAPE '\' ;

OPEN CUR_TABLE;

FETCH NEXT FROM CUR_TABLE INTO @table_name;

WHILE @@FETCH_STATUS = 0
BEGIN
	EXEC('DECLARE cr2 CURSOR FOR select count(*) from ' + @table_name)
	OPEN cr2
	FETCH NEXT FROM cr2 INTO @rec_count 
	CLOSE cr2
	DEALLOCATE cr2

	if @rec_count  > 0 PRINT @table_name

	FETCH NEXT FROM CUR_TABLE INTO @table_name;
END
CLOSE CUR_TABLE;
DEALLOCATE CUR_TABLE;
```

件数をどうやって取得して判定すりゃいいんじゃいと悩んだ。

＜参考＞
https://ameblo.jp/g-pinchan-new/entry-11496798995.html
https://www.atmarkit.co.jp/ait/articles/0209/03/news001.html
Auto Scaling を試してみた

Auto Scaling の概要については
↓
[Auto Scaling](https://qiita.com/leomaro7/items/60595987a308347d4d13)

なお、起動に失敗した場合はエラーメッセージに従って、下記のリファレンスを参考にトラブルシュートをするとよい。
[Amazon EC2 Auto Scaling のトラブルシューティング: EC2 インスタンスの起動失敗
](https://docs.aws.amazon.com/ja_jp/autoscaling/ec2/userguide/ts-as-instancelaunchfailure.html)


##■事前準備##

ELBは予め作成済のものとします。

![スクリーンショット 2019-03-02 20.32.26.png](https://qiita-image-store.s3.amazonaws.com/0/280929/77a80e4f-4464-9651-113f-5d17729c6bc3.png)


##1.起動設定##

「起動設定」から「起動設定の作成」
![スクリーンショット 2019-03-02 19.50.36.png](https://qiita-image-store.s3.amazonaws.com/0/280929/4672f44a-8fc9-bd4e-09f0-718af32c1c27.png)

**1. AMI の選択**
今回は作成済のAMIから起動するようにしました。
![スクリーンショット 2019-03-02 19.52.22.png](https://qiita-image-store.s3.amazonaws.com/0/280929/00e2165c-c161-dc81-1037-4b66ed051b35.png)

以下は通常のEC2インスタンスの起動と同じ設定なので、詳細は省略します。
**2. インスタンスタイプの選択**
**3. 詳細設定**
**4. ストレージの追加**
**5. セキュリティグループの設定**
**6. 確認**

##2.Auto Scaling グループの作成##

**1. Auto Scaling グループの詳細設定**

今回はMIN:2、MAX:4でAuto Scalingを作成するので、
　[グループサイズ]は「2」にしておきます。
![スクリーンショット 2019-03-02 20.04.17.png](https://qiita-image-store.s3.amazonaws.com/0/280929/a02dd42f-f712-4421-f5b3-299d3220e638.png)

ELBも設定していくので、
　[ロードバランシング]にチェック、
　[ターゲットグループ]は予め作成済のもの、
　[ヘルスチェックのタイプ]はELB
で作成しておきます。
![スクリーンショット 2019-03-02 20.06.56.png](https://qiita-image-store.s3.amazonaws.com/0/280929/a6d08571-735a-a638-ec2d-172ab3b2d6b6.png)


**2. スケーリングポリシーの設定**

「スケーリングポリシーを使用して、このグループのキャパシティを調整する」にし、
「スケーリング範囲 2 および 4 インスタンス。これらは、グループの最小サイズと最大サイズになります。」にする。
![スクリーンショット 2019-03-02 20.11.38.png](https://qiita-image-store.s3.amazonaws.com/0/280929/cc870974-65e4-770c-ce92-6c3b7ea76f5b.png)

スケールアウト
CPU使用率が40%を超えた場合に2インスタンス増やすように設定します。
![スクリーンショット 2019-03-02 20.18.01.png](https://qiita-image-store.s3.amazonaws.com/0/280929/197de86d-b48a-2736-84cc-7650458d598e.png)

スケールイン
CPU使用率が10%以下になった場合に2インスタンス減らすように設定します。
![スクリーンショット 2019-03-02 20.16.56.png](https://qiita-image-store.s3.amazonaws.com/0/280929/ab233bba-eb0c-b4d9-2d39-2533d02dfe41.png)

**3. 通知の設定**
インスタンスの起動成功、インスタンスの起動失敗、インスタンスの終了、インスタンスの終了失敗など、指定されたイベントの発生時に、指定されたエンドポイント（メールアドレスなど）に通知を送信するように設定できますが、今回は設定しないものとします。

**4. タグを設定**
Auto Scaling で作成されたEC2インスタンスであることがわかるようにタグをつけておきましょう。

**5. 確認**
設定完了です。

##3.作成されたことを確認する##
EC2インスタンスを確認すると実際に、2個作成されたことが確認できました。
![スクリーンショット 2019-03-02 20.29.15.png](https://qiita-image-store.s3.amazonaws.com/0/280929/92ba8644-e54b-6f53-6568-75e062256c80.png)

ELBのターゲットグループからも2つのEC2インスタンスが、healthy（成功）していることがわかります。
![スクリーンショット 2019-03-03 18.33.05.png](https://qiita-image-store.s3.amazonaws.com/0/280929/225687c4-2be6-4e37-bd0e-f572580c3ed9.png)


##4.負荷をかけて Auto Scaling が動いていることを確認する##

yesコマンドで負荷をかけた後、EC2インスタンスが4になっているか確認する。

```
$ yes dev/null &
$ top
```

EC2インスタンスが4になっていることを確認した後、killコマンドで停止して、EC2インスタンスが2になっているか確認する。

```
$ top
$ kill <PID>
```
初心者必見！データ構造について

[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしている@yuka_ponです。

プログラミングの勉強をしていて、**「データ構造」**を聞いたことのある方はいませんか？
データ構造とは、パソコン上のプログラムにおいて必要となる大量のデータを管理した構造を指します。
では、どのようにして管理しているのでしょうか？

今回は、データ構造で学んだことを記します。

#抽象データ型とクラス
プログラミングにおけるデータ構造は、基本的に**抽象データ型**または**クラス**で成立しています。
データ構造とそれに伴う操作を含めたものを意味します。
この中には、さらに次のようなものがあります。

- スタック
：最後にリスト（配列）に含んだものが最初に出ていく、LIFO(Last In, First 
 Out)を使った構造。データ保存をしたいときに使われる。
- キュー
：最初にリストに入ったものが最初に出ていく、FIFO(First In, First Out)を使った構造。

#連想配列
**連想配列**とは、キューとして指定した値を見つけ出すために、キーと値を関連付けてデータ保存をした構造です。
**[ハッシュ法](https://www.weblio.jp/content/%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E6%B3%95)**で保存していくことから、ハッシュテーブルとも呼ばれます。

#連結リスト
**連結リスト**とは、リストの各要素にリンクが含まれているものです。
次のリンクに移るだけのリストを**単方向リスト**、前または次のリンクに移るリストを**双方向リスト**と呼びます。
さらに、先端から終末まで繰り返してリンク先に移れるリストを**循環リスト**と呼びます。
このような様々なリストは、次のような構造で表します。

- ツリー：階層構造で表したリンク。バイナリーツリー（最大2つまでのリンクしか持たないツリー）などもある。
- ヒープ：[半順序集合](http://infoshako.sk.tsukuba.ac.jp/~hachi/math/csc2/poset.html)で表したツリー。


#さいごに
データ構造について詳しく知りたい方は、[コチラ](https://www.codereading.com/algo_and_ds/)をご覧ください。
iOSのLabelの文字間隔を指定可能にする (Swift 4.2)

# Labelの文字間隔

iOS開発において、 `Label` による文字列の間隔を変更したいケースがあります。これは [NSAttributedString.Key.kern](https://developer.apple.com/documentation/foundation/nsattributedstring/key/1527891-kern) を使用することで変更することが可能です。

**"kern"** はテキストにおける文字同士の間隔を意味するものであり、このプロパティに値を設定すると、文字列の間隔が調整可能となります。このデフォルト値は `0` であり、カーニング、つまり文字間隔が指定されていない状態です。文字間隔を広げる場合は0以上、文字間隔を狭める場合は0以下の値を指定します。

# コーディング例

[stackoverflowの回答](https://stackoverflow.com/questions/37689785/how-do-i-change-the-letter-spacing-in-a-uilabel) を参考にして、文字間隔を指定可能なカスタムLabelクラスを作ってみます。

```swift:CustomLabel.swift
import UIKit

open class CustomLabel: UILabel {
    @IBInspectable open var spacing:CGFloat = 0 {
        didSet {
            let attributedString = NSMutableAttributedString(string: self.text!)
            attributedString.addAttribute(NSAttributedString.Key.kern, value: self.spacing, range: NSRange(location: 0, length: attributedString.length))
            self.attributedText = attributedString
        }        
    }
}

```

作成した `CustomLabel` をビューに配置したLabelに適用します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12152/c6ac8b55-a22c-416a-c440-83e1e5357295.png)

Inspectorに `Spacing` の設定項目が表示されるので、任意の値を設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/12152/edf9b0fd-da4b-5c21-354b-c193dd7f3d0d.png)

すると、次のようにSpacingに設定した値に応じて、文字間隔が変更されます。

**Spacing=0**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12152/6ff11226-64ba-52b9-6a32-f61635ff7a4e.png)


**Spacing=10**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/12152/e136f92e-0f7a-a941-af76-6a0be621221f.png)

# 参考

[How do I change the letter spacing in a UILabel?](https://stackoverflow.com/questions/37689785/how-do-i-change-the-letter-spacing-in-a-uilabel)
シェルでコマンドを実行するということについて

# はじめに

この度、訳あってCLIツールをつくろうと思ったのですが、そもそもコマンドって何？ と思ったので簡単に調べてみました。

普段シェル（私の場合は bash なので以下 bash を想定して話しています）に対して `pwd` とか `ls` とか、はたまた自分で入れた `git` とか `aws` とかコマンドを入力して操作しているわけですが、これはつまり何をしているのか？ ということについてごく簡単に調べてみました。

# コマンドを実行するということ

まず、
コマンドを実行するということは、その処理内容が書かれた実行ファイルを実行するということ。
コマンドを入力するということは、実行する実行ファイル名を入力するということ。（コマンド = 実行ファイル名）

### シェルにコマンドを入力して実行する方法とその際の挙動

コマンドを実行したいとき、入力方法は下記2パターンあります。

- **スラッシュ付きで実行ファイルの格納場所も含めて実行ファイル名を入力する方法。**

    → 指定されたその実行ファイルを実行する

```例：
$ /bin/ls
``` 
    
- **単にコマンドを入力する方法。**日常的にはこちら。

    → 環境変数$PATHに書いてあるディレクトリの中からそのコマンドの実行ファイルを検索し、最初に見つかったものを実行する
        （より左に書いてあるディレクトリから順に検索していく）
        （ *"PATHが通ってなくて実行できない"* というのはこういうことだったんですね）

```例：
$ ls
```

結局のところコマンドを実行するということは、実行ファイルを特定してそれを実行する、ということなんですね。

ここでちなみに、
実行ファイルというのは、C言語などで書かれたプログラムを機械語にコンパイルしてビルドされたバイナリファイルのこと。
その環境（OSやアーキテクチャ）に合わせてビルドされたバイナリファイルしか実行できない。（例：darwin の amd64 など）

# おまけ

### ここまで調べて湧いてきた疑問

- シェルに入力したものはすべてコマンドとして受け取られるということ？
- ではシェルスクリプトを実行するときのあれは？ コマンドとして受け取られてるってこと？
- 入力したものはコマンドとして受け取られるとしたら、バイナリファイルとシェルスクリプトでは中身がぜんぜん違うのになぜそれぞれ適切に実行できるの？

ということで、コマンドの実行方法と比較して、シェルスクリプトの実行方法を確認しておきます。

## シェルスクリプトを実行するということ

実験でシェルスクリプトを実行しようとした際、実行権限がないと怒られたので、必要に応じて `chmod +x sample.sh` などします。

### シェルスクリプトの実行方法

- **bashコマンドの引数として指定する。**

     カレントディレクトリにファイルがある場合は下記で実行できる。ない場合でも場所指定すれば実行できる。 

```
$ bash sample.sh
``` 
   
```
$ bash ../sample.sh
```


- **コマンドと同様な扱いをする その1：スラッシュ付きで場所も指定して入力する。**日常的にはこれ。  
        
```例：
$ ./sample.sh
```

- **コマンドと同様な扱いをする その2：環境変数$PATHに書いてあるディレクトリにシェルスクリプトを置いて、シェルスクリプト名を入力する。**

     /usr/local/bin/ に sample.sh を置いて、ファイル名のみ入力する

```例：
$ sample.sh
```



ちなみに、

Windowsと違い、MacやLinuxでは拡張子という概念がないので、ファイル名に .sh が付いていたらシェルスクリプトというわけではない。.sh は人間が識別しやすいように習慣的に付けているだけ。samplesh というファイル名でも中身がシェルスクリプトならシェルスクリプト。

シェルスクリプトの中身の1行目にはShebang（例：`#!/bin/bash`）を書くが、これは実行するときに使用するインタプリタを指定しているだけで、なくてもシェルスクリプトとして動く。


### 疑問に対する解：
→ bashのマニュアルの書いてありました 
(日本語版：https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html の"コマンドの実行"の項)


最初はコマンドと同じようにその名前の実行ファイルを探すが、

> このファイルが実行可能フォーマットでないために実行が失敗し、 かつディレクトリでもない場合には、 このファイルは シェルスクリプト(shell script)であるとみなされます。

要するに、基本的にはコマンドであると仮定して処理するけど、コマンドではないとわかると次はシェルスクリプトとして処理するってことですね。

# 終わりに

マニュアル（公式ドキュメント）を読むって大事ですね。

コマンドはプログラムから生まれ出てきたもので、シェルスクリプトはそのコマンド群の並べることで成り立っている、という違いがわかりました。
プログラムを書くときとシェルスクリプトを書くときは別の思考回路を持て、というのはこういう違いからくるものなんですね。
参考：https://shellscript.sunone.me/tutorial.html

今回ごく初歩的な内容で厳密性に欠けるところも多々あるかと思います。間違いや同時に知っておくとよいポイント等含め、お気づきの際はコメントいただけたら幸いです。
Vuetifyのv-data-tableの見出し行（ヘッダー）をドラッグ＆ドロップで並べ替える

# はじめに

テーブルの見出し行（ヘッダー）をドラッグドロップして並び順を変更したいという要望

# 結論

![2019-03-03_19h03_35.gif](https://qiita-image-store.s3.amazonaws.com/0/133291/488facc0-78a1-0352-6fea-3c3ea95555cd.gif)


[drag-n-drop in Vuetify — Part II](https://medium.com/vuetify/drag-n-drop-in-vuetify-part-ii-2b07b4b27684)に掲載されていたので参考にする。

こちらも行をドラッグ＆ドロップして移動させるというサンプルだけど、見出し行でも同様。
一応、[vue draggable](https://github.com/SortableJS/Vue.Draggable)でも試したけど、躓いたので、ブログに記載の[Sortable.js](https://github.com/SortableJS/Sortable)を利用する

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="1da2" data-slug-hash="rRegZg" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid black; margin: 1em 0; padding: 1em;" data-pen-title="Vuetify Example Pen">
  <span>See the Pen <a href="https://codepen.io/1da2/pen/rRegZg/">
  Vuetify Example Pen</a> by Shigehiro　IDANI (<a href="https://codepen.io/1da2">@1da2</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

#