OmniAICreator/Qiita-1.07M huggingface dataset:
ProxyのせいでFirebase deploy 出来ないとき

無限に deploy 終わらないと思いますので、
npm や yarn でインストールした firebase-tools の中の **client.js** を直接修正する必要がある。

```js:client.js
// 15行目らへん
var Client = function(_url, protocols, options) {
  options = options || {};

  options.proxy = {
    origin:  'http://172.xx.xx.xxx:8080' // あなたの proxy url を設定
  }

  this.url     = _url;
  this._driver = driver.client(this.url, {maxLength: options.maxLength, protocols: protocols});
// ~~
```

## 例) Windows10
> C:\Users\xxxxxx\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\firebase\node_modules\faye-websocket\lib\faye\websocket\client.js

## 例）Windows10-WSL-yarn

```bash:command
yarn global dir
# /home/MYACOUNT/.config/yarn/global
```

> ~/.config/yarn/global/node_modules/faye-websocket/lib/faye/websocket/client.js

## 例）Windows10-WSL-npm
> /home/xxxxxx/.nodebrew/node/v9.11.1/lib/node_modules/firebase-tools/node_modules/firebase/node_modules/faye-websocket/lib/faye/websocket/client.js

# 参考
[Unable to deploy behind a proxy](https://github.com/firebase/firebase-tools/issues/155)
やむを得ない事情でスクリーンセーバーが解除できない時に出させないようにするには？

さて、題名からいきなり怪しいですが、

- PCを動かしっぱなしにしたいけどスクリーンセーバーが動いてしまうのは困る！
- かといってやむを得ない事情でスクリーンセーバー解除ができない！

という一体誰に対して需要があるのか分かりませんが、同じくやむを得ない事情で解除できない人向けの記事となります。

# 結論
マウスをずーっと動かし続けていればスクリーンセーバーは起動しないわけです。かといってずーっとPCの前でダラダラとマウスを動かし続けるのは苦痛なので、自動スクリプトを作成してマウスを動かし続けてもらえれば万事解決！ではやっていきましょう。

# PyAutoGui
使う言語はPythonです。最近Pythonばっかり触っているのですが楽しいです。
pyautoguiというモジュールをインストールします。

```
pip install pyautogui
```

そして好きな場所に**mouseMove.py**を作成し、以下のコードを入力します。

```
import pyautogui

pyautogui.PAUSE = 1
try:
    x, y = pyautogui.position()
    while True:
        pyautogui.moveTo(x, y+1)
        pyautogui.moveTo(x-1, y+1)
        pyautogui.moveTo(x-1, y)
        pyautogui.moveTo(x, y)
except KeyboardInterrupt:
    print('End')
```
作成したら、**mouseMove.py**と同じ場所にコマンドラインで移動し、

```
python mouseMove.py
```
と入力して実行します。するとカーソルが1ピクセルずつ四角形を描くように動き出します。これで成功です。止めたい場合はCtrl+Cを押すか、カーソルを左上隅に持っていけば例外が発生してプログラムが停止します。
仕組みとしてはシンプルで、pyautoguiの持つカーソル制御機能を使って1秒ごとにカーソルを動かしているだけです。もっと遅いインターバルでもいいよという方は、**pyautogui.PAUSE**の値を変更してください。単位は秒となります。

# まとめ
これでスクリーンセーバーが起動しない！やったね！
JavaScriptでnumpyのargsortを実装する

# 概要
JSで[numpyのargsort](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.argsort.html)を使いたいと思ったのですが、
参考になる資料がネット上で見つからなかったので、実装しました。

# argsortとは
argsortとは、ソートを実際にするのではなく、ソートをした結果の配列のインデックスを返すメソッドです。
例えば、上記のnumpyのargsortのドキュメントでは、

```py
>>> x = np.array([3, 1, 2])
>>> np.argsort(x)
array([1, 2, 0])
```
とあります。
numpyのsortでは、デフォルトでは昇順に並ぶので、
x = [3, 1, 2] は、 [1 , 2, 3]と並ぶのが正解です。
この、sort後の[1, 2, 3]が、元の配列xで何番目であるかという情報が、argsortで取得できます。
sort後の0番目 = 1 = x[1]
sort後の1番目 = 2 = x[2]
sort後の2番目 = 3 = x[0]
なので、argsortの結果は、[1, 2, 0] となります。

# コード
実際に、jsで実装したコードは次の通りです。

```js
function argsort(array) {
	const arrayObject = array.map((value, idx) => { return { value, idx }; });
	arrayObject.sort((a, b) => {
		if (a.value < b.value) {
			return -1;
		}
		if (a.value > b.value) {
			return 1;
		}
		return 0;
	});
	const argIndices = arrayObject.map(data => data.idx);
	return argIndices;
}

console.log(argsort([3, 1, 2]))  // => (3) [1, 2, 0]
```

# 参考
昇順に並び替えるアルゴリズムは、[JavaScript つい忘れてしまう配列のソート方法](https://qiita.com/PianoScoreJP/items/f0ff7345229871039672) さんを参考にしました。
降順でsortをするときのargsortをしたい、などの場合は、上記サイトを参考にargsort内のif文を変えることで変更できます。
Firefoxでの自動ダウンロード

# 問題

Microsoft Excelを自動的にダウンロードしたい時、以下のコードは普通だと思われます。

```
profile.setPreference("browser.helperApps.neverAsk.saveToDisk",
        		"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,";
```

「application/vnd.openxmlformats-officedocument.spreadsheetml.sheet」はMicrosoft ExcelのMIMEタイプです。しかし、相変わらず、「毎回確認する」というダイアログがでてきます。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/216936/0616a33e-3b06-d334-e08a-d8225d662b8f.png)

# 解決方法

ファイルのMIMEタイプは問題です。確かにExcelのMIMEタイプは正しいですが、Firefoxから見れば、ダウンロードファイルのMIMEタイプは違います。

Firefox -> ウェブ開発 -> ネットワーク(ctrl + shift + )　から見えます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/216936/ea67cf4d-1d34-3ee8-306b-16b86e1768a8.png)

上の図から、Firefoxが見たダウンロードファイルのContent-Typeはapplication/force-downloadです。だから、以下のコードを試して、ファイルは自動的にダウンロードされました。

```
profile.setPreference("browser.helperApps.neverAsk.saveToDisk",
        		"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, "
        		+ "application/force-download");
```
【PHP】日付を一日ずつ進めて表示させてゆく

日付を一日ずつ進めながら表示させたい。
結局、いつもこの方法を利用しているような気がする（もっと良い方法があれば教えてほしい）。

```php:
<?php

$start = '2017-11-15'; # 開始日時
$end = '2017-11-30'; # 終了日時

// dateを使う
for ($i = $start; $i <= $end; $i = date('Y-m-d', strtotime($i . '+1 day'))) {
    echo $i . PHP_EOL;
}

// DateTimeクラスを使う
/*
for ($i = new DateTime($start); $i <= new DateTimeImmutable($end); $i->modify('+1 day')) {
    echo $i->format('Y-m-d') . PHP_EOL;
}
*/
```

```:実行結果
2017-11-15
2017-11-16
2017-11-17
2017-11-18
2017-11-19
2017-11-20
2017-11-21
2017-11-22
2017-11-23
2017-11-24
2017-11-25
2017-11-26
2017-11-27
2017-11-28
2017-11-29
2017-11-30
```
MySQLのユーザ定義変数を利用してOracleの分析関数RANKを実現する方法

OracleにRANK()という分析関数がありますが、それをMySQL、Auroraにコンバージョンする方法をご紹介します。

##RANK() OVER(ORDER BY)

Oracleで書く場合、こんな感じです。（※給料（salary）の降順でランク付け）

```sql
SELECT
    emp_id,dept_id,job_id,salary,
    RANK()OVER(ORDER BY salary DESC) AS rank 
FROM emp;
```
実行結果：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123138/5e4779d9-17e9-4da1-0d67-390ea29828de.png)


MySQLでコンバージョンする場合、ユーザ定義変数と`IF(expr1,expr2,expr3)`関数で実現します。
考え方は以下の通りです。
　１．salaryで降順ソートする。
　２．抽出レコードに連番を付ける。←tmp1
　３．カレント行のsalary  = 一つ前のsalaryの場合、前のsalaryと同じランクにする。
　　　カレント行のsalary != 一つ前のsalaryの場合、ランクに連番を設定する。

```sql
SELECT
    emp_id, dept_id, job_id, salary,
    IF(salary=@_last_salary,@curRank:=@curRank,@curRank:=@_sequence) AS rank,
    @_sequence:=@_sequence+1 as tmp1,
    @_last_salary:=salary as tmp2
FROM      emp a, (SELECT @curRank := 1, @_sequence:=1) r
ORDER BY  salary desc;
```
実行結果：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123138/dd60f72a-78d9-ce4d-ad07-788bfa495f32.png)



##RANK() OVER(PARTITION BY ORDER BY)

Oracleで書く場合、こんな感じです。（※部門（dept_id）毎に給料（salary）の降順でランク付け）

```sql
SELECT 
    emp_id,dept_id,job_id,salary,
    RANK()OVER(PARTITION BY DEPT_ID ORDER BY salary DESC) AS rank
FROM emp;
```

実行結果：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123138/c6005285-ea9d-e27c-6f5a-bff6de750e35.png)

MySQLで書き換える場合、考え方は基本的に上と一緒です。
違うところは、部門（dept_id）が変わったらランクを１から振り直しのことです。

```sql
SELECT
    emp_id, dept_id, job_id, salary,
    IF(dept_id=@_last_dept_id,
        IF(salary=@_last_salary,@curRank:=@curRank,@curRank:=@_sequence),
    @_sequence:=1) AS rank,
    @_sequence:=@_sequence+1 as tmp1,
    @_last_salary:=salary as tmp2,
    @_last_dept_id:=dept_id as tmp3
FROM      emp a, (SELECT @curRank := 1, @_sequence:=1) r
ORDER BY  dept_id asc, salary desc;
```

実行結果：
![image.png](https://qiita-image-store.s3.amazonaws.com/0/123138/fd54fea7-f17f-cce4-4ce9-affd172f4d93.png)
DB(MariaDB)内の日本語が文字化けしてしまう問題について

## :pushpin: 状況

新型MacBookProとMacBookProの2015年モデルの2機種で同じDBに接続してselect文を実行した際、新型の方では日本語が正しく表示されていたが従来型の方だと文字化けして表示されてしまっていた。 

## 💻 接続先サーバーの環境

- OS: さくらVPS（CentOS 6）
- DB: MariaDB（v10.1.16）

同僚と一緒にあれやこれやと原因を探っていきました。
同じターミナル（iTerm2）使ってるし、接続先も同じだし、ターミナル等の設定も決定的に何かが違うということも無いし…

あっ…
**まさかOSが違うからとか…？**

## :bulb: と、いうことでHigh Sierraにアプデしてみました

見事に文字化けされることなく表示されました🙆
ただ、サーバーがCentOS以外だったらSierraでも表示されるのかとかの確認は取れてません。
あくまで上記環境のみで確認できたバグ（？）でした。
ubuntu16.04にてcudaのインストール方法

実行日2017/10/30
記録日2017/10/31
投稿日2017/11/27

#はじめに
　Linux初心者が備忘録として投稿した記事です。何かの参考になったら幸いです。

#注意
 先に、nvidiaのドライバインストールを終わらせてから以下の手順を進めてください。
[(初心者)Ubuntu16.04にてGTX-1050Ti用のnvidiaのドライバのインストール方法](https://qiita.com/shrimp_f/items/695e4a0de73ed695fe1b)

#結果
　うまくいった。

#実行環境
windows7 64bit がloaderのデュアルブート
cpu intel Core i7 860
メモリ　8GB

#方法
(追記2018/12/17)

このURLでは、現在cuda10.0のダウンロードになっている。
[CUDA Toolkit Download](https://developer.nvidia.com/cuda-downloads)

1050Tiがcuda10.0に対応しているかはわからないので、古いバージョンの9.2を入れたほうが良いかもしれない。
[CUDA Toolkit 9.2 Download](https://developer.nvidia.com/cuda-92-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1604&target_type=deblocal)
Linux, x86_64, Ubuntu, 16.04と順に選べばよい。

(追記終わり)

<del>・[CUDA Toolkit Download](https://developer.nvidia.com/cuda-downloads)
から、ubuntu16.04にあったcudaを探した。</del>


・Installer Typeがいくつかあり好きな方法を選べるが、自分は「deb[local]」という方法で行った。

・まず、Base Installerをダウンロードした。(下の方にある。1.2GBのファイル。)

・次に、ホームディレクトリで

```
$ cd Downloads
```
で、さっきダウンロードした.debファイルのあるディレクトリに移動して、(この際、ディレクトリ名が「ダウンロード」と日本語だとやりづらいのでアルファベットにしておくと良い)

```
$ sudo dpkg -i cuda-repo-ubuntu1604-9-0-local_9.0.176-1_amd64.deb
```
をして、以下のコマンドを順番に実行した。

```
$ sudo apt-key add /var/cuda-repo-<version>/7fa2af80.pub
```
(追記2018/12/17)
と、ここで"cuda-repo-&lt;version&gt;"がわからないぞ、となる。これは公開鍵を登録するコマンドだが実は/varディレクトリに"cuda-repo-ほにゃほにゃ"というディレクトリができてその中に公開鍵がある。ので、ホームディレクトリから$ cd /var などをして名前を調べてそれを上のコマンドに打ってやればいい。
ちなみに著者の場合は以下のようになった。

```
$ sudo dpkg -i cuda-repo-ubuntu1604-9-2-local_9.2.148-1_amd64.deb
```
また、ちゃんと意図したバージョンのcudaがインストールされるかのチェックは次のコマンド。

```
$ apt-cache search cuda
```

(追記終わり)


```
$ sudo apt-get update
$ sudo apt-get install cuda
```
このままだと、

```
$ nvidia-smi
```
がちゃんと表示されないので一回再起動する。
すると、ちゃんとcudaが入っているはず。


(追記2018/12/17)
追記の時には、GeForce GTX1060を使用していて、
[CUDA Toolkit 9.2 Download](https://developer.nvidia.com/cuda-92-download-archive?target_os=Linux&target_arch=x86_64&target_distro=Ubuntu&target_version=1604&target_type=deblocal)
から選択的にcuda9.2を選んでインストールをした。
インストールの際にはnvidia-smiは396.54が入った。(先にnvidia-smiを入れていてもcudaインストール時にアップグレードされるようだ。)もしかしたら相性の問題等あるので以下の記事を参考にすると良いかもしれない。

[Tensorflow環境構築の奮闘記＠Ubuntu16.04.3](http://hirune-ai.hatenablog.jp/entry/2018/01/31/Tensorflow%E3%81%AE%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AE%E5%A5%AE%E9%97%98%E8%A8%98%EF%BC%A0Ubuntu16.04.3)
[GeForce RTX 20 シリーズを載せたUbuntu 16.04にCUDA 9.2をインストール](https://qiita.com/Gandats/items/15bda1b470acfbf0d666)
(追記終わり)
Arduinoを使った3ch DMXコントローラーの製作


# 概要
ArduinoUnoを使って照明用のDMX512のための3ch DMXコントローラを安価に製作しました。ボリュームで制御します。
ソフトは、先人がすばらしいライブラリ(DmxSimple)を作っているので、これを利用しています。
また、DmxSampleを使わないプログラムも紹介します。
ArduinoUnoの出力をEIA-485(RS485)にするために、シールド（ハードウェア）を作成し、次に動かすためのスケッチ（ソフトウェア）を作成します。
# ハードウェア
DMX512を使うためには電気的にEIA-485に合わす必要があり、そのためにLT1785,SN75176,LTC485等のRS485トランシーバICをArduinoに接続する必要があります。
![RS485.jpg](https://qiita-image-store.s3.amazonaws.com/0/211560/ed177ac8-d8f5-f4a6-0b45-b5c1064842a4.jpeg)
引用元( https://playground.arduino.cc/DMX/DMXShield )

電子回路（今回はボリュームを3個使いましたが、ArduinoUnoは全部で6個のアナログ入力ができるので6chに拡張することができます）
![arduino2.JPG](https://qiita-image-store.s3.amazonaws.com/0/211560/e3c687e3-331d-aec0-6b64-9b60af29addb.jpeg)
作成したシールド
100均で買ったプラスチックの箱に、USBとキャノンの穴をあけました。Arduino Unoがぴったり入ります。LTC485はキャノンコネクタに直接ハンダ付して空中配線しています。ふたの所に3か所穴をあけてボリュームを取り付けました。
![photo03.JPG](https://qiita-image-store.s3.amazonaws.com/0/211560/a1ce4e51-a851-a214-4530-ce784df9ebb3.jpeg)

# ソフトウェア1(DmxSimpleを使う）
ArduinoのDmxSimpleライブラリを使って簡単にDMXコントローラーが製作できます。
DmxSimpleライブラリのインストール方法については、「ArduinoによるDMX512制御DMXSimpleを使う」 (https://qiita.com/Ina3/items/9af8e14d991e8b1791d4 )を参照してください。
プログラムは、DmxSimpleをインクルードしてDmxの出力ピンを指定します。今回は、Pin1を出力にしました。
3個のボリュームを使って、その値を読み込みDmx出力します。analogReadでは０Vから５Vまでの電圧を０から1023までの値に変換するので、4で割ってDmxの０から255の値（８ビット）に変換しています。ArduinoのanalogReadは０から５の6chあるので、そのままで最大6chのDMXコントローラが製作できます。
ボリュームをスライド式に変えると本物のDmxコントローラらしくなります。

```
#include <DmxSimple.h>
int ch1   = 0;
int ch2   = 0;
int ch3   = 0;
void setup() {
  DmxSimple.usePin(1);
  DmxSimple.maxChannel(6);
}
void loop() {
ch1   = analogRead(0)/4;
ch2   = analogRead(1)/4;
ch3   = analogRead(2)/4;
    DmxSimple.write(1, ch1);
    DmxSimple.write(2, ch2);
    DmxSimple.write(3, ch3);
    delay(15);
}
```
# ソフトウェア2(DmxSimpleを使わない）
ArduinoのDmxSimpleライブラリを使わなくても、DMXコントローラーが製作できます。
プログラムの詳細は、ArduinoによるDMX512制御（DmxSimpleを使わない）(https://qiita.com/Ina3/items/4a596d8f0849917c5058 )を参照してください。

```
int ch1   = 0;
int ch2   = 0;
int ch3   = 0;
int Tx = 1;//DMXoutputPin

void setup() {
}

void loop() {
  ch1   = analogRead(0)/4;
  ch2   = analogRead(1)/4;
  ch3   = analogRead(2)/4;

   pinMode(Tx,OUTPUT);
        digitalWrite(Tx,0);//Send a Low data of Break Signal
        delayMicroseconds(88);
        digitalWrite(Tx,1);//Send a High data of Mark after Break
        delayMicroseconds(8);
        Serial.begin(250000,SERIAL_8N2);//Set a Serial mode
        Serial.write(0x0);//Send a Start Code as 0
        Serial.write(ch1);//Send a Ch1 Data
        Serial.write(ch2);//Send a Ch2 Data
        Serial.write(ch3);//Send a Ch3 Data
        Serial.end( );//Reset a Serial mode
        delay(10);
 }

```
ReactNative で カスタムフォントを使用する

### 前提
* Project の名前は Hoge
* フォントのフルネームは、 Fuga, ファイル名は、Fuga.ttf

### 1.ttfファイルの配置

```
Hoge/assets/fonts/Fuga.ttf
```

（注意）
フォントのファイル名は、フォントのフルネームと一致させておくこと。
iOSでは、フォントのフルネーム、Androidでは、フォントのファイル名でロードさせるので、
フォントのファイル名をフォントのフルネーム名を一致させると、両方のOSで簡単に利用できます。

フォントのフルネームは、Macの場合、ファイルを右クリックして「情報を見る」→「フルネーム」で調べることができます


### 2. package.jsonの編集
下記の行を追加

```
"rnpm": {
"assets": ["./assets/fonts/"]
}

```

### 3. link
下記のコマンドを実行

```
$react-native link
```

下記が出力されるはず

```
rnpm-install info Linking assets to ios project
rnpm-install info Linking assets to android project
rnpm-install info Assets have been successfully linked to your project
```

### 4. 確認

```
$git diff
modified:   ios/Hoge.xcodeproj/project.pbxproj
modified:   ios/Hoge/Info.plist
modified:   package.json

Untracked files:
  (use "git add <file>..." to include in what will be committed)

android/app/src/main/assets/fonts/Fuga.ttf
assets/
```

* iOS
 - Projectファイルに、Fuga.ttfの参照が追加される
 - Info.plist に、<string>Fuga.ttf</string>という行が追加されている
* Android
 - android/app/src/main/assets/fonts/Fuga.ttfにコピーされる

### 5. Textタグの設定

```
<Text style={{fontFamily:'Fuga'}}>HogeHoge</Text>
```

### 参考にしたページ

```
https://medium.com/@danielskripnik/how-to-add-and-remove-custom-fonts-in-react-native-b2830084b0e4
```
knockout.jsのObservableArrayで項目の変更でも通知する

# 2017-12-01追記

```coffeescript
obsArray.notifySubscribers()
```

でよかった…。
knockout-es5を使っていたせいでハマっていたようだ。

```coffeescript
ko.getObservable(this, 'obsArray').notifySubscribers()
```

とすることで、knockout-es5を使っていても強制通知を行うことができた。
以降の内容はログとして残しておくけれど、意味はなさそう…。

# ObservableArrayの通知は配列への追加・削除などのみ

ObservableArrayの配列のアイテムの変更を行っても、`ko.computed`で検知してくれなかった。このため、変更が行われているにも関わらず、何も起きない…。

中身を変更しても検知しないが、強制通知する方法があるだろうと探して見たものの、どうも公式な方法では、なさそうだった。

# 強制通知を実装する

stack overflowでヒットした。

[Refresh observableArray when items are not observables](https://stackoverflow.com/questions/13231738/refresh-observablearray-when-items-are-not-observables)

どうするかというと、変更のあったアイテムを削除し、再度追加するという方法だった。ObservableArrayは、追加・削除は通知されるので、これならば通知が発生する。

```coffeescript
changedIdx = obsArray.indexOf(changedItem)
obsArray.splice(changedIdx , 1) # アイテムを削除
obsArray.splice(changedIdx , 0, changedItem) # 再度追加
```

# カスタム関数を追加

毎度毎度この処理を実行するのは大変なので、カスタム関数を定義する。

```coffeescript
ko.observableArray.fn.refresh = (item) ->
  changedIndex = this.indexOf(item)
  if changedIndex >= 0
    this.splice(changedIndex, 1)
    this.splice(changedIndex, 0, item)
```

これで、`observableArray.refresh(item)`と呼び出すだけで変更通知が行われる様になる。
Vueでのレイアウトの出し分け

わからなくて5時間ぐらい悩みました。
→ 可能であれば、[nuxtのレイアウト機能](https://ja.nuxtjs.org/api/pages-layout/)を使ったほうが良いと思っています。

# 概要
この2つのレイアウトを必要に応じて出し分けたい。

- ワンカラムのログイン画面。
- ツーカラムのメイン画面（ログイン後）

# 検討
- ログイン画面を静的コンテンツにする
→使おうと思えばVue使えるけど…微妙。

- メイン画面にサイドバーなどのコンポーネントの記述を含ませる
→ 各画面ごとに複数コンポーネントの記述をしなければならなくなるので、できればやりたくない。vueファイル内にはそのページの内容だけ書きたい。

# 解決策
[ネストされたルート](https://router.vuejs.org/ja/essentials/nested-routes.html)を使う。
2カラムレイアウトの方はMainコンポーネント内でコンテンツを呼び出す。

> / から始まるネストされたパスは root パスとして扱われることに注意してください。これによってネストされた URL を指定しなくてもコンポーネントをネストすることができます。

ドキュメント内にこう書かれているように、rootパスを使うこともできるので、URLがネストしている必要はない。

```html:Main.vue
<template>
  <div>
     <sidebar/>
     <router-view/>
  </div>
</template>

<script>
  import Sidebar from './Sidebar';

  export default {
    components: { Sidebar },
    name: 'app',
  };
</script>
```

```index.js
import Vue from 'vue';
import Router from 'vue-router';
import Login from '@/components/Login';　// 1カラムレイアウトのコンポーネント
import Main from '@/components/Main'; // 2カラムレイアウトのコンポーネント
import MainContents1 from '@/components/MainContents1';
import MainContents2 from '@/components/MainContents2';

export default new Router({
  routes: [
    {
      path: '/login',
      name: 'Login',
      component: Login,
    },
    {
      path: '/',
      component: Main,
      children: [
        {
          path: '/content1',
          component: MainContents1,
        },
        {
          path: '/content2',
          component: MainContents2,
        },
      ],
    },
  ],
});
```

# 結果
propsなどでの出し分け、分岐処理なしで必要に応じて複数のレイアウトを使い分けることができた。

- `/login` にアクセスすると1カラムレイアウト
- `/content1` `/content2` にアクセスすると2カラムレイアウト

# 備考
このままだと、ルートにアクセスした際に、router-viewが空の状態で描画されてしまうため、リダイレクトや代替コンテンツの設定が必要。
phantomJSで'Element is not currently visible and may not be manipulated'エラーが出る

#環境
CentOS Linux release 7.4.1708 (Core)
python 3.4.3
phantomjs 2.1.1
selenium 3.5.0
#code
```
driver = webdriver.PhantomJS(service_log_path=os.path.devnull)
driver.get(some_url)
buttons = driver.find_elements_by_css_selector(some_css_selector)
for button in buttons:
    button.click()
```
#症状
click()のタイミングでこんなのが出てくる。

```
selenium.common.exceptions.ElementNotVisibleException: Message: {"errorMessage":"Element is not currently visible and may not be manipulated","request":{"headers":{"Accept":"application/json","Accept-Encoding":"identity","Connection":"close","Content-Length":"81","Content-Type":"application/json;charset=UTF-8","Host":"xxx.xxx.xxx.xxx:xxxxx","User-Agent":"Python http auth"},"httpVersion":"1.1","method":"POST","post":"{\"id\": \":wdc:1511762011951\", \"sessionId\": \"4ba89190-d337-11e7-819f-c929cfc19434\"}","url":"/click","urlParsed":{"anchor":"","query":"","file":"click","directory":"/","path":"/click","relative":"/click","port":"","host":"","password":"","user":"","userInfo":"","authority":"","protocol":"","source":"/click","queryKey":{},"chunks":["click"]},"urlOriginal":"/session/4ba89190-d337-11e7-819f-c929cfc19434/element/:wdc:1511762011951/click"}}
Screenshot: available via screen
```

#対症療法
ブラウザサイズを指定する

```
driver = webdriver.PhantomJS(service_log_path=os.path.devnull)
driver.set_window_size(1350, 640)  # <----　ここ
driver.get(some_url)
buttons = driver.find_elements_by_css_selector(some_css_selector)
for button in buttons:
    button.click()
```

#結果
エラーが起こらなくなった。
めでたしめでたし。

#参考URL
https://github.com/ariya/phantomjs/issues/11637
【Github】ローカルからリモートリポジトリのへプッシュ

プロジェクト等をローカルからリモートへプッシュする際の備忘録です。


##1. 想定されるケース##
ローカル作成したプロジェクトをGithubのリモートリポジトリへプッシュする。

##2. Terminalで該当プロジェクトまで移動##

```
cd
cd Desktop/
cd yourProjectName/
```

##3. 該当プロジェクト内容確認##
下記のコマンドでプロジェクトフォルダ内でgit管理下に置かれていないファイルが確認できる。

```
git init // ローカルプロジェクトのイニシャライズ
git status
```

##4. まずローカル上でgit管理下に置く##

```
git add .
git commit -m "First commit."
```

```git add .```は、新規作成・変更されたファイルのみをaddする。

念のためbranchを確認（defaltはmaster）

```
git branch
//　*　master　と返ってくる
```

##5. リモートリポジトリへ接続・プッシュ##

Github上でリモートリポジトリを作成し、Quick StartのURLを入手。
下記のコマンドを入力して、ローカルとリモートを接続。
※この際、「READ.MEを自動作成する」的な項目にチェックを入れると、Quick StartのURLが出てこない。

sshキーを連動させている場合は、push前の段階でパスワード入力画面に。

```
git remote add origin ssh://git@github.com:UserName/ProjectName
git push -u origin master
```

プッシュまで完了したら、Githubの対象リポジトリの内容をブラウザ更新して確認。
正常にフォルダがアップロードされていたら終了。

## エラーが返ってくる場合の対処法
### fatal: remote origin already exists.
pushしようとした際に、上記のようなエラーメッセージが返ってくる場合があります。
その際は、"**git remote rm origin**"で一度originを削除し、再度originを登録することで正常にpushできます。

```
git remote rm origin
git remote add origin git@github.com:UserName/ProjectName
git push -u origin master
```

### error: failed to push some refs to 'git@github.com:---.git'
初回以降にcommitした内容をpushしようとする際、このようなエラーメッセージが返ってくる場合があります。

hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

これは、リモートにプッシュする前にリモートが他のpush等によって変更されたために起こるエラー。
"**git pull origin master**"でリモートの変更をpullすることによって解決します。

```
git pull origin master
```

上記のコードを入力するとVimの画面になるので、"commit　-m"のようにメッセージを登録することで、正常にpushできるようになります。

※Vim操作
i = 文字入力（insert）
wsc = Vim操作（insert）終了
:wq = 入力完了(Write and Quit)

### ssh: Could not resolve hostname UserName: nodename nor servname provided, or not known

リモートレポジトリに接続して、初回のpushをしようとしたところ、このようなエラーが返ってくることがあります。

```
ssh: Could not resolve hostname UserName: nodename nor servname provided, or not known

fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

色々ググって結局原因はわからないままなのですが、先ほどのエラーと同様に一度originを削除したところ、正常にpushされました。

```
git remote rm origin
git remote add origin git@github.com:UserName/ProjectName
git push -u origin master
```

---

以上です。
Rails　tutorial 総まとめ


章ごとに簡潔なまとめを自分なりにまとめてみる

#1章　ゼロからデプロイまで
・Ruby on RailsとはRuby言語で記述されるフレームワーク
・初心者には難しいローカル開発環境の構築をしなくてもいいようにクラウドIDEの紹介から入り使い方までを指南、ralisのインストールを行う
・Railsにはrailsコマンドがあり、実際にrails newコマンドでアプリをつくってみる、rails sでサーバーｗぽ立ち上げた
・Gitによるバージョン管理システムを導入しBitbucketの非公開リポジトリにプッシュ、Herokuにて本番環境にデプロイまでした

#2章　Toyアプリケーション
・コードを自動生成するScaffold機能を駆使してモデルデータを作成
１、ユーザー
２、マイクロポスト
（一つ一つ学習していくスタイルにはむいてないのであえてここで使用したらしい）
・MVCとはを学習
・モデルデータにバリデーション（制限）を設定
・モデルデータを相互に関連付けできることを紹介

#3章　ほぼ静的なページの作成（static_page）
・この章から本格的に作成していくsample_appを立ち上げる
・MVCのｃ：コントローラを生成してその役割を学習していく
・失敗するテストをあらかじめかいて成功を目指してシステムを作成していくテスト駆動開発を学習
・埋め込みRuby（.erb）とは
・ルーティングを行って取敢えずのMVCを実装完了

#4章　Rails風味のRuby
・オブジェクト指向のRubyを知る
・文字列もStringクラスのオブジェクトであり、それを扱うメソッドがたくさんある
・ruby自体に定義されたメソッド、自分で定義できるメソッドの違いを理解
・配列（Arrayクラス）範囲（Rangeクラス）、また、それぞれのメソッド、ブロックという機能
・コントローラ内のアクションも実はメソッド
・

#５章　レイアウトの作成
・HTMLのタグをつかってレイアウトの領域をわけていった
・Bootstrapフレームワークで迅速にきれいなレイアウト作成
・CSSでデザインを調整
・Railsのパーシャル機能でDRYなコードを目指す
・アセットパイプラインを学習。開発時には開発しやすく、本番環境ではデータが最小化されるため読み込み時間が短くなるという機能
・ルーティングにてルールを定義して、付随して使える様になる名前付きルートの活用法を学んだ

#6章　ユーザーモデルを作成する（User）
・マイグレーションファイルのchangeメソッドでモデルへの変更追加を行う事ができる事を学習
・属性にindexを追加することでこれから実装していく検索を伴うアクションにて、データ参照が簡潔に行われる
・indexが追加されることにより一意性の検証にも役立つ
・モデルに対してのバリデーションを設定（存在性、長さ、フォーマット）
・正規表現とは
・beforeをつかったコールバックメソッドにふれる
・ハッシュ化とは
・モデルに対してhas_secure_passwordメソッドを呼び出してパスワード関連の実装を行う

7章　ユーザー登録
・debugメソッドを実装して開発環境で動くブラウザにデバック情報を表示させる
・resoucesメソッドをルーティングに置く事でRESTfulなUserリソースとして扱うことができる（名前付きルートも自動生成された）
・Gravaterをつかってプロフィール画像を設定していく。その際ヘルパーメソッドとして定義した
・newアクション内でビュー側から情報を送信するform_forメソッドの引数に必要となるインスタンス変数を定義@user=User.new　→　Rails はpostリクエスト
・ビューにユーザー作成の際に必要となる情報を記載するフィールドを作成
・マスアサインメントの脆弱性を紹介、strong parameter　機能でユーザー側が変更できる属性を限定する
・条件分岐を利用して無効なデータ送信にはエラーメッセージを発行
・ユーザー情報を保存するアクションはcreateアクションを設けた。成功時にはビューとしてプロフィールページ（show）をレンダリング
・統合テストを作成して無効な送信から有効な送信まで一気にテストを行った
・本番環境に情報を流すのは大変危険なこと。SSLを設定するが、herokuのサブドメインであれば無料で設けられるとのことなので、herokuのPumaサーバーを導入した

#8章　ログイン　ログアウト
・ユーザー情報を作成保存削除するアクションのsessionsコントローラを作成する
・resoucesメソッドは使わず必要なアクションに対応するルーティングのみを名前付きルートで設定した
・sessionコンローラの役割はユーザを検索してきて有効なユーザなら情報を保持する
newはログインフォームの描画、
createでフォームから送られてきた情報をEメールで検索して存在したて、そのユーザーのパスと送られてきたパスが一致したらログインさせる（＝Railsのsessionメソッドに情報を保持させる）
・current_userメソッドとして使って行きたいので定義内で代入演算子　||= をつかって「ログインが完了しているユーザーなら現在のユーザー」として柔軟な設定を行う
・条件分岐がどんどん行われているので条件によってレイアウトを変更するコードを実装していく
・統合テストでは、ルーティング、データベースの更新、レイアウトの変更が正しく行われているかを確認できる
・最後にdestroyアクションを設定してログアウトを実現した
Mobile safariで意図しないCSRFトークンエラーがでる

# 再現環境

Rails5
Mobile safari

# 再現動作

1. ログイン中にホームボタンを押してホームに戻って一度safariのアプリを落とす。
2. safariを再度起動して、CSRFトークンの検証をする何かしらのフォームからデータ送信。

# 対応策

``` application.rb
config.action_dispatch.default_headers.merge!('Cache-Control' => 'no-store, no-cache')
```

ブラウザのキャッシュを拒否するように設定する。
もう少し良い対応策があればいいんですが。。。

## 参考

https://github.com/rails/rails/issues/21948
ROSが入っていたubuntuを14.04から16.04へアップグレードした記録

実行日2017/10/30
記録日2017/10/31
投稿日2017/11/27

#はじめに
　Linux初心者が備忘録として投稿した記事です。何かの参考になったら幸いです。

#目的
　PCにGeForce１０５０Tiを導入したので、ubuntuにnvidiaのドライバをインストールしようといろいろしていたところ、GUIの解像度が低くなったり２回に１回起動しなくなったりしたので、ubuntuをアップグレードすればついでにそこら辺も治るのではないかと思い実行した。

#結果
　自分のPCではうまくいった。解像度も戻った。

#実行環境
windows7 64bit がloaderのデュアルブート
cpu intel Core i7 860
メモリ　8GB

#方法
・まず、自分のPCにはROSが入っていたのでROSをアンインストールした。端末で、

```
$ sudo apt-get remove ros-*
```
とすると、ROS関係のものがすべて削除された。ubuntuのアップグレードの際、ROS関係のプログラムが邪魔をするようであった。


・その後、以下のコマンドを順番に実行した。

```
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get dist-upgrade
```

・次のコマンドを実行して、新バージョンの確認を行った。

```
$ do-release-upgrade -c
```

・そして、次のコマンドを実行してアップグレード。(だった気がする。うまく行かなかったら、「システム設定」から「ソフトウェアとアップデート」の中でできるはず？)

```
$ do-release-upgrade
```

・とても時間がかかるが、これでubuntu16.04へのアップグレードが完了するはず。
Array 操作関数の callback に async/await な関数を指定したい

ちょっと必要になったので考えてみた。実際には `Array.prototype.map` と `Array.prototype.filter` の async/await 版。

`Array.prototype.map`
---

先に答えを。イディオムになるかと思いきや関数として定義できてしまった。

```js
async function asyncMap(array, operation) {
    return Promise.all(array.map(async item => await operation(item)))
}
```

async/await な関数は戻り値が `Promise` オブジェクトになるので、 `Promise.all` ですべてが `resolve` されるまで待ってやることで目的の結果が得られる。

次のように使う。ユーザー情報を得る API に id を複数指定して、ユーザーの名前を一括で拾ってくる、というイメージ。

```js
asyncMap([0, 1, 2, 3, 4, 5], async id => {
    /*
     *  { "name": "<user's name>"}
     * */
    const response = await fetch(`http://example.com/api/users/${id}`)
    return response.json().name
})
```

`Array.prototype.filter`
---

こちらは次のようになる。

```js
async function asyncFilter(array, predicate) {
    const evaluateds = await asyncMap(array, async item => {
        const shouldExist = await predicate(item)
        return {
            item,
            shouldExist,
        }
    })
    return evaluateds
        .filter(evaluated => evaluated.shouldExist)
        .map(evaluated => evaluated.item)
}
```

次の 2 点から、そのまま `Array.prototype.filter` を適用すると `Promise` オブジェクトが評価され、すべての要素が残る結果となってしまう。

- `Array.prototype.filter` は同期的に処理されてしまう
- async/await の戻り値は `Promise` オブジェクト

これを避けるために一度 `asyncMap` で残すべきかどうかの真偽値を得て、その後同期的に `Array.prototype.filter` で処理してやる。

こちらもこんな感じで使う。どこかのグループに属しているユーザーの id を得るイメージ。

```js
const userIdsInGroups = await asyncFilter([0, 1, 2, 3, 4, 5], async id => {
    /*
     *  { "bolongsTo": ["<group name 1>", "<group name 2>", ...] }
     * */
    const response = await fetch(`http://example.com/api/users/${id}`)
    return 0 < response.json().belongsTo.length
})
```
パッケージのみで CentOS の Nginx を HTTP/2 対応にする

## HTTP/2
CentOS 7.4 から OpenSSL が 1.0.2 にバージョンアップされたため、完全にパッケージのみで Nginx を HTTP/2 に対応させることが可能になりました。

Apache は「[パッケージのみで CentOS の Apache を HTTP/2 対応にする](https://qiita.com/bezeklik/items/5286da14451e0c7a7d19)」を参照してください。

## Nginx
Nginx は 1.9.5 から HTTP/2 がサポートされました。[^nginx]

[^nginx]: https://www.nginx.com/blog/nginx-1-9-5/

### リポジトリ
EPEL リポジトリおよび Nginx 公式リポジトリのいずれでも Nginx 1.12.2 がインストールされますが、設定ファイルなどの内容が異なります。

#### EPEL リポジトリ
```bash
yum -y install epel-release && yum -y update && yum -y install nginx
sed -i'/^#    / s/^#//' /etc/nginx/nginx.conf
```
EPEL リポジトリで 1.12.2 がインストールできます。
EPEL リポジトリの設定ファイル `/etc/nginx/nginx.conf` には SSL の設定例がコメントアウトされて記載されているので、これをアンコメントしてそのまま利用します。

#### Nginx 公式リポジトリ
```bash
cat << "_EOF_" > /etc/yum.repos.d/nginx.repo && yum -y install nginx
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
_EOF_
```
```bash
cat << "_EOF_" > /etc/nginx/conf.d/default-ssl.conf
server {
    listen       443;

    location / {
        root   /usr/share/nginx/html;
        index  index.html;
    }

    ssl on;
    ssl_certificate     /etc/pki/nginx/server.crt;
    ssl_certificate_key /etc/pki/nginx/private/server.key;
}
_EOF_
```
Nginx 公式リポジトリの設定ファイルには SSL の設定例が記載されていないため、新たに設定ファイルを追加して記述します。

## SSL 証明書生成
```bash
mkdir -p /etc/pki/nginx/private
make -f /etc/pki/tls/certs/Makefile /etc/pki/nginx/server.crt
openssl rsa -in /etc/pki/nginx/server.key -out /etc/pki/nginx/server.key
mv -v /etc/pki/nginx/{,private/}server.key
```
`openssl` パッケージに含まれる Makefile でテスト証明書が作成できます。

## FirewallD
```bash
firewall-cmd --add-service=http{,s} --permanent && firewall-cmd --reload && firewall-cmd --list-services
```

## 起動と自動起動設定
```bash
systemctl start nginx && systemctl enable $_
```

## ブラウザで確認
<img width="1015" alt="nginx.png" src="https://qiita-image-store.s3.amazonaws.com/0/15175/ae7c019f-18f9-0ced-5a21-545487015a55.png">

デベロッパーツールの Network タブで Protocol が h2 になっているのが確認できます。
Node.jsのuncaughtException, unhandledRejectionのテストを行う

# TL;DR

対象のモジュールをrequireした後にエラーを起こすjsファイルを作成し、　`child_process` で呼び出す

# 詳細

以下のようなモジュール(main.jsとする)のuncaughtExceptionをテストしたいとする

```js
process.on('uncaughtException', err => {
  console.log('err!');
  process.exit(1);
});

const http = require('http');
const server = http.createServer((req, res) => {
  res.end();
});
server.listen(8000);
```

まず、エラーを発生させるためのjsファイル(error.jsとする)を作る

```js
require('./main');

setTimeout(() => {
  throw new Error('test error');
});
```

次に、テストコードでchild_processを使ってerror.jsを呼び出し、uncaughtExceptionの処理(エラー出力)を確認する。
以下、mochaを想定したテストコード。

```js
const child_process = require('child_process');
const assert = require('assert');

describe('when uncaughtException occurred', function () {
  beforeEach(function () {
    this.process = child_process.spawn('node', ['error.js']);
  });

  it('logging message', function (done) {
    let msg = '';

    // 標準出力を保存しておく
    this.process.stdout.on('data', (data) => {
      msg += data.toString();
    });

    // プロセスが終了したとき、標準出力に想定したテキストが出力されているか確認する
    this.process.on('close', () => {
      assert.equal(msg, 'err!\n');
      done();
    })
  });

});
```

# 補足

上の例ではテスト中に一瞬8000番ポートをLISTENしてしまう。これを防ぐには、`http.Server.prototype.listen` をmockに置き換えてしまえば良い。

```js
const { Server } = require('http');
Server.prototype.listen = () => {};

require('./main');

setTimeout(() => {
  throw new Error('test error');
});
```

上のファイルは `child_process` で呼び出されるため、呼び出し元のプロセスには影響しない。
そのためmock用のライブラリを使わずに直接 `http.Server.prototype.listen` を書き換えてしまっている。

また、unhandledRejectionなどのある程度処理が進んで生じるエラーを確認したい場合も同様に、モジュールの挙動を書き換えてunhandledRejectionが起きるようにすれば良い。
(これができるかどうかは元の実装次第になるが、promiseコールバックの例外処理でエラーログを吐く箇所などがあれば、そこで例外を起こすことができる）
Windows版 Mattermost を単独で SSL化する

## ■用途
* Windows版 Mattermost を単独で SSL化したい
	* [Google Chrome 62](https://forest.watch.impress.co.jp/docs/news/1086774.html) で「突然デスクトップ通知がされなくなった」などの対応として。。
		* IIS で URL Rewrite なり リバプロすれば済むのですが、したくない(できない)ケース

## ■方法
* CertFile と KeyFile を準備し、TLSを有効化する
    * 参考: https://docs.mattermost.com/install/config-tls-mattermost.html

## ■詳細
1. [crt ファイルと key ファイルを準備](https://qiita.com/leftouterjoin/items/5e9e7df1a51dd0db6c07) する
1. 以下のように config.json を編集する(システムコンソールからでも良い)
	* config.json の例 (※IP, パスは例です)
		* 変更前

			```json
			{
			    "ServiceSettings": {
			        "SiteURL": "http://192.168.1.101:8065",
			        "LicenseFileLocation": "",
			        "ListenAddress": ":8065",
			        "ConnectionSecurity": "",
			        "TLSCertFile": "",
			        "TLSKeyFile": "",
			```

		* 変更後

			```json
			{
			    "ServiceSettings": {
			        "SiteURL": "https://192.168.1.101:8065",
			        "LicenseFileLocation": "",
			        "ListenAddress": ":8065",
			        "ConnectionSecurity": "TLS",
			        "TLSCertFile": "C:/mattermost/cert/hoge.crt",
			        "TLSKeyFile": "C:/mattermost/cert/hoge.key",
			```

1. services.msc (など)でmattermostを再起動する(サービス化している場合)

## ■注意点
* http://ではアクセスできなくなります。。
西鉄の運行状況を通知してくれるBOTをなぐり書きした

## WHY?
濃霧の影響で西鉄が遅延するのを駅に着いてから知るのが辛かったので、BOT作った。

## HOW?
[毎朝西鉄の運行状況のサイト](http://jik.nishitetsu.jp/traffic/default.htm)を見て大牟田線の情報があれば[Typetalk](https://www.typetalk.com/ja/)に通知するbotをGASで作った。


### SOURCE
ロジックは無理やり文字列で判定した。
`'<h3 class="">天神大牟田線（太宰府線・甘木線含む）</h3><p>'`があればそのブロックの文字列をTypetalkにポストするだけ。
htmlの取得には`UrlFetchApp`のAPIを使った。

```js:
var TOKEN = 'YOUR BOT TOKEN';
function postTrafficInfo() {
  var html = UrlFetchApp.fetch("http://jik.nishitetsu.jp/traffic/default.htm").getContentText();
  if (html.indexOf('<h3 class="">天神大牟田線（太宰府線・甘木線含む）</h3><p>') > 0) {
    var infos = '';
    html.split('<h3 class="">天神大牟田線（太宰府線・甘木線含む）</h3><p>').forEach(function(v, i) {
      if (i > 0) {
        var tmp = v.split('</p>')[0].replace(/<br \/>/g, '\n');
        tmp = tmp.replace(/<br\/>/g, '\n');
        tmp = tmp.replace(/<br>/g, '\n');
        infos += tmp + '\n\n';
        Logger.log(tmp);
      }
    });
    postTrafficWithMention('YOUR USER ID', infos);
  }
}

function postTrafficWithMention(mention, message) {
    postSimpleMessage(TOKEN, '32504', mention + '\n' + message);
}

function postSimpleMessage(token, topicId, message) {
  var data = {
    message: message,
  };
  var options = {
    'method'     : 'post',
    'contentType': 'application/x-www-form-urlencoded',
    'payload'    : data
  };
  var url = 'https://typetalk.in' + '/api/v1/topics/' + topicId + '?typetalkToken=' + token;
  var res = UrlFetchApp.fetch(url, options);
}
```

毎朝6:00〜7:00と18:00〜19:00でスケジューリングしておいた。
上手く動けば大牟田線の情報だけを通知してくれる…はず。
かなりテキトーに書きなぐったので、不具合あればその都度修正していくスタイルで。
西鉄のサイトのhtmlの構造が変わったらたちまち使えなくなるけど、その時はまた対応する。

## PREVIEW
こんな感じで投稿される。実際はメンションが着くのでスマホに通知されるはず。
![スクリーンショット 2017-11-27 9.57.08.png](https://qiita-image-store.s3.amazonaws.com/0/29966/5ffac92d-48e5-f318-6948-75c5223e9177.png)
[Swift4,iOS,CoreData]NSFetchedResultsControllerでテーブルの日付別セクション分けする際の注意点

#概要
テーブルを使って、タイムスタンプを持っているデータを日付ごとにセクションわけして表示する方法は、いろいろなところで紹介れています。
例えば具体的な方法は

[[Swift,iOS,CoreData]NSFetchedResultsControllerでテーブルの日付別セクション分け](https://qiita.com/cfiken/items/13419064ce43b2ee245e#_reference-d977b3c0fccad74e78e5)

を参照してください。
これまでこの方法で正しく動作していましたが、Swift4にマイグレーションさせた後、セクションに表示する日付が取れなくなりました。
いろいろ調べた結果、Transient に設定した Attribute に対応するモデルクラスのプロパティに @objc を付加する必要がありました。
Swift3 から Swift4 への自動マイグレーションで @objc は、付加されませんでした。

#具体的な変更箇所
Transient に設定した Attribute の名前が sectionIdentifier であるとき、そのモデルクラスのプロパティの先頭に @objc を付加する。
（以下のコードの内容は、概要欄で紹介したリンク先と基本的に同じです。）

```swift
@objc var sectionIdentifier: String {
        
        get {
            
            self.willAccessValue(forKey: "sectionIdentifier")
            var tmp = self.primitiveValue(forKey: "sectionIdentifier") as? String
            self.didAccessValue(forKey: "sectionIdentifier")
            
            if tmp == nil {
                
                let calendar = Calendar.current
                
                let components = calendar.dateComponents([.year, .month, .day], from: self.completion_date as Date)
                
                tmp = String(format: "%ld", components.year! * 10000 + components.month! * 100 + components.day!)
                
                self.setPrimitiveValue(tmp, forKey: "sectionIdentifier")
            }
            
            return tmp!
            
        }
        
    }
```

(Xcode9.1 Swift4.0 使用）
ExcelからREST呼び出しをする方法

#VBAでRESTのリクエストを送信してみる
最近はいろいろなものをRESTで呼び出すケースが増えてきました。SOAPUIなどからRESTを呼び出すテストケースを作っていたのですが、テストケースが大量にあったためにExcelでテストケースを管理し、直接REST呼び出しをしてみることにしました。
##MSXML2.XMLHTTP.6.0を用いた呼び出し
単純なGETは以下のようなコードで簡単に呼び出すことが可能です。

```http.vba
Dim objHTTP As Object
Set objHTTP = CreateObject("MSXML2.XMLHTTP.6.0")
objHTTP.Open "GET", "http://test.com/index.htm, False
objHTTP.setRequestHeader "Authorization", "Basic EncodedUserNameAndPassword"
objHTTP.setRequestHeader "Content-Type", "text/plain"
objHTTP.send
```

##Proxyを設定する方法
IPアドレス制限があり、認証ありProxyを通す必要がある場合には、MSXML2.XMLHTTP.6.0ではなく、MSXML2.ServerXMLHTTP.6.0を用いて、setProxyCredentialsでProxyのユーザーIDとパスワードを指定します。
また、SSL証明書のエラーが発生する場合には、setOptionで、エラーを無視するように設定することで回避することが可能です。

```Proxy.vba
Dim objHTTP As Object
Set objHTTP = CreateObject("MSXML2.ServerXMLHTTP.6.0")
objHTTP.Open "GET", "https://test.com/index.htm", False
objHTTP.setRequestHeader "Authorization", "Basic EncodedUserNameAndPassword"
objHTTP.setRequestHeader "Content-Type", "text/plain"
objHTTP.setProxy 2, "proxyhost.com:9293"
objHTTP.setProxyCredentials "proxyUser", "ProxyPassword"
objHTTP.setOption 2, 13056
objHTTP.send
```

##まとめ
Excelから直接RESTリクエストを送信して、各種APIを呼び出すことができます。大量のテストケースを管理するのにExcelは便利ですし、戻りのJSONをパースしてマッチングさせることで、テストを自動化することが可能です。
Xcodeのリフレッシュ方法と対処できるエラーについて


Xcode今まで問題なくビルドできていたのに、急にできなくなったってことありませんか？
その場合、Cleanや再起動など（リフレッシュと表記することとします）で対処できる可能性があります。
今回はリフレッシュ方法に焦点を当てて、まとめてみました。

## 方法

##### Xcodeを再起動

「×」で閉じるだけでなく、 `Command + q` でタスクキルをして再起動をします。
gitでpullした時に、すぐコードが反映されない場合などに効果的だと思います。

##### Clean

`Shift + Command + k` でクリーンできます。
※Productタブ > Clean でもできます。

##### Clean Build Folder

Productタブ > Clean Build Folder です。
Productタブを開いた状態で Optionを押していると、 Clean の項目が Clean Build Folderに変わります。

##### DerivedDataの中身を削除

設定 > Locations > DerivedData にある「→」を押すと、DerivedDataのフォルダが開かれる。
このDerivedDataフォルダの中身を全部削除する。

##### ライブラリをアップデート

リフレッシュ？とは言わないかも？ですが、
対処法の一つではあると思うので、記載しておきます。
`Carthage` か `CocoaPods` を利用している方がほとんどだと思いますが、updateが必要なケースがあります。
発生したエラー内容をしっかり確認すれば、現コードがライブラリ対応できていないことが書いてあると思うので、その際にupdateを実行しましょう。

## エラー例

##### TDDIstiller instance can only be distilled only one time

`Assets.car error 'No such file or directory'`
という、あるべきファイルがないエラーが発生しました。
-> 私は、「DerivedDataの中身を削除」を実施したら直りました。

##### dyld\_fatal\_error

`dyld dyld_fatal_error` や `EXC_BREAKPOINT` などのエラーが出ました。
「DerivedDataの中身を削除」したり、下記を実行してみたりしたら直りました。
https://qiita.com/nacika_ins/items/b297d6335364bfd24976

## まとめ

それぞれがどんな原因で、どういう対処が適切なのか、
根本的なとこから理解したい。。。

エラー例などは今後見つけ次第追記していきます。
cocos2d-x v3系で新しいシェーダを追加してみた

[グレンジ Advent Calendar 2017](https://qiita.com/advent-calendar/2017/grenge) 初日担当の mad_khaki です。
クライアントサイドを中心にサーバ / データ分析 等もやってます。

今回は cocos2d-x v3.2 でシェーダを追加する手順についてまとめました。

# 1. GLSLで頂点シェーダ書く

```glsl:ccShader_GrayScale.vert
const char* ccGrayScale_vert = STRINGIFY(
attribute vec4 a_position;
attribute vec2 a_texCoord;
attribute vec4 a_color;
													
\n#ifdef GL_ES\n
varying lowp vec4 v_fragmentColor;
varying mediump vec2 v_texCoord;
\n#else\n
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
\n#endif\n
													
void main()
{
	gl_Position = CC_PMatrix * a_position;
	v_fragmentColor = a_color;
	v_texCoord = a_texCoord;
}
);
```

STRINGIFYマクロで文字列化しておく
ccShader_PositionTextureColor_noMVP.vertをそのまま使ってもよい

# 2. GLSLでフラグメントシェーダ書く

```glsl:ccShader_GrayScale.frag
const char* ccGrayScale_frag = STRINGIFY(
\n#ifdef GL_ES\n
precision lowp float;
\n#endif\n
varying vec4 v_fragmentColor;
varying vec2 v_texCoord;
													
void main()
{
	vec4 color = texture2D(CC_Texture0, v_texCoord);
	float alpha = color.a;
	float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
	gl_FragColor = vec4(gray, gray, gray, alpha);
}
);
```

STRINGIFYマクロで文字列化しておく
https://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AB
係数はWikipediaから適当に引っ張ってきた

# 3. ccShadersに定義を追加する

```cpp:ccShaders.h
extern CC_DLL const GLchar * ccGrayScale_vert;
extern CC_DLL const GLchar * ccGrayScale_frag;
```
```cpp:ccShaders.cpp
#include "ccShader_GrayScale.vert"
#include "ccShader_GrayScale.frag"

```

# 4. GLProgramクラスのstaticメンバに追加する

```cpp:CCGLProgram.h
static const char* SHADER_GRAYSCALE;
```
```cpp:CCGLProgram.cpp
const char* GLProgram::SHADER_GRAYSCALE = "ShaderGrayScale";
```

# 5. シェーダキャッシュに追加する

## enumに追加

```cpp:CCGLProgramCache.cpp
kShaderType_GrayScale
```

## loadDefaultGLPrograms()に追加
3項で追加した文字列とシェーダの実体(GLProgram)の対応関係をマップで管理

```cpp:CCGLProgramCache.cpp
GLProgram* p = new GLProgram();
loadDefaultGLProgram(p, kShaderType_GrayScale);
_programs.insert(std::make_pair(GLProgram::SHADER_GRAYSCALE, p));
```

## loadDefaultGLProgram(GLProgram *p, int type)に追加
ここで1項、2項で文字列化されたシェーダがコンパイルされる

```cpp:CCGLProgramCache.cpp
case kShaderType_GrayScale:
	p->initWithByteArrays(ccGrayScale_vert, ccGrayScale_frag);
	break;
```

## reloadDefaultGLPrograms()に追加

```cpp:CCGLProgramCache.cpp
p = getGLProgram(GLProgram::SHADER_GRAYSCALE);
p->reset();
loadDefaultGLProgram(p, kShaderType_GrayScale);
```

# 6. 実際にシェーダを設定する

```cpp:CCSprite.cpp
setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_GRAYSCALE));
```
WindowsでSSLサーバ証明書 pfx を crt と key に変換する方法

## ■用途
* WindowsでSSLサーバ証明書 pfx を crt と key に変換する

## ■方法
* DigiCert Certificate Utility for Windows を使用する

## ■詳細
1. https://www.digicert.com/util/ から DigiCertUtil.zip をダウンロードする
1. zip内の DigiCertUtil.exe を解凍して、Windowsサーバの適当な場所におき実行する
1. SSLメニューでインストール済みのサーバ証明書を選択し、Export Certificate クリックする
	* https://www.digicert.com/util/pfx-certificate-management-utility-import-export-instructions.htm

	> How to Export Your SSL Certificate w/Private Key Using the DigiCert Certificate Utility
1. ダイアログで "key file"を選択し。。(ry
1. key, crtが出力される
リモートサーバのauthorized_keysが持つ公開鍵のフィンガープリントを全て表示する

公開鍵は形式によってはとても長いので、目で見て同一かどうか判断するのが少々大変です。

OpenSSL には `ssh-keygen` コマンドで公開鍵の特徴とも言える **フィンガープリント** を表示してくれる機能があります。

```bash
ssh-keygen -l -f ~/id_rsa.pub
```

`-l` でフィンガープリント表示、`-f` で公開鍵ファイル名を指定します。

とはいえ authorized_keys ファイルは複数の（1行1個の）公開鍵が連結されており、その公開鍵一つ一つのフィンガープリントを表示するのはどうすればよいでしょう。

様々な方法が考えられますが、以下のような一発コマンドで行うのが手軽です。

```bash
for i in $(seq 1 $(wc -l ~/.ssh/authorized_keys | sed -e 's/^ *//' -e 's/ .*//') ) ; do
    ssh-keygen -l -f <(sed -n -e ${i}p ~/.ssh/authorized_keys)
done
```

for 文が in で取るリストは行数の行番号を取り、それに対して特定の `${i}` 行のみを表示する sed 構文 `${i}p` と、コマンドの出力結果を一時的にファイルのように扱える名前付きパイプ構文 `<(...)` を使用しています。
サービス・システムをつくるうえでユーザビリティテストは必要

先日、[UX DAYS TOKYO](https://uxdaystokyo.com/)さんの[セルフユーザビリティテスト検定講座：UXDT](https://uxdt.connpass.com/event/67590/)に参加させて頂きました！

ユーザビリティテストをやる工程はいまないですが、システム・サイトが使いづらい(機能が使われない泣)などの問題を解決するには必要だと感じました。


## ユーザビリティテストとは？
```
ユーザビリティテスト（ユーザテスト）は、ユーザにWebサイト/アプリを実際に利用してもらい、
その行動･発言の観察を通じて、「ユーザ心理」と「Webサイト/アプリの課題」を見つける手法。
```
簡単に言うと、、、ユーザビリティテストを行うことで、**システム・デザインの欠点**が発見できる！
リアルな体験を根拠にできる！

## UXの基本的な
### 人間の脳みそは2つのシステムに分かれている
- システム1
    - 努力なしで即座に判断できるときに使う
- システム2
    - 計算をしなければならないときに使う 

ユーザーに考えさせてしまう(システム2を使う)サイトはよろしくない。

---
### システム2を使わせないために最低限必要なモノ
- サイト名
- ページ名
- セッション及びサブセッション
- ローカルナビゲーション
- 現在地
- 検索

いまユーザーはどこにいるのか、このサイトには「何」が「どこ」にあるのかをしっかり伝えることが大事

```
わかりやすいクリック3回 ≒ 悪いクリック1回
```
わかりやすいクリック3回で目的のページにいくのと、わかりにくいクリック1回で目的のページにいくのは、ユーザーのストレスとしては変わらないそう。。。

## ユーザビリティテストのやり方

### 参加者
![image.png](https://qiita-image-store.s3.amazonaws.com/0/149041/60cf9e57-a8e7-552e-cc52-7620dd8c76f9.png)

- モデレーター
    - 司会役
    - ユーザーが行った行動に対して理由を聞いたりする(答えは言わない) 

- 被験者
    - 思ったこと、行動を「発言する」ひと
    - どこから遷移したらいいかわからないなど素直に行う
    - 諦めてもOK
- 記録者
    - どこで感情が動いたか、ユーザーの素直な対応を出来る限り記録する
- カメラ
    - 顔の表情・手元を撮影

- 開発者
    - ユーザビリティテストに参加しない
    - 行動を誘発してしまうから

---
### 内容
- わかるかテスト
- できるかテスト

**point**
`ユーザーが何をどう見ているのかをテストする`

### ユーザビリティテストをやることで
- ユーザーがどこで迷うのかがわかる
- 何が正解なのかチームで共通認識が持てる

### 行うタイミング
- 出来る限りどのタイミングでもやったほうがいい
    - ペーパープロト、モックアップ、デザイン、HTML...


---
今回のイベントでは実際に被験者・モデレーター・記録者の担当になり、実際のサイトのユーザビリティテストをやるグループワークもあったので、とてもわかりやすく、楽しかったです！
今回このイベントに参加してぜひユーザビリティテストを導入したいと感じました！
開発者が参加しないとのことなので、ウチの会社でどう取り入れていくかは課題もありそうですが...
Visual Studio | WPF > グラフ > LiveCharts > Geared > Values = values.AsGearedValues().WithQuality(Quality.Low) の内容

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
```

[Visual Studio | WPF > グラフ > LiveCharts > 折れ線グラフ描画のパフォーマンス > 1000点: zoomingとpanningが重い | 1万点: 表示されない](https://qiita.com/7of9/items/4f2a8df08c56268b2a9e)
にて気になった折れ線グラフの描画高速化。

```
Values = values.AsGearedValues().WithQuality(Quality.Low)
```

上記では何をしているのか。

https://lvcharts.net/App/examples/v1/wf/Installing%20Geared

> `2. A smarter values instance
>
>...
> then you can use the low quality to render it faster, the error of the lower quality is 10px, but in an opposite case, you care about accuracy, then you must use the highest quality, the rendering time will be slower, but you won't have any visual error, there are also 2 more available qualities, medium quality, with a max error of 5px, and high which is the default quality, it has a practically invisible max error of 2px.

low qualityにした場合の誤差が10px。
つまり、10pxに1点を打つように間引きをしているようだ。

10pxに1点というのは感覚的に「粗い」と感じる。
それくらいの間引きをしないとLiveChartsではスムーズな描画をできないのだろうか。

1000点
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/e79fd6d2-d9d1-c033-fb32-ecde23354e26.png)

1000点のlow quality (10px誤差)
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/06595892-6b02-26bf-f475-e85e73a36044.png)
【メモ書き】Swift4でQRコードリーダーを作ろうとした時…

使用バージョンは以下の通りです
*Xcode version 9.1*
*Apple Swift version 4.0.2*


#よし、QRコードを読み取るやつ作ろう！！！

###まずはネット上を検索…

良さそうなの発見！
https://www.hackingwithswift.com/example-code/media/how-to-scan-a-qr-code

###そのままのコードで試してみた
アプリ起動！
↓
カメラが起動した
↓
QRコードに近づけてみると…
↓
***<font color="Red">何も起きない！！！</font>***

#原因を調べてみた

というより、ちゃんと読み取れてないのでそこのコードに何かあるのかと思いました。
気になったのはデリゲート。
https://developer.apple.com/documentation/avfoundation/avcapturemetadataoutputobjectsdelegate

やはりここでした


```.swift
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [Any]!, from connection: AVCaptureConnection!) {

        //省略
    }
```
と今まで書いていたのが

```.swift
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection){
        //省略
}
```

に変更になっていたようです。
ここだけ直したら無事にQRコードをスキャンできました。
めでたしめでたし…
横スクロールするメニューを考える (Delphi)

最近のスマホのアプリでメニューバーの部分が横スクロールするパターンがあるので、こんな感じかなと作ってみた

##こんなの作りました
これは Win32で実行していますが、スマホでも同様に動きます
![Gif20171114.gif](https://qiita-image-store.s3.amazonaws.com/0/164551/e8a29f78-5454-9380-45ac-d5e8985c1314.gif)

##考え方
ToolBar の上に、横長のパネルを貼り付けて、それをぐりぐり動かしています。
パネルの X 座標の左右の限界値ですが、

- 右方向に押し出したときの限界の座標値は 0
- 左方向に押し出された際の X 座標の限界値は、Form.Width - Panel.Width の値になります 
(Panel.Width の値の方が大きいので、X 座標はマイナス値になる)

カーソルや指で触れたとき、放したときを MouseDown, MouseUp イベントで検知し MouseMove イベントで押したまま移動しているのであれば、その距離分をぐりぐり動かします。

##画面の構造
オレンジのコンポーネントの [HitTest](http://docwiki.embarcadero.com/Libraries/Tokyo/ja/FMX.Controls.TControl.HitTest) プロパティは True に、ブルー側は False にしています。つまり 横長の Panel と、ボタンの上の文字に当たる Label 上のマウスイベントを検知するようにしています
![layer.png](https://qiita-image-store.s3.amazonaws.com/0/164551/cb05a485-9d7d-7545-9883-bef9c771e054.png)

##設計画面
ざくっと！
![sc01.png](https://qiita-image-store.s3.amazonaws.com/0/164551/bb73a345-5789-0fcf-d80a-28d82f6aa26b.png)

##サンプルコード

```delphi
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.StdCtrls,
  FMX.Controls.Presentation, FMX.Layouts, FMX.ListBox;

type
  TForm1 = class(TForm)
    ToolBar1: TToolBar;
    Panel1: TPanel;
    Panel2: TPanel;
    Label1: TLabel;
    Panel3: TPanel;
    LabelX: TLabel;
    Panel4: TPanel;
    Label2: TLabel;
    ListBox1: TListBox;
    procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
    procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
      Y: Single);
    procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Single);
    procedure LabelClick(Sender: TObject);
  private
    saveX: Single;
    scFLG: Boolean;
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

procedure TForm1.LabelClick(Sender: TObject);
begin
// ボタンに見せかけた部分に触れたら ListBox 内に自分のコンポーネント名を表示
  ListBox1.Items.Add(TLabel(Sender).Name);
end;

procedure TForm1.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
begin
// 横長のメニューにマウス(指)がクリック(触れたとき)に、
// スクロールのためのフラグを ON にして、クリックされた X 座標の現在位置を保存
  SaveX := X;
  scFLG := True;
end;

procedure TForm1.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
  Y: Single);
begin
// フラグが ON の時のみ計算を行なう
  if scFLG then
    Panel1.Position.X := Panel1.Position.X + (X - saveX);

// スクロールの限界値をチェック
// 超えている場合は、左右の限界点を代入
  if Panel1.Position.X < (Form1.Width - Panel1.Width) then
    Panel1.Position.X := Form1.Width - Panel1.Width;
  if Panel1.Position.X > 0 then
    Panel1.Position.X := 0;
end;

procedure TForm1.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Single);
begin
// マウス(指)が離れたのでフラグ OFF
  scFLG := False;
end;

end.

```
PHPのリダイレクト処理について

PHPのリダイレクト処理について一つ疑問があったので書き記しておきます。

<h1>リダイレクト処理(header関数)は条件分岐できるのか？</h1>
headerが発行される前に出力がなければ条件分岐のソースは前半でなくても問題はない。

```php
<?php

if(エラー確認処理をしてもしエラーがあればリダイレクト) {

header("Location: registration.php")
exit();

} 

```

<h1>exit はどこに書けばよいのか？</h1>
<strike>厳密にいえばheaderで飛んだあとexitは実行されることはない。
exitはあくまでもheaderがうまく実行できなかった場合の保険。
なにがあってもそれ以下には進ませたくない箇所にexitを指定してあげるとよい。</srike>

※訂正をいただきました。
<blockquote>
間違い。
header(Location)しただけでは処理は終わらない。
そこで処理を終わらせたい場合はexitを書かなければならない。

https://qiita.com/sin_per/items/c55cd10ea611d56605e0
https://qiita.com/karur4n/items/c398b83e70e4479984b4
</blockquote>