OmniAICreator/Qiita-1.07M huggingface dataset:
関数型プログラミングの世界からやってきた Pipeline Operator

# Pipeline Operator

まずはこちらを

https://github.com/tc39/proposal-pipeline-operator

Elixirとかで見かける `|>` です。
現在はStage 1 Draftで、babelでもう導入可能です。

https://babeljs.io/docs/en/babel-plugin-proposal-pipeline-operator

---

## Usage

https://github.com/kashira2339/pipeline-operator-example

```js
const hello = str => str + "hello";

const space = str => str + " ";

const world = str => str + "world";

const exclamationAsync = async str =>
  new Promise((resolve, reject) => setTimeout(() => resolve(str + "!"), 300));

const toUppercase = str => str.toUpperCase();

const str = "";

const msg1 = world(space(hello(str)));
const msg2 = str |> hello |> space |> world;
const msg3 = str |> hello |> space |> world |> exclamationAsync |> await |> toUppercase;

console.log("msg1:", msg1); // => msg1: hello world
console.log("msg2:", msg2); // => msg2: hello world
console.log("msg3:", msg3); // => msg3: HELLO WORLD!
// msg3のawaitは2018/12/14現在未実装
```

挙動は単純で、 **「``x |> f``とあるとき値xを関数fの第一引数として渡す」**となります。

## Example Use Cases

リポジトリのWikiにもいくつか載っており、それぞれが有用です。
https://github.com/tc39/proposal-pipeline-operator/wiki/Example-Use-Cases

### validation

独立したバリデーション用の関数を組み合わせる

```js
const required = () => value => {
  if (!value) throw Error('required');
  return value;
}
const format = regex => value => {
  if (!regex.test(value) ) throw Error('invalid format');
  return value;
}

value
  |> required()
  |> format(/https?:\/\//)
  |> console.log
```

### React + Redux + react-redux + redux-form + react-router
また、react-reduxを採用したプロジェクトで散見される以下のようなコードも

```jsx
const Component = () => {
  return ...
}

function mapStateToProps(state) {
  return {
    ...
  }
}

function mapDispatchToProps(dispatch) {
  return {
    ...
  }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps)(reduxForm({ ... })(Component)))
```

export部分で関数のネストがみられるので、pipeline operatorで以下のように改善できる

```jsx
// before
// export default withRouter(connect(mapStateToProps, mapDispatchToProps)(reduxForm({ ... })(Component)))

export default Component
    |> reduxForm({ ... })
    |> connect(mapStateToProps, mapDispatchToProps)
    |> withRouter
```

---

### まとめ

pipeline operatorが使えるようになると、
関数を連鎖させるときの可読性が従来と比べて大きく向上するので、
それぞれの関数をコンポーザブルに保ち、用途に応じて合成していくことで
機能を実現していく設計の有用性がより増してきます。

昨今のJavaScriptや周辺ライブラリを追っていると、
[Array.prototype.flat,flatMap](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/flat)であったり
[Partial Application Syntax](https://github.com/tc39/proposal-partial-application)であったり
[React hooks](https://reactjs.org/docs/hooks-intro.html)であったり
関数型言語にみられるような特徴を持たせるような提案がボチボチみられます。
開発環境やビジネス要求の上でも変化の激しいフロントエンド開発において
関数型プログラミングの思想を取り入れることで参照透過性を高め、
テストのしやすさ=変化への強さを担保していきたいといった時代の流れなのでしょうか。

そうなってくると、
[elm](https://elm-lang.org/)のようなプログラミング言語の採用率が上がって行ったりするのか、
はたまた、関数型プログラミングにハードルを感じるプログラマが増え、
より簡単に素早くアプリケーションの作成ができる[Nuxt](https://ja.nuxtjs.org)がユーザーを増やしていくのか、
いずれにせよ興味深いです。
macOS MojaveでLiip PHPのインストール

# はじめに

php.netの[Mac OS X へのインストール](http://php.net/manual/ja/install.macosx.php) > [バンドルされている PHP の使用法](http://php.net/manual/ja/install.macosx.bundled.php)でも紹介されている[LiipのPHP](https://php-osx.liip.ch/)は、[macOS Mojave](https://www.apple.com/jp/macos/mojave/)ではそれまでのmacOSと違って、OSX標準のapacheにインストールできなくなりました。

Installing on Mojave
https://github.com/liip/php-osx/issues/249

これはMojaveでOSXのシステム整合性保護（System Integrity Protection: SIP）がより厳しくなったためですが、これを現状でうまく解決できる方法は現在見つかっていません。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="en" dir="ltr">Don’t upgrade to macOS 10.14 Mojave yet, if you rely on our php integration into Apple’s apache!<br><br>Here’s the bugreport: <a href="https://t.co/3FheyYS9cd">https://t.co/3FheyYS9cd</a> - Don’t have a solution yet :(</p>&mdash; php-osx.liip.ch (@php_osx) <a href="https://twitter.com/php_osx/status/1044557184267415552?ref_src=twsrc%5Etfw">2018年9月25日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これを回避する方法は現在２つあります。１つはSIPを無効にする方法、１つは標準のapacheの使用を諦めbrewのapacheを使う方法です。

## SIPを無効に

 1 macOSでコマンド+Rを押しながらリカバリーモードにboot
 2 ユーティリティからターミナルアプリを選択
 3 `csrutil disable;` と入力して再起動

 * https://support.intego.com/hc/ja/articles/115003523252-%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E6%95%B4%E5%90%88%E6%80%A7%E4%BF%9D%E8%AD%B7-System-Integrity-Protection-SIP-%E3%81%AE%E7%84%A1%E5%8A%B9%E5%8C%96

 * https://github.com/liip/php-osx/issues/249#issuecomment-433952554

## brewでapacheインストール

macOSのapacheを停止

```
sudo apachectl stop`
sudo launchctl unload /System/Library/LaunchDaemons/org.apache.httpd.plist 2>/dev/null`
```

brewでapacheをインストール

```
brew install httpd
```

インストール確認

```
which apachectl
```

apacheスタート

```
sudo apachectl -k start 
```

macOS起動時に自動起動

```
sudo brew services start httpd
```

## PHPをインストール

上記のどちらかを実行した後に https://php-osx.liip.ch を参照してPHPをインストールします。

```
curl -s https://php-osx.liip.ch/install.sh | bash -s 7.2
```
とすると

```
[WARNING]
Detected macOS Mojave 10.14. There are serious issues with it, due to the original apache not loading
foreign libraries anymore. PHP within apache will most certainly not work anymore if you proceed!
The cli version still will.
See this issue at https://github.com/liip/php-osx/issues/249 for details and discussion
****
Restart this script with
 curl -s https://php-osx.liip.ch/install.sh | bash -s force 7.2
to really install it
```

という警告が出るので示されてるように`force`で再度実行します

```
curl -s https://php-osx.liip.ch/install.sh | bash -s force 7.2
```

確認

```
php -v

PHP 7.2.9 (cli) (built: Aug 21 2018 07:42:00) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.9, Copyright (c) 1999-2018, by Zend Technologies
```
NTFS のスパースとか圧縮とかと、実際のディスクサイズとか

## 結論

なんでもかんでもzip圧縮すればよいというわけではないということ。

スパースファイルなら、そのままの方がディスクを食わない場合もある。

## きっかけ

[NTFS圧縮のススメ](https://qiita.com/tomoki0sanaki/items/e5da146512e34dc65df8)という記事を書いてみて、ふと仮想化ソフトウェアのディスクイメージって、スパースなんじゃないか?

となると、zip圧縮した方がディスク食うんではないか?

とか疑問を感じたので、実際に試してみた。

## 準備

まずはツールを作った(作らなくてもどっかに転がっていそうだけど、作れるものは作ってみたいんですよ～)。

[ファイルサイズを出力するだけのテストプログラム](http://rocketeer.dip.jp/sanaki/free/free153.htm)

シンプルに Win32API の [GetFileSize()](https://msdn.microsoft.com/ja-jp/library/Cc429319.aspx) と [GetCompressedFileSize()](https://msdn.microsoft.com/ja-jp/library/cc429287.aspx) を表示するだけ。

スパースファイルの作成は・・・作れなかったまで、fsutilコマンドで行った。

## 実験結果

### NTFS圧縮

まずはシンプルにNTFS圧縮の場合。
4MBぐらいのbitmapファイルを対象にする。
![02.jpg](https://qiita-image-store.s3.amazonaws.com/0/182822/d02effa5-1541-0315-0a9a-a05eb8ead8ca.jpeg)

NTFS圧縮されたファイルは、既定の設定だと、ファイル名は青くなる

![03.jpg](https://qiita-image-store.s3.amazonaws.com/0/182822/1b17ed79-b512-4054-5548-97c560c5c221.jpeg)

まぁ、こんな感じで、圧縮されてディスクに格納されるのが、NTFS圧縮。

### スパースファイル

見よう見まねでスパースファイルを作ってみる

![04.jpg](https://qiita-image-store.s3.amazonaws.com/0/182822/e86f3ba4-f2a8-e5c7-4c13-992ed2d250a9.jpeg)

最初のスパース前は、ファイルサイズと同じだけディスクを食っていたけど、スパースにしたら、ゼロになった。

### スパースファイルをzip圧縮してみる

次は、そのスパースファイルをエクスプローラのzip圧縮をしてみる

![05.jpg](https://qiita-image-store.s3.amazonaws.com/0/182822/3af957d7-8dd6-db4c-b0e1-7f3134288906.jpeg)

まぁ、当たり前だな。スパースでディスクを節約していたのに、圧縮処理(データのランダム化の一種)によって、スパースの効果がなくなっているって事だな。

つまり、スパースファイルをzip圧縮すると、ディスクの節約になるかもしれないし、ディスクの節約どころか無駄使いになるかもしれない

### スパースファイルをNTFS圧縮してみる

![06.jpg](https://qiita-image-store.s3.amazonaws.com/0/182822/0c2402f4-f960-8677-3aeb-4a7cad5c4bf4.jpeg)

NTFS圧縮サイコー!!
スパースファイルをNTFS圧縮しても、スパースの効果は失われないって事だな。

### 代替ストリームと GetCompressedFileSize() の関係

ふと、気になったので・・・・

代替ストリーム付のファイルを用意してみた。
![07.jpg](https://qiita-image-store.s3.amazonaws.com/0/182822/9e5b9bf4-6038-c62f-6baf-6c896b1c1c5f.jpeg)

あ、こんなツールも作っていたよ。[ZoneID を復活するスクリプト](http://rocketeer.dip.jp/sanaki/free/free141.htm)

とりあえず、代替ストリーム活用の代表がこれ(ゾーン情報)だと思う。

![08.jpg](https://qiita-image-store.s3.amazonaws.com/0/182822/590dd4c3-7124-ba04-4ea2-600bd5296808.jpeg)

関係ないようだ・・・GetFileSize() と GetCompressedFileSize() の違いで既定以外の代替ストリームがあるとかないとかは分からないという事だな。
ruby 配列の初歩

# 配列の初歩
最近ruby入門の本を読み出したので
メモがわりに細かいことを書いていこうと思います。
今回のテーマは配列の初歩的なことを書いていきます。

## 配列の基本操作(追加、変更、削除)
### 配列の作成
まずは配列の作成方法から。

```ruby
a = [1,2,3]
b = []
c = Array.new
d = [
  1,
  2,
  3
]
e = [
  1,
  2,
  3,
]
f = ['aaa','bbb','ccc']

g = [1, 2, 'aaa', 'bbb', [1, 2, 3]]
```

dのように配列は改行して書けたりもします。
また、eのように最後の要素にカンマをつけてもエラーにはなりません。
fのように数値以外も入れられ、gのように数値と文字列を混合させたり、
配列を入れたりもできます。

こんな感じです。
次はこの配列に様々な操作をしていきます。

### 配列の要素取得方法
要素を取得するときは以下のように変数名[添字(何番目か)]で取得できます。

```ruby
a[0] #=> 1
f[1] #=> 'bbb'
```

### 要素の追加,変更
上で作成した配列に対して要素を追加していきたいと思います。

```ruby
a[0] = 100 #=> 存在する添字に対して数値を代入するとその数値に変わります。
a #=> [100, 2, 3]
```

```ruby
a[4] = 200
a #=> [100, 2, 3, nil, 200]
```
以上のように配列の要素数より大きい添字を指定した場合、指定した添字には指定した値が入り、
その間にない添字の部分はnilが入る。
なのでa[3]のにはnilが入る。

また要素の最後に要素を追加したい時などは
以下のようにすると要素の最後に追加されます。

```ruby
a << 300
a #=> [100, 2, 3, nil, 200, 300]
```

### 要素の削除
次は要素の削除です。
要素の削除にはdelete_atメソッドを使用します。

```ruby
a.delete_at(0)
a #=> [2, 3, nil, 200, 300]
```
これはdelete_atで0番目の要素を削除しています。

## 最後に
以上で終わりです。
特に対したことはないですがたまに役立つことがあるので
今回はメモがわりに残しました。
PHPUnitでassert()がコケることをテストする

# やりたいこと
`PHP7.1`、`PHPUnit 7.2`で

```PHP
class Foo {
  public static function bar(string $a){
    assert($a === "po");
    echo $a;
  }
}
```
を

```PHP
class FooTest extends TestCase{
  /**
   * @test
   */
  public function barの引数がおかしい(){
    Foo::bar("hoge");
  }
}
```
みたいにテストしたい

## 解決策

```PHP
class FooTest extends TestCase{
  protected function setUp(){
    assert_options(ASSERT_ACTIVE,true);
    assert_options(ASSERT_EXCEPTION,false);
    parent::setUp();
  }

  /**
   * @expectedException \PHPUnit\Framework\Error\Warning
   * @test
   */
  public function barの引数がおかしい(){
    Foo::bar("hoge");
  }
}
```

## 解説
`assert()`は、`zend.assertions`が1かつ`assert.exception`が0のとき、`Fatal error`で死なずに`Warning`を出します。
[PHPマニュアル](http://php.net/manual/ja/function.assert.php#function.assert.expectations)にもあるように、本当は`php.ini`でこれを制御します。しかし、たぶん本番環境では`zend.assertions`は0だし開発環境では`assert.exception`は1なので、テストの時だけこれを変更するために**非推奨**の`assert_options()`を使います。

`PHPUnit`では、`Fatal`以外のエラーを例外に変換してくれるので、`@expectedException`に`Warning`を書けば`assert()`が働いていることを確認できます。

### おわりに
`assert()`自体がテストなのに`PHPUnit`でそれをテストするの、本末転倒感がある。
Highchartsでグラフの右下にデフォルトで表示されているクレジット「Highcharts.com」の削除・変更方法

# はじめに
データのビジュアライズにHighchartsを使っています。
Highchartsの公式サイトはこちら
[Interactive JavaScript charts for your webpage | Highcharts](https://www.highcharts.com/)

Highchartsは商用利用だと有償になりますが、簡単に見栄えの良いグラフが作れるので有償ならば一択な感じです。
どのようなグラフが作れるかはデモサイトが参考になります。
[Highcharts demos | Highcharts](https://www.highcharts.com/demo/)

今回、グラフの右下にデフォルトで表示されているクレジット「Highcharts.com」の削除・変更方法を説明します。
![図.png](https://qiita-image-store.s3.amazonaws.com/0/270785/aa9ed814-afe4-017e-e0cd-e452c5c5b8cc.png)

# クレジットの削除方法
チャート生成時のオプションに以下のように設定するだけです。

```javascript:
credits: {
    enabled: false
},
```

# クレジットの変更方法（リンク有り）
チャート生成時のオプションに以下のように設定します。
リンク先も忘れずに設定します。

```javascript:
credits: {
    text: '© EXAMPLE, Inc.',
    href: 'https://www.example.com'
},
```

# クレジットの変更方法（リンク無し）
チャート生成時のオプションに以下のように設定します。
リンク先を設定しない場合はstyleでcursorも無効にしておきます。

```javascript:
credits: {
    text: '© EXAMPLE, Inc.',
    href: null,
    style: {"cursor": "default", "color": "#999999", "fontSize": "10px"}
},
```

# おわりに
データのビジュアライズには主にHighchartsとChart.js（たまにD3.js）を使っています。
豊富なオプションやサンプルがある点でChart.jsも優れたライブラリですが
商用利用は有償だけあって、Highchartsの方が豊富さは一歩抜き出ている気がします。
小さなことだったりしますが、躓いたところなどHighcharts関連も今後少しずつアップしていこうと思っています。
PythonのMatplotlib のpyplot.histを使ってヒストグラムを2つ書いてみた

1つの図の中に2つのヒストグラムを書いたのでまとめ

#環境

- Windows10
- Anaconda3-5.2.0
- Python 3.6.5
- JupyterNotebook

#データセットの一部
###2018.csv
|順位|チーム|試合|打率|打点|平均|安打|
|:-----------|:------------|:------------|:------------|:------------|:------------|:------------|
|1|レッドソックス|162|0.268|876|5.41|1509|
|2|カブス|162|0.259|760|4.69|1450|
|3|インディアンズ|162|0.259|818|5.05|1448|
###2013.csv
|順位|チーム|試合|打率|打点|平均|安打|
|:-----------|:------------|:------------|:------------|:------------|:------------|:------------|
|1|タイガース|162|0.283|796|4.91|1625|
|2|レッドソックス|162|0.277|853|5.27|1566|
|3|ロッキーズ|162|0.27|706|4.36|1511|

用いたデータセットはそれぞれ2018年、2013年のMLBのチーム打撃成績です。実際は30チーム分のデータセットがあります。

#必要なライブラリのインポート

```python

import pandas as pd #pandasのimport
import matplotlib.pyplot as plt #matplotlibのimport
```
#csvの取り込み
それぞれの年のcsvを取り込みます

```python

m_18 = pd.read_csv("2018.csv") #pandasを使って2018.csvを取り込む（上記のデータセット）
m_13 = pd.read_csv("2013.csv") #pandasを使って2013.csvを取り込む（上記のデータセット）
```
#ヒストグラムを作成
今回はそれぞれの年の安打をヒストグラムにしたいと思います。

```python
plt.hist(m_18["安打"]) #2018年の安打
plt.hist(m_13["安打"]) #2013年の安打
```

###実行結果
![hist2.png](https://qiita-image-store.s3.amazonaws.com/0/326771/b292d1ca-044b-424e-68b0-0ca9c174ecb9.png)

うん。青の部分が全く見えなくてすごくわかりにくい。

#ヒストグラムの色を透明にする
すごくわかりにくいので、ヒストグラムを少し透明にします。
透明にするには、histでalphaを指定します。

```python
plt.hist(m_18["安打"], alpha=0.5)
plt.hist(m_13["安打"], alpha=0.5)
```
###実行結果
![hist3.png](https://qiita-image-store.s3.amazonaws.com/0/326771/fe03cbce-e636-bb31-80d3-7dfa96a16257.png)

さっきよりはましかなといった感じ。

#補足
ちなみに凡例がないので、付けるとしたらこんな感じで。

```python

plt.hist(m_18["安打"], alpha=0.5, label=2018)
plt.hist(m_13["安打"], alpha=0.5, label=2013)
plt.legend()
```
###実行結果
![hist4.png](https://qiita-image-store.s3.amazonaws.com/0/326771/f0d8f867-dac7-ad8e-0665-82ccb798b752.png)
laradock + PhpStormでPHPUnitを動かす

## はじめに
laradock での開発環境構築は[こちら](https://qiita.com/m03_89er/items/06f1344f915e3911eed1)。

## PHPStormでPHPUnitを動かす設定

### 1. CLI Interpreterの設定

- `Preference > Languages & Frameworks > PHP`を選択。
- `CLI InterPreter`の右端の`...`をクリック。

<img width="971" alt="スクリーンショット 2018-12-17 15.21.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/c9d76419-e463-6ceb-d84e-d9821701856e.png">

- `左上の+`をクリック。
- `From Docker, ...`を選択して`OK`をクリック。

<img width="383" alt="スクリーンショット 2018-12-17 15.38.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/087dae1f-2ca3-6e65-6102-482ba34a3cd7.png">

- `Docker Compose`のラジオボタンを選択。
- `Server : New`ボタンをクリック。

<img width="618" alt="スクリーンショット 2018-12-17 15.47.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/6cfa4eaf-fbed-10df-0947-ea33b9a2feb3.png">

- `Name`に適当な名前を入力。
- `Connect to Docker...`のラジオボックスから`Docker for Mac`を選択して`OK`をクリック。

<img width="454" alt="スクリーンショット 2018-12-17 15.21.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/a46c9b63-8901-ab57-2ecc-d32429cccef0.png">

- `Configuration File(s):`横のフォルダマークをクリック
- `Docker Configuration Files`を追加。下部`+`をクリックし、`laradock`内の`docker-compose.yml`を選択。

<img width="651" alt="スクリーンショット 2018-12-17 15.51.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/bc0d9daa-9895-2b25-c8c4-f946b685cd80.png">

- `Service`php-fpmを選択

<img width="619" alt="スクリーンショット 2018-12-17 16.02.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/9aafc31c-b0d1-c74d-d649-5dc25d2005d4.png">


- docker-compose.ymlが読み込まれ、設定に反映されます。

<img width="851" alt="スクリーンショット 2018-12-17 16.04.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/6c763a5a-dede-2173-b8c7-6252d42194dd.png">

### 2 PHPUnitの設定

- `Preference > Languages & Frameworks > Test Frameworks`を選択。
- `+`をクリックして、`PHPUnit by Remote Interpreter`を選択。

<img width="402" alt="スクリーンショット 2018-12-17 16.13.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/faa49741-4707-fd46-cba8-42a15c9d64d7.png">

- プルダウンから、先ほど設定した`php-fpm`を選択し、`OK`をクリック。

<img width="472" alt="スクリーンショット 2018-12-17 15.26.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/6092ea76-5713-db33-442e-4389e5e9a145.png">

- `Use Composer autoloader`を選択。
- `Path to Script`に、`vendor/autoload.php`のパスを設定(リモートパス)。
- `Default configuration file`に`phpunit.xml`のパスを設定(こちらもリモートパス)

<img width="770" alt="スクリーンショット 2018-12-17 15.27.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/91edc628-eb06-1b1f-64a2-814415a803fe.png">

### 3. パスマッピングの設定

- `Preference > languages & Frameworks > PHP`の`Path mappings`のフォルダマークをクリック。
- `Local Path`にプロジェクトルート、Remote PathにDocker内のプロジェクトルートを設定し、`OK`をクリック。

<img width="1110" alt="スクリーンショット 2018-12-17 16.26.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/92407/1d081104-04a8-3bc5-71d2-4524a6848c12.png">

### 4. テスト設定

- `メニュー > RUN > Edit Configurations`を選択。
- `Name`に適当な名前、`Defined in the configuration file`を選択。

### 5. テスト実行
- `メニュー > RUN > RUN...` もしくは `control + R`でテスト実行。
経路探索　PrologでPascalの例題を解く

![ArcSoft_画像227.PNG](https://qiita-image-store.s3.amazonaws.com/0/33927/74d9c21c-eede-6128-145d-2ea189791f5e.png)

#はじめに
Pascalの本にあった経路探索の問題を解きました。Prologにおける典型的な応用例です。

#問題
図のような道路網があったときに、１から６へ、同じ点を2度以上通らずに行くような道筋をすべて求めよ、という問題です。

![ArcSoft_画像228.PNG](https://qiita-image-store.s3.amazonaws.com/0/33927/6a948f30-eee3-ffe7-b713-facfea4b7988.png)


#PascalとPrologの対比
Pascalの回答例では隣接行列を用いていました。隣接行列とは図のようなもので、道のつながり具合を示したものです。

![ArcSoft_画像229.PNG](https://qiita-image-store.s3.amazonaws.com/0/33927/af9c172c-7741-11b3-9d59-a001b87f16fa.png)


Pascalの場合には、この隣接行列によるのが一般的だろうと思います。Prologの場合には述語で道路を表すことができます。

```

root(1,2).

```


無向グラフのようなものです。２から１へも移動できます。1,2を逆にして判定すれば簡単ですね。

#コード
ということで、Prologで書くとあっさりと書けます。下記の通りです。

```prolog

root(1,2).
root(1,3).
root(2,3).
root(2,4).
root(3,4).
root(3,5).
root(4,6).
root(4,5).
root(5,6).

run :- solve(1,[1]),fail.

solve(6,R) :- reverse(R,R1),write(R1),nl.
solve(N,R) :-
  root(N,O),
  \+(member(O,R)),
  solve(O,[O|R]).
solve(N,R) :-
  root(O,N),
  \+(member(O,R)),
  solve(O,[O|R]).


```


#実行
実行すると次のようになります。

```prolog

| ?- ['keiro.pl'].
yes
| ?- run.
[1,2,3,4,6]
[1,2,3,4,5,6]
[1,2,3,5,6]
[1,2,3,5,4,6]
[1,2,4,6]
[1,2,4,5,6]
[1,2,4,3,5,6]
[1,3,4,6]
[1,3,4,5,6]
[1,3,5,6]
[1,3,5,4,6]
[1,3,2,4,6]
[1,3,2,4,5,6]
no

```


#Prologの特長
バックトラック、ユニフィケーションがPrologの特長です。これらが活かせる問題のときには無類の強さを発揮します。

#終わりに
しばらくPrologを離れることになりました。Elixirに集中します。LispもPrologも素晴らしいプログラミング言語です。しかし、それはラテン語のような存在です。計算機科学を習得するにはいずれも必須だと私は考えています。一方、現代におけるモダンなプログラミング言語で現実のプログラミングに挑戦してみたいと思っています。Lisp・Prologの習得で学んだことを活かしてみたいと思っています。今までお読みいただきありがとうございました。


丹下のおっさん、燃え尽きたぜ…真っ白にな…
Androidで日時を端末の設定言語で標準っぽくフォーマットしたい

# どうしたい？

年/月/日は国毎に表示する順序が異なる。 2018年12月17日を端末の設定言語ごとに下記のように表示したい。

|言語|表示|
|----|----|
|英語(アメリカ)|12/17/18|
|英語(イギリス)|17/12/2018|
|日本|2018/12/17|

# どうやる？

JSR310 を利用すると簡単に実装できます。 Android では AndroidThreeTen を。

```kotlin

LocalDateTime.now().format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))
```

`FormatStyle.SHORT` はフォーマットのスタイルを定義してあります。 `FULL`, `LONG`, `MEDIUM`, `SHORT` などがあり、お好みのフォーマットを当ててください。

2017年12月17日をそれぞれのフォーマットに当てると下記のような結果になります。

**FormatStyle.SHORT**

|言語|表示|
|----|----|
|English(United Kingdom) |17/12/2018|
|English(United States) | 12/17/18|
|Japanese                |2018/12/17|

**FormatStyle.MEDIUM**

|言語|表示|
|----|----|
|English(United Kingdom) |17 Dec 2018|
|English(United States)  |Dec 17, 2018|
|Japanese                |2018/12/17|

**FormatStyle.LONG**

|言語|表示|
|----|----|
|English(United Kingdom) |17 December 2018|
|English(United States)  |December 17, 2018|
|Japanese                |2018年12月17日|

**FormatStyle.FULL**

|言語|表示|
|----|----|
|English(United Kingdom)| Monday, 17 December 2018|
|English(United States) | Monday, December 17, 2018|
|Japanese                |2018年12月17日月曜日|





上の例では日付だけをフォーマットしていますが、日付日時を同時に行いたい場合は　`ofLocalizedDateTime(FormatStyle)` を利用することができます。

# おまけ

上で適用したフォーマットから milliseconds へ変更する。つまり逆のこと。結構面倒で３ステップくらいあります。

1) text -> LocalDate
2) LocalDate -> ZonedDateTime 
3) ZonedDateTime -> milliseconds

```kotlin
// 注意: FormatStyle は^で変更したものと同じものを使用してください。
val localDate = LocalDate.parse(formattedText, DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))

val zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault())

val milliseconds = zonedDateTime.toInstant().toEpochMilli()
```

まとめると下記です。

```kotlin
// まとめ
        LocalDate.parse(formattedText, formatter)
                .atStartOfDay(ZoneId.systemDefault())
                .toInstant()
                .toEpochMilli()
```


# その他

簡単な AndroidThreeTen の使い方集です。

https://techblog.timers-inc.com/entry/2016/06/27/121939
PhpStormからLaradockのテストを実行する

### 経緯
PHPカンファレンス2018で[LaravelでTDDを体験しよう #phpcon2018](https://speakerdeck.com/omoon/laraveldetddwoti-yan-siyou-number-phpcon2018)がとても良くて、LaravelでTDDをしたいと思った。
（特にPhpStormから`Command + r`で都度テスト実行をしたいと思った。）

TDDはリズムが大切というお話で、ライブコーディングでTDDのリズムを体感できる大変有用な内容だったが、
Homestead前提だったということもあり、実際にLaradock環境で0からやろうとすると設定で少しハマった。

備忘も兼ねてPhpStorm+Laradockでテスト実行する手順を記載した。

### 前提
[PHPフレームワーク Laravel Webアプリケーション開発](https://www.amazon.co.jp/dp/4802611846)に記載された手順でLaradock環境が構築されていること。

Laravel：5.5.x
PhpStorm：2018.2.5
### 手順

#### ComposerでPHPUnitを最新にする
ターミナルでプロジェクトフォルダに移動し、`php vendor/bin/phpunit`を実行する。
上記でLaravelにデフォルトで存在するテストが動くか確認する。動けば問題なし。

もし動かない場合は、以下の手順を行う。
プロジェクトフォルダで`rm -rf vendor/bin`実行後に、`composer install`を実行。
これで再度`php vendor/bin/phpunit`を行えば動作するはず。

### Dockerを設定する
ここからはPhpStormでテスト実行するための作業。

`Command+,`でPreferencesを開き、「Build, Execution, Development」→「Docker」で「+」を選択する。
自分はDocker for Macを利用しているのでそちらを選択すると「Connection successful」と表示された。
「Name」は適当。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140303/4db1083e-53c6-1938-9fc3-5cb599d90865.png)

###　interpreterを指定する
引き続きPreferencesから「Languages & Frameworks」→「PHP」の「CLI Interpreter」の右にある「・・・」を選択する。
※画像は設定後の画像のため、少し異なるかも。
![Untitled1.png](https://qiita-image-store.s3.amazonaws.com/0/140303/7ef757b3-6a15-e2de-0287-3d8374587120.png)

以下の画面が開いたら設定をしていく。
「Name」は適当。
「Remote」で「Docker」を指定。
「Image Name」を自動で検索してくれるので「laradock_workspace」を選択する。
（laradock_php-fpmでも動作するようなのだけど、どちらがいいのだろう？）

「PHP Executable」右端の更新ボタンを押すと、PHPとXdebugを自動で見つけてくれる。
バージョンが表示されればOK。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/140303/cef9b8df-3ce8-4c8b-2900-a3a5a416244b.png)

次が重要（というよりハマった）で、このままだと「Path Mapping」に<Project root>→/optとなっており、次のPHPUnit設定で問題が発生する。
ここで「Docker Container」を「-v /Users/xxx/xxx/docker/プロジェクト名:/var/www/プロジェクト名」に指定する。
ホスト側のプロジェクトパスとコンテナ側のプロジェクトパスを合わせる作業となる。

![Untitled1.png](https://qiita-image-store.s3.amazonaws.com/0/140303/7ef757b3-6a15-e2de-0287-3d8374587120.png)

### PHPUnitを指定する
引き続きPreferencesから「Languages & Frameworks」→「PHP」の「Test Frameworks」で「+」から「PHPUnit By Remote Interpreter」を選択する。
「Use Composer autoloader」を選択し、「Path to script」にworkspaceコンテナのフルパスでautoload.phpで指定する。
PHPUnit versionが表示されればOK。（ここでエラーが出る場合は、interpreterの指定がうまくいっていない可能性が高い。）
![Untitled3.png](https://qiita-image-store.s3.amazonaws.com/0/140303/395a05a0-25b4-0771-7a0a-db85cef92e34.png)


###Test実行に設定する
最後に「Run/Debug Configurations」にて「Defined in the configuration file」を選択し、
ホスト側のプロジェクトにあるphpunit.xmlを指定する。
![Untitled4.png](https://qiita-image-store.s3.amazonaws.com/0/140303/d4d28fa1-9a01-a569-fbee-18c8cc9ef157.png)

これでPhpStormで`Command + r`でテストが実行できるようになる。
[Swift] ARSCNViewからの画像の撮り方

備忘録

```swift
let cuptureImage: cvPixelBuffer = sceneView.session.currentFrame!.capturedImage
```

でとる手もあるが、これは回転情報が失われるため、90度回転してしまう場合がある
回転情報を保持したまま処理したいので、UIImageのまま取ってこれる方がいい

```swift
let uiImage: UIImage = sceneView.snapshot()
```
【メモ】エクセルのグラフ軸範囲一括で変更

For Eachで各チャートオブジェクトのX軸範囲を変更する。

```vb

Sub アクティブシート上のグラフ軸範囲変更()
Dim cht As ChartObject

For Each cht In ActiveSheet.ChartObjects
    With cht.Chart.Axes(xlCategory)
    .MinimumScale = 43101 '2018/1/1
    .MaximumScale = 43404 '2018/10/31
    End With
Next cht

End Sub
```

グラフが2列並んでいて、左側に並べてある（左位置8.25）ものだけ縦軸変更

```vb
Sub 左のグラフの縦軸範囲変更()
Dim cht As ChartObject

For Each cht In ActiveSheet.ChartObjects
    If cht.Left = 8.25 Then
        With cht.Chart.Axes(xlValue)
        .MinimumScale = 18 '15℃
        .MaximumScale = 30 '30℃
        End With
    End If
Next cht

End Sub
```
ディレクトリ内のファイルの消去

## globでファイルのみを消去

```php
array_map('unlink', glob("path/to/dir/*.php"));
```

## イテレーターでファイルとディレクトリを消去

```php
foreach (new RecursiveIteratorIterator(new \RecursiveDirectoryIterator('path/to/dir', \FilesystemIterator::SKIP_DOTS),RecursiveIteratorIterator::CHILD_FIRST) as $file) {
    $file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname());
}
```
Django のカスタムコマンドでユーザーの登録、削除

次のページを参考にしました。
[How to Create Custom Django Management Commands](https://simpleisbetterthancomplex.com/tutorial/2018/08/27/how-to-create-custom-django-management-commands.html#basic-example)

カスタムコマンドの作り方はこちら
[Django のカスタムコマンドの作り方](https://qiita.com/ekzemplaro/items/7349d43388abfd8ca2db)

ユーザーの一覧

```py:home/management/commands/list_users.py
from django.core.management.base import BaseCommand
from django.contrib.auth.models import User

class Command(BaseCommand):
    def handle(self, *args, **kwargs):
        for user in User.objects.all():
            print(user.id,"\t", end="")
            print(user.username,"\t", end="")
            print(user.email)
```

ユーザーの作成

```py:home/management/commands/create_users.py
# ------------------------------------------------------------------
#
#	create_users.py
#
#					Dec/17/2018
# ------------------------------------------------------------------
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand

users = ['user01','user02','user03','user04','user05']
class Command(BaseCommand):
	help = 'Create users'

	def handle(self, *args, **kwargs):
		for user in users:
			email = user + "@test.com"
			password = 'saluton123'
			User.objects.create_user(username=user, email=email, password=password)
#
# ------------------------------------------------------------------
```

実行結果

```text
$ python manage.py create_users
$ python manage.py list_users
1 	admin 	test@test.com
2 	test01 	
3 	test02 	
4 	test03 	
20 	user01 	user01@test.com
21 	user02 	user02@test.com
22 	user03 	user03@test.com
23 	user04 	user04@test.com
24 	user05 	user05@test.com
```

ユーザーの削除

```py:home/management/commands/delete_users.py
# ------------------------------------------------------------------
#
#	delete_users.py
#
#					Dec/17/2018
# ------------------------------------------------------------------
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand

class Command(BaseCommand):
	help = 'Delete users'

	def add_arguments(self, parser):
		parser.add_argument('user_id', nargs='+', type=int, help='User ID')

	def handle(self, *args, **kwargs):
		users_ids = kwargs['user_id']

		for user_id in users_ids:
			try:
				user = User.objects.get(pk=user_id)
				user.delete()
				self.stdout.write('User "%s (%s)" deleted with success!' % (user.username, user_id))
			except User.DoesNotExist:
				self.stdout.write('User with id "%s" does not exist.' % user_id)
# ------------------------------------------------------------------
```

実行方法

```bash
python manage.py delete_users 20
```
CWLとsingularity 


# singularityのバージョン
CWLの実行エンジンとして `cwltool` を使う場合に、`--singularity`というオプションを付け加えることで、dockerでなくsingularityを使ってくれます。計算機クラスター環境によっては、（セキュリティの関係で？）dockerを使えない場合があるそうで、そのような場合には、**CWLで記載されたワークフローに一切の変更をせずに**使えるので、とても便利ですね。

ただし、singularityのバージョンは、2.5以上でないとエラーが出てしまうようです。インストールされているsingularityのバージョンが2.4以下の場合には、下記のページを参考にバージョンアップを試みてください。
http://neuro.debian.net/pkgs/singularity-container.html


# ちゃんと動いた
こちらの test-workflow.cwl を動かしてみました。
https://github.com/hacchy1983/CWL-workflows

singularityのバージョンを2.5.2にバージョンアップしたのちは、無事に動いてくれることを確認しました。

```
cwltool --singularity Workflows/test-workflow.cwl Jobs/small.ERR034597.test-workflow.yml
```
集合写真から証明写真風に切り取る

#目的
  集合写真から各個人の顔写真を自動生成する

#環境
    import cv2
    import os
#使用方法
  haarcascade_frontalface_alt2.xmlをpython3.X 下から探し出し、ソースを修正
  入力フォルダphoto/に集合写真を配置
  出力フォルダphoto_out/を作成
  python detect_person.py を実行
#ソースコード


```python:detect_person.py    


    #############################################################
    #
    # 下記　face_cascade_path　を正面或いは横顔認識ライブラリを選択
    #
    #############################################################
    # input: 集合写真を　./photo/　に入れる、複数枚可
    # output: ./photo_out/に出力する
    # 機能：集合写真から証明写真風に切り取る
    # 実行: python detect_person.py
    #############################################################

    import cv2
    import os
 
 
    #入力：集合写真フォルダ
    in_jpg = "./photo/"
    #出力：生成した証明写真フォルダ
    out_jpg = "./photo_out/"

    face_cascade_path = 'C:/Users/?????/AppData/Local/Programs/Python/Python37\
                   /Lib/site-packages/cv2/data/haarcascade_frontalface_alt2.xml' 
    '''
    face_cascade_path = 'C:/Users/?????/AppData/Local/Programs/Python/Python37\
                  /Lib/site-packages/cv2/data/haarcascade_profileface.xml' #横顔検出
    '''
    #リストで結果を返す関数
    def get_file(dir_path):
        filenames = os.listdir(dir_path)
        return filenames
 
    pic = get_file(in_jpg)
 
    for i in pic:
    # 画像の読み込み 
    image_gs = cv2.imread(in_jpg + i)
    image_height, image_width, _ = image_gs.shape
    # 顔認識用特徴量ファイルを読み込む --- （カスケードファイルのパスを指定）
    cascade = cv2.CascadeClassifier(face_cascade_path)

    
    # 顔認識の実行
    face_list = cascade.detectMultiScale(image_gs,
                scaleFactor=1.1,minNeighbors=1,minSize=(1,1))
    
    # 顔だけ切り出して保存
    no = 1
    for rect in face_list:
        x = rect[0]
        y = rect[1]
        width = rect[2]
        height = rect[3]
        hh = int(height/4)
        hhh = (y-hh if y-hh > 0 else 0)

        yh = (y + height + hh if y + height + hh < image_height else image_height-1)

        ww = int(width/4)
        xx = (x-ww if x-ww > 0 else 0)
        xw = (x + width + ww if x + width + ww < image_width else image_width -1 )

        dst = image_gs[hhh:yh, xx:xw]
        save_path = out_jpg + '/' + 'out_('  + str(i) +')' + str(no) + '.jpg'
        
        #認識結果の保存
        a = cv2.imwrite(save_path, dst)

        print(no)
        no += 1
```
JavaScriptでrange関数

### Symbol.iterator

```js
const range = i => ({
  [Symbol.iterator]() {
    return {
      index: 0,
      next() {
        return this.index < i
          ? { value: this.index++ }
          : { done: true }
      },
    }
  },
})
```

### Symbol.iterator + Generator

```js
const range = n => ({ 
  *[Symbol.iterator](){ 
    let index = 0 
    while(index < n) yield index++ 
  } 
})
```

### Generator
```js
function* range(n) {
  let index = 0
  while (index < n) yield index++
}
```

### Result

```js
for (const i of range(10)) console.log(i)

// 0
// 1
// 2
// 3
// 4
// 5
// 6
// 7
// 8
// 9
```
N+1問題について

#N+1とは
N+1 問題とは、Tree 状の情報を DB から読み出す際、全レコードの取得に一つ＋各レコード分だけ SQL を発行してしまう問題です。

N+1問題はパフォーマンスにも直結するので、解決したい問題だと思います。

ただ、私も含めて初心者には躓く要素の大きい問題なのではと思います。

#N+1問題を解決するためにGemでbulletを導入する
まずはGemfileに以下を追加して、``bundle install``しましょう。

```.Gemfile
group :development do
  # N+1問題のクエリを警告
  gem 'bullet'
end
```


次にconfig/environments/development.rbに次の設定を追加します。

```config/environments/development.rb
AppName::Application.configure do
  config.after_initialize do
    Bullet.enable = true # Bulletプラグインを有効
    Bullet.alert = true # JavaScriptでの通知
    Bullet.bullet_logger = true # log/bullet.logへの出力
    Bullet.console = true # ブラウザのコンソールログに記録
    Bullet.rails_logger = true # Railsログに出力
  end
end
```

この設定を行うことでN+1問題が発生している際は教えてくれるようになります。

#N+1問題の解決方法
上記のGemを導入すると以下のような警告をN+1問題が発生している画面で教えてくれます。*logでも教えてくれます。

```
N+1 Query detected
  Spree::Product => [:valiants]
  Add to your finder: :include => [:valiants]
N+1 Query method call stack
  /該当ファイル行
  /～

```

N+1の警告が発生するようなクエリを見つけたらincludeでSQLの実行時に合わせて関連テーブルを読み込みます。
*以下は一例です

```~_controller.rb
def show
  @products = Spree::Product.include(:variants).all
end
```

また、Remove to your finderと表示されることもあるのでこの場合は指定されているクエリを外しましょう。
PepperをスマホまたはPCのブラウザで操作する

[Pepper Advent Calendar 2018](https://qiita.com/advent-calendar/2018/pepper) の18日目です。よろしくお願いします。
#はじめに
 [笑ッカソン2018](https://pepper.doorkeeper.jp/events/81875)に参加させていただく際に、あったら便利かなと思って作成したアプリを公開します。
 当日はもっとすごいアプリがあって、このアプリは使わなかったんですが、何かの機会に使っていただければ、また、何かの参考になれば幸いです。
　また、接続先のURLをQRコードとして表示してはどうかというアドバイスをいただいたので、今回の公開を機に対応しました。

- Pepperを使った動画で笑いを生み出せ！「笑ッカソン2018」が開催（https://robotstart.info/2018/11/07/waraihackathon2018.html)
 
#注意事項
ソフトバンクロボティクス株式会社のPepperを活用し、独自開発したものです。

#開発環境
MacOS Mojabe 10.1４.1
Choregraphe 2.5.5.5
Pepper

#ソース
ソースは[こちら](https://github.com/piroku/warak)で公開しています。　

#使い方

##PC用のHTMLを編集する
　PC用のHTMLは、**/html/cms/index.html**　になります。サンプルでいくつかボタンを定義していますので、これをもとにボタンの２つの属性（**event-name,event-param**）を編集してください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131693/a34833cc-7083-c233-92d7-8f538da2de84.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131693/0694b490-738b-6c3c-cbb3-da261ced00fd.png)

##アプリを実行する
　アプリを実行すると、PepperのタブレットにQRコードが表示されます。アプリの起動の仕方によって、次の2つのいずれかが入ったQRコードが生成されていると思います。このURLにPCまたは、スマートフォンのブラウザ（Chromeのみ）から接続してください。

- http://(IPアドレス)/apps/.lastUploadedChoregrapheBehavior/cms/index.html
- http://(IPアドレス)/apps/warak-44da1e/cms/index.html

![image.png](https://qiita-image-store.s3.amazonaws.com/0/131693/5308cf81-7ddb-bf3b-3a24-b5fdbf5d25e1.png)

　接続する際に、BASIC認証のボックスが表示されますので、PepperのID,パスワードを入れてください。接続に成功すると「接続しました。」とPepperが発話します。

##ボタンをクリック
　HTMLが表示されたら、あとは好きなボタンをクリックするだけです。連打対策は行なっていません:sweat_smile:ので、ご注意ください。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131693/1edf1ede-5397-1378-b7ee-65d0a6261e03.png)

##アプリ終了
　Pepperの後ろバンパー長押しで終了します。

#アプリ解説
構成はこんな感じです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131693/34a7dee5-377d-3a72-d219-e83adc6be2e2.png)

ボタンクリックを行うと、「warak/cms/Tapper/View/ButtonTouched」イベントがPepperに通知されます。

例： イベント名(say)にイベントパラメータ(こんにちは）を指定

```html
<button type="button" event-name="say" event-param="こんにちは">発話(say)</button>
```
対応するPepper側では、「warak/cms/Tapper/View/ButtonTouched」の引数のイベント名(event-name)を判断し、それぞれの専用のボックスにイベントパラメータ(event-param)を渡しています。
イベント名を増やすことで、例えば　moveイベントを追加して、移動させることも可能になります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/131693/f1f642e7-b562-748e-c891-409e161876eb.png)

#イベントについて
 このサンプルで対応しているイベントは以下の通りです。拡張して遊んでみてください。

| イベント名<br>(event-name)         | イベントパラメータ<br>(event-param) | 説明<br>　　|
|:--|:--|:--|
|say|発話文字列|指定された文字列で発話します|
|animatedsay|発話文字列|指定された文字列で発話します（animated)|
|sound|"1"|音楽を再生します（サンプルでは"1"のみ）|
|tabletcolor|"1"から"9"|タブレットの色を変えます|
|eye|"1"から"9"|目の色を変えます|
|motion|"1"から"3"|モーションを実行します|
|tablet|"1"|特定の画像をタブレットに表示します（サンプルでは"1"のみ）|
|custom|"1"|モーションと特定の発話をしたいときなど（サンプルでは"1"のみ）|

#最後に
　笑ッカソン2018は、すごく新鮮で楽しかったです。みんなで同時にPepperを動かすのに、１つのアプリで連動させるのではなく、あえてみんなで同時にボタンを押して、何度もリテイクしたり、何か懐かしい感じもして、いい思い出になりました。
JenkinsでXCodeプロジェクトのテストアプリをDeployGateにアップロード、実装メモ

JenkinsでXCodeプロジェクトのテストアプリをDeployGateにアップロードするように実装したのでメモ

#環境準備
Macを使用。

以下のアプリをビルドするマシンにインストールし、セットアップを完了させる
・Jenkins
・XCode、及びcommand line tools
・DeployGateコマンドラインツール
DeployGateにログイン済みであること、ターミナルで、「dg --version」「xcodebuild -version」を入れてバージョンが出ること、Jenkinsのセットアップが済んでいることが前提になります。

[DeployGateコマンドラインツール　ドキュメント](https://docs.deploygate.com/docs/cli)
command line toolsは[Apple Developer](https://developer.apple.com/download/more/)からインストールしてください
Jenkinsは[こちら](https://jenkins.io/)

#ExportOptions.plist作成
まず、DeployGateにアップロードするIPAファイルを作るためには、Archiveを実行する必要があります。
command line toolsでAriciveを作成する場合、必ず「ExportOptions.plist」を作成する必要があります。

ExportOptions.plistはxcodeprojがあるフォルダの直下に作成してください。
例）「~/Documents/WorkSpace」にTestという名前のxcodeprojを作成した場合、ExportOptions.plistは「WorkSpace」の中に置く

ExportOptions.plist作成の仕方は以下のとおりです。
・予めXCodeのツール上でAriciveを実行、OrganizerでAd Hocを実行し、生成されるファイルの中にある「ExportOptions.plist」
・ExportOptions.plistを自作する
→必要なのは「provisioningProfiles」の部分です。

以下、実際に作成したExportOptions.plistの中身です。○○○○の部分を自分のプロジェクトに合わせてもらえればうまくいくはずです。

```ruby:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>compileBitcode</key>
	<false/>
	<key>destination</key>
	<string>export</string>
	<key>method</key>
	<string>ad-hoc</string>
	<key>provisioningProfiles</key>
	<dict>
		<key>○○○○</key>
		<string>○○○○</string>
	</dict>
	<key>signingCertificate</key>
	<string>iPhone Distribution</string>
	<key>signingStyle</key>
	<string>manual</string>
	<key>stripSwiftSymbols</key>
	<true/>
	<key>teamID</key>
	<string>○○○○</string>
	<key>thinning</key>
	<string>&lt;none&gt;</string>
</dict>
</plist>
```

#Job(シェルスクリプト作成)

JenkinsのJobを作成し、以下のシェルスクリプトを記述します。

```ruby:
#!/bin/sh

# プロビジョニングファイルを移行する
# 以下、WorkSpaceフォルダの中にkeyという名前のフォルダがあり、そこでプロビジョニングファイルを管理している場合
cd ~/Documents/WorkSpace/key
rm -f ~/Library/MobileDevice/Provisioning\ Profiles/*
cp *.mobileprovision ~/Library/MobileDevice/Provisioning\ Profiles/

# プロジェクトフォルダに移行
# Documentsフォルダに、WorkSpaceという名前のフォルダを作り、その下にXCodeのプロジェクトがあるという想定）
cd ~/Documents/WorkSpace

# 作業ディレクトリ作成
mkdir build

# CleanしてArchive作成(Debugを作成)
xcodebuild -workspace ○○.xcodeproj/project.xcworkspace \
-scheme ○○ \
-configuration Debug \
clean archive \
-archivePath ./build/build

# Exportしてipa作成
xcodebuild -exportArchive \
-archivePath ./build/build.xcarchive \
-exportPath ./build \
-exportOptionsPlist exportOptions.plist

# Deploygateにupload
dg deploy ./build/○○.ipa
```

「○○.xcodeproj」はXCodeのプロジェクト名、schemeは作成したscheme名を入れます。
最後、dg deployで作成したipaファイルをアップロードして完了です。

#現状の問題点
~~プロビジョニングファイルを更新すると、XCodeでプロビジョニングを設定しないと更新されないので、その部分を何かしらの形で変更する必要があります。
現在、その方法を調査中~~

解決。XCode経由でダウンロードしたプロビジョニングファイルが悪さしていたので、デフォルトでプロビジョニングファイルを格納しているフォルダの中を全部消して、差し替えるようにした。
bitbucketの差分を全て表示するブックマークレット

# Problem

bitbucketではコードの差分が多すぎると、以下のように省略されてしまいます。

<img width="840" alt="スクリーンショット 2018-12-17 16.08.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/9875/8c1183c4-7db0-dd17-2cc6-1a833a244cb4.png">

# Solution

BitBucketのPRページを開いた状態で、ブラウザのアドレスバーに以下のコードを入力し、Enterキーを押してください。
差分が全て展開されます。

```js
javascript:Array.from(document.getElementsByClassName('load-diff try-again')).forEach(l => l.click());
```
[CentOS7]Webminをインストールする

# はじめに

[前回の記事](https://qiita.com/caique/items/0ba98ca9f449c0761b30)ではSSLの設定を行った。
今回は同じサーバーに[webmin](http://www.webmin.com/)を導入する。

参考：http://ysklog.net/server/4425.html
参考：http://www.webmin.com/rpm.html

# インストール

## Perlモジュールのインストール

```
# yum -y install perl-Net-SSLeay
 :
省略
 :
Complete!
```

## Webminのインストール

このページのリストから最新版を確認する。
http://download.webmin.com/download/yum/
現在は`webmin-1.900-1.noarch.rpm`が最新だった。

```
# yum -y install http://download.webmin.com/download/yum/webmin-1.900-1.noarch.rpm
 :
省略
 :
Complete!
```

## Webminへのアクセス制限

指定したIP以外はアクセスできないようにする。
ただしIPが変わってしまうとアクセスできなくなるので注意。

自分のIPは[この辺のサイト](https://www.cman.jp/network/support/go_access.cgi)で調べられる。

```
# vi /etc/webmin/miniserv.conf
```

ファイルの末尾に以下を追加する。

```
allow=自分のIP 10.0.0.0/24
```
Webminの再起動

```
# /etc/rc.d/init.d/webmin restart
```

## firewallのポート開放

webmin用の10000ポートを開放する。

```
# firewall-cmd --zone=public --add-port=10000/tcp
success
# firewall-cmd --zone=public --add-port=10000/tcp --permanent
success
```

Webminにアクセスする。以下のアドレスにアクセスする。
※ 仮にドメインを`www.domain.com`とする

https://www.domain.com:10000

ただし、SSL接続の設定がされていないので、
「この接続ではプライバシーが保護されません」と表示される。

![privacy.JPG](https://qiita-image-store.s3.amazonaws.com/0/322587/3c2db739-1573-e4ae-2dc9-261cb3eed586.jpeg)

SSL接続の設定をする。

# WebminへのSSL接続

前の記事で設定したLet's Encryptの証明書をwebminの設定ファイルに記載する。

```
# vi /etc/webmin/miniserv.conf
```

設定ファイルを以下のように変更する。
※ 仮にドメイン名を`www.domain.com`とする

```
keyfile=/etc/letsencrypt/live/www.domain.com/privkey.pem
certfile=/etc/letsencrypt/live/www.domain.com/fullchain.pem
```

Webminの再起動

```
# /etc/rc.d/init.d/webmin restart
```

再度、Webminにアクセスする。
https://www.domain.com:10000

今度は警告が表示されずにアクセスできた。

# まとめ

Webminがあるとシステム管理がとても便利
次回は[PHPのアップデート](https://qiita.com/caique/items/cba366dfb008c09d82d9)をする予定。
Machine Learning コース Lecture1

#はじめに
最近オンラインで機械学習の授業を受けているのですが，学ぶことが多く，受けているだけだと忘れてしまいそうなので備忘録的にもここにまとめていく．
（全部英語なので日本語にまとめるだけでも勉強になりそう）
まだまだ勉強中の身なので，読んでて気になるところがあったらぜひコメントしてください．

オンライン授業について詳しく知りたい方は[こちら](https://www.edx.org/course/machine-learning-columbiax-csmm-102x-0)から!

#機械学習の概要
この授業では機械学習について以下のように分けていましたので僕のまとめもその観点からになることを先に断っておきます

||               |            |
|:----|:-------------:|:----------:|
|学習方法|教師あり学習     |教師なし学習   |
|モデリング方法|確率的モデル     |非確率的モデル |
|アプローチ|モデリングアプローチ|最適化アプローチ|

##教師あり学習
教師あり学習は大きく二つの方法に分けることができる

- 回帰 <br>
入力データを使って，直接値を出力させること
- クラスタリング<br>
入力データを使って，離散値（クラスタ）を出力すること

##教師なし学習
教師なし学習の目的は基本的にデータの構造を明らかにすること（最近はもっと他にも色々あるけど）
これはpredictionやrecommendations, efficient data explorationを助けてくれる

#データモデリング
次に機械学習の方法について大きく４ブロックに分かれている

|ブロック |                      ||
|:------|:---------------------|:---|
|ブロック１|Data                  |どんなデータ？|
|ブロック２|Build Model           |どんなモデル？|
|ブロック３|Infer hidden variables|パラメタの推定|
|ブロック４|Predict & Explore     |未知データの予測|

##具体例

####ガウス分布
例としてガウス分布について上のモデルの立て方を適応してみると

#### Data

```math
x_1,...x_n.~~Each~~x_i \in \mathbb{R}^d
```

####Build Model
 An i.i.d Gaussian model を仮定する

i.i.d assumption とは

```math
p(x_1,...x_n|\theta) = \prod_{i=1}^n p(x_i|\theta)
```
が成り立つこと．つまり，独立で同一の分布からデータが得られる


####Infer hidden variables
最尤推定法（Maximum likelihood）

最尤推定法は

```math
\hat{\theta}_{ML} := argmax ~~p(x_1,...x_n | \theta)
```
を満たす $\theta$ を推定することである　<br>
これはつまり得られたdata群に対して，このdata群を一番よく出現させるパラメタを推定している.
具体的な計算については割愛
<br>
その結果，ガウス分布のパラメタはそれぞれ

```math
\hat{\mu}_{ML} = \frac{1}{n}\sum_{i=1}^n x_i　 \\

\hat{\Sigma}_{ML} = \frac{1}{n} \Sigma_{i=1}^n (x_i - \hat{\mu}_{ML})(x_i - \hat{\mu}_{ML})^T

```
となる
つまり，最尤推定法を用いると，モデルの平均は得られたデータの平均，分散共分散も，その平均を用いて計算したものとなる．

####Predict
特にしない

####ちなみに密度関数

```math
p(x|\mu,\Sigma) := \frac{1}{(2\pi)^{\frac{d}{2}}\sqrt{det(\Sigma)}}\exp(\frac{-1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu))

```
windows10のWSL（ubuntu）のXwindowにmacからアクセスする

windows10のWSL(Ubuntu)はXwindow使えるのかどうか、もし使えるならmacをクライアントとしてX使えるかなー
と思ったので、実際にやってみたメモ。

## mac側
X11は最近のOSXには入ってないので、代わりにXQuartzを使う。
https://www.xquartz.org
ここから。
mac側の設定は特には無し。
一応、`xeyes`とかでちゃんと動くかは確認しておいたほうが良し。

## Windows(WSL)側
aptでいくつかインストール、sshとx11-appsが必要
`$ sudo apt install x11-apps`
ssh側の設定はX-forwardができるようにする。
他の設定はローカルネットワーク内のアクセス限定なのでパスワード認証も可能にした。
(ポート番号も適当な番号に変更しておく)

``` /etc/ssh/sshd_config
....
PasswordAuthentication yes
....
X11Forwarding yes
....
```

で、sshdを起動。
Windows側もこれくらでいけるはず。
（他、sshdの設定は別途ご参照）

## macからsshログイン
`$ ssh -X (user)@(コンピューター名).local -p (ポート番号)`
(windowsのコンピューター名に.localをつけてホスト名にできる。構成によるかもしれないのでだめならIPアドレスで)
ログインが成功したら、`xeyes`でmac側のXquartzが動くか確認。

以上でOK
cakephp2のインストールはcomposer.jsonにphpのバージョンを明記

以前こちらの記事に書いたcakephp2の始め方だが、

https://qiita.com/uedatakeshi/items/08d5c577e07489c4d9f9

いざやってみると最新のcakephp2だと依存関係でphp5.3に対応していないようなライブラリが入ってしまい、エラーを起こす、ことがあるようだ。

私が遭遇したのはphp5.4のサーバー。markbakerというやつがひっかかって動かない。

https://github.com/MarkBaker/PHPComplex

どうもphp5.6以上対応のようである。

ということでcomposer.jsonに以下を追加。

```json:composer.json
    "require": {
        "php": "^5.4.0",
```

すると今度は

```sh
  Problem 1
    - This package requires php ^5.4.0 but your PHP version (7.0.22) does not satisfy that requirement.
```

とcomposerに怒られる。走らせてるローカルのphpが７だとだめみたい。

しょうがないので昔入れたphp54とcomposer.pharを使ってinstall

```sh
curl -sS https://getcomposer.org/installer | php
sudo php54 composer.phar install
```


markbakerは消えました。。。
Matplotlibのpyplotインポート時のエラーを解決する

# はじめに
Matplotlibのpyplotをインポートしようとしたとき、以下のようにして "ModuleNotFoundError: No module named 'tkinter'" を吐いた場合に対処した方法を記します。

```
>>> from matplotlib import pyplot as plt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    ＜省略＞
  File "/home/bitpositive/.local/lib/python3.6/site-packages/matplotlib/backends/_backend_tk.py", line 5, in <module>
    import tkinter as Tk
ModuleNotFoundError: No module named 'tkinter'
>>> 
```

## 環境
- Python 3.6.7
- Matplotlibはpip3でインストール
- Ubuntu Budgie 18.04.1 LTS 64bit


# 解決方法
Matplotlibは、Python用のGUI構築ライブラリであるTkinterを利用しています。これが足りていないので、インストールします。


なお、python3-tkを忘れると、問題が解決しないので注意が必要です。私はこれで少しつまづきました。

```
$ sudo apt install tk-dev python3-tk
```

これでOK。

# 参考
- [matplotlib error - no module named tkinter](https://stackoverflow.com/questions/36327134/matplotlib-error-no-module-named-tkinter)
- [Ubuntu+Pyenv+Python3の環境でmatplotlibのグラフ表示ができなかった時の対処](https://qiita.com/sobeit@github/items/eb24bbcc02822223d8eb)
CSS Tips

備忘録的記事（随時更新予定）



# 要素を横に並べる


```css:sample.css
.parent {
/*　親要素にflexを指定 */
  display: flex;
}

.child1 {
/*　最初に配置 */
  flex: -1 
}

.child2 {
  flex: 0
}

.child2 {
/* 最後に配置 */
  flex: 1 
}
```

# 要素を左右中央に揃える


```css:sample.css
.parent {
  display: block;
}

.child {
  margin: 0 auto;
}
```

# 上下左右中央に配置する

```css:sample.css
.parent {
  position: relative;
}

.child {
  position: absolute;
  top: 50%;
  left: 50%;
  /*　少しずれた分を修正　*/
  transform: translate(-50%, -50%);
}
```

#横にはみ出したテキストを'...'で補完する

```scss

.target {
  max-width: 300px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
```

# divを横並びにしてはみ出した部分をスクロール対応させる

```scss

.parent {
  width: 100%;
  overflow-x: scroll;
  overflow-y: hidden; (webkit対応)
  white-space: nowrap; (折り返さない)
}
```

# 表示文字が多い時にグラデーションをかける

```scss
p {
  position: relative;
}
p::after {
  position: absolute;
  bottom: 0;
  left: 0;
  z-index: 2;
  content: '';
  width: 100%;
  height: 50%; //グラデーションの位置を指定
  background: linear-gradient(rgba(255,255,255,0) 0, rgba(255,255,255,.7) 20%, rgba(255,255,255,1) 80%);
}
```
AutoItでExcelを読み込む

## 概要

AutoItを使ってExcelを開いてセルの値をとってくる方法

## Excelから値を読み込む
シンプルに1つセルを読み込む場合、下記のようになります。


```:sample1.au3
#include <Excel.au3>

; Excelを起動します
$oExcel = _Excel_Open()

; Excelで開くファイルを指定します(下記ではデスクトップ上のtest.xlsxを開く想定)
$oWorkbook = _Excel_BookOpen($oExcel, "C:\Users\username\Desktop\test.xlsx") 

; A1セルを読み取る
$value = _Excel_RangeRead($oWorkbook, Default, "A1")

```

## Excelで指定したシートから値を読み込む
前述のサンプルに加え、シートの切り替えを加えます。

```:sample2.au3
#include <Excel.au3>

; Excelを起動します
$oExcel = _Excel_Open()

; Excelで開くファイルを指定します(下記ではデスクトップ上のtest.xlsxを開く想定)
$oWorkbook = _Excel_BookOpen($oExcel, "C:\Users\username\Desktop\test.xlsx") 

; --- 追加部分。シートの選択を行っている ---
$configSheetName = "Sheet2"
$oExcel.Sheets ($configSheetName).Select
;--- ---

; A1セルを読み取る
$value = _Excel_RangeRead($oWorkbook, Default, "A1")

```

## Excelがうまく開けなかった場合、エラーのポップアップを表示する
ファイルパスの指定がうまくいかなかった場合などにエラーのポップアップを表示させる場合のサンプル

```:sample3.au3
#include <Excel.au3>
#include <MsgBoxConstants.au3> ; --- 追加1 ポップアップのinclude --- 

; Excelを起動します
$oExcel = _Excel_Open()

; --- 追加2 Excelが開けなかった場合、開けなかった旨をポップアップで表示し終了します ---
If @error Then Exit MsgBox($MB_SYSTEMMODAL, "エラー", "Excelが起動できませんでした。")
; --- --- 

; Excelで開くファイルを指定します(下記ではデスクトップ上のtest.xlsxを開く想定)
$oWorkbook = _Excel_BookOpen($oExcel, "C:\Users\username\Desktop\test.xlsx") 

; --- 追加3 指定したファイルが開けなかったらその旨をポップアップで表示しExcelをクローズ、終了します ---
If @error Then
   MsgBox($MB_SYSTEMMODAL, "エラー", "指定したファイルが開けませんでした。ファイルパスを確認してください")
   _Excel_Close($oExcel)
   Exit
EndIf
; --- ---

; A1セルを読み取る
$value = _Excel_RangeRead($oWorkbook, Default, "A1")

```
お名前.COMのDDNSをLambdaを使って更新する

# 理由目的

自宅サーバのDDNS更新をAWSを使って行う。
普通に更新すれば良いじゃないと言われるが、以下の理由が。

- お名前.COMの更新ソフトはWindowsのみ
- 家で主に動いているサーバはNASのLinux(Synology DS216J)
- 今まではMyDNSを使用していたが、練習がてらサーバレスに変更したい。
- NASのLinuxは汚したくない(インストールしたくない)
- NASからの更新はCURLのGETのみ

というわけでLambdaとAPI-Gateway使って、更新させます。

# 方法
APIに自宅に割当されたIPアドレスを放り投げてOpenSSLにて更新を行います。

参考にさせていただいたQiita記事
##### LinuxやMacで お名前.com ダイナミックDNS の IPアドレスを更新する
https://qiita.com/ats124/items/59ec0f444d00bbcea27d

##### Lambdaでコマンドやシェルスクリプトを実行してみる(Node.js)
https://qiita.com/toshihirock/items/7393121263ffcec0a395

# 経緯
初めはEC2サーバを立てて更新しようと考えてましたが、
お金掛かるんで、なにかいい方法をと、Lambdaでシェルが実行できることを知り実行、
IDとパスワード、IPを対話形式で実行しようとしましたが、
expectがなく断念。

以下の方法で一応成功したので、記録。
なお、SynologyのNASで実行しましたが、戻り値が悪いのかこちらはまだエラーが出ています
IPの更新は出来ている・・・

# 構成-本文
CURLにGETで投げます。
Lambda内部にはID-PASSをベタ打ちしてます。

``` index.js
var exec = require('child_process').exec;
var fs = require('fs');

exports.handler = function(event, context) {
  
  var data;
  var IP;
 
  IP=event.key1;
  // 受け取ったIPを変数に。
  // IPの構文チェックは省略、ホントは入れてね。。
  
  // USERIDとPASSはこちらに。
  // HOSTNAMEが無いなら、空欄でもOK"HOSTNAME:"は必要
  // ドメインは説明不要
  // "IPV4:"のあとに更新したいIPアドレスを。
  data="LOGIN\nUSERID:0000000\nPASSWORD:XXXXXXXXXXXXXX\n.\n";
  data=data + "MODIP\nHOSTNAME:WWW\nDOMNAME:YOURDOMAIN.COM\nIPV4:";
  data=data + IP;
  data=data + "\n.\n";
  data=data + "LOGOUT\n.\n";
  
  // コマンド文を固めて、ファイルに保存。
  
   fs.writeFile("/tmp/cmd.txt", data, function (err) {
    if (err) {
        throw err;
    }
  });
  
  // exec.shに一気に入力
  // これでキー入力を代用。
  
  child = exec('/bin/bash ./exec.sh < /tmp/cmd.txt', function(error) {
      // Resolve with result of process
      context.done(error, 'Process complete!');
  });

  // Log process stdout and stderr
  child.stdout.on('data', console.log);
  child.stderr.on('data', console.error);
};

```

```  exec.sh
#!/bin/bash

openssl s_client -connect ddnsclient.onamae.com:65010 -quiet

exit
```

API-gatewayはひねりのないGET受信->Lambdaへの受け渡し。
誰でも触らせないために、APIキー・・・を入れたいが、SynologyのNASには設定がない(T_T)
URLを秘密にするしか無いのか？？？

あとはGETを受信するために・・・

* 統合リクエスト内部  マッピングテンプレートへ 

```
{
    "key1" : "$input.params('key1')"
}
```

Curlの構文は、
` curl https://XXXXXX.execute-api.AP-XXXXX.amazonaws.com/default/Lambda-exe?key1=IP-addr `

この後、お名前.COMのコンソールを見れば、更新されているかわかります。

# まとめ
難航したのは、APIの使い方。
デプロイ後のLambdaとの登録。
GETパラメータのマッピング

最大の難関は、expectが無いLambdaにてどうやってコマンドを送るか。。
ファイルで渡せてよかった。。。

練習には良かったけど、実用化は難しいかも。
SynologyのDDNS更新方法をもう少し調べましょうか。
良い方法を知っている人がいれば教えて下さい。。。。

というかここまでするなら、
余っているRaspberryPiを使ったほうが良いのかも・・・・
【Django】admin画面へurlタグでリンクを貼る

{% url %}を使ってDjangoの管理画面のページへのリンクを作成する。

### 新規追加ページ
```
<a href="{% url admin:[アプリ名]_[モデル名]_add %}">新規追加</a>
```

### 既存レコードの編集ページ
```
<a href="{% url admin:[アプリ名]_[モデル名]_change pk %}">編集</a>
```
※pkは変更したいレコードのID

### レコード一覧ページ
```
<a href="{% url admin:[アプリ名]_[モデル名]_changelist %}">一覧</a>
```
これ。「\_list」でしょ。と、思いきや「\_changelist」が正。