OmniAICreator/Qiita-1.07M huggingface dataset:
nuxtプロジェクトでnetlify-lambdaを利用する

## TL;DR

- nuxtのプロキシモジュールを使う : [@nuxtjs/proxy](https://github.com/nuxt-community/proxy-module)
- proxy の設定は [netlify-lambda](https://github.com/netlify/netlify-lambda) 参照

```js
// nuxt.config.js
module.exports = {
  modules: [
    '@nuxtjs/proxy'
  ],
  proxy: {
    '/.netlify': {
      target: 'http://localhost:9000',
      pathRewrite: { '^/.netlify/functions': '' }
    }
  }
};
```

## まえおき : netlify-lambda について

[netlify](https://www.netlify.com/) は簡単にデプロイできて、ビルドもしてくれて、おまけに [functions](https://www.netlify.com/docs/functions/) で AWS lambda をプロキシしてくれて、非常に助かっています。そんな **netlify functions** で開発をすすめるのにとても便利なパッケージが [netlify-lambda](https://github.com/netlify/netlify-lambda) です。

netlify-lambda は、

- `netlify-lambda serve` でローカル開発
- `netlify-lambda build` でlambda関数のビルド

をすることができる便利なパッケージです。使い方については [パッケージのREADME](https://github.com/netlify/netlify-lambda) をご覧いただくとして、 `netlify-lambda serve` を使う上で一点留意事項があります。

### netlify-lambda のパス

`netlify-lambda serve` をすると、lambda関数を `localhost:9000` でサーブするようになります。たとえば、 `hello.js` というファイルを作成すると、その関数へ `http://localhost:9000/hello` でアクセス出来るようになる寸法です。

しかし、 netlify 環境へデプロイした際には、 function へのアクセスパスは `/.netlify/functions/` になります。

- ローカル（netlify-lambda）でのパス : `/hello`
- リモート（netlify）でのパス : `/.netlify/functions/hello`

この差異を解決する為に、プロキシ機能を使う事が推奨されています。README にある webpack　debserver での例はこの様になっています。

```js

module.exports = {
  mode: "development",
  devServer: {
    proxy: {
      "/.netlify": {
        target: "http://localhost:9000",
        pathRewrite: { "^/.netlify/functions": "" }
      }
    }
  }
};
```

これで、 webpack debserver のアクセスをプロキシして、 `http://localhost:8080/.netlify/functions/hello` へのアクセスは、 `http://localhost:9000/hello` へとパスされる仕組みです。便利ですね。

長い前置きおわり。


## Nuxtプロジェクトで netlify-lambda

さて、デプロイと同時にビルドしてくれる netlify は nuxt と親和性が高いと考えるのですが、nuxt の場合は functions のプロキシはどうしたらよいでしょうか。

答えは簡単で、nuxt からもプロキシモジュールが出ています。 [@nuxtjs/proxy](https://github.com/nuxt-community/proxy-module#readme) です。

まずはプロキシモジュールをインストールし、

```
npm i @nuxtjs/proxy --save-dev
```

nuxt.config.js を編集して `modules` への追加と `proxy` の追加を施します。

```js
// nuxt.config.js
module.exports = {
  modules: [
    '@nuxtjs/proxy'
  ],
  proxy: {
    '/.netlify': {
      target: 'http://localhost:9000',
      pathRewrite: { '^/.netlify/functions': '' }
    }
  }
};
```

これでOKです。あとは `nuxt` の実行と一緒に `netlify-lambda serve` も起動してやれば、期待する働きをしてくれるでしょう。

```json
{
  "scripts": {
    "dev": "nuxt & netlify-lambda serve functions"
  }
}
```

前置きの方が長いですが、現場からは以上です。
【GCP】App Engine スタンダード環境とフレキシブル環境

##AppEngine
GCPには仮想マシンをベースに構築するCompute Engine、コンテナをベースに構築するKubernetes Engine。
それらのサービスに対し、開発者がコードのみに集中できるのがApp Engine。
どういうことかと言うと、SQLデータベース、インメモリキャッシュ、負荷分散、ヘルスチェックなどがすでに組み込まれており、
インフラストラクチャを気にすることなく、開発ができるということ。
用意されている実行環境は「スタンダード環境」と「フレキシブル環境」

##スタンダード環境
- ローカルディスクへの書き込みは不可。
- サードパーティ製のソフトウェアはインストール不可。
- フレキシブル環境よりインスタンスを速く開始できる。
- アプリが完全にアイドル状態であれば料金が発生しない。
- 対応言語に制限あり。（以下参照）
 - Java
 - Python
 - PHP
 - Go

##フレキシブル環境
- ローカルディスクへの書き込み可能。
- サードパーティ製のソフトウェアのインストールが可能。
- Compute Engineの仮想マシン上のDockerコンテナで実行される。
 - 稼働する地域を選択可能。
 - CPUやメモリの制限はほぼない。
 - 後方互換性の重要なアップデートがOSに自動的に適用される。
- 仮想マシンにSSHで通信可能。
VS CodeでPython環境を整える

２番、３番といわず１００番煎じくらいですが、VS CodeでPython環境を整えていきたいと思います。
バージョンごとにちょっと違っていることもあると思うので、今時点で最新の情報に基づいて新たにメモを記す価値はあると願ってます。

参考サイト：[Getting Started with Python in VS Code(VS Code公式チュートリアル)」](https://code.visualstudio.com/docs/python/python-tutorial)

 ## 環境
* Windows 10 Home
* Visual Studio Code v1.29
* Pythonは全く入れていない状況からのスタート

## Python(Windows)のインストール
ここでは、特定バージョンのpythonを単体でインストールし、必要なライブラリは都度pip installする場合の手順を記載しています。
複数バージョンのPythonを同居させる必要のある方や、Pythonと一緒に主要なライブラリがパッケージ化されたものを使いたい場合は、pyenvやAnaconda等、お好きなものをご利用ください。

1. [Python.orgのダウンロードページ](https://www.python.org/downloads/)からPython 3系の最新バイナリ(今回は3.7.1)をダウンロード<br>Windowsインストーラー版なら、pipも一緒に入ります。

2. 複数のPython環境を同居させている方を除き、Windowsの場合、インストール時にPATHを追加してしまうと楽です。<br>最初の画面で、「Add Python 3.7 To Path」を選択しておくと、pythonコマンドにpathが通ります。
![python.png](https://qiita-image-store.s3.amazonaws.com/0/321544/26612583-4b38-2359-b212-c86f8bcad221.png)
※インストーラーの最後に、Windows 10から260文字のファイルパス長の上限を解除できるようになったので、それを解除(Disable path length limit)するか聞かれます。長いファイルパスになりうるか必要に応じて解除してください。

3. pipを最新化して、最低限Python Extensions for VS Codeに必要なライブラリを入れておきます。<br>(2でpythonにpathを通したあとVS Codeを再起動して、VS Codeのメニューから新規ターミナルを開く)

```
python -m pip install --upgrade pip
pip install pylint
pip install yapf   ※またはautopep8、Blackのうち好きなもの。いずれもコードの整形に使う
```

## Visual Studio CodeにPython系のExtensionを入れる
メモ帳とコマンドプロンプトでPythonの開発するノリであれば、Extensionは何もいりませんが、せっかくなのでシンタックスエラーやLintがでるように、Extensionを入れたほうがいいと思います。

1. Extensions画面からPython for VS Code(Microsoft提供)を選択してinstallします。

2. pythonのパスを聞かれた場合は、先にインストールしたパスを指定します。

## 試しにPythonスクリプトを書いてみる
1. VS Codeのメニューから「フォルダを開く」を選択し、任意のフォルダを指定します。
2. 同じくメニューから「新規ファイル」を選択し、test.pyなどのファイル名を付けます。<br>拡張子から自動的にpythonスクリプトと認識されます。
3. 何か適当なコードを書きます。

```Python:test.py
if True:
    print('Hello world')
```

4. VS Codeのターミナル(開いてなければメニューから「新規ターミナル」を開きます)で実行してみます。

```terminal:ターミナル
PS C:\test>  python test.py
Hello world
```

これで最低限、pythonを快適に編集できるようになったと思います。
Slackでjoinしている231チャンネルを余すことなく見たい人生だった

この記事は**『[Slack Advent Calendar 2018](https://qiita.com/advent-calendar/2018/slack)』**の3日目の記事です。

## どういうわけか？: joinしすぎて見れない問題

皆さんSlackは活用していますか？　僕はSlackがとっても好きです！
チャットツールとしての基本を抑えているのはもちろんのこと、
様々なインテグレーションツールが利用できることや、
何よりAPIを使うことで自分好みの様々なツールやbotが作成できる点が
とても便利＆楽しいと感じています。

……が、その反面、いろんなチャンネルの話題を見たい！と思っていると、
気づいたらjoinしているチャンネル数が増えてしまうことがあります。

僕の入っているSlackチームには公開チャンネルだけで6000チャンネルくらいあるので、
その中から業務に関係あるもの、ちょっと興味があるものにjoinするだけでも
チャンネル数が軽く200を超えてしまったりします＞＜；

さすがにこれを全部じっくり見ていたら時間が無くなってしまうので、
普段は大半のチャンネルをミュートにしているのですが、
じっくり見ないにしてもなんとなく雰囲気は感じていたいな……と思ってしまいます。

## そうだ、ターミナルに全部流そう

昔、 IRC を使っていたときは LimeChat の下部分に
「全チャンネルの発言が表示される領域」があったため、僕はそれを活用していました。

あの体験ができれば今の僕の悩みも解決できるのでは！？と思い、
ちょっと前にペライチのRubyコードを書いて運用をしてみたところ
かなり僕の生活が豊かになりました！

せっかくなので自分用コードのまま眠らせず、お外に出してしまおう！ということで
今回ちょっとコードを整理したので紹介させていただきます。

## Senrigan : Slackの発言をターミナルに流すやつ

![senrigan.jpg](https://qiita-image-store.s3.amazonaws.com/0/25109/2eee8dfc-bb19-dbfb-0cc4-345894f8465b.jpeg)

- https://github.com/rutan/senrigan

Senriganは指定のチームで自分がjoinしているチャンネルの発言を
チャンネルの区別をすることなく、ターミナルに垂れ流すツールです。

「それってターミナル向けのSlackクライアントと違うの？」と思われるかもですが、
Senriganは投稿系の機能がなく、ただただログを表示するように
joinしている全チャンネルのログを流すだけのツールになっています。

Rubygemsとして作成しているので `gem install senrigan` でインストールできます。

```bash
$ gem install senrigan

$ SLACK_TOKEN='ここにキミのlegacy tokenを入れよう' senrigan
```

### なかみ

[slack-ruby-client](https://github.com/slack-ruby/slack-ruby-client) でSlack の Real Time Messaging API に接続し、
そこから送られてくるメッセージイベントの内容を解釈して、それっぽい色をつけて表示します。
シェルの色のコマンド覚えられないので、色付けには[colorize](https://github.com/fazibear/colorize)を使っています＞＜；

### 対応しているメッセージ

- 普通のメッセージ
- Attachment
- 編集（Edited）された通知

Editedを表示する機能は僕的にはとても便利で、
面白いことを言った後にすぐ消しちゃう人にも対応することができます。べんり。

ところで、SlackのMarkdownっぽいやつは、
パースの方法が極めて難解であることで有名です。
<img width="356" alt="難解な例" src="https://qiita-image-store.s3.amazonaws.com/0/25109/61878e00-c71a-0aa4-e3f6-a44bbec297ac.png">

- 参考: [Togetter的な社内Slackまとめサイトをつくった話](https://qiita.com/ru_shalm/items/32160b23df535ed78967#slack%E3%81%AEapi%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%81%8C%E9%9B%A3%E8%A7%A3%E9%81%8E%E3%81%8E%E3%82%8B)

ターミナル表示なのであんまり頑張る必要はないのですが、
さすがにユーザー名が `<@U123456>` とかなってたら何のこっちゃなので、
そのあたりの最低限の置換はやった上で表示しています。
（でも僕が知らない機能もたくさんあるので、まだまだ足りないかも…）

### なお、絵文字は…

~~諦めよう~~

macとかで表示できる普通の絵文字はなるべく対応したい気もするので、
[gemoji](https://github.com/github/gemoji) をつかって、文中の `:〜:` な部分を可能な限り絵文字に置き換えて表示しています。

```ruby
require 'gemoji'

emoji = Emoji.find_by_alias('smile')
emoji.raw # => 😄
```

でも gemoji は `🤔` のエイリアスが `thinking` なので、 
Slackの `:thinking_face:` は引っかからないんですよね……
ちゃんとやるなら、Slack用のエイリアス表が必要だ＞＜

## まとめ

僕がSlackを楽しむためにつくった＆使っているツールである Senrigan を紹介しました。

おそらくSlackは様々な使われ方をしていると感じており、
きっと各チームごとの特性に合わせた秘密のツールとかもたくさんあるんじゃないかなぁと思っています。

この AdventCalendar でもそういったツールの片鱗が見えたりするかもしれませんね٩(๑❛ᴗ❛๑)۶
PowerShellを弄るときは & 演算子を使う書き方を覚えておくと便利かも

本エントリは[PowerShell Advent Claendar 2018](https://qiita.com/advent-calendar/2018/powershell) の3日目の記事です。

簡単な Tips を共有するだけで良いとのことなので小ネタを投下します。

適切なタイトルが思い浮かばなかったので適当ですが Advent Claendar は惰性で追うものなので問題無いと思います。

これまでコマンドプロンプトや Bash で生きてきた人たちがギョームで PowerShell を触っているのを見ていると、配列の引数を渡すときに以下のような書き方をされることが多いと思います。

```powershell
Verb-Noun1 $hoge, $fuga, $piyo, $moge
```

やりたい処理がコマンド一発で終わるのであれば、この書き方で問題ないと思います。

ところが、たいていの場合は実行したいことは増えます。仕事は増えるものです。
素直に対応すると以下のようになります。

```powershell
Verb-Noun1 $hoge, $fuga, $piyo, $moge
Verb-Noun2 $hoge, $fuga, $piyo, $moge
```

分かりやすいかもしれませんが、冗長さがイケてないですね。
PowerShell に慣れてくると以下のような書き方になってきます。

```powershell
$hoge, $fuga, $piyo, $moge | Foreach-Object {
    Verb-Noun1 $_
    Verb-Noun2 $_
}
```

PowerShell で繰り返し処理を書くときは Foreach-Object ですね。余談ですが、この ScriptBlock の書き方に抵抗を感じる人が多いみたいです。これも特に問題ありません。もしかすると繰り返しのオーバーヘッドがあって前の処理より遅いかもしれませんが、冗長性はなくなりました。

ところが、試行錯誤の中では引数の方が増減することがあります。また、バッチ処理がコケて一部だけ手作業でリトライするようなシチュエーションもあります。このようなとき「一部の引数だけ消して、カンマの位置にも気をつけながらスクリプトを修正」という作業は、わりとストレスフルです。

理由付けに無理やり感がありますが、結論として私が個人的に推奨する書き方は以下のような感じです。

```powershell
& {
    $hoge
    $fuga
    $piyo
    $moge
} | Foreach-Object {
    Verb-Noun1 $_
    Verb-Noun2 $_
}
```

& 演算子は、後ろの式(この場合は ScriptBlock)を評価する演算子です。カンマが無くなったので引数が増減したときの微妙なストレスから解放されて嬉しいですね。処理 or 引数を部分的に省略するときもコメントアウトするだけなので楽になりました。diff も綺麗に取れるので VCS との相性も良い気がしています。

以上、PowerShell で何か弄くり回すときに便利な書き方でした。
超入門！slackのスラッシュコマンド をカスタマイズ。

※この記事は＜ストーリー編＞と＜論理編＞に分かれております。諸事情により詳しい技術のお話は別記事にまとめたいと思います。（じ、時間がなかったわけじゃないんだからね！）
##＜ストーリー編＞
どうも、おはこんばんにちわ！
みなさん社内のチャットツールは何を使っていますか？

僕が所属する会社では、"slack"です。
![slack.png](https://qiita-image-store.s3.amazonaws.com/0/264568/ddf81faa-0d14-1bba-cc27-d983bb60742d.png)
slackを使っているIT企業は多いのではないでしょうか。

そんなslackを使う中で、常日頃から不便に感じていた問題がありました。

それは、「チャンネルに複数のメンバーを招待するのがめんどくさい」問題です。

数人ならまだ良いのですが、僕たちは業務上、新しいチャンネルを作り、そこに40人くらいのメンバーを招待するという作業を、頻繁に行います。

この40人の招待が、めちゃくちゃ面倒くさい。
一般的な招待の仕方は、下記のような画面で、一人一人検索して招待するのですが、
<img width="1373" alt="スクリーンショット 2018-12-02 22.28.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/264568/5b31b8c1-93bc-e3e1-0897-1820740fcad2.png">

なぜか検索に引っかからない人もいるんですね🤔
なぜなんだ。。。

この作業にかかる時間とストレスを、削減するための結論が、
「そうや！スラッシュコマンドや。あれをカスタマイズして、コマンド１つで任意のメンバーを全員招待できるようにしよう。」
です。

#＜論理編＞
ここからは、実際に僕が、スラッシュコマンドをにカスタマイズした、手順と考え方についてです。
僕は本当に何もわからなかったので、とても苦戦しました。

簡単にまとめると、
①slack api を使いslack側にアプリを作成。どのワークスペースに結びつけるかもこの時。
②今度は、slackの外に、実際にスラッシュコマンドを打った時に、動く肝心のアプリを作る。
③slack apiに戻り、何というスラッシュコマンドを叩いた時に、どのアプリにアクセスするかを設定。
→完成！


という流れです。

①については、下記の記事を参考に作りました。
https://qiita.com/t-mimura/items/d6541ec596bdebea5a7b　

slackにはデフォルトで、スラッシュコマンド が複数用意されていますが、
さらに、カスタムしやすいように、「slack api」 というgemがあり、これをインストールすると、便利なメソッドがたくさん使えるようになります。
それらは②の工程で使うことになるでしょう。

今回僕が使ったのは、.users_list や　.groups_invite　です。
まず、 .users_listで全ユーザー情報を集め、その中で該当するユーザーだけ取得します。
プライベートチャンネルに複数人招待するメソッドが .groups_invite　になります。
.groups_inviteを使い、任意のユーザーをプライベートチャンネルに一度に招待可能というわけです。

どうですか？簡単に聞こえますよね。
ちなみに僕はわからなすぎて、形になるまでに１ヶ月くらいはかかりました。死

次回、「具体的なコードはこう書いた！」お楽しみに！！！！！
C（とか）で四則演算の結果すら合わない

...という恥ずかしい検索を仕事中にテンパってやってしまった話。

# 実際にやらかしたミス
### コード
```c++:before.cpp
#include <iostream>

#define IMAGE_HEIGHT 40
#define IMAGE_WIDTH 30
#define IMAGE_SIZE IMAGE_HEIGHT * IMAGE_WIDTH

#define BLOCK_HEIGHT 4
#define BLOCK_WIDTH 3
#define BLOCK_SIZE BLOCK_HEIGHT * BLOCK_WIDTH

int main(){
    std::cout << "image size: " << IMAGE_SIZE << std::endl;
    std::cout << "block size: " << BLOCK_SIZE << std::endl;
    std::cout << "# of blocks in a image: " << (IMAGE_SIZE / BLOCK_SIZE) << std::endl;
	return 0;
}
```
### 出力
```
image size: 1200
block size: 1200
# of blocks in a image: 900
```
# （とりあえずの）修正
### コード
`#define`がやってるのは文字列置換なのでカッコを明記する。**(thx. toori様)**
* 修正前：`IMAGE_HEIGHT * IMAGE_WIDTH / BLOCK_HEIGHT * BLOCK_WIDTH`
* 修正後：`((IMAGE_HEIGHT) * (IMAGE_WIDTH)) / ((BLOCK_HEIGHT) * (BLOCK_WIDTH))`

```c++:after.cpp
#include <iostream>

#define IMAGE_HEIGHT 40
#define IMAGE_WIDTH 30
#define IMAGE_SIZE ((IMAGE_HEIGHT) * (IMAGE_WIDTH)) // !!!

#define BLOCK_HEIGHT 4
#define BLOCK_WIDTH 3
#define BLOCK_SIZE ((BLOCK_HEIGHT) * (BLOCK_WIDTH)) // !!!

int main(){
    std::cout << "image size: " << IMAGE_SIZE << std::endl;
    std::cout << "block size: " << BLOCK_SIZE << std::endl;
    std::cout << "# of blocks in a image: " << (IMAGE_SIZE / BLOCK_SIZE) << std::endl;
	return 0;
}
```
ただし、以上の書き方はC++の書き方としてかなり宜しくない模様。~~なぜ拡張子をcppにした~~
（コメント参照。**thx. yumetodo様, ryoco様, amate様, y_itamoto様**）

### 出力
```
image size: 1200
block size: 12
# of blocks in a image: 100
```
# 教訓とか
* 何となく使ってる構文とかが何やってるか正確に理解してないと事故る
* こういう習慣で防げる系のミスは初学者のうちに潰したい
* とりあえずおちつく
* *（追記）些細な出来事を書いたら結果的に勉強になった（ありがとうございます）*
RANK関数はないけど、MySQLのみでランキング表示させたい

[qnoteアドベントカレンダー2018](https://qiita.com/advent-calendar/2018/qnote)の3日目です。

## MySQLでランキング表示したい。
ある日、RANK関数という関数があることを知り、MySQLで実行してみたが、***「そんなものはない！」***と怒られた。
よくよく調べてみると、Oracle DatabaseやMicrosoft SQL Serverでは、RANK関数が使えるが、MySQLではRANK関数が使えないことを知りました。

でも、どうにかしてMySQLだけでランキング表示が出来ないか試してみました。

### 使用するデータ
```sql
mysql> SELECT * FROM Address;
+-----------+---------------+--------------+-----+-----+
| name      | phone_nbr     | address      | sex | age |
+-----------+---------------+--------------+-----+-----+
| 井上      | NULL          | 福島県       | 女  |  55 |
| 佐々木    | 080-5848-XXXX | 千葉県       | 女  |  19 |
| 佐藤      | 090-1922-XXXX | 三重県       | 女  |  25 |
| 前田      | 090-0000-XXXX | 東京都       | 女  |  21 |
| 小川      | 080-3333-XXXX | 東京都       | 男  |  30 |
| 松本      | NULL          | 千葉県       | 女  |  20 |
| 林        | 080-3333-XXXX | 福島県       | 男  |  32 |
| 森        | 090-2984-XXXX | 東京都       | 男  |  45 |
| 鈴木      | 090-0001-XXXX | 和歌山県     | 男  |  32 |
+-----------+---------------+--------------+-----+-----+
9 rows in set (0.00 sec)
```

## 欠番なしのランキング
### コード
```sql
SET @rank=0, @before_line_age=0;
SELECT
 CASE WHEN @before_line_age = age THEN @rank
 ELSE @rank:=@rank+1
 END AS rank,
 name,
 @before_line_age:=age AS age
FROM Address
ORDER BY age;
```

### 結果
```sql
+------+-----------+-----+
| rank | name      | age |
+------+-----------+-----+
|    1 | 佐々木    |  19 |
|    2 | 松本      |  20 |
|    3 | 前田      |  21 |
|    4 | 佐藤      |  25 |
|    5 | 小川      |  30 |
|    6 | 林        |  32 |
|    6 | 鈴木      |  32 |
|    7 | 森        |  45 |
|    8 | 井上      |  55 |
+------+-----------+-----+
9 rows in set (0.00 sec)
```

## 何をやっているか
```sql
SET @rank=0, @before_line_age=0;
```

まず、ユーザー定数を定義
`@rank` : 行数を指定。
`@before_line_age` :  一つ上の行のageをここに代入。
 

```sql
SELECT
 ...
FROM Address
ORDER BY age;
```

Adressテーブルを年齢の昇順で並べる。

 
```sql
CASE WHEN @before_line_age = age THEN @rank
 ELSE @rank:=@rank+1
 END AS rank,
```

一つ上のage(`@before_line_age`)と該当のageが等しいか判定し、CASE句で分岐。
等しい場合は`@rank`をそのまま渡し、等しくない場合は`@rank+1`の値を渡す。

>小数点を含む比較の場合は注意
小数点を含む比較の場合、`=`では正しく比較できない場合がある。
その場合は、ABS()関数を使用して差分が一定数以下かを判定すると良い。
例：`ABS(@before_line_X – X) < 0.01`

```sql
@before_line_age:=age AS age
```

次の行の計算で使用するために、`@before_line_age`にageの値を代入しておく。

## まとめ
MySQLだけでランキングを表示したい事案があるかは不明だが、やってみると面白かった。
この試みをしたことで、MySQLでも以下の事ができることを知れた。

- ユーザー定数
- CASE~WHEN
- `:=`での代入

## 最後に
最後までお読みいただき、ありがとうございます。

私は未経験で11月から働き始めたばかりで分からないことだらけです。
ですので、「もっとこうした方が良い」「ここは違う」等アドバイスをいただけると大変助かります。
特殊記号が使えない時のための近似文字辞典

#結論

どうしても使いたい文字があるけど、
特殊文字扱いされて使えない時

**[shapecatcher.com](http://shapecatcher.com/)**
でお絵かきしてください。

似ているUNICODE文字を選出してくれます。

##**` `** SPACE (U+0020)

```:近似文字
 
 
 
 
 
 
 
 
 
 
 
 
 
　
ㅤ
﻿
```

##**`!`** EXCLAMATION MARK (U+0021)

```:近似文字
ļ
ḷ
ᴉ
Ị
ǃ
ᵎ
ⵑ
ꜝ
ﺇ
إ
יִ
```

##**`#`** NUMBER SIGN (U+0023)

**`C#`**とか……(さすがにこれ使えなかったら残念ですよね)

```:近似文字
⧣
ꖛ
ⵌ
⌗
⋕
```

##**`+`** PLUS SIGN (U+002B)

```:近似文字
ⵜ
┼
┿
⨨
┽
₊
╀
╁
┾
╄
╈
⁺
╅
╇
╆
╃
╋
➕
╂
╊
╉
✢
⧾
ߙ
☩
```

##**`-`** HYPHEN-MINUS (U+002D)

```:近似文字
―
—
⎼
ー
−
⏤
‒
─
₋
–
 ̶
౼
𝄖
```

##**`/`** SOLIDUS (U+002F)

```:近似文字
╱
⁄
⧸
 ̸
 ̷
⟋
∕
𝄍
```

##**`:`** COLON (U+003A)

```:近似文字
׃
∶
˸
꞉
⁚
ː
⢈
⡁
⠨
⢐
⠅
⡂
։
܃
܄
𝄈
﮾
﮽
```

##**`;`** SEMICOLON (U+003B)

```:近似文字
;
⁏
```

##**`=`** EQUALS SIGN (U+003D)

```:近似文字
ꘌ
゠
⚌
ニ
 ̳
 ͇
᐀
 ̿
⁼
═
‗
₌
꞊
ᚚ
˭
𝄗
```

##**`|`** VERTICAL LINE (U+007C)

```:近似文字
│
⎸
⎸
⏐
𝄀
𝇁
▕
▏
 𝅥
∣
౹
⎮
⎪
⎟
⎥
❘
╽
╿
 ⃒
l
⎜
╵
⎢
ǀ
┃
꘡
ꟾ
𝇂
I
```





##**`//`** DOUBLE SOLIDUS (U+002F)*2

```:近似文字
ᐥ
𝄓
 ⃫
ᨀ
```

##**`::`** DOUBLE COLON (U+003A)*2

**C++**の**`std::cout`**等で使用する**`::`**

```:近似文字
∷
⛚
⸬
ⵆ
⠭
⣒
⣉
።
⠶
⠛
⣤
```

##**`||`** DOUBLE VERTICAL LINE (U+007C)*2

```:近似文字
॥
Ⅱ
𝄥
װ
ǁ
```

他にも追加してほしい文字があったら教えてください。
Juliaでリンク共有されているGoogleスプレッドシートをCSVエクスポートを経由してDataFrameで読み込む

Julia 1.0.2で確認

```Julia
using Pkg
Pkg.add(["CSV", "DataFrames","GoogleSheetsCSVExporter"])
using GoogleSheetsCSVExporter, CSV, DataFrames

url = "https://docs.google.com/spreadsheets/d/1klF3cdwF91KtEV8MGgplkqpDGRDpKoD9zIerPJDGovA/edit#gid=0"
@show GoogleSheetsCSVExporter.fromURI(url) |> CSV.File |> DataFrame
```

# 参考

* https://github.com/eiel/GoogleSheetsCSVExporter.jl
MySQL レプリケーションのサポートポリシーがこっそり (?) 変わっていた話

この記事は **[MySQL Casual Advent Calendar 2018](https://qiita.com/advent-calendar/2018/mysql-casual)**・3 日目の記事です。

昨日は meijik さんでした~~（たぶん…）~~出てました。

 * **[[勝手に対応]MySQL8.0の分析関数の1(モードとメジアン)](http://blog.kimuradb.com/?eid=877547)（キムラデービーブログ）**

なお、私のこの記事の話は、**[第25回 中国地方DB勉強会 in 鳥取（倉吉）](https://dbstudychugoku.connpass.com/event/103072/)**で**山﨑さんが発表された内容の丸パクり**です（ごめんなさい）。Advent Calendar 3 日目がずっと空いたままだったので、つい（あ、まだ 5 日目が空いてる）。

※元ネタは第25回 中国地方DB勉強会 in 鳥取（倉吉）発表資料の**[ここ](https://speakerdeck.com/yoshiakiyamasaki/20181201-mysqlbaziyonatupufalseji-chu-zhi-shi?slide=75)**から 3 ページ分です。

## 変わったところ

これを書いている時点で、MySQL 5.6 日本語マニュアルにはまだ記述が残っているのですが、**[17.4.2 MySQL バージョン間のレプリケーション互換性](https://dev.mysql.com/doc/refman/5.6/ja/replication-compatibility.html)**の、

> 場合によっては、マスターと、マスターよりメジャーバージョン 2 つ以上新しいスレーブとの間で複製できます。ただし、MySQL 4.1 以前を実行するマスターから MySQL 5.1 以降を実行するスレーブに複製しようとすることに関する既知の問題があります。このような問題に対処するために、2 つの間に中間バージョンを実行する MySQL サーバーを挿入できます。たとえば、MySQL 4.1 マスターから MySQL 5.1 スレーブに直接複製するのではなく、MySQL 4.1 サーバーから MySQL 5.0 サーバーに複製してから、MySQL 5.0 サーバーから MySQL 5.1 サーバーに複製できます。

に相当する文章が英語マニュアルからごっそり削除されています。

結果、

> 2 つを超える MySQL Server バージョンを使用することは、マスターまたはスレーブ MySQL サーバーの数にかかわらず、複数のマスターを使用するレプリケーションセットアップでサポートされません。この制限は、メジャーバージョンだけではなく、同じメジャーバージョン内のマイナーバージョンにも適用されます。たとえば、チェーンまたは循環レプリケーションセットアップを使用している場合、MySQL 5.6.1、MySQL 5.6.2、および MySQL 5.6.4 は同時に使用できませんが、これらのリリースの任意の 2 つを一緒に使用することはできます。

という**原則**が適用されるため、

 * MySQL 5.6 から MySQL 8.0 にバージョンアップしたいとき、
 * 5.6 からは直接 8.0 へのレプリケーションはサポートされないので、
 * 間に 5.7 のスレーブ兼マスタサーバを**「中継サーバ」**として立ててレプリケーションする形でバージョンアップ

という構成にするのは、現在ではサポート外となっております。

※**「技術的に動くかどうかは別」**という話です。**「やるなら自己責任で」**ということですね。安全に行くなら「段階的バージョンアップ」か、レプリケーションを使わずサービス停止時間を長く取ってバージョンアップすることになるでしょう。こういうこともあるので、なるべくこまめにバージョンアップしていくのが吉です（間を飛ばして一気に上げるのはやめて）。

なお、「3 つ以上のバージョン間でのレプリケーション構成をサポートしない」点については、文中にある通り、マイナーバージョン（現在のバージョン表記でいうところの、3 つ目の数字）も同じですので、その点についてもご注意を。

具体的には、普段から循環 or 数珠繋ぎ形式のレプリケーションを使っている構成で、各サーバのマイナーバージョンのバージョンアップをする場合に、うっかり 3 マイナーバージョン混在構成にならないようにしてください。

※「運用中のシステムで 1 台ずつ日程をずらしてバージョンアップしてしまう」などが NG。但し「技術的に NG」とは言っていないので、やるなら自己責任で。

## 補足

これを書いている時点の MySQL 5.6 日本語マニュアルには、

> MySQL は、あるメジャーバージョンから次**以降**のメジャーバージョンへのレプリケーションをサポートします。

とありますが、英語の原文には、

> MySQL supports replication from one release series to **the next** higher release series.

とありますし、日本語マニュアルの続きの文章が、

> たとえば、MySQL 4.1 を実行するマスターから MySQL 5.0 を実行するスレーブ、MySQL 5.0 を実行するマスターから MySQL 5.1 を実行するスレーブなどへの複製ができます。

なので、日本語マニュアルの「以降」の文言は誤り（ないのが正しい）です。

---

明日（4 日目）は yoku0825 さんです！

 * **[ConoHaの上でひたすらMySQLをビルドする簡単なお仕事 in 2018](https://yoku0825.blogspot.com/2018/12/conohamysql-in-2018.html)（日々の覚書）**
GoでCGIしてみる

というわけでCGIしてみます。

## 一般的なGoのWebアプリケーションからの置き換え

普通、GoでWebアプリケーションを作るときは、`net/http`を用いてHTTPをしゃべるサーバを立てるかと思います。もしくは、各種フレームワークが同じようなことをやるでしょう。

```go
import "net/http"

func main() {
    http.ListenAndServe(
        ":8080",
        http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
            // do something
        }),
    )
}
```

CGIの場合は、Apache等のサーバがHTTPをしゃべるサーバとなり、CGIプログラムをサーバが実行します。なので、上記方法はそのまま使えません。

そこでGoには`net/http/cgi`というものがあります。これは上記`net/http`の`ListenAndServe`を置き換えればいいだけです。

```go
import (
    "net/http"
    "net/http/cgi"
)

func main() {
    cgi.Serve(
        http.HandlerFunc(func (w http.ResponseWriter, r *http.Request) {
            // do something
        }),
    )
}
```

## ローカルでの確認方法

現代においてはApacheを立てるというのも相対的に難儀な作業になってきました。そこでCGIアプリケーションを確認するための簡易的な方法を紹介します。

HTTPサーバミドルウェアの[h2o](https://h2o.examp1e.net/)を用います。以下の設定でCGIアプリケーションの確認ができます。

```yaml
listen:
  port: 8081
user: username
hosts:
  "localhost":
    paths:
      /:
        file.dir: ./
        file.index: ["index.cgi"]
        file.custom-handler:
          extension: .cgi
          fastcgi.spawn:
            command: "exec $H2O_ROOT/share/h2o/fastcgi-cgi"

access-log: log/access-log
error-log: log/error-log
pid-file: log/pid-file
```

以上をh2o.ymlで保存し、

```shell
$ h2o -c h2o.yml
```

で起動します。GoのCGIアプリケーションは`index.cgi`で保存しておきます。もちろんパーミッションは実行可能にしておきます。これで簡単にローカルでCGIアプリケーションの確認ができます。

## 実際のCGIアプリケーションを作ってみる

https://gist.github.com/mackee/2247f081ad860ed36c7b27bb6886b862

というわけで作ってみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/3629/625d5679-2c41-1cfb-2ee5-e962e54d89c4.png)

頑張ってる点としては

- カウンタがファイルサイズで記録して追記で済ませるタイプ
- コメント欄はファイル記録
    - 当時は考えていなかったCSRFだとかを考えないといけない
    - XSSは`html/template`がある程度防御してくれている
- ログはファイルに書いておいてレンタルサーバでデバッグしやすくする

という感じです。

## まとめ

- 簡単にですがGoでCGIについて説明しました
- コンテナだとかサーバレスだとかはCGIっぽいアーキテクチャかと思います。CGIで済むのであればCGIでプライベートサーバレス環境を作ってみると面白いかと思います
AdventCalenadr2018 2 WordPress でつくるブログメディアの企画を考える

この AdventCalenadr 企画では、ブログメディアをやると書いていますが、私の意図するところとしては、ブログというよりも企業のオウンドメディアのようなイメージで書いています。

つまりこの規格で言う、ブログメディアとは、メルマガやウェブマガジンのようなものかもしれませんし、ECショップのオウンドメディアかもしれません。

# メディアの企画を考える
ではメディアの企画を考えていきます。メディアの企画というのは読者がいてなりたつものです。なので最初はどういう読書によんでもらえるかを考えると良いです。

- メディア企画のポイント
	- 読者（ペルソナ）
	- メディアのコンセプト
	- KPI
	- KGI

個人なら、自分の好きなことをやるのも良いですし、はやりのものをやったり、会社組織なら会社の活動と親和性の高く収益が見込めるものにするとよいですね。

企画のポイントとしては、自分の強みを活かした企画にするというのと、あまり制約を儲けずに自由に考えるのが良いと思います。

## 読者
読者は30代男性がメインとか、10代女性向けなどのようにターゲットを決めておきます。

ターゲットは具体的であるほうが良いです

## メディアのコンセプト
読者を決めたら、メディアを通じて読者にどうなってもらいたいかを決めます。

例えば自転車のメディアなら、メディアを読むことで自転車についての疑問が解消し、自社商品の理解を深まった状態になるという感じでしょうか。

## KPI
KPI の指標はいろいろありますが、PV にすることが一般的でしょうか。PV にも良し悪しがあるのですが、まあわかりやすく PV が KPI になることが多いでしょう。

ビジネスでやるなら、最低10万 PV もしくは年内に 100万 PV 達成などのように決めると良いですね。

## KGI 
1年で100万 PV 達成した際に、どの程度の数字を達成するか、例えば商品の売上や、広告収入などを決めておきます。


# この AdventCalendar のメディア企画
このメディア企画で何をしようか全く決めていなかったのですが、決めないとなりません。

何か私に強みがあればよかったのですがそうでもないので、流行り物に乗っかることにしました。

Qiita で Python タグの投稿が人気ですが、機械学習や AI 周りの投稿を行うような企画にします。

## この企画の読者
AI や機械学習に興味を持っていたり、学習したいと思っているビジネスマンや学生を考えています。

## この企画のコンセプト
読んだ人が AI や機械学習について理解を進める助けとなるメディアにします。

ちょっとコンセプトは甘い感じです。

## この企画のKPI
「1年後に合計 3万 PV 月間 1万 PV とします。」

最初「1年後に1万PV」と書いたのですが、この書き方は期間が曖昧でよくなかったです。書いていませんでした。

もし、企業のオウンドメディアで月間1万程度の目標にするのでしたら、あまりインパクトがある数字ではないのでもっと大きな目標にするといいでしょう。


## この企画のKGI
「1年後に合計 3000円売上をあげる。」という KGI にします。

最初はこちらも「1年後に1000円」と具体的でない内容だったのよくなかったです。この記事を書いている時点では、キャッシュポイントが未確定なのでちょっと無理矢理感があります。

企業のオウンドメディアで KGI を決める顧客のリード獲得や、売上がいいですね。

# 最後に
WordPress というが WordPress が出てこないじゃないかと思うかもしれませんが、企画の一部が WordPress に関係があると考えています。

それは後ほど(☝ ՞ਊ ՞)
進め方の話～EHW2018「2つのやりかた」

# 概要

このエントリは、「Enterprise "hello, world" 2018 Advent Calendar 2018」の12/2向けのものです。このAdvent Calendarでは、複数個のエントリにまたがる話の流れも鑑みつつ、なるべく1エントリで１つのトピックをカバーできるようにする予定です。

このエントリで記載するトピックは、計画とか設計の話です。

# 前提

前提は、[「Enterprise "hello, world" 2018」](https://qiita.com/advent-calendar/2018/ehw2018)に準じます。

## 想定読者

「Enterprise "hello, world" 2018」的なネタとしては、下記のような状況を想定しています。

> Day1で渡されたバイナリの動作は分かったので、これを今風のアーキテクチャで動かさなければいけないことになったのだけれども、さてどうしたものか。

# 考え方

（どうせ、作るものは"hello, world"っていうだけ、というのは置いておいて）これから作るシステムが何を目的としていて、どうやってシステム化することで何を解消しようとしているのか、動かし方はどうするか、といったことを考えておくことが必要になります。

大きく2派あると思いますので、それぞれをトピックとして取り上げたいと思います。

参考として、TIS株式会社さんの「[Fintan](https://fintan.jp/)」を使わせていただきます。公開どうもありがとうございます。

## 慎重に進める派

ここはやはり、どーんとウォーターフォールで考えましょう。

前提で紹介した[ここらあたり](https://fintan.jp/?p=1145)を参考にしながら、開発プロセス標準に従い、以下を確かめましょう。

- 何を実現したいのか
- そのために何を作りたいのか
- 作りたいもののために何が必要なのか
- 必要なものをシステムとして実現するにはどうするか
- システムが実現されたことをどう確認するか
- システムが動き続けるにはどういう体制でどう取り組むのか

参照先には、エンタープライズでよくあるフォーマットも格納されているので、参考にできるかもしれません。

参照先は、WBS（お仕事の全体なスケジュール）として定義する内容、作成すべき成果物（アウトプット）について、だれがいつやるべきかについて一覧になっているので、議論を始める前提として活用できそうです。

## とにかく始める派

こちらは、いわゆる"アジャイル"的な方式です。

回し者ではないのですが、前提で紹介した[ここらあたり](https://fintan.jp)には、アジャイルで物事を進めるための考え方、体制の作り方、取り組みなども挙げられています。

このAdvent Calendar的な意味で言うと、まずは「インセプションデッキ」を書いて、何を実現するためにこの開発チームは集まったのか、から確認していくフェーズになるでしょう。

ゴールに対して少しずつ、動く形で確認できるものを作りながら進めるやり方も、とくに「いろいろ試してみなくてはわからない」領域においては、有効な手段です。


# とにもかくにも

EHW2018的に実現されるべきことはカレンダーの概要に書かれたことがすべてです。

> （単にhello worldと返すだけのものとしては）なるべくめんどくさく、システムとしてまとめ、コンテナ化されたものがデプロイされる動作確認できるようにしていくものとします。

これが実現されていれば、本プロジェクトのゴールは実現されたものとします。

どちらの手法をとったにせよ、最終的には、きちんと動作するシステムがなければ意味をなさないことには変わりがありません。
二つの手法は、思いが異なる複数名の人たちが、形が見えにくいシステム開発という中でどういう進め方にしようか、という大まかな取り決めを指すものだろうと考えることにして、このAdvent Calendarでは、日数もないことですので、後者の「とにかくはじめる派」方式で取り組むというデザインにします。

# まとめ

このエントリでは、「Enterprise "hello, world" 2018 Advent Calendar 2018」(EHW2018)の2日目として、

進め方の話をトピックとして取り上げました。

EHW2018のネタとしては、このあと、このプログラムと同じような目的を持つものを現代的なツール群を用いて、なるべくめんどくさく実現していくことを考えています。
2行で導入できるOpenSiv3D用パラメータ管理ツール

![param_.png](https://qiita-image-store.s3.amazonaws.com/0/100367/bcf7e581-1bbc-e4fa-bea7-eef8b5da7794.png)

パラメータをソースコードで管理するのは大変です。
現在の OpenSiv3D(v0.3.0) にはスクリプト機能があるので状況は良くなっていますが、それでも GUI ツールほど手軽な調整はできません。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">OpenSiv3D v0.3.0 から使えるスクリプト機能でデザインを素早くコーディング（動画は 4 倍速） <a href="https://t.co/WrXuBIxIu7">pic.twitter.com/WrXuBIxIu7</a></p>&mdash; Ryo Suzuki (@Reputeless) <a href="https://twitter.com/Reputeless/status/1034465307438370816?ref_src=twsrc%5Etfw">2018年8月28日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ということで OpenSiv3D 用のパラメータ管理ツールを試作しました。

#パラメータ管理ツール
こちらで公開しています。
https://github.com/agehama/SivParamEditor

このツールは1つのヘッダ（ParamEditor.hpp）と OpenSiv3D プログラム（Editor.cpp）から成ります。

#使用例
使用したいアプリケーションから `ParamEditor.hpp` をインクルードし、メインループの中で `pmt::Update();` を呼びます。あとは`pmt::GetColor(U"名前")` のようにして色の取得を行うことができます。

```cpp
#include <Siv3D.hpp>
#include "ParamEditor.hpp"

void Main()
{
	while (System::Update())
	{
		Window::ClientRect().draw({
			pmt::GetColor(U"BgTop"), pmt::GetColor(U"BgTop"),
			pmt::GetColor(U"BgBottom"), pmt::GetColor(U"BgBottom")
		});

		pmt::Update();
	}
}
```
このプログラムを単に実行すると、適当な色が勝手に割り当てられて描画されます。
![20181202-221506-089.png](https://qiita-image-store.s3.amazonaws.com/0/100367/20cf86a4-fdb6-cda7-867e-8fc3ce2585c2.png)

この状態でエディターを起動すると、次のようにプログラム内で使用した色が自動的に読み込まれます。
![20181202-221632-186.png](https://qiita-image-store.s3.amazonaws.com/0/100367/65744e37-99d7-2e03-c2d1-79529d291781.png)

この色の付いた部分をクリックして、色を変更すると元のアプリケーションにも反映されます。
![20181202-221725-483.png](https://qiita-image-store.s3.amazonaws.com/0/100367/78adc8d4-09f4-0b20-92c7-767441a21bbb.png)

このデータは作業ディレクトリ内の ParameterEditor/save.dat に自動的にセーブされるので、プログラムを終了しても次に起動した時に自動的に読み込まれます。
![20181202-221739-449.png](https://qiita-image-store.s3.amazonaws.com/0/100367/a9bfa759-005a-479c-629b-4b93e34194aa.png)

#補足

調整が終わったら `ParamEditor.hpp` をインクルードする前に `#define PMT_RELEASE_FLAG true` というマクロ定義を書けばエディタとの通信が行われなくなるので、ほぼコスト0で呼び出すことができます。

まだ作り途中ですが、以下の機能追加・修正を予定しています（やる気が続く限り）。

- Double, Int, Vec2 型への対応
- カラーエディターの修正
- パラメータのセット作成・切り替え機能
- ポート番号の変更
- 古いパラメータの削除

#終わりに
冒頭の画像はこのエディターのソースコードでした（ツールを作るためのツールが欲しい）。
undefined local variable or method `display_meta_tags` for #<#<Class:......>:....>[Rails]

# **undefined local variable or method `display_meta_tags` for　エラーに遭遇した話**

# **はじめに**

SNS投稿やシェア機能を実装する際にはOGPを設定することがマストになってくるかと思います。
railsではメタタグを便利に扱えるgemが用意されているので、今回はそれを利用した時に遭遇したエラーと解決策をご紹介します。

# **エラー**

Gemfileに下記記述を追加し、`bundle install`後、ページにアクセスすると下記エラーが発生しました。

```Gemfile
gem 'meta-tags'
```


<img width="1085" alt="metaTag_png.png" src="https://qiita-image-store.s3.amazonaws.com/0/269862/fa2cbfc5-5881-bab3-efe5-5e7a2385dc96.png">

# **解決策**

Gemfileを下記のように書きかえ、`bundle install`を実行するとエラーが解決されました。

```Gemfile
gem 'meta-tags', :require => 'meta_tags'
```

# **エラー記事まとめ**
＊2018/12/02時点で、まだ1記事しかございません。これからストックしていきます。
みなさんが同様のエラーに遭遇した時の一助になると幸いです。

[Mysql2::Error::ConnectionErrorの謎を解明！](https://qiita.com/takuyanin/items/d06168f63bdbffbce3f3)

# **おわりに**
メタタグをページごとに設定し、適切なタイトル、詳細などを推敲することはSEO対策にも繋がります。
時間ある時に、metaタグを設定したファイルの中身などを記事にまとめたいと思います。

何かご質問やご意見などがございましたら、下記コメント欄などにてコメントいただけたらと思います。
マテリアルに一工夫して、エフェクトをちょっとリッチにするあれこれ

https://qiita.com/advent-calendar/2018/ue4_zwei
アドカレ7日目の記事になります。

#　はじめに
　アドカレは初めてなので初投稿です、主にUE4を使用してエフェクトを作成しております、0ct0pusといいます。
　本日の記事は**マテリアルに一工夫して、エフェクトをリッチにしよう！**という題で記事を書かせていただきます。

# 1.こんな人向け
・そこまでエフェクトにコストをかけられないけど、もうちょっとリッチに見えるエフェクトを作りたい人。
・細かな調整をしなくても、それっぽく見えるようになって欲しい人


# 2.今回使ったもの、参考にした資料
・テクスチャはみんなだいすき、Paragonから持ってきました。Paragon Gruxに入っていたものを作例では使用しています。
・https://docs.unrealengine.com/en-us/Engine/Rendering/Materials/CurveAtlasesInMaterials
　カーブをテクスチャにするあれこれは上記ドキュメントを参考にしました。
　また、実際に作成したCurveAtlasテクスチャは64*64にしています

# 3.ほんへ
###基本的なマテリアルの最小構成。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311693/e94439b7-6b11-c8d4-d2c8-241f320444f2.png)
パーティクルシステム（以下,PS）を使用してエフェクトを作る際の非常にベーシックな構成です。
これに手を加えていきます。

**特徴**
　組みやすい
　シンプルなので負荷も最低限


###一工夫後
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311693/f4377689-400f-50c2-b78c-aab8b7461e4e.png)

色変化と、ディゾルブを入れ込みました。

**特徴**
　関数化してないと見づらい。


###第１の肝になる、**アルファ情報をもとにした、色変化機能**です
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311693/924a61aa-c40e-2665-89fe-1106cf1e0bdd.png)

 UE4からカーブをテクスチャ化できるようになったので、それを利用しています。
　Curve Atlas Row Parameter というノードを使ってもいいですが、テクスチャをパラメーター化できるのと、数値（パラメーターのCurve_Index）を変化させるだけでいろいろなカーブにアクセスできたほうが取り回しやすいため、このような構成になっています。

Rチャンネルに0~1のアルファ情報を与えることで、テクスチャの横軸の色を与え
Gチャンネルを数値で制御することで、列を指定しています。

[指定したい列]=[指定したい列番号（Curve_Index）]×[１列の幅（テクスチャが64列ならぶため、1/64）]

で、使いたい列を出しています。add0.5は、テクスチャのボケている部分が出ないようにしています。

###第２の肝になる、ディゾルブです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311693/f62b6a32-a28f-39a5-21b4-371614eedd7e.png)


ディゾルブ自体は様々な手法がありますが、今回は負荷が比較的軽量で、かつ0~1の数値でコントロールできる手法を取っています。
Dynamicパラメーターで0~1の値で制御します。
0~1の値を、-1~1に変換し、その値をディゾルブさせたいノイズテクスチャに加算します。この値を直接使うと-1~1の値になってしまうので、Saturateで0~1にクランプして、最後にオパシティ情報と乗算します。

更にディゾルブテクスチャがランダムになるように設定。

#4.ここまでかわりました。
左が基本的なマテリアルの最小構成、　右が今回一工夫加えたものです。
HITエフェクト
https://www.youtube.com/watch?v=EFpXkq9zeqQ　

パーティクル単体
https://www.youtube.com/watch?v=_yXE-HrKWrA　

#5.最後に
より詳細に調整したい場合は、ここに更に複数テクスチャを使用できるようにしたり、タイリング調整やテクスチャのスクロール機能。
テクスチャのディストーションなど様々な機能を入れ込んでいきますが、今回は
**そこまでエフェクトにコストをかけられないけどもうちょっとリッチに見えるエフェクトを作りたい人。**向けのため、かなり機能を絞らせていただきました。(機能が増えると触るパラメーターもカーブも増えてしまうためです。)
はじめてのアドカレということで、至らぬ点もあるとは思いますが、ここまで見てくださいましてありがとうございました。



#6.蛇足
超ものぐさなあなたは
![image.png](https://qiita-image-store.s3.amazonaws.com/0/311693/8e91fc3f-643a-26f4-d517-8226d8611a21.png)
このようにParticle Rerative TimeをOneMinusして、ディゾルブとオパシティにつないでしまいましょう。
パーティクルにライフタイムさえ入っていれば勝手に消えてくれるようになります。
Vimで編集中のファイルのGitホスティングサービス上のURLを取得する

障害発生時や実装時など、手元のエディタで開いているファイルのGitホスティングサービス上のURLを、Slackで共有したい時があるかもしれません。

私の場合、Vimを使っていてBitbucketのURLを共有したいというケースがありました。
それに対し、Vim scriptで `GitUrl` というコマンドを追加し、 `.git/config` の設定を元にURLを出力するようにしました。

以下にそのscriptと、補足を記載します。

## 追加したVim script

```vimscript
  function! GitUrl()
    let l:TEMPLATE = 'https://example.com/projects/__PROJECT__/repos/__REPOSITORY__/browse/__PATH__'

    let l:project    = system('git remote get-url origin | sed "s/\// /g" | awk ''{print $(NF-1)}'' | tr -d "\n"')
    let l:repository = system('git remote get-url origin | sed "s/\// /g" | awk ''{print $(NF)}'' | sed "s/.git$//" | tr -d "\n"')
    let l:path       = system('git rev-parse --show-prefix | tr -d "\n"') . expand('%')
    let l:remote_url = substitute(substitute(substitute(l:TEMPLATE, '__PROJECT__', l:project, ''), '__REPOSITORY__', l:repository, ''), '__PATH__', l:path, '')

    echo l:remote_url
  endfunction
  command! GitUrl call GitUrl()
```

例えば `railstutorial` プロジェクトの `hello_app` リポジトリの `app/controllers/application_controller.rb` を開いている場合、 `:GitUrl` を実行すると、以下のURLを出力します。

```
https://example.com/projects/railstutorial/repos/hello_app/browse/app/controllers/application_controller.rb
```

## scriptの補足

- Bitbucketはプロジェクトの下にリポジトリが所属する構成を期待しています。
- `git remote get-url origin` で取得するURLは、SSH URLを期待しています。URLからプロジェクト名とリポジトリ名を取得します。
  - 上記例では `ssh://git@example.com/railstutorial/hello_app.git`
- `git rev-parse --show-prefix` でルートディレクトリからの相対パスを取得し、 `expand('%')` で編集中のファイルの名前を追加し、パスを作成します。

GitHub以外のGitホスティングサービスを利用する場合、エディタ上でURLを取得するプラグインやエクステンションが探しづらいかもしれません。そういう場合に10行程度のVim scriptでしのげるのがよいと思いました。
論理演算子の評価について

#論理演算子の評価方法
特にインクリメント・デクリメント時には注意が必要


```Increment.java

public class Increment {

	public static void main(String[] args) {
		int x = 10;
		int y = 10;

		if (x >= 10 && ++y >= 10) {
			//xがfalseならyを評価しない
			System.out.println("x = " + x);
			System.out.println("y = " + y);
		}
		System.out.println("------");

		if (x >= 10 || ++y >= 10) {
			//xがtrueならyを評価しない
			System.out.println("x = " + x);
			System.out.println("y = " + y);
		}
		System.out.println("------");

		if (x >= 10 | ++y >= 10) {
			//xがtrueでもyを評価する
			System.out.println("x = " + x);
			System.out.println("y = " + y);
		}
		System.out.println("------");

		if (x > 10 & ++y > 10) {
			//xがfalseでもyを評価する
			System.out.println("nothing");
		}

		System.out.println("x = " + x);
		System.out.println("y = " + y);
	}

}
```

```
x = 10
y = 11
------
x = 10
y = 11
------
x = 10
y = 12
------
x = 10
y = 13
```
NuxtJSでURLパラメータを取得する方法

nuxt.jsでURLパラメータを取得したい時があったので調べてみました。

pages配下に以下のような階層構造を作成した時、最下層のnew.vueにアクセスするURLが `orders/orderId/offers/new` のように作成される。

```
pages
  └── orders
      └── _orderId
      　   └── offers
      　       └── new.vue
```

このときの `orderId` を取得する。

```new.vue
<template>
  {{ $route.params }}    // 1
</template>

<script>
export default {
  created: function() {
    console.log(this.$nuxt.$route.params.orderId)    // 1
  }
}
</script>
```
釈迦とロボット 「無明」を実装する？


![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/fe28c1a1-4e60-2689-c106-8d63c7cec964.png)
釈迦像（ウィキペディアより）

# はじめに
ロボットに心を実装したいと、みんな悩んでいると思います。
そこで、今回は仏教の側面から、心の実装について考えます。

仏教といっても釈迦（紀元前５世紀）以降に、各時代に各国で天才たちがいろいろな概念を加えて、膨大で複雑です。

シンプルに行きたいので、「釈迦の悟り」そのままである初期仏教を考えます。
初期仏教は、思いの外、整合性がとれていると感じます。「無明」はすごい。

# 釈迦は何と言ったか　無常、無我、無明

釈迦はつぎの３つを言いました（根本的な理念）。

「無常（むじょう）」　生滅変化してうつりかわり、しばしも同じ状態に留まらないこと
「無我（むが）」　あらゆる事物は現象として生成しているだけであり、それ自体を根拠づける不変的な本質は存在しない
「無明（むみょう）」　真理に暗いこと、智慧の光に照らされていない状態

これらを順に、心の実装の観点から見ていきましょう。

# 無常　
これは、生活実感にも合います。心の実装の観点からも特にコメントはありません。
つきつめると、物理的には瞬間の単位であるプランク時間$（5.391×10^{-44}秒）$で、プランク長$（1.6×10^{-35}m）$程度の「超ひも」が変化している。

# 無我
（１）これは、生活実感に合わないです。個人的には、自我の存在はリアリティがありすぎます。
（２）無我が正しいとすると、心も無さそうなので、その実装は不可能です。
（３）「実装に向けた心の定義ができない。心を実装したといわれても、その判定方法が不明」　
という現在の状況は、心が無いことと整合しているようにも見えます。
心が実装できたかの判定は、チューリングテストのような、各個人の主観的判断しかない気もします。

# 無明
（１）無明は真理に暗いことですが、この「真理」とは、上記の「無常」「無我」を指すようです。無明は宗教の話で、無知は学問の話らしい。
（２）実際には心が無いのに、無明により、自分自身に心があるように勘違いしている！
この勘違いが、心にリアリティがある理由です。
（３）ロボットへの心の実装を考えると、無明をロボットに実装すればよいことになる？
ロボット自身に無明を実装して、心があると勘違いさせればよい。
話としては整合性があるように思えます。

ロボットに勘違いを実装する方法は不明です。
人は、どうやって勘違できたんだろう？
闘いはこれからだ！


# 今後にむけて

つぎのキーワードが気になる。時間を作って調べていきたい。

##　龍樹（りゅうじゅ）　2世紀に生まれたインド仏教の僧
「空」の理論を体系化した、天才のようです。
名前も格好良い。松任谷由実をかけながら「龍樹の伝言」を聞きたい。

##　華厳経（けごんぎょう）　4世紀頃の大乗仏教経典
あらゆるものは自性（事物をそのものたらしめている本来的な不変の性質。本性。本質）はなく、ものの間の関係の束のみが存在する。（無自性＝空　のようです）
割り切っていて、シンプルで良いです。実装向きか。

機械学習 word2vec のベースである、単語意味の分布仮説(Distributional hypothesis)
「単語の意味はその単語が出現した際の周囲の単語によって決まる」の、すなおな拡張になっている？

ちなみに、奈良の東大寺大仏は「華厳経」に説かれる盧舎那仏という名の仏のようです。

##　禅（ぜん）　大乗仏教の一派である禅宗　釈迦の悟りを体験することが目標
「不立文字」　文字・言葉の上には真実の仏法がない。体験によって伝えるものこそ真髄であるという。体験第一。
このため禅宗では中心的経典がないようです。

禅はつねに具体的な事実を扱い、一般論には流れない。
抽象的(文字の世界)な一般論を扱うものではないらしい。実装向きではない？

自己（=実在）を知ろうと問うことは、「問う者」と「問い」に自己を分離させる。
しかし、問の答えは、分離以前のそのものから出てこなければいけない。
問いは分離の後に生まれ、分離以前には問いはなかった。このため、当然、答えはない。
論理が格好良い気がする。釈迦の悟りを体験してみたい。

### 禅と関係がある有名人

元アップルCEOのスティーブ・ジョブスは、禅に傾倒した仏教徒らしい。
結婚式は曹洞宗の禅僧、乙川さんに取り仕切ってもらったようです。

安倍首相は臨済宗国泰寺派の禅寺「全生庵」に、足を運んでいるようです。
江戸無血開城で活躍した、山岡鉄舟が建立した、禅寺です。

### 日本禅宗25流
日本の禅宗で有名なのは、つぎの２つのようです。
曹洞宗　道元　只管打坐　永平寺（福井県）正法眼蔵
臨済宗　栄西　公案禅　　多くの派がある

# おわりに
仏教は、新鮮でおもしろいです。坐禅もしたいし、公案も気になる。
仏教や哲学をベースにした、ものづくりをしてみたい。
欧米との差別化にもなるし、資本主義、成長主義、競争社会を乗り越えられるかも。
禅の心｢吾唯知足｣で幸せになろう。めざせ、前人未到！

# 参考情報

https://ja.wikipedia.org/wiki/無常
https://ja.wikipedia.org/wiki/無我
https://ja.wikipedia.org/wiki/無明

https://ja.wikipedia.org/wiki/初期仏教
https://ja.wikipedia.org/wiki/釈迦

https://ja.wikipedia.org/wiki/龍樹
https://ja.wikipedia.org/wiki/華厳経
https://ja.wikipedia.org/wiki/禅
https://ja.wikipedia.org/wiki/スティーブ・ジョブズ

禅 (ちくま文庫) 文庫 – 1987/9/1　鈴木 大拙 　http://amzn.asia/d/5v5gDYH
![image.png](https://qiita-image-store.s3.amazonaws.com/0/78212/b7b82c9a-8f9a-5bd5-df49-79bfb4718816.png)
<ansible> blockで囲んだ複数のタスクを with_itmes でループしながら処理する方法

ansibleレシピ シリーズ１

ansibleは時々、「こんなんできて当然でしょ！？」ということが出来ません。
けど、やらないと業務は進まない訳で、だけど分からないと書けない。。
そんな時にネットでぐぐって解決したり、実験しながら解決した内容を還元するシリーズその１。

なお、ansible 2.7.2 環境が前提です。

## やれると思ってできなかったこと (現象と問題)

普通に、取得した一覧を利用して、複数タスクを実行したかっただけ。
一覧をグルグル回すには、with_itemsを利用するのだが、blockで複数タスクをまとめて
実行しようとしたがエラーがでて実行できなかった


```main.yml

- name: 一覧を取得する
  shell: ls -A /var/www/html
  register: list_data

- block:
    - debug: msg="ファイナル・フュージョン {{ item }}"
    - debug: msg="承認！！ {{ item }}"
    - debug: msg="プログラムドライブ！！！！ {{ item }}"
  with_items: "{{ list_data.stdout_lines }}"

```


## 解決策

blockではwith_itemsを直接利用できないので、
blockの箇所をまるまる別のyamlに切り出して、それをincludeしてあげる。
そうすると上手くいく。

```main.yml

- name: 一覧を取得する
  shell: ls -A /var/www/html
  register: list_data

- include: sub.yml
  with_items: "{{ list_data.stdout_lines }}"
```

```sub.yml

- block:
    - debug: msg="ファイナル・フュージョン {{ item }}"
    - debug: msg="承認！！ {{ item }}"
    - debug: msg="プログラムドライブ！！！！ {{ item }}"
```
【Unity】ユニティちゃんの体の向きを滑らかに方向転回する

環境メモ
⭐️Mac OS Mojave バージョン10.14
⭐️Unity 2018.2.15f1

ユニティちゃんの体の向きを滑らかに方向転回する。
矢印キーを押して向きを変えて走らせる。

完成系↓↓↓↓
![forward.gif](https://qiita-image-store.s3.amazonaws.com/0/93155/42030093-4f02-a278-a4bf-8f6450e7744c.gif)


1.「UnityChan」「Models」の「unitychan」をヒエラルキーウィンドウにDrag&Dropして配置する。
<img width="840" alt="001.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/8509db66-9855-2c9e-436f-583cf289394d.png">

2.「Create」「Animator Controller」を選択し「UnityChanController」という名前にする
<img width="1017" alt="002.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/7e635280-7bc6-f097-d183-30b5507641f4.png">

3.ヒエラルキーウィンドウの「unityChan」に「UnityChanController」をセットする
<img width="1294" alt="003.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/3f0bd12a-4d9c-adcb-666f-b94612cddb8c.png">

4.「UnityChanController」を開き、アニメータービューで右クリック「Create State」「Empty」を選択する
<img width="1013" alt="004.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/a70fb3d2-484e-563c-2e03-25622173bfbf.png">

5.「 Empty」を「UnityChanWalk」に名前を変更する
Motion「RUN00_F」を選択する
<img width="1297" alt="005.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/d224e5a0-6357-25cd-b11e-66d1615bf3d2.png">

6.Unity Chanが走る姿の状態となる。
![run.gif](https://qiita-image-store.s3.amazonaws.com/0/93155/7732a96a-039a-86cc-4cac-89b981019d76.gif)

7.「DirectionScript.cs」を作成し、「unitychan」のコンポーネントに配置する
<img width="1291" alt="007.png" src="https://qiita-image-store.s3.amazonaws.com/0/93155/81fa64c5-868a-8a2a-818e-446ec5048c7f.png">


```c#:DirectionScript
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DirectionScript : MonoBehaviour {

    [SerializeField] float speed = 0.05f;
    [SerializeField] float smooth = 10f;
	
	// Update is called once per frame
	void Update () {
        // Horizontal 横方向移動に指定されたキー
        // Vertical 前後方向移動に指定されたキー
        // キーボードが押される
        Vector3 target = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
        if (target.magnitude > 0.1)
        {
            //体の向きを滑らかに変更する
            Quaternion rotation = Quaternion.LookRotation(target);
            transform.rotation = Quaternion.Lerp(transform.rotation, rotation, Time.deltaTime * smooth);
            //前方へ移動
            transform.Translate(Vector3.forward * Time.deltaTime * speed);
        }
        gameObject.transform.position += target * Time.deltaTime;
    }
}

```
自作左右分離キーボード初心者のすすめ #部品編

# はじめに
[FUN Advent Calendar 2018](https://adventar.org/calendars/2876)の2日目になります。
電子工作初心者に向けて1回目の自作で左右分離型キーボードを作るまでの手助けになればと思います。
今回の部品編と次回の手順編の2部構成でやる予定です。

## ターゲット
- 公立はこだて未来大学所属学生
- 電子工作初心者
- 自作キーボード未経験
- 自作したい分離キーボードがある

# 左右分離型キーボード
左右分離型キーボードの特徴として、通常のキーボードと異なり、キーが右手用と左手用に分かれて配置されています。詳しい話はggりましょう。

# 必要な部品
## 基板
回路を印刷する土台です。
回路が未実装の基板を**生基板**、実装済みのものを**PCB**と言います。
部品として利用されるのはPCBですが、某未来大学には基板加工機が存在するので生基板からPCBを作ることもできます。
生基板の加工には作りたいキーボードの回路データをGitHub等から落としてきて基板加工機を使って実装します。
自作キーボードセットを購入すると大体はPCBの状態で基板が入手できるのでそれを使いましょう。

必要個数は2枚
左右分離型は右用と左用で2枚のPCBが必要になりますが、ほとんどの場合は同じ実装のPCBを裏返して使うので、「全く同じPCBが2枚届いた！」などと焦らないように

## キースイッチ
キーボード選びの醍醐味でもあるキースイッチです。
キーを押したときの感触に影響を与えるのでこだわりましょう。
CherryMXと呼ばれるキースイッチが主流ですが、結構お値段が張るので入手しやすく値段も安いGateronを使ってみるのも良いと思います。

必要個数は自作したいキーボードの詳細を確認しましょう。
はんだ付けに失敗したときや不良品だった場合のことを考えて少し多めに用意しておきましょう。

## ダイオード
電流を一方向に制限するための部品です。
足がついてるものとチップ型の2種類がありますが、足がついている方が初心者にははんだ付けしやすいと思います。

必要個数はキースイッチと同数程度
キースイッチと同様、失敗したときや不良品だった場合のことを考えて少し多めに用意しておきましょう。

## コントローラ(MCU)
キーの入力を検知してPC側に入力データを送信するための変換機のようなもの。
作りたいキーボードの設計図やREADMEに型番が記載されているのでそれを使いましょう。

必要個数は2個

## コネクタ
左右の基板を接続するためのコネクタとPCに接続するためのコネクタの2種類があります。
TRRSジャックやUSB-Cが良く用いられますが、自作したいキーボードのREADMEを確認して選定しましょう

必要個数は2+2個

## タクトスイッチ
大体のキーボードがリセット用に採用しています。とりあえず買っておきましょう。

必要個数は2個

## ジャンパワイヤ
MCUと基板回路をつなげるために利用する場合があります。
10本前後あれば事足りるので誰かからもらっちゃいましょう
[カスカスくん](https://twitter.com/RickGoto)がバラ売りしてくれるそうなので相談してみると良いかも

## アクリル板・MDF
キーボードケースを作るときに使います。
大学のレーザーカッターを用いて簡単に切り出せるので用意しておきましょう。
ケースの設計図は大体の場合、自作したいキーボードのGitHub上にあがっているのでそれを拝借します。
キーボードのサイズやミスプリント時のロスを考えると、実装が完成してからサイズ感を確認して購入したほうが良いです。

# おわりに
本当は**闇の研究に対する防衛術**を書こうと思ってたんですが、僕自身が闇から帰還できていないので急遽キーボードネタに走りました。
以上です、お疲れさまでした。
Alloy Analyzerの開発環境をVSCodeで構築

この記事はGoodpatch Advent Calendar 2018 2日目の記事です。

昨年は仕様記述・検証ツールのAlloy Analyzerでこんな記事を書いてました。
[Alloy Analyzerでデータモデルのプロトタイピング \- Qiita](https://qiita.com/nsyee/items/1f1c2575e3b83bf3a386)
>データモデルの設計も実装の詳細を考える前にプロトタイピングしてアイデアを素早く検証しよう

この時点ではAlloyのセットアップは[公式サイト](http://alloytools.org/download.html)からjarファイルをダウンロードしてくるというちょっと煩雑な手順でしたが、現在ではVSCodeの拡張をインストールするだけで即実行することができます！

- [Alloy \- Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ArashSahebolamri.alloy)
- [GitHub](https://github.com/s-arash/org.alloytools.alloy)

![Dec-02-2018 22-28-22.gif](https://qiita-image-store.s3.amazonaws.com/0/577/069ec3e7-dc17-8989-fcee-0f668ffa2693.gif)

拡張の作者がAlloyのLanguage Server Protocol対応をしていて、ビルド済みのjarファイルが拡張にバンドルされて一緒にインストールされます。
現段階では独自にカスタマイズされたバージョンになりますが、Alloyの本家MLでは本体にマージされる方向で話が進んでいます。
[VS Code extension \- Google Groups](https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/alloytools/moJjuGV3GjQ/lQc3j_cVCgAJ) (要グループ参加)


この拡張は単にAlloyをバンドルしているというだけでなくエディターと協調して動作するよう統合されています。

- ショートカット(`Ctrl+Shift+A E`)やGUI操作によるAlloyコマンドの実行
- インスタンスや反例などの解析結果の表示
- シンタックス/コンパイルエラー表示
- 定義へジャンプ
- 参照を検索
- ファイルをまたいだリネーム
- アウトライン表示 / シンボルへジャンプ

Swingで作られたAlloy付属のエディターは正直使いづらくAlloy布教の障害となっていたのですが、この拡張のおかげで革命的に書きやすくトライ&エラーがサクサクできるようになりました。

環境が整ったところで、次回の投稿でAlloy Analyzerを用いたUI仕様記述に進んでみようと思います（12/9を予定）。
スクレイピングがバレてないか確認できるツールを作った話

# はじめに

皆さん、クローリング/スクレイピングしてますか？　してますね？（威圧確認

スクレイピングする際に気をつけなければならないことの１つに「**BANされないような挙動をする**」がある。

といっても、UA偽装やIP分散など経験のある人には共通認識ですが、慣れないうちだと結局何に気をつけるべきかあまりわからないと思う。

加えて、最近ではJavascriptが実行可能なクローラーでないとほしいデータが取れないサイトも増えてきており、
[puppeteer](https://github.com/GoogleChrome/puppeteer)で対応できるものの、逆にJS側でクローラーかどうか判別されやすくなってしまった。

と、いうことで、スクレイピングする際に、**クローラーであることをなるべく隠蔽できているか確認できる**ツール、「[スクレイピング確認くん](https://scrape.turai.work/)」を作った。

[スクレイピング確認くん https://scrape.turai.work ](https://scrape.turai.work/)

![screenshot-scrape.turai.work-2018.12.02-22-38-20.png](https://qiita-image-store.s3.amazonaws.com/0/107001/5aea7960-155f-2064-91ca-607372d0732c.png)

# なにができるの

このツールでは、

- User-Agent
- Accept-Language
- リモートホスト
- Javascriptの実行可能有無
- スクリーンサイズ
- ウィンドウサイズ

を取得して**通常のアクセスと似たアクセスかどうかを一発で確認できる**。

## puppeteerでアクセスした場合

特にオプションを指定パターン。Accept-Languageが含まれていない、User-Agentに「HeadlessChrome」が含まれてしまっている、ウィンドウサイズがおかしい（小さすぎる）などがわかる。

![result.png](https://qiita-image-store.s3.amazonaws.com/0/107001/6710b6d4-04fa-ce31-3b8b-49f04390f291.png)

ちなみに確認コードは以下

```javascript
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto('https://scrape.turai.work/');
  await page.screenshot({path: 'result.png', fullPage: true});
  await browser.close();
})();
```

## curlでアクセスした場合

キャプチャ非対応でも、 http://scrape.turai.work/json にアクセスするとJSON形式で返却するので確認できる。（jqはJSONの整形に使ってるだけなので必須ではない）

```sh
curl https://scrape.turai.work/json? | jq .
{
  "ua": {
    "name": "User-Agent",
    "status": "NG",
    "value": "curl/7.58.0"
  },
  "accept_language": {
    "name": "Accept-Language",
    "status": "NG",
    "value": null
  },
  "remote_host": {
    "name": "Remote-Host",
    "status": "NG",
    "value": "xxx.xxx.xxx.xxx"
  }
}
```

この場合はUA,Accept-Language未設定なのに加えて、AWSからアクセスしたのでリモートホストをXにしている。

別にAWSとかGCPからのアクセスがNGとは一概にいえないが、普段のアクセスでは本来ありえないので、やはりBANの対象になりやすい、というのは確実にいえる。

[確認先](http://scrape.turai.work/)で説明もつけたのでよかったら見てほしい。

# まとめ

アクセス先に迷惑をかけない範疇で楽しいスクレイピング生活を！（
Slickが出すクエリをなんとかしようとした話

## 前置き

どうも、謎の集団Zeneloの中でSQLとか見てる人です。
普段、クエリレビューなどをして生きているのですが、Zeneloがメインで使っている[Slick](http://slick.lightbend.com/)ってやつが、これまたやんちゃな子で、時々おかしなSQLを出力するのです。
あ、Slickってやつは
http://slick.lightbend.com/
で、O/RMっぽいやつです。
(Slick本家的に言うとF/RM,functional-relational mapperらしく、O/RMではないって強く主張しているので、明日僕は殺されるかもしれない）

## Slickが出してくれるクエリについて

規模の小さいプロダクトだと、多分Slickは何の問題もないのでしょう。

```scala
// priceが10未満で、name順にソートしたcoffeeの名前のみ取り出すクエリを作る
coffees.filter(_.price < 10.0).sortBy(_.name).map(_.name)
// select name from COFFEES where PRICE < 10.0 order by NAME
```
このクエリは[公式ドキュメント](http://krrrr38.github.io/slick-doc-ja/v3.0.out/%E5%B0%8E%E5%85%A5.html)から取ってきました。
ただScalaのコードをScalaらしく書くだけで、綺麗なクエリが出力されます。
さらに型チェックもされたり、インジェクションなどが起きないようになっていたりと、Scalaエンジニアにとって至れり尽くせりとなっています。

しかし、大規模な、4つか5つか以上のテーブルをINNER JOINなどで繋げようとした場合、変な現象が起きます。
ちょっとだけお見せすると、こちら。

---
<img width="526" alt="スクリーンショット 2018-12-02 22.14.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/67255/e16325e1-a885-556f-cda6-538eba123237.png">
---

後述する自作ツールの出力結果なのですが、なかなか香ばしいことになってますよね。
Slickは、大きなクエリになれば、テーブルやカラム名を**全て**、「xの後に数字がつく　(正規表現だと /x(\d)+/)」みたいなやつでどんどん置き換えていきます。
面白い仕組みではありますが、「x139.x152 = x184.x185」みたいなものを見せられて、何と何を比較しようとしているのかわかりません。
また、そのあと**使わないのに、とりあえず置き換えとく**みたいなことをしてくれるので、どこにも使われていない無駄な置き換えが出てきます。
このクエリがSlowQueryとして流れてきたときには、「どっからどう見ればいいんだ・・・」ってなってました。
(ちなみにこのSlowQueryは、整形ツールで見ると294行です。さらに言うと、x213まであります。なかなかの迫力ですよね。)

私はDBやSQLを見るためにこの集団に所属しているので、どんなSQLであっても、このSQLを見る必要があります。
とはいえ僕も一応エンジニア、数回は手で全部パースしてレビューしてってやってみたのですが、疲れたので自動化することにしました。

## 作ったツール

http://s.063.jp/index.html

個人で使うように作ったものなので、ほぼ何の機能もありません。
デザイン？なにそれおいしいの？って感じです。
ただ、asで言い換えているもののうち、使われていないものがあれば削除するだけです。

使い方は簡単で、「Query」ってところにSlickが出してきたクエリを入れると自動でSQLを見て、一度しか出てきていないものを検出してくれるので、チェックボックスを見て全部消しても良さそうなら「Execute」を押すだけです。
もし消しちゃダメな文にチェックボックスがついていればチェックボックスを外し、消してもいいのにチェックボックスがついてなければつけるだけです。
先ほど貼ったクエリもこのツールで見たものです。

例えば以下のように表示されたら、

---
<img width="526" alt="スクリーンショット 2018-12-02 22.37.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/67255/c562e84f-4918-b72f-fd52-46ef9816d2ce.png">
---

「x65.x74 as x75」の「x75」は他でも使われているから必要そうだけど、他のものは使われていなさそうだから消してもいい？
と言うことを表しています。
あとは「Execute」を押して、どんどん行数を減らしていきます。
最後に残るのは、本当に使われているものだけになります。
ちなみにこのクエリ、元を整形したものは294行ですが、このツールを通すことで出されたクエリは、同じ整形ツールで整形すると118行になりました🎉

## このクエリのその後

整形したあと、本当に必要な部分だけをドメイン知識を持った人と改善していった結果、(同じ整形ツールで)22行になって、マージされ、今日も元気に動いています。
もちろんSlowQuery一覧からは消えて、利用者も開発者もハッピーになりました😁

## Slickについての今後

流石に大きくなりすぎたプロダクトで、Slickで頑張っていくのは辛いよねって話になり、最近はPlainSQLに直してくれたりと、どんどん改善が続いています。
Slickが便利なところはSlickで、そうでないところはPlainSQLなどで、って方針でしばらくいくと思いますが、もしかしたらScalikeJDBCなどに載せ替えるかもしれません。(工数的にすごいことになりそうですけど・・・)

## このツールの今後

今後プロダクトに入るクエリについては、もう安心できる程度にZeneloメンバーはSQLについて関心を持って開発していると思っているのですが、まだまだ「昔は(パフォーマンス的に)大丈夫だったけど、今後は・・・」ってクエリの改善活動が残っています。
そこでこのツールを使っていきます。不便だなって思ったら機能追加します。プルリクなども歓迎です。

リポジトリはここ。
https://github.com/Goryudyuma/slick-refactoring-tool

このツールは、謎の集団Zeneloで今ブームな言語、Elmで書かれています。
[大魔王](https://qiita.com/ababup1192)の力は絶大で、その力にあやかったので、このツールも「えいっ」てやればいつの間にかできてました。
ただ、まだ僕の力が足りず、正規表現で頑張っちゃったので、次同じようなツールを作るときは、きちんとParserでやりたいと思います。

## 最後に

この記事は謎の集団zeneloのアドベントカレンダーの三日目の記事として書かれました。
他の記事も是非よろしくお願いします。
https://qiita.com/advent-calendar/2018/zenelo
大切なことはスタートレックから学んだ - 組織の考え方 -

スタートレックは宇宙ステーションが舞台のDS9を除いて、戦闘能力を持つ宇宙船のお話です。登場人物はピラミッド構造の組織に属し、上長の命令は絶対です。

しかし、惑星連邦の理念に反する場合や緊急事態では、命令に反することも行われます。今回は、そんな場面でのピカード艦長の言葉を紹介しましょう。

## きょうのことば
### 「私は命令に従っただけです」という言葉でどれだけほと多くの過ちが正当化されてきたと思う。自分の考えを持たず、ただ命令に従うだけの士官なら連邦には要らない。
　　　　　　　　　　　　　　　　ジャン・リュック・ピカード＠新スタートレック

このような上長の懐の深さが、組織を健全に保つのだと思います。

SRAでも上長に反論するような気骨のある人間を喜ぶ人が少なからずいて、オープンで風通しの良い環境を保っているのだと思います。気骨のある人は、ぜひSRAにお越しください。
大切なことはスタートレックから学んだ - 理念の大切さ -

スタートレックは未知の宇宙を航海するドラマです。未知の文明に遭遇した際に影響を与えてしまわないことが、重要な理念になっています。

そのほかにも惑星連邦憲法があって、裁判を行う際には重要な役目を果たします。しかし、未来においても裁判で不条理な主張をする人間がいます。そこで、ピカードが言った一言。

## きょうのことば
### ｢憲法の基本理念を勝手に覆す事はできない」
　　　　　　　　　　　ピカード@新スタートレック シーズン4 第21話

アジャイル開発が話題になりだした頃、クレド（信条）が話題になりました。会社や組織が同じ方向を向くためには必要なものです。

SRAにもクレドのようなものがありますが、聞く機会も少ないので暗記している人はあまりいないでしょう。とはいっても、その中に「プロフェッショナル集団である」という言葉があることだけは、多くの人が知っています。そのことが技術志向の会社であることにつながっています。

もちろん、SRAにもそうではないと思う人はいるでしょうが、組織の理念は勝手に覆すことはできないのです。