OmniAICreator/Qiita-1.07M huggingface dataset:
Archive したアプリの署名を付け替える

## 概要

訳あって開発時と申請時で異なる Bundle Identifier を使っており、申請に使うバイナリを手元の端末で試したかったのでその方法。

## 方法

### 1. ipa を作る

Archive して xcarchive を作ったら、Organize ウィンドウの Export から Development 用の ipa を作る

  - Development distribution options はそのまま (以下は場合により異なる)
    - App Thinning: None
    - Rebuild from Bitcode: YES
    - Strip Swift symbols: YES
    - Include manifest for over-the-air installation: NO)
  - Automatically manage signing で Next

### 2. 署名を付け替える

以下のコマンドを実行

```bash
fastlane sigh resign <対象の ipa ファイル> --signing_identity 'iPhone Developer: your name (ABCD123456)' -n "<付け替え先の bundle id>"
```

fastlane が入っていなければ

```bash
brew cask install fastlane 
```

signing_identity がわからない場合は

```bash
fastlane sigh resign <対象の ipa ファイル> -n "<付け替え先の bundle id>"
```

から表示される候補の名前を使う

### 3. 実機へのインストール

1. Xcode > Window > Devices でインストールしたいデバイスを選ぶ
1. + ボタンで先程の ipa ファイルを選ぶ

間違えった signing_identity を指定してインストールした場合などに、再びインストールすると Internal Error が表示されることがある。
このときは端末を再起動して再度試すこと。
100文字以上の文字列はカットして欲しいって言われた時の話

お客様より

・DBからテキストを引っ張ってきて画面に出して欲しい。
・HTMLタグが文章中に含まれているが、エスケープせず印字して欲しい。
   └ \<strong>タグと\<sub>タグ
・文字数が100文字以上の場合、その先は省略して欲しい（文末に「...」も出してほしい）
・**HTMLタグは100文字の文字数に含めないで欲しいが、当然画面には反映しろ。**

という依頼を受けた。

## ざっくり実装
```html+erb:text.erb
strong_array = text.scan(/<strong>(.*?)<\/strong>/)
sub_array = text.scan(/<sub>(.*?)<\/sub>/)

text = text.gsub(/<strong>|<\/strong>/,'')
text = text.gsub(/<sub>|<\/sub>/,'')

text = text.match(/[\s\S]{1,100}/)

strong_array.each do |val|
  text = text.gsub(val,'<strong>' + val + '</strong>')
end 

sub_array.each do |val|
  text = text.gsub(val,'<sub>' + val + '</sub>')
end

<%= raw text %>
```
さー画面に印字テストーーーーってところで問題が。
\<strong>タグで囲まれた部分は、「記号+文字列」で構成された所謂見出し部分なので、
基本的に他のテキストと被ることが無いのでギリセーフ。パリング成功。

が、\<sub>タグで囲まれた所が問題だった。
数字だったのだ。
例：（注釈\<sub>1\</sub>）のような感じ

そんなわけだから、安易にgsubなんかかけたらそりゃあデータが狂う狂う。

泣く泣く別の実装を探すも、私の探し方が悪いからか、
「文字列をn文字引っ張ってくる。
その際に特定の文字列は文字数カウントしない。
結果にはその弾いた文字列を含む」
なんて便利メソッドはどこにも見つからなかった。

正規表現も、私はせいぜいギラ程度のレベルしか扱えない。

召喚魔法も、上司が休暇では使えない。

こうなればもう。原点回帰の呪術（ゴリ押し）で組むしかない。

## 呪術：内なる大力

```html+erb:text.erb
<%
# およそ使わないであろう文字に変換
text.gsub!(/<strong>/, '★★★★★★★★')
text.gsub!(/<\/strong>/, '★★★★★★★★★')
text.gsub!(/<sub>/, '★★★★★')
text.gsub!(/<\/sub>/, '★★★★★★')
# 文字列を、1文字区切りの配列に変換する
safety_array = text.split("")
count = 0
index = 0
# 置き換えた文字を省いてカウントを進め、100文字目のindexを取得する
safety_array.each_with_index do |val, i|
  index = i
  next if val === '★'
  break if count === 100
  count += 1
end

# 閉じタグが付かずに終わった場合、該当のタグのカウントが-１となる
strong_tag_count = safety.scan('<strong>').size - safety.scan('</strong>').size
sub_tag_count = safety.scan('<sub>').size - safety.scan('</sub>').size
end_of_sentence = ""
end_of_sentence << '</sub>' if sub_tag_count > 0
end_of_sentence << '</strong>' if strong_tag_count > 0
end_of_sentence << '...'
%>

<%= raw text + end_of_sentence %>
```
無い頭を捻ったところで、この程度の実装しか出てこなかった。
「およそ使わないであろう文字」は制御文字で良かったかもしれない、
タグ置き換え部分はタグを配列に入れて回す方がスマートだったかもしれない などと思いつつ、
一応の完成とするのであった。

同じ場面に遭遇した魔法使いが居ればなるべく参考にはしないで欲しいし、
鼻で笑いながらツザリクでも唱えて欲しい。

願わくば、これを見た冒険者がイケてる実装を記してくれることを願い、この手記を終わりとする。



#### 追記
ぶった切るならコレで良いじゃん。

```
array.scan(/(<strong>|<\/strong>|<sub>|<\/sub>|\S)/).flatten
```

#### 追記２
最終的にこうなった。

```ruby
  def self.cutter(html,length,count = 0,cut = '',tags = [])
    if count < 1
      # タグナシの文字数が規定文字数以下ならそのまま返す
      return html if html.gsub(/<strong>|<\/strong>|<sub>|<\/sub>/,'').length <= length
      # 文章は1文字ごとに、タグは文字列で格納 改行も諸事情で1文字とする
      html = html.scan(/(<strong>|<\/strong>|<sub>|<\/sub>|\S|\n)/).flatten
    end
    target = html.shift
    # 開始タグのみ取得 その際、閉じタグ化 2文字以上はタグ また、/が含まれるのは閉じタグなので無視
    tags.unshift(target.clone.insert(1,'/')) if target.length > 1 && !target.include?('/')
    # 閉じタグをリストから除去 開始タグ取得時に閉じタグ化しているので、閉じタグが来たら判別できる
    tags.shift if tags.first.eql?(target)
    cut << target
    # 文字数に数えるのはタグ以外
    count += 1 if target.length == 1
    if count == length
      # 閉じられていないタグがあるならば、登場順に適用する
      # <strong>hoge<sup>1 とかで終わっても大丈夫
      tags.each do |val|
        cut << val
      end
      cut << '…'
      return cut
    end
    # 再帰処理
    cutter(html,length,count,cut,tags)
  end
```
WordPress Permissions Update Error 

The solution as it turns out is to reset the file permissions on the core files.
Provided you have SSH access to your server, the following commands may fix your issue.
Reset the permissions of all files to 664:

> find /path/to/site/ -type f -exec chmod 664 {} \;

Reset permissions of directories to 775:

> find /path/to/site/ -type d -exec chmod 775 {} \;

Reset the group to the wordpress group (or whatever group makes sense for you)

> chgrp -R wordpress /path/to/site/

After running those commands I was able to successfully update WordPress with no further issues.
C++ メモリバリア 使い方

必要性に追われて、メモリバリアを使ったコードを書くことになったので、自分用のメモとして残しておいたものです。

#メモリバリア

> MemoryBarrier（メモリバリア）または MemoryFence（メモリフェンス）とは、その前後のメモリ操作の順序性を制限するCPUの命令の一種である。

C++の標準ライブラリにおける、メモリバリアの定義はこちら。

```cpp:
namespace std {
  enum memory_order {
    memory_order_relaxed,
    memory_order_consume,
    memory_order_acquire,
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst
  };
}
```
※この記事では、***memory_order_acquire***と、***memory_order_release***だけを扱っています。
#マルチスレッドプログラムにおける利用例

```cpp:
#include <iostream>
#include <atomic>
#include <thread>

int data;
std::atomic<bool> ready(false);

void f()
{
  while (!ready.load(std::memory_order_acquire)) {
  }

  std::cout << data << std::endl;
}

int main()
{
  std::thread t(f);

  data = 765;
  ready.store(true, std::memory_order_release);

  t.join();
}
```

##アトミック変数
`std::atomic`
>アトミック変数とは、不可分な読み出しや書き込み、および読み書きを同時に行える変数である。

アトミック変数への操作は、他のスレッドによって割り込まれることがない。
つまり、アトミック変数は、その値の変更操作がスレッドセーフであるといえる。

std::atomicには、専用の操作関数が用意されている。

||        |
|:-----------------|------------------:|
| 読み込み用メンバ関数          |              load |
| 書き込み用メンバ関数          |            store |

###***load-acquire***
値の読み出し後の実行順序を制限する。

```cpp:
 while( !ready.load( std::memory_order_acquire ) ) {
 }
 
 // ここより下のコードが、
 // std::memory_order_acquire を指定した値の読み出しより、
 // 後に実行されることが保証される
 std::cout << data << std::endl;
```
###***store-release***
値の書き込み前の実行順序を制限する。

```cpp:
 data = 765
 // ここより上のコードが、
 // std::memory_order_release を指定した値の書き込みより、
 // 前に実行されることが保証される
 ready.store( true, std::memory_order_release );
```
#mutexとの違い
**MUTual EXclusion (相互排他、排他制御)**
>mutexとは、クリティカルセクションでアトミック性を確保するための排他制御のことである。
クリティカルセクションを同時に実行するスレッドが１つだけであることを保証する。

##ロックガード
`std::lock_guard`
C++の標準ライブラリで提供されている仕組み。

```cpp:
 uint32_t g_x;
 
 std::mutex mtx;
 
 void add_value()
 {
   std::lock_guard<std::mutex> lock(mtx);
   // クリティカルセクション ここから
   g_x++;
   // クリティカルセクション ここまで
 }
 
 void safe_print()
 {
   std::lock_guard<std::mutex> lock(mtx);
   // クリティカルセクション ここから
   printf( "%d", g_x );
   // クリティカルセクション ここまで
 }
```
共有変数の値を安全（スレッドセーフ）に読み込む、書き出すという点では同じ効果を得られるが、
以下の2つの特徴の違いを正しく理解しておく必要がある。

- メモリバリアは順序性を制御するものであり、クリティカルセクションを設けるものではない
- mutexのロックによるクリティカルセクションの実行中は、他のスレッドがその実行を妨げられる
自己署名証明書の作り方がいつの間にか変わっていました

PowershellDSCでAzureManagementAPIを証明書認証で利用していて、今回新たに環境構築していました。

その際に、windowsのPCで自己署名証明書を作成したかったのですが、
以前はmakecertを使用していましたが、いつの間にか使用できなくなっていたのであたらしいやり方でやってみようと思います。

#以前のやりかた
makecertで証明書を作成し、パスワードを設定してエクスポートするというやりかたです。

##まずは、
証明書を作成します。
cmdで実行します。

``` 
"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\makecert.exe" -sky exchange -r -n "CN=AzureManagementAPI" -pe -a sha256 -len 2048 -ss My "AzureManagementAPI.cer"
```

##次に
パスワードを作成しておきます。
ここからはpowershellで実行します。

``` 
$MyPwd = ConvertTo-SecureString -String "パスワード" -Force ?AsPlainText
```

##先ほど作成した証明書を探します。

```
$AzureCert = Get-ChildItem -Path Cert:\CurrentUser\My | where {$_.Subject -match "AzureManagementAPI"}
```

##最後に
証明書をエクスポートします

```
Export-PfxCertificate -FilePath C:\AzureManagementAPI.pfx -Password $MyPwd -Cert $AzureCert
```

##ポータルへアップロード
エクスポートしたファイルをAzureポータルにアップロードして完了です。

#あたらしいやり方

##まずは
###証明書作成
makecertの代わりになるのがNew-SelfSignedCertificateのようです。
New-SelfSignedCertificateを実行して証明書を作成します。

```
$cert = New-SelfSignedCertificate -DnsName AzureManagementAPI -CertStoreLocation "cert:\LocalMachine\My" -NotAfter (Get-Date).AddYears(1)
```

##次に
###パスワード作成

```
$password = ConvertTo-SecureString -String "パスワード" -Force -AsPlainText
```

##最後に
###エクスポートします。

####pfxでエクスポートする場合は以下を実行
```
Export-PfxCertificate -Cert $cert -FilePath "C:\azuremanagementapi.pfx" -Password $password
```

####または、cerでエクスポートする場合は以下を実行
証明書をAzure管理ポータルで使用する場合は以下を実行します。

```
Export-Certificate -Type CERT -Cert $cert -FilePath C:\azuremanagementapi.cer
```

##アップロード
上記で作成したcerファイルの方の証明書をAzureのポータルへアップロードすることで
AzureManagementAPIを利用することができるようになります。

以上です。

最後にシェルの全文を載せておきます。
信頼されたルートへは一旦ファイルへ掃き出しインストールするようになっています。

``` powershell

$DnsName = "AzureManagementAPI"
$NotAfter = (Get-Date).AddHours(1)
$passwordString = "password"
$filename = "mycert"

$CertDir = "C:\"
$pfxFileName = $CertDir + $filename + ".pfx"
$cerFileName = $CertDir + $filename +  ".cer"
$cert = New-SelfSignedCertificate -DnsName $DnsName -CertStoreLocation "cert:\CurrentUser\My" -NotAfter $NotAfter -KeyAlgorithm RSA
#PFX形式
$password = ConvertTo-SecureString -String $passwordString -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath $pfxFileName -Password $password
Import-PfxCertificate -Password $password -FilePath $pfxFileName -CertStoreLocation "cert:\CurrentUser\Root"

#CER形式
#Export-Certificate -Type CERT -Cert $cert -FilePath $cerFileName
#Import-Certificate -FilePath $cerFileName -CertStoreLocation "cert:\CurrentUser\Root"

```

#参考
https://docs.microsoft.com/ja-jp/azure/cloud-services/cloud-services-certs-create#what-are-management-certificates
https://docs.microsoft.com/ja-jp/azure/azure-api-management-certs
fastlaneで undefined method 'each' for nil:NilClass が出たら

iOSアプリのCI環境を作っていたらくそはまったのでメモしておきます。
fastlaneとTravisCIを使っていたのですが、fastlaneのgymを使うとタイトルのエラーが出てしまいました。

```
undefined method `each' for nil:NilClass
```

これの対処法は以下です。

>
**Part 1**
>
Check if you have the right version of RubyGems
>
```
$ gem -v
2.6.5 (or superior)
```
>
If you have not, upgrade your RubyGems:
>
```
$ gem update --system
if you can't use `sudo` like this:
$ sudo gem update --system
```
>
**Part 2**
>
Now check you have the last bundler version:
>
```
$ bundle -v
Bundler version 1.13.0 (or superior)
```
>
If you have not, upgrade your Bundler:
>
```
gem install bundler
```
引用：https://github.com/fastlane/fastlane/issues/6203#issuecomment-251627196

ずっとfastlaneを怪しんでいたけど、gemとbundlerのバージョンをちゃんと確認すればすぐ終わったのね...
strcmpを空文字比較で使うな

#if(strcmp($str,'')==0);を見つけたら抹殺しておけ
##Badコード

```php
//memberは必須やで
if(isset($_GET['MEMBER']) && strcmp($_GET['MEMBER'], '') == 0){
  http_response_code(404);
  exit;
}
```

絶対に許さない。```$_GET['MEMBER'] === ''```でいいだろ。
というか、GETパラメータに配列入ってくるとかちゃんと考えてるのかと小一時間
$_GETは入ってればArray以外はstrで返すからまだマシ（ほんとに？）だが、
falseも通るしnullも通る。そこに使ってほんとに良いのか？考えて実装してほしい。


```php

$method = $_SERVER['REQUEST_METHOD'];
if(strcmp($method, 'GET') == 0){
  $request['hoge'] = isset($_GET['hoge']) ? $_GET['hoge'] : null;
}
```

完全一致は===で良いだろ！いい加減にしろ！
わざわざ出現位置を調べる必要が無い。

##Goodコード
仮に文字検索なら
出現を調べるなら`strpos`など`**pos`関数です。
`strstr`を使う人が居ますが、`strpos`のほうが探す **だけ** なら適切です

```php
if(strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false){
  http_response_code(404);
  exit;
}
```

#脳死実装はやめて意味を考えて
新規コードはともかく、既存コードの変更で上や下の既存コードを何も考えずパクってくるのは大いに結構だが、安直に実装するなかれ。

※擁護するとstrcmpはPHP4時代やPHP5.0時代のnullバイト攻撃に対処するために最初の開発者は実装したのではと考えてるが真意は不明。
バーストリクエストとの戦い

# はじめに
外向けにサービスを展開していると、サービスにもよりますがバースト的なトラフィックが発生して、食いきれなくなることがあるかと思います。
自分の担当していたサービスでは、ピーク時には平常時の１０倍以上のリクエストがきて、ELBで食いきれなくなることが多々ありました。
試行錯誤を繰り返して、ある程度は解消したので、その時行った対策や検討などを書きたいと思います。


# バーストリクエスト
### バーストリクエストとは？
何らかしらの原因で急激にリクエストが増える事です。
下のメトリックスではLBへのアクセスが１０倍程度になっています。
<img width="980" alt="スクリーンショット 2017-10-24 9.10.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/202960/7d5c28c7-9404-da28-c58b-c0bae4cf8955.png">

### なぜ起きるか？
今回の場合は、アプリからAPIを叩かれるサービスを行っていたため、地震が発生した場合などニュースアプリ等から大量にリクエストが来て、この様な現象が発生していました。
他にも広告システムなど、キャッシュを効かせられないサービスではこのようなバーストが起きたりします。

### 発生して困る事
書くまでもない事ですが、一時的にサービスが使えなくなったり重要なデータが取れなかったりします。(例えば広告が出ない)
もちろん、どこまで対応するかはサービスのSLA次第ですが、できるだけ無くしたいですよね・・・・。

# 対策案検討時(ボトルネックを特定する)
基本的には、ロードバランサやインスタンスのメトリックスを見ればある程度はわかります。
* ELB 5XXs(カウント)が増えている場合　=> [LBのキャパシティが足りない可能性が高い](http://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/classic/ts-elb-error-message.html#ts-elb-errorcodes-http503)
* バックエンド接続エラー(カウント) or ターゲット接続エラー(カウント)が増えている場合 => 配下のインスタンスのキャパシティが足りていない可能性が高いです。（サーバ台数を増やしましょう）

今回対応したパターンでは、どちらも起きてそうでした・・・・・。

# 環境
## 構成図
<img width="545" alt="スクリーンショット 2017-10-30 9.23.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/202960/eb5b828d-b05a-1612-0ea4-825ee5ef3c8c.png">

## 対策前の環境
* ELB(CLB)
* APIサーバはapacheでpre-forkモデル
* サーバはautoscaleで必要に応じで増減させる

## 対策後の環境
* ALB
* APIサーバはgolangでrewrite
* サーバは台数固定
* クライアント側から再送を頑張ってもらう(対策前からもある程度はやっていたと思われる)

## 各対策の説明
* ELB->ALB(パフォーマンス向上を狙って変えてみたが劇的には変わらず。)
* apache->golang(そもそもpre-forkモデルがイケてなかったせいもあり、パフォーマンス的には劇的に改善。必要な台数は半分以下に)
* autoscale->台数固定　(バーストリクエストが来た場合に、そもそもautoscaleが間に合っていない様な状況だったので、ある程度食える台数を見積もって固定台数に変更。)
* クライアント側から再送(再送である程度は救えるが、リアルタイム性を要求するものには厳しい)

## ELBのオートスケールが間に合っていない場合の対策方法
* 常に負荷(ダミーリクエスト等)をかけておくと、ある程度台数いる状態になります。
* 明らかにリクエストが増えそうな場合はAWSに連絡すると一時的には、増やしてくれます。ELB暖気運転(Pre-Warming)申請というのを出して下さい。

# 最後に
基本的に、突発的なバーストトラフィックに対しては、autoscaleでは間に合わないことが多いです。
そういう意味では、最大キャパに合わせてサーバを設置できるオンプレの方が合っているかもしれないです。
AWS側でのこの辺の問題は気にしているようなので、今後改善されて行くことに期待してます。
Beyond Compare Setting

#概要

比較ツールとしては、[Winmerge](http://www.geocities.co.jp/SiliconValley-SanJose/8165/winmerge.html)がありますが、それよりも高機能で使いやすい[Beyond Compare](https://www.scootersoftware.com/index.php)の設定について書いておく。
[Beyond Compare](https://www.scootersoftware.com/index.php)

#初期設定
下記のように設定しておくことで、フォルダ選択時に下位のフォルダまで比較してくれる。

![2017-10-31_104915.png](https://qiita-image-store.s3.amazonaws.com/0/47172/44468188-c28f-e725-3c6a-c4320d741306.png)

![2017-10-31_104927.png](https://qiita-image-store.s3.amazonaws.com/0/47172/fd7f111d-5e00-b8ca-cf20-1724da85d573.png)
[PHP]ゲーム作成初心者がPHPでテト〇ス風ゲームを作ってみた

# 作ってみた

名前は **TETRICE** です！

![image.gif](https://qiita-image-store.s3.amazonaws.com/0/31393/ff37cee4-52f7-302c-2378-cc2300f5aeb3.gif)

リポジトリは[こちら](https://github.com/PruneMazui/tetorice)

# なんで？

どっかの質問サイトでPHPでゲームは作れますか？作るにはどうしたらいいですか？ってQに対するAが作れません or Javascript で作りますみたいな内容だらけだったのに触発されただけ。

ちなみにゲーム作ったことはほぼないです。

# いきなりまとめ

使ったことないけどCUIでグラフィカルなことしたいんだったら[termbox](https://github.com/nsf/termbox)使った方がいいと思う。
（この記事全否定）
[PHPライブラリ](https://github.com/adsr/termbox-php) → `yum install -y php-pecl-termbox`

# 他

スペルミスじゃないよ。
http://hot-topic-news.com/tetris-copyright

# [暇な人用]にっき

以下時系列で。

### 標準入力のノンブロッキング化

普通にキーボードの入力受けようとするとその時点でブロックされてしまう。  
（キーボード入力待ちみたいな状態）  
画面垂れ流しのまま標準入力を受けようとするとnon-blockingにしないといけない。

1. fcntl() で nonblocking にしてやろうとする
1. [dio_fcntl()](http://php.net/manual/ja/function.dio-fcntl.php) 『注意: この関数は Windows 環境にはまだ実装されていません。』
1. 色々ぐぐって `stream_set_blocking(STDIN, FALSE);`見つけた。
1.  組み込んでみるもなんか動かない。
1.  動かない報告いっぱいあった。

最終的に `stream_select` のタイムアウトを0にして標準入力を監視する方式にした。

```php:src/app/Controller.php
<?php
class Controller implements LoopProcessInterface
{
    private function readNonBlock(&$data) {
        $read = [STDIN];
        $write = [];
        $except = [];

        $result = stream_select($read, $write, $except, 0);

        if($result === false) {
            throw new \Exception('stream_select failed');
        }

        // Cygwinだとここが必ず1になるから`stream_get_contents`でブロック状態になってしまう・・・
        if($result === 0) {
            return false;
        }

        $data = stream_get_contents(STDIN);

        return true;
    }

    public function loopProcess()
    {
        $data = "";
        if ($this->readNonBlock($data)) {
            echo $data;
        }
    }
}
```
`stream_select` で変更があれば 1、変更がなければ 0 が返る。
1の時に入力内容を取得してブロック状態にならないようにしたかったのだが、Cygwin上だと必ず1が返る／(^o^)＼(未解決)

### ユーザー入力値の制御

* 標準入力をエンター押すまでじゃなくて押下した段階で取りたい
* ユーザーの入力をコンソールに出さない

右とか左とかならまだしもスペースとか入力した値を表示してしまうと画面表示時にずれちゃう。なのでパスワードの入力時みたいにユーザーの入力値を非表示にしたい。

正直気持ち悪いが stty コマンド呼び出して対応・・・
`shell_exec("stty -icanon -echo")`

プログラム終了時に元のターミナルに戻っても適用されたままなので元に戻す処理を組み込み。
`try - finally` で戻す場合、開発中にexit したときとか`finally`が呼ばれない。
ただしデストラクタは呼ばれるのでそっち側に組み込んだ。

### 画面の描画

とりあえず画面クリアして書き込めばいいんだろとか思って clear して echo したところちらつきと出力ログ大量みたいなことになった。やりたいこととしては top コマンドに近い感じなので標準出力の内容をカーソル移動して書き換える形にした。

こんな感じで[ANSIエスケープシーケンス](https://qiita.com/PruneMazui/items/8a023347772620025ad6)で戻って上書き可能。

```php:sample.php
<?php
for ($i = 1; $i <= 5; $i++) {
    $str = "--- {$i}/5 ---\n";
    echo $str;

    // カーソルを一つ上にずらす
    echo "\e[1A";

    sleep(1);
}
```
![cursor.gif](https://qiita-image-store.s3.amazonaws.com/0/31393/949a9d08-36a9-9e96-e9ce-af08ca65f0bb.gif)

この部分書き換え＋flush()を駆使することで意図通り綺麗にでるようになった。

他にも[ANSIエスケープシーケンス](https://qiita.com/PruneMazui/items/8a023347772620025ad6)でブロックの色を表現したりした。
（スペース2つ＋背景色を変更）


### その他

* ゲーム部分実装をかなりやっつけで作ってしまった感がある。  
テトリスのアルゴリズムちゃんとやるとかなりしんどそうね。
* ブロックの種類的に1色足りなかった・・・
* 完全にプロトタイプ作りながらなのでUnitテストがかなり後発になってしまった。
* TravisCI + Coveralls 導入した
Paper collection on Information Retrieval System

# Paper List by Time
   
- 2016
    - [Learning Term Weights for Ad-hoc Retrieval](https://arxiv.org/pdf/1606.04223.pdf)    
        - [A blog? on Linkedin](https://www.linkedin.com/pulse/learning-term-weights-ad-hoc-retrieval-vaibhav-agrawal)

- 2005
    - [Learn to Weight Terms in Information Retrieval Using Category Information](http://www.machinelearning.org/proceedings/icml2005/papers/045_LearnToWeight_JinEtAl.pdf) ICML
IBM Bluemixで.Net Coreしてみる

## IBM Bluemix

なにやらIBM Bluemixがライトプランなら無料で使える、ということなので使ってみました。
ちなみに.Net Core 2.0.0をインストール済みのMacでの話です。

## .Net Coreのチュートリアルをやってみる

.Net Coreのチュートリアルは [こちら](https://console.bluemix.net/docs/runtimes/dotnet/getting-started.html#getting_started) 。
読んでみると、.Net Core SDK 1.0.4をインストールしろ、と書いてある。
1.0.4かぁ…。と思いながら、

### Cloud Foundary CLIのインストール

まずはチュートリアルの通りにサンプルを実行。
Macにチュートリアルページにある、 [Cloud Foundry CLI](https://github.com/cloudfoundry/cli#downloads) をパッケージでインストール。
Homebrewでやろうとしたら、Rubyが2.0.0だとダメだと怒られたので…。

### サンプルを実行

書いてある通りにして特に問題なくローカルで試す。

```shell-session
$ git clone https://github.com/IBM-Bluemix/get-started-aspnet-core
$ cd get-started-aspnet-core/src/GetStartedDotnet
$ dotnet restore
$ dotnet run
```

http://localhost:5000/ をアクセスしてみる。
特に問題なし。

### サンプルのデプロイ

```shell-session
$ cd ../..
$ cf login
$ cf push
```

ライトプランではメモリが256Mまでなので、このままでは怒られます。
manifest.yml の memory: の値を256M以下に編集し直して再度 `cf push` を行う。
これも特に問題なく実行できます。

### push時のログ

```
-----> Installing .NET SDK
       .NET SDK version: 2.0.0
```

ん！？
.Net Core 2.0.0をインストールした、と出たじゃないですか。
これは試してみなければ、ということで。

## .Net Core 2.0.0で試す

mvcで作ったすの状態で動くかどうか試してみます。

### プロジェクトを作る

```shell-session
$ mkdir IBTest
$ cd IBTest
$ dotnet new sln
$ dotnet new mvc
$ dotnet sln IBTest.sln add IBTest.csproj
$ dotnet run
```

特に問題なくmvcのテンプレートで動きます。

### pushする

下記の内容で `manifest.yml` ファイルを作成。

```yaml
---
applications:
- name: IBTest
  random-route: true
  memory: 64M
  env:
    DOTNET_CLI_TELEMETRY_OPTOUT: 1
    DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true
```

Bluemixにpushします。

```shell-session
$ cf push
```

…問題なく動いているようです。
ダッシュボードを確認し、リンクをクリックしてページを開いてみると、これも問題なし。

```shell-session
$ cf app IBTest
```

と、情報をとってみると、

```
名前:               IBTest
要求された状態:       started
インスタンス:         1/1
使用:               64M x 1 instances
routes:            ibtest-xxx.mybluemix.net
最終アップロード日時:   Tue 31 Oct 10:40:42 JST 2017
スタック:            cflinuxfs2
ビルドパック:          ASP.NET Core (buildpack-v1.0.26-20170913-1346)

     状態   開始日時               CPU    メモリー       ディスク       詳細
#0   実行   2017-10-31T01:45:15Z   0.0%   26.3M of 64M   443.9M of 1G   
```

と。
まだメモリに余裕がありそうなので、いろんなことができそうです。
HikiでGitリポジトリを設定する方法

# 単独の Hiki で Git レポジトリを設定する方法

HikiFarm ではないという意味で、単独のHikiの場合です。

[オフィシャルサイトの情報](http://hikiwiki.org/ja/?cmd=view&p=repository&key=git)が間違っているので、下記に修正版を掲示します。
オフィシャルサイトがHikiなので、本当はそのページを修正してあげたいのですが、パスワードを求められてページを書き換えることができません。そのため、やむなくここでお知らせします。

## Git 篇

以下のような環境を例に説明します。
<dl>
  <dt>データ格納用のパス</dt>
  <dd>/home/foo/hiki/</dd>
</dl>

まず Hiki をセットアップした後、CGI の実行権限で以下を実行します。

```
 # ページデータのディレクトリ(text)に移動
 cd /home/foo/hiki/text
 # Git レポジトリの作成
 git init
 git config user.email "you@example.com"
 git config user.name "Your Name"
 # データのインポート(git addの後にピリオドがあることに注意)
 cd /home/foo/hiki/text
 git add .
 git commit -a -m 'import'
```

次に、hikiconf.rb に以下の設定を追加します。

```hikiconf.rb
 @repos_type = 'git'
```

あとは、せっかくなのでhistory.rbを有効にしましょう。
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':sql_last_run' at line 1

logstash で `jdbc statement => "SELECT * FROM member WHERE updated_at > :sql_last_run"` ってやると

```
Exception when executing JDBC query {:exception=>#<Sequel::DatabaseError: Java::ComMysqlJdbcExceptionsJdbc4::MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':sql_last_run' at line 1
```

というエラーがでる

## 理由

いつからか `sql_last_run` は `sql_last_value` になってた
Xcode ログに絵文字と「月の満ち欠け」を print してライフサイクル・デリゲートを理解する（Tips 小ネタ）

ライフサイクル・デリゲートが呼ばれるタイミングを正確に理解するため、ログを print で表示する際、絵文字と「月の満ち欠け」をつけるとわかりやすくなりました。　（添付画像参照）

![img2.jpg](https://qiita-image-store.s3.amazonaws.com/0/196881/06ad3003-82bc-d6ca-7511-6c2faf712783.jpeg)
[Junji Suzuki JBOYSOFT](http://www.jboysoft.jp/)

付記:
ライフサイクル、デリゲートが呼ばれるタイミングは、iOSの進化によって順序変更や Deprecated がありえます。
***
2017/10/31 執筆時の環境： Xcode 9.0.1 + iOS 11
》》Balancing between over-weighting and under-weighting in supervised term weighting

Start: 2017/10/30
Finish: 2017/10/??

[PDF](http://10.1016/j.ipm.2016.10.003)
[Slide not available yet](#)

# Very Similar Papers on context of supervised term weight
- 2015, New term weighting schemes with combination of multiple classifier for sentiment analysis [PDF](http://repository.taibahu.edu.sa/en/bitstream/handle/123456789/14629/New%20term%20weighting%20schemes%20with%20combination%20of%20multiple%20classifiers.pdf?sequence=1&isAllowed=y) [READ]()
- 2007, Supervised and Traditional Term Weighting
Methods for Automatic Text Categorization [PDF](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.151.3665&rep=rep1&type=pdf)
- 2005, Learn to Weight Terms in Information Retrieval Using Category Information [PDF](http://www.machinelearning.org/proceedings/icml2005/papers/045_LearnToWeight_JinEtAl.pdf) [READ]()
- 2009, Learning term-weighting functions for similarity measures [PDF](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/Yih-EMNLP-09.pdf)

# IDEAs of Application
- some supervised global term weighting can be useful to score term when genre-filtering


# ABSTRACT
- Supervised term weighting for text categorization.
- Proposed a new concept of **Over-weighting**, in context of controlling over-weighting and under-weighting
    - **over-weighting**: assign larger weight to terms with more imbalanced distributions across categories
    - **under-weighting**: ratios between term weights becomes too small. Because sublinear scaling and bias term shrink the ratios 
- Proposed a new supervised term weighting scheme, regularized entropy (*re*)
- Present 3 **regularization techniques**: add-on smoothing, sublinear scaling, bias term
- Evaluated on a lots of datasets on both tasks of topical classification and sentiment classification
- Other terminology:
    - regularization and over-weighting & under-weighting
    - scaling functions
    - bias term

# INTRODUCTION


# REVIEW of TERM WEIGHTING SCHEMES
   | weight(term, doc) = local_weight_of_term x global_weight_of_term x normalization_factor_of_doc |

- **Local term weighting**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/209734/5d51d73e-54f3-d2a5-c3fc-3a9b678a253e.png)


- **Global term weighting**

![image.png](https://qiita-image-store.s3.amazonaws.com/0/209734/ee800d7e-63a2-d69a-de27-d675f9c39b96.png)


# ...
Ansible RoleでNew Relic INFRASTRUCTUREのインストールを自動化

# はじめに
Amazon EC2インスタンスにNew Relicの[INFRASTRUCTURE](https://newrelic.nissho-ele.co.jp/products/newrelic-infrastructure)をインストールする場合、コマンドラインで実行してもそこまで手間ではないのですが、インスタンスの複数台環境などにおいては手作業だと手間がかかります。可能であれば、サクッと自動化して、インストールしたいところ。

そこで今回は、Ansibleを使ってEC2インスタンスへのNew Relic [INFRASTRUCTURE](https://newrelic.nissho-ele.co.jp/products/newrelic-infrastructure)エージェントインストールを自動化したいと思います。

幸いにもNew Relic [INFRASTRUCTURE](https://newrelic.nissho-ele.co.jp/products/newrelic-infrastructure)にはAnsible Roleが用意されておりますので、git cloneでダウンロードしてしまえばとても簡単にAnsibleによるエージェントインストールが可能です！GitHubのURLはこちら [GitHub infrastructure-agent-ansible](https://github.com/newrelic/infrastructure-agent-ansible)。

また、まだNew Relicをアカウント作成されていない方は[こちら](https://newrelic.nissho-ele.co.jp/)から。

# インストール手順
## 0. インストール準備
今回は下記の構成にて、Playbookを作成していきます。

- 起動環境: AWS EC2
- OS: Amazon Linux AMI release 2017.09

```yaml:Ansible-Playbook階層
ansible-playbooks
├── roles
│   └── nrainfragent
├── hosts
│   └── local
├── setup-infra.yml
```

まずはAnsibleのインストールから。pipを使ってインストールします。

```yaml:pip及びAnsibleのインストール
$ sudo easy_install pip
$ sudo pip install ansible
```

## 1. New Relic INFRASTRUCTURE Agentインストール用ロールのダウンロード
rolesディレクトリ配下にgithub上のINFRASTRUCTURE Agentインストール用ロールをダウンロードします。ダウンロード後、ディレクトリ名を"nrinfragent"に修正します。

```
$ cd roles
$ git clone https://github.com/newrelic/infrastructure-agent-ansible.git
$ mv infrastructure-agent-ansible nrinfragent
```

## 2. Hostsファイルの作成
今回はローカルホストに対して、Agentインストールを実行するため、Hostsファイル"local"作成します。

```yaml:ansible-playbooks/hosts/local
[localhost]
127.0.0.1
```

## 3. Playbookの作成
最後にINFRASTRUCTUREエージェントのインストールに必要な情報やロールを記載したPlaybookを作成します。ライセンスキー(nrinfragent_license_key)の箇所にご自身のNew Relic License Keyを入力ください。今回インストールするEC2のOSはAmazon Linuxとなりますが、OS名のオプション(nrinfragent_os_name)には"redhat"を、OSバージョン(nrinfragent_os_version)には"6"と入力します。

```yaml:ansible-playbooks/setup-infra.yml
---
- hosts: localhost
  roles:
    - role: nrinfragent
      nrinfragent_license_key: #ライセンスキーを入力
      nrinfragent_os_name: redhat
      nrinfragent_os_version: 6 
```

## 4. Playbookの実行
ここまでくれば3で作成したPlaybookを実行するのみです。管理者権限のオプション(-s)を付けるのをお忘れなく！

```
$ ansible-playbook -s setup-infra.yml

~~~略~~~

PLAY RECAP *********************************************************************
localhost                  : ok=9    changed=7    unreachable=0    failed=0
```

## 5. New Relic INFRASTRUCTURE画面で確認
Playbook実行が成功したら、New Relic Infrastructure画面で当該ホストが監視できていることを確認しましょう！

![SnapCrab_NoName_2017-10-31_9-40-58_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/150903/6f98dfa0-023e-b35e-f145-b3a3a43039ef.png)


# 最後に
いかがでしたか？New Relic INFRASTRUCTUREエージェントのインストール用ロールを使用することで、非常に簡単にAnsibleによる自動エージェントインストールを行うことができるようになりました。他のロールと組み合わせて、インスタンス起動時にはエージェントインストール用のAnsibleが走るように設定するとデプロイの手間はかなり減りそうですね。
当社ではソフトウェア関連取組みの一環として、クラウド型パフォーマンスモニタサービス「New Relic」を提供しています。詳しくは[こちら](https://newrelic.nissho-ele.co.jp/)から。
AzureのVM設定について

AzureのマーケットプレイスからWindows10Enterpriseのテンプレートを使った、Windows10を構築したのですが

日本語入力ができない状況になっています、例えば、アット-マークのキーを押しても（「）マークが表示がされてしまいます

キーボードのドライバも106/109用の日本語のドライバをインストールしても状況が変わらないです

もし、同様な症状に陥っている方がいらっしゃいましたら、ご教授頂ければ幸いです

以上、何卒宜しくお願いいたします
なぜMacのターミナルで「リナックスコマンド」が叩けるのか？

MacOSは「BSD系UNIX」を基礎にできているから。
BSD も Linux も UNIX の親戚だからリナックスコマンドは叩けると。

 https://ja.wikipedia.org/wiki/MacOS

めちゃくちゃスッキリ。
VirtualBoxのUbuntuでプロキシを設定するときのメモ

社内PCに入れたVMでubuntuを動かしたときに
インターネット見られなかったのでプロキシの設定をしたよ。

システム設定→ネットワーク→ネットワークプロキシ→HTTPプロキシ
適切に設定する。

システム全体に適用する。
→認証があるかも

webブラウザで何か見るときにも認証があるかも

メモ終わり
Ubuntu16.04 インストール後の初期設定メモ

# はじめに
このドキュメントは Ubuntu16.04 をインストールしたあとに、まずはじめに実施する初期設定をまとめたものです。

# おことわり
* 作業は root で実行してます。
* 個人的な好みであることをご承知おきください。

# パッケージ関連

## アップデート

```shell-session
~#
~# apt update
~# apt upgrade -y 
~# apt full-update -y 
~# apt autoremove -y
~# apt autoclean
~# apt clean
~#
```

```shell-session
~#
~# apt update && apt upgrade -y && apt full-upgrade -y  && apt autoremove -y && apt autoclean && apt clean
~#
```

## 不要なカーネルファイルを削除

```shell-session
~#
~# dpkg -l 'linux-*' | sed '/^ii/!d;/'"$(uname -r | sed "s/\(.*\)-\([^0-9]\+\)/\1/")"'/d;s/^[^ ]* [^ ]* \([^ ]*\).*/\1/;/[0-9]/!d' | xargs sudo apt-get -y purge
~#
```
[こちらのQiita記事](https://qiita.com/inohiro/items/5d358c30eb7bacb37c7c)を参考にさせていただきました。


## 追加パッケージ
```shell-session
~#
~# apt-get install -y aptitude
~# apt-get install -y curl dnsutils tree lsof
~# apt-get install -y zip unzip
~# apt-get install -y mailutils
~# apt-get install -y tree
~# apt-get install -y lsb-release
~# apt-get install -y man manpages-ja manpages-ja-dev
~#
```

```shell-session
~#
~# apt-get install -y aptitude curl dnsutils tree lsof zip unzip mailutils tree lsb-release man manpages-ja manpages-ja-dev
~#
```

## 設定変更

### ipv6無効化

```shell-session
~#
~# cat <<EOF >> /etc/sysctl.conf

# Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1

EOF
~# 
~# sysctl -p
~#
```

### SSHサーバー

```shell-session
~#
~# apt-get install -y openssh-server
~#
~# systemctl restart ssh
~# systemctl enable ssh
~#
```

### NTPサーバー

```shell-session
~#
~# vi /etc/systemd/timesyncd.conf
　：
[Time]
NTP=ntp.nict.jp ntp.jst.mfeed.ad.jp
　：
~#
~# systemctl start systemd-timesyncd
~#
~# systemctl enable systemd-timesyncd
~#
```


### timezone変更

```shell-session
~#
~# rm -rf /etc/localtime
~# ln -s /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
~# date
2017年 10月 13日 金曜日 00:29:30 JST
~#
```

### locale変更

```shell-session
~#
~# dpkg-reconfigure locales
~#
```

### デフォルトエディタを変更

```shell-session
~# update-alternatives --config editor
There are 4 choices for the alternative editor (providing /usr/bin/editor).

  Selection    Path                Priority   Status
------------------------------------------------------------
* 0            /bin/nano            40        auto mode
  1            /bin/ed             -100       manual mode
  2            /bin/nano            40        manual mode
  3            /usr/bin/vim.basic   30        manual mode
  4            /usr/bin/vim.tiny    10        manual mode

Press <enter> to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/bin/vim.basic to provide /usr/bin/editor (editor) in manual mode
~#
```

## その他

### IPアドレス固定

```shell-session
~# 
~# vi /etc/network/interfaces
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 192.168.X.X
    network 192.168.X.0
    netmask 255.255.255.0
    broadcast 192.168.X.255
    gateway 192.168.X.254
    dns-nameservers 192.168.X.254
~# 
```

### apt関連
add-apt-repository を使えるようにする

```shell-session
~# 
~# apt-get install apt-file
~# apt-get install software-properties-common
~#
```
[react 16 breaking changes]refsコールバック実行タイミング

# refsのコールバック実行タイミング
下記のreact 16の変更点に示された通り、refsコールバック関数の呼び出されるタイミングが、VirtualDom更新時ではなく、物理DOMに反映された時になります。

```
Shallow renderer no longer calls componentDidUpdate because DOM refs are not available.
This also makes it consistent with componentDidMount (which does not get called in previous versions either).
```

そのため、componentDidMountメソッドではrefコールバックで保存されたthis.refDomがnullになりますので、元々componentDidMountめそっどで行われたthis.refDomを使った処理をrefコールバックに移行しなければなりません。

```js
<div
  ref={(input) => {
    this.refInput = input;
    // ここでやる
    ...
  }}
  >
  ...
</div>
```

# 参考情報
[React v16.0](https://reactjs.org/blog/2017/09/26/react-v16.0.html)

[Refs and the DOM](https://reactjs.org/docs/refs-and-the-dom.html)
４次方程式はどうやってとくの？

#４次方程式の解法フェラーリの解法を知ろう
１次方程式の解き方から順番に解説していこうと思います。随所に練習問題を用意するので、解答を作成してみてください。できた解答はみんなで共有しましょう。
こちらの公式ページは以下になっております。
一緒に数学を学びましょう。
https://www.facebook.com/groups/1501129136648012/

大人になっても学ぶ楽しさを伝えたい。スマホで閲覧の方は画面を横にすると数式が見やすいと思います。
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">フェラーリの解法4まとめ<br>だれか解法細かく書いて〜 <a href="https://t.co/sP4EI2Ae3M">pic.twitter.com/sP4EI2Ae3M</a></p>&mdash; 数学小僧 博士号 (@mathsheen) <a href="https://twitter.com/mathsheen/status/924276865975558144?ref_src=twsrc%5Etfw">October 28, 2017</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## １．　一次方程式の解き方
まずは最も簡単な一次方程式の解き方から復習してみましょう。これは一体どうやって解くのだったでしょうか？

>問題（一次方程式）
>次の方程式を $x$ について解け。
>
```math
 2x=5
```

このとき答えはいくつになるでしょうか？

```math
\begin{align}
 2x+5&=0 \tag{両辺に５を足す}\\
2x&=-5 \tag{両辺を２で割る}\\
x&=-\frac{5}{2}
 \tag*{$\blacksquare$}
\end{align} 
```
###１．１　一次方程式の解の公式を求めてみましょう。
>公式（一次方程式）
>$a$ はゼロでない実数で、bは任意の実数とします。このとき、
>$ax+b=0$を $x$ について解くと次のようになる。
$$x=-\frac{b}{a}$$

実際、

```math
\begin{align}
 ax+b&=0 \tag{両辺を２で割る}\\
ax&=-b \tag{両辺を２で割る}\\
x&=-\frac{b}{a}
 \tag*{$\blacksquare$}
\end{align}
```

それぞれ、一般の式と具体的な例を表を見て比べてみましょう。

| 一般の式| 例| 
|:-:|:-:|
|  $ax+b=0$ | $2x+5=0$ |   
|  $a$ | 2  |   
|   $b$|  5 |   
|$x=-\frac{a}{b}$ |  $x=-\frac{5}{2}$ |

###　１．２　コメント
<blockquote class="twitter-tweet" data-lang="en"><p lang="ja" dir="ltr">一次方程式の一般解を出しましょう。<br>ax=bをxについて解いてみよう。<br>その時のaとbはどのような値を取るのでしょうか？<a href="https://t.co/XLtU14jawW">https://t.co/XLtU14jawW</a> <a href="https://t.co/uT0rJvizMc">pic.twitter.com/uT0rJvizMc</a></p>&mdash; 数学小僧 博士号 (@mathsheen) <a href="https://twitter.com/mathsheen/status/925267404736708608?ref_src=twsrc%5Etfw">October 31, 2017</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
ーーーーーーーー編集中　随時更新していきます〜ーーーーーーーーー
##２．　２次方程式について
###２．１　具体的に４次方程式を解いてみよう
###２．２　２次方程式の公式
###２．３　コメント
##３．　３次方程式について
###３．１　具体的に３次方程式を解いてみよう
###３．２　３次方程式の公式
###３．３　コメント
##４．　４次方程式について
###４．１　具体的に４次方程式を解いてみよう
###４．２　４次方程式の公式
###４．３　コメント
【エラー対応】フィルタ EncodeFilter の起動中の例外

エラータイミング：eclipseのTomcat開始時
原因：filter.EncodingFileter が所定の場所に見つからない
対策：filter.jarダウンロードし、Tomcatのlibに配置
http://techfun.cc/javaserverside/windows-javaserverside-tomcat.html

【エラー内容】
～前半省略～
情報: サービス Catalina を起動します [金 9 04 17:30:56 JST 2015]
情報: Starting Servlet Engine: Apache Tomcat/8.0.24 [金 9 04 17:30:56 JST 2015]
情報: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. [金 9 04 17:30:56 JST 2015]
重大: フィルタfilterClass の起動中の例外です [金 9 04 17:30:57 JST 2015]
重大: One or more Filters failed to start. Full details will be found in the appropriate container log file [金 9 04 17:30:57 JST 2015]
重大: 以前のエラーのためにコンテキストの起動が失敗しました [] [金 9 04 17:30:57 JST 2015]
警告: Name = postgres Property maxActive is not used in DBCP2, use maxTotal instead. maxTotal default value is 8. You have set value of "30" for "maxActive" property, which is being ignored. [金 9 04 17:30:57 JST 2015]
警告: Name = postgres Property maxWait is not used in DBCP2 , use maxWaitMillis instead. maxWaitMillis default value is -1. You have set value of "108000000" for "maxWait" property, which is being ignored. [金 9 04 17:30:57 JST 2015]
情報: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time. [金 9 04 17:30:57 JST 2015]
情報: Starting ProtocolHandler ["http-nio-8080"] [金 9 04 17:30:57 JST 2015]
情報: Starting ProtocolHandler ["ajp-nio-8009"] [金 9 04 17:30:57 JST 2015]
情報: Server startup in 1436 ms [金 9 04 17:30:57 JST 2015]
docker/alpineでどこにも配送しないsmtpサーバーを作る

## ゴール

alpineのコンテナに postfixをインストールしてどこにも配送しないsmtpサーバーを作る。
さらにsaslauthdをインストールし、コンテナの外からSMTP AUTHが使えるようにする。

## 対象環境

windows 10 で動作する docker for windows

## コンテナ起動

alpine:latestイメージを使って新しいコンテナを起動する。
コンテナ外からSMTPにアクセスするためにポート25を開ける。
```
PS > docker run -it -d -p 25:25 --name my_alpine alpine
```

## パッケージインストール

必要なのはpostfix,saslauthd関連。

```
# apk update
# apk add postfix postfix-pcre
# apk add mailx
# apk add cyrus-sasl cyrus-sasl-crammd5
# apk add rsyslog
```
rsyslogを入れてるのは postfixが出力するログを確認するため。まじめなコンテナを作る場合はsyslog専用コンテナを作る方がよいかも。

## postfixの設定

前に設定した [テスト用に外に一切配送しないSMTPサーバーを作る](https://qiita.com/okadabasso/items/d88366e54b20655004f0) の設定を流用して外に配送しないようにする。

vi /etc/postfix/main.cf

```:/etc/postfix/main.cf
myhostname = localhost.localdomain
mydomain = localdomain
myorigin = $myhostname
mydestination = $myhostname, $mydomain

smtpd_sasl_auth_enable = yes
smtpd_recipient_restrictions = permit_mynetworks,
     permit_sasl_authenticated,
     reject_unauth_destination
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = $myhostname
smtpd_client_restrictions=permit_sasl_authenticated,reject

alias_maps = hash:/etc/postfix/aliases,pcre:/etc/postfix/aliases.regexp
transport_maps = pcre:/etc/postfix/transport_maps
smtpd_sasl_application_name = smtpd
broken_sasl_auth_clients = yes
```

vi /etc/postfix/aliases.regexp

```:/etc/postfix/aliases.regexp
/(?!^root$|^mailuser$)^.*$/ mailuser
```

vi /etc/postfix/transport_maps

```:/etc/postfix/transport_maps
/^.*@.*$/ local
```

エイリアス設定を有効にするために newaliases を実行する必要がある。
普通のOSだとpostfixをインストールしたら関連ディレクトリとか勝手に作ってくれるけど、そんなにうまくはいかないのでメールボックス用のディレクトリも作る

```shell-session
# newaliases
# mkdir /var/mail
```

## saslauthdの設定

外からのメール送信をSMTP AUTHで認証したいので、そのように設定する。

vi /etc/sasl2/smtp.conf

```:/etc/sasl2/smtp.conf
pwcheck_method: auxprop
auxprop_plugin: sasldb
mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5
log_level: 7
```

## 送信用ユーザー作成

メール送信に使うユーザーを作る。
ローカルユーザーだけ作っても外からは認証できないのでsasl用のユーザーも作る

```
# adduser mailuser
#  saslpasswd2 -c -u localhost.localdomain mailuser
```

saslユーザーDBをpostfixが読み込めるように所有者を変更する

```
# chown postfix /etc/sasldb2
```

## サービスを開始する

```
# postfix start
# saslauthd -a shadow
# rsyslogd -n &
```

それぞれ supervisorとかなんとかで起動するようにした方が良いのだけど、今のところここまで。

## この後

これらのタスクを Dockerfileにまとめる。

## その他

postfixとか saslauthd とかdocker hubにいろいろイメージはあるわけだけど、どうしてここまで苦労して作るのか、と言えば思いがけず外にテスト用メールを漏らしたくないから。

あと、現在のalpine:latest でインストールできる  cyrus-sasl には pam認証がない。必要ならソースからビルド、ということになる。
JavaとOpenCVで似ている動画を検出するrev.2



前回からいくつか改良を加えました。

[JavaとOpenCVで似ている動画を検出するrev.1 - Qiita](https://qiita.com/estaro/items/c9df99f7ef8413537019)

# 画像比較の変更

## 特徴量による比較

ヒストグラムに加え、特徴量を比較するようにしました。
特徴量のアルゴリズムにはいろいろありますが、ここでは「AKAZE」というものを使用します。
詳しくはわかりませんが、OpenCV3から追加されたものらしく、良さそうだったためです（雑）。

グレースケールに変換してから処理します。

```java
FeatureDetector detector = FeatureDetector.create(FeatureDetector.AKAZE);
DescriptorExtractor executor = DescriptorExtractor.create(DescriptorExtractor.AKAZE);

Mat gray = new Mat();
Imgproc.cvtColor(resizedFrame, gray, Imgproc.COLOR_RGB2GRAY);
MatOfKeyPoint point = new MatOfKeyPoint();
detector.detect(gray, point);
Mat desc = new Mat();
executor.compute(gray, point, desc);
```

続いて、取得した特長量のMatを比較するにはDescriptorMatcherを使います。
これもいくつか方法を選べますが、これもよくわからないので、BRUTEFORCEを選択しておきました。

```java
DescriptorMatcher macher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE);

MatOfDMatch feature = new MatOfDMatch();
macher.match(video1.getFeatureImg().get(i - 1), video2.getFeatureImg().get(i - 1), feature);
List<Double> distanceList = new ArrayList<>();
for (DMatch dMatch : feature.toList()) {
    distanceList.add(Double.valueOf(dMatch.distance));
}
```

今回は動画比較の結果を平均で扱うことにしました。
"距離"なので小さい値の方が"似ている"と判断することができます。

## 再生時間による比較

処理時間を減らす目的もあって、再生時間の差が10%を超えるものについては比較しないようにしました。

```java
long playtime1 = video1.getPlayTime();
long playtime2 = video2.getPlayTime();
long playtimeDiff = Math.abs(playtime1 - playtime2);
if ((playtimeDiff / playtime1) > 0.1) {
	return null;
}
```

今の仕組み上、動画が"含まれる"ような関係のものは比較できないので、仕方なしです。

# その他変更

## 結果からエクスプローラを開く

結果を確認した後にファイルを確認できるようにコンテキストメニューを追加しました。
TableViewにコンテキストメニューを追加する方法は以下の通りです。

```java
ContextMenu menu = new ContextMenu();
MenuItem mi = new MenuItem("エクスプローラで開く");
mi.setOnAction(event -> {
	TableItem item = table.getSelectionModel().getSelectedItem();
	String command1 = "explorer /select," + item.getOrg().getVideo1().getFilename();
	String command2 = "explorer /select," + item.getOrg().getVideo2().getFilename();
	try {
		Runtime.getRuntime().exec(command1);
		Runtime.getRuntime().exec(command2);
	} catch (IOException e) {
		e.printStackTrace();
	}
});
menu.getItems().add(mi);
table.setContextMenu(menu);
```

例外処理が適当･･･。

# おわりに

思った以上にヒストグラムの比較だけで"似ている動画"は検出できました。
フレームレート、解像度など、元のデータを圧縮したような関係のデータを検出するには十分な精度だと思います。
これ以上となるとディープラーニングになるんでしょうかね。

次の課題は非機能的な面になっています。

実行時間についてはCore i5-4690, メモリ4GB割り当ての環境で、70ファイルで90秒程度でした。
jconsoleで見ながら動作させていますが、メモリはファイルが増えると厳しそうなので、改善の余地がありそうです。

現在取り組んでいるのが、結果をキャッシュすることと、ヒストグラムや特徴量をファイルに書き出して、メモリに持つことをやめる、といったあたりですが、中々うまくいきません。

おいおい改善していきたいです。

おわりです。

# 参考
MySQLが起動しない　　ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

#mysqlでエラーが発生してしまった。

```
mysql -u root
```
これが起動できない

```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
```

探しても見つからなかったので、mysql.sockを作る

```
$  sudo touch /tmp/mysql.sock
```

```
mysql -u root
```
再度起動してみても、またエラー

```
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
```

権限の書き換え

```
$  sudo chown [username] /tmp/mysql.sock
```

mysqlを再起動。

```
$ mysql.server start
```



SUCCESS!!!!!!!!!!!

やっほーーーい


参考リンク
MySQL5.7が起動できない。: [https://qiita.com/gaogaomango/items/933a1f55004920a4323d](https://qiita.com/gaogaomango/items/933a1f55004920a4323d)

MySqlのソケットエラーを解決する: [https://qiita.com/kanohisa/items/564035efd74d9c75bdcb](https://qiita.com/kanohisa/items/564035efd74d9c75bdcb)


<br>
####追記
なんとなく起因としては、mac OS High Sierraにアップデートしたからだと思う。High Sierraのバージョンアップをしたら同じ現象にまたなった為。

なぜ、バージョンアップしたらソケットが通らなくなるのかは未だ分からん
<br>
####追追記
別件でsocekt通信について調べたので、ついでに参考リンクを貼っておく↓

知ったかぶりをしていたソケット通信の基礎を改めて学んでみる
https://qiita.com/megadreams14/items/32a3eed4661e55419e1c
ソケット通信についてたっぷり書いてある↓
調べなきゃ寝れない！と調べたら余計に寝れなくなったソケットの話
https://qiita.com/kuni-nakaji/items/d11219e4ad7c74ece748
TCPHTTPからどんなものか詳しく書いてある↓
【TCP/IP】勉強がてらHTTPクライアントもどきをPythonで作ってみる
https://qiita.com/chooyan_eng/items/087d2fd20294ed35e550#tcp%E3%81%A8http
MySQLのソケット(UNIXソケット)情報を確認する
https://rensrv.com/hs/osx/mysql/resol/chk-socket/
MySQLにSocketで接続する（UNIXソケット）
https://rensrv.com/hs/osx/mysql/con-socket/
UNIXドメインソケット
https://www.otsuka-shokai.co.jp/words/unix-domain-socket.html
H2Oをcentos6にインストールする方法

https://github.com/tatsushid/h2o-rpm
より引用

```bash
nano /etc/yum.repos.d/h2o.repo
```

以下をコピペ

```bash
#bintray-tatsushid-h2o-rpm - packages by tatsushid from Bintray
[bintray-tatsushid-h2o-rpm]
name=bintray-tatsushid-h2o-rpm
#If your system is CentOS
baseurl=https://dl.bintray.com/tatsushid/h2o-rpm/centos/$releasever/$basearch/
#If your system is Fedora
#baseurl=https://dl.bintray.com/tatsushid/h2o-rpm/fedora/$releasever/$basearch/
gpgcheck=0
repo_gpgcheck=0
enabled=1
```

自動でインストール

```bash
yum install h2o -y
```

デフォルトの設定だとApacheの設定やSSL証明書が無い等のエラーが出るので/etc/h2o/h2o.confを書き換える。
例えば

```bash
user: nobody
hosts:
  "localhost:8080":
    listen:
      port: 8080
      host: 0.0.0.0
    paths:
      "/":
	file.dir: /var/www/html
access-log: /var/log/h2o/access.log
error-log: /var/log/h2o/error.log
pid-file: /var/run/h2o/h2o.pid
```
書き換え後

```bash
sudo /etc/init.d/h2o start
```

成功したらWebブラウザで
http://localhost:8080
にアクセスする。

以下のように表示されたら成功
============================================
Welcome to H2O - an optimized HTTP server

It works!
macOS向けのアプリを作ろうとして、ファイルが保存できないときの対処方法

オライリーのLearning Swift 2nd EditionのPart IIを写経していたらちょっとハマったので備忘録。

プロジェクト開始時に"Create Document-Based Application"のチェックをONにしています。


現象としてはファイル名の入力ダイアログは表示されるが、ファイル名が入力できないうえに保存場所も指定できない状態。  

デバッグログの表示画面には以下のようなメッセージが表示される。

```
*** Assertion failure in -[NSVBSavePanel viewWillInvalidate:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/AppKit/AppKit-1561.0.100/Nav.subproj/OpenAndSavePanelRemote/NSVBOpenAndSavePanels.m:387
2017-10-31 04:17:45.645317+0900 Notes[50506:2843650] -[NSVBSavePanel init] caught non-fatal NSInternalInconsistencyException 'bridge absent' with backtrace (
	0   CoreFoundation                      0x00007fff541a132b __exceptionPreprocess + 171
	1   libobjc.A.dylib                     0x00007fff7ab35942 objc_exception_throw + 48
	2   CoreFoundation                      0x00007fff541a6f12 +[NSException raise:format:arguments:] + 98
	3   Foundation                          0x00007fff5629b690 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
	4   AppKit                              0x00007fff519a01f6 -[NSVBSavePanel viewWillInvalidate:] + 188
	5   ViewBridge                          0x00007fff78422cb3 -[NSRemoteView invalidate:] + 292
	6   ViewBridge                          0x00007fff78430449 -[NSRemoteView _advanceToConfigPhaseLegacy] + 1111
	7   ViewBridge                          0x00007fff784312dc -[NSRemoteView _viewServiceMarshalProxy:withDetailedErrorHandler:] + 230
	8   ViewBridge                          0x00007fff78

```

##　環境

書き忘れていたので追記。

- macOS High Sierra (10.13)
- Xcode 9.0
- Swift 4

## 対処方法


App Sandboxという機構に妨害されているだけなのでCapabilities で"App Sandbox"という項目の”File Access"->"User Selected File
"を`Reade/Write`に変更するだけ。

### 変更前


![スクリーンショット 2017-10-31 4.19.18.png](https://qiita-image-store.s3.amazonaws.com/0/98220/8e88195a-e4d7-d36c-92d2-80395b550a29.png)


### 変更後

![modifed_capabilities.png](https://qiita-image-store.s3.amazonaws.com/0/98220/6ff0ebdc-c3c1-deb0-5943-cc5545cd1fd7.png)


1. "User Selected File"という項目を"Read Only"から"Read/Write"に変更
2. "App Sandbox entitlement"云々という警告が表示されるので"Fix Issue"を押す

![スクリーンショット 2017-10-31 4.19.45.png](https://qiita-image-store.s3.amazonaws.com/0/98220/a679c1d3-6780-bed8-2852-e17018fb065a.png)

## その他

上記の手順でダメな時は、関係がありそうな変数なりメソッド名に`@objc`、あるいはクラス定義の前に`@objcMembers`を記述する。

## 参考

そのものズバリ解決策が書いてあった。

- [NSPersistentDocument: *** Assertion failure in -[NSVBSavePanel viewWillInvalidate:] — Mac Lovin'](https://maclovin.org/blog-native/2017/nspersistentdocument-assertion-failure-in-nsvbsavepanel-viewwillinvalidate)
LaravelのEloquentと関連するテーブル名をカスタマイズする

#背景
Laravelを使いつつも、DDDで設計を行っていて、
Eloquentモデルをドメインモデルと区別するために、
EloquentReservation、EloquentOptionといった名前にすることがありました。

この場合、デフォルトの設定だとテーブル名を、
`eloquent_reservations`、`eloquent_options`としなくてはならず、
長ったらしくなってしまいます。

そこで、関連するテーブル名をカスタマイズする方法を調べたのでここにメモします。

#結論

と、いっても簡単で、`$table`プロパティにテーブル名を設定するだけです。

```php
namespace App;

use Illuminate\Database\Eloquent\Model;

class EloquentReservation extends Model
{
    /**
     * モデルと関連しているテーブル
     *
     * @var string
     */
    protected $table = 'reservations';
}
```

以上。
Vue.jsでFirebaseを始めよう 6.入力＆送信編

入力したものを送信する部分を作る

### 入力用のdataを用意する
nameとmessageを追加する

```JavaScript
data () {
  return {
    list: [],     // 最新状態はここにコピーされる
    name: '',     // 名前
    message: '',  // 送信メッセージ
  }
}
```

### 入力部分のhtml

dataに追加したnameとmessageをinputの `v-model` に入れて紐付ける

```html

<!-- 名前の入力欄 -->
<label for="nameInput">名前</label>
<input type="txt" id="nameInput" v-model="name">

<!-- メッセージの入力欄 -->
<label for="nameInput">メッセージ</label>
<input type="txt" id="nameInput" v-model="message">
```

Vue Devtoolsで入力データがdataに反映されてることを確認しよう。

<img width="647" alt="vue-fire.png" src="https://qiita-image-store.s3.amazonaws.com/0/2972/56d1a34a-f6ef-80f7-94ec-7cebce4b3399.png">


### 送信ボタン

イベントハンドラーに `sendMessage` を入れる

```
<!-- 送信ボタン -->
<button type="button" class="btn btn-default" @click="sendMessage">
  送信
</button>
```

### sendMessageの実装
firebaseに送信する部分を実装する。methodsに以下の関数を追加しよう。

```JavaScript
sendMessage () {
  // 空欄の場合は実行しない
  if (!this.name || !this.message) return
  // 送信
  firebase.database().ref('myBoard/').push({
    name: this.name,
    message: this.message
  })
  // 送信後inputを空にする
  this.name = ''
  this.message = ''
}
```

名前とメッセージを入力して、送信ボタンを押してみよう。リストに新しいデータが追加されるはず。ブラウザをリロードして、データがちゃんと残ってることを確認しよう。firebaseを使えば、簡単に永続化できるんだ！