OmniAICreator/Qiita-1.07M huggingface dataset:
Twitterにスクリーンショットを簡単に送信するツールをC#で製作しました。

この記事は　[個人開発 #2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/private-developmen2) の16日目です。

今回はじめてのQiita記事を投稿します。
至らぬ点があるかもしれませんが宜しくお願いします。
#開発したものの概要
Twitterにスクリーンショットを送信したいけど、わざわざキャプチャして送信するのも面倒…
そんな時に簡単にスクリーンショットを送信するツールをC#を用いることで製作しました。
~~要はWindowsのSnniping Toolの送信できる版です。~~

紹介サイトhttp://atriasoft.work/captchasender
DLURL:https://www.vector.co.jp/soft/winnt/util/se518858.html

# 制作に使用したもの 
- [C#](https://ja.wikipedia.org/wiki/C_Sharp)
    - Windows Form Applicationで制作。
    - Windoesデスクトップソフトウェア開発に適している。
- [CoreTweet](https://github.com/CoreTweet/CoreTweet/wiki/Home(%E6%97%A5%E6%9C%AC%E8%AA%9E))
    - TwitterAPIをC#で叩く時に非常に便利なライブラリ。
    - コレ自身はTwitterAPIを叩くことしか請け負わないので、TwitterAPIの説明をよく読むことが大切。
- [git](https://git-scm.com/)
    - 今回初めて導入してみた。みんな大好きgitくん。
    - なにか間違いが起こった時に戻したり、新機能の実装などを並行しながらでも安定して行える点が魅力。
    - そのうち初心者さん向けgit記事でも公開してみたい。
    - GitHubは怖いのでまだ使っていない。

# 実際に制作したもの
### [CaptchaSender](https://www.vector.co.jp/soft/winnt/util/se518858.html)
UIはシンプルかつ、コンパクトを目指しました。
自分のモットーである「説明書がなくても大体動かせる」デザインが実現できたと思っています。
![Dufm5OKVAAAYN-7.png](https://qiita-image-store.s3.amazonaws.com/0/86472/7ecb5ae3-9090-cb2b-7abb-47d3eeeab080.png)
何気なく苦労したのはアイコンや画像のデザインでした。画力が欲しい。
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/86472/200b80f7-a8e0-3488-3afd-0019b96a3e89.jpeg)
切り取りを行った際には切り取った画像と一緒に送信画面が表示されます。
上のテキストフィールドに文字を入力すると、画像と一緒にテキストも送信することができます。
140字を超えたテキストはもちろん弾かれます。

#CoreTweetってすげぇ
![CoreTweetってすげぇ.jpg](https://qiita-image-store.s3.amazonaws.com/0/86472/3901b51e-74bd-254a-bc32-2a8e5d8f58d3.jpeg)
TwitterAPI関連の実装は全てCoreTweetに頼り切っています。
基本的にこちら側でデータを用意してやって、ライブラリに投げるだけなので初心者プログラマーの自分でも簡単に実装することができました。
#感想
とても楽しく制作することができたので◎(マル)
自分はよくゲームをすることが多いので、ゲームなどのスクリーンショットをその場でTwitterに送信できるようになって結構楽になりました。
このソフトがなにかに役立てばいいな…と思っています。

#おわりに
ご覧いただきありがとうございました。
カレンダーに間に合わせるために少しばかり無茶をしたので多分バグが多く含まれています。
もしよければ公開後に使っていただいて、フィードバックをいただけると嬉しいです。
[筆者のTwitter](https://twitter.com/AtriaSoft)

Advent Calendar 2018　17日目は　@hackpopo　さんです！

追記
2018/12/21：DLリンクを更新しました。
2018/12/31：誤字訂正
2019/10/24：タイトル変更、内容をもっと詳細に。
[Excel VBA]MakeWhiteGridSheet～選択中のシートを白いExcel方眼紙(18px * 18px)に～

【2018/12/16 更新】
nukie_53さんから頂いた補正ソースを併記させて頂きました。
どうもありがとうございます！
***

選択中のシートを白いExcel方眼紙(18px * 18px)にするプロシージャです。

＜実行前＞
![Book1 - Excel 2018-12-16 09.07.03.png](https://qiita-image-store.s3.amazonaws.com/0/326908/400d8043-10d6-e7b9-752b-3cd59b00a662.png)
＜実行後＞
![Book1 - Excel 2018-12-16 09.11.16.png](https://qiita-image-store.s3.amazonaws.com/0/326908/94b8e091-cd53-fadd-0a76-f1c34f427978.png)

```vb:MakeWhiteGridSheet.bas
'***********************************************************
'[summary]make a white grid sheet (18px * 18px)
'[return]-
'[argument]-
'[detail]
'   1)select all cells
'   2)change cell size to 18px * 18px
'   3)fill with white
'[remarks]
'[create date]2018/12/15
'[update date]
'***********************************************************
Sub MakeWhiteGridSheet()
    ''select all cells
    Cells.Select
    ''change cell size to 18px * 18px
    Selection.ColumnWidth = 0.72
    Selection.RowHeight = 6.8
    ''fill with white
    Selection.Interior.ThemeColor = xlThemeColorDark1
    Selection(1).Select
End Sub
```

######
【2018/12/16 更新】
nukie_53さんより以下のコメントおよび補正ソースを頂きました！
ありがとうございます！
>ColumnWidthは「セルのスタイル」の「標準」に設定されているフォントに依存し、「そのフォント○文字分の幅」を指定します。
>そのため、現在の指定方法ではフォントが変更されたときに追従できないことになります。
>そのあたりも含めてざっくり補正をかけると以下のようになるでしょう。

```vb:MakeWhiteGridSheet2.bas
Sub MakeWhiteGridSheet2()
    Const GridSizePx = 18
    Const Pt_per_Px = 72 / 96 '環境依存
    Const GridSizePt = Pt_per_Px * GridSizePx

    With Cells
        Dim a1Cell As Excel.Range
        Set a1Cell = .Item(1)

        ''change cell size to 18px * 18px
        .RowHeight = GridSizePt

        Dim i As Long
        For i = 1 To 2 '誤差のため1回では指定した数値ぴったりにならない事がある
            Dim charWidth_per_Pt As Double
            charWidth_per_Pt = a1Cell.ColumnWidth / a1Cell.Width
            .ColumnWidth = charWidth_per_Pt * GridSizePt
        Next i


        ''fill with white
        .Interior.ThemeColor = XlThemeColor.xlThemeColorDark1
    End With 'Cells
    a1Cell.Select
End Sub
```
恥ずかしながら全く知らなかったので勉強になりました！
ありがとうございました！！
Qiitaのタグとバージョン指定

今日、「Laravel #2 Advent Calendar 2018 16日目」として以下の投稿をしました。
[Laravelから使うApache Solr](https://qiita.com/hidea/items/a77bb1145040534f5141)

せっかくなので、「[良い記事を書くためのガイドライン](https://help.qiita.com/ja/articles/qiita-article-guideline)」や
「[タグにバージョンを設定するには](https://help.qiita.com/ja/articles/qiita-tagging)」にも書かれているようにバージョン付きのタグを設定してみました。

![laravel:5.7 solr:7.6 Solarium:4 PHP:7.2](https://qiita-image-store.s3.amazonaws.com/0/4668/3d837dd4-ba90-88fe-a6a4-69b89a020909.jpeg)


これっていくらなんでも機能しなさすぎではないでしょうか。
随分と以前からこの仕様はあった気もするのですが （以前にも同じ疑問をもって調べて諦めた記憶が…）

「検索で使えない（っぽい）」

「投稿の表示でも省略される」

と折角のバージョン表記がまったく意味を成していません。
みんな諦めているだけかも知れませんが、せめてタグの所にバージョン表記くらいして欲しいところです。
Laravelから使うApache Solr

Apache Solr
オープンソース全文検索エンジンサーバ
http://lucene.apache.org/solr/

Solarium PHP Solr client library
https://github.com/solariumphp/solarium

Solrはどこかにセットアップされていることを前提とします。

各バージョンは以下の通りとなります。
PHP 7.2、laravel 5.7、solr 7.6、Solarium 4

## セットアップ

PHP用のSolrアクセス用のライブラリである、Solariumをセットアップします。

```
$ composer require solarium/solarium
```

設定ファイルを書きます。ローカルに「test」という名前のコアをつくりました。

```ruby:config/solarium.php
<?php
return [
    'endpoint' => [
        'localhost' => [
            'host' => env('SOLARIUM_HOST', '127.0.0.1'),
            'port' => env('SOLARIUM_PORT', 8983),
            'path' => env('SOLARIUM_PATH', '/solr'),
            'core' => env('SOLARIUM_CORE', 'test'),
        ]
    ]
];
```

## レコードを追加

コアにデータを登録します。書籍データです。

```php
    // Solrクライアント取得
    $client = new Solarium\Client(config('solarium'));
    // 更新オブジェクトを生成
    $update = $client->createUpdate();

    // まとめて登録
    foreach ($books as $book) {
        $doc = $update->createDocument();

        $doc->source = $book->source;
        $doc->sid = $book->isbn;
        $doc->country = $book->getIsbnCountry();
        $doc->title = $book->title;
        $doc->author = $book->author;
        $doc->pubdate = $book->pubdate;

        $update->addDocument($doc);
    }

    // Solrへ更新をコミット
    $update->addCommit();
    $result = $client->update($update);

    if ($result->getStatus() != 0) {
        Log::error('Solr update failed.');
    }
```

## レコードを検索

登録した書籍データを検索します。
固定フィルターや、オフセットと取得数、ソートの設定が可能です。
ただし、ソートをすると検索スコアに関係なくソートされてしまうので注意が必要です。

```php
    // Solrクライアント取得
    $client = new Solarium\Client(config('solarium'));
    // 検索オブジェクトを生成
    $query = $client->createSelect();

    // フィルターを設定
    $query->createFilterQuery('source')->setQuery('source:openbd');
    // 検索クエリ
    $query->setQuery('title:よつばと! AND author:"あずま きよひこ"');
    // オフセットと取得数を設定
    $query->setStart($offset)->setRows($limit);
    // ソートを設定
    $query->addSort('pubdate', $query::SORT_DESC);

    // 検索を実行
    $result = $client->select($query);

    // 検索結果
    // 結果.総件数 : $results->getNumFound();
    foreach ($results as $doc) {
        // 結果.各アイテム : $doc->isbn
    }
```

簡単ですが以上です。
Cloud BuildでGitのブランチ名をdockerイメージのタグに指定するコツ

この記事は、[Business Bank Group Developers Advent Calendar](https://qiita.com/advent-calendar/2018/bbg_developers) 16日目の記事です。

---
Cloud Buildに関しては手前味噌ですが、以下の記事を参考にしてください。

* [Google Cloud BuildでGitHubのpushを契機にdockerイメージをビルドする](https://qiita.com/bigplants/items/ca6ffe88f86567d5ede7)
* [Multi-stageのDockerfileをCloud Buildでビルドするコツ](https://qiita.com/bigplants/items/73f4e16b840207f09e81)

Cloud Buildでdockerイメージをビルドする時に、Gitのブランチ名をタグに指定するのはよくやる事だと思います。

# dockerの場合
例えば、dockerコマンドでタグ付けする場合は、

```shell
docker build -t <repo name>:$(git rev-parse --abbrev-ref HEAD) ./
```

こんな感じかと。
しかし、これだと問題が生じる可能性があります。
ブランチ名に`/`が入っているとエラーになります。

ブランチのネーミングに以下のようなルールがある場合です。

* feature/xxx
* epic/xxx

以下で対応可能です。

```shell
docker build -t <repo name>:$(git rev-parse --abbrev-ref HEAD | tr / -) ./
```

`/` を `-` に置き換えて一件落着。

# Cloud Buildの場合
前述の方法でブランチ名をつけてみましょう。
しかし、Cloud Buildではそう簡単にはいきません。

Cloud Buildのカスタムビルドではshellを実行できません。

## NGな例
```yaml:cloudbuild.yml
steps:
- name: 'gcr.io/cloud-builders/docker'
  args:
  - 'build'
  - '-t'
  - "gcr.io/$PROJECT_ID/$REPO_NAME:$(echo $BRANCH_NAME | tr / -)"
  - '.'

```
これだとshellの文字列がそのまま出力されてしまいます。

## OKな例
```yaml:cloudbuild.yml
steps:
- name: 'gcr.io/cloud-builders/docker'
  entrypoint: 'bash'
  args:
  - "-cvx"
  -   docker build
    -t asia.gcr.io/$REPO_NAME/$REPO_NAME:$(echo $BRANCH_NAME | tr / -)
    .
```
これでいけます。
ポイントは、dockerコンテナの中でビルドしているところです。
shellも実行できます。
この方法を使えば実質なんでもできちゃいます。

# さいごに
Cloud Buildはビルドツールとしてはガチガチな印象を少し持ってましたが、このTipsを見つけてかなり柔軟性が増しました。
今後も様々な用途でCloud Buildを使ってみようと思っています。


明日は、@kyokoshimizuさんの番です。
よろしくお願いします！
[Rails] form_with内でのcollection_selectの使い方（ドロップボックスでの検索）

簡単にできるかなと思って少しだけハマったのでform_with内でのcollection_selectの使い方を整理します。

#実現したい事
1. ドロップボックスで選択した項目による検索
2. ドロップボックスの中身はDBから取得

#環境
Ruby version 2.5.1
Rails version 5.1.6

#サンプル
Userが所属している会社の住所の都道府県で検索したい。
リレーションは下記の様になります。
User(tournament): belongs_to :company
Company(field): has_many :users

また、companyテーブルはprefectureというカラムを持っているとします。

```slim:index.html.slim
= form_with(url: search_users_path, method: :get, local: true) do |form|
  = form.label :"都道府県"
  = form.collection_select :prefecture, Company.group(:prefecture).order(id: :desc), :prefecture, :prefecture, {prompt: ""}
  = form.submit
```
各コードの説明します。

form_with: form_forとform_tagを合わせたものです。詳しくは他の記事を参照してください([【Rails 5】(新) form_with と (旧) form_tag, form_for の違い](https://qiita.com/hmmrjn/items/24f3b8eade206ace17e2))。ここではsearch_users_pathにフォームの内容を送る様になっています。
local: trueはform_withはデフォルトで非同期通信で送信する様になっているので、これで無効にしています。（もちろん必要あれば有効にしてください。）

collection_selectはDBの情報を元にドロップボックスを生成するメソッドです。
下記にどの様に使われるかまとめます。コメント部分は上記の例で実際に記述した項目を書いています。

```ruby:sample.rb
collection_select(
  object, #今回はform_withで既にオブジェクトを渡しているので省略（省略しないとエラーになります。）
  method, #:prefecture : paramsで送る時のkeyになります。つまり今回はparams[:prefecture]で選択したドロップボックスの項目が取得できます。
  collection, #Company.group(:prefecture).order(id: :desc) : 実際にドロップボックスに入る配列を渡します。
  value_method, #:prefecture : optionタグにセットされるvalue属性になります。<option value="ここに値が入る（今回はcompanyの都道府県の値）">
  text_method, #:prefecture : optionタグにセットされる実際のテキストになります。つまり今回の場合は<option value="千葉県">千葉県</option>みたいなhtmlが出力されます。
  options = {}, #{prompt: ""} : オプションです。このオプションではドロップボックスの一番上を空欄に指定しています。
  html_options = {} #省略 : htmlオプションです。
) 
```

collectionのところでCompany.group(:prefecture).order(id: :desc)としていますが、これはgroupメソッドを使ってCompanyモデルのprefectureカラムから重複を除いたものを出力しています。これをしないで例えばCompany.allとしてしまうと東京の会社が3社あったらドロップボックス内に"東京"が3つ出てきてしまいます。なのでgroupを使ってprefectureが同じものは1つだけ抽出しています。

あとはコントローラで選択した都道府県にある会社を抽出します。

```ruby:users_controller.rb
#他のアクションは省略
def index
  @users = User.all
end

def search
  companies = Company.where(prefecture: params[:prefecture]) #選択した都道府県にある会社を全て取り出している。
  @users = User.where(company_id: companies.pluck(:id)) #抽出した会社からidだけを取り出して、その会社に所属しているuserを抽出している。
  render "index"
end
```

pluckの使い方は他の記事やサイト様にお任せしますが、companiesからidだけを抜き出して配列で出力してくれます。

#まとめ
見返すと大した事はしていないのですが、結構時間かかったのでまとめました。
もっと良い方法があれば教えていただけると助かります。

#参考情報
[Can someone explain collection_select to me in clear, simple terms? (Stack Overflow)](https://stackoverflow.com/questions/8907867/can-someone-explain-collection-select-to-me-in-clear-simple-terms)
swiftのコーディングルールを作ってみた

# 目的

これから、人にも引き継いでいくので、ルールを作っていく。
ブラッシュアップは定期的に行っていくs

## 関数や、変数名の付け方

キャメル記法（ロウワーキャメルケースってやつ）で。いまそうなってないやつは今後直していきます。
参考：https://blog.e2info.co.jp/2015/09/24/namingrules/

### 役割を明確に
commonディレクトリや、utilディレクトリは禁止
長くなってもいいから役割を明確に。
〜Utilとかはなるべく使わない。
色々な機能が入らないように、プログラムが短くなるように（目標200行）名前を考える。

### ただし
realmのモデル名は、ロウワーキャメルケース
propertyの定義は、スネークケースで！

## NSUserDefaultsの扱い

UDWrapperを使ってください。
https://gist.github.com/fwhenin/b770228a982230bd8690

## Unwrapped optionalは原則禁止

アプリが落ちる原因になりやすいので、不要の場合は使わない。
IBOutlet系の定義時などやむを得ない場合のみ。

## 依存性の低い作りに

protocol.delegate,callbackを駆使して、依存性の低い（単体テストをしやすい作りに。）

## データベース

Realm一択。現時点では。

## UnitTestコードはなるべく書く。

あまり頻繁に修正が入らないところはなるべく書いてね。

### testing framework
XCUITest/XCTest
ネットワーク系はmockを使う。
https://gist.github.com/joemasilotti/7ff31584c0b6981a8f41
作る上で上記を参考にした

## インスタンス変数にあまりBoolは使わない。
そのうち、そのフラグがなにを意味するかわからなくなりそうなので、避けられるときは避ける。
なるべく関数内のローカル変数で頑張ってほしい。
使い方に気をつける。といった意味が近いかも。

## classメソッドで解決できるものは、classメソッド
## singletonインスタンスで解決できるものはsingletonで
## AppDelegateに定義するものは、protocolを用意する

アプリで共通に使うものは、classメソッド,singletonでやる。
Appdelegateでインスタンスを生成してもできるけど、
AppDelegateにインスタンスを大量に置くと、controllerでAppDelegateだらけになり、
可読性が下がり、依存性が高くなるので、あまり良くない
単体テストをしやすくするために、protocolを使う。

# IBoutlet系は、weak
strongにすると、循環参照が発生する
InterfaceBuilderにあるやつを、swift側で参照するだけなので、weakで十分。

# メモリ管理で不安な場合

ちゃんと、オブジェクトが終了したときに、終了したことをデバッグで確認する
具体的には、一番簡単（でもめんどいよ）の方法が、
各クラスに
```
deinit
```
メソッドを追加して、こちらがコールされるか確認する。例えば、Aって画面を閉じるときに、
```
Aのdelnitが呼ばれていない=メモリが残り続ける
```
ので、一番最悪なパターンは、電池の減りが早くなることに繋がる。
→lldbで確認する手もあるっぽい。

## protocolとdelegate

宣言する際の用途によって、後ろに~protocol/~delegateにするか決める。

### 処理を委託するなら
```
~delegate
```
インスタンス変数は
```
weak var delegateXxxxx: XXXXXdelegate?
```

### interfaceやtraitみたいな使い方をするなら
```
protocolとする
```

## 汎用性の高そうなものが開発中に出来た場合

targetを分けて、そちらに移し、後々FWできるか検討する。

## gitのsubmoduleを使う。

社内で作った、FWはgitのsubmoduleで取り込む
使い方はこちら。(修正中)
[iOSのフレームワークを作ってみる](http://52.192.71.74:8080/knowledge/open.knowledge/view/313)

## ある機能に対してのprotocolは追加するものと同じgroup(ディレクトリ)に配置する
その前提で進めてみて、うまくいかないようであれば、別で管理するところを作るなどする。

## ViewControllerは〜ViewController、xibは〜Viewとつける
[ここを参考に](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621487-nibname)
iOSのfwをつくってみる

# 目的
以前Carthageで取り込む前提でiOSのフレームワークを作ったが、毎回別PJでビルドするのが、めんどくさくなり、運用の途中で、断念した。

が、アプリの数が増えてくるとカブる部分も出てくるので、なんか他にいい方法がないか再度模索してみた。

# そもそも
iOSって、だいたい
* gitのsubmodule
* cocoapods
* carthage
* その他
みたいに外部ライブラリを使う方法がある。

これの、
* gitのsubmodule

は試したことがなかった。社内でlaravelの開発で使われだして、
* 結構使い勝手が良いぞ
* アプリそのものを作りながら進化させられるので、これは効果的ではないか？

という結論に至ったので、そちらで対応する方向に。

## 結論から言うと
うまく行った。これなら、FWのビルドも、かなり楽！

## サンプルPJ
https://github.com/shiratsu/CustomPresentDismissAnim
https://github.com/shiratsu/TestFramework

## まずは、
TestFrameworkをsubmouleとして、CustomPresentDismissAnim
に取り込む。
```
git submodule add https://github.com/shiratsu/TestFramework.git
```

## xcodeのTestFrameworkのPJを追加
TestFramework.xcodeprojをCustomPresentDismissAnimに追加

## Embedded Binariesにframeworkを追加
xcodeprojを追加すると、選択肢に出てくるはず。
ここにあると、リリースビルドとか気にしなくて良くなる。
追加する際にFWはGeneric iOS Deviceでビルドしておくこと

## submoduleを含むプロジェクトのclone
barを含んだfooプロジェクトをcloneするには以下のコマンドを打ちます。

```
$ git clone https://github.com/s-nlf-fh/foo.git
$ cd foo
$ git submodule update --remote
```

## submoduleの開発
branchを作ったほうが良い。そうしないとpush出来ない。

## import文を書く
```
import TestFramework
```

## 注意点
Framework側のメソッドがpublic( or open、使う側でoverrideさせないなら、public)にしてください。プロジェクト外からアクセスするのに必要です。
あと、backlogからはsubmodule使ってるようにはなぜか見えない。

## 課題（というか今後どこかでぶつかりそうなこと）
リリース時のビルド作るときどうするかは検証できてない

### embeded framework
こちらを使えば、リリースビルドも解決する？~~まだ詳しく検証してない~~
→検証した。うまくいった。とくに難しくなかった

### 問題発生
コンビニでは取り込めたけど、ショットでは取り込めない（開発ビルドはできるけどリリースビルドは作れない。）

### 以下を参考にした
embeded frameworkは使わず、以下の方法を取った
https://qiita.com/wai21/items/3a2a7a7170ab9c5c1952#%EF%BC%96%E3%82%B7%E3%83%9F%E3%83%A5%E3%83%AC%E3%83%BC%E3%82%BF%E3%83%BC%E3%81%A8%E5%AE%9F%E6%A9%9F%E3%81%AE%E5%85%B1%E9%80%9A%E3%81%AE%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B

ちゃんと確認してないけど、以下でも良いと思う。
https://medium.com/allatoneplace/writing-custom-universal-framework-in-xcode-9-and-ios-11-7a63a2ce024a

大変疲れた。
Scalatraの開発環境構築メモ

基本的には[ここ](http://scalatra.org/getting-started/)に書いてあるが、IntelliJ+Scalatra前提として自分用メモ
(Scalatraの場合、ちょっと特殊な手順？っぽい)。

`sbt new scalatra/scalatra.g8`でパッケージ名などの質問に答えるとどっかから落としてきたプロトタイプを元にプロジェクトが作成される。

IntelliJ IDEAのsbt shellで`jetty:start`をすると`http://localhost:8080`で立ち上がる。
`~;jetty:stop;jetty:start`とすると自動的に再起動される。
`~`がコードが変更されたときに作動するらしい。`;`は複数コマンドを入力する際に使うものらしい。

debugしたい場合はbuild.sbtの最後のほうに以下追加して起動させた後、IntelliJのEdit ConfigrationからRemoteを選択してポート5005でデバッグする。

```scala
javaOptions ++= Seq(
  "-Xdebug",
  "-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
)
```
Chainerを使ってM3ナットをカウントしてみる

# はじめに
　Chainer meetup #8で発表させていただいた内容（[スライド](https://www.slideshare.net/samacoba1983/chainer-125935410)）の内、[「DiscoGANを使って「教師なし」でお米を数えてみる」](https://qiita.com/samacoba/items/f04ed6a3a170fd97cef5)の続き部分を文章にしたものなります。なので、初めて見られる方は前の投稿の方もみていただけると助かります。

　あと、meetupの動画が[youtube](https://www.youtube.com/watch?v=Q-AXDTuVdk8)上がっているので、そちらの方がわかりやすいかもしれません。

# 今回のデータとやりたいこと
　今回はM3ナットをデジカメで撮影したサンプルのサンプルを二つ（16個と108個）用意しました。これらをDiscoGAN使ってカウントしやすいガウス球ドメインに変換し、その後カウントします。お米の時は、ランダムにばらまくガウス球の数は「見た目」でだいたいオーダだけを合わせていたのですが、どの程度適応できる範囲があるかわからないのでランダムにばらまく数(13個、26個、52個、131個）を変えてテストしてみました。
![スライド1.PNG](https://qiita-image-store.s3.amazonaws.com/0/109458/a4016dfd-70f0-e214-e13f-f36710fb44f0.png)

# ばらまく数を変えた結果
　この表は16個のナット画像に対し、平均13個のガウス球をばらまいたもので学習させるとカウントが20回中5回成功したという見方をします。画像のナットの数に対して、オーダがずれるとカウントが失敗する傾向があります。
![スライド2.PNG](https://qiita-image-store.s3.amazonaws.com/0/109458/4000ff00-e4cb-091f-f792-beac301baaef.png)

　どんな風に失敗したかというと、ナット16個 << ガウス球52個 のような場合は１個のオブジェクトに対して多くの球が生成されるようになり、ナット108個 >> ガウス球26個 のような場合は黒を生成しやすくなる傾向になりました。
![スライド3.PNG](https://qiita-image-store.s3.amazonaws.com/0/109458/e0c3a32e-c56a-5d67-85be-db2802da0945.png)

　また、4種類のランダム画像をそれぞれ25％の確率で学習したものもうまく学習されませんでした。
![スライド4.PNG](https://qiita-image-store.s3.amazonaws.com/0/109458/e40883d8-1bf8-a255-5dcd-596915bcc87a.png)

# ディーラ（仮）を使ったネットワーク
　そこで４種類のランダム画像を調整して配るような「ディーラ(仮)」を使ったネットワークを作成して、学習させてみました。ディーラは１⇒4個のネットワークで、ChainerにFunctionとして実装させているGunbel-Softmaxを使ってサンプリングを行うことで、簡単に逆伝播もできるようになります。変換器と同様にディーラ側のロスも識別機をだます方にしてあるので、結果として変換器の出力とディーラの選ぶランダムガウス球画像が似通ってくれるのを期待しています。
　ChainerだとFunctionとLinkをつなげさえすれば簡単に逆伝播できるので、とても楽です。
![スライド5.PNG](https://qiita-image-store.s3.amazonaws.com/0/109458/27b140db-a3c6-92da-838b-758927b28054.png)

# ディーラを使った結果

[こちらはナット16個の動画](https://youtu.be/0WRxl1CgN-A)
[こちらはナット108個の動画](https://youtu.be/mr2yQPAN7BE)

　学習が進むにつれ、ディーラ（仮）がナット画像の数に近い数のランダムガウス球画像を出すように調整してくれるため、カウントがある程度うまくいくようになりました。
![スライド6.PNG](https://qiita-image-store.s3.amazonaws.com/0/109458/fe5ab8ec-b95f-2ed7-f314-366dc9588d02.png)


# さいごに
　本当はもう少ししっかりしたデータを出したかったのですが、現状不安定で、meetupに間に合わせるために、最初にうまくいった例を出さざる負えなかった感はあります。なのでもうすこし時間をかけてデータを整えていきたいと思っています。

　また、コード[こちら](https://github.com/samacoba/ObjectCounter/tree/master/researchs/No03_dealer_counter)に置いておきました
Slackの背景に画像を設定する

Slack、便利ですよね。いつも使っているからこそ自分好みにしたいですよね。
私はいつも、サイドバーの色を変な色に変えたりしています。
ですが、どうしても真っ白な背景だけは変えられず、すこし寂しい感じがします。

調べてみたところ背景に(むりやり)画像が設定できるようなので自己責任で設定していきたいと思います。

# 1.画像を用意する
<img src="https://qiita-image-store.s3.amazonaws.com/0/193857/f3c95185-64a2-8080-eaf0-b174ba535d96.png" width=50%>
切り抜きが雑ですが、画像を切り抜きました。ちなみにデフォルトで入っているプレビューのスマート投げ縄でサクッと切り抜けます。
<img width="300" alt="スクリーンショット 2018-12-16 5.23.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/193857/9717497c-eac7-fe21-53bc-14371f2fbdbe.png">

# 2.画像をBase64へ変換する
ターミナルで``$ Base64 〇〇.png``とかで変換します。
画像サイズは1MB以下に抑えないとだめっぽいです。1の画像の用意で画像サイズを変える等してください。どうしても高画質がいいのであれば諦めてください。

# 3.いざSlackへ
とりあえずSlack.appのパッケージを表示しましょう。(こういう裏側みるとわくわくしますよね。)
その中に
``Contents/Resources/app.asar.unpacked/src/static/ssb-interop.js``
があるはずですのでお好みのエディタで開きます。
一番下へ下記のようにheadへstyleを入れてあげます。
(いろいろいじれそうなので、web版slackでidとかタグなどを見ながらやるといいかもしれない)

```js
document.addEventListener('DOMContentLoaded', function() {
   var background = `
      #messages_container{
         background-image: url('data:image/png;base64,(先程Base64変換した画像)
     ~ 省略 ~
   `;
   $("<style></style>").appendTo('head').html(background);
}
```

書き込んだら保存をして、Slackを再起動しましょう。
すると、画像が反映されているはずです。

<img width="1276" alt="スクリーンショット 2018-12-16 5.08.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/193857/372a6d45-cdbc-0e9d-bc27-ddf26fb06968.png">

# まとめ
普段使っているアプリの中を覗いてみるのは結構面白かったです。
slackはまだまだいろいろいじれそうなので、なにかアイデアが浮かんだらなにかしてみようと思います。

# おまけ
SlackにTwitterのタイムラインを表示させてみたが、当たり前だけど実用性がなさすぎて、ボツになった図
<img width="364" alt="スクリーンショット 2018-12-16 5.46.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/193857/26e6c888-ea4a-4781-6bc8-d1cae1a4da19.png">
Pipenv + Hydrogen (atom)

プロジェクト名は`python-playground`にする．

```bash
mkdir python-playground
cd python-playground/
pipenv --python 3.6 # お好みで
pipenv install jupyter ipykernel # jupyterは必要なのだろうか？
pipenv run python -m ipykernel install --user --name python-playground
```

atomを開いてHydrogenをインストール．
設定のKernel Gatewaysを以下に変更：

```json
[{"name": "python-playground", "options": {"baseUrl": "http://localhost:8888"}}]
```

```bash
cd python-playground/
atom .
```

でatomを起動して↓みたいに書いていく．⌘+Enterで1行実行ぽい．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/280809/276ef2c3-0254-911a-4faf-9ba086297fb9.png)

多分これで動くはず．

起動はできたぽいけどどういう仕組みなのかちょっと謎．どなたかわかる方いたら教えてください！
クラスメソッドのプロパティはインスタンスで共有されてしまう

# インスタンスごとに同じ値が取得できてしまう


他の人のソースを触っていて、以下のような現象に遭遇。
`hoge.val()`の結果が最後に作成したインスタンスの値になってしまう。

```javascript

class Test {
  constructor(commonVal) {
    this.commonVal = commonVal;
    this.hoge.val = () => this.commonVal;
  }
    
  hoge() {
    // do something....
    return;
  }
}

const fuga = new Test('aaaaaaaaaaa');
const fuga2 = new Test('bbbbbbbbbbb');

fuga2.hoge.val() // ← "bbbbbbbbbbb"
fuga.hoge.val()  // ← "bbbbbbbbbbb" !?
```

## 原因
classのメソッドはprototypeに宣言されることが原因でした。
hogeはメソッド定義されていますのでprototypeに宣言され、その中にvalというプロパティが作成されてしまいます。
その結果、何個インスタンスを生成しようとも、最後に生成されたインスタンスで戻り値が上書きされてしまうわけです:helmet_with_cross:
上記はchromeのコンソールで確認しましたが、babelでプリコンパイルしても同様の挙動になります。
（[babelもクラスメソッドはprototypeに宣言するから](https://babeljs.io/docs/en/babel-plugin-transform-classes)）

そもそも上記のようなコンストラクタの記述が好ましくないと思うのですが、他人のソースなので意図が読めず・・・（grepしたけど、hoge.valはどこにも使用されていなかった）

以上、わかればどうということはないのですが、挙動やソースが意味わからなさすぎて2時間くらいかかりました:santa:
C#で学ぶダックタイピング

# 最初に

本記事は「Adaptive Code」で得た知見から掘り下げて記事にしたものとなります。

記事の対象者は以下の知識を持っていることが前提となります。

- C#の基礎的なコードが書けること。
- 動的・静的型付けがわかること。

## ダックタイピングとは？

動的に型付が行われる言語ではよく、この「ダックタイピング」が行われます。

ダックタイピングの名前はダックテストに由来します。

*「もしもそれがアヒルのように歩き、アヒルのように鳴くのなら、それはアヒルである。」*

つまり、**同名のメソッドやプロパティを持つオブジェクトに関しては、等しく扱えることを提案するもの**です（実際に後述するコードを見た方が直感的にわかりやすいかもしれません）。

C#ではこれを**dynamic**で実現することができます。インターフェイスを作成しなくても問題ありません。単純に同名及び引数が合っているかどうかを見ています。

## dynamic？

C# 4.0で追加された機能です。このdynamicの使い方に戸惑う方が身近に居たので今回紹介も兼ねて記事にしてみた次第です。

元々C# 3.0 以前では、 静的型付けしか行えませんでした。そのため、オブジェクトが持つプロパティ名やメソッド名をコンパイル時に知っておく必要がありました。

このdynamicキーワードを使用することで、CLRの静的な型付けから**DLR(Dynamic Language Runtime)の動的型付けに切り替える**ことが可能となります。以下のコードで登場するpetというプロパティが存在するかどうかは**実行時に調べられます**。

```C#
void dynamic GetPet(dynamic someone)
{
    if (someone == null) return;
    return someone.pet;
}
```


## 実際のコード

```C#
using System;

namespace Hoge
{
    public class Dog
    {
       public void Walk()
        {
          Console.WriteLine("Dog Walk.");
        } 
    }
    
    public class Cat
    {
        public void Walk()
        {
          Console.WriteLine("Cat Walk.");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var cat = new Cat();
            AnimalWalk(cat);

            var dog = new Dog();
            AnimalWalk(dog);
        }
        
        static void AnimalWalk(dynamic animal)
        {
            if (animal == null) return;

            // CatもDogもWalkを実装済み。
            animal.Walk();
        }
    }
}
```
```
出力結果：

Cat Walk.
Dog Walk.
```

## メリット

- コードが簡素化されるため見通しが良くなる。
- Pythonのような動的言語との相互運用に便利
- XMLやJSONのようなデータと連携しやすくなる。

## デメリット

- 名前のつづり間違いは実行するまでエラーかどうか確認できない。
- ソースは短くなるが、性能面では静的な定義に劣る

## 参考
- [++C++; // 未確認飛行 C  dynamic](https://ufcpp.net/study/csharp/sp4_dynamic.html?sec=data#data)
- [連載：C# 4入門 第1回 dynamic型](http://www.atmarkit.co.jp/fdotnet/csharp4/csharp4_01/csharp4_01_02.html)
Raspberry pi 3 B+ にZabbix Agent 4.0をインストールしてみた

#概要
- Raspberry pi 3 B+ をZabbixで監視するために Zabbix Agent 4.0をインストール

#手順
##1. Repository 導入

```bash
# wget https://repo.zabbix.com/zabbix/4.0/raspbian/pool/main/z/zabbix-release/zabbix-release_4.0-2+stretch_all.deb

# dpkg -i zabbix-release_4.0-2+stretch_all.deb

# apt update
# reboot
```

##2. Zabbix Agent 導入

```bash
# apt install zabbix-agent
```

##3. Zabbix AgentのVer確認

```bash
# zabbix_agentd -V
zabbix_agentd (daemon) (Zabbix) 4.0.2
Revision 87228 26 November 2018, compilation time: Nov 26 2018 09:32:37

Copyright (C) 2018 Zabbix SIA
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it according to
the license. There is NO WARRANTY, to the extent permitted by law.

This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/).

Compiled with OpenSSL 1.1.0f  25 May 2017
Running with OpenSSL 1.1.0j  20 Nov 2018
#
```

無事インストールされました。

##4. Zabbix Agentのconfig変更

```bash
# vi /etc/zabbix/zabbix_agentd.conf
```

##5. Zabbix SenderとGetの導入

```bash
# apt install zabbix-sender
# apt install zabbix-get
# zabbix_sender -V
zabbix_sender (Zabbix) 4.0.2
Revision 87228 26 November 2018, compilation time: Nov 26 2018 09:32:37

Copyright (C) 2018 Zabbix SIA
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it according to
the license. There is NO WARRANTY, to the extent permitted by law.

This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/).

Compiled with OpenSSL 1.1.0f  25 May 2017
Running with OpenSSL 1.1.0j  20 Nov 2018
# zabbix_get -V
zabbix_get (Zabbix) 4.0.2
Revision 87228 26 November 2018, compilation time: Nov 26 2018 09:32:37

Copyright (C) 2018 Zabbix SIA
License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it according to
the license. There is NO WARRANTY, to the extent permitted by law.

This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/).

Compiled with OpenSSL 1.1.0f  25 May 2017
Running with OpenSSL 1.1.0j  20 Nov 2018
#
```

おわり
距離センサーVL53L0Xをマイコンとの距離を長く使用する

秋月にて販売されているＶＬ５３Ｌ０Ｘ使用　レーザー測距センサモジュール（ＴｏＦ）、
最大2mまで、距離を短い設定にすればミリ単位で計測ができ、PSDセンサーより使い勝手が良いと考えたため、arduinoで使用した。
今回問題として発生したのが仕様がi2cのため、センサーとarduinoとの配線距離が1m超えたあたりからエラーでタイムアウトが発生し、エラーが連続した際復帰がされず、距離が測れないという問題が起きた。

使用したライブラリ
Adafruit_VL53L0X Library
VL53L0X by Pololu


#対策まとめ
エラーが連続した際、再度i2cの設定を読み込ませようと考えたが他のi2c接続の通信が途切れるため、物理的にarduinoをもう一台用意しＶＬ５３Ｌ０Ｘ専用として使用し、arduino同士をシリアル通信で距離データを送りエラーが発生し続けた場合
、主arduinoからセンサー用arduino自体をリセットを掛けるという方法。デメリットとして、リセットを掛けている際データが途切れる点。


#ＶＬ５３Ｌ０Ｘに関して
レジスタマップや制御方法が、メーカー非公開ということで、皆がライブラリを使用している。初期設定の一部分を書き直すだけで、簡単に長距離モード、高精度モード、距離を変更できるが、エラー部分の対応方法に関しては項目がなかった。ライブラリ内を確認し変更できれば、もしからしたら、今回の問題も解決できたかもしれない。


#その他
知見者にアドバイスをもらい、他に以下の行為を試してみたが今回は大きく状況が変わることがなかった。
・I2Cの通信速度自体を100khz→25khzに落とす
・プルアップ抵抗を内部３３ｋΩから1.6kΩへ落とす
他にi2cから別の通信方法に変更する方法を教えてもらったが、簡単に済ますためマイコンを別途用意する方法を今回行った。

#参考ページ

・実際に機器に組み込んだ場合のコードを書いています。
測距センサ VL53L0X を用いた身長測定器
https://homemadegarbage.com/vl53l0x01

・arduinoとの接続配線と精度の説明をされています。
作りながら学ぶArduino+=電子工作入門
距離を正確に測る　その2　レーザーVL53L0X
https://www.denshi.club/cookbook/sensor/distance/2vl53l0x.html

・設定値の説明をされています
平凡な日常を平凡に綴る 
デジタル積雪計を作る
http://msms1003.blogspot.com/2017/12/vl53l0x.html

・スイッチサイエンス製での使用をされています。
Hobby robot laboratory
https://sites.google.com/site/memorandumjavaandalgorithm/arduino-jiang-zuo-ju-lisensa-vl53l0x

・精度を確認されています。
yuqlidの日記
http://yuqlid.hatenablog.com/entry/2016/09/11/002804

・今回使用しなかったが複数台使用参考になります。
ArduinoでVL53L0Xを複数同時に使う
http://rcj-quantity.info/2017/12/13/arduino%E3%81%A7vl53l0x%E3%82%92%E8%A4%87%E6%95%B0%E5%90%8C%E6%99%82%E3%81%AB%E4%BD%BF%E3%81%86/

・ライブラリーの説明をされています。
Adafruit_VL53L0X Library
https://learn.adafruit.com/adafruit-vl53l0x-micro-lidar-distance-sensor-breakout/arduino-code
Hyper-V + systemd-nspawnの開発環境を作る(4) ～ コンテナ起動設定 ～


[前回](https://qiita.com/yaasita/items/88b54fd6c2fef9195508)の続き

# 起動設定

起動設定をして、machinectlコマンド経由で起動してみます


    curl -L https://git.io/fpNm1 > /etc/systemd/system/systemd-nspawn@.service

これだけです
あとはmachinectlコマンドで操作できます

    # コンテナイメージ一覧
    machinectl list-images
    # 動作コンテナ一覧
    machinectl list
    # start
    machinectl start ubuntu
    # stop
    machinectl stop ubuntu
    # 再起動後も自動起動させる
    machinectl enable ubuntu
    # 自動起動の解除
    machinectl disable ubuntu

試しに`machinectl enable ubuntu`してからホストを再起動してみます

    systemctl reboot

再起動後 `http://10.100.0.3/` にアクセスしてubuntu1の文字が見えたらOKです

-----

続く
autoload_pathsを修正して謎エラーをなくした話


アドベントカレンダー15日目になります！

## config.autoload_pathsの設定

最近、現場でautoload_pathsを修正する機会がありました。

```ruby
#config/application.rb

 config.enable_dependency_loading = true # ウッ！

 config.autoload_paths += %W(#{config.root}/lib) # 重複・・？
 config.autoload_paths += Dir["#{config.root}/lib/**/"]
 config.autoload_paths += %W(#{config.root}/app/services)

 # ...snip
 # 
 # 以下app/以下のautoload設定が並ぶ
 #
```

歴史的な何かで、本番でのautoloadが可能になっていたのですが、やっかいなエラーを引き起こすのでオフにします。

ついでに他の設定も見直してみました。

## 現状

どうやらapp/以下に切った独自のフォルダに加えて、lib/以下をautoload_pathに加えたいという意図がありそうです。

さらにautoloadをオフにするにあたって、現在autoload対象になっているフォルダをすべて本番でeager_load対象にする必要がありました。

## やったこと

ロードしたい対象フォルダを、本番用にeager_load指定しつつ、開発環境用に別途autoload指定もしないといけないかと思っていましたが、[この辺をみると](https://github.com/rails/rails/blob/fc5dd0b85189811062c85520fd70de8389b55aeb/railties/lib/rails/engine.rb#L686)eager_load_pathsに指定するとautoload_pathsにも含めてくれるようです。

また、app/以下の独自フォルダですが、デフォルトで[eager_load_pathsに加えられます](https://github.com/rails/rails/blob/0b75743e345f98d3f53f5a29fcd0e91d2a370a24/railties/lib/rails/engine/configuration.rb#L41)

つまりapp/以下のファイルのロードについて心配する必要はありません。

なので、残るはlib/以下の対処だけとなり、最終的にこんなシンプルになりました。

```ruby
config.eager_load_paths += Dir["#{config.root}/lib/**/"]
```

lib/tasks以下にあるrakeタスクがeager_loadされているのが気持ち悪いので、のちほど手を打とうかなと考えています。

```ruby
 config.autoload_paths += Dir["#{config.root}lib/**/"] -  Dir["#{config.root}lib/tasks/**/"]
```

うん。ダサいw


どうやらpathオブジェクトを使ってフォルダ丸ごと除外するというコードが[最近railsに入ったっぽい。](https://github.com/rails/rails/commit/cffbf73a4761816d894a49fbec7f070f27ebbff4)

いろいろと試してみて、いい感じにかけるようであればまたシェアしたいと思います。

## 検証方法

念のためステージングでeager_loadされていることを確認しました。

```ruby
Rails.configuration.eager_load_paths
=> [.... # eager_loadされたパスが大量に並ぶ ]

ActiveSupport::Dependencies.autoloaded_constants
=> [.... # ロード済みの定数が並ぶ] # 起動直後でもlib/以下の定数が問題なく並ぶことを検証
```

一方、改修前のブランチ、およびローカル環境ではlib/以下の定数がロードされていないことを確認できました。

```ruby
ActiveSupport::Dependencies.autoloaded_constants
=> [.... # 起動時にロードされたクラス名だけが並ぶ]
```

## 結果

なぜか本番デプロイの直後だけ、クラス名を参照したコードが落ちるという現象がありました。

```
Circular dependency detected while autoloading constant XXXXXX（クラス名）
```

エラーが起こるクラス名はその時々で変わるのですが、lib以下のクラス名についてだけこの現象が起こるということに気づき、lib以下のクラスがうまくロードされていない可能性を疑いました。

改修後１ヶ月ほど経ちますが、全くエラーが起こらなくなりました。

## 注意点

[Rails Guide](https://edgeguides.rubyonrails.org/autoloading_and_reloading_constants.html#autoload-paths-and-eager-load-paths)にautoload_pathsの設定に関して詳しい解説があります。

ちょっと気になる注釈があり、

> But using autoload_paths on its own in the past (before Rails 5) developers might configure autoload_paths to add in extra locations (e.g. lib which used to be an autoload path list years ago, but no longer is). However this is now discouraged for most purposes, as it is likely to lead to production-only errors. It is possible to add new locations to both config.eager_load_paths and config.autoload_paths but use at your own risk.

「Rails5より前ではlib/以下をautoload_pathsに含めることがよく行われていたが、現在はappフォルダ以外の場所にコードを置いてautoload対象にするのは勧めない」となっています。本番特有のエラーが起こる可能性があるから、やるなら自己責任でな、という話です。

libを切っているアプリケーションはちょいちょい見かける印象ですが、どこかでフォルダ構成を見直した方がいいのかもしれませんね。
Unity：損はしないはず、コピペで使える簡単な計算

[グレンジAdvent Calendar 2018](https://qiita.com/advent-calendar/2018/grenge) 17日目の記事です。
グレンジでクライアントエンジニア（Unity）をしています。

今回はUnityでまぁまぁ使う計算、判定を何個か書くので、コピペして使っちゃってください！


▼対象（t）の正面に対して指定座標（targetPosition）が右側か判定

``` 
public bool IsRight(Transform t, Vector3 targetPosition) {
	Vector3 diff = targetPosition- t.position;
	Vector3 axis = Vector3.Cross(t.forward, diff);
	return axis.y > 0;
}
```

![temp1.png](https://qiita-image-store.s3.amazonaws.com/0/216754/f682ab2a-a319-7cc7-a75b-9d6b831ab26f.png)


▼対象（t）の正面に対して指定座標（targetPosition）が下側か判定

```
public bool IsDown(Transform t, Vector3 targetPosition) {
	Vector3 diff = targetPosition- t.position;
	Vector3 axis = Vector3.Cross(t.forward, diff);
	return axis.x > 0;
}
```

![temp2.png](https://qiita-image-store.s3.amazonaws.com/0/216754/fc679632-0d49-01f6-c40f-84920943a255.png)


▼角度（angle）を+180～-180に整える

```
public float AdjustAngle180(float angle) {
	float subNormal = Mathf.Floor((Mathf.Abs(angle) + 180f) / 360f) * 360f;
	return (angle > 0f) ? angle - subNormal : angle + subNormal;
}
```
※180f、360fは定数で定義しておいたほうがいいです

▼2つの角度（rot1, rot2）間の差を計算　※上記のAdjustAngle180(float angle)を使用してます

```
public float CalcAngleGap(float rot1, float rot2) {
	rot1 = AdjustAngle180(rot1);
	rot2 = AdjustAngle180(rot2);
	return AdjustAngle180(rot1 - rot2);
}
```

▼2つの角度ベクトル（vec1,vec2）間の差ベクトルを求める ※上記の CalcAngleGap(float rot1, float rot2)を使用してます

```
public static Vector3 CalcAngleGap(Vector3 vec1, Vector3 vec2) {
	Vector3 gapAngle = new Vector3(
		CalcAngleGap(vec1.x, vec2.x),
		CalcAngleGap(vec1.y, vec2.y),
		CalcAngleGap(vec1.z, vec2.z)
	);
	return gapAngle;
}
```

▼2点間（position1, position2）のベクトルの大きさが指定したもの（magnitude）より大きいか

```
public bool IsMagnitudeGreaterThan(Vector3 position1, Vector3 position2, float magnitude) {
	return (position1 - position2).sqrMagnitude > magnitude * magnitude ;
}
```

▼中心座標（center）、半径（radius）の球内に指定座標（targetPosition）があるか ※IsMagnitudeGreaterThan(Vector3 position1, Vector3 position2, float magnitude)を使用します

```
public bool IsInSphere(Vector3 center, float radius, Vector3 targetPosition) {
	return IsMagnitudeGreaterThan(center, targetPosition, radius) == false;
}
```


簡単な計算なので内容はすぐに理解できるかと。
改良の余地だらけなのでコピペしていろいろ試してみてくださいm(__)m
Common Data ServiceにPowerBIで接続して可視化する

##この作業が必要だった背景
![かんがえるひとイラスト](https://qiita-image-store.s3.amazonaws.com/0/140547/0ef60416-d107-8a91-6455-69b0c30761b5.png)
10年以上も経営していますが、中小企業の悲しい現実です。
開発会社らしくRedmineやVSTSなどで、スケジュールの進捗管理などは行っておりますが、実際に見積もった金額に対して、各プロジェクトて使用した時間（工数）をカウントして、利益を逐次把握することが出来てませんでした。
 
##様々なツールでの工数記録チャレンジ
それこそ、始めは社員数も4人でしたから、OneNoteに工数をみんなで書いたりしてました。（もう案件名が自由入力過ぎて集計に問題ありました笑）
次のエクセルでの管理は、時間の数字を記入するセルに「お休み」とか文字列が入ってたり😭、みんなエンジニアなんですが、忙しいのでコストの把握する行為なんて、そんな扱いです💦

##限界を感じPowerAppsで工数管理をアプリ化
アプリ化は、フルスクラッチで開発するよりも、PowerAppsで遥かに早く作成できました。
これで運用を開始して記録を始めたら、結果を計測し分析して対応策を練り、次の改善に繋げていかなければなりません。何より大変な工数入力をしている社員にメリットを提供しなければ文化が根付きません。

**ここでデータを定期的に可視化するのに、PowerBIを利用して、Common Data Serviceへ繋げる必要がありました。**

#接続設定方法
1.PowerAppsのログイン画面へ進み、接続したい環境を選んだら、歯車アイコンより「高度なカスタマイズ」を選択します。
![PowerAppsホーム画面スクリーンショット](https://qiita-image-store.s3.amazonaws.com/0/140547/c759a318-55de-9e04-cba3-a005d56de3f0.png)

2.表示したリストの最下部にある「開発者リソース」の「リソース」を選択。（※この後、環境によりログインが改めて求めらるかも知れませんが、現在と同じOffice365のログインアカウントを入力してください）
![リソース画面の選択](https://qiita-image-store.s3.amazonaws.com/0/140547/a7d5040b-aa96-ba93-1b12-9a9b458def32.png)

3.表示した画面のURLの下記部分の文字列をコピーしテキストファイルとして保存します。（このURLをPowerBIからの接続先情報として利用します）
![URLコピー部分](https://qiita-image-store.s3.amazonaws.com/0/140547/0646d2a0-ebe0-3be3-8502-ff3b0cba1884.png)

4.PowerBIデスクトップを起動して、「データーを取得」から「その他」を選択します。
![PowerBIデータ接続説明スクリーンショット](https://qiita-image-store.s3.amazonaws.com/0/140547/a10e78f6-5ce4-afe5-3b93-f590751c5b0d.png)

5.「データを取得」ウィンドウから、「アプリ用 Common Data Service（ベータ）」を選択し「接続」を押します。
![アプリ用 Common Data Service（ベータ）へ接続スクリーンショット](https://qiita-image-store.s3.amazonaws.com/0/140547/9c93a4e4-537c-ca40-9901-a6fdf9d2f2d4.png)

6.「アプリ用Common Data Service」ウィンドウの「サーバーURL」に先ほどのPowerAppsの設定画面で保存したURLの文字列を貼り付けて「OK」ボタンを押します。
![サーバーURL入力スクリーンショット](https://qiita-image-store.s3.amazonaws.com/0/140547/a71ea3c1-afb2-e5ee-26bc-83fc6fb6cc72.png)

7.「ナビゲーター」ウィンドウの「エンティティフォルダ」を開き接続したいエンティティを選択し「読み込み」ボタンを押します。
![名称未設定-5.png](https://qiita-image-store.s3.amazonaws.com/0/140547/6f21f2dd-5de7-7832-9350-d409f22a4fdd.png)

8.一通り読込が完了すると「フィールド」にエンティティとフィールドが表示されます。
![名称未設定-6.png](https://qiita-image-store.s3.amazonaws.com/0/140547/2ace82c3-2c0e-0dc1-5132-ef867f2fb0f5.png)

以上で、接続設定完了です。

##最後に
記事の初めに書いた「社内で、どのように工数管理を可視化して業務改善したか」を、12月21日（金）に行われる、「ローコーディングの極み！Power Platform Day Winter '18」で、登壇させていただき詳しくお話することになりました。
ご興味のある方は、ぜひセッションへのご参加をお待ちしております。

■ローコーディングの極み！Power Platform Day Winter '18
https://power-platform.connpass.com/event/111641/
(Swift 3)ViewController同士の値の受け渡し

今回、ViewController同士の値の受け渡し方法がわかったので、メモとして書いていきます。

UIはこんな感じ
<img width="728" alt="スクリーンショット 2018-12-16 2.18.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/322915/48cca971-4256-44b3-86c0-58ee15aa4293.png">

仕様：
”GO”を３回タップすると右の画面（MainView)に遷移して、”Back”を４回タップすると左の画面(SecondView)に遷移する簡単なもの。
MainView→SecondView: ”Hello”を渡す
SecondView→MainView: ”Back”を渡しLabelに表示する


MainViewのソースコード

```swift:ViewController.swift

    var backText: String?
    @IBOutlet weak var label: UILabel!

    //画面遷移時に呼ばれる
    override func prepare (for segue: UIStoryboardSegue,sender: Any?){
        guard let identifier = segue.identifier else {
            //identifierが取得できなかったら処理を終える
            return
        }
        
        if identifier == "toSecond" {
            let secondViewController = segue.destination as! SecondScreen
            //SecondScreenで宣言した変数（String型）にsenderの値を格納する
            secondViewController.receiveText = sender as! String
        }
    }
    
    var count=0
    ///タップするたびに呼び出される
    @IBAction func Button(_ sender: UIButton) {
        
        count = count + 1
        print(count)
        
        if count == 3 {
            //SecondScreenを呼び出して表示する
            //self.performSegue(withIdentifier: 遷移するidentifierの名前, sender: 送りたいもの（今回は”Hello"）)
            self.performSegue(withIdentifier: "toSecond", sender: "Hello")
            count = 0
        }
    }
```

SecondViewのソースコード

```swift:SecondScreen.swift
    
    //受け取る値を格納するもの
    var receiveText: String?

    override func viewDidLoad() {
        super.viewDidLoad()

        //表示
        print(receiveText)
        // Do any additional setup after loading the view.
    }
```

```swift:SecondScreen.swift
    var count = 0
    
    @IBAction func BackButton(_ sender: UIButton) {
        
        count = count + 1
        print(count)
        if count == 4 {

            //MainControllerの情報を取得
            let pvc = self.presentingViewController as? ViewController

            //MainControllerにあるラベルに”Back”を表示させる
            pvc?.label.text = "Back"

            //MainViewに戻る
            dismiss(animated: true, completion: nil)
        }
    }
```

これでViewController同士の値の受け渡しができるようになる。

>参考
>>【Swift】コードを使った二つの画面遷移の方法
https://qiita.com/zlia_7/items/e99b77372d8c0f38d98b
>>Swift 前画面への値受け渡しについて
https://teratail.com/questions/47140
>>NavigationControllerとViewControllerの遷移/値の渡し方/受け取り方/戻り方まとめ
https://virusee.net/swift4-move-view/
kubeadmでノード追加時にconfigmaps "kubelet-config-1.13" is forbiddenとなったときの対処法

# 事象

kubeadmでKubernetesクラスタを運用していて、**久しぶりに**ノード追加をしようと、新しいノードでkubeadm joinしたらconfigmaps "kubelet-config-1.13" is forbiddenというエラーになる場合があります。

おそらくは2018年12月頃より以前にクラスタを作成し、それ以降にノードを追加しようとした際に発生します。

```
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.13" ConfigMap in the kube-system namespace
configmaps "kubelet-config-1.13" is forbidden: User "system:bootstrap:######" cannot get resource "configmaps" in API group "" in the namespace "kube-system"
```

# 原因

この時期の前後で、kubernetes.repoから導入するkubeadm,kubeletのバージョンが1.12から1.13に上がったと考えられます。すると、クラスタ作成時は1.12で作成されますが、ノード追加時に新規ノード側のkubeletが1.13になってしまい、バージョンが不整合になっていることが原因です。

内部的には、kubelet-config-1.12というConfigMapしかない状態で、新規ノードがkubelet-config-1.13を探しに行ってエラーになっています。

そのため、両者のバージョンを合わせる必要があります。今回は、クラスタ全体をバージョンアップするのではなく、新規ノードのバージョンをクラスタに合わせる方法で対応します。

# 手順

新規ノードでkubeadm,kubeletをインストールするときにバージョンを明示します。例えばyum系の場合は次のようにします。

```
# yum install -y kubelet-1.12.3-0 kubeadm-1.12.3-0 --disableexcludes=kubernetes
```

これで、kubeadm joinすれば問題なく通るはずです。

以上です。
ラズパイとQRコードリーダー(not カメラ)で何か作れるように

[レッドインパルス](https://redimpulz.com/)のたかけんです。
こちら、[IoTLT Advent Calendar 2018](https://qiita.com/advent-calendar/2018/iotlt_neo) 、16日目の記事になります！

## はじめに

ラズパイとQRコードを組み合わせ作品例って、多いですよね。
勤怠管理とか蔵書管理とか。

[Raspberry Pi 3 QRコードリーダー - Qiita](https://qiita.com/maskoba/items/0773e7139ba417e2f6ce)

実装方法として、カメラを取り付けて画像認識でQRを読み取る方法があります。
しかしこの方法の場合、QRの読み取りの精度やそこまで良くなかったり読み取るまでに時間がかかったりなどの問題もあります。

## USB接続のバーコードスキャナを使う

USB接続のバーコードスキャナを使うと、ちょっと値段はしますが、素早く、かつ正確に読み取ることができます。

[Amazon | Sumeber 自動バーコードスキャナ無指向性ハイスピードCCDデスクトップ2Dミニバーコードリーダーハンズフリーモバイル支払いのための2M USBケーブルで (MP168) | バーコードスキャナー | 文房具・オフィス用品](http://amzn.asia/d/44KWZLI)

構成としては、こんな感じになります。

![raspi_qr.png](https://qiita-image-store.s3.amazonaws.com/0/71453/2c68ad63-1ddc-a33a-ff72-4759e177aefc.png)

## 問題

USB接続のバーコードスキャナは、外付けのキーボードとして認識されます。
なので、ラズパイでそのまま使おうとすると、入力待ちのターミナルやブラウザなどの入力フォームにカーソルがフォーカスされていないと、入力できないです。

IoTデバイスなので、ラズパイの起動が完了したらフォーカスとか気にしないで、QRコードが読めるようにしたいですね。

## バックグラウンドのキー入力を取得する

バックグラウンドのキー入力を取得できるpythonライブラリを使います。

https://pypi.org/project/pynput/

以下、サンプルコードです。

```python
from pynput.keyboard import Key, Listener

def on_press(key):
    global qr_data
    # 1文字ずつqr_dataに
    if str(key) != 'Key.enter':
        try:
            qr_data += key.char[0:1]
            return
        except AttributeError:
            return
    # 最後はenter入力になる
    else:
        print(qr_data)
    qr_data = ''


if __name__ == '__main__':
    with Listener(
        on_press=on_press,
    ) as listener:
        listener.join()
```

バックグラウンドのキー入力が取れるようになったら、後はカメラの場合と同じですね。

私はこの後は、pynputとWebSocketサーバをThreadで立ち上げ、キー入力の結果をWebSocketで送り、結果をラズパイに取り付けたモニタのブラウザに表示させつつ、Kintoneにデータを送るようなプログラムに作成し、Supervisorでデーモン化し、systemdで自動起動するようにしました。

## 余談

バックグラウンドでキー入力を取れるということは、悪用もできそう...。
使い方にはご注意ください！！

### 追記

MacOSだと、sudoで実行してもキー取得できなかったです。
おそらくセキュリティ対策が講じられているのかと。


## 参考

[Pythonでキーイベントを取得したかったけどできなかった話←できました。 - 豆腐とコンソメ](https://www.tohuandkonsome.site/entry/2017/05/22/002531)
私のゼミにおけるプレゼン指南

# はじめに
研究室に配属されて1年8ヶ月立ち，やっとアウトプットする気になった私が
ゼミで学んできたプレゼンテーションのやり方について書きます．

備忘録と後輩に向けての資料的な役割もあるので
うちのゼミ特有の決まりは無視してください．

# パワーポイントの設定など
まずは，プレゼンで使うパワーポイントの設定をしましょう．

- スライドサイズを3:4に
- ページ番号を表示させる

慣れてきたら，スライドマスターから自分で細かく編集するのも良いですが，
最低限この2つの設定はしておきましょう．


[スライドのサイズを変更する](https://support.office.com/ja-jp/article/%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E3%81%AE%E3%82%B5%E3%82%A4%E3%82%BA%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B-040a811c-be43-40b9-8d04-0de5ed79987e)
[パワーポイントでスライドに番号を挿入する方法](https://dekiru.net/article/5369/)

# スライドは発表の補助ツール
プレゼンテーションにおいて，スライドは大切ですが，
役割はあくまで補助ツールです．
そこをしっかりと意識して作る時の注意事項についてまとめます．

### 文章はなるべく書かず，体言止めにする
上記で述べたように，補助ツールなので，長々と文章を書く必要はありません．
なるべく体言止めで短くまとめるのが良いです．

聴講者の立場になって考えても，発表者の発言を聞きながらとなると余計に
長文を読む気にはならないと思います．

### 1枚のスライドに言いたいことを1つ
１枚のスライドに情報量が多すぎても良くないです．
結局何が言いたいのかわからなくなってしまいます．

スライドを作成する際は，このスライドで言いたいことは何かを
整理してから作るのが良いと思います．

### 図や表，式などを積極的に載せる
補助ツールとして，図や表を使うことは1番有効です．
特に図は，視覚的に見せる方が圧倒的にわかりやすいです．

なので，下手に文章で説明するよりも，
図を大きく載せて発表時に口で説明した方が良いです．

ただし，載せる際にも注意するべきことがあります．
- 図のリンク
- 式のパラメータや変数
- グラフの軸の説明や単位

これらをわかりやすく示しておくと聴講者が説明を聞きやすくなります．

# 研究発表での使い方
研究発表時に意識するべきことについてまとめます．
ここからはゼミ特有のルールも混ざります．

### 使用する色は3色
文字の色を変えることで印象を変えることは重要ですが，
たくさんの色を使いすぎると逆効果です．

また，色ごとに意味を統一しておくことも重要です．
なのでうちのゼミでは
- 黒：**標準**
- 赤：**メリット**
- 青：**デメリット**

の3色でスライドを作りましょう．

### 基本の流れを押さえる
研究の発表では，基本となる流れがあります．
これを押さえておけばある程度形になります．

- 背景・目的
- 提案手法
- 実験
- 結果
- 考察
- まとめ
- 参考文献
の順に発表していきましょう．

### 背景目的部分では，タイトルを全て説明する
発表タイトルには用いる手法や目的が含まれていると思います．

〇〇（手法）を用いた△△識別（目的）
のような形です．

これに対して，
なぜ〇〇という手法を使うのか
△△識別はなぜ必要なのか
というのを背景目的部分でしっかりと説明してください．

### スライド間の流れを意識する

１枚１枚のスライドに繋がりがない発表をする人は多いと思います．
1枚目：背景について説明します．~~です．
2枚目：次に目的を説明します．
3枚目：次に提案手法について説明します．

といった形で，スライド間に繋がりがありません．
喋り方にもよりますが，1つの発表は繋がったものにしましょう．

1枚目：--といった背景があります．
2枚目：そこで--をする必要があるため，本研究の目的は--です．
3枚目：目的をを達成するために~~という手法を提案します．

という形で繋がりのある発表の方が聴講者が理解しやすいです．


# 細かい注意事項あれこれ
他にもあげるとキリがないですが，自分の備忘録のためにも
覚えている分だけ注意事項を書いておきます．

### 英語の略称は正式名称を書いてから使う
論文などで書くときも同じですが，
いきなり英語の略語などを使うのはNGです．

Leave-One-Out-Cross-validation(LOOCV)法
という風に正式名称を１度書いたあとで略称を使いましょう．

### 常に発表として完結させる
これは完全にうちのゼミ特有の話になりますが，
毎週行われるゼミでの発表だったとしても，その発表で完結させてください．

なので，「今週の進捗」というようなスライドはいりません．
先週の発表で説明したので省略するなどはもってのほかです．

毎回初めての聴講者に対して全て説明するようなつもりで発表することが
1番練習になると思います．

### 箇条書きは並列なもので統一する

良い例
- 犬
- 猫
- うし

悪い例
- 犬
- 米
- 鞄

説明している場面によっては一概に悪いと言えませんが，
意図を理解していただければと思います．

# まとめ

常識的なことからゼミ特有の細かいことまで色々と説明してきましたが，
結局1番重要なことは，**聴講者がわかりやすいかどうか**です．

上記のルールから多少外れたとしても，聴講者がわかりやすくなる場合もありますし，
常に自分のスライドや発表が理解してもらえるか客観的に評価していくと良いと思います．
CloudSQLのIO性能を観察する（準備編）


# 概要

CloudSQLのIO性能を観察する。CloudSQLはGCPで提供されているRDBMSのマネジメントサービス。（AWSで言うところのRDS）

CloudSQLのディスクのスループットとIOPSは、ディスクサイズで決定されるため、ここを変化させたときのパフォーマンスの変化も観察する。

この記事では検証のための準備を行う。（長くなりそうなため記事を分割）

# 検証方法

MySQLの"LOAD DATA LOCAL INFILE"でファイルから巨大なデータを読み込ませる。必要に応じて複数プロセスから並列でデータをロードする。

# 環境
## CloudSQL
 * MySQL 第 2 世代
 * MySQL 5.7
 * asia-northeast1-a
 * インスタンスタイプ、ディスクサイズは検証ごとに変える

## クライアント側
CloudSQLに対して接続するためのクライアント。 

 * ComputeEngine
 * n1-standard-1（vCPU x 1、メモリ 3.75 GB）
    * クライアント側がボトルネックになりそうなら、スケールアップする
 * asia-northeast1-b
 * Debian GNU/Linux 9
 * ディスクは200GBのボリュームをアタッチ

# セットアップ
## クライアントの作成、設定

 * WebUIからインスタンスを作成
 * IPアドレスは、CloudSQLに登録するため固定IPアドレスにする（エフェメラル -> 静的）

```
$ sudo apt install mysql-client
$ mysql --version
mysql  Ver 15.1 Distrib 10.1.37-MariaDB, for debian-linux-gnu (x86_64) using readline 5.2
```

## MySQLインスタンスの作成

 * WebUIからインスタンスを作成
 * 接続を許可するIPするとして、クライアントの静的IPアドレスを指定
    * 本当はCloudProxyを使った方がいいが、面倒なので今回はIPアドレスを許可する

## 検証用のデータやMySQLテーブルの用意

BigQueryの公開データが、いい感じでサイズが大きいので利用させてもらう。 
今回は、`bigquery-public-data.stackoverflow.stackoverflow_posts`を使った。（行数：31,017,889、サイズ：29.36 GB）

* BigQueryのWebUIから上記のテーブルをCSV形式でエクスポートする。圧縮は指定した方が良い。
    * 必要に応じてストレージ（GCS）のバケットを作成する
    * データサイズが大きいので、エクスポート先のファイル名に"*"を使わないとエラーになる
* ComputeEngineでもろもろ準備する

```
$ cd /path/to/work_dir
$ mkdir data/ && cd data/
$ gsutil -m copy gs://your_backet_name/csv/* .

# いい感じにファイル名を指定していたら不要かも
$ find . -type f　| xargs -i mv {} {}.gz

$ find . -type f | xargs gzip -d

$ cd ..
```

スクリプトを設置して実行権限を付与する。

```sh:table_load.sh
#!/bin/bash

# 環境に合わせて変える
FILE_DIR="data/"
MYSQL_HOST="xxx.xxx.xxx.xxx"
MYSQL_USER="user"
MYSQL_PASS="pass"
MYSQL_TABLE="t1"
MYSQL_DB="mydb"

for f in $(ls $FILE_DIR); do
	echo "START $f"
	# 一行目はCSVのヘッダがあるのでIGNOREする
	# バックスラッシュが含まれるとエスケープの関係で"utf-8ではない"的なエラーが出るので、"ESCAPED BY"が必要
	command="LOAD DATA LOCAL INFILE \"$FILE_DIR$f\" INTO TABLE $MYSQL_TABLE
	         FIELDS TERMINATED BY ',' ESCAPED BY '' IGNORE 1 LINES;"
	mysql -h$MYSQL_HOST -u$MYSQL_USER -p$MYSQL_PASS -e "$command" $MYSQL_DB
	echo "END $f"
done
```

* MySQLにデータベース、テーブルを作成する

```
MySQL [(none)]> create database mydb;
MySQL [(none)]> use mydb;
MySQL [mydb]> create table ...（下記を参照）
```

```sql:create_table.sql
-- id, parent_idなどはBigQueryではINTEGERのためINTにしたくなるが、データがない(null)の場合もあるので、
-- INTにするとwarningが発生する. 今回はVARCHARやTEXTにしても問題ないと判断.（IO性能が見たいだけなので）
CREATE TABLE t1 (
    id VARCHAR(10),
    title TEXT, 
    body TEXT, 
    accepted_answer_id VARCHAR(10), 
    answer_count VARCHAR(10), 
    comment_count VARCHAR(10), 
    community_owned_date TEXT, 
    creation_date TEXT, 
    favorite_count VARCHAR(10), 
    last_activity_date TEXT, 
    last_edit_date TEXT, 
    last_editor_display_name TEXT, 
    last_editor_user_id VARCHAR(10), 
    owner_display_name TEXT, 
    owner_user_id VARCHAR(10), 
    parent_id VARCHAR(10), 
    post_type_id VARCHAR(10), 
    score VARCHAR(10), 
    tags TEXT, 
    view_count VARCHAR(10)
);
```

* 設定したスクリプトを実行すると、データのロードが始まり、データベースにIO負荷がかかる

# 参考文献

* 13.2.6 LOAD DATA INFILE 構文
    * https://dev.mysql.com/doc/refman/5.6/ja/load-data.html