OmniAICreator/Qiita-1.07M huggingface dataset:
プロの現場では必須！　新人デザイナーに伝えるIllustratorの基礎

## 概要
新人が入るたびにIllustratorを教えていたけれど、人によって解釈が違ってしまったので文章でまとめます。
他の会社の人も参考にしてください。

## ファイルの作成方法
「ファイル」→「新規」から、作りたいものを選択（なければカスタマイズ）。単位のpxとmmを間違えないように（あとで変えられるけれど）。

webの場合はアートボードを1920pxなのか1280pxにするのかファイルで統一します。
制作するwebサイトのレスポンシブの切り替えを何段階にするかによって自動的に決まります。

例：横幅1000pxの場合1280pxで作成など。

### ガイドライン
適切な場所にガイドラインを引いてから始めます。
ノーガイドラインとかやっちゃダメ。それはアートになってしまう。

#### Webの場合
Widthに合わせてガイドラインを作成。そこからはできるだけはみ出さないように。
わざとはみ出す場合はネガティブマージンなどをCSSの作成方法を考えながらレイアウトします。
#### 紙の場合
紙面の中央、トンボ、ドブ、ノド、小口などに適切にガイドを引きます。
ノドや小口などは、テキストの級数を考え、ベタ組みなのか、一歯詰めなのか、テキストがきちんと組まれるように数値を計算した上で設定します。
（級数と文字数を考えると自動的に決まります。1Q=0.25mm）


### レイヤー
印刷、Webなどその後の後工程のことを考えてレイヤーを作ります。海外で使用する場合も考えて、レイヤー名は英語に統一。

Webの場合は下記のようにします。
基本はSASSの構成ファイル名に合わせるけれど、粒度によって要調整。
* Header
* Footer
* Text
* Icon
* Images
* Button
* Background

こうすると、コーディングの時に迷わなくて済みます。


### リンクファイル
基本はPSDファイルをリンクします。
格納場所は、同一階層状のLinksフォルダ。
リンクファイルがJPGの場合はPhotoshopでPSDへバッチ処理、PSDへ変換してから使用します。理由は、JPGファイルやTiffをリンクすると、どんどんファイルが重くなって取り回しが悪いから。。

### アートボード
アードボードは整数値のxy軸から開始。
複数アートボートを作るときはそれぞれの開始位置を「-5000,0」「-3000,0」などにします。
こうすると、それぞれのアートボートの移動が整数値になり動かしやすくなります。
また、アートボードの名称は「PC」「SP」などわかりやすくつけます。
一括で書き出す場合に、ファイルがわかりやすくなるからです。


## ファイルの保存方法

### ファイル名

ファイル名は下記のようにします。

* 180209-hogehoge-hogehoge-v1.0.ai

最初は日付、続いてクライアント名、その先に案件名、最後にバージョン。
Ver情報をつけておくと、何回構成入ったかすぐわかって良いです。
v2.0へアップデートするときは大きな修正が入ったとき。
それ以外は0.1の方をアップデートしていきます。

###　保存方法

普通に保存でOK。ただし、Illustratorは下位互換とはいえ、基本は下位保存はしません。（ファイルのアウトラインが取られることがあるから。）

また、PDF互換ファイルのチェックは外します。
PDF互換ファイルにチェックを入れると、PDFで確認できるようになる代わりにファイルが重くなります。PDFで確認したいなら、別にファイルを作成します。

### 納品ファイルについて
パッケージから全ファイルを収集してそれを納品します。
注意点としては、リンクファイル内にさらにリンクファイルがあると、それは溢れるので注意。


## 覚えておくべきショートカット

最初にツールパネルのショートカットは全て覚える。ツールの切り替えは、マウス移動ではなくキーボードで行うこと。
例：「v」→移動、「s」→拡大縮小など。

こうすると、オブジェクトを10px移動移動したいときは、
1. オブジェクトを選択
2. 「v」をクリックした後に「enter」をクリック
3. 10pxと入力
で、できるのですごく効率的。拡大縮小なども同様。

これ以外にもよく使うものは常にショートカット。

### 環境設定について

選択範囲・アンカーについての項目で「オブジェクトの選択範囲をパスに制限」にチェックを入れること。ここにチェックを入れると、下にあるオブジェクトが、上のオブジェクトをロックしなくても選択できるようになるので、ものすごく便利。

以上


## おそらく役立つ情報 
痒いところに手が届くかもしれない記事を書いています。
フォローしてくれるとやる気になります！

- Qiita　プログラミングに関する情報はこちら
http://qiita.com/nadonado


- Twitter　日々のつぶやきはこちら
https://twitter.com/hironado
curlを100回やってダウンロード時間の平均を求める

クラウドのスピード試す時に使ってた

```sh
#!/bin/bash

# スピード調査をするURL群（スペース区切り）
D="example.com www1.example.com www2.example.com"

# 平均を取るために繰り返す回数
RPT=100

echo '%{time_total}' > curl-format.txt

for R in $D
do
   TIME=0
   echo $R
   echo

   for i in $(seq 1 $RPT)
   do
#       echo i=$i
       TRY=$(curl -w "@curl-format.txt" -o /dev/null -s $R)
       TIME=$( python -c "print $TRY+$TIME") 
   done

#   echo TIME=$TIME
#   echo RPT=$RPT
   RES=$( python -c "print float($TIME)/$RPT" )
   echo $R avarage is $RES
   echo

done
```
dns問い合わせを毎分行うscript



dnsの調子が悪い時に叩くと、復帰した時がわかーる

```sh
bash /dns example.com 8.8.8.8
```
```sh
#!/bin/bash

# dns問い合わせ連続でする

while true;
do

  date
  nslookup $@
  sleep 60

done
```



別にscriptにする必要もないけど、いろいろ足しやすいので。
Oracle テーブル毎のレコード件数を取得 PL/SQL

```PL/SQL:count_tables.sql
--
--     TABLE_NAME毎のレコード件数を取得
--     レコード件数の多いテーブルでは負荷が大きいので注意。
--
--  history
--    2018/03/03 索引構成表を除く
--
SET ECHO OFF
SET FEEDBACK OFF
SET LINESIZE 400
SET PAGESIZE 5000
SET TERMOUT OFF
SET TRIMSPOOL ON
SET SERVEROUTPUT ON SIZE UNLIMITED
ALTER SESSION ENABLE PARALLEL DML ;
-- SPOOL pass includes CONNECT_IDENTIFIER, USER_NAME and SYSDATE
COLUMN USER_NAME    NEW_VALUE USER_NAME
COLUMN SYSTEM_DATE  NEW_VALUE SYSTEM_DATE
SELECT USER || '_' AS USER_NAME
     , TO_CHAR(SYSDATE, 'YYYYMMDD_HH24MISS') AS SYSTEM_DATE
FROM DUAL ;
SPOOL count_tables_&&_CONNECT_IDENTIFIER._&&USER_NAME&&SYSTEM_DATE..log
-- Windows ↑,  UNIX/Linux では ↓ を有効に
-- SPOOL count_tables_\&&_CONNECT_IDENTIFIER._\&&USER_NAME\&&SYSTEM_DATE..log
SET TIMING ON
DECLARE
    CURSOR CUR_TA
    IS
        SELECT
            TA.TABLE_NAME
          , 'SELECT /*+ INDEX_FFS(TA) PARALLEL(DEFAULT) */ COUNT(*) FROM "' || TA.TABLE_NAME || '" TA' AS SQL_STRING
          , NVL2(TM.COMMENTS, ' -- ' || TO_SINGLE_BYTE(TRIM(TM.COMMENTS)), NULL) AS TABLE_COMMENTS
        FROM USER_TABLES TA
        LEFT OUTER JOIN USER_TAB_COMMENTS TM
        ON  TA.TABLE_NAME = TM.TABLE_NAME
        WHERE
            TA.DROPPED = 'NO'  -- except trash box, since Oracle10.1.0
        AND TA.IOT_TYPE IS NULL  -- except index composition table
        AND TA.TABLE_NAME NOT IN
            (
            'CHAINED_ROWS'  -- except Oracle side table
          , 'EXCEPTIONS'
          , 'PLAN_TABLE'
          , 'PLAN_TABLE$'
             )
        ORDER BY
            TA.TABLE_NAME ;

    L_COUNTS  NUMBER ;
BEGIN
    DBMS_OUTPUT.PUT_LINE('TABLE_NAME                                    COUNT COMMENT') ;
    DBMS_OUTPUT.PUT_LINE('----------------------------- --------------------- --------------------------------------------') ;
    FOR REC_TA IN CUR_TA LOOP
        EXECUTE IMMEDIATE REC_TA.SQL_STRING INTO L_COUNTS ;
        DBMS_OUTPUT.PUT_LINE(RPAD(REC_TA.TABLE_NAME, 31) || TO_CHAR(L_COUNTS, '999,999,999,999,990') || REC_TA.TABLE_COMMENTS) ;
    END LOOP ;
END ;
/
SET TIMING OFF
SPOOL OFF
SET ECHO ON
SET FEEDBACK ON
SET LINESIZE 80
```
How to change IP address with esxcli



```
% esxcli network ip interface ipv4 get
Name  IPv4 Address    IPv4 Netmask   IPv4 Broadcast  Address Type  Gateway         DHCP DNS
----  --------------  -------------  --------------  ------------  --------------  --------
vmk0  192.168.0.3  255.255.255.0  192.168.0.255  STATIC        192.168.0.254     false
```

```
% esxcli network ip interface ipv4 set -i vmk0 -I 192.168.0.7 -N 255.255.255.0 -t static 
```
1. スプレッドシートを利用して統計解析　一様乱数の生成

# 乱数(一様乱数)の作成と平均値の表示
## Google Spreadsheetを利用した統計解析
表計算ツールを利用して統計解析を行う
Pythonを利用して同じことを行う場合は[1. Pythonを利用して統計解析 - 一様乱数の作成](https://qiita.com/percipere/items/da332d14e491cda221bb)を参照

グーグルのアカウントでスプレッドシートを新規作成
![Screen Shot 2018-02-07 at 14.04.14.png](https://qiita-image-store.s3.amazonaws.com/0/213053/cdda8109-851e-24c9-707c-d7d39c1c4123.png)

一行目を平均値を表示するための行とする
A1セルにタイトルとしてAverageと記入する

##10個の乱数の作成
B2セルに=RAND()を入力
![Screen Shot 2018-02-07 at 14.05.23.png](https://qiita-image-store.s3.amazonaws.com/0/213053/14b6e19e-7f35-2f62-cef7-cfb697b5fabd.png)

B2セルの内容をB11セルまで下方向にコピペ
![Screen Shot 2018-02-07 at 14.05.57.png](https://qiita-image-store.s3.amazonaws.com/0/213053/b57ae479-0c95-93c9-4c80-3e6b99714c6e.png)

##乱数の平均値の計算
B1セルに=Average(B2:B11)を入力
![Screen Shot 2018-02-07 at 14.19.30.png](https://qiita-image-store.s3.amazonaws.com/0/213053/dbc9af95-731c-329f-3c83-7ef02f047b6e.png)

1行目の値が目立つように文字色を青に変更

##乱数の塊を複数作成
B行をコピーしてして、C列からI列までペースト
![Screen Shot 2018-02-07 at 14.07.33.png](https://qiita-image-store.s3.amazonaws.com/0/213053/b7ebd2de-be4d-5261-0c1e-b3bc72e2fd8d.png)

表計算なので

* 行方向にセルをコピーすれば一つの列の塊の中の乱数の個数はいくらでも増やせる（１行目のAverage関数の中の範囲指定は都度変更する必要がある)
* 列方向にセルをコピーすれば乱数の塊はいくらでも増やせる

どこかのセルを編集する度に、各セルが再計算されるので都度乱数は変更される。

今日はここまで:smiley:
Node.jsよくわかってない俺が調べる環境変数の取得方法

俺です。
最近EC2原人しつつコンテナ猿人はじめました。パラレル原人です。

Node.js Expressアプリのコンテナ起動時にcomposeやSystem Managerから拾ってきた環境変数が適用できてるか調べる方法を残します。

これでok

```
host $ docker ps
※get container id
host $ docker -it <container id> /bin/bash
container$ node
node> node.process.env
```


完
【メモ】Vue.jsアプリ構成の調査で参考になった記事一覧


## Vue
- [Vue](https://jp.vuejs.org/index.html)
- [Vue router](https://router.vuejs.org/ja/)
- [Vuex](https://vuex.vuejs.org/ja/)
- [Vue loader](https://vue-loader.vuejs.org/ja/#)
- [Vue.jsとAxiosなら驚くほど簡単に作れる！外部APIを使ったWebアプリの実例](https://www.webprofessional.jp/fetching-data-third-party-api-vue-axios/)

## ライブラリ
- [Lodash/Underscoreは必要ない（かも）](https://qiita.com/ossan-engineer/items/ad5313d84da82c6ac421)
- [[Question] what advantage does axios give us over fetch? EOM](https://github.com/axios/axios/issues/314)
- [React NativeのHTTPリクエストにはfetchよりaxiosを使ったほうが安定しそう](http://mmiyauchi.com/?p=1883)

## テスト
- [vue-test-utils](https://vue-test-utils.vuejs.org/ja/)
- [JavaScriptテスト自動化キホンのキ](https://qiita.com/y-tsuna/items/6b8b824e444030070754)
- [フロントエンドにテストを導入](https://qiita.com/howdy39/items/cdd5b252096f5a2fa438)
- [Karma + PhantomJS + Mocha + power-assertでクライアントサイドJSのユニットテスト環境を構築してみた](https://liginc.co.jp/187209)
ローカル環境設定メモ

# memo
webサイトつくったりで必要なやつ（適時更新）

## ローカル環境設定手順
  - コーディング用fontをインストール > [fira-code](https://github.com/tonsky/FiraCode) / [Ricty Diminished](https://github.com/mzyy94/RictyDiminished-for-Powerline)
  - [homebrew](https://brew.sh/) のインストール
  - nodebrew > node.js のインストール
    - `nodebrew setup`
    - `nodebrew ls-remote` インストール可能な最新版を確認
    - `nodebrew install-ninary stable` 最新の安定版をインストール
    - `nodebrew use <VERSION>` 使用するnode.jsのバージョンを指定
    - `echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile`
  - sublie textのインストール
    - [package controll](https://packagecontrol.io/installation) のインストール
  - IED
    - [Visual Studio Code](https://code.visualstudio.com/download)  のインストール
    - ~~[Aptana](http://www.aptana.com/index.html)...?~~
    - ~~[Brackets](http://brackets.io/) (オワコン化)~~

## Sublime Text のpackage
  - Abcus → インデントの整列
  - AutoFileName
  - BracketHighlighter
  - compass
  - Emmet
  - HTML5
  - SCSS
  - Seti_UI
  - SideBarEnhancements


## xampp
  - セキュリティ設定 phpmyadmin  
    1. `/Applications/XAMPP/xamppfiles/bin/mysqladmin -u root -p password`
    1. `open /Applications/XAMPP/xamppfiles/phpmyadmin/config.inc.php`
    1. 「auth_type」=>「cookie」,「password」=>「任意」に変更

## brew
  - fish        :shell
  - node        :node.js
  - rbenv       :ruby
  - ruby-build  :ruby build tool

## vagrant
  - plugin: vagrant-vbguest
  - centOS 6.9
  - shell: [fish](https://fishshell.com/)
Laravel5.5 で非同期処理(Queue)を実装【sync編】

# 環境
- CentOS 6.9
- Apache 2.2
- MySQL 5.6
- PHP 7.1
- Laravel 5.5

# 設定ファイル
必要に応じてデフォルトの設定内容を変更する。

## .env

```php:.env
    QUEUE_DRIVER=sync
```

とりあえずデフォルトの `sync` のままで進める。
※ `sync` の場合は非同期にならないが、
　ジョブの動作確認ができるまでは、最初は `sync` にしておいて、正常動作が確認できてから、　`database` に切り替えることにする。

## config/queue.php

```php:config/queue.php
    'connections' => [
        ～省略～
        'database' => [
            'driver' => 'database',
            'table' => 'jobs',
            'queue' => 'default',
            'retry_after' => 90,
        ],
        ～省略～
```

ここもひとまずデフォルトのままで。
あとで必要に応じて `database` の設定項目を変更する。

# ジョブクラスの作成
artisanコマンドでジョブクラス
 `StoreDataFile` （任意のクラス）を生成する。

```:console
$ php artisan make:job StoreDataFile
```
` app/Jobs/StoreDataFile.php `が生成される。

# ジョブクラスの実装

```php:app/Jobs/StoreDataFile.php
class StoreDataFile implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected $inputs;
    protected $user_id;

    /**
     * Create a new job instance.
     *
     * @return void
     */
//    public function __construct(Request $request, $user_id) //-- (1)
    public function __construct(array $inputs, $user_id)  //-- (2)
    {
        $this->inputs = $inputs;
        $this->user_id = $user_id;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        //ここに非同期で行いたい処理を実装
    }
}
```

ビューで入力した値を利用したかったので、コンストラクタの引数に`Request` クラスを指定していたが(1)、以下のエラーが発生。

```
Serialization of 'Closure' is not allowed
```

どうやらシリアライズできないオブジェクト（`Request` クラス）を指定することはできない[[*]](#note1)ようなので、
`$request->all()` で配列にして渡すようにした (2)。
<a name="note1">*</a> eloquentのモデルは例外???

参考：[LaravelでMailableなオブジェクトをqueueで送信したら"Serialization of 'Closure' is not allowed"というエラーになった件の解決方法](https://qiita.com/pinekta/items/f95742547f9fd8b2a446)

# コントローラからのジョブのディスパッチ

```php:TestController.php
        //StoreDataFileジョブをディスパッチ
        $this->dispatch(new StoreDataFile($request->all(), auth()->id()));
```

これでひとまず完成。
`database` を利用した非同期処理の実装はまた次回。。。

次回：[Laravel5.5 で非同期処理(Queue)を実装【database編】](https://qiita.com/tsuyopon-md/items/d8bafbda3b4f7b05add3)

# 参考
- [Laravel 5.5 キュー](https://readouble.com/laravel/5.5/ja/queues.html)
- [laravel5.5のキュー投入によるジョブ処理を導入する](https://www.ritolab.com/entry/36)
初心者でもすぐ使えるPromiseオブジェクトまとめ

## ■はじめに
これまでは、setTimeoutを使って無理くり順次処理を実現していました。
趣味や簡単なプログラムなどでは良いのかもしれませんが、本格的なプログラムやゲームなどを作り始めると完全にコールバック地獄になるので、今回Promiseについて少し調べてみました。

## ■同期処理について
一つの処理が終わるまで、次の処理を実行しない。

### ▼概念的なコード例
```
/* 処理1 -> 処理2 -> 処理3 の順番で実行される */
console.log("処理1");
console.log("処理2");
console.log("処理3");
```

## ■非同期処理について
同時に複数の処理が実行されるため、順番に記述した場合でも、意図した順番で実行させることが難しくなる。

### ▼概念的なコード例

```
/* 処理2 -> 処理3 -> 処理1 の順番で実行される */
setTimeout(() => console.log("処理1"), 5000);
console.log("処理2");
console.log("処理3");
```

setTimeoutメソッドを実行してる間にも、それ以降の処理を実行している。

## ■Promise オブジェクトについて
MDNを見ると、「非同期処理の最終的な完了もしくは失敗を表すオブジェクトです。 」とある。
[Using promises - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Using_promises)

まあとりあえず使ってみよう。
Promise オブジェクトを利用する場合、非同期処理を関数でまとめる。

```
// 非同期処理のまとまり
let asyncFunc = val => {
    // Promise オブジェクトを戻り値として返す
    return new Promise((resolve, reject) => {
        if(val) {
            resolve("success");
        } else {
            reject("error");
        }
    });
}

// asyncFuncの引数がある場合は、"success" で、ない場合は、"error" が出力される。
asyncFunc("hoge").then(
    response => { console.log(response); } ,
    error => { console.log(error); }
);
```

### ▼Promise コンストラクター

```
new Promise((resolve, reject) => {
    if(val) {
        resolve("success");
    } else {
        reject("error");
    }
});
```

・引数の説明
第一引数 は、処理の成功を通知する関数
第二引数  は、処理の失敗を通知する関数

Promise オブジェクトは、コールバック関数の resolve と reject のどれを実行したかを状態として持ちます。
非同期処理の中身で、resolveを呼び出してあげれば、成功とし、rejectを呼び出してあげれば、失敗とし後続の処理に移ります。
※Promiseが自動で状態判断する訳ではないので、自らresolveもしくはrejectを呼び出してあげる必要があります。

### ▼then メソッド

```
asyncFunc("hoge").then(
    response => { console.log(response); } ,
    error => { console.log(error); }
);
```

・引数の説明
第一引数 は、成功時のコールバック関数
第二引数 は、失敗時のコールバック関数
※失敗時は、catchメソッドを用いた方法もありますので、後述します。


### ▼catch メソッド

```
asyncFunc().then(
    response => { console.log(response); } 
).catch(
    error => { console.log(error); } 
);
```
then メソッドの第二引数を省略し、catch メソッドを用いてエラー出力を行なっています。
こちらの方が見通しの良いコードが書けそうですね！


以下のように両方に記述した場合は、thenが優先されます。

```
asyncFunc("hoge").then(
    response => { console.log(response); } ,
    error => { console.log("then : " + error); }
).catch(
    error => { console.log("catch : " + error); } 
);
```

## ■まとめについて
殴り書きみたいですみません。。
少し長くなってきたので、一旦ここで切らせていただきます。
（Promise オブジェクトに関わるそのほかのメソッドは、また別の記事に記載させていただきます。）

以下のような処理を順番に実行したい場合は、promiseを使うと良さそう。

・Promiseを使わないと・・・

```
/* 処理2 -> 処理3 -> 処理1 の順番で実行される */
setTimeout(() => console.log("処理1"), 5000);
console.log("処理2");
console.log("処理3");
```

・Promiseを使えば・・・

```
/* 処理1 -> 処理2 -> 処理3 の順番で実行される */
Promise.resolve()
.then(() => { console.log("処理1"); })
.then(() => { console.log("処理2"); })
.then(() => { console.log("処理3"); });
```

### ▼ちょっと補足
今回のように単純に順番の処理を行い場合は、`Promise.resolve()`と省略した方がシンプルにかけそう。
特に出しわけも必要としていないので、以下を省略した形になります。

```
new Promise((resolve, reject) => {
    if(val) {
        resolve("success");
    } else {
        reject("error");
    }
});
```
Unityでモザイク処理したい

# やりたかったこと

シーンの中に磨りガラスのようなオブジェクトを置いて、好きな部分にモザイクをかける的なことがしたい。

こんな感じ
![capture.gif](https://qiita-image-store.s3.amazonaws.com/0/56668/f5c92422-fba5-6a51-b09d-6109f5c1e4ad.gif)

## やってみた

以下のようなシェーダーを作成して、このシェーダーを使用するマテリアルを作成します。シーンにQuadを作成して、マテリアルを設定するだけです。

```csharp
Shader "Custom/GlassBlur" {
    Properties {
	    _blurSizeXY("BlurSizeXY", Range(0, 1)) = 0
    }
    SubShader {

        // 不透明オブジェクトを描画した後に実行する
        Tags { "Queue" = "Transparent" }

        // オブジェクトの背景テクスチャーを _BackgroundTexture に取得する。
        GrabPass { "_BackgroundTexture" }

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag 
            #include "UnityCG.cginc"

            sampler2D _BackgroundTexture;
            float _blurSizeXY;

            struct v2f
            {
                float4 position : POSITION;
                float4 screenPos : TEXCOORD0;
            };

            v2f vert(appdata_base i) {
                v2f o;
                o.position = UnityObjectToClipPos(i.vertex);
                o.screenPos = ComputeGrabScreenPos(o.position);
                return o;
            }

            half4 frag( v2f i ) : COLOR
            {
                float2 screenPos = i.screenPos.xy / i.screenPos.w;
                float depth = _blurSizeXY * 0.01;

                half4 sum = half4(0.0h, 0.0h, 0.0h, 0.0h);
                float count = 0.0;
                
                for (float x = -1.0; x <= 1.0; x += 0.25) {
                    for (float y = -1.0; y <= 1.0; y += 0.25) {
                        sum += tex2D( _BackgroundTexture, float2(screenPos.x + x * depth, screenPos.y + y * depth));
                        count += 1.0;
                    }
                }

                return sum / count;
            }
            ENDCG
        }
    }
}
```

GrabPassというのを使うとオブジェクトを描画する前に背景の絵をテクスチャーとして参照できるようになります。あとはそのテクスチャーを参照しながらフラグメントシェーダーの中で各点について周囲のピクセルの平均を取るような計算をしています。
平均を計算する部分とかもう少し効率化できそうな気がするけど簡易的にはこれで。
初心者が話すUiPath　～Excel処理問題【懇親会編】 [1]～ 


とあるシチュエーションを想像し、
実際にそれを自動化してみましょう。
（自分で課題を考えると、すぐには思いつかないものなので、
　問題だと思って是非トライしてみてください！）

今回はそのシチュエーションを書いていきます。
私が作成したものの解説、作成手順は次の記事から行います。


## 作りたいもの　～シチュエーション～
とある会社で、毎月懇親会が開かれるとしましょう。
懇親会前には、一次会・二次会それぞれの
参加・不参加のアンケートが出されます。

アンケート結果はExcelのCSV形式でダウンロードができます。
因みに表示はこんな感じ↓

| 氏名 |  回答日時 |    一次会   |二次会|
|:-----------------|------------------:|:------------------:|:------------------:|
| 田中　太郎|20YY/01/01 |参加します。|参加します。
| 前田　良子|20YY/01/02 | 参加しません。 |参加しません。
| 笹口　芳樹 |20YY/01/01 |参加します。 |参加しません。
| 吉田　眞子|20YY/01/03 |参加します。|参加します。
| 山田　清志|20YY/01/01 |参加します。|参加しません。
| 田辺　理子|20YY/01/02 | 参加しません。 |参加しません。

集金はその部署の代表者が集めるとしましょう。
代表者は懇親会までに、自分の部署の人間のアンケート結果から
参加者と不参加者を調べます。
（excelを開いて～、
　ctrl+Fで同じ部署の方の名前を検索して～の手順）

お金は一律3000円。
そして役職者は少し多めにし、
新卒の子たちはタダで参加できる事にしましょう。

社長・専務（参加）　：3000+8000円
社長・専務（不参加）：0+8000円
部長（参加）　：3000+3000円
部長（不参加）：0+3000円
課長（参加）　：3000+500円
課長（不参加）：0+500円
一般（参加）　：3000円
一般（不参加）：0円
新卒　　　　　：0円

部署は3つ。
（それぞれの部署ごとの名簿.csvが存在するとします。
　また社長・専務の分は管理本部が集めるとします。）
①　管理部
②　営業部
③　開発部

こんな現状があったとしましょう。

## 作りたいもの　～欲しい機能～
上記の話から、必要な機能をまとめてみましょう

・一次会、二次会の参加予定人数の把握
・アンケート未回答者の把握
・excelのソート（参加、不参加、アンケート未回答）
・それぞれがいくら払うかの計算（役職に依存）
・部署ごとにexcelを分ける
・部署代表にexcelを添付し、メールで送る


以上を踏まえて、実際に作ってみましょう！

（どんな風に作るのか想像してから、読み進めてみてください！
もし可能な方は実際に作ってみてください！）

## 必要なExcelデータ
適当な名前で名簿とアンケート結果を作ってみました！
名前をこれだけ出すのは大変でした...
こちらを使って、作ってみてください！

[課題資料](https://drive.google.com/drive/folders/1AGNnW32SiZPx5SSo5dIBG9EECCw2ReXH?usp=sharing)（Googleドライブに飛びます）
※ダウンロードすると、同じ行全ての文字が合わさったものになってしまうので、
Webで表示し、コピーペーストをして使用してください。

## 何も考えず作ってみたよ

<img width="636" alt="UiPath.png" src="https://qiita-image-store.s3.amazonaws.com/0/234754/f5785b16-ad6a-4b26-6b4f-40b189a1fc22.png">

....はい、バカです。
一つのシーケンスに、ひたすらIf文を突っ込み、ごり押しで作成しました。
（ちゃんと機能します笑）

しかし、これはどう見ても美しくない。
何より分かりづらい！

この教訓から、シーケンスを分ける事を意識しての作成を心掛けました。

## フローチャートの下書き
作成する上でまず設計書を書きましょう。
簡単ですよね！

...嘘です。
私は設計書が作成できず、
まだ小さな機能から、どんどん肉付けしていくように作成してます。
先輩方のように綺麗に書けません。

しかし、これも訓練なので挑戦してみました。
ただの箇条書きになってしまいましたが、
どの機能から手を付けるべきか、また作成のイメージが少しついたので
やって損はないと思います。
　

　

[次の記事](https://qiita.com/akira-f/items/9793327cda1b27aa70d2)から、今回のシチュエーションを自動化するにおいて
作成したものの解説、手順を書いていこうと思います。

是非皆さんも挑戦してみてください！
yum install javaのあとにalternativesでバージョンを切り替える

#alternativesを使う
```
sudo yum -y install java-1.8.0-openjdk

# install 完了後

JAVA_PATH=$(sudo alternatives --display java | grep priority | grep 1.8 | cut -d ' ' -f 1)
sudo alternatives --set java $JAVA_PATH

# java -versionで確認
```
確認環境は、AmazonLinuxの`ami-ceafcba8`(amzn-ami-hvm-2017.09.1.20180115-x86_64-gp2)

##使いどき
良いか悪いかは別として、シェルスクリプトでpackageのインストールなどを自動で行いたいときとかを想定
自分の場合はAmazonLinuxで1.8.0をインストールして、embulkを使おうとした際に遭遇

`yum remove`で1.7.0を削除しようかと思ったけれど、依存している`aws-apitools`があったので、他の方法として`alternatives`を使用
ぐぐってみた感じだと、`alternatives --config java`で切り替える方法が上位に来ている様子
これだけわかってればなんとかなるだろっていうGitのあれこれ


昨年に途中参加させていただいたプロジェクトで、Gitを使ってソースコードの管理がされているものの、チーム全体の練度があまり高くなかった。
そこで「このくらいわかってればなんとかなる」っていうのをまとめてみたのだけれど、それをこちらにも残しておこうと思う。
Gitが既に入っている環境で、はじめてGitで並行開発してみたとかそういう人向けですね。

## Gitを使えるとは言っても
Work treeとStage(Index)がわかっていない人が結構いる。「add」するって感覚がわからないのだそう。
というのも、社内で使用しているツールがバラバラで、なんとなく使っているという人が多かったみたいです。主にTortoiseGitとSourceTreeに二分されていた。GUIだとだいたいそうなるよね。
なので、まずはコマンドだとこんな感じですよっていう流れを覚えていただいたという次第。

## まずはここから覚えよう
大切なのは「ローカルとステージ」「コミット」「マージ」「プッシュ」の4つです。これだけ覚えておけば、通常の作業は問題ないです。ね、簡単でしょ？  
では、よく出る言葉を見てみましょう。

### よく出る言葉

* repository(リポジトリ)  
  - gitで履歴管理を行う領域
* remote repository(リモートリポジトリ)
  - サーバーにあるリポジトリ。pushする先はここ。単にリモートと呼ぶ事が多い
* local repository(ローカルリポジトリ)
  - 自分のPCにある履歴の管理場所。作業するのはここ
  - 任意のディレクトリで同一リポジトリでも違うリポジトリでも自由に作ることがでる
* branch(ブランチ)  
  - 履歴管理を分岐させたもの。違う機能を作るとか、リリース時期が違う時とかに使う
* commit(コミット)
  - 変更したファイルを変更履歴に登録すること。あと、登録された履歴のこと
* work tree(ワークツリー)
  - ファイルを編集・操作する領域
* index(インデックス)
  - コミット予定のファイルを登録する領域
* stage(ステージ)
  - インデックスにファイルを登録すること
  - add(アド/アッド)する という方がよく使われると思う
* head(ヘッド)
  - 現在作業しているブランチ、コミット
* checkout(チェックアウト)
  - 現在のヘッドを任意のコミットに移動すること
* fetch(フェッチ)
  - リモートリポジトリの変更を確認すること
* merge(マージ)
  - 別のブランチを現在のブランチのヘッドに継ぎ足すこと
  - リモートの同一名ブランチも「別のブランチ」扱いなので注意
* pull(プル)
  - ローカルリポジトリにあるコミットに、リモートリポジトリの新しいコミットを反映させる
  - フェッチしてマージするのと同じ
* push(プッシュ)
  - ローカルリポジトリの変更をリモートリポジトリに反映させること
* diff(ディフ)
  - ファイルの差分を表示する。単に差分って言ったりもする
* conflict(コンフリクト)
  - マージの際に同一ファイルの同じ箇所が変更されてコミットが作られない状態
  - 「コンフリクトした」以外だと競合してるとか言うと思う

これで「リモートのブランチのこのコミットからブランチを切って作業してね。ローカルの作業をコミットしたら元のブランチにマージしてプッシュしといて」って言われても平気ですね！

## cuiでの操作を見てみよう
本題です。TortoiseGitやSourceTreeなどを使うことでguiでの操作は可能ですが、ネットでも書籍でもcuiでのコマンド操作を基準に教えているので、軽く覚えておくと良いかと。
この共通認識が欠けるからうまくいかないんだなーって感じます。イメージしてみるだけでも変わるはず。
### よくつかうコマンド
大抵は以下のループになるかと。
※ <>の中身は適当に置き換えてたり飛ばしたりしてくださいね

* `git fetch <origin> <BRANCH NAME>`  
  - remoteに変更がないか確認。<>は省略可能
* `git pull <origin> <BRANCH NAME>`
  - リモートブランチへの更新をローカルにマージ
  - ブランチ指定するときは今いるブランチに気をつけないとダメだよ
* `git checkout -b <NEW BRANCH NAME>`
  - 現在のヘッドから新たにブランチを作ってチェックアウト
* `git diff`
  - コミット間/ファイル間の差分を確認
* `git add <FILE NAME>`
  - ファイルをコミット予定に入れる
  - 前述にありますが、「ステージする」「アドする/アッドする」 とか言います
* `git commit -m'<COMMIT MESSAGE>'`
  - インデックスにあるファイルを、指定したコミットメッセージを付けてコミット
  - -m'<COMMIT MESSAGE>'がない場合は、コミットメッセージ入力のため、コマンドライン上でエディタが起動します。viとかvimとかemacsとか
* `git push <origin> <BRANCH NAME>`
  - コミットをリモートに反映します
  - リモートが他で更新されていた場合、マージしろって怒られるので先に一度fetchなりpullなりしましょう


### たまにつかうコマンド

* `git checkout .`
  - いま編集しているやつを全部なかったことにして現在のブランチのヘッドに戻します
* `git stash save <STASH NAME>`
  - 一時的に作業中断して別ブランチを触りたい時、ファイルを退避させます。クイックセーブだね
  - 作業前にリモートをプルしてなかったとかいう恥ずかしいときにも使えます。コンフリクトに注意
* `git stash pop <STASH NAME>`
  - 上記で退避させたファイルを呼び戻します
* `git stash list`
  - 退避させたファイルのリストを表示。たまに退避させたことすら忘れますよね
* `git commit --amend`
  - コミットメッセージをtypoしたとか恥ずかしい時に使います
  - コミット漏れした時とかにも使います。コンパイル終わってなかった！とかたまにあるよね
* `git branch -m <NEW BRANCH NAME>`
  - ブランチ名をtypoしたとか恥ずかしい時に使います
* `git reset <COMMIT NUMBER>`
  - 間違ったコミットをしたとか、バグを**プッシュ前に**見つけたとか、恥ずかしい時に使います
  - もうプッシュしてたらやっちゃダメだよ

## 最後に
最初にも書きましたが、Gitを触りはじめた人や黒い画面が苦手でよくわかってない人が現場で作業する際、お作法がわかってなかったりする際に役立つことをまとめたつもりです。
足りない情報や正確性に欠ける部分があるかもしれません。ご指摘いただければ幸いです。
ScrollView内にConstraintLayoutを使用する際の注意点

#【概要】
LinearLayoutやFrameLayoutのようにConstraintLayoutもScrollViewの一番最初の子として追加することは可能です。

```xml
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="arara.com.testcodestyle.MainActivity">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="長い文字列..."
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>
    </android.support.constraint.ConstraintLayout>

</ScrollView>
```

しかし、通常はこれでスクローリングできるのですが、作っているアプリでAndroidの設定からフォントサイズを変更した場合に、Constraint内のViewが重なり合ったような状態で表示されてしまう現象に遭遇しました。

#【解決方法】
https://stackoverflow.com/a/48299530

ようは、上記で言うところの、`TextView`の`app:layout_constraintBottom_toBottomOf`が`parent`だと駄目だというもの。

今回は、これを使ってmarginをセットしていたので、`app:layout_constraintBottom_toBottomOf`を削除して、`ConstraintLayout`に対してpaddingをセットすることで対応しました。

ただ、上記のXMLではそもそも現象が再現しないので、「ScrollView内のConstraintLayoutに対してconstraintBottomでconstraintをつけた場合」というだけではなく、どうも再現には色々な条件があるようです・・・。
jCaptchaリロードをajaxで実装

# 環境
- windows7
- java7
- javaServerFaces2.2
- glassfish4.1

# やりたいこと
jcaptchaをリロードボタンクリックでajaxを利用して再描画
画面ごとリロードすればjcaptchaもリロードされるけど・・・

# 方法
## 成功例
```html:xhtml
<!-- jcaptcha表示部 -->
<div class="jcaptchaItemBlook">
　　<h:graphicImage id="jcaptchaImage" value="/jcaptcha" />
</div>

<!-- ajax実装部 -->
<h:commandButton class="jcaptchaReloadBtn" value="画像更新" immediate="true">
　　`<f:ajax listener="#{controller.reload}" render="jcaptchaImage" event="click" />
</h:commandButton>
```
```java:java
public String reload() throws CaptchaServiceException {
　　　　 return "#{request.contextPath}/jcapcha" + Math.floor(Math.random() * 100);
}
```

## 失敗例
```html:xhtml
<!-- jcaptcha表示部 -->
<div class="jcaptchaItemBlook">
　　<img id="jcaptchaImage"  src="#{request.contextPath}/jcaptcha" />
</div>
```
## 説明など
- 失敗例の記載以外の部分は、成功例と同様です。
- imgタグだとajaxの戻り値としてvalueを設定できなかったので、graphicImageを採用
- xhtml側のgraphicImageタグに"#{request.contextPath}/jcapcha"を設定すると、contextPathが2重に表示されたので削除
- java側は逆に戻り値として"#{request.contextPath}/jcapcha"をつけてあげる必要がある

# 事件発生！
- chromeでは問題なく動作するのに、FireFoxとIEではrefreshされないという問題がテスト時に発覚！

## 対応方法
```html:xhtml
<!-- jcaptcha表示部 -->
<div class="jcaptchaItemBlook">
　　<p:graphicImage id="jcaptchaImage" value="/jcaptcha" cache="false" />
</div>
```
- primeFacesのタグに変更する必要があった。
- cache="false"を追記する。


# 最終例
```html:xhtml
<!-- jcaptcha表示部 -->
<h:panelGroup class="jcaptchaItemBlook">
　　<p:graphicImage id="jcaptchaImage" value="/jcaptcha" cache="false" />
</h:panelGroup>

<!-- ajax実装部 -->
<h:commandButton class="jcaptchaReloadBtn" value="画像更新" immediate="true">
　　<f:ajax listener="#{controller.reload}" render="jcaptchaImage" event="click" />
</h:commandButton>
```
```java:java
@Getter
@Setter
private String captchaImage;
public void reload() throws CaptchaServiceException {
　　this.setCaptchaImage("/jcaptcha");
} 
```
- ajaxの基本どおりに戻り値をvoidにし、setterを利用するように変更。
- <div>だと微妙な気がしたので<h:panelGroup>に変更。
- getter/setter はlombok.jarを使用してます。


# jcaptcha実装についてはこちら
> http://d.hatena.ne.jp/kaiseh/20090502/1241286415
> http://www.in-vitro.jp/blog/index.cgi/Library/20050827_01.html

# 参考サイト
> https://yoshio3.com/2011/01/18/jsf-20-ajax-support/
> https://stackoverflow.com/questions/5822665/jcaptcha-refresh-only-image-not-whole-page

# 参考サイト②（事件発生解決）
> https://www.primefaces.org/docs/vdl/4.0/primefaces-p/graphicImage.html
> http://download.oracle.com/otn-pub/jcp/jsf-2.0-fr-eval-oth-JSpec/jsf-2_0-fr-spec.pdf
2Pカラーを効率的に変換しよう

動機
---------------------------------------
一般的にカラー変換はshaderを使って、runtimeで変換する
ただ、フレーム毎に変換するのは非効率と思います

もしカラー変換の結果をtextureに記録して、そのままモデルに使う
その方が効率的だと思います


カラー変換
---------------------------------------
カラー変換について、一般的なやり方は
まずRGBをHSVに変換して、そのあとHueを弄って、最後にRGBに戻る

HSVについてはこちらを参考にさせていただきました
[HSV](https://ja.wikipedia.org/wiki/HSV%E8%89%B2%E7%A9%BA%E9%96%93)


手順
---------------------------------------

1.textureのRGBを抽出して、HSVに変換したあと、新のtextureに保存する（以降、このtextureをHSVテクスチャと呼ぶ
<div class="code-frame" data-lang="hlsl"><div class="highlight"><pre><span></span>
// RGB空間をHSV空間へ変換する
// Alphaを変換maskとして記録する
Texture2D RGB2HSV(Texture2D fromRGB)
{
    int width  = fromRGB.width;
    int height = fromRGB.height;
    Texture2D toHSV = new Texture2D (width, height, TextureFormat.ARGB32, false);

        Color[] cols = fromRGB.GetPixels();
        for(int Indx = 0; Indx < cols.Length; ++Indx)
        {
            float h = 0f;
            float s = 0f;
            float v = 0f;

            Color.RGB2HSV(cols[Indx], out h, out s, out v);
            cols[Indx].r = h;
            cols[Indx].g = s;
            cols[Indx].b = v;
       }

       toHSV.SetPixels(cols);
       toHSV.Apply();
       return toHSV;
}
</pre></div></div>

[Color.RGB2HSV](https://docs.unity3d.com/ScriptReference/Color.RGBToHSV.html)はRGBをHSVに変換する関数、変換したHSVの値は正規化した値(0.0-1.0の範囲に)
そのままRGBチャンネルに記録できます

2.HSVテクスチャのRGBを抽出して、Rチャンネル(Hue)を変換する、そのあとRGBに戻る
<div class="code-frame" data-lang="hlsl"><div class="highlight"><pre><span></span>
// HSV空間をRGB空間へ変換する
// Alphaを変換maskとして使用する
Texture2D ChangeColor(Texture2D fromHSV, float diffHue)
{
    int width  = fromHSV.width;
    int height = fromHSV.height;
    Texture2D toRGB = new Texture2D (width, height, TextureFormat.ARGB32, false);

        Color[] cols = fromHSV.GetPixels();
        for(int Indx = 0; Indx < cols.Length; ++Indx)
        {
            float h = cols[Indx].r;
            if(0f < cols[Indx].a)
            {
                h += diffHue;
                h -= Mathf.Floor(h);
            }

            cols[Indx] = Color.HSVToRGB (h, cols[Indx].g, cols[Indx].b);
       }

       toRGB.SetPixels(cols);
       toRGB.Apply();
       return toRGB;
}
</pre></div></div>

結果
---------------------------------------
使用したモデルは[Goblin robber](https://assetstore.unity.com/packages/3d/characters/humanoids/goblin-robber-66959)

![ColorChange.gif](https://qiita-image-store.s3.amazonaws.com/0/235561/2c7f21f6-f057-18cd-00ad-3ad4863409ac.gif)
Spring-Boot メインクラスが見つからない

# 実行時にメインクラスが見つからない

gitから取り込んだSpring-Bootのプロジェクトを起動しようとすると以下のようなエラーが出ることがあった。

**エラー: メイン・クラス com.example.Hoge が見つからなかったかロードできませんでした**

# 原因

こちらで再現した原因としては以下の通り。

* Eclipse + STS Pluginで実装した環境でgitにアップ。
* STS（非Eclipseプラグイン）で上記を『既存プロジェクト』としてインポート。
    * .projectファイルはコピペで製造。

この方法だと見つからないエラーとなる。また、取り込んだプロジェクト上でクリーンビルドしようがMavenアップデートしようが解決しない。

# 対応

プロジェクトのインポートをSTSより以下の方法で行うと、正常に起動できた。

* パッケージエクスプローラ上を右クリック
* インポートを選択
* インポートウィザードからMavenを展開
* 既存Mavenプロジェクトで次へ
* ルートディレクトリーでgit cloneしたパッケージを選択

この後、（習慣的にMavenアップデート及びクリーンビルドを実施して）正常に起動した。
備忘録＆参考まで。
Googleスプレッドシートの処理遅延対策

GoogleAppsScript(GAS)で、スプレッドシートに記入する処理をする際、
記入したはずなのに印刷時に反映されてなかったりといった、
意図しない結果になることがあります。

これ、たとえば請求書を作ったとして、
宛名は正しいのに金額だけ前のまま、
というような、心臓に悪いバグの原因になります。
しかも発生したりしなかったり、中途半端に発生したりするので、
原因がわかりにくい。検索にも苦労したので以下にメモ。

対策として、下の一行を適宜挿入します。
スプレッドシートの再描画的な処理になるようです。
VBAの`DoEvents`的に挿入しておけばよいでしょうか。

```flush.js
SpreadsheetApp.flush(); // シートの再描画 
```
他に、処理を遅延させる方法として、

```sleep.js
Utilities.sleep(1000); // シートの処理完了を待つ 
```
も利用できます。単位はミリ秒。
VBAの`Application.Wait`やWindowsAPIの`Sleep`にあたります。
SQLSTATE[HY000]: General error: 3 Error writing file '/tmp/MLmffUHO' (Errcode: 28 - No space left on device)

#環境
* Amazon Linux AMI release 2017.03 
* 5.7.21-log MySQL Community Server (GPL)

#発生状況
SQLが実行されるページを表示

#今回の発生原因
MySQLのバイナリログが増えすぎてディスク容量が枯渇したため

#今回の解決策
MySQLのバイナリログを削除

#参考
https://dev.mysql.com/doc/refman/5.7/en/binary-log.html

#その他
エラーが解消されたら是非いいねお願いします
【2018年2月】忙しい人のためのPower BI Desktop Update

忙しい人のためのPower BI Desktop Update
2018年2月アップデート情報のぼく的まとめです。

![図1.png](https://qiita-image-store.s3.amazonaws.com/0/165789/f992b2ac-eb7c-b2da-9e8a-67c19077efb9.png)




# 注意事項

- このまとめは[PowerBI Blog(公式)](https://powerbi.microsoft.com/ja-jp/blog/)の内容を紹介しています
- 内容は、個人的に解釈や試行を加えています
- 英語が不自由なので、訳や意味などを間違えている可能性があります
- アップデート内容の網羅はしません。原則、「Reporting」と「Analytics」、一部の「Custom Visual」に絞ります
- **作成したところから順次公開します。**途中で挫折してたらスミマセン・・・(´・ω・｀)


# Reporting

## 複数チャートでのフィルタリング
<font color="#999999"><i>Multi-select data points across multiple charts</i></font>

レポート内の複数のチャートを使って、
フィルタリングができるようになりましたよーというお話。
ctrl + click で選択すると、そのフィルタがレポートに反映されるようです。

## 複数ページへのスライサーの同期
<font color=#999999"><i>Sync slicers across multiple pages of your report</i></font>

「Sync slicers」機能が追加。
複数ページにスライサーによるフィルタが反映されます。
待ってましたって感じですね。
Sync slicersはView tabから使えますよ。


## 数値スライサーの改善（プレビュー）
<font color=#999999"><i>Numeric range slicer improvement - whole number snapping(preview)</i></font>

数値スライサーの改善。
小数点は丸めちゃいますよ、ということでしょうかね。


## ジオコーディングの高速化（WEBプレビュー）
<font color=#999999"><i>Faster geocoding for Bing maps(web preview)</i></font>
ジオコーディング高速化するよー。というお話。
これ、現状ではDesktopは関係なく、Power BI Service の話みたいですね。

## チャート外へのデータラベル表示
<font color=#999999"><i>Overflow data labels for bar and column charts</i></font>
データラベル、今まではデータバーの中に納まりきらない場合は表示されないor外側に表示されましたが、
収まらなくても表示できるようになりましたー。

## 書式設定&分析ウインドウの検索
<font color=#999999"><i>Serch the formatting and analytics pane</i></font>
書式設定&分析ウインドウで、検索ボックスができましたー。というお話。
たくさん機能が追加されたもんね。
ただ、僕としてはこれ操作しにくいんだよなー。
他office製品と同じように、上部のリボンにならないかな？


# Analytics
## 日付テーブルのマーク
<font color=#999999"><i>Mark custom data tabel</i></font>
日付テーブルをマークして、日付階層やタイムインテリジェンスが使えるようになったよ。というお話。
ん？これ、今まで日付テーブル作ってリレーションはってたのと何か違いあるのかな？
すみませんが要検証案件です。。。

※以下、とても詳しく記事内で解説されていますー。
[・日付テーブルとしてマークする とは](https://qiita.com/PowerBIxyz/items/4b2b17a091bf7e8bfec6)


## クイックメジャーの一般機能化
<font color=#999999"><i>Quick measures are now generally available</i></font>
クイックメジャーがまだプレビューだったのに衝撃（笑）。
すっかり一般機能だと思い込んでました。

## DAX関数への追加［UTCNOW() and TUCTODAY()］
<font color=#999999"><i>UTCNOW() and UTCTODAY()</i></font>
DAXに、時刻表記に関する関数が２つ追加。
今までのNOW(),TODAY()関数だと、タイムゾーンが異なる人にファイルが渡ると時刻表記がずれちゃうので、協定世界時（UTC）を表示してくれる関数。
グローバルに活躍する人向きの関数ですねぇ。




# 終わりに
とりあえず走り書きレベルですみません。
英語が不自由な方のために早々にUPしました。
画像とかまた追加します。
が、ブログみてもらったほうがいいかもですね。

個人的には、カスタムビジュアルの[Network Visualaization and Filter](https://zoomcharts.com/en/microsoft-power-bi-custom-visuals/blog/introducing-network-chart-custom-visual-for-microsoft-power-bi)試したい！
ネットワーク系の可視化は面白そうですね。

# 過去Update記事

- [2018年1月](https://qiita.com/h_kobayashi1125/items/9eb4ac99b2f707364eab)

<br>
---

**正確な情報は、必ず公式ブログ等でご確認ください！**
[PowerBI Blog(公式)](https://powerbi.microsoft.com/ja-jp/blog/)
How to escape connection string in cx_Oracle SQLAlchemy

### How to escape connection string

 If database password contains special characters, connection string should be escaped as URLencode:


- NG

```
create_engine('oracle+cx_oracle://user:$$$$@host/database'))
```


- OK

```
create_engine('oracle+cx_oracle://user:%24%24%24%24@host/database')
```


or 

```
create_engine('oracle+cx_oracle://user:%s@host/database' % urlquote('$$$$'))
```

### References
https://stackoverflow.com/questions/1423804/writing-a-connection-string-when-password-contains-special-characters

http://docs.sqlalchemy.org/en/latest/core/engines.html
古いDjangoで書かれたものをVersionUpする。

1.4で書かれてたDjangoのプログラムを今のカタチにアップデートすることにしました。
目標は　Django　Version 1.4 →1.11 (Python2系の最終版ですかね)
作り直したほうが早いかもしれませんが、細かく丁寧に作られてて同じものを作るのが大変だと思ったため…。
色々悩みすぎて、うろ覚えです…。

#### 環境
ubuntu1604LTS
python2.7.12

### django 1.4 -> 1.6
・特に問題なく動いた。(とうろ覚え)

### django 1.6 -> 1.7 
・そもそも起動しない
→settings.pyにこれを記載したら警告が消えた。

```
import django

django.setup()
```
・Southの廃止。
→INSTALLED_APPSからsouthを削除。


・testで警告が出るように鳴った（新しいTest　runnerがあるよ。っていう警告みたいです。）

```
# python manage.py test
Creating test database for alias 'default'...
System check identified some issues:

WARNINGS:
?: (1_6.W001) Some project unittests may not execute as expected.
    HINT: Django 1.6 introduced a new default test runner. It looks like this project was generated using Django 1.5 or earlier. You should ensure your tests are all running & behaving as expected. See https://docs.djangoproject.com/en/dev/releases/1.6/#new-test-runner for more information.
System check identified some issues:
```
→settings.pyにこれを記載したら警告が消えた。

TEST_RUNNER = 'django.test.simple.DjangoTestSuiteRunner'
※こちらは1.11では不要な記載になるみたい。

・makemigrateでエラーが出る。
→APPPSのmigrationディレクトリの中のファイルを全て削除。
 `__init__.py` だけにする。
  ※以前の履歴でsouthが動いていた場合、makemigrateできないため。

### django 1.7 -> 1.8
settings.pyの中の書き方が変わった。
TEMPATE_DIR,TEMPLATE_LOADERSなごが廃止。
TAMPLATEに変わる。

こちらを参考にさせていただきました。
https://www.monotalk.xyz/blog/django-18%E3%81%8B%E3%82%89settingspy%E3%81%AEtemplates%E3%81%8C%E9%9D%9E%E6%8E%A8%E5%A5%A8%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E8%AD%A6%E5%91%8A%E3%81%8C%E5%87%BA%E5%8A%9B%E3%81%95%E3%82%8C%E3%82%8B/


### django 1.8 -> 1.9
忘れました…。

### django 1.9 -> 1.10
urls.pyやらsettings.pyの書き方が変わった
パラメータの記載が `（ ）丸括弧`ではなく`[ ]`

### django 1.10 -> 1.11
調査中
Celerydが動かない…。


全てDjangoは新規インストールです。
１．４で稼働中であれば、
`pip install -U Django==1.11`
でアップデートした場合、Djangoのほうで都合よく解釈してくれてるみたいで、
Settings.pyとかurls.pyは旧式の表記でも動作しました。

djangoはVersion1.7辺りから大幅に変わった印象。
django2.0はPython3.x系なので、知識が浅い自分にはこれ以上Versionを上げる時はすごい苦労しそう。

### django 1.11 -> 2.02

DjangoというよりPythonの話かもしれませんが軽くまとめてみます。
Python3系が基本になったのでPython２.7で好意的に解釈されてたものもエラーになったり
色々変わった印象。

①
`import commands`が廃止され、
`import subprocess`に統合された様子。

②自分で作ったモジュール（スクリプト）をインポートする際の記載が若干変わる。
同階層のスクリプトでも、パスを指定しないとだめになったみたいです。

旧：　`from cmd_exec import *` 
↓
新：　`from . import cmd_exec`　
こちらでもいけるみたいです。
`from .cmd_exec import *`

③Print文の書き方は変わりました。
・カッコが必要
旧：`print "\n".join(configs)`
↓
新：`print("\n".join(configs))`

・テキストの差し替え？にはformatが推奨されてるらしい。
旧：`print 'command execute "%s"' % (hostname)`
↓
新：`print("command execute {}".format(hostname))`

・try~exceptの書き方が若干かわる。

旧： `except Exception, exp:`
新： `except Exception as exp:`

③modelsの書き方
・ForeignKeyには `on_delete=models.CASCADE`オプションが必要。

```
     platform = models.ForeignKey(
        Platform,
        blank=False)
```
↓

```
     platform = models.ForeignKey(
        Platform,
        blank=False,
        on_delete=models.CASCADE,
        )
```

④urls.pyの書き方
adminサイトの書き方が若干かわったみたいです。
旧：　`url(r'^admin/', include(admin.site.urls)),`
↓
新：　`url(r'^admin/', admin.site.urls),`
Oracle オンライン再定義でハマった話（マテリアライズドビューの裏仕様）その2

#前回まで
こんにちは。前回はオンライン再定義を実施しようとしてハマったところまで書きました。
https://qiita.com/terry_carp/items/c12b0e771c2935c231fd
今回は、解決編です。

#高速リフレッシュの謎を解く
まず、なんでこれまで経験しなかったほど、
データ同期に時間がかかったのかを調べることにしました。
既に運用しているマテビューとオンライン再定義で作成されたマテビューを
データ同期する際に実行されているSQLを見てみたところ、以下の違いがありました。

##①既に運用しているマテビュー
　1. 溜まっているMLOGをSELECTする。
　2. 取得したレコードをベースにループし、
　　MLOGに記録されているDML_TYPE（UPDATE・INSERT・DELETE）に従い、
　　1件ずつUPDATE・INSERT・DELETEしていく。

##②オンライン再定義で作成されたマテビュー
　1. 溜まっているMLOGをSELECTする。
　2. 取得したレコードに該当するマテビュー上のレコードを一旦DELETEする。
　3. MLOGに記録されているDML_TYPEがUPDATE・INSERTのものをMERGE文でUPSERTする。

##時間がかかる理由
なるほど。。。
対象のテーブルはこれまでの数々のチューニングによりINDEXが乱立していたため、
マテビュー（当然コピーしているのでINDEXの数も同じ）からDELETEするのに時間がかかっていることが分かりました。
UPSERTもまあまあ時間がかかっていた。

##高速リフレッシュの裏（？）仕様
それと、どうやら高速リフレッシュの仕様として、
「マテビューがリモートにある場合」は①の方法でリフレッシュ
「マテビューがローカルにある場合」は②の方法でリフレッシュ
することが分かりました。

今回は既存のテーブルを置き換えるということでマテビューがローカルにあったので、
②の方法でリフレッシュされたという訳です。
このカラクリが分かったので、
マテビューがローカルにあるか、リモートにあるか以外の事はすべて同じ条件で、
高速リフレッシュを試したところ、
②では50分程度かかったものが、①では1分ちょっと。マジか！！！

#さて、どうするか？
上記のことが分かったので、どうにかこねくり回して①の方法実現したいところなのですが、
オンライン再定義パッケージはDB_LINK越しに使うことはできないので、
泣く泣く見送り。

ということで以下の手順を策定

①ローカルDBにループバックDB_LINKを張る。

②①で作成したDB_LINK越しに対象テーブルをマスタとしたマテビューを仮表として作成する。
（CREATE MATERIALIZED VIEWで作成、SELECT句に「ORDER BY CLIENT_ID」を付ける）

③②で作成したマテビューに元表と同じ制約・INDEXを作成する。
（制約やINDEX名は仮の名を付けておく）

④DBMS_MVIEW.REFRESHを5分毎に実行し、データ同期を行う。

（この間に一週間程度かけて、オンラインアプリで実行されるSQLを仮表に対して実行して実行計画に問題がないかを確認）

⑤仮表を実テーブル化する。
（DROP MATERIALIZED VIEWをPRESERVE TABLE句つきで実行）

⑥実テーブル化したテーブル・制約・INDEX名をリネーム

※⑤・⑥を実施するときはその後の関連作業があるため、サービス停止。

要はローカルにループバックDB_LINKを張って、
Oracleに「リモート越しにやってますよ～」と見せかけるということですね。

結果・・・うまくいった！

#まとめ
オンライン再定義（と同様の事）を行う場合の手法とそれぞれのメリデメは以下の通りです。
##オンライン再定義パッケージを使用
###メリット
 1. 作業者の手順が少なくて済む（これは結構デカいです）
 2. 事前にパラレル指定をしておけば、DBMS_REDEFINITION.START_REDEF_TABLE（初回のデータ同期）をパラレル実行できる。
 3. マスタテーブルにINDEXをあまり張っていない場合は、データ同期にも時間がかからない。 

###デメリット
 マスタテーブルに大量レコードを保持している
 かつ
 大量のINDEXが張ってあるテーブルの場合、
 データ同期（SYNC_INTERIM_TABLEまたはFINISH_REDEF_TABLE）の際に非常に時間がかかる恐れがある。
 ※個人的にはオンライン再定義したくなるテーブルはこれに当てはまることが多いと思っています。

##ループバックDB_LINK経由でMVIEW作成→実テーブル化
###メリット
大量レコードかつ大量のINDEXが張ってあるテーブルの場合でも、
高速リフレッシュ（DBMS_MVIEW.REFRESH）を短時間で完了できる可能性が高い。

###デメリット###
1. CREATE MATERIALIZED VIEW（初回のデータ同期）をパラレル実行できない。（DB_LINK経由なので）
2. 作業者の手順が多くなるので、作業者の負担が高い。
3. 作業ミスのポイントも増える。

まとめると、
「オンライン再定義パッケージ」はとても便利な機能ではあります。
しかし、オンライン再定義をしたくなるテーブルは、
長年の技術的負債が溜まっているような状態になっている場合が多いと思われ、
そのようなテーブルには向いていないという矛盾した課題を抱えています。
その場合は、「ループバックDB_LINK経由でMVIEW作成→実テーブル化」で代用することが可能。
ということになります。

長文、駄文失礼いたしました！
K-NOMPの証明書周りでハマった話

K-NOMPのWebページをhttps対応にすべく、Let's encryptを用いて証明書を生成。
そのままconfig.jsonにkey/certの位置を流し込み、ブラウザからの接続はok。

```json
"tlsOptions" : {
    "enabled": true,
    "key":"/etc/letsencrypt/live/example.net/privkey.pem",
    "cert":"/etc/letsencrypt/live/example.net/cert.pem"
}
```

と思っていたが、wgetやcurlからのアクセスが弾かれる

```
$ wget https://example.net/api/stats
--2018-02-07 04:02:34--  https://example.net/api/stats
Resolving example.net (example.net)... 101.x.y.z
Connecting to example.net (example.net)|101.x.y.z|:443... connected.
ERROR: cannot verify example.net's certificate, issued by ‘CN=Let's Encrypt Authority X3,O=Let's Encrypt,C=US’:
  Unable to locally verify the issuer's authority.
To connect to example.net insecurely, use `--no-check-certificate'.
```

certに指定すべきは`cert.pem`ではなく`fullchain.pem`だったようです。おわり
ログ確認ことはじめ（Apache編）

アクセスやらエラーを調査する際に使える（かもしれない）コマンド群です。
今回はApache編ですが、もちろん他ログでも使用できます。

>**■特定IPが記されている行だけ抽出**
zgrep "192.168.XXX.XXX" ssl_request_log*

>**■特定IPを複数指定する場合**
zgrep "192.168.XXX.XXX\|192.168.XXX.YYY" ssl_request_log*

>**■特定IPかつPOST以外の接続方法でアクセスした行を抽出したい場合**
zgrep "192.168.XXX.XXX" ssl_request_log* | grep -v "POST"

>**■特定IPのアクセス状況をリストアップする場合**
zgrep "192.168.XXX.XXX" ssl_request_log* > ./list.txt

>**■上司に*"先月の10～11時台のアクセス状況を日毎に出して～"*と言われた場合**
zgrep "Jan/2018:10\|Jan/2018:11" ssl_request_log*



zgrepを使用することで、logrotateで圧縮されたログからも解凍する事なく抽出できるので便利です。
Oracle オンライン再定義でハマった話（マテリアライズドビューの裏仕様）その１

#はじめに
こんにちは。
今回は、Oracle（11gR2）が提供している、オンライン再定義パッケージ（DBMS_REDEFINITINONパッケージ）を使って、
ハマった話と、ハマってる最中に知ったマテリアライズドビューの裏仕様について語りたいと思います。
ハマっていた時にこのあたりの情報がネット上にまるでなかったので、
同じようにハマっている方が世にいればその助けになればと思います。

#やろうとしたこと
私が担当しているシステムでは長年の運用によってデータ量が肥大してしまい、
オンラインアプリのパフォーマンスが劣化してしまっていました。
DBMS_REDEFINITINONパッケージを使い、とあるキー（仮にCLIENT_IDとします）で並び変えて再定義すると、
「パフォーマンスが大幅に向上するぜ！」とDBAさんから提案を受けたので、
「よっしゃ！やりましょう」となりました。
（オンラインアプリで使用しているSQLの大半はCLIENT_IDを検索キーとして使用しているので、
同一CLIEND_IDのレコードを近いブロックに寄せておくことで、検索時の読み取りブロック数を減らすという目論み）

#私たちが立てたの再定義の大まかな手順
①DBMS_REDEFINITION.CAN_REDEF_TABLEで対象のテーブルがオンライン再定義が可能か確認する。

②DBMS_REDEFINITION.START_REDEF_TABLEで対象のテーブルの仮表を作成してデータコピーする。
（この時にオプションを指定してCLIENT_ID順に並び替える）

③DBMS_REDEFINITION.COPY_TABLE_DEPENDENTSで対象のテーブルの依存オブジェクト（制約やインデックスなど）を仮表にコピーする。

④DBMS_REDEFINITION.SYNC_INTERIM_TABLEで15分毎に適宜、対象のテーブルから仮表へデータ同期を行う。
（この間に一週間程度かけて、オンラインアプリで実行されるSQLを仮表に対して実行して実行計画に問題がないかを確認）

⑤DBMS_REDEFINITION.FINISH_REDEF_TABLEで元表と仮表の名前を入れ替えてオンライン再定義を完了させる。

※⑤を実施するときはその後の関連作業があるため、サービス停止。
（この時点で「オンライン再定義」ではないですがｗ）

#仮表はマテリアライズドビューとして作成される
DBMS_REDEFINITION.START_REDEF_TABLEで作成された仮表はマテリアライズドビュー（以下マテビュー）として作成されます。
そして、DBMS_REDEFINITION.SYNC_INTERIM_TABLEで実施されるデータ同期は
マテリアライズドビューの高速リフレッシュと同じ仕組みのようです。

#マテリアライズドビューは現システムで運用実績あり！しかしデータ同期でハマる！
オンライン再定義の対象としていたテーブルは、今回4テーブルだったのですが、
全て、これらのテーブルをマスタ表とするマテビューを作成していて、
日々の高速リフレッシュを含めた運用実績があったため、
オンライン再定義中のデータ同期も問題なく終わると思ってました。
しかし、当日、落とし穴が待っていました。。。
手順の①～③までは順調に消化、一回手動で「DBMS_REDEFINITION.SYNC_INTERIM_TABLE」実行してみることになりました。
このとき溜まっていたマテリアライズドビュー・ログ（以下MLOG）は15,000件程度、
これまでの経験から、「まあ、1分くらいで終わるっしょ！」と
タカをくくっていましたが、終わらない。。。
結局、完了するのに30分かかりました。

先程お話しした通り、対象のテーブルをマテビューで他システムに連携している関係上、
限られた時間の中でオンライン再定義完了→他システムのマテビューの再作成を行わなければならないため、
この同期にかかる時間は死活問題で、この程度の件数でこんな時間かかってしまっては。。。
ということでオンライン再定義計画は頓挫してしまいました。。。
（次回に続く）
https://qiita.com/terry_carp/items/93a6c0f911fae1e9960a
Cognos Analytics でリスト列タイトルを自由に表現する

#概要
リストのタイトルをこんな感じに、階層化してみたり、マージしてみたり、基準値行を書いてみたり、というやり方です。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/4efd8a27-0119-bd6f-d58c-77f0f5f45cee.png)

#手順
まずは普通にリストを作成し、データアイテムを置きます。
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/7f376448-3d2b-b165-a54c-3c2485604e77.png)

適当なセルをクリックし「・・・」⇒「ヘッダーとフッター」⇒「リストのヘッダーとフッター」を選択。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/5fe0d2e2-c32b-e91e-f3a0-2dda1f3fab67.png)

リストのページ・ヘッダーをチェックしOK。
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/d1f92264-6621-ed24-ffa6-fc397b70a5be.png)

追加された「リストのページ・ヘッダー」をクリックし「リストの行のセルを上に挿入」を選択。
![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/e5c6c115-0270-17a0-1f4e-fef194fc105a.png)

2行指定しOK。
![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/8a4e4bcb-3442-8d7f-c647-4648f8002a8b.png)

同様にヘッダーの下にも1行追加。
![007.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/05d94500-ec25-2946-9851-74b6a75e616a.png)

Ctrlボタンを押しながら、元々のセルタイトルをクリックし、プロパティからボックスのタイプ「なし」を選択。
![008.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/27097f4b-54da-dcda-fabb-60bdef23ed4d.png)

「リストのページ・ヘッダー」を選択し、「セルを分割」
![009.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/abc06d66-2935-25c7-7cf0-3a1542c4fe1e.png)

「セルの結合」「セルの分割」を使って、形を整えていく。
※横のセル同士は結合可能ですが、縦のセル同士は結合できません。
![010.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/fd76990e-6f21-9eb6-a622-04b63e39ddce.png)

セルに文字を書きたい時は、「アンロック」しておいて
![011.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/d9bb1cc7-ad8a-a333-12fb-1dd1c77892fe.png)

「テキスト・アイテム」をセルに配置して、記載します。
![012.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/311403bc-8688-5f29-02c8-67bef6c8b02b.png)

後は各セルのプロパティの「境界線」と「背景色」で見た目を整えていけば。
![013.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/8b3d0fb2-3872-4b66-146f-098bea26cbe1.png)

完成！
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/a0fa8509-7ab2-9eb0-fc4e-91db57cad004.png)

良く使うと思いますが、ふっと手順忘れたりするので投稿しておきました。
ご活用下さい。
Windows10端末にAzure Functions CLIをインストール

Azure Functions CLIをインストールします。

#環境
Windows10：1703(OSビルド 15063.850)
Node：v8.9.4
npm：5.6.0
Nodeとnpmが入ってない場合は[この手順](https://qiita.com/taketakekaho/items/9710294c6f3c46ee6024)実施

#手順
[ここ](https://www.npmjs.com/package/azure-functions-cli)にある手順やります。

######インストール
```:cmd.exe
>npm i -g azure-functions-cli
```

```:出力メッセージ
npm WARN deprecated azure-functions-cli@1.0.0-beta.94: WARNING: This package has been renamed to azure-functions-core-tools. See https://github.com/Azure/azure-functions-cli/issues/92 for more info
C:\Users\kahori_takeda\AppData\Roaming\npm\azurefunctions -> C:\Users\kahori_takeda\AppData\Roaming\npm\node_modules\azure-functions-cli\lib\main.js
C:\Users\kahori_takeda\AppData\Roaming\npm\func -> C:\Users\kahori_takeda\AppData\Roaming\npm\node_modules\azure-functions-cli\lib\main.js
C:\Users\kahori_takeda\AppData\Roaming\npm\azfun -> C:\Users\kahori_takeda\AppData\Roaming\npm\node_modules\azure-functions-cli\lib\main.js
+ azure-functions-cli@1.0.0-beta.94
added 1 package in 13.617s
```

######エイリアス設定
```:cmd.exe
>func
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/a3a463ca-0fa6-b271-4232-82142040cb7b.png)

```:cmd.exe
>azfun
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178016/95ffb2cf-41f9-08bb-6051-9960ee59a146.png)

あとは細かい設定っぽいので…とりあえずここまででよい気がする。
Node.jsで単体testを書く際に，モジュールをstubに置き換える

テスト対象関数で`require()`が使われていて，どうにかして置き換えたい時があります

本来ならtestし易いように関数の構成を変更してstubを使えばいいと思いますが，
諸事情あって中のソースは変更しないでテストをする　ということをしました．

方法としては`require`をフックする　ということをします


## 書いたコード
```javascript

var moduleStubs = {};
var originalJsLoader = require.extensions['.js'];

var stubOnModule = function(module) {
  var path          = require.resolve(module);
  var stub           = sinon.stub();
  moduleStubs[path] = stub;
  delete require.cache[path];
  return stub;
};

require.extensions['.js'] = function (obj, path) {
  if (moduleStubs[path])
    obj.exports = moduleStubs[path];
  else
    return originalJsLoader(obj, path);
};

afterEach(function() {
  for (var path in moduleStubs) {
    delete moduleStubs[path];
  }
});



```

requireモジュールの中身にあまり詳しくないですが，どうやら`require.cache[path]`に
キャッシュがあるようなのでそれを削除し，
requireでjsファイルが呼ばれたらキャッシュしてあったstubを返すようにしています

`afterEach`に関してはmochaでテスト完了後に毎回stubを直す処理を書いています，．

## 使い方

`stubOnModule(“ws”);` とテストの最初にかけば，その後呼ばれるrequire(‘ws’)はstubに置き換わります．

あくまでstubへの置き換えだけなので，new や 下位pathへのアクセスをされるとプロパティがなくてエラーになります

```javascript

it('test', function(){
  stubOnModule("module");

  var m = require("module"); //return stub

  var instance = new m(); // OK
  var value = m.b; // ok
  
  m.a(); // error : m.a is not a function
  var value = m.c.d; // error : Cannot read property 'd' of undefined
  var instance2 = new m.A({}); // error : ws.Server is not a constructor
  
});


```

その場合は，一つ一つstubにしてあげましょう

```javascript

it('test', function(){
  var stub = stubOnModule("module");
  stub.a = sinon.stub();
  stub.c = sinon.stub();
  stub.c.d = sinon.stub();
  stub.A = sinon.stub();

  var m = require("module"); //return stub

  
  m.a(); // error : m.a is not a function
  var value = m.c.d; // error : Cannot read property 'd' of undefined
  var instance2 = new m.A({}); // error : m.A is not a constructor
  
});


```



## 参考
https://stackoverflow.com/questions/6997459/how-to-stub-require-expect-calls-to-the-root-function-of-a-module