OmniAICreator/Qiita-1.07M huggingface dataset:
jq コマンドで JSON オブジェクトの結合

こんにちは。
jq コマンド（の ```+``` コマンド）を使って、 JSON オブジェクトを結合してみました。下記例は、下位階層へ ```properties.info: "hello"``` を追加したので多少複雑です。

```console
$ echo '{"type": 0, "properties": {"id": 0}}'  | jq '. + {"properties": (.properties + {"info": "hello"})}' 
{
  "type": 0,
  "properties": {
    "id": 0,
    "info": "hello"
  }
}
```
結局pythonのforループはどのように書けば早いのか

# 結局pythonのforループはどのように書けば早いのか

結局pythonのforループはどのように書けばいいのか悩むことが多く、個人的に少し試してみましたので備忘録として書いておきたいと思います。

forループを高速にするための記法としては、「リスト内包表記」が有名ですが、ジェネレータを使った書き方も試してみます。

三重forループを以下4つの書き方を試してみます

* 愚直にforループを回す
* リスト内包表記
* ジェネレータ内包表記
* 愚直にforループを回しつつyieldで返す（ジェネレータを作る）

## 比較してみる

### 愚直にforループを回す

```python
N = 300
lst=[]
for X in range(N):
  for Y in range(N):
    for Z in range(N):
      lst.append(X+Y+Z)
ans = sum(lst)
```

forループを3つ重ねてみました。
5回実行したときの平均所要時間は6.06[sec]でした。

### リスト内包表記

先ほどのコードをリスト内包表記で書いてみます。

```python
N = 300
tmp_list = [X+Y+Z for X in range(N) for Y in range(N) for Z in range(N)]
ans = sum(tmp_list)
```
5回実行したときの平均所要時間は4.36[sec]でした。

### ジェネレータ内包表記

リストを作る必要はないのでジェネレータ式に変更してみます。リストの[]を()に変更するだけです。

```python
N = 300
tmp_list = (X+Y+Z for X in range(N) for Y in range(N) for Z in range(N))
ans = sum(tmp_list)
```
5回実行したときの平均所要時間は3.54[sec]でした。
ジェネレータ式にすると、早くなりますね。

### 愚直にforループを回しつつyieldで返す（ジェネレータを作る）

内包表記を用いることで記述を簡潔にできますが、処理によっては可読性を損なうことがあります。できればforループを使いつつ、高速化する方法が欲しいところです。
そこで下記のようにジェネレータを定義する関数を用意してみました。

```python
  def sample():
    for X in range(N):
      for Y in range(N):
        for Z in range(N):
          yield X+Y+Z

  ans = sum(sample())
```

5回実行したときの平均所要時間は3.71[sec]でした。

遅くなるかと思いましたが、ジェネレータ内包表記とほとんど差がない実行速度にできました。可読性が悪くなるような内容ならこのようにヘルパー関数のようなものでジェネレータを作ってみるとよさそうです。


## まとめ

|forループの書き方|実行速度(5回の平均)|メリット|デメリット|
|----|----|----|----|
|愚直にforループを回す|6.06|可読性がよい|遅い|
|リスト内包表記|4.36|やや早い|可読性を損なう場合がある|
|ジェネレータ内包表記|3.54|早い。メモリを節約できる。|可読性を損なう場合がある。ジェネレータのため複数回呼び出せない|
|愚直にforループを回しつつyieldで返す|3.71|早い。メモリを節約できる。可読性を担保できる。|ジェネレータのため複数回呼び出せない。|

結論としては、
forループを書く際の基本方針は、
__ジェネレータを用いて書く。基本は内包表記で書き、ただし可読性を担保できないようであれば、ジェネレータを関数で定義する。__

もちろん、例外はあると思います。

以上です。

## あとがき

@intermezzo-frさんの記事 [Pythonのリスト内包表記の速度](https://qiita.com/intermezzo-fr/items/43f90e07e4cebe63aeb6) を拝見すると、愚直なforループが遅いことの原因はappendの実行速度にあるそうです。そういう意味では、愚直にforを書いてyieldで返しても内包表記と実行速度がほとんど変わらないのは自然かもしれません。
セキュリティCTFをはじめた

高校の友達から「セキュリティCTF楽しいよ」と言われセキュリティCTFをはじめてみることに。
調べてみると問題の中にFLAGがあり、そのFLAGを色々として見つけ出すものらしい。

最初は何をしたらいいのか全く分からなかったが徐々に理解できた。
そんでまあ理解できるとハマる。
楽しすぎやろ。。。

いま問題に使ってるサイトは
http://ksnctf.sweetduet.info/
https://ctf.katsudon.org/
https://ctf.cpaw.site/index.php

回答見ないでどこまで行けるかチャレンジで頑張ってます。
プログラムは一応3年ぐらい。

回答の記事書いていく予定
Electronでメニューバーを消す方法（Windows）

frame: falseにすると消えるとか（フレームレスになる）
titleBarStyle: 'hidden'で消えるとか（IOSでしか働かない）
Windowsでの情報が少なかったので悩みましたが結果的に

```js
mainWindow = new BrowserWindow({});
mainWindow.setMenu(null);
```
これだけでした。
flask(自分用)

Flask



```Python3
from flask import Flask
from flask import render_template

＃temlatesフォルダを読み込む
app = Flask(__name__, template_folder='./templates')

@app.route('/')
def index():
    return render_template('./index.html')

if __name__ == '__main__':
    from argparse import ArgumentParser
    parser = ArgumentParser()
    parser.add_argument('-p', '--port', default=5000,
                        type=int, help='Listen On')
    args = parser.parse_args()
    port = args.port

    app.run(host='0.0.0.0', port=port, threaded=True, debug=True )
Androidアプリ作成でつまづいた点【随時更新】

# はじめに
こんにちは、ハイノです。

初めてAndroidアプリ開発を行っているのでつまづいた点を備忘録として投稿します。
今回の投稿では、つまづいた点を随時更新形式で列挙していくものです。
解決策はまた、見つけた場合に別記事で投稿する形にしたいと考えています。

Androidアプリ開発初心者がつまづくポイントは同じところが多いと予想していますので、
同じく初めてAndroidアプリ開発を行うという方にも私がつまづいた点を共有できれば
と考えています。
また、「ここでつまづいたときの解決策はこんなのがあるよ」ってコメントを頂けると
非常にありがたいです。
では、以下につまづきポイントを列挙していきます。

# つまづきポイント　※随時更新
1. xmlでlayoutを作成しているときにGUIの設定に頼って画面サイズに対応できないこと
2. Oauth通信
3. TwitterAPIの通信方法
4. JSONのパース方法
5. Listener
6. Fragment
 1. DialogFragment 
7. Layout 
 1. textviewの自動文字サイズ変更
 2. 画面サイズに合わせた動的レイアウト
8. アニメーション
 1. 連続実行
 2. 同時実行
 3. カーブの表現
 4. PathAnimation 

# 解決方法　※随時更新


7.Layoutについて
下記サイトが非常にわかりやすくて参考にしました。
https://qiita.com/mii-chang/items/ee965c1e8826d4e59414

7.1. textviewの自動文字サイズ変更について
下記サイトがわかりやすく記載がありましたので参考にしました。
https://blog.k3n.link/entry/auto-sizing-text-view

特に[singleLine="true"］[maxLines="1"]の違いに関して。


# 開発環境
Android Studio 3.4.1
Let's Encryptの自動更新でERR_SSL_PROTOCOL_ERROR発生

# 起こったこと

Let's Encryptの証明書をcertbot-autoを使って自動更新をかけているが、2019年7月13日の深夜の更新で、一部のサイトでERR_SSL_PROTOCOL_ERRORが表示されるようになった(Chrome)。IEやEdgeでも同様にエラー表示。

※certbot-autoは証明書の残期間が1ヶ月を切らないと証明書の更新を行わないので、上記の更新の日付はあまり意味がありません。これまでにも発生しているかもしれませんし、今後も発生するかもしれません。たまたまこちらの環境で、この日に発生したというだけの情報です。

# 忙しい人のための結論

HTTPSのデフォルトサイトに下記の記述を入れれば良い。

```nginx
ssl_session_tickets off;
```

# もう少し詳しい説明

[etckeeper](https://qiita.com/bezeklik/items/a66f1cfdba7fb4e368f6)を入れているので、当該の更新で何が変わったのかを確認する。どうやら、このあたりが怪しい。ssl_session_tickets off; をコメントアウトすると案の定復帰。

```
diff --git a/letsencrypt/options-ssl-nginx.conf b/letsencrypt/options-ssl-nginx.conf
index 292d429..3cc2b9b 100644
--- a/letsencrypt/options-ssl-nginx.conf
+++ b/letsencrypt/options-ssl-nginx.conf
@@ -4,8 +4,9 @@
 # the up-to-date file that you will need to refer to when manually updating
 # this file.
 
-ssl_session_cache shared:le_nginx_SSL:1m;
+ssl_session_cache shared:le_nginx_SSL:10m;
 ssl_session_timeout 1440m;
+ssl_session_tickets off;
```

options-ssl-nginx.conf というのは何かというと、certbotでnginxの設定を自動修正した場合に、virtualhostの設定にこんな感じでincludeされるデフォルトの設定。

```nginx
    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/info-lounge.jp/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/info-lounge.jp/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
```

問題のssl_session_ticketsはこういうものらしい。

> TLSセッションチケットは簡単に言うとTLSのセッション情報を暗号化してクライアント側に保存することで HTTPS通信時に行われるTLSハンドシェイクの手順を省略してネットワークレイテンシを削減するための仕組みです。
https://tech.mercari.com/entry/2015/11/16/170037

options-ssl-nginx.conf でこの行だけコメントアウトすれば問題なく稼働するが、このファイルを書き換えた場合には、今後Let's Encrypt側の推奨値が変わっても、このファイルの自動アップデートがかからなくなるとの記載がある。

```nginx
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file.
```

そこで、問題の本質を解決するために調査をすると、こんなチケットが見つかった。
https://github.com/jwilder/nginx-proxy/issues/580

あとは、[忙しい人のための結論](https://qiita.com/MasaGon/items/c6719e723e9fb57e3a4f#%E5%BF%99%E3%81%97%E3%81%84%E4%BA%BA%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E7%B5%90%E8%AB%96)のとおり。

```nginx
server {
    listen       443 ssl default;
    server_name  _;
    ssl_session_tickets  off;
    ssl_certificate      /etc/pki/tls/certs/xxx.xxx.xxx.xxx.crt;
    ssl_certificate_key  /etc/pki/tls/private/xxx.xxx.xxx.xxx.key;
    return       444;
}
```
印刷用CSSを使用する

# CSSのメディアクエリを使う場合

```css
@media print{
    /* 印刷時に適用させたいスタイルを定義する */
}
```

## 参考

- [レスポンシブの基本、メディアクエリの書き方](https://sole-color-blog.com/blog/71/)


# 別CSSをインポートして使う場合

```css
@import url("print.css") print; /* インポートで指定して、印刷時のみ適用されるようにする */
```

## 参考
- [CSSの@importを使って別のCSSファイルを読み込む方法を徹底解説!!](https://www.sejuku.net/blog/83216)

# HTMLのlinkタグに指定する場合

```html
<!-- media属性に指定して、印刷時のみ読み込まれるようにする -->
<link rel="stylesheet" type="text/css" media="print" href="sample.css">
```

## 参考

- [HTMLのlinkタグとは？基本的な書き方とrel属性まとめ](https://saruwakakun.com/html-css/basic/link-rel)


# bootstrapの場合

- **bootstrap.css**には以下のスタイルが定義されている
    - ver: 3.2.0の場合

```css
@media print {
  * {
    color: #000 !important;
    text-shadow: none !important;
    background: transparent !important;
    box-shadow: none !important;
  }
  a,
  a:visited {
    text-decoration: underline;
  }
  a[href]:after {
    content: " (" attr(href) ")";
  }
  abbr[title]:after {
    content: " (" attr(title) ")";
  }
  a[href^="javascript:"]:after,
  a[href^="#"]:after {
    content: "";
  }
  pre,
  blockquote {
    border: 1px solid #999;
    page-break-inside: avoid;
  }
  thead {
    display: table-header-group;
  }
  tr,
  img {
    page-break-inside: avoid;
  }
  img {
    max-width: 100% !important;
  }
  @page  {
    margin: 2cm .5cm;
  }
  p,
  h2,
  h3 {
    orphans: 3;
    widows: 3;
  }
  h2,
  h3 {
    page-break-after: avoid;
  }
  select {
    background: #fff !important;
  }
  .navbar {
    display: none;
  }
  .table td,
  .table th {
    background-color: #fff !important;
  }
  .btn > .caret,
  .dropup > .btn > .caret {
    border-top-color: #000 !important;
  }
  .label {
    border: 1px solid #000;
  }
  .table {
    border-collapse: collapse !important;
  }
  .table-bordered th,
  .table-bordered td {
    border: 1px solid #ddd !important;
  }
}
```

- 例えば、**navbar**をHTML側のclass要素に指定してる場合、印刷時に**display: none;**が適用される


### 参考
- [CSS · Bootstrap](https://getbootstrap.com/docs/3.4/css/)
conda updateで「Solving environment: failed」となった時の解決法

# 前置き

今まで出来ていたAnacondaパッケージのアップデートが急にできなくなった．表題にあるメッセージが出てだ．ネットで検索していろいろ試していたら偶然にも解決できたので，メモとして残しておく．

但し，何故でここに書いた方法で上手くいったのかは正直分かりません．また，他の人が同じようにしても成功する保証はないです．試す場合はあくまでも自己責任でお願いします．

# どうやったら直ったか

まず

```
conda install anaconda
```

を実行．これでパッケージの不整合が直った．それから普通にcondaコマンドで

```
conda update --all
```

としただけ．

# 参考

https://stackoverflow.com/questions/55527354/the-environment-is-inconsistent-please-check-the-package-plan-carefully
VSCodeのRemote WSLでWSLを快適に使う

VSCodeの拡張機能Remote WSLのおかげで、WSLでの開発がめっちゃ便利になってて涙が出そうになった話。

## この記事の対象者

- WindowsユーザーでWSL(Windows Subsystem for Linux)を使っていて、
- VSCodeを使ってWSL上で開発がしたい人

## できるようになること

- VSCodeでの、WSL内の環境を用いた実行やデバッグ、コードナビゲーションなど

## はじめに

私はPythonをよく使うのですが、たまにWindowsをサポートしてないパッケージに出会って舌打ちしそうになります。あと、C++との関係でWindowsにインストールするのが手間だよ～ってパッケージもありますね。

そんなときにちょっとWSLを使ってみようかとなるわけですが、これまではいい感じの開発環境を簡単に作れずここでまたイラッとしていました笑。
（WSLのパスを半ば無理やり設定したり、Jupyterで我慢してみたり、VcXsrvでWSLにGUI環境を作ってみたり...）

さて、そうこう思ってるうちに、いつの間にやらRemote WSLというVSCodeの拡張機能が出ていました。この拡張機能を使うとWSLでの開発がとってもやりやすくなったので紹介したいと思います。

## 導入手順

次のようにしてRemote WSLをインストールします（[公式の説明](https://code.visualstudio.com/docs/remote/wsl)通りです）。

- WSL(お好きなLinuxディストリビューション)のインストール
- VSCodeのインストール（Windows側に）
- 「Remote Development」という拡張機能を検索してインストール

はい、これだけです。
この記事を読んでいる時点で最初の2つのステップは済んでいると思うので、最後の拡張機能のインストールを行えばいいだけですね。

（現時点(19/07/14)、Marketplaceの[説明](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)にはVSCode Insidersをインストールしろと書いてありますが、Insiders版じゃなくても使えました。）

## 使い方

インストールしたら早速使ってみましょう（以下も[公式の説明](https://code.visualstudio.com/docs/remote/wsl#_open-a-folder-in-wsl)通り）。

まずはWSLのターミナルで編集したいディレクトリに移動して、ターミナルで

```bash
code .
```
とするとVSCodeが開きます。
初回に限りWSL側に必要なものがインストールされるのでちょっと時間がかかります。

これでWSLでの開発をVSCodeで出来るようになりました！
実行やデバッグ、コードナビゲーションなどなどをWSLにある環境から利用できるようになります（拡張機能や設定については後述）。

ちなみに、公式の説明には、

> Navigate to a folder you'd like to open in VS Code (including, but not limited to, Windows filesystem mounts like /mnt/c)

とあるので、作業フォルダが/mnt/c以下（つまりWindows側）だと何か問題があったりするのかもしれません。

## 拡張機能と設定について

さて、ここまででだいたい使えるようになっているのですが、Windowsで使うのと同じように使うためにはもう少しだけ手順が必要です。

### 拡張機能

拡張機能によっては、WSL側にインストールが必要です。
例えば、Python拡張機能をRemote WSLで使うには、WSLのフォルダを開いている状態で拡張機能を検索->インストールという手順が必要です。
（下の画像の「インストール on WSL」でインストールを行う）

![スクリーンショット (62).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274226/43d9d9e5-1170-2329-7393-50772acd990a.png)

カラーテーマなどの拡張機能は追加でインストールを行わなくても大丈夫でした。

### 設定

機能によっては、WSL用の設定をする必要があります。

Remote WSLでも、Windows側のユーザー設定を見に行くようになっているのですが、実行ファイルへのパス等はWindowsのものを参照されても困ります。
WSLのフォルダを開いている状態で設定を確認すると、下の画像のように「リモート」という項が現れています。Remote WSLを使っている際には、こちらの設定が優先されるのでWSL用に適宜設定を変更してあげましょう。

![スクリーンショット (64).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274226/831e0b50-1de3-4b17-224b-c45c819e43b0.png)

## 終わりに

だいぶWSLの使い勝手が良くなってきましたね！
諸般の事情によりなかなかWindowsから脱することができないので、WSLが発表されてからこれまでの間とてもお世話になってきました。

WSLにはI/Oパフォーマンスの問題だったりもありますが、Windows PCだけで色々完結させられるのは便利すぎるので、改良を期待しながら今後もありがたく使っていきます～
M5Stack で 音声出力


# 音声出力を試してみた

## AquesTalk-ESP32
AquesTalk-ESP32を使う。
[アクエストからDL](https://www.a-quest.com/download.html#a-etc)

> AquesTalk ESP32	2.0.1 (2018/08/10)

## 解凍してコピー
以下のパスにライブラリとヘッダをコピー
{PATH_Arduino_ESP32}\tools\sdk\lib\libaquestalk.a
{PATH_Arduino_ESP32}\tools\sdk\include\aquestalk\aquestalk.h

{PATH_Arduino_ESP32}の部分はesp32のセットアップ時に作成した環境。
※aquestalkフォルダはなかったので作成


## platform.local.txtを作成

以下を記述し、
compiler.c.extra_flags="-I{compiler.sdk.path}/include/aquestalk"
compiler.cpp.extra_flags="-I{compiler.sdk.path}/include/aquestalk"

もともと存在しているplatform.txtから[compiler.c.elf.libs]をコピーして、末尾に[-laquestalk]を追加

```
compiler.c.elf.libs=-lgcc -lopenssl -lbtdm_app -lfatfs -lwps -lcoexist -lwear_levelling -lhal -lnewlib -ldriver -lbootloader_support -lpp -lsmartconfig -ljsmn -lwpa -lethernet -lphy -lapp_trace -lconsole -lulp -lwpa_supplicant -lfreertos -lbt -lmicro-ecc -lcxx -lxtensa-debug-module -lmdns -lvfs -lsoc -lcore -lsdmmc -lcoap -ltcpip_adapter -lc_nano -lrtc -lspi_flash -lwpa2 -lesp32 -lapp_update -lnghttp -lspiffs -lespnow -lnvs_flash -lesp_adc_cal -llog -lexpat -lm -lc -lheap -lmbedtls -llwip -lnet80211 -lpthread -ljson  -lstdc++ -laquestalk
```

## コンパイルして書き込み
サンプルをDLしてコンパイルして書き込み
http://blog-yama.a-quest.com/?eid=970188

めっちゃ早口だけどしゃべった！

### さらにAqeusTalkTTSを使ってみた。
http://blog-yama.a-quest.com/?eid=970195

辞書ファイルをSDカードに入れてセットしなくてもそのまま使えると言えば使える。
漢字じゃなかったからなのか？？

それよりも早口なのはなんでなんだろう？
速さ？のパラメータを100→20に変更して、それなりに聞こえるようになった。

### 辞書を使用
SDカードを用意し、辞書ファイルをカードに入れてサンプルを使って改めて試してみる。
早口なのも治った。不思議である。。
せっかくなのでM5Stackでしゃべったものでアレクサを起動させてみようかと思ったのだが、起動しなかった。合成音声だと起動しないのか抑揚の問題なのか。。
ユークリッド距離さえあればコサイン類似度が計算できる。

#概要
scikit-learnでk-meansを用いてクラスタリングしているときに思いました。
__「距離関数をコサイン類似度にしたい」__
scikit-learnのk-meansでは距離関数としてユークリッド距離しか使えません。
scikit-learnのコードを書き換えて、独自の距離関数を使えるようにした[記事](https://qiita.com/Kensuke-Mitsuzawa/items/67c17f6bda8a1097740c)もあります。
しかし、結構面倒くさそうだし処理速度の低下が気になります。
そこで[こんな投稿](https://stats.stackexchange.com/questions/299013/cosine-distance-as-similarity-measure-in-kmeans)を見つけました。
本投稿はこの投稿を要約・加筆します。
結論を言うと
__「正規化してからユークリッド距離をとるとコサイン類似度を測れる」__
です。
#距離関数の定義
まずユークリッド距離とコサイン類似度の定義を確認しておきます。
2点 $P(x_1, ..., x_n), Q(y_1, ..., y_n)$ に対して、$\vec{x}=(x_1, ..., x_n), \vec{y}=(y_1, ..., y_n)$ とします。

ユークリッド距離は
$$d(P, Q) = |\vec{x} - \vec{y}| =  \sqrt{\sum_{k=1}^{n} (x_k-y_k)^2}$$
コサイン類似度は
$$cos(\vec{x}, \vec{y}) = \frac{\vec{x}\cdot\vec{y}}{|\vec{x}||\vec{y}|} = \frac{\sum_{k=1}^{n}x_k y_k}{\sqrt{\sum_{k=1}^{n}x_k^2} \sqrt{\sum_{k=1}^{n}y_k^2} }$$
です。

#コサイン類似度をユークリッド距離で測る
$\vec{x}, \vec{y}$ を正規化したものを改めて $\vec{x}, \vec{y}$ とします。
すると、$|\vec{x}| = 1, |\vec{y}| = 1, cos(\vec{x}, \vec{y}) = \vec{x}\cdot\vec{y}$となります。
ここでユークリッド距離を計算すると（ルートを書くのが面倒なので2乗してます。）

```math
\begin{align}
d(P, Q)^2 &= |\vec{x} - \vec{y}|^2 \\
&= |\vec{x}|^2 - 2 \vec{x} \cdot \vec{y} + |\vec{y}|^2 \\
&= 2(1 - cos(\vec{x}, \vec{y}))
\end{align}
```
つまり、「ユークリッド距離が 0 に近い」と「コサイン類似度が 1 に近い」が同値になります。
また、コサイン類似度はベクトルのなす角によって決まり、正規化はベクトルの長さのみを変更するものなので、正規化前と後でコサイン類似度は変化しません。
よって、
__「正規化後のユークリッド距離が近い」⇔「コサイン類似度が高い」__
となります。

#直感的な理解
2次元で考えるとわかりやすいです。
正規化後はP, Qは単位円上にあるので、下図のような状況になります。
$d(P, Q)$ と $\vec{x}, \vec{y}$ のなす角 $\theta$ が連動していることがわかります。
$\vec{x}, \vec{y}$ のコサイン類似度が高いということは、なす角 $\theta$ が小さいということなので、
正規化後では「ユークリッド距離が近い」⇔「コサイン類似度が高い」となります。
![コサイン類似度.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373677/b094afa3-dcba-af3a-82b8-f603fc3a3e5a.png)

#コード例
scikit-learnで書く場合は以下のようになります。

```python
from sklearn import preprocessing, cluster
normalized_vec_list = preprocessing.normalize(vec_list)

result = cluster.KMeans(n_clusters=5).fit(normalized_vec_list)
```

#おわり
いちいち距離関数を独自に設定せずとも、ちょっとした工夫（正規化）をするだけでOKというのがお手軽で良いですね。
ただし、コサイン類似度にしか対応できません。
その他の距離関数を使うための工夫があれば是非教えてください。
画像を並べた際に出来る謎の隙間を解決！

#はじめに
画像を隙間なく並べて表示する際に、謎の隙間が出来てしまったことはありませんか？:astonished:
例えば以下のような感じ！縦に画像を並べたいのですが、画像と画像の間に隙間があいてしまっています！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419062/181ab382-3456-84e5-d9e1-f30609785630.png)


こちらを表示させる為のHTMLファイルも載せておきます。

```test.html
<!DOCTYPE html>
<html lang ="ja">
  <head>
    <meta charset = "utf-8">
    <link rel="stylesheet" type="text/css" href="../style/test.css">
    <title>テスト</title>
  </head>
  <body>
　　 <!-- ここで画像を設定しています！ -->
    <img src = '../sample.jpeg' class = 'image1'><br>
    <img src = '../sample.jpeg' class = 'image2'>
  </body>
</html>

```
今回はこの謎の隙間について調べた内容をまとめます！

#隙間の正体

###この隙間を作っている正体は、インライン要素に設定されているベースラインです！###
インライン要素というとわかりづらいですが、テキストの文字、特に英語を考えるとわかりやすいです。
以下の画像をご覧ください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419062/39b56c9e-2672-2758-5fe1-efa133afd442.png)
(参考画像元URL： https://www.tagindex.com/stylesheet/frame/vertical_align.html)

qやp、yなどはベースラインに対して配置が下にはみ出るのが普通です。
英語を書く際の常識ですね。
文字等のインライン要素も、ベースラインに対してこの**"下にはみ出る部分"**を余白として設定しています。
そのため、画像を並べるとその分の隙間が空いた状態になってしまいます。
画像を表示させる為のimgタグもインライン要素なので、隙間が空いてしまうんですね。

#隙間を埋めるには
謎の隙間を埋めるための方法を２つ紹介します！どちらも1行で書けるので簡単です！
ゴールとしては以下のように、画像と画像の間の隙間が無くなればOKです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419062/06956040-5557-ae66-fd42-61cd2173eca7.png)


###方法１：インライン要素をブロック要素にする###
インライン要素だから空白が空くだけなので、ブロック要素に変えてしまえば良いです！
(※この場合ブロック要素にしているので、htmlのbrタグは不要なので消してくださいね！)

```test.css
.image1 {
  display: block;
}
```

###方法２：vertical-alignをbottomに設定する###
vertical-alignは、ベースラインの位置を変更することができるプロパティです！
このvertical-alignをbottomにすることで、謎の余白を消すこと出来ます。

```test.css
.image1 {
  vertical-align: bottom;
}
```

#さいごに
隙間をなくす方法として２つ紹介しましたが、インライン要素のままにしたいかブロック要素にしたいかで使い分ければ良いかと思います！
プログラミングを始めた当初、ベースラインについて把握していなくて少しだけ詰まってしまったのでまとめてみました！
お役に立てれば幸いです:relaxed:
2019年版 レスポンシブのブレークポイント数値

レスポンシブのブレークポイントを2-3年前と同じにしていませんか。
Webサイト制作で表示デバイスの多様化により、
端末切り替え型からリキッド型のレスポンシブに変化しています📱

2019年のブレークポイントを再検討してみました👨🏻
プロジェクトのデザイン・ターゲットなどで数値を微調整しますが、考え方は統一しています。

リキッドレスポンシブが主流になってから…実装の考えること多いですね〜💦

#ブレークポイント Sassのmixin

ブレークポイント切り替えの数値と
Sassのmixinは以下のようにしています。

```
$sp320: 320px;
$sp: 375px; //デザインカンプの横幅
$tb: 760px;
$pc: 980px; //PCコンテンツ幅の最小値
$wide: 1400px; //PCのmax-widthの数値

//@include sp320{}
@mixin sp320 {
  @media (max-width: $sp320) {
    @content;
  }
}

//@include sp{}
@mixin sp {
  @media (max-width: $sp) {
    @content;
  }
}

//@include tb{}
@mixin tb {
  @media (min-width: $sp) and (max-width: $pc) {
    @content;
  }
}

//@include pc{}
@mixin pc {
  @media (min-width: $pc) {
    @content;
  }
}

//@include wide{}
@mixin wide {
  @media (max-width: $wide) {
    @content;
  }
}

```
それぞれのブレークポイントについて、
考えを説明していきますね。

#小さいスマホ用 320px〜375px📱

スマホデザインカンプが横幅375pxの場合に設定

SPのデザインカンプは横幅320px幅
または375px幅で作成するパターンが多いと思います。
横幅が小さいスマホ用に縮小調整を指定する範囲となります。

見出しやナビゲーションのfont-sizeを小さくしたり、
余白の調整や小さいサイズのスマホでもコンテンツが溢れないように調整します。

#スマホ用 375px〜759px🤳🏻

スマホデザインカンプが横幅320pxの場合は数値を320pxで指定

spとpcの間がタブレット指定。コンテンツ部分はSPをベースにfont-sizeやGridを調整。
SP320px幅とPCmax-widthは希望があれば指定する。

#iPad、タブレット用 760px〜979px📱
768pxの1桁目を切り捨てした数値をブレークポイントに指定

SPをベースに余白の調整やコンテンツカラム数を変更します。
Webサイトではタブレット用デザインカンプが入らない場合が多いので、
余白の単位ベースを％指定にするとレスポンシブ対応がスムーズになります。
気になる箇所だけ個別に数値を指定します。

#PC用 980px〜💻
PC用の指定です。コンテンツ幅を指定する場合が多いです。

#PC Wide用 1400px🖥
見出しのfont-sizeを相対指定にした場合、どこまで拡大するか。
コンテンツ幅のmax-widthを指定するため、横幅最大の数値を関数指定します。

私のチームではこのようにしていますが、
他の現場でどんな指定を使ってらっしゃるか気になります👀
Raspberry Pi Zero W のインストール及びUSBによるSSH(シリアルコンソール)接続、Meshネットワークの構築まで（Serial console over USBをそえて）  

#0. 概要
Raspberry Pi Zero Wに母艦 (windows 10)から接続するまでに思いの外、時間が掛ったので備忘録として残しておく。

#1. Installation
Raspberry Pi Zero Wが焼かれたSDカードの作成までをここで行う

## 必要なもの
RaspberryのIMG:
https://www.raspberrypi.org/downloads/raspbian/

SDカードにIMGを焼く（DDコマンド的なもの）:
https://sourceforge.net/projects/win32diskimager/

色々と試したがWin32Diskimagerが一番エラーが出ずにうまくいった。

## 作業
1）RaspberryのIMGファイルを公式サイトからダウンロードする

2）SDカードを母艦のマシンに指して、ドライブの番号を覚えておく

3）Win32Diskimagerを使って、ダウンロードしたRaspberryのIMGを指定、SDカードのドライブを指定してWriteを押す。

後は1時間ほど待てばSDカードが出来あがる。
基本的には、この作業のみでRaspbbery Piは立ち上げることができる。

その後、Raspberry Pi上で作業を行うにあってRaspberry PiのI/Fから作業するのは面倒なので、Raspberry Piをネットワークに接続してSSH接続をし、母艦から操作する必要がある。

なお、ネットワークも環境が変わればいつでも接続できるわけではないので、シリアルコンソールで扱いたいと考える。GPIOのシリアルをUSBに変換してくれる市販のツールもあるが、非常に面倒なのでRaspberryのUSBから直接シリアルコンソールを使えるようにしたい。

#2. Setup SSH
SDカードに焼いた後、SDカードの`boot`パスを開き、
以下の設定を行いSSH接続およびUSB経由でシリアルコンソール接続を行う

#2.1. Lunch up SSH
SSHの接続について説明する。

1) SDカードの`boot`パスをく
2) 空ファイルのsshを作成する

これで起動時にssh接続ができるようになる。
このファイルがない場合はConnection refuseというエラーが出る。

#2.2. Network Configuration
ワイヤレス接続の設定について説明する。

1) SDカードの`boot`パスをく
2) wpa_supplicant.confファイルを作成する
3) 以下をファイルに書き込む

``` bash
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="SSID"
    psk="Passphrase"
}
```

これで起動時にネットワーク接続の設定ファイルがコピーされて、起動時に自動接続されるようになる。

#2.3. SSH over USB
なお、2.2.の設定を終えたところで、インターネットに自動接続されないことが多々ある。このため、USBのインタフェースを通してRaspberry piと母艦マシンをシリアル接続したいと考える。

1) SDカードの`boot`パスを開く
2) `config.txt`を開き以下を入力する

``` bash
dtoverlay=dwc2
```
入力個所はEnable Audioあたりに入れておくのが一般的らしい。

3) `cmdline.txt`ファイルを開き、以下を入力する。

``` bash
modules-load=dwc2,g_serial, g_ether
```
入力個所はrootwaitに次ぎ位に入れるのが一般的らしい

これでシリアル接続が可能になる。また、G_etherを入れることで、ネットワークインターフェースとしても使える

4) Raspberry piを起動した後に以下をシェルに入力してUSBをシリアル接続化させる。

``` bash
$sudo systemctl enable getty@ttyGS0.service
```

# 3. Mesh network
おまけでメッシュネットワークを構築する。

## adhoc
まず`/etc/network/interface`を開き、以下を末尾に入力する

``` bash
auto wlan0
iface wlan0 inet static

address 192.168.6.2
netmask 255.255.255.0
wireless-channel 11
wireless-mode ad-hoc
wireless-essid testadhoc
wireless-key 12367890
```

そして、Rebootする。

## ノード化
以下でノード化するアプリケーションをインストールする

`$ sudo apt-get install olsrd`

以下で起動
`$ sudo olsrd -i wlan0 -d 1`

これで、Ad-hocでOpen Shortest Path First(OSPF)的なルーティングを可能とする。
例えば2-3が接続断でも2が1を介して3に接続するなんていうことができる。
Windows版QEMUにNetBSD-8.1(sparc)をインストールしてみた。

Windows版QEMUにNetBSD-8.1(sparc)をインストールしたので、記録を残しておく。
QEMUもOSも枯れている環境だからか、非常にすんなり導入～OS起動まで出来た。
注) sun4mマシンを使用、sparc64ではない

(詳細を後ほど追記予定)

### 環境情報
端末：Windows 10 (64bit), NEC Lavie LS150/F(Pentium B950 2.10GHz, MEM 4GB)
QEMU-w64-setup-20190218.exe

QEMU用の仮想(qcow2)ディスクおよび.isoファイルをC:\qemuworkに格納
QEMUシステムファイルをC:\qemuwork\qemuに格納

### 事前準備
いつもの儀式：qcow2ディスクを作成する
コマンドプロンプトを開き
C:> cd "c:\qemuwork"
C:> qemu\qemu-img.exe create -f qcow2 c:\qemuwork\netbsd-sum4m.qcow2 70G

(追記)こちらも参照
[Windows版QEMUにTAP-driverをインストールしてみた。](https://qiita.com/Selenia/items/9aee211db847b2980865)

### インストール
C:> qemu\qemu-system-sparc.exe -drive file=netbsd-sum4m.qcow2,if=scsi,bus=0,unit=0,media=disk -drive file=NetBSD-8.1-sparc.iso,format=raw,if=scsi,bus=0,unit=2,media=cdrom,readonly=on -boot d
(1行で入力)
![qemu_netbsd-sparc_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/95593040-b728-2151-d797-71ca8ebcc1ea.png)
![qemu_netbsd-sparc_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/2cff7474-98bd-31ed-39f1-3555f04b21ad.png)
![qemu_netbsd-sparc_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/f58cec65-1d2d-33d9-5bcb-a5882a928fbc.png)
![qemu_netbsd-sparc_17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/8a84daa5-167a-57bc-f615-73154a69f4c5.png)
![qemu_netbsd-sparc_19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/e54cd89e-d824-69c5-85fb-2e910fec04f0.png)
![qemu_netbsd-sparc_22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/4e21a176-f770-805d-165c-bcc5a9936fbf.png)

...installationは2～30分くらいかかる

### インストール後の設定
packagesインストール後に、OS起動に必要な最小限の設定(ホスト名、IPアドレス、DNS、タイムゾーン、rootパスワード＆ユーザ作成、サービス起動有無など)を設定する
![qemu_netbsd-sparc_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/fd29664f-85b7-86ea-ed2d-caeb3ce0d550.png)


### OS起動
一旦QEMUを落とし、コマンドプロンプトから次のコマンドで仮想マシンを起動する
C:> qemu\qemu-system-sparc.exe -drive file=netbsd-sum4m.qcow2,if=scsi,bus=0,unit=0,media=disk -boot c

注)
初回起動時
Updating fontconfig cache: 
の箇所で3分ほど待つが気にしない

xdmの利用をYESにしていたならば、次の画面が表示される
![qemu_netbsd-sparc_41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/e86e67d9-db4f-70d3-3405-45978b5dc36b.png)

よくあるX上の標準アプリを起動してみた
![qemu_netbsd-sparc_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451166/cbff6210-ddd8-706d-4935-7a1a49c491a5.png)

Enjoy it!

(参考)
[QEMU: Documentation/Platforms/SPARC](https://wiki.qemu.org/Documentation/Platforms/SPARC)
[Alexa]ASK Toolkit for Visual Studio Codeを試してみる

## 概要
[Alexa Dev Day 2019](https://alexadevdaytokyo2019.splashthat.com/) でASK CLIについて紹介があったので使ってみています。
ask cloneしてローカルのVSCodeで開発
ASK Toolkit for Visual Studio Code(Beta)
が利用できるようになっていたので試してみました。

[ASK Toolkit for Visual Studio Codeで開発を始める](https://developer.amazon.com/ja/docs/ask-toolkit/get-started-with-the-ask-toolkit-for-visual-studio-code.html)
の画面付きサンプルです。参考になれば。

### 動作手順

#### 前提条件
「AWS Lambdaを使用してスキルのバックエンドのビジネスロジックをホストします。」
とありますがAlexa-Hosted Skilldでもできました。


#### VS CodeにASK toolkitをインストールする
普通です
<img width="685" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/e484f97d-aeb9-eefd-aa75-4e7a89bbe88d.png">

#### コマンド一覧
コマンド一覧です。
ASK CLIから実行できるコマンドが網羅されています
<img width="501" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/13efa1cf-2081-b8bc-19fc-fb972d42db97.png">

#### 既存スキルのクローンを作成
テンプレートをつかって新規作成もできるようなのですが
ひとまず既存のAlexa-HostedスキルのHello-Worldをcloneします

毎回、プロファイル選択が求められます
<img width="459" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/1e8cac55-fced-3303-672b-818a7cff1929.png">

TERMINAL画面でプロジェクト選択など（ASK CLIと同じ）
Windows環境だとPower Shellを立ち上げなくてよくなります。
<img width="524" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/77bdd2e8-54a2-12a1-5303-dc56620c39fb.png">

選択するとワークスペースに追加されます
<img width="288" alt="5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/e5d80521-1422-a7e6-a3a8-1522017ed11f.png">

#### 開発およびデプロイ
VSCodeで開発して、ASKコマンドでデプロイします
<img width="619" alt="10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/e32624e9-3ded-b7b7-1c9e-fc468ded13e5.png">

コードだけ変えたとき、モデルだけ変えたときなどでコマンドを分けると早いです。
<img width="447" alt="11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/107c6fa6-7681-c6a9-1912-d45d6af60a24.png">


#### テスト
ask dialogにあたる以下のコマンドを実行します。
ちなみにask dialogの終了は「!quit」だそうです。
<img width="446" alt="8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/7c60002a-9e92-de6a-055b-e5b62966da3f.png">

Terminalで確認できます。（ASK CLIと同じ）
<img width="634" alt="9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/e5a18ab8-53ba-44df-0874-61f2f67d52f1.png">


#### その他
ASK ToolkitとASK CLIの対応表は
[ASK Toolkit for Visual Studio Codeで開発を始める](https://developer.amazon.com/ja/docs/ask-toolkit/get-started-with-the-ask-toolkit-for-visual-studio-code.html)
に一覧されています。

ASK CLIにはない、
* Developerコンソールを開く
* ASK CLIとの対応表を開く
<img width="447" alt="7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278271/bc226fd6-7d15-4176-6789-58a91650d8ff.png">
が地味に便利だと思います。

### まとめ
Power Shellを別コマンドで開かなくてよいだけでもよいですね
S3のPersistentManagerの削除を行うことがそこそこあるので
ASK CLIかASK ToolkiのOpenコマンドで開けるようになるとよいな
Vive Focus Plusを使ったVRアプリ開発に関するメモ

# はじめに
Vive Focus PlusはスタンドアロンVRHMDであり、HMDのカメラによる位置トラッキングに加え、超音波トラッキング付きのコントローラーにより、両手の位置を取得できるという特徴がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/814044dd-fe82-85eb-891d-2adf8ad060cc.png)

値段は10万円弱と高めで、エンタープライズ向けの用途が主である。

アプリケーションの開発はUnityとVive Wave SDKで行うことができ、アプリはVIVEPORT経由で配布できる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/fddf0ded-cd00-d594-afed-13dd975b37b2.png)

クローズドベータ版の配布も可能なので、開発中のアプリを気軽にシェアできる。

以下にVive Focus Plusで開発するのに必要な設定、その他開発に便利な情報をまとめた。以下の作業の多くで**ADB(Android Debug Bridge)が必要になる**ので、事前にPCを設定しておくこと。

#USBでのPCとの接続

USBでPCとHMDをつないだときに下の画面が出てきたら、「ファイルの転送」を選ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/52684693-ead7-2341-3d84-78d8cdfa202a.png)

なぜかこの画面のときはコントローラーが使えないので、頭を動かして視線マーカーを操作する必要がある。

#USBデバッグの有効化

Vive Focus Plusは出荷時にすでに開発者モードになっているが、USBデバッグを有効化する必要がある。メニュー画面から「設定」→「詳細設定」を選択。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/217e03f7-c080-c460-aff0-b5612a8c7234.png)

さらに、「開発者向けオプション」を選び、「USBデバッグ」の項目のトグルスイッチを押してUSBデバッグを有効にする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/bd40383e-3aa2-4355-4fe4-98a7cac13e1c.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/5a4763f8-87b1-3231-148d-ed9eabf17c95.png)

有効な状態でUSB接続がされていると、以下の画面が出てくるので、チェックボックスにチェックを入れてOKを押す。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/f42bbd63-62e7-c82a-ccc2-c513cc1267fb.png)

#ワイヤレスでのPCとの接続

ADB(Android Debug Bridge)が使える環境であれば、ワイヤレスでPCにつなぐことも可能。Android Studioを使ったファイルのやり取り、scrcpy（後述）による画面のキャスト、Unityでビルドしたアプリのインストールなどもワイヤレスでできるようになる。

ただし、設定の途中でUSB接続が必要になるので注意。

最初に、開発者向けオプション（上記参照）のWi-Fi Statusを選ぶ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/d6b58dee-14ec-a664-c99c-708dcb10040c.png)

すると、Wi-Fiに関する情報を見る画面が出る。ここで「REFRESH STATS」のボタンを押すと情報が表示されるので、そこのIP Addressをメモっておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/8bcef8e8-13b1-1e42-3a09-50592dc1a200.png)

次に、コマンドラインで
`adb tcpip 5555`
と入力し、ケーブルを抜いて
`adb connect DEVICE_IP:5555`　(DEVICE_IPはさっきメモしたIP Address）

と入れることで、ワイヤレス接続できる。

# 開発に便利な情報

##scrcpyによる画面キャスト

HMDに表示中の画面をPCにキャストできるscrcpyというアプリがあり(https://github.com/Genymobile/scrcpy), Vive Focus Plusでも使用できる。上記の方法でワイヤレス化している場合は、ワイヤレスでのキャストも可能。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/6b5453da-ed65-971b-6315-7f0c5f02a724.png)


普通にキャストすると複眼で表示されるので `scrcpy -c 1310:1410:120:100` などと画面サイズと位置を指定して実行すると単眼にすることも可能である。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/09ee0c1d-fcd3-c344-0a51-7c2f26bf40a4.png)


## モバイル用の最適化

[Wave SDKのドキュメンテーション](https://hub.vive.com/storage/app/doc/en-us/MobileVRperformancechecklist.html)に、モバイル向けの最適化に関する情報があるので参考にしてください。特に、Build settingでTexture CompressionをASTCに設定することに注意してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58503/b4afd231-8d4f-2eb7-765d-8db761993110.png)
WSLでバーチャルホストの設定

WSLでバーチャルホストの設定

[この記事](https://qiita.com/sutara79/items/95a5c59830006c715ae5)を読んでLaravelのブラウザテストをしようと思い、bloglaravel58.comというサーバーネームでバーチャルホストの設定をした時にハマったことを書きます。

### 環境
PHP 7.2
Ubuntu 18.04(WSL)

```txt:/etc/apache2/sites-available/virtualhost.conf
<VirtualHost *:80>
    ServerName bloglaravel58.com
    Serveradmin webmaster@virtual.host
    DocumentRoot /home/user/php/app/lara58/public
    ErrorLog /var/log/apache2/virtual.host.error.log
    CustomLog /var/log/apache2/virtual.host.access.log combined
    LogLevel warn
    <Directory /home/user/php/app/lara58/public>
        AllowOverride All
        Options All
        Require all granted
    </Directory>
</VirtualHost>
```

```txt:/etc/hosts
127.0.0.1	localhost
127.0.0.1	bloglaravel58.com
```

これで`http://bloglaravel58.com`にアクセスしたら`ERR_NAME_NOT_RESOLVED`が出ました。

調べてみると[このissue](https://github.com/Microsoft/WSL/issues/512)を見つけました。
windows側でもetc/hostsファイルに書かないといけないようです。

管理者権限でメモ帳を開いて`C:\Windows\System32\drivers\etc\hosts`に

```
127.0.0.1	bloglaravel58.com
```

と書きます。

これで完了です。
Laravel + Nuxt + Fargate + ALBでドメインを設定しhttps通信を実現する


# 下準備
下記の手順でドメインの名前解決は完了させる
[【AWS】お名前.com で取得した独自ドメインを Amazon Route 53 で名前解決して EC2 インスタンスの Web サーバーにアクセスさせる手順](https://go-journey.club/archives/8340)

# 証明書の発行
[ACM証明書発行をDNS検証で行う【エンジニアブログより】](https://www.wantedly.com/companies/serverworks/post_articles/101309#_=_)

[お名前で購入したドメインをAWSのALBにhttpsの設定して使う方法。](https://qiita.com/masahirok_jp/items/dccaee14cf7fbb908df6)

# ALBに対してhttps通信の設定
ALBで今はリダイレクトもやってくれてNginxでリダイレクトの設定を行わなくてもいいらしい

[ALBを使ってる時はNginxでhttp->httpsへリダイレクトの設定しなくて良くなった](https://blog.hatappi.me/entry/2018/07/27/091946)

http(80ポート)をhttps(443)にリダイレクトを行う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305479/15c4c04d-d9a3-4df2-d820-ba77c216f8c0.png)

ALBのセキュリティグループの設定にHTTPSを追加する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305479/3feddaa1-66fa-6682-3f51-1972369c36af.png)

ALBのリスナーにHTTPSを追加する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305479/cbe2d4e4-1eae-cc01-b66b-859deda364dd.png)
M5stickVの電源の切り方

RISC-V CPU搭載AIカメラのM5stickV、
みなさんの手元にも届きましたでしょうか。

![0716a5fdd9b8e4fed2d5c10e37e84b1e.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273740/e79c252a-3fe5-f81c-cb51-6f59d9aa358d.jpeg)

付属のM5ロゴ付きのケーブルがすごく満足度高いです。

電源を入れると早速認識してくれます。

![7868b24eb2bf6ff01199eede9f5e52cd.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273740/ade944e7-6079-0f74-41d2-a5bc3742e25b.jpeg)


さて電源を切るかと思い、色々ボタンを押すも反応なし。

公式にはPOWER SWITCHを2秒でON、6秒でOFFと書いてあるのですが、

![D-s94M-U4AIPL9Z.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273740/8bb111b2-3b7a-d827-62f5-a347853a747d.jpeg)


6秒押したら再起動はしても電源が切れない。。。

仕方ないのでケーブルを抜いてライトをつけて充電がなくなるのを待つ。

![4914ed9c22d4ba7c6054cfa095a69d3f.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273740/6489671f-8f8f-19ae-2cb2-ddb49a4e8610.jpeg)


## POWER SWITCHの罠

使うたびに充電切れるの待つ訳にはいかないので、色々試してみるも電源が切れない。

もしかして5.98秒しか長押ししてないのかと思いストップウォッチで6秒測って長押しするも、、、再起動。

なんだかなーと思い、ケーブルを抜いて6秒長押ししみたところ、

なんと！

なんと！！

なんと！！！

電源が切れました。

M5stickVは***電源につないでいる状態だと電源が切れない***という罠があるようです。

そういえば電源に繋ぐと勝手に電源ONされるので、再起動というか電源OFF→自動電源ONしていたのかもしれません。

M5stickVの電源を切りたいときは「電源に繋がってるケーブルを抜いてからPOWER SWITCHを6秒長押し」する必要があるようです。

***

いかがでしたか？
親クラスも含めて、メソッドの定義場所を特定する

## 経緯
このモンキーパッチを解読していたところ、元の`columns`がどのクラスで定義されているかを知りたくなった。

```ruby
module ActiveRecordInvisibleColumn
  INVISIBLE_COLUMNS = {
    'foos' => ['bar'],
  }.freeze
  def columns(table_name)
    super.delete_if { |column| INVISIBLE_COLUMNS.fetch(table_name, []).include?(column.name) }
  end
end

ActiveSupport.on_load :active_record do
  ActiveRecord::ConnectionAdapters::Mysql2Adapter.prepend(ActiveRecordInvisibleColumn)
end
```

## ハマった罠
initializeに引数が必要らしく、面倒。

```ruby
irb(main):036:0> ActiveRecord::ConnectionAdapters::Mysql2Adapter.new
ArgumentError: wrong number of arguments (given 0, expected 4)

irb(main):037:0> ActiveRecord::ConnectionAdapters::Mysql2Adapter.new(nil, nil, nil, nil)
NoMethodError: undefined method `fetch' for nil:NilClass
```

## 結論
これで解決した。
allocateはinitializeをskipしてインスタンス化できるメソッド。

```ruby
irb(main):035:0> ActiveRecord::ConnectionAdapters::Mysql2Adapter.allocate.method(:columns).source_location
=> ["/Users/xxxx/.rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-4.2.11.1/lib/active_record/connection_adapters/abstract_mysql_adapter.rb", 469]
```

## 参考
https://qiita.com/jnchito/items/fc8a61b421d026a23ffe
https://techracho.bpsinc.jp/hachi8833/2019_07_04/75432
https://eagletmt.hateblo.jp/entry/2017/09/24/004709

### 共同編集者
@popmac
Facebookにアップロードされた画像が追跡されている噂を検証してみた

# 事の発端
<blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/hashtag/facebook?src=hash&amp;ref_src=twsrc%5Etfw">#facebook</a> is embedding tracking data inside photos you download.<br><br>I noticed a structural abnormality when looking at a hex dump of an image file from an unknown origin only to discover it contained what I now understand is an IPTC special instruction. Shocking level of tracking.. <a href="https://t.co/WC1u7Zh5gN">pic.twitter.com/WC1u7Zh5gN</a></p>&mdash; Edin Jusupovic (@oasace) <a href="https://twitter.com/oasace/status/1149181539000864769?ref_src=twsrc%5Etfw">July 11, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

どうやらfacebookの画像に追跡データが自動的に貼り付けられている、という内容

# 検証してみた
※素人が検証してみたレベルですので…各自検証をしてくださると嬉しいです。

## 検証環境
macOS 10.14.15
exifはexiftoolを用いて確認・編集

##  手法
1. JPEG画像を用意する
2. そのJPEG画像のexifデータのうち、"SpecialInstructions"の値がないことを確認する
3. そのJPEG画像をfacebookにアップロードする
4. facebookにアップロードした画像をダウンロードする
5. exifデータのうち、"SpecialInstructions"の値を確認する

## 検証1
### 手法
毎度おなじみ、いらすとや様の画像　(png画像)をmacのプレビュー.appでjpg画像に変換して検証します。
![undou_front_bridge_man.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160611/9e7d9539-7fae-c0ff-758c-6b422e5c90f0.jpeg)

この画像をfacebookにアップロードしたのち、ダウンロードしました。
### 結果
その画像のexifデータを参照すると、確かに"SpecialInstructions"の値に`FBMD`から始まる98文字の値がありました。(念の為、実際に表示された追跡データと思われる値は非公開とさせていただきます。)

さらに、その画像を再びfacebookにアップロードし、それをダウンロードすると、"SpecialInstructions"内に同一の値が存在しました。

## 検証2:追跡データをいじってみた
### 手法
先ほど見つけた追跡データのうち、下6桁(今回の場合、`2a0000`でした)を`123456`に変更して再びfacebookにアップロードし、それをダウンロードしました。
### 結果
その画像のexifデータを参照すると、"SpecialInstructions"の値に`FBMD`から始まる98文字の値があり、下6桁は`2a0000`となっていました。

## 検証3:追跡データをさらにいじってみた
### 手法
検証2で変更したデータを`123456`のみの6桁に変更し、再びfacebookにアップロードしダウンロードしてみました。
### 結果
その画像のexifデータを参照すると、"SpecialInstructions"の値に`FBMD`から始まる98文字の値があり、下6桁は`2a0000`となっていました。

## 検証4:追跡タグがついていない画像を他人のアカウントからアップロードしてみた
### 手法
元の画像を他人に渡し、手順1と同様のことをしたのちに、この手法で得た追跡コードと私が手順1で得た追跡コードを比較してみました。
### 結果
異なる追跡タグが付与されました。

## 検証5:全く違うJPEG画像で試してみた
### 手法
全く別物のJPEG画像でfacebookにアップロードし、ダウンロードしてみました。
### 結果
その画像のexifデータを参照すると、"SpecialInstructions"の値に`FBMD`から始まる98文字の値があり、異なる値となっていました。

# 結論(仮)
"SpecialInstructions"の値は、facebookが「画像をアップロードしたユーザ情報」+「同一の見た目の画像」(メタデータは異なっていても構わない)に対して1つのタグを発行しているのでは？

(随時更新していきます)
WSLでの~/.kube/config

# 環境とか

* Windows10 64bit Pro
* WSL1
* WSLで動かしてるのはUbuntu

# tl;dr

* Win10での`~/.kube/config`とWSL上のUbuntuでの`~/.kube/config`はデフォルトでは異なる
* `$HOME`が違うから当たり前
* 対応は手っ取り早く↓のどっちかやればいい
    * WSL側から`/mnt/c/Users/$USER/.kube/config`を環境変数に設定
    * WSL側で`/home/$USER`の下に、`.kube`ディレクトリ以下の構成をコピーしてやる

# 理由

* Win10側の`$HOME`は`C:\Users\$USER`だが、これはWSL側では`/mnt/c/Users/$USER`として見えている
* WSL側での環境変数の`$HOME`は普通のLinuxと同じでデフォルトでは`/home/$USER`に設定されている
* だからデフォルトでは`$HOME`は引き継がれない。というか別物である
tensorflowでSemantic Segmentation(MASK R-CNN)を動かしてみた（→いい感じ） 

#目的
（勉強は後でするとして、）**セグメンテーションを動かしてみたかった。**

**単に、以下の方の記事のとおりで動きました。。。**という**だけ**の内容です。
ただ、
実際、適当に入力画像を自分で選んで、自分の環境で実行させると、
**人が実行した記事や、書籍を見るのとは違った印象**があります。
**動かしてみることをお勧めします。:candy:**

そのまま実行できるレベルの情報があるいくつかの記事を参考にして実施してみたが、**３連敗。**
で、4つ目として、以下の記事を参考にしたら、動いた。驚き。

　whoopsidaisies's diary
　2018-02-27 
　tensorflowでMASK R-CNNによるSemantic Segmentation 
　（ http://whoopsidaisies.hatenablog.com/entry/2018/02/27/184448 ）

環境の差とかだと思うが、エラーはいくつかは出た。
ググると解決する程度の簡単なもののみでした。
記憶が辿れれば、それは、別途、メモとして残します。



#環境

OS：　Windows10 バージョン1803(OSビルド 17134.829)
　※細かい条件を書かれている方がいたので念のため。
　　極端には、古くないはず。
WSL(Windows Subsystem for Linux):上記のWindows10のとおり
Linux:Ubuntu 18.04LTS
opencv:3.4.0
　　※3.4.1とかではないです。opencv関係してる？？。


#実行結果
無料フリー写真を入力とした。
2番目は欠番（セグメンテーション的には、うまくいったが、写真があまり好きになれなかったので、没。）

**どれも、すごい、検出力だと思いました。期待通り！！！**

1番目

![_newDogMan1out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/08468b49-58b3-aee0-5026-5ca75a8b6bb4.png)

※犬が、3匹だと思ってるんですかね。。。



2番目（好みの問題で欠番。技術関係なし。）

3番目


![_newDogMan3out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/be2abaea-7583-00f3-6598-47f6cec4a70e.png)
※女性の指（手）が、人として扱われていない。。。


4番目

![_newDogMan4out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/2fc90366-51e1-48ac-2005-f425ff3f8f44.png)
※女性の衣服とか、手が、人として扱われていないのが、興味深いですね。
　人が犬をあやす、もっとも、基本的な「構成」なんですがね。。。


#まとめ
とにかく、セグメンテーションが動させてよかった。
繰り返しですが、以下の記事を、ほぼ、そのまま、実行しただけ。

　whoopsidaisies's diary
　2018-02-27 
　tensorflowでMASK R-CNNによるSemantic Segmentation 
　（ http://whoopsidaisies.hatenablog.com/entry/2018/02/27/184448 ）

DNNとかが、今後どこに着地できるのかは、よく知りませんが、
セグメンテーションとかは、取り込まれるべきものですよね。

**一度、自分好みの画像で実行されることをお勧めします。**


#関連（本人）

[畳み込みニューラルネットワーク（CNN)の説明が煽りすぎでは？（1層目ぐらいしか成功していないのでは？）](https://qiita.com/enoughspacefor/items/02dc8d556b9db65d4ee6)
[良書「ゼロから作るDeep Learning -- Pythonで学ぶディープラーニングの理論と実装」を読む](https://qiita.com/enoughspacefor/items/d545b23bd64d285647de)
[Google Lensはどんな技術でできているのか？GoogleだからTensorflow？GoogLeNet?](https://qiita.com/enoughspacefor/items/872c3c6f6ad25b6180bb)
[ニューラルネットワーク活性化関数SigmoidとReLUの関係](https://qiita.com/enoughspacefor/items/f9a64c18d2bd16226355)

#今後
また、何か関連する検討ができれば。
少し、勉強します。
コメントなどあれば、お願いします。:candy:
JetsonNanoでマイニング

## 概要
たったの1万2千円で買えるGPUボードなので、暗号通貨のマイニングができるんじゃないかという話題はよく見かけます。一応、確認だけしておかないとということで。

ただ、それ目的で買うのはやめたほうがいいですよ。絶対に元取れないから。

## 検証
暗号通貨の一種で、Monero (XMR)というものがあります。
Moneroは匿名性が高く、取引に個人情報が不要です。メールアドレスすらもいらない。
そんなわけで、マネーロンダリングとかの懸念があって、国内では取り扱っている取引所はありません。
つまり換金ができない。
ただ、ASICを積極的に排除している(ASICが開発されると計算方式を変えて使えなくする)ので、ハッシュレートが低く、CPUやGPUでもマイニングができます。

マイニング環境は、GitHubで手に入ります。
CPU用：https://github.com/xmrig/xmrig
GPU用：https://github.com/xmrig/xmrig-nvidia

### インストール
不要なのもあるかもしれないけど、ざっくり行きます。

```
$ sudo apt -y install cmake automake libgtk2.0-dev libssl-dev libcurl4-nss-dev libuv1-dev libmicrohttpd-dev
$ git clone https://github.com/xmrig/xmrig-nvidia.git
$ cd xmrig-nvidia 
$ mkdir build 
$ cd build
$ cmake .. -DCUDA_LIB=/usr/local/cuda-10.0/lib64/stubs/libcuda.so
$ make
$ vi config.json
```
config.jsonを作成します。内容は、[GitHub](https://github.com/xmrig/xmrig-nvidia/blob/master/src/config.json)にあるサンプルをコピペして、以下の部分を自分の環境に書き換えるだけです。

```.json
"pools": [
    {
        "url": "donate.v2.xmrig.com:3333",
        "user": "YOUR_WALLET",
        "pass": "x",
           :
    }
],
```

### 実行
```
$ ./xmrig-nvidia
```
ちゃんと動きます。
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276188/618fa936-36d9-8109-b5df-c3704c6bbaf6.jpeg)

```
$ sudo jtop
```
![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276188/0a28bf9b-9b31-9888-8c34-ec8f9437b14a.jpeg)

### ハッシュレート
18H/s程度出ています。
acceptedもちゃんと出るので使えるんじゃないですかね。

電気代は一般的な家庭で、東京電力の場合、1kWh=26円くらいと思われます。
10Wだとすると、24時間で6.24円。
報酬はプールによって異なりますが、18H/sだと24時間でおそらく0.0001XMR未満。
1XMRが0.01BTCくらい。1BTCが100万円の場合、24時間で1円いくかどうか。
(どっちみち少なすぎて送金できないですね)

参考までに、GTX1080Tiで770H/s、core i7-7700Kで195H/s、ラズパイ3B+で0.9H/s(成功しない) くらいです。
どの環境使っても電気代を超えることはないです。
スクレイピングでhtmlのテーブルから情報を抜きcsvにする方法

#この記事では.
旅行などで検索サイトを使わない場合などにwikiやお国のサイトを使うが、
プレーンなhtmlに情報が張り付いているので検索が面倒。

こういうやつ。
https://www.env.go.jp/water/yusui/result/sub4-2/PRE13-4-2.html

ということで、スクレイピングして自分で検索可能なものを作る際にデータを抜き出すときのメモ。
htmlのテーブルならヘッダも含めてループしてcsvにしておく。(今回特殊なヘッダなので手で作ったけど、、)
あと、コードはurl固定だけど、PRE{都道府県コード}の引数を与えれば全都道府県を一回でcsvにすることが可能。
都道府県コードは別ページにあった。

#スクレイピングのコード

```python:
import requests
from bs4 import BeautifulSoup

import csv
# アクセスするURL
url = 'https://www.env.go.jp/water/yusui/result/sub4-2/PRE13-4-2.html'
# reqest and parse
response = requests.get(url)
response = BeautifulSoup(response.content, 'html.parser')
# テーブル情報を取得
table = response.findAll('table')
rows = response.findAll('tr')
# csvデータ作成
csvFile = open("ebooks2.csv", 'wt', newline = '', encoding = 'utf-8')
writer = csv.writer(csvFile)
# ヘッダーが二重になっていて取り出すのが面倒なのでここは記載してしまう
csvItem = ['回答市区町村名','名称','ふりがな','所在地','概要等','アクセス制限','湧水保全活動','湧水写真・位置図']
writer.writerow(csvItem)
# ここからが1行ごとの処理
for row in rows :
    # 項目ずつlist.append
    csvItem = []
    for cell in row.findAll('td'):
        csvItem.append(cell.text)
    #  ヘッダもこのループ内なので項目がない場合は無視
    if len(csvItem) > 0:
        writer.writerow(csvItem)
csvFile.close()
```

#参考
ほぼほぼ以下をコピペで使ってます.
https://qiita.com/hujuu/items/b0339404b8b0460087f9
誰かが作ったapiサービス
https://springwaterapi.docs.apiary.io/#
windows 10 で画面スナップショット

# win + shift + s
範囲選択してクリップボードコピー

# alt + printscreen
アクティブウィンドウをクリップボードコピー

# printscreen
画面全体のクリップボートコピー

マルチディスプレイの時は、すべての画面のスクリーンショットとなる

# win + printscreen
画面全体コピーをファイルに保存。ピクチャ\スクリーンショット

マルチディスプレイの時は、すべての画面のスクリーンショットとなる
【Ruby】prependの使い道


## まとめ
1. prependしたクラスの挙動の前後に、処理を追加したい
2. prependしたクラスの挙動を完全に上書きしたい

## 1. prependしたクラスの挙動の前後に、処理を追加したい
モンキーパッチではこのパターンがよく使われている。

```ruby
module Hoge
  def execute
    pp 'モジュール'
    super
  end
end

class Human
  def execute
    pp 'クラス'
  end
end

Human.prepend(Hoge)

Human.ancestors
=> [Hoge, Human, ....]

Human.new.execute
#=> 
'モジュール'
'クラス'

```

## 2. prependしたクラスの挙動を完全に上書きしたい
```ruby
module Hoge
  def execute
    pp 'モジュール'
  end
end

class Human
  def execute
    pp 'クラス'
  end
end

Human.prepend(Hoge)

Human.ancestors
=> [Hoge, Human, ....]


Human.new.execute
#=> 
'モジュール'
```

## 2'.  prependしたクラスの挙動を完全に上書きしたい -> includeではダメ
```ruby
module Hoge
  def execute
    pp 'モジュール'
  end
end

class Human
  include Hoge

  def execute
    pp 'クラス'
  end
end

Human.ancestors
=> [Human, Hoge, ....]

Human.new.execute
#=> 
'クラス'
```


## おまけ: 継承している場合
superを呼ぶと、Humanだけでなく、Humanの親クラスであるAnimalまで探索される。

```ruby

module Hoge
  def execute
    pp 'モジュール'
    super
  end
end

class Animal
  def execute
    pp '親クラス'
  end
end

class Human < Animal
end

Human.prepend(Hoge)

Human.ancestors
=> [Hoge, Human, Animal, ....]

Human.new.execute
#=> 
'モジュール'
'親クラス'

```

## 参考
https://eagletmt.hateblo.jp/entry/2017/09/24/004709

### 共同編集者
@popmac
CircleCIとJIRAを接続する

JIRA CloudとCircleCIを統合してみます。

- [CircleCI for Jira](https://marketplace.atlassian.com/apps/1215946/circleci-for-jira?hosting=cloud&tab=overview)

# 手順

1. JIRA Cloudに[CircleCI統合](https://marketplace.atlassian.com/apps/1215946/circleci-for-jira?hosting=cloud&tab=overview)をインストール
    - トークンが生成される
    - <img width="692" alt="スクリーンショット 2019-07-12 15.48.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50056/fe1cef03-e03b-dd92-c243-243f17c66c03.png">

1. 生成されたJIRAのトークンをCircleCIのプロジェクトに登録
    - <img width="1924" alt="スクリーンショット 2019-07-12 15.50.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50056/8250b104-4c6e-14af-686b-676584bb5e07.png">
1. [CircleCIのAPIトークン](https://circleci.com/account/api)を作成。これはJIRAのOrb内で使用する
1. 生成されたCircleCIのトークンを`CIRCLE_TOKEN`という名前でContext(or プロジェクトの環境変数)に追加
1. JIRAのOrbを`config.yml`に登録
   
   ```yaml
      orbs:
        slack: circleci/slack@3.2.0
   ```

- 最後に、ワークフローの`post-steps`とかにJIRAの通知処理を追加
   
   
   ```yaml
      workflows:
        build:
          jobs:
            - build-resources:
                post-steps:
                  - jira/notify
   ```   

# CIの結果をJIRAタスクから確認
接続されるとJIRAタスクにビルド結果が反映されるようになり、直接CircleCIの結果へ飛ぶこともできます(JIRAの構成によって表示が異なる模様?)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50056/01aa8ad6-af5b-1619-4ea6-9a71ffd6f805.png)


# CircleCIからJIRAタスクを作成
ビルド画面の右上にJIRAタスク作成ボタンが現れるので、ビルドに関連するタスクがこの画面から直接作成できます。
<img width="990" alt="スクリーンショット 2019-07-12 15.54.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50056/7cd3ba61-2a91-7902-8170-dd07b2737831.png">

# メモ
- もしかしたら通知はジョブごとに実施してワークフロー全体をJIRAタスクから確認することもできるのかも?
pandasで文字列からなる列を操作する

下書きに眠っていたので供養

スタックオーバーフローの下記記事をまとめました。
[Convert categorical data in pandas dataframe - Stack Overflow](https://stackoverflow.com/questions/32011359/convert-categorical-data-in-pandas-dataframe)


1. 

# カテゴリカルにせず、文字列の列を整数列に変換する場合
```python
In [1]: pd.factorize( ['B', 'C', 'D', 'B'] )[0]
Out[1]: array([0, 1, 2, 0])
```

# カテゴリカル変数として扱う場合

```python
In [1]: df = pd.DataFrame(
                {'col1':[1,2,3,4,5],
                 'col2':list('abcab'), # str
                 'col3':list('ababb')  # str
                })
In [2]: df.columns
Out[2]: Index(['col1', 'col2', 'col3'], dtype='object')
```
この時点で全ての列はobjectになっているので、categoryにcastする

```python:
In [3]: df['col2'] = df['col2'].astype('category')
In [4]: df['col3'] = df['col3'].astype('category')
```
`select_dtypes(['category'])`でカテゴリカル変数になっている列を取得できるので、

```python
In [5]: cat_columns = train.select_dtypes(['category']).columns
In [6]: cat_columns
Out[6]: Index(['col2', 'col3'], dtype='object')
```

となる。
Pythonで、パッケージやモジュールの構造を視覚化する

下書きに眠っていたので供養

# 何がしたかったか

タイトルの通り。
Pythonで提供されているモジュールの全体像を知りたいときが度々あるけれど、日本語で調べてもなかなかヒットしないので、メモしておく。

# Snakefood
Snakefoodというモジュールを使うとできるらしい。僕らのStack Overflow(本家)を調べると簡単に見つかった。
[visualize structure python module - Stack Overflow](http://stackoverflow.com/questions/6957484/visualize-structure-python-module)

# インストール
このSnakefood, PyPIに登録されているsetup.pyが古いからか、エラーを吐く。

```
C:\ pip install snakefood
Collecting snakefood
  Using cached snakefood-1.4.tar.gz
    complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "C:\Users\Owner\AppData\Local\Temp\pip-build-umj3pjm5\snakefood\setup.py", line 19
        except IOError, e:
    SyntaxError: invalid syntax
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\Users\Owner\AppData\Local\Temp\pip-build-umj3pjm5\snakefood\setup.py
```

どう見ても", e"がおかしいが、自分で直すのも不安なので、本家から持ってくることに。
[snakefood: Python Dependency Graphs](http://furius.ca/snakefood/)

Bitbucketへのリンクがあるので、そこから落とせる。

僕は pip の仕組みなんて知らずに使っている新人類なので、インストーラの指定とかやったことない。以下を参考にした。
[【Python】pipの使い方 - TASK NOTES](http://www.task-notes.com/entry/20150810/1439175600)

pipで -e オプションをつけて、レポジトリを指定すればインストールできる。
分散バージョン管理システム周りのことはよくわからないので、いったんローカルに落としたフォルダを指定した。

```
C:\ pip install -e {path}
Obtaining file:///{path}
Installing collected packages: snakefood
  Running setup.py develop for snakefood
Successfully installed snakefood
```

となって完了。

# 補足
他に、少なくとも2つツールがあった。
[Python dependencies inside a package - Stack Overflow](http://stackoverflow.com/questions/20829697/python-dependencies-inside-a-package/20839064#20839064)