OmniAICreator/Qiita-1.07M huggingface dataset:
Celery4.2.1でタスクにデフォルトのQueueを指定する

[呉高専 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/kurekosen) 1日目の記事です。

今年もこの季節がやってきましたね。なんだか今年は例年より暖かい気がしています。
さて、呉高専の専攻科生のちゃんゆーです。1日目は軽めなお話です。

PythonでジョブキューといえばCeleryが挙げられますが、CeleryのQueue指定方法について書いていきます。

## 目次
- 前提
- タスク実行時にQueueを指定する方法
- タスクにデフォルトのQueueを指定する方法
- Djangoの場合
- まとめ

## 前提
環境は

```
$ pip freeze
celery==4.2.1
```

を想定しています。

公式ドキュメントより、下記タスクを定義しているとします。

```python
from celery import Celery

app = Celery('tasks', broker='pyamqp://guest@localhost//')

@app.task
def add(x, y):
    return x + y
```

[First Steps with Celery — Celery 4.2.0 documentation](http://docs.celeryproject.org/en/latest/getting-started/first-steps-with-celery.html)

なお、以下のQueue、Workerを起動しているものとします。

```
$ celery -A proj worker -Q high
$ celery -A proj worker -Q middle
$ celery -A proj worker -Q low
```


## タスク実行時にQueueを指定する方法
こちらはよく見かける指定方法。

```python
add.apply_async(queue='high')
```

addタスクが、highのQueueで実行されます。


## タスクにデフォルトのQueueを指定する方法
タスクによっては、実行するQueueを固定したい場合もあるでしょう。
その場合は、デコレータに指定してやります。

```python
@app.task(queue="high")
def add(x, y):
    return x + y

add.apply_async()
add.delay() # もちろんdelayでもOK!
```

このことを知らず、呼び出し側から毎度指定していたのですが、その必要もなかったのですね…

この辺よく調べるとドキュメントにもちゃんと書いてありました。
[celery.app.task — Celery 4.2.0 documentation](http://docs.celeryproject.org/en/latest/reference/celery.app.task.html)
ちゃんと読み込む必要ありますね…

## Djangoの場合
DjangoでCeleryを使う場合、以下のように `shared_task` デコレータを使うことが多いと思います。

```python
from celery import shared_task

@shared_task
def add(x, y):
    return x + y
```

この場合、 `@app.task` と同様にQueueの指定ができます。

```python
@shared_task(queue="high")
def add(x, y):
    return x + y

add.delay()
```

## まとめ
今回はCeleryのデフォルトのQueueの設定方法をまとめました。
ちなみに、デフォルトのQueueを指定しても、呼び出し時に指定すると、呼び出し時に指定したQueueが優先されるようです。

それにしても、Celeryって日本語記事ほとんどなくってつらい…


さて、明日はどんな記事が投稿されるのでしょうか！
お楽しみに！
linux kernel 4.19でdocker buildできなくなった

# 追記
4.19.11-arch1-1-ARCHで修正されたようです。
https://github.com/docker/for-linux/issues/480#issuecomment-449306713

# 概要
久しぶりにdocker buildをしようとしたらbuildに失敗しました。
下記のエラーが出てapt-get installができません。

```
dpkg: error: error creating new backup file '/var/lib/dpkg/status-old': Invalid cross-device link
```

# 原因
どうやらlinux kernel 4.19からoverlayの設定に変更があり、metacopyがデフォルトでonになったようです。
https://github.com/docker/for-linux/issues/480

ホストOSのkernelバージョンを確認してみると確かに4.19でした。

# 対処法
とりあえずmetacopy設定をoffにすればbuildは成功しました。

```
echo N | sudo tee /sys/module/overlay/parameters/metacopy
```

ただし再起動すればまたonになってしまうので、起動時に上記コマンドを走らせるようにした方がいいらしいです。

そのうち修正されると思うのでそれまではこの方法で凌ごうと思います。
KUSANAGIについて質問です

kusanagi初心者です。

Wordpressより管理画面→テーマ編集でCSSを編集しようとしたのですが

変更を保存するには事前にこのファイルを書き込み可能にする必要があります。詳しい情報は Codex を参照してください。

というエラーメッセージが出て、変更を保存ができず編集ができません。

検索して調べてみてパーミッションを606や775,777に変更してみても変わりません。

どなたか方法が分かる方、ご教授お願い致しますm(_ _)m
Beatsシリーズへの貢献するには

# はじめに

今年はBeatシリーズに対して個人で貢献することができました。

そこで、Beatシリーズへ貢献するにはどのようにビルドやテストを行えばよいかを書こうとした記事です。

しかし公式がどうすればよいかを文章にまとめてくれていたのでここでは簡単にポイントや私が詰まったところを説明します。

[Contributing to Beats](https://www.elastic.co/guide/en/beats/devguide/current/beats-contributing.html)

~~多分、私が投降した後に作られているので私のプルリクがあまりにも酷かったのが原因かと…~~
~~関係者の皆様ご迷惑をおかけしました(日本語ですみません)~~

# CLAへのサイン

とりあえずプルリクを送る前にまずは、 Contributor License Agreementに署名しましょう。
これを忘れるとプルリクを送っても止められちゃいます。
私は業務では触っていないので個人として署名しました。

# 実行環境

Linux(Ubuntu)を使いましょう。(Macはもっていないので未確認ですが、内容的にはできそうです)
Windows + Docker for Windowsではビルドはできるのですが問題が多く、特にテスト環境で詰まることが多々ありました。
Docker for Windowsはディレクトリのマウント周りが弱く、またウイルス対策ソフトのファイアウォールで邪魔されるなどの問題もありました。
また、Cent OSもテスト用PyhtonとDocker周りの実行がうまくいかず、問題の解消ができませんでした。
あきらめてUbuntuを利用することで解消できました。

参考までに私の当時のビルド環境ですが、Windows 10 Pro Build 1709のHyper-V上でUbuntu Server 16.04を利用しました。
仮想マシンにコア4つメモリ8GBでビルドとテストを行いましたが特に不自由なくできました。

# ドキュメント

何を変更したのか必ずドキュメントに書きましょう。
自分の変更をみんなに知ってもらうチャンスです。
CHANGELOG.asciidocと自分が貢献したディレクトリにあるasciidocファイルです。

# さいごに

簡単になってしまいましたが、公式がまとめてくれたドキュメントがとてもよくできているのでその手順にのっとれば誰でもできます！
[issue](https://github.com/elastic/beats/issues)はたくさんあるので、興味がある人は是非やってみましょう！

明日は@tsgkdtさんの「canvasといらすとやで１つネタを」です。
Cシェルのリダイレクトまとめ

#Cシェルのリダイレクトまとめ
業務都合でcシェルを読んでみたけどリダイレクトがよくわかんなかったので覚書。
記号でググっても検索エンジンは引っ張ってきてくれないからね。


#上書きと追記
これは他のshellと同じ。

```bash:上書きの場合
echo hoge > hoge.txt
```

```bash:追記の場合
echo hoge >> hoge.txt
```

言うまでもない感じ。

#エラー
検索しようにも記号だけでなかなか出てこない曲者。
リダイレクト記号　＋　アンパサンド（アンド）

```bash:
rm hogehoge >& hoge.txt
```

ちなみに出力は以下の通り。

```bash:
cat hoge.txt
rm: cannot remove 'hogehoge': No such file or directory
```

標準出力とエラー出力とかの詳しい記事は以下を参照。とてもわかりやすい！

* [標準入力・標準出力ってなに?](https://qiita.com/angel_p_57/items/03582181e9f7a69f8168)

#noclobber変数が設定されている場合
noclobber変数をSETしているとリダイレクトによる上書き処理（　>　）が禁止される。
（個人で設定している人はあまりいないだろうけど）

その状態でも強制的にリダイレクトによる上書き処理をしてしまいたい場合は以下の通り。
リダイレクト　＋　エクスクラメーション（ビックリ）

```bash
echo hoge >! hoge.txt
```
詳しくは以下の素晴らしい記事に（省略）

* [シェルスクリプトでリダイレクトによる上書き防止](https://qiita.com/b4b4r07/items/3779fc3ab98b918c7711)

#ファイル出力もリダイレクトもしたい！
コマンドteeを使う。

```bash
rm hogehoge |& tee hoge.txt
rm: cannot remove 'hogehoge': No such file or directory
```

出力されたファイルも以下の通り。

```bash
cat hoge.txt 
rm: cannot remove 'hogehoge': No such file or directory
```

以上でした。
【TIC-80】ゲーム作って公開するぞ！（その２）

##一週間でやったこと

- タイトル画面（仮）作成
- ステージセレクト画面作成途中

![week1.gif](https://qiita-image-store.s3.amazonaws.com/0/284455/4466e64c-c72f-1893-fd88-12537f012dc8.gif)


‥‥やばい、全然すすんでない。
いや、ゲーム動画みるのも勉強のうちだから！

そして頭使わなくていい作業「かなドット打ち」をする

![kana.gif](https://qiita-image-store.s3.amazonaws.com/0/284455/b59c80ae-ef88-f03a-3f5d-1470d9fdff83.gif)

日本語表示は優先度低いだルルォ！

とりあえず優先度付きで実施する項目を挙げていく

1. ゲーム（パズル）部分
2. デモ（操作方法説明部分）
3. 音関係
4. かな表示
5. コンフィグ
6. マウス操作

とりあえずゲームモード（タイトル、ゲーム、ゲームオーバーとか）の
切り替えを実装してみた。

ゲーム系（特にゲームエンジン上で作成）の場合、毎フレームよばれる処理（一般的には `Update()` とか？ TIC-80 では `TIC()`関数）があるので、そこから各処理に分岐させる必要がある（多分）

とりあえず以下のように実装。

```gamemode.lua
-- （略）
title=function()
	-- タイトル画面処理
	-- 何かボタン押されたら mode=2
end

stgsel=function()
	-- ステージセレクト処理
end

init=function()
	mode=1
	game={title,stgsel}
end

init()

function TIC()
	game[mode]()
end
```

うーむ、ステージセレクトで決定したステージ数をゲーム処理に引き渡すのはグローバル変数でいいかなあ。TIC-80の仕様上、ほぼ単一ファイルでの実装かつ小規模だから。

とりあえず実装しようそうしよう（残り3週間）
Mysql2::Error::ConnectionErrorの謎を解明！

# **最初に**
アプリケーションを開発している中でプログラマーは時間の半分以上をエラー解決に費やしているといっても過言ではないですよね。その中でも個人的に苦手意識が強い`Mysqlエラー`に遭遇しました。
「なんだ、アクセス権限のエラーか。表示されたユーザとホストに権限を与えることで解決できるだろう」
と思ったのも束の間。。
どハマりしました。。エンジニア歴の長いお友達やcoconalaなどで助けを求めましたが一向に解決に至らず。。
それもそのはず。エラーの原因はまさかまさかのところにありました。。


<img width="1140" alt="Action_Controller__Exception_caught.png" src="https://qiita-image-store.s3.amazonaws.com/0/269862/5718f89c-09cb-2148-9fa6-5cdff4d53431.png">

# **対応**

```
$ unset DATABASE_URL
$ printenv
```
環境変数 `DATABASE_URL` を設定していたために、database.ymlファイルには不備がないにも関わらず、こちらの画面が表示されていたのでした。ですので、上記のように `unset` コマンドで環境変数を解除した後に、　`printenv` コマンドで解除されているのが確認できればOK。

しかし、これで治る場合もあるのですが、
ターミナルでサーバーを常時起動させるためにタブを二つ開いている方は要注意。
サーバーを一度切って、同様のコマンドをこちらのコマンドラインでも実行する必要があるみたいです。

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

[undefined local variable or method `display_meta_tags` for #<#<Class:......>:....>](https://qiita.com/takuyanin/items/c37b9842926a78531ac2)


# **終わりに**
こちらのエラーには数日悩まされました。。
とても疲れましたが、エンジニアリングにエラーはつきものですので、エラー解決をもっと好きになることによって、幸せを掴んでいきたいと思います。
React nativeで作ったアプリケーションを自分のiOSデバイスで動かす

## 必要な物
* Mac
* Xcode
* iOSデバイス

## 1. プロジェクトを開く

自分のReact nativeのプロジェクトの、xcodeプロジェクトファイルを開く。

場所は、React nativeプロジェクト内 `ios` ディレクトリ内に `<プロジェクト名>.xcodeproj` として存在している

## 2. Teamの設定

プロジェクト設定のGeneral(多分初期状態で開かれている？)の `Signing` 内 `Team` が `None` になっているので、設定を行う。

`<自分の名前> (Personal Team)` というのがあると思うので、選択する。

もし無ければ、 **Apple ID の作成**と言う作業が必要かも知れないので、別途ググって作ってください。

## 3. Build

メニュの `Product > Build` にてビルドを行う。結構時間が掛かった（数分）

## 4. お手元のiOSデバイスを接続する

接続したら、メニューの `Product > Destination` より自分のiOSデバイスを選択する。

## 5. プロファイルの信頼作業

画面左上に「再生」ボタンがあるので押す。
画面がロックされているので解除してね。と出たりする。（その場合はロックを解除）

最初、プロファイルが信頼されていないので **エラーする**。
自分のiOSデバイスの設定画面を開き `一般 > プロファイルとデバイス管理` 内に、自分の Apple ID の選択が出てくるので、これを開き `〜 を信頼` する。

## 6. 再度Deploy

再度、再生ボタンを押すことにより、デバイスにアプリがdeployされ、開かれる。(割と時間がかかる)

出来た。 :tada: 
<img width="375" alt="image.png" src="https://qiita-image-store.s3.amazonaws.com/0/13836/7b98c27f-27d5-a767-d9b9-307c7f4366f1.png">
JUCE 5.4.0以降でVST 2.xをビルドするための設定

# JUCEって何？

JUCE (Jules' Utility Class Extensions)は、C++言語によるマルチメディア系アプリケーションの開発を支援するフレームワークです。クロスプラットフォーム設計のライブラリと、付属されているプロジェクトジェネレータ『Projucer』から各種IDE(VisualStudio, Xcode, Makefile)向けにプロジェクトファイルを出力することで、ワンソースからWindows, macOS, Linux, iOS, Android で動作するアプリケーションを作成することができます。
[公式サイト](https://juce.com/)

JUCEの最大の特徴として、オーディオプラグインを開発するためのテンプレートが充実していることが挙げられます。VST/AudioUnit/AAX/RTASプラグインといった、DTMユーザーにはお馴染みのプラグインフォーマットを開発するのに長けており、日本国内外で多くの採用事例があります。
JUCEについてより詳しく知りたい場合は、こちらの記事[JUCE ハンズオン 〜JUCEをはじめよう〜](https://qiita.com/COx2/items/12a48c4a30c49732dcc5)や、[JUCE Advent Calendar 2017](https://qiita.com/advent-calendar/2017/juce)をご覧いただければと思います。

# VSTプラグインとは？

<img src="https://qiita-image-store.s3.amazonaws.com/0/93566/3bdfe3a5-88ae-cd6c-2730-8037003396d3.jpeg" width=30%>

VST(Steinberg's Virtual Studio Technology)とは、ドイツのSteinberg（スタインバーグ）社が提供している仮想音響技術のことです。音源（シンセサイザー）として機能するものはVSTi(VST instrument)とも呼ばれます。C++のダイナミックライブラリで実装され、DAW(Digital Audio Workstation)等のホストアプリケーションに組み込むことができ、フィルタや仮想楽器をシミュレートすることができます。仕様そのものはクロスプラットフォームなC++ライブラリで提供されているため、プラットフォーム上でコンパイルしてしまえば、そのプラットフォーム上で楽器やエフェクターとして使用することが出来ます。

本記事では、そのVSTプラグインを実装するにあたり、より簡単かつGUI用のコンポーネントが充実しているJUCEフレームワークを利用します。

# JUCE 5.4.0からはVST 2.xの出力が非推奨に

Steinberg社がVST 2.x のサポートを終了するのに合わせて、2018年11月にリリースされたのJUCE 5.4.0からはVST 2.xの出力が非推奨扱いになりました。
また、JUCE 5.3.2以前ではJUCEライブラリ内にVST 2.xのCインターフェースを定義したクラスが同梱されていましたが、そのクラスも取り除かれるようになりました。
JUCEとしては非推奨ではあるものの、Steinberg社から個別にライセンスを受けることでVST 2.xを出力することができます。
具体的には、旧バージョンのVST SDKを入手し、Projucerのライブラリパスを設定することでVST 2.xを出力することができるようになります。
※本記事では、旧バージョンのVST SDKを所有していることを前提として解説していきます。

# グローバルパスの設定
Projucerのメニューバーから[File]->[Global Paths...]を選択します。
![globalpath.png](https://qiita-image-store.s3.amazonaws.com/0/93566/43a5220f-31d1-2576-e368-1514ab421650.png)

Glopal Paths設定画面のうち、`VST(Legacy)SDK`の項目を設定します。
![globalpath2.png](https://qiita-image-store.s3.amazonaws.com/0/93566/1c388c65-38da-6f8e-be8b-82848bf5dc0e.png)

旧バージョン(3.6.10以前)のVST SDKに含まれるフォルダーから`VST2_SDK`フォルダを選択してOKを押します。
![vst2sdk.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/6bc39a26-ce6e-cb97-b0c5-1e4b9fb9b042.png)

プロジェクト設定の[Plugin Formats]の項目にチェックを入れてプロジェクトを保存する。
![vst2check.PNG](https://qiita-image-store.s3.amazonaws.com/0/93566/8171c910-29be-da9e-c709-e1b241d9ba9d.png)

ここまでの設定を行ったら、後は通常通りプロジェクトをビルドするだけでVST 2.xのdllファイルが出力されるようになります。
新規登録フォームの作り方

#はじめに
前回は[PHPで掲示板](https://qiita.com/hengineery/items/481616ee1ac1385c0877)を作りましたが今回は登録フォームを作っていこうと思います。

#環境
PHP 7.2.1
MAMP
MySQL

#作業
#####1.フォームを作成
<img width="489" alt="index1.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/e4468fe1-e2e7-1ae0-cc1a-98248e5a278f.jpeg">

ローカル環境で表示すると
<img width="297" alt="register1.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/1c300959-1658-32df-9125-8db3ba4758a4.jpeg">

はい、シンプル

#####2.入力のチェック
<img width="553" alt="index2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/b68d0321-d093-7f6f-6b41-d08c9de78895.jpeg">
というわけで、PHPで追記

まず、`mysqli_connect`でDBへ接続し、ダメなら`mysqli_connect_error`でエラーを表示。接続できた場合は`array_key_exists`で`$_POST`にemailとpasswordが入ってるか確認し、空の場合は`echo`で入力してくださいと表示。

emailだけ入力した場合
<img width="293" alt="register2.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/d9378be8-9700-4ea4-2780-10c6bae1461c.jpeg">
passwordだけ入力した場合
<img width="287" alt="register3.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/43d3bb74-e956-96a8-ee29-fccae51d0f80.jpeg">
ちゃんと表示されてます。

#####3.メアドの重複チェック
<img width="767" alt="register4.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/fc6eadc9-bb75-96e1-acea-3a0f4cd16cae.jpeg">

というわけで、赤線枠を追記

まず、変数`$query`に`$_POST`の中にあるemailをDBから格納し、その結果を`$result`に格納。そして、もし`$result`にあるデータが0より多ければ`echo`で表示

<img width="299" alt="register5.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/0f914fb8-33ac-7504-f939-4af0828846ba.jpeg">
すでにDB内にあるメアドとパスワードを入力するときちんと表示されました。


#####4.ユーザー登録
<img width="833" alt="index3.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/bfc1b095-365e-439b-c1ee-fca6035ec1c4.jpeg">

まず、`$query`に`INSERT INTO`関数を使って`$_POST`にあるemailとpasswordをusersフォルダーにあるemailとpasswordに挿入するように命令して、`mysqli_query`関数で返ってきたものを`echo`で表示する。
<img width="295" alt="register6.jpg" src="https://qiita-image-store.s3.amazonaws.com/0/320494/e9d4bd38-2498-874e-8a15-b13ff1e56ccf.jpeg">

ちゃんと登録されました。

###おわり
SeleniumでWEBゲームのテストにかかるテスター工数は0にできるのか

本記事は[ゲームのソフトウェア品質向上アドベントカレンダー](https://qiita.com/advent-calendar/2018/testkaizen)の2日目の記事として執筆しています。

##WEBゲームのテスト
私の会社ではWEBゲームをまだまだ絶賛提供中なため、そのテストの需要も存在します。
（ガチャ引いて、デッキを組んで、クエストを進んでボスを倒して…ガラケーでもできて…といったタイプのゲームです）

WEBゲームのテスト環境はPCのブラウザ＆実機（スマホやガラケー）の組み合わせが主流で、テスターさんたちは日々ガチャを繰り返したり、イベントを何度もクリアしたりしながら挙動や仕様がおかしくないか検証して、ゲームの品質維持に努めてくれています。

PCのブラウザで繰り返しの検証を行っていると聞くと、導入したくなるのが**ブラウザ自動操作ツールのselenium**です。
ブラウザ自動操作でテストが行えれば、テスターさんの工数の大幅削減が期待できますが…。
本記事では、私の測定したWEBゲームへのselenium導入効果について記載していきたいと思います。

なお、実際のコードやら技術的な話は素晴らしい先行記事がたくさんあるので、そちらをご参照ください…

##結論
**seleniumではWEBゲームのテスター工数は0にできません**

##理由と検討内容
大きな理由としては、以下の二つが挙げられます。

- **実機の確認は無くせない**
- **WEBゲームの構造がselenium検証に適していない**

まず第一に、環境差異を考えると実機の確認は削れません、という点が挙げられます。
例えば、**ガラケーの低い解像度で画像が問題なく表示されるか…等の環境依存の問題**は、実機でないと確認できません。

次に、**そもそもWEBゲームがseleniumでのテストに適した作りをしていない**といった点が挙がります。
seleniumにWEBブラウザの操作をしてもらうには、触ってほしいWEBページの要素の情報と、やってほしい操作をスクリプト化して教えてあげる必要があります。

![google.png](https://qiita-image-store.s3.amazonaws.com/0/320947/0e7a2197-5564-9681-fe01-a4542ca2ce69.png)
この画像はGoogle検索画面のページ構成なのですが、例えば検索文字列を入れるフォームには、「q」という名前が割り振られています。
例えば、seleniumでここに文字を入れてほしい場合には、「qという名前の場所に○○という文字列を入れて」といった形でスクリプトを書いてあげます。

つまり**やってほしい操作が複数ページにまたがり、バリエーションが豊富なほどスクリプトを作る手間が増えてしまう**のですが…
WEBゲームでは同じ構造のページでも、中の要素の情報がバラバラだったり、イベントごとに全くページ構造が違ったものがリリースされてきたりするので、
**スクリプトを作る工数＞人力でテストを行う工数**
となってしまう可能性すら出てきてしまいます…。

じゃあSeleniumで検証しやすいページ構造にしてもらえばいいのでは？と言う疑問も出ると思うのですが、
これから新しく作るゲームならばともかく、長年運用しているゲームの構造を変えるというのは、予期せぬ不具合につながる危険性を孕んでおり、一筋縄ではいきません…。

これらの理由から、seleniumでテスター工数は0にできないという結論に結びつきます。
そしてそもそも、seleniumは導入できるのか？という疑問も浮かび上がってきますね。

##WEBゲームのテストにseleniumは導入できないのか？
ここも結論から述べると、selenium導入余地がある部分は存在します。
例えば同じ施策内で何度も繰り返し同じ作業をする必要があるもの…
真っ先に思い浮かぶのは**ガチャ**ですね。
##seleniumを使ったガチャの検証
ガチャについては、人力で検証するよりもseleniumで検証することがむしろ望ましいと思われます。
特にseleniumが優位性を発揮できるのは、以下の2点でしょう。

- **繰り返し処理が必要である**
- **排出結果をテキスト化して機械的に処理できる**

ガチャの検証では、ガチャ自体の正常動作の確認のほかに、排出内容の検証や、ガチャ実行時のおまけの検証が含まれます。
全ての排出対象アイテムが獲得できることを検証する必要がある場合や、おまけをもらうまでに膨大な回数のガチャを実行する必要がある場合、seleniumによる繰り返し処理が活きてきます。

また、排出内容の目視確認は見落としのリスクがありますが、テキストベースであればselenium自身の機能で情報を取得し、任意のプログラミング言語でテキストファイル化してあげれば、VBA等の後続処理でデータとして取り込み、機械的に処理することができます。

排出結果が画像ベースの場合は難易度は上がってしまいますが、pitaliumなどの画像解析ライブラリを用いることで対応が可能です。

このように、ガチャの検証においてはselenium導入の余地があると言えるでしょう。

##まとめと今後の課題
今回の検討結果としては、

- **seleniumはWEBゲームのテスター工数を0にする魔法のツールではない**
- **ただしガチャなど強味がいかせる部分もある**

ということがわかりました。

実際にガチャの自動実行ツールについては既に実装しており、ある程度の効果は見込めています。
今後の課題としては、さらなる導入余地の検討とともに、開発サイドとの連携を深めて、自動化しやすい構造を作り上げていくことだと思いました。

##参考資料

・沢山あるselenium系ツールを解説しているブログ
[Selenium何とかっていうツールがやたら色々あるのはどういうわけなのか](https://blog.trident-qa.com/2013/05/so-many-seleniums/)
・seleniumの使い方解説サイト
[Seleniumの仕組み](https://app.codegrid.net/entry/selenium-1)
Laravelで外部サイトにリダイレクトさせたい

# 結論
```php5
return redirect()->away('https://www.google.com');
```

# コメント
なんでこんなに簡単なのに調べるのに苦労してしまいました。自分のGoogle力がダメダメです。。
ちゃんと公式ドキュメントは読みこもうと誓った一日でした。
【論文まとめ】DropBlockについて

DeepLearningが深い層でも学習に成功した一つの理由としてDropoutが有名です。それを改良し精度を向上させた**DropBlock**という手法の論文を紹介します。

- 論文
  - **DropBlock: A regularization method for convolutional networks[^1]**
- Conference
  - NIPS2018
- Reference
  - [arXiv:1810.12890 [cs.CV]](https://arxiv.org/abs/1810.12890)


この記事は、Wantedlyの勉強会で取り上げられた論文・技術をまとめたものです。
[2018年に読んだ機械学習系論文・技術まとめ at Wantedly](https://qiita.com/advent-calendar/2018/wantedly_ml)

## どんなもの？
Google Brainチームが書いた論文で、NIPS2018に採択されました。

Deeplearningが深い層でも学習に成功した一つの理由としてDropoutが有名です。
Dropoutは、ランダムにユニットの値を使えなくすることで過学習を防ぎ、汎化性能を向上させる効果がありますが、全結合層で特に有効でConvolution層ではあまり有効ではないという報告があります。[^2]
この論文ではその理由を、**Convolution層では空間的に隣り合ったユニットは共通の情報を多く共有しており、情報の相関があるため**と指摘しています。
![[^1]より引用](https://qiita-image-store.s3.amazonaws.com/0/64964/8d88c814-7f90-bb79-bcb1-81638b76f82c.png)

DropBlockではこれを防ぐための素朴な解決法として、Feature Mapで空間的に連続する$block\\_size * block\\_size$の領域をランダムに使えなくします。（下の例では5*5）
![[^1]より引用](https://qiita-image-store.s3.amazonaws.com/0/64964/55a677f7-34bb-5fca-8eaf-3287be7c2280.png)

実験結果から、Classification、Object Detection、 Semantic Segmentationと言った複数の画像処理の問題に対して精度が向上しています。

## 先行研究と比べてどこがすごい？
発想が似た手法として、Cutout[^3]という方法があります。画像の一部をマスクしてその領域の平均値で埋めるものでData Argumentationとして使われます。
この論文では、Cutoutと比べても精度が向上していると報告しています。
Cutoutは最初の入力画像で情報を隠し、Dropblocはネットワークの途中のFeature Mapで情報を隠すとすると、途中のFeatureMapでも隠すほうが効果があるようです（組み合わせたらどうなるんだろう？）

## 技術や手法のキモはどこ？
こう書くと単純で素朴な手法でうまく行ったように見えますが、実際はいくつかの工夫が必要だったように読み取れます。

- Scheduled DropBlock
    - ランダムに消す割合が大きいと学習初期でうまくいかない。学習の初期では$keep\\_prob$を1.0（ほとんど消さない）からスタートして徐々に下げていく（消す割合を増やす）というスケジューリングが有効。
- Dropoutよりもパラメータが必要
    - Droblockを入れる場所はどこが最適でしょうか？自明ではないため実験によって決定しています。
    - どのくらいの領域をZERO値にするか？これも潤沢な計算量があるため、実験を行いResnet-50に対しては$block\\_size=7$が最適だとわかりました。

## 読んでみての感想
**自分なりの解釈**： 画像の中に犬がいるとき、その犬らしさは本来は頭でも胴体でも尻尾でもわかってほしい。ただ今の多くのネットワークは、一番当てやすい頭だけを見てそこの情報だけから犬と当てている。問題を解くにはそれが一番効率的だから。Dropblockはランダムに連続する領域をDropするので、Convolution層の中で犬の頭に強くActivateしている領域全体がDropされるかもしれない、そのときは胴体とか尻尾の部分からも当てなくてはならないという難しさを課している。

問題と解決方法が素朴なアイディアで、やってみて上手くチューニングしたらうまくいったという印象でした。同時にまだDeeplearningが上手く解決できていない部分があることを感じさせるものでした。上手く動かすためにはいくつかのパラメータを探索して最適値を探さないと行けない悩ましさがあると感じます。

[^1]: [DropBlock: A regularization method for convolutional networks](https://arxiv.org/abs/1810.12890)

[^2]: [Deep Residual Learning for Image Recognition](https://arxiv.org/abs/1512.03385)
[^3]: [Improved Regularization of Convolutional Neural Networks with Cutout](https://arxiv.org/abs/1708.04552)
MIPSのコード

gcc4が吐き出したコード

```
00000090 <main>:
  90:   3c1c0000        lui     gp,0x0
  94:   279c0000        addiu   gp,gp,0
  98:   0399e021        addu    gp,gp,t9
  9c:   27bdffe0        addiu   sp,sp,-32
  a0:   afbf0018        sw      ra,24(sp)
  a4:   afbc0010        sw      gp,16(sp)
  a8:   8f840000        lw      a0,0(gp)
  ac:   8f990000        lw      t9,0(gp)
```

PIC(Position Independent Code)なコードなのでリンク時にgpなどの値が入る

ldでリンクしたコード

```
800010b0 <main>:
800010b0:       3c1c0001        lui     gp,0x1
800010b4:       279ca060        addiu   gp,gp,-24480
800010b8:       0399e021        addu    gp,gp,t9
800010bc:       27bdffe0        addiu   sp,sp,-32
800010c0:       afbf0018        sw      ra,24(sp)
800010c4:       afbc0010        sw      gp,16(sp)
800010c8:       8f848018        lw      a0,-32744(gp)
800010cc:       8f99802c        lw      t9,-32724(gp)
```

gpが0x0001a060でそれからアクセスする800010c8で落ちる。

そもそもリンク時にワーニングが出る。

```
mips-ld: Main.o: warning: linking PIC files with non-PIC files
```

-mno-abicallsを付けてコンパイルするとこんなコード

```
80001098 <main>:
80001098:       3c048000        lui     a0,0x8000
8000109c:       27bdffe8        addiu   sp,sp,-24
800010a0:       afbf0010        sw      ra,16(sp)
```

これだとワーニングが出なくて動く。

なんでPICでリンク時にgpが狂うのかな。。。
AWS WordPress(Bitnami) にFTP接続する方法

# 前提

AWSのインスタンスで、WordPress Certified by Bitnami を作成している。

***※手順の途中で、EC2インスタンス作成時に作った、鍵ファイル（\*\*\*.pem）が必要になります。***

※この記事では、FileZillaを使用しています。

# 手順

1. FileZillaを起動
2. ファイル→サイトマネージャー→新しいサイトをクリック
3. 各情報を入力
    - プロトコル：SFTP
    - ホスト：EC2インスタンスのグローバルIP
    - ポート：（空）
    - ログオンタイプ：鍵ファイル
    - ユーザー：ubuntu
    - 鍵ファイル：作成していた鍵ファイル（**\*.pem）
4. 接続をクリック
![4.jpg](https://qiita-image-store.s3.amazonaws.com/0/227525/4b5fd214-cf3d-2784-0457-21f52c10ad8e.jpeg)

# 雑感

下手にレンタルサーバーを借りるより、早く、安く、フル権限のwordpressを構築できる。最安400円/月（EC2 300円/月[t2.nano 3年契約]、独自ドメイン 1200円/年）。構築時間は、EC2インスタンス10分、FTP設定10分（＋独自ドメイン設定10分）。
Alpine LinuxにnvmをインストールしたDockerイメージの作成

Docker for WindowsでAlpine Linuxにnvmをインストールしたイメージを作成します。
作業環境と作成するDockerイメージの内容は以下になります。

#### 作業環境
* Windows10 pro
* Docker for Windows

#### 作成するDockerイメージの内容
* Alpine Linux
* nvm : v0.33.11

また、今回作成したDockerfileはこちらで公開しています。
[https://github.com/iida-teco/alpine-nvm](https://github.com/iida-teco/alpine-nvm)

# NVMのインストール
まずは、nvmをインストールする手順を確認していきます。
Alpine Linuxの最新版をベースイメージに使うので以下のコマンドで起動します。

```powershell
PS C:\> docker run --rm -it alpine:latest
/ #
```

これで、Alpine Linuxのコンソールになったと思います。

次に、NVMのインストールですが[公式ドキュメント](https://github.com/creationix/nvm#installing-nvm-on-alpine-linux)の手順通りに入れます。
まずは、ビルドに必要なパッケージをインストールしていきます。

```console
/ # apk update
/ # apk add --no-cache curl bash ca-certificates openssl ncurses coreutils python2 make gcc g++ libgcc linux-headers grep util-linux binutils findutils
```

また、インストールスクリプトの最後でnvmの環境変数を`.bashrc`に追記してくれるのですが、パッケージをインストールしただけでは`.bashrc`が作成されないので、あらかじめ作成しておいてから、インストールスクリプトを実行します。

```console
/ # touch ~/.bashrc
/ # curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
```

これでnvmがインストールされたのでバージョンを確認します。

```console
/ # bash
bash-4.4# nvm --version
0.33.11
```

ちゃんと入っていますね！

## Dockerfileの作成
では、上記の手順をもとにDockerfileを記述していきましょう。

```dockerfile:Dockerfile
FROM alpine:latest
RUN \
    apk update && \
    apk add --no-cache curl bash ca-certificates openssl ncurses coreutils python2 make gcc g++ libgcc linux-headers grep util-linux binutils findutils && \
    touch ~/.bashrc && \
    curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
```

DockerfileをおいているディレクトリまでPowershellもしくはコマンドプロンプトで移動して以下のコマンドを実行します。

```powershell
PS C:\> cd C:\works\docker\alpine-nvm
PS C:\works\docker\alpine-nvm> docker build -t alpine-nvm .
```

これでDockerイメージが登録されていると思います。

```powershell
PS C:\works\docker\alpine-nvm> docker images
REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE
alpine-nvm                 latest              b7c4edde3e8c        About an hour ago   208MB
```

以上で、Alpine Linuxにnvmをインストールしたイメージが出来上がりました！

今回作成したDockerfileはこちらになります。
[https://github.com/iida-teco/alpine-nvm](https://github.com/iida-teco/alpine-nvm)

また、Docker Hubでも公開しています。
[https://hub.docker.com/r/iidateco/alpine-nvm/](https://hub.docker.com/r/iidateco/alpine-nvm/)

## 参考にしたサイト
[GitHub : creationix/nvm #Installing nvm on Alpine Linux](https://github.com/creationix/nvm#installing-nvm-on-alpine-linux)
WSL Ubuntu上でのnpmパッケージ インストール高速化

WSLでのnpm installとかyarnがもっさりして遅いのはWindows Defenderが原因。

# 高速化手順（1）
1. 「PC設定」から「更新とセキュリティ」を開く
2. 左メニューの「Windows セキュリティ」を選択
3. 右の一覧から「ウィルスと驚異の防止」を選択
4. 新規ウィンドウから「ウィルスと驚異の防止の設定」を選択
5. 下部にある「除外」を選択
6. 「+除外の追加」を選択
7. 以下の「先頭ドライブ」と「ユーザー名」を自分のものに置き換えて追加

__WSL Ubuntuのディレクトリパスを追加__
C:\Users\ユーザー名\AppData\Local\Packages\CanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgsc

※Ubuntu OS以外も同様の手順でOK

## 高速化手順（2）
高速化手順（1）の 4 以降に出る「リアルタイム保護」をオフにする。
※脆弱化するので注意

## 参考にしたURL
https://medium.com/@leandrw/speeding-up-wsl-i-o-up-than-5x-fast-saving-a-lot-of-battery-life-cpu-usage-c3537dd03c74
AssetsCatalogのColorSetをStoryboardで指定するとviewDidLoadで色が変更されない

# はじめに
表題の通りです。
ハマったので共有します。。。

# 現象
<img width="869" alt="スクリーンショット 2018-11-30 20.13.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/110630/db91c89c-d3da-8cb0-ba0b-1513100be9af.png">
<img width="929" alt="スクリーンショット 2018-11-30 20.14.31.png" src="https://qiita-image-store.s3.amazonaws.com/0/110630/158a95e3-4e7e-31f7-ab79-002accd092fe.png">

AssetsCatalogで作成したColorSetをstoryboardで指定します。
上記画像ではViewControllerのviewに作成した色を指定しています。

```swift:ViewController.swift
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        self.view.backgroundColor = .red
    }


}
```

viewDidLoadで背景色を赤に変更してみましたが、緑のままでした。。。

# 解決?

メインスレッドで非同期実行することで色の変更は出来ました。

```swift:ViewController.swift
class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        DispatchQueue.main.async {
            self.view.backgroundColor = .red
        }
    }


}
```

# さいごに

どなたか理由や対策をご存知の方がいらっしゃったら教えてください。。
↓
コメントにて解説いただけました！ありがとうございました。
また、海外にもまとめている方がいらっしゃいました。
https://devblog.xero.com/managing-ui-colours-with-ios-11-asset-catalogs-16500ba48205
clickではじめる社内コマンドツール -その1-

業務中に繰り返し行う作業を社内コマンドとしてまとめています。
その中で共有できそうな知見がいくつか出てきたので[SENSY Advent Calendar 2018](https://qiita.com/advent-calendar/2018/sensy)で数回に分けて紹介していきます。
第一回目は、CLIツール作成のために利用しているPython製ライブラリの[click](https://click.palletsprojects.com/en/7.x/)を紹介します。

* 第ニ回目: [サブコマンドの作り方](https://qiita.com/rhoboro/items/a9aa1fb0ae439dd74a31)

## clickの紹介

clickは、[Flaskをサポートするため](http://click.palletsprojects.com/en/7.x/why/)に作られたCLI作成ライブラリです。
CLIツール作るなら絶対これ！ってくらいめちゃくちゃおすすめです。

個人的には下記のような点が気に入っているためよく使っています。

* ミニマルに始められる
* デコレータでコマンドやオプションを増やせる
* サブコマンドも作れる
* 対話形式やエディタの起動も簡単

### 最小限のコードで始める

[ドキュメント](https://click.palletsprojects.com/en/7.x/)の出てくるコードを参考に最小コードを書くとこのようになります。

```python
import click

@click.command()
def cli():
    click.echo('Hello World!')

if __name__ == '__main__':
    cli()
````

たったこれだけでCLIツールができあがります。素敵ですね。

```sh
$ python hello.py
Hello World!
```

オプションを追加するのも1行追加するだけでとても直感的です。

```python
import click

@click.command()
@click.option('--name', '-n', help='The person to greet.')
def cli(name):
    click.echo(f'Hello {name}!')

if __name__ == '__main__':
    cli()
```

動作結果はこちら。

```sh
$ python hello.py --name rhoboro
Hello rhoboro
$ python hello.py -n rhoboro
Hello rhoboro
```

## setup.pyでコマンド化

せっかくCLIツールを作ったのにいつも`python hello.py`と打って起動するのは少し面倒ですよね。そこで`setup.py`を書いて`pip install`できるようにしましょう。

下記は[ドキュメントにあるコード](https://click.palletsprojects.com/en/7.x/setuptools/)をコピペして名前を変えただけです笑

```python
from setuptools import setup

setup(
    name='hello',
    version='0.1',
    py_modules=['hello'],
    install_requires=[
        'Click',
    ],
    entry_points='''
        [console_scripts]
        hello=hello:cli
    ''',
)
```

さきほど作った`hello.py`とこの`setup.py`を同じディレクトリにいれて`pip install`します。pipの`-e`オプションはコードの修正を即時反映するためのオプションです。開発中は利用しておくと便利です。

```sh
# ここでは仮想環境を用意してグローバルへのインストールを避けてます
$ python3 -m venv venv
$ . venv/bin/activate
# インストール
(venv) $ pip install -e .
(venv) $ hello -n rhoboro
Hello rhoboro!
```

`hello`だけで動くようになりました！素晴らしい！

## コマンドの補完

ありがたいことにbashとzshであればコマンド補完も簡単に実現できます。ちなみに、コマンド補完はインストールしている時のみ利用できます。
詳細は[ドキュメント](https://click.palletsprojects.com/en/7.x/bashcomplete/)にありますが下記を書くだけです。

* bashなら`.bashrc`に`eval "$(_HELLO_COMPLETE=source hello)"`
* zshなら`.zshrc`に`eval "$(_HELLO_COMPLETE=source_zsh hello)"`

ここではevalを直接実行して一時的に有効化して試しています。

```sh
# .zshrcに書くのがいい
$ eval "$(_HELLO_COMPLETE=source_zsh hello)"
$ hello -n<TAB>  # これで　ame 　が補完されます
```

## まとめ

今回はclickの紹介をしました。
次回からはシリーズとして実際にclickを使っていく中でためた知見を共有できればと思っています。次回はまずサブコマンドの作り方を中心に紹介します。
clickは使ってみると本当に簡単で便利なので是非作ってみてください。
ブロック要素

#ブロック要素
・見出しh1～6や段落のこと
・ひとかたまりとなる要素
・要は箱
・横幅を指定してあげないと基本100%となる
・高さ「　**height**　」と余白「　**padding**　」を指定することができる

```ruby:html
<div>
	<a href="～～.com"><img src="画像の置き場所" alt="画像説明"></a>
</div>
```
##主なブロック要素##
|コード|内容|
|:--|:--|
|div|入れすぎるとみっともないけどかなり便利なディブ子ちゃん。この子自体に意味はない|
|h1～h6　　　|見出し|
|header|ヘッダー|
|main|メイン|
|footer|フッター|
|section|メニューやサイドメニュー等|
|article|記事にしたい文章|
|p|段落|
|hr|罫線|
|table|テーブル|
|ul,ol,dl|リストたち|

###CSSで指定してあげることによってインライン要素もブロック要素として扱うことができる
・classまたはidまたはブロック要素に効かせてあげる
「　**display:block;**　」

```ruby:html
<p class="display">test</p>
```

```ruby:CSS

.display{
display: block;
height: 100px;
padding: 10px;
}
```
###基本的に横並びにはできない
・基本横幅100%だから
・どうしてもしたかったら「　**float**　」を使ってあげる

```ruby:css
.display{
display: block;
float: left;
height: 100px;
padding: 10px;
}
```
Rails で Gravatar を使ってみる

### Gravatar って何？

様々な方が書かれているので、本記事では、詳しくは書きません。

- [Gravatar API の使い方](https://qiita.com/kaznmb/items/e010ba2eeeba62250f1a#gravatar%E3%81%A3%E3%81%A6)

slack.com, github.com 
様々なところで活用されています。

# Rails で Gravatar を使ってみる

公式のサンプルコード： <https://ja.gravatar.com/site/implement/images/ruby/>

```ruby
require 'digest/md5'
 
# email に含まれる大文字を、小文字にする
email_downcase = email.downcase
 
# MD5値を取得
hash = Digest::MD5.hexdigest(email_downcase)
 
# URLを作成
image_src = "https://www.gravatar.com/avatar/#{hash}"

# URLを作成 (デフォルトと、レーティングをした場合)
image_src = "https://www.gravatar.com/avatar/#{hash}?r=g&d=mp"
```

```ruby
# == Schema Information
#
# Table name: users
#
#  id               :bigint(8)        not null, primary key
#  email            :string           not null <- not null制約も設けているので、下で1行で書いてますが、丁寧に書いてあげた方がいいと思います。
#

require 'digest/md5'

class User < ApplicationRecord
  def avatar_url
    "https://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(self.email.downcase)}?r=g&d=mp"
  end
end
```

## 様々なURLパラメータ

### 1. レーティング 
`rating` または、 `r` で、 [映画](https://ja.wikipedia.org/wiki/%E6%98%A0%E7%94%BB%E3%81%AE%E3%83%AC%E3%82%A4%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0#G)にもある[レイティングシステム](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%82%A4%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0#%E6%80%A7%E7%9A%84%E8%A1%A8%E7%8F%BE%E3%81%AA%E3%81%A9%E3%81%AE%E6%A4%9C%E9%96%B2)が用意されている。

`g` （General audiences?） : 誰が見ても大丈夫（本当か？)。
`pg` （Parental guidance suggested?） : 低俗なジェスチャー、挑発的な服装をし、軽度の暴力が含んまれるコンテンツである可能性がある。
`r` （Restricted?） : 日本語にするのが厳しいので、原文： *may contain such things as harsh profanity, intense violence, nudity, or hard drug use*
`x` (Extreme?) : 日本語にするのが厳しいので、原文: *may contain hardcore sexual imagery or extremely disturbing violence.*

通常使うのは、 `g` で、 `r=g` とするのが良いのではないでしょうか。

### 2. デフォルトの画像
`default` または、 `d`* で、gravatar.comにて登録されていないemailだった場合に返却する画像ファイルのURL。

urlでの指定の他に、

`mp` (mystery-person) : ![i](https://www.gravatar.com/avatar/00000000000000000000000000000000?d=mp)
`identicon` : ![i](https://www.gravatar.com/avatar/00000000000000000000000000000000?d=identicon)
`monsterid` : ![i](https://www.gravatar.com/avatar/00000000000000000000000000000000?d=monsterid)
`retro` : ![i](https://www.gravatar.com/avatar/00000000000000000000000000000000?d=retro)
`robohash` : ![i](https://www.gravatar.com/avatar/00000000000000000000000000000000?d=robohash)

が指定できます。


### API のドキュメントについて

[Image Requests - ja.gravatar.com](https://ja.gravatar.com/site/implement/images/)


#### gravatarのアイコンを使いたい時のURL

非公式です。

![gravatar image](https://www.gravatar.com/avatar "gravatar")
<https://www.gravatar.com/avatar>

### ちなみに
gravatar.com 利用しやすくするための GEM もあります

- [gravtastic | RubyGems.org](https://rubygems.org/gems/gravtastic)
Macのターミナルで複数ディレクトリの中の一つのファイルだけコピーしたかった物語

# 動機

複数ディレクトリの中にある複数ファイルからファイルをひとつだけ取り出して別ディレクトリにコピーしたいと思いました。Macで。なるべく無駄なく。

# 結論

ディレクトリ構造が``directory/subdirectories/files.txt``だった場合。

```sh
echo directory/* | xargs -n 1 sh -c 'find $0 | sort | head -n 2 | grep .txt | xargs -I{} cp {} toDirectory/'
```

# キモ

まず、``echo directory/*``でサブディレクトリだけ表示させます。
それを``xargs -n 1``でひとつづつ次のコマンドに渡します。
で、サブディレクトリの中身をfindして、今回はアルファベット順で先頭になるファイルだけ用いたかったので、``sort``をかけます。そして、``head -n 2``で先頭2行だけを取得。1行目はサブディレクトリ名、2行目はアルファベット順で先頭になるファイルです。今回ファイル名には``.txt``の拡張子がついているので、``grep .txt``でそれを抜き出します。ここは``head -n 2 | tail -n 1``でもいいです。
それをさらにxargsに渡して、こんな感じに変数を作ってcpに渡します。
ここ、普通にGNU cpなら``xargs cp --target-directory=toDirectory``でいいのですが、Macのcpは実は``--target-directory``および``-t``オプションがないらしいのです。なので、こんな書き方をするそうです。

# 参考ページ
http://web.sfc.wide.ad.jp/~sagawa/gnujdoc/coreutils-5.0/coreutils-ja_2.html#SEC6
https://lukesilvia.hatenablog.com/entry/20081026/p1

# 募集
もっとこんな風に書けるよ、というものがあったらぜひ教えてください。
温度データSlack投稿システムを「５分」で作ってみた！

[Slack Advent Calendar 2018](https://qiita.com/advent-calendar/2018/slack) 2日目です！
先日[Slackとボタンスイッチセンサーで「呼び出しシステム」を作ってみた！](https://qiita.com/mikawan/items/ac196bbb5506a3251c55)
を投稿したのですが、今回は温度データをSlackに簡単に投稿します！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/247209/b60918fd-5e18-18a8-36e0-e1f4f28326ee.png)
作るのは５分でやっちゃいます:sunglasses:

ただ単に温度だけ表示するより、暑いときには別のメッセージが出るようにしたいと思います！

|条件|投稿コメント|
|:---|:---|
|２８℃以上|○○度です。暑いですね・・・。|
|２０℃以下|○○度です。寒いですね・・・。|
|それ以外|○○度です。|

とコメントを変えてみたいと思います！

#準備するもの
■実機
WindowsPC
Gravioレンタルデバイスの温度データ

■サービス
[Gravio](https://www.gravio.com/jp/gpromo/1901-casual-iot)　（インストールが必要）
・Gravio Studio Version　2.0.2000
・Gravio Server Version　2.0.1997
Slack（トークンまで事前準備）

以上です。

え？これだけ？
そもそもGravioって？？
となるかもしれませんが、そのあたりが気になる方は**[参考](https://qiita.com/mikawan/private/8184cdcc64642aa3729e#%E5%8F%82%E8%80%83)**のリンク集を見ていただければと思います。

#Gravioの設定
##STEP1　センサーの設定
###センサーとペアリング
温度センサーとペアリングします。
センサーがチカチカっと光り、以下の画面が表示されれば、ペアリング完了です。
![温度センサーペアリング](https://qiita-image-store.s3.amazonaws.com/0/247209/6506bf18-8f91-b280-5d84-731aaf969f94.png)
ペアリングについては、[こちら](https://www.gravio.com/jp/sensor-setup-guide)をご参照ください。

###センサーの登録
（1） エリア・レイヤーを登録する
画面右上の”＋”ボタンをクリックし、エリアを作成します。
エリアを作成すると自動的にレイヤーが作成画面が表示されるので、SENSING DEVICE TYPEにAqara-Temperatureを選択します。

（2） レイヤーにデバイス（センサー）を登録する
一番右のデバイスウィンドウの”⊕”ボタンを選択し、デバイスを追加します。
デバイスのスライドボタンをONにすることで、データの収集が開始されます。

##STEP2　Slackの設定
今回は、温度に関する３種類のSlack投稿動作を準備します。

|動作|動作ファイル名|コメント|
|:---|:---|:---|
|1|温度通知|○○度です。|
|2|暑いときコメント|暑いですね・・・。|
|3|寒いときコメント|寒いですね・・・。|

Gravio上で、アクションを作成します。
Slackコンポーネントを設置して、
コンポーネントのプロパティにトークンとチャネル、メッセージを設定するだけです。
動作1を作成した場合は以下を設定します。

|項目|内容|
|:---|:---|:---|
|Token|"取得したトークン"|
|Channel|#general|
|Text|av.Data　+"℃です。"|

メッセージ内容にセンサーデータを使用する場合は、"av.Data"を使用します。
アクション（動作）ファイル名を編集しておくと、あとで設定をするときわかりやすいです。
（アクション編集画面の左上にあるAction1と書かれているところを変更するとアクション名が変わります）

【2018/1/31追記】
**アクション変数について**
アクション変数とは、センサーデータとSTEP3で設定する動作条件が一致した場合に実行されるアクション内にて使用できるデータです。
条件と一致したタイミングのセンサーデータ（Data）の他にも、データの取得日時（Timestamp）やセンサーのID（SensorDeviceID）などのデータを使用できます。

##STEP3 動作タイミング（トリガー）の設定
トリガー画面から、"＋”をクリックしトリガーを作成します。
温度データを受信したタイミングで常に温度を投稿する
トリガーの設定内容は以下のとおりです。

|項目|設定値|
|:---|:---|
|エリア|温度データのエリア|
|レイヤー|温度データのレイヤー|
|アクション名|温度通知|
|Interval|10（Default）|
|Classic/Threshold Triger|Classic Trigger（Default）|
|温度|>=0|

温度が28℃を超えたとき、20℃を下回ったときのトリガーは、
アクション名と温度の項目を変更し、トリガーを追加します。

変更点

|項目|暑いときのトリガー|寒いときのトリガー|
|:---|:---|:---|
|アクション名|暑いときコメント|寒いときコメント|
|温度|>=28|<=20|

ここまでで設定が完了です。

#動作確認
室温から手で温めたあと、冷凍庫にセンサーをいれて、両方の動作が確認できました！
![Slack画面](https://qiita-image-store.s3.amazonaws.com/0/247209/fe1be478-e725-fc3a-c219-526a88665f2c.png)

#あとがき
簡単に室温をSlackで共有してみました。
サーバー室や飲食店の室温管理には使えそうですね！
今回は温度センサーを使いましたが、それ以外でも同じようなことができます。
例えば、開閉センサーを使ってドアが空いたタイミングでSlackに通知するといったことができちゃいます！
よかったら、Gravioを試してみてください♪

#参考
[Gravioとは？](https://www.gravio.com/jp-blog-article/2018-11-02-about-gravio)

[Gravioのインストール方法](https://qiita.com/mikawan/items/56aaecc05db56723523a)

[温度センサーのデータをエクセルで簡単に表示]
(https://qiita.com/mikawan/items/3d93543566680afda868)

[Slackとボタンスイッチセンサーで「呼び出しシステム」を作ってみた！](https://qiita.com/mikawan/items/ac196bbb5506a3251c55)
今年は挑戦の年！

# メリークリスマス！

## 今年は挑戦の年でした

今年は[ゲームタイトル](http://games.dmm.com/detail/rocketnurse/)をリリースしたり、[Dapps](https://cryptokanojo.com)をリリースしたりと **`投資`と`挑戦`** の年となりました。
0からコンテンツを作るのは会社のエネルギーを大量に使います。
エネルギーに見合う成果を得るのは尋常じゃなく難しいですが、それでも挑戦させてくれた会社に感謝しています！**みんなありがとう！！**  
今年実った小さい種を、来年は育てる年にしたいなぁと思っています。

## 今年弊社で一番活躍した技術は `Javascript`

Dappsにしろゲームにしろ、最も利用された言語は `Javascript` でした。
フルネイティブな案件よりも、 `SPA` や `PWA` などの`JS`を多様する案件がやはり弊社でも増えて来ています。
**フルネイティブな案件よりJS関連の案件の方が比率が多かった**のが今年の大きな印象でした。


## 来年に向けたトライ

来年は **`Dapps` をより多くやっていきたい** と思っています。
加えて、やはり変わらず **ネイティブに強い技術会社であり続けたい** と言う思いも有るため、ネイティブの案件もやはり積極的に取っていきたいなと思っています。


## 最後に：来年も弊社は若手エンジニアに飢えている

アドベントカレンダーを見ていただいて、「面白そうな会社だなー」と思った若手エンジニアな貴方！
是非是非 [こちら](https://www.passion-navi.com/company/index/3308) からご連絡下さいｗ

今年まだまだありますが

### 来年もよろしく！メリークリスマース！ヽ(=´▽`=)ﾉ
クリスマス イルミネーションもどき

こちらは[「Obniz Advent Calendar 2018」](https://qiita.com/advent-calendar/2018/obniz) の12月1日の記事になります。

**12月**といえば**クリスマス**を想う方も多いと思います。そこで、
ObnizでフルカラーLEDを制御して、クリスマス イルミネーションを再現しようと考えました。
当初20〜30球のフルカラーLEDを考えてましたが、まったくの準備不足で入手/検証する時間がなくなり、手持ちの8球のLED[^1]となってしまいました。

[^1]: [Adafruit NeoPixel Stick 8](https://www.adafruit.com/product/1426)

~~発光~~点灯のアルゴリズムは以下の通り単純なものです。

- 8球の中から任意の1〜3球を選択
- yellow, green, red, blue から任意の1色を選択し、先に選んだLEDに設定
- 任意の時間ウエイト


「クリスマス イルミネーションを再現」とは言い難いので、「クリスマス イルミネーションもどき」としましたが、雰囲気だけでも・・・。

BGMはクリスマス ソングのメロディIC[^2]です。ちょっと音痴なのは抵抗やコンデンサーをケチったせいかも？？

<iframe width="481" height="360" src="https://www.youtube.com/embed/8Y6_4t614s0?rel=0" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
[^2]: [UM3481](http://akizukidenshi.com/catalog/g/gI-05272/)


12月1日のトップバッターでしたが、力不足ですみません（´>人<｀）。

```javascript:コード例
//javascript
obniz.repeat(async function() {
  const pixels = randomSample(makeArrayRange(stick8.NUM_PIXELS), ramdomInt(1, 3));
  const rgb = [yellow, green, red, blue][ramdomInt(4)];
  stick8.clear();
  for (let n of pixels) {
    stick8.setRgb(n, rgb)
  }
  stick8.show();
  await obniz.wait(100 + ramdomInt(10)*100);
});
```
MarkdownをGitHub風のPDFに変換する

# 概要

MarkdownをPDFに変換する。その際、GitHub風の見た目にしたい。

* ツール
  * [Visual Studio Code - Code Editing. Redefined](https://code.visualstudio.com/)
  * [Markdown PDF - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=yzane.markdown-pdf)

PDFに変換するまでは、VSCodeに拡張を導入するだけで可能。出来上がるPDFをGitHub風の見た目にするためにCSSを入手したり設定ファイルを編集する必要がある。

## 設定項目

拡張の設定に、任意のCSSを指定する項目がある。

[Styles options](https://github.com/yzane/vscode-markdown-pdf/blob/master/README.ja.md#styles-options)

## CSSの入手

ここから入手できる。

[sindresorhus/github-markdown-css: The minimal amount of CSS to replicate the GitHub Markdown style](https://github.com/sindresorhus/github-markdown-css)

以下の記事も参考に。

[githubのmarkdown-cssをぶっこ抜く方法 - Qiita](https://qiita.com/__mick/items/c80fab6c185a41882880)

>適当なエディタを開いて.markdown-を空文字にall-replace(すべて置き換え)する

参考記事内にあるように、事前にCSSに対して上記の編集が必要。

## 設定の実行

設定を開く→「◯個の設定が見つかりました」のすぐ下にある「…」をクリック→settings.jsonを編集

```json-doc
    // 単なる好み
    "markdown-pdf.displayHeaderFooter": false,
    // github-markdown.cssにすべて任せるので、デフォルトのスタイルを無効化
    "markdown-pdf.includeDefaultStyles": false,
    // 入手したCSSのパスを指定
    "markdown-pdf.styles": [
        "C:\\arbitrary-place\\github-markdown.css"
    ],
```
golang 版 mb_convert_kana でひらがな・カタカナ・全角・半角を正規化する

[PicApp アドベントカレンダー](https://adventar.org/calendars/3448)4日目です。

なんらかのテキスト処理を行う際の前処理として、ひらがなをすべてカタカナに変換する、半角カタカナを全角カタカナに変換するといった処理を行うことがあると思いますが、golang ではそれを直接実現する標準パッケージはなさそうです。（`text/unicode/norm` で[それらしいことはできます](https://qiita.com/tomoemon/items/63ba00d830e7a9a11f8e)）

実際のところ、自前で実装するにしても大した規模ではないため、わざわざ外部パッケージの依存を増やすほどのことでもないかもしれません。が、いくつかのパターンを切り替えたり、テストしたりすることを考慮すると、パッケージとして切り出されている方が便利でしょう。

さて、この種の変換でぱっと思い浮かぶのは PHP の [mb_convert_kana](http://php.net/manual/ja/function.mb-convert-kana.php) です。よく使うパターンの変換方法を用意してくれていて、かつそれらの任意の組み合わせが可能です[^php]。golang でこれと同程度のことが実現できるパッケージを探したのですが見つからなかったので作りました。

[^php]: ガラケー向けのサービスを作っていた当時、片っ端からカタカナを半角カタカナに変換するのにお世話になりました

https://github.com/tomoemon/text_normalizer

下記、簡単な使用例です。
全角記号を半角に、全角数字を半角に、英字を半角に、ひらがなとカタカナを濁点なしの全角カタカナに、というオプションを指定しています。

```go

import (
	"fmt"
	"github.com/tomoemon/text_normalizer"
)

func main(){
	s := "# ＃ 5 ５ a A ａ Ａ ｱ ｶﾞ ア ガ あ が"
	n := text_normalizer.NewTextNormalizer(
		text_normalizer.ZenkakuSignToHankaku,
		text_normalizer.ZenkakuNumberToHankaku,
		text_normalizer.AlphabetToHankaku,
		text_normalizer.KanaToZenkakuKatakana,
		text_normalizer.RemoveDakuten)
	fmt.Println(n.Replace(s))
}
```

出力

```
# # 5 5 a A a A ア カ ア カ ア カ
```

このように一つの文字列に含まれる複数の文字種をまとめて変換することができます。
WebGL（three.js）でポスタリゼーション

こんにちは、[yohei kojima](https://twitter.com/youhe__) です。

今回はWebGLを使ってポスタリゼーションの実装をしたのでその解説をしていきます。
WebGLというと3Dのゴリゴリしたものを作るイメージですが、2Dでも活用できたりします。今回は画像や動画を加工するポスタリゼーションというものを紹介します。

# まえがき
WebGLアドベントカレンダーではないのでWebGLについて簡単に解説しておきます。
WebGLはJavaScriptのAPIの１つで2Dや3Dのグラフィックスをレンダリングするためによく使われています。また、[three.js](https://threejs.org/) はWebGLを扱うライブラリの１つでとても有名です。簡単に3Dなサイトが作れます（たぶん）。

・WebGLを使っているサイト
![ppp.png](https://qiita-image-store.s3.amazonaws.com/0/84990/849d7c97-5ace-67f5-3d97-4a2d7debb4c7.png)
http://campoallecomete.it/#!/en
http://lightgraffiti.littlesun.com/

・WebGL参考サイト
[Three.js入門サイト - ICS MEDIA](https://ics.media/tutorial-three/index.html)
[WebGL 開発支援サイト wgld.org](https://wgld.org/)

# デモ
先にデモを載せておきます。（今回webcameraはスマホで動かないです。スミマセン）
https://youhe.jp/demo/posterization/

・GUIの説明
original -> オリジナル表示のON / OFF
webcamera -> webカメラのON / OFF
mono -> 白黒のON / OFF
threshold -> 階調数を変更するしきい値

・こんな感じになります
![pp.png](https://qiita-image-store.s3.amazonaws.com/0/84990/3c3969bf-c24b-1436-7456-3116d8268816.png)


# 解説
ポスタリゼーションとは階調変更と言われる画像処理です。WebGLでいうとポストエフェクトの１つになります。
画像はRGBそれぞれ0~255の256階調で表されており、この256階調を変更することがポスタリゼーションです。階調数を変えるとイラストっぽい表現ができたりします。

・RGBのRを階調変更した例
256, 16, 8, 4の順で階調数を減らしています。
![r.png](https://qiita-image-store.s3.amazonaws.com/0/84990/8d70dc5b-2295-3175-4929-34f0b821d851.png)

この処理を1pxごとのRGBに行うとデモが作れます。

## ソースコード解説
シェーダーだけコメントアウトで解説します。

```glsl:posterize.vs
precision highp float;

uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;

attribute vec3 position;

varying vec2 vTexCoord;

void main() {
  // position.xy を正規化してフラグメントシェーダーに渡す
  vTexCoord = (position.xy + 1.0) / 2.0;

  gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
```

```glsl:posterize.fs
precision highp float;

uniform sampler2D imgTxt; // 画像テクスチャ
uniform float threshold; // しきい値

varying vec2 vTexCoord;

// 写像について
// http://twilightdve.hatenablog.com/entry/2014/06/23/142555
float map(float val, float s1, float e1, float s2, float e2) {
  return s2 + (e2 - s2) * ((val - s1) / (e1 - s1));
}

float posterize(float v) {
  // v には 0.0 ~ 255.0 の値が入っています。
  // これを 0.0 ~ threshold に写像を使って変換します。
  float m = map(v, 0.0, 255.0, 0.0, threshold);

  // floorで整数にしたあと階調数で割る
  float f = floor(m) / (threshold - 1.0);

  // 0 ~ p未満 の整数を返します。
  return f;
}

void main() {
  // テクスチャから色情報を取得
  // RGBは 0 ~ 255 で表すことが多いのですが、
  // texture2D では 0.0 ~ 1.0 の値が返されます。
  vec4 destColor = texture2D(imgTxt, vTexCoord);;

  // RGBを別々に処理します。
  // 今回はわかりやすいように * 255.0 して
  // 0.0 ~ 255.0 の値を posterize に渡します。
  destColor.r = posterize(destColor.r * 255.0);
  destColor.g = posterize(destColor.g * 255.0);
  destColor.b = posterize(destColor.b * 255.0);

  // ポスタリゼーションの処理をした色を出力
  gl_FragColor = vec4(destColor.rgb, 1.0);
}
```
※ webカメラや白黒の判定などポスタリゼーションに関係のないソースは除外しています。

# あとがき
今回はポスタリゼーションの紹介でしたが、他のポストエフェクトを合わせるとよりイラストっぽい表現ができます。
https://youhe.jp/jiyuchou/illustration/

WebGLやってみてね。
python モジュールhidapiとhidに注意。

# TL;DR

pythonモジュールhidapiとhidは
両方ともimport hidで読み込めるので注意。
紛らわしい。

```
pip install hidapi
```
でインストール。でも、使うとときは

```python
import hid
```

### hidapi 0.7.99.post21
https://pypi.org/project/hidapi/

### hid 0.1.1
https://pypi.org/project/hid/

- hid 0.1.1は見た所python2系で書かれているが、python3系でpip installをしても入ってしまう。
- hid 0.1.1が入っていると、import hidすると、hid 0.1.1が優先されるようでhidapi は読み込まれない。

なので、間違えて入れたら、pip uninstall hid
JSで描画したViewをHeadless ChromeでPDF化するまで

[aptpod](https://www.aptpod.co.jp/)が贈る、[aptpod Advent Calendar 2018](https://qiita.com/advent-calendar/2018/aptpod)の2日目担当蔵下です。普段はJSでごにょごにょ開発しています。

# 本記事の経緯

普段の開発ではIoTの高粒度なデータを扱うことが多く、Viewを実装する上でもかなり工夫しないと動作が激重で使い物にならない...ことになりかねません:fearful: 今回、複数の高粒度のデータ（数十件分）をJSの描画ロジックで描画しブラウザで印刷するという要件があったのですが、ある程度のスペックがないと印刷まで数分、ネットワーク上のプリンターで出力するまでまた数分（場合によってはプリンターが不安定に...）という状況に出くわしました。

この状況を解決するためにクライアント側で実装している描画ロジックを切り出し、Node.js（サーバー）側でHeadless Chromeに描画 → PDF化 → クライアント側でPDFをダウンロードして印刷するまでを試してみることにしました。

# 必要なもの

- Node.js
- [Puppeteer](https://github.com/GoogleChrome/puppeteer)
  - Node.jsからHeadless Chromeを簡単に扱えるフレームワーク
  - 何気に初めて触ったけど意外と簡単だった
- 印刷用HTML（切り出した描画ロジックを実行）


# インストール

任意の場所に作業用のフォルダーを用意して、Puppeteerをインストールします。

```
npm i puppeteer
```

# 描画からPDF化するまで

ソースコードを書く前に、今回の `Node.js（サーバー）側でHeadless Chromeに描画 → PDF化` を実現するためには次のような処理が必要になります。

1. Headless Chromeから描画ロジックを実行するHTMLを読み込む  
→ HTML側でデータの読み込み処理は実行させたくなかったためNode.js側からデータを渡す
2. HTML側で描画ロジック（JS）を実行
3. 描画ロジックが完了したことをHeadless Chromeへ伝える
4. Headless Chrome側でHTMLをキャプチャしPDF化

このフローでは `3. 描画ロジックが完了したことをHeadless Chromeへ伝える` が肝です。それがないと描画ロジックが実行される前にキャプチャの処理が走るため、真っ白なPDFが出来上がるという残念な感じになります:fearful:


# ソースコード

## Node.js側のタスク

```js:build-pdf.js
const fs = require('fs')
const puppeteer = require('puppeteer')

(async () => {
  // PDFの出力先
  const OUTPUT_PATH = './pdf/'
  // PDFのファイル名
  const FILE_NAME = 'capture-pdf'
  // PDFの用紙フォーマット
  const FORMAT = 'A4';
  const URL = '描画ロジックを実行するHTMLのURL'

  // Headless Chromeを起動
  await puppeteer.launch()
    .then(async browser => {
      // ページ
      const page = await browser.newPage()

      // 描画ロジックに必要なデータ
      const data = {
        text: 'お酒大好き！'
      }
      // HTMLの描画ロジック側からwindow.puppeteerGetDataでdataを取得できるように
      await page.exposeFunction('puppeteerGetData', () => data)

      // HTMLの描画ロジック側からwindow.puppeteerPdfでPDF生成
      await page.exposeFunction('puppeteerPdf',
        async () => {
          // 出力先のディレクトリが無ければ生成
          if (!fs.existsSync(OUTPUT_PATH)) {
            fs.mkdirSync(OUTPUT_PATH);
          }

          // PDF作成処理
          await page.pdf({
            path: `${OUTPUT_PATH}${FILE_NAME}.pdf`,
            format: FORMAT
          });

          // Headless Chromeを閉じる
          browser.close();
        }
    })
})();
```

## Puppeteerと連携するために描画用ロジックに追加するプログラム

描画ロジックで使うデータをPuppeteer側から受け取る処理。

```js
if (window.puppeteerGetData) {
  // Puppeteer側からデータを受け取る
  const data = window.puppeteerGetData()
  console.log(data.text) // 'お酒大好き！'
}
```

描画ロジック完了後、Puppeteer側でのHTMLキャプチャ処理を実行する。

```js
if (window.puppeteerPdf) {
  // Puppeteer側のキャプチャ処理を実行
  window.puppeteerPdf()
}
```

# タスクの実行

上のソースコードが書けたらタスク実行！！！！

```
node build-pdf
```

出力先にPDFが作成さえれば無事成功:tada:

# いろいろ試行錯誤したけど思い返せば簡単にできた

Headless Chromeを使ったHTMLのPDF化は、GitHubなどでライブラリとして公開されていたものもありましたが、ページのload完了は見てくれるけどJSの実行完了はみてくれなかったので、最終的には自分でごにょごにょしました（Puppeteer使ったけど:sweat_smile:）。

体感では、描画ロジック実行 → 印刷できる状態（ブラウザでは印刷ダイアログ表示）に比べると数倍速くなったかなと思います（ちゃんとベンチ取れよ〜 お仕事の兼ね合いであれがあれなもんで）。

[aptpod Advent Calendar 2018](https://qiita.com/advent-calendar/2018/aptpod)の別日にまた他のネタで書く予定なので、引き続きお付き合いいただけると嬉しいです！
Go 言語の標準ライブラリから多値の戻り値についての思想をでっち上げる

株式会社 ACCESS の Advent calendar へようこそ。僕は ACCESS 従業員の三原と申します。この記事の題名にいきなり Go 言語と書いていますが、僕は今まで C 言語を生業としていて、Go 言語を使ったのはここ半年ほどです。そんな初心者の僕が、Go 言語の使い方はこんなものなのかな、と思ったところを述べさせていただきます。

# Go 言語の文法だと、多値の戻り値は素直でない?

Go 言語では関数が多値の戻り値を返せることが特徴と言われています。

しかしプログラミング言語に造詣が深い人からは、文法・機能が素直でないと指摘されます。関数の戻り値を変数に入れることなく同じ型シグネチャの引数として渡せないといった制約があるためです。

……なのですが、僕は Go 言語の標準ライブラリを使っている限りにおいて、制約だとは思っていませんでした。何も考えていなかっただけなのですが、ある程度は自然だと思えた理由を述べるのが、この記事の目的です。

# 言語機能と標準ライブラリからいくつか

ここで、Go 言語の言語機能と標準ライブラリに触れさせていただきます。

## 多値のようで多値でないから素直でない?

Go 言語の言語機能と標準ライブラリにて、多値のようで多値でないと指摘される点があります。

1つは Type Assertion

```Go
var i foo
j, ok := i.(bar)
```

このとき ```j``` は ```i``` を型変換したものですが ```ok``` は型変換の成否を表しており、2つは意味が違います。このように意味が違う変数が混ざる点が多値のようで多値でないと指摘されます。

もう1つは Error を返すもの。ここでは ```File.Read()``` を例にとります。
https://golang.org/pkg/os/#File.Read

```Go
// 変数 file にファイルを open しているものとします
len, err := file.Read(buf)
```

このとき ```len``` は読み込んだデータの長さですが ```err``` は Error の有無を表しており、2つは意味が違います。これも意味が違う変数が混ざるので多値のようで多値でないと指摘されます。

でも、Go 言語でソフトウェアを実装しているとき、多値の戻り値を扱うのはこういうケースがむしろ主だったりしませんか?

## 多値のようで多値でないのが本義?

この、多値のようで多値でないケースをむしろ Go 言語で関数が多値の戻り値を返す本義だと思ってしまえば、それは不思議ではなくなります。

上に挙げた例では、一方の変数の値によって他方の変数の解釈が変わります。一方が他方の解釈を変える、それが Go 言語での多値の戻り値の意義と目的なのではないか。

ある情報の解釈を変えてしまう情報、それは「メタ」です。上の例では、一方がベタな情報で、他方がその解釈を変えるメタ情報です。

ベタな情報とメタ情報を同時に返すこと。それが Go 言語の言語機能と標準ライブラリに繰り返し現われるパターンです。

多値の戻り値を返すのはレベルが違う情報を同時に返すとき、というのが Go 言語での多値の戻り値の本義なのではないか。常に同時に同じレベルで扱う情報を複数返すときには struct を定義することにしていないか。そんなことを思ってみるわけです。言語設計者に確認していない妄想ですが。

そう思うと、多値の戻り値をそのまま関数の引数にできないことは、不便ではありますが、故が無いわけではないです。常に全ての戻り値を参照することが一般的ではないこと、例外条件が2つの関数で一致するとは限らないこと、を考えると、多値の戻り値をそのまま関数の引数に渡すことは見えないバグの温床になりかねません。その点から見ると、いったん変数に入れるというクッションを置くことも、ありといえばあり、です。

また、このことは、Go 言語の多値の戻り値が他言語の例外のように使えることの素直な解釈に結びつきます。他言語ではレベルの違う情報を戻り値と例外に分けているところを、Go 言語では多値の戻り値のそれぞれがレベルが違う、という素直な対応に結びつきます。

# C 言語からなにが変わったか

ここで C 言語での標準ライブラリの例として POSIX の read() 関数を引きます。(下記 URL は Linux の man ページ)
https://linuxjm.osdn.jp/html/LDP_man-pages/man2/read.2.html

read() 関数の戻り値は

- 1 以上 ... 読み込んだデータの長さ
- 0 ... ファイルディスクリプ他の終わりに到達した
- -1 ... エラー。詳細は変数 errno を参照

戻り値が1つの C 言語では、値域によって戻り値の意味を変えていました。

Go 言語では意味を変える役目を別の戻り値に別けた、ということなのかもしれません。

それさえ達成できればよいと思っていたのか、その答えを聞いたわけではありませんが。

明日は @komitake さんです。どうぞお楽しみに。