OmniAICreator/Qiita-1.07M huggingface dataset:
QuizKnockの名詞抜きクイズをpythonで再現してみた。クイズもあるよ^^

# 名詞抜きクイズとは

東大生クイズ王 伊沢拓司さんを編集長とするWEBメディアQuizKnock。[^1]
YouTubeでも活動をされており、その中の企画で名詞抜きクイズというものがあります。

詳しくはこちらの動画をご覧ください。

[【穴あき】クイズ王なら名詞がなくても正解できる説【9割減】](https://youtu.be/POrlmU-pqiQ)

業務で形態素解析をやる機会があり、その日の帰宅後に観た動画がちょうどこれで「あ、形態素解析」。
ということでpythonでクイズを再現してみました。

# 準備
必要なライブラリは形態素解析するためのjanomeのみ。
pip installで簡単に入れられるのでjanomeを使ったけど、MeCabでもなんでもいいです。

```shell

pip install janome
```

時事問題などに対応するために、新語や固有語辞書を追加したほうが良い気もします。

#やること
クイズの問題文を形態素解析。→名詞を文字数分の空白に置き換え。
これだけ。

#実装

```python
from janome.tokenizer import Tokenizer


def filter_noun(text):
    tokenizer = Tokenizer()
    tokens = tokenizer.tokenize(text)
    quiz = []
    for token in tokens:
        if token.part_of_speech.startswith('名詞'):
            quiz.append(' ' * len(token.surface))
        else:
            quiz.append(token.surface)
    return ''.join(quiz)

```

#やってみた
動画内で出題されたクイズで試してみます。

```python:第１問

filter_noun('マラソンなどで一気に何人もの選手を追い抜くことを、ある野菜を使って何というでしょう？')
```

結果がこちら。

```
    などで一気に  もの  を追い抜く  を、ある  を使って というでしょう？
```

動画内で出題された状態と同じになりました^^

正解は「ごぼう抜き」です。
ちなみにQuizKnockメンバーの山本さんは「などで一気に」が読み上げられた時点で正解していました:dizzy_face:

もう一問やってみた。

```python:第２問
filter_noun('「入り江」という意味のスペイン語に由来する、日本では志摩半島や三陸海岸に見られる複雑に入り組んだ海岸を何というでしょう？')
```

結果がこちら。

```
「   」という  の     に  する、  では    や    に見られる  に入り組んだ  を何というでしょう？
```

それっぽいかんじになった。
正解は「リアス式海岸」。

# さあ問題。



エンジニアのみなさんに名詞抜きクイズ〜

```:第１問
       に  を置く、      、          、        、     の4つの  の   を取って  する  は というでしょう？
```

```:第２問
      を      することで   の         と協働して   をレビューしたり、      を管理しつつ  を    ができる、最も     な            は何でしょう？
```



```:第３問
     で に  、  から  に向け、  が  する  を何というでしょう？
```

いかがでしょうか。わかったかたはコメントお待ちしてます。
（ちょうどいい難度の問題を作ることが難しかったので、ちょっと調整しました、ごめんなさい笑）


[^1]: [https://quizknock.com/](https://quizknock.com/)
認証のあるプロキシ環境下でComposer installがうまく行かないときの対応方法

- 環境
    - Windows7 32bit
    - Composer version 1.6.5 2018-05-04 11:44:59

# 事象 : 認証のあるプロキシ環境下で`install`がうまくいかない
- [プロキシ環境下で composer でインストール出来なくなった（HTTP/1.0 400 Bad Request） - ngyukiの日記](https://ngyuki.hatenablog.com/entry/2013/05/07/234643)
- [composerがproxy関係でコケるときの対処方法](https://matsu-chara.hatenablog.com/entry/2013/08/30/133923)


## 対応方法 : 環境変数にプロキシを設定する
[Command-line interface / Commands - Composer](https://getcomposer.org/doc/03-cli.md#http-proxy-or-http-proxy)によると
「環境変数で`HTTP_PROXY`にプロキシを設定してね。」
「プロキシが`request_fulluri`フラグをサポートしていなかったら環境変数で`HTTP_PROXY_REQUEST_FULLURI`と`HTTPS_PROXY_REQUEST_FULLURI`に`false`か`0`を設定してね。」
と言っている気がします。(正確に読みたい方はサイトを見てください。)

```bash:bashを使う場合
# 1回やればOKなところ--------
$ echo "export HTTP_PROXY=http://{ユーザ名}:{パスワード}@{プロキシ}:{ポート}/" >> ~/.bash_profile
$ echo "export HTTPS_PROXY=$HTTP_PROXY" >> ~/.bash_profile
$ echo "export HTTP_PROXY_REQUEST_FULLURI=0" >> ~/.bash_profile
$ echo "export HTTPS_PROXY_REQUEST_FULLURI=$HTTP_PROXY_REQUEST_FULLURI" >> ~/.bash_profile
$ source .bash_profile
# ここまで---何度もやると.bash_profileが大変なことになる------------------
$ composer install
```

```bash:Windowsコマンドを使う場合
set HTTP_PROXY=http://{ユーザ名}:{パスワード}@{プロキシ}:{ポート}/
set HTTPS_PROXY=%HTTP_PROXY%
set HTTP_PROXY_REQUEST_FULLURI=0
set HTTPS_PROXY_REQUEST_FULLURI=%HTTP_PROXY_REQUEST_FULLURI%
composer install
```
Composerが反応しないときの対応方法

- 環境
    - Windows10
    - Composer version 1.6.5

# 事象 : なぜかComposerが反応しない

```bash
$ composer --version
# いつまで待っても無反応
```

# 原因 : デバックしているから
## 対応 : デバックをやめる
PhpStormの![image.png](https://qiita-image-store.s3.amazonaws.com/0/159761/69552163-3aad-4acb-cae3-ccfbe0cd71c8.png)を![image.png](https://qiita-image-store.s3.amazonaws.com/0/159761/90f3d6d3-f2fb-ad14-d9ab-605a1049d8c9.png)にして、php.iniのxdebugをOFFにする。

```bash
$ composer --version
Composer version 1.6.5 2018-05-04 11:44:59
```
SoundFont 2.04 の仕様書の和訳(未完成版)

以下のリンクに和訳(未完成版)を出しています. 参考程度にしてください. ジェネレーター機能の一部以外は和訳済みのはずです. 
https://github.com/zaief44444/sf2/tree/master/sfspec24_japanese
未完成ですが完成させるモチベがありません. 言い訳させてもらいますが, このSoundFontという規格自体があまり優れたものではないと思うのとMIDI2.0の時代がやってくるのでより統一的かつ優れた規格に対応するために, SoundFontを新しく学ぶよりも他の音源の形式を勉強したいからです. 一応, SoundFont自体はMIDIと親和性があるようにある程度設計されているため, MIDI2.0の恩恵を受けるには新しい音源の規格でないといけません.
### モジュレーターについて
SoundFontにはモジュレーター機能という知る人ぞ知る機能があるようで仕様書では長々とページが割かれています. しかしこの機能はリンクに書いた通りMIDIと相性が悪いのでほとんど使われていないです. 私がSoundFontの使用状況についてあまり知らないまま勉強し始めた時はモジュレーター機能について色々SoundFontについてよく知っていそうな人から教えてもらいましたが, 前述した通り使わない機能なので無駄な徒労でした. しかも仕様書の英語が特にモジュレーター機能の部分が難解すぎて私のSoundFontの勉強はモジュレーターの勉強に殆んど割いてしまいました. ジェネレーター機能についてちゃんと説明するのが多分一番重要かつ需要も高いのでしょうが, 肝心のその部分が未完成で, モジュレーターの部分だけ完成した和訳になんの需要があるのか私にはわかりません.
ubuntu video driver ,AMD Ryzen cpu.何するの？

#ubuntu on Ryzen. 2019
AMD Ryzen 3000番台のCPUに、
ubuntuをのせた際に、
画面が横に伸びていて、
どうしていいのか分からなくなった時の防備録。

AMDのサイト、
https://www.amd.com/en/support
にて、ダウンロードできる、
ということだったのですが、
何を選んでいいのか分からず困っていました。

Radeon RX Vega 64
を選んでインストールすれば、
とりあえず、画面が横に伸びている状況から脱出できました。

\+ Ubuntu x86 64-Bit
をクリックして広げると、ダウンロードボタン出ますので、
ubuntu用のドライバをダウンロード。

ファイルをダウンロードしたあとは、
https://amdgpu-install.readthedocs.io/en/latest/install-prereq.html
にて、インストールの手順が挙げられていますが、

$ cd ~/Downloads
$ tar -Jxvf amdgpu-pro-YY.XX-NNNNNN.tar.xz
$ cd ~/Downloads/amdgpu-pro-YY.XX-NNNNNN
$ ./amdgpu-install -y
$ reboot

位で問題なく、画面が横に伸びている状況から脱出できました。

終わり.
Atom利用時にのみ反映される環境変数

# 経緯
パスを通す事ができないけどPHPは手元にあるって状況でいろいろ探してたところ、Atomの環境変数にPHPを突っ込む対応ができたのでメモ。

他にも同じようなことをしているものはあったけど、ローカルのパスを指定して追加するって対応がなかなか見つからなかった、数日前の自分が見つけられるようになれば良いんだけど。


# 対応手順

**init.coffee** を開いて下部の内容を追加するとパスに追加が可能。

init.coffeeの開き方は「file→init script」

※japanese-menuで日本語化している場合、「ファイル→起動スクリプト」で開けます

```coffee
process.env.PATH = [process.env.PATH,"C:\\xampp\\php",].join(";")
```
* `\`(バックスラッシュ)はエスケープされるので2つ繋げて`\\`にする。
* 追記後はリロードすること。「Ctrl+Shif+P → window: reload」

# 補足
Atom上で**Ctrl+Shift+I**で開発ツールを出して、コンソール上に**process.env.PATH**と打ち込むと現状の通っているパスリストが見れる。

上記対応後に打ち込んで、結果が望んでいた通り追加されていれば完了。
「WEBを支える技術」のまとめ２.５

「Webを支える技術」のまとめです。

#HTTP
HTTPのなかでも、ステータスコードについてまとめました。

#ステータスコード
HTTPはリクエスト/レスポンス型のプロトコルです。すべてのリクエストにはレスポンスが返ります。リクエストの結果得られるレスポンスメッセージの中で、その意味を伝えるステータスコードについて見ていきます。

##ステータスコードの分類と意味
ステータスコードは3桁の数字であり、先頭の数字によって5つに分類することが出来ます。

###1xx:処理中
処理が継続していることを示します。クライアントはそのままリクエストを継続するか、サーバの指示に従ってプロトコルをアップデートして再送信します。

###2xx:成功
リクエストが成功したことを示します。

###3xx:リダイレクト
他のリソースへのリダイレクトを示します。クライアントはこのステータスコードを受け取ったとき、レスポンスメッセージのLocationヘッダを見て、新しいリソースへ接続します。

###4xx:クライアントエラー
クライアントエラーを示します。原因はクライアントのリクエストにあります。エラーを解消しない限り正常な結果を得られないので、同じリクエストをそのまま再送信することはできません。

###5xx:サーバエラー
サーバエラーを示します。原因はサーバ側にあります。サーバ側の原因を解消すれば、同一のリクエストを再送信して正常な結果が得られる可能性があります。

このように、ステータスコードを先頭の数字で分類することで、クライアントはとりあえず先頭の数字を見ればサーバがどのようなレスポンスを返しているのかを理解でき、クライアント側でどのような処理を行うべきか知ることが出来ます。
また、ステータスコードがあとから追加された場合も、先頭の数字の約束さえ守っていれば、クライアントは最低限の処理で対応することが出来ます。

##よく使われるステータスコード

###200 OK
リクエストが成功した場合に出力されます。

###201 Created
リソースを新たに作成できたことを示します。POSTとPUTのレスポンスとして返ります。
また、POSTの場合には、新しく作成したリソースのURIはレスポンスのLocationヘッダに絶対URIとして入ります。

###301 Moved Permanently
リクエストで指定したリソースが新しいURIに移動したことを示します。古いURIを保ちつつ、新しいURIに移行する際に用いられます。新しいURIはレスポンスのLocationヘッダに絶対URIとして入ります。

###303 See Other
リクエストに対する処理結果が別のURIで取得できることを示します。例えばブラウザからPOSTでリソースを操作した結果をGETで取得するときに使用します。


###401 Unauthorized
適切な認証情報を与えずにリクエストを行ったことを示します。レスポンスのWWW-Wuthenticateヘッダで、クライアントに対して認証方式を示します。


###404 Not Found
指定したリソースが見つからなかったことを示します。レスポンスにはその理由が入ります。

###500 Internal Sever Error
サーバ側で何かしらのエラーが生じていて、正しいエスポンスを返せないことを示します。レスポンスボディにはその理由が返ります。

###503 Sever Unavailable
サーバがメンテナンスなどで一時的にアクセスできないことを示します。レスポンスボディにはその理由が返ります。レスポンスのRetry-Afterヘッダで、再開時期がおよそ何秒後かを通知することもできます。

##まとめ
ステータスコードは大きく分けて5つに分類でき、それぞれに意味があります。ステータスコードを正しく使用することは大切なことです。設定する際は、よく考えましょう！
cURLしてHTTPステータスが200以外だったら再起動する

# 背景
弊社の社内システムはLinux+Apache+Tomcatで動いているものがあるのですが、原因不明でTomcatが停止してしまい、HTTP503が発生する現象が発生していました。

## 言い訳
今どきApacheではなくてnginxにしたいし、Tomcatが停止してしまうのはバグなような気がしますが、それほどクリティカルなシステムでもないし、業務が停止してしまうほどではないので優先度：最低の状態。

# 表題のとおり
旧時代的な対応ですが、このような対応にしました。まあ、備忘録です。

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

# 死活監視したいURL
REQUEST_URL=http://hoge/paka

HTTP_STATUS=`curl -LI ${REQUEST_URL} -o /dev/null -w '%{http_code}\n' -s`

echo `date '+%y/%m/%d %H:%M:%S'` "HTTP STATUS:"${HTTP_STATUS}

if [ $HTTP_STATUS = "200" ]; then
  echo `date '+%y/%m/%d %H:%M:%S'` "動いているよ！"
  exit;
else
  echo `date '+%y/%m/%d %H:%M:%S'` "死んでいるよ！"
  systemctl restart tomcat.service
fi
```

cronでこのシェルを実行する場合は環境変数に注意です。
本当はログの出力をしていたけど、それは省略。適当にやってください。
Error: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp()を解決する

#⇣なんやねんお前
```console

Error: No Firebase App '[DEFAULT]' has been created - call Firebase App.initializeApp()

```
#これで解決

```javascript
firebase.initializeApp(config);
```

firebaseの初期化を忘れてた。

#追記
configのところは自分の環境によって変えてね...
Rubyワンライナーメモ : 文字列の先頭を小文字にする

1ライナーで完結する書き方をやってる人が検索で出てこなかったので。
tapとsub!を組み合わせると出来ます。

```ruby:downcase.rb
"HogeHoge".tap{ |s| s.sub!(s[0], s[0].downcase) }
```
Cloud Functions for Firebase でCloud Vision APIを叩く

メモとして残しておく。
コピペで動くようにしておきました。

事前にGCPや、Firebaseの設定などをすましてる前提です。

まずは `package.json` の `dependencies` 下記にコピペします。

```json
"dependencies": {
    "@google-cloud/storage": "^3.0.3",
    "@google-cloud/vision": "^1.1.3",
    "firebase-admin": "^7.0.0",
    "firebase-functions": "^3.2.0",
  },
```

コピペしたら下記のコマンドを実行

```
npm install
```

そしたら `index.js` を編集します。コピペで動くはずです。
下記の実装ではFirebase Storageにファイルがアップロードされたことをトリガーにしています。別のトリガーの場合は適宜変更してください。

```javascript

import * as functions from "firebase-functions";
import * as admin from "firebase-admin";
admin.initializeApp(functions.config().firebase);
const vision = require("@google-cloud/vision").v1p1beta1;
const client = new vision.ImageAnnotatorClient();

// 画像のリサイズ処理
export const detectImage = functions.storage
  .object()
  .onFinalize(async object => {
    // ファイルパスの取得
    const filePath = `gs://${object.bucket}/${object.name}`;
    // ContentTypeの取得
    const contentType = object.contentType;

    if (filePath == null) return null;
    if (contentType == null) return null;

    // 画像以外だったらなにもしない
    if (!contentType.startsWith("image/")) {
      console.log("これは画像ではありません");
      return;
    }

    if (typeof filePath === "undefined") {
      console.log("filePath undefined");
      return;
    }

    return (async () => {
      const data = await client.labelDetection(filePath);
      console.log(data[0].labelAnnotations);
    })()
      .then(() => console.log("success"))
      .catch(err => console.log("エラーが発生しました" + err));
  });


```

## 参考

https://github.com/GoogleCloudPlatform/nodejs-docs-samples/blob/master/functions/imagemagick/index.js
「ソースコード全部読まなきゃ病」と闘う方法

「OSS読んでパターンの勉強したくて、毎回挑戦してるんだけど、いっつも諦めるんだよね...。」とか「会社で新しいソースコード読む事になったんだけど量が多くて大変だよね...。」みたいな事をよく思っていた自分のような方を対象に、こうすればいいんじゃい？と自分が思ったことをまとめます。

# 最大の恐怖「全部読まないといけない」
自分のOSSリーディング活動を邪魔している感情や考えが、まずこの**「全部読まないといけない病」にあることを自覚しました。**「すごい人はOSSを毎日のように読んでる」「フレームワークの中身を全て知っている」こんな決めつけが根っこにありました。

それでGitHubでアルファベット順にならぶコードを上から順番に読もうとして途中で飽きたり挫けたり...。あるあるじゃないでしょうか？

ただよく考えるとそれって意味ある？という疑問が湧きました。
例えば小説や本などは最初のページから最後のページまでの時系列データなので、順番に読む事に意味はあります。ただ、ソースコードに関しては時系列データじゃないよね？と。

なのでいくつか読み方を考えてみました。

# 対処法1 「Facadeを読む」
これは自分が上記の問題に対して一番初めに試してみたものなのですが、かなりの効果を感じています。 `~Manager` や、OSS利用の窓口になっているAPIって必ずありますよね？まずはそこから読み始めます。一番使う回数の多いところ周辺から徐々に理解をしていく方式に切り替えると、繋がりが分かりやすく意味ある読み方ができそうです。

# 対処法2 「必要なところだけ読む」
対処法1を理解していても「全部理解しなきゃ」と思っていると、どんどん読み込もうとしてしまって時間がかかったり嫌になったりします。なので、今知りたい知識が理解できたらそれより深くは読まないとか、利用していて分からないクラスや疑問が止まらない対象が出てきたら読む。という進め方が出来そうです。

# 対処法3 「時間を決めて読む」
「いつまでも読める」と考えると、どうしても必要のないコードを読んでしまいます。なので「このコードを読む時間は30分までと決める！この時間内で読むしかない」とすれば、コードを読む優先度を考えて、優先度の高いものから考えて読むでしょう。それを繰り返していくと良いと思います。

実際、自分の抱えているコードすべてをきちんと読もうとすると、読むだけで５年かかることもあります。業務でそればかりするわけにもいかないので、読みきれませんね。関連する部分（＋アルファ）だけ集中的に読みます。

presented by @7of9 さん

# 対処法4 「古いバージョンから読む」
OSSだと古いバージョンほど機能が少なく、コアな機能しか実装されていないので、そのバージョンやコミットを読んでいくことで短い時間で効率良くコア部分に詳しくなる事ができます。

アンチパターンとして新しいバージョンで破壊的変更が行われている場合で、せっかく理解したのに...。という事が起こり得ます。

presented by @pCYSl5EDgo さん

# 終わりに
「全部読まなきゃ！」→諦めた。成果ゼロ。
よりも
「窓口だけ読んでみよう！」→3ファイル読めた。
の方が健全に進捗が出せていると思うので、「〜できないと〜する価値がない」みたいな考え方はやめて、まず読めるコードから読んでいって、いつのまにか全部読んでた。くらいで良いのではないかと思っています。
ROS2でpythonのサンプルを動かす

# 環境
公式[ホムペ](https://index.ros.org/doc/ros2/Installation/)を参考にインストールした．

|        |       バージョン|
|:-----------------|:---------------------:||
| OS|            Linux(Ubuntu bionic(18.04))|
| ROSディストリビューション|              ROS2 Dashing Diademata|

# 事前準備
ROS2のコマンドを使えるように事前に環境セットアップします．
以下のコマンドをターミナルが立ち上がる度に入力します．

```
source /opt/ros/dashing/setup.bash
```

ただし毎回入力するのがめんどくさい場合は`~/.bashrc`の末尾に追加して自動化します．通常はこちらです．

```
echo "source /opt/ros/dashing/setup.bash" >> ~/.bashrc
```

これで`~/.bashrc`の中にコマンドが追加されたので，ターミナルが立ち上がる度に自動実行されます．
※ただし自分の環境(screen+zsh)ではターミナルの立ち上げが若干遅くなったのでどちらかを選ぶことをオススメします．


# まずは基本から
pythonのサンプルを動かすところまで [^1].

ROS2を実行したいフォルダを作ります.

``` 
mkdir -p ~/ros2_example_ws/src 
cd ~/ros2_example_ws 
```

次にgitからpythonのサンプルプログラムをDL

``` 
git clone https://github.com/ros2/examples src/examples 
```

自分のインストールしたディストリビューションに合わせるためにgit checkoutを行います

```
cd ~/ros2_example_ws/src/examples/
git checkout $ROS_DISTRO
cd ~/ros2_example_ws
```
次にcolconコマンドでコンパイルをします．ros1で言うところのcatkin_makeです．

``` 
colcon build --symlink-install 
```

colconが完了すると`~ros2_example_ws/install`に出力されます．
実行するためにpathを通します．
ワークスペース`ros2_example_ws`の中で以下を実行．

```
 . install/setup.bash
```

次に実際にプログラムを実行します．

subscriberを実行．

```subscriber.
ros2 run examples_rclcpp_minimal_subscriber subscriber_member_function
```

新しくターミナルを立ち上げてtalkerを実行.
※pathが通っていなかったら実行できないので同じ手順でpathを通しましょう．

```talker.
ros2 run examples_rclcpp_minimal_publisher publisher_member_function
```

これでtalkerが発信した情報をsubscribeが受け取って表示します．

# 終わりに
ROS2でpythonのサンプルを動かすところまで書きました．
次は自分で作成したpythonプログラムを追加して動かす方法と注意点です[^2]．

[^1]: https://index.ros.org/doc/ros2/Tutorials/Colcon-Tutorial/
[^2]: https://qiita.com/inomu/items/5bd47b4d223434d57615
ethers.js で SHA-256 ハッシュ値を取得

ethers.js で SHA-256 ハッシュ値を取得するサンプルコードです。

```js
// ethers.js をインポート
const ethers = require('ethers')

// ハッシュ値を得たいメッセージ
let message = "piyo"

// メッセージのバイト列を取得
let messageBytes = ethers.utils.toUtf8Bytes(message)

// メッセージの SHA-256 ハッシュ値を取得
let hash = ethers.utils.sha256(messageBytes)
console.log(hash)
```

#Ref.
- https://docs.ethers.io/ethers.js/html/api-utils.html?highlight=sha256#hash-functions
- https://scrapbox.io/a42/ethers.js_で_SHA-256_ハッシュ値を取得
【実験】max-widthがmin-widthよりも小さいとどうなるのか？

## 【実験】max-widthがmin-widthよりも小さいとどうなるのか？
タイトルの通りです。APIの公式解説サイトはこちらです。
試してみました。
どうやら、この矛盾した設定をした場合はmin-widthが優先されるようです。（MacのChromeで確認）

この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
RailsのMVCをまとめてみる

#はじめに
RailsはMVCアーキテクチャを採用しています。
MVCアーキテクチャに基づき、Railsはどのような流れで処理を行っているのかを確認していこうと思います。

#注意すること
調べていて分かったことなのですが、どうやら
**RailsはMVCではない**
のだそうです。正しくは
**RailsはMVC2である**
そうです。
(Model2MVCやModel2など、他にも呼び方があるみたいです)

「Rails MVC」と「MVC」で検索して理解を深めようとした結果、
**分かったような分かっていないような**
というモヤモヤした気持ちになった方もいるのではないでしょうか。

今回はMVCとMVC2の違いについてはまとめませんが、
**MVC？あぁRailsのやつだよね？**
という理解は厳密には間違っているそうですので、先に記述しておきます。

#RailsのMVC
MVCは次の3つの要素を指します。

* Model(モデル)
* View(ビュー)
* Controller(コントローラー)

![Rails_MVC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471978/ee574e21-d151-2b42-5cff-cacb79fa64ce.png)

それぞれの役割は次のようになります。
##Model
データベースを管理し、検索・挿入・更新・削除などを行います。
##View
Webページ上でどのように表示するかが定義されています。
##Controller
ModelとViewに指示を出します。
Modelから必要な情報を取得し、それらをもとにViewにWebページを構築させます。

また、RailsではControllerでの処理をアクションと呼び、
複数定義することができます。

##処理の流れ
Model・Controller・Viewは次の順番で処理されます。

![Rails_MVC_Order.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471978/19814bdb-b413-c8f5-fd1d-0b5efd81e8a7.png)

もう少し具体的に処理を書きだすと

1. 指定されたControllerの、指定されたアクションが起動
2. ControllerはModelを通してデータベースとやりとりする
3. データベースから取得したデータを元に、ControllerはViewにWebページを構築させる
4. Viewの内容をレスポンスとして返す

といった流れとなります。
#ルーティングについて
routes.rbファイルに定義された通り、
リクエストされたURLとControllerのアクションを結びつけます。
地図みたいなものですね。
![MVC_URL_Routes_MVC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471978/5057e999-05a7-5e2e-ce2a-64cc4e7d45e1.png)
#おわりに
各ファイルの役割や処理の流れが整理できていなかったのですが、
投稿するためにまとめることで多少理解できたかなと思います。
コーディングしているときに迷わないよう、常に処理を意識しながら作業していこうと思います。
Joblibの様々な便利機能を把握する

# Joblibとは
[**Joblib**](https://joblib.readthedocs.io/en/latest/)は、並列処理などいろんな便利機能を寄せ集めたようなPythonライブラリです。
Joblibを使うことで

+ **並列化**
+ **メモ化**
+ **直列化**〔シリアライズ〕

などを簡単に実装でき、特に**Pythonコードの高速化**に役立ちます。

Joblibは一般に並列化に使われることが多いようですが、[ドキュメント](https://joblib.readthedocs.io/en/latest/)を覗いてみると他にも便利な機能が色々とまとめられていたので、本記事ではその辺を整理してみました。

なお、Joblibは**pip**でインストールできます。

```bash
pip install joblib
```

# 並列化
下記の例では平方根を返す関数（`math.sqrt`）を**並列化**しています。

```python
from joblib import Parallel, delayed
from math import sqrt

out = Parallel(n_jobs=2)(delayed(sqrt)(i) for i in range(100))
print(out)

# [0.0, 1.0, 1.4142135623730951, 1.7320508075688772, 2.0, 2.23606797749979, ...
```

ポイントは、`n_jobs=2`でコア数を指定しているところです。
`n_jobs=1`でコア数が1、`n_jobs=2`でコア数が2になります。
もちろん、**コア数が多ければ多いほど高速になります。**
またコア数の上限は環境に依りますが、`n_jobs=-1`とすることで自動的に上限のコア数がセットされます。

# メモ化
下記の例では平方根を返す関数（`math.sqrt`）を**メモ化**（[Wikipedia](https://ja.wikipedia.org/wiki/メモ化)）しています。

```python
from joblib import Memory
import math

cachedir = "./memory_cache"
memory = Memory(cachedir, verbose=0)

@memory.cache
def calc(x):
     print("RUNNING......")
     return math.sqrt(x)

print(calc(2))
print(calc(2))
print(calc(5))

# RUNNING......
# 1.41421356237
# 1.41421356237
# RUNNING......
# 1.73205080757
```

ポイントは、関数を`@memory.cache`でデコレートしているところです。
デコレートした関数の出力結果に注目してみましょう。

1回目の実行では、引数`2`を与えて通常通り計算が行われています。

しかし、同じ引数（`2`）を与えた2回目の実行では、関数の中で**計算は行われず計算結果だけが返ってきている**ことがわかります。

そして、1回目や2回目と異なる引数（`5`）を与えた3回目の実行では、今度は関数の中で計算が行われた上で計算結果が返ってきています。

このような挙動を特定の関数に与えるテクニックを**メモ化**と言います。
重複する引数による関数の再計算を防ぐことで、特に同じ引数が頻出する場面（[フィボナッチ数列](https://ja.wikipedia.org/wiki/フィボナッチ数)など）で高速化が期待できます。

# 直列化 〔シリアライズ〕
*※ここでの直列化はオブジェクトのバイナリ列への変換を指します。*

下記の例では平方根を返す関数（`numpy.sqrt`）が返したリストを**直列化**（[Wikipedia](https://ja.wikipedia.org/wiki/シリアライズ)）しています。


```python
import joblib
import numpy as np

out = np.sqrt(np.arange(1024)) 
filename = "./pydata"

with open(filename, "wb") as f:  
    joblib.dump(out, f, compress=3)
    
with open(filename, "rb") as f:  
    loaded = joblib.load(f)

print(loaded)

# [  0.           1.           1.41421356 ...,  31.95309062  31.96873473  31.98437118]
```

流れとしては、

1. 関数（`numpy.sqrt`）がリストを出力する（もちろん関数は何でもよい）
2. `joblib.dump`を使ってリストを圧縮して`./pydata`に保存する（`compress`で圧縮率の変更が可能）
3. `joblib.load`を使って圧縮データから元のリストを復元する

ということを行なっています。

# まとめ
|項目|利用|備考|
|:--|:--|:--|
|並列化|`joblib.Parallel`|同時に複数の演算処理を実行する|
|メモ化|`joblib.Memory`|計算結果を一時保存し、重複する引数による関数の再計算を防ぐ|
|直列化|`joblib.dump`,`joblib.load`|大容量の計算結果を圧縮して保存する（取り出す）|

***Joblibで素敵なPythonライフを！***

# 参考
- [Joblib: running Python functions as pipeline jobs — joblib 0.13.2 documentation](https://joblib.readthedocs.io/en/latest/)（公式の英語ページ）
- [GitHub - joblib/joblib: Computing with Python functions.](https://github.com/joblib/joblib)（GitHub）
- [私が選ぶ2015年の”新しい”Pythonモジュール トップ5 | POSTD](https://postd.cc/my-top-5-new-python-modules-of-2015/)
Nature Remo 不安定→安定へ

#備忘録
Wi-Fiルータ　WF800HP(ブリッジ接続）からWG1200HS3(ブリッジ接続）に交換したとたんに
NatureRemoが赤点滅する回数が増えた。
WF800HP(ブリッジ接続）の時は安定していたのに～。
朝6:30　起きたらNature Remo赤点滅してる～。リセット何回もやってもういや~。。。
Amazonの評価が悪い投稿ははブリッジ接続でDHCPなのからか。。。。
Nature Remoとかこの類の機種は発展途上だと思っている。他の機種はわかりませんが。
#Wi-Fiルータ環境
中継器　Aterm　WG1200HS3(ブリッジ接続）
Gatewayルータ　NTT RT500KI
ブリッジ接続ではNature Remoの固定アドレス設定はできない。
WG1200HS3　での　DHCP固定割当設定はメニューに出てこない。
そうかGatewayルータでDHCP固定IPアドレス設定をするのか。
アホだね。僕。
##2019-07-30
###
GatewayルータでDHCP固定IPアドレス設定してみました。
ついでに　GoogleHomeもね。
　ラズパイでしゃべらせる設定で停電とかでＩＰアドレス変わると設定しなおしだもんね。
Nature Remo安定するかな。。。。
##2019-07-31
だめだ～
###朝6:30
Nature Remo赤点滅してる～。
再設定で復旧。
###18:40帰宅
Nature Remo赤点滅
2.4Ghz帯域を1Ch固定としてみた。
とりあえずWi-Fiルータ再起動。でNature Remo復旧。
また様子見。めんどくさ～。
##2019-08-01
朝ＮＧなので　元に戻す。
リセットすると復旧できる。改善したのか。
Nature Remoの設置位置を少し高くしてみる。
###20:00
帰宅するとエラーになっていない。
様子見。
##2019-08-02
朝、帰宅共にエラーになっていない。
設置位置、DHCP固定IPアドレス設定がキモかもね。
話題の粛清ソートアルゴリズム「スターリンソート」をPythonで実装した

# スターリンソートとは
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ソートされていない要素を粛清することでO(N)でソートできるスターリンソートとかいうのを見て爆笑してる</p>&mdash; やんぎん (@4116You) <a href="https://twitter.com/4116You/status/1155619860027547648?ref_src=twsrc%5Etfw">July 28, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

今話題の計算量が $O(n)$ で済む驚異のソートアルゴリズム、スターリンソートをご存知でしょうか。

中身はいたってシンプルで、ソートされていない要素を削除（粛清）して、強引に昇順リストを生成します。
例えば、`[1, 2, 1, 1, 4, 3, 9]`というリストをスターリンソートすると`[1, 2, 4, 9]`になります。（1, 1, 3が粛清されました）

**粛清**というパワーワードがポイントですね。


既に先人達が色々な言語で実装しておりますが、知らない言語しかなかったのでこの度Pythonで実装してみました。

# 先駆者達
[計算量O(n)の画期的なソートアルゴリズムであるスターリンソートをHaskell で実装してみた #Haskell](https://qiita.com/Tatsuki-I/items/380d6bd06515b872b2b2)
[計算量O(n)で噂のスターリンソートを実装してみた](https://qiita.com/MeilCli/items/721526d716851e92192a)
[[Rust] スターリンソートと PartialOrd](https://qiita.com/osanshouo/items/1d4f56d93ee8ac8bdf55)
[rubyでスターリンソートをやってみた（ブロック渡しも可能）](https://qiita.com/haru_pad/items/1598690e1105f3e33389)
# Pythonで実装
コード

```python
data = [1, 2, 1, 1, 4, 3, 9]
purge = [] #purge : [動詞]〜を粛清する

# 粛清すべき要素のインデックスを探す
tmp = data[0] - 1
for i, e in enumerate(data):
    if e < tmp:
        purge.append(i)
    else:
        tmp = e

# Let's 粛清!!
for i, e in enumerate(purge):
    data.pop(e - i)

print(data)
```

標準出力

```terminal
[1, 2, 4, 9]
```

`1 1 3`が粛清され、見事に昇順ソートされましたね。
ルールに従わない要素は消す、なんとも強引なアルゴリズムです。

よいこのみなさんは他の正しいソートアルゴリズムを使いましょう。

# 追記
`pop()`は粛清感が出るけど計算量が $O(n)$ じゃなくなる、とのコメント多数頂いたので`pop()`を使わない実装を考えました。

```python
data = [1, 2, 1, 1, 4, 3, 9]
purged_data = [] #purge : [動詞]〜を粛清する
tmp = data[0] - 1

for i, e in enumerate(data):
    if tmp <= e:
        purged_data.append(e)
        tmp = e
print(purged_data)
```

```terminal
[1, 2, 4, 9]
```
粛清感が薄れますが、このほうがすっきりしますね。
計算量も減りますし。

（ていうか粛清感ってなんだよ）
LVMでボリューム拡張手順（虎の巻）



ボリューム拡張が必要になってくると思うのでその覚書

基本的にCentOS系のOSで検証をしているけど、Debianでも使えると思う

前提条件：VirtualBoxのHDDがVDI形式であること

vmdkだと可変ではないので拡張できない、そういった場合は別のHDDを作ってそれをアタッチメントすればよい

以下はVirtualBoxで拡張後にゲストOS内で認識させる方法

fdiskを実行して新規パーティションを立てる

ブロックサイズは認識されているので基本的にはおおもとの/dev/sdaを参照する。
/dev/sdaは

```
[root@localhost ~]# fdisk /dev/sda

WARNING: DOS-compatible mode is deprecated. It&#039;s strongly recommended to
         switch off the mode (command &#039;c&#039;) and change display units to
         sectors (command &#039;u&#039;).

Command (m for help): p
Disk /dev/sda: 33.3 GB, 33263140864 bytes　★ ここが　現時点のサイズと違う状態であれば使っていない空間がある
255 heads, 63 sectors/track, 4044 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00070a84

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          64      512000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              64        1306     9972736   8e  Linux LVM


パーティションを新規に作成するので&#034;n&#034;を選択して作成

Command (m for help): n
Command action
   e   extended
   p   primary partition (1-4)　★　基本はこっちを選択する
p


今回はパーティション3を作成する。
限定的な容量追加など特別の事情がない限り後はデフォルトでOK

Partition number (1-4): 3
First cylinder (1306-4044, default 1306):
Using default value 1306
Last cylinder, +cylinders or +size{K,M,G} (1306-4044, default 4044):
Using default value 4044

確認のため&#034;p&#034;で確認をする。

Command (m for help): p

Disk /dev/sda: 33.3 GB, 33263140864 bytes
255 heads, 63 sectors/track, 4044 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00070a84

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          64      512000   83  Linux
Partition 1 does not end on cylinder boundary.
/dev/sda2              64        1306     9972736   8e  Linux LVM
/dev/sda3            1306        4044    21997670   83  Linux　★ここが追加されていればOK
```
Railsチュートリアル（第1章、第2章）

# はじめに
Railsチュートリアルの第1章と第2章を終わらせました。
ポイントだけまとめます。

# 環境構築
環境構築は昨日記事を書きました。
[DockerでRailsの環境構築](https://qiita.com/minuro/items/1fe384354168a78d64ec)

# Herokuへのデプロイ
まず、Herokuのアカウントを作成します。
https://signup.heroku.com/
<img width="956" alt="heroku作成.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/311225/8a46332c-454e-d6b4-72c8-346ea38393fe.png">
上記のページで必要事項を入力して、アカウントを作成します。

次にHerokuのインストールをします。
以下のサイトに書いてあるコマンドを実行し、Homebrewを使用してHerokuをインストールします。
https://devcenter.heroku.com/articles/heroku-cli

```
brew tap heroku/brew && brew install heroku
```
以下のコマンドでバージョンが表示されたら成功です。

```
heroku --version
```
次に以下のコマンドを実行して、herokuのログインとssh鍵の登録を行います。
herokuに登録したメールアドレスとパスワードを聞かれます。

```
heroku login --interactive
heroku keys:add
```
次に、Heroku上のアプリケーションを作成します。

```
heroku create
```
最後にHerokuにリポジトリをプッシュしてデプロイ完了です。
gitでバージョン管理している必要があります。

```
git push heroku master
```

# scaffold
scaffoldはモデルとそれの作成/取得/更新/削除といった画面をまとめて作成してくれるものらしいです。
※私はDocker上で動かしているので、先頭に`docker-compose run web`をつけています。

```
rails generate scaffold "モデル名" "カラム名":"型"
```
その後、マイグレーションファイルを元にDB上のテーブルを作成します。
以下のコマンドで、まだマイグレーションされていないファイルをmigrateします。

```
rails db:migrate
```
これで`"ルート"/users`というパスにアクセスでき、追加などを行うことができます。

# validate
追加や編集時に入力内容のチェックを記述できます。
`/app/models/`配下の各モデルファイルに以下のように記述します。
チェックはカンマ区切りで追加できます。

```
validates "カラムのシンボル", "チェック内容"

# チェック例：最大値140文字
# length: {maximum: 140} 
```

# モデル同士の関連
あるモデルが複数のモデルを持っている場合は、`has_many`、ひとつのモデルに紐づく場合は`belongs_to`をモデルファイル内に記述します。

```
has_many: "モデルのシンボルの複数形"
belong_to: "モデルのシンボルの単数形"
```

# Herokuでのmigrate
Herokuにデプロイする場合は、プッシュ後に、migrateを実行しておきます。

```
heroku rails db:migrate
```
LeetCode / Convert Sorted Array to Binary Search Tree

（[ブログ記事](https://mhiro216.hatenablog.com/entry/2019/07/30/221740)からの転載）

[https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/]

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

Example:
<img width="607" alt="スクリーンショット 2019-07-30 8.38.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/7d1a5a0c-d000-e6c6-8566-1e7da8d43887.png">
<b>a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1</b>ということで、
<b>2つのsubtree間の深さに2以上の違いがないtree」</b>を作れと言われています。

#### 解答・解説

##### 解法1
<b>2つのsubtree間の深さも1より大きな違いがないようなtree</b>は色々考えられるわけですが、問題文にもあった下図のように、
<img width="83" alt="スクリーンショット 2019-07-30 20.29.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122973/3f79657b-b4b3-9bfb-3577-40c77afdc345.png">
（binarytreeライブラリで作ってみましたがイマイチですね。。。）

<b>大元のrootから左右に2本subtreeが出て、あとは1本しかsubtreeがないようなtreeを考え、2つのsubtreeの深さに2以上の違いがないtree</b>
を作るのがシンプルなアルゴリズムになります。より具体的には、
[-10, -3, 0, 5, 9] -> left: [-10, -3], root: 0, right: [5, 9]
のように、中央値をrootとし、中央値より前の値のリストをroot.leftに、中央値より後の値のリストをroot.rightとします。
そして、root.leftとroot.rightに対して同じ処理をする再帰的な構造にします。

```python
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution: 
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        if not nums:
            return None
        mid = len(nums) // 2
        root = TreeNode(nums[mid])
        root.left = self.sortedArrayToBST(nums[:mid])
        root.right = self.sortedArrayToBST(nums[mid+1:])

        return root
```

##### 解法2

Discussionを眺めていたら、リストのスライスはコストが高いということで、修正案がありました。

```python
class Solution: 
    def sortedArrayToBST(self, nums: List[int]) -> TreeNode:
        def convert(left, right):
            if left > right:
                return None
            mid = (left + right) // 2
            node = TreeNode(nums[mid])
            node.left = convert(left, mid - 1)
            node.right = convert(mid + 1, right)
            return node
        return convert(0, len(nums) - 1)
```

Python操作に関するコストは以下のページにまとまっています。

[https://wiki.python.org/moin/TimeComplexity:embed:cite]
Ubuntu 19.04でRedmineのプロジェクトへのメンバーの追加ができない件

Ubuntu19.04のRedmineで設定を始めて、プロジェクトにメンバーを追加しようとした段で詰まったので、備忘録として。

## プロジェクトの「設定」から「ユーザー」→「新しいメンバーの追加」としても何も出ない。

いや、「新しいメンバーの追加」をクリックしても何も出ないので、丸3日間くらい悩みましたよ。マヂで。

## 何気に「Ctrl+Button-2」したら出た

Redmine.jpで「[プロジェクトのメンバーを追加](http://redmine.jp/tech_note/first-step/admin/add-project-member/)」を調べる際に画像を見ていたら、「これって、モーダルダイアログが開いてるんじゃない？」って気がついた。しかし、ブラウザのポップアップブロックの設定をオフにしてみたりするも改善せず。
じゃぁ、何気に別ウィンドウ or タブで開いたらどうなるんだろうと「Ctrl+Button-2」を押すと、目的の割当画面が出るじゃないですか！！！！
それで、双方の操作時のログを改めて `/var/log/redmine/default/production.log` で調べてみると、動作しているスクリプトが異なっていました。

* 通常クリック: `members/new.js.erb`
* Ctrl-Button-2: `members/new.html.erb`

## 原因と思われるもの

じゃぁ、通常クリックでどんなことが起こっているのかと、「Ctrl-Shift-I」でChromeの開発者モードに入ってみると何やら「application.js」でエラーが発生していました。なんでも「zIndexは関数じゃねーよ」とお怒りのようで…。

## AdHoc (間に合わせって意味だけどね) な解決策

んでもって、以下のように修正したらとりあえず目的のモーダルダイアログがちゃんと開くようになりました。
でも、「Close」ボタンの上にテキストで「Close」って出てる。Why？
最後までちゃんと調べていないけど、もしかしたらjQuery.jsの仕様変更について行っていないのでしょうか。

```diff
--- /usr/share/redmine/public/javascripts/application.js.orig	2019-01-20 15:57:15.000000000 +0900
+++ /usr/share/redmine/public/javascripts/application.js	2019-07-30 20:37:21.826614150 +0900
@@ -426,7 +426,7 @@
   if (el.length === 0 || el.is(':visible')) {return;}
   if (!title) title = el.find('h3.title').text();
   // moves existing modals behind the transparent background
-  $(".modal").zIndex(99);
+  $(".modal").zIndex = 99;
   el.dialog({
     width: width,
     modal: true,
@@ -434,7 +434,7 @@
     dialogClass: 'modal',
     title: title
   }).on('dialogclose', function(){
-    $(".modal").zIndex(101);
+    $(".modal").zIndex = 101;
   });
   el.find("input[type=text], input[type=submit]").first().focus();
 }
```

`ubuntu-bug` でバグレポートを上げておいたけど、英語がメチャクチャなので伝わったかは？？？？
今回のパッチは「とりあえず」なので、適用は自己責任でお願いします。

## 11月1日追記

バグレポートの回答は (もっと前に頂いていましたが) UbuntuのパッケージのJQueryとRedmineでパッケージされているJQueryのバージョンが異なるというものでした。

言ってる間にUbuntu 19.10がリリースされましたが、この問題は間に合っていませんので再度パッチ当てが必要でした。
Codeforces #573C (1191C) Tokitsukaze and Discard Items

Codeforces #573C (1191C) Tokitsukaze and Discard Items
===

https://codeforces.com/contest/1191/problem/C

問題解読が難しい。この問題は以下のように言い換えられる。

```
- あなたは1からnのn個の数字を持っている
- この数字はk個ごとに区切られている。
- m個の特殊な数字を定義する。これをp1,p2,..,pmとする
- あなたは一番最初にある特殊な数字を消す。この際、同じ区切りにほかの特殊な数字があるならそれも消す。
- 数字を消した際、後ろの数字は前に詰められる
- 何回ですべての数字を消せるかを述べればよい
```

例の通りを考える。

```
1 2 3 4 5 | 6 7 8 9 10
n=10の時は5と6の間で区切られる。[3,5,7,10]がpの場合、
まず、3を消す。この際、同じ区切りに5がいるので、3,5を消す。
1 2 _ 4 _ | 6 7 8 9 10
となり消した_は詰められるので
1 2 4 6 7 | 8 9 10
となる。つぎに7を消す。
1 2 4 6 8 | 9 10
つぎに10を消す。
これによって3回で消せた
```

まず、制約を確認すると、nは10^18以下ということで極端に値が大きいため、シミュレーションでないことは自明。
mは10^5であるし、これが問題の主たるinputなので、これを走査して解くことが推定される。

以下のように考察した。

```
上記例で
[3,5,7,10]
のとき、一番最初にある数字から消すので、3が消えることは自明である。
次の数字も消せるかが関心である。本問ではk=5のため、1-5の間の数字は消せるため、消せることが分かる。
ここで2つの文字を消したため、次に[7,10]について、本来の位置から2つ前に詰まる = 減算されることが分かる。
つまり、[5,8]の位置にいる。
ここで、5を消すが、これは1つ目の区切りであるため、2つめの区切りにある8は消せない。
こうなると、[7]が残るため、2つめの区切りにある7(もともとは10)を消す。
```

と言い換えられる。
ただし、上記の例では例えば[7,10]を２つ減算して[5,8]として扱う(mapでsubする)と書いたが、
実際にこれを行うと、NlogNの時間がかかる。
しかし、ここまでで消した数offsetとみなすとうまくいく。(後述)

また、同じページにあるかの判定は

```
k個ごとにページが増加する本なのであれば、ある数aの所属するページはa - 1 / kである。
```

である。すなわち、上記例であれば、[7,10]をoffset から offset～offset + kまでの数字であるかを調べればよい。

実装例: 

```Python
n, m, k = map(int, input().split())
dat = list(map(int, input().split()))

res = 0
x = 0
# 特別な数を最後まで読み込む
while x < m :
    # 消す処理をする = resを++する
    res += 1
    # このターンで消した文字の数
    cutnum = 0
    # offsetは何ページ目であるか(0を1ページ目)を示す
    offset = (dat[x] - x - 1) // k
    # あるページにはk個しか数字がないことは自明であるから
    # 特別な数をk個処理する
    for i in range(k):
        # もし、特別な数がこれ以上ないなら抜ける
        if i+x >= m:
            break
        # 処理している特別な数が消せる対象化の判別
        # (dat[x + i] - x): 特別な数の数値 - これまでに消した数 = 今、実際にいる位置
        # (offset * k): 今のページの先頭の位置
        # k: 削除対象となる数
        if (dat[x + i] - x) - (offset * k) <= k:
            cutnum += 1
        else:
            # 消せなかった場合、特別な数のリストは昇順であるため、
            # ★これ、昇順という保証問題文にないですね（おそらく、HACK対象）
            # それ以降の数は消せないのでループを抜ける
            break
    # 今まで消した数に、今消した数を加算する
    x += cutnum
print(res)
```

https://codeforces.com/contest/1191/submission/57985947
Spring Boot + WireMockでNoHttpResponseException

# 事象
商用で動いているSpring BootのAppを改修した。
AppにはRestTemplateを使って他の連携先システムのREST APIを呼びにいく箇所があり、該当箇所を含む単体テストはWireMockでモックサーバを立てて実施していた。

改修に応じてテストを追加した所、既存のテストが突然
`NoHttpResponseException:[server] failed to respond`
などと例外を吐いてコケるようになった。

テストを単体で実行すると通り、通しで実行するとコケるという状態のため、テスト自体のミスでは無い模様。
ということで調査開始。

# 原因
WireMockへアクセスするAppのHttp Clientに、HttpURLConnectionを使用している場合に発生するバグらしい。


https://github.com/tomakehurst/wiremock/issues/97
SpringのRestTemplateも内部的にはHttpURLConnectionを使っているので該当。

# 対策
spring-cloud-contract-wiremockを使う。


https://github.com/tomakehurst/wiremock/issues/97
同issueに何種類かの対策が示されているので、お気に召すものを採用すれば良いと思われる。
一応の選定基準は以下の様な感じ。

* Spring Bootのバージョンを上げる or HttpClientを変える
商用で動いているAppなので、テストのために構成変更は基本NG→✕

* HttpClientのconnection reuseを無効化
設定場所が分からないし、Appの動作に影響出そう→✕

* spring-cloud-contract-wiremockの利用
テストのライブラリ変更だけで完結→○

spring-cloud-contract-wiremockは名前の通り内部でwireMockを利用しているので、テストコードの変更も最小限で済みました。
具体的には、サーバ設定の記法を変更して、既存のテスト用resourceのディレクトリを指定してやるだけ。
詳しい使い方は[公式](https://cloud.spring.io/spring-cloud-contract/multi/multi__spring_cloud_contract_wiremock.html)参照

```java:Configuration(before)
public class ExampleUnitTest {
    @Rule
    public WireMockRule wireMockRule = new WireMockRule(8080);
.... 
```
```java:Configuration(after)
@AutoConfigureWireMock(port = 8080, stubs = "classpath*:/META-INF/**/mappings/**/*.json")
public class ExampleUnitTest {
....
```
上記の通り、私の場合は`stubs = `で指定しているテスト用resourceのパスをよしなにしてやるだけで既存のテストコードがそのままパスするようになりました。
メモ：cakephp3でmigrateした後に`Exception: SQLSTATE[42S22]: Column not found: 1054`が・・・

#概要
cakephp3でmigrateした後はmodelsのキャッシュを削除しないと、キャッシュに残っているテーブル定義を参照し削除したはずのカラムでエラーが表示された。

```
Exception: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'ChannelCounters.rank_video_count' in 'field list' in [/var/www/html/youtuberank/vendor/cakephp/cakephp/src/Database/Statement/MysqlStatement.php, line 39]
```

#対応方法
以下のコマンドでmodelsのキャッシュを削除する。
`bin/cake cache clear _cake_model_`
AndroidのライブラリでminSdkVersionとtargetSdkVersionをライブラリで指定していない場合にアプリに勝手にパーミッションが追加される

# 概要
いろんな理由で社内などでライブラリを作ってmavenサーバーで公開して、それをアプリで参照したりとかってよくありますよね？
最初に結論ですが、そのときに**ライブラリ側でtargetSdkVersionが指定されていないと勝手に`READ_PHONE_STATE`と`READ_EXTERNAL_STORAGE`と`WRITE_EXTERNAL_STORAGE`が追加されてしまいます**
リリース前にGoogle Playで気づいたりすると再アップロードして確認などでリリースが翌日になったり、面倒なことになりがちです。(パーミッション変更がプルリクで検知できるともっといいですね)

# どう調べたか

通常、mafniestに追加されているPermissionはAndroidManifest.xmlにある`Merged Manfiest`という項目をみて、そこで右クリックして `Go to Declaration`することで、ライブラリを特定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/9da5db89-faca-c8bb-fe48-9d67d2884da1.png)

しかし、今回はメインのManfiest.xmlに飛ばされるのみで、原因がわかりませんでした。


[ドキュメント](https://developer.android.com/studio/build/manifest-merge#inspect_the_merged_manifest_and_find_conflicts)より、ビルド中に生成される `anifest-merger-[バリアント名]-report.txt`という項目を見れば良いことが分かったので、それを見てみました。
find . -name "manifest-merger*txt"
./app/build/outputs/logs/manifest-merger-[バリアント名]-report.txt

そこで以下のように吐き出されていました。
`reason: library has a targetSdkVersion < 4`

```
IMPLIED from .../src/main/AndroidManifest.xml:2:1-550:12 reason: library has a targetSdkVersion < 4
uses-permission#android.permission.READ_PHONE_STATE
IMPLIED from .../src/main/AndroidManifest.xml:2:1-550:12 reason: library has a targetSdkVersion < 4
uses-permission#android.permission.READ_EXTERNAL_STORAGE
IMPLIED from .../src/main/AndroidManifest.xml:2:1-550:12 reason: library requested WRITE_EXTERNAL_STORAGE
```

で以下のスタックオーバーフローにたどり着きました。

https://stackoverflow.com/questions/27792660/google-play-detecting-new-permissions-after-using-android-studio

# 原因はなにか
ここからはちょっと興味の話なのですが、なぜtargetSdkVersion < 4だとパーミッションが追加されるのでしょうか？
ここにドキュメントがあります
https://developer.android.com/reference/android/Manifest.permission.html#WRITE_EXTERNAL_STORAGE
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27388/1aa9b024-8da2-7f04-b2e2-5aea8bdfd652.png)

コードをたどっていくと、以下にたどり着きます。
https://android.googlesource.com/platform/tools/base/+/5521274ec220aea3f2b38d77dd34aeb463666da2

```
When importing libraries targeting past versions of the SDK with some
implied permissions (and possible other element types) into an
application targeting a newer SDK, we must explicitely declare those
implied permissions for the application to run correctly.
```

正しくアプリが動くために、新しいOSでは明示的に指定する必要があるパーミッションを全部追加しちゃうっぽいです。

そのパーミッションを追加するmergerのコードはここにあるようです
https://android.googlesource.com/platform/tools/base/+/2343d80f0fed536331249d0190294de0a9660358/build-system/manifest-merger/src/main/java/com/android/manifmerger/XmlDocument.java
imglabのビルド/使い方

#背景
アニメキャラクターの顔パーツの座標推定モデルを制作するにあたりデータセットを作成することになった．自分でアノテーションツールを作るのも手間なので既存の便利そうなimglabを使うことにした．

#imglab
物体検出や顔特徴の検出の記事を(個人的には)よく見かける機械学習のライブラリdlibがあるが，imglabはそれに付属している画像に対するアノテーションツールである．
一般的に，物体検出モデルであれば画像のどの領域に物体が写っているかをBoundingBoxで示した学習データが必要になる．道路や街の映像に対し車や人等を示したデータセットは大量に見つかるが，自分の作りたい用途向けに使える既存のデータセットがなければ自分でちまちまデータを作る必要がある．
ペイントで座標を確認してExcelにまとめるなんて方法では効率が悪すぎる．グラフィカルに位置を指定したり，次の画像にかんたんに飛べるなどの機能をもったアノテーションツールを使ったほうが現実的だ．

#ビルド(for Windows)
1. CMakeのインストール  
CMakeのページ(https://cmake.org )からダウンロードしてインストールする．
2. dlibの取得  
dlibのページ(http://dlib.net/ )からダウンロードして展開する．
3. ビルド

```Bash
cd dlib-19.17\tools\imglab\  
mkdir build && cd build  
'C:\Program Files\CMake\bin\cmake.exe' --build . --config Release  
make -j1  
cd Release  
```
※必要に応じてVisual Studio 2017のインストールが必要

#使い方
##基本的な使い方
1. アノテーションしたい画像を1つのフォルダにまとめる  
     
```Bash  
mkdir images  
cp -r <somewhere>\*.jpg ./images/  
```    
    
2. アノテーションデータが保存されるxmlファイルを作成する  
     
```Bash  
cd images  
..\imglab.exe -c <name>.xml .  
```    
    
3. imglabを起動して，実際にアノテートする

```Bash
..\imglab.exe <name>.xml
```
- Shiftを押しながらマウスボタンダウンしてアップすると矩形が指定できる
- 矩形周辺をダブルクリックすると選択状態に変わり，さらにDeleteを押すと矩形を除去できる
- 事前に「Next Label」テキストボックスにラベル名を入力しておくことで矩形にラベリングできる
    - 物体検出であれば「車」「人」などのラベル付け
- 学習に悪い作用をしそうな画像は「File」->「Remove Selected Images」で除去できる
- 必ず，最後に「File」->「Save」で保存する
- 画像領域内でCtrlを押しながらマウスホイール操作で拡大縮小ができる

##顔のパーツアノテーション向けの使い方
以下のようにimglabを起動することで，矩形に付随するパーツの位置を示すことができるようになる．

```Bash
..\imglab.exe <name>.xml --parts "LE RE LM RM AG"
```
矩形を選択した状態で，パーツ位置で右クリックを押すとパーツ名一覧が表示される．
一覧から1つ選択するとパーツ名に対応する点を示すことができる．
  
  
以下，必死にアノテーション作業を続けている途中経過．
そのうち，モデルの方の学習の話にとりかかれるはず...
![annotation_imglab.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/277756/725e88aa-c8bf-fe6f-74d6-28cfe8d0bc96.png)
VagrantでVScodeのRemote Developmentを使おう！

# はじめに

最近LaravelのでVagrantを用いたHomestead環境で作業をしており,remoteの作業環境としてVScode拡張機能のSSH FSを使用していました([この記事](https://qiita.com/hppRC/items/d713a7756c5a4b5a35ed)).

上記記事を投稿したところ,VScodeではもうremote developmentが使えるよ！と教えていただいたので,使ってみたいと思います.

実行環境
- macOS Mojave v10.14.5
- VScode v1.36.1


# クソ簡単

とりあえずVagrantを動かすディレクトリに移動します.
その後,vagrantでssh接続する際の設定をみてみます.

```
cd Homestead
vagrant ssh-config
```

上記コマンドのように,vagrantが動くところに行って`vagrant ssh-config`,というイメージで大丈夫です.

すると以下のようにvagrantでssh接続する際の設定が吐き出されます.

```
Host homestead
  HostName 127.0.0.1
  User vagrant
  Port [port.No]
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/[username]/Homestead/.vagrant/machines/homestead/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL
  ForwardAgent yes
```
vagrantならすでにリモート側にssh接続をする準備が整っているので,ホストのssh接続に関するconfigに設定を書き込んでおきます.

以下のコマンドを実行してください.
`vagrant ssh-config`で出力される結果を`~/.ssh/config`に書き込みます.

```
vagrant ssh-config >> ~/.ssh/config
```

設定は以上だけで終わりです！

あとはVScode(アップデートはしておいてください)で拡張機能の"Remote Development"を検索してください.

Remote Developmentをインストールしたら,画面左下に表示される`><`のようなマークをクリック,"Remote-SSH: Connect to Host"を選択して先ほど設定したリモートサーバの名前を選択します.

以上で接続終了です！

ローカルに入っている拡張機能はリモート側では導入されていないことがありますので,必要な拡張機能をインストールしてカスタマイズしていきましょう.

# まとめ
設定ファイルの記述がコマンド一発なのはCHO-RAKUですね.
各種intellisenseやemmet, git lensなどの拡張機能も使えてかなり開発が捗りそうです.
VScode, 最強！！
freezeされたオブジェクトとされていないオブジェクトのパフォーマンスの違い

[Run tests]ボタンを押すと自分の環境でテストできます。

https://jsperf.com/performance-frozen-object/74

「operations per second」ってことは１秒間にどれだけ計算できるかってことだから多い方が早いってことですね。
僕の環境ではfreezeされたオブジェクトの方が72%遅かったです。
環境は[Testing in Chrome 75.0.3770 / Windows 10 0.0.0]です。
連続する数字を配列に代入する方法 JavaScript版

`1, 2, 3, ...` みたいに連続する数字を使ってアルゴリズムを工夫したら、 `for` 文少なく書けますよね。

Ruby には `Array(1..3)` のように、 `..` 演算子を使うことで簡単に書けます。

JavaScript では簡単に書けないのでしょうか？

> ES2015での記述を使います。

# 初級編: `for` 文を使う

素直な発想をすると、 `for` 文が理解しやすくて忘れません。

```javascript
const seq = []

for (let i = 1; i <= 3; i++) {
  seq.push(i)
}

console.log(seq) // [ 1, 2, 3 ]
```

# 中級編: `function *` 文を使う

`async` / `await` がデファクトになって、ジェネレータ関数はあまり登場頂くことは少ないのですが、 `for` 文が登場するので分かりやすいですね。

```javascript
const seq = [...(function * () {
  for (let i = 1; i <= 3; i++) {
    yield i
  }
})()]

console.log(seq) // [ 1, 2, 3 ]
```

# 上級編: 空配列のインデックスを使う

配列を作成する `Array(n)` コンストラクタを呼び出すと、配列の要素数が `n` である空の配列を作成します。

```javascript
console.log(Array(3)) // [ <3 empty items> ]
```

この空配列のインデックスを繰り返すと、良い感じで連続する数字が取得できます。

```javascript
const seq = [...Array(3)].map((i, index) => index + 1)

console.log(seq) // [ 1, 2, 3 ]
```

または、 `Array.prototype.keys()` を使う方法があります。

```javascript
const seq = [...Array(3).keys()].map(i => i + 1)

console.log(seq) // [ 1, 2, 3 ]
```
ラグランジュの未定乗数法

#定理：ラグランジュの未定乗数法
$x,y$はここでは実数としておきます。ここでは2変数に限定して話を進めます。
1.$z=f(x,y)$の極値を与える点$(x,y)=(X,Y)$が存在するとします。
2.また、$x,y$は束縛条件$g(x,y)=0$を満たしているとします。
3.$(x,y)=(X,Y)$において$\frac{\partial g}{\partial y}\neq 0$とします。
このとき、$(x,y)=(X,Y)$において次が同時に成り立つような実数$\lambda$が存在します。

```math
\begin{align}
\frac{\partial f}{\partial x}-\lambda\frac{\partial g}{\partial x}&=0\\
\frac{\partial f}{\partial y}-\lambda\frac{\partial g}{\partial y}&=0\\
g(X,Y)&=0
\end{align}
```

#ラグランジュの未定乗数法を証明します。


1.は次のようにも言い換えられます。
1'.$(x,y)=(X,Y)$において、$f$の全微分は$df=0$をみたす。
また2.より$g$の全微分についても$dg=0$が恒等的に成り立ちます。
これらを以下のように書き直します。

```math
\begin{align}
df&=\frac{\partial f}{\partial x}dx+\frac{\partial f}{\partial y}dy =0 \\
dg&=\frac{\partial g}{\partial x}dx+\frac{\partial g}{\partial y}dy =0
\end{align}
```
前者は$(x,y)=(X,Y)$において成立し、後者は任意の$x,y$について成立します。
ここで後者を変形し、
$$
dy=-\frac{1}{\frac{\partial g}{\partial y}}\cdot\frac{\partial g}{\partial x}\cdot dx
$$
として前者の式に代入します。
$$
df=
\underline{
\bigg(
\frac{\partial f}{\partial x}-\frac{\frac{\partial f}{\partial y}}{\frac{\partial g}{\partial y}}\cdot \frac{\partial g}{\partial x}
\bigg)
}
\cdot dx
$$
すでに1'.で記したように、この式の下線部は$(x,y)=(X,Y)$で0となることから、
$$
\lambda=\frac{\frac{\partial f}{\partial y}}{\frac{\partial g}{\partial y}}
$$
とおくと題記の関係式が得られます。■
#ラグランジュの未定乗数法の使い方
$h(x,y)=f(x,y)-\lambda g(x,y)$とおき（$\lambda$は未定定数）、次の連立方程式を解きます。

```math
\begin{align}
\frac{\partial h}{\partial x}\bigg|_{x,y=X,Y}&=0 \\
\frac{\partial h}{\partial y}\bigg|_{x,y=X,Y}&=0 \\
g(X,Y)&=0
\end{align}
```
これを解いて定数$X,Y,\lambda$を求めれば、極値$f(X,Y)$が得られます。
#ラグランジュの未定乗数法を応用する。
高校数学の公式として知られる次の主張を証明しましょう。
##主張：点と直線の距離
直線$ax+by+c=0$と定点$(x_0,y_0)$の距離$d$は次で表される。
$$
d=\frac{|ax_0+by_0+c|}{\sqrt{a^2+b^2}}
$$
##証明
直線上の点$(x,y)$と定点$(x_0,y_0)$の距離$d$について、$d^2$を最小化します。
つまり、$g(x,y)=ax+by+c=0$において$d^2=f(x,y)=(x-x_0)^2+(y-y_0)^2$を最小化します。

$$h(x,y)=(x-x_0)^2+(y-y_0)^2-\lambda(ax+by+c)$$
とし、極値を与える点を$(x,y)=(X,Y)$とします。

```math
\begin{align}
\frac{\partial h}{\partial x}\bigg|_{x=X,y=Y}=2(X-x_0)-a\lambda &=0 \\
\frac{\partial h}{\partial y}\bigg|_{x=X,y=Y}=2(Y-y_0)-b\lambda &=0 \\ 
aX+bY+c&=0
\end{align}
```
を連立させましょう。まず$X,Y$を消去して
$$\lambda = \frac{-2(ax_0+by_0+c)}{a^2+b^2} $$
を得ます。これを$d^2$の式に代入して
$$ \min(d^2)=f(X,Y)= \frac{1}{4}\lambda^2(a^2+b^2)=\frac{(ax_0+by_0+c)^2}{a^2+b^2} $$
となり、正の平方根を取ることで題記の結果を得ます。■
###追記1
この応用例自体は高校数学の縛りでも導出できますが、こちらの方がシンプルであり
さらに応用が利きます。例えば、定点$(x_0,y_0)$と曲線$g(x,y)=0$の（最短）距離は
まったく同様の計算から導出できます。
###追記2 なぜ最小値なのか
ところで、ここで求めた$\min(d^2)$は極値であることは間違いありませんが、なぜ最小値となるのでしょうか？　これは$f(x,y)$をそれぞれ$x,y$で二階偏微分すると正の係数が残ることから、図形が下に凸であると言えるためです。
###追記3 身も蓋もありませんが……
ここまで書いていて気付いたのですが、ラグランジュの未定乗数法は束縛条件式$g(x,y)=0$が陰関数のときに有効な手法です。
この例では$ax+by+c=0$は$y=...$の形に表現できるので、そのまま$d^2$の式に代入して
$y$を消去すれば単純な一変数関数の微分問題に帰着できます。
（ただし二次式の展開がちょこちょこ入って面倒です）
コード で フローチャート シーケンス図 ガントチャート等 を 描く② ～mermaidで図を描く～

# 目的
- mermaidで実際に図形を描く方法をまとめる
※本記事ではmermaidを描く方法の紹介を主に行う。mermaidの出力する方法は「コード で シーケンス図等 を 描く ～mermaidの図を出力する～ mermaidまとめ③」で記載予定、記載後本記事にリンクを貼る予定。

# この記事のターゲット
- mermaidがどういうものかのイメージはついたが、どうやってコードを書くかわからない方
- mermaidで図を作ってみたくてうずうずしている方
- mermaidが気になっているが書き方次第で導入を迷っている方  
※mermaidの基本を知りたい方は[こちら](https://qiita.com/miriwo/items/babd1fc51adfa6bc60ad)

# 押さえるポイント
- svgファイルとして出力したいときとMarkdownファイルに図として挿入したい時とで記載する場所が異なる。
- svgファイルが欲しい時→mermaid公式の[Mermaid Live Editor](https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbkFbQ2hyaXN0bWFzXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuQiAtLT4gQ3tMZXQgbWUgdGhpbmt9XG5DIC0tPnxPbmV8IERbTGFwdG9wXVxuQyAtLT58VHdvfCBFW2lQaG9uZV1cbkMgLS0-fFRocmVlfCBGW2ZhOmZhLWNhciBDYXJdXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ)のCodeの部分に記載する。
- Markdownファイルに図として挿入したい時→コードブロックでmermaidを指定して記載する。

# サンプルコード
本記事の説明で使用するサンプルコードを記載する。  
※記載方法は別途記事でまとめる予定なので、今回は単純に下記のコードをテンプレートとしてコピーして使ってください。

``` mermaid
graph LR
    A[Hard edge] -->|Link text| B(Round edge)
    B --> C{Decision}
    C -->|One| D[Result one]
    C -->|Two| E[Result two]
```
↓プレビュー
![mermaid_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/01d0fb25-e29a-9334-f495-e4d306bc04c9.png)




# 書き方の例(svgファイルが欲しいとき)
1. 下記webサイトにアクセスする。下記にリンク先のスクリーンショットを貼る
[Mermaid Live Editor](https://mermaidjs.github.io/mermaid-live-editor/#/edit/eyJjb2RlIjoiZ3JhcGggVERcbkFbQ2hyaXN0bWFzXSAtLT58R2V0IG1vbmV5fCBCKEdvIHNob3BwaW5nKVxuQiAtLT4gQ3tMZXQgbWUgdGhpbmt9XG5DIC0tPnxPbmV8IERbTGFwdG9wXVxuQyAtLT58VHdvfCBFW2lQaG9uZV1cbkMgLS0-fFRocmVlfCBGW2ZhOmZhLWNhciBDYXJdXG4iLCJtZXJtYWlkIjp7InRoZW1lIjoiZGVmYXVsdCJ9fQ)

1. 下記画像の赤枠内のすでに記載されているコードを消し、前述したサンプルコードをコピーして貼り付ける
    ![mermaid_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7be0f280-4e40-1502-bb8b-2e2983e27c48.png)


1. 下記画像の青枠内ような図がプレビューに表示されれば記載完了
    ![mermaid_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/97c56621-56f3-0786-bc4f-11929b7d74ae.png)


# 書き方の例(Markdownファイルに図として挿入したいとき)
1. mermaidのプレビューを行うプラグイン`Markdown Previw Mermaid Support`をインストールする  
※プラグインのインストール方法は下記記事の日本語プラグインのインストール方法を参考にインストールをお願い致します。[Visual Studio Code 導入方法 VSCode ダウンロードから日本語化対応まで～画像付き導入解説～](https://qiita.com/miriwo/items/306769d90d910944e471)
1. 新規のMarkdownファイルを作成する。
Visual Studio CodeでのMarkdownファイルの作成方法は[こちら](https://qiita.com/miriwo/items/d75eee46d60e2e909b53)
1. コマンドブロックを作成する。
Markdown記法の基本は[こちら](https://qiita.com/miriwo/items/d75eee46d60e2e909b53)
1. コマンドブロック内に記載するコードを`mermaid`として設定する。
    ![mermaid_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/45fa227a-2125-522d-4838-6e722ee9dcc5.png)
1. コマンドブロック内に、前述したサンプルコードをコピーして貼り付け、赤矢印のプレビューボタンを押す。(筆者のプレビューボタンは二つあるがここでは気にしないこと)
    ![mermaid_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/35afbe2a-236c-985a-0bc2-ac1724734cd9.png)
1. 下記画像のような図がプレビューに表示されれば記載完了
    ![mermaid_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/3a538f7d-4408-1748-a997-049dcb7dbfb9.png)

    

# まとめ
- 図をsvgファイルとして取得したいときは[Mermaid Live Editor]()を利用する。
- 図をMarkdownファイルに乗せたいときはコマンドブロック内に記載する。
計算量O(n)の革命的なソートアルゴリズムをPHPでも

[計算量O(n)の画期的なソートアルゴリズムであるスターリンソートをHaskell で実装してみた #Haskell - Qiita](https://qiita.com/Tatsuki-I/items/380d6bd06515b872b2b2)

スターリンソートは当然、PHPでも簡単に実装することができます。 https://3v4l.org/g9bR2

```php
<?php

namespace stalin;

function sort(array $xs): array
{
    if (count($xs) <= 1) {
        return $xs;
    }
    
    $zs = $xs;
    $x = array_shift($zs);
    $y = array_shift($zs);
    
    if ($x <= $y) {
        return [$x, ...sort([$y, ...$zs])];
    }
    
    return sort([$x, ...$zs]);
}
```

動かしてみます。

```php
echo json_encode(\stalin\sort([1, 2, 1, 1, 4, 3, 9]));
// [1,2,4,9]
```

完璧ですね。 ~~PHP 7.3？ そんな古いバージョンのことは知りません~~

## 参考

 * [PHP: rfc:spread_operator_for_array](https://wiki.php.net/rfc/spread_operator_for_array)

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">スターリンソートが流行ってるらしいので… <a href="https://t.co/5sor37Dl2D">https://t.co/5sor37Dl2D</a></p>&mdash; tadsan.exe (@tadsan) <a href="https://twitter.com/tadsan/status/1156168496956338179?ref_src=twsrc%5Etfw">July 30, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>