OmniAICreator/Qiita-1.07M huggingface dataset:
pymc3でアヒル本8章をやってみた

この記事は、「StanとRでベイズ統計モデリング」(アヒル本)という本をpymc3で実装したものです。

ベイズに関しては他にもたくさん記事があるので、ここでは割愛させていただきます。

この記事では、上記の本第8章の階層ベイズに関するトピックについてpymc3による実装をしてみます。


# 1. データ
アヒル本の8.1.4で使っているデータは、大手４社の社員の年齢と年収などに関するデータをシミュレーションで作成したものです。
多少は異なりますが、同じようにデータを生成してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180524/39a20783-7f5f-cb98-d210-58b9cc7e0890.png)


### 変数の説明
<p><b>Y_sim: </b>年収</p>
<p><b>X: </b>年齢(23を引いた値)</p>
<p><b>KID: </b>会社のID(0~3)</p>
<img width="162" alt="スクリーンショット 2020-02-19 10.14.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180524/d5db4ce1-d5be-220b-fab7-d2647750a7f3.png">


### 列間の相関を確認

・　YとXが正の相関、つまり年功賃金が考慮されたシミュレーションデータになっています。

<img width="471" alt="スクリーンショット 2020-02-19 10.12.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180524/dc04b2fc-4c37-dd5f-51bc-d3d15c8c3027.png">


# 2. モデル
<img width="958" alt="スクリーンショット 2020-02-19 10.21.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180524/b5e91cf5-584b-2056-fc9e-2c8b8a90eedb.png">


# 3. 実装
```
df["KID"]=df["KID"]-1
n_KID=len(df["KID"].unique())
kids=df["KID"].values

with pm.Model() as hierarchical_model:
    mu_a = pm.Normal('mu_a', mu=0., sd=1000)
    sigma_a = pm.HalfNormal('sigma_a', 1000.)
    mu_b = pm.Normal('mu_b', mu=0., sd=10)
    sigma_b = pm.HalfNormal('sigma_b', 10.)

    a = pm.Normal('a', mu=mu_a, sd=sigma_a, shape=n_KID)
    b = pm.Normal('b', mu=mu_b, sd=sigma_b, shape=n_KID)
    eps = pm.HalfCauchy('eps', 5.)

    y_est = a[kids] + b[kids]*df.X.values

    y_like = pm.Normal('y_like', mu=y_est,
                           sd=eps, observed=df.Y_sim)
    trace=pm.sample(1000)
```
(初期値の設定は粗めです)

# 4. 結果

```
pm.traceplot(trace);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180524/58c59b58-d4f9-e268-ebb6-1f334023574f.png)

aとbはパラメータですがしっかりと会社ごとに区間が推定されていることがわかります。



```
"""
BFMIが0.3よりも大きいため程々に良いモデルと今回は解釈する
"""
bfmi = np.max(pm.stats.bfmi(trace))
(pm.energyplot(trace, legend=False, figsize=(6, 4))
   .set_title("BFMI = {}".format(bfmi)));

```
BFMIは0.3以上あると良いと言われているようです。
<img width="356" alt="スクリーンショット 2020-02-19 10.25.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180524/777ef818-1a4c-1150-c10f-b17decda8511.png">
1発じゃんけん16人の場合2発じゃんけん説

1発じゃんけんとは
5人以上でジャンケンをする場合に、１〜5の数字を指で出した場合に1発で勝負が決まるというもの。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">数年前に開発した、5人以上でジャンケンしてもほぼ１発で勝負が決まる１発ジャンケンを記録として残しておきます。<a href="https://twitter.com/hashtag/%EF%BC%91%E7%99%BA%E3%81%98%E3%82%83%E3%82%93%E3%81%91%E3%82%93?src=hash&amp;ref_src=twsrc%5Etfw">#１発じゃんけん</a> <a href="https://t.co/sxMSRka95e">pic.twitter.com/sxMSRka95e</a></p>&mdash; 三日月マンハッタン仲嶺 (@mikadukinakami) <a href="https://twitter.com/mikadukinakami/status/1231209843467309058?ref_src=twsrc%5Etfw">February 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

結果例
1,2,3,4,5と出した場合、基本一番数字が大きい人が勝ちとなるが1が出てる場合、１の勝ちとなる
1,1,3,4,5と出た場合、1はあいこ負けとして3,4,5で勝負となる。この場合5の勝ち
1,2,3,5,5と出た場合、5はあいこ負けで4の勝ちとなる
2,4,4,5,5と出た場合、4と5はあいこ負けとなり2が勝ちとなる

この1発ジャンケンは5人以上と謳っているが実は人数が増え17以上となるとあいこの確率が50%を超える
ちょうど２回に1回は勝負が決まるのが16人だったので結果を見てほしい
結果は毎回ランダムです。

[16人で1発ジャンケンを1000回した結果](https://docs.google.com/spreadsheets/d/1XiEGe5joswO49r82TWHP3tnyPKCE2JfLKToNWRuOwuQ/edit?usp=sharing)

あと統計的には2で勝てる確率は少ない

以上

追伸
すでに裏付けるデータあって草
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">「ジャンケンが1発で決まること」が一番のポイントのようなので1発で決着する確率をシミュレーションで求め，普通のジャンケンと比較しました。<br><br>結果，参加人数にかかわらず1発ジャンケンの方が1発で決着する確率が何倍も高いことがわかりました。<br><br>人数が7人でも90%の確率で決着するのは素晴らしい。 <a href="https://t.co/gISTKxuV0O">pic.twitter.com/gISTKxuV0O</a></p>&mdash; しんめー (@WB_DataAnalyst) <a href="https://twitter.com/WB_DataAnalyst/status/1231316357972668416?ref_src=twsrc%5Etfw">February 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
GitHub ActionsでNukeeperを使う

C#のプロジェクトで参照しているnugetパッケージを更新してPRを作成してくれる[Nukeeper](https://github.com/NuKeeperDotNet/NuKeeper)便利ですよね。
でもどうせなら定期的に自動的に実行してほしいです。

なのでGitHub Actionsで実行する設定を作ってみました。
(最初、Marketplaceにないかなーと探したんですが、まだないようです…)

↓こんな感じ

```bash:nukeeper.yml
name: Nukeeper

on:
  schedule:
    - cron: '0 0 * * 6'
jobs:
  dotnet:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/setup-dotnet@v1.4.0
    - run: |
        dotnet new manifest
        dotnet tool install nukeeper
        dotnet nukeeper repo https://github.com/${{ github.repository }} ${{ secrets.GitHubToken }}
```

* 毎週日曜00:00に実行するように設定してますので、適宜変更してください
    * (GitHub ActionsはJenkinsみたいにHないのね…皆一斉に動いて大丈夫かしら？)
* Nukeeperを動かすために.Net Coreをセットアップしています
* Nukeeperをローカルインストールするためにマニフェストを生成しています
    * グローバルインストールではパスを通したりでセッションを再起動する必要があるっぽい？ためローカルインストールにしています
* チェックアウトしてカレントパスを指定すれば動くかな？と思ったんですが、動かず…
    * リポジトリパスを設定する方式にしています
* GitHub Actionsではデフォルトで`github.token`でトークンが取れるんですが、どうも何かの権限が足らないようで動きません
    * 別途`repo`にアクセス権のあるトークンを生成し、リポジトリのトークンに設定する必要があります。
ローカル環境から本番環境へ...

<h3>森から更なる森へ...</H3>
ローカル環境でさえ覚えることが多過ぎて死にそうでしたが、
最近本番環境というか、AWSなんかの外の環境設定の学習で覚えることが多過ぎて
死にそうです( ；∀；)
個人的には、rubyの森→railsの森→awsの森+docker+CircleCIなどなど
ポートフォリオ作るのに、やることがこんなにあったんだなぁと...
愚痴を垂れていても仕方がないので、一つずつ頑張って理解(解析)して
いくしかないですねぇ...メンタル気をつけます＼(^^)／
ARKitで2つのポイント間に線を引く

ARSCNViewやARViewで2つのポイント間に線を引きたいことがあります。
勿論一旦ピクセルにしてOpenCVといったライブラリで線を引くこともできますが、ここではオブジェクトを配置して線を引いてみます。

ARSCNView(SecneKit)だと[SCNCylinder](https://developer.apple.com/documentation/scenekit/scncylinder)、ARView(RealityKit)だと[generateBox](https://developer.apple.com/documentation/realitykit/meshresource/3244417-generatebox)といったオブジェクトで擬似的に線に見立てると思います。
しかし、これはオブジェクトですので、線を引くのと違い、長さと回転をいい具合に調整する必要があります。
オブジェクトの回転ですが、Transform、EulerAngle、Quaternionのいずれかを用いて表します。
ただし、RealityKitでは直接EulerAngleを指定できませんのでTransformを使うか、Quaternionを用いる必要があります。
こういったピンポイントの処理を調べるのが面倒ですのでStack Overflowで調べた結果がこちらです。

## EulerAngles

[How to draw a line between two points in SceneKit?
](https://stackoverflow.com/questions/58470229/how-to-draw-a-line-between-two-points-in-scenekit)

```swift
let eulerAngles 
    = simd_float3(Float.pi / 2,
                  acos((to.z-from.z)/distance),
                  atan2((to.y-from.y),(to.x-from.x)))
```

SceneKitでは上記のEulerAngleの計算でうまく動作しました。
なお、RealityKitでは、ここでのEulerAngleの結果をTransformで初期化してもうまく動作しませんでした。

```
Transfrom(pitch: Float, yaw: Float, roll: Float)
Creates a new transform from the specified Euler angles.
```

## Quaternion

[Draw SceneKit object between two points](https://stackoverflow.com/questions/35002232/draw-scenekit-object-between-two-points)

ここでは2017年3月のTransformの手法が良い回答となっていますが、良い回答からしばらく経った2019年の7月の誰も支持してないQuaternionの回答が良かったのでそれの引用になります。
勿論Transformの手法でも動作することを確認しましたが好みでなかったので割愛です。

手法ですが、長さを求めたうえで内積(cross)と外積(dot)を求めます。

```swift
let vector = to - from
let height = simd_length(vector)
let line_axis = simd_float3(0, height/2, 0)

let vector_cross = simd_cross(line_axis, vector)
let qw = simd_length(line_axis) * simd_length(vector) + simd_dot(line_axis, vector)
let q = simd_quatf(ix: vector_cross.x, iy: vector_cross.y,
                   iz: vector_cross.z, r: qw).normalized
```

### 平行ベクトルにおける問題

[Finding quaternion representing the rotation from one vector to another](https://stackoverflow.com/questions/1171849/finding-quaternion-representing-the-rotation-from-one-vector-to-another)

```cpp
Quaternion q;
vector a = crossproduct(v1, v2);
q.xyz = a;
q.w = sqrt((v1.Length ^ 2) * (v2.Length ^ 2)) + dotproduct(v1, v2);
```
上のコードですと平行ベクトルの場合にハングするようですが、先ほどの線の長さを求める書き方だと一応問題なさそうです。
気づいた方いましたらお知らせください。

正しく制御したコードはEigenの[FromTwoVectors](https://github.com/libigl/eigen/blob/master/Eigen/src/Geometry/Quaternion.h)を参照するのが良さそうです。

## Swift Playground
こちらにコードをあげました。
https://gist.github.com/otmb/9ab1c43774811ad8c5ff697f3538e762

出力すると球と球の間を繋ぐオブジェクトが配置でき、うまく動作しているようです。

<img width="309" alt="スクリーンショット 2020-02-23 2.46.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35973/ae144896-f7d7-3c02-9e9b-85840b47c943.png">
Re:ゼロから始める競技プログラミング生活　初心者が少しでも高いパフォーマンスを取るために~ABC154~156感想を添えて~

お久しぶりです。2週間以上投稿しない間にABC154,155,156受けました。
154がCまで解けてパフォーマンスが104、155がBまでで135、156がCまでで354でした。

・・・なかなか厳しいけど、徐々にパフォーマンスは上がってきた。

そして今回はAtCoder初心者の私が計3回のABCを経験して感じた、プログラミング力ではなく、付け焼き刃の技で少しでもパフォーマンスを高くするやり方を偏見多めで書いていきます。

#C問題を解き終わるまでのスピードが肝
コンテストが開始する前にもう戦いは始まっています！！その回の難易度にも寄りますが、初心者はC問題までで解き終わることが多い（多分）ので、その辺りに人口が集中します。なのでこのC問題までを早めに解けばそれだけでパフォーマンスが上がります。ABC156のC問題までを２５分で解くとパフォーマンスが約600、４０分かけて解くと約350、時間ギリギリだと約100です。

ちなみに、15分で解くと800超えます。俗にいう緑パフォです。笑

15分はしんどいですが、Cまでをある程度早く解くことさえ継続できれば初心者でも理論上は茶コーダーになれます。

じゃあどうやって早く解くのかって話ですよね。以下からは私のような初心者がC問題までを早く解くための付け焼き刃のような方法を書いていきます。

#入力例を変数に入れてコードテストする
これはとても大事です。
AtCoderは提出したコードが間違っていると5分のペナルティーが課せられます（これがかなり順位に影響する）

「いちいちコードテストなんかしていたら時間ロスするじゃん」と思ったそこのあなた！！
初心者を過大評価しています。

初心者はもちろんコードを書くことに慣れていないのでスペルミスや構文ミスが多いです。
そして提出したコードがREで返ってきてペナルティーを喰らうわけです。

A問題でもちゃんとコードテストすることを強く勧めます。
ちなみに、私はABC154でガンガン提出しまくってペナルティー45分喰らいました。笑

#入力例の文章をよく読む
初心者は問題文だけ読んでも何言ってるかわからないです、特にC問題からは。笑
でも入力例の文章を読んでから問題文に戻るとすんなり頭に入ってくることがあります。

問題文を読み返すより早く理解できるためお勧めです。
#コピペを使う
これはせこい。笑
でも、少しでもパフォーマンスを上げるためには必要なことです。ここは悪に染まりましょう。笑
特に関数のコピペは出力時の引数を書き換えるだけなのでお勧めです。

そして、コンテストが終わったらしっかりコピペしたコードの中身をじっくり見て勉強しましょう。**コピペは知識の前借りです！！**

私もABC156で10進数をn進数に変える関数をコピペしたので勉強してきます。笑
#ノートに図を描く
C問題は少し数学的なひらめきがないと解けない場合が多々あります。
しかし、これは逆にチャンスです！！ひらめきさえすれば爆速で提出できます。
https://atcoder.jp/contests/abc156/tasks/abc156_c
このABC156のC問題を例にあげると、問題文に最小値がうんたらと書いてあるけど、結局は座標の中点を求めれば良いだけなのでそれさえ気づくことができれば一瞬で解けます。

やることは数学と同じなのでノートに図だったりを色々書いてみることでひらめきの助けになります。

```python

N = int(input())
X = list(map(int,input().split()))
P = sum(X)/len(X)
P = round(P)
count = 0
for i in range(N):
  count += (X[i] - P)**2
print(count)
```
コードも簡単なので初心者でも検索しながらであればすぐに書けます。本当にひらめきだけです。

こんな得意げに語っておいて私は点Pが整数値だということを忘れていてペナルティー15分喰らったのですが()

#最後に
以上がAtCoder初心者が付け焼き刃で少しでも高いパフォーマンスを取る方法を書いてきたのですが、一番言いたいことは**「凡ミスを失くそう」**です。もうこれに尽きます。

そして、本記事は競技プロブラミング初心者の私が偏見に基づいて書いたものであるため、何か競プロガチ勢の逆鱗に触れるようなことを意図せず書いてしまっていた場合は優しくご指摘くださいm(_ _)m
Unity Accelerator + Prometheus + GrafanaをDockerでサービス化する

# はじめに

Unity2019.3からAsset Pipeline v2が追加されてUnity Acceleratorを組み合わせるとインポートしたアセットをキャッシュおよび共有することができます。

- [Unity Accelerator でチームの作業をスピードアップ](https://blogs.unity3d.com/jp/2019/09/11/speed-up-your-team-with-the-unity-accelerator/)

それまでのUnityにもAsset Pipeline v1とキャッシュサーバーでキャッシュできていましたが、Unity Acceleratorには以下の違いがあります。

- キャッシュサーバーと同居できる
- Collaborateのキャッシュに対応
- 不要なキャッシュを定期的にクリーンアップ
- 転送されたバイト数や接続されたエディターなどの情報をPrometheusから利用できるメトリクスで公開

フォーラムの以下のスレッドによるとDockerHubでイメージが公開されています。

- [Consider making a Docker Container for Accelerator?](https://forum.unity.com/threads/consider-making-a-docker-container-for-accelerator.809115/)
- https://hub.docker.com/r/unitytechnologies/accelerator

Unity Acceleratorは[Prometheus](https://prometheus.io/)とダッシュボードの[Grafana](https://grafana.com/)を組み合わせるとメトリクスを可視化できるのでdocker-composeでサービス化しました。


# Dockerでサービス化

https://github.com/shiena/docker-unity-accelerator

## 設定ファイル

```accelerator.env
COLLAB_REGISTRATION_TOKEN=ft0bJvbRD
DISABLE_USAGE_STATS=yes
```

- [Unity Collaborate](https://unity3d.com/unity/features/collaborate)と連携する場合は`COLLAB_REGISTRATION_TOKEN`にトークンを設定します。
- 統計情報の送信を抑制する場合は`DISABLE_USAGE_STATS`に任意の値を設定します。

## サービスを実行

```
docker-compose up -d
```

サービスを起動するとそれぞれ以下からアクセスできます。

- Unity Acceleratorおよびキャッシュサーバー: 起動したPCのIPアドレス
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000
    - 初期アカウントとパスワードは`admin`と`admin`

Grafanaでは[Unity - Manual:  Unity Accelerator](https://docs.unity3d.com/Manual/UnityAccelerator.html)の一覧にあるメトリクスを扱えます。


## Local Administraotr Dashboard

v1.0.272+gb7c26b9からLocal Administrator Dashboardが追加されて http://localhost:10080 からアクセスできるようになりました。

ConfigurationとLogsは以下のコマンドでパスワード設定が必要です。

```
docker-compose exec accelerator /agent/unity-accelerator tool adminpw mysupersecretpassword ​
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8995/e90e49c8-a792-4b85-b089-fb540a2753c5.png)

# 公式イメージ公開前にDocker化で工夫したこと

- ~~Unity AcceleratorをダウンロードするURLからバージョンが分からないのでバージョンを確認する方法を用意しています。~~
- v1.0.196+ge1f9988で修正されました。~~キャッシュサーバー追加でインストーラーを非対話モードで実行するとnpmのパスが展開されないバグがあるので対話モードprintfで強引にインストールしています。(バグ報告済み)~~
- v1.0.242+gf11031dで修正されました。~~v1.0.196+ge1f9988で初回起動時などpidファイルがなかったり空の時に起動できないバグがあるのでパッチを当てています。~~
- 公式イメージが公開されたので独自Dockerfileから切り替えました。
plotlyでタイトルにハイパーリンクを貼る

# plotly で html を作成

スクレイピング結果をplotlyで可視化したhtmlを見ているときに、
スクレイピング元のサイトに行きたいことがあった。

plotly出力後のhtmlを加工しようと思ったが、
ぐちゃぐちゃしてよくわからなかったので（html初心者なので）、
簡単にできないかと思って色々試していると意外とすんなりできた。


## グラフタイトルに直接&lt;a href="">&lt;/a>を記入する

レイアウト指定部分で、タイトルを指定する際に、

```python

layout = plotly.graph_objs.Layout(
    title={"text":"title"},
    xaxis={"title":"x_label"},
    yaxis={"title":"y_label"},
)
```

ハイパーリンク（&lt;a href="">&lt;/a>）を直接書き込むだけ。
結局タイトルがそのままhtml化されるので、ハイパーリンクが適応される。
仕組みを考えると納得です。

```python

layout = plotly.graph_objs.Layout(
    title={"text":"<a href='{リンク先}'>title</a>"},
    xaxis={"title":"x_label"},
    yaxis={"title":"y_label"},
)
```

### 追記:直接HTMLを記載する方法を発見(Dash)

Dashにて、divタグ等を直接記載している[記事](https://rstudio-pubs-static.s3.amazonaws.com/375295_bc1b2d98c9604a60b56d41b36eeb5780.html)を見つけました。
htmlをリッチにする場合はこちらのほうがいいかもしれない。

↓ 該当部分

```python

app = dash.Dash()
app.layout = html.Div([
    html.H1('Hudson River'),
    html.H2('Site'),
    dcc.Dropdown(
        id='dropdown-site',
        options=[{'label': i, 'value': i} for i in sites],
        placeholder="Select Site",
        clearable=False,
        value='125th St. Pier'
    ),
    html.H2('Date'),
    dcc.Dropdown(id='dropdown-date', 
                 value='2013-10-16'),
    html.H2('Findings'),
    dcc.Graph(id='graph-with-slider')
])

```
pandas v1のgroupbyで複数の統計量を取得したい場合

# 概要
pandasのgroupbyで１つのカラムに複数の関数を適用させるためにdict形式でagg()の引数を与えていたが、v1でその機能が削除されてしまっていたため、使用できなくなった。その解決方法。
データは[pandasのドキュメント](https://pandas.pydata.org/pandas-docs/version/1.0.0/user_guide/groupby.html)にあったものを利用しています。

# データ
```python
animals = pd.DataFrame({'kind': ['cat', 'dog', 'cat', 'dog'],
                                 'height': [9.1, 6.0, 9.5, 34.0],
                                 'weight': [7.9, 7.5, 9.9, 198.0]})
```

<img width="171" alt="スクリーンショット 2020-02-23 0.59.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231357/725cefd8-7f68-8f23-4afd-5c18770785b0.png">

# 今回やろうとした処理とエラー
```python
# kindごとに、heightの合計値と件数を集計し、それぞれ"sum_all", "count_all"という名前にする
animals.groupby("kind")["height"].agg({"sum_all":"sum", "count_all":"count"})
```
- 想定していた出力(v1になる前はできてた)
<img width="174" alt="スクリーンショット 2020-02-23 1.05.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231357/519ce73f-7ca5-997b-2b23-f0ab24e7b844.png">

- 実際の出力

```
SpecificationError: nested renamer is not supported
```



# 何が原因だったか
- ドキュメントのwhats newに記載があった
    - https://pandas.pydata.org/pandas-docs/stable/whatsnew/v1.0.0.html
    - nested renamingというらしいが、これがなくなったらしい

>Removed support for nested renaming in DataFrame.aggregate(), Series.aggregate(), core.groupby.DataFrameGroupBy.aggregate(), core.groupby.SeriesGroupBy.aggregate(), core.window.rolling.Rolling.aggregate() (GH18529)

- 以下に記載がありますが、一つのカラムに対してaggregationとrenameを同時に行うことがいけないらしい
    - https://pandas.pydata.org/pandas-docs/stable/whatsnew/v0.20.0.html#whatsnew-0200-api-breaking-deprecate-group-agg-dict

# 解決方法
- 集約とrenameを同時に行っていることが問題なので、それを分ければ良い

```python
animals.groupby("kind")["height"].agg(["sum", "count"])
                                 .rename(columns={"sum": "sum_all", 
                                                  "count":"count_all"})
```

- [Named Aggrecation](https://pandas.pydata.org/pandas-docs/version/1.0.0/user_guide/groupby.html#named-aggregation)(v0.25からの機能)を利用する

```python
animals.groupby("kind")["height"].agg(sum_all="sum",
                                      count_all="count")
```

- (参考)カラムをしていない状態でのNamed Aggrecationだと以下のような書き方になる
    - この書き方だとどの変数に対して集約するか指定できるのでわかりやすい

```python
animals.groupby("kind").agg(sum_all=("height", "sum"),
                            count_all=("height", "count"))
```

# 参考
- https://pandas.pydata.org/pandas-docs/version/1.0.0/user_guide/groupby.html#aggregation
- https://stackoverflow.com/questions/60229375/solution-for-specificationerror-nested-renamer-is-not-supported-while-agg-alo
VBScript超速入門

# VBScript超速入門

## はじめに

いまさらながらVBScript（以下VBSと記）についての入門を書いてみる。
なぜ過去の遺産にもなりつつあるVBSについて書くかというと、単純に業務で既存VBSのコードを改修することになったから。なので自分の勉強とノートを兼ねている。
Windowsのシェルをこれから勉強したいならVBSではなくPowerShellをおススメする。

## コメント

一行コメントは以下のようにシングルクォートか Rem を使う。

```vb
' コメント
Rem これもコメント
```

VBSには複数行コメントはない！

## 変数

VBSは動的型付けの言語。なので変数は宣言せずとも使えたりする。

```vb
v = 1
```

ただ、変数宣言の構文も用意されている。

```vb
Dim v ' 変数宣言
v = 1
```

ちなみに宣言と同時に初期化とかやりたくなるけど、これはエラーになるので注意。

```vb
Dim v = 1 ` これはエラーになる
```
## 定数

定数には **Const** を使う。
定数は**宣言と同時に初期化**できる。というか初期値を代入しないといけない。あたりまえだけどそのあと変更することはできない。

```vb
Const c = 1
```

## 配列

### 固定長配列

VBSで配列を使うには以下のように宣言。

```vb
Dim arr(2)
arr(0) = 0
arr(1) = 1
arr(2) = 2
```

JavaとかCの配列は、指定する数がそのまま要素数になるのだが、VBSでは指定できる最大インデックスになる。つまり、上記の指定だとインデックスが 0 から 2までの3要素をもった配列になるので注意。かくいう自分も勘違いしてた。。

### 動的配列

動的配列を使う場合は ReDim を使う。注意点としてReDim を使う対象の配列変数の括弧の中は空にしておくこと。

```vb
Dim arr()

ReDim arr(2)
arr(0) = 0
arr(1) = 1
arr(2) = 2
```

ただ、上記の記述だと再度拡張したときに、もとのデータが消失してしまう。
もとのデータを保持したまま拡張する場合は、拡張時に Preserve を付ける。

```vb
Dim arr()

ReDim arr(2)
arr(0) = 0
arr(1) = 1
arr(2) = 2

ReDim Preserve arr(3)
arr(2) = 3
```


## 制御文

条件分岐とループっていう制御文について。

### 条件分岐

VBSの条件分岐は If と Select Caseがある。

#### If文

まずは if文から。

```vb
If a = 1 Then
  ' 処理1
ElseIf a = 2 Then
  ' 処理2
Else
  ' 処理3
End If
```

#### Select Case

お次はいわゆるSwitch文。VBSでは**Select**だけどね。

```vb
Select Case a
Case 1
  ' 処理1
Case 2
  ' 処理2
Case Else
  ' 処理3
End Select
```

他の言語でよくあるswitch文のbreakは必要ない。

### 繰り返し（ループ）

VBSの繰り返しは大きく分けて For と While がある。

#### For文

```vb
For i = 1 To 3
  ' 処理
Next
```

残念ながらVBSには他の言語でいう continue 的なものが存在しない。

#### While文

```vb
While a = 1
  ' 処理
Wend
```


## 関数

VBSには**Subプロシージャ**と**Functionプロシージャ**という二種類の関数が存在する。
その違いは戻り値があるかないか。

### Subプロシージャ

Subプロシージャは**戻り値がない**関数。

```vb
Sub sampleSub
  ' 処理
End Sub
```

### Functionプロシージャ

Functionプロシージャは**戻り値がある**関数。
戻り値の返したかたが、関数名と同名の変数に代入するという独特の返しかたなので注意。

```vb
Sub sampleFunc
  ' 処理
  sampleFunc = 1 ' 戻り値
End Sub
```

## クラス

なんとVBSでは**クラス**を扱える。

### クラス定義

```vb
Class Sample
  ' フィールドおよびメソッドを定義
End Class
```

#### コンストラクタ

VBSのコンストラクタ名は Class_Initialize。

```vb
Class Sample
  Sub Class_Initialize
    ' コンストラクタの処理
  End Sub
End Class
```

### インスタンスの生成

インスタンスの生成は **newキーワード**を使うというのは他の言語と一緒。
ただし注意点は インスタンスを格納する変数の前に**Set を付けないといけない**ということ。

```vb
Dim a
Set a = new Sample
```

## 参考にしたサイト

[公式ドキュメント](https://docs.microsoft.com/ja-jp/previous-versions/windows/scripting/cc392489(v=msdn.10))

[VBScript入門講座](http://vbscript.web.fc2.com/)
Unityでスプライトシートを使ってアニメーションさせる方法

#はじめに
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591107/6cc5f9f3-0be0-c57d-38ef-b66127516740.png)
一枚の画像でアニメーションする方法を紹介します。
経緯としては普段のゲーム開発環境では一枚一枚をプログラムで読み込む作業があったのですが、
なんとunityでは簡単な設定でできるらいしいので試してみます。
#設定
- 画像を用意
 - 画像をproject>assets>imageに投下
 - ![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591107/d985b61a-0c68-87da-449a-9a9541f6ef3d.png)

- 画像の設定方法
- Pixels Per Unityを設定
    - 今回は一つの画像が300*300なので(300)に設定しました。300ピクセルを１ユニットに設定
- Filter Modeの設定
    - 画像もドット絵なのでPoint(no Filter)に設定
- Compressionの設定
    - Noneに設定
- Sprite Modeの設定
    - スプライトエディターで画像を編集したいのでMultipleに設定
- 今までの設定は以下
    - ![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591107/41e759bc-b98a-c316-992e-7e1cc6058552.png)

#編集開始！
- Sliceを押下
![キャプチャ33.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591107/6026c77e-5788-a605-1a04-1cf509d6133d.png)

- あと適当に設定する
    -  自分の場合
    -  TypeをGrid By Cell Sizeに設定
    -  一枚の画像サイズを設定する(300*300)
- エディットでサイズが任意のものになっているか確認し「Apply」を押下する。
- あとは画像を実行画面にドロップしてアニメーションファイルを保存する。
#実行して確認してみる
- gifで出力する方法がわからないので、
- いまいちなのですが、何とかアニメーションすることができました。
 ![キャプチffffャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591107/9db03980-c6c3-8201-1e51-3e48f6aa0dbd.png)
xib、storyboardのstringsファイルへの追加方法

## はじめに

Interface Builder を多言語対応するには、以下の２つの方法で対応が可能です。
1. Interface Builder Storyboard : 言語毎にStoryboardを作成しレイアウトを設定
2. Localizable Strings : レイアウトは同じで言語毎のstringsファイルを作成

今回、後者を選択後に新たにリソースをstringsファイルに追加する方法です。
情報が少なく見つけにくかったので、忘備録として以下に記しておきます。


## 環境

* macOS Catalina 10.15.2
* Xcode 11.3.1


## 手順

手順は参考元にあるとおり。

xib、storybaord は Base.lproj フォルダに格納されているので、そこでコマンドを実行。
言語.lproj にstringsファイルが格納されているので、マージすれば追加できます。


## 参考元

[Updating Storyboard and Xib Strings Files Using ibtool](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/MaintaingYourOwnStringsFiles/MaintaingYourOwnStringsFiles.html)

> Updating Storyboard and Xib Strings Files Using ibtool
>
> When you change user-facing text in .storyboard or .xib files, use the ibtool command to generate new strings files. Use another tool—for example, FileMerge—to identify the changes and merge them into the existing strings files for each language you support. Xcode doesn’t automatically update the corresponding strings files when you edit a .storyboard or .xib file.
>
> In Terminal, change to the Base.lproj folder, and run this command to generate a strings file for an xib file:
>
> ``` 
> ibtool [MyNib].xib --generate-strings-file [MyNib_new.strings]
> ```
>
>Optionally, localize the changes in the output file before merging the changes with the [MyNib].strings file in each lproj folder. To launch FileMerge from Xcode, choose Xcode > Open Developer Tool > FileMerge.
>
> Alternatively, you can use the ibtool command to merge translations back into a nib file and perform other incremental localization updates, as described in the ibtool man page. Or use the appleglot command to manage changes to the strings files, as described in Importing Localizations.
debian mariadb 外部接続

# bindコメントアウト

```
vi /etc/mysql/mariadb.conf.d/50-server.cnf 
# コメントアウト
#bind-address           = 127.0.0.1
```
##確認

```
select user, host from mysql.user;
```
## 権限追加
```
GRANT ALL PRIVILEGES 
ON app_db.* TO some@"192.168.%" 
IDENTIFIED BY 'pass1234' with grant option;
FLUSH PRIVILEGES;
```
[ubuntu]Google Testの導入方法

#概要
仕事でGoogle Testを使うことになったので導入方法などをメモ。
#環境

- Ubuntu 18.04.4 LTS
- Google Test v1.10.0


#1. ダウンロード

```
curl -OL https://github.com/google/googletest/archive/release-1.10.0.tar.gz
```

#2. 解凍

```
tar -zxvf release-1.10.0.tar.gz
```

#3. ビルド & インストール

```
mkdir -p googletest-release-1.10.0/build
cd googletest-release-1.10.0/build
cmake ..
make install
```

/usr/local/includeと/usr/loca/lib下にヘッダファイルとライブラリが展開されるので、あとはそれらをテスト環境に取り込むだけ。

#4. テスト
```C++:ソースコード
#include  <gtest/gtest.h>

//テスト対象の関数
int sum(int a, int b){
    return a+b;
}

//テストコード
TEST(TestCase, sum) {
    EXPECT_EQ(2, sum(1,1));        //OK
    EXPECT_EQ(1000, sum(123,877)); //OK
    EXPECT_EQ(-8, sum(-12,3));     //NG
}
```

```:ビルド
g++ test.cpp -lgtest_main -lgtest -lpthread -o test
```
libpthredもリンクする必要がある。

```:テスト結果
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from TestCase
[ RUN      ] TestCase.sum
test.cpp:10: Failure
Expected equality of these values:
  -8
  sum(-12,3)
    Which is: -9
[  FAILED  ] TestCase.sum (0 ms)
[----------] 1 test from TestCase (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 0 tests.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] TestCase.sum

 1 FAILED TEST
```
raw-cpuidのcpuid!マクロが便利

チッス！ｗ

Rustでcpuidを使うときは[raw-cpuid](https://github.com/gz/rust-cpuid)が便利です。
しかしこのcrateはfunctionallyに扱えて便利なのですが、新しい機能をサポートしてなかったりAMDが提供しているやつにアクセスする手段がなかったりときどき困ることがあります。
ライブラリにパッチを投げて機能を追加してもらうのが本来よいのですが、まあとりあえず手元でゴニョっとしたい…というときに `cpuid!` マクロを使うという手段があります。

例としてCore i7以降で追加されたProcessor Topologyを使ってみましょう。

```rust
use raw_cpuid::cpuid;

fn main() {
    /// For Intel Core I7 and later, use `0x0B` to determine number of processors.
    ///
    /// https://www.scss.tcd.ie/Jeremy.Jones/CS4021/processor-identification-cpuid-instruction-note.pdf
    ///   5.1.12 Processor Topology
    let cpu_info = cpuid!(0x0B);
    let threads_per_core = cpu_info.ebx & 0xFFFF;
    println!("{}", threads_per_core);
}
```

便利ですね。
Raspberry PiのBad Knowledge

## はじめに
Raspberry Pi（以下RPi）からLinuxを触り始めた人も多いと思います。
そのせいなのかわかりませんが、RPi関連の日本の記事はあまりよくない設定を推奨している場合が多々見受けられます。
（あまりよくない設定の記事を最初に書いた人からずっとよくない知識が受け継がれているのだと思うのですが・・・）
なので、きちんとした設定を書こうと思います。
※ちなみに、ここに記載されていることのほとんどは公式のドキュメント([Raspberry Pi Documentation
](https://www.raspberrypi.org/documentation))を読めば書いてあるので、時間がある人はしっかり公式の物を読みましょう。

今回はRaspberry Pi OS向けに書いています。（2020年5月頃にRaspbianから名称が変更されました）

※特定の人を批判する目的で記載したわけではありません。

## 開発に最低限必要な物について
開発に使用できるパソコンを持っているという前提で書くと、よく書かれている

- HDMIケーブル
- モニタ
- キーボード
- マウス

は最悪なくてもいいです。RPiはヘッドレスインストールが出来る為、モニタ類がなくても設定は一通り出来るんですね。更にGUIを使用したい場合もVNCなどで繋げればいいです。ただ、完全に必要ないかと言われればそうではなく、リモート接続（OTG接続）が出来なくなった場合にモニタ類を直接繋いで何が原因か切り分けできたりするので持ってれば嬉しいレベルです。

※あまりいないとは思うのですが、Linux初心者の方でRPi上でGUIを使用して開発するぞ！って人や、CLIに恐怖を感じるレベルの人はこれらは持ってた方がいいかもしれないです。余計な躓きから開放されます。

## セキュリティについて
よく書かれている
> rootパスワードを設定しましょう！

これは嘘です。設定してはいけません。これはあえて設定されていません。設定されていない場合は使用不可となりますが、設定してしまうと使用可となってしまう為です。自らセキュリティ的に脆弱にしています。

## ssh有効化について
よく書かれている
> mkdir /boot/ssh

これは微妙です。マニュアルには以下のように記されています。
> When the Raspberry Pi boots, it looks for the ssh file. If it is found, SSH is enabled and the file is deleted.
google翻訳：**Raspberry Piが起動すると、sshファイルが検索されます。見つかった場合、SSHが有効になり、ファイルが削除されます。**

しっかりと**ファイル**と記載されていますね。また、**ファイルは削除されます**とのことなのでディレクトリは削除されません。ゴミが残ります。下記ユニットファイルを参照すればわかります。

```/lib/systemd/system/sshswitch.service
[Unit]
Description=Turn on SSH if /boot/ssh is present
ConditionPathExistsGlob=/boot/ssh{,.txt}
After=regenerate_ssh_host_keys.service

[Service]
Type=oneshot
ExecStart=/bin/sh -c "systemctl enable --now ssh && rm -f /boot/ssh ; rm -f /boot/ssh.txt"

[Install]
WantedBy=multi-user.target
```

これは起動時に実行される為、前述の**ディレクトリを作成してSSHを有効化する**方法の場合、**セキュリティ上の理由で後からSSHを無効にした際に再起動するとまたSSHが有効になる**、という問題が起きてしまうんですね。

## IPアドレスについて
これは別に悪いことではないんですが、もっと簡単な方法がありますよーという紹介です。

よくある記載で、
> （SSHする際に）IPアドレスを確認して〜、固定IPアドレスを設定して〜

というのがあると思うのですが、新し目の開発環境であればBonjour(mDNS)を使用してSSHすることができます。
ちなみに以下のような感じで接続します。

```bash
root@0ec7cd4678a7:~# ssh pi@raspberrypi.local
```

## おわりに
初学者に人気のコンテンツって、どうしてもアクセス数目当てで適当なことを書く人が多くなるイメージがあります。
何が正しいかをしっかり見極めた上で楽しいLinuxライフを送っていきましょう！
手探りDocker #2

前回の記事の続きになります。
[手探りDocker #1](https://qiita.com/GodPhwng/items/2edf8792630674a2f811)

次の記事
[手探りDocker #3](https://qiita.com/GodPhwng/items/9711d0648cf358361882)

# サンプルアプリケーションのインストール
前回も参考にしたサイト[docker docs](https://docs.docker.com/docker-for-windows/dashboard/)
の以下を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/a312ba77-8fd5-ae69-d18e-df2dd337524a.png)

以下のGitHubのリポジトリをクローンし、クローンしたフォルダに移動して以下コマンドを打ちます。
https://github.com/dockersamples/example-voting-app
以下コマンドを打って「投票アプリ」を起動？します。
`docker-compose up --build`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/587a54b1-0e83-50c9-d5bb-39dca0fac887.png)

実行するとPythonのエラー？警告？が出ている。

他にも
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/66eb79cb-ca39-a55a-fe12-95b8fecfecd4.png)
や
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/f98156a3-d498-0ac7-c493-db9d7223707a.png)
その他に
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/5a8f91e0-441b-ae20-a618-43fda967acc0.png)
と警告やエラーが出ている・・・

挫折しそう・・・

まず**1つ目のエラー**から調査していきます。
google翻訳に入れてみたところ、

```
非推奨：Python 2.7は2020年1月1日にサポートを終了しました。
Python2.7のメンテナンスが終了したため、Pythonをアップグレードしてください。 
pipの将来のバージョンでは、Python 2.7のサポートが廃止される予定です。
 pipでのPython 2サポートの詳細については、
https：//pip.pypa.io/en/latest/development/release-process/#python-2-supportを参照してください。
```
警告っぽいです。学習用なので、このまま進めようと思います。

次に**2つ目のエラー**
ググってみたところ、OSがMACでないために表示される警告の模様
[npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.0.14](https://stackoverflow.com/questions/40226745/npm-warn-notsup-skipping-optional-dependency-unsupported-platform-for-fsevents)
警告なので問題ないとの意見がちらほらみられるので、これもこのままとする

**3つ目のエラー**
訳すと「強制的にあなたが何をしているかを知っていることを願っています」とのこと
全然意味が分からない
調べてみるとnpmのキャッシュをクリアすると解消するらしい。
でもコマンドで打ったのは`docker-compose up --build`だけですから、どうすりゃいいのよって感じです。
警告なのでとりあえず飛ばします。

**最後のエラー**
`example-voting-app_vote_1`と`example-voting-app_result_1 `のコンテナが開始できていないらしい
以下のような画面がでていた。ドライブ共有が原因っぽい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526982/caffa5c2-e045-3c6e-70e4-14a65a5143c2.png)

`Share it`を選択しても解決はしなかった。

今日はここまで・・・

[次回](https://qiita.com/GodPhwng/items/9711d0648cf358361882)
Unityでスクリプトがアタッチできない！

##発生したエラー
タイトルの通り、スクリプトをアタッチしようとすると、
`Can't add script behaviour 〇〇. The script needs to derive from MonoBehaviour!`
とエラーが出ます。
調べてみるとファイル名とクラス名が不一致の場合に起こるエラーのようですが、もちろん一致していますし、再インポートしても治りません...。
絶望的な気分でしたが、なんとか解決したので共有します。

ちなみにUnityのバージョンは "2018.4.17f1" です。

##解決
気が付かなかったのですが、アタッチ時にコンソールにて詳細なエラーメッセージが表示されていたようでした笑
みんなもコンソールはちゃんと確認しよう（戒め

コンソールのメッセージによると、今回使用していたUnityちゃんのアセットパッケージに含まれていたスクリプトにエラーが発生していたようでした。
[Unity AssetStore / "Unity-Chan!" Model](https://assetstore.unity.com/packages/3d/characters/unity-chan-model-18705)

どうやら一つでもスクリプトに不備があると他のスクリプトもアタッチできなくなってしまうようですね。(間違ってたら申し訳ない)

エラーを起こしているスクリプトを修正すると、無事ほかのスクリプトもアタッチすることができるようになります。

##さいごに
今回はコンソールの確認不足という恥ずかしいオチでしたが、参考になれば幸いです。
抜けている情報や誤りがあれば改善しますのでコメントにてお願いします。
Jupyter notebook のカスタマイズ

# Jupyter notebook のカスタマイズ

Jupyter notebook のデフォルトの文字がすごく見づらかったのでカスタマイズしてみた．

# インストール
pipを使ってjupyterthemesをインストール


```:terminal
pip install jupyterthemes
pip install --upgrade jupyterthemes
```

Optionなどの細かい話は[ここ](https://github.com/dunovank/jupyter-themes)を参照.

# 自分のカスタマイズ
色々なfontを試した結果現在は以下の設定.


```:terminal
jt -t oceans16 -f hack -tf latosans -tfs 105 -nf opensans -nfs 105 -cellw 1200 -T -N
```
ONTシーケンスのデータで de novo assemblyがしたい

訳あってde novo assemblyをすることになった。
ロングリード、ショートリード、 Hi-Cの三点盛りでアセンブルするぞ！

おおまかな流れ
1. DNA抽出->シーケンス
2. flyeでアセンブル <-今回はここまで
3. racon, pilonでポリッシング
4. BUSCOによるアセンブリ評価
5. Hi-Cで染色体スケールのスキャフォールディング
6. アノテーション

#### 材料について
材料:
イネ科の植物の若めの葉っぱ

ゲノムサイズ:
400Mbくらい

DNA抽出:
ロングリード用:
伝統的なCTAB法 (DNAをくるくるっとまきとるやつ)で抽出後、断片化DNAをShort Read Eliminator (日本ジェネティクス SS-100-101-01)を用いて除去
CTABの方がNucleoBond HMWより長いのが取れている気がする。粘り気が全然違う。...気がする。
イルミナシーケンス用:
DNeasy (Qiagen)

ライブラリ調整&シーケンス:
ONT:
ここから先は外注（いつか自分でもやってみたい）
Illumina:
Kapa Hyperのキット
PCRは3cycle (ほんとはPCRフリーの方が良かったようだ)
だいたい数千万リード 150 PE
Hi-C:
ビオチンがアホみたいに高いのでUeli labのプロトコルを多少モディファイして系を小さくした。
今回はHind IIIで切った。



解析サーバー:
DDBJのスパコン

----
#### Step.1 flyeによるde novo assembly
Kolmogorov. et al. *nature biotechnology* (2019)
https://github.com/fenderglass/Flye

1.1. condaでインストール

```shell
conda install -c bioconda flye
```

1.2. de novo assembly
今回はONTシーケンスはとくに前処理なし。error-correctionや、長いリードだけ取ってくるなどした方がいいらしい。
N50: 20kbくらい
平均長: 10kb弱
だいたいゲノムの100xくらいのカバレッジ

```sh
#!/bin/sh
#$ -S /bin/sh
#$ -cwd

##### シェルスクリプトを使用する場合、パスを明示しないとどうもうまくいかない
export PATH=$PATH:~/miniconda3/bin/

#### 仮想環境の立ち上げ
#### 仮想環境を作ってそこにインストールしたので
source activate nanopore

flye --nano-raw hoge.fq.gz \
 --out-dir output \
 --genome-size 400M \
 --threads 16
```
`--out-dir` 出力するディレクトリ名の指定
`--nano-raw` ONTの場合はこのオプションをつける
`--genome-size` おおよそのゲノムサイズを指定
`--threads` 使用CPU数

以上のスクリプトを下のようなオプションつけて投げた

```sh
qsub -l s_vmem=128G -l mem_req=8G -pe def_slot 16 hoge.sh
```
だいたい1日ちょっとでアセンブルが終わった。

アセンブル結果の確認はseqkitが便利
Shen et al. *PLOS ONE* (2016)
https://bioinf.shenwei.me/seqkit/
以下のコマンドでおおよそのアセンブル結果を得る

```sh
seqkit stats -a hoge.fasta
```

つづく
Andoird端末上で Linux を遊ぶ 1


AndroidにLinux環境を入れれるアプリ「[UserLAnd](https://play.google.com/store/apps/details?id=tech.ula&hl=ja)」の備忘録です。

**動作確認環境**
- UserLand v2.6.5
- Ubuntu 18.04
- MIUI 11 (Android 10)
- Xiaomi Redmi K20 Pro / 非root状態

# UserLAndとは

Android端末上でLinuxディストリビューションを扱えるようにしたアプリです。root作業は非特権ユーザが疑似的にroot作業を行える proot の仕組みを利用しているみたいです。Linuxに詳しくない自分には正直良く分かりません。

# インストール～起動まで
## 初回起動時
1. 「[UserLAnd](https://play.google.com/store/apps/details?id=tech.ula&hl=ja)」をインストールして起動します。GUI画面が開きます。
1. 画面内「Distribution」で動作させるLinuxを選びます。今回は Ubuntu を選択。
1. 初回起動時に Username、Password、VNC_Password を設定する画面が表示されます。適宜入力して「Continue」をタップでインストールが開始します。
1. インストール時間は端末や回線に依存するので、画面が切り替わるまでは待ちましょう。
1. 初回起動では SSH、VNC、XSDL のどれで接続するか聞かれます。今回は SSH を選択。
1. シェル画面に移行します。パスワードを入力してログインします。

## 終了と2回目以降の起動
1. UserLAndのGUI画面より終了は行います。GUI画面を立ち上げます。
1. 画面内「Distribution」で停止させるLinuxを長押し→「Stop App」とすると終了します。
1. 再度起動したい場合、画面内「Distribution」で動作させるLinuxを選びます。
1. 2回目以降の起動では接続設定やパスワード設定は聞かれません。
1. 接続設定を変更したい場合、画面内Linuxを長押し→「App Info」から変更可能です。


# Ubuntu 18.04 インストール直後

インストール直後なので、パッケージ更新しておきましょう。

```shell
$ sudo apt update
$ sudo apt upgrade
```

Ubuntu18.04からデフォルトで ifconfig が使えないようです。
個人的には不便なので net-tools を入れて ifconfig を使えるようにします。

```shell
$ sudo apt install net-tools

$ ifconfig
Warning: cannot open /proc/net/dev (Permission denied). Limited output.
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 1000  (UNSPEC)

wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.1.98  netmask 255.255.255.0  broadcast 192.168.1.255
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 3000  (UNSPEC)

```

ifconfig コマンドでIPアドレスを確認出来ます。SSHサーバ起動済みなので、以降は端末ソフトでPCから作業すると楽です。ポート番号は **2022** で、dropbear という軽量SSHサーバが立っています。

スマホのCPUやメモリに余裕がある場合はデスクトップ環境を入れても良いです。軽量デスクトップ環境の「LXDE」をサポートしているので、それを入れます。

```shell
$ sudo apt install lxde
```

とりあえず最低限の設定は以上です。
あと何回かは、自分のLinux学習も兼ねて記事を書いてみようかと思います。



# UserLAnd特有の問題と思われるもの

UserLAnnd特有というか、proot 動作しているシステム全般かもしれない。

## systemctl コマンドは失敗する。

以下エラーが出るため、systemctlコマンドは失敗します。
serviceコマンドの場合は上手くいきます。

```shell
$ sudo systemctl start apache2
System has not been booted with systemd as init system (PID 1). Can't operate.

$ sudo service apache2 start
 * Starting Apache httpd web server apache2
```
猫の日だにゃったにゃので、猫っぽい言葉に変換するものを作ってみたにゃ

###なんでまとめたにゃ？
今日が02/22（猫の日）だにゃったにゃので何とにゃくまとめてみましたにゃ
→気づけば、日付またにゃいでて、02/22に間に合ってにゃいけどにゃ！

普通に、読みづらいのと、恥ずかしいので、以降は普通に書いていきますね。


###環境は？
[Google colaboratory](https://colab.research.google.com/notebooks/welcome.ipynb?hl=ja)を使用しサクッと簡単なものを作りました。
簡単に記述しておくと、Google提供のブラウザ上から無償で使用できる、Jupyter Notebook環境ですね。
スマートフォンなんかからも、アクセスしてエディット＆実行できます。（すごい便利）


###どんなふうに？
1.入力された日本語をローマ字に変換（ライブラリ：pykakasiを使用）
2.ローマ字を猫っぽく変換（ただの置換）
3.ローマ字を日本語に再変換（ライブラリ：romkanを使用）
4.以上

###実際の中身については？
使用しているライブラリは以下です。

|ライブラリ名|内容|リンク|
|:-----------------|:-----------------------------------------|:-----------------------------|
|pykakasi|日本語（漢字・ひらがな・カタカナ）→ローマ字変換|https://github.com/miurahr/pykakasi|
|romkan|ローマ字→日本語（ひらがな・カタカナ）変換|https://pypi.org/project/romkan/|

#####サクッとライブラリインストール
```python
pip install git+https://github.com/miurahr/pykakasi romkan 
```

#####コード
```python:
# coding: utf-8
from pykakasi import kakasi
import romkan

#日本語→ローマ字
def j2roma(jtext):
  kakasi_ = kakasi()

  kakasi_.setMode('H', 'a')  #ひらがな→ローマ字
  kakasi_.setMode('K', 'a')  #カタカナ→ローマ字
  #kakasi_.setMode('J', 'a') #漢字→ローマ字
  kakasi_.setMode("s", True) #分かち書き

  conv = kakasi_.getConverter()

  #print(jtext)
  return conv.do(jtext)
  #char_list = list(conv.do(filename))
  #print(char_list)

#猫っぽく変換（ここに変換するローマ字を追加）
def s2h(rtext):
    dst = rtext.replace("na","nya")
    dst = dst.replace("ta","tanya")
    dst = dst.replace("da","danya")
    return dst

#ローマ字→日本語
def roma2j(rtext):
    return romkan.to_hiragana(rtext)

#メイン
def nyaa(jtext):
  rtext = j2roma(jtext)
  rnyan = s2h(rtext)
  jnyan = roma2j(rnyan)
  return jnyan

```

#####実行＆リザルト

```python:実行
nyaa("メロスは激怒した。必ず、かの邪智暴虐じゃちぼうぎゃくの王を除かなければならぬと決意した。")
```

```python:リザルト
'めろす は 激 怒 したにゃ。 必 ず、 かの 邪 智 暴 虐 じゃちぼうぎゃくの 王 を 除 かにゃければにゃらぬと 決 意 したにゃ。'
```


#まとめ

意外とそれっぽくなりますね、あと、ねこはかわいい。


#参考
[Pythonを使ってフェフ姉言葉に変換してみた件](https://qiita.com/satsukiya/items/a99b2736831015115701)
flexboxで画像と文字の横並びアイテムを作る

# はじめに
画像と文字の横並びをいい感じに作りたかったので、順を追って試してみたときのイメージ図を備忘録として残していく。

目標としてはこんな感じ。
<img width="346" alt="(0).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/be27eac8-0246-9e1d-64c1-3e4f61ca4d7c.png">

## 環境
※以下を使用する。
flexbox
bootstrap 4系

## まずはflexboxを使ってみる
<img width="349" alt="(1).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/9792ae75-7f0f-3c70-6d6c-ab2fee3921bb.png">

```style.css
.img-container{
  display:flex;/* flexbox */
}
```
```index.html
<div class="img-container">
  <img src="img.png">
  文言
</div>
```
デフォルトは横並びみたいです。imgと文言がくっついちゃいます。

## 水平方向に真ん中にしてみる。
<img width="344" alt="(2).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/e2146e38-4430-a55f-7039-fab5ba1e1c3f.png">

```style.css
.img-container{
  display:flex;/* flexbox */
  justify-content:center; /* 水平方向 */
}
```
```index.html
<div class="img-container">
  <img src="img.png">
  文言
</div>
```
文言が真ん中にならないので何とかしなきゃ

## 垂直方向を真ん中にしてみる
<img width="344" alt="(3).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/77e73092-a1e7-ce21-d805-258633def985.png">

```style.css
.img-container{
  display:flex;/* flexbox */
  justify-content:center; /* 水平方向 */
  align-items: center; /* 垂直方向 */
}
```
```index.html
<div class="img-container">
  <img src="img.png">
  文言
</div>
```
画像と文字がくっついちゃってる。ぴったしくっついてる。余白明けたい。

## 余白を開けてみる。(ゴール)
<img width="372" alt="(4).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/377612/ade047ea-9fe8-5a86-1f62-c9e22435baa7.png">

```style.css
.img-container{
  display:flex;/* flexbox */
  justify-content:center; /* 水平方向 */
  align-items: center; /* 垂直方向 */
}
```
```index.html
<div class="img-container">
  <img class="mr-3" src="img.png">
  文言
</div>
```
bootstrapでmr-3を使ってイメージの右側に余白を開けてみた。
【Javascript】関数の引数の使い方

⑴記事の背景
学習の一環として、【Todoリスト】を作成していく中である関数の外部で中で定めた定数を外の関数でも使用したいときにどのようにすれば使えるのか教えてもらい、それを忘れない為。備忘録。

引数とは：プログラムやある特定の数値などで、関数に渡すもの

書き方：
const 関数名　 = function(引数名１,引数名2){
    処理（例：return 引数1 + 引数2)
};
console.log(3,5) ▶️　８
引数名１や引数名２などは、自分で好きな名前を付けられる。
実際に関数を使うときに具体的な名前や数値などを入力すれば良い。

＜Todoリスト作成時に使った内容＞

```js

 for (let i = 0; i < radioBtn.children.length; i++) { 

             if (radioBtn.children[i].checked === true) { 
                 changeTodoDisplay(radioBtn.children[i].value); 
                 console.log(radioBtn.children[i].value); 
             } 
         } 

const changeTodoDisplay = function (radioBtnState) { 
        console.log(radioBtnState); 
        if (radioBtnState === 'all') { 
             todoShow(todos); 
       }; 
         if (radioBtnState === 'working') { 
             const filterTodo = todos.filter(function (todo) { 
                 return todo.stateBtn.textContent === "作業中"; 
             }); 
             todoShow(filterTodo); 
             console.log(filterTodo); 
         }; 
         if (radioBtnState === 'complete') { 
             const filterTodo = todos.filter(function (todo) { 
                 return todo.stateBtn.textContent === "完了"; 
             }) 
             todoShow(filterTodo); 
         }; 
     } 
```
今回、forの中で取り出したvalueを具体的な引数（radioBtn.children[i].value）として渡して、関数の中で使っている。　※radioBtnState＝radioBtn.children[i].value

引数を使う事で、ある関数の中で定めた定数でも、外の関数の中で引数として渡して使用することができる。
numpyの1次元配列のshapeがややこしかった

#概要
numpy初心者向けの記事です。Pythonを使い始めて間もない頃、1行列のshapeの出力について勘違いしてました。割と引っかかりやすいんじゃないかなと思い、実例をもとに共有いたします。

#例
まず以下のarrayのshapeを見てみる。

```
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a.shape)
```
出力は以下のようになります。

```
(2, 3)
```
左側に行列の行、右側に列が表示される。数学的にも2行3列と表現されるので納得。

```math
\begin{bmatrix}
1 & 2 & 3 \\
4 & 5 & 6
\end{bmatrix}
```

行を一つ減らして、再びshapeを出力してみる。

```
b = np.array([1, 2, 3])
print(b.shape)
```

出力は以下。

```
(3, )
```

...? 1行3列で、(1, 3) が出力されると思ったけど違った。。

以下のように行列積を計算してみる

```
a = np.array([2, 2])
b = np.array([[1, 2], [3, 4]])
print(np.dot(a, b))
print(np.dot(b, a))
```

すると、結果は

```
[ 8 12]
[ 6 14]
```

行列積の計算の際は、もう一つの行列の shape に応じて、柔軟に行ベクトル、列ベクトルとして計算してくれることがわかる。

#まとめ
一次元配列のshapeは要素が1個のタプルになり、(要素数, )として表現される。数学的には1つの行のみを持つ行列を行ベクトル、1つの列のみを持つ行列を列ベクトルと呼ぶが、ndarrayの一次元配列では行ベクトルと列ベクトルの区別はない。
firefox でタブバーや URL バーを非表示にする

作ったものをアプリっぽい見た目にしたくなったので

1. `firefox -P` で新しいプロファイルを作成して `firefox -p ${profile_name}` で起動
2. url bar に `about:config` と入れて `toolkit.legacyUserProfileCustomizations.stylesheets` を `true` にする
3. url bar に `about:profiles` と入れて作ったプロファイルのディレクトリを開く。 linux なら `~/.mozilla/firefox/random.profile-name` みたいなのになってるはず
4. そこに `chrome` というディレクトリを作り以下のファイルを `userChrome.css` という名前で保存(内容は [Firefox App Mode | Hummdis](https://hummdis.com/projects/2019/firefox-app-mode/) より)
5. `firefox -p ${profile_name} ${url}`

### linux 用

```userChrome.css
/*
* Custom App Mode Settings for Firefox.
* This duplicates the effects of Chrome App mode.
*
*/
/* Hide the tabs bar. */
/* Hide solo tab */
#TabsToolbar {
    visibility: collapse !important;
}

/* Hide main toolbar contents EXCEPT Address bar */
#nav-bar toolbarbutton, #search-container, #stop-reload-button {
    display: none !important;
}
#nav-bar {
    min-height: 0px !important;
}

/* Hide Address bar when NOT focused (e.g., F6) */
#urlbar:not([focused]), #urlbar:not([focused]) * {
    min-height: 0 !important;
    max-height: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
}
```

### windows 用

```userChrome.css
/*
* Custom App Mode Settings for Firefox.
* This duplicates the effects of Chrome App mode.
*
*/

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");

/* Hide the Toolbars. */
#TabsToolbar,
#PersonalToolbar,
#BookmarksToolbar,
#MenuToolbar,
#tabbrowser-tabs {
    visibility: collapse !important;
}

/* Hide main toolbar contents EXCEPT Address bar */
/* leaves space for the window buttons */
#search-container,
#stop-reload-button {
    display: none !important;
}

#nav-bar {
    margin-top: -32px !important;
    margin-bottom: -4px !important;
}

/* Hide Address bar when NOT focused (e.g., F6) */
#urlbar:not([focused]),
#urlbar:not([focused]) * {
    min-height: 0 !important;
    max-height: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    border: none !important;
}
```

## 以下 gnome desktop でアプリにする方法

`~/.local/share/applications` 以下に `.desktop` ファイルを作る

```sample.desktop
[Desktop Entry]
Name=Sample
Exec=firefox -P sample http://sample/
Terminal=false
Type=Application
```

## 参考
- [Firefox: Hide Native Tabs and Titlebar - Xilin Sun - Medium](https://medium.com/@Aenon/firefox-hide-native-tabs-and-titlebar-f0b00bdbb88b)
- [プロファイルマネージャーを使用して、Firefox のプロファイルを作成または削除する](https://support.mozilla.org/ja/kb/profile-manager-create-and-remove-firefox-profiles)
httpbinによる超簡単APIクライアントテスト

# 概要
外部のAPIモックサーバー[httpbin](https://httpbin.org/)を利用して、axiosの動作テストをしてみる。

# デモ

<p class="codepen" data-height="265" data-theme-id="default" data-default-tab="html,result" data-user="tyariponzu614" data-slug-hash="ExjNLKP" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="axios test">
  <span>See the Pen <a href="https://codepen.io/tyariponzu614/pen/ExjNLKP">
  axios test</a> by らい さむ (<a href="https://codepen.io/tyariponzu614">@tyariponzu614</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
IMGファイルのマウント

１）まずマウントしてみる

mount -o loop0 ./XXX.img /mnt/1
mount: /dev/loop0 is write-protected, mounting read-only
mount: wrong fs type, bad option, bad superblock on /dev/loop0,
       missing codepage or helper program, or other error
       In some cases useful info is found in syslog - try
       dmesg | tail or so.


２）失敗したら調査
parted ./XXX.img unit B print
モデル:  (file)
ディスク /root/XXX.img: 10292707328B
セクタサイズ (論理/物理): 512B/512B
パーティションテーブル: msdos
ディスクフラグ: 

番号  開始      終了         サイズ       タイプ   ファイルシステム  フラグ
 1    1048576B  7444889599B  7443841024B  primary  ext4              boo

2-1)詳細を設定しマウント操作
 #mount -o loop,offset=1048576,sizelimit=7443841024 ./XXX.img /data3
herokuのアプリ名(URL)変更方法【10秒でできる】

アプリを作成しwebに公開する時、手軽さからherokuを用いる方は多いのではないでしょうか。
ただ、デフォルトで生成されるアプリ名って、ランダムな英語でちょっと覚えにくいです。

```例.
$ heroku create
Creating app... done, fathomless-beyond-39164
https://damp-fortress-5769.herokuapp.com/ 
https://git.heroku.com/damp-fortress-5769.git
```

せっかく自分が作成したアプリなんだし、オリジナルな名前を付けてあげたいですよね？
そこでこの記事では、herokuのアプリ名とURLにオリジナルな文字列を設定する方法をご紹介します。

#前提条件
この記事で紹介する方法は以下を行っていることが条件となっています。

* heroku CLIがインストール済でコマンドライン上でherokuコマンドが使えること
* ```$ heroku create```しており、アドレスが生成されていること

#方法
すごく簡単です。
コマンドラインで以下を実行します。

```
$ heroku apps:rename hogehoge
```

すると以下の実行結果が表示されると思います。

```
Renaming damp-fortress-5769 to hogehoge... done
https://hogehoge.herokuapp.com/ | https://git.heroku.com/hogehoge.git
Git remote heroku updated
 ▸    Don't forget to update git remotes for all other local checkouts of the app.
```

アプリ名が```hogehoge```に変更され、URLも```https://hogehoge.herokuapp.com/```に変更されています。
更にgitのリモート設定も```https://git.heroku.com/hogehoge.git```に自動的に更新されています。

もちろん以前のURLではアクセスできません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478616/2fcff8bc-7e3f-b39b-67fc-3d957c3497de.png)

#herokuサイトからも変更可能(ただしgitリモートは変わらない)
herokuのユーザーページからもアプリ名の変更が可能ですが、このとき**gitのリモートは変更されない**ので注意が必要です。
その際は、以下のコマンドでgitのリモート設定も変更しましょう。

```
$ git remote rm heroku
$ heroku git:remote -a hogehoge
```

#参考になった記事・サイト
[【herokuコマンド】アプリ名変更](https://qiita.com/chihiro/items/f5f4793fe99002286973)
[Herokuのアプリ名を変更する + Gitリモート設定変更](https://m.designbits.jp/13072918/)
sshd Port番号変更

#Configの変更

vi /etc/ssh/sshd_config

＃Port 22

とかかれた箇所を、#を取り、１００２２番を使いたい場合は

Port 10022

と変更

#Selinux対策
昨今、SELinuxもONで使うことに慣れてきたようです

まずは確認
＃semanage port --list | grep ssh
ssh_port_t                     tcp      22

＃semanage port --add --type ssh_port_t --proto tcp 10022
※RHEL8.xでは導入されています。

＃semanage port --list | grep ssh
ssh_port_t                     tcp      10022, 22
※ポートが増えていることを確認


#サービスの再起動
systemctl restart sshd

#確認

ログオンし確認する。

slogin -p 10022 (ID)@xxx.xxx.xxx.xxx

ログオンできれば正常に変更。
余談）
scpの場合は、

scp -P 10022 ←Pは大文字を言いたい
日本語が入っている  SageTeX ソースを TeXShop でコンパイルするための対応 (pdfLaTeX 版)

TeXShop のショートカット (Command-T) やメニューの Typeset で SageTeX ソースをコンパイルするとき, 日本語が入っている場合に LaTeX の documentclass で対応する便法があります. 
 
## 実際に試した使用環境

バージョン情報は以下の通りです.

* macOS Mojave 10.14.6
* TeXLive2017+TeXShop 3.97 (奥村晴彦／黒木祐介 著 改訂第7版 LaTeX2ε 美文書作成入門) mac風インストール
* pdfTeX  Version 3.14159265-2.6-1.40.18 (TeX Live 2017) (preloaded format=pdflatex 2018.10.7)
* SageMath-8.9 

TeXShop の設定は [SageTeX を TeXShop で使うために Sagemath のバージョンを TeXShop に登録すること](https://qiita.com/rana-aerea/items/468f221bbab18131316e) か [Sagemath のバージョンアップごとの SageTeX と TeXShop の設定を簡単にするにはアプリにシンボリック・リンクを張ること](https://qiita.com/rana-aerea/items/0b79d4d65dde5d5df313) の設定を使います.

## 日本語が入っている LaTeX ソースを pdfLaTeX で コンパイルするための設定の資料

`@zr_tex8r` さんの [pdfLaTeX + CJK パッケージで日本語する方法](https://qiita.com/zr_tex8r/items/cdaac1500718eb9fa330) にある対策を使いました.

## ソースごとの設定
文書の documentclass を

```TeX
\documentclass[pdflatex,a5paper,ja=standard]{bxjsarticle}
```

にします. また, SageTeX を使うソースの最初の行に次のマジックを入れます.

```TeX
% !TEX TS-program = sage 
```

## SageTeX + TeXShop の使用例 

```TeX:2020-02-22-sagetex-by-texshop.tex
%!TEX TS-program = sage
\documentclass[pdflatex,ja=standard]{bxjsarticle}
\usepackage{sagetex}
\begin{document}
title: \textsf{SageTeX} with some KANJI through TeXShop

file and date: 2020-02-22-sagetex-by-texshop.tex (pdflatex + bxjsarticle.cls)

author: @rana-aerea

Reference: [日本語が入っている  SageTeX ソースを TeXShop でコンパイルするための対応 (pdfLaTeX 版)]
    https://qiita.com/rana-aerea/items/306ff7949925c72fa7d1

\textsf{SageTex} は {\LaTeX} 文書から \textsf{Sagemath} を呼び出して計算できます.
\begin{sagecommandline}
    sage: P = x^3 - 7*x + 6   # assign a polynomial to P
    sage: factor(P)           # factorize the polynomial
\end{sagecommandline}

Compile this file by
\begin{verbatim}
    Opening by TeXShop
    and then by typing Command-T.
\end{verbatim}

Verified on:
\begin{verbatim}
    SageMath-8.9 (macOS)
    TeXShop 3.97
    pdfTeX  Version 3.14159265-2.6-1.40.18 (TeX Live 2017)
        (preloaded format=pdflatex 2018.10.7)
    macOS Mojave 10.14.6
\end{verbatim}
\end{document}
```