OmniAICreator/Qiita-1.07M huggingface dataset:
PostgreSQLから複数行を取得するCOBOLプログラムの例

PostgreSQLに検索クエリを発行して、その結果の複数行を取得するCOBOLプログラム(以下)を作成する。このCOBOLプログラムでは、デフォルト値から変更されたPostgreSQLのすべての設定について、パラメータ名と設定値を[pg_settings](https://www.postgresql.jp/document/current/html/view-pg-settings.html)から取得する。

# COBOLプログラム例

このCOBOLプログラムのコードの各行は、**8桁目以降**から始まっていることに要注意。
COBOLプログラムのコンパイルについては[こちら](https://qiita.com/fujii_masao/items/817af1c5947f2bfdf06e)を参考に。

```cobol
       IDENTIFICATION DIVISION.
       PROGRAM-ID. DESCRIBE_CONFIG.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 PG_SETTINGS.
            03 NAME    PIC X(48).
            03 SETTING PIC X(48).

       EXEC SQL BEGIN DECLARE SECTION END-EXEC.
       01 DBNAME   PIC X(32) VALUE "postgres".
       01 USERNAME PIC X(32) VALUE "postgres".
       01 PASSWORD PIC X(32) VALUE SPACE.
       EXEC SQL END DECLARE SECTION END-EXEC.

       EXEC SQL INCLUDE SQLCA END-EXEC.

       PROCEDURE DIVISION.
       MAIN.
            EXEC SQL
                CONNECT :USERNAME IDENTIFIED BY :PASSWORD
                    USING :DBNAME
            END-EXEC.

            EXEC SQL DECLARE PSCURSOR CURSOR FOR
                 SELECT name, setting FROM pg_settings
                      WHERE setting <> boot_val ORDER BY name
            END-EXEC.

            EXEC SQL
                 OPEN PSCURSOR
            END-EXEC.

            EXEC SQL
                 FETCH PSCURSOR INTO :PG_SETTINGS
            END-EXEC

            PERFORM UNTIL SQLCODE NOT = 0
                 DISPLAY PG_SETTINGS
                 EXEC SQL
                      FETCH PSCURSOR INTO :PG_SETTINGS
                 END-EXEC
            END-PERFORM.

            EXEC SQL
                 CLOSE PSCURSOR
            END-EXEC

            EXEC SQL
                DISCONNECT ALL
            END-EXEC.

            STOP RUN.
```
ASP.NET Core Web アプリケーションでMySQLを使う

# はじめに

突然ASP.NET Coreを触ることになったので、勉強がてら適当なアプリを作り始めたのですが、
DBからデータを読み込んだり書き込んだりするという初歩的なところでハマってしましました。
せっかく調べたので、やったことをまとめておきたいと思います。


# 環境

DBサーバ

| App       | Version   |
|:----------|:---------:|
| CentOS    | 7.4       |
| MySQL     | 5.7       |

開発環境

| App         | Version   |
|-------------|-----------|
|Windows      |Windows 10 |
|Visual Studio|2017       |
|.Net Core    |1.1        |


# DBの準備
VPSにMySQLをセットアップして、適当なテーブルを用意します。
DBには、SSLで接続できるようにしてください。
今回はテスト用に「MyTests」テーブルを作りました。

MyTests

| カラム名 | 型           | 備考   |
|:-------|:------------|:-------|
| Id     | int(11)     | AI, PK |
| Name   | varchar(45) |        |
| Age    | int(11)     |        |


# ASP.NET Core プロジェクトを作成

Visual Studio 2017で、ウィザードに従ってプロジェクトを作成します。
ここでは、ASP.NET Core 1.1を使って進めていきます。

![01_CreateProject.png](https://qiita-image-store.s3.amazonaws.com/0/141789/1301e507-9b4b-a964-798a-5ba7f3adadc1.png)


# MySql.Data.EntityFrameworkCoreをインストール

MySQLにアクセスするには「MySql.Data.EntityFrameworkCore」が必要なので、NuGetパッケージマネージャーを使ってインストールします。
最新の安定版である6.10.4をインストールしました。

![02_Install-MySqlDataEF.png](https://qiita-image-store.s3.amazonaws.com/0/141789/82c8e3f4-7274-eebf-e39c-8871e1645081.png)


# テーブルに対応したクラスを用意

データを読み書きしたいテーブルに対応するクラスを作成します。
Modelsフォルダの下に、「MyTest.cs」を用意して、MyTestクラスを作成しました。

[追記]
実行時に、「プライマリーキーがない」というエラーが出る場合は、System.ComponentModel.DataAnnotationsをusingして、プライマリーキーとなるメンバーのすぐ上に[Key]を追記するとうまくいきます。

![03_Create-Table-Class.png](https://qiita-image-store.s3.amazonaws.com/0/141789/4f463b5b-cfa6-7a7c-74d5-00260846bb95.png)


# コンテキストクラスを用意

DBとやり取りするためのコンテキストクラスを用意します。
このクラスは、DBContextの派生クラスで、DBSet<MyTest>型のメンバーを持つクラスです。
Dataフォルダの下に、「MySQLSampleDbContext.cs」を用意して、MySQLSampleDbContextクラスを作成しました。

![04_Create-DBContextClass.png](https://qiita-image-store.s3.amazonaws.com/0/141789/8afe9a54-4a8c-24cd-2ecb-d60795d20710.png)


# DBとの接続に必要な情報を用意

appsettings.jsonのConnectionStringsに、接続文字列を追加します。

```
"MySQLSampleDbConnection": "Server=<IP Address>;Database=<DB Name>;User Id=<DB User Name>;Password=<Password>;"
```
適宜、以下のように読みかえてください。

|項目             |内容           |
|:---------------|:---------------|
|< IP Address >  |  DBサーバのアドレス|
|< DB Name >     |  DBの名前       |
|< DB User Name >  | DBのユーザ名   |
|< Password >    |  DBのパスワード   |

![05_ConnectionString.png](https://qiita-image-store.s3.amazonaws.com/0/141789/22e2118a-8d8a-58f8-fb61-7e5ed40ef934.png)


# Framework Serviceを追加

StartupクラスのConfigureServicesの中で、用意したMySQLSampleDbContextをserviceに追加します。
GetConnectionStringの引数に渡している文字列は、appsettings.jsonに追加した接続文字列のキーです。

![06_AddService.png](https://qiita-image-store.s3.amazonaws.com/0/141789/2c586e14-a0c7-ea0e-c0c9-da3dbd6aed26.png)


# テーブルからデータを読んでみる

試しにテーブルからデータを読み込んで見ました。
MyTestControllerを用意すると、良い感じでDbContextが降って来るので、それを使ってデータを読み込み、Viewに渡して表示しています。

![07_LoadDataFromDB.png](https://qiita-image-store.s3.amazonaws.com/0/141789/0d5036e2-8c42-0fe1-7fa8-20693104440e.png)


# ソースコード

折角なので、プロジェクトをGitHubに上げておきました。
接続文字列は適宜自分の環境に差し替えてください。
> [MySQL_Sample](https://github.com/tatsuteb/MySQL_Sample)
LaravelのクエリビルダでSQL文を直接実行(select,insert,update,delete,その他)

##準備
`config/app.php`の`alias`でファサードのエイリアス`DB`が登録されていることを確認

```php
//config/app.php
'aliases' => [
    'DB' => Illuminate\Support\Facades\DB::class,
];
```
`DB`ファサードを使うクラスで`use`する

```php
use DB;
```

##select
```php
DB::select("SELECT * FROM users");
DB::selectOne("SELECT * FROM users WHERE id = ?", [1]);
```

##insert
```php
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
```

##update
```php
DB::update('update users set votes = 100 where name = ?', ['John']);
```

##delete
```php
DB::delete('delete from users WHERE id = ?' [1]);
```

##その他
```php
DB::statement('drop table users');
DB::statement('alter table users auto_increment = 1');
```

公式ドキュメントに掲載されているものだと、`select`や`insert`等はあるが、そのほかの`drop`や`alter`等は記載されていないので困っていた。
`DB::statement()`が使えるので色んなSQL文をLaravelから実行できる。

(参考)
http://recipes.laravel.jp/recipe/1036
サーバ間でディレクトリの存在、所有者、グループ、パーミッションをチェックする

ディレクトリを比較すること自体が時代遅れのようにも思いますが。。。。
サーバリプレイスなど、あるサーバに対して別の機器を使って同様の環境をる場合、ディレクトリはプログラムで作成するとして本当に一致しているかチェックするシェルです。数百、数千以上の台数になると構成管理ツールなどで統合管理するべきだと思いますが、数台という規模であれば環境整備のコストと比較して選択肢の一つになり得るのではと思ってます。

**作業の流れ**
1.サーバAのディレクトリ一覧取得
2.一覧を新たに構築するサーバBに配置
3.チェックスクリプト実行
→標準出力に結果を出力する

**チェック仕様**
ディレクトリの存在、所有者、グループ、パーミッションをチェックする

**ディレクトリ一覧取得**
パーミッション、所有者、グループ、フルパスを出力する

```shell-session
$ find /home -type d | xargs stat --format='%a %U %G %n' > test.ls
755 root root /home
700 kusakari kusakari /home/kusakari
700 kusakari kusakari /home/kusakari/Maildir
760 kusakari kusakari /home/kusakari/.pki
700 koji koji /home/koji
```

**実行するチェックスクリプト**
本当は構成管理ツールや、Serverspecなど利用すべきだとは思うけど・・・。

```sh:check.sh
#! /bin/sh
cat $1 | while read line
do
  PERM=`echo ${line} | cut -d' ' -f 1`
  USER=`echo ${line} | cut -d' ' -f 2`
  GROUP=`echo ${line} | cut -d' ' -f 3`
  DIRPATH=`echo ${line} | cut -d' ' -f 4`
  RESULT=`find ${DIRPATH} -samefile ${DIRPATH} -perm ${PERM} -user ${USER} -group ${GROUP}`
  if [ $? = 0 ]; then
    echo "O ${PERM} ${USER}:${GROUP} ${DIRPATH}"
  else
    echo "X ${PERM} ${USER}:${GROUP} ${DIRPATH}"
  fi
done
```

**実行**
OKケース（一致した）

```shell-session
$ ./check.sh test.ls
O 755 root:root /home
O 700 kusakari:kusakari /home/kusakari
O 700 kusakari:kusakari /home/kusakari/Maildir
O 760 kusakari:kusakari /home/kusakari/.pki
O 700 koji:koji /home/koji
```

NGケース（一致しなかった）

```shell-session
$ ./check.sh test.ls
X 755 root:root /home
X 700 kusakari:kusakari /home/kusakari
X 700 kusakari:kusakari /home/kusakari/Maildir
X 760 kusakari:kusakari /home/kusakari/.pki
X 700 koji:koji /home/koji
```
パケット解析で役立つWiresharkの機能

書籍「実践パケット解析」の中で役立つと感じた箇所をピックアップしています。

## 便利な機能たち

- `統計[Statistics] -> 対話[Conversation]`
- `統計[Statistics] -> 終端[EndPoint]`
- `統計[Statistics] -> プロトコル階層[Protocol Hierarchy]`

<img width="280" alt="wiresharkFunctions" src="https://qiita-image-store.s3.amazonaws.com/0/103672/25c714d6-dfa9-6672-9e49-d45654a7ec8d.png">

### 対話[Conversation]

IPアドレスとポートごとに分類して一覧表示されます。ここでは「**どこから、どこへ向けて、どれだけの量のパケットが送られているか**」を把握することが出来ます。

<img width="1597" alt="Conversation" src="https://qiita-image-store.s3.amazonaws.com/0/103672/3be923ac-ac8b-3361-b939-6046e9b91b4c.png">

## グラフ

### IOグラフ

変化が多いと不安定であることが伺えます。

<img width="962" alt="ioGraph" src="https://qiita-image-store.s3.amazonaws.com/0/103672/adb6bf86-c10c-111c-b3e8-e80948f8690a.png">

ズームして細かく確認したいグラフの箇所をクリックすることで、パケット一覧の該当する箇所付近が選択されます。

### ラウンドトリップタイムグラフ

ラウンドトリップグラフ(RTT)とは、「**パケットの受信が確認されるまでにかかる時間**」を表します。つまり、**パケットが宛先に届き、その返答が自分に戻ってくるのにかかった時間**のことです。

`Statistics -> TCP Stream Graph -> Round Trip Time Graph`

<img width="962" alt="RTT" src="https://qiita-image-store.s3.amazonaws.com/0/103672/b085c3cf-7940-4192-0c8f-a1c829426d3b.png">

### フローグラフ

`Statistic -> Flow Graph`

<img width="1479" alt="flowGraph" src="https://qiita-image-store.s3.amazonaws.com/0/103672/ae5480b1-0fb7-06ef-65b0-7ba6ad6adf92.png">

## 自動解析されたプロトコルが異なるとき

個別のパケットを選択して`Decode as -> Transport`で任意のプロトコルを選択する。

## パケット長

- イーサネットの最大フレームサイズ　1518バイト
- これからイーサネット、IP、TCP HEADERを差し引いた1460バイトが7層のプロトコルヘッダ、データに使用可能

## パケットのマーキング

- マーキング: `Ctrl + M`
- 次のマーキング: `Shift + Ctrl + N`
- 前のマーキング: `Shift + Ctrl + B`

## キャプチャ/BPF構文

BPF構文を使って作成したフィルタを「式」とよび、それぞれの式は１つ以上の「プリミティブ」で構成されている。プリミティブは１つ以上の「修飾子」とそのあとに続くID文字列または数値のセットから構成される。

### 修飾子の種類
- Type(host, net, port)
- Dir(src, dst)
- Proto(ether, ip, tcp, udp, http,ftp)

` dst host 192.168.0.10 && tcp port 80 `

### 論理演算子
- AND(&&)
- OR(||)
- NOT(!)

## ホスト名とアドレスによるフィルタ

IPv4の場合

` host 172.16.16.149 `

IPv6の場合

` host 2001:db8:85a3:8a2e:370:7334 `

ホスト名

` host testserver2 `

Macアドレスでも指定可能

` src host 00-1a-a0-52-e2 `

## ポートとプロトコルによるフィルタ

ポート8080

` port 8080 `

宛先がポート8080

 ` dst port 8080 `

IPv6を除外

` !ip6 `

## プロトコルフィールドによるフィルタ

到達不能のメッセージ（タイプ3）

` icmp[0] == 3 `

Pingパケット(ICMP)

` icmp[0] == 8 || icmp[0] == 0 `

ICMPのタイプ3、コード1（ホスト到達不能）パケット

` icmp[0:2] == 0x0301 `

RSTフラグがセットされたTCPパケット

` tcp[13] &4 == 4 `

### よく使うフィルタ

フラグがセットされた TCPパケット

` tcp[13] &XXX == XXX `

- URG: XXX=32
- ACK: XXX=16
- PSH: XXX=8
- RST: XXX=4
- SYN: XXX=2
- FIN: XXX=1

TCP SYN-ACKパケット

` tcp[13] == 18 `

指定したMacアドレスで送受信されるトラフィック

` ether host 00:00:00:00:00:00 `

ブロードキャストパケット

`broadcast`

### フィルタ式の文法

#### 演算子

- 等しい `==`
- 等しくない `!=`
- 大なり `>`
- 小なり `<`
- 以上 `>=`
- 以下 `<=`

#### 論理演算子

- 論理和 `and`
- 論理積 `or` 
- 排他的論理和 `not`
- 否定 `xor`

### ポート

- `1-1023` スタンダードポートグループ
- `0` は予約済みなので除外
- `1024-65535` エフェメラルポートグループ（日本ではウェルノウンポート）
形態素解析しやすくなるツールを作った

PyQt5を使って，テキストファイルをGUIで選択して形態素解説するツールやコードが調べた限りなさそうだったので作りました．(一回一回，テキストファイルの場所をターミナルで調べるのが怠いので．)

PyQtで完結しろよというツッコミは今回はスルー


形態素解析というのは，
**今日は月が綺麗ですね．**という文が与えられた時，

```
今日	名詞,副詞可能,*,*,*,*,今日,キョウ,キョー
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
月	名詞,一般,*,*,*,*,月,ツキ,ツキ
が	助詞,格助詞,一般,*,*,*,が,ガ,ガ
綺麗	名詞,形容動詞語幹,*,*,*,*,綺麗,キレイ,キレイ
です	助動詞,*,*,*,特殊・デス,基本形,です,デス,デス
ね	助詞,終助詞,*,*,*,*,ね,ネ,ネ
．	記号,句点,*,*,*,*,．,．,．
```
のようにすることを形態素解析といいます．今回はmecabを使ってます．

実行すると，
このようにQTのファイルダイアログが表示されます．
<img width="400" alt="形態素解析するファイルを選択" src="https://qiita-image-store.s3.amazonaws.com/0/33329/8a6e30b8-fb18-248d-9242-2f8876fbcaa1.png">

形態素解析したいテキストファイルを指定して（クリックして）OPENボタンを押すとウィンドウが閉じられて，出力がターミナルに表示されます．
<img width="400" alt="ターミナル.png" src="https://qiita-image-store.s3.amazonaws.com/0/33329/09362f8b-3316-b153-2581-b539ce58e021.png">
(文字すごい小さいですが，名詞をスペース区切りで表示してます．)

あとは，ターミナルでパイプラインでファイル名打って保存したりして使ってください．

以下がコードです．
@shiracamusさんにリファクタリングしていただきました。
**※事前にpipでPyQt５とmecabをインストールしておいてください．**

```morphological_analysis_gui.py
# -*- coding: utf-8 -*-
import sys
import MeCab

from PyQt5.QtWidgets import QApplication, QWidget, QInputDialog, QLineEdit, QFileDialog
from PyQt5.QtGui import QIcon

class FileNameDialog(QWidget):
    title = '形態素解析するファイルを選択'
    left, top, width, height = 10, 10, 640, 480

    def open(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(
            self, self.title, "", "Text File (*.txt)", options=options)
        return fileName

def show_words(text):
    # 辞書にneologdを使用
    m = MeCab.Tagger("/usr/local/lib/mecab/dic/mecab-ipadic-neologd")
    list_parse_text = m.parse(text).split("\n")
    for p_text in list_parse_text:
        if p_text.find("名詞,一般") >= 0 or p_text.find("名詞,固有名詞") >= 0:
            print(p_text[:-1].split("\t")[0] + " ", end="")

def main():
    app = QApplication(sys.argv)
    # sys.exit(app.exec_())
    dialog = FileNameDialog()
    fileName = dialog.open()
    dialog.close()
    if fileName:
        with open(fileName, 'r') as f:
            text = f.read()
            show_words(text)

if __name__ == '__main__':
    main()
```



[追記:2017/12/22]
ファイルを複数選択できるようにしました．
下のgithubのが最新のものとなります．

morph_gui
https://github.com/Ooshita/morph_gui
Rustで入出力するときのサンプル

自分用にサンプルコードを載せる。
リファレンスで調べながら書いたので、コードもリファレンスのを参考にした。
ファイルへの入出力、バッファへの入出力、ソケットへの入出力のコード。
バージョンは1.21.0。

```rust
use std::fs;
use std::io::{Write, Read, BufWriter, BufReader, copy};

fn file_io() {
    {
        // write
        let string = "Hello, file io!";
        let mut f = fs::File::create("test.txt").unwrap(); // open file, you can write to file.
        // "create" open as write only mode.
        f.write_all(string.as_bytes()).unwrap(); // byte-only
       
        // file is closed here.
    }

    {
        // read
        let mut f = fs::File::open("test.txt").unwrap();
        // "open" open as read only mode
        let mut buf = vec![];

        f.read_to_end(&mut buf).unwrap(); // read here
        println!("{}", std::str::from_utf8(&buf).unwrap()); // to &str
        // println!("{}", String::from_utf8(b).unwrap()); // or String
    }

    // seek
    // f.seek(std::io::SeekFrom::Start(3)) // seek points head + 3 byte.
}

fn buffer_io() {
    {
        // write
        let b = "Hello, buffer io!";
        let mut f = BufWriter::new(fs::File::create("test.txt").unwrap()); // buffering write
        f.write(b.as_bytes()).unwrap();
    }


    {
        // read
        let mut f = BufReader::new(fs::File::open("test.txt").unwrap()); // buffering read
        let mut buf = vec![];

        f.read_to_end(&mut buf).unwrap();

        println!("{}", std::str::from_utf8(&buf).unwrap());
    }
}

fn string_io() {
    let mut buf = vec![];
    {
        // write
        let test = "Hello, string io!";
        let mut f = BufWriter::new(&mut buf);
        f.write(test.as_bytes()).unwrap();
    }
    let string = std::str::from_utf8(&buf).unwrap();
    println!("{}", string);

    {
        // read
        let mut buf = BufReader::new(string.as_bytes());
        let mut read_str = String::new();

        buf.read_to_string(&mut read_str).unwrap();

        println!("{}", read_str);
    }

}

#[allow(dead_code)]
fn net_io() {
    use std::net;

    {
        // connect
        let s = "Hello, network io!";
        let mut stream = net::TcpStream::connect("127.0.0.1:30001").unwrap();
        let _ = stream.write(s.as_bytes());

        {
            let mut buf = String::new();
            stream.read_to_string(&mut buf).unwrap(); // read from stream, until EOF
            println!("{}", buf);
        }
    }

    {
        // listen
        let listener = net::TcpListener::bind("127.0.0.1:8080").unwrap();
        match listener.accept() {
            Ok((_socket, _addr)) => println!("Connection comes!"),
            Err(_e) => println!("Error"),
        }
    }
}

fn copy_io() {
    let mut writer = vec![];
    let s = "Hello, copy reader to writer!";
    let mut reader = BufReader::new(s.as_bytes());

    copy(&mut reader, &mut writer).unwrap();

    println!("{}", std::str::from_utf8(&writer).unwrap());


}

fn main() {
    // if you writes much bytes, you should buffering

    file_io();
    buffer_io();
    string_io();
    // net_io();
    copy_io();

    // string add
    let mut s = String::from("Hello");
    s.push_str(", world!");
    println!("{}", s);
}

```
docker-composeでGitBucket+PostgreSQLを起動する

`docker-compose`でGitBucketとPostgreSQLを起動する。
# 方針
* GitBucketは[公式のDockerイメージ](https://hub.docker.com/r/gitbucket/gitbucket/)を使う。
* PostgreSQLの起動完了を待ってから（ポート5432にアクセス可能になってから）GitBucketを起動する。

# 準備
```shell-session
$ mkdir data
$ wget https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh -P data
$ chmod +x data/wait-for-it.sh
$ vi docker-compose.yml
```

`docker-compose.yml`は以下のとおり。

```yaml:docker-compose.yml
version: '2'

services:
  gitbucket:
    image: gitbucket/gitbucket
    restart: always
    ports:
      - 8080:8080
      - 29418:29418
    volumes:
      - ./data:/gitbucket 
    depends_on:
      - db
    environment:
      - GITBUCKET_DB_URL=jdbc:postgresql://db/gitbucket
      - GITBUCKET_DB_USER=gitbucket
      - GITBUCKET_DB_PASSWORD=gitbucket
    command: ["/gitbucket/wait-for-it.sh", "db:5432", "--", "java", "-jar", "/opt/gitbucket.war"]

  db:
    image: postgres:9.5-alpine
    restart: always
    environment:
      - POSTGRES_DB=gitbucket
      - POSTGRES_USER=gitbucket
      - POSTGRES_PASSWORD=gitbucket
    volumes:
      - ./db:/var/lib/postgresql/data
```

# 起動
```shell-session
$ sudo docker-compose up -d
```

# 参考
* [Control startup order in Compose](https://docs.docker.com/compose/startup-order/)
* [docker-composeでDBの起動完了を待ってからWebアプリを実行する](https://qiita.com/shiena/items/47437f4f7874bf70d664)
『独習Git』6章メモ

# 確認したコマンド
- git diff
- git diff --staged

# メモ

```
★初期状態。コミットした時点から何もいじってないので出力もない
ubuntu# git diff
★vimってから
ubuntu# vim file1
ubuntu#
★diffとると差分が表示される
ubuntu# git diff
diff --git a/file1 b/file1
index e69de29..bda0724 100644
--- a/file1
+++ b/file1
@@ -0,0 +1,2 @@
+file1
+
★ただしaddしてないのでまだステージングエリアには表示されない
ubuntu# git diff --staged
★addして
# git add file1
★diff取ると何も表示されないけど
ubuntu# git diff
★ステージングエリアには表示される
ubuntu# git diff --staged
diff --git a/file1 b/file1
index e69de29..bda0724 100644
--- a/file1
+++ b/file1
@@ -0,0 +1,2 @@
+file1
+
```
Ebeanでテーブル一覧(show tables)を取得する


誰得かもしれませんが、ebeanでshow tablesのSQLコマンドを叩き、テーブル名をJSONで取得するやり方をご紹介します。

## 開発環境

Java8
Play Framework 2.5.1(Java)
sbt 0.13.11

## DB構成
DB名: sample_db

テーブル名:
・tweet
・user

モデルの操作は、Playに同梱されているEbeanと呼ばれるORMを利用します

## Controller

ここではSampleControllerというコントローラー内のgetTables関数に処理を記述しておきます。

```java
//app/controllers/SampleController.java

public Result getTables() {
        String sql = "show tables;";

        List<SqlRow> sqlRows = Ebean.createSqlQuery(sql).findList();
        List<String> tables = new ArrayList<String>();

        sqlRows.forEach((row) -> {
            tables.add(row.getString("tables_in_sample_db").toString());
        });

        JsonNode json = Json.toJson(tables);
        return ok(json);
}
```


## ルーティング

```
GET    /tables     controllers.SampleController.getTables
```

これだけでOKです


## 見てみよう

あとはcurlでAPIを叩いて確認しましょう。

```bash
curl "localhost:9000/tables"
```

value部にちゃんとテーブル名が取得出来ているのが確認出来ました。

```
["tweet","user"]
```


## ポイント
実装を見てお気づきかもしれませんが、今回の実装では、findListメソッドで取得したSqlRow型Listの結果をそのまま返さず、forEachで新たに作成したString型のListをJSONで返却しました。

これはSqlRowをそのまま返却すると以下のように、カラム名=valueのようなフォーマットで返されてしまうからです。

```json
[{"tables_in_sample_db":"tweet"},{"tables_in_sample_db":"user"}]
```
`tables_in_hogehoge` が必要な場面があるのかはその業務によりけりですが、単純にDBからテーブル名だけを取得したい場合は、新たにListを作ってgetStringメソッドでString化したValueを格納する作業が必要です。


## 参考記事
・ [Java Play framework 2.0で、ebeanを利用した直接SQL](http://programmer-jobs.blogspot.jp/2012/08/java-play-framework-20ebeansql.html)
・ [クラス SqlRow](http://qiita.com/rubytomato@github/items/17aed34b6294b4f205ea#ebean%E3%81%AE%E8%A8%AD%E5%AE%9A)
Snackbar表示中に別のSnackbarが表示できないことがある件

ちょっとハマったのでメモしておきます。
以下のコードだとSnackbar上のボタンを押したときに出る2回目のSnackbarが高確率で表示されません。

```kotlin
Snackbar.make(view, "Snackbar1", Snackbar.LENGTH_LONG)
    .setAction("Action") {
      Snackbar.make(view, "Snackbar2", Snackbar.LENGTH_LONG).show()
      val stringBuilder = StringBuilder()
      for (i in 0..10000000) {
        stringBuilder.append("test")
      }
    }
    .show()
```

こんなにメモリが少ない状態を無理に作らなくても、メモリが少ないアプリでは普通に表示されなかったりします

# なぜ？
SnackbarはSnackbarManagerというシングルトンなクラスが管理しており、前のSnackbarが消えてから次のSnackbarを表示する制御がされています。
次のSnackbarを表示するとき、実際に表示するためのレイアウトなどを参照しているcallbackはWeakReferenceになっていて、それがあれば表示を行います。
そのため、2つ目のSnackbar.showから、前のSnackbarが消えるまでに、メモリ不足の場合にcallbackが開放されてしまいnullが入ってしまい、表示されないことがあります。

```java:SnackbarManager.java
    private static class SnackbarRecord {
        final WeakReference<Callback> callback;
        int duration;
        boolean paused;

        SnackbarRecord(int duration, Callback callback) {
            this.callback = new WeakReference<>(callback);
            this.duration = duration;
        }
```


```java:SnackbarManager.java
            final Callback callback = mCurrentSnackbar.callback.get();
            if (callback != null) {
                callback.show();
```

# どのように対応するか？

普通にSnackbarをメンバ変数で持ったり、以下のように持つことで対応できます。他にいい方法があれば教えてください！

```xml
<resources>
  <item name="retain_snackbar" type="id"/>
</resources>
```

```java
Snackbar snackbar = Snackbar.make(view, "Snackbar2", Snackbar.LENGTH_LONG);
view.setTag(R.id.retain_snackbar, snackbar);
snackbar
    .addCallback(new Snackbar.Callback(){
      @Override public void onShown(Snackbar sb) {
        view.setTag(R.id.retain_snackbar, null);
       }
    })
   .show();
```
Elastic BeanstalkのRubyプラットフォームでRails & Webpackerをデプロイする

そのままデプロイしようとするとエラーで落ちてしまうので、asset precompileが走る前に下記を解決する必要がある。

- nodejsのバージョンを6.0以上に上げる
  - 元々入っているバージョンは4.6
- yarnをインストールする
- `yarn install` を実行

# 対応方法
[Webpackerのissue](https://github.com/rails/webpacker/issues/118#issuecomment-295594321) を参考に、 `.ebextensions/01_yarn.config` を設置する。
`./bin/yarn install` が存在しなくて動かないので `yarn install` に変更した。
Raspberry Pi 3/ Zero / Zero W等で watchdogを有効化する

# Overview

Raspberry Pi3をサーバーにして、１日１回再起動させたりもしているが、たまに固まることがある。
そこで、Raspberry Pi 3/ Zero / Zero W等で watchdogを有効化にしてみます。

diff表記にします。

```-``` が先頭の行は修正前
```+``` が先頭の行は修正後 (```+``` は不要)

# /bootの編集

```/boot/config.txt
-#dtparam=watchdog=off
+dtparam=watchdog=on
```

# watchdog.conf

```/etc/modprobe.d/bcm2835-wdt.conf
+options bcm2835_wdt heartbeat=10 nowayout=0
```

# system.conf

```/etc/systemd/system.conf
-#RuntimeWatchdogSec=0
+RuntimeWatchdogSec=5
```

watchdog.confで、10秒間heartbeatが来ないと再起動に設定したので、
５秒おきにheartbeatするように設定する例です。

再起動して、```dmesg | grep bcm``` とかして watchdogが動いてることを確認してください。
『独習Git』4章メモ

# 扱うコマンド
- git init
- git status
- git add 
- git commit -m
- git log
- git ls-files

# コマンド例

```
★空のディレクトリ(repo)上で `git init`コマンドを実施し、リポジトリが作成される（.gitディレクトリができる） 
ubuntu# git init
Initialized empty Git repository in /home/kure/repo/.git/
ubuntu# ls
ubuntu# ls -laht
合計 12K
drwxr-xr-x  7 root root 4.0K Nov  9 23:21 .git
drwxr-xr-x  3 root root 4.0K Nov  9 23:21 .
drwxrwxr-x 26 kure kure 4.0K Nov  9 23:21 ..

★ この時点でgit logしてもブランチにコミット履歴が無いからか、怒られる
ubuntu# git log
fatal: your current branch 'master' does not have any commits yet

★この時点でgit ls-filesしてもまだ何もGitに追跡されてないので、何も表示されない
ubuntu# git ls-files
★ファイル作成
ubuntu# touch file1

★git statusで見ると、追跡されてないファイル（今作ったfile1）が見える
ubuntu# git status
On branch master

最初のコミット

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        file1

★git addで追跡を開始するとls-filesでも見えるようになり、git statusの結果もnew fileとして表示される
ubuntu# git add file1
ubuntu# git ls-files
file1
ubuntu# git status
On branch master

最初のコミット

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   file1
★コミットする
ubuntu# git commit -m "first"
[master (root-commit) ab05ab6] first
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 file1
★statusで見てもコミットしたばかりなので、他にコミットするものが無い、というメッセージが表示される
ubuntu# git status
On branch master
nothing to commit, working directory clean
★git logで見るとコミットのログが表示される
commit ab05ab6618fccddb3155061b246600a20a1b6f21
Author: root <@gmail.com>
Date:   Thu Nov 9 23:23:08 2017 +0900

    first
```
[Swift4] Twitterにスクリーンショットを投稿する方法

# スクリーンショットの取得
ViewControllerの中に以下の関数を追加

```swift
     /**
     * @brief  スクリーンショットを取得する
     * @return UIImage
     */
    func getScreenShot()-> UIImage {
        // キャプチャ範囲を決定
        let width = Int(UIScreen.main.bounds.size.width)  //画面横幅いっぱい
        let height = 100
        let size = CGSize(width: width, height: height)
        // ビットマップ画像のcontextを作成
        UIGraphicsBeginImageContextWithOptions(size, false, 0.0)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        // 対象のview内の描画をcontextに複写する.
        self.view.layer.render(in: context)
        // 現在のcontextのビットマップをUIImageとして取得.
        let capturedImage : UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        // contextを閉じる.
        UIGraphicsEndImageContext()
        return capturedImage
    }
```

# Twitterへの投稿
実装手段は主に2通り

||UIActivityViewController|TwiterKit|
|:---:|:---:|:---:|
|○|実装一瞬。LINEやFacebookにも対応。|アプリ入ってなくてもツイートしてもらえる。 | 
|×|アプリ入ってないとツイートできない|導入がちょっとだけ手間|

ここではUIActivityViewControllerを使う

.pngの場合: **UIImagePNGRepresentation()**をかませる
.jpegの場合: **UIImageJPEGRepresentation()**をかませる

```swift
// スクリーンショットを取得
let shareImage = UIImagePNGRepresentation(getScreenShot())
// 共有項目
let activityItems: [Any] = [shareImage!, "投稿したいテキストおおおお"]
// 初期化処理
let activityVC = UIActivityViewController(activityItems: activityItems, applicationActivities: nil)

// iPad用処理
if UIDevice.current.userInterfaceIdiom == .pad {
    activityVC.popoverPresentationController?.sourceView = self.view
    activityVC.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.size.width / 2.0, y: self.view.bounds.size.height / 2.0, width: 1.0, height: 1.0)
}

// UIActivityViewControllerを表示
self.present(activityVC, animated: true, completion: nil)
```


# 参考
[スクリーンショットをUIImageに保存する方法](http://anthrgrnwrld.hatenablog.com/entry/2015/10/19/203907)
React+Redux+Electronで雑に開発をはじめるとき

Vue.jsとかだと[electron-vue](https://github.com/SimulatedGREG/electron-vue)というツールが公式にあって、これ入れてコマンド叩けばhot reloadありvuexありrouterありeslintありの環境が対話形式で作られてくので楽なんだけど、Reactはそういうの無くて色々だるいので雑に作って良いなら好みのboilerplateをcloneして作ったほうが早い。

- [electron-react-boilerplate](https://github.com/chentsulin/electron-react-boilerplate)
- [basic-electron-react-boilerplate](https://github.com/pbarbiero/basic-electron-react-boilerplate)
- [electron-react-webpack](https://github.com/pastahito/electron-react-webpack)

小さいboilerplateにredux,eslint,electron-packagerあたりをインストールするかelectron-react-boilerplateみたいな全部入りのやつを使うかは趣味。

electron-vueみたいなツールなんでないんだろ。文化ってやつか。

**[追記]** basic-electron-react-boilerplateをベースにeslintとか入れる設定した追加したやつを作った。

- [my-basic-electron-react-boilerplate](https://github.com/YuheiNakasaka/my-electron-react-boilerplate)
C言語のchar*をSwiftに渡す

#すること
C言語でchar*を返し、swiftでStringとして扱う

# 場面
HelloFrameWork(Cocoa Touch Framework)を作成し終えたので、swiftからその中のメソッドを使いたい

# C言語

hello.hは、Xcodeでpublicヘッダーにしておく

```hello.h
#ifndef HELLO_H
#define HELLO_H

char* getHello();

#endif
```

```hello.c
char* getHello() {
    return strdup("Hello");
}
```

# swift

```swift
let hello_char = getHello()
let hello: String = String(cString: hello_char)
// メモリ解放
free(hello_char)
```

# 参考
[公式 ドキュメント Using Swift with cocoa and Object-C](https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithCAPIs.html)

# 追記
strdup()を使うのはやはり美しくないようです。
より良く書くなら、swift側でdestinationとなる引数を与えて、そこに値を入れるようにすべきです。
jQueryのとネイティブの寸法系メソッドの違い

jQueryの寸法系のメソッドは、DOMに対して大幅な変更が入っている部分もあります。

# メソッド名が統一されていない例

IEがDHTMLとして入れたものをそのまま引き継いでいるという歴史的経緯もあってか、寸法系のプロパティは通常の要素と`window`や`document`で別物になっている例も多く、jQueryがそれを吸収していたりもします。

たとえば、`scrollTop`や`scrollLeft`はスクロールするエレメントにあるプロパティですが、`window`や`document`にはないので、これらでは代わりに`window.pageYOffset`や`window.pageXOffset`を取り出しています。

## 4段階の取得メソッド

jQueryでは、幅・高さの取得系メソッドは、3つ・4段階に分かれています。

* `width`/`height`…中身とパディングの間が基準
* `innerWidth`/`innerHeight`…パディングとボーダーの間が基準
* `outerWidth`/`outerHeight`…ボーダーとマージンの間
* `outerWidth(true)`/`outerHeight(true)`…マージンの外側

普通のエレメントの場合、jQueryの内部では中身、マージン、パディング、ボーダーなどをCSSとして取得して足し合わせる、というような処理を行っています。

ネイティブDOMで容易に取得できるのは、`.clientWidth`/`.clientHeight`でパディングの外側（jQueryの`inner`系相当）、`.getgetBoundingClientRect()`経由でボーダーの外側（jQueryの`outer`系相当）などがあります。

そして、`window`や`document`については、jQueryで特殊な扱いをしています（`width`だけ書きますが、`height`も同じです）。

* `$(window).outerWidth()`…`window.innerWidth`（スクロールバー込みの幅）
* `$(window).innerWidth() & $(window).width()`…`document.documentElement.clientWidth`（スクロールバー抜きの幅）
* `$(document).***width()`（3つとも同じ）…「`document.body`と`document.documentElement`の`scrollWidth`と`offsetWidth`（2×2=4通り）、`document.documentElement.clientWidth`」の5つの中での最大値

# `offset`の違い

jQueryで書いてあった`.offset().top`を機械的に`.offsetTop`に置き換えたところ、値が合わない、ということが発生しました。調べてみると、

* jQuery…`.offset`の基準点はドキュメントの左上
* ネイティブ…`.offsetTop`の基準はoffsetParent ノード（`position`をかけた要素など、ドキュメントの途中にも入りうる）

と、基準が違うとのことでした。ということで、ドキュメントの左上から測りたいときは、以下のjQueryのコードを参考に組み立てるのが良さそうです。

```js:jQuery.fn.offset()より取得部分を引用
if ( !elem.getClientRects().length ) {
	return { top: 0, left: 0 };
}

rect = elem.getBoundingClientRect();

doc = elem.ownerDocument;
docElem = doc.documentElement;
win = doc.defaultView;

return {
	top: rect.top + win.pageYOffset - docElem.clientTop,
	left: rect.left + win.pageXOffset - docElem.clientLeft
};
```
webサーバについて

Webサーバとは、HTTPリクエストを受け取り、HTMLなどのWebページをHTTPレスポンスとして返すサーバのことです。単なる静的Webサイトであれば、Webページ（HTML、CSS、画像など）をレスポンスとして返すだけですが、リクエストで要求されたWebページがRuby(ERB)で出来ていると、rubyコマンドで実行されて出力されたWebページをレスポンスとして返します。Webサーバを起動しなければ、仮にHTTPリクエストが来ても誰も処理しないのでHTTPリクエストは無視されます。HTTPリクエストが来た時にWebサーバが起動していれば、何らかのレスポンスを返します。
.gitignoreに記載したのに反映されない件


.gitignoreにファイルを指定することで、git上にアップしたくないファイルをアップせずに済みます。
ローカルでのみ必要なファイルがある場合に非常に便利です。

しかし、.gitignoreに記載したのに反映されなかったことがあったので、原因と解決策について記載します。

## 原因

一度gitにアップしてもらったものを、.gitignoreに追加したことが原因だった。
キャッシュにインデックスが残っているので、.gitignoreの設定が反映されていなかった。

## 解決策

### 手順

1. .gitignore 編集
2. キャッシュを削除
3. commit & push

キャッシュ削除の際、ファイルを削除しているわけではないのでご安心を。
また、pushした際に大量のremoveログが出るが、ローカルのファイルが消えたわけではないのでご安心を。

### キャッシュ削除の方法

下記コマンドを実行する。
ファイル全体キャッシュ削除が確実だが、怖い人はファイル指定をしてもいいと思う。

```
$ git rm -r --cached . //ファイル全体キャッシュ削除
$ git rm -r --cached [ファイル名]	//ファイル指定してキャッシュ削除
```

## まとめ、補足

エンジニアが一度はハマるポイントだと思います。
同じミスをしないように気を付けましょう。
IronPython2.7とCPython2.7での文字列の違い

IronPythonは文字列の扱いが標準のCPythonと違うようなので比較してみました。

# おさらい

その前にPython2(CPython2)の文字列について簡単におさらいしておきます。

Python2の文字列にはstrとunicodeの２つがあります。(以下、バイト文字列、ユニコード文字列と表現します)

```pycon:バイト文字列
>>> str()
''
>>> 'あ'
'\x82\xa0'
```

```pycon:ユニコード文字列
>>> unicode()
u''
>>> u'あ'
u'\u3042'
```

バイト文字列の実体はバイト配列です。`len()`の結果はバイト数を返します。
これに対してユニコード文字列は文字数を返します。

```pycon
>>> isinstance(str(), bytes)
True
>>> len('あ')
2
>>> len(u'あ')
1
```

ユニコード文字列をバイト文字列に変換するには`encode()`、バイト文字列をユニコード文字列に変換するには`decode()`を使用します。

```pycon
>>> u'あ'.encode('shift_jis')
'\x82\xa0'
>>> 'あ'.decode('shift_jis')
u'\u3042'
```

Python2の文字列についてもっと詳しく知りたい人は以下を参照してください。

[Unicode HOWTO — Python 2.7.14 ドキュメント](https://docs.python.org/ja/2.7/howto/unicode.html)
[Python2のstr/unicodeとencode/decode - Qiita]
(https://qiita.com/yubessy/items/9e13af05a295bbb59c25)
[Python2で文字列を処理する際の心掛け - Qiita]
(https://qiita.com/FGtatsuro/items/cf178bc44ce7b068d233)

# 比較

それではCPython2.7とIronPython2.7を比較していきます。

## インタープリタでの表示結果

|実行内容|CPython2.7|IronPython2.7|
|:---:|:---:|:---:|
|`'あ'`|`'\x82\xa0'`|`u'\u3042'`|
|`u'あ'`|`u'\u3042'`|`u'\u3042'`|
|`b'あ'`|`'\x82\xa0'`|`b'B'`|

IronPythonの文字列は`u`をつけなくてもユニコード文字列になるようです。

## type

|実行内容|CPython2.7|IronPython2.7|
|:---|:---:|:---:|
|`type('あ')`|str|str|
|`type(u'あ')`|unicode|str|
|`type(b'あ')`|str|bytes|
|`type(str())`|str|str|
|`type(unicode())`|unicode|str|
|`type(bytes())`|str|bytes|

IronPythonの文字列はバイト文字列もユニコード文字列も型としてはstrになるようです。

## isinstance()

|実行内容|CPython2.7|IronPython2.7|
|---|:---:|:---:|
|`isinstance('あ', str)`|True|True|
|`isinstance('あ', unicode)`|False|True|
|`isinstance('あ', bytes)`|True|False|
|`isinstance(u'あ', str)`|False|True|
|`isinstance(u'あ', unicode)`|True|True|
|`isinstance(u'あ', bytes)`|False|False|

## `==`

|実行内容|CPython2.7|IronPython2.7|
|:---:|:---:|:---:|
|`'あ' == u'あ'`|False|True|
|`'あ' == b'あ'`|True|False|
|`u'あ' == b'あ'`|False|False|

## encode/decode

|実行内容|CPython2.7|IronPython2.7|
|:---:|:---:|:---:|
|`u'あ'.encode('shift_jis')`|`'\x82\xa0'`|`u'\x82\xa0'`|
|`type(u'あ'.encode('shift_jis'))`|str|str|
|`u'あ'.encode('shift_jis').decode('shift_jis')`|`u'\u3042'`|`u'\u3042'`|
|`type(u'あ'.encode('shift_jis').decode('shift_jis'))`|unicode|str|

IronPythonではエンコード/でコードすると文字コードは変わるけど型はそのままのようです。
型が同じなのでバイト文字列とユニコード文字列を判別する方法はありません！

# まとめ

- CPython
    - 文字列にはバイト文字列を扱うstr型とユニコード文字列を扱うunicode型がある
    - unicodeからstrに変換するにはencode()、strからunicodeに変換するにはdecode()を使用する
    - str型とbytes型は等価
- IronPython
    - 文字列はstr型しかない
    - 同じstr型でも内部ではバイト文字列で持っている場合とユニコード文字列で持っている場合がある
    - encode()/decode()しても型は変わらない
    - strとbytesは別物
TypeScript のちょっとした検証をしたい時にぱっと作れる環境

TypeScript の検証などを行いたい時にすぐに試せる最小の手順を整理してみました。

検証した際の各バージョンは以下のとおりです。

- node v8.1.4
- npm 5.4.2
- tsc Version 2.6.1

## tsc の準備

TypeScript のインストール

```shell-session
npm install -g typescript
```

tsconfig.json の作成

```shell-session
tsc --init
```

作成された tsconfig.json の編集は任意
target、module を色々と変えると面白いです。

## npm の準備

```shell-session
npm init
# 任意で型定義ファイルをインストールしてください。
# 以下は node.js の型定義ファイルをインストールしています。
# tsconfig.json の types に追加すると、適応されます。
npm install @types/node
```

## tsc でコンパイル

ts ファイルを作成して以下のコマンドを実行する

```shell-session
tsc
```

最終的にプロジェクト以下はこのようになります。

```
.
├── index.js // 生成された js ファイル
├── index.ts // 作成した ts ファイル
├── node_modules
├── package-lock.json
├── package.json
└── tsconfig.json
```
Zabbix API（参照系）の逆引きメモ


しばらく前から運用系の業務に従事することになり、そこで監視システムとして使われていたZabbixとお近づきになる生活が始まりました。

Zabbixをもうちょい乗りこなして賢く使いたいので、自分の試してみた範囲でAPIの叩き方を逆引きメモとして残したいと思います。

なお、私は運用の作業者ロールでZabbixを利用しています。テンプレートの設定とか、監視設定の構築に関わる部分の話はできません。
「こんな設定内容見たいけど、どうすればいいの？」というニーズにはマッチするところがあるかなと思います。
※一部コピペで書いてない部分があります。動かないスニペットがあったらすいません。

# 使用環境

- Mac OS X / El Capitan
- Python 3.6
- Zabbix 2.2

ZabbixのAPIを生で叩くのは工数もかかって率が悪いので、ここではZabbix APIのラッパーとして[py-zabbix](https://pypi.python.org/pypi/py-zabbix/)を利用します。

必要に応じてdatetimeとかjsonとかyamlとか、他のモジュールも利用します。

---


# 登録ホスト名からIP/DNS name/Portを引く

[host.get](https://www.zabbix.com/documentation/2.2/manual/api/reference/host/get)を使います。 "selectInterfaces" のパラメータを出力させるように引数を与え、そこからIPやポートの情報を参照します。

Interfaceの詳細はこの辺を御覧ください。

 [Zabbix Documentation 2.2: Host interface object](https://www.zabbix.com/documentation/2.2/manual/api/reference/hostinterface/object#host_interface)

_type_ や _useip_ が割と重要かと思います。 _useip_ は "0"ならDNS name、 "1"ならIPを使っている、ということになります。

```python
# Zabbix API オブジェクトの生成（以降ここは省略）
import pyzabbix
zapi = pyzabbix.ZabbixAPI(url='https://localhost/zabbix/', user='admin', password='zabbix')

# host.get
## ホスト名完全一致で引くなら以下
param = dict(
    output = "extend",
    selectInterfaces = "extend",
    filter = {
        "name": hostnames  # 複数対象でも検索は可能。 str or list
    }
)
## ホスト名部分一致で引くなら以下
param = dict(
    output = "extend",
    selectInterfaces = "extend",
    search = {
        "name": hostnames  # str or list
    }
)

ret = zapi.host.get(**param)

# 一致したホスト名を列挙
hostnames = [ host["name"] for host in ret ]

# インタフェースの参照
hostname = ret[0]["name"]
interfaces = ret[0]["interfaces"]

## DNSを登録しているインタフェース
use_dns = [ i for i in interfaces if i["useip"]=="0" ]
for i in use_dns:
	print("{} {}:{}".format(hostname, i["dns"], i["port"]))

## IPを登録しているインタフェース
use_ip = [ i for i in interfaces if i["useip"]=="1" ]
for i in use_ip:
	print("{} {}:{}".format(hostname, i["ip"], i["port"]))

# タイプが「エージェント」になっているインタフェース
ip_or_dns = lambda intf: intf["ip"] if intf["useip"]=="1" else intf["dns"]
agent_interfaces = [ i for i in interfaces if i["type"]=="1" ]
for i in agent_interfaces:
	print("{} {}:{}".format(hostname, ip_or_dns(i), i["port"]))

```


(2017.11.09) ネタができ次第、追記していく予定です。
firewalldの設定


# 概要

開発用のサーバなので予期せぬ不具合を防止するためにfirewalldを無効化する。


# firewalldの無効化

#### firewalldの停止

以下のコマンドでfirewalldを停止、無効化する。

```bash:firewalldの停止、無効化
sudo systemctl stop firewalld
sudo systemctl disable firewalld

<出力結果>
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
```


#### firewalldの起動状態を確認する

以下のコマンドでfirewalldが停止していることを確認する。

```bash:firewalldの起動状態確認
systemctl status firewalld

<出力結果>
● firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)
```

# 次の手順

[時刻同期Chronyの導入](https://qiita.com/mattsun/items/f2dc3519e1a628f81923)


以上
HTMLファイルから取得したいボタンを選択する

### Gouttteの使い方
> テストで最近よく使うので、PHPの代表的なスクレイピングライブラリであるGoutteの使い方をまとめます。
また実際にGoutteで、HTMLファイルから取得したいボタンを選択してみます。

### Goutteのインストール
> Composerでインストールします。

```bash
$ cd path/to/goutte
$ composer require fabpot/goutte
```

Goutteの大まかな使い方は以下のような手順になります。
1. Goutteの読み込み
2. Goutte クライアントを作成
3. ページをリクエスト
4. 取得したCrawlerオブジェクトのメソッドでスクレイピング

#### Goutteの読み込み
> Goutteの読み込みは以下のように行います。
一度書いてしまえば、あとは3番からを繰り返せばいいはずです。

```php
require_once 'path/to/goutte/vendor/autoload.php';

use Goutte\Client;
```

#### Goutte　クライアントを作成

```php
$client = new Client();
```

#### クライアントにページをリクエストする

```php
$crawler = $client->request('GET', 'http://example.com/');
```
> 上記では$crawlerにhttp://example.com/へGETリクエストをさせています。


#### 実際にページをスクレイピング

```php
$name = $crawler->filter('body > name')->text();
```


### 実際にHTMLファイルからボタンを選択する
> 今回はファイル上にあるTransferボタン(Typeはsubmit)を選択するものとします。
selectButtonの中には取得したいボタンのラベル名、もしくはname属性を指定してあげると取得することができます。
同じファイルの中に、同じname属性、もしくはラベル名が存在するときには、別のname属性をつけてあげるか、異なる方を指定してあげると良いと思われます。

```php
$crawler->selectButton('Transfer')
```
sudoの設定

# 概要

特定のアカウントに特権を与える。


# wheelグループの設定

#### パスワード不要の設定

wheelグループはパスワードなしでsudoを実行できるようにする。

以下のコマンドでsudoの設定ファイル：/etc/sudoersファイルを編集する。

```bash:visudoで設定変更
sudo visudo
```

```text:/etc/suduers　･･･visudoコマンドで編集
（中略）
### wheel nopasswd begin
## Allows people in group wheel to run all commands
### comment out
### %wheel  ALL=(ALL)       ALL

## Same thing without a password
### uncomment
%wheel        ALL=(ALL)       NOPASSWD: ALL
### wheel nopasswd end
（中略）
（以下の設定で、/usr/local/binを追加する）
#
# Adding HOME to env_keep may enable a user to run unrestricted
# commands via sudo.
#
# Defaults   env_keep += "HOME"

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin

```

# 次の手順

[firewalldの設定](https://qiita.com/mattsun/items/7bc7900cd8576090e718)


以上
プログラミング未経験者がエンジニア目指す

# N予備校の章
第0章 入門コースをはじめる方へ
第1章 はじめよう
 01.プログラミングを体験してみよう
 02,はじめてのHTML
 03,さまざなHTMLタグ(ulタグまで)
## はじめに
平成29年11月3(金)からＮ予備校に体験入学。
本日11月9日までの間に第1章の03,さまざなタグの
Ulタグまで進められました。

お仕事おわったあとにちょっとずつ進めてた。
## 概要
・ブラウザとは何か学ぶ
・chromeのconsoleを使って計算させる
・HTMLとは何か学ぶ
・VS Codeを使ってHTMLを書く
・HTMLの様々なタグについて学ぶ（h,p,a,img,ul,table)

## 分かったこと
・ブラウザとはホームページを表示するもの。
・HTMLとはホームページを作るための言語。
・HTMLのタグのそれぞれの役割が知れた。

## 疑問点
・特になし。何がわからないのかそれがわからないから、疑問が浮かばない。
## 感想
・初めてプログラミングをして楽しいと思えた。
・テキストを見ながらでもプログラミングができたことに感動した。
## 終わりに
・お仕事おわりは眠いけど、エンジニアになりたいから頑張る。
OctoberCMSのadminユーザがなくなったときの対処法

マイグレーションをごちゃごちゃやっていると、たまにデフォルトで入っているadminユーザ（テスト用だろうが）がなくなる、ときの対処法。

プロジェクトルートで下記を実行。

```
php artisan db:seed --class="\Backend\Database\Seeds\SeedSetupAdmin"
```

マイグレーションをdownしてupしたときに、プラグインのマイグレーションなどでコケて最後のadminユーザ追加が実行されなかった時に使える。

出典：https://octobercms.com/forum/post/admin-account-suspended-how-to-get-back-in
1on1MTGをやってみた


業務の傍ら、 **1on1** という取り組みをやってみたので、やり方や感想について記載します。

## 事前説明

### 1on1とは

ヤフーさんが本を出している。
ヤフーの1on1 - 部下を成長させるコミュニケーションの技法
https://www.amazon.co.jp/dp/B0716B52LP/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1

私の言葉で要約すると、 **「業務時間内で、社員同士が1対1で仕事場に関することなどを話す場」** である。

※本では上司と部下で1on1のコーチングをしているが、別に上司と部下じゃなくても問題ないと思う。

## 1on1の取り組み

私の会社では既にいくつかの部署が取り組んでいたが、自分の部署では行っていなかったので、
後輩が私のチームに入ってきたタイミングで、2人で実施してみた。
ちなみに後輩は、自分とは別プロジェクトに所属する、1コ下の後輩だった。

### 1on1を取り入れた理由

そもそもなぜ1on1をやろうと思ったのか。

**理由1：マネジメント業務の取り組み・練習がしたかったから。**

現在自分は社会人経験が浅く、立場としてそこまで高くない。
ただそのうちマネジメント業務に携わりたいと思っていたので、今のうちから何かしらの取り組みに取り組みたかった。

**理由2：仕事以外で職場の人と話す機会が少なかったから。**

飲み会が多い職場なら別かもですが、自分の部署は飲み会が少なく、
職場の人とコミュニケーションを取る機会が少なかった。
同じ職場で働く以上、コミュニケーションを取ることが業務上大事だと思うので、
何かしらの取り組みがしたかった。

**理由3：後輩が円滑に仕事できるように。**

自分が今の部署に最初入ってきた時、
OJTの方が多忙だったこともあり、業務や会社の業務外のことなど聞く機会があまりなくて困った。
そこで、部署に入ってきた人にとって、普段聞きにくいことを聞けるような場が必要だと思った。

**理由4：流行っているから。**

最近とてもトレンドだったので。笑

### 1on1のやり方

やり方は人によって、環境によって異なるとは思うが、
自分たちに合うやり方・ルールを予め考えてみた。

- 期間：週1
- 時間：1回30分
- テーマ：後輩が考える

上司が複数人の部下、例えば10人の部下と1on1をする場合、2週間に1回15分で実施した方がよいかもしれない。
ただ、今回は1人の後輩としか1on1しなかったので、無理がないよう1週間に1回30分でやってみた。

また、本にも記載ある通り、テーマは基本後輩に考えてきてもらうようにした。
私からテーマを出すこともあるが、後輩が出すテーマを優先度高くした。

ちなみに、後輩には言わず、私が勝手に決めた暗黙のルールが下記。

- 怒ることはあまりしない。自分の意見は控えめにして、傾聴する。
- 次の1on1までに何をするか、毎回宿題を出す。

個人的に、1on1が苦痛、と思われることを一番危惧した。
怒ってしまったり、自分の意見を相手に押し付けてしまったりすると不快にさせてしまう。
このようなことがないように気をつけた。

また、1on1は週1という習慣的作業なので、毎週なにかしらの成果が出せるよう、宿題を出した。
例えば、「毎週1本Oiitaに記事を書く」「毎週気になる記事を1on1の場で紹介する」など。
もちろん、この宿題を忘れてしまった場合も怒ることはしない。

## やってみた感想

### 私の感想

**良かった点1：コミュニケーションが活発になった**

1on1をする前とした後で、日常的にコミュニケーションが多くなったように感じた。
今まで用がなければ話さなかったところが、
何気ないことでも話すようになった気がする。

**良かった点2：他チームが何をやっているか、どういう状況なのかが分かる**

普段だと自分のチーム、部署しか知らず、考えが閉鎖的になってしまいがちだが、
1on1を別チームの人と行なうことで、他のチームはどういう状況なのか、何をやっているのか、どんな取り組みをしているのかが知れる機会となった。

**良かった点3：リフレッシュの時間になる**

仕事が立て込んでいたとしても、怒らない平穏な場として1on1の時間があったので、
私としてもリフレッシュの時間に感じた。

**悪かった点1：雑談が多くなりがち**

雑談自体が悪いとは思っていないが、
テーマを事前に考えておかなかったりすると雑談が多くなってしまいがち。
どんなことを話すか、私も事前にある程度候補を考えておいた方がスムーズかと思った。

### 後輩Mさんの感想

後輩にもやってみてどうだったか聞いてみた。

**良かった点1：不明点を聞ける**

新参者である私からすると、先輩に不明点を聞ける機会があるのはとてもありがたい。(例：既存サービスのアーキの話など)

**良かった点2：仲良くなれる**

プライベートの話をすることもあり、先輩との親近感が増す。
また、業務上での悩み相談もできるため、業務に対してのストレス緩和にもなり得る。

**良かった点3：自分で取り組んでいる活動に対してのFBがもらえる**

個人的に作っているアプリなどがあれば1on1で見せてFBをもらうことができた。
個人的には、誰かに作ったものを見てもらうことでモチベーションの向上に繋がるため、嬉しい機会である。
また、FBをもらい改善点や今後追加したい機能なども明らかになるのも良い点である。

**悪かった点1：業務時間を割かなくてはならない**

どうしても業務での実装に集中していたり、
タスクが山積みになっていると1on1の時間を業務に充てたいと感じることがある。

**悪かった点2：テーマを決めにくい**

1on1では後輩がテーマを決めるという方式になっているが、どうしても話す内容が浮かばなかったりする。
そういう時は、どうしても雑談になりがちだったりもする。

## まとめ、補足

気になることがあるので、時間を割いてメンバーと話をしよう。などと考えると腰が上がりにくい人もいるかと思います。
その時間が習慣的にあるというのは有意義だと思います。
総じて、1on1やってみて良かったと思うので、これからも継続してやっていこうと思っています。

チームメンバーとのコミュニケーションに悩んでいる人、
会社で悩みがあるのに聞きにくい人、
特に悩みとかないけど1on1してみたい人など、
ぜひ1on1やってみてください。
Node-redでmsgの中身をコピーするときに値渡しと参照渡しで困った件

node-redもJavascriptなんだからあたりまえなのかもですが、一瞬びっくりしたのでメモ。

#状況
1. CloudantからのID検索により、とあるObject（例えばeventとする）がmsg.payloadに入った
2. 後々このeventにフラグ一つを追加してCloudantに戻したいので、`msg.eventorg = msg.payload`として他所に逃がしておく。（コピーはFunction NodeでもChange Nodeでも同じ）
3. その後、**msg.payload**(msg.eventorgでは無い）の中に入っているカンマ区切りのプロパティをsplitして配列にする。（まぁこの処理は何でもよくて、つまり、**payload**を弄るということが言いたい）
4. その後色々な処理をする
5. 4の処理が成功したので、以下のように**eventorg**で保管していた値に新たなフラグをくっつけて、Cloudantに戻す。

```js
msg.payload = msg.eventorg;
msg.payload.isSent = true;
```

#何が起きるか
3で**msg.payload**に対して処理したsplitが何故か**msg.eventorg**にも反映されてしまうのです！オカルト！:scream:

#何故か
javascriptの仕様で、オブジェクトのコピー時は参照渡しになってしまうので、後で**msg.payload**を弄っても**msg.eventorg**まで変わってしまうわけです。
オカルトでも何でもないですね。:smile:

#ではどうやって回避したか
`msg.eventorg = msg.payload`
を
`msg.eventorg = JSON.parse(JSON.stringify(msg.payload));`
という具合に一度テキストにふやかしてからJSONにすることで、値渡しにすることができます。美しくは無いですが、めでたしめでたし。
Angular5における多言語機能の実現



# _ng5-i18n-demo_ Angular5による多言語化のサンプル
[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)


_ng5-i18n-demo_ はAngular5における多言語化機能をテストするためのプログラムです。

_ビデオ解説_
<https://youtu.be/5-6dwYtfRO4>


## 概要 
   - _ng5-i18n-demo_ はAngular5を利用して多言語環境を実現したいと考えている人のためのプログラムです。

 ## 必要環境

   - Node.js
   - TypeScript2
   - Angular/Cli (for Angular5 or later)


## インストール方法


このツールをインストールするためには、

   - まずこのプログラム用のディレクトリを作成し、そのディレクトリに移動します。

```bash
$ mkdir mydir
$ cd mydir
```
   - そのディレクトリで以下のようにクローンを作成します。

```bash
$ git clone https://github.com/Ohtsu/ng5-i18n-demo.git 
```

   - 作成された _ng5-i18n-demo_ に移動し、"npm install"を実行します。

```bash
$ cd ng5-i18n-demo
$ npm install 
```

### ローカルサーバ(英語版)の起動
以下のようにローカルサーバを起動します。 

```bash
$ ng serve
```

次にブラウザで **http://localhost:4200** にアクセスします。  

  - ***初期管理画面*** 

  <img src="https://raw.githubusercontent.com/Ohtsu/images/master/ng5-i18n-demo/ng5-i18n-demo_en-page_01.png" width= "640" >


### 他の言語でのサーバ(日本語)の起動 
以下のようにローカルサーバを起動します。 

```bash
$ npm run start:ja
```

次にブラウザで **http://localhost:4200** にアクセスします。  

  - ***初期管理画面*** 

  <img src="https://raw.githubusercontent.com/Ohtsu/images/master/ng5-i18n-demo/ng5-i18n-demo_ja-page_01.png" width= "640" >


## バージョン

   - TypeScript         : 2.4.2
   - @angular/cli       : 1.5.0
   - Node               : 6.11.3


## 参考文献

- "Internationalization (I18N)",
<https://v2.angular.io/docs/ts/latest/cookbook/i18n.html>

- "Internationalization (I18N) Japanese Translation by mixplace in Qiita",
<https://qiita.com/mixplace/items/3f1e1190e38c14f5297d>



## 変更履歴

 - 2017.11.9 version 0.1 uploaded
 - 2017.11.14 ビデオのＵＲＬを修正

## Copyright

copyright 2017 by Shuichi Ohtsu (DigiPub Japan)


## License

MIT © [Shuichi Ohtsu](mailto:ohtsu@digipub-net.com)
.ssh/config で PasswordAuthentication no に設定されているホストに一時的にパスワード認証で接続する


以下のように公開鍵認証の設定となっているホストであっても

```~/.ssh/config
Host target-host
  HostName xx.xx.xx.xx
  User no-password-user
  # 通常は公開鍵認証のみとする
  IdentitiesOnly yes
  PasswordAuthentication no
  IdentityFile ~/.ssh/secret_key  
```

コマンドラインで `-o PasswordAuthentication=yes` すれば設定をオーバライドしてくれる。


```shell:一時的にパスワード認証を使用する
$ ssh another-user@target-host -o PasswordAuthentication=yes
```
モバイルルータのインターネットへの接続状況をロギングする

## 概要
ローカル上のモバイルルータとインターネット上のクラウドサーバへの接続状況をロギングするスクリプト

## 用途
モバイルルータ（以下、ルータ）を使ってIoTシステムなどを運用していると、インターネット接続が不安定になることがある。このとき、

- ルータが死んでいるのか
- ルータは生きているがインターネットへのアクセスが不安定になっているのか

といった原因の切り分けを行いたくなる。そこで、ルータとクラウドサーバへの接続状況をロギングすることで、不安定となる原因の分析を可能とする。

ついでに、ルータのグローバルIPも取得する。モバイルルータを使ったIoTシステムでは、ルータのグローバルIPが切り替わるときに、サーバとの接続が切れて、アプリに問題が生じたりするので、グローバルIPをロギングできるとシステムのデバッグに役立つ。

## スクリプト
接続状況の確認にはpingを用い、グローバルIPの取得はcurlを用いている。
接続状況をロギングしたいルータとクラウドサーバのIPアドレスをそれぞれ、router_ipとserver_ipに設定し、実行すると日別のログファイルに接続状況が書きだされる。
実際に利用する場合は、このスクリプトをcronで定期実行している。

```check_status.sh
#!/bin/sh
ulimit -c unlimited
date=`date +"%Y-%m-%d"`
status=`date +"%Y-%m-%d %H:%M"`

router_ip="192.168.XXX.XXX" #local router IP address
server_ip="YYY.YYY.YYY.YYY" #cloud server IP address

#send ping to local router
/bin/ping ${router_ip} -c 3 >> /dev/null

#check return value from local router
if [ $? -eq 0 ]; then
status=${status}" router:OK"
else
status=${status}" router:NG"
fi


#send ping to cloud server
/bin/ping ${server_ip} -c 3 >> /dev/null

#check return value from cloud server
if [ $? -eq 0 ]; then
status=${status}" server:OK"
else
status=${status}" server:NG"
fi

#get router's global IP address
status=${status}" GlobalIP:"`curl -m 20 ifconfig.me`

echo ${status} >> ./log/${date}.log
```
AWSでSMSを送る際の月々の利用制限緩和

AWS SNSでSMSを送信できるけど、送信時に発生するコストの上限が毎月決まっている。
この制限を解除するには、AWSに問い合わせして上げてもらう必要がありますが、問い合わせから上限の変更までは数日かかってしまう。

上限緩和のリクエスト時に1発で必要な情報をまとめておかないと、サポートから質問が来て、その返信が必要になる。
サポートとのやり取りに1往復半日程度はかかってしまい、上限の変更完了までの期間が長くなってしまうので、上限緩和までの期間を最小限に抑えるため、必要な情報をまとめておく。

# 問い合わせ手順

[ここ](https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase&limitType=service-code-sns)のフォームに下記の内容を入力する。
ポイントは、 `Use Case Description` の内容で、ここにどのようにSMSを利用するのかを記載しておくと、スムーズに申請が進行する。

- Regarding: Service Limit Increase
- Limit Type: **SNS**
- Request 1
  - Limit: **Request Number of Topics**
  - New Limit Value: **希望する上限金額(USD)**
- Use Case Description: **下記Use Case Descriptionの項目参照**
- Support Language: **日本語**
- Contact method: **どちらでも可**

## Use Case Description

```
SMS送信に関する、月ごとのSMS使用制限の引き上げをお願いいたします。

①メッセージ送信元のウェブサイト、アプリケーション等の名称:
②メッセージを送る対象電話番号の収集方法:
③送る予定のメッセージの種類:
④具体的な送信予定の一日あたりのメッセージ数:
⑤具体的なユースケース:
⑥メッセージ送信先の国:
```

①の名称については、開発中などであれば未定でも大丈夫だった。

# 参考

- [Amazon SNSのSMSを送信](http://docs.aws.amazon.com/ja_jp/sns/latest/dg/SMSMessages.html)
Linux端末でCPU温度をロギングする

## 概要
とある用途で使っていたLinux端末が熱暴走したことをきっかけに、Linux端末のCPU温度をロギングをするShell Scriptを書いた。


```check_cpu_temp.sh
#!/bin/sh
ulimit -c unlimited
date=`date +"%Y-%m-%d"`
status=`date +"%Y-%m-%d %H:%M"`
status=${status}" "`cat /sys/class/thermal/thermal_zone0/temp`

echo ${status} >> ./log/${date}.log
```
基本的に、/sys/class/thermal/thermal_zone0/tempを読んでCPU温度を取得し、日付ごとのログファイルに書き込む。
利用時は、このShellScriptをcronで定期実行してロギングしている。

### 注意：
ロギングされる温度は1000倍されています（摂氏[℃]に変換するには1/1000倍してください）
ListBoxの全項目を高速に選択する

ListBoxの全項目を選択したいとする。
![selectall.png](https://qiita-image-store.s3.amazonaws.com/0/212471/aeebdc3b-6137-b54e-d577-a771555d8b6d.png)

SelectAll的なメソッドは存在しないので、自前で頑張る必要がある。

# 素朴な実装(これはダメ)

```csharp:素朴な実装
for (int i = 0; i < listBox1.Items.Count; i++)
{
    listBox1.SetSelected(i, true);
}
```

ぱっと思いつくのがこの方法だが、残念ながら、遅い。

# Windows APIを使ってみる

```csharp:宣言
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
private const int LB_SETSEL = 0x185;
```

```csharp:処理
SendMessage(listBox1.Handle, LB_SETSEL, 1, -1);
listBox1.SetSelected(0, true);
```

Windows APIを使って全選択メッセージを直接送ってやる方法だ。これなら一瞬だ。

# SendKeysしてみる

先述の方法で充分なのだが、もっと簡単に一行で済ます方法もある。

```csharp:SendKeys
SendKeys.SendWait("{HOME}+{END}");
```

HOMEキーで先頭を選択し、SHIFTキーを押しながらENDキーで最終項目まで選択するという操作を再現している。これも一瞬だ。
予め全選択したいコントロールにフォーカスが合っている必要がある。

(この記事は[昔書いた記事](https://tgws.plus/prog/listbox.selectall/)から余計な演出と遠回りを省いて再掲したものです。)