OmniAICreator/Qiita-1.07M huggingface dataset:
INDEXを貼らないと行ロックにならない件

タイトルのとおりですが、InnoDB は行ロックをかける事で有名ですが、行ロックをかけるには必ず INDEX が必要になります。
今回はその事について簡単にまとめようと思います。

#行ロックがかからない例
まずは、行ロックがかからない例を書いてみます。
下記のような単純な test テーブルを用意します。

```sql
+----+--------+
| id | number |
+----+--------+
|  1 |      1 |
|  2 |      2 |
|  3 |      3 |
|  4 |      4 |
|  5 |      5 |
|  6 |      6 |
|  7 |      7 |
|  8 |      8 |
|  9 |      9 |
| 10 |     10 |
+----+--------+
```

コンソール A でトランザクションを開始して、number = 1 の行を FOR UPDATE で取得します。

```sql
コンソール A

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM test WHERE number = 1 FOR UPDATE;
+----+--------+
| id | number |
+----+--------+
|  1 |      1 |
+----+--------+
1 row in set (0.00 sec)

```

次にコンソールBを立ち上げて、コンソールAがトランザクションを終了するまえに、number = 2 の行を FOR UPDATE で取得します。

```sql
コンソール B

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM test WHERE number = 2 FOR UPDATE;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

```

取得できませんでした。
これは、コンソールA のクエリによってテーブルロックがかかっているため、コンソールBが影響を受けたわけです。

#原因
InnoDB は INDEX 上のレコードをロックすることでレコードロックを行います。
その為、今回の用に INDEX が貼られていない場合、ロックをかけるべきレコードが特定できないので、テーブル自体にロックをかけてしまいます。

# 行ロックをかけてみる
というわけで、number カラムに INDEX を貼って、行ロックがかかるか試してます。
まずは number カラムにINDEX を貼ります。

```sql

mysql> CREATE INDEX number_index ON test (number);
Query OK, 0 rows affected (0.02 sec)
Records: 0  Duplicates: 0  Warnings: 0
```

では、この状態で先ほどと同じ事をやってみます。

```sql
コンソール A

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM test WHERE number = 1 FOR UPDATE;
+----+--------+
| id | number |
+----+--------+
|  1 |      1 |
+----+--------+
1 row in set (0.00 sec)

```

コンソールAがトランザクションを終了するまえに、number = 2 の行を FOR UPDATE で取得します。

```sql
コンソール B

mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM test WHERE number = 2 FOR UPDATE;
+----+--------+
| id | number |
+----+--------+
|  2 |      2 |
+----+--------+
1 row in set (0.00 sec)

```

今度は、コンソールBでも結果が返ってきました。
うまく行ロックができたようです。


#まとめ
* InnoDB は INDEX 上のレコードをロックすることでレコードロックを行う
* INDEX を貼っていないとテーブルロックがかかる
C > stdint.hを使うことで処理が変わってしまう > ミス: unsigned intをuint8_tで定義した

http://ideone.com/YV3IdY

```c
#include <stdio.h>
#include <time.h> // use for test. not available on IDE

time_t getElapsedSecond(int yyyy, int mm, int dd, int hh, int nn, int ss){
    struct tm workdt;
    workdt.tm_isdst = -1; // summer time flag
    workdt.tm_year = yyyy - 1900;
    workdt.tm_mon = mm - 1;
    workdt.tm_mday = dd;
    workdt.tm_hour = hh;
    workdt.tm_min = nn;
    workdt.tm_sec = ss;
    return mktime(&workdt);
}

void getDateTimeString(time_t srcdt, char *dstPtr)
{
    if (dstPtr == NULL) {
        return; // error
    }
    struct tm *workdt;
    workdt = localtime(&srcdt); 
    workdt->tm_year = workdt->tm_year + 1900;
    sprintf(dstPtr, "%04d/%02d/%02d %02d:%02d:%02d", 
        workdt->tm_year, workdt->tm_mon + 1, workdt->tm_mday, 
        workdt->tm_hour, workdt->tm_min, workdt->tm_sec
    );
}

typedef struct {
	unsigned int OI; // [s]
	unsigned int MI; // [s]
	unsigned int W; // [s]
	unsigned int R; // [s]
	unsigned int N; // [s]
} SETTING_t;

time_t getNextWtime(time_t torigin, time_t tnow, SETTING_t *setPtr)
{
	if (setPtr == NULL) {
		return 0; // error // TOOD: 0z > use error value for time_t
	}
	// case 1: (now - origin) % OI == 0
	unsigned long A = (tnow - torigin) / setPtr->OI;
	if ((tnow - torigin) % setPtr->OI == 0) {
		return torigin + (A + 1) * setPtr->OI;
	}

	// case 2: (now - origin) % OI != 0

	//   case 2-a: (now - A*OI) % MI == 0
	
	//   case 2-b: (now - A*OI) % MI != 0
	
	return 0; // TODO: 0z > remove after debug
}

void AssertCheck(time_t torigin, time_t tnow, time_t tnextWans, SETTING_t *setPtr)
{
	char szbuf[30];
	if (setPtr == NULL) {
		return; // error
	}
	time_t tnextWres = getNextWtime(torigin, tnow, setPtr);

    getDateTimeString(tnow, szbuf);
	printf("%s - ", szbuf);
    getDateTimeString(tnextWres, szbuf);
	printf("%s:", szbuf);
	printf("%c", (tnextWres == tnextWans) ? 'T' : 'F');
	printf("\r\n");
}

void Test_group_run()
{
	time_t torigin = getElapsedSecond(2017, 8, 2, 13, 48, 55);
	SETTING_t setting = { 3600, 600, 60, 5, 3 }; // OI, MI, W, R, N

	// case (2)
	AssertCheck(torigin,
		        getElapsedSecond(2017, 8, 2, 13, 48, 55),
           	    getElapsedSecond(2017, 8, 2, 14, 48, 55),
	            &setting);
	
}

int main(void) {
	Test_group_run();

	return 0;
}
```

```txt:run
2017/08/02 13:48:55 - 2017/08/02 14:48:55:T
```

SETTING_tの定義に関してunsigned intをuint8_tに変更することで結果がTからFに変わってしまった。


~~優先作業が終わってから時間に余裕があれば見直すかもしれない。~~

### 教えていただきました

@mt08 さんの[コメント](http://qiita.com/7of9/items/1965c5e8d9e839652808/#comment-a3a2b4e577e86e8b3715)
にて型の間違いを教えていただきました。

情報感謝です。
無名関数の使い方について


#無名関数とは

無名関数とは、関数名を持たない関数のこと。
変数に代入したり、引数としてコールバック関数を要求する箇所で使用することができる。(PHP5.3以降から使用可能)

##つかいどころ
限定した箇所でしか使用しない関数を宣言したい場合

##関数
array_walk() , array_map() , array_filter()　など...

#使用例
```php
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>無名関数について</title>
	<link rel="stylesheet" href="">
</head>
<body>
	<?php 
		$nature = array('water','forest','tree','cloud','sun','river');
		$filter_less5 = function($text) {
			return strlen($text) < 5;
		};
		echo '<p>5文字未満のデータ</p>';
		echo '<ul>';
		$filter_less5 = array_filter($nature,$filter_less5);
		foreach($filter_less5 as $data) {
			echo '<li>'.h($data).'</li>';//tree,sun
		}
		echo '</ul>';

		$filter_equal5 = array_filter($nature,function($text){
			return strlen($text) === 5;
		});
		echo '<p>5文字のデータ</p>';
		echo '<ul>';
		foreach($filter_equal5 as $data) {
			echo '<li>'.h($data).'</li>'; //water,cloud,river
		}
		echo '</ul>';

		function h($string) {
			return htmlspecialchars($string,ENT_QUOTES,'UTF-8');
		}
	?>
</body>
</html>
```

#補足

strlen　→　バイト数を計算する(全角文字などは、２文字になる 例：あ　→　2　あa →　3)
mb_strlen →　文字列の文字数をカウントする　(あ　→　1　あa　→　2)
Elasticsearchの管理ツールを導入してみた



elasticsearch-head  とは、
設定情報やデータをブラウザの管理画面として提供してくれるプラグインです。

まずは、ソース取得。

git clone git://github.com/mobz/elasticsearch-head.git

```
Cloning into 'elasticsearch-head'...
remote: Counting objects: 4067, done.
remote: Total 4067 (delta 0), reused 0 (delta 0), pack-reused 4067
Receiving objects: 100% (4067/4067), 2.10 MiB | 1.41 MiB/s, done.
Resolving deltas: 100% (2224/2224), done.
```

cd elasticsearch-head/
npm install

```
npm WARN prefer global coffee-script@1.10.0 should be installed with -g
.....
npm WARN EPACKAGEJSON elasticsearch-head@0.0.0 license should be a valid SPDX license expression
```
npm run start

```
> elasticsearch-head@0.0.0 start /xxxx/elasticsearch-head
> grunt server

Running "connect:server" (connect) task
Waiting forever...
Started connect web server on http://localhost:9100
```

ブラウザからアクセスすると、表示された

![スクリーンショット 2017-08-02 15.36.05.png](https://qiita-image-store.s3.amazonaws.com/0/151710/50bb1461-10ed-24cf-7bcf-3d7d1a6c871e.png)
Android Crosswalk webview で javascript の console.log や DOM構造を見る

Windowsの場合の例です。

Android Studio と ADV の Android エミュレーターで、crosswalkを組み込んだwebviewアプリをデバッグしているとき、普通のデスクトップPC版 Chrome ブラウザのアドレスバーに下記を入力すると、Android エミュレーター上で実行されているcrosswalk/webviewをインスペクタで見れる。

```
chrome://inspect
```
YouTubeにアップできる縦位置動画のプロジェクト設定

# 720x1280のカスタム解像度で作る
![スクリーンショット 2017-08-02 14.54.17.png](https://qiita-image-store.s3.amazonaws.com/0/18569/543fa993-7104-d524-50f7-5e899768fdf2.png)


Final Cut Proの場合の設定方法。新規プロジェクト作成画面で `カスタム設定を利用`を選ぶ。

## 設定する項目は解像度
`720x1280` もしくは `1080x1920`にする。
普通の720pフォーマットは 1280x720だから縦と横が入れ替わっている点がポイント。

ちなみにiPhone6の画面サイズは `750x1334`。
なので画面収録した動画などのケースでは720がおすすめ。

フレームレートは普通は30pで十分。この辺りは素材や好みに合わせてどうぞ。

中間コーデックもお好みで。


# 書き出しの設定も同様に

![スクリーンショット 2017-08-02 15.06.53.png](https://qiita-image-store.s3.amazonaws.com/0/18569/d19eafef-7104-7a2f-2545-5ca7f6f28e17.png)


Compressorで書き出す場合の設定例。こちらもカスタム設定を作成する。

ここでも大事なのは解像度。縦と横の入れ替わった720pないし1080pになっているのが重要。
そしてスクエア画素で。
圧縮方式などはお好みでどうぞ。
rippleのシークレットキーとアドレスを新規に作成する

# rippleのシークレットキーの作成

キーを扱うための[ripple-keypairs](https://www.npmjs.com/package/ripple-keypairs)という公式のライブラリが提供されている
ネットワークに接続しない環境（コールドウォレット）で作成可能

```:install
npm i ripple-keypairs
```

```:javascript
var keypairs = require('ripple-keypairs');
var secret = keypairs.generateSeed();
var keypair = keypairs.deriveKeypair(secret);
var address = keypairs.deriveAddress(keypair.publicKey);
console.log({secret:secret, address:address, keypair:keypair})
```

```:console
{ secret: 'shzy4ckH1E77MCZNqw6aPLnNmkoEf',
  address: 'rfAZN4TBETTtYwPbu7Uz2BYMuQRJpvdSb',
  keypair: 
   { privateKey: '00BBF6A27C1FB16DEB27CAA6E4BD79F1CB49A7640288E6E33F4A139C71B37A5BC6',
     publicKey: '03C37EDCB29E8793208C30C6DD8E346EC282712C34C749C71C73A38955C8FAC920' } }
```

## PS

keypairs.generateSeed()の引数に16byteのエントロピーを指定可能なので信頼できるエントロピーソースが別にあるのであればそれを指定できる

エントロピー指定可能なので遊びでつくったものとして以下の様なものがある

* https://github.com/you21979/node-ripple-wallet-bip39

```
var bip39 = require("bip39");
var keypairs = require('ripple-keypairs');

var generateAddress = function(options) {
  var secret = keypairs.generateSeed(options);
  var keypair = keypairs.deriveKeypair(secret);
  var address = keypairs.deriveAddress(keypair.publicKey);
  return { secret: secret, address: address };
}

var mnemonicToRippleAddress = module.exports = function(mnemonic, password){
    var masterseed = bip39.mnemonicToSeed(mnemonic, password);
    return rippleAddress = generateAddress({ entropy: masterseed })
}
```
Angularの多言語対応

調べながら書いたので間違っていたらスミマセンmm


# Angularの多言語対応

## 概要

**Angularの４系**でやっています。
Angularの多言語対応については、[こちら](https://angular.io/guide/i18n)のドキュメントを参考にしました(・ω・)

簡単にいうと...`message.ja.xlf`, `message.en.xlf`などの言語ファイルを作り、ここで管理していくみたいです。

```message.ja.xlf
<?xml version="1.0" encoding="UTF-8" ?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
  <file source-language="en" datatype="plaintext" original="ng2.template">
    <body>
      <trans-unit id="hello" datatype="html">
        <source>Hello world</source>
       <target>わんこ</target>
        <context-group purpose="location">
          <context context-type="sourcefile">src/app/app.component.ts</context>
          <context context-type="linenumber">1</context>
        </context-group>
      </trans-unit>
    </body>
  </file>
</xliff>
```

# 具体的なやり方

## ① package.jsonにこれを書きます。

```package.json
"scripts": {
  "i18n": "ng-xi18n"
}
```

## ② component.htmlには、こんな感じで書きます。

```app.component.html
<h1 i18n="@@hello">
  Hello world
</h1>
```

## ③ 辞書ファイルを作ります。

これでappにlocalができて、そこに辞書ファイルができます。
他の言語が欲しい場合は、`messages.ja.xlf`の部分を`messages.en.xlf`などとして増やしていきます。

```
npm run i18n -- --i18nFormat=xlf  --outFile=src/locale/messages.ja.xlf
```

## ④ 辞書ファイルを編集する

`target`というところに変換したい文字をいれます。

```messages.ja.xlf
<trans-unit id="hello" datatype="html">
  <source>
    Hello world
  </source>
  <target>
    こんにちは世界
  </target>
  ...
</trans-unit>
...
```

##⑤　実行します(・ω・)

`--locale ja --i18n-format xlf --i18n-file src/locale/messages.ja.xlf`とつけると日本語環境で実行されます。

```
ng serve --aot --locale ja --i18n-format xlf --i18n-file src/locale/messages.ja.xlf
```

##⑥ ビルドします

```
ng build --aot --output-path dist/ja --base-href ja --locale ja --i18n-format xlf --i18n-file src/locale/messages.ja.xlf
```

# 言語の切り替え方法

こちらの[記事](https://medium.com/@feloy/deploying-an-i18n-angular-app-with-angular-cli-fc788f17e358)を参考にさせていただきました！

```app.component.ts
import { Component, LOCALE_ID, Inject } from '@angular/core';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  languages = [
    { code: 'en', label: 'English'},
    { code: 'es', label: 'Español'},
    { code: 'fr', label: 'Français'}
  ];
  constructor(@Inject(LOCALE_ID) protected localeId: string) {}
}

<!-- app.component.html -->
<h1 i18n>Hello World!</h1>
<template ngFor let-lang [ngForOf]="languages">
  <span *ngIf="lang.code !== localeId">
    <a href="/{{lang.code}}/">{{lang.label}}</a> </span>
  <span *ngIf="lang.code === localeId">{{lang.label}} </span>
</template>
```
How to connect Google Calendar with Tempo - Chrome only

#Turn google meetings into JIRA worklogs

chrome-extension://hhokjfockalnaabnhaaojdjgjodnceom/google-calendar.html
https://github.com/msolomonTMG/jira-timesheet-google-calendar-extension

### JIRA プロジェクト名に数字があると　動作しない...
 ex. PROJ2 → PROJZ


```https://github.com/msolomonTMG/jira-timesheet-google-calendar-extension/blob/master/google-calendar.js

if (event.description) {
          // check the description and the meeting title for a ticket
          if (event.description.match(/([A-Za-z]+-[0-9]+)/)) {
            var ticketInDescription = event.description.match(/([A-Za-z]+-[0-9]+)/)[0];
            ticket = ticketInDescription;
          }
          if (event.summary.match(/([A-Za-z]+-[0-9]+)/)) {
            var ticketInTitle = event.summary.match(/([A-Za-z]+-[0-9]+)/)[0];
            ticket = ticketInTitle;
          }
```
[Laravel] groupBy() で関数とか使いたい時 

#  GroupByで関数使いたい

## 検証環境

Laravel 5.4.23

## やり方

以下のやり方でいける

```php
<?php

$query->groupBy(\DB::raw(...));
```

Eloquentで好きなSQLを書きたい場合は、

基本的に `DB::raw()` を使用すればよさそう
keepaliveでセグメントを超える時の設定ハマりどころ

初心者がkeepaliveを設定していたらドハマりしたのでメモ。
# 環境
 * CentOS6.9
 * keepalived.x86_64 1.2.13-5.el6_6

## iptables
**iptables -A FORWARD -j REJECT　を打ち消す**
セグメントを超えた負荷分散の場合、パケットをフォワードする必要がある。
その際、CentOS6のデフォルト設定のiptablesではWebサーバからの帰りパケットがリジェクトされてしまう。

``iptables -A FORWARD -j ACCEPT``はスマートじゃないので、必要な分だけ許可。
以下は_eth1(外)側のネットワークからeth2(内)側へ_http通信する場合の記述

```
-A FORWARD -i eth1 -o eth2 -p tcp --sport 80 -j ACCEPT  # <- 追記
-A FORWARD -j REJECT --reject-with icmp-host-prohibited # <- 元からある
```

`net.ipv4.ip_forward=1`を設定するのは様々なサイトで情報があったが、この設定は無くてハマった。
そんなこと記載する価値もない常識だという可能性もあるが…

## 設定ファイル
**括弧の前には空白必須**
本当は必須じゃないかもしれないけれど、空白置いといて損はない。
なおセグメントには一切関係ない。

### NG
urlの後ろに空白を入れず括弧をした場合、**何故か一番目のreal_serverだけ反映される。**  何故だ…

```
virtual_server 172.16.0.5 80 {
    lb_algo wlc
    lb_kind NAT

    real_server 192.168.254.132 80 {
        HTTP_GET {
            url{
                path /
                status_code 200
            }
        }
    }
    real_server 192.168.254.133 80 {
        HTTP_GET {
            url{
                path /
                status_code 200
            }
        }
    }
    real_server 192.168.254.134 80 {
        HTTP_GET {
            url{
                path /
                status_code 200
            }
        }
    }
}
---------------------------------------------------------------------
[vagrant@LVS1 ~]$ sudo ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  172.16.0.5:80 wlc
  -> 192.168.254.132:80           Masq    1      0          0
```

### OK
```
virtual_server 172.16.0.5 80 {
    lb_algo wlc
    lb_kind NAT

    real_server 192.168.254.132 80 {
        HTTP_GET {
            url {
                path /
                status_code 200
            }
        }
    }
    real_server 192.168.254.133 80 {
        HTTP_GET {
            url {
                path /
                status_code 200
            }
        }
    }
    real_server 192.168.254.134 80 {
        HTTP_GET {
            url {
                path /
                status_code 200
            }
        }
    }
}
---------------------------------------------------------------------
[vagrant@LVS1 ~]$ sudo ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
UDP  172.16.0.5:80 wlc
  -> 192.168.254.132:80           Masq    1      0          0
  -> 192.168.254.133:80           Masq    1      0          0
  -> 192.168.254.134:80           Masq    1      0          0
```
All About ACS: IBM i Access Client Solutionsで出来ないことと改善要望

#Access Client Solutionsで出来ないこと
ACS は「Java で書かれた Access for Windows」や「Access for Windows をそのまま Java に移植したもの」ではありません。
「同等の機能を Java で実装しなおしたもの」と考えた方がいいでしょう。
OS のネイティブコードでの記述が必要な ODBC や OLE DB などは、Windows / Linux のネイティブコードで記述された Application Package が用意されていますが、それ以外の機能はすべて標準的な Java で記載されています。
そのため、データペースへのアクセス以外で Java で実現できない機能もできなくなっています。
ACS で対応できない代表例を記載します。

##着信リモート・コマンド(cwdrxd)に対するRUNRMTCMDでのWindowsプログラムの実行
Access for Windows では、着信リモート・コマンド(cwdrxd)サービスに対して、IBM i から RUNRMTCMD を発行することで、Windows プログラムを無人実行できました。
ACS には、この機能がなくなっています。
実行は無人でなくてはいけないか、IBM i からでなくてはいけないかで、いくつかの方法が考えれます。


- IBM i からコマンドを送るという点では 5250 経由の「STRPCCMD」が利用できます。実行にユーザーの関与/5250の利用が許されるのであれば「STRPCCMD」への移行は一つのオプションでしょう。

- どうしても「RUNRMTCMD」でならない場合、Windows用の「REXEC」のサーバーを用意し RUNRMTCMD を使い続けることが考えれられます。
RUNRMTCMD は「REXEC」という UNIX 上で古くから使われるプロトコルを利用します。そのため、RUNRMTCMD で AIX や Linux にコマンドを発行することも可能です。
適切なWindows用の「REXEC」のサーバーが用意できれば、RUNRMTCMD を使い続けられるでしょう。

- IBM i を関与させない方法もあるかもしれません。
対象の Windows にリモートデスクトップで入り、コマンドを実行することや、Windows 間の連携機能でコマンドが実行できるかもしれません。

- どうしても IBM i から無人でWindowsコマンドを実行しなければならない場合、 5733-SC1 で用意される IBM i 上のOpenSSH からWindows 用のOpenSSH を呼び出す方法もあるでしょう。Windows 10 April 2018 Update (1803) では OpenSSH サーバーが正式に組み込ました。Windows Server 2019 でも利用可能です。

## Excel データ転送 ADD-IN
Excel 内から呼び出すデータ転送 ADD-IN はなくなりました。
代わりに今開いているExcelへ/からデータを転送する「アクテイブ Excel スプレッドシート」が転送先/元として用意されています。
また、ダウンロードだけでよければ、Windows Application Package を導入し、OLE DB、ODBC という外部データソース、MS-Query によるDBCS接続といった方法も考えられます。


#できるようにしてほしい。
ACS に限らず、機能の改善・拡張は Request for Enhancement (RFE) で IBM に要求できます。

下記で更新情報を見ると、RFE で始まる番号が付いたものがあります。これらは、RFE から取り込まれた機能改善です。

ftp://ftp.software.ibm.com/as400/products/clientaccess/solutions/readmespacs.txt

日本発では、5250 のフォント表示が汚いというのが、RFE 経由で改善されました。
GDI 印刷と同等のことが ACS ではできませんでしたが 1.1.8 で Java Print Service(JPS)で実装されました。これも RFE によるものです。

申請先はこちらです。

https://www.ibm.com/developerworks/rfe/

英語ですが、[こちらの「IBM Request for Enhancement (RFE) allows IBM i clients to affect the course for the future」](https://www.ibm.com/developerworks/ibmi/library/i-ibm-rfe-trs/index.html) が、IBM i クライアントに対する RFE の要求の記事です。

IBM i 用ではありませんが 日本語で[「RFE Community で機能拡張の要望を登録する方法について」](http://www-01.ibm.com/support/docview.wss?uid=swg21631369)という記事もあります。

##「Vote」も大事
自分で RFE を要求するだけでなく、他人の RFE に投票することができます。
投票が多ければ、多数の要求があると IBM に理解させ優先順位を上げさせることができます。

***
2019-02-18
- GDIと同等の印刷ができるようになったことに対する修正
- sshd の情報を更新 

「All About ACS」では IBM i に対する新しいクライアント「IBM i Access Client Solutions」の情報をいろいろ提供していきます。
[記事一覧はこちら](http://qiita.com/6onoda/items/2dc925586d8d3b8644f2)で確認いたけます。

許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
***
RubyをWindowsにインストールする

# はじめに

Rubyデビューをすることになり、先ずは、WindowsにRubyをインストールしてみたので、インストール手順のメモ書きです。インストールした後に気付いたのだが、わざわざ手順をドキュメントで残す程の大した手順でもなかったが・・・

# Rubyのインストール手順

1. 次のURLにアクセスする https://rubyinstaller.org/

![ruby01.png](https://qiita-image-store.s3.amazonaws.com/0/94029/7be41fd2-9954-4a25-2ac1-99a776f9cf82.png)

2.《Download》をクリックする

![ruby02.png](https://qiita-image-store.s3.amazonaws.com/0/94029/a166a7f2-02b7-4351-9c50-b825772d5781.png)

3.**Ruby 2.4.1-2(x64)**が最新そうなので、これをダウンロード

4.**rubyinstaller-2.4.1-2-x64.exe**がダウンロードされるので実行する

5.ウィザードに沿って進める

6.**I accept the License**を選択して**Next**

![ruby03.png](https://qiita-image-store.s3.amazonaws.com/0/94029/414741d9-c76e-c2e2-5b23-7a3f384320a4.png)

7.オプションの確認画面が出てくるが、チェックは全て外す。そして**Install**

8.C’est fini

# Rubyの確認

1.Windowsのメニューの中から**Start Command Prompt with Ruby**を起動

![ruby04.png](https://qiita-image-store.s3.amazonaws.com/0/94029/50fea4b7-7e81-7ef4-5d3e-d530468285bc.png)

2.DOSの画面から、コマンド**ruby -v**をうつ。Rubyのバージョンが正しく表示されればＯＫ
Amazon SQSを使ってみた

## 分かったこと

* キューに入ったデータを取得する方式は、ショートポーリングとロングポーリングの方式があって推奨されてるのはロングポーリング
http://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/general-recommendations.html
> ロングポーリングは、ほとんどの場合にショートポーリングよりも推奨されます。

* 標準キューの場合、順不同なため最後に追加されたキューが最後に取得できるとは限らない

## Rubyから使う場合

* ネットで検索した時に出てくるサンプルコードはAWS SDK for Rubyのv1で書かれたものが出てくる場合があるので注意
* 実装例
  * http://docs.aws.amazon.com/sdk-for-ruby/v2/developer-guide/sqs-examples.html

### キューに追加

```ruby
sqs = Aws::SQS::Client.new
sqs.send_message(
  queue_url: "https://sqs.ap-northeast-1.amazonaws.com/123445/queue_name",
  message_body: {
    id: 1,
    title: 'title',
    created_at: Time.current
  }.to_json
)
```

### キューから取得

```ruby
poller = Aws::SQS::QueuePoller.new("https://sqs.ap-northeast-1.amazonaws.com/123445/queue_name")
poller.poll(max_number_of_messages: 10, idle_timeout: 60) do |msg|
  result = JSON.parse(msg.body)
end
```

## Elixirから使う場合

* Elixir用のAWS SDKがないため[ex_aws](https://hex.pm/packages/ex_aws)を使うことになる
* ex_awsを使う場合、AWSのAPIがSQSのレスポンスはXMLで返ってくるようでsweet_xmlも追加しないとエラーになった
* 使い方のコードのサンプルがあまりないので、テストコードを見ると参考になった
  * https://github.com/CargoSense/ex_aws/blob/master/test/lib/ex_aws/sqs_test.exs
    
### 追加したパッケージ

```ex
{:ex_aws, "~> 1.0"},
{:poison, "~> 2.0"},
{:hackney, "~> 1.6"},
{:sweet_xml, "~> 0.6.5"}
```

### キューに追加

```ex
body = %{"id" => 1, "title" => "title", "created_at" => DateTime.utc_now() } |> Poison.encode!
ExAws.SQS.send_message("/123445/queue_name", body) |> ExAws.request!(region: "ap-northeast-1")
```
基本情報技術者試験に２回落ちた男が振り返り、挑戦する

# これまでの試験の結果(^q^)

|  | 午前 | 午後 |
|:-:|:-:|:-:|
| 1回目 | 52点  | 55点  |
| 2回目 | 75点  | 52点 |

# なぜこうなったのか・・・Σ(・∀・；)


- 1回目（高校時代）
  - 合格率20%しかないし受かるはずがないと諦めていた。
  - 遊びたかった。（甘え）

- 2回目（短大時代、平成29年春）
  - 午後はなんとかなると思い、午前のほうに力を注いでいた。
  - すこし難しかった。（午前・午後共に新しい問題が多かったように思う。）

# 2回の失敗を振り返って思うこと・気づいたことΣ(ﾟ∀ﾟﾉ)ﾉｷｬｰ


高校時代に逃げずにやればよかったと思う。高校時代に国家資格を取れると進学・就職において有利に立てます。なにより資格の欄を埋めることができるし、自己アピールとして面接や提出書類にかけるのはメリットになります。もちろん、大学・短大・専門学校でも同じようなことが言えます。


午前は過去問。午後は過去問を解きながらわからないことはその場でインターネットで調べたり、同じ学生や先生に聞くことが大事だと思います。でも一番大事なのは回数をこなすことではないかと（俗に言う慣れというやつです）

# 3回目に向けてやらなければならないことφ(..)
そろそろ自分の話ばかりで勉強方法を教えろやカスって言われそうなので・・・


- 午前
　下記のサイトで過去問をやる

　[基本情報技術者試験ドットコム](http://www.fe-siken.com)

　[応用情報技術者試験ドットコム](http://www.ap-siken.com)

応用情報技術者試験の午前は基本情報技術者試験の午前とほぼ同じなのでこちらのほうもやっておくといろいろ応用が効くかな。（応用情報だけに...）僕は念のためにやろうかと思います。やらなくても僕が70点超えたので多分なんとかなります。

- 午後　本を買い、ひたすら練習
　

　本はネットで評価が高いものを買えばいいと思います。

　自分はこれを持ってます。

　[キタミ式イラストIT塾 基本情報技術者](https://www.amazon.co.jp/キタミ式イラストIT塾-基本情報技術者-平成29年度-きたみ-りゅうじ/dp/4774185221/ref=zg_bs_502776_4?_encoding=UTF8&psc=1&refRID=3HD7XCKP1NHCSFS84EQA)

解説重視の本。分かっているようで分かっていないことを分かりやすく書いてくれています。読むのが好きなら為になる一冊。

　[基本情報技術者-パーフェクトラーニング過去問題集](https://www.amazon.co.jp/平成29年度-秋期-基本情報技術者-パーフェクトラーニング過去問題集-情報処理技術者試験-山本-三雄/dp/4774190527/ref=zg_bs_502776_7?_encoding=UTF8&psc=1&refRID=3HD7XCKP1NHCSFS84EQA)

午前も午後も過去問が乗っており、問題の後に解説があるので見やすく、説明も丁寧。

本を買うなら中古でいいと思います。
自分が使っているサイトはこれ（ ・∀・）

　[ブックオフオンライン](http://www.bookoffonline.co.jp)

ほんとにお金使いたくない人はサイトで過去問漁ってやればいいかな。解説・解答がない場合があるから調べながらやるのをおすすめします。


　[IPAのホームページ](https://www.jitec.ipa.go.jp)


試験の概要や区分を読んでおくといいかもしれない(*´ω｀*)
春と秋の年２回しか実施されないから早めの申込みを（申し込み忘れたことがあったなんて言えない・・・）

最近は社会でセキュリティの事件が多かったためか、セキュリティの問題が多い傾向にあるのでそこを意識してやろうかなと思います。受かったら報告しようかな(^^)

興味を持ったら挑戦しましょう！失敗しても構いません。僕は２回失敗してますからね...

では良い資格ライフを(^O^)／

# 追記

2018年10月の試験にて合格しました！
午前77.5点、午後77.5点でした
zebedee のような vpn の代替としての StreamRelay.NET.exe

StreamRelay.NET.exe にはストリームに暗号処理を被せる事ができるため、VPN(Zebedee)の代替のようなことを行わせることもできる。

---
### 諸注意

zebedee プロトコル互換ではないし、zebedee のようなマルチプロトコルを含有できるようなものでもなく、あくまで通信を暗号化する、そして、鍵交換を安全に行う、という内容です

---
### クライアント側

`StreamRelay.NET.exe -LocalPort 90 -RemoteHost 192.0.2.1 -RemotePort 10990 -RemoteProxy netstream:///?CipherAlgorithm=AES^&CipherECDH`

「remote」と呼称される側のストリーム側に

- 暗号アルゴリズムは AES
- 鍵交換に ECDH

---
### サーバ側

`StreamRelay.NET.exe -LocalPort 10990 -RemoteHost 192.0.2.2 -RemotePort 80 -LocalProxy netstream:///?CipherAlgorithm=AES^&CipherECDH`

「local」と呼称される側のストリーム側も

- 暗号アルゴリズムは AES
- 鍵交換に ECDH

---
### 鍵交換アルゴリズム

.NET Framework には、ECDH 法しか標準で実装されていないので、ECDH しか用意していない。

当然、事前共有鍵をセットして、それを使う、という事も可能ですよ

---
### 圧縮

リアルタイムに圧縮/伸張してくれるフィルタ・ストリームがみつからない

---
### 暗号一般

[ファイル暗号化コマンドとしてのStreamRelay.NET.exe](http://qiita.com/tomoki0sanaki/items/f58ac77662b194cb562a)

---
### ブロックサイズ

暗号アルゴリズムとか、暗号モードによっては、ストリーム暗号のように1Byte単位にする事もできる

---
### 目次へ戻る

[目次というか最初の一歩](http://qiita.com/tomoki0sanaki/items/85f20cbe18378e33cd6f)
Vue.jsではじめる多言語対応

調べながら書いたので間違っていたらスミマセンmm

## 方法 / 前提
 - フロントのFWはVue.jsを採用。
 - 言語対応の方法としてi18nという[国際規格](https://ja.wikipedia.org/wiki/国際化と地域化)を採用。
   - Vue.jsのi18nプラグイン -> https://github.com/kazupon/vue-i18n  
( ※ kazuponさんという日本のVue.js界隈で有名な方が作成したものを推奨 / こまめにメンテされている)

## 具体的な書き方
サンプルがたくさんあるので、下記を見ればすぐ分かる
https://github.com/kazupon/vue-i18n/blob/dev/examples/

```vue.script.js
import Vue from 'vue';
import VueI18n from 'vue-i18n';

const data = require('./message.json');

// 言語の設定
Vue.use(VueI18n);
const i18n = new VueI18n({
  locale: 'ja', // デフォルト言語はjaにしておくが、ブラウザの言語を拾ってきてここに入れる => 言語変更されたら書き換える
  messages: data
});

// Vueたん
const app = new Vue({
  el: '#app',
  i18n: i18n,
  data: {},
  created() {},
  methods: {
    handleClick_changeLanguage(lang) {
      this.$i18n.locale = lang;
    }
  }
});

```

##  翻訳用のjsonファイル


json形式で言語ファイルを作り、言語はここで管理する。
基本的に1ページに対し、1jsonファイルがベスト。（検討中）
jsonデータはサーバ側から貰ってもよい。

```message.json
{
  "ja": {
    "message": {
      "title": "タイトルだよーん",
      "subtitle": "ここがサブタイトルになります"
    }
  },
  "en": {
    "message": {
      "title": "title dayo-n",
      "subtitle": "sub title dayo-n"
    }
  },
  "han": {
    "message": {
      "title": "標題",
      "subtitle": "副標題"
    }
  }
}

```
`en.json` や `ja.json`のように言語ごとに分けることもできるし、
上記例の`message.json`のように英語と日本語を1ファイルで管理することも可能。


### component.htmlはこんな感じ

```app.component.html
<div id="app">
  <header class="header">
    <div>
      <p class="header__sub-text">{{ $t("message.subtitle") }}</p>
      <h1 class="header__title">{{ $t("message.title") }}</h1>
    </div>
  </header>

  <nav>
    <ul>
      <li><a href="#" v-on:click.prevent="handleClick_changeLanguage('en')">英語</a></li>
      <li><a href="#" v-on:click.prevent="handleClick_changeLanguage('ja')">日本語</a></li>
      <li><a href="#" v-on:click.prevent="handleClick_changeLanguage('han')">繁体字</a></li>
    </ul>
  </nav>
</div>
```

## 追記
`vue-i18n for Server-Side Rendering` も併せて使うと良さそう
https://github.com/kazupon/vue-i18n/tree/dev/examples/ssr
Node.js  v4.2.6 v8ライブラリ C++アドオンのAPIまとめ

Node.js v4.2.6のC++アドオンに関してです。
UbuntsuにNode-REDをインストールしたら、Node.jsがv4.2.6になったのですが、そのバージョンのC++アドオン(v8)の技術情報が少ない上に、よくドキュメントから使用する関数を見つけにくかったのでまとめました。

## Node.js バージョン確認方法
```bash
node -v
v4.2.6
```

##関数の登録
`NODE_SET_METHOD`の行を登録するAPIの数だけ並べます。

```cpp
void Init(Local<Object> exports, Local<Object> module) {
	NODE_SET_METHOD(module, "test", test); // ""内はAPI名, 後ろは関数名
}

```

##データの受け取り
### 関数の宣言
```cpp
void test(const FunctionCallbackInfo<Value>& args) {
    ....
}
```

### 文字列 --> char の場合
```cpp
const char* ToCString(const String::Utf8Value& value) {
    return *value ? *value : "<string conversion failed>";
}
void test(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    String::Utf8Value str(args[0]);
    const char* str_char = ToCString(str);
    ....
}
```
### 文字列 --> v8:String の場合
```cpp
void test(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    String str = arg[0]->ToString();
    ....
}
```
### Boolean の場合
```cpp
void test(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    Local<Boolean> obj = arg[0]->ToBoolean();
    ....
}

```
### 数値の場合
```cpp
void test(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = args.GetIsolate();
    double value = arg[0]->NumberValue();
    ....
}
```
## 値の代入方法
```cpp
Local<String> str = String::NewFromUtf8(isolate, "hello");     // 文字列
Local<Number> num = Number::New(isolate, 10);     // 数値
Local<Boolean> boo = Boolean::New(isolate, true);     // bool
```

## 戻り値
戻り値は、args.GetReturnValue()で返します。

### 数字

```cpp
  Local<Number> double_num = Number::New(isolate, value);    // double型
  Local<Number> int_num = Integer::New(isolate, value);      // integer型
  args.GetReturnValue().Set(double_num);
```

### 文字列
```cpp
  args.GetReturnValue().Set(String::NewFromUtf8(isolate, "hello world"));
```

### JSON
```cpp
  Local<Object> obj = Object::New(isolate);
  obj->Set(String::NewFromUtf8(isolate, "msg"), String::NewFromUtf8(isolate, "hello world"));
  args.GetReturnValue().Set(obj);

```

## エラーを返す
```
if(!args[0]->IsString()) {
　　　　isolate->ThrowException(Exception::TypeError(
　　　　　　　　String::NewFromUtf8(isolate,"args must be string")));
　　　　return;
}
```
## 関数を登録する
```cpp
void Init(v8::Local<v8::Object> exports){
	NODE_SET_METHOD(exports, "func1", func1);
	NODE_SET_METHOD(exports, "func2", func2);
}
```
こうすると、nodejsではこのように呼び出すことができます。

```js

var addon = require('./build/Release/addon');
addon.func1(xxx);
addon.func2(xxx);
```
ElectronでUUIDを取得して、読み込んだサイト内のJSに受け渡す


コード：https://github.com/mo49/electron_test

[node-machine-id](https://github.com/automation-stack/node-machine-id)を使用する


## webview

サイトを読み込む準備

```index.html
<webview id="webview" src="https://www.google.co.jp/" autosize="on"></webview>
```

> 参考
https://electron.atom.io/docs/api/webview-tag/



## ipcMain | プロセス間通信

Electronで実行するJS

```javascript:main.js
const path = require('path');
const url = require('url');

const {app, BrowserWindow, ipcMain} = require('electron');
const {machineId} = require('node-machine-id');

let mainWindow;

app.on('ready', () => {
  machineId().then(id => {
    createWindow();
    ipcMain.on('webview-ready', event => {
      // channel経由でレンダラープロセスに非同期に返信し、任意の引数を渡す
      // ipcMain.send()ではない点に注意
      event.sender.send('machine-id',id); // ipcRenderer.on('machine-id')で受ける
    })
  })
});

function createWindow() {
  mainWindow = new BrowserWindow({width:800,height:600});

  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, 'src/index.html'),
    protocol: 'file',
    slashes: true,
  }));

  mainWindow.on('closed', function() {
    mainWindow = null;
  })
}
```

> 参考
https://github.com/electron/electron/blob/master/docs-translations/jp/api/ipc-main.md



## ipcRenderer | プロセス間通信

index.htmlで読み込むapp.js

```javascript:app.js
const {ipcRenderer} = require('electron');
const webview = document.querySelector('webview');

// dom-readyはあらかじめ登録されているイベント
webview.addEventListener('dom-ready', () => {
  ipcRenderer.on('machine-id', (event, machineId) => {
    webview.executeJavaScript(`window.onApplicationReady && window.onApplicationReady("${machineId}");`)
    console.log(machineId);
  })
  ipcRenderer.send('webview-ready'); // ipcMain.on('webview-ready')で受ける
})
```

> 参考
https://github.com/electron/electron/blob/master/docs-translations/jp/api/ipc-renderer.md



## webviewで読み込んだサイト内でJSを実行

`window.onApplicationReady`は、
webviewで読み込んだサイトの中で実行できるJS

つまり読み込んだサイト内のJSで、machineIdを使用することができるようになった

```javascript
window.onApplicationReady = (uuid) => {
  console.log(uuid);
}
```

> 参考
https://github.com/electron/electron/blob/master/docs/api/web-contents.md
C言語入門

## C言語の超基本
### 基本的な記述
```C
#include <stdio.h>

int main(void){
    printf("Hello World!\n");
    return 0;
}
```
- まず「main関数」から実行される
- 「return 0;」の行が実行されるとプログラムが終了(「main関数」が終了)

### 変数宣言
```C
// 変数宣言してから代入
int a;
a = 0;

// 変数宣言と同時に導入
int b = 0;
```

### 配列の宣言
```C
int a[10]; // int型の要素を10個持つ配列の宣言

int a[5] = {5, 4, 3, 2, 1}; // 宣言と同時に初期化

int a[] = {1, 2, 3, 4}; // 初期値の個数に応じて配列の要素数を決めたい時
int a[4] = {1, 2, 3, 4}; // 上記と同様

int a[10] = {0}; // すべて0で初期化したい時のみ可能
```


### for文
```C
int i;
for(i = 0; i < 10; i++){
    printf("Hello World!");
}
```

### if文
```C
if (a > 1000){
    printf("a は 1000 より大きい\n");
}else if (a > 500){
    printf("a は 1000以下で500より大きい\n");
}else{
    printf("a は 500以下\n");}
```

### ポインタ
ポインタ型の変数を宣言するというのことは住所を住所を指し示す値を入れる箱を用意することを意味する。

```C
#include　<stdio.h>

void main() {
    int data;
    int *ptr;

    data = 5;

    printf("整数型の変数dataの値= %d\n", data);
    printf("整数型の変数dataのアドレス= %08X\n", &data);

    ptr = &data;

    printf("ポインタ型の変数ptr = %08X\n", ptr);
    printf("ptrが指す場所に保存されている値= %d\n", *ptr);
}

/* 
結果:
整数型の変数dataの値= 5
整数型の変数dataのアドレス= 0012FF7C
ポインタ型の変数ptr = 0012FF7C
ptrが指す場所に保存されている値= 5 
*/
```
|                  |  整数  |  住所 |
|:-----------------:|:-----:|:----:|
| int data; と宣言  | data  | &data |
| int *data; と宣言 | *data | data  |
[参考： 初級C言語講座](https://www.sgnet.co.jp/c/6-3.html)

### 記憶クラス指定子

| 指定子       | 意味  　|
|:-----------------:|:------------------|
| auto             | オブジェクトに自動記憶クラスを与える。関数内でのみ使用可。　 |
| register           | 変数の使用頻度が高いことをコンパイラに知らせる。ほかはautoと同じ。　 |
| static             | オブジェクトに静的な記憶クラスを与える。関数の中でも外でも使用可。　 |
| extern               | オブジェクト用のメモリが他のどこかで定義されていることを示す。　 |
| typedef           | 型に別名をつける。構文の便宜上記憶クラス指定子に分類されている。　 |
[参考： C言語のstatic指定子について](http://www.c-lang.org/static.html[http://www.c-lang.org/static.html)

### サンプルプログラム
2整数の最大公約数を求める関数（m>nと仮定）

```C:GCD.c
int GCD(int m, int n){
    int r;
    r = m % n;
    if(r==0)
        return n;
    else
        return GCD(n, r)
}
```

平成28年度総合分析情報学コース第３問

```C
char* F(int n, int b){
    static char outb[66] = {0};
    int i = 64;
    for(; n > 0 && i > 0 ; --i, n /= b)
        outb[i] = "0123456789abcdefghijkl"[n % b];
    return &outb[i+1];
}
```
記事本文のフォントカラーは黒じゃだめなんですか？？

**黒がだめなんではなく、真っ黒がよろしくないんです。**

背景色（#FFFFFF）真っ白に対してフォント色（#000000）真っ黒ではコントラストが強すぎて
ユーザーが閲覧する際は、目が疲れてしまい、よくない組み合わせであります。
部分のみ使うのであれば構わないのですが、文章を書くときにこの組み合わせを使ってしまうと
読むのにかなり、ユーザーに負担がかかってしまいます。

自分もWeb初心者だったころは、

「白と黒だからこれでいいだろ。。。」と思って#ffffff , #000000 で設定しておった時期が自分にもありました。。。

結局、現実世界でも背景と文章が真っ白と真っ黒という組み合わせっていうのはあまりなくて
どこか白じゃなかったりどこか黒じゃなかったり。。。そういった感じで世の中回っているみたいです。
身近な例でいいますと、紙と鉛筆がわかりやすいのかな。と思います。

紙は真っ白なこともありますが、鉛筆は本当に真っ黒じゃありませんよね。

ということで、何か制作をする際には真っ白と真っ黒は避けたほうが無難です！
黒にもいろいろありまして、
だいたい背景真っ白に対してグレーっぽい黒だと読みやすくなります！


1. #111111（ここはもしかするとコントラストが強いかも。。。）
2. #222222
3. #333333
4. #444444
5. #555555
6. #666666 etc...

だいたいこのあたりがよく使われたりします。
自分自身は、#4d4d4dや#3c3c3cなどを使ったりしますが、上記のような連続したもので全然問題なしです。
純粋な白黒の組み合わせではなく、どちらか一方が少し薄い白と黒を使うよう意識すれば、
ユーザーにも優しいWeb開発が進められることができます！
![color.png](https://qiita-image-store.s3.amazonaws.com/0/195099/d4cea69f-b11d-3527-b372-156474808e54.png)
【php】webサイトから、欲しい情報を3行で取得する方法

「webサイトから欲しい情報だけを集めたい」そんなことはありませんか？

「スクレイピング」という技術を使うことによって、カンタンにwebサイトから欲しい情報を取得することが出来ます。

#スクレイピングとは
>WebサイトからWebページのHTMLデータを収集して、特定のデータを抽出、整形し直すことである。

引用：[IT用語辞典](http://www.sophia-it.com/content/Web%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0 "IT用語辞典")

今回は**「phpQuery」**を使ってスクレイピングを実装します。
名前の通りで、phpを使います。

#phpQueryの導入方法
[公式サイト](https://code.google.com/archive/p/phpquery/downloads "公式サイト")からzipファイルをダウンロードします。


解凍したら中にある「phpQuery-onefile.php」をお好きなところに配置してください。
今回は、わかりやすくルートに配置しました。

```
root/
　├ index.php
　└ phpQuery-onefile.php
```

それでは、[Wikipediaの「ウェブスクレイピング」ページ](https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0 "ウェブスクレイピング")より、見出し要素の「ウェブスクレイピング」を取得したいと思います。
コピペしやすい様に、スクレイピングに必要な3行を先に記載します。

```index.php
<?php
  require_once("./phpQuery-onefile.php");
  $html = file_get_contents("https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0");
  echo phpQuery::newDocument($html)->find("h1")->text();
?>
```

##1行目　phpQueryを読み込む

```index.php
<?php
  require_once("./phpQuery-onefile.php");
?>
```
「phpQuery-onefile.php」のパスを指定してください。
ルートに配置しているなら、コピペでOKです。

require_once:外部ファイルを一度だけ読み込む

##2行目 取得したいwebサイトを読み込む

```index.php
<?php
  $html = file_get_contents("https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0");
?>
```

URLを[file_get_contents("")]の中に貼り付けます。
次に、適当な変数を用意して、代入します。
これで、サイト全体の情報が$htmlに格納されました。

##3行目　見出し要素を取得、表示

```index.php
<?php
  echo phpQuery::newDocument($html)->find("h1")->text();
?>
```
$htmlの中にサイトの情報が沢山詰まっています。
欲しい部分をピックアップして、出力してみましょう。

見出しの「スクレイピング」は\<h1>要素なので、上記の様に指定します。

表示結果

```index.php
ウェブスクレイピング
```

簡単にスクレイピング出来ましたね。

ちなみに「->text()」を外すと、htmlとして出力されます。

#おまけ
##深い階層にある場合はどうするの？
例えば[Wikipediaの「ウェブスクレイピング」ページ](https://ja.wikipedia.org/wiki/%E3%82%A6%E3%82%A7%E3%83%96%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0 "ウェブスクレイピング")より、目次の5番目を取得したい場合はどうすれば良いのでしょうか。
先ほどと同じ感覚で、

```
<?php
  echo phpQuery::newDocument($html)->find("li")->text();
?>
```

と指定してしまうと、ページ内全ての\<li>を取得してしまいます。

このような場合は、「->find()」を複数連結させて必要な情報を探します。
目次の5番目は、

\<div class="toc">
↓
\<ul> 
↓
\<li>
↓
\<li>の5番目

このような順番で探し当てます。

Chromeのデベロッパーツールなどで、ソース部分を確認して見てください。
windowsなら、F12
MACなら、command + option + i
で開ます。


これをコードにすると

```
<?php
  echo phpQuery::newDocument($html)->find(".toc")->find("ul")->find("li:eq(4)")->text();
?>
```

こんな感じです。

表示結果

```index.php
5 脚注
```

**「:eq(4)」**を加えることで、4番目の要素を指定して取得できます。
（要素は0番目から始まるので、5番目が欲しい時は4を指定します。）

他にも便利なオプションがあります。

<table>
  <tr>
    <td>:eq()</td>
    <td>指定した番号の要素を取得する。</td>
  </tr>

    <td>:even</td>
    <td>偶数の要素を取得する。（※0番目から始まります）</td>
  </tr>
  <tr>
    <td>:odd</td>
    <td>奇数の要素を取得する。（※0番目から始まります）</td>
  </tr>
  <tr>
    <td>:gt()</td>
    <td>指定した番号以降の要素を取得する。</td>
  </tr>
  <tr>
    <td>:lt()</td>
    <td>指定した番号までの要素を取得する。</td>
  </tr>
</table>

詳しくは[こちら](https://code.google.com/archive/p/phpquery/wikis/Selectors.wiki)を参考にしてください。





#最後に
webから情報を集めたいけど、どうやって調べたら良いのか分からない人向けに書きました。
その中に、スクレイピングという手段があることを知る機会になっていただけたら幸いです。
コマンドプロンプト上でF11を押しても全画面表示されなくする方法

コマンドプロンプト上で動作するアプリケーションの中にはファンクションキーで操作するものもありますが、あるアプリケーション上でその機能を使おうと思ってF11キーを押したら全画面表示されてしまいました。

プロパティから「Ctrlキーショートカットを有効にする」を無効にしたら解決しました。
ググっても同じような話が無かったのとオプション名が分かりづらかったので共有しておきます。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/71419/c81473d7-418c-41ba-29ad-92f85ff195ec.png)
Centos6.6 安装odbc使用微软的driver连接sqlserver




## 安装
RedHat Enterprise Server 6

```
Copy
sudo su
curl https://packages.microsoft.com/config/rhel/6/prod.repo > /etc/yum.repos.d/mssql-release.repo
exit
sudo yum remove unixODBC-utf16 unixODBC-utf16-devel #to avoid conflicts
sudo ACCEPT_EULA=Y yum install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y yum install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo yum install unixODBC-devel
```

RedHat Enterprise Server 7

```
Copy
sudo su
curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo
exit
sudo yum remove unixODBC-utf16 unixODBC-utf16-devel #to avoid conflicts
sudo ACCEPT_EULA=Y yum install msodbcsql
# optional: for bcp and sqlcmd
sudo ACCEPT_EULA=Y yum install mssql-tools
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
source ~/.bashrc
# optional: for unixODBC development headers
sudo yum install unixODBC-devel
```


## 编译pdo-odbc

解压php-5.6.17.tar.gz源码。

```
tar zxf php-5.6.17.tar.gz
cd php-5.6.17
cd ext
cd pdo-odbc
/usr/local/bin/phpize
./configure --with-pdo-odbc=unixODBC,/usr/ --with-php-config=/usr/local/bin/php-config
make
sudo make install
```
**重点是php的源码包里有一个ext文件夹，好多扩展其实已经放到里边了**

## 配置

查看/etc/odbcinst.ini中，应该有了sql server的连接驱动

```
[PostgreSQL]
Description=ODBC for PostgreSQL
Driver=/usr/lib/psqlodbcw.so
Setup=/usr/lib/libodbcpsqlS.so
Driver64=/usr/lib64/psqlodbcw.so
Setup64=/usr/lib64/libodbcpsqlS.so
FileUsage=1

[MySQL]
Description=ODBC for MySQL
Driver=/usr/lib/libmyodbc5.so
Setup=/usr/lib/libodbcmyS.so
Driver64=/usr/lib64/libmyodbc5.so
Setup64=/usr/lib64/libodbcmyS.so
FileUsage=1

[ODBC Driver 13 for SQL Server]
Description=Microsoft ODBC Driver 13 for SQL Server
Driver=/opt/microsoft/msodbcsql/lib64/libmsodbcsql-13.1.so.9.0
UsageCount=1
```
**注意这个配置文件中，方括号里边的就是驱动名称，用来在odbc.ini中选择驱动用的。**

odbc.ini例子

```
[MyDSN]
Driver=ODBC Driver 13 for SQL Server
Description=My Test ODBC Database Connection
Trace=Yes
Server=test.sqlserver.com
Port=1433
Database=dbname

```

## 连接测试

```
isql MyDSN username passwod


+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL> quit

```

**php code example**

```
<?php

 putenv('ODBCSYSINI=/etc/');
 putenv('ODBCINI=/etc/odbc.ini');

    $username = "xxxx";
    $password = "xxxxxx";
    try {
      $dbh = new PDO("odbc:MyDSN",
                    "$username",
                    "$password"
                   );
    } catch (PDOException $exception) {
      echo $exception->getMessage();
      exit;
    }
    echo var_dump($dbh);
    unset($dbh);
?>

/usr/local/bin/php test.php 


#Result
object(PDO)#1 (0) {
}


```
Lumen by Laravel

Lumenを試したときのちょっとした構築メモ。

# Lumen
Laravelの作者 Taylor Otwell（元マイクロソフト）が作ったmicro framework。
「美味い、安い、速い」という牛丼のようなWAF。[公式HP](https://lumen.laravel.com/)

# 選んだ理由
- PHPだしぃ〜（学習が簡単）
- シンプルだしぃ〜（micro frameworkを自称するだけあって必要最小限の機能）
- 速そうだしぃ〜（PHPのクセに高速な動作を謳っている）
- オサレ！(ﾟ∀ﾟ)

# 環境
```
仮想環境：vagrant
OS：Ubuntu 14.04.5
言語：PHP7.1
Webサーバー：nginx/1.12.1
```

# 手順メモ
### PHP7.1とExtensionをインストール
リポジトリを追加。
`$ sudo add-apt-repository ppa:ondrej/php`
`$ sudo apt-get update`

本体とExtensionをインストール
`$ sudo apt-get install php7.1 php7.1-fpm php7.1-mbstring php7.1-xml php7.1-zip`

### Composerインストール
`$ curl -sS https://getcomposer.org/installer | php`
`$ sudo mv composer.phar /usr/local/bin/composer`
`$ sudo chmod +x /usr/local/bin/composer`

### Lumenをインストール
`$ cd /srv/www`
`$ composer create-project --prefer-dist laravel/lumen sample`

### nginx設定
最小限の設定だけしてみる。

/etc/nginx/nginx.conf

```
user www-data;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        off;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
```

/etc/nginx/conf.d/default.conf

```
server {
    listen       80;
    server_name  lumensample.local;

    root   /srv/www/sample/public;
    index  index.php index.html index.htm;

    location / {
	try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
	try_files $uri /index.php =404;
	fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass   unix:/var/run/php/php7.1-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
```

### fpmの設定


/etc/php/7.1/fpm/pool.d/www.conf

```
listen.owner = www-data ←nginxのconfで設定したuserにしておく
listen.group = www-data
listen.mode = 0660
```

### サービス再起動
`$ sudo service php7.1-fpm restart`
`$ sudo service nginx restart`

### ブラウザでアクセス
hostsにlumensample.localを追加。
ブラウザのURLにhttp://lumensample.localを入力してアクセス。
↓みたいなバージョンが表示されればOK.
<img width="350" alt="スクリーンショット 2017-08-02 13.58.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/167554/4201f0dc-a88d-7a8a-1b26-ef49b40905f2.png">

お手軽！！
CentOSからKeras with CNTK backendを動かす

# CentOSからKeras with CNTK backendを動かす
KerasがCNTKに対応しました。
https://docs.microsoft.com/en-us/cognitive-toolkit/Using-CNTK-with-Keras

インストールして動かしてみたので、手順を紹介します。

## 環境
CentOS7.3とPython3.5で、CPU onlyです。
マイクロソフトのサイトを見るとLinuxの環境構築方法はUbuntuだけしか書かれてませんが、Centos7.3でも無事に動きました。
（ボヤキ：ディープラーニング系はもはやUbuntu一強になってきましたね。）

## CNTKのインストール
公式手順は以下にあります。
https://docs.microsoft.com/en-us/cognitive-toolkit/setup-linux-python?tabs=cntkpy21

ここではCentos7.3へのインストール方法を紹介します。

まずはAnaconda3をインストールします。
以下からバージョンを選んでインストールします。
https://www.continuum.io/downloads

コマンドラインでインストールする場合は以下でインストールできます。

```
wget https://repo.continuum.io/archive/Anaconda3-4.3.1-Linux-x86_64.sh
bash Anaconda3-4.3.1-Linux-x86_64.sh -b -p /opt/anaconda3
echo 'export PATH="/opt/anaconda3/bin:$PATH"' >> /etc/profile
source /etc/profile
```

CNTKにはOpenMPIが必要です。
CentOS7.3には以下でインストールし、環境変数も設定します。

```
yum -y install openmpi openmpi-devel
export PATH=/usr/lib64/openmpi/bin:$PATH
export LD_LIBRARY_PATH=/usr/lib64/openmpi/lib:$LD_LIBRARY_PATH
```

いよいよCNTKのインストールです。
`pip install`で環境にあわせたURLを指定します。
Linux、CPUonly、Python3.5だと以下になります。

```
pip install https://cntk.ai/PythonWheel/CPU-Only/cntk-2.1-cp35-cp35m-linux_x86_64.whl
```

指定するURLの一覧は以下にあります。
https://docs.microsoft.com/en-us/cognitive-toolkit/setup-linux-python?tabs=cntkpy21

インストールがうまくいけば以下でCNTKのバージョンを表示できます。

```
python -c "import cntk; print(cntk.__version__)"
```

![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/f4e194ca-a4e2-2827-e328-9a94cfab4d30.png)


サンプルプログラムとチュートリアルは以下で取得可能です。

```
python -m cntk.sample_installer
```

## Kerasで使う
KerasでCNTKを使うにはバックエンドを変更する必要があります。
https://keras.io/ja/backend/

バックエンドは/User'sHOME/.keras/keras.jsonで変更しますが、この段階ではまだ.kerasディレクトリがありません。
一度PythonからKerasを呼び出して、作る必要があります。

```
python -c "import keras"
```

![2.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/d24b314c-88cc-ca1a-7326-9cdc4a3662c1.png)


デフォルトではTensorFlowがバックエンドになっていると思います。
/User'sHOME/.keras/keras.jsonを編集します。

```
# 編集前
{
    "floatx": "float32",
    "image_data_format": "channels_last",
    "epsilon": 1e-07,
    "backend": "cntk"
}

# 編集後
{
    "floatx": "float32",
    "image_data_format": "channels_last",
    "epsilon": 1e-07,
    "backend": "cntk"
}
```

これでKerasをCNTKバックエンドで使うことができるようになります。

Jupyter Notebookでimport KerasをするとバックエンドがCNTKになっていることがわかります。

![3.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/46a2affb-8e39-5919-b4bf-561aba3432cb.png)


## とりあえずMNIST
ひとまずMNISTのMLPサンプルを動かしてみました。
https://github.com/fchollet/keras/blob/master/examples/mnist_mlp.py

こういうネットワークになっています。

![4.PNG](https://qiita-image-store.s3.amazonaws.com/0/55384/dd5370ba-8c15-e71b-2ec5-9e41a5b57c0b.png)


プログラムは既存のKerasのものがそのまま動きます。編集不要です。

概要と結果
- トレーニングデータ：28x28の画像60000枚
- テストデータ：28x28の画像10000枚
- バッチサイズ：128
- エポック：20
- CNTKバックエンドのトレーニング所要時間：314秒
- CNTKバックエンドのテスト成績：Loss 0.106430094829、Accuracy 0.9835


### 余談
ディープラーニングフレームワークが乱立していますが、DL4Jが比較をしてくれています。意外とよくまとまっています。
https://deeplearning4j.org/ja/compare-dl4j-torch7-pylearn
All About ACS: IBM i Access Client Solutionsの情報源

#ACSのホームページ
ACSのホームページが、こちらです。

https://www-01.ibm.com/support/docview.wss?uid=isg3T1026805

ここから下記にリンクされています。

[Base PacakgeのDownload]
 https://www.ibm.com/services/forms/preLogin.do?source=swg-ia 
[導入方法のQuickStartGuide]
 ftp://ftp.software.ibm.com/as400/products/clientaccess/solutions/QuickStartGuide_en.html
[マニュアル替わりのGettingStarted]
 ftp://ftp.software.ibm.com/as400/products/clientaccess/solutions/GettingStarted_en.html

また、最新のバージョン情報や次のリリース予定は 下記に掲載されています。

[Additional information for IBM i Access Client Solutions](https://www.ibm.com/developerworks/community/wikis/home?lang=en#!/wiki/IBM%20i%20Technology%20Updates/page/IBM%20i%20Access%20Client%20Solutions%20(5733XJ1))

#導入方法を記載したQuickStartGuide
基本的な導入方法は QuickStartGuide に記載されます。
zip 内に最上位、および「Documentation」フォルダーに「QuickStartGuide.html」として同梱されます。
日本語版は、zip 内に「Documentation\GettingStarted_ja.html」として存在します。ただし、内容が更新されていない場合もありますので、最新情報は英語文書で確認すべきです。

#マニュアル替わりのGettingStarted
詳細なユーザーへの展開方法やコマンドラインのオプションを使った制御情報などの詳細は GettingStarted.html に記載されます。
zip 内の「Documentation」フォルダーに英語版として「GettingStarted.html」が、日本語版として「GettingStarted_ja.html」が存在します。

#日本語での紹介資料

[PC を選ばずに5250エミュレータを使用できる！ －IBM i Access Client Solutions － ](https://www.ibm.com/developerworks/community/files/form/anonymous/api/library/2611a60d-16eb-4932-83b5-0a823b5cf69e/document/e550ff24-6744-470c-ac8c-acad98ed184d/media/PC%E3%82%92%E9%81%B8%E3%81%B0%E3%81%9A%E3%81%AB5250%E3%82%A8%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%A7%E3%81%8D%E3%82%8B%EF%BC%81%20IBM%20i%20Access%20Client%20Solutions%20201501.pdf) という資料が日本IBMから公開されています。

#IBM Knowledge Center
公式マニュアルである IBM Knowledge Center の [「IBM i Access Client ソリューション」](https://www.ibm.com/support/knowledgecenter/ja/ssw_ibm_i_73/rzajr/rzajropconoverview.htm)のページです。
ページの右下で表示言語を日本語に設定できます。

#IBM Support のTechnote・技術情報
IBM Support のページには英語のTechnote (FAQ)、日本語の技術情報(FAQs)などが記載されています。
発生するエラーメッセージへの対策なと、詳細な情報が得らえます。
残念ながら簡単に ACS 関連の一覧を出す方法がないので [Google で IBM Support サイトから「ACS」をキーワードに検索するリンク](https://www.google.co.jp/search?q=ACS+site%3Ahttp%3A%2F%2Fwww-01.ibm.com%2Fsupport%2Fdocview.wss) を記載します。
さらにキーワードを追加して、検索を絞り込んでください。

***
2019-02-18 
- リンク切れなど情報の更新

「All About ACS」では IBM i に対する新しいクライアント「IBM i Access Client Solutions」の情報をいろいろ提供していきます。
[記事一覧はこちら](http://qiita.com/6onoda/items/2dc925586d8d3b8644f2)で確認いたけます。

許可の無い転載を禁じます。
この記事は筆者の個人的な責任で無保証で提供しています。
当記事に関してIBMやビジネスパートナーに問い合わせることは、固くお断りします。
***