OmniAICreator/Qiita-1.07M huggingface dataset:
[baserCMS4]噂のBurgerEditor（有料版）に自作プラグインのブロックを追加してみる

#BurgerEditorとは？
[BurgerEditor](https://market.basercms.net/products/detail.php?product_id=66)は、[baserCMS](http://basercms.net/)の編集エディタをブロック型のエディタに変更するプラグインです。
![block.png](https://qiita-image-store.s3.amazonaws.com/0/323998/5c15d282-97bf-87f5-8dc6-da536db2ca01.png)
今回はこのBurgerEditorにオリジナルのブロックを追加する方法を記載します。なお、**オリジナルのブロックを追加できるのは有料版だけ**になりますので、ご注意ください。
##ブロックとタイプ
BurgerEditorのブロックはフォルダごとに管理されており、以下の場所に配置されています。

`/app/Plugins/BurgerEditor/Addon/block/`

開いてみると、中には以下のようにブロック毎のフォルダが沢山入っています。
![finder2.png](https://qiita-image-store.s3.amazonaws.com/0/323998/410e6948-70fc-b919-58c0-8bee96ed5cd7.png)
それぞれのブロックフォルダの中には、ブロックを構成するファイル群が入っていますが、概ね以下の３つが入っているようです。

- index.php
- panel.png
- style.scss

いちばん大切なのはindex.phpで、ここではブロックの中身を記述します。panel.pngはアイコン画像、style.scssはこのブロックに関するスタイルを定義するためのSassファイルのようです。

###ブロックは、「タイプ（機能の種類）」を組み合わせて作られる
ブロックは、そのブロック内で使用する**タイプを組み合わせて作ります**。タイプとは画像、文章エディタ、YouTube、GoogleMap、表組みなど、ブロックの中に入れたい機能の種類を指します。（実際の呼び方が「タイプ」で合っているかどうかは分かりません・・・）

例えば「2カラムで左に画像、右に文章」というブロックがあるとすると、index.phpに2カラムのHTMLを記述したうえ、画像を使いたい左カラムに画像タイプを、文章をいれたい右カラムにはCKEditorタイプを呼び出します。

####利用できるタイプの種類
ブロックで利用できるタイプは以下の場所にフォルダ単位で格納されています。

`/app/Plugins/BurgerEditor/Addon/type/`

ざっと眺めただけでも・・・
ボタン、CKEditor、ファイルダウンロード、JSなどの埋め込みタグ、GoogleMap、Googleストリートビュー、水平線、画像、リンク付き画像、表組み、見出しタグ、YouTube
などがあるようで、これらを組み合わせて自由にブロックを作ることができます。

ちなみに・・・実はタイプを１つも使わなくても、とりあえずブロックとして機能させることができます。ですので、ユーザーが編集する余地のないブロック（今回の本題が良い例？）も作ることができます。

##スケジュールプラグインの休日カレンダー（営業日カレンダー）を出力するブロックを作る。
まずはブロック用のフォルダ（/app/Plugins/BurgerEditor/Addon/block/）の中に、新規フォルダ「holiday」を作ります。名前は何でもよさそうですが、今回は後で見たときにすぐ分かるようにしておきたいと思います。
![holiday.png](https://qiita-image-store.s3.amazonaws.com/0/323998/96288063-5636-a8c3-25c5-5a056a7d4add.png)
「holiday」フォルダの中には前述の３つのファイルを用意します。そのうちindex.phpには以下のように記述しました。タイプは使わずに休日カレンダーを出力するためのヘルパーを記載しています。

```php
<div class="hogehoge">
    <?php $this->BcBaser->holidayCalendar() ?>
</div>
```
さらに、作ったブロックをBurgerEditor上で選択できるよう、以下のファイルに追記を行います。今回はその他の項目に追記しました。

```php
'その他' => array(
		'table' => '2カラムテーブル',
		'gallery' => 'ギャラリー',
		'text-gallery1' => 'ギャラリー<small>+テキスト(左)</small>',
		'text-gallery2' => 'ギャラリー<small>+テキスト(右)</small>',
		'google-maps' => 'GoogleMaps',
		'youtube' => 'YouTube',
		'embed' => '埋め込みタグ<small>script / form</small>',
		'hr' => '区切り線',
		'holiday' => '休日カレンダー<small>スケジュール</small>'
	)
```

すると・・・
![panel.png](https://qiita-image-store.s3.amazonaws.com/0/323998/5f07ce14-e452-a05a-55af-3b8fe3cccd56.png)
ブロックが出たっ！ これを選択すると・・・
![cal.png](https://qiita-image-store.s3.amazonaws.com/0/323998/2f24e32a-5ef4-0176-5c42-934b75bef2f8.png)
無事に出力されました。

###ただし、動的な出力にはならない
今回ヘルパーを使って出力させましたが、固定ページやブログのデータベースには、このヘルパーを使って**出力されたHTMLが保存**されます。動的に何かを出力させるようなブロックを作る場合には、もっと別のアプローチが必要そうです。
pluck→カラム名でHashにしたい時

なにかのバッチ処理をしたりする時、
何かしらのレコードから、いくつかのカラムをpluckして、
配列操作したい時ありませんか？
でもテーブルから複数レコードをpluckしてきた値って、ArrayのArrayで、
これをこのまま扱っていくと、
`some_array.map {|array| array[1] * (array[3] - array[2]) ...`
と、言うような宇宙人向けコードを生み出してしまいませんか？

そこで、今回はカラム名でHash化する方法を考え出したのでご紹介しようと思います。

```Ruby
pluck_columns = [:hoge, :fuga, :piyo]
TekitouModel.pluck(*pluck_columns).map do |tm|
  pluck_columns.zip(tm).to_h
end

```

以上です。
仕事中に思いついたので備忘録的に記させていただきました。
実はもっと簡単な方法あったりしたらお願いします。
(pluckに指定するcolumnの名前と、hashにしたいキー名が異なるなら、
zipのレシーバにする配列を、pluckする配列と別途用意してあげれば大丈夫です)
ChainerXをWindowsで使用してみた


ChainerXについては既存の記事を見てください。
Chainerの新しいバックエンドになり、CPUの影響が大きい学習が高速化されます。

https://qiita.com/SatoshiTerasaki/items/defbb1ea49b88c452118

https://qiita.com/SatoshiTerasaki/items/82c0bd344708558a6964

現在、ChainerXはマージされたばっかりというのもあり、Linuxでしか動作しません。
ですが世の中の全てのユーザーの環境がLinuxというわけでもありません。
Windowsの人もいます。ということで、WindowsでChainerXを使用してみようとしました。


公式のリポジトリのバージョンでは動作しないので、フォークして改造しています。


いずれ、公式にPRを送る予定です。


PRを送りました。

公式にマージされました。

公式のリポジトリでも動作しますが、下記のリポジトリでWindows対応を開発しています。

https://github.com/durswd/chainer/

ここからクローンしてください。

コンパイラにはVisualStudio2017の標準のコンパイラではコンパイルできなかったのでLLVMを使用しています。
LLVMの64bitを使用しています。下記のリンクからインストールするとVisualStudioでもLLVMが選択できるようになります。

http://releases.llvm.org/download.html#7.0.0

クローンしたchainerと同じ階層にディレクトリを作成し、cmakeでコンパイルします。
CUDAを使用しない場合はOFFにしてください。

```
cmake -G"Visual Studio 15 2017 Win64" -T llvm -D CHAINERX_BUILD_CUDA=ON -D DEFAULT_CHAINERX_ENA
BLE_BLAS=OFF -D CHAINERX_BUILD_PYTHON=ON ..\chainer\chainerx_cc\
```

VisualStudioのプロジェクトが生成されるのでReleaseでコンパイルします。
コンパイルすると、``` chainerx\python\Release ``` に ``` _core.pyd　``` が生成されます。


インストールですが、そのあたりの変更がこの記事を書くまでに間に合わなかったので手動で使用できるようにします。

setup.pyに対応しました。これらのことをしなくともCHAINERX_BUILD_CUDAとCHAINER_BUILD_CHAINERXを環境変数を設定してsetup.pyを実行すればインストールされます。

chainerのリポジトリの

```
chainer
chainermn
chainerx
```

これらをChainerを使用するディレクトリにコピーします。``` _core.pyd ``` は chainerxのディレクトリの中にコピーします。

適当にChainerXを使用するコードを書きます。

```
import chainerx as chx

x = chx.array([[0, 1, 2], [3, 4, 5]], dtype=chx.float32)

print(x.shape)
print(x.dtype)
print(x.device)
```

動きました！

CUDAを有効にしてコンパイルすれば、CUDAも使用できます。

```
import chainerx as chx

x = chx.array([[0, 1, 2], [3, 4, 5]], dtype=chx.float32, device='cuda:0')

print(x.shape)
print(x.dtype)
print(x.device)
```


まだWindows版は個人的に開発中ということもあり、
実は動かないケースもあると思いますがその時は連絡していただけると助かります。


早めに公式にPRを送る予定です。


公式にPRを送りました。


OS固有の問題以外はテストも通っていますが、不具合が発生する場合は連絡して抱けると助かります。
micro:bitであえての有線シリアル通信を使う

![image.png](https://qiita-image-store.s3.amazonaws.com/0/71746/1206235c-9c4d-780a-b589-df44a5d76ebe.png)

#内容
micro:bitにはBluetooth(BLE)を搭載しているため相互通信にはそちらを使うのがシンプルで便利です。
しかし、他製品との通信などを想定し、シリアルも試してみました。

#端子の接続
micro:bit A　　　GND　　P0　　P1
　　　　　　　　　|　　　|　　　|
micro:bit B　　　GND　　P1　　P0

#動画
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">シリアル通信 <a href="https://t.co/U5vwsgCErz">pic.twitter.com/U5vwsgCErz</a></p>&mdash; Takeshi (@hal2000_jp) <a href="https://twitter.com/hal2000_jp/status/1071043839173873664?ref_src=twsrc%5Etfw">2018年12月7日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


#サンプルコード
Aボタンを押すと相手側にAが表示されます。
![serial通信.PNG](https://qiita-image-store.s3.amazonaws.com/0/71746/2d775dd1-684d-a013-8803-47df480f0ac1.png)

#謎
最初にボタンを押しても動作せず、2回目で動作する
3回目のボタンを押す場合は13秒程度間隔を空けないと動作しない
【swift 4】 EventKit でカレンダーにイベントを保存する。

# EventKitの使い方 (swift 4)
アプリ内で、ユーザーのカレンダーにイベントを保存する簡単なサンプルを示します。
いくつかのポイントがあります。
## ポイントその１
Info.plistに「Privacy - Calendars Usage Description」を + し、"カレンダーに保存"などのコメントを加えます。
![CalendarSavePlist.gif](https://qiita-image-store.s3.amazonaws.com/0/193431/fce81964-3f2b-3163-f212-1f092915a1e0.gif)
## ポイントその2
「import EventKit」を加えます。
## ポイントその3
EKEventStore.authorizationStatus(for: .event)
でアプリがカレンダーへアクセス出来るかを調べます。
未確定（== .notDetermined)の場合は、
requestAccess(to: .event
でユーザーに承諾してもらいます。
## コード
UITextFieldを「myTextField」、
「保存」ボタンを「hozonButton」とします。
UITextFieldに文字を入力して保存ボタンを押すと、本日のカレンダーにイベントが追加されます。
![CalendarSaveSCRN.gif](https://qiita-image-store.s3.amazonaws.com/0/193431/91c2eb4e-0b68-b2d4-a2a9-59054853e701.gif)

```swift
import UIKit
import EventKit

class ViewController: UIViewController {
    
    @IBOutlet var myTextField:UITextField!
    @IBOutlet var hozonButton:UIButton!
    
    let eventStore:EKEventStore = EKEventStore()

    override func viewDidLoad() {
        super.viewDidLoad()
        if EKEventStore.authorizationStatus(for: .event) == .notDetermined{
            eventStore.requestAccess(to: .event, completion: { (granted, error) in
                if granted && error == nil {
                    print("granted")
                }
                else{
                    print("not granted")
                }
            })
        }
    }
    
    @IBAction func myActionHozon(){
        guard let i = myTextField.text, i != "" else { return }
        if EKEventStore.authorizationStatus(for: .event) == .authorized{
            let event = EKEvent(eventStore: eventStore)
            event.title = i
            event.startDate = Date()
            event.endDate = Date()
            event.isAllDay = true
            event.calendar = eventStore.defaultCalendarForNewEvents
            do {
                try eventStore.save(event, span: .thisEvent)
                let alert = UIAlertController(title: "保存完了", message: "カレンダーに保存されました。", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                self.present(alert, animated: true, completion: nil)
            }
            catch {
                print("Save is failed.")
            }
        }
        else{
            let alert = UIAlertController(title: "カレンダーアクセス", message: "カレンダーに保存するためには、\n設定>\nプライバシー>\nカレンダー\nでアクセスを許可して下さい。", preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
            self.present(alert, animated: true, completion: nil)
        }
    }
}
```
ブラックを辞めてフリーランスになる人へ送るロードマップ

#前書き

この記事は、ブラック企業をやめてフリーになる知人に実際に送った「ロードマップ」を加筆修正したものです。
記事として最低限の体裁は整えたつもりですがまあポエムです

具体的には以下のような人を想定してます

- ブラック現場で 5 年くらい Java とか COBOL とかをやってた
- Git とか npm とか「最近」の話題はあまり知らない
- フリーランスになってWEBをやりたい
- 3ヵ月くらいは働かなくて大丈夫



中堅以上のエンジニア（＝ググり能力強者）向けなので細かい説明は省いてます
あくまで道筋を示すだけです

#10ステップのロードマップ

###1. 気力が自然に湧いてくるまで静養する
まずはとにかく休みましょう
旅行に行ってもいいし自宅で無になってもいいし自由

###2.いいPCを買う
速いとやっぱり違うので

環境構築の手間とかを考えるとやっぱ Mac がよさそう

###3. 仕事用メールアドレスを作る
Slack とか SNS とか求人サイトとかの登録用

###4. JavaScriptで簡単なゲームを作る
ヌメロン、マルバツゲーム、ブラックジャックなど

JSはフロントでもサーバでも使えるし最近は治安も良くなってきたので間違いない

入門には [Progate][3] が有能

できれば Vue or React で作れれば感じがいいです:ok_hand_tone3:
ある程度 JS 知ってたら Vue は秒で覚えられるので是非:ok_hand_tone3:
（読み込みはとりあえず CDN で:ok_hand_tone3:）
  
###5. Git と GitHub の利用法を習得する

やっぱり [Progate][1] が有能
あと[漫画][6]もいいらしい

まあ普段はほとんど:point_down:のコマンドしか使わんとおもう

```bash:よく使うgitコマンド
status, add, commit (-m), push, pull, merge, checkout (-b), diff, log, stash　 
```

オシャレな人は`pull`を使わず`fetch`&`merge`を使うらしいけどそれはまた先の話

あと普通は`git config`でエイリアス書いて、status は st みたいに略して使います
実際の開発の流れは [Github flow][4] で検索検索

#####ググるべき重要な概念
- .gitignore
- プルリクエスト
- conflict
- [Github flow][4]

###6. GitHub Pages か netlify でページを公開してみる

4.で作ったやつね
どちらも基本無料なので安心安心

SNSやってたら流して感想もらおう

###7. Vue CLI を使ってモダンに開発してみる

※Vue or React と書くのが面倒なので以降は Vue と書きます、適宜読み替えてください

本題：[Vue CLI][2] を使えばすごく簡単にモダンな開発が始められる！
Webpack とか Babel とか gulp とかそういう怖いのも覚えなくて大丈夫！

ただ Vue CLI を使うには Node と npm (or yarn) が必要です
Node のインストールは辛いけどここさえ乗り越えればモダンな開発者の仲間入り

###8. 「ログイン機能」「画像投稿機能」「画像DL機能」があるWebアプリを作ってみる

この3つが作れれば大抵のWebアプリは作れるって誰かが言ってた

 フロントエンドは Vue or Nuxt 
 バックエンドはPHP or Firebase or Node(NuxtのSSRモード) or Python とか

###9. 職務経歴書的なものを作る

上で作ったのとかもバンバン載せときましょう

職務経歴書のひな形は、エンジニア向け求人サイトのプロフィール入力フォームが参考になります

###10. エンジニア向け求人サイトに登録する
[CODEAL][5]とかね
他にも結構あるんで「フリーランス リモート エンジニア」とかで検索検索

あと Twitter やってるとたまに声がかかったり、よく募集情報が流れてきたりします

案件決まってからお金が入るまで結構ラグいのでちゃんと逆算しよう

#その他有能そうなスキル
TypeScript, jest, 各種CIツール, AWS色々, GCP, SCSS, Docker, GraphQL, Express, Bash, Laravel, Django とか...

実際は jQuery とか WordPress とか EC-CUBE とかを使う案件も結構あるから、まあそういうのも気が向いたら

いろんなケースがあるからあくまで参考までに‥

[1]:https://prog-8.com/languages/git
[2]:https://qiita.com/567000/items/dde495d6a8ad1c25fa43
[3]:https://prog-8.com/languages/es6
[4]:https://b.pyar.bz/20140122/github-flow/
[5]:https://www.codeal.work/
[6]:https://www.amazon.co.jp/dp/B071D4D6XX
EV3のSDカードスロットを壊さないためにも、プログラムの更新はUSBを使おう


[2016年のAdvent Calendarの最初の記事](https://qiita.com/advent-calendar/2016/etrobo)にもあるように、EV3の壊れやすいパーツというと、真っ先に思い浮かぶのは戻るボタン（左上のボタン）ではないでしょうか？毎年１度は聞く気がします。

もうひとつ気をつけてほしいところにSDカードスロットをあげたいと思います。[^1]
戻るボタンが壊れた場合、（以後保証は受けられなくなりますが）修理の方法を紹介してる人がいたり、EV3RTの戻るボタンの機能を他のボタンに置き換えることによって（ハードウェアでなくソフトウェアで対応することによって）回避することができますが[^2]、SDカードが読めなくなってしまうと、EV3RTは使えなくなります。
ダメージが大きいので、多くの方に知っておいてほしいとの思いからここで紹介することにしました。

# できるだけSDカードの抜き差しをしない

EV3RTの初期にはSDカードを抜き差ししなければアプリの更新ができなかった時期がありました。
今では以下の３つの方法があるので、SDカードは挿したままでアプリの更新をしましょう。
書き込み方法は[TOPPERSのサイト](https://dev.toppers.jp/trac_user/ev3pf/wiki/SampleProgram#PC%E3%81%8B%E3%82%89EV3%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E3%83%AD%E3%83%BC%E3%83%89%E6%96%B9%E6%B3%95%E3%81%AE%E9%81%B8%E6%8A%9E)に紹介してあります。
 
* USB経由での書き込み
* Bluetooth経由での書き込み
* Bluetooth PAN経由での書き込み


技術教育でも使用しているUSB経由での書き込みが使いやすいのではないでしょうか。
最近ではETロボコン関係では教育で使っていることもあって、USBが一番利用者が多いかと思いますが、今のところUSBが壊れた話は聞いたことがないです。それでも心配な人はBluetoothを使うのがよいかもしれませんね。

# WindowsはTeraTermマクロがおすすめ？

(2018/12/16 追記)
おそらく長年開発をしている実行委員の中でも一番EV3を触っている時間が長いと思われる「最速ダミーカーの中の人」は[最もオススメしたいBluetooth転送](https://qiita.com/pulmaster2/items/3af3b8158c113d9f9237)と言ってますね。
私はBluetooth通信のできるWindows環境がないので使用感など不明なのですが、めんどくさい部分のマクロの書き方まで教えてくれているので、Windowsユーザーの方はこちらも試してみると良いのでは？

[^1]: 要するに壊れたということです(私じゃないよ！) :cry:
[^2]: 戻るボタンの機能を他のボタンに割り当てるように書き換えたEV3RTを申請すれば2018年現在のETロボコンで使用可能です
Robocopyの帯域制限はWindowsの機能でやりましょう

# この記事で伝えたいこと
* Robocopyには帯域制限のための`/ipg:`というオプションがありますが、帯域制限機能としては不安定です
* 代わりにWindowsの帯域制限機能を使ってください

# Robocopyとは
* すでに良い解説記事があるのでそちらをご覧ください
  * [Windowsの「robocopy」コマンドでフォルダをバックアップ／同期させる](http://www.atmarkit.co.jp/ait/articles/0704/20/news130.html) 
  * [RobocopyのTips](https://qiita.com/fjtter/items/23ed492c906194c300c1) 
  * [Windowsのrobocopyコマンドでファイルコピー中断後に自動再開させる](http://www.atmarkit.co.jp/ait/articles/1404/30/news110.html)
      * この記事で帯域制限とipgオプションについて解説があります 

# ipgオプションで帯域制限できるらしいが。。。
* 使ってみたところ、小さいファイルが沢山あるときと大きいファイルがあるときで、同じ容量の送信でも使用する帯域が大きく異なる事象が判明しました
* その原因と、代わりにどうすればいいかを解説します

## まずRobocopyとipgオプションの挙動をざっくり説明[^1]
1. 指定されたディレクトリ配下のファイルを1つ選択
2. コピー元・コピー先のファイルの更新日付等チェックしてコピー先に送信する必要があるかチェック
3. 送信する必要があると判断した場合ファイルをオープン
4. オープンしたファイルを送信しきるまで次の操作をする
  * 1ブロック(1MB)分まで読み取って送信
  * ipgオプションが指定されている場合はその秒数待つ
5. 全ファイル送信しきるまで1.〰4.を繰り返す

[^1]: 記事の内容や実際に動かしていく中で、「こう動いてると考えるのが妥当」と判断して記載しています。公式にMicrosoftに問い合わせたりして確認した内容ではありません

## 何が問題か
* ipgは1ブロック送信するごとの待ち時間で、コマンド実行時に指定した値で一定です
* ほとんどの場合、ファイルの末端のブロックは1MB未満になります
  * きっちり1MBで分割できるファイルサイズである場合以外はそうなります。
    * 例えば、1MB+1Byteのファイルサイズだと、先頭1ブロックは1MBで、次のブロックは1Byteになります
    * 0.5MBのファイルサイズだと、0.5MBの1ブロックのみになります
* ブロックサイズはバラバラなのに待ち時間（ipg）は一定のため、使用する帯域(MB/s)はブロックサイズ応じてバラバラになります
* 普通はフォルダ内のファイルサイズはバラバラなので、例えば次のような不安定な帯域使用になります
  * 大きいファイルが多いフォルダのコピーをしてる間は使用帯域が大きくなる
  * 上記のフォルダのコピーが終わり、小さいファイルが多いフォルダのコピーになると急に帯域が少なくなる



# 次の合計2MBを送信する2つの例で計算すると分かりやすいと思います
1. 2MBのファイル1つを送信。ipgで1秒の待ち時間を指定
  * ブロックは1MBのブロック2つ。ブロックごとの待ち時間1秒なので、2秒の待ち時間
      * 送信量 / 待ち時間 = 2MB / 2s = 1MB/s 
2. 0.5MBのファイル4つを送信。ipgで1秒の待ち時間を指定
  * ブロックは0.5MBのブロック4つ。ブロックごとの待ち時間1秒なので4秒の待ち時間
      * 送信量 / 待ち時間 = (0.5MB * 4) / 4s = 0.5MB/s  

 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/304012/0c2dac01-8102-ed95-45d6-4cf40ddb149a.png)

# 代わりにどうするのか
* この機能を使ってください
  * [アウトバウンドの帯域制限をWindows標準機能で行う](https://qiita.com/DogFortune/items/70e66f9e5c4c04429565)
  * 記事タイトルにもあるようにアウトバウンド制限になります。
    * Robocopyをコピー元のサーバーで実行する等して、インバウンド制限を気にしないようにする必要がありそうです
  * 調べたところ、Windows7, Windows 2012から使える機能です
Elasticsearchで「最近よくいいねされてる」順の検索結果を出す

CGM系のサービスで必要そうな「最近よくいいねされてる順」でリアルタイムに検索結果を出力する方法です。

## 単純ないいね数順ソートの問題
- いいねの累計数が多いコンテンツに検索結果の上位がいつまでも固定されてしまう。
- 直近30日以内のいいね数順のように期間を絞る方法にしても、その期間内のいいねが少なかったり、全く無かったりする検索ワードの場合、上手くいかない。

## いいねトレンドスコアを計算する

<img width="894" alt="いいねトレンドグラフ.png" src="https://qiita-image-store.s3.amazonaws.com/0/43604/d6ee843e-c0b0-7ee4-2cb4-d14a5638468f.png">

コンテンツの直近N件のいいねについて、いいね時刻が現在時刻から過去に行くほど値が0に漸近する減衰関数に応じた値を各いいねのスコアとし、それらを全て足し算すると、そのときの「いいねトレンドスコア」が計算できます。最近のいいねほど価値が高く、昔のいいねほど価値が低い重みとなるスコアです。

### スコアを計算するコード (Python)

```python
def trend_score(item):
    # 直近のいいねN件取得
    likes = item.likes[:N]

    # いいねトレンドスコアの計算
    score = 0
    for like in likes:
        score += decay(datetime.now(), like.created_at)

    return score

# 減衰関数
def decay(t1, t2):
    diff = (t1 - t2).total_seconds()
    return math.exp(-diff / 3600 / 24 / 40)
```

このスコアをいいねがある度に計算し、Elasticsearchに保存しておけば、検索時にスコア順にソートすると「いいねトレンド順」で検索結果を出力できます。

しかしこれだけだと問題があり、いいねが途絶えたコンテンツのスコアが更新されず、ずっと高いままになってしまいます。本来ならいいねが途絶えているのでスコアは下がっていくのが正しいはずです。

このスコアは検索対象の全コンテンツで更新する必要があるため、コンテンツ数が少ない場合は全コンテンツのスコアを定期バッチで計算し直すこともできますが、コンテンツ数が多いと現実的でないことがあります。

## 検索時に最終いいね時刻の減衰関数をスコアに掛け算して近似する

[Elasticsearchでは減衰関数をスコア計算に利用することができる](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#_supported_decay_functions)ため、この問題の解決に使います。いいね時に「最終いいね時刻」もElasticsearchに保存しておき、検索時に下記スコア順でコンテンツを取り出します。

> 先程定義したいいねトレンドスコア × 最終いいね時刻を入力とした減衰関数のスコア

「最終いいね時刻を入力とした減衰関数のスコア」で利用する減衰関数は「いいねトレンドスコア」で利用した減衰関数と似たものを使います。
<img width="890" alt="減衰関数グラフ.png" src="https://qiita-image-store.s3.amazonaws.com/0/43604/67f0e74b-5a0a-335e-db28-08a497871c84.png">

最終いいね時刻が検索時の時刻から離れているほど、検索時の「本当のいいねトレンドスコア」は小さくなるはずです。そのため上のような「最終いいね時刻を入力とした減衰関数のスコア」を検索時に掛け算することで、「本当のいいねトレンドスコア」を近似します。近似の程度は結構雑ですが、実用上問題なければ良いかなと思います。

Elasticsearchのスコア計算部分のクエリは下記のようになります。

```python
"query": {
    "function_score": {
        "functions": [
            {
                # いいねトレンドスコア
                "field_value_factor": {
                    "field": "trend_score",
                    "missing": 0
                }
            },
            {
                # 最終いいね時刻の減衰関数
                "exp": {
                    "last_liked_at": {
                        "scale": "30d",
                        "decay": 0.5
                    }
                }
            }
        ],
        # 掛け算する
        "score_mode": "multiply"
    }
}
```

## まとめ
Elasticsearchの減衰関数を利用して「最近よくいいねされてる」順で検索結果を出す方法を説明しました。他にももっと良い案がある可能性はあります。いいねデータ自体をElasticsearchに全部保存し、いいねトレンドスコアごと検索時に全部ゴリ押しで計算する方法もできるかもしれません。でもかなりCPU使いそうです。コンテンツ数が少ない場合はバッチでスコア更新したほうが楽かもしれません。サービスのコンテンツ量や性質に応じて設計を考えると良いと思います。
Laravel5.5でmonolog->pushHandlerするときはログレベルを指定しなければならない

※Laravel5.5の話です
※[Laravel5.6からはログの仕様そのものが変わっています](https://qiita.com/hrdaya/items/b01d5621937a0710ca64)

## 概要

Laravelでは柔軟なログ設定が可能。
ログを標準出力にだしつつファイルにも記録したいということも可能で、これを以下のようにMonologに追加する形で実装していました。

```php
$handler = new \Monolog\Handler\StreamHandler('php://stderr');

$monolog = \Log::getMonoLog();
$monolog->pushHandler($handler);
```

## ログレベルの変更がきかない

開発時にずっとdebugレベルだったのでなんとも思わなかったが、ふとデプロイ後に.envを書き換えてもdebugレベルが出続ける。

```shell
# 相変わらずdebugレベルが出力される

$ cat .env | grep APP_LOG_LEVEL
APP_LOG_LEVEL=info
```


## ログレベルの指定がない場合にはdebugとなる

ログレベルの判定をどこでやっているのか追っていくと、
`vendor/monolog/monolog/src/Monolog/Handler/AbstractHandler.php` でやっていることがわかりました。

```php
    /**
     * @param int     $level  The minimum logging level at which this handler will be triggered
     * @param Boolean $bubble Whether the messages that are handled can bubble up the stack or not
     */
    public function __construct($level = Logger::DEBUG, $bubble = true)
    {
        $this->setLevel($level);
        $this->bubble = $bubble;
    }

    /**
     * {@inheritdoc}
     */
    public function isHandling(array $record)
    {
        return $record['level'] >= $this->level;
    }

    /**
     * Sets minimum logging level at which this handler will be triggered.
     *
     * @param  int|string $level Level or level name
     * @return self
     */
    public function setLevel($level)
    {
        $this->level = Logger::toMonologLevel($level);

        return $this;
    }
```

必要箇所だけぬいてます。
`isHandling` でレベル判定してます。
そもそもログLevelは `__construct` で `setLevel` 関数が呼ばれここでしています。

backtraceなどで追いかけると、MonologのHandlerを作るときにコンストラクタが呼ばれ、ログレベルが設定されるようです。
前述Handlerを作るところで出力先のみ指定していたので、debugが自動的に選択されてしまったようです。

## 修正

`.env`に指定するのはログレベルの文字列ですが、これを数値に変換しなければなりません。
これも `setLevel` の実装を参考に以下のようにしました。

```php
$level = \Monolog\Logger::toMonologLevel(config('app.log_level'));
$handler = new \Monolog\Handler\StreamHandler('php://stderr', $level);

$monolog = \Log::getMonoLog();
$monolog->pushHandler($handler);
```
IntelliJとScalaでHello Worldした際に、はまったこと

前回の[「Windows10でScalaの開発環境を作るためにやったこと」](https://qiita.com/kaysquare1231/items/62854b97630c7687bdae)では、開発用の環境を作りました。
今回は、その環境で「Hello World」をしようとしたら思ったより苦戦したので、はまりポイントの備忘です。

間違いなどあればコメントで、訂正していただけると嬉しいです。


##参考サイト
下記のサイトを参考にしながら進めていきました。
- [Scala入門時に役立つ情報まとめ](https://qiita.com/nesheep5/items/49019b9df4836d36ec1f)
- [ドワンゴ社 新入社員Scala研修資料](https://dwango.github.io/scala_text/IDE.html)
- [Getting Started with Scala in IntelliJ](https://docs.scala-lang.org/getting-started-intellij-track/getting-started-with-scala-in-intellij.html)
- [IntelliJ Run Configuration - Running your Scala application](http://allaboutscala.com/tutorials/chapter-1-getting-familiar-intellij-ide/intellij-run-configuration-scala-application/)

##1. JDKがインストールされていなかった
環境作成時には、最新バージョンのJavaをインストールしていた。
しかし、JDKはインストールしていなかったので、追加でインストールが必要になった。
[Java SE Downloads](https://www.oracle.com/technetwork/java/javase/downloads/index.html)

※プロジェクト作成時に赤枠部分の設定が必要
![02_JavaJDK.PNG](https://qiita-image-store.s3.amazonaws.com/0/308224/4db5aadf-886f-9416-5459-8ccfdd17b836.png)

##2. プロジェクトにscalaファイルが追加できない
###現象
![03_Scalaがない.png](https://qiita-image-store.s3.amazonaws.com/0/308224/a5a11e50-4098-5ef7-4c45-e1d5aed1ad7c.png)

###原因
1. プロジェクトにFrameworkが追加されていない
2. ScalaSDKのライブラリが作られていなかった

###解決方法
下記の2つのStepでscalaファイルを追加できるようになりました。

Step1. プロジェクトにFrameworkを追加する
![04_AddFramworkSupport.png](https://qiita-image-store.s3.amazonaws.com/0/308224/e762371a-c8ff-8d3c-bc77-9d3e9a524a9a.png)

Step2. ライブラリを作成する
![05_ScalaSDK追加方法①before.png](https://qiita-image-store.s3.amazonaws.com/0/308224/089dbe64-3821-3fa0-c497-9f6c42c34414.png)
![07_ライブラリ作成.PNG](https://qiita-image-store.s3.amazonaws.com/0/308224/c94ed0ff-5439-d2e4-7880-7fae74b3d0e5.png)


##3. 実行時にjava.lang.ClassNotFoundExceptionが発生する
###現象
![java_error.PNG](https://qiita-image-store.s3.amazonaws.com/0/308224/08b634bd-6148-6071-6305-120932af6921.png)

###原因
未だに分かってません。。。
とりあえず下記の2つの解決策で実行できるようになりました。


###解決策①
最初はBeforeのソースを記述していましたが、Afterに修正すると実行できるようになりました。

```Before.scala
object Sample {
  def main(args: Array[String]): Unit = {
    println("hello world")
  }
}
```

```After.scala
object HelloWorld extends App {
  println("hello world")
}
```


###解決策②
仕事でScalaを使っている友人の同僚からの下記のアドバイスを頂き、試したことろ実行できるようになりました。
>1. メニューの Run -> Edit Configurations
2. 左のメニューから Application を選択。なければ左上の + を押して追加
3. Main class と書いてあるとこの横の ... を押す
4. Project タブで main object を選択
5. 実行
Bootstrapで指定した幅（sm）の時、縦に空白を入れたい

##bootstrapの幅別での表示分け

```
col-lg-数字 = 画面サイズが≥1200pxの場合このクラスが適応されます。
col-md-数字 = 画面サイズが≥992pxの場合このクラスが適応。
col-sm-数字 = 画面サイズが≥768pxの場合このクラスが適応。
col-xs-数字 = 画面サイズが<768pxの場合このクラスが適応。
```

##bootstrapはメディアクエリに対応している
bootstrapは別ファイルでCSSを指定しなくても
HTMLのタグの中にclass名を指定するだけで簡単に整ったデザインのページを作ることができますが、

***レスポンシブデザインに対応しているという特徴もある（画面幅に合わせてレイアウトを変えること）。***
通常ではCSSのメディアクエリというものを使って
レイアウトを調整することになるのですが
Bootstrapを使うと
どのような画面サイズであっても必要に応じて
自動調整して最適なレイアウトを実現することが
容易にできるのです！

#しかし縦のスペースを作りたい場合は、独自にCSSで指定する必要があるらしい。
***縦に***余白を少し入れたい。smサイズ限定で。
というような、特定のサイズの時だけ定期用させたい場合は以下のように指定



###横幅768以上(sm以上)で適用

```css
@media (min-width: 768px) {
.generate {
margin-top: 10px;
}
}
```

###横幅992以下(md以下)で適用

```css

@media (max-width: 992px) {
.generate {
margin-top: 10px;
}
}
```

###横幅768以上(sm以上)・横幅992以下(md以下)で適用
こう指定すれば、sm以下、md以上では適用されない。

```css

/* これが正解 */
@media (min-width: 768px) and ( max-width:992px){
.generate {
margin-top: 10px;
}
}
```

***ポイントはandで繋げてmin , maxを指定できたこと。***

＊(***横に余白入れたい場合はco-sm-offset-1***とかで簡単にできるのだがね)。

参考
http://www.yuta-system.com/homepage/pccss3.html
https://shared-blog.kddi-web.com/bootstrap/mediaquery.html
http://www.mdesign-works.com/blog/web/responsive-design-css/
https://sole-color-blog.com/blog/71/
Keycloak のインストール

Keycloak のインストールを試してみたのでメモ。
環境はCentOS 7

# 前提条件
これぐらいが必要らしい

|システム|スペック|
|:------|:------|
|Java|Java 8 JDK|
|コマンド|zip, gzip もしくは tar|
|RAM|512M|
|ディスク容量|1G|

# 手順

1. tarファイルをダウンロード

    ```
    # curl -LkvOf https://downloads.jboss.org/keycloak/4.7.0.Final/keycloak-4.7.0.Final.tar.gz
    ```

2. ダウンロードしたtarファイルを展開

    ```
    # tar xvzf keycloak-4.7.0.Final.tar.gz
    ```

3. `/opt`配下に移動

    ```
    # mv keycloak-4.7.0.Final /opt/keycloak
    ```

4. keycloak実行用ユーザ作成

    ```
    # useradd keycloak
    ```

5. keycloakのディレクトリの所有者を実行用ユーザに変更

    ```
    # chown -R keycloak:keycloak /opt/keycloak
    ```

6. サービスファイルを作成

    ```
    # vi /usr/lib/systemd/system/keycloak.service
    ```

    ```keycloak.service
    [Unit]
    Description=Keycloak server daemon
    
    [Service]
    User=keycloak
    ExecStart=/opt/keycloak/bin/standalone.sh -b=0.0.0.0
    ExecStop=/bin/kill -INT $MAINPID
    
    [Install]
    WantedBy=multi-user.target
    ```

    **` -b=0.0.0.0`をつけると制限なくなるので、本番などでは絶対にやらないようにしてください。あとでここは修正します**

7. 自動起動設定

    ```
    # systemctl enable keycloak
    ```

8. 起動

    ```
    # systemctl start keycloak
    ```


# 参考
- [公式ドキュメント - Server Installation and Configuration Guide](https://www.keycloak.org/docs/latest/server_installation/index.html)
【SAPUI5】PageとPanelコントロールで見栄えをよく

##はじめに
今回は、PageとPanelという2つのコントロールを使ってアプリの見栄えをよくします。

- コントロールについては[こちら](https://qiita.com/tami/items/3283e6bc7eee9005a903)
- ベースになるアプリは[こちら](https://qiita.com/tami/items/53990a14e5ca919ec35a)

## ゴール
**Before**
以下のようなアプリが、
![WS000031.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/afc807bd-a055-19a6-0ff6-7c6d1b737aa8.jpeg)

**After**
このようになります。だいぶFioriらしい見た目になったのではないでしょうか。
![WS000032.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/13028e39-4b6c-91ae-00e6-e29334a4e2e9.jpeg)


##ステップ
###1. 外枠を作る
まず、App.viewの構造を次のようにします。
![WS000030.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/453989a2-d932-48e0-c288-27e1fe0eb74b.jpeg)

外側のApp, pagesというタグは、ページ遷移のために存在します。今回のケースでは、あってもなくても見た目は変わりません。
内側のPage, contentの中に画面に表示する要素を入れます。
全般的に、大文字で始まるタグ（例：Page）がコントロールで、小文字で始まるタグ（例：content）がそれ以外（たとえば、コンテンツのかたまり）を表していると思われます。
コードは以下のようになります。

```xml
<mvc:View 
	controllerName="test.helloworld.controller.App" 
	xmlns="sap.m" 
	xmlns:l="sap.ui.layout" 
	xmlns:mvc="sap.ui.core.mvc">
	<App>
		<pages>
			<Page title="Page1">
				<content>
				</content>
			</Page>
		</pages>
	</App>
</mvc:View>
```
この時点で実行するとタイトルだけが表示されます。
![WS000033.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/2bf01014-2943-93e2-ccaf-461c8f6c67f8.jpeg)


###2. contentの中にPanelコントールを入れる
Panelはコントロールの一種で、私は画面の要素を乗せる"お皿"のようなものだと理解しています。（公式リファレンスは[こちら](https://sapui5.hana.ondemand.com/#/api/sap.m.Panel/aggregations)）
![WS000037.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/39f20a3f-2d11-9923-16ac-ee594fadcfab.jpeg)

contentの内側にPanel, さらにその内側のcontentの中にUI要素を配置します。contentは要素をまとめる役割らしく、あってもなくても見た目は変わりません。

2020/7/24追記
あってもなくても変わらないのは、contentがPanelのデフォルトaggregationだからです。デフォルトaggregationの場合は明示的に指定する必要はありません。（ビューが複雑になるので指定しないことを推奨します）


Panelを入れたコードは以下のようになります。

```xml
<mvc:View 
	controllerName="test.helloworld.controller.App" 
	xmlns="sap.m" 
	xmlns:l="sap.ui.layout" 
	xmlns:mvc="sap.ui.core.mvc">
	<App>
		<pages>
			<Page title="Page1">
				<content>
					<Panel headerText="panel1">
						<content>
							<l:VerticalLayout class="sapUiContentPadding">
								<Button text="Say Hello!" press="onShowHello"/>
								<Text text="{mPrice>/product/name}"/>
								<Text text="{mPrice>/product/price}"/>
							</l:VerticalLayout>								
						</content>
					</Panel>
				</content>
			</Page>
		</pages>
	</App>
</mvc:View>
```
###3. 実行結果
実行結果は以下のようになります。
![WS000032.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/76247c49-7733-7b78-114f-9388c36bb2ad.jpeg)

##おまけ
Pageの中にPanelを複数入れることができます。
`<Panel>`から`</Panel>`までをコピーして、`</Panel>`の下に追加すると以下のようになります。
![WS000036.JPG](https://qiita-image-store.s3.amazonaws.com/0/276021/c6364e28-6a48-6a9c-48a8-2687e0814f34.jpeg)

では、pagesの中にPageは複数入れられるのか？
試してみたところ、1つ目のPageの内容しか表示されませんでした。

##参考にしたページ
[Get Started: Setup and Tutorials-Walkthrough-Step 11: Pages and Panels](https://sapui5.hana.ondemand.com/#/topic/3b9d9f84930d43df90ad0789d99bd4a3)
The importance of english in engineering

#はじめに
かっこつけてタイトルを英語で書いたものの、この記事で伝えたいことは、
「技術は目まぐるしく進歩し、そしてそれらについていくためには世界共通語である英語で最新の情報を手に入れる必要がある（場合が多いと思う）。」

→ 英語で検索できるかできないかでキャッチアップに大きな差がつく！と言えるのでは:point_up:

#何か(something)の意味を調べたい場合
調べたい語句をそのまま検索してもいいだろうが、

**(something) definition**
definition = 定義

または

**(something) meaning**
meaning = 意味

#何か(something)同士を比較したい場合
似たような目的のライブラリを比較したい場合などには、

difference between A and B が思いつきやすいだろうが、
difference = 違い

**A vs B**

ex.

jQuery vs Umbrella

の方がよさげ:santa:

# 何か(something)の代わりを探したい場合
**(something) alternative**
alternative = 代替手段

ex.
evernote alternative

# 難しい概念を直感的に説明しているものを探したい場合
**(something) intuitive**
intuitive = 直感の

前提として検索結果のページを読めなきゃ話にならないんですがね・・・

#余談(1)
:keyboard: **A.プログラマーとB.そうではない人を見分ける方法**

以下の略語／単語を示して反応をチェックする方法が最も効果的である。


| 単語       　　　 |  　A.プログラマー　　|    B.そうではない人  |
|:-----------------|------------------:|:------------------:|
| DB               |　データベース　　|     ドラゴンボール 　 |
| キャッシュ	   |  メモリ内のデータ   　|       現金:moneybag:
| ホスト            |    コンピュータ 　　|職業　|
| ターミナル   |   Mac付属のソフト　|  飛行機やバスの発着所|
| Swift            |　プログラミング言語 |       車種 or 歌手  |
| PHP             |    プログラミング言語 |       出版社       |
| JSon          　 |データ形式 　　|      13日の金曜日 or 厚切り  |

#余談(2)
**プログラマー(のみ)のための英単語帳**

ひとまず思いつくところで。

**default**
欠席、不履行
default valueは指定が「無かった」時の値であり、本来はdefaultに「初期」という意味はない。

**string**
紐、弦
文字列の「列」。本当は文字じゃなくても良いのだろうが……

**legacy**
遺産
プログラマ的には「負の遺産」という意味で使われる。本来の語とテストコードは関係ない。

**boot**
ブーツ（長靴）
起動の意味は無い。なぜIT界隈だとbootが起動の意味に使われるようになったかは、諸説ある模様。

**float**
浮く、浮いたもの
浮動小数点数の「浮動」であり小数の意味はない。

**hash**
細切れにする
データ全体を細切れにし小さな値にまとめたものをハッシュ値と呼ぶ。さらにハッシュ値をキーとした連想配列をHashMap呼ぶ。

**wrap**
包む、くるむ
プログラミング用語としては、254→255→0→1 のように、値が限界を超えた時に反対側の限界値にもどること。レースの周回 (lap) とは関係ない。

**port**
港
プログラミング用語としてはTCP/IPのポート番号としてしか利用されない。import/exportの語源だが、portとimportが同じ文脈で使われることは無い。

#まとめ
少しずつ英語アレルギーをなくすために、触れる機会を創出することが何より重要:pick:
つらつらと書いただけで読み応えのない記事になってしまったので、次回はもう少しいい感じのものを書きたいと思います。
自分用　Github 

#メモ。GitHub初めて使います。

使用ディレクトリめちゃくちゃ。あとで整理する

**1. Git初期設定ユーザ情報設定**

    git config --global user.name "ryo..."　//自分が誰で
    git config --global user.email "ryo@...jp"　//どんなメアド

**2. ROSパッケージをローカルにクローン**

    git clone https:...git

**3.リポジトリディレクトリに移動**

    cd practice 
    git branch -a //現在のブランチチェック、基本localになってるかのチェック`

**4.branchの切り替え**

    git checkout develop //開発するときはdevvelopブランチに移動する
	
**5.練習用のブランチ？作成　localで行うときは以下のようなbranch名前をつけ移動する**

	git branch feature/ryo/practice 　//feature/担当者/内容...tagを記入できる？調べないと
	git checkout feature/ryo/practice 

**6.ローカルで変更した内容をリモートサーバーへ送る。**

	git add .	//ファイルをステージングエリアに設置（必ず）。公開するものは選べるが” .”は全部。
	git commit -m “add a practice file”	//何したかわかるようにする
	git remote -v　//でfetchとpush先、リポジトリ名の確認可能
	git push origin develop:develop　//*次回からgit push のみで自動的に更新される。↓アドレス名登録されてないとき、しかしデフォはoriginになってるはず。
	（git push https://...git develop:develop）

**7.別のbranchに統合する(mergeで結合し、masterに上げる)//12/26 Git2.0時のアプデによりgit pushからgit pullへ変更**

    git checkout develop
    git merge --squash feature/ryo/practice
    git pull

**8.現在の状態を確認.master?local?どこにいる？**

    git status



###ローカルリポジトリ１から作成する場合

**1.ローカルリポジトリを１から作成し、リモートリポジトリに連結する場合**

	mkdir test
	cd test

**2.READ.mdファイル作成、中身にpractice書き込む。**

	echo "# practice" >> README.md

**3.testファイルを.gitファイルにする。**

	git init
**4.READMEファイルを追加。説明文載せとくと見る人にわかりやすい。**

	git add README.md 

**5.ファイルやディレクトリの追加・変更をリポジトリに記録するにはコミット。前回と現在の状態までの差分を記録したコミットが作成される。中身ないとエラー吐く。あとこれでmasterってブランチとしてローカルディレクトリ登録されてる感じする。**

	git commit -m “first commit”

**6.まず、リモートリポジトリのアドレスの名前を登録する。（push時にurl入力不要)**

	git remote add origin https://github.com/ryo/practice.git

**7.コンソール：リモートリポジトリにローカルリポジトリの履歴をpush**

	git branch feature/ryo/pra1 //作業用ブランチ作っとく
	git checkout feature/ryo/pra1 //作業用ブランチ移動しておく
	git add .  
	git commit -m "add branch"　//変更や追加をコミット
	git branch -a 　//現在のブランチ確認してから
	（git push -u origin master　//リモートに上げる）
	 git push -u origin  feature/ryo/pra1: feature/ryo/pra1 //(ローカルブランチ：リモートブランチ)


**追記：後日、他の人が編集したとしたら・・・**

	git fetch origin  //リモート最新情報取り込む
	git checkout feature/ryo/pra1
	git merge origin/master //mergeで取り込んだ最新状態を現在のブランチへ統合する。このorigin/masterはローカルにあるorigin/master。

####参考文献：
[Git勉強中☆ローカルで作業ブランチを作成しリモートへPushするまでの手順
]( https://www.granfairs.com/blog/staff/gitbeginner01 )
[git addで変更されたファイルをステージングエリアに追加する方法【初心者向け
]( https://techacademy.jp/magazine/10168 )
配列と連結リストの違いをGoのソースコードから説明しようとしたらコードリーティング力が問われて挫折した

配列と連結リストの違いを学んで説明しようとしたのですが「せっかくだから実際の実装から取ってこようぜ」という欲を出した結果コードリーディング力が問われて挫折することに……。

## 配列と連結リストの違い

配列は定規のメモリに名札がついているイメージ。
連結リストは鎖に名札がついているイメージ。

配列（固定長の基本的なやつ）は宣言した長さのメモリを確保して、indexから決まるメモリアドレスにアクセスします。
連結リストは要素それぞれが前後の要素のアドレスを持ち、たどるようにアクセスします。リスト構造体は始点と長さを持ちます。

それゆえ、連結リストは切り貼りしたりずらしたりに強く、配列は弱い。
逆にindexが重要となる場合には配列のほうが得意、という特徴があります。

## 以下、Goのソースコードでチェックしようとして挫折した原因。

[github.com/golang/goのライセンス表示](https://github.com/golang/go/blob/master/LICENSE)

Goのソースコードを読み解いていきましょう。

## 連結リスト

containers/list/list.goにあります。

```go
// Element is an element of a linked list.
type Element struct {
	// Next and previous pointers in the doubly-linked list of elements.
	// To simplify the implementation, internally a list l is implemented
	// as a ring, such that &l.root is both the next element of the last
	// list element (l.Back()) and the previous element of the first list
	// element (l.Front()).
	next, prev *Element

	// The list to which this element belongs.
	list *List

	// The value stored with this element.
	Value interface{}
}
```

```go
// List represents a doubly linked list.
// The zero value for List is an empty list ready to use.
type List struct {
	root Element // sentinel list element, only &root, root.prev, and root.next are used
	len  int     // current list length excluding (this) sentinel element
}
```

### 解説

連結リストは簡単に見つかります。
省略していますが各構造体に適切なメソッドが実装されています。

## 配列

問題だったのは配列の方です。
考えればわかることだし、調べればすぐ気がつくのですが、配列は言語仕様です。

つまり、構文解析とか評価とかあのあたりのコンパイラの概念を理解した上で探さなければたどり着けません。
一度始めたからにはやるっきゃないと今日一日時間の許す限り探しましたが、到達できませんでした……。

Goの内部構造に興味をもつ良い機会でした。
コンパイラを学びながら調べるのを続けます。
sympyで「行列の平方根の数値計算(Square root of a matrix)」をやってみた

(参考)行列の平方根の数値計算
https://qiita.com/Kgm1500/items/b3bb1a3246ae4bdfb1ab
(参考)Square root of a matrix
https://en.wikipedia.org/wiki/Square_root_of_a_matrix

```fullscript.py
from sympy import *
from mpmath import *
A=Matrix([[5,4,1],
          [4,6,4],
          [1,4,5]])
print(A)
print(sqrtm(A))
# Matrix([[5, 4, 1], [4, 6, 4], [1, 4, 5]])
# [                 2.0  1.0  3.33606965638267e-20]
# [                 1.0  2.0                   1.0]
# [3.34095591577049e-20  1.0                   2.0]
```

2019-01-03
#本家stackoverflowでsqrtmを教えてもらった
How to round Matrix sqrtm in sympy?

https://stackoverflow.com/questions/53923323/how-to-round-matrix-sqrtm-in-sympy
Apache Sparkが遅かったり、落ちちゃう時に試してみるオプション

Sparkで機械学習をするとき、前処理もSparkでやりますよね。
前処理って面倒ですよね。カテゴリ値とか連続値とか合成変数とか。
無邪気に変数を定義するデータサイエンティストにイラっとします。

さて、ある程度の大きさのデータを処理すると、
タイムアウトとかOOMとか、処理が遅かったりしますね。
そんなときに試してみると良いかもしれないオプションです。

##Dynamic Allocation
無駄なリソースを使わないことに越したことはないので、動的リソース確保ができるようにします。
DynamicAllocationを有効にするには、ShuffleServiceも有効にする必要があります。
使われないExecutorが削除されるので、Shuffleのファイルを別な場所に退避させておくためです。
`spark.dynamicAllocation.enabled`
`spark.shuffle.service.enabled`

頻繁にExecutorを作成、削除するのも無駄なので削除される時間を調整しましょう。
`spark.dynamicAllocation.executorIdleTimeout`

## Memory Magement
データがメモリから溢れたら元も子もないのでサイズ調整しましょう。
`spark.memory.offHeap.enabled`
`spark.memory.offHeap.size`
`spark.executor.memory`
`spark.yarn.executor.memoryOverhead`

##Shuffle
OOMとかFetchエラーが出る場合は分割サイズが大きいのかも、もっと分割しましょう。
`spark.default.parallelism`
`spark.sql.shuffle.partitions`

メモリよりディスクが遅いのは自明なのでキャッシュサイズを調整しましょう。
`spark.shuffle.file.buffer`
`spark.unsafe.sorter.spill.reader.buffer.size`
`spark.shuffle.unsafe.file.output.buffer`
`spark.shuffle.service.index.cache.entries`

圧縮ブロックサイズも調整して、無駄は無くしましょう。
`spark.io.compression.lz4.blockSize`

ShuffleServer自体の性能も調整しましょう。
`spark.shuffle.io.serverThreads`
`spark.shuffle.io.backLog`
`spark.shuffle.registration.timeout`
`spark.shuffle.registration.maxAttempts`

##タスク再実行
１つのタスクが遅いために全体が引きずられて遅くなることがあります。
再起動を判断する投機的実行と再実行する閾値を定義します。
`spark.speculation`
`spark.speculation.multiplier`

`spark.max.fetch.failures.per.stage`

##TimeOut
デフォルトでTimeOutエラーがでるようなら調整しましょう。
`spark.sql.broadcastTimeout`
`spark.network.timeout`


##シリアライズ／フォーマット変換
`spark.serializer=org.apache.spark.serializer.KryoSerializer`

もし、ORCフォーマットのHiveテーブルを読み書きする際は設定しましょう。
`spark.sql.orc.enabled`
`spark.sql.hive.convertMetastoreOrc`
`spark.sql.orc.filterPushdown` 
`spark.sql.orc.char.enabled`

##そのた
デフォルトだと試行回数が2回なので1回にします。
`spark.yarn.maxAppAttempts`


パラメータ多過ぎですが(YARN、Hiveも加わると。。。)、それも楽しかったりしますよね！！
Enjoy Apache Spark！
2018年12月第1週　今週気になった記事まとめ

# 今週気になった記事まとめ
##■マルチタスクは幻想だがその幻想が現実のパフォーマンスを上げる
https://gigazine.net/news/20181202-illusion-multitasking-positive-effect/
確かに集中力はマルチタスク状態だと上がっているような・・・？
でも正確性や効率はやはり下がっていると思うので、結果マイナスじゃないかな・・・。

##■球体型相棒ロボット｢CIMON｣が宇宙デビュー。気分屋でヘソ曲がりさん
https://www.gizmodo.jp/2018/12/companion-robot-cimon.html
色々なアニメ、映画などのAIを見ているとちょっと抜けた部分があるくらいがAIとしての味わいを出している気がするが、それをプログラミングするのは実際とても技術的にも塩梅という部分でも大変だわなぁ。。

##■新卒からの質問をソシャゲっぽい仕組みにしたら捗った話
https://qiita.com/y-tsuna/items/fced3a9515c8f585ca50?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
当然ケースバイケースな部分もあるでしょうが、かなり上手くできている仕組みだなと。
同じことをするかまでは分からないけれど、一つのモデルとしてちゃんと覚えておきたい。

##■エアコンより環境に優しい冷房システムのコンテスト開催、賞金は3億円以上！
https://techable.jp/archives/88555
皆に優しい、とても前向きなコンテストで面白い

##■インフラエンジニアと謎のサーバ
https://qiita.com/kanga/items/979b0bdc4653e025483a
現場にもあったなぁ。
基本的な調査は記事の内容でできるのだけど、やはり最後の最後で「こいつは何のために動いてるんだ？」が分からないことが多い。
あとたまにどんだけ調べてもそもそもどうやって動いているのか謎が解けないやつもたまにいる
rails  member　ルーティング

##メンバー (member) ルーティングを追加したい場合は、memberブロックをリソースブロックに1つ追加します。
デフォルトの７つのルーティング以外にも、ルーティングを追加できます。


```rb

resources :photos do
  member do
    get 'preview'
  end
end
```

上のルーティングは***GETリクエスト***とそれに伴う***/photos/1/preview***を認識し、リクエストを***Photosコントローラのpreviewアクション***にルーティングし、リソースid値をparams[:id]に渡します。
同時に、photo_preview_urlヘルパーとphoto_preview_pathヘルパーも作成されます。




memberルーティングブロックの内側では、次に述べるHTTP動詞が指定されたルーティング名を認識できます。指定可能な動詞はget、patch、put、post、deleteです。***memberルーティングが1つだけしかないのであれば、以下のようにルーティングで:onオプションを指定することでブロックを省略できます。***

```rb

resources :photos do
  get 'preview', on: :member
end
```

:onオプションを省略しても同様のmemberルーティングが生成されます。***この場合リソースidの値の取得にparams[:id]ではなくparams[:photo_id]を使用する点が異なります。***
VSCodeの拡張機能をバージョン指定でインストールする方法をまとめてみた.

#この記事では..
VSCodeの拡張機能がアップデートされて困ったことないですか?私の設定が悪いのか.
Veturが14.3になり,何故か vue-cli3.0 & TypeScript の開発環境でワーニングが鳴り止みません..
シングルコートがダブルコートに勝手に変換されダブルコートでワーニングを食らうという..残念..

良く分からないからいろいろモジュール調べるとVeturが怪しいとなりバージョンを戻して見ようと思いました.
あれ,そういえばバージョンってどう指定するのか知らない..ということで手順をまとめておきます.

#手順
##VSIXファイルをインストール
ほしい拡張ツールをクリック,変更ログタブをクリック,ほしいバージョンのVSIXをクリック.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/baec2e71-2ae9-8590-8844-a5a2bec95fa5.png)
(画像は既に戻しているものです.混乱させらすみません..)

##拡張機能をインストール
VSCodeの拡張機能タブの...ボタンよりVSIXからのインストール...よりインストール.
![image.png](https://qiita-image-store.s3.amazonaws.com/0/283053/622da209-a4ab-8ab0-2cfc-73c62493895d.png)

これで読込が終われば,完了.
ワーニングもなくなりました!

#自動でアップデートしたくないんだけど..
この場合は,User settingに以下を追加する.
1つ目がVSCodeのアップデート
2つ目が拡張に対するアップデート
用途に合わせて使う.

```json
"update.channel": "none",
"extensions.autoUpdate": false
```

#まとめ
自動アップデートに関しては,なんか起こると面倒だからという消極的な理由でオフりましたが,
案件で指定のバージョンなどが有る場合はオフる必要があると思います.
今回はまったので..次回に活きる事を期待します!
アイカツ！のマイページから情報を取得するやつを作る その1

# はじめに

この記事は、[アイカツ！ Advent Calendar 2018](https://adventar.org/calendars/3700)の7日目の記事です。内容としては、現在大好評稼働中のアーケードゲーム、[データカードダス アイカツフレンズ！](http://www.aikatsu.com/friends/)のマイページから情報を取得するツールを作成中で、その内容と進捗の紹介になります。

前日の記事は[iyanayatudaze](https://adventar.org/users/7164)さんによる[スギカツフレンズ！2018 レポ - ねむい](https://yellowho.hatenablog.com/entry/2018/12/06/222352)でした。

ちなみに、これまでアイカツ！ Advent Calendar 2018では以下のような技術系記事が投稿されています。

- [アイカツ！画像でLGTMできるChrome拡張機能をストアに公開しました - matのブログ](https://romiogaku.hateblo.jp/entry/2018/12/01/223906)
    - 2日目
- [Aikatsu Music Medoly - アトリエあざらし](http://blog.a-azarashi.jp/entry/2018/12/05/060344)
    - 5日目

# aikatsu-dcd-parser
[kakakaya/aikatsu-dcd-parser: Fetch and parse Aikatsu! DCD mypage data.](https://github.com/kakakaya/aikatsu-dcd-parser)
取得及びパースをするライブラリ本体と、それを利用したCLIツールの2つが含まれており、いずれも `dcdkatsu` という名前でインポートや実行が可能です。


[現時点（v0.1.0）](https://github.com/kakakaya/aikatsu-dcd-parser/releases/tag/v0.1.0)で実装済みなのが、以下に示す `user` コマンドです（JSON整形は`jq`、画像の表示には`catimg`を使っており、このツールの機能ではありません）。マイページに表示される情報を取得し、JSONで出力しています。

[![asciicast](https://asciinema.org/a/RNuFBCcp5w01q9ZG9pR453jcO.svg)](https://asciinema.org/a/RNuFBCcp5w01q9ZG9pR453jcO) 

## インストール
そのうちバイナリを配布します。多分次回記事には間に合わせますが、現時点ではまだなので今すぐ試したい方はGoをインストールして以下の手順を踏んでください。動作確認環境は `go 1.11.2` です。

- CLIツールをインストールしたい場合（普通の人はこちら）
    - `go get -u -v github.com/kakakaya/aikatsu-dcd-parser/cmd/dcdkatsu`
- 取得部分をライブラリとして使いたい場合
    - `go get -u -v github.com/kakakaya/aikatsu-dcd-parser`
    - 解説は省略するので、ドキュメントはGoDocを参照してください。[dcdkatsu - GoDoc](https://godoc.org/github.com/kakakaya/aikatsu-dcd-parser)

## 使い方
まず取得対象にしたいユーザーのマイページを開きます。※ログインする方ではなく、Twitterに共有などのボタンから得られるURLです。
![2018-12-07_22-04-03.png](https://qiita-image-store.s3.amazonaws.com/0/80036/c1798c63-b4b2-07b5-6741-a8ad80a24d0b.png)
上記画像のようなURLで、 `http://mypage.aikatsu.com/mypages/index/` に続く部分（以下、ユーザーID）をコピーします（上記画像だと`RXL...v3x`）。

次に、上節での手順を済ませていれば `dcdkatsu` コマンドが使えるようになっているはずなので、次のように実行します。

```shell 
dcdkatsu user <ユーザーID> 
```

すると、いい感じにJSONが出力されます。


# おわりに
こっそり作ってアドベントカレンダー終盤に公開するつもりでしたがSHINING LINE*を途絶えさせないためにも開発途中での公開と相成りました。今後も途絶えそうになったらぼちぼち開発の進捗を記事として公開しようかな、と考えています。

なお、今後以下のような機能の実装を考えています。

- 取得間隔の制限（サーバへの負荷を防ぐため）
- 取得可能な機能の追加
  - デジタルバインダーの取得
  - ログインが必要な部分の取得
    - フレンズ
    - バッジ
    - ランキング実績
    - 大会実績
    - アーカイブ
      - アイカツスターズ！1弾〜5弾
      - アイカツスターズ！星のツバサ編
- 取得結果の保存、差分表示
- テストの作成
    - ランキング周りが面倒そう
- CI
    - やるだけ
- バイナリの配布
  - goreleaserを試す

他にも欲しい機能やマサカリがあったら、この記事のコメントにお願いします。これは非公式なものであり、データカードダス アイカツフレンズ！公式や、バンダイナムコ、その他権利者の方に問い合わせないようお願いします。また、怒られたらすぐに消します。

明日は[hazel_calm](https://adventar.org/users/24386)さんの「アイカツについてなにか書きます。」です。
DXOpalのWindow.draw_boxのバグを修正した

こんにちは、yharaです。今日はDXOpalのバグを一つ直したので、どんな流れで作業したのかを解説してみます。

## 白がグレーになる？

前回の[DXOpalでUndertaleっぽい画面を作る \- Qiita](https://qiita.com/yhara/items/c9a2a21ff24c65978205)を書いてて気づいたんですが、draw_boxで四角形を描いたときの見た目が怪しい。

これ最初のスクリーンショットで、白で1pxの四角形を描いたつもりですが、なんか暗くないですか？白というよりはグレーっぽいような…

![スクリーンショット 2018-12-05 20.50.35.png](https://qiita-image-store.s3.amazonaws.com/0/43/ddaa58f8-85c5-55ab-fc03-9e0921bafaac.png)

## 原因

Twitterでつぶやいたところ、canvasの座標系の(0, 0)は「左上のピクセル」ではなく「左上のピクセルの左上の隅」を指しているので、綺麗な1pxの線を引くには0.5を足してやらないといけないということを教えてもらいました。

- https://twitter.com/yhara/status/1070293143952605184

## 修正

とりあえず再現コードはあるわけなので、これが直ったかすぐわかるように開発環境をセットアップします。

[DEVELOPMENT.md](https://github.com/yhara/dxopal/blob/master/DEVELOPMENT.md)に書いてありますが、bundle exec rackupすると[公式サイト](https://yhara.github.io/dxopal/)とほぼ同じものが立ち上がるので、これを使ってデバッグします。

## 公式サイトとconfig.ruの違い

「ほぼ同じ」と言ったのは、公式サイト(github pages)ではビルド済みのbuild/dxopal.min.jsが使われるのに対し、config.ruで起動した場合はlib/以下のコードが毎回コンパイルされるという違いがあるからです。

デバッグ中は少し直すために再ビルドするのは面倒すぎるので、rackupで起動したものを使うと便利です。config.ruの[ここのgsub](https://github.com/yhara/dxopal/blob/2e08804796f5ae07877a1c473504f71643882745/config.ru#L24)で、html内のdxopal.min.js読み込み箇所をコンパイルされたコードが読み込まれるよう差し替えています。

## 再現コードを組み込む

最初に表示される、赤い丸が移動するデモのソースはexamples/top_page/main.rbにあります。ということで、ここに適当に `Window.draw_box(10, 10, 50, 50, C_RED)` を入れて、ブラウザをリロードします。

四角が出ました。[^1]ちょっとわかりにくいですが、赤い丸と比べて微妙にピンクっぽくなっています。

[^1]: 出ない場合はdeveloper consoleのdisable cacheを有効にしてください。

![スクリーンショット 2018-12-06 20.55.50.png](https://qiita-image-store.s3.amazonaws.com/0/43/42832fe2-04f9-2fe1-e80a-3ea8fa75b7f4.png)

## 修正する

Window.draw_boxの本体はlib/dxopal/image.rbにあります。WindowとImageは似たようなメソッドを持つので、Image側に集約しているためです。

ということでimage.rbのboxメソッドを以下のように修正します。

```diff
       %x{
         ctx.beginPath();
         ctx.strokeStyle = #{_rgba(color)};
-        ctx.rect(x1, y1, x2-x1+1, y2-y1+1);
+        ctx.rect(x1+0.5, y1+0.5, x2-x1+1, y2-y1+1);
         ctx.stroke();
       }
       return self
```

ブラウザをリロードすると、くっきりした線が出ました。いいですね〜。これですよこれ。

![スクリーンショット 2018-12-06 21.01.23.png](https://qiita-image-store.s3.amazonaws.com/0/43/99d95189-1824-bd97-3c6b-9644ece881cf.png)

## もう一つのバグ

これで、昨日の最後のデモも綺麗に表示されるはず…

![スクリーンショット 2018-12-06 21.10.23.png](https://qiita-image-store.s3.amazonaws.com/0/43/b5824878-c062-5dae-2f67-54c76084b157.png)

と思ったけど、まだ中央だけ太くなっていますね。ctx.rectの第3・第4引数は幅と高さですが、上のdiffを見ると、`+1`が余計な気がします。

ということでそこも修正すると…

```diff
       %x{
         ctx.beginPath();
         ctx.strokeStyle = #{_rgba(color)};
-        ctx.rect(x1, y1, x2-x1+1, y2-y1+1);
+        ctx.rect(x1+0.5, y1+0.5, x2-x1, y2-y1);
         ctx.stroke();
       }
       return self
```

![スクリーンショット 2018-12-06 21.13.32.png](https://qiita-image-store.s3.amazonaws.com/0/43/3c11d756-caf2-503e-ce07-57d89405ba35.png)

いい感じになりました。:tada:

## まとめ

今日はDXOpalのバグを一つ修正しました。リリースは月末にしようと思っています。お楽しみに。

- チケット：https://github.com/yhara/dxopal/issues/16
- 修正コミット：https://github.com/yhara/dxopal/commit/4c6634a5473973baec32f8642ed479ff666ea6ca
メタボっ腹な古株技術者が転生したらIFTTTっ腹になっていた件

タイトルは５秒前の思いつきです。
こんにちは、しのやんです。
[スマートスピーカーIFTTT 大喜利 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/ssifttt)の7日目です。
Qiita投稿もアドベントカレンダーも初めてだと思います。もし初めてじゃなかったら多分辛いことと一緒に忘れてしまったのでしょう。
宜しくお願いします。
さて。

# IFTTT連携アイデア妄想編
正直IFTTTを使いこなしてはいない私が、通勤電車の中やトイレや風呂や会社の自動ドアに挟まって変な声をあげた瞬間に思いついたアイデアを、徒然なるままに列挙して自己レビューしてみたいと思います。
ネタ投稿ですいません。
実際に試して挫折したものがいくつかあります。
実現したものはありません。

## WiFiのある地下鉄の駅をスキャンする
- This: Android Device - Connects to any WiFi network
- That: ??? （緯度経度がWebhookに渡せれば・・・？）

会社までの通勤電車の駅数が多く(25駅以上)、1日3時間以上は通勤に人生を費やしている私にとってギガ節約は大事なのです。キャリア提供のWiFiがある駅が分かれば、駅に着く直前にWiFiをONにしてGooglePlayのアプリアップデートやネトゲーのパッチダウンロードを済ませ、ギガを稼ぐのです。

実用度：★★★☆☆
面白さ：☆☆☆☆☆
通勤環境改善度：☆☆☆☆☆

## 特定のWiFiにつないだら、Wifiをoffにする
- This: Android Device - Connects to a specific WiFi network
- That: Android Device - Turn off WiFi

「WiFiに繋がったらWiFiをoffにする」ってしょーもないネタを思いついた時に、あれ、特定の怪しいネットワークだけつながないようにできるんじゃない？って思って作りましたが、繋がっちゃった時点でアウトな気がする。

実用度：☆☆☆☆☆
面白さ：★☆☆☆☆
良さそうで良くなかった度：★★★☆☆

## いま停車している駅の新名称を考えてくれる
- This: ??? (今いる駅を知るには…？）
- That: Webhooks　（Lambdaあたりでちょちょっと）

漢字＋カタカナの駅名、流行ってるのかな？

実用度：☆☆☆☆☆
面白さ：★★★★☆
イマドキ度：★★★★★

## 昼に会社から外出しなかったら勝手に出前を頼んでくれる
- This: Location - You enter or exit an area
- That: Webhooks　（Lambdaとかで14時までにWebhook来るかチェックして、来なかったら出前サービスにhttpリクエスト投げる）

シャチクになってもご飯は食べよう。

実用度：★★★☆☆
面白さ：★★☆☆☆
頼んだ事に気づかず配達人激怒度：★★★★☆

## Googleカレンダーを市松模様に塗る
- This: Button widget - Button press
- That: Google Calendar - Create a detailed event

カレンダーをキャンバスに見立ててドット絵にいそしむもよし、予定がいっぱい入っている陽キャを装うもよし。でもThatが日付指定に融通聞かないようなので、LambdaからGoogleCalendarにアカウントリンクしてごにょごにょ…あぁ時間が無いや…

実用度：★☆☆☆☆
面白さ：★★★★☆
自分の予定を見せる相手がいないと悲しい度：★★★☆☆

## アレクサ、テストとトリガー、と言うとClovaがアレクサ、テストとトリガー、と言う
![15441822345111.jpg](https://qiita-image-store.s3.amazonaws.com/0/309295/5369a8ee-23f8-9aa7-3632-7cd878106900.jpeg)
- This: Amazon Alexa - Say a specific phrase ⇒ "テスト"
- That: Clova - Post message to Clova ⇒ "アレクサ、テスト、とトリガー"

な…　何を言ってるのか　わからねーと思うが
あ…ありのまま 今　起こった事を話すぜ！
要はアレクサとクローバで無限ループをさせたかったわけですが、よくよく考えてみたらクローバの通知は「通知を教えて」と言ってあげないとしゃべらないので実現しなかったのでした。

実用度：☆☆☆☆☆
面白さ：☆☆☆☆☆
自己満足度：★★★★★

# アレクサに伝える愛のダジャレトリガー編
- アレクサ、クロノトリガー  
 ⇒ 光の速さで真っ先に誰もが思いつくネタ。
- アレクサ、宴会のトリが…！  
 ⇒ 終りがシまらないとどうしようもない
- アレクサ、お値段以上ニトリガー  
 ⇒ たびたびお世話になってます。

# ・・・すいません、これくらいで
オフィスで堂々とこんな駄文が書けるこの会社が好きです。

きまぐれでまたQiita書くかもしれません。その時はまたお会いしましょう！
以上ﾃﾞｽｰ(^o^)ﾉｼ
macOSでpyenvを使うまでに何度か失敗したので

なかなかpyenvでpython3.6が入らなかったので、備忘として。

* OS
    * macOS Mojave 10.14.1
 
* 入れたいpythonのバージョン
    * 3.6.5 

# pyenvをインストール
```
$ brew install pyenv
```

# 3.6.5を入れようとしたが失敗
```
$ pyenv install 3.6.5

...
zipimport.ZipImportError: can't decompress data; zlib not available
make: *** [install] Error 1
```

https://qiita.com/zreactor/items/c3fd04417e0d61af0afe
を参考に、macOSのSDK headerの入れてみます。

# また失敗
```
$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /

...
installer: Error - the package path specified was invalid: '/Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg'.
```

まず、xcode-selectが入っていなかったみたいです。

# xcodeのインストール
```
$ xcode-select --install
```

# macOSのSDK headerのインストール
```
$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /

installer: Package name is macOS_SDK_headers_for_macOS_10.14
installer: Installing at base path /
installer: The install was successful.
```

# またまた失敗
```
$ pyenv install 3.6.5    

...
PermissionError: [Errno 13] Permission denied: '/lib/python3.6'
```

sudoでやれとのこと。

# またまたまた失敗
```
$ sudo pyenv install 3.6.5

...
PermissionError: [Errno 1] Operation not permitted: '/bin/easy_install-3.6'
make: *** [install] Error 2
```

`~/.pydistutils.cfg`があると、エラーになるとのことです。

# 成功！！
```
$ sudo pyenv install 3.6.5

...
python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-3.6.5.tar.xz...
-> https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tar.xz
Installing Python-3.6.5...
python-build: use readline from homebrew
Installed Python-3.6.5 to /Users/<user>/.pyenv/versions/3.6.5
```

# まとめ
pipenvを使うためにpyenvを入れる上で、困っている人がいたらぜひ参考にしてください。