OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonでconfluenceに新規ページを作る

業務でコンフルを使っているのですが、ページの作成をどうにか自動で出来ないかと思い、APIを探してみたらあったのでさっそく使ってみました。
以下にAPIのサンプルがあるので、curlですがすぐに試すことができます。
[Confluence REST API Examples](https://developer.atlassian.com/confdev/confluence-server-rest-api/confluence-rest-api-examples)
リファレンスは[こちら](https://docs.atlassian.com/atlassian-confluence/REST/latest/)
## curlで実行してみる
まずはサンプルにある通りcurlで作ってみる。

```
curl -u username:password -X POST -H 'Content-Type: application/json' -d'{"type":"page","title":"new page","space":{"key":"TST"},"body":{"storage":{"value":"<p>This is a new page</p>","representation":"storage"}}}' http://your_confluence_domain/rest/api/content/
```
どこかの子ページとして作りたい場合はこっち

```
curl -u username:password -X POST -H 'Content-Type: application/json' -d'{"type":"page","title":"new page", "ancestors":[{"id":1234}], "space":{"key":"TST"},"body":{"storage":{"value":"<p>This is a new page</p>","representation":"storage"}}}' http://your_confluence_domain/rest/api/content/
```
どうやら`"ancestors":[{"id":1234}]`で親ページを指定している模様。

## Pythonで新規ページを作る
指定するパラメータはcurlのときと同様。
※一部抜粋

```py
import requests
def main():
  payload = {
    'type': 'page',
    'title': 'new page',
    'space': {
      'key': 'TST'
    },
    'ancestors': [{'id': 1234}],
    'body': {
      'storage': {
        'value': '<p>This is a new page</p>,
        'representation': "storage"
      }
    }
  }
  
  headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Basic ' + base64.b64encode('username:password')
  }

  url = 'http://your_confluence_domain/rest/api/content/'

  response = requests.post(url, data = json.dumps(reqdata), headers = headers)
  response.raise_for_status()
```
【PHP入門】while文（ループ処理）の書き方]

※こちらの記事は、プロスタ編集部が学習者の多いPHPの文法記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。
参考サイト：[【PHP入門】while文（ループ処理）の書き方](http://programming-study.com/technology/php-while/)

#【PHP入門】while文（ループ処理）の書き方]

プログラムを作成していると同じ処理を何度も繰り返したい時があります。この同じ処理を何度も繰り返すことを「ループ(loop)」と呼びます。PHPでループ処理を行う構文はいくつかありますが、最も簡単なループ構文の一つがwhile文です。
目次 
1 [while文の書き方](##while文の書き方)
2 [実際にwhile文を書いてみよう](##実際にwhile文を書いてみよう)
3 [while文の条件判断が行われるタイミング](##while文の条件判断が行われるタイミング)
4 [無限ループ](##無限ループ)
5 [breakを使う](##breakを使う)

##while文の書き方

while文は以下のような形式で書きます。

```
while (条件) {
  何かを実行する文 1行目;
  何かを実行する文 2行目;
        ;
}
```


while文は()内に書かれた条件がが成立している間、波括弧{}内に書かれた文が繰り返し実行されます。

##実際にwhile文を書いてみよう

以下のコードを打ち込んで実行してみてください。

```
<?php
	$age = 7;
	while ($age <= 18) {
		echo "$age years old. I go to scool.\n";
		$age = $age + 1;
	}
?>
```

「最初の年齢が7歳で年齢が18歳以下の間、学校へ行く」というプログラムです。

実行結果は以下のようになります。

>7 years old. I go to scool.
8 years old. I go to scool.
9 years old. I go to scool.
10 years old. I go to scool.
11 years old. I go to scool.
12 years old. I go to scool.
13 years old. I go to scool.
14 years old. I go to scool.
15 years old. I go to scool.
16 years old. I go to scool.
17 years old. I go to scool.
18 years old. I go to scool.

##while文の条件判断が行われるタイミング

次に、条件判断がいつおこなわれるのかを見るために、最初の年齢を19歳にして実行してみます。

```
<?php
	$age = 19; // 最初の年齢を 19 歳にする.
	while ($age <= 18) {
		echo "$age years old. I go to scool.\n";
		$age = $age + 1;
	}
?>
```

結果は何も出力されません。というのも変数ageの値が19でプログラムがスタートし、while文の条件では変数ageが18以下かどうかを判定しているためです。つまり、最初から条件が成り立っていないため、波括弧{}で囲まれた文は実行されません。while文ではまず条件の判定が行われ、その結果が真である場合に{}内の文が実行されるということに注意してください。

##無限ループ

以下の例では、while文が無限ループになってしまいます。失敗しやすい部分ですので注意してプログラムを行ってください。

無限ループ例①: 条件式が間違っている。

```
<?php
	$age = 7;
	while ($age >= 7) {
		echo "$age years old. I go to scool.\n";
		$age = $age + 1;
	}
?>
```
無限ループ例②: 条件に使われている変数がループ内で変化しない。


```
<?php
	$age = 7;
	while ($age <= 18) {
		echo "$age years old. I go to scool.\n";
	}
?>
```
##breakを使う

while文のループの途中でエラーが発生した場合など、強制的にループを抜けたい時にはbreak文を使います。

特にファイルの読み書きやネットワークへのアクセスなど、実行時にエラーが発生しやすいコードがループ内に含まれている場合は、エラーが発生した時点でループを抜け出すようにしておかないと、何度も同じエラーを発生させることになります。


```
while (条件) {
    :
   $ret = do_something(); // なにかをする関数。エラーが出たら false を返却する。
   if ($ret==false) {
       break;             // エラーが出たら while ループを強制的に抜け出す。
   }
}
```
UILabelの複数行可変高さまとめ

何かと面倒なiOSの高さ問題。AutoLayoutを使う前提です。

# 共通
コードからでもStoryboardからでも構わないですが、UILabelのnumberOfLinesを0にします。
これで複数行表示できるようになります。

# UITableViewCellの中で使う場合
Cellの高さを自動で計算させる方法があります。
[SwiftでUITableViewCellの高さを動的に変更する](http://qiita.com/ytakzk/items/d7bb8182d43cdfc9b580)

ポイントは、
1. UILabelと隣接するViewまでの上下距離に関する制約をつける
2. 以下の2行をviewDidLoad()あたりに書く

```swift
tableView.estimatedRowHeight = 適当な高さ
tableView.rowHeight = UITableViewAutomaticDimension
```

後は普通にUITableViewのDelegateとDataSourceを実装すればOK。
高さは勝手に計算されるので、heightForRowAtは不要です。

## なんかスクロールがおかしい・・・？
上記だけでは、reloadData()とかscrollToRowAtIndexPath()をするとスクロールがおかしな位置に行ってしまうことがあります。
まだ生成されていないセルの高さを、estimatedRowHeightで設定した値で計算するためみたいです。
[Autolayout で UITableViewCell の高さを設定すると reloadData 後にカクカクすることがある](http://qiita.com/usagimaru/items/664d0d67fe6f8f7fafed)

正常にスクロールさせるには、estimatedHeightForRowAtで正確な高さを返します。
とは言え一度セルが生成されるまでは正確な高さはわからないので、最初はestimatedRowHeightを返します。
そして、willDisplayなどセルが生成された後で、実際のセルの高さを配列などに保存し、次からは保存した高さを返します。

```swift:これらを追加
private var cellHeightList: [IndexPath: CGFloat] = [:]
    
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    if let height = self.cellHeightList[indexPath] {
        return height
    }
    else {
        return tableView.estimatedRowHeight
    }
}
    
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if !self.cellHeightList.keys.contains(indexPath) {
        self.cellHeightList[indexPath] = cell.frame.size.height
    }
}
```

# UIViewで使う場合
子供の要素から適切なサイズを計算してくれる素敵なメソッドがあります。
[UIKit - AutoLayoutを利用した高さ可変のTableHeaderViewをつくる](http://umadash.hatenadiary.jp/entry/2016/05/26/225058)

ポイントは、
1. UILabelと隣接するViewまでの上下距離に関する制約をつける
2. UILabelのtextに文字列を入れる
3. UIViewに対して、setNeedsLayout()とlayoutIfNeeded()を実行
4. systemLayoutSizeFitting(UILayoutFittingCompressedSize)でサイズを計算
5. 4で得られたサイズを使ってUIViewのframeなり制約なりを更新する

```swift:例えば高さの制約を更新する場合
@IBOutlet weak var someViewHeightConstraint: NSLayoutConstraint!
private var someView: UIView!
private var label: UILabel!
func calcHeight() {
    // 手順2
    label.text = "複数行のテキスト"
    // 手順3
    someView.setNeedsLayout()
    someView.layoutIfNeeded()
    // 手順4
    let size = someView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
    // 手順5
    someViewHeightConstraint.constant = size.height
}
```

## これって・・・
そうですね、セルの高さ計算にも使えます。
[テーブルビューのセル毎にピッタリの高さを計算する](http://sasata299.hatenablog.com/entry/2014/05/19/085817)
でも最初に紹介した方法のほうが簡単です。

# おわりに
昔は頑張って計算するしかなかったみたいなので、それに比べればだいぶ楽になりました。
それでもAutoLayoutとかテーブルの高さ計算の仕組みとかわかってないとうまくいかなかったりするので、メモ代わりに記事にしました。
リンク集みたいになってしまいましたが、誰かの役にたてば幸いです。
サッと一時ブランチを作って作業して捨てる

なにかちょこっとだけ作業するたびにトピックブランチをつくって終わったら消すということをしている。

 1. `git branch <branch-name> [<start-point>]`
 2. `git checkout <branch-name>`
 3. 作業
 4. add & commit & push
 5. `git checkout <some-branch>`
 6. `git branch -D <branch-name>`

めんどくさくなってきたので専用コマンドを作った。こういうものを書くのは初めてなので[こちらの記事](http://qiita.com/kawaz/items/2b6ef25f63a4f5300e84)のものを書き換えて作った。

```bash:.bashrc
tmpbranch() {
  (
  d=$(mktemp -d "${TMPDIR:-/tmp}/${1:-$2}.XXXXXXXXXX") && git worktree add $d $1 -b $2 && pushd "$d" || exit 1
  "$SHELL"
  s=$?
  if [[ $s == 0 ]]; then
    rm -rf "$d"
    popd
    git worktree prune
    git branch -D $2
  else
    echo "Directory '$d' still exists." >&2
  fi
  exit $s
  )
}

```

実行するとブランチが作成され、linked working treeが`/tmp`にできて、そこに移動する。`exit`するとディレクトリとブランチとworking treeが削除される。これによって作業は以下のようになった。

 1. `tmpbranch <branch-name> <start-point>`
 2. 作業
 3. add & commit & push
 4. `exit`

いい感じである。もしかしてこんなもの書かなくても別の便利な方法があったりするんだろうか?
memo: よくある、アプリをダウンロードする系ボタンの公式ベクターデータ

# App Store と Play Store ダウンロード用ボタンの、公式ベクターデータ提供ページのパス

ググれば出るけどメモ

- [App Store badge](https://developer.apple.com/app-store/marketing/guidelines/jp/#downloadOnAppstore)
    - App Store では、英語版か、各言語に応じた表記バージョンがあり、いずれもダウンロードすると、pdf/svg/eps 形式が入っている。

- [Google Play badge](https://play.google.com/intl/ja/badges/)
    - Play Store では、言語の選択をした上で、画像形式から eps が選択できる。
Mac のミニマムな Web サーバー Valet 超簡単メモ

- [公式サイト](https://laravel.com/docs/5.3/valet)
- 要 [Homebrew](http://brew.sh/index_ja.html)

# 通常のコマンド

インストール方法は後に記載。

## 起動

```
valet start
```


## 終了

```
valet stop
```

### PHP のバージョンを変える

Valet 2.2 から採用された新しい機能です。

```
valet use php@7.1
valet use php@7.2
valet use php@7.3
```

【2019/2 時点】Homebrew はサポート中の PHP しかサポートしていません。以前のバージョンを使おうとすると Valet が動かなくなってしまいます。

## 特定のディレクトリを指定する

```
cd [ディレクトリ]
valet link [ドメイン名]
```

※ valet park したディレクトリに上記の名前でシンボルリンクが作成

## 特定のドメインを SSL にする

```
valet secure [ドメイン名]
```

元に戻す

```
valet unsecure [ドメイン名]
```

## ドメインを変更

デフォルトでは *.test というドメインになっているので、他の TLD ドメインに変更する

```
valet domain [TLDドメイン]
```

例:

```
valet domain app
```


# 初期設定

## Valet をインストール

```
brew update
brew install php
composer global require laravel/valet
cd ~
vi .bash_profile
```

~/.composer/vendor/bin を PATH に含ませる

```
export PATH="$PATH:~/.composer/vendor/bin"
```

上記を「.bash_profile」として保存。ファイルが既にある場合は上記を追加。。
そして、上記の設定を有効化。（ターミナルを再起動しても良い）

```
source ~/.bash_profile
```

Valet をインストール

```
valet install
```

Nginx などをインストールします。

## Database をインストール

```
brew install mariadb
```

- 127.0.0.1 にインストールされる。
- ID は `root`
- パスワードなし

mysql コマンドや、[MySQL Bench](https://www-jp.mysql.com/products/workbench/) などのソフトを使ってデータベースは管理。

MariaDB を常に起動するように設定する場合は

```
brew services start mariadb
```



### パスワード付きのユーザーを作成する

```
mysql -u root -h 127.0.0.1
CREATE USER '【ユーザー名】'@'127.0.0.1' IDENTIFIED BY '【パスワード】';
GRANT ALL PRIVILEGES ON *.* TO '【ユーザー名】'@'127.0.0.1' WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit;
```

## サイトのフォルダを指定

サイトデータを入れる大元の場所を準備

```
cd [親ディレクトリ]
valet park
```


以上

# アップグレード

```
composer global update
valet install
```

但し、メジャーアップデートの後は

```
valet stop
valet uninstall
composer global require laravel/valet
valet install
valet restart
```

で、park や link 作業をやり直す


# サンプル設定例

## 例: /User/○○○/Sites に環境を作る

開発環境のファイルを下記のような構成で準備する

```
○ 親ディレクトリ (例: ~/Sites)
┣ concrete5
┣ test
┗ blog
```

ターミナルで下記コマンドを実行

```
cd ~/Sites
valet park
```

下記のドメインでフォルダの中身が表示される

フォルダ      | ドメイン名
-------------|----------
concrete5 以下 | concrete5.dev
test 以下 | test.dev
blog 以下 | blog.dev

## MySQL のユーザーを作る

例: `concrete5` というユーザー名と `concrete5` というパスワードを設定

```
mysql -u root -h 127.0.0.1
CREATE USER 'concrete5'@'127.0.0.1' IDENTIFIED BY 'concrete5';
GRANT ALL PRIVILEGES ON *.* TO 'concrete5'@'127.0.0.1' WITH GRANT OPTION;
FLUSH PRIVILEGES;
exit;
```



# クレジット

この記事が役に立ったら、「 **CMS は concrete5 が一番**」と頭の中で10回唱えてみてください〜。
RaspberryPiで3.2インチLCDタッチディスプレイ使ってみた

この記事は諸事情により、[このリンク先](https://sublimer.hatenablog.com/entry/2016/12/07/000000)に移行しました。
This article has moved to [this link](https://sublimer.hatenablog.com/entry/2016/12/07/000000) due to various reasons.
【PHP入門】ファイルへの書き込みをする方法 – file_put_contents関数

※こちらの記事は、プロスタ編集部が学習者の多いPHPの文法記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。

参考サイト：[【PHP入門】ファイルへの書き込みをする方法 – file_put_contents関数](http://programming-study.com/technology/php-file-put-contents/)

#【PHP入門】ファイルへの書き込みをする方法 – file_put_contents関数
PHPの関数 file_put_contents()を使って、ファイルに文字列データを書き込む方法をご紹介します。

##ファイルに文字列を書き込む

PHPでは、file_put_contents()を使えばファイルに情報を簡単に書き込むことができます。この関数は、fopen()、fwrite()、 fclose()を続けて実行してデータをファイルに書き込む動作を一回で行えます。

file_put_contents()を使うときは、データを書き込むファイル名とファイルに書き込むデータを指定します。ファイルが存在しない場合は、新しくファイルを生成しますが、すでにファイルが存在する場合は上書きします。ただし、フラグが設定されている場合は別です。
実行に成功した場合は、ファイルへ書き込まれたバイト数が返されます。実行に失敗した場合は、「false」が返されます。

```
file_put_contents(ファイル名,書き込むデータ,フラグ);
```

例1）sample.txtというファイルに「HELLO WORLD」という文字列を書き込む

```
<?php

file_put_contents("sample.txt", "HELLO WORLD");

?>
```

これにより、自動的にsample.txtというファイルが作成されて、「HELLO WORLD」という文字列が書き込まれました。

ファイルに追記する

file_put_contents()では、フラグを指定することでオプションを設定することができます。
フラグは以下の3つです。 複数のフラグを指定する場合は論理演算子「 | 」を使います。

・FILE_USE_INCLUDE_PATH
ファイルをインクルードディレクトリから探します
・FILE_APPEND
既存ファイルへ追加で書き込みをします
・LOCK_EX 
書き込み中にファイルをロックをして、他の人からの書き込みができなくします

例2）既存ファイルに追記する

```
<?php
 
file_put_contents("sample.txt", "HELLO WORLD2", FILE_APPEND);
 
?>
```

フラグにFILE_APPENDを指定することで、ファイルの上書きではなく追記ができるようになります。例1）と例2）のコードにより、sample.txtには「HELLO WORLD」と「HELLO WORLD2」という文字列が書き込まれました。
WRF > 複数日での処理時に最終日の23時00分のファイル生成に失敗する > Could not find matching time in input file wrffdda_d01 > run_daysの設定間違い

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
```

WRF(Weather Research and Forecasting Model)関連。

WRFのwrf.exeにて処理をした時、処理日数の違いで「最終日の23時00分のファイル」が生成されないことがあるようだ。

- 1日の処理 (2016/11/21)
   - 生成される
- 2日の処理 (2016/11/20-11/21)
   - 生成される
- 4日の処理 (2016/11/18-11/21)
   - 生成される
- 6日の処理 (2016/11/16-11/21)
   - 生成されない
- 8日の処理 (2016/11/14-11/21)
   - 生成されない

./wrf.exeを実行するまでの手順は同じで、namelist.inputを変更しただけで上記の違いが出るようだ。

生成されないとき、以下のエラーメッセージがrsl.out.0000に残る。

```rsl.out.0000
...
Timing for Writing wrfout_d01_2016-11-22_00:00:00 for domain        1:    0.20014 elapsed seconds
           6  input_wrf: wrf_get_next_time current_date: 2016-11-22_00:00:00 Status =           -4
-------------- FATAL CALLED ---------------
FATAL CALLED FROM FILE:  <stdin>  LINE:     928
 ... Could not find matching time in input file wrffdda_d01
-------------------------------------------
```

(追記 2016/12/08)
6日の処理を再実行したところ、「生成された」。何か違う条件が関係するのだろうか。


### ~~とりあえずの対処~~

~~以下のいずれか。~~

~~A. 最終日を1日後ろにして計算~~
~~B. 複数日数をNまでにする (Nがいくらかは要調査)~~

run_daysの設定を見直す。


### 関連しそうな情報

[link. 1](http://skryb.info/m/wrf-users@ucar.edu/AANLkTikXKf3WTTTDxDRConYZzXuCo1_dAvsrmKtiy9g_@mail.gmail.com)

### 設定の間違い

(追記 2016/12/08)

`namelist.output`の`run_days`の値を1日多く設定していたようだ。

「8日の処理 (2016/11/14-11/21)」に対して`run_days = 9`としてしまっていたことに気づいた。

start_day, end_dayなどの設定よりも多い日数をrun_daysに設定した時出るエラーのようだ。
Ubuntu 16.04 でサスペンド復帰後 Wi-Fi が使えなくなったときの対処

# 問題

Ubuntu 16.04 を使っていますが、サスペンドから復帰すると、たまに Wi-Fi が使えなくなることがありました。
ログアウト/ログインや、``sudo service networking restart``を試してみましたが、効果なし。

再起動すれば直るので放置していましたが、ちょっと調べたらあっさり解決したので、備忘録として残しておくことにします。
もっと早く調べてみるべきだった。

# 一行で解決

```bash
nmcli n on
```
syslog を調べてみたところ、サスペンド復帰後にネットワークマネージャーが
立ち上がっていなかったらしいので、これを手動で起こしてやればよいようです。

### 参考
古いバージョンでも同じ現象があったようです。
下にスクリプトが紹介されていますが、16.04 では `nmcli` の書式が違う
らしく、うまく動きません。
[Since 14.04 Upgrade Wifi does not connect after suspend, ralink RT3290](https://ubuntuforums.org/showthread.php?t=2218043&p=13000035#post13000035)
AMPって結局、ニュース・ブログ記事以外にも使えるの？

昨年の10月にグーグルがAMPを発表しました。

スマホページが高速表示される一方で、使えるタグに制限があり、ニュースやブログ記事以外のリッチコンテンツには不向きだなという印象がありましたが、

そんなAMPについて、ニュース・ブログ記事以外でもAMP対応するメリットはあるのか？といった部分をまとめたので、共有させていただきます。

## AMPのメリットのおさらい

例えば話題のニュースを検索すると、、、

![トランプ   Google 検索.png](https://qiita-image-store.s3.amazonaws.com/0/153088/a7c54b0f-b7f9-ba68-3af9-6ff300938fac.png)

検索結果の上部がAMPラベル付きのカルーセルで埋まっており、ニュース記事が占めています。このように、ニュース・ブログ記事においては、検索結果でより目立つことが出来ます。

そして、クリック後の画面がこちらになります。

![ドルは113円後半、トランプラリーは一巡か   Article  AMP    Reuters.png](https://qiita-image-store.s3.amazonaws.com/0/153088/6becf045-3db3-ba37-b829-692a9241a260.png)

これはAMPページになってまして、URLは下の形になります。URLの先頭がgoogle.co.jpでAMPページはグーグルに保存されていることがわかります。
https://www.google.co.jp/amp/jp.mobile.reuters.com/article/amp/idJPKBN13V09J


また、AMPページは決められたタグしか使えないので、ページ自体が軽く、データもグーグルに保存されているので、高速表示が可能です。

## でも、ニュース・ブログ記事しか効果ないし使えない？

結局、AMPによるメリットを享受できるのは、ニュース・ブログ記事限定、と思われるかもしれませんが、既に、ニュース・ブログ記事以外にもAMPページの急速なコンテンツリッチ化により、ECサイトのAMPページもコンテンツリッチ化が進んでいます。

例えば、今年の10月31日にGoogleでの公式発表で、下のようにAMPページのinputタグとformタグのサポートが始まったため、商品詳細ページも作り込むことが出来るようになりました。

![form-error.gif](https://qiita-image-store.s3.amazonaws.com/0/153088/bec5dbcd-04f1-fcd5-a118-173426dc60a1.gif)

### また、コンテンツリッチ化のおかげで、AMPページにカルーセルも表示できるようになりました。
こちらはebayの事例になります。

![Smartphone Cases and Covers   eBay.png](https://qiita-image-store.s3.amazonaws.com/0/153088/a2eb71e1-3031-4b1d-98be-cf7cc17bdfe0.png)

### そして検索結果でも、ECサイトにAMPラベルがつきました。

![cell phone case cover   Google 検索.png](https://qiita-image-store.s3.amazonaws.com/0/153088/c598f91a-214d-0a61-ea6f-114baf0d98c2.png)

## 今のところ検索順位への影響はないと言われているけど・・・
AMP対応に合わせて、ちゃんと構造化をさせることで、検索結果のリッチスニペット化ができます。

![1 5. AMPをニュース系以外にも導入すると良い理由と最新の事例を紹介   Google ドキュメント.png](https://qiita-image-store.s3.amazonaws.com/0/153088/c48ded34-bf7d-460b-99c1-d978ca66b429.png)

これは、楽天レシピの例ですが、レシピページも構造化させることで検索結果がリッチスニペット化しサムネイル画像が付き、AMP対応することでAMPラベルも付与されます。

このように、ニュース・ブログ記事以外でもAMP対応のメリットを享受できるようになってきました。

## ここまでが現時点のことで、他にも、、、

AMPに関する最新情報は常に[AMPプロジェクトのロードマップ](https://www.ampproject.org/roadmap/)で確認することができます。
その情報によると、決済周りについても使い勝手をよくしようとしているみたいです。

## まとめ

* ニュース・ブログ記事以外にもECサイトやレシピサイトにグーグルはAMPラベルを付与しています。
* ニュース・ブログ記事以外にもAMPページのコンテンツリッチ化が急速に進んでいます。
* AMPだけでなく構造化データも検索結果で目立つために重要です。

また、AMPついて新しい事がわかりましたら、シェアします。
ライセンスダイアログをサクッと実装する

## LicensesDialog

https://github.com/PSDev/LicensesDialog

<img width="213" alt="Screenshot_20161207-182942_png.png" src="https://qiita-image-store.s3.amazonaws.com/0/99731/753c79c4-0c88-c05e-9924-8d0eb98c2c1f.png">

Androidアプリの作成に使ったライブラリのライセンスをアプリにすばやく組み込むにはLicensesDialogがおすすめです。


##インストール

下のエラーが発生してインストールできない困ったｗ

Warning:Conflict with dependency 'com.google.code.findbugs:jsr305'. Resolved versions for app (3.0.1) and test app (2.0.1) differ. See http://g.co/androidstudio/app-test-app-conflict for details.
Error:Execution failed for task ':app:prepareDebugAndroidTestDependencies'.

Dependency Error. See console for details.

### エラーを回避

下を追加したら動いた

```py3

 configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
 }

```

### 全体

```py

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "24.0.0"
    defaultConfig {
        applicationId "jp.co.test.licensedialog"
        minSdkVersion 15
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    //追加
    configurations.all {
        resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'
    }
    //追加
    compile 'de.psdev.licensesdialog:licensesdialog:1.8.1'

    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.0.1'
    testCompile 'junit:junit:4.12'

}

```

## アクティビティで表示

```java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        showLicense();
    }

    private void showLicense() {
        final Notices notices = new Notices();
        notices.addNotice(
                new Notice("butterknife", "", "Copyright 2013 Jake Wharton", new ApacheSoftwareLicense20()));

        notices.addNotice(
                new Notice("timber", "", "Copyright 2013 Jake Wharton", new ApacheSoftwareLicense20()));

        notices.addNotice(
                new Notice("material-dialogs", "","Copyright (c) 2014-2016 Aidan Michael Follestad", new MITLicense()));


        final LicensesDialogFragment fragment = new LicensesDialogFragment.Builder(getApplicationContext())
                .setNotices(notices)
                .setShowFullLicenseText(false)
                .setIncludeOwnLicense(true)
                .build();

        fragment.show(getSupportFragmentManager(), null);
    }
}

```
jquery clickableMap 

クリッカブルマップ（イメージマップ）ロールオーバーです。
hover画像ファイル名は、「\_on」＋ areaタグ順に応じたメイン画像の連番となります。
hoge.png　→ hoge\_on1.png, hoge\_on2.png…
画像プリロードはありません。

jquery1.9.1で動作を確認。

```ruby:jquery.clickableMap
(function($) {
  $.fn.clickableMap = function(){
    return this.each(function() {
      var _off = $('.imagemap img',this).attr('src');
      var num = 0;
      var targetImg = $('.imagemap img',this);

      $('area',this).each(function() {
        num++;
        var elm = _off.replace(/(_on)[0-9]*/,'');
        var _on = elm.substr(0, elm.lastIndexOf('.')) + '_on' + num + _off.substring(_off.lastIndexOf('.'));
        $(this).hover(
          function() {
            $(targetImg).attr('src', _on);
          }, function() {
            $(targetImg).attr('src', _off);
          }
        );
      });
    });
  };
})(jQuery);

jQuery(function($) {
  $('.clickableMap').clickableMap();
});
```

```ruby:html
<div class="clickableMap">
  <div class="imagemap"><img src="imagemap.png" alt="" width="500" height="500" usemap="#imageMap"></div>
  <map name="imageMap">
    <area href="#" alt="" shape="rect" coords="0,0,500,250">
    <area href="#" alt="" shape="rect" coords="0,250,500,500">
  </map>
</div>
```

昔に書いてあまり使っていないコードです。
今見るとラッパー要素にclass指定するよりも、usermap/nemeを属性でセレクタ指定して簡潔にしたりと、他にも改良の余地あり。
近年クリッカブルマップ使うこともなかなか無いと思いますが。
【PHP入門】画面にエラーを表示する方法

※こちらの記事は、プロスタ編集部が学習者の多いPHPの技術系記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。
参考サイト：[【PHP入門】画面にエラーを表示する方法](http://programming-study.com/technology/php-error/)

#【PHP入門】画面にエラーを表示する方法


PHPでプログラムを作成中に不具合が発生した場合に、ブラウザなどの画面上でエラー確認しながら、対応する場面はよくあります。
今回は、エラーを表示する方法として「display_errors」とPHPの設定項目を使った方法を紹介します。

display_errorsは以下の2パターンで設定が可能です。

1.php.iniで設定する

2.ini_setを用いてphpファイル内で設定する

今回は以下のコード「sample.php」を使って、上記２種類の方法を比較しながら、紹介していきます。

```
<?php
// 正常なコード
echo "start<br/>";

// 変数の前に$がないのでエラーになる
echo test == 1;

// 正常なコード
echo "end<br/>";
```
##php.iniで設定する

プログラムを作成/動作確認しているWebサーバの設定が変更可能な場合は、php.iniの以下の項目を、


``` 
display_errors = OFF
```

以下のように変更することで、エラーを画面に表示可能です。


``` 
display_errors = ON
```

php.iniを設定後は、Webサーバを再起動することで、設定が反映されます。
上記を設定後、ブラウザで最初に提示したプログラムのPHPファイルにアクセスすると、「Notice: Use of undefined constant test – assumed ‘test’ in /Library/WebServer/Documents/sample.php on line 6」と画面上に表示されます。

##ini_setを用いてphpファイル内で設定する

前述のphp.iniで設定する方法は、設定変更後にWebサーバを再起動する必要があります。その場合、レンタルサーバーや商用環境で使用しているサーバでは、設定変更をすることが困難な状況もあります。

そこでPHPのファイル内でdisplay_errorsを設定する方法として、ini_set関数を使用した方法を紹介します。エラーを確認したいファイルの先頭など、検証したいコードの前に以下のコードを追加します。

```
// エラー表示なし
ini_set('display_errors', 0);
 
// エラー表示あり
ini_set('display_errors', 1);
```

上記の「エラー表示あり」の設定を追加してファイルを保存後、先ほど同様にブラウザでアクセスすると、同様にエラーが表示されるようになります。
ここでの違いは設定値がON/OFFではなく、1/0での設定によるものです。

ただし下記のようなプログラムのタイプミスによりエラーは、PHPのプログラム解析中のエラーになるため、ini_set関数でdisplay_errorsを設定しても、画面上にエラーメッセージが表示されません。


>// echo関数のタイプミスによるエラー
echoi "test"


これはPHPのプログラムファイルが実行途中でエラーになり、ini_set関数の実行による設定が反映される前にプログラムが終了してしまうためです。このような場合には注意が必要です。
Github Pull RequestをJenkins経由でテストを実行する場合にパラメータを設定する方法

この記事は [リクルートライフスタイル Advent Calendar 2016](http://qiita.com/advent-calendar/2016/recruitlifestyle) の7日目の記事です。

## はじめに

データ基盤Tの@byaです。
本記事は「Pull Requestの内容からパラメータを取得し、JenkinsでJobを実行する」について聞きます。

基本的にJenkinsの[Github Pull Request Builder Plugin](https://github.com/janinko/ghprb)を使えば、Githubの指定したリポジトリにPull Requestが作成されと、Jenkinsであらかじめ設定したJobが実行し、その実行結果をGithubに通知し、記録してくれます。つまり、このレポジトリにどのようなPull Requestきても、同じ「A」というjobが実行されます。しかし、業務上は「Pull Requestの内容に応じて、別々のjobを実行したい」という場合があると思います。その工夫について以下書きます。

## 準備

用意するものは、GithubリポジトリとJenkinsサーバーです。 設定や導入について以下の記事を参考してください。

* [Pull Request Builder PluginをJenkinsに導入する](http://qiita.com/kompiro/items/a097b3b36aa30bc751c6)
* [Jenkinsでプルリクエストをビルドする](http://qiita.com/quattro_4/items/6b1962909ce868f12e5a)

## パラメータを設定する

Pull Requestの内容によってJenkinsで実行されるjobが異なるので、それを識別させるにはPull Requestのdescription(説明)にパラメータを設定します。以下の画像は、"Job ID"にJenkinsのjobを指定する例です。

![Screen Shot 2016-12-07 at 16.51.39.png](https://qiita-image-store.s3.amazonaws.com/0/72573/6d2152f4-0e3b-cb26-e108-0890899dac53.png)

## パラメータを取得する

上記のパラメータを取得するために以下のpythonを書きました。

```python
# coding:utf-8
from fabric.api import local
import json


oauth_token = "githubの oauth token"
github_api_url = "githubのAPI URL"
owner = "レポジトリのオーナー名"
repo = "レポジトリ名"
git_current_commit_id = "コミットID"


def _search_pullreq_id(oauth_token, git_current_commit_id, pull_requests):

    for i in range(len(pull_requests)):
        pq_commits_raw = local('curl -H "Authorization: token {0}" {1}'.format(
            oauth_token, pull_requests[i]["commits_url"]), capture=True)
        pq_commits = json.loads(pq_commits_raw)

        for pqc in pq_commits:
            if git_current_commit_id == pqc['sha']:
                # Found
                return i

# Extract parent commit id
commit_raw = local('curl -H "Authorization: token {0}" {1}/repos/{2}/{3}/commits/{4}'.format(
    oauth_token, github_api_url, owner, repo, git_current_commit_id), capture=True)
git_current_commit_id = json.loads(str(commit_raw))['parents'][-1]['sha']

# Fetch all Pull Requests
pull_requests_raw = local('curl -H "Authorization: token {0}" {1}/repos/{2}/{3}/pulls'.format(
    oauth_token, github_api_url, owner, repo), capture=True)
pull_requests = json.loads(str(pull_requests_raw))

# Search current commit's pull request id
pull_request_id = _search_pullreq_id(oauth_token, git_current_commit_id, pull_requests)

# Extract current pull request's description
description = pull_requests[pull_request_id]['body']

# Extract jod id
job_id = description.split("Job ID:")[1].splitlines()[0].strip(":").strip().encode('utf-8')

```

ややハードコーディングになってしまいましたが、やっていることはPull Requestされたgithubの「commit id」から「pull request id」を特定し、その「pull request id」からの「説明文(body)」を抽出して、パラメータを取得しています。
ちなみに[Github Pull Request Builder Plugin](https://github.com/janinko/ghprb)を使うと、githubの「commit Id」しか分からないため、上記のように「pull request id」を取得するコードを自分で書かなければなりません。

## まとめ

上記でやったことを図にまとめると：
![Screen Shot 2016-12-07 at 18.24.51.png](https://qiita-image-store.s3.amazonaws.com/0/72573/e80ca639-7961-c950-dd44-8a77459ea69e.png)
研究室の Raspberry Pi (1才2ヶ月)に愛着が湧いている

[CPS Lab Advent Calendar 2016](http://www.adventar.org/calendars/1536) の 8 日目の記事です。
前日は @harhogefoo の[ゼロから始めるプログラミング生活](http://harhogefoo.xyz/blog/2016/12/07/zero_kara_programming/) です。


---


研究室内には誰がいるのか確認する目的で設置された Raspberry Pi がある。今ではみんなでカスタマイズして多機能になったのでまとめてみようと思う。

成長を見てほしいので**歴史順に紹介する。**

![IMG_6731.jpg](https://qiita-image-store.s3.amazonaws.com/0/40717/c280ecbe-47e1-223f-7d07-eae23699760c.jpeg)

# スピーカー再起動
ラボのテレビスピーカーが壊れていて、再起動が必要になる場面がよくある。
詳細: http://ikoann.blogspot.jp/2016/12/iot.html

問題解決の中継器として 受信用 TWE-Lite が生えた Raspberry Pi が設置された。これがはじまり。

# 室内確認カメラ
二部屋ある研究室が離れていて、もう片方からラボ内に誰がいるか知りたい需要があった。とりあえずカメラがつけられて内向け API で叩けるようにした。
ネットワークにつながってる bot により Slack からコマンドで呼び出せるようになったりした。「これヤバイんじゃない？(プライバシー)」という声が上がり始める。

実際にはあまり使われず、**みんなのストレスもあり廃止された**。


# 音声コントロール
「マイクつけたら面白いんじゃね？」というノリでマイクを付けた。

音声認識ライブラリの [Julius](http://julius.osdn.jp/) を使って予め決めたキーワードを受け取って処理できるようにした。

Raspberry Pi に「maimai」と名付けて、「オーケーマイマイ！」で命令待機するようにした。
**maimai は耳を得た。**

スピーカー再起動も声で出来るようになった。

# コーヒー
「maimai にコーヒー淹れてほしいよね」というノリで作った。
![IMG_6729.JPG](https://qiita-image-store.s3.amazonaws.com/0/40717/c203a6ef-6211-8e60-5903-d50bef3318c9.jpeg)


**[@s_dm_u](https://twitter.com/s_dm_u) がコーヒーサーバーをハックした。**ESP8266 で http リクエスト受けたらコーヒーを入れるようにしてくれた。代償に濃度選択ボタンは「濃い」しか選べなくなってしまったが犠牲はつきものだ。

豆を挽いてコーヒーサーバーにセットするところは手伝わなければいけない。すべて maimai に任せるのは傲慢である。**でもすべて maimai にやって欲しい。**

これで「コーヒー入れて！」で maimai にコーヒーを作ってもらった気分を満喫できるようになった。

# スピーカー
「maimai にスピーカーつなげたら面白いんじゃね？」というノリでスピーカーがついた。
AquesTalk や VOICEROID で日本語も喋るようになった。

**maimai は声を得た。**

内向けにテキスト読み上げ API 化した。また Slack bot によりコマンド化されたが、導入時はちょっとラボが荒れた。

楽曲とか効果音も流せるし、**この時は可能性が広がってワクワクしたのを覚えてる。**

「力が欲しい」で完全勝利するような音楽流れたり、「トランザム！」でトランザム BGM が流れたり、わけわからないコマンドが増えた。


# Chromecast
「天気はテレビに予報図とか表示してほしくね？」というノリで作った。
テレビについてる Chromecast を活用した。[pychromecast](https://github.com/balloob/pychromecast) を使ってメディアをテレビに表示できる。
「雨雲レーダー！」で雨雲レーダー画像を取ってきて表示してくれる。

![IMG_6735.JPG](https://qiita-image-store.s3.amazonaws.com/0/40717/111f0a40-bc54-d00c-52b9-1df63613a110.jpeg)


# IRKit
「朝テレビからニュース流してほしくね？」というノリで作った。
残留する学生も多いので目覚ましが欲しかった。
朝7:30 にさわやかな音楽を流し、7:35 にテレビでニュースチャンネルをつけるようにした。

**一度大音量でパンクな楽曲流した時メンバーにキレられたので消した。**

とりあえず「テレビつけて！」で maimai がつけてくれる。


# その他
## 時報
講義時間の20分前に「x限目の20分間です」と通知してくれる。これにはみんな依存し始めのていて、maimai が止まった時は遅刻しそうになった。
昼飯どきと夕飯どきにも時報をする。

## ランダム飯
登録した食事、店舗からランダムにチョイスしてくれる。夕飯時報のときも教えてくれる。

## Youtube 再生
API に追加した。url を渡すとプレイしてくれる。
【Swift入門】for-in文の使い方

※こちらの記事は、プロスタ編集部が学習者の多いSwiftの技術系記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。
参考サイト：[【Swift入門】for-in文の使い方](http://programming-study.com/technology/swift-for-in/)

#【Swift入門】for-in文の使い方

for-in文の書き方

for-in文はfor文の一種で、コレクションなどに含まれる要素を1つずつ取り出して処理するのに便利です。for文と違って、インデックスカウンタ(例えばi++)を書く必要がありません。特にロジックに支障がなければ、for-in文を使用するように心がけましょう。バグの作り込みを減らせます。

基本的なfor-in文の書き方を次に示します。

```
for 定数名  in コレクションなど {
	処理
}
```

定数名は、このfor-in文内だけで有効です。また、定数名には、暗黙のうちにlet宣言がされます。つまり、定数名の値を「処理」の中で変更することはできません。

##実際にfor-in文を書いてみよう

コレクションの一つである配列を使って、配列要素を取り出して出力してみます。

```
let  intArray : [Int]  = [ 10 , 20 , 30 , 40 ,50 ]

for value in intArray{
    print(value)
}
```

実行結果は次のようになります。
>10
20
30
40
50

次にディクショナリ(辞書)を使ってみましょう。

```
let  dictionary = [ "one" : 1 , "two" : 2  , "three" : 3]

for (key , value) in dictionary{
    print("\(key) = \(value)")
}
```

実行結果は次のようになります。

>one = 1
three = 3
two = 2

実行結果を見ると、one, two, threeの順番になっていませんね。ディクショナリで定義した順番に取得されるとは限りませんので注意してください。

コレクションの代わりに、範囲演算子を指定して二つの数字の区間を指定することができます。まず、1から5までを出力してみます。

```
for value in 1...5{
    print(value)
}
```

実行結果
>1
2
3
4
5

範囲演算子を変えてみます。

```
for value in 1..<5{
    print(value)
}
```

実行結果
>1
2
3
4

“1…5”は5を含みますし、”1..<5”は5を含みません。 for-in文の中で、処理を中止したい場合には、”break”を使用します。また、以降の処理を行わずにループに戻りたい場合には、”continue”を使用します。
mrubyで末尾再帰

あまり知られていませんが(Googleとtwitterの検索を調べた結果)、mrubyには末尾再帰のための処理が入っています。でも、ほとんどテストされていないので基本的には動きません。昔ちょっと動かしたことがあるのでその話を書きます。

# TAILCALL命令
mrubyのバイトコードインタプリタにはTAILCALLという命令があります。この命令はもちろん現状では使われていません。余談ですが、mrubyのインタプリタの命令には使われていないものがいくつかあります。NOPなんかもそうですね。
TAILCALLは、SENDに似たような処理なんですがメソッドの呼び出し情報を格納するcallinfoのエントリーを新しく追加するのではなく今実行中のメソッド呼び出し情報が入っているエントリーに上書きしてしまいます。また、レジスタも呼び出し元で使っているレジスタに上書きしてしまいます。詳しくは[コード](https://github.com/mruby/mruby/blob/master/src/vm.c#L1685) を読んでください。

# コンパイラ
mrubyのバイトコードコンパイラ(mruby-compiler mrbgem)にはTAILCALL対応の処理が入っていますが、現状では無効化されています。
https://github.com/mruby/mruby/blob/master/mrbgems/mruby-compiler/core/codegen.c#L308
処理を読むと、RETURN命令の直前のSEND命令はTAILCALL命令に置き換えられるようです。

# バグ
コンパイラの部分を有効にすれば動くのでは？って思うかもしれませんが動きません。昔、動かしたことがあるのですがいくつかの[パッチ](https://github.com/mruby/mruby/issues/2756) を当てるとao benchくらいなら動くようになります。興味のあればどうぞ
これ、本家に取り込まれていないんですよね。私もそれでいいと思っています。なぜなら make testが通らないからです。がんばればなんとかなるとかではなく、原理的に非互換が生じちゃうんですよね。そのテストは local_variables。本来あるはずのローカル変数の領域を潰しちゃう(だから再帰してもスタックが膨れない)のだから当然互換は取れないですよね。

# おわりに
性能がそれほど上がるものでもなかったので、これっきりになっています。楽しかったので無駄だとは思っていませんが。将来、mrubyで関数型プログラミングが流行りだす未来があれば引っ張り出しましょう。
【Swift入門】switch文を使って条件分岐する方法

※こちらの記事は、プロスタ編集部が学習者の多いSwiftの技術系記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。
参考サイト：[【Swift入門】switch文を使って条件分岐する方法](http://programming-study.com/technology/swift-switch/)

#【Swift入門】switch文を使って条件分岐する方法

基本的なswitch文の書き方を次に示します。

目次 
1 [switch文の書き方](##switch文の書き方)
1.1 [複数の値に同じ処理を行う](##複数の値に同じ処理を行う)
1.2 [fallthroughを使って次のcaseの処理を実行する](##fallthroughを使って次のcaseの処理を実行する)
1.3 [範囲演算子を使用する](##範囲演算子を使用する)
2 [実際にswitch文を書いてみよう](##実際にswitch文を書いてみよう)


##switch文の書き方

基本的なswitch文の書き方を次に示します。

```
switch 値または式 {
case 値1:
	値1のときの処理
case 値2:
	値2のときの処理
case 値3:
	値3のときの処理
default:
	上記の値1,2,3以外の場合の処理
}
```

“値または式”が判定対象です。caseの後ろには、整数または文字列を使うことができます。defaultの処理は、caseで指定された条件のいずれにもヒットしなかった場合、実行されます。
case、defaultとも何らかの処理を記述する必要があります。何も行わない場合には、”break”を記述しなければなりません。breakはswitch文の処理を終了させるだけの役目です。

##複数の値に同じ処理を行う

複数の値に同じ処理を行いたい場合には、caseの後ろに値を列挙します。

```
switch 値または式 {
case 値1 , 値2:
	値1か値2のときの処理
case 値3:
	値3のときの処理
default:
	上記の値1,2,3以外の場合の処理
}
```

##fallthroughを使って次のcaseの処理を実行する

caseにヒットした場合、そのままでは、次のcaseは無視されます。
caseにヒットした後、その後のcaseの処理も実行したい場合には、明示的にfallthroughを指定します。

```
switch 値または式 {
case 値1:
	値1のときの処理
	fallthrough
case 値2:
	値2のときの処理
case 値3:
	値3のときの処理
default:
	上記の値1,2,3以外の場合の処理
}
```

上の例の場合、値1がヒットしたとき、”値1のときの処理”を実行した後、”値2のときの処理”も実行されます。”値3のときの処理”は、”値2のときの処理”の後にfallthroughが無いため実行されません。

##範囲演算子を使用する

caseには、for-in文などでも使われる、範囲演算子を使用することができます。それにより、一つの値でなくある範囲の値にヒットさせることができます。

```
switch 値または式 {
case 範囲演算子1:
	範囲演算子1にヒットしたときの処理
default:
	上記のcaseにヒットしなかった場合の処理
}
```
	
caseで指定する条件には、整数や文字列以外に、タプルを使用することができます。タプルをswitch文で使用することはあまり多くないと思いますが知っておいて損はありません。具体例は後述します。

##実際にswitch文を書いてみよう

シンプルな変数の判定を行ってみます。

```
let i : Int = 10

switch i {
case 10:
    print("これは十です。")
case 20:
    print("これは二十です。")
case 30:
    print("これは三十です。")
default:
    print("これは十、二十、三十以外の数字です。")
}
```

実行結果は次のようになります。

>これは十です。


次に、switch文の判定対象を定数iから式に変えてみます。

```
let i : Int = 10

switch i * 2{
case 10:
    print("これは十です。")
case 20:
    print("これは二十です。")
case 30:
    print("これは三十です。")
default:
    print("これは十、二十、三十以外の数字です。")
}
```

実行結果は次のようになります。

>これは二十です。

今度は、caseに範囲演算子を指定してみます。

```
let i : Int = 10

switch i {
case 1..<10:　　　 // 1から10未満を意味します。
    print("これは1から9の間です。")
case 10...20:      // 10から20以下を意味します。
    print("これは1から20の間です。")
default:
    print("これは1から20の間ではありません。")
}
```

実行結果は次のようになります。

>これは1から20の間です。

タプルを使用して、複数の値の組み合わせにヒットさせる例を示します。

```
let valuePair : (Int , String) = (1, "一")

switch valuePair {
    case (1 , "一" ):
        print("これは数字の1と漢数字の一です。")
    case (2 , "二" ):
        print("これは数字の2と漢数字の二です。")
    default:
        print("すみません、わかりませんでした。")
}
```

実行結果は次のようになります。

>これは数字の1と漢数字の一です。
Rubyクイズ

自分が実際に業務でRubyを書いていてハマったところ、ハマりかけたところ、あるいは初心者がつまづきやすいところをクイズにしてみました。
皆さん、実行せずに答えられますか?

答えは[こちら](http://qiita.com/isuke/items/b8cc8fb5804fb522cb3f)

## クイズ1

Aの出力結果は何でしょう?

```ruby
def hoge(options = {})
  foo = options.delete(:foo)
  puts "foo is #{foo}"
  puts "options is #{options}"
end

options = {foo: 'FOO', bar: 'BAR'}
hoge(options)
puts options #=> A
```

## クイズ2

A, Bの出力結果は何でしょう?

```ruby
INIT_STR = 'INIT STR:'

def hoge(num)
  temp = INIT_STR
  num.times do |n|
    temp << " #{n}"
  end
  temp
end

puts hoge(3) #=> A
puts hoge(3) #=> B
```

## クイズ3

Aの出力結果は何でしょう?

```ruby
def hoge(options = {}, foo: 'FOO')
  puts options
  puts foo
end

hoge(bar: 'bar', foo: 'foo') #=> A
```

## クイズ4

A〜Hの実行結果は何でしょう?

```ruby
Array(1)            # => A
Array(nil)          # => B
Array([])           # => C
Array.new           # => D
Array.new(1)        # => E
Array.new(nil)      # => F
Array.new(nil.to_i) # => G
Array.new([])       # => H
```

## クイズ5

Aの実行結果は何でしょう?

```ruby
class Hoge
  def foo
    self.bar
  end

private

  def bar
    puts 'bar'
  end
end

Hoge.new.foo # => A
```

## クイズ6

Aの実行結果は何でしょう?

```ruby
class Hoge
  attr_accessor :foo,

  def initialize(foo)
    @foo = foo
    puts @foo
  end
end

Hoge.new('bar') # => A
```

## クイズ7

A, Bの実行結果は何でしょう?

```ruby
def hoge
  sleep 1 # 重い処理
  'hoge'
end

if result1 = hoge
  puts result1 # => A
end
puts result2 if result2 = hoge # => B
```

---

思いついたら追加します。
RSpecの小技集

この投稿は [RSpec Advent Calendar 2016](http://qiita.com/advent-calendar/2016/rspec) (幻の)7日目の記事です。

自分用メモとして投稿しようと思ったのですが、ちょうど今日のAdvent Calendarが空いていたので飛び入り参加させていただきました。（そういう意味で `幻の7日目` です ）

---

RSpecを書いていてよく「〇〇したいんだけど、どうやるんだっけ？」とググることが多かったのでまとめてみました。
RSpecの基本文法を理解している中級者以上向けの内容と思います。

RSpecは3.4を使っています。（ちょっと古くてすみません）
前提として以下のクラスがあるとします。
サンプルコードに出てくる `foo` という変数はこのFooクラスのインスタンスです。

```ruby
class Foo
  def bar
    1
  end

  def baz(arg)
    2
  end
end
```

# 複数インスタンスのメソッドが呼ばれる度に異なる値を返す

クラス`Foo`の複数インスタンスでメソッド`bar`が呼ばれる度に異なる値を返したい場合のやり方です。

まず、単一インスタンスであれば

```rb
allow(foo).to receive(:bar).and_return(:a, :b, :c)
```

でOKですが、これを単純に

```rb
allow_any_instance_of(Foo).to receive(:bar).and_return(:a, :b, :c)

expect(Foo.new.bar).to eq :a
# -> OK
expect(Foo.new.bar).to eq :b
# -> Failure
```

としても期待通りには動きません。

そこで以下のようにします。

```rb
values = [:a, :b, :c]
allow_any_instance_of(Foo).to receive(:bar) { values.shift }

expect(Foo.new.bar).to eq :a
# -> OK
expect(Foo.new.bar).to eq :b
# -> OK
```

ブロック/Procで渡せばbarが呼ばれる都度評価されるので、配列の先頭から取り出されていきます。


# メソッドの引数に応じてスタブ値を変える

(上記の「複数インスタンスのメソッドが呼ばれる度に異なる値を返す」とあまり変わりませんが。。。)
元のメソッド引数もそのまま渡されるので、それを使用します。

```rb
values = { a: 10, b: 20 }
allow(foo).to receive(:baz) { |arg| values[arg] }
expect(foo.baz(:a)).to eq 10
expect(foo.baz(:b)).to eq 20
```


# 複数メソッドをまとめてスタブする

```rb
allow(foo).to receive_messages(hoge: 1, fuga: 2)
expect(foo.hoge).to eq 1
expect(foo.fuga).to eq 2
```

# メソッドチェインをまとめてスタブする

```rb
allow(foo).to receive_message_chain(:bar, :to_s).and_return(10)
expect(foo.bar.to_s).to eq 10
```

# 元のメソッドを呼ぶ（スタブしない）

任意のメソッドが呼ばれたかのチェックはされますが、スタブされずそのまま元のメソッドが呼ばれます。（サンプルコードは簡略化しすぎて自明になってますが・・・）

```rb
allow(foo).to receive(:bar).and_call_original
expect(foo.bar).to eq 1
```

# 複数のmatcherをand/orでつなぐ

mathcherはand/orでつなぐことができます。ただし `not_to` (`to_not`)の場合は繋げられません。
失敗時には対応したmatcherのメッセージがちゃんと表示されます。

```rb
expect(1).to be_present.and be_integer.and be_odd
expect(0).to be_blank.or be_zero

# 以下のように書くのと同じです。
expect(1).to be_present
expect(1).to be_integer
expect(1).to be_odd
```

# matcherをネストさせる

ちなみに `receive().with()` で使用できる[Argument Matcher](https://github.com/rspec/rspec-mocks#argument-matchers)も使用できます。

```rb
val = [
  { foo: "foofoo", bar: { hoge: 10, fuga: 20 }, baz: 0 },
  { foo: "beebee", bar: { hoge: 30, fuga: 40 }, baz: [5, 6, 7] }
]
expect(val).to match_array([
  include(foo: be_include("oo"), bar: kind_of(Hash)),
  include(foo: be_include("ee"), baz: array_including(5))
])
```

---

こういうこともできるんだよ、という意図で本記事を書きましたが、RSpecで凝ったことをやろうとすることは対象コードのテスタビリティが低いということかもしれず、設計を見直した方がいいかもしれません。
FuelPHPでAPIを作る時にバリデーションのせいでGETとPOSTだけしか使えないけどPUTとかDELETEも使いたい


どうもこんにちは。
FuelPHPでController_RestやController_Hybridを継承したコントローラを作るとHTTPメソッドを指定したAPIが作成できますよね。

```php:php
class Controller_Some_Api extends Controller_Rest
{
    public function get_users()
    {
        // なんか処理
    }

    public function post_users()
    {
        // なんか処理
    }

    public function put_users()
    {
        // なんか処理
    }

    public function delete_users()
    {
        // なんか処理
    }
}
```

こんな感じでエンドポイント1つだけ作ってHTTPメソッドのみで各種操作を行えることが出来ます
`somedomain.com/v1/users`

なので「よっし、更新系はPUTかPATCH使っていくぜぇ～」と思ってパラメータ付きのPUTリクエストを送信しました。

リクエストは普通に来る

しかし、値の有効性を確認するためのバリデーションが一切通ってくれない

まずInput::put()やInput::param()を取得してみるとpostやgetと違って残念な感じで返ってくる

期待したPUT値はこんな形

```php:php
{ "value_a": "aaa" }
```

だがこういう形で返ってくる

```php:php
{ "------WebKitFormBoundaryKBQloznTHgbTPFxN\r\nContent-Disposition:_form-data;_name": "\u0022value_a\u0022\r\n\r\naaa\r\n------WebKitFormBoundaryKBQloznTHgbTPFxN--\r\n" } }
```

これではvalidationのrunに値セットしてもダメなのでGETとPOSTしか使えんやないかと

しかもvalidationの中では受け取った値以外をチェックする時にPOSTじゃないと見てくれないらしいのでやっぱりPUTとかだとだめっぽい

```php:core/classes/validation.php
public function run($input = null, $allow_partial = false, $temp_callables = array())
{
    if (is_null($input) and \Input::method() != 'POST')
    {
        return false;
    }
```


だけどどうしてもcontrollerではput_～～～と書きたいしバリデーションもしたい！
という時に使える方法

リクエストする側にPOSTでリクエストしてもらってリクエストヘッダーに`X-HTTP-Method-Override: PUT`を指定してもらう

こうするとcontrollerでInput::post()でパラメータが普通に取得できるようになります。

```php:php
public function put_users()
{
    // putで宣言してるけどポスト値を取得できる
    $params = Input::post();
    // なんか処理
}
```

のでバリデーションrunをした時に引数としてパラメータを渡してあげればちゃんとバリデーションできるはずです

ただpostでパラメータは取得できますがcoreにあるHTTPメソッド判定の`Input::method()`ではPUTと判定されるので値を明示的に渡さないとバリデーションしてくれないと思います


結局リクエストする側はPOSTで送信しないといけないし、リクエストヘッダーに値を入れ忘れる可能性もあるのでなんか微妙…

FuelPHPの話というよりHTTPの仕様でごまかした感じです
雑なまとめですが以上です
fusetoolsとは何か

Fuse、ご存知ですか？？

簡単に言うとUXマークアップと呼ばれるXMLベースの記述でアプリが作れちゃうシロモノです。Intel社でグラフィック処理開発を担当したエンジニアがメインになって開発していて、GPU処理に力を入れていることもあり、滑らかなインタラクション実装ができます。iOS/AndroidのUIとカスタマイズUIをコンポーネントとしてサポートしていて、遅延なくリアルタイムで実機画面を確認しながらコードを変更したりデバックできることも主な特徴です。

そして、もうひとつの特徴が、JavaScriptを含めることができること。なので、Webのエンジニアなら、そこまで勉強しなくて簡単にネイティブアプリがつくれちゃうかもしれないです！

今回は簡単にどんなものかご紹介したいと思います！

###ホーム

アプリを立ち上げると、下記の画像のようなダッシュボード画面が表示されます。

![01.png](https://qiita-image-store.s3.amazonaws.com/0/100937/190f2399-0031-d9a9-3d34-bfdaee32e486.png)

エディターとしてはSublime Text3とAtomのプラグインが公式に提供されています。サードパーティとして、VS Codeのプラグインも作られているみたいです。Fuseの推奨はSublimeのようで、Fuseを立ち上げると、Sublime Textのセットアップも行ってくれます。

最初に紹介した**UX Markup**という独自の記述方法のサンプルを掲載します。

```sample.ux
<App>
    <DockPanel Padding="10,10,10,10">
        <ScrollView ClipToBounds="true">
            <StackPanel>
                <Text FontSize="30">Hello, world!</Text>
                <Slider />
                <Button Text="Button" />
                <Switch Alignment="Left" />
            </StackPanel>
        </ScrollView>
    </DockPanel>
</App>
```

ダッシュボードの「Start app preview」をクリックするとプレビューを実行することができます。スマートフォンがUSB接続されていれば実機での確認も可能です。先ほどのコードを実行すると、下記の画像のように表示されます。

![02.png](https://qiita-image-store.s3.amazonaws.com/0/100937/a2dfdc0e-d69e-4b0f-e849-07fc00b0c512.png)

プレビューを実行している間は、コード側に変更があるとリアルタイムでプレビュー側に適用されます。お客さん先に、持って行きながら、その場でコードを変更して、FBを反映することができるので、開発スピードは格段に上がると思います。

######リアルタイムプレビューの様子
[![リアルタイムプレビューの様子](http://img.youtube.com/vi/ra1MkGQ4KV0/0.jpg)](http://www.youtube.com/watch?v=ra1MkGQ4KV0)

クリックするとYoutubeに飛びます。

内部的には実行時に、UX Markupがネイティブコードにコンパイルされます。なので、iOS,Android用にコードを書き分ける必要がなく、当然デバイスの表示や処理はネイティブで行われるので、実行後のアニメーションやインタラクションも滑らかで、とても快適です。

公式サイトにたくさんの[サンプル](https://www.fusetools.com/examples)が掲載されていて、そのコードもダウンロードできるようになっています。まずはそれを見ながら、どんだけ簡単に作れるかを実感していただければと思います。

まだ、バージョンが0.30であり、未実装な部分もありそうですが、現在安定している機能だけでも、十分使えるツールであると感じています。日本ではまだあまり広まっていないようなので、アドベントカレンダーで公式サイトの情報をまとめていければと思います。（簡単な翻訳程度になるかも･･･）

また、[コミュニティ](https://www.fusetools.com/community)として、公式サイトのフォーラムの他、Slackが用意されています！まだまだ発展途上なので、今後のバージョンアップがとても楽しみです！
【JavaScript入門】If文を使って条件分岐する方法

※こちらの記事は、プロスタ編集部が学習者の多いJavaScriptの文法記事を公開することで、皆様の学習にお役に立ちたい意図で投稿しております。
参考サイト：[【JavaScript入門】If文を使って条件分岐する方法](http://programming-study.com/technology/javascript-if/)

#【JavaScript入門】If文を使って条件分岐する方法

##JavaScriptのif文とは？


条件分岐というと難しく聞こえるかもしれないので一つの例を出します。


Aの場合はこの処理をする。
Bの場合はこの処理をする。
それ以外の場合はこの処理をする。

というような形で条件を決めて自分の行いたい命令をプログラミングすることが出来るものです。JavaScriptだけでなく「全てのプログラム言語」共通でif文が存在するということも理解しておきましょう。

##実際にif文を使ってみよう

では簡単な説明を済ませた所で具体的に条件分岐「if文」について詳しく見ていきましょう。JavaScriptでは必ず<script></script>の記述するルールなのでそれも忘れずにしておきましょう。

記述の仕方はこの通りです

if (条件) {
条件が正しければ処理が実行される　※別の言い方で条件が「真であれば」と表現する。
}

```
<script>
var tensuu = 80;
if (tensuu >= 70) {
	document.write(“70点よりも点数が良いのであなたはすごいです！”);
} 
 
</script>
```

If…else 文を使ってみよう

今度は応用のテクニックです。とはいっても慣れれば複雑な処理も簡単に行うことが出来るので慣れておくようにしましょう。

記述の仕方はこの通りです

if (条件) {
条件が正しければ処理が実行される
} else {
それ以外の場合の処理が実行される
}

```
<script>
var tensuu = 80;
if (tensuu >= 70) {
	document.write(“70点よりも点数が良いのであなたはすごいです！”);
} else {
	document.write(“あなたは70点以下なのでもう少し頑張りましょう！”);
}
</script>
```

このように、「else」を使うことでそれ以外の条件も付け加えることが出来ます。
Delphi/C++Builder/RAD StudioのIDE画面のフォントを差し替えて見やすくしてみよう

# WindowsのフォントはMacに比べてイマイチだよねー
と思いませんか？ (はい・yes）

だけど、とりあえずDelphi/C++BuilderのIDE画面については、フォントカスタマイズを行うと、それなりの見た目になります。（自分的には）

# まずはDelphi/C++Builder/RADStudioのIDEのデフォルトの状態を見てみよう
デフォルトの状態はこんなもんです。まあ普通ですねー。可もなく不可もなく。
![image](https://qiita-image-store.s3.amazonaws.com/0/149350/6ce0243a-193d-87bd-5deb-d99b62ba2398.png)

# カスタマイズしてみるとこんな感じ。
これをカスタマイズしてみるとこんな感じです。ずいぶんと見た目の雰囲気が違いますね。
![image](https://qiita-image-store.s3.amazonaws.com/0/149350/70f0b829-6cb5-e490-012b-84106fdc0536.png)

# 設定変更箇所

## IDE の見た目のフォント変更
このフォントは「源ノ角ゴシック」というフォントを使っています。Google と Adobe が共同開発したというフォントであり、無償で利用できます。

GitHubなどで配布されてます。
https://github.com/adobe-fonts/source-han-sans

これをDelphi/C++BuilderのIDEで使用するように、レジストリの設定変更を行います。このレジストリの情報は docwiki.embarcadero.com の以下のページに説明があります。

[IDEビジュアル設定のシステムレジストリ](http://docwiki.embarcadero.com/RADStudio/Berlin/ja/IDE_%E3%83%93%E3%82%B8%E3%83%A5%E3%82%A2%E3%83%AB%E8%A8%AD%E5%AE%9A%E3%81%AE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0_%E3%83%AC%E3%82%B8%E3%82%B9%E3%83%88%E3%83%AA_%E3%82%AD%E3%83%BC)

「源ノ角ゴシック」にはフォントの太さが７種類くらいありますから、好みのものを選んで頂くとよいでしょう。あるいは自分の好みの他のフォントを使うのも当然ありです。

## ソースエディタの使用フォントを Ricty にしてみる

ソースエディタのフォントは、[ツール] => [オプション] から設定変更できます。今回は Ricty を使用しています。
![image](https://qiita-image-store.s3.amazonaws.com/0/149350/1af21d0d-418e-4aed-beb0-965285b42fde.png)

Ricty については、こちらのページをご覧ください。
http://www.rs.tus.ac.jp/yyusa/ricty.html

## ソースエディタの使用フォントを Source Code Pro にしてみる
Ricty ではなく、Source Code Pro を使うと、こんなカンジになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/149350/a31df90f-8a3a-068f-9d62-d4f36d43c9b1.png)

Ricty よりはこっちかなあ。だけど Source Code Pro には和文フォントを含んでいないんですよ。だから本当に使いたいのは、Source Code Pro + 源ノ角ゴシック という合成フォントの Source Han Code なのですね。だけど Delphi/C++Builder の IDE では Source Han Code を選べないという。。。

## ソースコードエディタのフォントで可読性がどのように変わるか？
フォントを選びたい理由は、Oと0、1とlとI みたいな判読しづらい文字を確実に見分けたいからなのです。いくつかのフォントでこれらの文字を比べてみると、フォントによって可読性が全くかわることが分かります。

この表は Excel でフォントサイズ10を指定した場合のもの
![image](https://qiita-image-store.s3.amazonaws.com/0/149350/2cb1ee86-8234-b43a-a617-61ff52c31584.png)

フォントサイズ14だとこんな感じ。
![image](https://qiita-image-store.s3.amazonaws.com/0/149350/7bb9e7a7-ef98-5ca7-5d8e-1090a0e68677.png)

こうして比べると、日本語部分はさておき、見間違えそうな英数字は見た目が全然違いますよね。こういう類の間違いは楽しくないので、一目で区別したいんです。

そんなわけでビジュアルはとても大事です。だから自分にとって使いやすい環境をそろえて Hack しましょう！
ファイルパスの操作


ファイルのパスをつなげるようなときに、もちろんStringでつなぐとかは論外として、、いままでは

```java
File base = new File("/tmp/base");
new File(new File(base, "more1"), "more2");
```	
こんな風にくるんでくるんで、みたいな処理をしていたのが、

```java
Paths.get("/tmp/base","more1","more2").toFile();
```

このように可変長引数を使ってつなげるようになりました。いまどきの言語だと当たり前なんですけど、Javaもキレイになりました。。
jquery smart rollover

よくあるスマートロールオーバーです。
focusにも対応しています。

src：hoge_off.png ←→ hoge_on.png
対象:img:hover / input[type="image"]:hover / a:focus img / input[type="image"]:focus

jquery1.9.1/1.11.1で動作を確認。

```ruby:jquery.smartrollover
(function($) {
  $.fn.smartRollover = function(){
    return this.each(function() {
      var image = $(this);
      var _off = $(this).attr('src');
      var _on = $(this).attr('src').replace(/^(.+)_off(\.[a-z]+)$/,'$1_on$2');
      var on = function() {$(image).attr('src', _on);};
      var off = function() {$(image).attr('src', _off);};

      // image:hover
      $(image).hover(function() {
        $(this).stop();
        on();
      },function() {
        $(this).stop();
        off();
      });

      // a:focus img
      $(image).parent('a').focus(on);
      $(image).parent('a').blur(off);

      // input[type="image"]:focus
      $(image).focus(on);
      $(image).blur(off);
    });
  };
})(jQuery);

jQuery(function($) {
  $('[src*="_off."]').smartRollover();
});
```
zabbix agentをwindowsにサクッと入れるshell メモ

# zabbix3.2-agent-Setup
最新確認
- http://www.zabbix.com/jp/download.php

1. ここから対象のDLを確認
    1. Windows全般
        1. http://www.zabbix.com/downloads/3.2.0/zabbix_agents_3.2.0.win.zip


# このshellの手順
1. \c直下に/zabbix-agent ディレクトリを作る
1. 作成したディレクトリに、64bitのbinを配置する。
1. 同じ場所にzabbix_agentd.confを配置し、環境に合わせて内容を編集する。
1. 管理者権限でコマンドプロンプトを起動する。

## 以下powershellで上記手順の実行
IPにとか適宜書換

```powershell
mkdir C:\zabbix_agent
invoke-webrequest -uri http://www.zabbix.com/downloads/3.2.0/zabbix_agents_3.2.0.win.zip -outfile C:\zabbix_agent\zabbix_agents_3.2.0.win.zip

# ZIP 解凍
# Powershell V5以降なら以下でできるはずなのだが・・
#expand-archive -path C:\zabbix_agent\zabbix_agents_3.2.0.win.zip -destinationpath C:\zabbix_agent\

$file = "C:\zabbix_agent\zabbix_agents_3.2.0.win.zip"
$shell = New-Object -ComObject shell.application
$zip = $shell.NameSpace($file)
$dest =  $shell.NameSpace((Split-Path $file -Parent))
$dest.CopyHere($zip.Items())

# exeとconf配置
Copy-Item C:\zabbix_agent\bin\win64\*.exe C:\zabbix_agent\
Copy-Item C:\zabbix_agent\conf\zabbix_agentd.win.conf C:\zabbix_agent\
Rename-Item C:\zabbix_agent\zabbix_agentd.win.conf  zabbix_agentd.conf 

Remove-Item C:\zabbix_agent\zabbix_agents_3.2.0.win.zip


# Fileの書換
$conf= Get-Content C:\zabbix_agent\zabbix_agentd.conf -Encoding UTF8
$conf= $conf.Replace("LogFile=c:\zabbix_agentd.log", "LogFile=c:\zabbix_agent\zabbix_agentd.log")
$conf= $conf.Replace("Server=127.0.0.1", "Server=192.168.X.XXX")
$conf= $conf.Replace("ServerActive=127.0.0.1", "ServerActive=192.168.X.XXX:10051")
$conf= $conf.Replace("Hostname=Windows host", "Hostname=${Env:COMPUTERNAME}")
#$conf= $conf.Replace("# HostnameItem=system.hostname", "HostnameItem=system.hostname")
$conf= $conf.Replace("# HostMetadata=", "HostMetadata=")


#$conf= $conf.Replace("", "")
#$conf | Out-file C:\zabbix_agent\zabbix_agentd.conf -Encoding UTF8 これだとUTFがうまくいかね。
[IO.File]::WriteAllLines("C:\zabbix_agent\zabbix_agentd.conf", $conf)

# Agent Install サービス登録 作成したディレクトリに移動し、以下のコマンドを入力する。
cd  C:\zabbix_agent
.\zabbix_agentd.exe -i -c C:\zabbix_agent\zabbix_agentd.conf

# サービス開始
.\zabbix_agentd.exe -s -c zabbix_agentd.conf

# サービス削除
# .\zabbix_agentd.exe -d
```


### firewall開ける
IPにとか適宜書換

```powershell
if (-not(Get-NetFirewallRule | where Name -eq "Zabbix Agent"))
{
    New-NetFirewallRule `
        -Name "Zabbix Agent" `
        -DisplayName "Zabbix Agent" `
        -Description "for Zabbix Agent" `
        -Group "Zabbix" `
        -Enabled True `
        -Profile Any `
        -Direction Inbound `
        -Action Allow `
        -EdgeTraversalPolicy Block `
        -LooseSourceMapping $False `
        -LocalOnlyMapping $False `
        -OverrideBlockRules $False `
        -Program Any `
        -LocalAddress Any `
        -RemoteAddress 192.168.16.0/24 `
        -Protocol TCP `
        -LocalPort 10050 `
        -RemotePort Any `
        -LocalUser Any `
        -RemoteUser Any
    
}
else
{
		echo "Windows PowerShell Remoting port TCP 10050 was alredy opend. Show Rule"
		Get-NetFirewallPortFilter -Protocol TCP | where Localport -eq 10050
}
```

powershell痒い所に微妙に手が届かない・・
Uninstallとか超めんどくさそう。