OmniAICreator/Qiita-1.07M huggingface dataset:
Go言語でWindowsのServiceを作成する

# もくてき

Go言語で作成したプログラムを何とかしてWindows Service化したい！
できることなら、同じソースコードを使用して、LinuxのSystemdのServiceにもしたい！
なんてことを考えて探してみた所、とても便利なパッケージがありました。

Linuxの方は何とでもなるので、一先ずWindows Service化を試してみました。

# 使用するパッケージ

[kardianos/service](https://github.com/kardianos/service) というパッケージです。
ServiceのInstall,Uninstall,Start,Stopができるパッケージで、Windows XP以上, Linux(systemd | Upstart | SysV),  OSX Launchdに対応しているようです。

# 使い方

https://github.com/kardianos/service/tree/master/example
ここに、作成例が4種類公開されてます。

自分でも何か良いサンプルになるものを書いてみようとしてみはみましたが、結局の所は↑のexampleのようなものが出来上がりました。
https://github.com/mako2kano/go_example_service/blob/master/main.go

# Windowsにインストールしてみる

↑のgo_example_serviceは、windows環境でgo buildするとgo_example_service.exeができます。
Powershellをadminで起動して、"go_example_service.exe install"と打ってenterすると、インストールできるはずです。
インストール後にServicesを起動してみると、確かにインストールされてます。

![インストール.png](https://qiita-image-store.s3.amazonaws.com/0/54830/9dc25b43-c088-83c6-3556-a3e911688df0.png)

"go_example_service.exe uninstall"でアンインストールです。


# Windowsで動かしてみる

"go_example_service.exe start"すると、Start()メソッドが呼ばれて動き出します。
例ではStart()の中で、↓のRun()を読んでるので、1秒に1回ログを出力してます。

```go
func (e *exarvice) Run() error {

	logger.Info("Exarvice Start !!!")

	ticker := time.NewTicker(1 * time.Second)
	for {
		select {
		case tm := <-ticker.C:
			logger.Infof("Still running at %v", tm)
		case <-e.exit:
			ticker.Stop()
			logger.Info("Exarvice Stop ...")
			return nil
		}
	}
}
```

startした状態で、Event viewerを見てみると、Windows LogsのApplicationのところに、logger.Infof()やlogger.info()で出力したMessageが出てます。

![イベントログ.png](https://qiita-image-store.s3.amazonaws.com/0/54830/c8951501-9cba-b764-b53b-229f981ee6f6.png)

"go_example_service.exe stop"で停止します。

# 参考にしたページ

[goでWindows serviceを作成する](https://qiita.com/yamasaki-masahide/items/c60e49a908c7927ca600)
この記事を最初に見つけて、試してみようと思いましたが、記事が古いせいか使っているパッケージも古く、使い方も若干違うようでしたので、記事を書いてみました。

# 注意すること！！！

tickerを5秒にしたら、startが出来なくなりました。

Errorの内容は、「Failed to start service. The service did not respond to the start or control request in a timely」で、この現象はserviceをinstall後にStartした時のみ出てました。Run()で動かした場合は出ませんでした。

理由が全く分からなくて、書き直したり動作確認してる中で、tickerを1秒にしたらstart出来るようになりました。

具体的に何秒かは調べてませんが、serviceを開始するにあたって、長い間だんまりだとタイムアウトして応答無しと判断されてしまうようです。

## 原因?と回避策（2018年6月14日追記）

Service Control Managerのstartのtimeoutは30000msらしいです。
つまり30秒です。
```
A timeout was reached (30000 milliseconds) while waiting for the Exarvice (Go Service Example) service to connect.
```
解せぬ。

Goで作成したプログラムがstartするまでに25秒以上はかかっていて、その後更にtimerで5秒以上待ってたのが原因なのでしょうか？

回避策としては、regeditを起動して、**HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control**の**ServicesPipeTimeout**の値を30000から60000等に変更すれば良いようです。
**ServicesPipeTimeout**が無い場合は作成します。
※この設定は再起動されるまで反映されないです。
default_scopeにハマった

## 環境
- Rails 5.0.3
- ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin17]

## 事情
default_scopeにハマってしまったので、メモします。

UserとGroupのモデルがあって、UserはGroupの作成者として紐付いています。

```ruby:user.rb
class User < ApplicationRecord
  has_many :groups 
  default_scope { where(is_deleted: false) }
end
```

```ruby:group.rb
class Group < ApplicationRecord
  belongs_to :user
end
```

さて、GroupsControllerのindexにすべてのグループとその作成者の情報を表示するために、こういうコードを書きました。

```ruby:groups_controller.rb
def index
   @groups = Group.includes(:user).all
end
```

```
<% @groups.each do |group| %>
  <tr>
    <td><%= group.id %></td>
    <td><%= group.name %></td>
    <td><%= group.user.name %></td>
    ...
  </tr>
<% end %>
```

そして、一つのユーザーを削除されました。そしたら、グループ一覧ページに以下の**エラー**になってしまった。

```ruby
undefined method `name' for nil:NilClass
```

確かに、ユーザーが削除されたので、default_scopeが効いてuserが空っぽになっちゃう。

## 対策
いろんな方法を試したんだけど、`Group.includes(:user).all`これを修正して、Groupの中からuserのdefault scopeを外すことができませんでした。

結局以下のあまりイケてない方法で解決しました。影響範囲は全Groupのユーザーになってしまった。

```ruby:group.rb
belongs_to :user, -> { unscope(:where) }, inverse_of: :groups
```

inverse_ofはrubocopの警告で追加したんです。Groupモデルからuserのdefault scopeを外すようにしました。

## 感想
最初から手間を惜しまず、default_scopeを使わないのは正解でした！
magento2：開発環境構築 Vagrant

# 構築手順

・ vagrantで仮想環境を構築
・ composerを使って、magentoのソースをダウンロード
・ 仮想環境上でmagentoの動作確認

# 導入手順

## workディレクトリを作成する

```
$ mkdir ./magento2
$ cd magento2/
```

## vagrantで環境構築

### vagrant init

```
$ vagrant init
```
↑いつもの。

### boxを指定する

```
config.vm.box = "gbarbieru/xenial"
```

今回はubuntuを使いたかったので、上記を定義

### private networkのコメントを外す

```
config.vm.network "private_network", ip: "192.168.33.10"
```

### magento2はメモリを使うので、メモリを増やす

```
config.vm.provider "virtualbox" do |vb|
#   # Display the VirtualBox GUI when booting the machine
#   vb.gui = true
#
#   # Customize the amount of memory on the VM:
   vb.memory = "1024"
end
```

### vagrant up

しばらく待ちます。boxのインストールからだと10分くらい私は待ちました。

### vagrant ssh

サーバにSSHで接続します。

### 必要なモジュールをインストールします

```
$ sudo su
$ apt-get update
$ apt-get install -y apache2 git snmp mysql-server php-bcmath php-curl php7.0-gd php-imagick php7.0-intl php7.0-xsl php-mbstring php7.0-mbstring php-gettext libapache2-mod-php7.0 mcrypt php7.0-mcrypt php7.0-xml php-soap php7.0-zip php-mysql unzip
```

mysqlのパスワード記入を求められるので、任意で設定します。

### apacheの設定変更

```
$ vim /etc/apache2/apache2.conf
```

```
<Directory /var/www/>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
</Directory>
```

上記のコメントをはずす

```
Servername localhost
```

上記を追記します。

### a2enmodでrewriteを有効にする

```
$ cd /etc/apache2/mods-enabled/
$ a2enmod rewrite
```

### apacheの実行ユーザ・グループを変更する

```
$ vi /etc/apache2/envvars
```

```
export APACHE_RUN_USER=vagrant
export APACHE_RUN_GROUP=vagrant
```

## データベースを作成する

```
$ mysql -u root -p
> create database magento2 ;
> exit;
```

## apache再起動

```
$ service apache2 restart
```

## ブラウザで表示確認

`http://192.168.33.10` にアクセスし、
`/var/www/html/index.html` が表示できることを確認する

表示確認が出来たら、`/var/www/html/`の中身を綺麗にする

```
$ rm -rf /var/www/html/*
```

## composerインストール

```
$ cd ~
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
$ php composer-setup.php
$ sudo mv composer.phar /usr/local/bin/composer
```

### composerが使えることを確認

```
$ composer --help
```

## composerでmagento2をインストールする

```
$ composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition /var/www/html/ 
```

※ magento marketplaceのアカウントが必要
※ アカウント発行手順は [こちら](https://qiita.com/kumanizm/items/3e826ff278296f0960ea)

### magento2用に権限を調整する

```
$ chmod -R 777 /var/www/html/app/etc
$ chmod -R 777 /var/www/html/var
$ chmod -R 777 /var/www/html/pub/media
$ chmod -R 777 /var/www/html/pub/static
$ chmod -R 777 /var/www/html/generated
```

## ブラウザでのセットアップを行う

`http://192.168.33.10` にアクセスする

![スクリーンショット 2018-06-13 17.24.11.png](https://qiita-image-store.s3.amazonaws.com/0/103/765b4af4-6037-ba25-ed4c-1ad848d82f16.png)
![スクリーンショット 2018-06-13 17.24.40.png](https://qiita-image-store.s3.amazonaws.com/0/103/e1f2646b-9ced-7f83-8401-a59eb0462f86.png)
leafletプラグイン > leaflet-fusesearch


あいまい検索Fuse.jsをLeafletで使えるようにするプラグイン

[naomap/leaflet-fusesearch](https://github.com/naomap/leaflet-fusesearch)


![image](https://qiita-image-store.s3.amazonaws.com/0/49910/097f193b-df05-1698-bde0-e3193e79c190.png)



## install fuse.js 
```
$ npm install fuse.js

```


```html
    <link rel="stylesheet" href="./node_modules/leaflet/dist/leaflet.css" />
    <script src="./node_modules/leaflet/dist/leaflet.js"></script>

    <script src="./node_modules/fuse.js/dist/fuse.min.js"></script>
    <link rel="stylesheet" href="./leaflet-fusesearch/src/leaflet.fusesearch.css" />
    <script src="./leaflet-fusesearch/src/leaflet.fusesearch.js"></script>
    <script src="./js/data.js"></script>
    <link rel="stylesheet" href="./css/leaflet.infopane.css" />

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.js"></script>

```

JS

```js
    var map = L.map('map');
    map.setView([51.505, -0.09], 13);
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);


    var searchCtrl = L.control.fuseSearch()
    searchCtrl.addTo(map);
    map.addControl(searchCtrl);

    var props = ['nom_comple', 'libcategor', 'commune'];
    searchCtrl.indexFeatures(jsonData.features, props);
```
コマンドラインツール作成時のオプション／引数設定ガイドライン

ターミナルとかで動く軽いツールをサクッと作るときに機能が増えてくると
そういえばオプションってどうゆう書式やったっけってひとのための忘備録(Windows、Linux)
Macはようわかりません(多分Linuxと同じ)。
##一般的なアレ
```terminal
コマンド名 [--option1] [--option2=オプション引数] [--option3 オプション引数] 引数1 引数2
```
- オプションは引数の前に書くほうが良い(作るときは普通、最後や真ん中に入れても動くようにする)。
- オプションを表す記号は、Windowsでは`/`、Linuxでは`--`か`-`。最近は、Windowsであっても`--`や`-`に合わせることが多い。理由はLinuxではスラッシュが使えないから。
- Windows:よく使うと思われるオプションは省略形を用意する(例:`/res`と`/resource`、`/?`と`/help`)。
- Linux:オプションはふつう1文字。`--`を使うときのみ、2文字以上。例:`-h`と`--help`、`-v`と`--version`。すべてのオプションにおいて、この2パターンを両方用意すべき。
- 各オプションは、省略してあっても動くようにする。引数はふつう入力必須。
- オプション引数については、`=`でつなぐか、空白を1個あけて続けて書く。前者の場合、`=`の前後に空白を入れてはならない。
- `-`で始まるオプションは繋げれる(例:`-a -b -c`→`-abc`)

###特殊なオプション
`/?(/help)[-h(--help)]`と`/ver(/version)[-v(--version)]`は、必ず用意するもの。

- これらがコマンドのどこかに含まれていると、ヘルプまたはバージョンの出力をして終了する(それ以外の動作はしない)。

##とりあえず
Linuxにあわせませう。
mp4などの動画ファイルをCSSスプライトアニメーションに変換する

#はじめに
- mp4などの動画ファイルが重く、スプライトアニメーションで実装したい場合の変換フローの個人的備忘録です。
- 環境はMacです。

#動画から一定時間ごとのキャプチャをとる
**VLC media player**というフリーの動画再生プレイヤーを利用します。

```
環境設定 → インターフェース → すべてを表示 → ビデオ → フィルター → シーンフィルター → （設定する） → 保存
```
（設定項目場所が、ふ…深い…。）

<img width="50%" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/221915/22a6332f-5e8a-c71d-1ccc-2c2f5b0e8048.png">

・***「ディレクトリパスのプレフィックス」***…キャプチャ画像が吐き出される場所を指定します。　
・***「レコーディングレシオ」***…何コマおきにキャプチャ画像をとるかという設定です。当然、数値が少ないほどスプライトアニメーションはなめらかになりますが、画像は重くなりますので、そのあたりはバランスで。

あとは目的のmp4を再生するだけで自動的[^1]にキャプチャ画像が生成されます。
ここでは3コマおきに設定しましたので、こんな名前で吐き出されます。

```
00001.jpg
00004.jpg
00007.jpg
00010.jpg
00013.jpg
00016.jpg
00019.jpg
00022.jpg
00025.jpg
```

#キャプチャ画像名を一括で変更する
Macの場合、キャプチャ画像をすべて選択状態にして右クリックメニューの「***（選択状態の画像数）項目の名前を変更…***」で変更できます。
ここではとりあえずシンプルに「pic1.jpg」みたいな感じにしてみます。

<img width="496" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/221915/6ba73a6a-c023-8a94-b2d7-bcee05744948.png">

```
pic1.jpg
pic2.jpg
pic3.jpg
pic4.jpg
pic5.jpg
pic6.jpg
pic7.jpg
pic8.jpg
pic9.jpg
pic10.jpg
```

#キャプチャ画像を結合してスプライト画像を作る
**[ImageMagick](http://www.imagemagick.org/script/index.php)**を利用します。
**[HomeBrew](https://brew.sh/index_ja)**でインストール可能です。
**ターミナル**でキャプチャ画像の入ったフォルダに移動し、以下のコマンドを入力します。
以下は`pic1.jpg`〜`pic10.jpg`の10枚のキャプチャ画像を`sprite.jpg`という名前の画像に縦向きに結合する例です（横向きは`+append`）。

```terminal:Terminal
convert -append pic1.jpg pic2.jpg pic3.jpg pic4.jpg pic5.jpg pic6.jpg pic7.jpg pic8.jpg pic9.jpg pic10.jpg sprite.jpg
```

#CSS3アニメーションで動かす
```html:HTML
<div class="anime"><img src="img/sprite.jpg" alt=""></div>
```

```scss:SCSS
.anime {
  position: relative;
  overflow: hidden;
  width: 200px;
  height: 200px;
  img {
    position: absolute;
    top: 0;
    left: 0;
    animation: anime-sprite 1s steps(10) infinite;
  }
}

@keyframes anime-sprite {
  0% {
    transform: translate(0, 0);
  }
  100% {
    transform: translate(0, -100%);
  }
}
```

- 上記コードはあくまでもイメージです。
- `animation`の各プロパティの説明についてはここでは割愛します（`steps`が肝です）。
- スプライト画像を背景画像にして`background-position`で操作すると、GPUレンダリングではないので再描画のため重くなりますし、IE11あたりで不具合が出た気もするので、画像にして`transform`するのがパフォーマンス的によろしいかと。まあ、ケースバイケースだと思いますが。

#まとめ
- gifアニメは修正やコントロールが大変なので、CSSスプライトアニメーションは便利だと思います。
- 上記フローがあれば作成にそれほど時間はかからなくて済むと思います。逆に言えば手作業では厳しいです。
- スプライト画像は長くなると結構重くなりますので、コマ数を削ったりサイズを小さくしたりするなど調整は必須です。

　
***
【参考サイト】
- [動画をVLC Playerで連続的に静止画像として書き出す方法 | 観て聴いて考えた軌跡](http://blog.hieroglyph.me/archives/49)
- [Macで複数の画像を結合させて１枚の画像に変換する方法](https://qiita.com/narikei/items/a4e0f1df9b71f5d7f15e)
- [Imagemagickの使い方日本語マニュアル – 日本語のマニュアルが少ない画像加工ツールImageMagickの使い方を、初心者の方にも解りやすいよう詳しく丁寧に解説しています。](http://imagemagick.rulez.jp/)
- [はじめよう！スプライトアニメーション - Qiita](https://qiita.com/nekoneko-wanwan/items/b0e64404a5cff582247a)
- [CSSスプライトアニメーションをGPUレンダリングさせる - Qiita](https://qiita.com/takumifukasawa/items/7463d9fa48aced1cf3cb)

[^1]: 今回の設定を解除しないかぎり動画再生のたびに自動的に画像が生成されますので、普通に動画を再生したい場合は今回の設定を解除する必要があります。
uwsgi 補遺

# vacuum
uwsgi に vacuum オプションがある。意味は「try to remove all of the generated file/sockets」なんだそうだ（[ref](http://uwsgi-docs.readthedocs.io/en/latest/Options.html#vacuum)）。

なるほどわからん。

フラグ自体は `vacuum` フィールドに格納される。実際の処理は
https://github.com/unbit/uwsgi/blob/master/core/uwsgi.c#L1653
 にあるように、「プロセス終了時に」「pidfile をクリンナップしたり、unix domain socket を閉じたりだとか」を実行するということだそうだ。

「[プロセス終了時に](https://github.com/unbit/uwsgi/blob/master/core/uwsgi.c#L2174)」という一番大事なところが書いてないから意味が分からなかった。


# systemd
uwsgi は [new-style daemon](https://uwsgi-docs.readthedocs.io/en/latest/Systemd.html) なのだそうだ。

しかしこれだけでは何のことやら。

詳しく調べてみた。uwsgi は、環境変数 `NOTIFY_SOCKET` が存在すれば、`sd_notify` で `READY=1` を送り込む。オンオフの設定無し。

systemd は `NOTIFY_SOCKET` を設定するので、systemd unit ファイル側では `Type=notify` にするのが良いだろう。


# ini-paste-logged
一つの ini ファイルで python logging の設定まで済ませることができる。

**ただし** logger の設定で失敗すると、このファイルに定義されている他の設定も影響を受けて、無視されたりすることに注意。ファイル出力先のディレクトリが必要なら**必ず**用意しておくこと。


# Workers
`workers` と `processes` は同一。プロセス数。`cheaper` で起動数の調整がされる。

`threads` は `enable-thread` を自動的に有効にする。


# Keep-Alive
HLSで設定レジスタを作る


![Config.png](https://qiita-image-store.s3.amazonaws.com/0/72075/0ffd533e-685b-47f5-650d-9ffe88b676fc.png)

---

PSからPLのモジュールへ値を読み書きしたいとき、AXI経由で読み書きするのが普通かと思う。
モジュールがAXIに対応していなければ、AXIとの変換モジュールを作ることになる。
その場合、

* GPIOモジュールを使う
* RTLをガリガリ書く

と言う手段があるが、GPIOではどのレジスタの何ビット目が何だったかがコードに現れないので辛いし、
RTL書くのは輪をかけて面倒である。

というわけでHLSで書く。イメージとしてはこんな感じ。

```C++
typedef struct{
	int32_t A;
	bool B;
} Config_write;

typedef struct{
	uint16_t C;
	bool D;
	uint8_t E;
} Config_read;

void HogeConfigurator(
	Config_write wcfg_axi,
	Config_read& rcfg_axi,

	Config_write& wcfg_pl,
	Config_read rcfg_pl
	){
	wcfg_pl = wcfg_axi;
	rcfg_axi = rcfg_pl;
}

```

PLへ書き込む設定値は`Config_write`、PLから読み込む設定値は`Config_read`構造体にまとめる。
引数の`~_axi`はAXI側、`_pl`はモジュール側である。

`_axi`と関数本体のインターフェースを`s_axilite`にして
`_pl`のインターフェースを`ap_none`にすればAXI経由で操作でき、おまけにドライバをHLSが生成してくれる。


(本当にap_noneでええんか?validいらんのか?と警告が出るが無視する。)

レジスタ指定をつければ、`XHogeConfigurator_Start()`を呼ぶとまとめて変更が反映される動作になるし、
つけなければ即座に変更が反映される動作になる。
定数定義場所 指針

# はじめに
アプリケーションにおいて定数を何処に定義するかについて以下に指針を記載する。

## 定数クラス
* プログラム内で使用する値
* 1度宣言したら以降変更が入らない値

`例) プログラム中で使うコード値や固定文言  `  
列挙型(enum) を使用できないか検討する
使用する際はスコープを意識して機能や役割ごとに定数クラスを作成すること。
{システム名}Constants.java とかは作らない。
インタフェースに定数を定義し使用することも本来のインタフェースの目的から離れてしまうので避けること。

## プロパティファイル
* プログラム内で使用する値
* 環境毎に変更したい値  

`例) 接続情報(DB, 各サービス, ユーザID, パス)、ログ出力レベル、出力先(ログ, ファイル)`

## DB(コードテーブルetc)
* 頻繁に変更する可能性がある値

・・・とあったがバージョン管理出来ないし使いたくない。
    アプリケーションの再リリースが不要というメリットが語られるが
    そうせざるを得ないケースが発生するのはアプリケーションのつくりそのものがイケていないと思う。

## 環境変数
* マシン固有の値  
`例) VM起動時のパラメータ`

************************************************************
# 参考リンク
[定数ってどう管理するのが良いかね] (http://neos21.hatenablog.com/entry/2016/09/29/013020)
[定数の管理場所] (http://lnen.blogspot.com/2010/01/blog-post_25.html)
[アプリケーションを作る上で定数の配置場所の判断基準。DB？ファイル？] (http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=44490&forum=7)
[[Java]考えなしに肥大化する定数クラス] (http://d.hatena.ne.jp/cero-t/20090315/1237138482)
[Properties file vs Constants class in Java] (https://stackoverflow.com/questions/10801746/properties-file-vs-constants-class-in-java)
Amazon CloudFront & Lambda@Edgeが作るlogGroupの保存期間をスクリプトから一括でセット

Lambda@Edgeでは実行ログの出力先が特殊で、CloudFrontが処理したエッジリージョンのCloudWatch Logsをつかいます。
デフォルトの保存期間がNever Expiresで、かつ初回アクセス発生時に作られるので、あとから保存期間をスクリプトで一括セットしたい。


## コード

logGroupNameのprefixはどのリージョンでも`/aws/lambda/us-east-1/{function_name}`になるのに注意ですかね。


```python:set_log_retention_days.py
#!/usr/bin/env python
import boto3


ec2_client = boto3.client('ec2')
all_region_items = ec2_client.describe_regions()
all_regions = [x['RegionName'] for x in all_region_items['Regions']]

policies = [
    {
        'prefix': '/aws/lambda/us-east-1.myservice-production-',
        'days': 90
    },
    {
        'prefix': '/aws/lambda/us-east-1.myservice-development-',
        'days': 14
    },
]

for pol in policies:
    for r in all_regions:
        print(r)
        logs_client = boto3.client('logs', region_name=r)
        log_groups = logs_client.describe_log_groups(logGroupNamePrefix=pol['prefix'])
        for log_group in log_groups['logGroups']:
            print(log_group['logGroupName'])
            result = logs_client.put_retention_policy(
                logGroupName=log_group['logGroupName'],
                retentionInDays=pol['days']
            )
            print(result['ResponseMetadata']['HTTPStatusCode'])
```

## 実行してみた

リリースしてしばらくしたら実行。現状どうなってるかは気にしなくて良いタイプ。

```shell-session
$ ./scripts/set_log_retention_days.py 
ap-south-1
eu-west-3
eu-west-2
eu-west-1
ap-northeast-2
/aws/lambda/us-east-1.myservice-production-origin_request
200
/aws/lambda/us-east-1.myservice-production-origin_response
200
/aws/lambda/us-east-1.myservice-production-viewer_request
200
ap-northeast-1
/aws/lambda/us-east-1.myservice-production-origin_request
200

...

```



先立って作っておく、でも良いのかもですが、リージョン自体が増えたりするのでスクリプトにしておくほうがよいかなと。
ESLintの導入手順まとめ

ESLintの導入したときの手順をまとめる

## yarn add
`yarn add --dev eslint eslint-config-airbnb eslint-plugin-import babel-eslint``

## 設定ファイル
プロジェクト直下の内容のファイルを置く

```json:.eslintrc.json
{
  "env": {
    "es6": true,
    "browser": true,
    "jquery": true // if use $
  },
   "plugins": [
    "import"
  ],
  "parser": "babel-eslint", // for async/await
  "extends": "airbnb-base"
}
```

## ESLintの実行
Railsで `app/frontend/javascript`にjsを配置するときの例
`--fix`オプションは可能なものは自動修正するオプション

以下の様に`packge.json`の`scripts`に追加して
`yarn run lint:javascript`で実行

```json:package.json
...
  "scripts": {
    "lint:javascript": "eslint --fix app/frontend/javascripts/**/*"
  },
...
```
馬鹿の一つ覚え: CSS

# CSS

#### CSSをタグの中に埋め込む
```HTML
<span style="color: #38755d; font-size: 200%">木賊色</span>
```

#### CSSをHTMLヘッダの中に埋め込む
```HTML
<head>
  <style>
    .red       { color: #ff0000; }
    .green     { color: #008800; }
    .blue      { color: #4444ff; }
    .white     { color: #ffffff; }
    .big       { font-size: 125%; }
    .sup       { font-size: 75%; vertical-align: 40%; }
    .sub       { font-size: 75%; vertical-align: -25%; }
    .underline { text-decoration: underline; }
    .clear     { clear: both; }
    p.center   { text-align: center; }
    a img      { border: none; }
    /* コメント */
  </style>
  <!-- コメント -->
</head>
```

#### CSSを別ファイルで用意する
```HTML
<head>
  <link rel="stylesheet" href="./foo.css" type="text/css">
</head>
```

#### ページ全体の文字の大きさを指定
```HTML
<body style="font-size: 200%">
```

#### マージンとパディングの設定
```HTML
<div style="margin: /* 要素の枠の外側 */ 8px; padding: /* 要素の枠の内側 */ 4px ">
```

#### センタリング
```HTML
<div style="text-align: center"><!-- テキストだけでなく画像などのインライン要素にも -->
  <img src="centered.jpeg" alt="centering"><br>
  テキストや画像<br>
</div>

<div style="text-align: center">
  <table>
    <tr><td>センタリング1</td><td>センタリング2</td>
    <tr><td>センタ3</td><td>センタ4</td>
  </table>
</div>

```

#### 表のセンタリング
```HTML
<table style="background-color: #ededed; width: 1024px; margin: auto">
```

#### 表の中の個々の要素の左寄せ、センタリング、右寄せ
```HTML
<tr><td>設定なし 設定なし 設定なし</td></tr>
<tr><td style="text-align: left">左寄せ</td></tr>
<tr><td style="text-align: center">センタリング</td></tr>
<tr><td style="text-align: right">右寄せ</td></tr>
<tr><td style="vertical-align: top">上へ</td></tr>
<tr><td style="vertical-align: bottom">下へ</td></tr>
```

#### テキストに下線
```HTML
テキストに<span style="text-decoration: underline">下線</span>を引く<br>
```

#### テキストを着色
```HTML
テキストを<span style="color: red">赤色</span>に<br>
```

#### 表の中の個々のセルに着色
```HTML
<td style="background-color: yellow">foo</td>
```

#### テキストの回り込みを解除
```HTML
<img src="foo.png" alt="foo" style="float: right; border: 1px black solid">
<br style="clear: right">
<br style="clear: left">
<br style="clear: both">
```
```HTML
<div style="clear: left"></div>
<p style="clear: right"><br></p>
```

#### ページの中央に枠を作ってその中に書き込む
```CSS
  body { background: #e7e7e7; }
  div  { background: #ffffff; width: 800px; padding: 40px; text-align: text-left;
         border: 1px solid #bcbcbc; margin: 80px auto; line-height: 200%; }
```

#### 表のサイズを指定
```CSS
  table { width: 640px; }
```

#### 表のの枠線
```CSS
  table, ht, td { border: none; }    /* 枠線を付けない */
  table { border: solid 1px #dcdcdc; }    /* 表だけに枠線 */
```

#### 画像の周囲に線
```HTML
<img src="foo.jpeg" alt="枠で囲む"
    style="border: solid 2px green">
<img src="foo.jpeg" alt="上下に線"
    style="border-top: solid 12px blue; border-bottom: solid 8px lime">
```

#### 画像を隙間なく配置
```HTML
<img src="foo.png" alt="no space" style="float: left; vertical-align: middle">
```

#### フォームの枠やボタンの大きさを指定
```HTML
<input type="text" name="organism" style="font-size: 2em">
<input type="submit" value="Submit" style="font-size: 2em">
```

#### リストの行間
```HTML
<li style="padding: 8px 0">foo</li>
```
【小ネタ】今からすぐ出る阪急バスの路線検索結果から時刻表を表示するボタン


至極単純な処理だが、また使うこともあるかもなのでメモ。

[阪急バスの路線検索](https://www.hankyu-bus.jp/route)の結果ページのURLは、発車/到着/日付時刻等のクエリを含むので、とりあえず今の時刻で出発/到着地を設定し検索。結果ページのURLの日付時刻の部分を、今の日付時刻に置き換えてやることにより、希望路線の今から発車するバスの経路と発車時間のページのリンクを生成する。

```html
<p id="busTimeTableLinkButton"></p>

<script>
/**
 *  今からすぐ出る阪急バスの路線検索結果から時刻表を表示するボタン
 */
// 現在日時と時刻を取得し整形 (2018/06/13 15:55 → 201806131555)
var now = new Date(),
	dayAndTimestr = now.getFullYear()
		+ ( '00'  + (now.getMonth()+1) ).slice( -2 )
		+ ( '00'  + now.getDate() ).slice( -2 )
		+ ( '00'  + now.getHours() ).slice( -2 )
		+ ( '00'  + now.getMinutes() ).slice( -2 );

// 検索結果ページURLの日付時刻の部分だけ変える
var busTimeTableLink = '<a href="https://www.hankyu-bus.jp/nsresult?mode=0&fr=%E5%B7%9D%E8%A5%BF%E3%83%90%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%9F%E3%83%8A%E3%83%AB%E3%80%94%E9%98%AA%E6%80%A5%E3%83%90%E3%82%B9%E3%80%95&frsk=B&to=%E8%90%A9%E5%8E%9F%E5%8F%B0%E3%80%94%E9%98%AA%E6%80%A5%E3%83%90%E3%82%B9%E3%80%95&tosk=B&dt=' + dayAndTimestr + '&p=1" target="_blank">今から出るバスの時刻表を見る</a>';

// 出力
document.getElementById("busTimeTableLinkButton").innerHTML = busTimeTableLink;
</script>
```
mfkessaiをrubyで使う

Mfkessaiサービスをrubyで実装する

Mfkessaiとは請求代行サービス、[詳しいURL](https://mfkessai.co.jp/)

公開されている以下のgemを使う

https://gitlab.com/torufukui/mfkessai-ruby

ライブラリは、利用可能なアカウントの秘密鍵と本番環境かテスト環境かのURLの設定をする必要があります。


簡単な例

```
require "mfkessai"
Mfkessai.api_url = "https://sandbox"
Mfkessai.api_key = "mfkessai_test_..."

# list customers
Mfkessai::Customer.list

# retrieve single customer
Mfkessai::Customer.retrieve("customer_test_123")
```

## 決済の取引を行なう

```
require "mfkessai"
Mfkessai.api_url = "https://sandbox"
Mfkessai.api_key = "mfkessai_test_..."

# 取引を登録
params = {
  "amount": 2160,
  "date": "2018-04-16T00:00:00+09:00",
  "destination": {
    "address1": "千代田区1-2-3",
    "address2": "サンプルビル3F",
    "cc_emails": [
      "another.test1@example.jp",
      "another.test2@example.jp"
    ],
    "customer": {
      "office_name": "サンプル商事株式会社",
      "user_defined_id": "customer123456"
    },
    "customer_id": "ABCD-EFGH",
    "department": "経理部",
    "email": "kesai.tanto@example.jp",
    "name": "請求先氏名",
    "prefecture": "東京都",
    "tel": "03-1234-5678",
    "title": "",
    "zip_code": "111-1111"
  },
  "destination_id": "XXXX-YYYY",
  "due_date": "2018-05-31T00:00:00+09:00",
  "email_flag": true,
  "issue_date": "2018-05-16T00:00:00+09:00",
  "posting_flag": false,
  "transaction_details": [
    {
      "amount": 2000,
      "description": "商品名A",
      "quantity": 2,
      "unit_price": 1000
    },
    {
      "amount": 160,
      "description": "消費税",
      "quantity": 1,
      "unit_price": 160
    }
  ],
  "user_defined_id": "transaction00000001"
}

Mfkessai::Transaction.create(request_body: params)
```

## 顧客のリスト取得する

```
require "mfkessai"
Mfkessai.api_url = "https://sandbox"
Mfkessai.api_key = "mfkessai_test_..."

# 顧客リストを取得
Mfkessai::Customer.list
```

詳しい使用方法・対応APIは[README.md](https://gitlab.com/torufukui/mfkessai-ruby
)を参考にしてください
AI研究トレンドのお勉強


# はじめに

arxivにある論文からAI研究トレンドをまとめたという、以下のサイトを眺めていて、初めて見る単語がいくつかあったのでお勉強してみました。


[A Peek at Trends in Machine Learning](https://medium.com/@karpathy/a-peek-at-trends-in-machine-learning-ab8a1085a106)

ちなみに、筆者は、AI、機械学習に関してほぼ素人で数式を見ると頭が痛くなるタイプなので、ふわっと分かったをまとめています。


# Batch Normalization

2015 年に提案された手法。

[Batch Normalization: Accelerating Deep Network Training by Reducing Internal Covariate Shift](https://arxiv.org/abs/1502.03167)

隠れ層のアクティベーション（活性化関数における出力）の分布は、基本的にばらついていた方がよい。（0,1に集中していたりすると、勾配消失問題(*1)が起こりやすくなるらしい）

そこで、重みの初期値を適切に設定することで、アクディベーションの分布を適度に広げ、学習をスムーズに行えるようにする。（初期値に、どのような値を設定するかで、学習の成否が分かれることがある）

初期値に依存せず、このアクティベーションを強制的に広がりを持たせて分布させるのが、Batch Normalization とのこと。

こんな感じで、ニューラルネトワークに挿入する

![batchnorm.png](https://qiita-image-store.s3.amazonaws.com/0/152321/628c65b9-42c6-5255-5b15-e3f56d5b3ce3.png)


次のような利点があるらしい。

- 学習係数を適度に大きくし学習の進行速度を上げられる
- 初期値にそれほど依存しない
- 過学習を抑制する


*(*1)勾配消失問題とは*

>ディープラーニングによる判別結果と正解データの誤差を、出力層側から入力層側に向かって伝播して、パラメータを変化させることで精度を上げていく（誤差逆伝播法またはバック・プロパゲーションという）際、複数の層を伝播していく過程で誤差情報が消失してしまう現象。

(引用元)[ディープラーニングって何？人工知能ブームに火をつけたアルゴリズムをどう捉えるべきか](https://markezine.jp/article/detail/24185)

# Style Transfer

ニューラルネットワークによる画風変換のこと

(参考URL)[Style Transferの外観](https://www.slideshare.net/zaburo/style-transfer)

こんなやつです。

![スクリーンショット 2018-06-13 15.33.13.png](https://qiita-image-store.s3.amazonaws.com/0/152321/afc926ca-af41-221c-f1e6-9855193fa6bb.png)


(引用元)[Image Style Transfer Using Convolutional Neural Networks](https://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Gatys_Image_Style_Transfer_CVPR_2016_paper.pdf)

# FCN（Fully Convolutional Networks）

名前の通り、全てが畳み込み層（Convolutional layer）で構成されるニューラルネットワークのこと。

以下論文のような Semantic Segmentation 向けのアルゴリズム。Semantic Segmentationとは、簡単にいうと、各ピクセルがどのオブジェクトに属しているのかをラベリングすること。

[Fully Convolutional Networks for Semantic Segmentation](https://arxiv.org/abs/1605.06211)

![スクリーンショット 2018-06-13 15.09.21.png](https://qiita-image-store.s3.amazonaws.com/0/152321/288af26b-58d1-ee48-acc7-313372477b2c.png)

一番右の画像(Image)に対して、その一つ隣の画像(Ground Truth)を学習させることにより左側２列のような画像を出力できるようにしたいというもの。比較に用いられているSDSは、Simultaneous detection and segmentationという別の手法です。

# Siamese Network(SNs)

Siamese Networks は、GANs(Generative Adversarial Networks)のように、2つのネットワークが共に作用する。ネットワークが競い合うGANsとは異なり、SNsはネットワーク出力を2つの異なる入力で比較し、その類似点を比べる。

(参考URL)[ディープラーニングネットワーク (GAN と Siamese) を組み合わせハイクオリティでリアルなイメージを生成](https://aws.amazon.com/jp/blogs/news/combining-deep-learning-networks-gan-and-siamese-to-generate-high-quality-life-like-images/)

![スクリーンショット 2018-06-13 15.22.53.png](https://qiita-image-store.s3.amazonaws.com/0/152321/81cadcc0-72f3-2c63-0d8b-89131b27889e.png)


# Adam（Adaptive Moment Estimation）

オプティマイザー（最適化アルゴリズム）の一種。

最急勾配を下げていく、それ以外の勾配方法も試すことで、鞍点からの抜け出しが速くなる可能性があるとのこと。

(参考URL)[Adamのパラメータ設定](http://exochronos.hatenablog.com/entry/2016/05/07/194033)


理解できないと思われるので、数式は見ていませんが、単語は覚えたので一旦よしとします。

# おわりに

トレンドとしては、ResNetsとかニューラルネットや画像処理に関する技術が多かった気がします。
はやく、こうした最新の論文を読みこなして、面白そうなものは実装できるようになりたいです・・・
Cronの使い方とテクニックと詰まったところ


# Cronとは

毎日、この時間にプログラムを実行したい！
一時間に一回、検査を走らせたい！
毎月一度、バックアップしたい！

という感情になったことは、誰しもあるでしょう。

**そんなとき、Cronの出番です**

Cronは起動している限り`定期的にプログラムを実行してくれる`アプリケーションです。
(WindowsではタスクスケジューラというアプリケーションがGUIで提供されています)

# はじめに

今回は、Ubuntu 16.04でやってみたいと思います。

# 使い方

## 1. Cronの設定ファイルを確認する
	
```text:tree
/etc/
├── cron.d
│   ├── anacron
├── cron.daily
├── cron.hourly
├── cron.monthly
├── crontab
├── cron.weekly
```

### cron.d

このフォルダに入った**拡張子のないファイル**が実行されます。
普段はこちらのフォルダ内にファイルを作成して操作を行います

### cron.***

こちらは、日ごと、時間ごと、月ごと、など、
実行しやすいように既に作成されています。この中に実行ファイルを入れれば実行できますが、
ファイルが膨大にならない限り`cron.d`に個人で作成したほうが楽かもしれません

### crontab

このファイルはcronの一番メインのファイルです。
こちらに記載しても動きますが、このファイルの形式を元に動かすことになるので、
編集する際はしっかりバックアップをとっておくことをおすすめします。

## 2. cron.dにファイルを作成する

ここでは、`拡張子のない任意の名前のファイル` = `test_cron` とします

```bash:bash
$ cp /etc/crontab /etc/cron.d/test_cron
```

## 3. cronの説明

`/etc/cron.d/test_cron`を編集します
	
```cron:/etc/cron.d/test_cron

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user	command
17 *	* * *	root    cd / && run-parts --report /etc/cron.hourly
25 6	* * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6	* * 7	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6	1 * *	root	test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

```

コメントアウトされている通りに記載します。


```bash:test_cron
# m h dom mon dow user	command
分　時　日　月　曜日 ユーザー　コマンド

# 1分ごと
* *    * * *  root   touch /home/ubuntu/test.txt

# 1:00〜1:59まで1分ずつ実行
* 1    * * *  root   touch /home/ubuntu/test.txt

# 毎日1:00に実行
0 1    * * *  root   touch /home/ubuntu/test.txt

# 毎月12日~20日00:00に実行
0 0    12-20 * *  root   touch /home/ubuntu/test.txt

# 毎週月曜日〜金曜日00:00に実行
0 0    * * 1-5  root   touch /home/ubuntu/test.txt

```

## 4. Cronの実行

```bash
$ sudo service cron restart
```

# テクニック

## Cronのログを出す

```bash
$ vim /etc/rsyslog.d/50-default.conf

# コメントアウトを外す
# cron.*                          /var/log/cron.log

$ sudo service rsyslog restart
```

## Cronで実行しているコマンドのログを出す

```bash:test_cron
* *    * * *  root   touch /home/ubuntu/test.txt >> /[通常ログファイルの場所] 2>> [エラーログファイルの場所]
```

## 数秒毎に実行する

```bash:test_cron
# for i in `seq [何秒から] [何秒ごと] [何秒まで]`;do (sleep ${i}; [実行するコマンド] ) & done;
# 10秒ごと
* *    * * *  root   for i in `seq 0 10 59`;do (sleep ${i}; touch /home/ubuntu/test.txt ) & done;
```

## 外部ファイルから環境変数を読み込み、何秒ごとに実行するかを指定する


```bash:/home/ubuntu/.env
TIME=15
```

```bash:test_cron
# bashになっていることを確認する
SHELL=/bin/bash
* *    * * *  root   for i in `source /home/ubuntu/.env && seq 0 ${TIME} 59`;do (sleep ${i}; touch /home/ubuntu/test.txt ) & done;
```


# 詰まったところ

## 1. Tabキー等空白文字の文法ミス

Tab,Spaceキーの場所

```bash
*[Space]*[Tab]*[Space]*[Space]*[Tab]root[Tab]Commands   
```

## 2. 起動コマンドで起動していない

```bash
$ sudo service cron status

Active: active (running)

```

になってることを確認する

## 3. Sourceコマンドを使用する際、Bashになっていない

```bash:test_cron
# bashになっていることを確認する
SHELL=/bin/bash
```


以上

2019/08/01 : まだまだ現役動作してます
【サルが書く】CakePHPで<i>を使ったアイコンを表示する時のlinkHtmlHelperの書き方

わきゃ

```php

<?= 
    $this->Html->link(
    '<i class="ti-github"></i>github',
    [
        'controller' => 'fugafuga',
        'action' => 'index',
    ],
    [
        // これを設定することでHTMLタグをエスケープせずに表示してくれます。
        'escape' => false 
    ]
)
?>

```

```html
<!-- 出力結果 -->
<a href="/fugafuga"><i class="ti-github"></i>github</a>
```
pyenvの設定

#はじめに

pyenvとanacondaの共存が良くわかってないですが、良くわかってないなりに解決したので記録します。

##現象
pythonのバージョンが３系に切り替わらない

```
h115:~ takaaki$ pyenv global 3.6.5
h115:~ takaaki$ pyenv versions
  system
  2.7.10
  2.7.14
  3.5.0
 1 .bash_profile +                                                                                                                                                              X
* 3.6.5 (set by /Users/takaaki/.pyenv/version)
  anaconda3-4.2.0
h115:~ takaaki$ python -V
Python 2.7.14 :: Anaconda custom (64-bit)
```

##原因
bash_profileの設定がおかしかった。

```sh:.bash_profile
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"

#ここがおかしい
export PATH="/anaconda3/bin:$PATH"
```

##解決策
`export PATH="/anaconda3/bin:$PATH"`をコメントアウトするとなおる
手書き証拠変造の証明を画像認識でやってみる

![図１.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/2a277c28-7c36-3d7b-a0cb-ab7bd8132eb7.jpeg)

#概要
　裁判というものは普通生活しているとなじみのない世界ですが、法律事務所にとっては日常の仕事の場になります。実際のな裁判の流れは、『事実認定』というプロセスが入り、認定された事実をもとに裁判所が法律や判例を参照して、判断を行っていくというのが実際の流れになります。
　裁判所は判例を出すと、法律解釈に対して、影響を与えることから、非常に前例主義であり、過去からの法律解釈の積み上げも重視する傾向にあると思います。
　AIを法律事務所が利用する例がありますが、本記事は、証拠の判定の中で、手書きメモの変造の判断にAzureのCustom Visionを使用するということを考えてみました。変造や捏造の立証は難しいことから、実際はその手の証拠が提出される場合も残念ながら多くあります。
　本件の内容は、裁判所に提出していますが、現在は審理がこれからなので結果は先になりそうです。
#裁判の流れ
　下級審おこなわれる裁判の多くは、事実認定で結論決まってきます。事実を争うことが主眼になり、自身の主張を証明するために証拠がすべてそろっているわけではないので、間接的な証拠を使ったり、複数の事実から、必要な事実が推定されることを狙った作成を立てたり等、担当弁護士の腕が反映される部分ではないかと思います。
![事実認定.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/f972b8b3-cc76-5fb6-bea0-3f0632f6df75.jpeg)

#筆跡鑑定
　日記や手書きメモが証拠として提出される場面はよくありますし、言った言わないという揉め方は日常のどのような場面で誰でも直面する問題ではないかと思います。ただ、よほど揉めることを想定していない限り、録音しているわけではないので、揉めた場合にはまめに記録を残している方が有利になります。
 問題は単なる行き違いだったらただの揉めごとなのですが、計画的に捏造されている場合や後で都合よく書き換えられている場合、なかなか反論が難しいことを多くあります。筆跡鑑定の専門家はとても高額になる事情から、大きな案件でなければ、中々お願いしにくい事情もあります。鑑定士にお願いすると同じ人が書いた比較用のデータを要求されます。
![比較参照.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/e2eeba24-0e78-94c9-afb5-ae7ec4ebf183.jpeg)
　鑑定士への提出資料を見ていると、やっていることは、機械学習ではないかと思ったのが記事のアイデアになります。

　本件の提出資料の一部ですが、下記のように元々数字だったものを数字以外に書き換えています。30という数字が記述されていたら、まずい状況になるので、書き換えたようです。
![変造.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/950b4a6e-6d8f-c776-82ae-6e3c7fb4eeae.jpeg)

　数字の変造は領収書などの会計の世界でもあり得る話です。
#Custom Vision Serviceの利用
　内容はDeepLearningのサンプルで必ず使用されるMINISTを思い出しますが、MINISTのデータから判定させると必ずしも良い結果が得られるとは限らないです。
　本件でも実行してしてみましたが、口の字は見た目０に近い場合があるので、０のように判断してしまう場合もあります。FC層を取り出して転移学習する方法もありますが、それをやるなら、汎用の画像認識と変わらなくなるので、Custom Visionを試すことにしました。
 Azure Custom Vision Serviceは汎用のサービスなので、通常の筆跡鑑定を頼んだ場合と違い、判断にかたよりが入りません。また、筆跡鑑定はとても高価なので、個人の訴訟などには非常に使いにくいサービスになります。
　参照用のデータは大きくとれませんでしたが、7－8枚程度準備しました。
##0のデータ
![0data.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/88aaf5f1-0352-f336-9432-4ae5ec160407.jpeg)
##口のデータ
![kdata.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/aef7dd3a-cd43-c0ae-e571-39e920ad0fce.jpeg)

##判定結果になります。
０と判断してよいと考えられ、提出資料は変造されていると推定されました。
![結果.JPG](https://qiita-image-store.s3.amazonaws.com/0/177932/3fb7e79f-37e3-e0af-2cb6-2e5dd1663a4d.jpeg)
#結論
汎用的なサービスが充実してきたので、応用はアイデア次第ではないかと思います。客観性の表現が難しい世界に画像認識は客観性を持ち込めるため、この分野は有効ではないかと考えています。
Railsでレコード更新後に更新前の情報を取得する

# レコード変更前と変更後の値を比較したい
Railsで開発していて、レコード変更前と変更後の値を比較したい実装が出てきて、どうやろうかなーと思ったら`previous_changes`という便利なメソッドが用意されていました。

# 使い方

Hogeというテーブルのnameカラムに'変更前'という文字列が格納されているとします。

```ruby
@hoge = Hoge.find(1)
@hoge.update("name = '変更後'")

@hoge.previous_changes
# {"name"=>['変更前', '変更後'], "updated_at"=>[Wed, 13 Jun 2018 14:12:50 JST +09:00, Wed, 13 Jun 2018 14:13:42 JST +09:00]}

```

どのカラムにどういった変更が入ったかを知るのに便利ですね。
ログインを指定時間後には必ず自動でログアウトさせるベストな方法

いまさらながらなんですが、指定時間経過後自動でログアウトさせる方法について説明します。

###アクセスが無くなってから３０分後に自動でログアウトさせたい

ッテ要望は必ずあると思います。
そんなとき単純にsessionのlifetimeを設定すればいいじゃないか。と思うかもしれません。

```php:php
session_set_cookie_params
```

これって、確実に指定した時間でセッションが終了する、というものではありません。
lifetimeを管理しているのは、
GC（ガベージコレクション）です。
session_gcというものがありますが、これは、ある一定確率でゴミ掃除してくれるというものです。
つまり、ある確率でしかセッションは消えない、ということです。

ということは、セッションが消えないときもある、ということになりますね。

ということで、単純に自分で管理すればいいわけです。

Phalcon使いなので、Phalconで説明します。
ちなみに、ログインしたときから３０分経過すると自動ログアウトの処理です。

GCで確率を必ず実行するようにするよりも、この処理のほうが確実で、デバッグしやすいですよね。



```php:session_set
$this->session->set("created", new DateTime('now'));
```

```php:ControllerBase.php
public function initialize() {

    /**
     * セッションの終了をチェックする
     */
    if ($this->session->has('created')) {
        $created = $this->session->get('created');
        if ($created < (new DateTime('now'))->modify('-30 minute')) {
            // 指定時間経過後
            $this->session->remove('created'); 
        }
        // 最終アクセスから経過後としたいなら以下を生かせばいい createedよりも別の名前がよいかも
        //$this->session->set("created", new DateTime('now'));
    }
}
Qt Creator 忘備録

# 前提
* CentOS 7 前提
* epel の Repository　は 登録済み とする。

# install
```
yum --enablerepo=epel install qt-creator
```
* version 4.1.0 (qt-creator-4.1.0-4.el7.x86_64)

# 設定
## 暗化
* "Tools" → "Options" → "Environment" → "Interface" tab
    * "Thema:" → [Flat Dark]

![01.PNG](https://qiita-image-store.s3.amazonaws.com/0/169589/c2c761c2-8188-06e9-9777-de16206837be.png)

# 続く
さっそくVue NativeでHello Worldしてみた

[Vue Native](https://vue-native.io/) が話題になっていたので、さっそく試してみました。

# Vue Native とは

[What is Vue Native?](https://vue-native.io/docs/index.html#What-is-Vue-Native)

Vue.jsでネイティブアプリが作れるツール。中身的にはReact NativeのAPIをラップしているらしい。

# 前提条件

* node 6.0以上
* npm 4.0以上
* React Native CLIがグローバルにインストールされていること

React Native CLIのインストール

```
npm install -g react-native-cli
npm install -g create-react-native-app
```

# Vue Native CLIを使ってプロジェクトを作る

```
npm install -g vue-native-cli
```

インストール後はターミナルの再起動を忘れずに。

```
vue-native init <プロジェクト名> // Create React Native App を使う
vue-native init <プロジェクト名> --no-crna //　Create React Native App を使わない
```

Create React Native Appを使うとExpo.ioというアプリで動作確認ができる

**参考**

* [Create React Native app](https://github.com/react-community/create-react-native-app) 
* [Expo](https://expo.io/)
* [React Native アプリの開発で create-react-native-app を使うべきかどうか - IT探検記](http://itexplorer.hateblo.jp/entry/20170902-create-react-native-app)

今回は `helloVueNative` という名前でCreate React Native Appを使いプロジェクトを作成しました。

## 生成されるファイル

```
helloVueNative
├── .babelrc
├── .gitignore
├── .watchmanconfig
├── App.vue
├── node_modules
├── README.md
├── app.json
├── package.json
├── rn-cli.config.js
├── vueTransformerPlugin.js
└── yarn.lock
```

## 起動

```
cd helloVueNative
npm start
```

ここでエラー発生。

```
> helloVueNative@0.1.0 start <プロジェクトディレクトリのパス>
> react-native-scripts start

12:56:26: Unable to start server
See https://git.io/v5vcn for more information, either install watchman or run the following snippet:
  sudo sysctl -w kern.maxfiles=5242880
  sudo sysctl -w kern.maxfilesperproc=524288

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! helloVueNative@0.1.0 start: `react-native-scripts start`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the helloVueNative@0.1.0 start script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/<ユーザー名>/.npm/_logs/2018-06-13T03_56_26_545Z-debug.log
```

メッセージ通りだけど、watchmanをインストールするかカーネルパラメータを変更すれ。とのこと。

```
brew install watchman
```

```
npm start

> helloVueNative@0.1.0 start <プロジェクトディレクトリのパス>
> react-native-scripts start

13:25:38: Starting packager...
Packager started!
```

無事起動。

# 確認方法

起動したターミナル画面で以下を入力。

1. `a` を入力 -> Android エミュレータの起動
2. `i` を入力 -> iOS エミュレータの起動
3. `s` を入力 -> メールでアプリのURLを送る
4. `q` を入力 -> QRコードを表示する
5. `r` を入力 -> 再起動
6. `R` を入力 -> キャッシュを消して再起動
7. `d` を入力 -> developモードにトグルする

今回は環境の問題でエミュレータで確認。

<img width="442" alt="iPhone X - 11.4 2018-06-13 13-54-23.png" src="https://qiita-image-store.s3.amazonaws.com/0/45634/7beee0a0-a4e8-1954-c990-9931c650dc5f.png">

確認できました。

# ライブリロード

`App.vue` を編集してみる。

```App.vue
<template>
  <view class="container">
-   <text class="text-color-primary">My Vue Native App</text>
+   <text class="text-color-primary">Hello Vue Native App</text>
    </view>
</template>
```

<img width="435" alt="iPhone X - 11.4 2018-06-13 14-01-33.png" src="https://qiita-image-store.s3.amazonaws.com/0/45634/f7ceda67-af69-2be6-2342-789526369c74.png">

ライブリロードされました。
以上です！
備忘録：OpenCV 3.1.0 ソースコンパイル時のヘッダファイルがなくて困る現象まとめ

Torch7のためにどうしてもOpencv3.1.0がソースからのビルドで必要になった時の備忘録
Ubuntu14.04で確認

## linux/videodev.h not found

>https://stackoverflow.com/questions/5842235/linux-videodev-h-no-such-file-or-directory-opencv-on-ubuntu-11-04

ここの回答が一番解決しやすい。要はlibv4l-devをapt-get install して、リンクを張るだけで解決します。

## sys/videoio.h not found 

>https://github.com/opencv/opencv/issues/6262

ここのissueが解決につながった。要はもともと必要ないものらしく、cmakeオプションで
```
-D WITH_V4L=OFF
```
を追加することで、回避可能

## ffmpeg/avformat.h not found

/usr/include/libavformat/内に同名のファイルが存在。バージョンの違いにより細かくなっているらしい　そのままリンクでつなげば大丈夫

## メモ：graphcuts でbuild中にerrorが発生
CUDA8.0以降で発生らしい
>https://github.com/stereolabs/zed-opencv/issues/41
>https://github.com/opencv/opencv/pull/6510/files

バージョン問題らしいので、もしエラーが発生したらソースコードを上記の#6510のように追記しましょう。
通信環境を調査(networksetup,ifconfig,iperf)

#いろいろなコマンドで通信環境を測定

目標としてSSID,RRSI,NOISEやスループットといった物を測定したい

    sudo airport -s # SSIDとRSSIを取得

    networksetup -setairportnetwork en0 [SSID] [password] # SSIDを用いてネットワークを切り替える

    ifconfig en0 | grep 'inet 10' | grep -v '127.0.0.1' | cut -d: -f2 | awk '{ print $2}' # ipアドレスを取得

    iperf -s # server側を立ち上げる

    iperf -c [IPアドレス] # client側からアクセス

これを組み合わせると得たい数値が測定できそう．
JavaとJavaScriptの「別物感」を印象づけるフレーズ集

JavaとJavaScriptをよく知らない者の中にはそれらを混同し、JSのことを指して「Java」と呼ぶ者がいる。そうした人に、言語特徴の違いはさておき、まずはJavaとJavaScriptが別物であることを印象づけることが効果的である。その後に、本人が望めばだが、それぞれの言語の特徴について話に入ると良い。本稿では、そのような状況において役立つかも知れないJavaとJavaScriptの別物感をうまく伝えるフレーズをいくつか紹介する。

## 「メロンとメロンパンくらい違う」

* 同じ食べ物であるが、しかしその性質が全く別であることをうまく表現している。
* 子供でも知っている単語を使うので、多くの人が腑に落ちやすいだろう。
* この表現は中でも広く使われているようで、応用表現として「Javaが書けるならJavaScriptも書けるだろ」のような無茶振りに対する返し文句として**「メロン農家の人にメロンパン売ってくださいって言ってみてください」**というのも考案されている。

## 「インドとインドネシアくらい違う」「オーストリアとオーストラリアくらい違う」

* 似た名前の国名を使った表現である。
* ただし、このフレーズを使う相手は、きちんと地理を理解してなければならない。さもなければ、下記のコピペのようなやりとりに至ってしまうだろう。
    * 「JavaとJavaScriptって違うんですか？」
    * 「インドとインドネシアぐらい違う」
    * 「インドとインドネシアって違うんですか？」

## 「『ブラックジャック』と『ブラックジャックによろしく』くらい違う」

* 作品のタイトルは似ているが、著者が違う、内容も画風も違うというところからJavaとJavaScriptの違いを表現する。
* 漫画好きの相手であれば、すっと理解されることだろう。

## 「加藤あいと阿藤快くらい違う」

* 一見すると似ているが、全然違うということを有名人の名前をつかって表現したもの。

## 「民主党と自由民主党くらい違う」

* 民主党が2016年3月27日に解散したため、最近はあまり使う機会がないかもしれない。
stylelintのorderモジュール選定

## やりたいこと

CSSのプロパティを自動ソート（reorder）したい



## reorderするメリット

- 順番を気にせず書いて楽できる
- スタイルの無駄な重複を防げる
- 読みやすくなる
- gzipサイズが減りやすい



## 使用ツール

`stylelint` を使って自動修正する。
大昔は `CSScomb` を使っていて、少し前は `stylefmt` を使っていた。
今は `stylelint` に `--fix` オプションがついて `stylefmt` が不要になったので、
`stylelint --fix` をそのまま使う。
なお `prettier` では `reorder` を実装するつもりがないので出来ない。
理由についてはこちら。
https://github.com/prettier/prettier/issues/1963



## stylelintのorderモジュール選定

`stylelint` 自体は `order plugin` があるだけで、実際にどの順番でソートするのか？という点では他のモジュールをextendして使うか、自分で順番を設定する必要がある。
大量にあるCSSプロパティを手作りで順番定義するのは死ねるので、基本的には何かをextendして使うことになる。そこで、軽く調べてすぐに出て来た `stylelint-order` のリポジトリを調査し、その中から選ぶことにする。

| package                                                      | properties | releases | contributors | Latest commit | star |
| ------------------------------------------------------------ | ---------- | -------- | ------------ | ------------- | ---- |
| [stylelint-config-recess-order](https://github.com/stormwarning/stylelint-config-recess-order) | 244        | 7        | 4            | 2018/3        | 19   |
| [stylelint-config-property-sort-order-smacss](https://github.com/cahamilton/stylelint-config-property-sort-order-smacss) | 208        | 12       | 3            | 2018/4        | 13   |
| [@jetbrains/stylelint-config](https://github.com/JetBrains/stylelint-config) | 176        | 5        | 4            | 2018/3        | 3    |
| [stylelint-config-rational-order](https://github.com/constverum/stylelint-config-rational-order) | 204        | 2        | 1            | 2017/12       | 8    |
| [stylelint-config-order-bootstrap](https://github.com/swordray/stylelint-config-order-bootstrap) | 209        | 1        | 1            | 2018/4        | 1    |
| [stylelint-config-idiomatic-order](https://github.com/ream88/stylelint-config-idiomatic-order) | 42         | 2        | 3            | 2017/6        | 22   |
| [stylelint-config-fransvilhelm-order](https://github.com/adambrgmn/stylelint-config-fransvilhelm-order) | 121        | 3        | 1            | 2017/4        | 1    |

この中から、次の2点に着目して選定したい

- 定義しているpropertiesが多いもの（少ないとsortする意味がない）
- よくメンテされているもの

 `properties` は多ければ多いほど良いとして、メンテされているかどうかは`releases ` `contributors` `Latest commit` を参考にすればいいだろうか。一応 `star`も載せておいた。



## 結論

次の2つのどっちかを使うのが良さそう

- [stylelint-config-recess-order](https://github.com/stormwarning/stylelint-config-recess-order)
- [stylelint-config-property-sort-order-smacss](https://github.com/cahamilton/stylelint-config-property-sort-order-smacss)

そして `properties`の多さで `stylelint-config-recess-order` を使うことにした。というか1年前から使っていたのだが、今回改めて調査しなおしたら、結局同じものをそのまま使うことになった。また1年後、再調査するかもしれないし、しないかもしれない。
Python - JPG,PNG, JPEG to WebP Format 

#<b>INTRODUCTION</b>
This article I am gonna show you, How to convert all image file format into WebP format using <b>PIL(Python Image Library)</b> but first of all let me explain about what is <b>WebP</b>.

#<b>WHAT IS WEBP?</b>
<b>WebP</b> is an image format which is develop by Google, It is a modern image format that provides superior lossless and lossy compression for images on the web. Using WebP, webmasters and web developers can create smaller, richer images that make the web faster.

#<b>GETTING STARTED</b>

##<b>1. Library Setup</b>
First of all , we have to install webp by using pip

```terminal
pip install webp
```

then , we have to install pillow. If you have pillow install please reinstall it because it is not going to work. you can reinstall pillow by

```terminal
pip uninstall Pillow
pip install Pillow
```
##<b>2. Start Image Conversion</b>

```python
from PIL import Image

imagePath = "Your Image Path" #example ./test.jpg
outputPath = "Output Path" #example ./myWebPimage.webp
quality = "Number of quality you want" #example 100

im = Image.open(imagePath)
im.save(outputPath,'webp',quality = quality)
```
Yes , That's it. It is very easy. I hope you find it useful.
[学習用]Git＋Herokuで使うコマンドと手順。2名用。

#通常のとき
```
$ git pull heroku master
$ git add .
$ git commit -am "make it better"
$ git push heroku master
```

make it betterは分かりやすい名前や内容であれば良いかと。
pull と commit 忘れずに！

#データベースとかGemファイル追加したとき
```
$ git pull heroku master
$ bundle install 
$ rake db:migrate
```

他の人が、組んでくれたものを取り込む。
データベース周りやGemファイルが追加されているときは
上記をしないと、自分のローカルアプリがエラーになるので覚えておく。

#元に戻したいとき
```
$ heroku releases
$ heroku rollback v19
```

失敗したり、元に戻したいときは
releases で一覧表示されるから、戻したい番号を見つけて
「rollback v19」の様にコマンドを入れると戻れる。

デプロイした人の番号、メールアドレス、日時が表示されるのですぐにわかる。

#他の人と被った時
更新内容がほかの開発者と被ったとき。
とくに自分の方は大した内容でないときの対処方法は

```
$ git reset --hard 
$ git pull heroku master
```

で無事解決します。
git reset --hard で直前のmaster状態に戻れる様です。
なので、1回戻ってからpull すれば同期できます。
その後にいつも通り、commit して push すれば大丈夫。

#データベース周り増やした時
```
$ heroku run rails db:migrate
```

Herokuでも rails db:migrate が必要なときは
上記のコマンドでOK。
S3をpathlibっぽく操作する実装をするときに役立つモジュール

Python3.4以降、標準ライブラリにpathlibが追加され、「オブジェクト指向っぽくファイルを操作」できます。同じようにS3のパスを操作できないか、調べてみました。

S3をpathlibっぽく操作できると便利な気がしたので、いろいろ調べています。

ちなみにrequestsやpipenvで有名なkennethreitzさんが[s3monkey](https://github.com/kennethreitz/s3monkey)というライブラリを作っているようなので、調べてます。

# globの実装

パターンに一致するファイルを列挙するメソッドです。[公式ドキュメント](https://docs.python.jp/3/library/pathlib.html#pathlib.Path.glob)のコードを見るとこんな感じ。

```python
>>> sorted(Path('.').glob('*.py'))
[PosixPath('pathlib.py'), PosixPath('setup.py'), PosixPath('test_pathlib.py')]
>>> sorted(Path('.').glob('*/*.py'))
[PosixPath('docs/conf.py')]
```

ただ、[globモジュール](https://docs.python.jp/3/library/glob.html)は実際のファイルパスに機能してしまうため、globの記法(UNIXのファイルパスの記法)によるマッチングだけ行うには[fnmatchモジュール](https://docs.python.jp/3/library/fnmatch.html)を使うようです。

これの[fnmatch](https://docs.python.jp/3/library/fnmatch.html#fnmatch.fnmatch)や[fnfilter](https://docs.python.jp/3/library/fnmatch.html#fnmatch.filter)が使えそうですね。

```python
import fnmatch
import os

for file in os.listdir('.'):
    if fnmatch.fnmatch(file, '*.txt'):
        print(file)
```

# s3のバケットとキーを分割する

StackOverflowの「[s3 urls - get bucket name and path](https://stackoverflow.com/questions/42641315/s3-urls-get-bucket-name-and-path)」を参考に、こんな関数を用意しました。

```python
from urllib.parse import urlparse

def split_s3_path(s3_path):
    parsed = urlparse(s3_path)
    return parsed.netloc, parsed.path.lstrip('/')

bucket, key = split_s3_path('s3://bucket_name/folder1/folder2/file1.json')

print(bucket)
# => 'bucket_name'
print(key)
# => 'folder1/folder2/file1.json'
```

# 一つ下の階層を取得する

boto3のlist_objectsメソッドは、ディレクトリ以下のファイルを再帰的にリストアップしてしまいます。本当はディレクトリに見えている"/"は、単なるKeyの一部なのでこういう挙動のほうが自然ではあるのですが。

1階層下だけを取得する場合はちょっと工夫する必要があります。これもStackOverflowの「[Retrieving subfolders names in S3 bucket from boto3
](https://stackoverflow.com/questions/35803027/retrieving-subfolders-names-in-s3-bucket-from-boto3)」を参考に実装できます。

```python
import boto3

def ls(s3_path):
    # lsの対象がディレクトリのときはうまく機能するが、ファイルのときは空リストが返ってきてしまうので要実装
    client = boto3.client('s3')
    bk, key = split_s3_path(s3_path)
    # rootのときだけ空文字
    if key:
        key = f'{key}/'
    result = client.list_objects(Bucket=bk, Prefix=key, Delimiter='/')
    return [c['Prefix'] for c in result.get('CommonPrefixes', [])]
```

# オンメモリでファイルを開く

get_objectの結果を読み込むと、バイナリで返ってくるので、utf-8の文字列に変換する必要があります。

```python
def s3_read(s3_path):
    client = boto3.client('s3')
    bk, key = split_s3_path(s3_path)
    result = client.get_object(Bucket=bk, Key=key)
    return result['Body'].read().decode('utf-8')
```

pathlibっぽくwith句を使うのはもうひと工夫必要そうです。