OmniAICreator/Qiita-1.07M huggingface dataset:
マルコフ連鎖でレポートを自動作成してみた

# マルコフ連鎖とは
マルコフ連鎖を簡単に説明すると、前の時点の状態によって次の時点の状態が決まるというものです。
文章での具体例を見てみると、「おなかが」という言葉を見たら次に「空いた」が来そうな感じがしますよね。でもこれは「空いた」だけが正解ではなく、他にも「いっぱい」が来てもいいわけです。なので、これを確率で表すことを考えようと思います。
「おなかが」の次に続く言葉は、60%の確率で「空いた」、40%の確率で「いっぱい」になると仮定しましょう。この確率が遷移確率と呼ばれる次のそれぞれの状態の確率になります。
ここまでで簡単にですが、マルコフ連鎖について説明しました。ここら辺の話を詳しく知りたい方は [マルコフ連鎖の基本とコルモゴロフ方程式（高校数学の美しい物語）](https://mathtrain.jp/markovchain) 読んでみてください

ただし、文章がマルコフ連鎖ですべて説明できるかといわれたらそうではありません。例えば「僕は おなかが」ときたら「空いた」になる確率が高そうですが、「もう おなかが」ときたら「いっぱい」になる確率が高そうです。
これは文章は一つ前だけでなくもっと前の言葉にも依存しているということです。もっと言えば文脈なんてのにも依存します。しかし、この記事ではマルコフ連鎖を扱うのでここら辺は別の記事で紹介できればと思います。

# プログラム
今回作成したプログラムは自分で作成した報告書のデータを用いて新たなレポートを自動生成することを目的としました。ということでまずファイルを読み込んでいきます。

```python

import random
from janome.tokenizer import Tokenizer

with open("data.csv", "rt", encoding="utf-8_sig") as f:
    text_raws = f.read()
text_raws = text_raws.replace("\n", "@\n").split("\n")
```

data.csvを読み込みました。ここでは筆者の報告書のデータですがこれを外部に公開するのは多少まずい気がするので、githubに載せる際は適当な文章にしておきます。
読み込んでから置換しているのは文末のマークとして`@`を挿入したかったからです。

```python

text_lists = []
t = Tokenizer()
for text_raw in text_raws:
    text_list = []
    tokens = t.tokenize(text_raw, wakati=True)
    for token in tokens:
        text_list.append(token)
    text_lists.append(text_list)
```

Tokenizerを用いて形態素解析を行っていきます。形態素解析とは文章を単語に分かち書きするもので、例えば以下のようになります。


["僕はqiitaに記事を投稿する。"]
↓
['僕', 'は', 'qiita', 'に', '記事', 'を', '投稿', 'する', '。']

また、デフォルトでは品詞などの余分な情報も付記されてしまうのでパラメーターを`wakati=True`とすることで言葉だけを取り出しています。

```python

dic = {}
for text_list in text_lists:
    for i in range(len(text_list) - 1):
        if text_list[i] in dic:
            lists = dic[text_list[i]]
        else:
            lists = []
        lists.append(text_list[i + 1])
        dic[text_list[i]] = lists
```
ここでは、{"おなか":["すいた","いっぱい"]}のような辞書形式で前の言葉と次の言葉の対応関係を生成しています。

```python

word = input("最初の言葉を入力してください")
generate = word
word = list(t.tokenize(word, wakati=True))[-1]
limit = 10000
cnt = 0

while cnt < limit:
    try:
        word = random.choice(dic[word])
        if word == "@":
            break
    except:
        break
    cnt += 1
    generate += word
print(generate)
```
最初の言葉は入力してもらう形式にしました。そして入力した言葉を形態素解析して、その最後の単語からマルコフ連鎖をスタートさせます。遷移確率に関しては辞書の中からランダムに取り出すことで、出現回数に応じて比例させることにしています。
最後に文末のしるしとして導入した、`@`に到達するか無限ループしないように上限を決めて終了です。

以上で、プログラムは完成しました。実際に試してみましょう。

入力「今日は」
生成「今日はあまり満足の手順を集約して不自然な技術を踏まえることを利用することが遅れができた。」

入力「人」
生成「人に着けようともっと多くている将来に具体的大雨のデータの手順を技術支援という流れを見ることが必要と思った。」

ちょっと何言ってるかわかんないですね。冒頭でも述べましたが、言語は直前の言葉だけで決まるものではないため、「多く→て→いる」のように不自然なつながり方をしてしまいました。次回はLSTMなどを使ってより多くの過去の状態から最適な語を判断できるように改良したいと思います。
[ソースコードはこちら](https://github.com/eycjur/main/blob/master/machine_learning/NLP/markov.py)

# 参考文献
[Pythonでツイートを生成したい！ -マルコフ連鎖編-](https://qiita.com/h_tashiro/items/9d1c3dfece86b1848625)
[マルコフ連鎖の基本とコルモゴロフ方程式（高校数学の美しい物語）](https://mathtrain.jp/markovchain)
【PHP】シングルクォーテーションとダブルクォーテーションの違い

#プログラミング勉強日記
2020年9月7日
シングルクォーテーションもダブルクォーテーションも同じ場面で使用するけど、実際にどんな違いがあるのかをまとめる。

#特徴
　シングルクォーテーション：中身を文字列として扱う（変数や制御文字列もただの文字列として扱う）
　ダブルクォーテーション：中身を文字列として扱うが、変数や制御文字列はもともとの元として扱う
　
　シングルクォーテーションはすべて文字列として扱うので、シングルクォーテーションの方が速度が速い。

#速度における違い
　以下のようにただの文字列を出力する場合は、出力される内容は同じ。

```php:例
//ダブルクォーテーション
echo "Hello World";
echo '<br>';

//シングルクォーテーション
echo 'Hello World';
```

```:出力結果
Hello World
Hello World
```

　冒頭でも述べたが、動作処理速度は変数展開を用いる場合と変数の単純代入の場合、<font color=blue>シングルクォーテーション>>ダブルクォーテーション</font>である。(約1.2~2倍程度の差がある)
　しかし、文字列連結の場合と文字列比較の場合には速度の差はあまりない。


#動作における違い
　冒頭に変数や制御文字列の扱いが異なると記述したが、具体例を用いて説明する。制御文字列は、改行(`\n`)や空文字(`nil`)といった文字以外の特別な制御を実行するために用いられる文字。
　以下の具体例のように、シングルクォーテーションの場合は、制御文字列や変数がそのまま文字列として出力されている。ダブルクォーテーションはそのまま変数の中身や制御文字列として出力されている。

```php:例
$str = "World";

echo 'Hello $str';
echo "Hello $str";
echo "Hello {$str}";

echo 'Hello World\n';
echo "Hello World\n";
```

```:出力結果
Hello $str
Hello World
Hello World
Hello World\n
Hello World(表示上改行される)
```

#まとめ
　システムとしてはわずかではあるが、シングルクォーテーションを使用した方が早くなる。（大規模なシステムの場合は大きい差になる）
　基本的にはシングルクォーテーションを使用して、必要な個所(変数展開など)のときにダブルクォーテーションを使うと良い。

#参考文献
[【PHP】’（シングルクォーテーション）と”（ダブルクォーテーション）はどちらを使うべきか(PHP高速化)](https://pecopla.net/web-column/php-quote)
[ダブルクォーテーション、シングルクォーテーションの違い](http://www.24w.jp/study_contents.php?bid=php&iid=php&sid=string&cid=006)
AtCoder ABC177 A-Dをpythonで

#AtCoder ABC177 A-D問題までpythonで解いてみた.
AtCoder ABC177に参加したのでその記録として投稿しようと思います.
##A問題
高橋君は青木君と待ち合わせをしています。
待ち合わせ場所は高橋君の家からDメートル離れた地点であり、待ち合わせの時刻はT分後です。
高橋君は今から家を出発し、分速Sメートルで待ち合わせ場所までまっすぐ移動します。
待ち合わせに間に合うでしょうか？
###考えたこと
分速Sメートルで移動できる高橋君がT分で移動できる最大距離はS*Tです.
この値とDを比較すれば良いです.(不等号を間違えて1WA出しました())

```Python
d, t, s = map(int, input().split())
if s*t >= d:
    print("Yes")
else:
    print("No")
```
##B問題
2つの文字列S,Tが与えられます。TがSの部分文字列となるように、Sのいくつかの文字を書き換えます。
少なくとも何文字書き換える必要がありますか？
##考えたこと
len(S)>=len(T)より文字列TをSの中で動かしていき,その一致した最大文字数だけlen(T)から引いた値が答えとなります.

```Python
s = input()
t = input()
sl = len(s)
tl = len(t)

cnt = 0
ans = 0

for i in range(sl-tl+1):
    for j in range(tl):
        if t[j] == s[i+j]:
            cnt += 1
    
    ans = max(cnt, ans)#ans:一致した文字数の最大値
    cnt = 0

print(tl - ans)
```
##C問題
N個の整数A1,…,ANが与えられます。1≤i<j≤Nを満たす全ての組(i,j)についての Ai×Ajの和を mod(10**9+7)で求めてください。
##考えたこと
愚直にfor文を二重で回すとO(N^2)よりTLEになってしまう...
とりあえず書き出してみると以下のことが分かった.
ex.i=1, 2,...の時を考える.
sum = A1+A2+...ANとする.
i=1の時
A1 x A2 + A1 x A3 + A1 x A4 + ・・・・ + A1 x AN
= A1 x (sum - A1) 
i=2の時
A2 x A3 + A2 x A4 + A2 x A5 + ・・・・ + A2 x AN
= A2 x (sum - A1 - A2)
これならばO(N)で抑えられる.
これをPythonで実装すると,

```Python
n = int(input())
A = [0]+list(map(int, input().split()))
mod = 10**9 + 7
S = sum(A)
ans = 0

for i in range(1, n):
    ans += A[i]*(S-A[i])
    ans %= mod
    S -= A[i]

print(ans)
```
## D問題
人1から人NまでのN人の人がいます。「人Aiと人Biは友達である」という情報がM個与えられます。同じ情報が複数回与えられることもあります。
XとYが友達、かつ、YとZが友達ならば、XとZも友達です。また、M個の情報から導くことができない友達関係は存在しません。
悪の高橋君は、このN人をいくつかのグループに分け、全ての人について「同じグループの中に友達がいない」という状況を作ろうとしています。
最小でいくつのグループに分ければ良いでしょうか？
##考えたこと
UnionFindTreeで最大の集合の要素数を答えれば良いです.
最大の集合を分解しその１つ１つの要素にその他の集合の要素を割り振れば良いからです.
UnionFindTreeの解説はYoutubeでかつっぱさんの動画をみれば理解できると思います.
'Friend'という文字列が入った問題はUnionFind使いがちらしいです()

```Python
import sys
sys.setrecursionlimit(10 ** 9)

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.root = [-1]*(n+1)
        self.rank = [0]*(n+1)

    def find(self, x):#親となる要素を探索
        if self.root[x] < 0:
            return x
        else:
            self.root[x] = self.find(self.root[x])#再帰
            return self.root[x]

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return

        elif self.rank[x] > self.rank[y]:#深い木に連結
            self.root[x] += self.root[y]
            self.root[y] = x#yの親をxとする

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            if self.rank[x] == self.rank[y]:
                self.rank[y] += 1
    
    def issame(self, x, y):#x, yが同じ集合か判定
            return self.find(x) == self.find(y)

    
    def count(self, x):#要素の個数
        return (-1)*self.root[self.find(x)]

n, m = map(int, input().split())
uf = UnionFind(n)

for i in range(m):
    a, b = map(int, input().split())
    uf.unite(a, b)

ans = 0

for i in range(n):
    ans = max(ans, uf.count(i))

print(ans)
```
AtCoder ABC176 A-Dをpythonで

#AtCoder ABC176 A-D問題までpythonで解いてみた.
AtCoder ABC176に参加したのでその記録として投稿しようと思います.
##A問題
高橋君はたこ焼きが好きです。
たこ焼き器を使うと、1度に最大で X個のたこ焼きを作ることができます。
これにかかる時間は作る個数によらずT分です。N個のたこ焼きを作るためには何分必要ですか？
###考えたこと
N個のたこ焼きを作るためにX個作る作業を何回行う必要があるか考えました.
N%X == 0 の時に注意してN//Xを考えれば良いです.

```Python
n, x, t = map(int, input().split())

cnt = n//x

if n%x == 0:
    print(cnt*t)
else:
    cnt += 1
    print(cnt*t)
```
##B問題
整数Nが9の倍数であることと、Nを十進法で表したときの各桁の数の和が9の倍数であることは同値です。
Nが9の倍数であるか判定してください。
0 < N < 10**(200000)
###考えたこと
Nを文字列として受け取り,最上位から順に整数に変換しながら加えていけば良いです.
自分はNが非常に大きくなる可能性があるため逐次9で割っていたのですが,その必要はなかったみたいです.

```Python
n=input()

l = len(n)
mod = 9
judge = 0
for i in range(l):
    judge += int(n[i])
    judge %= mod

if judge == 0: print("Yes")
else: print("No")
```
##C問題
N人が1列に並んでおり、前からi番目の人の身長はA_iです。
それぞれの人の足元に、高さが0以上の踏み台を設置し、全ての人が次の条件を満たすようにしたいです。
条件：踏み台を込めて身長を比較したとき、自分より前に、自分より背の高い人が存在しない
この条件を満たす時の、踏み台の高さの合計の最小値を求めてください。
###考えたこと
難しく考えず,今現在注目している人の身長と次の人の身長を比較して
A_i < A_i+1 であれば踏み台は必要ではありません.
A_i >= A_i+1 の時後ろの人に踏み台が必要です.(身長差がない場合(A_i == A_i+1の時)は踏み台の高さは0です)
この時最小の踏み台の高さhは A_i - A_i+1 です.
A_i+1 = A_i と更新することを忘れずにi=1~n-1まで調べれば良いです.

```Python
n = int(input())
a = list(map(int, input().split()))

ans = 0

for i in range(n-1):
    if a[i] >= a[i+1]:
        ans += a[i] - a[i+1]
        a[i+1] = a[i]
    else:
        pass

print(ans)
```
##D問題
###考えたこと
道'.'続きのところはいくら移動してもコスト(魔法を使う回数)は0であるから,道続きな部分を集合にすれば良いと思った.
しかし,集合にしたところでコストを最小にする道の選び方をどのように実装すれば良いかわからなかった為コンテスト中にはAC出来なかった.

```Python
from collections import deque

H, W=map(int, input().split())
ch, cw=map(int, input().split())
dh, dw=map(int, input().split())
ch-=1 #0_indexedにする
cw-=1
dh-=1
dw-=1

grid=["0"]*H
for i in range(H):
    s=input()
    grid[i]=s

Inf=10**12
cost=[[Inf] * W for i in range(H)] #各マスへの移動コスト

walk=[(0, 1), (0, -1), (-1, 0), (1, 0)]
warp=[]

for i in range(-2, 3):
    for j in range(-2, 3):
        if i==0 and j==0:
            continue
        if (i, j) not in walk:
            warp.append((i, j))

q=deque()
cost[ch][cw]=0
q.append((ch, cw, 0))

while q:
    x, y, c=q.popleft()
    for dx, dy in walk: #移動A
        nx = x+dx
        ny = y+dy
        if 0<= nx < H and 0<= ny < W and grid[nx][ny]=="." and cost[nx][ny]>c:
            cost[nx][ny]=c
            q.appendleft((nx, ny, c)) #移動Aはコスト０,キューの先頭に追加
    
    for dx, dy in warp:#移動B
        nx = x+dx
        ny = y+dy
        if 0<= nx < H and 0<= ny < W and grid[nx][ny]=="." and cost[nx][ny]>c+1:
            cost[nx][ny]=c+1
            q.append((nx, ny, c+1)) #移動Bはコスト1,キューの最後尾に追加


if cost[dh][dw]==Inf:
    print(-1)
else:
    ans=cost[dh][dw]
    print(ans)
```
どうやら深さ優先探索(DFS)というアルゴリズムを用いるみたいだった.
典型的なアルゴリズムらしい()のでしっかりと理解し,次は実装出来るようにしておきたい.
やっていることは理解できるのですが,問題に適用するとなると急にハードルが上がる気がします😢
#### 参考
MA-R-CO NOTEさん
https://marco-note.net/
Pull Reaquest template　作成手順

# PRのテンプレート作成手順
チーム開発をしていて、必ず必要だと思ったので記事にしました。
今までなかった現場もあったので、あるととても良いです。
PRの内容がすっきりして、レビュー時にコミュニケーションコストが省けるし、何をやったのかcloseしてもわるのであるととても便利です。
無いチームは書くことをお勧めします。

## 作り方
``` sell 
$ cd 作りたいディレクトリに移動
$ mkdir .github
$ cd .github
$ touch pull_request_template.md
``` 
## テンプレ中身(Markdown）
### サンプル

``` md 

## PRの概要

<!-- このPRの概要を記入してください -->

## レビューして欲しい箇所

<!-- PRで特にレビューして欲しい箇所を記載してください -->

## Draftにした理由（WIPでも良いと思う）

<!-- Draftにした理由を記載してください -->

## スクリーンショット

<!-- 作業した箇所のスクリーンショットなどあれば貼ってください -->
Before       | After
------------- | -------------
<image src="" width="320">|<image src=""  width="320">


## その他

 <!-- レビュワーへの参考情報（実装上の懸念点や注意点などあれば記載） -->

```
上記の内容をマージすればマージ以降PRの入力欄にこの内容が反映されます。

## まとめ
上記意外にもチーム内でいろいろ決めて追加していくと良さそう。これはあくまでも参考程度の内容です。
SciPyでの境界点問題の取り扱い

衝撃マヌーバ (Impulsive Transfer) を伴う軌道の設計で生じる境界点問題（Boundary Value Problem）の取り扱いについて。狙い撃ち法（Shooting method: https://ja.wikipedia.org/wiki/%E7%8B%99%E3%81%84%E6%92%83%E3%81%A1%E6%B3%95
）では収束しない場合が多いため、```minimize()```や```root()```などの関数を使用する必要が出てくるので、メモ。

仮定する問題
======
拘束条件ベクトル $F$ と制御パラメータベクトル $X$ を考える

```math
\begin{align}
X =& \left[ x_1, x_2, \ldots, x_n \right]^T   
\\
F =& \left[ f_1, f_2, \ldots, f_m \right]^T
\end{align}
```

一般的に、$n=m$により問題の収束に必要となる。仮に衝撃マヌーバの場合、各方向の $\Delta V$ のコンポーネントや遷移時間 (time of flight) などが含まれる。具体的には、

```math
X = \left[ V_x, V_y, V_z, t_f \right]^T
```
などが考えられる。$F$と$X$からヤコビ行列 $DF$求めると

```math
DF = 
\begin{bmatrix}
    \dfrac{\partial f_1}{\partial x_1} & \cdots & \dfrac{\partial f_1}{\partial x_n} \\
    \vdots & \ddots & \vdots \\
    \dfrac{\partial f_m}{\partial x_1} & \cdots & \dfrac{\partial f_m}{\partial x_n} 
\end{bmatrix}
```

となる。狙い撃ち法を使用する場合、$X$は

```math
   X^{j+1} = X^j - \left[ DF(X^j) \right]^{-1} X^j
```

で求められる。



軌道設計に```scipy.optimize.root()```を使用する場合
===============

まず、求根アルゴリズムを用いて$F=0$を求める場合を考える。アルゴリズムの違いはあっても、この場合```root()```に与えられるインプットは狙い撃ち法を使う場合と近いため使用しやすい。



**参考**
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.minimize.html


軌道設計に```scipy.optimize.minimize()```を使用する場合
===============

次に、所謂最適化問題として取り扱う場合、constraint vector $F$ を拘束条件とし、例えば必要となる $\Delta V$ を最小化する問題として捉える。その場合、

```math
\begin{aligned}
\min _{X} ( \Delta V_x^2 + \Delta V_y^2 + \Delta V_z^2 )
\text { such that } \begin{aligned}
F(X) &=0 \\
\end{aligned} 
\end{aligned}
```
とする。




**参考**
https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.root.html#r9d4d7396324b-1
https://org-technology.com/posts/scipy-root-finding-multidimensional-functions.html
https://people.duke.edu/~ccc14/sta-663/MultivariateOptimizationAlgortihms.html
floatボタン（と言いつつimg）、2重送信防止

※ CSSで、.float-buttonを`display:none;`しておく。

1、画面描画完了後に表示
→ ロード前に押されると、画面描画後にリロードのような挙動になるため
2、二重送信防止


```javascript
// フロートボタンを画面描画後に有効化
$(window).on('load', function() {
    // フロートボタン表示：PC
    if (jQuery(window).width() > 768) {
        $('.float-button.pc').fadeIn();
    }else{
    // フロートボタン表示：SP
        $('.float-button.sp').fadeIn();
    }
});

$('.float-button').on('click', function() {
    var thisElement = $(this);

    // 2重クリック防止
    if(!thisElement.hasClass('clicked')){
        thisElement.addClass("clicked");
        var top = $('.top-box').offset().top;

        // PC表示の場合、ヘッダー分をマイナス
        if (jQuery(window).width() > 768) {
            var top = top - 103;
        }
        $('html, body').animate({scrollTop: top}, 1000, "swing", function(){
            thisElement.removeClass("clicked")
        });
    }
});
```
EC-CUBEのPurchaseFlowを極力自然にカスタマイズ

PurchaseFlowをカスタマイズしたい。
でも競合はできるだけ避けたい。

# 結論

``` php:app/Customize/Common/Collections/DecorativeArrayCollection.php
<?php

namespace Customize\Common\Collections;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;

class DecorativeArrayCollection extends ArrayCollection
{
    public function __construct($elements = [])
    {
        $elements = ($elements instanceof Collection)
            ? $elements->toArray()
            : $elements;

        parent::__construct($elements);
    }
}
```

``` yaml:app/config/eccube/packages/purchaseflow_customize.yaml
services:
    eccube.purchase.flow.shopping.item_validators_decorate:
        class: Customize\Common\Collections\DecorativeArrayCollection
        decorates: eccube.purchase.flow.shopping.item_validators
        arguments: ['@eccube.purchase.flow.shopping.item_validators_decorate.inner']
        calls:
            - [add, ['@Customize\Service\PurchaseFlow\Processor\CustomizeItemValidator']]

```


# 解説

## 本体ファイルの変更を避ける

- 本体ファイル(`app/config/eccube/packages/purchaseflow.yaml`)を変更するのは簡単だが、本体アップデートの追従の手間が増える。別ファイル(今回は`app/config/eccube/packages/purchaseflow_customize.yaml`)に記述する。
- 読み込み順は恐らくファイル名の昇順であるため、ファイル名に気をつける。(なんなら`z_purchaseflow.yaml`とかでもいい)

## ServiceをDecorateする

- Decorateの説明はこちら https://symfony.com/doc/3.4/service_container/service_decoration.html
- 要は、元となるサービスをコンストラクタに渡して別のサービスに置き換える機能。
- しかしDoctrineのCollectionのコンストラクタにはarrayしか渡せない。そのためCollectionを受け取れる独自のCollection(今回はDecorativeArrayCollection)が必要。
- `calls`にて追加したい機能を`add`する。

おしまい。

# 追記

## ある程度任意の順番にProcessorを挿入したい

こんな感じでいいんじゃないですか。しらんけど。

``` php:app/Customize/Common/Collections/DecorativeArrayCollection.php
<?php

namespace Customize\Common\Collections;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Eccube\Service\PurchaseFlow\Processor\PriceChangeValidator;

class DecorativeArrayCollection extends ArrayCollection
{
    public function __construct($processor, $elements = [])
    {
        $elements = ($elements instanceof Collection)
            ? $elements->toArray()
            : $elements;

        /* 最初に挿入する
        array_unshift($elements, $processor);
        */

        /* 任意のクラスの後に挿入する
        $newElements = [];
        $inserted = false;
        foreach ($elements as $element) {
            $newElements[] = $element;
            if ($element instanceof PriceChangeValidator) {
                $newElements[] = $processor;
            }
        }

        if (!$inserted) {
            // 任意のクラスが存在しなかった場合の処理
        }
        */

        parent::__construct($elements);
    }
}
```

``` yaml:app/config/eccube/packages/purchaseflow_customize.yaml
services:
    eccube.purchase.flow.shopping.item_validators_decorate:
        class: Customize\Common\Collections\DecorativeArrayCollection
        decorates: eccube.purchase.flow.shopping.item_validators
        arguments:
            - '@Customize\Service\PurchaseFlow\Processor\CustomizeItemValidator'
            - '@eccube.purchase.flow.shopping.item_validators_decorate.inner'

```
Linux MIntにおいてXserviceの無効化手法[備忘録]

はじめに
---
新しいPCにLinuxMintをインストールした際Geforceドライバがなかなかインストールできなかったため最終的な解決策を備忘録として記述。

コマンド
---

```shell
sudo service mdm stop
```

これを実行後にNvidia公式サイトから手に入れたドライバをインストールで無事入った。
【tips】Raspberry Pi OS の日本ミラーサーバー

## 公式からのDLがおそすぎる！
とお悩みの日本にお住まいのそこのあなた．
[こちら](http://ftp.jaist.ac.jp/pub/raspberrypi/raspios_armhf/images/)が Raspberry Pi OS のミラーサーバーです．
北陸先端科学技術大学院大学に感謝の意を表しながらダウンロードさせていただきましょう．
![Screenshot from 2020-09-07 18-12-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156659/47a2860e-4fe7-7403-efa0-694f8dae9a28.png)
Huawei Push Kit - ユーザーのアプリ認知度と通知を向上

#Push Kitとは
Huawei Push KitはHuaweiの開発者向けのメッセージサービスです。クラウドと端末とコミュニケーションチャネルを確立します。Push Kitを使うと、ユーザーへ最新のメッセージが送信できます。これにより、開発者はユーザーとのクロスな関係を維持し、ユーザーの意識と活動を向上させることができます。
以下の図は、クラウドから端末にメッセージを送信するプロセスを示しています。ユーザーは通知メッセージをタップすると、アプリ、ウェブページ、またはアプリ内の特定の画面を開くことができます。ユーザーへの連絡には、Huawei Push Kitが推奨される方法です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/c460e22f-337f-0dca-c552-4662cc672dbe.png)
#特徴
##信頼性高い
- 受信率が９９％です。
- 毎秒１０００万メッセージまで送信できます。
- ２００国以上対応します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/30a69fe6-ee30-cc30-cfbc-68b0b9f8d094.png)

##精確
- トピック別またはユーザータグ別で通知が送信できます。
- 日程プッシュ設定も可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/95f2ddda-0302-0cd9-69c0-8796dd0d0acb.png)

##多種フォーマット
複数のスタイルをサポートされます。
- 短いテキストスタイル
- 大きいテキストスタイル
- 大きい画像スタイル
また、音声通知とマルチ言語表示も対応します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/2c1a35e4-cc74-1601-a658-ecab5f02be28.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/53cd6594-36a3-350a-844d-60ff7c8cafa3.png)

##リアルタイムフィードバック
リアルタイムのフィードバックにより、アプリケーションはプッシュメッセージの損失率を即座に取得できます。開発者は、プッシュメッセージを受信していないユーザーを正確に把握し、ユーザーがクローズドマーケティングループを作成するための再マーケティング戦略を策定することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/fc7ef6be-383b-a66b-7825-4c92ab73c701.png)

##便利なオペレーション
オペレーションモードが二つをサポートされます。
- 便利なHuaweiAGCのプッシュコンソールでタスク管理、ユーザー種別、プッシュプラン作成または分析のリポートが確認できます。
- Huaweiプッシュサーバーと連携したの開発コンソールでカスタマイズな動作もサポートされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/651cb226-bcca-c297-8f68-cbccf94e9589.png)

 
##プッシュ通知流れ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/70667588-74ec-f550-15aa-8e8c2df9b36e.png)

#ワークケース
Tiktokアプリで、PushKit対応次第、KPIを改善しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/2b1f8059-a6b2-ec58-f8c1-c282f2e944e1.png)


#導入ステップ
開発前、[Huaweiデベロッパーサイト](https://developer.huawei.com/consumer/en/)をアクセスし、デベロッパーアカウントを登録必要があります。登録次第、[AppGallery Connectサイト](https://developer.huawei.com/consumer/en/service/josp/agc/index.html)をアクセス、アプリが作成できます。
完全な手順は以下となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50470/0af1aa3f-3f1e-505f-e746-4cafc3c07c39.png)

ステップバイステップ開発ガイドは[コードラボ](https://developer.huawei.com/consumer/en/codelab/HMSPushKit/index.html#0)を参考できます。
また以下のリソースも参考可能です。
- [Githubリポジトリ](https://github.com/HMS-Core)
- [開発向けフォーラム](https://forums.developer.huawei.com/forumPortal/en/home)
- [Stack Overflow](https://stackoverflow.com/questions/tagged/huawei-mobile-services?tab=Newest)
- [Youtube](https://www.youtube.com/watch?v=cgdpiXKM6LU&list=PLy7rmPPfUv3Z6bFTiTTSJkAJR-F02UNX6)
CakePHPで既存のDBからMigration、Seedファイルを生成する

# やりたこと
すでにあるデータベースからMigration、Seedファイルを生成する

# 環境
* PHP7.4
* cakephp4.1.2

# 手順

* Migrationファイルの生成

１ファイルで生成される。ファイルを分割して生成する方法はなさそう。

```
bin/cake bake migration_snapshot Initial
```

* Seedファイルの生成

テーブルごとに実行が必要。一括実行はできなそう。

```
bin/cake bake seed --data Articles
```

# 参照
https://book.cakephp.org/migrations/2/ja/index.html#id18
preventDefaultはなぜ必要なのか

動作環境
Ruby 2.6.5
Rails 6.0.3.2

JavaScriptにおけるpreventDefaultがどういった働きをしているかをようやく理解することができたので、整理するために投稿してみました。

## preventDefaultの意味
preventDefaultの必要性について話していく前に、そもそもpreventDefaultが何をしているのかを説明します。

###default（デフォルト）の挙動をprevent（妨害）しています。

説明になっていないと思うかもしれませんが、厳密な説明をしようとすると、おそらくかなり長い行数が必要となってしまいますし、具体的な例を提示した方がわかりやすいと思い、端的に説明しました。早速、具体的な例を元に説明していきます。

## preventDefaultの具体例

``` Ruby:index.html.erb
<%= form_with url:  "/posts", method: :post do |form| %>
  <%= form.text_field :fuga  %>
  <%= form.submit '投稿する' , id: "submit" %>
<% end %>
```
index.rbにて投稿するボタンをクリックすると、fugaに入力した内容が投稿されるとします。
このままだと、投稿するボタンをクリックすると、ページの読み込みが始まってしまうので、下記のJavaScriptを記載することで非同期通信にしたとします。

``` JavaScript
function hoge() {
  const submit = document.getElementById("submit");
  submit.addEventListener("click", (e) => {
    // 投稿するボタンをクリックした時と同じ挙動のコード（長くなってしまうので、省略）
  });
};
window.addEventListener("load", hoge);
```
しかし、ここで１つ問題が生じてしまいます。それは、非同期通信にしたことによって同じ挙動が追加で行われてしまうので、１回の投稿で２回分投稿したことになってしまうということです。
具体的に説明すると、投稿するボタンをクリックすることで非同期通信が行われ、ページの読み込みなしで投稿が１つ増え、ページの再読み込みをすることで、本来の投稿するボタンをクリックした時の挙動が反映されて、投稿が１つ増えます。そのため、結果として同じ投稿が２回されるということが起きてしまいます。

この問題を解決するためにprevent.Defaultを使います。以下のように１行追加するだけです。

``` JavaScript
function hoge() {
  const submit = document.getElementById("submit");
  submit.addEventListener("click", (e) => {
    e.preventDefault();
    // 投稿するボタンをクリックした時と同じ挙動のコード（長くなってしまうので、省略）
  });
};
window.addEventListener("load", hoge);
```

これによって、デフォルトの挙動を妨害することができるので、１回の投稿で２回分投稿することがなくなりました。
しかし、ここで私は「そもそもデフォルトの挙動って何？」「なぜ都合よく非同期通信だけの挙動が妨害されていないの？」
といった疑問を抱いておりました。

## デフォルトの挙動とは？
基本的にRuby on Railsでのデフォルトの挙動は、ビューでの操作によって、ビューからコントローラーに情報が送られ、コントローラー内のいずれかのアクションが動くという認識で問題ないようです。
今回でいうと、投稿するボタンをクリックしたことでcreateアクションが動き、fugaを保存するということがデフォルトの挙動です。通常のRuby on Railsの流れですね。
そのため私は、preventDefaultを**「通常のRuby on Railsの流れを妨害するもの」**と捉えております。
js　コールバック関数のイメージが掴めた気がする記事

##この記事について
Vue.jsの勉強をしているけど、ちゃんと基礎を勉強しなきゃと思いjsの勉強を始めました。
そこで今までなんとなくでしか使ってなかったコールバック変数が何者かが分かった気がするするので投稿。


##参考記事
https://qiita.com/yukiji/items/ae2dbbd34f8557d5af19



##コールバック変数って？
**高階関数**と呼ばれる関数の**引数となる関数**である。


##とりあえず高階関数ってなに。。。

###高階関数とは
高階関数とは関数を引数、戻り値に使う関数である。
つまり、引数にコールバック引数を受け取って関数の中で関数を実行するんや！

```ruby:qiita.js
function 高階関数（コールバック関数）{
　 #色んな処理を実行したり。。。
  #コールバック関数の処理
}
```


####どんな役割があるのか？
例えば自分がギリシャ時代の奴隷の管理者だとして、いちいち全ての奴隷の体調が良い状態で仕事をしているのか確認をするのはチョーめんどくさいわけです。
そんな時に奴隷の中で監督者を指名して、その監督者が確認した上で休憩を取らせるようにさせる。
**この監督者が高階関数の役割なのだ！！！**つまり**関数で関数を監視させるのが高階関数**


監督者がいなかったら、いちいち全ての仕事で同じ作業をしないといけない。

```ruby:qiita.js
function cut(stone) {
 if(#/もし健康だったら /)
　　#石を削る仕事をさせる
  end
end
}


function polish(stone) {
 if(#/もし健康だったら /)
　　#石を磨く仕事をさせる
  end
end
}

```

そこで！！！高階関数（監督者）の出番じゃ！！！！

```ruby:qiita.js

#--------  高階関数   ----------
function health(func) {
 if(#/もし健康だったら /)
    #funcがコールバック関数で高階関数の中で処理をさせる
　　func();
 end
};



#--------  コールバック関数  ----------

function cut(stone) {
　　#石を削る仕事をさせる
};


function polish(stone) {
　　#石を磨く仕事をさせる
};

```


##まとめ
繰り返しをしないためにもチョー便利なのが高階関数とコールバック関数のコンビなんやな。
jQuery クリックで要素へanimateしてスクロール

```javascript
$('.selector-on-click').on('click', function() {
    var selectorTop = $('.selector').offset().top;

    // PC, SP表示の違いを吸収（例：fixedのヘッダー分をマイナス)
    if (jQuery(window).width() > 768) {
        var selectorTop = selectorTop - 103;
    }
    // 1秒、swing(スムーズ感が出る)で設定
    $('html, body').animate({scrollTop: selectorTop}, 1000, "swing");
});
```
リスト型、タプル型

リスト型、タプル型を使いこなす

リストをソートする
Pythonのリスト型では、要素の並び順を入れ替えるソートを簡単に行なえます。
数値を要素として持つリストに対してsort()メソッドを呼び出すと、要素を昇順に並べ替えることができます。
リスト型は変更可能なデータ型であることから、sort()メソッドを呼び出した結果、リストオブジェクト自体が書き換わります。

【昇順に並び替える】
monk_fish_team = [158, 157, 163, 157, 145]
monk_fish_team.sort()
monk_fish_team
↓
145, 157, 157, 158, 163

sort()メソッドは、なにも引数を与えずに呼び出すデフォルトの動作では、数値を昇順にソートするようになっています。
プログラムではそのような処理を行うことが多いためです。しかし、引数を与えることで並び替えの仕方を変更することができます。
例えば、reverseというキーワード引数をしていしてTrueを渡すと、並び順を降順にできます。

【降順に並び替える】
monk_fish_team = [158, 157, 163, 157, 145]
monk_fish_team.sort(reverse = True)
monk_fish_team
↓
 163, 158, 157, 157, 145


ソート順をカスタマイズする
ソートという操作は、データの大小や優劣を比較して、順番を決める処理に他なりません。
sort()メソッドは、順番を決めるための基準を別途与えることで、単純な数値の大小以外に基づいた
ソート順のコントロールが可能になります。

【sort()メソッド】
S.sort(Key, reverse)
※Sは処理の対象となるリストを表しています

sort()メソッドの引数は、他のメソッドとは違い、引数のキーワード指定が必須になっています。
Keyには、順番を決める基準を返す関数を渡すことで、ソート順をカスタマイズできます。
また、reverse引数は先程紹介しましたが、並び順を降順にする場合にTrueを指定します。
デフォルトはFaldeで、昇順に並び替えます。

具体的な例を使って、ソート順をカスタマイズする方法について説明します。
文字列型のsplit()メソッドのときに使った、茨城県のとある女子校の持っている戦車の
名前、速度や装甲厚などのデータを元に、戦車を強い順にソートすることを考えます。
まず、1つの戦車についてのデータを表現する方法について考えます。
名前や数値など、異質なデータを並べて管理するのに向いているのはタプル型です。
戦車ごとに、名前、速度、装甲厚、主砲の口径のデータをタプルにして
「（”八九式中戦車”, 20, 17, 57）」のように記述します。
このデータを、5台分並べます。

【タプルのリストを作る】
tank_data = [(“IV号戦車”, 38, 80, 75), (“LT-38”, 42, 50, 37),
		     (”八九式中戦車”, 20, 17, 57), (“III号突撃砲”, 40, 50, 75), (“M3中戦車”, 39, 51, 75)]

このデータをソートするためには、何を持って強いとするか、ということを明確に定義する必要があります。
厳密な定義は難しいですが、ここでは簡易に「速度、装甲厚、主砲口径を足した数値が大きいほうが強い」
というルールを作ってみます。
リストの要素を数値にして返す関数を作ります。この場合は、リストに入っている戦車データのタプルを渡すと
諸元を足して返す関数を作ればよいです。
タプルの1番目から先の数値を足して返す関数を作ります。
【戦車の諸元を足して返す関数evaluate_tankdata()】
def evaluate_tankdata(tap):
	return tup[1]+tup[2]+tup[3]

上記のevaluate_tankdata()関数を使えば、戦車を数値的に比較できます。
定義したタプルのリストを使って、戦車の強さを数値化してみましょう。
【各戦車の強さを表示する】
evaluate_tankdata(tank_data[0])
↓
193

evaluate_tankdata(tank_data[4])
↓
165

これで、リストの中にあるデータを比較することができるようになりました。
この関数を、sort()メソッドの引数keyに渡します。
そうすると、リストの要素を関数に渡しながら評価して、要素をソートしてくれます。
では、実際にsort()メソッドを使ってデータを並び替えてみます。
その後、並び替えたリストを表示してみます。
【戦車の強さでソートする】
tank_data,sort(key=evaluate_tankdata, reverse=True)
tank_data
↓
[(“IV号戦車”, 38, 80, 75), (“III号突撃砲”, 40, 50, 75), (“M3中戦車”, 39, 51, 75), (“LT-38”, 42, 50, 37),(”八九式中戦車”, 20, 17, 57)]

sort()メソッドは昇順に並び替えを行うのがデフォルトの動作です。
Reverse引数にTrueを渡して順番を降順にし、強い順、つまりevaluate_tankdata()関数の返す数値が大きい順に並べています。
IV号戦車の性能が一番高いことがわかりました。
このように、リストの要素を評価する関数を作って引数を与えると、sort()メソッドの動きをきめ細かくカスタマイズすることができます。
Magenta.jsでローファイヒップホップ曲の無限生成？Lo-Fi Player

![lofiplayer.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61803/58c34dcd-fe4e-2059-022d-3c25223e18e2.jpeg)

Sony Flow MachineのLo-Fi Beats “サクラチル”に感化されたのでしょうか？
MagentaもMagenta.jsを使用したLo-Fiヒップホップ生成ウェブアプリ

Lo-Fi Player
https://magenta.github.io/lofi-player/

をリリースしました。

音楽生成や操作してみた動画をアップしましたのでご覧になってみてください。
２つの音楽データ（前半後半）の選択、ベースパート、ドラムパートのオン・オフ、背景画像効果音選択、などが可能です。

https://youtu.be/CmN2-jJoj0c


##Lo-Fi Player技術的解説 (VAEについて）

このLo-Fi PlayerはMagenta.jsの中でもMusicVAEのInterpolation（２つの音楽データをつなぐことで新たな音楽を作る）というモデルが使用されている様です。
本来この２つの音楽データ（それぞれ１小節）を最初と最後に配置し、その間にある空間を埋める事により新たな音楽生成を行うのがMusicVAEの仕組みです。
最初と最後が１小節ずつ、としてその間が１４小節分あれば合計１６小節の音楽が生成されます。
図にしてみると下図の様になります。

![m1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61803/0f5c5b22-6014-68df-5057-51ff260f65d0.png)


この区間を埋める時に、関連性の低い音データまでを考慮してしまうと、ニューラルネットワークの計算も大変、かつ、いわゆる音楽的に外れる可能性も高くなってしまいます。
そこでデータの重要な部分だけを残して削減（エンコーダ）し、元に戻す（デコーダ）を行うのがVAE (Variational Auto Encoder )です。
このVAEがMusicVAEの名前の由来になっています。
VAEの使用と不使用の効果を視覚化したのが下図です。

![m2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61803/49a4b59c-0b95-1070-829d-43a1a56e505d.png)

MusicVAEは（オフィシャルに公開されているもの）最大３トラックの音楽生成が行えます。
今回のLo-Fi Playerも

**・メロディー**
**・ベース**
**・ドラム**

の３トラックの生成が行われています。
ちなみにドラム以外は単音です。
複数トラックの生成はニューラルネットワークの仕組み的に（データの取り扱い＝数式設計の難易度）、それぞれの整合性をとるのが非常に大変なのですが、VAEによるデータの次元削減で音楽的関連性の低いデータを排除する事で、より確率高く、整合性のある音楽生成を可能にしています。
さらに詳しいMusicVAEの解説は近日オーム社様から発売される私の書籍に書いていますのでもしよろしければご覧になってみてください。


今回のLo-Fi Playerは合計４小節の音楽生成でしょうか？
 とすると最初と最後の２小節は、上述した通り、元となっている音楽データで、その間の２小節がMusicVAE生成、合計４小節の音楽生成が行われる仕組みなのかもしれません。


プログラムの中身に興味がある方はGitHubにコードが公開されていますので見てみるのも良いでしょう。

Lo-Fi Player GitHubページ
https://github.com/magenta/lofi-player

さらにPlay Mgenatサイトというものがあり、コードも自分で書き換え、音楽やビジュアルの変更が可能なあたりもいかにもMagentaです。

Play Magenta
https://play-magenta.glitch.me/

Play Magentaのコードはこんな感じです。

```javascript
synth = new Tone.Synth({
 envelope: {
   attack: 0.005,
   attackCurve: "linear",
   decay: 0.1,
   decayCurve: "exponential",
   release: 1,
   releaseCurve: "exponential",
   sustain: 0.3,
 },
 oscillator: {
   count: 3,
   harmonicity: 1,
   modulationFrequency: 0.4,
   modulationIndex: 2,
   modulationType: "square",
   partialCount: 0,
   partials: [],
   phase: 0,
   spread: 20,
   type: "triangle",
   width: 0.2,
 },
});
     
synth.toDestination ? synth.toDestination() : synth.toMaster();
```

ちなみに開発者のVibert Thioさんは、記憶に間違いがなければ、元は個人的にMagenta.jsを使用した音楽ゲームアプリを投稿し、それが認められて？現在Google AIのMagentaチームインターンとなった経緯がある方の様です。

日本からも優秀なMusicニューラルネットワーク開発者が生まれる事を願い、さらに音楽AIエンジニア教育事業に力を入れていきたいとあらためて思いました。
node環境でのmysql

#nodejs環境でmysqlを使用する方法

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

```
const mysql = require('mysql')
const connection = mysql.createPool({
     host: 'localhost',
     user: 'root',
     password: 'secret',
     database: 'my_db'
})
```

##データの参照
###select文

```
connection.query('SELECT * FROM `books` WHERE `author` = ?', ['David'], function(error, results, fields){
//error: クエリ実行時にエラーが発生したらエラーオブジェクトを持つ
//results: クエリの実行結果を持つ
//fields: クエリ実行結果のフィールドに関するオブジェクト
})
```

##データの挿入
###insert文

```
connection.query('INSERT INTO `books` SET ?', data, function(error, results, fields){
//error:クエリ実行時にエラーが発生したらエラーオブジェクトを持つ
//results:クエリの実行結果を持つ
//fields:クエリ実行結果のフィールドに関するオブジェクト
})
```

##データの更新
###update文

```
connection.query('UPDATE `books` SET カラム名 = ? WHERE id = ?, ['name', 3], function(error, results, field){
//error:クエリ実行時にエラーが発生したらエラーオブジェクトを持つ
//results:クエリの実行結果を持つ
//fields:クエリ実行結果のフィールドに関するオブジェクト
})
```

##データの削除
###delete文

```
connection.query('DELETE FROM `books` WHERE id = ?', [3], function(error, results, fields){
//error:クエリ実行時にエラーが発生したらエラーオブジェクトを持つ
//results:クエリの実行結果を持つ
//fields:クエリ実行結果のフィールドに関するオブジェクト
})
```
Gradle × intelliJ で UnitTest が動作しないとき

下記のオプションを変更

```
設定 > ビルド、実行、デプロイ > Gradle
テストの実行に使用: IntelliJ IDEA
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111110/0e4c9a49-8f51-4cc9-cb12-55b100595e28.png)

以上です！
collectdをインストールしてMetricFireにメトリックを送信する方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614998/f7b6a886-3f7f-8199-9cb7-b6f2f00e5609.png)


#こちらの動画をご覧ください。
https://www.youtube.com/watch?v=oKTHaneWVkY&feature=emb_logo


#MetricFireとは？
 
[MetricFire](https://try.metricfire.com/japan/?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=How%20to%20install%20collectd%20and%20send%20metrics%20to%20MetricFire)は、オープンソースの監視ツールスイートを使用してインフラストラクチャ、システム、アプリケーションの監視を提供する本格的なプラットフォームです。 このプラットフォームでは、PrometheusサービスまたはGraphite-as-a-Serviceのいずれかを使用し、美的に魅力的なGrafanaダッシュボードにメトリックを表示できます。

MetricFireを使用すると、強力な監視機能により、複雑なシステムを一目で理解できます。 この記事では、MetricFireを理解してビジネスで使用するために知っておく必要のあるすべてを取り上げます。

[無料トライアル](https://www.hostedgraphite.com/accounts/signup-metricfire/?signup=japan&utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=How%20to%20install%20collectd%20and%20send%20metrics%20to%20MetricFire)にサインアップして、MetricFireを始めましょう。 あなたはプラットフォームに乗り、私たちが提供しなければならないツールを見ることができます。 また、[デモを予約](https://calendly.com/metricfire-chatwithus/chat?utm_source=blog&utm_medium=Qiita&utm_campaign=Japan&utm_content=How%20to%20install%20collectd%20and%20send%20metrics%20to%20MetricFire)して、モニタリングのニーズについて直接お問い合わせください。
Examples of categories, orders, monoids

3.1: Examples of categories, orders, monoidsのノート

### 単純なカテゴリーの例
Arrowは抽象的ななにか。関数というわけではない。

#### オブジェクト０個で構成されるカテゴリー
空

#### オブジェクト１個で構成されるカテゴリー
![1-obj-cat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499443/43728817-8f30-87fd-0ce7-6e057a0d71ac.png)

#### オブジェクト２個で構成されるカテゴリー
![2-obj-cat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499443/3176e889-4742-5137-9104-a8041ac9d336.png)

### グラフからカテゴリー
#### Free construction (Freeカテゴリーを作るもの)
手順：
1. 全てのオブジェクトにid Arrowをつける。
2. 全てのCompose可能なArrowを、結合律を満たしつつComposeする。Compose結果のArrow（$g \circ f$とか）もComposeの対象になる。

### Hom set
あるオブジェクトから別のオブジェクトへのArrowのセット。例えば、

- カテゴリー$C$での、$a$から$b$へのArrowのセット
$C(a,b)$ 

- カテゴリー$C$での、$a$から$a$へのArrowのセット
$C(a,a)$ 


### Orders Category
Orderでは、Arrowは "$\leqq$" relationを表す。

![a-leq-b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499443/2b432c02-2e3a-229f-69c0-1ef38d598b5d.png)


#### Preorder/Thin (category)
- 最も一般的な制約。Pre-orderは、ほぼPartial orderだがそうでない。
- オブジェクト$a$から$b$の間にありえる、１方向のArrowは０または１個
- Loopは存在し得る。（$a$->$b$, $b$->$a$の２つのArrowが存在するケース）
- Preorderの上に制約の追加していくことで、面白いカテゴリーになっていく

##### 定義
- ArrowsがComposable(transitive)
- id Arrowが存在(reflexive)
- Compositionがassociative
![pre-order.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499443/e2dce0c6-ecfb-8881-bc6e-96a4511e1bd4.png)

###### 注意点
- オブジェクト間のArrowは、１方向に最大１つなので、epi/mono morphismは常に成り立つが、RelationはInvertibleではない
- Hom setは、空またはシングルトンのセットになる。

#### Partial order
##### 定義
- Preorderで、Loopが存在しないもの(antisymmetric)。$a$->$b$がある場合、$b$->$a$はない。グラフでいうなら、Directed Acyclic Graph。

###### 注意点
- オブジェクト間にArrowが存在するとは限らない。比較できないオブジェクトのペアも存在し得る。
- Loopがないので、Invertibleではない

#### Total order
##### 定義
- Partial orderで、全てのオブジェクトの間にArrowが存在するもの。(Connexity)

###### 注意点
どのオブジェクトのペアも、常に比較ができる。

### Monoid
- オブジェクトが１つのカテゴリー（オブジェクトが１つのカテゴリーは全てMonoid)
- id Arrowが存在する
- id Arrowでないが存在してもよい
- どんな２つのArrowでもComposeができる

![monoid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/499443/ebf98bd1-d9c9-f055-7ec2-9a7a1a83308a.png)

#### 群論でのMonoid
群論でのMonoidは、圏論のMonoidよりも昔から定義されている。

##### 定義
集合$S$で、二項演算が$\times$だとして、以下を満たすもの：

- $\times$が結合律を満たす
$(a \times b) \times c = a \times (b \times c)$

- $S$が単位元が存在する 
$\exists \; e \; \forall a, \; e \times a = a \times e = a$

##### 例
全て結合律を満たしている。

- 自然数の掛け算
  - 単位元は１

- 文字列の結合
  - 単位元は空文字

- リストの結合
  - 単位元は空リスト

##### 圏論と群論のMonoid
２つのMonoidは、完全に同じものを別に見方でみている、

###### 圏論から群論
$M$というMonoidがあると、$M(m, m)$というhom-setが導かれる。
これは、$id$を含む全ての$m$から$m$に行くArrowが含まれるセットになるので、ここから、群論で考えられる。

- 群論の演算はComposition
- 結合律も満たす
- 単位元は、id arrow

###### 群を圏論で考える例
自然数の足し算がなす群を、圏論で考えると

- Arrowは、+5や+7などを表す
- Compositionは、+5と+7をcomposeして+12など
- id arrowは+0
- 全てのオブジェクト間にArrowが定義されている

### 圏論とプログラミング言語
#### 型のカテゴリー

- Monoidは、弱く型付けされたプログラミング言語と一致する。全てのArrowがCompose可能。
- 強く型付けされたプログラミング言語と一致するカテゴリーでは、Composeするときには、Arrowの型を合わせる必要があるので、全てのArrowがCompose可能なわけではない。
- 弱く型付けされたプログラミング言語は、型を一つに絞った、強く型付けされたプログラミング言語と考えることができる。

## 動画
Bartosz Milewski / Category Theory 3.1: Examples of categories, orders, monoids
https://www.youtube.com/watch?v=aZjhqkD6k6w
【Java】メイン・クラスXXXが見つからなかったかロードができませんでした

###別のファイルをコピーして作成しただけなのになんで実行できないの？クラスファイルも生成されているのに！！
`java_lessons/com/dot/myapp`にMyApp.javaを作成。
MyApp.javaをコピーして`Practice.java`を作成。
試したいことをPractice.javaに書いていく。

MyApp.javaの外部クラスを`java_lessons/com/dot/myapp/model`に入れていて、それを読みこんでいたけど、外部クラスを読み込まずに簡単なコードを試したいのでpackageとimportを削除してPractice.javaを作成して行った。

そしてコンパイルはうまく行ったけど、実行ができない。

実行しようとすると

`メイン・クラスcom.dot.myapp.Practiceが見つからなかったかロードができませんでした`というエラーのループに。

調べたらPATHがどうとか書いてたけど、java_lessonsのディレクトリとは別にtestディレクトリを作成してそこにPractice.javaを移動してコンパイル・実行をするとできた。

ということはPATHがどうとかいう話ではないのではないかと考えた。

でもどうしたらいいかわからない。

ん〜こう言う時ってどうしたらいいんだろう。質問できる人がいたらいいけど、独学だからいません！ネットで聞けばいいけど、それならなんとか自分で対処したい！


###解決までのプロセス

とりあえず考えられる原因をいくつか列挙できればそれぞれの原因について調べて見れば、同じようなエラーメッセージと合わせて検索に引っかかるはず！！


###自分が作成したファイルと実行できていたコピー元のファイルを比較して原因究明

1. mainはなんか特別なメソッドらしいから、別ファイルだけどmainが同じ階層に存在しているのがおかしいのか？
2. packageを利用してないから消したけど、利用してないけど書けばできるのか？
3. やっぱりPATHを通す設定が必要なのか？
4. vagrantでsshで接続して実行とかしてるけど、ファイルの保存ができてなかったりして実行ファイルを読み込めない？
5. FTPにCyberduckを利用しているけど、それがうまく行っていない？



###あとはトライアルアンドエラー

####1.の対処
java_lessonsの階層深くに入っていたけど、まずは別のディレクトリを作成して移動する。

1. java_lessonsの横にtestフォルダを作成
2. Practice.javaをそこに移動
3. ターミナルでtestに移動
4. コンパイル・実行
5. 実行できた　→　mainメソッドは同じ階層に一つしかアカン？
6. test/practiceのフォルダを作成
7. ファイルを移動
8. コンパイル・実行
9. できない　→　mainは一つしかないのに・・・
10. またtestに移動させる
11. コンパイル実行
12. できた　→　mainの数じゃなくてディレクトリの問題
13. ターミナルで実行したいファイルがあるディレクトリに移動してから実行
14. できた！！

収穫
ターミナルで移動してから実行すればいい。

しかし、もともとのMyAppは階層深くにあってもできたぞ？

ということは、ターミナルで移動してから実行しなくてもできるようにする方法があるということですね。

ということで、
####2.の対処
packageの利用はしてないけど、とりあえずpackage宣言をしておこう！

```java
package com.dot.myapp;
```

これを冒頭につけて、最初のディレクトリ、つまり、
`java_lessons/com/dot/myapp`にPractice.javaを戻してコンパイル実行。

いけました。

収穫
package宣言すれば階層深くにいても実行できる。
でも、さらに一つ下のディレクトリmodelにあるクラスは利用してないのに書かないといけない？

ここでまたファイルを移動させて実験。

`java_lessons/com`に移動させて`package com;`と宣言して実行。

できた

収穫
ターミナルがいるディレクトリより下の階層にある場合は、package宣言でそのファイルのディレクトリを書けばいい！


###自分なりの結論

package化するというのは、PHPとかでfunctionやdefineだけのファイルをmodelに入れて管理するための方法かと思いきや、実行させる時に、ターミナルのいるディレクトリより下にある場合に書く必要があるということ。

###自分なりの収穫
いくつか原因を列挙してからやってたまたま最初の方に解決策が見つかったけど、とにかくいろいろ実際に試してみるのが早いのかな。

エラーメッセージをそのまま検索してもひっかかるときはあるけど、それよりもいろいろ自分で考えて試して解決する方が理解は深まる。

理解が深まるということは、同じ状況じゃないにしても、似たような状況では原因として考えられるものを列挙しやすくなり、結果的に解決が早くなる！


とにかく自分で考えて自分で解決する回数をこなしてスピードを上ていこう！
【前編】ネットワーク構築（IPsec）

##今回やること
セキュリティについて勉強をしている中で、VPNを構築したいと思っていたので
その中でも一般的に使われているIPsecを構築してみようと思います。
ただ構築したことがないので、完全手探りです。
いきなり構築は無謀なので、まずは事前知識を補完していこうと思います。

##使用ツール
GNS3
IOS: c2600-adventerprisek9-mz.124-17


##用語集（備忘録）

※自分用にざっくりまとめてます（しっかりまとめたら長すぎるため）

|用語|概要|
|:-----|:-----|
|AH|IPパケットを認証するプロトコル。暗号化はしない。|
|ESP|認証と暗号化両方する。|
|IKE|セキュア環境じゃないネットワークで秘密鍵を交換するプロトコル。|
|SA|IPsec-VPNで使用されるコネクションのこと。|
|ISAKMP SA|接続相手を認証して共通秘密鍵を共有するSA。|

##構築の流れ（ざっくり）
IPsecやること多くて難しいので、ざっくりまとめます。
IKEにフェーズ１とか２というのがあるらしく、先に簡単にまとめ。

###**フェーズ１**
ISAKMP SAを確立するのが。
接続相手を認証する際、認証に使われる暗号化の有無でモードが分かれる。

|IKEフェーズ１|概要|
|:---|:---|
|メインモード|暗号化するほう。|
|アグレッシブモード|暗号化しないほう。|

###**フェーズ２**
IPsec SAを確立するための情報交換を行う。
色々な情報を交換したあとにIPsec SAが確立する。

・暗号アルゴリズム
・ハッシュアルゴリズム
・IPsec SAの寿命
・DHグループ
・ID（ESP、AHを識別するためのもの）
・PFS（IPsec SAで使用する共通秘密鍵を安全に作成するための情報）

では流れのまとめ。

###**大体の流れ**
１、IKEのポリシー定義（ISAKMP）
２、事前共有鍵の設定（pre-share）
３、SA確立のためにIPsecトランスフォームセットに正義　**※１**
４、IPsecの対象トラフィック定義
５、暗号マップ定義

**※１**
IPsec SAを確立するためにトランスフォームセットを必ず設定することになるらしい。
トランスフォームの種類も複数あるみたい。

・ESP
暗号化トランスフォーム
認証トランスフォーム

・AH
認証トランスフォーム


##コマンド集（備忘録）
コマンドが多くて訳が分からなくなるので、まとめます。
###フェーズ１
|コマンド|説明|
|:---|:-----|
|crypto isakmp policy  [priority]|ISAKMPポリシーの設定。数字が低いほど優先度が高い。|
|encryption　[暗号化の値]|暗号化アルゴリズムの設定。デフォルトは**des**になる。|
|authentication [ pre-share ]|認証方式の設定コマンド。３種類ある。|
|crypto isakmp key [pass] address [ip]|事前鍵の設定。|

まだまだありますが、フェーズ１で使いそうなのをまとめてみました。

##まとめ
やはりセキュリティの技術なだけあって、かなり難しいです。
コマンドも多いし、暗号化の種類も色々あるしで結構骨が折れます。
まだまだ調べることが多いですが、ある程度まとめられたら実際に構築してみようと思います。

以上です。
【VBA】書式設定と入力規則設定を施す

##日付しか入力出来ないようにする
指定した範囲に__yyyy/mm/dd__の書式設定と、__日付以外入力出来ない入力規則__をつけます。

あんまり繰り返し作業することではないかもしれないのですが、以前、複数のシートに入力規則をつけなければならずめんどくさかったのでマクロで設定しました。
またやる時のために書いとこうと思いました。

##入力規則の設定内容
・2019/01/01以降の日付のみ入力可能
・セルを選択したら入力時メッセージを表示する
・2019/01/01以降の日付以外を入力したらエラーメッセージを表示する
・日本語入力はオフにする

```VB
Sub FormatSetting() '書式設定と入力規則設定を施す
    Dim DateCol As Long 'IDの列番号を格納する変数
    DateCol = WorksheetFunction.Match("登録日", Master.Rows(1), 0) 'Match関数で列数格納
    Dim LastRow As Long '最大行数を格納する変数
    LastRow = Master.Rows.Count '最大行数格納
    Dim TargetRange As Range '書式設定する範囲を格納する変数
    '書式設定する範囲を格納
    Set TargetRange = Master.Range(Master.Cells(2, DateCol), Master.Cells(LastRow, DateCol))
    
    TargetRange.NumberFormatLocal = "yyyy/mm/dd" '書式設定
    TargetRange.Validation.Delete 'すでに設定されている入力規則を削除
    '2019/01/01以降の日付のみ入力許可
    TargetRange.Validation.Add Type:=xlValidateDate, AlertStyle:=xlValidAlertStop, Operator:=xlGreaterEqual, Formula1:="2019/01/01"
    TargetRange.Validation.IgnoreBlank = True '空白を許可
    TargetRange.Validation.InputTitle = "入力規則" '入力時メッセージタイトル
    TargetRange.Validation.InputMessage = "yyyy/mm/dd形式で入力してください。" '入力時メッセージ文
    TargetRange.Validation.ErrorTitle = "エラー！" 'エラーメッセージタイトル
    TargetRange.Validation.ErrorMessage = "2019/01/01以降の日付をyyyy/mm/dd形式で入力してください。" 'エラーメッセージ文
    TargetRange.Validation.IMEMode = xlIMEModeOff '日本語入力をオフ
    
    MsgBox "書式設定と入力規則設定が完了しました！"
End Sub
```
【実行結果】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/5b28fa9e-bef7-93df-e3fe-ae8dabeb240a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700414/a0ea68a5-e9e6-d292-efaa-abff52b8514a.png)


##ワタシ流こだわり
今回のようなマクロは`With`使う方もたくさんいますよね？
ワタシは`With`使わない派です！

あとワタシいつもRangeの指定は

```VB
Set TargetRange = Master.Range(Master.Cells(2, DateCol), Master.Cells(LastRow, DateCol))
```
こうするんですけど、長いですよね:joy:
どのセルからどのセルまでってのが理解しやすくて…

分かりやすくていい指定のしかたたくさんあると思うんですが
みなさんどうしてますか？
【Swift】ストライド型について

###1.はじめに
---
今回は範囲型ともう一つの基本的なデータ型である、ストライド型について解説します。前回の記事では範囲型のことを解説しており、今回の記事とつながりがある内容なので、見てない方はお時間ありましたら是非ご覧ください。
URL（https://qiita.com/0901_yasyun/items/0e86c602ddff1c472786）

###2.ストライド型とは
---
ストライド型とは、整数や実数などの比較できる値に対して、開始点と終了点、刻み幅から構成される構造体のことを指します。開始点から終了点まで、刻み幅ごとに値を取り出すことができます。
ストライド型には２種類あり、StrideThrough型とStrideTo型があります。それぞれの方のインスタンスは、標準ライブラリの次の関数を使って生成できます。型Tは実際に因数に指定して型によって決まります。

```
func stride(from: T, through: T, by: T.Stride) -> StrideThrough<T>
func stride(from: T, to: T, by: T.Stride) -> StrideTo<T>
```

###3.StrideTo型
---
関数strideはfor-in文と一緒によく使われるので、その一例を以下に示します。

```Swift:
for x in stride(from:0, to:20, by:2){  // 0から20の直前まで2刻みで
    print(x, terminator:" ")
}

print()  // "0 2 4 6 8 10 12 14 16 18 "と表示する
```

このように、fromで指定した値からtoで指定した値まで、byで指定した値で刻みながらループしていることが分かります。しかしここで注目してほしいのは、**最後の数が18である**という点です。このようにStrideTo型は、順番に取り出した最後の値が終了点の値と一致した場合、その値は採用しません。

###4.StrideThrough型
---
一方、StrideThrough型は終了点の値も含みます。実数を使った例を以下に示します。

```Swift:
for x in stride(from:1.0, through:0.0, by:-0.2){  // 1.0から0.0のまで-0.2刻みで
    print(x, terminator:" ")
}

print()  // "1.0 0.8 0.6 0.4 0.2 0.0 "と表示する
```

このように、StrideThrough型をfor-in文で使った場合、終了点の値も含むことが分かります。ただし、刻み幅を使って増加、減少させていくので、必ずしも最後の値が終了点と同じになるとは限りません。また実数の場合には誤差が伴うので、加算していっても終了点の値と一致しないこともあります。

###5.プロトコルStrideable型
---
ここでストライド型の引数の型について説明します。関数Stride(from: to: by:)の場合、宣言は正確に書くと以下のようになります。

```
func stride<T>(from:T, to:T, by:T.Stride) -> StrideTo<T>
    where T : Strideable
```

Tは型パラメータです。where T: Strideableの部分は、型Tはプロトコル**Strideable型**に適合していなければいけないという制約を表しています。
プロトコルStrideable型にもきちんとした定義内容がありますが、若干主旨からずれてしまうのと、まだ私が記事で説明していない内容が出てくるなど、少し複雑な話になってしまうので、今回具体的な定義内容は省略します。
しかし、ストライド型を使ううえでプロトコルStrideable型が、見えないところで内部的に関わっているということだけ、頭の片隅に置いておきましょう。

###6.おわりに
---
今回は前回に引き続き、範囲型ともう一つの基本的なデータ型であるストライド型について、簡単に解説しました。データ型は様々なコードを書く上で、効果的に使える場面が多々あると思います。経験を積むだけどんどん効果的に利用できるようになると思うので、積極的に使っていきましょう。
[CSS] 親要素を無視して、子要素を画面いっぱいに広げる

containerで1024pxとかなっている時、
背景色だけいっぱいに広げたい、とか言うときに使う。

innerはcontainerと同じ幅に設定。
コンテンツの横幅は揃って、ignore~の箇所の背景色のみ画面いっぱいになる。

```html
<div class="container">
    <div class="background-orange ignore-parent-width">
        <div class="ignore-parent-width-inner">
        </div>
    </div>
</div>
```

```sass
.container{
    width: 1024px;
    min-width: 1024px;
}
.background-orange{
    background-color: #FFF6F5;
}
.ignore-parent-width{
    // 親要素を無視して子要素の幅をいっぱいに広げる https://tecb.jp/blog/1517
    width: 100vw;
    position: relative;
    left: 50%;
    transform: translateX(-50%);
    .ignore-parent-width-inner{
        width: 1024px;
        min-width: 1024px;
        margin: 0 auto;
    }
}

// スマホ表示
@media (max-device-width: 480px) {
    .container{
        width: 100%;
        min-width: 100%;
    }
    .ignore-parent-width{
        // 親要素を無視して子要素の幅をいっぱいに広げる https://tecb.jp/blog/1517
        width: 100vw;
        position: relative;
        left: 50%;
        transform: translateX(-50%);
        .ignore-parent-width-inner{
            width: 100%;
            min-width: 100%;
            margin: 0 auto;
        }
    }
}
```
【React -- jsx】jsxでスタイル付け(CSS)をする際のメモ

スクールのチーム開発の際に学んだ、jsxでスタイル（CSS）付けをする方法について記載します。
初学者が作業を進める上で知ったこと/ぶち当たったことが主で、jsxの注意点が網羅されているわけではありません。ご容赦ください。

##対象読者
・ほぼ初めてjsxに触れる方
（ごく初歩的な内容のため、すでにReactを使いこなしているという方には既知の内容と思われます）

##環境
React.js 16.13.1
Node.js 12.13.1

---

###１、スタイルのつけ方
・ライブラリ'emotion'をインポートしてcssという名前をつける
（※スタイル付けをするためのライブラリは他にもあるようです）
・スタイルを付けたいタグに任意のclassNameをつける。（この場合、”titleClass”）
・つけたclassNameを定義する形で `` の内にスタイルを記述。

```react:example.js
import React from 'react';
import { css } from 'emotion';

const App = () => {
  return(
    <div className={hoge}>
      <h1 className={titleClass}>Hello World</h1>
    </div>
);
};

const textClass = css`
  color:red;
`;
```

###２、通常のHTMLやCSSと違うこと
・1つのコンポーネントにつき、大元の親となるタグは1つだけ。
（上記のexample.jsでいうと、return()の一つ下の階層に配置できる要素は&lt;div className={hoge}&gt;の一つだけで、その&lt;div&gt;の内部の階層なら複数のタグを配置できる。）
・&lt;img&gt;や&lt;input&gt;など、通常のHTMLでは閉じタグがないタグでも、セルフクロージングタグが必要。 

```
<img>NO
<img>NO</img>
<img />Available!
```

###３、スタイルのつけ方---タグ内に記述する場合
style={{プロパティ名："値"}}

・{{}}内はオブジェクトである
・プロパティ名にハイフンが含まれる場合は、キャメルケースの記載に直す
　例： margin-bottom => marginBottom
・プロパティが複数ある場合は、","でつなぐ

```react:example2.js
<div style={{marginBottom:"20px", color:"white"}}>example2</div>
```

###４、タグの属性の値に、JSの記述を使う
単純なことですが、つまづいたのでメモ。
例：オブジェクト"user"の、プロパティ"friendName"の値を、placeholderに表示されるようにする。
方法１

```
<input type="text" placeholder={"友達の" + user.friendName + "さんを紹介する"}></input>
```
方法２

```
<input type="text" placeholder={`友達の${user.friendName}さんを紹介する`}></input>
```
以上。

---
アウトプットの練習も兼ねて、学んだことを記事にしました。
React自体の理解が不十分な状態で書いておりますので、記事中に誤りなどあればご指摘頂けますと幸いです。
ggplot::geom_flat_violinのススメ

# はじめに

私は[dgrtwo氏](https://gist.github.com/dgrtwo)の作ったggplot2用の[geom_flat_violin.R](https://gist.github.com/dgrtwo/eb7750e74997891d7c20#file-geom_flat_violin-r)がお気に入りで、よく使わせていただいています。
しかし、このプロットを取り挙げて下さっていたはてなブログの記事がいつのまにやら消えており、悲しかったので簡単に使用法をまとめてみました。

# 準備
残念なことに、スクリプトには余計な" ) "が含まれているので一度[こちら](https://gist.github.com/dgrtwo/eb7750e74997891d7c20#file-geom_flat_violin-r)からダウンロードし、50行目にある" ) "を消去しておいてください。

以下のコードを実行すると不要な)についてエラーメッセージを確認できます。

```r
library(devtools)

source_url("https://gist.githubusercontent.com/dgrtwo/eb7750e74997891d7c20/raw/ed346ccc73cfffcc9e9f1ca51281bb078f4d48a6/geom_flat_violin.R")

> source_url("https://gist.githubusercontent.com/dgrtwo/eb7750e74997891d7c20/raw/ed346ccc73cfffcc9e9f1ca51281bb078f4d48a6/geom_flat_violin.R")
SHA-1 hash of file is 5763fa02179f37bc448799e51370cb07290ea09a
 source(temp_file, ...) でエラー: 
  /var/folders/4s/z0ll_w5s007fvk07vs41w6yh0000gn/T//RtmpMtIvAM/file1e61517c6333:50:13:  予想外の ')' です 
49:                      xmax = x + width / 2)
50:             )
                ^
```

編集したスクリプトは適当な名前(例えばgeom_flat_violin.R)で保存し、ワーキングディレクトリに置いておきます。

# 導入

ggplot2と先程のスクリプトを読み込みます

```r
library(ggplot2)
source("geom_flat_violin.R")
```

# 使用例

おなじみのirisです

```r
p<-ggplot(NULL)
p<-p+geom_flat_violin(data=iris,mapping = aes(x=Species,y=Sepal.Length,fill=Species),scale="count",trim=FALSE)+
  ggtitle("Sepal.Length")
p<-p+geom_dotplot(data=iris,mapping=aes(x=Species,y=Sepal.Length,fill=Species),binaxis = "y",dotsize = 1,stackdir = "down",binwidth = 0.1,position = position_nudge(x=-0.025))
p
```
![flat_violin_exp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683885/24d35d8f-4390-ceb3-0be9-3a5cf8e5e790.png)

geom_dotplotとの組み合わせにより、値の分布が非常に分かりやすくなりました。
position_nudgeを駆使すれば平均値や標準偏差を導入することもできます。

下の箱ひげ図と比べると見やすさが段違いです。

```r
p<-ggplot(NULL)
p<-p+geom_boxplot(data=iris,mapping=aes(x=Species,y=Sepal.Length,fill=Species))
p
```

![geom_box_exp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/683885/1d339a4d-4598-a719-f545-6bbad491539d.png)


# さいごに
私はgeom_flat_violinを知る以前、箱ひげ図を多用していました。
しかしながら、年齢層が上の方は数学で箱ひげ図を習っていない場合があるそうです。
箱ひげ図って事前知識なしに理解するのは難しいですよね。
その点こいつは直感で理解できる破壊力があります。
ぜひ活用してみてください。enjoy!!

# 参考
jbburant氏のプロット作図例
https://gist.github.com/jbburant/b3bd4961f3f5b03aeb542ed33a8fe062
JavaScriptでアクセス元のiOSかAndroidかを判定する

# はじめに

本関数の内容

* ES2015のアロー関数を使用
* ブラウザでWebページを表示時にアクセス元のOSをユーザエージェントを元に判定する
* 正規表現を使ったiOS, Android, その他のOSを反映

各OSのユーザエージェントは[こちら](https://developers.whatismybrowser.com/useragents/explore/
)を参考にした

iPadは13よりiOSではなくiPadOSになり、PC向けのWebサイトを表示する設定をしている場合はUserAgentにiPadと入ってくれないので、トリッキーな判定をする必要がある

ref: https://stackoverflow.com/a/57924983/4480860

# iOSかAndroidかを判定する関数
Androidの場合に表示するURLスキーム

```js
const getMobileOS = () => {
  const ua = navigator.userAgent
  if (/android/i.test(ua)) {
    return "Android"
  }
  else if (/iPad|iPhone|iPod/.test(ua))
     || (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1){
    return "iOS"
  }

  return "Other"
}
```

## 使い方
この関数の例はAndroidとiOSで開いている場合にそれぞれストアのアプリのサイトを開いたり、アプリを直接起動するurl schemaを出し分けるのに使う。

```js
const os = getMobileOS()
# console.log(os) => 'Android'
# console.log(os) => 'iOS'
# console.log(os) => 'Other'
```


# 補足 正規表現の説明

説明した関数の中で使用している`/android/i.test(ua)`を例に説明

* `/android/` が正規表現の本体
* `/android/i` のiは正規表現のフラグで大文字小文字を判定しない
  * AndroidやANDROID,aNdRoIdに対応することになる
  * `/android/i`では検証する文字列のどこかに大文字小文字を気にしないでandroidを含む文字列があるかどうかを判定する
* `/android/i.test(ua)` のtestメソッドは引数の文字列uaに含まれる文字列が`/android/i`の正規表現にヒットするかどうかを`true/false`で返す
rmよりも安全なコマンド

rm って怖いですよね。消したらもう元に戻らない（リポジトリがGitとかで管理されている場合をのぞく）

Unix系列の場合、

```
$ kei.sugano$ cat /usr/local/bin/poi 
mv $* ~/.Trash
```

まあこんなスクリプト用意しちゃえばいいですよっと

上記は Mac OSXの場合なので、そうでない場合

```
mkdir -p ~/.Trash
```

これもやるべきでしょう。

あとは、poiスクリプトに実行権限あげれば、

```
$ poi file.txt
```

とかやると　file.txt は勝手に消えてくれますし、ゴミ箱にはあります。

以上です。