OmniAICreator/Qiita-1.07M huggingface dataset:
Xorshift のNimでの 実装（３２ビット版だけ）

# 本日は

C,Python,Go にひきつづいて Nim による Xorshiftを実装してみます．

[Nim by Example: For Loops & Iterators](https://nim-by-example.github.io/for_iterators/)
のClosure Iteratorsの項目を参考にしました．

# 実装例
```Nim
#Reference:https://nim-by-example.github.io/for_iterators/
import math 
proc xorshift32(seed = uint32(2463534242)): iterator(): uint32 =
  return iterator(): uint32 =
    var y = seed
    while true:
      y = y xor (y shl 13)
      y = y xor (y shr 17)
      y = y xor (y shl 5)
      yield y

proc uniform(rand=xorshift32(), b=0.0,e=1.0): iterator():float64=
  const maxUint32 = math.pow(2.0,32.0)-1
  return iterator():float64=
    while true:
      var value=b+float64(rand())/maxUint32/(e-b)
      yield value
      
when isMainModule:
  var N=100_000_000
  var counter=0
  var uniform01=uniform()
  var x,y :float64
  for i in 1..N:
    x=uniform01()
    y=uniform01()
    if x*x+y*y<1.0:
      counter+=1
  echo "Pi=", 4.0*float64(counter)/float64(N)
```

シフト演算子が＞ふたつで実現するのではなく専用の二項演算が定義されることを調べるのに時間がかかりました．じつはTutorialのChapter１にこっそりと記されています:

[Nim Tutorial (Part I)](https://nim-lang.org/docs/tut1.html)

> The and or xor not operators are also defined for integers, and provide bitwise operations. Left bit shifting is done with the shl, right shifting with the shr operator. Bit shifting operators always treat their arguments as unsigned. For arithmetic bit shifts ordinary multiplication or division can be used.

NimはPythonのように関数(proc)の引数にデフォルト引数を定義できるのでうれしいです．といってもNim独特のクセがありますが．Nimは書けるようになると楽しく書けますが，かけるまでの壁が高めな気がします・・・．
GASのメール送信1日100件までの制限について

GASでメールを送信する時、G Suiteとかじゃなく普通のアカウントの場合1日100件までというやや厳しい制限があります。
https://developers.google.com/apps-script/guides/services/quotas

GASからは次のようにして残りの可能な数を取得することができます。

```gas:
MailApp.getRemainingDailyQuota()
```

試して見たところ、**to,cc,bccで指定されたアドレスの合計分**がカウントされていくみたいです。

プロジェクトごとではなく、1つのアカウントで100件なので、複数人に通知するのであれば、なかなか厳しいものがありますね:dizzy_face:
[git] git reset hard originは万能ではない [自分メモ]

git reset hard origin はいつ何時いかなる時も誰の干渉も受けずにとにかくremoteリポジトリの内容をローカルに適用するものだと勘違いしてた。

git fetch後じゃないと最新のremoteの情報に上書きされない。

当たり前といえば当たり前だが、勘違いしまくってたのでメモ。

git pull originするときは必ずgit fetchする癖はついてたのに...

```
git fetch -p
git reset hard origin/master
```
Spyder 統合環境を用いたPythonスクリプトの速度の改善

Python スクリプトの速度を改善する自己流のやりかたを示します。

別バージョンの関数を実装して、それが同じ値を返していることをassert で確認しつつ、profileで実際に新しく作った別バージョンの方が処理時間が短いことを確認する。
　正しく動いていて、速くなっていないかぎり、古い版を置き換えることができません。


もちろん、以下の書籍のアドバイスは参考にした上で。
[「ハイパフォーマンスPython」](http://www.oreilly.co.jp/books/9784873117409/)
English [High Performance Python](http://shop.oreilly.com/product/0636920028963.do)


### Spyder 統合環境を用いたPythonスクリプトの速度の改善

- [Run][Profile] を実行する。
    - プロファイルが簡単にできるので、どこがボトルネックになっているかを確認できる。
    - その消費時間の多い関数・メソッドが遅い理由を考える。
    - その関数の速度改善版を別の関数名で作成する。
    - 元の関数と速度改善版の関数を両方呼び出し、結果をassert で同じ値を返していることを確認する。
    - その版についてプロファイルをする。本当に速度改善版になっているかを確認する。
    - 値と速度とを確認できた後は、速度改善版の関数だけを呼び出すように書き換える。
    - このようにして、テストしつつ速度の改善できる。

```.py:
# pylint: disable=C0103
"""
級数の和の計算の高速化の事例。

"""
import cv2 

def squareSum(n):
    """return square sum
    note last term  is (n-1)**2.
    """
    return sum([i**2 for i in xrange(n)])


def squareSum_ver2(n):
    """return square sum using Formula of sum of series.
    note last term  is (n-1)**2.
    """
    return (n-1)*n*(2*n-1)/6

if __name__ == "__main__":
    time0 = cv2.getTickCount()
    a = squareSum(100000)

    time1 = cv2.getTickCount()

    f = squareSum_ver2(100000)
    time2 = cv2.getTickCount()

    print a
    assert a == f

    print (time1- time0)/cv2.getTickFrequency()
    print (time2- time1)/cv2.getTickFrequency()

```

注：
　ここに示した例は、級数の和の公式を用いるということで、極端な違いがでる例を示しました。同じアルゴリズムでも書き方の違いでこう改善できるという例は、まずは避けました。


- 速度の改善の余地がありそうな項目
    - numpy, pandas などでfor 文でnumpy.array、pandas.DataFrameの要素をdata[i, j]などと添え字でアクセスしている。
        - 典型的な使い方の場合だと、numpyやpandasの標準的な関数やメソッドでその操作が用意されている可能性がある。それを使うと格段に処理が速くなる。
            - [numpyで明示的にループを書くと極端に遅くなる](https://qiita.com/nonbiri15/items/ef97b84832055ab807fb)
        - OpenCVの画像データの扱いも同じ。2重のfor文を書いている部分の多くが、cv2に標準的に用意されている関数で置き換えられる場合がある。この場合も格段に処理が速くなる。
            - [画像処理で2重ループをなるべく書くな](https://qiita.com/nonbiri15/items/9d4296b3a79fad38bf76)
            - どうしても２重ループを書かなくてはならない場合：
                - Cythonを使って書き換えることで高速化する。
                   Python言語の場合だと、明示的な型の指定がないために、各種演算の前に型を確認する操作が入ってしまう。しかもループ（および多重ループ）の中で、同じ変数に対してループの回数だけ型の確認を行ってしまうことが極端に遅くする理由となっています。
    - for 文の中で範囲判定をif 文で実行している。
        -  for 文の外で範囲を決めておいて、それを`for x in items:`のような利用のしかたをする。
        -  python の中で `if x > x0:`　を実行すると、xやx0の型をしらべてから、どの型での大小関係の比較を呼び出すのか判断するため、C/C++言語に比べてコストが高くつく。
    - xrange()を使わずにrange()を使ってしまっている(Python2.x)。
        - `for i in range(10000):`などと気軽に書いてしまうと、0から9999までの値が入ったリストを生成してしまう。(Python2.xの場合) 
        - そのため、無駄にメモリを浪費してしまう。 
          

---- 
参考とすべき書籍
[一つ上のPython使いになろう](https://qiita.com/nonbiri15/items/e81425e60eacb0333ff5)にそのような書籍の紹介を書きました。
Max/MSPでOSの判定を入れる


Max/MSPをあまり触ってきていないので、別の方法がある場合は教えていただけるとうれしいです！

# mxjの実装

``` java
import com.cycling74.max.*;

public class MyPlatform extends MaxObject {
    private static final String OS_NAME = System.getProperty("os.name").toLowerCase();

    public static boolean isLinux() {
        return OS_NAME.startsWith("linux");
    }

    public static boolean isMac() {
        return OS_NAME.startsWith("mac");
    }

    public static boolean isWindows() {
        return OS_NAME.startsWith("windows");
    }

    public static boolean isSunOS() {
        return OS_NAME.startsWith("sunos");
    }

    public MyPlatform() {
        declareIO(1, 2);
    }

    public void bang() {
        if (isWindows()) {
            outlet(0, "bang");
        } else if (isMac()) {
            outlet(1, "bang");
        } else {
            outlet(2, "bang");
        }
    }
}
```

ビルド後にclassファイルをcodeディレクトリに入れて下さい。

## リポジトリ
* https://github.com/rinsyan0518/MyPlatform

# 使い方
bangを送ると対象のoutletからbangが届きます。
![screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/51292/00112037-f56e-79c4-8ec0-09da4d7fe076.png "screenshot.png")
なぜ仮想マシンのブラウザがホストOSのブラウザから見えるのか

※仮想ゲストにWebサービス等ブラウザを用いた表示サービスをを構築している前提

仮想ゲストは仮想ホストの物理NICを用いて仮想論理ネットワークを構成する。
この仮想論理ネットワークと疎通できる構成になっている端末であれば、TCP/IPの通信を以てブラウザから閲覧することができる。

仮想ゲストがNATネットワーク構成、かつポートフォワーディング構成であれば仮想ホストは勿論、他端末(もちろん仮想ホストとネットワーク的な通信ができることが前提)でも閲覧することは可能。
AWS Certified Big Data – Specialtyを受けてきた

まだ日本語版がなく英語版でしたが、AWS Certified Big Data – Specialtyを受けてきました。
受験を考えている方の参考になれば幸いです。

# 試験概要
- 時間：170分
- 問題数：65問※
- 全て文章題、正解を1個または複数個選択

https://aws.amazon.com/jp/certification/certified-big-data-specialty/
上のリンクには3hoursとありますが、問題を解く時間はプロフェッショナル系と同じ170分です。
また、問題数は65問出題されましたが、上記リンクに説明がないので問題数は変わるかもしれません。

# 結果
幸い合格でした。
（60%だと多分不合格ですが）とりあえずの目標は60%だったので、大満足です。

Overall Score: 72%

Topic Level Scoring:
1.0  Collection: 50%
2.0  Storage: 55%
3.0  Processing: 87%
4.0  Analysis: 87%
5.0  Visualization: 85%
6.0  Data Security: 70%

# 受験者のスペック
参考になるかわかりませんが。。。

- AWS歴：３年８ヶ月
- 保有資格：アソシエイト×３、プロフェッショナル×２、他ベンダー等の資格いくつか
- 外観：メガネぼーず

# 感想
主観になりますが、難易度は下のような感じです。
　アソシエイト系　＜　Big Data　＜　プロフェッショナル系
プロフェッショナル系を持っている方なら、案外サクッと取れるんじゃないかなと思います。

時間は10数分余りました。プロフェッショナルを受けた時も同じくらい時間が余ったので、問題の詰まり具合はプロフェッショナルと同じくらいと思って良いと思います。

問題文ですが、プロフェッショナル系と同じかやや短いように感じました。
英文の難易度ですが、日頃から（なかなか日本語に訳されない）AWSの英文ドキュメントを読んで鍛えていれば、なんとかなるレベルではないかと思います。

# 感想その２
にしても試験時間170分は、軽く生命の危機を感じるくらいに長すぎます。
せめて2時間以内にして欲しいところです。
jQueryの.triggerとネイティブイベント

jQuery離れを進めようと、少しずつ既存コードをネイティブDOMで書き直しているような箇所もあったりする[^1]のですが、混在すると特有なトラブルに見舞われたりもします。

# TL; DR

* jQueryの`.trigger`で起きるのは、「jQuery上のイベント」、「`on***`」、「（起こせるものは）標準操作」だけ
* `addEventListener`でセットしたイベントを駆動させることはない
* ただ、`click`では「標準操作」がイベントも引き起こす

# 発生した問題

jQueryで書いていたものを徐々に切り替えていたのですが、jQueryで`trigger`したはずのイベントが、`addEventListener`で拾えない、ということが発生しました。

# jQueryのイベントシステム
jQuery 1.0が出た頃は、ブラウザのDOMへの対応状況も、現代から見ればめちゃくちゃと言っていい状況でした。そんな中でバブリングなどをきちんと実現するために、jQueryはイベントシステムを**自前で構築しています**。これは、最新版の3系列でも同じ状況です。

そして、`trigger`のコードを追いかけてみたところ、以下のような動作になっていました。

0. DOMの仕様のように、DOMツリーの上からたどって目的の要素を抽出して[^2]、そこについているjQueryイベントと`on***`を実行していく
1. ターゲットから上位に戻っていって、引き続きイベントを実行していく
2. `.preventDefault()`されていなかった場合、（存在すれば）ネイティブな動作をさせるメソッド（`focus()`、`click()`、`submit()`など少数派です）を実行する

ということで、`addEventListener`でセットされたものを呼ぶのに必要な`dispatchEvent`などは、**どこにもありませんでした**。なお、ネイティブの`click()`だけは例外的に、「イベントも実行する」メソッドになっていますので、これだけは実行されます。

# 結論

jQueryのイベントはjQueryでしか受けられないので、カスタムイベントで状態の受け渡しをする系を作っているような場合は、先にイベントを`trigger`する側をネイティブに切り替えないと、イベントを拾えなくなります。なお、jQueryもネイティブの`addEventListener`でイベントを拾っていますので、逆に「ネイティブDOMで`dispatchEvent`したイベントをjQueryのハンドラで拾う」ことは、問題なく可能です。

# 脚注

[^1]: SPA移行が現実的でない環境なので、複雑なウィジェットはRiotに移して、そこまで大掛かりにならない部分や、つなぎ目はネイティブに実装、という感じで進めています。
[^2]: なお、jQueryにキャプチャフェーズはありません。
カウント最小ページを更新


```C
if initf==CLR
	cnt_min = 0xFF0000
	cnt_max = 0
	cnt_max_page = 0
	page_i = 0

if search_sel == 1
	read
	if read失敗
		writable_page=0
		return;

	if パリティエラー
		writable_page=0
		return;

	tmp_cnt計算

	if tmp_cnt < cnt_min			//なんとなく手前のページから書いていきたいし、=なしで
		cnt_min = tmp_cnt
		writable_page = page_i

	if tmp_cnt > cnt_max			//最初0から更新されないとダメな気がするから=ありで
		cnt_max = tmp_cnt			//と思ったけど、配列からcnt_max_pageに変えて、
		//cnt_max_page[page_i] = page_i	//手前のほうから書いていきたいから、やっぱ=なしで
		cnt_max_page = page_i		//cnt_max_pageはinitfで初期化してるから大丈夫なはず

	page_i = page_i + 2

	if page_i > 7
		//initf = CLR				//ここでinitf=CLRしたらsearch_sel==2で困るのでは？
		search_sel = 2
		return;


else if search_sel == 2
	//if cnt_max_page == page_i		//cnt_max_pageは、0のとき以外は1つしかない前提だから、
	read(cnt_max_page+1, ep2)		//↑こんなことせずとも、こうして決め打ちでreadでokか？
	if read失敗	//積算値更新できないけど、どうしようもない？ sel1のwritable_pageに
		search_sel = 0
		return

	update_memo(e2)

	initf = CLR
	search_sel = 0
	return
```
mozjpegをgnu parallelで並列に実行

```cmoz.sh
#!/bin/bash
from="a/"
to="b/"
ex="*.png"
find $from -name $ex | parallel -j+0 "cjpeg -outfile $to{/.}.jpg {}"
```
#gnu parallel
`-j+0`: 最大論理コア数で実行
`{}`: パイプでもらった引数(ex. `a/001.png`)
`{/.}`: パイプからもらった引数をファイル名だけにして(/)さらに拡張子も取る(.)(ex. `001`)
#そのた
Q. print0とかつけなくていいの？
A. よい。ユニコードだろうがスペースだろうが突っ込めば思ったとおりに'\n'デリミタで動いてくれる。parallelもcjpegも良い子。
selenium実行時に「WARN Selenium [DEPRECATION] :prefs is deprecated. Use Selenium::WebDriver::Chrome::Options#add_preference instead.」と注意される場合の修正方法

# 問題点

`Selenium::WebDriver`をインスタンス化する際に`prefs`を指定しているseleniumのコードを実行すると、`WARN Selenium [DEPRECATION] :prefs is deprecated.Use Selenium::WebDriver::Chrome::Options#add_preference instead.`と警告が表示される。

```ruby:sample.rb
require 'selenium-webdriver'

prefs = {
  download: {
    prompt_for_download: false,
    default_directory: '~/Downloads'
  }
}

driver = Selenium::WebDriver.for :chrome, prefs: prefs

driver.get 'https://www.google.co.jp'
puts driver.title
driver.quit
```

```shell-session
$ ruby selenium.rb
2017-10-30 19:40:19 WARN Selenium [DEPRECATION] :prefs is deprecated.
Use Selenium::WebDriver::Chrome::Options#add_preference instead.
...
```

# 原因

`prefs`オプションは廃止予定のため利用してると警告が表示されてるようです。

# 修正方法

警告文に`Selenium::WebDriver::Chrome::Options#add_preference`と記載されているため、このオプションを利用するように修正します。

参考サイト：[Ruby Bindings · SeleniumHQ/selenium Wiki](https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings)

修正後は実行時に警告文が表示されなくなりました。

```ruby:sample.rb
require 'selenium-webdriver'

prefs = {
  prompt_for_download: false,
  default_directory: '~/Downloads'
}

options = Selenium::WebDriver::Chrome::Options.new
options.add_preference(:download, prefs)

driver = Selenium::WebDriver.for :chrome, :options => options

driver.get 'https://www.google.co.jp'
puts driver.title
driver.quit
```

```shell-session
$ ruby selenium.rb
...
```
【JavaScript】オブジェクト配列のソートする方法

**下記機能が実現できます。**
**①複数キーでソートする**
**②キーごとソート順を指定できる**

下記はES6の例：

```JavaScript
const sortItems = (settings) => {
  const items = Object.keys(settings);
  const length = items.length;

  return (obj1, obj2) => {
    let i = 0;
    let result = 0;

    while(result === 0 && i < length) {
      const key = items[i];
      const value = settings[key];
      const property = { key, sort: value };

      result = (function (prop) {
        const order = prop.sort ? 1 : -1;
        const item = prop.key;

        return (a, b) => {
          const result = (a[item] < b[item]) ? -1 : (a[item] > b[item]) ? 1 : 0;
          return result * order;
        }
      }(property))(obj1, obj2);

      i++;
    }

    return result;
  }
}
```

**使用例：**

```JavaScript
const datas = [
  {a: 1, b: 1, c:1},
  {a: 1, b: 2, c:1},
  {a: 1, b: 3, c:2},
  {a: 2, b: 4, c:2},
  {a: 2, b: 5, c:3},
  {a: 2, b: 6, c:3},
];

// true:昇順、false: 降順
datas.sort(sortItems({ a: true, c: false }));
```

**実行結果：**

```JavaScript
| a | b | c |
|---|---|---|
| 1 | 3 | 2 |
| 1 | 1 | 1 |
| 1 | 2 | 1 |
| 2 | 5 | 3 |
| 2 | 6 | 3 |
| 2 | 4 | 2 |
```
C言語で小数点以下を切り捨てて整数部分だけ取り出す

ググるとmodf関数を使う方法とか、floor関数を使う方法とかはでてきたけど、自分で試したみた結果これで十分じゃね？って思ったのでメモしておきます。

```c:aaa.c
double a = 3.32984;
int b = a;
```
これでb=3が代入されて、aの整数部分だけ取り出せます。
Ruby｜グループごとにカウントするサンプル


## はじめに

いま、内定者研修の講師を後輩くんと組んでやっています。課題を出しているのですが、やってみたら面白かったのでメモ程度ですが掲載します。

~~StackOverflowで「このプログラムどう？」とか聞くと質問の質が悪いとかでBANされるかもしれないのでQiitaにするとか口が裂けても言えない~~

## 課題

課題：０〜１００点のテスト結果を区間ごとにカウントアップするプログラムを作成してください。カウントアップの出力例は次のとおりです。

```
  0点から 10点：*****
 11点から 20点：****
 21点から 30点：***
 31点から 40点：**********
 41点から 50点：******
 51点から 60点：***
 61点から 70点：****
 71点から 80点：****
 81点から 90点：*******
 91点から 99点：****
 91点から 99点：
100点から100点：
```

## 解答例

```ruby
scores = Array.new(50){ rand(0..100) }

class ScoreRange
  def initialize(first, last = first)
    @range = Range.new(first, last)
    @count = 0
  end

  def in?(value)
    @range.include?(value)
  end

  def count_up
    @count += 1
  end

  def to_s
    "%3d点から%3d点：" % [@range.first, @range.last] + '*' * @count
  end
end

ranges = [
  ScoreRange.new(0, 10),
  ScoreRange.new(11, 20),
  ScoreRange.new(21, 30),
  ScoreRange.new(31, 40),
  ScoreRange.new(41, 50),
  ScoreRange.new(51, 60),
  ScoreRange.new(61, 70),
  ScoreRange.new(71, 80),
  ScoreRange.new(81, 90),
  ScoreRange.new(91, 99),
  ScoreRange.new(91, 99),
  ScoreRange.new(100)
]

scores.each do |score|
  match_range = ranges.detect{|range| range.in? score }
  match_range.count_up if match_range
end

puts ranges
```

`Range`だけでもかけると思いますが、区間にどれだけマッチしたかをカウントしたかったのでクラスを作成しました。後置if文はやや冗長ですが、、、、
機械学習で二次方程式の解 0

深層学習とはどういうものなのだろうと思い

[はじめての深層学習(ディープラーニング)プログラミング](https://www.amazon.co.jp/%E3%81%AF%E3%81%98%E3%82%81%E3%81%A6%E3%81%AE%E6%B7%B1%E5%B1%A4%E5%AD%A6%E7%BF%92-%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E6%B8%85%E6%B0%B4-%E4%BA%AE/dp/4774185345)

この本を図書館から借りて来て、軽い気持ちで読んでみました。
すると、序盤で何十万円もするグラボを、しかも並列に何個も並べてとか書いてあり
本も読み終えずに、途中で貧乏人には無理だと諦めていました。

ついでにこの本も予約していて

[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E4%BD%9C%E3%82%8BDeep-Learning-%E2%80%95Python%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%A3%E3%83%BC%E3%83%97%E3%83%A9%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0%E3%81%AE%E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E8%A3%85-%E6%96%8E%E8%97%A4-%E5%BA%B7%E6%AF%85/dp/4873117585)

私の順番が回ってきたので読んでみると
なんだか、思ったよりすごく簡単そうなに見えました。
もっと、とんでもない数学を駆使してやっているのかと思いきや
大学数学の基礎、下手をしたら高校生でもわかるような数式が書いてありました。

私にもできる気がしてきました。
ただ、金はない。
本に書かれている内容も、細かいやり方が羅列して書かれている感じで
何がしたいのだか、私の知能ではよくわかりませんでした。

しかし、インターネット時代、田中TOMさんの名前で
2人の若者がわかりやすく動画で解説してくれていて

https://www.youtube.com/watch?v=oA6QfWUJj-8

お陰様でなんとなくわかってきました。
ただ、金の問題が残っていました。
どうしたものか
画像処理じゃなくテキストなら
そういえば、電脳賞とかあったし、自動化ツールを作りネットからソースをダウンロードして
、、、うーーん
変数が多すぎて、複雑すぎる。
簡単なのが良い
あ、非線形で最も簡単と言えば
二次方程式の解があった。
答えは当然わかりきっていて学習もへったくれもないのですが
だからこそ、私にでもどうにかなるかも
世界中の天才・秀才だけじゃなく
私ごときでも何かできるかもしれない。
そんな気がしてきました。

会社の仕事は暇な時間が多く、やる事やったんだからとっとと帰らせて欲しいものですが
金に支配されているため、定時までいなくてはいけない状態で、毎日苦痛の時間を紛らわすのが大変だったのですが
少し、私の人生に希望らしきものが
ただ、コンプライアンスがどうのこうのと会社のパソコンに開発ツールはインストールできませんが
表計算ソフトExcelは使える状態でした。

しかし、会社のExcelだと途中でNUM

続きを書くのが飽きてきたので
読んでくれる人がいそうなら続きを書きます
bisonでコンフリクトメッセージが出た時の対処方法(2)

[前回](https://qiita.com/tosyama/items/1bd4f69fa6fe4ee9494f)の投稿の解決編です。前回はコンフリクトの概要と思っていないコンフリクトが出て私の心が折れたところまで:sweat:でした。元の問題のサンプルコードなどはお手数ですが、前回のページをご覧ください。

# コンフリクトを分析する
コンフリクトの警告が出た時、当てがついていればすぐ修正できますが、大抵は正しいと思って書いているので、なんで?と困惑することになります。また、警告メッセージも不親切で、コンフリクトの数しか表示されず、何行目等の情報はでません。かといって、あてずっぽうで修正するのも、時間がかかるし直ったとしても修正に自信がもてないと思います。少し面倒でも、ちゃんと原因まで特定して対処したほうがよいでしょう。

## レポートの出力
実はbisonにはコンフリクトも含めた詳細なレポートを出力する機能があります。前回の最後に書いたように下記のレポート出力のオプションを付けてコマンドを実行しましょう。入門系のサイトを見ても簡単な計算機の例しか書いていないことがほとんどなので、知らない人も多いのではないかと思います。

```shell-session
$ bison conflict.yy  -r all --report-file=conflict.log
```
すると、指定した場所(ここではconflict.log)にレポートが出力されます。テキストエディタで開いてみてください。

## レポートの見方
コンフリクトがあれば最初に以下のような情報が出力されているはずです。

```:conflict.log
State 16 conflicts: 1 shift/reduce
State 28 conflicts: 1 reduce/reduce
State 38 conflicts: 1 shift/reduce
State 40 conflicts: 2 shift/reduce
State 41 conflicts: 2 shift/reduce
...
```
ソースの場所は書いてませんが、コンフリクトがでたStateとその番号が出てます。なにか手がかりになりそうです。試しに一番問題がありそうなreduce/reduce conflictの"State 28"を検索してみましょう。

```:conflict.log
...
State 28

    7 return_value: type_def ID .  [ID, ',']
   21 declaration: type_def ID .  [',', ';']

    ','       reduce using rule 7 (return_value)
    ','       [reduce using rule 21 (declaration)]
    ';'       reduce using rule 21 (declaration)
    $default  reduce using rule 7 (return_value)
...
```
なんか、それっぽい情報が書かれてますので、これが分かれば原因が分かりそうですね。ただし最大の問題は、このレポートの読み方についての情報がどこにあるのか私が知らないので(え?)、ここからは私の勘による解説です。ドキュメントを知ってる方がいたら教えてください。とはいえ、手がかりはこれしかないので、しばらく眺めて下さい。何か見えて来るでしょう?

記述が上部と下部に分かれてますね。上が現在の読み込んだ状態(2つまで)と、次に来る字句(トークン)、下が対応するアクションみたいなもんでしょうか。つまりState 28は、type_defとIDを読み込んだ状態ときの定義です。日本語(?)にすると

- type_defとIDを読み込み済で、次にくるトークンが　「ID」または「,」だったら [type_def+ID]をreturn_valueにする(還元)。
- type_defとIDを読み込み済で、次にくるトークンが　「,」または「;」だったら [type_def+ID]をdeclarationにする(還元)。

と書かれているようです。。。あれれ。 「,」が来たらどちらになるんでしょうね。

下部には具体的な動きが記述されています。つまり

- 「,」が来たらルール7を使って return_value にする。
- (衝突したので「,」が来た場合、declarationにするのは無し)
- 「;」が来たらルール21を使って declarationにする。
- それ以外(IDが来たら) ルール7を使って return_value にする。

と書かれています。このままだと何が起こるかわかるでしょうか?
このままだと、「,」が来た場合には問答無用でreturn_value(関数の戻り値)と解釈されるので、恐らく複数のdeclartation(変数宣言) は文法エラーになってしまうと思われます。

# コンフリクトの解決方法
ここまで原因が具体的にわかれば、いくつかの対策が打てるのではないでしょうか?　下記の対策があると思います。

1. 構文の見直し - 構文を変えられるのでしたらこれが一番楽でしょう。
 - 例えば、関数宣言の前にキーワード (funcなど)を付けて、状態を分ける。今回の場合だと、funcが来た後のtype_def+IDは必ずretun_value、なければdeclarationが確定。
 - return_valueとdeclarationの構文を全く同じにする。今回の場合だと名前なしreturn_valueをなくして、タイプ名を同じものを使用するとできる。
2.  字句解析器の方で先読みなどして、トークンを分ける。- 今回は有効ではないですが、結構実用性高いと思います。
 - 例えばIDではなく、字句解析器で先読みして、後に「(」が出てくるようであれば、ID -> RET_IDとする。
3. GLRパーサーにする。先読みすればあいまいさがないと自信がある場合の秘密兵器。(私は使ったことないですが。。)

```
%glr-parser
%expect-rr 1
```
上の記述があると、bisonはデフォルトのLALR(1)パーサーでなくて、GLRパーサーを生成します。簡単にいうと、あいまいさがないところまですべての分岐を覚えておいて、あいまいさが解決した時点でいらないものを破棄します。2つ先読みぐらいだったらほとんど遅くならないと思いますが、アルゴリズム的には100倍遅くなっても文句言えません。

# shift/reduceの分析と解決は?
同じように、レポートを眺めてれば、見えてくるのでは、、、、ではダメでしょうか。
今回は力尽きたのでまた次回(需要がありそうなら..)。多分、解決のカギは　```% left```。
mysqliでクエリエラーを出力するようにする

ログを見に行くのが面倒で画面に出力して欲しくなったので。

## やり方

[mysqli_report](http://php.net/manual/ja/mysqli-driver.report-mode.php)を使う。

```php
mysqli_report(MYSQLI_REPORT_ERROR);

// テーブル名をtypoしている。正しくはinformation
$mysqli->query('select * from infomation where info_id = 1');
```

これを実行すると下記の警告を出力してくれる。

```
Warning: mysqli::query(): (42S02/1146): Table 'test.infomation' doesn't exist in /Applications/MAMP/htdocs/index.php on line 11
```

## 蛇足

`MYSQLI_REPORT_INDEX`を追加するとインデックス未使用時に警告が出るようになります。

```php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_INDEX);
```
Windows コマンド xcopy

# xcopy

```
> xcopy  コピー元  コピー先 /D /E /I /R /Y
```

　オプション説明
　/D コピー先に同名のファイルが存在する場合は更新日が新しいファイルのみコピーする
　/E ディレクトリ、サブディレクトリが空であってもコピーする
　/I コピー先のディレクトリが存在しない場合は新規にディレクトリを作成する
　/R 読み取り専用属性のファイルも上書きコピーできるようにする
　/Y 同名のファイルが存在する場合、上書きの確認を行わない
SmartGit > Open in ExplorerとReveal in Explorerの違い > /eと/selectの違い

```txt:動作環境
Windows 7 Pro (32bit)
SmartGit Version 17.0.5 #10143, installed: #10132
SmartGit付属のMinGW32
grep (GNU grep) 2.24
head (GNU coreutils) 8.25
```

SmartGitのrepositoriesペインにおける右クリックメニュー。
以下の違いが分からなかった。

- Open in Explorer
- Reveal in Explorer

有償サポートに連絡したら、3分で返事が来た。

Preferencesに定義されたコマンドを実行するとのこと。
定義は以下のようだ。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/32792ae7-dc0b-a290-b8ae-f47f78a1928c.png)

以下に説明はあるが「/e」の説明はない。
http://www.geoffchappell.com/studies/windows/shell/explorer/cmdline.htm
メモ: ruby で 日付と unix_timestamp を変換する

# はじめに
ruby で 日付と unix_timestamp を変換する方法をよく忘れるので、自分用メモ。

# 日付を unix_timestamp　に変換
```
irb(main):001:0> require 'time'
=> true
irb(main):002:0> Time.parse("2017-10-29 00:00:00").to_i
=> 1509202800
```

# unix_timestamp を 日付に変換
```
irb(main):003:0> Time.at(1509202800)
=> 2017-10-29 00:00:00 +0900
```
【selenium】geckodriverを入れてFirefoxを動くようにする［Windows 7］

こんにちは。
最近、Appiumとseleniumが使う頻度が増えて、普及させたい欲が出てきたので、
いろんな環境で最適なインストール手順を探っております。

今回は、geckodriverについて。

pythonのバージョンをあげたりとseleniumの作業環境を変更した後、seleniumを実行したら、以下のようなエラーが表示されてしまいました。


```
selenium.common.exceptions.WebDriverException: Message: 'geckodriver' executable needs to be in PATH.
```


どうやらgeckodriverが見つからないとのことのようです。

##1. geckodriverを手に入れる

geckodriver自体をDLしていない方は、まずはこちらからDLをお願いします。

https://github.com/mozilla/geckodriver/releases/tag/v0.19.0

※現時点の最新版が　0.19.0　でした。ご利用タイミングに合わせて最新のものをご使用ください。

##2. geckodriverを解凍して、任意の場所に配置する

配置する場所自体はどこでもOKです。

PATHを設定するので、分かりやすい場所がいいと思います。

自分はとりあえず、geckodriverというフォルダを作成して、以下のディレクトリにgeckodriver本体を配置しました。
（解凍したフォルダをそのままC:ドライブ下に持ってきた感じです。）

```
C:\geckodriver
```
##3. システム環境変数のPATHに追加

システムのプロパティ開く　→　詳細設定のタブをクリック　→　環境変数…　と進んで、PATHの編集画面を表示します。

参考：[Windows 環境変数 Path の設定方法](http://next.matrix.jp/config-path-win7.html)

末尾に以下のディレクトリを加えれば完了です。

```
C:\geckodriver
```

エラー画面が出てから、コマンドラインを立ち上げたままの方は一旦、閉じましょう。
開き直してから、実行し直すとgeckodriverが読み込まれて、Firefoxが起動するかと思います。

トラブルシューティングということで、少し短いですが、以上です～
【node.js】express + Vue.jsでシンプルなテンプレートを作った

# はじめに
趣味のプロダクトを新たに作るにあたり、PHPはそろそろ飽きてきていたので新たな言語にチャレンジしようと思い、node.jsをインストールしていじってみたのですが、なかなかこれが動作が速くてよさげだったので採用することにしました。
いろいろ勉強していくうちに、gulpとかwebpackとか便利機能が沢山あると知り、またJavaScriptによるクライアントサイドのフレームワークも多数出ているので、これらをまとめてテンプレート化してしまえないか？という挑戦の記録がこのポストになります。

# やりたかったこと
* 出来るだけ構造を簡素にする
* gulpとwebpackを併用してファイル変更を検知し自動ビルド
* nodemonでサーバーサイドファイルの監視も同時に行い
* ファイル変更を検知してブラウザの自動リロード
* Vue.jsの単一ファイルコンポーネント構造を使用

### 出来るだけ構造を簡素にする
express+Vue.jsのテンプレートとしては、以下のようなものが見つかりました。
https://github.com/express-vue/express-vue - Vue.js公式のSSR用テンプレート
https://github.com/abusaidm/vue-express - abusaidm氏のテンプレート
上の方のテンプレートは公式だけあってがっちり作ってあるのですが、がっちり過ぎて初心者の私としてはいじくり方が分からないのと、あくまでもルーティングはexpressに任せたい（Vue.jsは描画に専念させたい）ということで、下のabusaidm氏のテンプレートを基に作っていくことにしました。

### gulpとwebpackを併用して自動ビルド
最初はgulpのみでやろうと思いコードまで書いたのですが、gulp-browserifyがブラックリスト入りしていることや、gulpだけでやらせるとビルドが果てしなく重かったので、webpackを導入しました。gulpはタスクランナーに専念させます。

### nodemonでサーバーサイドファイルの監視
サーバーサイドの監視もさせたいので、gulp-nodemonを使って監視させ、変更があったらサーバーを再起動させます。

### ファイル変更を検知してブラウザの自動リロード
browserSyncを使います。クライアントサイドのファイルを監視させるとともに、nodemonにより再起動されたら更新作業を行わせるようにしてあるので、クライアントサイドでもサーバーサイドでもファイルを変更したらブラウザが自動リロードされます。便利。

### Vue.jsの単一ファイルコンポーネントを使用
今後作成する趣味プロダクトでは、コンポーネント指向のVue.jsが合っていると感じたのでVue.jsに即決。拡張子vueの単一ファイルコンポーネントをwebpackで読み込ませてビルドできるようにしました。

# できたもの
https://github.com/kaito3desuyo/express-vue-starter-template
こちら。使い方はREADMEを参照していただければ。

# 感想
環境構築だけで三日掛かるのはさすがに長すぎると思います。
今更ですが、crowi-plus を ConoHa の VPS にインストールしてみた


## はじめに
いろいろ作業したりしたときのメモを GoogleDrive には記録していたのですが、共有とかできたらいいなとネットを調べたていたら Crowi-plus というものがあるということで、インストールしてみました。
どうせインストールするならクリーンな環境へ、と思い、ConoHa の VPS にインストールすることにしました。

## ConoHa の VPS
以前同僚に「クラウド環境どこがいい？」って聞いたときに、「ConoHa とかいいんじゃない？簡単で。」と聞いてましたので、試しに一つ立ち上げた経緯がありましたので、今回も ConoHa で VPS を立ち上げます。
＃確かに簡単に立ち上がります。

＃ちなみに ConoHa ではお友達紹介キャンペーンというのがありまして、以下アドレスからごにょごにょしてもらえると嬉しいなって、思います(^_^)/ → [ConoHa](https://www.conoha.jp/referral/?token=O2JlhfumtFJ8nZUpQtrIbZ46VWnpguc3PFi2OdlYASZXLZ9LD5w-7J9)

## Crowi-Plus

→ https://github.com/weseek/crowi-plus

＃Crowi の改造版のようです。

## 手動でインストール
VPS（OS:Debian8.7 メモリ:1GB SSD:50GB CPU:2）を立ち上げて、手動でインストールしてみました。Crowi-plus 自体は動くようになりましたが、Elaticsearch との連携がなんかうまくいかなかったので、Docker を使ってインストールしてみます。

## Docker の インストール
→ http://qs.nndo.jp/2017/04/29/489/

というわけで、先ほど作った VPS を削除して、再度立ち上げてインストールです。
apt にあるかなと `$ aptitude search docker` ってするとなんか `docker` ってのが出てきますが、これは違うので注意です。
欲しいのは `docker.io` 。aptのソースリストを追加しないと出てこないみたいです。

/etc/apt/source.list/docker.list を作って以下を追加。

```
deb http://ftp.jp.debian.org/debian/ sid main
deb-src http://ftp.jp.debian.org/debian/ sid main
```

```
$ sudo aptitude update
```

```
$ sudo aptitude install docker.io
```

```
$ docker -v
$ Docker version 1.13.1, build 092cba3
```

でバージョン確認。表示されればインストール完了です。

## crowi-plus のインストール
→ https://github.com/weseek/crowi-plus-docker-compose

なんかこの Install and Start のまんまでした。

```
git clone https://github.com/weseek/crowi-plus-docker-compose.git crowi-plus
cd crowi-plus
docker-compose up
```

これで `http://localhost:3000` にアクセスするとアプリケーションが立ち上がっています。
＃Docker恐ろしい子。。。

しかしこのままだと通信内容取られ放題なので SSL を当ててみます。
これもすでに当ててあるものが Docker にあったので使わせてもらいます。

## Let's Encrypt で SSL化 ついでに nginx 対応にするぞ
→ https://github.com/weseek/crowi-plus-docker-compose/tree/master/examples/https-portal

これもほぼそのままw
さっき clone した `crowi-plus` の下にサンプルがあるのでそれをとりあえずコピー

```
cd crowi-plus
cp examples/https-portal/docker-compose.override.yml .
```

中身を少し書き換えて

```
environment:
  DOMAINS: 'example.com -> http:/app:3000'

これの example.com を自分のドメインに書き換えます。
```

で `$ docker-compose up` ですよ。
出来上がり！！

## あとがき
あっという間に Wiki サイトが構築できて、しかも SSL まで適用されるとか。。。
ホント、すごい時代になったもんだ(^^
Content-Disposition: attachment; filenameのrfc 6266形式

書き出すと長くなるので要点のみ。
また例に漏れず試行錯誤の混乱中に書いているので要注意。

失敗時は大抵URL末尾がファイル名になる。

日本語ファイルの文字化けつらひ。

# Chrome 62

## :rage:NG

`filename*="utf8''urlエンコードされたファイル名"`

e-mailでもたまにある属性値をダブルクォーテーションで囲む形式。

### 追記

`filename`自体へのダブルクォーテーションは可のようだ。

>     Content-Disposition: INLINE; FILENAME= "an example.html"
>
   Note: This uses the quoted-string form so that the space character
   can be included.
>

引用符があるのでスペースを含めることができるが、URLエンコードするfilename*には関係がない。

[RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)#example]


## :smile:OK

`filename*=utf8''urlエンコードされたファイル名`


# IE11

## :rage:NG

`filename*=utf8''urlエンコードされたファイル名`

## :smile:OK

`filename*=utf-8''urlエンコードされたファイル名`

大概のライブラリは表記ゆれを許容してくれるが、IEはダメだったみたい。
また、IEはRFC 6266対応がIE9からと
http://www.msng.info/archives/2014/04/internet-explorer-11-user-agant-change.php
にあったが、開発者ツールのドキュメントモードでバージョンを落とすだけでは再現はしない？(5に落としても成功)

# Firefox

他でNGでも大抵うまくいくように見える。


# 併記方式

`filename=hogehoge;filename*=utf8''urlエンコードされたファイル名`

`filename*=utf8''urlエンコードされたファイル名;filename=hogehoge;`

これは各ブラウザ`filename*=`が優先されるようだ。
`filename*=`に対応していないブラウザが`filename=`を参照してくれることを確認できれば併記方式が安全なのだが…

併記で行けそう

[ダウンロードファイル名、文字化けとの格闘 - ねぎぶログ](http://negiblog.hatenablog.com/entry/2015/06/19/%25e3%2583%2580%25e3%2582%25a6%25e3%2583%25b3%25e3%2583%25ad%25e3%2583%25bc%25e3%2583%2589%25e3%2583%2595%25e3%2582%25a1%25e3%2582%25a4%25e3%2583%25ab%25e5%2590%258d%25e3%2580%2581%25e6%2596%2587%25e5)

>結論：
>
ブラウザ判定のロジックを入れ込むことなく、 複数のブラウザにてダウンロードファイルの文字化けを避けたい場合は、 レスポンスヘッダに
>
```
Content-Disposition: attachment;
                     filename="ファイル名";
                     filename*=UTF-8''URLエンコーディン
グされたファイル名
```
上記のように設定しよう。 恐れることはない、filename*が有効なブラウザではfilename側は無視される。



[RFC 6266 - Use of the Content-Disposition Header Field in the Hypertext Transfer Protocol (HTTP)#example]:https://tools.ietf.org/html/rfc6266#section-5
nodistのnpmにはnpxがバンドルされないので、別途入れてみた。

先日、[nodistでnode.jsを入れた後npmがバージョンアップできない問題](https://qiita.com/horihiro/items/b2d67fabf9d63cdaf1ec)という記事で、おかしな対応策を書いたら、正しいnpmのアップデート方法をコメントで指摘してもらった。

実際やってみたところ、npmが正しくバージョンアップできた。感謝。

しかしながら、npm5からバンドルされているはずのnpxが入らなかったので、npx単独でインストールしてみたら入った。

```
C:>npm i npx -g
C:>npx -v
9.7.1
```

解決。
Objective-C で OS バージョン判定を簡潔に行う方法


## 概要
OS のバージョンを調べる方法が、Objective-C だと面倒くさい方法しかないのかと思ってて、うんざりしてたら、そんなことなかったので紹介。

## 環境
* MacOS 10.12.6
* Xcode 9.0.1

## 従来の方法
記述量が多くて面倒だった。

```objc
if ([UIDevice currentDevice].systemVersion.floatValue >= 11.0) {
	NSLog(@"iOS11以上だよ");
} else {
	NSLog(@"iOS11未満だよ");
}
```

## 簡潔な方法
記述量が少なくて良い。

```objc
if (@available(iOS 11.0, *)) {
    NSLog(@"iOS11以上だよ");
} else {
    NSLog(@"iOS11未満だよ");
}
```

## 注意点
`@available(〜)` と他の条件を一緒に記載すると warning が出る。
ネストすれば大丈夫。

**NG**

```objc
Bool isClose = YES;
if (@available(iOS 11.0, *) && isClose) {
    NSLog(@"iOS11以上だよ");
}
```

**OK**

```objc
Bool isClose = YES;
if (@available(iOS 11.0, *)) {
    if (isClose) {
        NSLog(@"iOS11以上だよ");
    }
}
```

ネストせずに書けたらいいなぁ。

参考：[Negating Objective-C's @available keyword](https://stackoverflow.com/questions/46388490/negating-objective-cs-available-keyword)

## まとめ
新しいやり方がないか、定期的に確認しないとダメだね。
Xcode 9 + fastlaneでもManualでipaを作る


Xcode 9で`配布用証明書`と`Provisioning Profile`のみでipaを作ろうとした時に無事死亡したので解決方法を残します。

Xcode 8での[Automatically manage signingに負けないfastlaneでのiOSアプリ配布](https://qiita.com/nokono/items/1d3d200eef7ea7d705e3)を元に作成していますので、細かな部分はそちらを参考にしてください！
ipaを作りたい！というタイトルですが、DeployGate等でアプリ配布も可能です。

# 環境
- Xcode 9.0.1
- fastlane 2.62.1

# Automatic Code Signingオフができない！

オンオフの切り替えしても変わってくれない(´・ω・｀)
[fastlane action disable_automatic_code_signing(path: "Project.xcodeproj") not working](https://github.com/fastlane/fastlane/issues/10637)

## 解決方法
**fastlaneで切り替えをしない！**

Xcode 9から`Code Signing Style`を設定できるようになっていました。（全然知らなかった。。）
Manualにしておけばfastlaneで変えなくて良くなります！

`Build Setting`で`Manual`に設定します。
![スクリーンショット 2017-10-30 11.41.01.png](https://qiita-image-store.s3.amazonaws.com/0/187223/dce1a16f-80f4-6331-00b2-cb638dca3d5d.png "スクリーンショット 2017-10-30 11.41.01.png")

# エラーとの遭遇
app作成は成功し、その後の`xcrun`でエラーが出ます。

## エラーの関係箇所ログ抜粋

```
Generated plist file with the following values:
▸ -----------------------------------------
▸ {
▸   "provisioningProfiles": {
▸     "": "hoge adhoc"
▸   },
▸   "method": "ad-hoc"
▸ }
▸ -----------------------------------------

Error Domain=IDEProvisioningErrorDomain Code=9 ""プロジェクト名.app" requires a provisioning profile with the Push Notifications feature." UserInfo={NSLocalizedDescription="プロジェクト名.app" requires a provisioning profile with the Push Notifications feature., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}
```

## エラーの解決方法

`provisioningProfiles`がうまく設定されていないようなので、`gym`で`export_options`オプションを指定します。[参考](https://github.com/fastlane/fastlane/issues/10664)

```Fastfile
gym(
  export_options: {
    provisioningProfiles: {
      "com.example.hoge" => "hoge adhoc"
    }
  }
)
```

他のオプションも記載されていますが、私の環境では最低限上記が設定されていればipaができました。
`com.example.hoge`や`hoge adhoc`は適宜読み替えてください！

# まとめ
Xcode 9対応の変更は下記の2点のみでした。

- `Code Signing Style`の設定
- `gym`に`export_options`のオプション指定

Xcode 9から`Code Signing Style`ができてFastfileも若干スッキリします。
export_optionsのほうはそのうちfastlane側で対応されそうな気がしますね！
LINQでのJOINについての備忘録

メモ書きとして内部結合と外部結合をそれぞれ。
あってるのか怪しいので間違いあればご指摘お願いいたします。

```csharp:内部結合
var innerRecords = from human in humanList
                       join pc in pcList
                           on human.PcId equals pc.Id
                   where Pc.Id == "2"
                   select new {
                                    human.Name
                                  , pc.Name
                              };
```

```csharp:外部結合
var outerRecords = from human in humanList
                       join pc in pcList
                            on human.PcId equals pc.Id into subPcList
                   from pc in subPcList.DefaultIfEmpty()
                   where pc.Id == "2"
                   select new {
                                    human.Name
                                  , pc.Name
                              };

```

---
参考：　[左外部結合の実行 | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/linq/perform-left-outer-joins)
[Unity]MonoDevelopからVSCodeに移行しました

# **まえがき**
Unity5.2を使っていたこともあり、
未だに痛MonoDevelop(以下、Mono）を使ってました。
MacをXcode8.0以降に対応しようとしたところSierraが必須の為アップデート。
SierraにしたらMonoが頻繁に落ちる&デバッガが重いという自体になりました。

その為、思い切ってVSCodeを導入してみました。
結果、かなり軽くなり快適です。
あとは色々と覚えつつチューニンナップしていくという段階まできました。

ただ導入が割りとやることあったので残しておきます。

## 環境
* macOS Sierra(10.12.6)
* Unity5.2.4

# **まず、プラグインの入れ方**
* アクティビティ バーを表示する**[非表示の場合のみ]**
 * [タブ] → [表示] → [アクティビティ バーを表示にする]
* 入れたいものを検索する
* [インストール]をクリック

# **ほぼ必須系**
## C#のサポートを入れる
* プラグイン「C#」をインストール

## デバッガを入れる
* プラグイン「Debugger for Unity」をインストール

## Gitの履歴を見られるようにする
* プラグイン「Git History (git log)」をインストール

## 自動フォーマットを有効にする
* 設定を開く
 * [タブ] → [Code] → [基本設定] → [設定]
* 「formatOnType」を入力して絞り込む
* カーソルを合わせると鉛筆マークが出来るので[編集] → [True]

# **お好みで**
## 見た目を変える
* 設定を開く
 * [タブ] → [Code] → [基本設定] → [配色テーマ]
* 好きなテーマを選択する

## メソッドの参照（codeLens)をオフにする
* 設定を開く
 * [タブ] → [Code] → [基本設定] → [設定]
* 「editor.codelens」を入力して絞り込む
* カーソルを合わせると鉛筆マークが出来るので[編集] → [False]
ICM メモ

この暫定修正プログラムをインストールする暫定修正プログラムには管理者権限が必要です。

1. 5.3.1.0-ICM-IF001.zipファイルをダウンロードし、その内容を一時的な場所に抽出します。
2. 開いているケースマネージャアプリケーションからすべてログアウトし、以前に開いたブラウザセッションをすべて終了します。
--> ICM WASの停止

3. 次のフォルダまたはファイルの名前を変更し、バックアップコピーを<CaseManager_install_home>ディレクトリの外に移動して、バックアップコピーを作成します。
 a. <CaseManager_install_home>/configure/exploded_apps/api_was
 b. <CaseManager_install_home>/configure/exploded_apps/api_wl
 c. <CaseManager_install_home>/configure/exploded_apps/client
 d. <CaseManager_install_home>/configure/exploded_apps/builder
 e. <CaseManager_install_home>/configure/deploy/ICMAdminClientPlugin.jar
 f. <CaseManager_install_home>/configure/deploy/ICMAPIPlugin.jar
 g. <CaseManager_install_home>/configure/plugin/com.ibm.ecm.configmgr.app.acm_5.3.1.201706161434.jar
-- > <CaseManager_install_home>/configure 以下をtarでバックアップ

4. configmgr.app.acm_5.3.1.201706161434.jar以下のディレクトリ内の内容を削除します。
 a. <CaseManager_install_home>/configure/exploded_apps/api_was
 b. <CaseManager_install_home>/configure/exploded_apps/api_wl
 c. <CaseManager_install_home>/configure/exploded_apps/client
 d. <CaseManager_install_home>/configure/exploded_apps/builder

5. 暫定修正内容を抽出したディレクトリに移動します。

6. /apiの内容を暫定修正からフォルダディレクトリにコピーします。
 a. <CaseManager_install_home>/configure/exploded_apps/api_was
 b. <CaseManager_install_home>/configure/exploded_apps/api_wl

7. 次の場所にversion.txtをコピーします。
 a. <CaseManager_install_home>/configure/exploded_apps/api_was
 b. <CaseManager_install_home>/configure/exploded_apps/api_wl

8. 暫定修正から/clientの内容をフォルダディレクトリにコピーします。
 a. <CaseManager_install_home>/configure/exploded_apps/client

9. 暫定修正から/builderの内容をフォルダー・ディレクトリーにコピーします。
 a. <CaseManager_install_home>/configure/exploded_apps/builder

10. 次のファイルを暫定修正から<CaseManager_install_home>/configure/deployディレクトリにコピーして置き換えます。
 a. ICMAPIPlugin.jar
 b. ICMAdminClientPlugin.jar

11. 暫定修正から<CaseManager_install_home>/configure/pluginsディレクトリにcom.ibm.ecm.configmgr.app.acm_5.3.1.201709061204.jarをコピーして置き換えます

12. Case Manager設定ツールを起動し、次のタスクを実行します。
 a. Content Platform Engineクライアントコネクタファイルを更新
 b. Case Manager Applicationsの作成
 c. Case Manager APIの導入
 d. Case Manager Builderのデプロイ
 e. IBM Case Managerサービス・プラグインの登録
 f. ウィジェットパッケージのデプロイと登録、特にICMClientウィジェットパッケージ。 
    <IBM Case Manager install location>/configure/deploy/ICMClient.zip
 g. IBM Case Manager管理クライアント・プラグインを登録

13. IBM Case Managerサーバーを再始動します。 
14. IBM Case Clientにアクセスする前に、ブラウザー・キャッシュを消去してください。
Unity2017のバージョンディレクティブ

残念ながらUnityはバージョンが変わるたびにそれなりに非互換が発生するため、リリースバージョンによってdefineディレクティブがいろいろ定義されています。が、公式ドキュメントでは説明がそっけない。

Unity - マニュアル: プラットフォーム依存コンパイル
https://docs.unity3d.com/ja/current/Manual/PlatformDependentCompilation.html

ということで、こんなスクリプトを貼り付けて2017.1.1f1と5.6.1f1でコンパイルしてみました。

```
#if UNITY_2017
        Debug.Log("Unity2017");
#endif
#if UNITY_2017_1
        Debug.Log("Unity2017.1");
#endif
#if UNITY_2017_1_1
        Debug.Log("Unity2017.1.1");
#endif
#if UNITY_2017_OR_NEWER
        Debug.Log("Unity2017 or newer");
#endif
#if UNITY_2017_1_OR_NEWER
        Debug.Log("Unity2017.1 or newer");
#endif
#if UNITY_2017_1_1_OR_NEWER
        Debug.Log("Unity2017.1.1 or newer");
#endif
#if UNITY_5
        Debug.Log("Unity5");
#endif
#if UNITY_5_OR_NEWER
        Debug.Log("Unity5 or newer");
#endif
#if UNITY_5_2_OR_NEWER
        Debug.Log("Unity5.2 or newer");
#endif
#if UNITY_5_3_OR_NEWER
        Debug.Log("Unity5.3 or newer");
#endif
#if UNITY_5_6_OR_NEWER
        Debug.Log("Unity5.6 or newer");
#endif
#if UNITY_5_7
        Debug.Log("Unity5.7");
#endif
```

結果 (左が2017.1.1f1 右が5.6.1f1)

![Unity2017.1.png](https://qiita-image-store.s3.amazonaws.com/0/141731/e83828e8-2c14-0ff8-4439-289893926e2f.png "Unity2017.1.1f1") ![Unity5.6.png](https://qiita-image-store.s3.amazonaws.com/0/141731/6e3fbb1e-247f-0a1c-186c-33ae0539765e.png "Unity5.6.1f1")

ここから分かることは、

- "OR_NEWER"にはリリースバージョン番号のみ付けられる。
  - マイナーバージョン番号(ex. 5.6.1の".1")は付けられない。
  - リリースバージョン番号の小数点以上(ex. 5.6.1の"5")だけでもダメ。
- 5.3未満のバージョンに"OR_NEWER"はない。
  - Unity5.2までは"OR_NEWER"がなかった？
- パッチリリースは判別できない。
- "UNITY_5"にUnity2017は入らない。
 - **2017が実は内部バージョン5.7だったりはしない。** ← これが知りたかった。

です。困るのは、"UNITY_5"を使ったサードパーティ製の古いスクリプトが案外たくさんあることで、どうしたものかと…。各社にとっては「Unity、勝手にバージョン番号増やすな！！」というところなんでしょうけども。

ちなみに、ビルドログにはmcsでのコンパイル時に渡されるdefineが出力されています。って、最初からこっち見ればよかった…。

```Unity2017.1.1f1
-define:UNITY_5_3_OR_NEWER
-define:UNITY_5_4_OR_NEWER
-define:UNITY_5_5_OR_NEWER
-define:UNITY_5_6_OR_NEWER
-define:UNITY_2017_1_OR_NEWER
-define:UNITY_2017_1_1
-define:UNITY_2017_1
-define:UNITY_2017
```
Paper collection on Learning Term Weights

# Paper List by Time
   
- 2017
    - [Balancing between over-weighting and under-weighting in **supervised term weighting**](http://10.1016/j.ipm.2016.10.003)


- 2016
    - [Balancing Between Over-Weighting and Under-Weighting in **Supervised Term Weighting**](http://10.1016/j.ipm.2016.10.003)
    - [**Learning Global Term Weights** for Content-based
Recommender Systems](http://web.cs.ucla.edu/~ypgu/papers/WWW16_term_weights.pdf)
    - [**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)


- 2015
    - [**New term weighting schemes** with combination of multiple classifier for sentiment analysis]()


- 2014
    - [A study of **supervised term weighting scheme** for **sentiment analysis**](http://10.1016/j.eswa.2013.10.056)
    - [Reducing Over-Weighting in **Supervised Term Weighting** for
Sentiment Analysis](https://aclanthology.info/pdf/C/C14/C14-1125.pdf) COLING 2014


- 2013    
    - [Using tf-idf as an **edge weighting scheme** in
user-object bipartite networks](https://arxiv.org/pdf/1308.6118.pdf)

- 2011

- 2010

- 2009
    - [**Learning term-weighting** functions for similarity measures](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/Yih-EMNLP-09.pdf) EMNLP 2009     
        - [2016, Similarity Models for Ad Relevance Measures](https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/YihJiang-MLOAD10.pdf) Same first author, Microsoft Research

- 2008
 
- 2007
    - [Imbalanced text classification: **A term weighting approach**](https://ccc.inaoep.mx/~villasen/bib/Imbalanced%20text%20classification-%20A%20term%20weighting%20approach.pdf)
    - [**Supervised and Traditional Term Weighting**
Methods for Automatic Text Categorization](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.151.3665&rep=rep1&type=pdf)


- 2006


- 2005
    - [**Learn to Weight Terms** in Information Retrieval Using Category Information](http://www.machinelearning.org/proceedings/icml2005/papers/045_LearnToWeight_JinEtAl.pdf) ICML


- 2003
    - [An information-theoretic perspective of tf–idf measures](https://ccc.inaoep.mx/~villasen/index_archivos/cursoTL/articulos/Aizawa-tf-idfMeasures.pdf)


- 1997



# Others
- [A supervised method of feature weighting for measuring semantic relatedness]()
- [Statistically weighted reviews to enhance sentiment classification]
- [Extractive summarization of product reviews](https://www.linkedin.com/pulse/extractive-summarization-product-reviews-muthusamy-chelliah) Linkedin blog?
- [How scoring works in Elasticsearch](https://www.compose.com/articles/how-scoring-works-in-elasticsearch/)
- [Optimizing Search Results in Elasticsearch with Scoring and Boosting]()
- [Tf-idf :: A Single-Page Tutorial - Information Retrieval and Text Mining]()


# Blog?
- [**Supervised Term Weighting Schemes** for Text Classification](https://aysent.github.io/2015/10/21/supervised-term-weighting.html)
- [](http://www.machinelearning.org/proceedings/icml2005/papers/045_LearnToWeight_JinEtAl.pdf)
【バリデーション】2つのカラムのどちらか一方は必須としたい。

2つカラムがあって、どちらか片方は必須としたい。
ここでしか使わないんだからValidatorの拡張はめんどくさい。あぁ、めんどうだ。

下のソースの場合、telかemailのどちらか片方は入力して欲しい。ちなみに、timeはtelが入力されたら必須です。

Controllerに書く。

```InquiryController.php

　　　　　　　　　　　　　　　　　// ベースとなるルール
        $rules = [
            'name' => 'required|max:255',
            'tel' => 'sometimes|numeric|max:14',
            'time' => 'required_with:tel',
            'email' => 'sometimes|max:255|email',
            'text' => 'max:1024',
        ];
        // 電話番号かメアドかのどちらかは必須
        if (is_null($request['tel']) || is_null($request['email'])) {
            // 電話番号が空の場合、電話番号のバリデーションをクリアし、メアドのバリデーションを追加する。
            if (is_null($request['tel'])) {
                $rules['email'] = 'required_without:tel|sometimes|max:255|email';
                $rules['tel'] = '';
            }
            // メアドが空の場合、メアドのバリデーションをクリアし、電話番号のバリデーションを追加する。
            if (is_null($request['email'])) {
                $rules['tel'] = 'required_without:email|sometimes|numeric|max:14';
                $rules['email'] = '';
            }

        }
        $validator = Validator::make($request->all(), $rules);
```

telもemailも入力されていないと「emailが指定されていない場合、telを指定してください。」と表示されます。
telは入力ありで、timeが未選択だと「telが指定されている場合、timeも指定してください。」と出ます。
ここはもう少し考えよう……。

と、自分メモでした。


[追記]
おまけです。
エラーメッセージのtelとかtimeとか、日本語にしました。
これの下の方に「attributes」ってあるので、その配列のところに定義します。

```resources/lang/ja/validation.php
    'attributes' => [
        'email' => 'メールアドレス',
        'name' => '名前',
        'tel' => '電話番号',
        'time' => '連絡可能時間帯',
        'text' => 'その他ご要望等',
    ],
```
PostgreSQL 同値判定の比較演算子まとめ

PostgreSQLにおいて、同値判定関連の比較演算子をまとめてみました。
ふと忘れるときがあったので、メモついでに。
自分がよく使う組み合わせ演算子も合わせて書いてみました。

詳細は
https://www.postgresql.jp/document/9.6/html/functions-comparison.html
にて。

- A, B: 何かの値
- T: True
- F: False
- N: Null


||case1|case2|case3|case4|case5|
|:---:|:---:|:---:|:---:|:---:|:---:|
|x|A|A|A|N|N|
|y|A|B|N|B|N|
|x = y|T|F|N|N|N|
|x <> y|F|T|N|N|N|
|x IS NOT DISTINCT FROM y|T|F|F|F|T|
|x IS DISTINCT FROM y|F|T|T|T|F|
|x IS NULL|F|F|F|T|T|
|x IS NOT NULL|T|T|T|F|F|
|x IS NULL OR y IS NULL|F|F|T|T|T|
|COALESCE(x, y) IS NOT NULL <br> NOT(x IS NULL AND y IS NULL) <br> x IS NOT NULL OR y NOT IS NULL|T|T|T|T|F|
|COALESCE(x, y) IS NULL <br> x IS NULL AND y IS NULL|F|F|F|F|T|
|COALESCE(x =y, x IS DISTINCT FROM y)|T|F|T|T|F|
SpringSecurityでDBログイン認証処理を実装してみた(MyBatis使用)その２

#概要
[前回](https://qiita.com/Hyuga-Tsukui/items/8c7e3d9201d07d2be089)の続きです。
今回は、ServiceクラスとSecurityConfigクラスを作ってこうと思います。

#手順
##Serviceクラスの設定
Serveiceクラスは、SpringSercurityで定義されているUserDetailsServiceインターフェイスをの実装クラスです。

```java:TCustomerService
@Service
public class TCustomerService implements UserDetailsService {

	@Autowired
	private TCustomerMapper tCustomerMapper;//DB接続処理を行うMapperクラスを参照します。

	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		TCustomer tCustomer = tCustomerMapper.findByUsername(username);
		if(tCustomer == null) {
			throw new UsernameNotFoundException(username + " is not found");
		}
		return new TCustomerUserDetails(tCustomer);
	}
}
```
#SecurityConfigの設定
このクラスは、認証に関する設定を担当し、SpringSecurityで定義されているWebSecurityConfigureAdapterを継承します。
user,pass等の変数は後述する、loginForm.htmlにて定義しています。

```java:WebSecurityConfig.java
@Configuration
@EnableWebSecurity
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)//デフォルトConfigの上書き
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		//アクセスポリシーの設定
		http.authorizeRequests()
			//指定したパターンごとに制限をかける
			.antMatchers("/js/**", "/css/**").permitAll()//制限なし
			.anyRequest().authenticated();//上記以外は制限あり
		//フォーム認証の設定
		http.formLogin()
			//ログインページの指定（指定なしの場合デフォルトのものが用意される
			.loginPage("/loginForm")
			//ログイン処理のパス
			.loginProcessingUrl("/login")
			//ログインフォームの入力値のname
			.usernameParameter("user")
			.passwordParameter("pass")
			//ログイン成功時に遷移するページ(trueで成功時は常にここに飛ぶ）
			.defaultSuccessUrl("/", true)
			//失敗時の遷移先、アクセス制限は解除する
			.failureUrl("/loginForm?error=true").permitAll();
	}
}
```

WebSecurityConfigにつきましてはSpringScurity4.0以前では独自の認証方法を設定した、UserDetailsServiceを実装したクラスを明示的に参照する必要がありましたが、4.1以降では、DIコンテナから自動検出するそうです。

今回はここまで、次回はログインフォームと、ログインしたユーザを迎えるかんたんなtopページを作ろうと思います。

参考書籍　[Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発](http://www.shoeisha.co.jp/book/detail/9784798142470)
参考サイト [公式doc](https://docs.spring.io/spring-security/site/docs/current/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html#formLogin--)
俺用ionicメモ

## 初期設定

### cordovaとionicをインストール

```
$ npm install -g cordova ionic
```

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

```
$ ionic start hogehoge
$ cd hogehoge
```

### config.xmlの編集

* `<widget id="io.ionic.starter" version="0.0.1" ...>` バンドルID（パッケージ名、バージョン
* `<name>MyApp</name>` アプリ名
* `<description>An awesome Ionic/Cordova app.</description>` 説明
* `<author email="hi@ionicframework" href="http://ionicframework.com/">Ionic Framework Team</author>` メルアド、HP
* など 

## cordovaプラグインのインストール

cordovaプラグインをTypescriptでラップしたionic-nativeを使う
https://ionicframework.com/docs/native/

cordovaプラグインとnodeのモジュールをそれぞれインストール
画面の向きを扱うScreen Orientationならこんな感じ

```
$ ionic cordova plugin add cordova-plugin-screen-orientation
$ npm install --save @ionic-native/screen-orientation
```

### ionic-native化されてないcordovaプラグインは？

一応直接触ることはできる
ただしTypescript化されていないので型は使えない

```
$ ionic cordova plugin add cordova-plugin-file-opener2
```

してcordovaプラグインのみをインストールしたのちコード内に以下を書く

```
declare const cordova;
```

詳しくは
https://qiita.com/saihoooooooo/items/822d594fa3639e5c8080

## webで確認

```
$ ionic serve
```

でブラウザが立ち上がる（＋ライブリロード）

## iOSエミュレート

### iOSをプラットフォームに追加

```
$ ionic cordova platform add ios
```

### ios-simのインストール

```
$ cd platforms/ios/cordova && npm install ios-sim@latest
```

https://forum.ionicframework.com/t/issues-starting-ios-simulator-from-cli/107376

### エミュレータのリスト

```
$ ionic cordova emulate --list
Apple-TV-1080p, tvOS 11.0
Apple-TV-4K-4K, tvOS 11.0
Apple-TV-4K-1080p, tvOS 11.0
Apple-Watch-38mm, watchOS 4.0
Apple-Watch-42mm, watchOS 4.0
Apple-Watch-Series-2-38mm, watchOS 4.0
Apple-Watch-Series-2-42mm, watchOS 4.0
Apple-Watch-Series-3-38mm, watchOS 4.0
Apple-Watch-Series-3-42mm, watchOS 4.0
iPhone-5s, 11.0
iPhone-6, 11.0
iPhone-6-Plus, 11.0
iPhone-6s, 11.0
iPhone-6s-Plus, 11.0
iPhone-7, 11.0
iPhone-7-Plus, 11.0
iPhone-SE, 11.0
iPhone-8, 11.0
iPhone-8-Plus, 11.0
iPhone-X, 11.0
iPad-Air, 11.0
iPad-Air-2, 11.0
iPad--5th-generation-, 11.0
iPad-Pro--9-7-inch-, 11.0
iPad-Pro, 11.0
iPad-Pro--12-9-inch---2nd-generation-, 11.0
iPad-Pro--10-5-inch-, 11.0
```

### ターゲット指定（動かず。。。修正に期待）

```
$ ionic cordova emulate ios --target="iPhone-8, 11.0"
```

## Androidエミュレート

* jdkをインストール
 * http://www.oracle.com/technetwork/java/javase/downloads/
 * ただし1.8以上かつ1.9はまだ未対応。。。
* Android Studioをインストール
 * https://developer.android.com/studio/index.html
 * 必要に応じてAndroid StudioのSDK Managerからダウンロード・同意を行う
* Android Studioでなにかしらプロジェクトを作り

## 実機へのデプロイ

https://ionicframework.com/docs/intro/deploying/

## アイコン・スプラッシュ

`resources/icon.png`、`resources/splash.png`を置き換えた後に

```
$ ionic resources
```

を実行する

http://blog.ionic.io/automating-icons-and-splash-screens/

アイコンは`1024×1024`、スプラッシュ画像は`2732×2732`の.png/.psd/.aiを用意する

## ログ

https://qiita.com/jyjoestrummer/items/e150d52f626992390a0f
Spring Data JPA において継承戦略を SINGLE_TABLE にした際、想定外のクラスにてインスタンスが生成される現象について

#概要
下記のようなクラス構成にて、継承戦略を実施した際に、本来生成されるべきクラスでインスタンスが生成されず、全てのインスタンスが、Sales になる現象が発生しました。

```Company.java
@Entity
@Getter
public class Company<U extends User> {

    @Id
    private Integer id;

    @OneToMany
    @JoinColimn(name = "userId")
    private Set<U> users;
}
```

```User.java
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@NoArgsConstructor
@Getter
public abstract class User {
    @Id
    private int id;
    @ManyToOne
    private Company company;
}
```

```Sales.java
@Entity
@DiscriminatorValue("sales")
@NoArgsConstructor
@Getter
public class Sales extends User {
}
````

```Programmer.java
@Entity
@DiscriminatorValue("programmer")
@NoArgsConstructor
@Getter
public class Programmer extends User {
}
````

#原因
Company クラスにて、User クラスの型パラメーターを指定していますが、@OneToMany の型に型パラメーターを指定しているのが原因でした。
DBに格納されている値 (規定では user.dtype 列) が機能しない動作となりました。
明示的に DiscriminatorColumn を指定しても同じ動作となりましたので、型パラメーターを指定したリレーションは使えないことが想定された動作のようです。
下記のように、users フィールドの型を User クラスに指定することで現象は回避できました。
IntelliJ IDEA にて型安全が保証されていない、という警告が出たのでリファクタしましたが、結果として型が安全ではなくなってしまった次第です。

```Company.java
@Entity
@Getter
public class Company<U extends User> {

    @Id
    private Integer id;

    @OneToMany
    @JoinColimn(name = "userId")
    private Set<User> users;
}
```