OmniAICreator/Qiita-1.07M huggingface dataset:
Processingで強引にシーン管理

## TL; DR



- Processingの仕組みを書き換えて、シーン管理を可能にしてみた
- 作ったもの: [progfay/sceneManager](https://github.com/progfay/sceneManager)





## シーンごとに、コードを書き分けたい



一般的にシーンをかき分ける方法はたくさんあります。

Processingでは以下のようなコードで、シーン別に処理を記述することができます。



```java
void draw () {
    switch (MODE) {
        case 1: // main menu
            drawMainManu();
        case 2: // config menu
            drawConfigMenu();
		// :
    }
}

void mousePressed () {
    switch (MODE) {
		case 1: // main menu
            mousePressedOnMainMenu();
        case 2: // config menu
            mousePressedOnConfigMenu();
        // :
    }
}
```



しかし、上記のコードでは、問題点がいくつかあります。

- シーンが追加される度に、 `draw()` や `mousePressed` などを更新する必要がある
- 描画やイベント毎に関数を作成しなければならず、まとまりがない
- `frameCount`は初期化されず、`setup()` のような関数の実行もし辛い



そこで、以下のような書き方ができることを理想として、本記事ではそれを目指していきます。



```java
class MainMenuScene {
    void setup () {
        // setup main menu
    }
    
    void draw () {
        // draw main menu
    }
    
    void mousePressed () {
        // mouse pressed on main menu
    }
}

class ConfigMenuScene {
    void setup () {
        // setup config menu
    }
    
    void draw () {
        // draw config menu
    }
    
    void mousePressed () {
        // mouse pressed on config menu
    }
}
```





## Processingの仕組みを書き換える



[Processing](https://processing.org/) では、 `handleDraw()` をOverrideすることで `draw()` や `setup()` などの仕組みをハックすることができます。 (参考: [Processingの仕組みを覗いてみる](https://qiita.com/progfay/items/27b8bce2ae01602c32ca#handledraw) )



試しに、以下のコードを実行すると、 `"handleDraw"` の出力が繰り返されるだけで、 `setup()` や `draw()` は実行されません。



```java
@Override
void handleDraw() {
    println("handle draw");
}

void setup() {
    println("setup");
}

void draw() {
    println("draw");
}
```





## `handleDraw()` にシーン管理処理を組み込む



`handleDraw()`  をOverrideして、シーン管理のための処理を組み込んでしまえば、理想のシーン管理が実現できます！



以下のコードみたいな雰囲気で組み込みます。



```java
@Override
public void handleDraw () {

    // :

	if (frameCount == 0) {
		currentScene.setup();
	} else {
        
        // : 
        
		currentScene.draw();
        
        // :

	}

    // :

	frameCount++;
}
```



これだけでは `mousePressed` などのイベント系が使えないので、そちらは別の方法で対処します。

Processingに組み込まれているイベントは高々11個なので、以下のような処理を書くことで対応できます。



```java
@Override
  void mousePressed() {
  currentScene.mousePressed();
}
```





## 適当に作った



GitHub: [progfay/sceneManager](https://github.com/progfay/sceneManager)



- シーン作成は `Scene` クラスを継承して、普段どおりに `setup()` や `draw()` , `mousePressed()` などを書く

- `SceneManager.set(sceneName, Scene)`: シーンをセットする
- `SceneManager.changeScene(sceneName)`: セットしたシーンに遷移する



その他のAPIはコードを読んでください。 (https://github.com/progfay/sceneManager/blob/master/src/SceneManager.pde)



## 終わりに



この方法では、Processingの仕組みを書き換えてしまっているため、意図せぬ挙動をする可能性があります。

本記事で伝えたかったのは、Processingは仕組みを書き換えても許してくれるような寛大な心を持っているということです。

非常にニッチな知識ですが、様々なことに応用できることを祈っています。
epsファイルがLaTeXでズレる問題を解消

# 問題
matplotlib等で作成したepsの座標がズレているために，LaTeXで図の位置がずれてしまう．という問題がある．
epsのBoundingBoxが悪さをしている．

# 解決方法

Ghostscriptを入れた際についてくる，`ps2pdf`と`pdf2ps`を用いる．
具体的には，`ps2pdf`を用いて一度epsファイルをpdfファイルにする．
`pdf2ps` を用いて，変換後のpdfファイルを再度epsファイルに変換する．

一度，PDFファイルに変更する事によって，上手く座標が調整される．

なお，Ghostscriptは以下のコマンドで手に入る．

``` 
brew install ghostscript
```


上記の動作を実現するために，
以下の様なスクリプトを書いている．

```epsbound.sh
#!/bin/tcsh
set input = $1:r
ps2pdf -dEPSCrop -dPDFSETTINGS=/prepress $input.eps $input.pdf
pdf2ps $input.pdf {$input}_rev.eps
rm $input.pdf
```
検索効率倍増！ Chromeをより便利にする拡張達

## はじめに
- Chromeを使う際に便利な拡張をご紹介します
- マウスをほとんど使わなくても、操作する事が出来るようになるので検索効率が倍増します

今回紹介するのは以下の拡張です。
- [Vimium](https://chrome.google.com/webstore/detail/vimium/dbepggeogbaibhgnhhndojpepiihcmeb?hl=ja)
- [Copy URL+](https://chrome.google.com/webstore/detail/copy-url%2B/capojgaalppngkaagaobmigigcgnidmn/related?hl=ja)
- [uAutoPagerize](https://chrome.google.com/webstore/detail/uautopagerize/kdplapeciagkkjoignnkfpbfkebcfbpb?hl=ja)
では順番に紹介していきます。

## Vimium
非常に多機能な拡張で導入するだけでほぼマウスを使わずにブラウザ操作をできるようになるのですが、私がよく使う機能を紹介します。

### jとkで上下スクロール
![jk.gif](https://qiita-image-store.s3.amazonaws.com/0/295800/38ffa350-df00-f159-2a77-6e025ba8ed0e.gif)

### f で表示された黄色の文字を叩きリンク先にジャンプ
![f.gif](https://qiita-image-store.s3.amazonaws.com/0/295800/ac73e161-ee22-0e50-fca7-a80e998acffb.gif)

### ggとGで一番上、一番下にスクロール
![g.gif](https://qiita-image-store.s3.amazonaws.com/0/295800/85d836b9-bf71-19b4-4c11-8c116abab231.gif)


### hで戻る,ｌで進む（※カスタマイズが必要）
![hl.gif](https://qiita-image-store.s3.amazonaws.com/0/295800/f885776a-c76a-b395-a3ce-86ed9b6bdb0b.gif)


【カスタマイズ】
1. vimium拡張ボタンをクリックしOptionsを表示
2. custom key mappingsへ以下のコードを貼る

```
map h goBack
map l goForward
```

## Copy URL+
- 開いているページのURLをショートカットでクリップボードにコピー出来るようになります
- Vimiumでも、```yy```を押せばできるのですがショートカットキーを使用したときに、通知がこないのでこちらをつかっています

![url.gif](https://qiita-image-store.s3.amazonaws.com/0/295800/f50f9b4a-d71d-17de-6bda-98496aec78bc.gif)

<img width="1243" alt="スクリーンショット 2018-12-24 15.47.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/295800/7466a7a7-8868-d9c8-c3ca-4745be6cd4a8.png">

またオプションにある引数を利用する事で、**titleタグのテキスト**や**選択しているテキスト**をコピーしたり、**短縮URLでのコピーやaタグに入れた状態でコピー**する事など様々なカスタマイズができるので便利です(^o^)
ショートカットも自分の好きなものに設定する事ができます。

## uAutoPagerize
ページナビゲーションを自動的に展開してくれる拡張です。

![url.gif](https://qiita-image-store.s3.amazonaws.com/0/295800/86d0e368-85d7-4524-4b92-d2b207fda3c3.gif)


## 最後に
AlfredやKarabiner-Elementsを使うと、もっともっとChrome便利に使う事が出来るようになるのですが、それままた次の機会に!
では、よき検索ライフを!!
Google Chrome 拡張機能 "Window Resizer"について

# Window Resizerについて
ブラウザ Google Chromeの拡張機能である。※ 画面のリサイズなどに用いられる。

# Window Resizer 追加の手順

1. Google検索のトップページより「アプリ」をクリック。
![スクリーンショット 2018-12-24 15.47.26.png](https://qiita-image-store.s3.amazonaws.com/0/304332/d308fcbd-3781-d937-0467-4aa98edd3592.png)

2. 「ウェブストア」をクリック。
![スクリーンショット 2018-12-24 15.47.33.png](https://qiita-image-store.s3.amazonaws.com/0/304332/a799d547-958e-15bc-4d6b-00726066c682.png)

3. 「Window Resizer」を検索すると、検索結果に「Window Resizer」が表示されるので、「Chromeに追加」をクリック。
![スクリーンショット 2018-12-24 15.47.47.png](https://qiita-image-store.s3.amazonaws.com/0/304332/2bff2c49-7552-9858-54c9-f1c6417a87b2.png)

4. 画面右上に「Window Resizer」のアイコンが出てくるので、その中の「Toggle the resize tooltip」をクリック。
![スクリーンショット 2018-12-24 15.48.43.png](https://qiita-image-store.s3.amazonaws.com/0/304332/dc4d8345-14c7-8a07-3b7b-5b3f992e896b.png)

5. 画面サイズ変更時にpx表記で右下にその時の画面サイズが表記されるようになる。
![スクリーンショット 2018-12-24 15.58.08.png](https://qiita-image-store.s3.amazonaws.com/0/304332/fedcd255-dcac-11b0-482a-b30ae689d852.png)

# 終わりに

Bootstrapのレスポンシブデザイン(グリッドシステム)を理解する際に、参考になった。
【平成30年度秋期】応用情報に落ちてみた

#応用情報受けてみた！
「やっぱりITに従事するからには情報処理系は取っておきたいよね！」ということで、
応用情報を受けてきました。
※基本情報は平成29年度秋期で取得済みです

#さあ結果は…
![2018秋季結果.png](https://qiita-image-store.s3.amazonaws.com/0/188440/2e1bcaa3-fc7a-52c9-e6fa-39ea1b09b9b8.png)

**惜しい…悔しい…**
午後試験が10点足りませんでした。ちくしょっ
逆に午前試験は合格ラインの20%超えているので、
合格ラインから見れば十分得点できていましたね。

##ただの結果報告ではつまらない
不合格者なりに色々お伝えできることがあると思うので、
ポエムとしてツラツラ書いていきます。

#どんな勉強をしたか？
## 試験概要
基本情報を持っているので、応用情報もさほど変わらないことを理解していました。
まず簡単な試験の概要です。

- 午前試験：四択、全80問、80点満点。合格ラインは60%(48点)以上得点すること。
- 午後試験：記述、全10問中5問を選択して回答(うち、セキュリティ文やは必須)、100点満点。合格ラインは60%(60点)以上得点すること。

**午前試験がすべて四択であり、かつ半分近くが過去問の使いまわし**となります。
**午後試験は毎年問題が異なり、問題数や配点も異なるため対応が難しい**ことで知られています。(例えば過去のセキュリティ問題が解けるようになることが対策にはならないということです)
そのため難易度としては完全に**午前試験 ＜＜＜ 午後試験**です。

## 午前対策

> 半分近くが過去問の使いまわし

ここを突かない手はないですね。**ひたすら過去問を解きまくりましょう。**
私は午前試験対策として、[応用情報技術者試験ドットコム](https://www.ap-siken.com/apkakomon.php)さんでひたすら過去問を解きまくりました。
具体的にどのくらい解いたかというと…

![ドットコム.png](https://qiita-image-store.s3.amazonaws.com/0/188440/69551eb4-1934-1eac-0bff-538e337dfeed.png)

意外とやってましたね。逆にこれだけやれば午前試験についての不安はなくなると思います。午前試験において不安はなかったので。
私の場合は通勤時間(電車)が片道1時間以上あるので、少なくとも出社時はずーっと解いてました。帰りは元気があればやる程度です。
もともと音楽を聴きながらぼーっとしているだけだったので、**時間を有効活用できているような気持ちになりとても有意義**でした。

## 午後対策
こちらは正直言って効果的と言える対策が最後まで見つかりませんでした。
午前と同じく応用情報技術者試験ドットコムさんの過去問を解く、しかやりませんでした。
過去問から選択する分野を絞りこみ、その5分野を集中的に過去問を解きました。

#何が足りなかったか
**アウトプット(過去問)だけではなく、インプット(学習)が足りなかったことが原因**かな、と思っています。
午前試験については基本情報と同じく過去問の使いまわしがメインになるため、
過去問を解くことに集中した方が合格に近づく勉強方法であることが分かっていました。
位置づけとしても午前試験が基礎知識になるため、午前試験対策を主にやっていきました。

しかしその結果、午前で出題される知識しか定着せず、午後試験に答えられるほどの知識が身についていないことに気づけませんでした。
次回の春試験に向けて、**参考書を購入しインプット(学習)をメイン**にやっていこうと思います。

#何を得られたか
###日々の充実感、モチベーションが得られた
これは嬉しい誤算でした。

受験した理由は何気ないものでしたが、
いざ受験申込をして合格を目指し始めると**日々の行動がそれに向けて動き出します。**
先述しましたが「ただの通勤時間が勉強できる時間になる」ように、**いわば人生において意味をもてなかった時間が、資格取得という今後の人生で役立つかもしれないものを得るための時間に変わるようになりました。**
それによって仕事するだけの毎日では得られなかった**充実感やモチベーションを得ることができる**ようになり、直接関係はない日々の業務や私生活もメリハリがでます。

「合格しないと意味がない！」と思っていましたが、受験することそのものに意義があると感じます。

#最後に
**春試験で合格できるように頑張ろう！次こそは合格を！**

見事合格された皆さんはおめでとうございます！！
残念ながら不合格だった皆さんは一緒に頑張りましょう！！
メモ：「３０日でできる！OS自作入門 」13日目

## タイマー２

1) 文字列表示を簡単に
- 文字列を背景も一緒に作る関数を作ってリファクタリング

2) FIFOバッファを見直す
- 今までは timerごとにfifo8_statusを呼ぶ必要あった、タイマ１００個になったら困る
    - timerfifo を一個だけにして取り出すときにどのタイマかを判断する方法

3) 性能を測定してみる (c-f)
- Qemu 上ではうまく動作しかなった
    - 遅いのはおそらく、画面の再描画されていないからだと思う。
    - 10秒のタイムアウト時画面表示されないのはなぞ

4) FIFOバッファを見直す２ (g)
- FIFO バッファを一個にして、カーソル点滅、各タイマ、キーボード入力、マウス入力などをIDで分ける
- FIFO8 (unsigned char *buf) -> FIFO32 (int *buf)

5) 割り込み処理を短く４　（ｈ）
- TIMER を LinkedList にして　　next を持つ

6) 番兵を使ってプログラムを短くする
- 最低でもタイマ１個はあるようにすること

１３章はほぼリファクタリングに関するものだった。
Amazon CloudFrontをAnsibleで構成管理（cloudfront_distribution）


# 経緯
仕事でもSPA（single-page application）を利用した構成を依頼される機会が増えてきました。
IaaS中心での構成に比べ、コストが安く済むため、スモールスタートでコストを抑えたいという時にメリットがあるためです。
今回はSPAの構成でよく使われるAWS CloudFrontをAnsibleの「cloudfront_distribution」で設定する方法を紹介したいと思います。

# cloudfront_distributionモジュールについて
Ansibleの中でAWS CLIを用いて設定する方法もありますが、今回はモジュールを用いた設定例を紹介します。

[cloudfront_distribution](https://docs.ansible.com/ansible/2.6/modules/cloudfront_distribution_module.html)
基本的には公式ドキュメントに書いてある通りなので、説明は省きます。

# Ansible Playbookの設定例
なにはともあれ実際の設定例。

```main.yml

- set_fact:
    origin_domain_name: "s3.hogehoge"
    origin_website_domain_name: "s3.hogehoge.s3-website-ap-northeast-1.amazonaws.com"
    domain_name: "hogehoge.com"
    default_root_object: "index.html"
    # logファイルをs3に格納する場合は利用
    # bucket_for_logs: "log.s3.hogehoge"
    # log_prefix: "logs/"

# create distribution
- cloudfront_distribution:
    default_origin_domain_name: "{{ origin_website_domain_name }}"
    # origin settings
    origins:
        - domain_name: "{{ origin_domain_name }}"
          id: "{{ origin_domain_name }}" 
        - domain_name: "{{ origin_website_domain_name }}"
          id: "{{ origin_website_domain_name }}" 
    #  cache behavior settiongs
    cache_behaviors:
        - path_pattern: "/static/*"
          target_origin_id: "{{ origin_domain_name }}"
          viewer_protocol_policy: "redirect-to-https"
          min_ttl: 0
          max_ttl: 31536000
          default_ttl: 86400
          forwarded_values:
            query_string: false
        - path_pattern: "/index.html"
          target_origin_id: "{{ origin_domain_name }}"
          viewer_protocol_policy: "redirect-to-https"
          min_ttl: 0
          max_ttl: 31536000
          default_ttl: 86400
          forwarded_values:
            query_string: false
    default_cache_behavior:
          target_origin_id: "{{ origin_website_domain_name }}"
          viewer_protocol_policy: "redirect-to-https"
          min_ttl: 0
          max_ttl: 31536000
          default_ttl: 86400
          forwarded_values:
            query_string: false
            cookies:
              forward: none
            headers: 
              - "*"
          smooth_streaming: false
          compress: false
          allowed_methods:
            items:
              - GET
              - HEAD
            cached_methods:
              - GET
              - HEAD

    # distribution settings
    price_class: "PriceClass_All"
    aliases : 
      - "{{ domain_name }}" 
    default_root_object: "{{ default_root_object }}"
    state: present
    #logging:
    #  enabled: true
    #  include_cookies: false
    #  bucket: "{{ bucket_for_logs }}"
    #  prefix: "{{ log_prefix }}"
```

#### 説明と備考

- リソースはS3に配置するものとしてoriginに指定しています。
- キャッシュの設定はデフォルトのものを入れているが必要に応じて変更を行ってください。
- Updateをかける際は冪等性を保つために「Distribution ID」を指定して実行した方が良さそうです。

# あとがき
現状のAnsibleモジュールでは、SSL証明書を設定する部分が未実装のため、そこも設定を入れようという場合にはAWS CLIを使った方が良い気がします。ただし、cloudfrontにACMの証明書を使う際は米国東部で作成したものだけ利用できます。
私の開発環境

### はじめに
アドベントカレンダー初投稿になります。
私の職場とプライベートでの開発環境について書かせていただきます。

### 自宅
#### キーボード
Happy Hacking Keyboard Professional2 US配列 墨 無刻印
初めて購入したHHKBになります。
無刻印にした理由はとにかくかっこいいから。
無刻印になれるのに苦労しましたが慣れれば快適です。(数字のキーだけどうしてもわかりにくかったのでRealforceの交換キーを使用しています)
#### マウス
Magic Trackpad2
自宅ではiMack 5k 27inchi を使用しているので付属のトラックパッドを使用しています。
トラックボール少し使用していた時期もありましたがやはりMacにはトラックパッドですね。

![IMG_7273.jpg](https://qiita-image-store.s3.amazonaws.com/0/199851/87b34944-67cc-263b-6b64-c7042afd612a.jpeg)

ちなみにパームレストは自宅、職場ともにエレコムのやつ使っています。
幅がHHKBと同じで安くて高さがちょうどよく愛用しています。

### 職場
#### キーボード
Happy Hacking Keyboard Professional2 US配列 白
今年のはじめにオークションにて１万円ほどで購入したものです。
SIer(笑)の文化であるキーボード持ち込み禁止の職場だったのですが今年の頭から客先への常駐で解禁されたので急遽入手しました。
(身バレ防止で公式の写真です)

![sample.jpg](https://www.pfu.fujitsu.com/hhkeyboard/hhkbpro2/images/overview_standard_l.jpg)

#### マウス
Elecom M-DT1URBK
トラックボールは人差し指はです。
赤いボールのやつほしい

![sample2.jpg](http://www.elecom.co.jp/photo/p02/M-DT1URBK_02.jpg)

### コーヒー
私はコーヒーは一切飲みません。
私の仕事中の飲み物といえば、

そう。**プロテイン**です。

最後におすすめのプロテインについて

#### X-PLOSION
現在メインで飲んでいるプロテインになります。
ナチュラル(味なし)で18kg(3kg*6袋)まとめて買うと1400円/kgと抜群のコスパを誇ります。

![aaa](https://shop4-makeshop.akamaized.net/shopimages/xp2013/0000000000112.jpg)

#### バルクスポーツ
前飲んでいたメーカになります。
味にもよりますがBIG WHEYという種類で大体2400円/kgくらいですが味はまあまあいいと思います。
Amazonの定期お得便の値段がコロコロ変わるので使用をやめました。

![aaa](https://www.bulksports.com/upload/save_image/bulk_bigwhey_5kg_sub_3.jpg)


#### ビーレジェンド
前一度お試しの１色バラエティーパックみたいなのを購入して試したのですがまずくてそれっきり買っていませんでした。
最近?出ていた波動拳味なるものが美味しいと評判で物は試しに購入したのですが大当たり。非常に美味しくはじめての方にもおすすめです。
味は公式には乳酸菌飲料の味のようです。最近はドラゴンボールとのコラボでかめはめ波味というのが出ています。(こちらはエナジードリンクの味らしいです)
こちらは3200円/kgと値が張ります。(他の味も大体1kg 3000円オーバー)
![aaa](https://dbcn1bdvswqbx.cloudfront.net/client_info/REALSTYLE/itemimage/BLPC18AP1/hadouken.jpg)

以上、私のおすすめプロテインでした。
タンパク質取れていますか？
足りていないタンパク質はプロテインパウダーで補いましょう!
【Android】マルチモジュール 簡単なサンプル

この記事はand factory Advent Calendar 2018 Day 24の記事になります。
前日は@tsumuchan の「[【Realm】忘れがちなcloseは、拡張関数のuseを使うと便利【Kotlin】](https://qiita.com/tsumuchan/items/c5e926a96229a92c1f06)」でした。

## きっかけ
Androidアプリを配信する方法として、従来のアプリをインストールする方法以外にも、インストールせずにアプリを試すことができるInstant Appや、アプリ全体ではなくユーザが必要としている機能毎にインストールができるDynamic Deliveryなど発表されています。これらを実現させるためにはアプリを複数のモジュールに分割する必要が出てきました。

また、上記の配信が不要でも、今後Androidアプリが高度化する上で、依存性を限られた部分に閉じ込めるコードを維持するために複数モジュールはありなのかと考えています。

ここでは、サンプルアプリを作成して、簡単な複数モジュールを動すところまでを書きたいと思います。

## 動作環境
Android Studio 3.2.1

## サンプルコード
https://github.com/yiwaisako/simple_multi_module_sample

## 作成手順
### アプリを新しく作成する
新しくアプリを作成して起動すると Hello World　という文字が表示されると思います。

### libraryモジュールを追加する
- [File] -> [new] -> [New Module] -> Android library を選択してnextを押します
- 名前はmylibraryを指定します。ディレクトリパスを適当な場所を指定して追加してください。

### appモジュールの依存設定にlibraryモジュールを追加する

```app/build.gradle
dependencies {
    implementation project(":mylibrary")　// この記述を追加

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
```

## libraryモジュール内にActivityを作成する
- libraryモジュールのsrc/main/java/パッケージ名/LibActivity(※1)を追加します。
  AndroidStudioが用意しているメニューからActivityを生成するとレイアウトファイルの用意やAndroidManifest.xmlの変更もやってくれるので便利です。

※1: appモジュールと同じ名前でActivityを追加すると上手く動かないです。おそらく名前が重複するとappモジュールのファイルを優先してビルドしているのかもしれません。


## 動作確認のためTextViewを追加する
- libraryモジュールのMainActivityのレイアウトXMLに動作確認用のTextViewを追加してください。

## appのマニフェストのアプリ起動時に表示されるActivityをlibraryのものに修正する
```app/AndroidManifest.XML

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
    <activity android:name="jp.yiwaisako.simple_multi_module_sample.mylibrary.LibActivity">
// 上のようにパスを変更
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>
```

## 動作確認
アプリを起動してlibraryモジュールに追加したActivityが表示されていれば問題ないと思います。

## まとめ
libraryモジュールを作成してActivityを立ち上げるまでを記載しました。ここまでは簡単に試すことができるので、複数モジュールを試すには良いかと思います。
ただ、DaggerやBuild.gradleの効率的な記載などハードルもありますので、自分なりに良い方法が見つかったら追記していきたいと思います。

## 参考
Multiple application modules in one Android project
https://medium.com/mindorks/multiple-application-modules-in-one-android-project-36e86ceb8a9

How modularization can speed up your Android app’s built time
https://medium.freecodecamp.org/how-modularisation-affects-build-time-of-an-android-application-43a984ce9968

annict-android
https://github.com/kgmyshin/annict-android

multi-module-no-susume
https://speakerdeck.com/kgmyshin/multi-module-no-susume
【プレゼン】1分で相手を動かす話し方 2/ 2【読書メモ】

https://qiita.com/h_sasaki_223/items/cb94ba4b9068a63b4c2f の続きです。
※対人で話す場合に必要な要素のみを抜粋

## 中学生が理解できるレベルの言葉しか使わない
- 難しい言葉を使うと、その言葉が引っかかり、その意味がやっと理解出来た時には、いつの間にか話は先に進んでいて、置いて行かれてしまった聞き手は「もういいや」と諦めてしまう
- 聞き手が完全に理解できる言葉を選ぶようにする

```
例: PVという言葉は業界によって意味が違う
- Web業界 -> Page View
- 音楽業界 -> Promotion Video
- ファイナンス -> Present Value
```

## イメージで心を動かす
1. ビジュアルを見せる
2. 「例えば」をキーワードに、具体的な事例を示す

```
「僕は、自分が勤めている会社が好きです。理由は3つあります。
1点目は働きやすい職場だからです。
2点目は一緒に働いている人たちが素敵だからです。
3点目は仕事にやりがいがあるからです。
```
どのくらい働きやすいのか？
働いている人たちは、どのくらい素敵か？ イメージが湧かない。

```
「僕は、自分が勤めている会社が好きです。理由は3つあります。

1点目は働きやすい職場だからです。
**例えば、フレックスタイムで自由に働け、またリモートワークで自宅で働くこともできます。**

2点目は一緒に働いている人たちが素敵だからです。
**例えば、人の足を引っ張るような人はいません。**

3点目は仕事にやりがいがあるからです。
**例えば、会社は常に新規事業に積極的で、チャレンジする機会に恵まれています。**
```

## ピラミッドストラクチャーは3段で作る
```
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　[結論(~は~である)]
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　｜
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　[根拠(なぜなら)]　　[根拠(なぜなら)]　　[根拠(なぜなら)]　　
　　　　　　　　　　　　　　　/           /              /       \             \            \
[事実（例えば~）]　　[事実（例えば~）]　　[事実（例えば~）]　　[事実（例えば~）]　　[事実（例えば~）]　　[事実（例えば~）]　　
```

## 「超一言」で包み込む
- 「聞き手にイメージが湧いて、納得してくれる、正しいことだと伝わる」　≠「聞き手が動いてくれる」
- 自分の伝えたいことを一言のキーワードで表す（覚えやすく、その一言でプレゼン全体を表現するようなキーワード）
- 例：「今日くる、明日くるではなく、きっちりくる、だから"キチリクルン"です」　「あの時の君のキチリクルン、よかったよ」

##　いかに相手の立場に立って、話すか
- 「主観（話している自分）のみ」ではなく、「話している自分と相手を俯瞰で見る」
- 実際に相手の席に座ってみる。聞き手の視点でプレゼンターの場所で自分が話しているところを想像してみる。

## プレゼンテーションのフレームワーク
詳細をまとめて挟み込む
- SDS(Summary(まとめ) - Detail(詳細) - Summary)  
主張と根拠のピラミッド
- PREP(Point(主張) - Reason（根拠） - Example（例示） - Point)  
革新的な取り組みの提案
- PCSF(Problem(問題) - Change(変化) - Solution(解決策) - Future(未来))

```
// 結論で挟むSDS
禁煙をすべきです。
理由は3つあります。
1点目は・・・。
例えば・・・。
2点目は・・・。
・・・
だから、禁煙をすべきなのです。
```

## まとめ

**準備**
- 出来るだけ簡単な言葉で組み立てる
- 聞き手の立場で話し手を想像する
- 話し手と聞き手を俯瞰で見てみる
- イメージを用意してみる

**話す内容**
- ３段のピラミッド（結論・根拠・例示）で構成する。
- 相手の頭の中に枠組みを用意してあげて、そこを穴埋めするようなイメージで話す。
- 印象的なキーワードで、相手の記憶に残す
- フレームワークに当てはめてみる
ruby on railsのエラーメッセージ日本語対応で躓いたこと

#エラー文日本語対応は充実したリファレンス多いが

[Rails で I18n を使って日本語化](https://qiita.com/yutackall/items/0ff97132f31e5bacbf00)

上記の記事を参考に行ったが、少々苦戦した。

これから同じような躓きをする初学者向けに、以下注意点２点投稿する。
##1.まずja.yamlテンプレートをgithubからコピーすべし

```
# 日本語のテンプレートをDL
wget https://raw.github.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml -P config/locales/
```

テンプレート置き場は `config/locales/`

##2.ja.ymlに追記したいなら書き順に気をつけるべし

上記の記事では
モデルのファイルは別に`config/locales/models/ja.yml`
に保存しているようだが、
今回はテンプレートに追記してみる。

```
ja:
  activerecord:
    errors:
      messages:
        record_invalid: "バリデーションに失敗しました: %{errors}"
        restrict_dependent_destroy:
          has_one: "%{record}が存在しているので削除できません"
          has_many: "%{record}が存在しているので削除できません"
    attributes:
      user:
        name: 名前
        password: パスワード
        email: Eメール
```
(上記はユーザーモデルを追記した場合）

ymlはインデントで階層を認識しているっぽいので
きちんと`ja.activerecord.attributes.モデル名.` 
となるように、インデックスを揃えて記述することがポイント
（筆者は当該ファイルの一番下に追記したらSyntaxちゃんに
怒られたので注意）

ただ、管理しやすいようにファイルは分割して管理した方が良いかも
#参考記事

[YAMLとは何か？ - いつもRailsの設定ファイルで出てくるやつの正体](https://qiita.com/Yama-to/items/587544993fb62610528a)
[i18nについて]
(https://morizyun.github.io/ruby/rails-function-i18n-internationalization.html)
Linux ファイルの圧縮、解凍

#gzip, gunzip

圧縮コマンド：gzip　　
解凍コマンド：gunzip、もしくは gzip -d
拡張子：.gz

gzipオプション

| オプション | 説明 |
|:--|:--|
| -d | 圧縮ファイルを展開する |
| -c | 標準出力へ出力する |
| -r | ディレクトリ内のファイルをすべて圧縮する |

```bash:sample
$ ls
data.txt

$ gzip data.txt
$ ls
data.txt.gz
# もとのファイルは削除されて、.gz拡張子の圧縮ファイルができる

$ gunzip data.txt.gz
$ ls
data.txt
# gzip -d data.txt.gz でも同じ
```

#bzip2, bunzip2
bzip2、bunzip2も同じように使用できる。gzipよりも圧縮効率は高いが処理に時間がかかる。

圧縮コマンド：bzip2
解凍コマンド：bunzip2、もしくは bzip2 -d
拡張子：.bz2

bzip2オプション

| オプション | 説明 |
|:--|:--|
| -d | 圧縮ファイルを展開する |
| -c | 標準出力へ出力する |

#xz, unxz
bzip2よりもさらに圧縮効率が高いが、さらに処理に時間がかかる。

圧縮コマンド：xz
解凍コマンド：unxz、もしくは xz -d
拡張子：.xz

xzオプション

| オプション | 説明 |
|:--|:--|
| -d | 圧縮ファイルを展開する |
| -k | 圧縮後、解凍後に元ファイルを削除しない |
openFrameworks・Kinect v1を用いた人の静止判定、足幅の計算

この記事はkinect v1を用いた人の座標の取得方法ではなくその座標を用いた静止判定の方法を紹介しています！人の座標の取り方はアトリエフレームワークス、[openFrameworks・Kinect v1を用いた人の検知](https://qiita.com/aframeworks-blog/items/35cd4f35b42cfffeda5e)をお読みください。

　今回は人がある一定時間静止したかどうかを判定をするコードを実装したので紹介したいと思います。とても初歩的で簡単な方法です。よかったら参考にしてください。

##静止判定を行うクラスの実装

　今回実装したクラス`KN_stop`の機能としては、
-人の座標を渡したらその人がある一定時間静止したかどうかを判断する
- 静止した人の両足の幅を計算する
の2つです。

hppファイルとcppファイルを以下に示します。

```KN_stop.hpp

#ifndef KN_BASIC
#define KN_BASIC
#include <stdio.h>
#include "ofMain.h"
#include "ofxOpenNI.h"
#include "KN_basic.hpp"
#endif
 
class KN_stop{
    
public:
    void setup();
    void update();
    void draw();
    
    bool stopJudge(ofVec2f _manPos1,ofVec2f _manPos2);
    float calcDist(ofVec2f _manPos1,ofVec2f _manPos2);
　　float mLegDist;//静止したときの両足の幅
    
　　bool mIsStanding;//一定時間静止したかどうか
    int mTime;//静止時間を保存
    ofVec2f mPreManPos[2]; //前フレームでの判定人物の両足座標
    
　　int StopTime=2;//定数：静止と判定する秒数(今回は2秒)
    int JudgeInterval=150;//定数：足が動いていないと判定する値
    int FrameRate = 60;//定数：フレームレート数
    
    int count;////kinectによる雑音を除去するための変数
};
```

```KN_stop.cpp

/*
引数
・判定する人の両足の座標
 
返り値
・止まったことの判定　bool
・その時の立ち幅 float
 
*/
 
#include "KN_stop.hpp"
 
void KN_stop::setup(){
  
　　//各変数の初期化
    mIsStanding = false;
    mTime = 0;
    mLegDist =0;
    mPreManPos[0]= ofVec2f(0,0);
    mPreManPos[1]= ofVec2f(0,0);
     
}
 
void KN_stop::update(){
    
}
 
void KN_stop::draw(){
    
}
 
bool KN_stop::stopJudge(ofVec2f _manPos1,ofVec2f _manPos2/*現在の人の両足座標*/){
    
　　//前フレームと両足の座標の変化を計算
    float dist1 = ofDist(_manPos1.x,_manPos1.y,mPreManPos[0].x,mPreManPos[0].y);
    float dist2 = ofDist(_manPos2.x,_manPos2.y,mPreManPos[1].x,mPreManPos[1].y);
    
	//人が動いたかどうかで条件分岐
    if(dist1<JudgeInterval && dist2<JudgeInterval){//前フレームとの変化量が小さい→静止とみなす
        mTime++;//静止している時間をインクリメント
        count=0;
    }
    else{//前フレームとの変化量が大きい→動いたとみなす
        
	if(count>30){//kinectによる雑音を除去する
        mIsStanding =false;
        mTime=0;//静止時間リセット
        count=0;
		}
        count++;
    }
    
    //足の座標を保存→次フレームで使用
    mPreManPos[0]=_manPos1;
    mPreManPos[1]=_manPos2;
	
　　//静止時間がStopTime(このコードでは2秒)を越えたらtrueを返す
    if(mTime>FrameRate*StopTime){
        mIsStanding = true;
 
    }else{
        mIsStanding = false;
    }
    
    return mIsStanding;    
}
 
//両足の幅を計算
float KN_stop::calcDist(ofVec2f _manPos1,ofVec2f _manPos2){
 
    mLegDist= ofDist(_manPos1.x,_manPos1.y,_manPos2.x,_manPos2.y);
    return mLegDist;//両足の幅を返す
    
}
```

　*前フレームの人の両足の座標と現在のフレームの座標を比較*し、その変化量が小さければ動いていない！静止している！と判断します。この方法はセンサーの状態を随時見て変化を検出するときに使われます。例えばボタンのON、OFFの変化をみたいときなどでも利用できる方法です。
　座標間の計算は`ofDist`にお任せです。

##Kinectの値がぴゅんっと飛んじゃう雑音の影響を少~しだけ軽減

`count`がどのような機能を果たしているか説明します。デバッグをしている中でkinectの雑音(壁に反応したり…)で、人の座標位置が一瞬だけどこかへぴゅんっ！と飛んでしまうということがありました…そのせいで本当は静止しているのに、静止判定がうまくいかないということに…！これをなんとかしたいとひねり出して考えたのがこの`count`の処理。少し`mTime`をリセットする条件を狭くしたものです。内容は、

- `dist1`と`dist2`に対して静止の判定に入らなかった時に、`count`をインクリメント
- `dist1`と`dist2`に対する判定が30回以上falseになったときに、静止判定とする！

というもの！これを用いてなんとか動く静止判定を実装しました…！！
foliumで表示時点で情報をpopupする設定に苦労した話(Google Colab)

## foliumとは
* JavaScriptのLeafletをパースしたライブラリ。
* マップを使って可視化するには便利なツール。
![breadSample.PNG](https://qiita-image-store.s3.amazonaws.com/0/10574/2b41e39c-b55b-5204-1e0c-88338c39aaa6.png)

## 環境
* google colab(ここに落とし穴)

## 実現したいこと
* 収集したパン屋さんの住所から緯度経度を割り出し、地図にプロットする。

## ソース
```pip.py
pip install folium
```

```test.py
import folium

import pandas as pd

chiba_cities = pd.DataFrame({
    'city': ['ハルタ', 'ブルクベーカリー 札幌円山本店', 'DONQ 円山店', 'すぎうらベーカリー 円山店','ペンギンベーカリーカフェ 円山裏参道店'],
    'latitude': [43.057320, 43.056397, 43.055939, 43.056211, 43.054867],
    'longtude': [141.322706, 141.321842, 141.319576, 141.318643,141.321690],
    'population': [1000, 1000, 1000, 1000, 1000]
})

maruyama_map = folium.Map(location=[43.056000, 141.321000], zoom_start=15)

for i, r in chiba_cities.iterrows():
    popup=folium.Popup(r['city'], max_width=1000,show=True)
    folium.Marker(location=[r['latitude'], r['longtude']], popup=popup).add_to(maruyama_map)
maruyama_map
```
## 発生したエラー
```error.py
TypeError: __init__() got an unexpected keyword argument 'show' folium
```
* foliumにshowが無いというエラー。
* あれ？Githubのソース確認してもshowあるYO!!
 
## 何にハマったか？
* Google colabで無意識に`pip install folium`すると0.2.1が入る。
* なんと2016年9月バージョン。
* popupクラスのshowは0.6.0に実装。ここ!!

## 正解
```pip.py
pip install folium==0.7.0 # 2018年12月時点最新版
```

## 教訓
* PyPIのリリースノートはちゃんと読みましょう(反省)。


## 参考資料
* PyPI(https://pypi.org/project/folium/)
* Github(https://github.com/python-visualization/folium/issues/831)
  * この#831の2018/03/30レスに「show argument was added in #772,」と書いていて、上記PyPIのリリースノート0.6.0に#772をaddしたと書いているじゃないですか...
C言語で動的確保された文字列配列の要素をswapする関数


#内容
arrで渡される文字列配列のa番目とb番目を入れ替えます。
#注意点
- reallocが失敗することは考慮してません。
- reallocでの注意点はすべて当てはまります。

#コード
```str_swap.c
#include <stdlib.h>
#include <string.h> 

void str_swap(char** arr, int a,int b ){
    char* tmp = realloc(tmp,sizeof(char)*(strlen(arr[b])+1));
    strcpy(tmp,arr[b]);
    arr[b] = realloc(arr[b],sizeof(char)*(strlen(arr[a])+1));
    strcpy(arr[b],arr[a]);
    arr[a]= realloc(arr[a],sizeof(char)*(strlen(tmp)+1));
    strcpy(arr[a],tmp);
    free(tmp);
}
```

#経緯
文字列の長さが違う要素を持った文字列配列の任意の要素をswapする必要があった。
各要素は自身の長さちょうどのメモリしか確保されていないので、それ以上の長さの文字列を代入できない。
てことでreallocしちゃいました。

#その他
初投稿！
VyOS の auth.log を Power BI Desktop で分析しよう

# はじめに
Power BI を使おうと前から思っていながら何を分析しようか、興味あるネタが無いなぁと思いつつ、ズルズル時間だけが経過してしまったため Advent Calender を動機させていただきました。
私のようにちょっと気おくれしてしまった方や初心者の方に「初学者でもこんなことができるんだ」と思っていただき、 Power BI を使ってみようと思っていただければ幸いです。

ということで、この記事は [Power BI Advent Calender 2018]("https://qiita.com/advent-calendar/2018/powerbi") の15日目です。

# 概要
VyOS というソフトウェアルータを踏み台に自宅に SSH トンネリングで接続するため sshd をポート番号を変えてインターネットに公開しているのですが、ログにアタックされた記録があったので攻撃元の傾向を分析してみました。

ゴールは以下の分析ができることです。
1. 攻撃元の国・IPの比率、分布
2. 攻撃の時系列の傾向 (いつ頃の攻撃が多いとかがわかるグラフ)
3. 攻撃時に使われたユーザ名の比率、傾向 (どんなユーザ名を使ってログイン試行されたかがわかるグラフ)

今回は 2 番で躓いてしまい、 1 番のみとなります。

# レポートの作成
## 準備
auth.log をそのまま利用するには微妙なので、攻撃に関する情報のみを抽出しCSVにします。私は秀丸エディタで Grep したり正規表現で不要な行を削除するなどし、下記カラムになるように加工しました。
国コードカラムは、攻撃元 IP から国コードを返してくれるサービスを利用し、

| タイムスタンプ | リモートホスト | 国コード | ポート | プロトコル | アカウント名 | メッセージ |
|---|---|---|---|---|---|---|

実際の CSV はこのような感じです。ログそのものは 2015 年からありましたが攻撃の記録を抽出した結果、 2016 年 1 月～ 2018 年 11 月が分析対象期間となりました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/5e657019-a984-44a8-8548-8047f2c55021.png)

# Power BI Desktop に CSV を取り込む
## Power BI Desktop を起動し、「データを取得」から該当 CSV を選択

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/013de426-5382-36a3-bd04-00b356827c9d.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/b554f487-55f6-ffdf-a090-ac533bf56f3a.png)


## データの型を必要に応じ編集し、読み込み

* 今回は編集が不要だったので、「読み込み」のみを実施しました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/4ae14dc8-9b70-0a63-c98a-74904b5b218e.png)

* 読み込みが終わると、こんな感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/b6875927-c470-b368-2a94-0adcc1502412.png)

## 攻撃元の分布を地図のビジュアルで表示

* 視覚化の「マップ」を選択　→　フィールド (ペンキ塗りローラーのようなアイコンの左隣) の場所に「国コード」・サイズに「タイムスタンプ」を D&D →　適宜サイズ変更します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/4a4f7867-a2f0-fe41-a853-474c31e76c4e.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/964e8f84-57ca-1984-734e-cae2deb9e051.png)

* 書式 (ペンキ塗りローラーのようなアイコン) のカテゴリ等をいじるとこんな感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/16f657b5-7209-13ca-75d7-be8dffee8033.png)

## 攻撃元IPの比率を円グラフのビジュアルで表示

* 前項で編集したビジュアルを選択していない状態で、視覚化の「円グラフ」を選択　→　フィールドの詳細に「リモートホスト」・値に「タイムスタンプのカウント」を D&D

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/a2f68020-a4ff-a7a9-19e9-ed298793d5a6.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/a00738c8-958e-7b85-6cdf-9d78aa6e5e23.png)

* 書式で詳細ラベル等をいじるとこんな感じです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/f5c2efb5-2cee-a68a-aa25-9e7814a67cc4.png)

# おまけ
今回はここまでになりますが、最後に Power BI のすごいところをご紹介したいと思います。
既に地図にマッピングしてくれるだけで驚くところだと思うのですが、右側のグラフデータの 1 つを選択すると、左の地図にフォーカスされるんです。凄くないですか。
もう紙で何枚も印刷して「あーでもない」「こーでもない」と無駄な時間を費やさなくても、見たいデータを選択すれば良いんです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/2e376e9d-d985-89fd-d2bd-9d89412b5805.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/66349/32485900-b503-f800-20e6-515daf3448e3.png)
herokuの本番環境のPostgreSQLはGUIで管理しよう

#開発環境では動くのに、本番環境で動かない
そういうこと、ビギナーエンジニアには経験があるはず。
そして得てして本番のデータベースが悪さしていることも多い。
そこをGUIで簡単に管理しちゃおうよというお話。

以下は僕のエラー対応の棚卸しになります。

##１.本番環境でスレッド一覧を見ようとして、エラー
ポートフォリオ作成して途中段階でのこと。
なぜか本番環境でスレッド一覧画面が表示できない。
heroku logs —tail して、ログ漁ってみると

>2018-12-22T10:33:58.330119+00:00 app[web.1]: F, [2018-12-22T10:33:58.330053 #4] FATAL -- : [e366020e-2b0e-4f48-bbc5-ef0c233c0319]
2018-12-22T10:33:58.330182+00:00 app[web.1]: F, [2018-12-22T10:33:58.330119 #4] FATAL -- : [e366020e-2b0e-4f48-bbc5-ef0c233c0319] 
 ActionView::Template::Error (undefined method `downcase' for nil:NilClass):

なるほど、以下のgravater_forのヘルパーメソッドで
nilのemailに対してdowncaseしようとして怒られているわけか、、、
でもvalidateしているからnilなんて入らないはずなのになぁ。


```ruby
module UsersHelper
  def gravatar_for(user)
    gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
    gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
    image_tag(gravatar_url, alt: user.name, class: "gravatar")
  end
end
```
##2.Posticoを入れて本番データベースを見てみる
本番データを調査する必要が出てきましたので、思い切って
掲題の通りPostgreSQLのGUIツール導入することに
手順は以下の記事ご参考。
[PostgreSQLのデータをGUIでいじる（macOS/Postico）](https://qiita.com/junara/items/8ee572151727288f6576)
[Heroku Postgresで使うGUIクライアント。]
(https://qiita.com/niiyz/items/69e15b6d03c0023e6452)

んで本番のusersテーブルを見に行くと

<img width="1438" alt="スクリーンショット 2018-12-22 20.08.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/321850/957edace-eeb4-6ed3-97d4-2d1e3567642c.png">

なるほど、開発途中で試しに入れたuserデータがメールの情報持っていなくて
そこを参照してnilだよと怒られていたわけか。
原因究明完了。

##3.本番データベースのリセット

```
# herokuのデータベースリセットは　-aでherokuでのアプリ名を指定しないといけないから注意
$ heroku pg:reset DATABASE_URL -a YOUR_APP_NAME
$ heroku run rails db:migrate
$ heroku run rails db:seed
```
herokuのデータベースURLとか設定が見たいんであればターミナルで

```
$ heroku config -a YOUR_APP_NAME
```
実行か、herokuにログインしてsettingを見に行くとわかるよ。
これで本番でもスレッド一覧画面に行けるようになったとさ。
yield_selfを使い、ある特定の条件の時だけwhere句を有効にした話

コーディング中に、特定の条件の時だけwhere句を有効にしたい！と思うことがありました。
最初は単純にif文で分岐していたのですが、あまりにもダサいと思ったので奮闘してみました。


```ruby:サンプルコード
if kind == 'hoge'
   User.where(kind: kind)
else
   User.all
end
```

## ActiveRecordを拡張
[こちらの記事](https://qiita.com/retosu/items/043b5c962abe8b2da773)を参考に、ActiveRecordを拡張してみました。
記事内の拡張コードはRails5では動かなかったので、Railsのコードを読みつつ以下のように拡張しました。

```ruby:拡張コード
ActiveRecord::QueryMethods::WhereChain.include(Module.new do
  def if(condition, opts, *rest)
    return @scope unless condition

    @scope.where_clause += @scope.send(:where_clause_factory).build(opts, rest)
    @scope
  end
end)
```

```ruby:サンプルコード
kind = 'hoge'
User.where.if(kind == 'hoge', kind: kind).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`kind` = hoge"
kind = 'fuga'
User.where.if(kind == 'hoge', kind: kind).to_sql
=> "SELECT `users`.* FROM `users`"
```

いい感じですね :tada: 

## レビューで却下される
ドヤ顔でプルリクを送るもレビューで以下の指摘を受けました。

- Railsのバージョンが上がった時このコードが動く保証がない
    - 現にRails4の拡張コードがRails5で動かなかった
- Rails標準機能でないため、初めてこのコードを見た人が戸惑うのではないか
    - 驚き最小の原則は重要

ごもっとも。。。としか言えなかったので拡張コードの採用は見送りました。

## yield_selfを使う
もうif文で書くかと諦めかけていたところ、yield_selfを使ってはどうかと助言をいただきました。
yield_selfを使ったコードがこちら。


```ruby:サンプルコード
kind = 'hoge'
User.yield_self{|scope| kind == 'hoge' ? scope.where(kind: kind) : scope.all }.to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`kind` = hoge"
kind = 'fuga'
User.yield_self{|scope| kind == 'hoge' ? scope.where(kind: kind) : scope.all }.to_sql
=> "SELECT `users`.* FROM `users`"
```

以下のようにQueryMethodを繋げることもできます。

```ruby:サンプルコード
kind = 'hoge'
User.yield_self{|scope| kind == 'hoge' ? scope.where(kind: kind) : scope }.where(age: 0..10).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`kind` = hoge AND (`users`.`age` BETWEEN 0 AND 10)"
kind = 'fuga'
User.yield_self{|scope| kind == 'hoge' ? scope.where(kind: kind) : scope }.where(age: 0..10).to_sql
=> "SELECT `users`.* FROM `users` WHERE (`users`.`age` BETWEEN 0 AND 10)"
```

yield_selfを使ったコードは無事LGTMしていただきました :tada: 

## まとめ
- yield_self便利
- チーム開発で拡張は控えた方が無難かも
Kibanaのインストール

やってみたのでメモ。やることは多くない

# 前提
- CentOS7
- Java8インストール済み

# 手順
1. サインインキーを登録する

    ```
    # rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    ```

2. リポジトリ情報を登録する

    ```
    # vi /etc/yum.repos.d/kibana.repo
    ```
    
    ```kibana.repo
    [kibana-6.x]
    name=Kibana repository for 6.x packages
    baseurl=https://artifacts.elastic.co/packages/6.x/yum
    gpgcheck=1
    gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    autorefresh=1
    type=rpm-md
    ```

3. yumでインストールする

    ```
    # yum -y install kibana
    ```

4. 再読み込みする

    ```
    # systemctl daemon-reload
    ```

5. 起動する

    ```
    # systemctl start kibana
    ```

# 参考
- [Installing from the RPM repository](https://www.elastic.co/guide/en/kibana/current/rpm.html)
中国語を拼音（ピンイン）に変換する

ニッチかもしれませんが、Swiftで中国語をピンインに変換する方法を紹介します。

使用するメソッドは `applyTransform` のみです。

* [applyingTransform(_:reverse:) - NSString | Apple Developer Documentation](https://developer.apple.com/documentation/foundation/nsstring/1407787-applyingtransform)

## 使用例

```swift

let chinese = "中文"
if let transform = chinese.applyingTransform(.mandarinToLatin, reverse: false) {
    print(transform) // zhōng wén
}
```

## 補足

今回使用した`.mandarinToLatin`は[StringTransform](https://developer.apple.com/documentation/foundation/stringtransform) の一つで他にも全角⇄半角の変換（`.fullwidthToHalfwidth`）やひらがな⇄カタカナの変換（`.hiraganaToKatakana`）なども用意されています。
LogStashのインストール

やってみたのでメモ。あまりやることは多くない

# 前提
- CentOS7
- Java8インストール済み

# 手順
1. サインインキーを登録する

    ```
    # rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
    ```

2. リポジトリ情報を登録する

    ```
    # vi /etc/yum.repos.d/logstash.repo
    ```
    
    ```logstash.repo
    [logstash-6.x]
    name=Elastic repository for 6.x packages
    baseurl=https://artifacts.elastic.co/packages/6.x/yum
    gpgcheck=1
    gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    autorefresh=1
    type=rpm-md
    ```

3. yumでインストールする

    ```
    # yum -y install logstash
    ```

# 参考
- [Installing Logstash - YUM](https://www.elastic.co/guide/en/logstash/current/installing-logstash.html#_yum)
Unity 2018.3からPlayerPrefsを全削除するメニューアイテムが標準で追加された

Unity 2018.3から、PlayerPrefsを削除するメニューアイテムが、標準で追加されました。

次の画像のように、`Edit > Clear All PlayerPrefs`を選択すると、

![ClearAllPlayerPrefs.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/73a4b3bd-de81-02c7-5e69-839e935b4801.png)

次の画像のようなダイアログが出てきて、

![dialog.PNG](https://qiita-image-store.s3.amazonaws.com/0/4125/0bf3de0b-03d2-e5bb-d1df-4d429c87ad3b.png)

Yesを押すと、`PlayerPrefs`の中身が削除されるようです。


便利！

ただ、この機能リリースノートに載っていない？

https://unity3d.com/jp/unity/whats-new/unity-2018.3.0


Unity 2018.2まではこんな感じで`Menu Item`から`PlayerPrefs`を削除できるようにするコードを書いていた人も多いと思うけれど、このコードも必要なくなりました！


```csharp

using UnityEngine;
using UnityEditor;

public class DeleteAllPlayerPrefs
{
    [MenuItem("Tools/DeleteAll PlayerPrefs")]
    public static void Execute()
    {
        PlayerPrefs.DeleteAll();
        Debug.Log("PlayerPrefs.DeleteAll()");
    }
}
```



やったね！
画像投稿機能のあるアプリでherokuを使っている場合、何故クラウドストレージでの管理が必要か

#デプロイするたびに画像が消える問題
以下のようにPictureUploaderを実装しているとします。

```ruby
class PictureUploader < CarrierWave::Uploader::Base
 include CarrierWave::MiniMagick
 process resize_to_limit: [300, 300]

 storage :file

 # アップロードファイルの保存先ディレクトリは上書き可能
 # 下記はデフォルトの保存先
 def store_dir
   "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
 end

 # アップロード可能な拡張子のリスト
 def extension_whitelist
   %w(jpg jpeg gif png)
 end
end
```

とりあえずはユーザーがあげた画像はローカル（storage: file)で
管理して、後でクラウドストレージで管理すればいいよねと思っていました

**が、しかし**

pushして自動デプロイするたびにローカルの画像が消える由々しき事態！何故なんだ、、、
#理由はデプロイのたびにコンテナ変わるから

herokuはコンテナ（仮想サーバ環境）で動いていて、新しくデプロイされるとそのコンテナごと新しく作り変えられるので、保存すべきファイルなどはs3や外部のストレージに保存しないといけないらしい。

こういう仕組みを**「Immutable Infrastructure」**という。

これに関しては以下の記事がよくまとまっているので是非。
(ここら辺はアプリ側の人間もがっつり学ばないといけない時代になってきましたね)

[「Immutable Infrastructure」 by 伊藤 直也氏 #jawsdays – JAWS DAYS 2014 参加レポート Vol.02](https://dev.classmethod.jp/cloud/aws/jawsdays2014-02/)

#AWSのS3で管理しよう

そこでS３で管理しようという流れになるんですね。
みんな大好きrailsチュートリアルでS３の導入方法は
書かれているので、こういった背景を踏まえつつ実装すると良いんではないでしょうか。
[Rails on Rails チュートリアル 13章]
(https://railstutorial.jp/chapters/user_microposts?version=5.1#cha-user_microposts)
[S3に直接画像をアップロードする（Ruby on Rails）]
(https://qiita.com/DaichiSaito/items/80e89f0c96d88afcc5ff)

注意点としては、githubにpushするときに
**IAMユーザーのアクセスキーやシークレットキー
をハードコーディング(直書き)したものを絶対にpushしないこと。**
アカウント不正利用されまくってしまうのでご注意。
（環境変数で設定すべし）
Go言語でS3のイベントをHookしてLambdaを実行するときの書き方

S3のイベントをHookしてLambdaを実行するサンプルはいくつかあったが、Go言語の情報がほとんどなかったのでテンプレだけ書いておく。
eventは自作せず、aws-lambda-goが提供している`events.S3Event`を使う
`events.S3Event`の中には`event.Records`があり、その中にイベントを発生させたS3のBucket,Keyが入っている


``` go
package main

import (
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

func s3lambda(ctx context.Context, event events.S3Event) (interface{}, error) {
	for _, record := range event.Records {
		// recordの中にイベント発生させたS3のBucket名やKeyが入っている		
		bucket := record.S3.Bucket.Name
		key := record.S3.Object.Key
	}
	resp := &struct {
		StatusCode uint `json:"statusCode"`
	}{StatusCode: 200}
	return resp, nil
}

func main() {
	lambda.Start(s3lambda)
}
```
Scalaの遅延評価(lazy)を関数オブジェクトで使ってみる

## 概要
Scalaでよく使う遅延評価(lazy)を、関数オブジェクトに適用して、処理効率を上げてみたときの内容をサンプルコードにまとめます。なお、遅延評価の詳細については[プログラミング言語Scala 日本語情報サイト 第 14 章 遅延評価val](https://sites.google.com/site/scalajp/home/documentation/scala-by-example/chapter14)を参照ください。

## 例題
以下が処理効率化する前のサンプルコードです。partitionの中で本来一度で済むはずのOptionの空判定やSeqのlengthメソッドの呼び出しを、ループ回数分だけ行っています。なお、partitionについては@f81@githubさんの[第10章：Scalaの「Traversable」リファレンス](https://qiita.com/f81@github/items/62ad3c56ce6be271ef35#partition)を参照ください。

```Before.scala
  def testBefore(judgeOpt: Option[Int]) = {
    val numberList = Seq(1,2,3,4,5,6,7,8,9,10)

    val (leftList,rightList) = numberList.partition{ n =>
      if (judgeOpt.isEmpty) {
        false
      } else if (judgeOpt.get > numberList.length) {
        true
      } else {
        if (n % judgeOpt.get == 0) {
          false
        } else {
          true
        }
      }
    }
    println(leftList)
  }
```
## lazyを使ったサンプルコード
対応として1つ目と2つ目のブロックをあらかじめBooleanで評価するという手もありますが、今回はlazyを用いて処理の効率化を実現してみます。
下記のサンプルコードの通り、関数オブジェクトを遅延評価する関数（judgeFunction）を作成しpartition内で使用する判定関数を一度の評価で決定します。なお、judgeFunction中の「println("None")」や「println("Over")」は一度しか処理されません。

```After.scala
  def testAfter(judgeOpt: Option[Int]) = {
    val numberList = Seq(1,2,3,4,5,6,7,8,9,10)
    def judgeFunction(judgeOpt: Option[Int], list: Seq[Int]):(Int) => Boolean = {
      if (judgeOpt.isEmpty) {
        println("None")
        (_: Int) => false
      } else if (judgeOpt.get > list.length) {
        println("Over")
        (_: Int) => true
      } else {
        divideFuncton(_: Int, judgeOpt.get)
      }
    }
    def divideFuncton(target: Int, input: Int):Boolean = {
      if (target % input == 0) {
        false
      } else {
        true
      }
    }
    
    lazy val f = judgeFunction(judgeOpt, numberList)
    val (leftList,rightList) = numberList.partition{ n =>
      f(n)
    }
    println(leftList)
  }
```
GitHubでissue管理して開発しよう

# 個人開発でもチーム開発を意識しよう

チーム開発を見据えて開発しよう
そのために、このissue管理は非常に有効です

---


# 前提条件
・gitの仕組みを理解し、基本コマンドを習得していること
・githubアカウントを持ち、リモートリポジトリ、リモートブランチの概念及び　基本操作を抑えられていること
※git、githubのシステムがよくわかってない場合は？
⇨開発必須スキルのため、コマンド丸覚えではなく原理から理解しよう
おすすめ教材、記事:
[もう怖くないGit！チーム開発で必要なGitを完全マスター](https://www.udemy.com/unscared_git/)
(セールの時に買うといい、1800円とかで買える）
[いまさらだけどGitを基本から分かりやすくまとめてみた]
(https://qiita.com/gold-kou/items/7f6a3b46e2781b0dd4a0)
（この記事も良くまとまってる）

---

# 対象

・マスターブランチからリモートリポジトリに直接pushしているビギナー
・作業用ブランチからpushしてプルリク作ってるけどマンネリ化してきたビギナー

---

# issue管理のメリット
1.企業にチーム開発を見据えて開発できているという好印象を与えられる
2.やったこと、やるべきことが細かい単位で可視化できるので、やる気が継続する

---

# issue管理の7ステップ
## 1.githubでissueを作ろう
![スクリーンショット 2018-12-17 2.01.03.png](https://qiita-image-store.s3.amazonaws.com/0/321850/efa23e18-1949-0463-ee3f-ebed4d8509eb.png)
githubで対象リモートリポジトリに行ってissueタブを開くと
new issueというボタンがあるので、そこからissueを作成

issueの単位としては、数時間もしくは一日くらいで終わるタスク量に設定するとやる気が継続するのでオススメ

作成した後、作業名の横に出る＃数字は、issue番号（上の写真でいう#11)
で、後でブランチやコミットメッセージで紐づけるのでメモっておく

---

## 2.ターミナルで作ったissueに対応する作業ブランチを作ろう
```
＃数字にはさっきのissue番号を入れるとわかりやすいよ
$ git branch  ‘#数字'
＃作業ブランチに移動
$ git checkout ‘#数字'
```
そこから黙々と対応する作業をこなそう

---

## 3.作業が終わったら、ターミナルでadd、commitして、リモートリポジトリにpushしよう
```golang

$ git add .
$ git commit -v '#数字'
＃コミットメッセージに必ず対応issue番号を入れる！

$ git push orign

```
ポイントはコミットメッセージを必ずissue番号にすること！
そうすることでこのcommitがgithub上のissueと結びつくよ

---

## 4.githubでプルリクを作ろう
![スクリーンショット 2018-12-17 1.59.47.png](https://qiita-image-store.s3.amazonaws.com/0/321850/eee9210e-9afb-c361-abc5-06766bc63168.png)

該当のリモートリポジトリでこんな画面が出るはず。このボタンを押す。

![スクリーンショット 2018-12-17 2.00.10.png](https://qiita-image-store.s3.amazonaws.com/0/321850/fc808d05-9b15-b430-bc90-699bcc8825b3.png)
その後このボタンを押して作成

---

## 5.githubでプルリクをマージしよう

![スクリーンショット 2018-12-17 2.00.29.png](https://qiita-image-store.s3.amazonaws.com/0/321850/39e195ad-3934-1d60-0643-aa1651292bd3.png)

コンフリクトがないことを確認してボタンを押す
本来なら責任者が再鑑してからマージすることを意識しておこう

---

## 6.githubでissueをクローズしていらないブランチを削除しよう

issueタブを開いて、クローズボタンを押します

![スクリーンショット 2018-12-25 23.22.46.png](https://qiita-image-store.s3.amazonaws.com/0/321850/58757ded-9159-bc5d-4672-256f1f15f685.png)
きちんとクローズされてるか、コミットとissueが結びついてるかチェック
ブランチも適宜削除
(ブランチをリベースして使い回すなら消さなくてもOK)
ここは自動化の余地あり！
↓↓↓↓↓↓↓ あなたの記事の内容

---

## 7.ターミナルでマスターブランチに移動してリモートリポジトリからpullして最新状況を取得しよう

```
$ git checkout master
$ git pull origin master
#適宜作業ブランチ削除 リベースして再利用してもいいよ
$ git branch -d ‘#数字’
```
そして１.に戻ってissueを作成するの繰り返しで開発していこう
Linux ユーザ追加周りメモ

ユーザ追加周りのコマンド忘れがちなのでメモ。

## ユーザの追加と確認
```
$ sudo adduser <username>
$ cat /etc/passwd | grep home
ec2-user:x:500:500::/home/ec2-user:/bin/bash
<username>:x:501:501::/home/<username>:/bin/bash
```
## ユーザのパスワード変更とsudo権限付与
```
$ sudo passwd <username>
ユーザー <username> のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: 全ての認証トークンが正しく更新できました。
$ sudo visudo
<username>        ALL=(ALL)       ALL // この行を追加
```
## SSHログインの設定
```
$ sudo su - <username> // ユーザ切り替え
　$ mkdir .ssh // .sshディレクトリ作成
　$ ls -al
　$ chmod 700 .ssh/
　$ cd .ssh/
　$ touch .ssh/authorized_keys
　$ chmod 600 .ssh/authorized_keys // 後は公開鍵の中身をログインしたい方から貰って貼り付ければOK
```
## ユーザの削除
```
$ sudo userdel -r <username>
```
RedmineとGitを連携させる

こちらは [Redmine Advent Calendar 2018](https://adventar.org/calendars/3352 "Redmine Advent Calendar 2018 - Adventar") 24日目の記事になります。

この記事ではRedmineとGitを連携させる基本的な方法を紹介します。

Linuxの基本操作になります。

##シナリオ

ネットワーク上に構築されたRedmineがありその「/var/git」以下等へGitリポジトリが配置されている。

Redmineのメンバーに対して自分の所属しているプロジェクトのGitリポジトリ以外は変更できないようにする。

ただし所属していないプロジェクトのリポジトリの取得は可能。

また外部のGitエクスプローラーを利用するときはRedmine側のGitリポジトリからhook処理で同期を行う。

###記事で利用した検証環境

- CentOS7
- Redmine 3.4系
- Gitはyumコマンドでインスール
- Redmineは [Redmine 3.4をCentOS 7.3にインストールする手順 | Redmine.JP Blog](http://blog.redmine.jp/articles/3_4/install/centos/ "Redmine 3.4をCentOS 7.3にインストールする手順 | Redmine.JP Blog") を参考にインストール

##Redmineの設定

###外部リポジトリブラウザとの連携設定

ここではリポジトリブラウザにGitHubを利用する場合を想定します。

- 「 **/home/git** 」を作成する
- 「 **/home/git/.ssh** 」へSSHペア鍵を作成する
- 作成した公開鍵をGitHubアカウントへ登録する
- 「 **/gitdir/repo/hooks/post-update** 」を作成する

###post-updateの内容

リポジトリがpushを受け取ると連携先のGitHubリポジトリが更新される

<details>
<div>

```bash:/var/git/path/to/my/repo/hooks/post-update
#!/bin/sh

#################################################
########          change variables
#################################################
GITHUB_REPO_NAME=my-some-repo
GIT_REPO_DIR=path/to/my/repo
WORKING_DIR=${GITHUB_REPO_NAME}-github
#################################################
#################################################


# ワーキングディレクトリを初期化する
rm -rf $HOME/${WORKING_DIR}
# リポジトリを取得する
git clone --mirror /var/git/${GIT_REPO_DIR} $HOME/${WORKING_DIR}

# Githubへ更新されたリポジトリをpushする
sh -c "cd $HOME/${WORKING_DIR}; git remote set-url origin git@github.com:gituser/${GITHUB_REPO_NAME}.git"
sh -c "cd $HOME/${WORKING_DIR}; git push --mirror"

# ワーキングディレクトリを初期化する
rm -rf $HOME/${WORKING_DIR}

```
</div>
</details>

###GitHubのPull Requestについて

CircleCI、Travis CI等のCIツールとGitHubが連携している場合、PR（pull request）でCIを回すのは難しくなります。と言うのもRedmineとGitHub両方でPRを書く必要が出てくるためです。

なのでRedmine側でPR処理を行う必要があります。具体的にはチケットのステータスを適宜変更する事で対応出来ると思います。

GitHubと紐づいているCIツールに関してはgit pushで毎回CIが回る状態になっているのが望ましいです。

###プロジェクトに紐づいたリポジトリの設定

- 各プロジェクトごとにgroupを作成する
- プロジェクトに紐ついているGitリポジトリの所有者を「git:repogroup」へ変更する

##ユーザーの設定

- Redmineが稼働しているシステムでRedmineへ登録されているユーザー名等でLinuxユーザーを作成する
- Redmineが稼働しているシステムでプロジェクトに紐づいたgroupにユーザーを登録する
- Redmineが稼働しているシステムで各ユーザーのシェルを **git-shell** へ変更する
- Redmineが稼働しているシステムで各ユーザーの 「 **/home/user/.ssh/authorized_keys** 」へユーザーの端末の公開鍵を登録する

###git-shellの設定

git-shellはシステムにGitをインストールした時点で同時にインストールされます。ユーザーのシェルにgit-shellを指定するとgitコマンド以外は実行できないユーザーになります。

詳しくは [Git - サーバーのセットアップ](https://git-scm.com/book/ja/v1/Git-サーバー-サーバーのセットアップ "Git - サーバーのセットアップ") を参考にしてみてください。

##まとめ

各ユーザーへGitの操作権限を細かな設定を行う事でRedmineをよりセキュアに利用する事が出来ます。

例えばメンバーに初心者が含まれる場合は「/gitrepo/hooks」以下へ設定を書き込む事でより権限の弱い設定を適応する事が出来ます。開発初心者はmasterブランチへはpush出来ないようにする、などです。

また熟練した開発者にはより強い権限を与える事が可能です。担当しているプロジェクトのGitリポジトリを削除、作成等含め完全に操作できる等、です。

Gitだけで設定が完了する訳ではないため若干複雑になりがちですが自作のヘルパースクリプト等を用意しておくと比較的簡単に設定が可能になります。

GitHub、Gitlab等を利用すればこれらの設定はツールのGUIから可能になります。ですが **外部リポジトリブラウザの利用が制限されている環境** も少なくないと思われます。

そう言った環境下でRedmineとGitをセキュアに利用するひとつのアイディアと思っていただければと。