OmniAICreator/Qiita-1.07M huggingface dataset:
Composer経由でphpQueryをインストール

phpでwebスクレイピングするときに使用するライブラリに`phpQuery`というものがあります。
[zipでダウンロード](https://code.google.com/archive/p/phpquery/downloads)できるようですが、今回はcomposer経由でインストールしたいと思います。

## 環境

- macOS Mojave 10.14.1
- Composerインストール済み

## 1. 作業するディレクトリで`composer init`

```terminal
$ composer init
```

対話式でconfig設定する画面になりますが、今回はすべてスキップします。
すると、作業ディレクトリ内に`composer.json`が作られていると思います。

## 2. phpQueryを検索

今回はcomposerでphpQueryがインストールできるか検索しただけなので、スキップしても問題ありません。
パッケージ検索は`composer search {検索するパッケージ}`

```terminal
$  composer search phpQuery
electrolinux/phpquery phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library
jaeger/querylist Simple, elegant, extensible PHP Web Scraper (crawler/spider),Use the css3 dom selector,Based on phpQuery! 简洁、优雅、可扩展的PHP采集工具(爬虫)，基于phpQuery。
foolz/sphinxql-query-builder A PHP query builder for SphinxQL. Uses MySQLi to connect to the Sphinx server.
(略)
atofighi/phpquery phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library
ridaamirini/phpquerybuilder An fast, small SQL Builder based on FluentPDO
```
ちゃんとありますね。

## 3. phpQueryインストール

それではインストールしていきましょう。
composer経由でパッケージインストールする際は、`composer require {パッケージ名}`

```terminal
$ composer require electrolinux/phpquery
Using version ^0.9.6 for electrolinux/phpquery
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing electrolinux/phpquery (0.9.6): Downloading (100%)         
Writing lock file
Generating autoload files
```

`composer.lock`ファイルと、`vendor`ディレクトリが生成されていると思います。

## 4. インストールされたか確認

```terminal
$ composer info
electrolinux/phpquery 0.9.6 phpQuery is a server-side, chainable, CSS3 selector driven Document Object Model (DOM) API based on jQuery JavaScript Library
```
ちゃんと入っていますね。

## サンプルコード

こんな感じで使用します。

```php
<?php

require './vendor/autoload.php';

$html = file_get_contents('取得したいURL');
// h1要素を取得して出力
echo phpQuery::newDocument($html)->find("h1")->text();
```
2018/11/9 [速報] Egret3D 1.3 がリリースされました

# 元記事
[Egret3D 1.3 发布，增强灯光渲染效果、完善Egret3D 编辑器、Unity3D导出工具等功能](https://mp.weixin.qq.com/s/C4X6lCYuJDXPemfJtBIRwg)

# 概要
- ノーマルとスペキュタクラーマップを追加してライトニングレンダリングエフェクトが強化されました
- Egret3D エディターの改善
- コマンドラインツールスクリプトの改善(paper-cli 1.7)
- Unity3D エクスポーツツールの改善
- ドキュメントセンターへオンラインのサンプルの追加
pythonで自作関数をモジュール化・パッケージ化

pythonでの自作関数の作り方と使い方を説明していきます．

プログラムを作成していると，**同じような処理**が何度も出てくることがあります．
このような時に同じような処理が出てくる度に書くのはとても手間になります．それを自分の使いやすいように関数にしてしまったものが**自作関数**です．


# ファイル内の自作関数
自作関数の形式はこのようになっています．

```python
def 関数名(引数1,引数2,...):
    #関数の処理を記述
    return 戻り値
```

では，具体的に自作関数とそれを実行するプログラムを作っていきます．

```python:test_1.py
# 2つの変数の和を計算する自作関数
def my_sum(x,y):
    z = x + y
    return z

# main関数
if __name__ == '__main__':
    out = my_sum(1,2)
    print(out)
```

```python:output
3
```

これが一番基本的な自作関数の作り方と実行方法です．
しかし，この方法ではプログラムがどんどん長くなってしまい．扱いにくいプログラムになってしまいます．
そこで，別のファイルに自作関数をまとめる方法を紹介します．

# 同じディレクトリ内の自作関数
自作関数をまとめておくファイル（my_function.py）を作成します．
ファイル名はどんな関数かわかりやすいものにすると管理しやすいです．
自作関数で必要なライブラリはこのファイルで呼び出す必要があります．

```python:my_function.py
# 2つの変数の和を計算する自作関数
def my_sum(x,y):
    z = x + y
    return z

# 2つの変数の差を計算する自作関数
def my_dif(x,y):
    z = x - y
    return z
```

次に実行するプログラムを作成します．
実行するファイルと自作関数のファイルが同じディレクトリにある場合は

```python
import 自作関数のファイル名
```

とすれば自作関数を呼び出すことができます．
では実際に呼び出してみます．

```python:test_2.py
#自作関数のインポート
import my_function

if __name__ == '__main__':
    a = my_function.my_sum(2,1)
    b = my_function.my_dif(2,1)
    print(a)
    print(b)
```

```python:output
3
1
```

このように自作関数をまとめたファイルを作ることにより，実行するプログラムを短くすることができます．
しかし，もっと大きなプログラムになった場合は自作関数も多くなってしまいます．それに従って自作関数のファイルが多くなってしまい管理が難しくなってしまいます．ここで登場するのが**パッケージ化**です．

# パッケージ化
先ほど作った自作関数のファイルをディレクトリでまとめていきます．
自作関数のファイルの作り方は同じなので「my_functin.py」を使います．
![スクリーンショット 2018-10-26 18.22.02.png](https://qiita-image-store.s3.amazonaws.com/0/302862/b336a745-9fda-a603-039d-fb1e7993514d.png)
このようにディレクトリを作成します．ここでもディレクトリの名前は管理しやすいように変更して大丈夫です．
ディレクトリの中に「\_\_init__.py」という空のファイルを作る必要があります．このディレクトリはパッケージとして使われると言うことを示しています．
インポートの仕方が少し変わり，

```python
#自作関数のインポート
from ディレクトリ名 import モジュール名
```

このようになります．では，実際に実行するファイルを作成します．

```python:test_2.py
#自作関数のインポート
from my_module import my_function

if __name__ == '__main__':
    a = my_function.my_sum(2,1)
    b = my_function.my_dif(2,1)
    print(a)
    print(b)
```

関数自体は変えてないので出力は変わりません．
Golang mgo でページネーション

https://github.com/globalsign/mgo

mgoはGoでMongoDBを扱うためのライブラリ。
これを用いてページネーションしたい。

が、いかんせんMongoDBもmgoも初めて触ったのでよくわからない。
とりあえずmgoにはページネーションのための便利関数のようなものはなさそう。
[minquery](https://github.com/icza/minquery) というライブラリもあるようだが、 `cursor` の扱いが今ひとつ分からなかったのと、ごくシンプルな要件が実現できればよかったので自前実装することにした。

サンプルコードがNode.jsだが下記を参考にした。

https://scalegrid.io/blog/fast-paging-with-mongodb/

`Approach 1: Using skip() and limit()` を採用。
この方式は `実装が簡単だがデータ量が増えるにつれてパフォーマンス上の問題を抱える` とあるが、大したデータ量ではないのでこちらで。

# サンプルコード

```golang
// 本来は引数で渡す
perPage := 10 // ページあたり件数
currentPage := 1 // 現在のページ

session, err = mgo.Dial("mongodb://mongo/test")
if err != nil {
	log.Fatalln(err)
}
db = session.DB("test")

var people []*Person

q := db.C("people").Find(bson.M{}).Skip(perPage * (currentPage - 1)).Limit(perPage)
q.All(&people)
```
[MSSQL]テーブルまとめて削除する

#DROP TABLE おさらい
テーブル定義およびそれらのテーブルのすべてのデータ、インデックス、トリガー、制約、権限の仕様を削除します。
削除されたテーブルを参照しているすべてのビューとストアド プロシージャは、明示的に削除する必要があります。

##構文
```sql
DROP TABLE [ IF EXISTS ] [ database_name . [ schema_name ] . | schema_name . ] table_name [ ,...n ] [ ; ]
```
|引数|説明|
|:--|:--|
|IF EXISTS|既に存在する場合にのみ、テーブルを削除します。[^1]|
|database_name |データベースの名前を指定します。|
|schema_name|テーブルが所属するスキーマの名前を指定します。|
|table_name |削除するテーブル名を指定します。|

#テーブルまとめて削除する
何かの処理中にテーブルをバックアップ(テーブル名のプリフィックスにBACKUP_を設定)して、処理後に削除。みたいなシナリオを想定してます。
FOREIGN KEY 制約や複数スキーマ等の複雑なことは想定していません。

```sql
DECLARE @sql AS nvarchar(max)
SELECT @sql=ISNULL(@sql,'') + N'DROP TABLE dbo.' + name + N';' FROM sys.tables t WHERE t.name LIKE N'BACKUP_%' AND t.type=N'U'
EXECUTE (@sql);

GO
```

```sql:カーソル利用例
DECLARE @cur CURSOR;
DECLARE @tblname AS nvarchar(128);

SET @cur = CURSOR FORWARD_ONLY STATIC READ_ONLY FOR SELECT name FROM sys.tables t WHERE t.name LIKE N'BACKUP_%' AND t.type=N'U';

OPEN @cur;
FETCH NEXT FROM @cur INTO @tblname;

WHILE @@FETCH_STATUS = 0
BEGIN
    IF OBJECT_ID(N'dbo.' + @tblname, N'U') IS NOT NULL 
    	EXECUTE(N'DROP TABLE dbo.' + @tblname);
	FETCH NEXT FROM @cur INTO @tblname;
END;
CLOSE @cur;

GO
```

###IF EXISTSの利用
IF EXISTS を利用するとテーブルが存在する場合のみ削除してくれます。[^1]

```sql
    --IF OBJECT_ID(N'dbo.' + @tblname, N'U') IS NOT NULL 
    --	EXECUTE('DROP TABLE dbo.' + @tblname);
	EXECUTE('DROP TABLE IF EXISTS dbo.' + @tblname);
```

[^1]: SQL Server 2016(13.x)以降で利用可能です。
Macでアプリの強制終了をより楽にしたい人へ

#Macのアプリ強制終了の仕方

Macでのアプリ強制終了はcmd + option + escやdockから右クリックなどといっぱいありますが、
今回は自分的に今までより簡単にできるやり方を紹介したいと思います。
<img width="227" alt="スクリーンショット 2018-11-12 12.10.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/213712/27a92b99-d469-a0b9-08ab-0a4f3389a14b.png">
　      


#cmd + tabでアプリ移動中に強制終了
自分はアプリ間を移動する時よくcmd+tabを使っているのですが、ここから強制終了できます！
手順としては
・cmd+tabでアプリを選択画面を出す
・削除したいものの前でtabだけ離す（cmdは押したままです）
・でqを押す
そうするとアプリが強制終了してくれます！
そのままアプリも移動できる！！一石二鳥（笑）

####終わりに

知ってる人が多かったらすみません。
ただ、自分ができた時に感動したのでまだ知らない人がいたら使ってみてください^^
Laravel5.7における複合プライマリキーを持つテーブルへの挿入と更新

# Laravelと複合プライマリキー
既存の複合プライマリキーを持つMySQLのテーブルに対する操作で混乱したので備忘録。
複合キーはLaravelでは有名なネタのようですが、幸いにもこれまで対応する機会はありませんでした。
事情によりサロゲートキーは導入できない前提です。

**mpywさんよりコメントで便利なトレイトを教えていただいたので、公開半日もせず大幅に改稿しました。**

# HasCompositePrimaryKey トレイトの導入
mpywさんより教えていただいたトレイトです。
https://github.com/mopo922/LaravelTreats/blob/master/src/Model/Traits/HasCompositePrimaryKey.php

含まれている LaravelTreats をまるごとインストールします。

```
$ composer require mopo922/laravel-treats
```

Model にトレイトを挿入します。

```php:KeywordItem.php
class KeywordItem extends Model
{
    use \LaravelTreats\Model\Traits\HasCompositePrimaryKey;

    /**
     * モデル主キー
     * @var int
     */
    protected $primaryKey = [ 'keyword_id', 'item_id' ];

    /**
     * 複数代入する属性 (データの代入が必須)
     *
     * @var array
     */
    protected $fillable = [ 'keyword_id', 'item_id' ];
}
```

これで動いてくれたら嬉しいコードで問題なく挿入・更新ができるようになりました。

```php		
// new OK, update OK
$new = KeywordItem::firstOrNew([ 'keyword_id' => $keyword_id, 'item_id' => $item_id ]);
$new->status = $status;
$new->save();
```

わーい!!

**追記。**
https://github.com/mopo922/LaravelTreats/issues
現在、chunkまわりで不具合もあるようなので利用時は気をつけてください。

# HasCompositePrimaryKey トレイト導入前の解決法
以下は、トレイト導入前の投稿となります。

Modelの定義は以下の通り。

```php:KeywordItem.php
class KeywordItem extends Model
{
    /**
     * モデル主キー
     * @var int
     */
    protected $primaryKey = [ 'keyword_id', 'item_id' ];

    /**
     * increment無効化
     */
    public $incrementing = false;

    /**
     * 複数代入する属性 (データの代入が必須)
     *
     * @var array
     */
    protected $fillable = [ 'keyword_id', 'item_id' ];
}
```

新規、更新ともに成功。

```php
// new OK, update OK
$new = KeywordItem::where([ 'keyword_id' => $keyword_id, 'item_id' => $item_id ]);
if ($new->count() === 0) {
    $new = new KeywordItem([ 'keyword_id' => $keyword_id, 'item_id' => $item_id ]);
    $new->status = $status;
    $new->save();
}
else {
    $new->update(['status' => $status]);
}
```

新規はうまくいくものの、更新した値が反映されない。

```php
// new OK, update NoUpdate
$new = KeywordItem::where([ 'keyword_id' => $keyword_id, 'item_id' => $item_id ])->first();
if (is_null($new)) {
    $new = new KeywordItem([ 'keyword_id' => $keyword_id, 'item_id' => $item_id ]);
    $new->status = $status;
    $new->save();
}
else {
    $new->update(['status' => $status]);
}
```

新規はうまくいくものの、更新で例外エラーが発生。

```php		
// new OK, update Error
$new = KeywordItem::firstOrNew([ 'keyword_id' => $keyword_id, 'item_id' => $item_id ]);
$new->status = $status;
$new->save();
```

新規、更新ともに例外エラーが発生。ただし新規の例外はINSERT後となる。

```php
// new Error(but after insert), update Error
$new = KeywordItem::firstOrCreate([ 'keyword_id' => $keyword_id, 'item_id' => $item_id ]);
$new->status = $status;
$new->save();
```

新規は挿入されないし、更新も値が反映されない。

```php
// new NotInsert, update NoUpdate
KeywordItem::updateOrCreate(
    ['keyword_id' => $keyword_id, 'item_id' => $item_id],
    ['status' => $status]
);
```
以上です。
なんだか、直接クエリ書く方がシンプルな気がしてきます。
【cakephp3】定数の扱い方を自分なりに考えてみた。

#動作環境
PHP 5.6
cakephp3

#内容
定数について何度か考えたり、参考になるものを探しました。
ですが、納得のいくものが見つからず
自分なりに定数の扱い方を考えてみました。

##ディレクトリ構成
app/config/Configure/

calephpでは Configure::read(); で呼び出すので、config下にConfigureディレクトリを作成して、そこに定数を置くことにしました。

##Configure配下のファイルを読み込む
正直あんまり納得言ってないけど今回はこんな感じにしました。
もし、他によい方法あれば教えてください・・・。

```configure.php
<?php

$const_files = scandir(CONFIG. "Configure");

foreach ($const_files as $const_file) {
    if($const_file === ".") continue;
    if($const_file === "..") continue;
    if($const_file === "configure.php") continue;
    require(CONFIG. "Configure/". $const_file);
}

```

## bootstrap.phpで読み込む

```app/config/bootstrap.php
try {
    Configure::config('default', new PhpConfig());
    Configure::load('app', 'default', false);

    // 追加部分
    Configure::load('Configure/configure', 'default');

} catch (\Exception $e) {
    exit($e->getMessage() . "\n");
}
```

##Configure下に定数を扱うファイルを置く


```const.php
<?php
$config = [
    "site" => [
        "name" => "サイト名",
    ],
];
```

## 定数の呼び出し

```Controller.php
use Cake\Core\Configure;
$site_name = Configure::read('site.name');
```
PlayFab始めました


#そもそもPlayFabとは
リアルタイムにクラウド型ゲームの運営を行うためのバックエンドプラットフォームです。
ログインや課金回り、更新やイベントの分リアルタイム析などのサービスを提供しています
基本的な機能は無料で使えますが、追加機能を利用したい場合は課金が必要になります。



#早速登録してみる

(1)PlayFabのサイトにアクセス
https://playfab.com/
![playfab01.png](https://qiita-image-store.s3.amazonaws.com/0/313446/cd1b61c1-d0f9-12c0-934e-926c944da6c4.png)

(2)メールアドレスなど必要事項を入力して無料アカウントを作成
　「無料アカウントを作成」をクリックするとメールアドレスの確認が行われる
  　すでにMicrosoftアカウントを持っている場合は「Microsoftアカウントでサインインする」をクリックする
![playfab02_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313446/4c2e262f-5ef4-7715-a0d2-d491139a6024.png)

(3)ログインするとポータル画面で自分の管理するゲームを確認することができる
![playfab03.png](https://qiita-image-store.s3.amazonaws.com/0/313446/cc7d6735-f2c2-749a-73b3-ca5880fa311d.png)

(4)英語設定だとわかりにくいため、言語設定を変更する
　 ログインユーザ名の横から「My Profile」を選択
![playfab04.png](https://qiita-image-store.s3.amazonaws.com/0/313446/107e22cd-b709-731a-4d2d-f4af766b3537.png)

(5)Languageを「日本語」、TimeZoneを「(UCT＋09：00) Osaka,Sapporo,Tokyo」に変更
※二段階認証も入れたほうが良いのでチェックを入れ、Google Authenticatorなどで認証できるようにする
![playfab05.png](https://qiita-image-store.s3.amazonaws.com/0/313446/7c7ac849-55e4-053c-0042-443984bcaf06.png)

(6)日本語に変更され準備完了！
![playfab06.png](https://qiita-image-store.s3.amazonaws.com/0/313446/7bdf121b-e301-0a79-18b3-f333983b171e.png)
Squid の設定と使い方

Squid をプロキシサーバーとして設定して使う方法です。

Ubuntu 18.10 にインストールしました。

```bash
sudo apt install squid
```

インストールすると、起動しています。

設定ファイルのうち、次を変更します。

```text:/etc/squid/squid.conf
#http_access allow localhost
http_access allow all
#http_access deny all
```

>これは全てのアクセスを受け入れるので良い設定ではありません。運用する時は、再考する必要があります。

テストに使った squid.conf

```text:/etc/squid/squid.conf
acl localnet src 0.0.0.1-0.255.255.255	# RFC 1122 "this" network (LAN)
acl localnet src 10.0.0.0/8		# RFC 1918 local private network (LAN)
acl localnet src 100.64.0.0/10		# RFC 6598 shared address space (CGN)
acl localnet src 169.254.0.0/16 	# RFC 3927 link-local (directly plugged) machines
acl localnet src 172.16.0.0/12		# RFC 1918 local private network (LAN)
acl localnet src 192.168.0.0/16		# RFC 1918 local private network (LAN)
acl localnet src fc00::/7       	# RFC 4193 local private network range
acl localnet src fe80::/10      	# RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80		# http
acl Safe_ports port 21		# ftp
acl Safe_ports port 443		# https
acl Safe_ports port 70		# gopher
acl Safe_ports port 210		# wais
acl Safe_ports port 1025-65535	# unregistered ports
acl Safe_ports port 280		# http-mgmt
acl Safe_ports port 488		# gss-http
acl Safe_ports port 591		# filemaker
acl Safe_ports port 777		# multiling http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
include /etc/squid/conf.d/*
#http_access allow localhost
http_access allow all
#http_access deny all
http_port 3128
coredump_dir /var/spool/squid
refresh_pattern ^ftp:		1440	20%	10080
refresh_pattern ^gopher:	1440	0%	1440
refresh_pattern -i (/cgi-bin/|\?) 0	0%	0
refresh_pattern \/(Packages|Sources)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern \/Release(|\.gpg)$ 0 0% 0 refresh-ims
refresh_pattern \/InRelease$ 0 0% 0 refresh-ims
refresh_pattern \/(Translation-.*)(|\.bz2|\.gz|\.xz)$ 0 0% 0 refresh-ims
refresh_pattern .		0	20%	4320
```

Squid の再起動

```bash
sudo systemctl restart squid
```

サーバー内からのテスト

```bash
curl  --proxy http://localhost:3128 https://qiita.com
```

サーバー外からのテスト

```bash
curl  --proxy http://testserver.co.jp:3128 https://qiita.com
```
初心者　最小コードで学ぶ機械学習

機械学習わからなすぎるから、
グーグルのチュートリアル
コラボトリーで限界までまとめたったでぇ




https://colab.research.google.com/drive/1mxQL3u5qndfBx4_d9BfE0O-k-55ADnVG

アップルは０でオレンジが１という想定で学習させる

```python:tensorflow.py
from sklearn import tree# 学習機能を入れる
 
       # 　[重さg　,　1は滑らか0はゴツゴツ]
features = [[140, 1], [130, 1], [150, 0], [170, 0]]  # 学習材料設定
      #[ここでは0はアップルで1はオレンジ]上の値に対しての答えを入れてく
labels = [0, 0, 1, 1]# 学習の答え設定
 

clf = tree.DecisionTreeClassifier()  # 学習方法設定
clf = clf.fit(features, labels)  # 学習
 
      # 　[重さ160gで0はゴツゴツ]なのでオレンジ
print clf.predict([[160, 0]]) # 推定したいデータ入力
```
[1]

結果はオレンジっていうのがGOOGLE MLの最初のやつ



詳細はGOOGLE MLの動画で
Intellij IDEAでRailsプロジェクトのbundleができない

# 環境
- IntelliJ IDEA 2018.2.5 (Ultimate Edition)
- macOS 10.14.1
- Ruby 2.2.2

これらを使ってSDKとBundlerのパスは設定済み
https://www.task-notes.com/entry/20160508/1462676400
https://qiita.com/keitakn/items/76d6707db7d23fe4ca85
https://qiita.com/sunny4381/items/b9317d73b98eb1470140

# ~~原因~~
Ruby 2.4系からBundlerがdefaultのgemになったことによるRubyMineのバグらしい。。
https://intellij-support.jetbrains.com/hc/en-us/community/posts/360000609684-Cannot-find-bundler?page=1#community_comment_360000235919

# 追記
JRubyと認識されてたからだった。
https://www.task-notes.com/entry/20160508/1462676400
の「プロジェクトの作成パターン」の通りやればそのままできた。作成画面が微妙に違ってるので、自分の場合はこうだった。
<img width="744" alt="Screen Shot 2018-11-12 at 23.06.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/68213/0d4b49e3-b56c-7ed4-8519-e88dd69585a0.png">
Laravel SeederでFakerを使ってダミー画像作成

## これは何
LaravelのSeederでDB書き込みだけじゃなくて、ダミーの画像投稿ができたので記録です。

## 背景
ファイルダウンロードリンクのテストのために、ファイルアップロードをしておく必要がありました。今やっているプロジェクトではSeederでDBの中身を作成していましたが、画像実体はストレージに入れていなかったのでSeederを流した直後に画像ダウンロードを試すことができませんでした。
これまでにPHPUnitでのテストで画像アップロードはやっていたので、テストを流した後にダウンロードを試せましたが、ちょっと面倒なので最初から入っていて欲しいという気持ち。

## やり方
Faker はこちら https://github.com/fzaninotto/Faker
`composer require fzaninotto/faker --dev` とかでインストールして使用する。 


FileFactory.php を作成してアップロードする方法を定義しておく

```database/factories/FileFactory.php
<?php

use Faker\Generator as Faker;
use Illuminate\Http\UploadedFile;

$factory->define(Infra\EloquentModel\File::class, function (Faker $faker) {

    // ファイル実体の保存
    $fileRealPath = UploadedFile::fake()->create('tempfilename.pdf', 10)->store('private/files');

    return [
        'original_name' => $faker->unique()->realText(10),
        'content_type' => 'application/pdf',
        'storage_type' => 'local',
        'path' => $fileRealPath
    ];
});
```

DocumentFactory.php はFileFactoryを使用するやつ。DocumentSeederからFileFactoryを直接呼び出してもいいが、繰り返しSeederに同じコードを書かないために間に噛ませている。

```database/factories/DocumentFactory.php
<?php

use Faker\Generator as Faker;

$factory->define(\Infra\EloquentModel\Document::class, function (Faker $faker) {
    return [
        'file_id' => function () {
            // 上のFileFactoryで設定したものを呼び出し。ここらのid()を呼び出すコードは環境によって全然違うと思うのでよしなに
            return factory(\Infra\EloquentModel\File::class)->create()->toDomain()->id();
        },
        'title' => $faker->unique()->realText(20)
    ];
});

```

SeederでFactoryを呼び出して実際にファイル作成保存とDB保存

```database/seeds/DocumentSeeder.php

<?php

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Factory as Factory;

class DocumentSeeder extends Seeder
{
    public function run(Factory $factory)
    {
        // 登録したFactoryをofで呼び出し
        $factory->of(\Infra\EloquentModel\Document::class)->times(1)->create();
    }
}
```

DatabaseSeederからDocumentSeederの呼び出しも忘れずに

```database/seeds/DatabaseSeeder.php
    public function run() 
    { 
        $this->call(DocumentSeeder::class);
    }
```

あとは `artisan migrate:fresh --seed` でもやって適用（freshはDropテーブルするのでLocal環境以外で実行するときにはお気をつけて）
React.memoとReact.lazyの勉強まとめ

## React.memo
[Change logs](https://reactjs.org/blog/2018/10/23/react-v-16-6.html)

```
Class components can bail out from rendering when their input props are the same using PureComponent or shouldComponentUpdate.
Now you can do the same with function components by wrapping them in React.memo.

クラスコンポーネントは、入力プロンプトがPureComponentまたはshouldComponentUpdateを使用して同じ場合、レンダリングから救済することができます。
関数コンポーネントをReact.memoでラップすることで同じことができます。
```

わからん

[React.memo](https://reactjs.org/docs/react-api.html#reactmemo)

わかんねぇよ・・・

[React 16.6の新機能](https://qiita.com/jkr_2255/items/45079573e0691878eb541)

関数コンポーネントをクラスコンポーネントにできるってことか。

## React.lazy
[Change logs](https://reactjs.org/blog/2018/10/23/react-v-16-6.html)

```
You may have seen Dan’s talk about React Suspense at JSConf Iceland. 
Now you can use the Suspense component to do code-splitting by wrapping a dynamic import in a call to React.lazy().

あなたはDan’s talk about React Suspense at JSConf Icelandを見たかもしれません。
Suspence componentを使用して、React.lazy（）の呼び出しで動的インポートをラップすることで、コード分割を行うことができます。
```

わからん

[React.lazy](https://reactjs.org/docs/code-splitting.html#reactlazy)

他のjsファイルのcomponentを使う際に、`import`ではなく、クラス化で使えるようにするってことか。

```lazy.js
import OtherComponent from './OtherComponent'
//変更前

const OtherComponent = React.lazy(() => import('./OtherComponent'));
//変更後
```

```
This will automatically load the bundle containing the OtherComponent when this component gets rendered.

このコンポーネントがレンダリングされると、OtherComponentを含むバンドルが自動的にロードされます。


React.lazy takes a function that must call a dynamic import(). 
This must return a Promise which resolves to a module with a default export containing a React component.

これは、Reactコンポーネントを含むdefaultエクスポートを持つモジュールに解決するPromiseを返す必要があります。
```
[React 16.6の新機能](https://qiita.com/jkr_2255/items/45079573e0691878eb54)


返り値はPromiseを指定する。defaultからコンポーネントを取れるオブジェクトを返すから。

実際のコードはここを参照
[React 16.6で追加されたReact.Suspenseについて](https://qiita.com/yoshi_ksk/items/706acf084a7f2c560b26)
PHPの型はauto wiringのためにある

https://qiita.com/dossari-book-archive/items/ad4f7bcaaebca6281154
ここを読んで、既に該当部分は消えてたんだけど、コメントで漸進型付けが推されていたので気になった。
PHPの場合は他の言語と違って、厳密さや保守性のために型を書くのではなくて早く作るためとか楽をするために型を書く場合が多いんじゃないかなーと思う。


auto wiring については
http://blog.tojiru.net/article/444541164.html
ここが分かりやすい。
ここに書いてある通り、Javaのやり方でインターフェースを書いたりしても微妙で、面倒になることの方が多い気がする。


PHPのDIは

```php
class MyActionController
{
  public function index(Request $request, FooModel $fooModel)
  {
    // ...
  }
}
```

と書いたら何も設定していなくても自動的に`Request`や`FooModel`を持ってきてくれるという使い方で、別にインターフェースを利用した多態性のためにやっているわけではない。（フレームワークやライブラリの開発者でなければ）

```php
class FooModel
{
  public function __construct(Db $db, BarModel $barModel)
  {
    $this->db = $db;
    $this->barModel = $barModel;
  }
}
```
`FooModel` のコンストラクタがこんな感じになっているとすると、これも自動設定される（DI？）。`BarModel` の…という感じで連鎖的に次々自動設定される。自動設定のための設定ファイルは特に書かない。
大抵のフレームワークやコンテナはほとんどこの機能があるのではないかな。
Javaだともうちょっとインターフェースや依存関係をしっかり設計しようという気になるけども、PHPは実装クラスをそのまま持ってくる。インターフェースはあまり使わない。
他の漸進的型付けを扱う言語ではこういう使い方はしないよね？


まあauto wiringを使わない関数でも型を書いて静的チェックをすることもあるけど、静的チェックをしない人でもauto wiringはフレームワークが用意しているので知らずに使ってる場合が多いのではないかなという印象。


PHP7.4 で Typed Properties が入ったら、リクエスト変数のidからクラスプロパティのDB Entityクラスを自動設定しやすくなって、ますますauto wiringが捗る予感がする。


> 例えば、動的型付けなのに、静的型付けで扱うようなインターフェースを導入する思想が自分には理解できません。

この意見には基本的には賛成。例外は、PHPではフレームワークやライブラリが乱立する傾向にあるので、その乱立したフレームワークが共通のインターフェースを使ってくれていると混乱せずに済む。
プロジェクトの中で使う分にはあまり役に立たないけれど、各FW同士の多態性という面では役に立っている。
Python Dictionaryから 2D numpy array の変換方法

Dictionaryから２D arrayに変換する必要があったのでその方法のメモ

```
import numpy as np

myDict = {0: {0: 0, 1: 548, 2: 776, 3: 696, 4: 582},
          1: {0: 548, 1: 0, 2: 684, 3: 308, 4: 194},
          2: {0: 776, 1: 684, 2: 0, 3: 992, 4: 878},
          3: {0: 696, 1: 308, 2: 992, 3: 0, 4: 114},
          4: {0: 582, 1: 194, 2: 878, 3: 114, 4: 0}}

orderedNames = list(myDict.keys())
dataMatrix = np.array([list(myDict[i].values()) for i in orderedNames])
print(dataMatrix)

[[  0 548 776 696 582]
 [548   0 684 308 194]
 [776 684   0 992 878]
 [696 308 992   0 114]
 [582 194 878 114   0]]

```

ちなみに逆方向は、以下のコードでできます。
参照：https://stackoverflow.com/questions/42949309/convert-2d-numpy-ndarray-to-nested-dictionary

```
dict = {index:{i:j for i,j in enumerate(k) if j} for index,k in enumerate(array2D)}
print(dict)
```

たまに変換することがあるので、参照用メモ。
AWS初心者なのでまずはWordPressを入れてみる ① ～ by Intuz AMIでのログイン方法

# 基本はガイダンス通り

[AWSの10分間チュートリアル](https://aws.amazon.com/jp/getting-started/tutorials/)に沿えばかなり簡単にできる。
多分沿わなくてもすぐできる。AMI（セットアップ済みの設定）のどれが無料かは目立つ目印をつけていてくれるので、一年間忘れたりしていなければ課金はされない。

インスタンス作成も流石に早い。kvmで仮想ゲスト立てたり、少ないリソースをやりくりしたりポートフォワーディングを駆使したりしてVirtualBoxでマルチサーバー環境を構築していた時代は最早過去のものなのか…。

# ガイダンスと違ったところメモ（2018/11/12現在）

- WordPress AMIの提供元がガイダンスにあるBitNamiではなく、Intuzしかない
- ガイダンスとはadminのパスワードの初期値の探し方が違う

### WordPress AMIの提供元がガイダンスにあるBitNamiではなく、Intuzしかない

無料なのには変わりないので、おそらく大して問題なし。

### ガイダンスとはadminのパスワードの初期値の探し方が違う

ガイダンスではシステムログに書いてあるよ！と言っているが、ない。
これは[AWS MarketPlaceの該当AMIのページ](https://aws.amazon.com/marketplace/pp/B01N6ATJ9S)に書いてあった。

> Usage Instructions: Once the instance is running, enter the public ip provided by Amazon web services into your browser. You will then see the WordPress application. You have to wait for the health checks to pass. The default server administrator is 'admin' and your password is your instance id. You may change this username and password within the application settings. You can also access your instance via SSH using the username 'ec2-user' and your Amazon private key.

要するに、

`admin/[インスタンスID]`

でログインできる。
これでダッシュボードへのログイン、記事の投稿・削除を確認。

# ②以降に続きます（むしろそっちが本番）

予定：
②MySQLインスタンスを別途作成し、連携したWordPressを構築する
③S3ストレージを別途作成し、画像はS3に保存するように連携したWordPressを構築する
記事を投稿するときとかに使うリッチテキストが入力できるようなUIを

「WYSIWYG（ウィジウィグ）」と呼ぶらしい。

※以下のような感じのUIのこと
![image.png](https://qiita-image-store.s3.amazonaws.com/0/265544/7fd3eb89-532c-8b3a-78a6-f4e7d6b9a631.png)
LINE Messaging API から Dialogflow に Webhook してみる

# LINE Messaging API x Dialogflow 


このドキュメントは、[LINE Messaging API](https://developers.line.me/ja/docs/messaging-api/) と [Dialogflow](https://dialogflow.com/) のWebhook 連携方法および手順についてざっくり記述してます。


## LINE Messaging API から Dialogflow に Webhook してみる

### STEP 1: チャネルを登録する（LINE Messaging API） 

1. LINE Developersの公式ドキュメント「[Messaging APIを利用するには](https://developers.line.me/ja/docs/messaging-api/getting-started/)」に記載の手順に沿ってチャネルを作成する。

2. チャネルが作成出来たら、対象のプロバイダから作成したチャネル ページにアクセス
  ![](https://qiita-image-store.s3.amazonaws.com/0/81813/9e4f5dfd-1f22-882e-b4be-c2474bc042bd.jpeg)
  
3. 「チャネル基本設定」タブの「メッセージ送受信設定 > Webhook送信」を「利用する」に切り替える
  ![](https://i.imgur.com/HsIlKb7.png)

3. 「チャネル基本設定」にて、以下の3つの情報をコピーしておく。
  ※ Dialogflow とのWebhook連携で使用
  
| 区分 | 名称 | 説明 |
| -------- | -------- | -------- |
| 基本設定 | Channel ID     | チャネルを区別するための識別子 |
| 基本設定 | Channel Secret     | チャネル固有の秘密鍵 |
| メッセージ送受信設定 | アクセストークン（ロングターム）     | API利用に必要なトークン。 **※ 要発行** |


### STEP 2: Dialogflow の Integration を設定する

1. Dialogflow のダッシュボードメニューから、"Integrations" をクリック。 
2. グリッド形式の対応アプリ一覧から、LINEを選択してトグルチェックをONにする

![](https://i.imgur.com/6fUaoiy.png)

3. 表示されるダイアログに、前述のLINE Messaging APIの設定情報を入力する
   * **Channel ID**
   * **Channel Secret**
   * **Channel Access Token**

4. Webhook URL をコピー

5. STEP 1 で作成した LINE のチャネル ページに戻り、 コピーした Webhook URL を「チャネル基本設定」タブの「メッセージ送受信設定 > Webhook URL」に設定

6. ダイアログの「START」ボタンをクリックして、BOTを有効にする。
![](https://i.imgur.com/FkBdq0X.png)


### STEP 3: 接続を確認する

1. LINE のチャネル ページ の「LINEアプリへのQRコード > QR コード」を読み取って、アプリ検証ができる。
Javaの2次元配列（多次元配列）の要素数を動的にする

#始めに
Javaで普通に2次元配列を作ろうと思うと、第2要素の要素数が全て一定になってしまいますが、第2要素の要素数を第1要素や他の変数によって変える方法が分かったので共有しようと思います！

#通常の2次元配列の定義
```java
int[][] arrays = new int[m][n];
```

#第2要素が動的に決められる2次元配列の定義
```java
//2要素目の要素数が入った配列などを用意（なんでもいい）
int[] array = {2, 3, 5};
//1要素目だけ要素数を定義
int[][] arrays = new int[array.length][];
for (int i = 0; i < arrays.length; i++){
    //1要素目をfor文等で回しながら、2要素目の要素数を定義していく
    arrays[i] = new int[array[i]];
}

//おまけ
System.out.println(arrays.length);
for (int i = 0; i < arrays.length; i++){
    System.out.println(arrays[i].length);
}
//出力
//3
//2
//3
//5
```

#多次元配列
同じ様に

```java
int arrays[][][] =new array [m][n];
//省略
arrays[i][j] = new int[array[j]];
```
とやれば何次元でもできるはずです！（未確認）

#終わりに
この様に動的に要素数を変えることでより、配列がより便利になるかと思います！！
もし間違い等あればお気軽にコメント等下さい！！
Azure始めました

# まずはAzureを使い始めてみる
世の中AWSでゲームシステム作ってみようという記事は多いので
あえてAzureでやってみようという試みです。

### まずは無料登録
(1)Azureサイトで無料登録
https://azure.microsoft.com/ja-jp/ にアクセスし「無料で始める」をクリック
![azure01.png](https://qiita-image-store.s3.amazonaws.com/0/313446/cefef69f-db86-d710-9887-b8a79eefec22.png)

(2)さらに無料で始めるをクリックする
![azure02.png](https://qiita-image-store.s3.amazonaws.com/0/313446/672964c6-7be1-5bda-2719-4fe2524b5a9c.png)

(3)Microsoftアカウントでログイン
　 持っていない場合は新規作成
　 ※新規登録手順は割愛
![azure03.png](https://qiita-image-store.s3.amazonaws.com/0/313446/e623ee2d-8bd6-d823-84c8-3b6855723051.png)

(4)ポータルに移動をクリック
　　早速初めてみる！
![azure04.png](https://qiita-image-store.s3.amazonaws.com/0/313446/5f08f80a-4f32-ca0f-7263-47f5b64d8dfc.png)

(5)ログインできたので早速初めて見る
![azure05.png](https://qiita-image-store.s3.amazonaws.com/0/313446/da091a3b-5000-24a2-1247-1abc19d1ef6a.png)


あまりほかの人の記事との差別化ができてませんが、
まぁ今後に向けてということで
Rで非線形近似

# Rで任意の関数によるfitting curveを描く

- 目的の関数でfittingしたい。
- nls関数を使う。
- nlsは，自由に関数式を指定することができる非線形回帰分析の関数である。
- nls では、最小2乗法で係数 (パラメータ) を求めている。

## nls関数の書き方（引数）

`nls(formula,start,trace) `

- 例

`fm<-nls(y1~a*x1^(3/2)+b,start=c(a=1,b=1),trace=TRUE)`

- formula : fittingしたいデータとの関係式を具体的に書く。ここで，y1とx1がデータである。aとbはパラメータである。
- start : パラメータの名前とその初期値を指定する。初期値は、データ解析者の勘と経験に頼るのが殆どである。
-  trace : パラメータの計算の過程を返すか否かを指定する引数である。計算過程の結果を返す場合は、TRUE(あるいはT)を指定する。デフォルトはFALSEになっている。

## テストデータ

以下のデータを使う。

| x      | y    |
|:-----------------:|:------------------:|
|0|3.37|
|4|-2.48|
|10|-3.92|
|20|-4.30|
|25|-5.72|
|30|-6.54|
|40|-7.83|

- エクセルで線形近似

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99215/25aa365a-95b3-f2ba-3332-9e80de13da91.png)

## 近似に使いたい関数

$y=ax^\frac{3}{2}+b$

- つまり，aとbのパラメータを決めたいということである。

## コード

```R:fitting.r

x1<-c(0,4,10,20,25,30,40)
y1<-c(3.37E+00,-2.48E+00,-3.92E+00,-4.30E+00,-5.72E+00,-6.54E+00,-7.83E+00)

fm<-nls(y1~a*x1^(3/2)+b,start=c(a=1,b=1),trace=TRUE)

plot(x1,y1)
lines(x1,fitted(fm))
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99215/088f39cf-1498-369c-829f-5c8186ab9212.png)

## 決定されたパラメータの値を見る

- summary関数を使う。

```
> summary(fm)

Formula: y ~ a * x^(3/2) + b

Parameters:
  Estimate Std. Error t value Pr(>|t|)  
a -0.03254    0.01015  -3.204   0.0239 *
b -0.79665    1.30549  -0.610   0.5684  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2.3 on 5 degrees of freedom

Number of iterations to convergence: 1 
Achieved convergence tolerance: 1.527e-07
```

## fitting curveの各点の値を取得する 

```R
 data.frame(fitted(fm))
```

```
> data.frame(fitted(fm))
  fitted.fm.
1 -0.7966525
2 -1.0569395
3 -1.8255273
4 -3.7067501
5 -4.8636375
6 -6.1428431
7 -9.0276515
```

7つのデータは，x1のそれぞれの位置でのfitting curve上の値を出力している。
インプットテストデータとの相関係数を計算すると，0.82であった。

## 非線形近似曲線を滑らかにプロットする

方法は2つある。
(1) fitting curveの出力するデータポイントを細かく刻む。
(2) fitting curveのparameterから関数そのものをプロットする。

どちらも綺麗な曲線が描ける。
しかし，(1)の場合は predict 関数を用いるが，fittingに用いたinputデータの値の範囲内でしかプロットできない。
したがって，(2)の方が万能である。以下に例を示す。

```R:fitting02.r
x0<-c(0,4,10,20,25,30,40)
y0<-c(3.37E+00,-2.48E+00,-3.92E+00,-4.30E+00,-5.72E+00,-6.54E+00,-7.83E+00)

x1<-c(4,10,20,25,30,40)
y1<-c(-2.48E+00,-3.92E+00,-4.30E+00,-5.72E+00,-6.54E+00,-7.83E+00)

fm1<-nls(y1~a*x1^(3/2)+b,start=c(a=1,b=1),trace=TRUE)

plot(x0,y0)
#lines(x1,fitted(fm1))


# For high resolution
## (1) Try1: generation of many points
## *** can plot only range of input data
#r <- range(x1)
#x2 <- seq(r[1],r[2],length.out=200)
#y2 <- predict(fm1,list(x1=x2))
#lines(x2,y2)

## (2) Try2
## *** just plot the function
a1 <- coef(fm1)[1]
b1 <- coef(fm1)[2]
lines(x<-c(0:40),a1*x^(3/2)+b1)
```

この例では，最初のデータはフィッティング解析から除外してある。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99215/4bc739b7-9ef1-6300-34c3-c00ff8d62556.png)


## 参考

- nls 関数の基本的な使い方

https://www1.doshisha.ac.jp/~mjin/R/Chap_17/17.html

- 非線形近似曲線を滑らかにプロットする

https://stackoverflow.com/questions/9918807/how-get-plot-from-nls-in-r
[Xcode]ColorSetで色指定を便利に（小ネタ）

iOS11から使えるColorSetで、UIColorに定義されている色を追加してみました。

![スクリーンショット 2018-11-12 10.46.56.png](https://qiita-image-store.s3.amazonaws.com/0/20784/4427b365-96d9-a0e6-831a-8f73d65787bc.png)

というか、なぜこの色指定はRecentlyUsedColorsと、灰色ばっかりのiPhoneSDKで構成されてるんでしょうか。もちろんカラーパレットを出せば全部出せるんですが。

## ColorSetの設定が面倒くさい問題

xcassetsを作成して、Finderで開き、中身をコピペしたらそのまま使えるようです
なので複数プロジェクト用に１個作っておくと楽です

コピペ元置いておきます
https://github.com/osanaikoutarou/ColorDefineSample

## WebSafeColor256色全部入れてみる

![スクリーンショット 2018-11-12 10.46.20.png](https://qiita-image-store.s3.amazonaws.com/0/20784/f91024ef-e169-7b20-a215-8c6bac5f1793.png)

これはやりすぎ？
ColorSetの定義はjsonでされているため、割と簡単にカラーコードから生成できました
まあこれもカラーパレット開けば全部指定できるんですが
GoでMySQL接続するメモ

# これはなに
Go言語でMySQLに接続する場合に筆者が設定している項目です。

# 前提
動作確認はしていないですが、JSON型を採用したいのでMySQL 5.7以降の話です。
InnoDBです。MyISAMなんて知りません。

# 利用ライブラリ
StructとDBのつなぎには[sqlx](https://godoc.org/github.com/jmoiron/sqlx)を採用します。

```golang
import (
        "database/sql"
        _ "github.com/go-sql-driver/mysql" // Using MySQL driver
        "github.com/jmoiron/sqlx"
)
```

# 接続部分

```golang
// NewMySQL is create connection to MySQL using sqlx
func NewMySQL(dsn string) (*sqlx.DB, error) {
        DB, err := sqlx.Open("mysql", dsn)

        if err != nil {
                return nil, err
        }
        err = DB.Ping()
        if err != nil {
                return nil, err
        }

        return DB, nil
}
```

# DSN
[DSN (Data Source Name)](https://github.com/go-sql-driver/mysql#dsn-data-source-name)の仕様

```
[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...&paramN=valueN]
```

## オプションパラメータについて
DB NAMEのあとにクエリストリングらしきものを書くとDB接続オプションになるので、MySQLの接続オプションを利用できる。

- `parseTime=true`
    - sqlxを使っていて、bindする先のStructで`time.Time`を受け取れるようになる便利
- `autocommit=0`
    - rollback忘れとかこわいので、、
- `sql_mode=%27TRADITIONAL,NO_AUTO_VALUE_ON_ZERO,ONLY_FULL_GROUP_BY%27`
    - `%27`はダブルクオートのエスケープ
    - [kamipo TRADITIONAL](http://www.songmu.jp/riji/entry/2015-07-08-kamipo-traditional.html)
- `read_only=ON`
    - リード用DBとかを用意するけど開発環境で2つDBを用意するのが面倒なのでオプションでRead_onlyにすることがある

## DSN環境変数スニペット

```shell
export MYSQL_HOST="127.0.0.1"
export MYSQL_TCP_PORT="3306"
export MYSQL_PWD=""
export MYSQL_USER="root"
export DB_NAME="hogedb"
export DSN="${MYSQL_USER}:${MYSQL_PWD}@tcp(${MYSQL_HOST}:${MYSQL_TCP_PORT})/${DB_NAME}?parseTime=true&autocommit=0&sql_mode=%27TRADITIONAL,NO_AUTO_VALUE_ON_ZERO,ONLY_FULL_GROUP_BY%27"
```
ブラウザのコンソールへ文字エンコードについての警告が表示されたときの対処


警告

```
HTML ドキュメントの文字エンコーディングが宣言されていません。
ドキュメントに US ASCII 外の文字が含まれている場合、ブラウザーの設定によっては文字化けすることがあります。
ページの文字エンコーディングはドキュメント中または転送プロトコルで宣言されなければなりません。
```

対処
HTMLのhead部にて文字コードを指定する。

```
<meta charset="utf-8"/>
```

参考
W3C
https://www.w3.org/International/questions/qa-html-encoding-declarations.ja
【Vagrant】Windows上でVagrantをワンクリックで起動させるバッチ「Vagrant Launcher」


# コマンドを打つのが煩わしい

毎回コマンドプロンプト開いて～プロジェクトのディレクトリへ移動して～`vagrant up`コマンド叩いて～
という一連の動作を行うのが苦痛なのでこの動作を自動でするようにバッチファイルつくります（Win限定）

**2019/03/26**：設定ファイルも実行ファイルも1ファイルにまとめた[VLauncher](https://github.com/sola-msr/VLauncher)作りました。

# ソースコード

**パスの設定ファイル**

```config.bat
@echo off

REM --------------
REM config file
REM --------------

cd /d %~dp0

REM Directory with virtualization software (VirtualBox.exe)
REM (* It may be possible to use VMware, but I have not tried it.)
SET VIRTUALIZATIONSOFTWARE_DIR=

REM Project directory
SET PROJECT_DIR=
```

`PROJECT_DIR`には**Vagrantfile**があるプロジェクトのフォルダパス、
`VIRTUALIZATIONSOFTWARE_DIR`には**VirtualBox.exe**があるフォルダパスを記述してください。

`VIRTUALIZATIONSOFTWARE_DIR`に記述するフォルダパスの例：

```
SET VIRTUALIZATIONSOFTWARE_DIR=C:\Program Files\Oracle\VirtualBox
```

以下はクリックする**本体のバッチファイル**

```vagrant_launcher.bat
@echo off
REM Vagrant Launcher

CALL config.bat

echo **** Vagrant Launcher ****

echo Vagrant Launcher is executeing...

cd /d %~dp0

cd %VIRTUALIZATIONSOFTWARE_DIR%

REM * By default it is written assuming to use VirtualBox.
start VirtualBox.exe

cd %PROJECT_DIR%

echo vagrant up command execute.
vagrant up

cmd /k cd %PROJECT_DIR%
```

↑の二つのファイルを同じところにおいて、
**vagrant_launcher.bat**を実行してください。

# バッチファイルを作るのもめんどくさい

つ [sola-msr/Vagrant-Launcher](https://github.com/sola-msr/Vagrant-Launcher)

上の1ファイル版
つ [sola-msr/VLauncher](https://github.com/sola-msr/VLauncher)


# おわり
-  VMwareでも動くかもしれませんが試してないです
- 何となく作ってみましたけどWindowsのbatchfileはよくわからないすね
VSCodeで最初にやること

# 日本語化
1. 拡張機能「Japanese Language Pack for VS Code」をインストール
2. VSCode上で「Ctrl+Shift+P」を押してコマンドパレットを開く
3. Configure Display Languageを選択
4. locale.jsonが開く
5. localeをjaに設定

# Emacsをインストール
- 拡張機能「Emacs Friendly Keymap」をインストール
- でもctrl+v, ctrl+sはwindows系を使いたい

###ctrl+vをペーストにしたい場合

```json:\Users\hoge\.vscode\extensions\lfs.vscode-emacs-friendly-0.8.2\package.json
{
    "key": "ctrl+v",		
    "command": "emacs.C-y",
    "when": "editorTextFocus && !editorReadonly"
}
```

### ctrl+sを保存にしたい場合

```json:\Users\hoge\.vscode\extensions\lfs.vscode-emacs-friendly-0.8.2\package.json
{
    "key": "ctrl+s",
    "command": "workbench.action.files.save",
    "when": "editorTextFocus"
}
```

# ターミナルをanacondaに変更
起動スクリプトを下記に配置


```python:\Users\hoge\Anaconda3\envs\anaconda3.bat
%windir%\System32\cmd.exe "/K" C:\Users\hoge\Anaconda3\Scripts\activate.bat C:\Users\hoge\Anaconda3
```

VSCode > ファイル > 基本設定 > 設定 で下記を追加

```json:UserSettings
{
    "python.pythonPath": "C:\\Users\\hoge\\Anaconda3\\pythonw.exe",
    "terminal.integrated.shell.windows": "C:\\Users\\hoge\\Anaconda3\\envs\\Anaconda3.bat",
}
```
ctrl+@ でターミナルを起動
レビューまたはフィードバックダイアログを表示するライブラリを公開しました


```
「アプリ楽しんでる？」
はい → ストアでのレビューや評価を依頼する
いいえ → メールや独自画面での改善点や要望を依頼する
```
この形式のレビュー促進ダイアログを弊社[応援navi](https://play.google.com/store/apps/details?id=jp.co.runners.ouennavi&hl=ja)というアプリに実装したところ、以下のように累計評価が1年間で3.8から4.4まで上昇しました。
また毎年2月にはある大規模マラソン大会が開催されるのですがその月のレビュー数自体も2017年は10件であるのに対し、ダイアログ実装後の2018年は119件と10倍以上に増えました。


![r-navi-review.png](https://qiita-image-store.s3.amazonaws.com/0/18273/d8a6c36f-68f7-0cfd-3385-20d7055a5686.png "r-navi-review.png")


今回別のアプリにもこのレビュー促進ダイアログを実装することになり、ちょうどいい機会だったのでライブラリ化してOSSとして公開しました。

# リポジトリ
https://github.com/r-bies/RateOrFeedback

ページは英語になっていますが、issueやプルリクは日本語でおｋ

# 使い方
## 依存関係
build.gradleに以下を追記します。

```
implementation 'jp.co.runners:rateorfeedback:0.0.1'
```

## 呼び出し
ダイアログを表示したいタイミングで以下のように呼び出します。

```kotlin
RateOrFeedback(this)
        // レビュー用ストアURL
        .setPlayStoreUrl("https://play.google.com/store/apps/details?id=com.google.android.gm")
        // 改善点・要望の送信先メールアドレス
        .setFeedbackEmail("email@example.com")
        // ダイアログを表示する
        .show()
```

## オプションなど
```kotlin
RateOrFeedback(this)
        // レビュー用ストアURL
        .setPlayStoreUrl("")
        // 改善点・要望の送信先メールアドレス
        .setFeedbackEmail("email@example.com")
        // [showIfNeedsで使用されます]
        // 一度、評価するか改善点を送信するを選択した場合、それ以降はダイアログが表示されません。
        // この値をインクリメントすることで再度ダイアログが表示されるようになります。
        .setReviewRequestId(0)
        // [showIfNeedsで使用されます]
        // 前回ダイアログを表示してから次にダイアログを表示してよいタイミングまでの期間です。
        .setIntervalFromPreviousShowing(60 * 60 * 24 * 7)
        // [showIfNeedsで使用されます]
        // アプリをインストールしてから、ここで指定された期間はダイアログを表示しません。
        .setNotShowTermSecondsFromInstall(60 * 60 * 24 * 7)
        .setAskLikeAppDialogMessage("このアプリを楽しんでいますか?")
        .setAskLikeAppDialogPositiveTitle("楽しい!")
        .setAskLikeAppDialogNegativeTitle("そうでもない")
        .setAskLikeAppDialogOnPositive {
            // レビュー依頼ダイアログを表示する代わりに何かしたい場合は上書きしてください
        }
        .setAskLikeAppDialogOnNegative {
            // 改善点・要望依頼ダイアログを表示する代わりに何かしたい場合は上書きしてください
        }
        .setRequestReviewDialogMessage("それはよかった！よければストアでレビューして頂けないでしょうか？")
        .setRequestReviewDialogPositiveTitle("レビューする!")
        .setRequestReviewDialogNegativeTitle("今はしない)
        .setRequestReviewDialogOnPositive {
            // レビュー依頼でレビューする!を選択された場合の操作を上書きします
        }
        .setRequestReviewDialogOnNegative {
            // レビュー依頼で今はしないを選択された場合の操作を上書きします
        }
        .setRequestFeedbackDialogMessage("改善点や要望を送信しますか？")
        .setRequestFeedbackDialogPositiveTitle("送信する!")
        .setRequestFeedbackDialogNegativeTitle("今はしない")
        .setRequestFeedbackDialogOnPositive {
            // 改善点や要望を送信する!を選択された場合の操作を上書きします
        }
        .setRequestFeedbackDialogOnNegative {
            // 改善点や要望依頼ダイアログでいまはしないを選択された場合の操作を上書きします。
        }
        // 条件次第でダイアログを表示する
        .showIfNeeds()
```
Git LFS で次のエラーメッセージが出たときの一発対処法：Encountered 3 file(s) that should have been pointers, but weren't:

git-lfs 使ってるディレクトリをチェックアウトしたり、ブランチ移動してたりするとたまにこうなる

```
Encountered 1 file(s) that should have been pointers, but weren't:
	Assets/xxx.png
```

チーム内に git-lfs 有効にしてない人がいたり、たまたまマージのタイミングでポインタになってないファイルがあるのが原因です。

TL;DR;
===
```bash
git update-index --assume-unchanged -- 対象のファイル

# 量が多いとき
git status -s | cut -c 4- | xargs git update-index --assume-unchanged
```

根本解決
===
.gitattributes では git-lfs 対象なのにポインタになってないファイルがあるのが原因です。
まとめて LFS 化しましょう。

```bash
rm .git/index && git reset
```
Mac App – Slack でチャンネル名のエイリアスを作る方法 (チャンネルはリダイレクトされる)

# 注意

- Macアプリでの挙動確認。
- Windowsでは動いていないかも知れない。

# チャンネル名を変更しても、Slackは以前のチャンネル名を覚えている

2018年11月現在。

クイックスイッチャー(チャンネルスイッチャー)で1個前、2個前のチャンネル名を入力しても、新しいチャンネル名がヒットするのを確認した。


# 最新 `#times-yumainaura`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/7dd94bf6-d481-28e9-c0bd-d8382730031b.png)


# 1個前 `#times-inaura`


![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/bfe96986-d3de-d118-fc5a-ad92d06492b3.png)

# 2個前 `#times-yinaura`

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/d3f884bd-bed7-d3e4-f7ce-f5eca2fba244.png)


エイリアスがチェーンしているというか、リダイレクトのリダイレクトというか、多重的に「過去のチャンネル」を覚えている気がした。

# iPhoneアプリでは未対応の模様

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/04239a79-023f-4b15-a036-7a9dba57f71a.png)



# 環境

- Mac App

# あわせて読みたい？

- [Slackのヘビロテ・チャンネルを探しやすくて業務効率を2億倍上げよう。クイックスイッチャー力を上げよう。 - Qiita](https://qiita.com/YumaInaura/items/9cfddde788b666c470e1)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Slackでreactionしてくれた人の情報を集める方法

## はじめに
- Slackでreactionしてくれた人の情報を集めたかった
- マウスオーバーでも誰がリアクションしたかは確認できるけどユーザIDを正確に集めたかったので目ではやりたくない
- プログラマたるもの楽をするために苦労をしたい

![Screenshot from 2018-11-11 01-36-41.png](https://qiita-image-store.s3.amazonaws.com/0/3507/20a0e6f2-7db0-f66f-6ee2-a4ffc3d78ff4.png)

## SlackのAPIを使う
- reactions.getがあるのでこれを使えばよさそう
https://api.slack.com/methods/reactions.get/test
![Screenshot from 2018-11-11 01-55-43.png](https://qiita-image-store.s3.amazonaws.com/0/3507/95be28fa-a518-1b3c-6e8e-6bc6dec92bac.png)

- Required Argumentがtokenのみなので、このまま叩けばなんらか情報が取れるかと思ったけど以下レスポンスが返ってきた

```
{
    "ok": false,
    "error": "no_item_specified"
}
```
- アイテムを特定できないとダメそうですね
  - アイテムはこいつらを指しているらしい (file, file comment, channel message, group message, or direct message)
- 今回はchannel messageを特定できれば良いのでtimestampを調べることにした
- messageのURLをコピーするとチャンネルIDとタイムスタンプがついている
    - このような感じ https://XXXXXXXX.slack.com/archives/C1234567890/p1541732787005700
    - reactions.getが要求する形式に合わせる `p1541732787005700` -> `1541732787.005700`
- chanMel とtimestampを設定してAPIを叩いてみたら欲しい情報が得られた
    - どうやらchannel messageの場合はchannelとtimestampは必須らしい（APIドキュメントのErrorsに書いてある）

```
            {
                "name": "woman-gesturing-ok::skin-tone-4",
                "users": [
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890",
                    "W1234567890"
                ],
                "count": 19
            }
```
※ ユーザIDはマスク済み

# まとめ
- reaction情報を集めたいメッセージのURLをコピーする
- タイムスタンプのフォーマットをAPIに合わせる p1541732787005700` -> `1541732787.005700`
- channelとtimestampを使ってreactions.get apiをコールする
GCE > Wordpress > ContactForm7


Google Compute Engineで動作するWordpressのContactForm7でメール送信



## 登録
Cloud Marketplace のSendGrid登録

https://console.cloud.google.com/marketplace/details/sendgrid-app/sendgrid-email

無料プランで開始


## SendGridAPIキーの登録

[SendGrid APIキーの登録](https://app.sendgrid.com/settings/api_keys)



## プラグイン

sendgridで検索してsendgridプラグインを入れる
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/4f8498f6-ee0a-76f0-c45e-88f6e142962d.png)

### プラグイン設定

設定 > Sendgrid

APIキー等々を入力
![image](https://qiita-image-store.s3.amazonaws.com/0/49910/32a2b7f6-82eb-1b8e-4025-e47de2fae8f2.png)




## 参考


[SendGrid でのメールの送信  |  Compute Engine ドキュメント  |  Google Cloud](https://cloud.google.com/compute/docs/tutorials/sending-mail/using-sendgrid)



[Setup Contact Forms for WordPress on Google Cloud – One Page Zen](https://www.onepagezen.com/configure-contact-forms-wordpress-google-cloud/)



[KUSANAGI × IDCFクラウド × SendGrid ハンズオンセミナーを開催しました \| SendGridブログ](https://sendgrid.kke.co.jp/blog/?p=4886)
Pythonでブロックチェーンを組んでみる実験

# pythonで遊ぶ機会があったのでお遊びで作ったもののメモ

``` py
import hashlib
import json
import datetime
import pickle

class Block:
    def __init__(self, index, timestamp, transaction, previous_hash):
        self.index = index
        self.timestamp = timestamp
        self.transaction = transaction
        self.previous_hash = previous_hash
        self.difficulty = 4 #難易度を追加
        self.property_dict = {str(i): j for i, j in self.__dict__.items()}
        self.now_hash = self.calc_hash()
        self.proof = None # プルーフを追加
        self.proof_hash = None # プルーフを追加して計算したハッシュ
 
    def calc_hash(self):
        block_string = json.dumps(self.property_dict, sort_keys=True).encode('ascii')
        return hashlib.sha256(block_string).hexdigest()
 
    # プルーフの検証用関数
    def check_proof(self, proof):
        proof_string = self.now_hash + str(proof)
        calced = hashlib.sha256(proof_string.encode("ascii")).hexdigest()
        if calced[:self.difficulty:].count('0') == self.difficulty:
            self.proof_hash = calced
            return True
        else:
            return False
 
    # プルーフを採掘するための関数
    def mining(self):
        proof = 0
        while True:
            if self.check_proof(proof):
                break
            else:
                proof += 1
        return proof
 
# トランザクションを生成
def new_transaction(sender, recipient, amount):
    transaction = {
        "差出人": sender,
        "あて先": recipient,
        "金額": amount,
    }
    return transaction

block_chain = []

block = Block(0, 0, [], '-') #最初のブロックを作成
 
block.proof = block.mining()
 
block_chain.append(block)
 
i=0
while datetime.datetime(2018, 11, 10, 3, 20) > datetime.datetime.now(): 
# for i in range(10):
    # i=0
    # i=i+1
    block = Block(i+1, str(datetime.datetime.now()), new_transaction("太郎", "花子", 100), block_chain[i].now_hash)
    block.proof = block.mining()
    block_chain.append(block)


    with open('sample.pickle', mode='wb') as f:
        pickle.dump(block_chain, f)
        f.close()
    
    i=i+1

    for block in block_chain:
        for key, value in block.__dict__.items():
            print(key, ':', value)
        print("")
    print("==== ==== ==== ==== ==== ==== ==== ==== ====")

#    for block in block_chain:
#        for key, value in block.__dict__.items():
#            print(key, ':', value)
#        print("")

'''
print("==== ==== ==== ==== ==== ==== ==== ==== ====")
with open('sample.pickle', mode='rb') as f:
    pickle.load(f)
    f.close()

    for block in block_chain:
        for key, value in block.__dict__.items():
            print(key, ':', value)
        print("")
'''

'''
for block in block_chain:
    for key, value in block.__dict__.items():
        print(key, ':', value)
    print("")
'''
```
# 参考
https://www.sejuku.net/blog/75079
PHPで正規表現

#正規表現

PHPで正規表現を使ってパターンマッチングをします。

##パターンマッチングをする関数

preg_matchは文字列の中が正規表現にマッチするものがあるかどうかを調べてくれます。

`preg_match(”正規表現”,文字列)`

##正規表現の書き方

PCRE 関数(`preg_match`)の正規表現の前後には必ずデリミタを入れます。慣習的によく使われるデリミタ文字のひとつが`/`です。
後ろの`/`の後に修飾子を付けることで、マッチングの方法が指定できるのですが、今回は割愛します。

正規表現の例です。

```php:
if(preg_match("/[^0-9]+/",$number){
      header('location: input.php');//input.phpにリダイレクト
      exit();
}
```

- [^ ]：括弧内の文字を除く任意の一文字
- [0-9]：0から9の任意の一文字
- +：前の文字を1回以上繰り返し

正規表現では、それぞれこのようなことを意味しています。
このことから`/[^0-9]+/`は、

「0から9以外の任意の一文字が一回以上続いて登場する」

と言いたいと分かります。

プログラム全体としては
「文字列\$numberの中に数字以外の文字があったら、input.phpというページにしてね」
と言っているのです。
php-master-changes 2018-11-11

今日は昨日に引き続き ext/fileinfo の修正、re2c で生成される字句解析器のコードのリポジトリからの削除、SQLite3 の `@name` 記法サポートの修正があった！

# 2018-11-11
## weltling: Rework magic data
- https://github.com/php/php-src/commit/0e38909170b92ae3da5efd18b7b92df52c80051d
- [7.3~]
- ext/fileinfo で使う libmagic のデータファイルを修正

## weltling: Fork test with pcre.jit=0
- https://github.com/php/php-src/commit/3fd46e19ac3e8ef2950a65edef4c95fcd4c08242
- [7.2~]
- ext/fileinfo で、pcre.jit=0 用のテストを追加

## weltling: Update libmagic.patch [ci skip]
- https://github.com/php/php-src/commit/ee50461e4b33321d4bf8b8de33a08ce3e298ba2c
- [7.2~]
- ext/fileinfo で、libmagic へのパッチを更新
- [昨日の修正](https://qiita.com/sj-i/items/e452558301e12e26895e#weltling-fix-regex) のパッチへの反映

## petk: Remove lexer files generated by RE2C
- https://github.com/php/php-src/commit/f0251a8b16631edf06830e08698cef5d76c1e01b
- re2c で生成される字句解析器のコードをリポジトリから削除
- internals で 3 ヶ月くらい前に[話があった](https://externals.io/message/102796)奴
- .gitignore にも追加
- リリース時のソースコード配布物にはこれまで通り含める
- genfiles について、生成の経過を表示するなどのリファクタリング

## cmb69: Support SQLite3 `@name` notation
- https://github.com/php/php-src/commit/86c6b3bdcdba44c90f88895e4d040120fe058c01
- ext/sqlite3 で、SQLite3 の `@name` 記法のサポートを追加