OmniAICreator/Qiita-1.07M huggingface dataset:
オートレイアウトを使ってlabelを可変にする方法

オートレイアウトを使用してlabelをメッセージ量に応じて可変にする方法を勉強したので備忘録としてここに記す。

#Autolayout
1、まずはlabelのあるCustomViewを作成
<img width="341" alt="スクリーンショット 2019-11-23 11.59.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302540/1bcbe54d-a3c3-3076-6889-182c772d0165.png">

２、伸縮させたいlabelを選択した状態で下記画像の[lines]の項目を「０」にする
<img width="250" alt="スクリーンショット 2019-11-23 12.01.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302540/f353ad09-fd74-59cf-b561-4d734c577a51.png">

3、部品全てに上下左右と高さに制約をかける。（最下部から順に上に制約をつける場合、最下部以外の部品は上左右のみでOK）なお、伸縮させたいlabelに対しては高さの制約をつけないで上下左右のみでOK

以上にてAutolayout側の設定は終了。続いてコード側

#コード

```swift
        // ここの大きさは任意
        view1 = CustomeView.init(frame: CGRect(x: 0, y: 0, width: 408, height: 300))

        // 文字を代入する前のlabelの高さを取得
        let oldlabel = view1.label.frame.height

        view1.label.text = "ああああああああああああああああああああ"

        //sizeToFitは必須
        view1.label.sizeToFit()

        // 文字を代入する後のlabelの高さを取得
        let newlabel = view1.label.frame.height

        //　更新前とあとの高さの差分を取得
        let DifferenceLabel = newlabel - oldlabel
        
        // viewに表示させないから不必要
        self.view.addSubview(view1)

        // ここの高さに差分をプラスする
        view1.frame = CGRect(x: view1.frame.origin.x, y: view1.frame.origin.y, width: view1.frame.width, height: view1.frame.height + a)

       // 場合に応じてViewを再描画
       view1.layoutIfNeeded()
```
これにてコードは終了
これでlabelの文字量に応じて可変になるはず

#締め
textViewでも可変にする方法があれば教えてください！
フォルダ毎のサイズ順にソートしてmoreで見る


```
du -h -d 1 | sort -h -r | more
```

sortのオプション
```-h, --human-numeric-sort
              人間が読むことができる形式の数値を比較する (例: 2K 1G)
```
てのを最近知ったので。
#Rails + FactoryBot でデータ作成 create での validation を無効化する例 : trait を利用

# trait 指定なし

```rb
FactoryGirl.define do
  factory :person do
    name { nil }
    sex { nil }

    to_create { |instance| instance.save(validate: false) }
  end
end
```

# trait 指定あり

こいつで範囲を限定的にできる

```rb
FactoryGirl.define do
  factory :person do
    name { nil }
    sex { nil }

    trait :no_validation do
       to_create { |instance| instance.save(validate: false) }
    end
  end
end
```




# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2745








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
robocopyでドライブの内容を丸ごとコピーする方法

#robocopyでドライブを丸ごとコピーする方法
いつも忘れるのでメモ

 - W: から E:へ全データコピーする
 - ディレクトリのタイムスタンプとかも保持する
 - `System Volume Information`と`$RECYCLE.BIN` を無視する
  -  `` "`$RECYCLE.BIN" `` の `` ` `` を忘れないこと。

```shell
PS W:\> robocopy W: E: /mir /DCOPY:DAT  /XD "System Volume Information" "`$RECYCLE.BIN"
```



## `` ` ``を忘れてしまった残念な例

```shell
-------------------------------------------------------------------------------
   ROBOCOPY     ::     Windows の堅牢性の高いファイル コピー
-------------------------------------------------------------------------------

  開始: 2019年11月20日 23:03:30
   コピー元 : W:\
     コピー先 : E:\

    ファイル: *.*

 除外ディレクトリ: System Volume Information
            .BIN

  オプション: *.* /S /E /DCOPY:DAT /COPY:DAT /PURGE /MIR /R:1000000 /W:30

------------------------------------------------------------------------------

                           0    W:\
                           0    W:\$RECYCLE.BIN\
                           0    W:\$RECYCLE.BIN\S-1-5-18\
2019/11/20 23:03:31 エラー 5 (0x00000005) コピー先ディレクトリにアクセスしています E:\$RECYCLE.BIN\S-1-5-18\
アクセスが拒否されました。
30 秒間待機しています...
```

##壊れかけディスクからのサルベージ対応
リトライ回数を設定する： `/R:3`のように回数を指定する
ファイルを除外する：`/XF "ファイル名.jpg"`のように指定する
ラズベリーパイのデータが破損したので初期化する（OSの再インストール）

#経緯
先日、ラズベリーパイがフリーズしたので、強制的に電源を切り再起動。再起動後にファイルマネージャーを開いたところ、開いたら1秒もたたないうちにファイルが閉じられる（落ちる）。コマンドをたたいて開いてもだめ。ファイルエクスプローラーが完全に使えなくなりました。
ラズベリーパイの環境がスパゲティ気味だったので、思い切って初期化を決意しました。

#初期化するにあたって（必要なもの）
ラズパイにOSをインストールするときは、PC経由でSDカードにRASPBIAN等を書き込んだと思います。ですが、再インストールはラズパイ本体のみでできます。

#やったこと
ラズパイのデータを避難。
ラズパイのOSを入れ直す。
再起動して初期設定。

これだけです。

#手順
①ラズパイの電源を入れ、「Raspberry Pi」のロゴの画面で、「Shift」キーを押します。
![3D23C4CF-09B5-473A-85DB-55609CEB729E_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/b307c03b-f1c3-56e4-0625-dd02f897a76d.jpeg)


②OSを選択する画面が表示されるので、Raspbian にチェックを入れます。
（自身がインストールしたOSを選択してください）
言語 は日本語を選択して、「インストール」をクリック→「はい」をクリックして下さい。
![D2E165C9-D651-4F65-B135-D71249AA6A1F_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/7cbc0cb1-04d8-1cdc-aa0c-6b315a014bee.jpeg)
![792A7E3D-A9E1-468D-B651-2FF4E65D2F94_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/48f11802-53d7-060b-70f1-362e3a87de6f.jpeg)
③再インストールが実行されます。
![3A14645B-BD0D-4FA3-92F3-B6724C2AC53C_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/9d4a3760-f741-402f-6c7c-61d6f533609f.jpeg)

④「OSのインストールに成功しました」と表示されます。「OK」をクリックして再起動しましょう。
![049AE389-4D6A-42E4-831C-B7115D95E6DD_1_105_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/457895/c96f996c-7d52-c9b2-34a4-9eaaba4a7ce5.jpeg)




⑤これで再インストールが完了です。次は初期設定をしましょう。

#まとめ
今回はラズベリーパイのOSの再インストールの手順を紹介しました。
データが破損し、やむおえずOSの再インストールを強いられる日に備え、日頃からデータのバックアップを心掛けましょう・・・
SamsungのUSBメモリ 128GBのベンチをとるMUF-128AB/EC 

# 概要
- 書き込みが遅い
- 読み込みは公称300Mb/sを考えると妥当
- 小さいのででっぱらない
- 値段（￥3,212）を考えれば特別コスパはよくない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/c405eae6-b1d0-0291-2813-941270326da4.png)

# Machine
Onemix2s
# USBメモリ
## 機種名
「Samsung USBメモリ 128GB Fitタイプ 正規代理店保証品 MUF-128AB/EC」
## 容量
128GB
## リンク
https://www.amazon.co.jp/gp/product/B07GYWC3VK/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1
## フォーマット
NTFS
# Crystal Disk Mark

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/04a32ad9-db3e-2d32-e595-a856fdf0753e.png)

# AS SSD benchmark
## ふつうのテスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/74b0c2de-110f-4800-6834-2a003cf5e38c.png)

## Compression-Benchmark 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/e1b6e026-e656-b140-d7a4-4cdd8881030d.png)

# 関連
https://qiita.com/haniokasai/items/d617299f824791c489ab
IoT Ltに初参加してみた件w

# Iot Ltって何？
　今回、初めてIot Ltのイベントに参加してみました。
　内容としては、個々に開発したIot関連の成果物を発表し合うもので、情報共有や発信の場になっています。
　結構、かっちりとしたセミナーかなって思っていましたが、アットホームな感じで楽しかったです。　参加者の中には未経験の人もいるので、これからIotを勉強しようと思っている方にはオススメです！

# 会場の雰囲気
　登壇した人たちはみんな自分たちで開発したものを紹介していました
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536127/629722ee-aacd-196b-cb50-57f28d1a1024.png)
コーラがないと体調が悪くなってしまう人のために冷蔵庫のコーラがなくなったらSlackを使って携帯に通知するシステム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536127/7bfaad5a-c5c4-1ed8-a7d1-2a695f119bb7.png)
ペッパーを使ったシステムも！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536127/09f3e081-e79a-3279-8ccd-862955109937.png)
レベルアップ機能がついているスマート電子レンジは力作でした！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536127/028e1dc9-3512-952c-95df-251ec7debed1.png)
名言も飛び交うｗ　確かに「esp32」があればなんとかなる！

# 最後に懇親会
　Forkwell様とソニー様がスポンサーとなって参加費はなんと無料!!!
　
登壇された方々とお話をして、とても楽しかったです！！！
実際に作品を手に取って中の構造や仕組みについて教えてもらえるなど、とても刺激的な会でした

社会人になってこのような会に出たことはなかったので、うれしかったです

##そして...
最後にじゃんけん大会

GR-LYCHEEをかけて私も挑みました
ですが、最後の最後に負けてしまいましたが!

![写真 2019-11-20 22 31 07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536127/fdd1967f-5a15-591f-1556-52234cfd60e4.jpeg)

なんとGR-CITRUSとその拡張ボードのWA-MIKANをいただきました
マジ感謝！！！

# 最後に
IOTをやってみたけど、なかなかできないとか、そもそもIOTて何だよ
と思っているなら参加すべきです!

いろんな方たちと交流が深められるので楽しい時間を過ごせました!
次回も参加します!!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536127/4031261f-c46f-861d-9f90-92d991d6799a.png)
WSL2 の Ubuntu 18.04 で ssh-agent がうまく起動できないとき

# 前提
WSL2 Ubuntu 18.04
Git にコミットするときの秘密鍵のパスワード入力をスキップしたくて ssh-agent に登録したかった。

# 発生した問題
よくある 

```shell

eval `ssh-agent`
```
で `ssh-agent` を起動しようとしても

```shell

Could not open a connection to your authentication agent.
```
となる。

# 解決方法
shell を指定する

```shell

ssh-agent fish
```

でいけた。

```shell
ssh-agent zsh
ssh-agent bash
```

もいけた。
gulp-autoprefixerでベンダープレフィックスを自動で付ける

`gulp-autoprefixer`を使えば、CSSのベンダープレフィックスを自動で付けられます。
## インストール
```
$ npm install -D gulp gulp-stylus gulp-autoprefixer
```

## タスクを書く
```js:gulpfile.js
const { src, dest } = require('gulp')
const stylus = require('gulp-stylus')
const autoprefixer = require('gulp-autoprefixer')

const stylusCompile = () =>
  src('./src/**/!(_)*.styl')
  .pipe(stylus())
  .pipe(autoprefixer({
    cascade: false
  }))
  .pipe(dest('./dest/'))

exports.default = stylusCompile
```
`npm run build`のコマンドで実行できるように`package.json`にスクリプトを登録しておきます。

```json:package.json
{
  ...
  "scripts": {
    "build": "gulp"
  }
  ...
}
```

## 実際に動かす
下記のようなStylusを書いて

```sass:style.styl
.foo
  display flex
  justify-content center
  align-items center
```
コンパイルすると

```
$ npm run build
```
下記のようなCSSが出力されます。

```css:style.css
.foo {
  display: -webkit-box;
  display: flex;
  -webkit-box-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  align-items: center;
}
```
## 対応ブラウザを指定する
`.browserslistrc`を`gulpfile.js`と同じ階層に作成すれば、`.browserslistrc`の内容に応じたベンダープレフィックスを付けられます。

```:.browserslistrc
last 2 versions
not ie <= 10
> 1% in JP
```
この状態で、下記のようなStylusを書いて

```sass:style.styl
.foo
  display flex
  justify-content center
  align-items center
```
コンパイルすると

```
$ npm run build
```
下記のようなCSSが出力されます。

```css:style.css
.foo {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: center;
  -ms-flex-pack: center;
  justify-content: center;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
}

```
aws-vaultの初回パスワードを忘れた時

# 背景
aws-vaultを初回起動したとき、キーチェーンのパスワード入力が求められる。
その際のパスワードを忘れてしまうと、aws-vaultが使えなくなるため、
パスワードを消して初期化したい。

# コマンド
```
rm ~/Library/Keychains/aws-vault.keychain-db
```
上記dbファイルにパスワードが格納されている模様なので、それを消せば初期化できる。

# 参考
https://github.com/99designs/aws-vault/issues/171
puppeteer-coreとMacにインストール済みのChromeを使って自動操作

いわゆる「ぐぐれかす」をPuppeteerで作って練習したときのメモ

![ggrks.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/6fe9d92d-f2df-56f1-e1e5-bd355dfeba40.gif)

## インストール済みのChrome for Macを使うには？

**puppeteer標準でChromiumブラウザがくっついてくるが、Chromiumダウンロードめっちゃ時間がかかる**ので、とりあえず手元にChromeをインストール済みなら、それを使って自動操作をしたい。

puppeteer-core を使って、手持ちのChromeのゲストセッションを開くには？と調べたら、[issueで質問](https://github.com/GoogleChrome/puppeteer/issues/288) してる人がいて、「公式Docに書いてるでしょ」って書いてたｗ

Macだったら

```js
const launchChrome = puppeteer.launch({
    // MacにインストールされているChromeを使う。
    executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
});
```

これでよさそう。

**(2021.08.05 追記) Puppeteer 10.2以降であれば、もっと簡単にかけます！**

```js
const launchChrome = puppeteer.launch({
    // MacにインストールされているChromeを使う。
    channel: 'chrome',
});
```

## ゲストセッションを開くには？

デフォルトでゲストセッションが開く？よくわからないけど、なんとなく

```js
const launchChrome = puppeteer.launch({
    // MacにインストールされているChromeを使う。
    channel: 'channel',

    args: [
        // ゲストセッションで操作する。
        "--guest",
    ],
});
```

こんな感じで指定しておくとよさそう？

## 普段ブラウザを使うように、ウインドウを開くには？

これは、launchオプションと、pageのsetViewportの両方の指定が必要。

```js
const launchChrome = puppeteer.launch({
    // MacにインストールされているChromeを使う。
    channel: 'chrome',

    // ブラウザ画面を表示しながら（ヘッドレスモードを無効にする）。
    headless: false,

    args: [
        // ゲストセッションで操作する。
        "--guest",

        // ウインドウサイズをデフォルトより大きめに。
        '--window-size=1280,800',
    ],
});

launchChrome.then(async (browser) => {
    // 大抵のサンプルコードはここで単純に browser.newPage() しているだけのものが多いが、
    // ブラウザを開いたときにすでに１つタブが開いている場合には、２つ目のタブが開いてしまう。
    // それを防ぐため、すでにタブが開いている場合にはそれを使うようにする。
    const page = (await browser.pages())[0] || (await browser.newPage());

    await page.setViewport({ width: 1280, height: 800 });

})
```

デフォルトだと、ウインドウサイズが少し小さい。なので、1280x800に指定している。

あと、多くのサンプルコードでは無造作に `browser.newPage()` しているが、自分の場合にはなぜかタブが２つ開いてしまったので、すでにタブが開いていたらそれを使うようなロジックにしてみた。

## キーボードの打鍵速度を人間味のあるスピードにするには？

### 全体的にゆっくりめに操作をしたい場合

`puppeteer.launch()` に `slowMo` オプションを指定すれば良い。
体感的には、50〜100くらいを指定するのがよさそう。

### 一部の操作だけゆっくりめに操作したい場合

`page.click` や `page.type` などのメソッドには `delay` オプションがある。

たとえば、先の「ぐぐれかす」で、検索キーワード入力部分に `delay: 200` (5キー/sec)を指定すると

```js
await page.type("input[name='q']", searchKeyword, { delay: 200 });
```

こんなかんじで、ゆっくりキーワードが入力される。

![ggrks.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/fce3271d-8eb8-fef9-6719-14c7bf8c3ed7.gif)

## まとめ

基本的な操作方法はぐぐればでてくるし、 [api.md](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md) みればAPI仕様もシンプルにわかる。
なんだけど、puppeteerはChromiumブラウザのダウンロードが遅い!!ので、puppeteer-coreと手持ちのChromeを使ってサクッと自動操作する方法をまとめてみました。

ソースコードは↓にまとめてあります。
https://github.com/YusukeIwaki/ggrks-puppeteer
opencv-pythonで右クリックイベント取得が上手く行かない

# 内容
タイトル通りです. opencv-pythonでマウスイベントを取得していたところ, **右クリックのイベント取得をしようとするとdefaultの機能でmenuが開かれてしまいました**.
調べた所なにもしないでも上手くいっている方もいるのでopencvのバージョンが原因かもしれません.

- 環境  
Ubuntu 18.04 LTS  
opencvはpipでinstall(多分これが原因)
- 日時  
2019/11/20

# 解決法
[opencv 2.2 documentation » ユーザインタフェース](http://opencv.jp/opencv-2svn/cpp/user_interface.html#cv-namedwindow)
[stackoverflow/Why does a right click open a drop down menu in my OpenCV imshow() window?](https://stackoverflow.com/questions/56623487/why-does-a-right-click-open-a-drop-down-menu-in-my-opencv-imshow-window)

によると, **右クリックでmenuが開くのはどうやらこのQtバックエンドによる機能**のようです.
なので, この機能をなくすか他のバックエンドにする必要があるみたいです.
バックエンド云々はよくわからないのと, この機能は必要ないのでこの機能をなくします.

[先の公式documentから]

- flags ウィンドウのフラグ．現在サポートされるフラグは以下のとおりです：
    - CV_WINDOW_NORMAL or CV_WINDOW_AUTOSIZE: CV_WINDOW_NORMAL を指定すると，ユーザがウィンドウサイズを変更できるようになります．逆に CV_WINDOW_AUTOSIZE を指定すると，表示画像（ ShowImage を参照してください）にフィットする様にウィンドウサイズが自動的に調整され，ユーザはウィンドウサイズを変更することができなくなります．
    - CV_WINDOW_FREERATIO or CV_WINDOW_KEEPRATIO: CV_WINDOW_FREERATIO を指定すると，アスペクト比を保たずに画像サイズが調整され，逆に CV_WINDOW_KEEPRATIO を指定すると，アスペクト比を保つように調整されます．
    - CV_GUI_NORMAL or CV_GUI_EXPANDED: CV_GUI_NORMAL を指定すると，ステータスバーとツールバーのない以前のウィンドウを表示することができます．逆に CV_GUI_EXPANDED を指定すると，機能強化された新しいGUIが表示されます．


どうやら, `cv2.namedWindow` の引数のflagsを指定すればできるようですね.

```
cv2.namedWindow("hoge", CV_GUI_NORMAL)
cv2.namedWindow("hoge", cv2.CV_GUI_NORMAL)
cv2.namedWindow("hoge", cv.CV_GUI_NORMAL)
```

### どれもだめでした!!!
なんでだろう...

[stackoverflow/NameError: global name 'CV_GUI_NORMAL' is not defined](https://stackoverflow.com/questions/28834980/nameerror-global-name-cv-gui-normal-is-not-defined)にこのような具体的な値が書いてあり, ...

```
WINDOW_AUTOSIZE = 1
WINDOW_FREERATIO = 256
WINDOW_FULLSCREEN = 1

WINDOW_GUI_EXPANDED = 0
WINDOW_GUI_NORMAL = 16

WINDOW_KEEPRATIO = 0
WINDOW_NORMAL = 0
WINDOW_OPENGL = 4096

WND_PROP_ASPECT_RATIO = 2

WND_PROP_AUTOSIZE = 1
WND_PROP_FULLSCREEN = 0
WND_PROP_OPENGL = 3
WND_PROP_VISIBLE = 4
```

`WINDOW_GUI_NORMAL = 16`  なので, ...

```
cv2.namedWindow("hoge", 16)
```

### 上手くいきました!!!

上記の数値は[High-level GUI](https://docs.opencv.org/3.4/d0/d28/group__highgui__c.html)に詳しく書いてありますね.
コマンドのフルパス展開

#コマンドのフルパス展開
通常のコマンドの前に`=`をつけることで、外部コマンドのフルパスに展開できる。
これは、エイリアスの回避に用いられる。

```
$alias ls='ls -F
$echo ls
 ls -F
$echo =ls
 /bin/ls
```
日本語プログラミング言語「プロデル」でZipfの法則のグラフを描く

## はじめに

自然言語処理・情報検索界で最も有名なのがZipf's Lawですが，これは，どんなテキストでやっても同様の傾向が見られるはずなので，[日本語text8](https://github.com/Hironsan/ja.text8)を使ってやってみます。

## 実装

### 前処理

Zipfの法則では，別に単語に分割する必要はないのですが，text8は既にスペース区切りになっているので，これをそのまま利用します。プロデルにsplit相当の手順はないので，以前実装したものがありますが，なんとこれがとても遅い。全部で何語あるかというと，

```shell
nipo@nipo:~$ wc ja.text8
        0  16900732 100000347 ja.text8
nipo@nipo:~$ 
```

1690万語です。コンパイルしても非常に遅くなります。原因は恐らく，区切り文字が出現する都度配列に追加しているからです。内部のデータ構造がどうなっているか知りませんが，配列の大きさが変わる場合，全てのデータ＋追加したデータをメモリの別の場所に移すはずなので，これを1600万回もやっていたらどんどん遅くなるでしょう。

今回は，別に単語を配列に入れる必要がないので，1語ごとに辞書に出現回数をカウントしていくことにします。よって，次のような，アクセスする度に次の単語を返す手順を持つ種類を書きました。

```プロデル:文字列操作.rdr
文字列分割器とは
	【分割対象：文字列】は，「」。
	【前回位置：整数】は，0。
	【今回位置：整数】は，1。
	はじめ（対象）の手順
		分割対象は，対象。
	終わり
	自分を【区切り文字：文字列】で分割する手順
		繰り返す
			もし今回位置が分割対象の文字数より大きいなら
				「」を返す
			もし終わり
			もし今回位置が分割対象の文字数なら
				今回位置は，今回位置＋1。
				分割対象の［前回位置＋1］文字目以降を返す。
			もし終わり
			もし分割対象の［今回位置］文字目が区切り文字なら
				【結果】は，分割対象の［前回位置＋1］文字目から［今回位置－前回位置－1］文字取り出したもの。
				前回位置は，今回位置。
				今回位置は，今回位置＋1。
				結果を返す。
			でないなら
				今回位置は，今回位置＋1。
			もし終わり
		繰り返し終わり
	終わり
終わり
```

これを使って，良い感じに辞書に頻度を数え上げていきます。

```プロデル
「文字列操作.rdr」を参照する。
「行列.rdr」を参照する。
「グラフ描画.rdr」を参照する。
「色.rdr」を参照する。
「Produire.WinControl.dll」を利用する。
「Produire.PGraphics.dll」を利用する。

コーパスという文字列分割器（「ja.text8」から読み込んだもの）を作る。
【頻度：辞書】。
繰り返す
	単語は，コーパスを「 」で分割したもの。
	もし単語が「」なら
		繰り返しから抜ける
	もし終わり
	もし頻度が無なら，頻度（「_［単語］」）は，0。
	頻度（「_［単語］」）は，頻度（「_［単語］」）＋1。
繰り返し終わり
```

### データを並べ替える

サイズを指定しない場合さっきと同じことが起こるので，サイズを指定して配列を作りたいのですが，これには固定長配列という種類を用います。しかし，この固定長配列は並び替え手順が実装されていません（マニュアルには書いてある）。

また，コンパイルすると，配列の要素へのアクセスが非常に難しくなるので，注意します。

```プロデル
【頻度一覧：整数の配列（頻度の個数）】は，固定長配列（頻度の個数）を作ったもの。
カウンタは，1。
限界は，頻度一覧の個数。
頻度の見出しを【キー】へそれぞれ繰り返す
	もしカウンタが限界未満なら
		頻度一覧（カウンタ）は，頻度（キー）。
	もし終わり
	カウンタは，カウンタ＋1。
繰り返し終わり
```

さて，これで頻度一覧に頻度の値が全て入ったので，大きい順に並べ替えます。

```
頻度一覧を大きい順に並び替える
```

これはエラーです。固定長配列には並び替えの手順が実装されていません。そこで，配列を経由します。

```プロデル
【頻度降順：配列】は，｛｝。
頻度降順は，頻度一覧のクローン。
頻度降順を大きい順に並び替える。
```

これで準備ができました。

### 描画

今回は，20000を超えるデータ数があり，プロットしても何も見えないので，上位600個に限ります。

```プロデル
データという行列（1，600）を作る。
データの中身（1）は，頻度降順の1番目から600個切り出したもの。

グラフというグラフ（600，600）を作る。
グラフにデータで折れ線グラフを描く。
グラフを表示。
待機。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150160/421ac06f-9d13-ac86-edde-f795feac69f1.png)

おお～！！Zipfみがありますね！！
PythonでPDF結合GUIを作る その２

今回はその2です

　[その1　TkinterでUI作成](https://qiita.com/you3feet/items/ba4f0c05d236101fe44d)
　**その2　PyPDF2でPDF操作**
　その3　pyinstallerでexe化＋アイコンを付ける

# ログインユーザー名を取得
保存先をデスクトップに指定するためにログインユーザー名を取得

```python
merger = PyPDF2.PdfFileMerger()
user = os.getlogin()
username= str(user) 
```
#ボタン「Open」のアクション
以下の流れで結合するPDFファイルを確認します
　
　ファイルパス確認
　　  　↓
　PDFファイルをリストにappend
　　  　↓
　テキストボックスに結合するPDFファイルを表示

```python
# Open
def clicked():
    txt3.delete(1.0, tkinter.END)
    filePath = txt1.get()

    if os.path.exists(filePath):
        pass
    else:
        txt3.insert('1.0','パスが見つかりません')

    drawings = []
    allFiles = os.listdir(filePath)
    
    for f in os.listdir(filePath):
        if os.path.join(filePath, f)[-4:] == '.pdf':
            drawings.append(f)
  
    count = int(len(drawings))
    txt3.insert('1.0','以下のPDFファイルを結合します\n\n')
    for i in range(count):
        txt3.insert(1.0 * i + 3.0, drawings[i] + '\n')
```
#ボタン「Merge」のアクション
PDFファイルを結合して "ファイル名.pdf" をデスクトップに保存します

```python
# Merge
def merge():
    filePath = txt1.get()
    #filePath = str(txt1.get())
    savePath = 'C:\\Users\\' + username + '\\Desktop' 
    savedName = txt2.get()

    drawings = []
    allFiles = os.listdir(filePath)
    for f in os.listdir(filePath):
        if os.path.join(filePath, f)[-4:] == '.pdf':
            merger.append(os.path.join(filePath, f))
        
    merger.write(os.path.join(savePath, savedName + '.pdf'))
    merger.close()

    txt3.insert(tkinter.END, '\n\n**************************\n\n')
    txt3.insert(tkinter.END, savedName + '.pdf　として保存しました')
```
#ボタンにcommandを追加
その1でコメントアウトしていた箇所です

```python
# Openボタン
button = tkinter.Button(root, text="Open", command=clicked, width=8, height=2, font=(u'Meiryo', 8), bg='#add8e6', fg='#000000')
button.place(x=80, y=120)

# Mergeボタン
button = tkinter.Button(root, text="Merge", command=merge, width=8, height=2, font=(u'Meiryo', 8), bg='#4169e1', fg='#ffffff')
button.place(x=200, y=120)
```

できました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/447145/d053eb76-d434-16a9-b251-9d0957fffc37.png)


# 参考
https://pg-chain.com/python-button-command
Sourcetrail(macOS版)をJavaコードで使ってみる

<h3>Sourcetrail</h3>
Sourcetrailがオープンソース化されました。
ソースコードの全体像と詳細を提供する検索エンジンです。
<a href="https://www.sourcetrail.com">Home Page</a>
<a href="https://github.com/CoatiSoftware/Sourcetrail">Git</a>
<h4>対象言語</h4>

- C
- C++
- Java
- Python

他の言語は「SourcetrailDB」ツールで拡張出来るようです。

<h3>インストール</h3>
<a href="https://github.com/CoatiSoftware/Sourcetrail/releases">Download Page</a>

- 使用したいOS・形式をダウンロードする
今回はmacOSのzip形式
「Sourcetrail_2019_4_61_macOS_64bit.zip」(2019/11/20時点最新)
- ファイルを解凍する
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_01.png)

- Sourcetrail.appが実行ファイル
Applicationフォルダに移動する、またはそのまま使用

<h3>実行</h3>

- Sourcetrail.appを実行

<h3>使用(Java)</h3>

- 起動画面
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_02-scaled.png)

- New Project選択
<a href="http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_03.png"><img src="http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_03-1024x769.png" alt="" width="1024" height="769" class="alignnone size-large wp-image-2261" /></a>
- 必要事項入力

Sourcetrail Priject Name：プロジェク名
Example：ExampleJava
Sourcetrail Priject Location：Sourcetrailファイルを保存する場所
Example：/Users/shi-n/xyz/sourcetrail/

- Add Source Group選択

JavaタブのEmpty Java Source Group選択
Next選択
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_04.png)

- Java Version選択
選択出来るのは10まで
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_05.png)

- Files & Directories to Indexにソースのトップフォルダを指定
再起的にソースコードを検索してくれる
「show files」で対象ファイルを確認出来ます
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_06.png)

- コンパイルするのに使用するClass Pathがあれば追加する
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_07.png)

- 最終確認してCreate選択
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_08.png)

- 設定に問題がなければStart Indexingダイアログが表示、Start選択
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_09-scaled.png)

- Start Indexingダイアログが表示されない場合、Javaパスがない等のエラーが表示されるため、解決する
Javaパスがない場合は「PREFERENCES」メニューで設定画面表示
「Java Path(64bit)」にlibjli.dylibのパスを設定
Example：/Library/Java/JavaVirtualMachines/jdk-10.0.2.jdk/Contents/Home/lib/jli/libjli.dylib

- 実行結果を確認
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2019/11/sourcetrail_10-scaled.png)

<h3>今後やってみたいこと</h3>
- 解析を色々確認
- Windowsで動作
- Swiftを対応してみる！？
LaravelでMySQLに接続エラーをしないために【MAMP環境】

![スクリーンショット 2019-11-20 18.03.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472701/484656c7-3e73-1c97-8303-d7a6a00e886b.png)

*〜事の経緯〜*

認証機能を`php artisan make:auth`で作り、migrateで認証テーブルを作成しようとするも...

<b>php artisan migrateでエラー起きた...</b>

```
SQLSTATE[HY000] [2002] Connection refused 
(SQL: select * from information_schema.tables where table_schema = 
laravel and table_name = migrations and table_type = 'BASE TABLE')
```

現在Laravel勉強中なのですが、今までSQLiteを使っていて、今回はベーシックにMySQLに繋ごうとしたら、少し苦戦しました。

原因は`.envとdatabase.phpの記述ミス`でしたが、同様の罠にハマる方に参考になればと思います。

<b>環境</b>
OS : macOS Mojave 10.14.5
MAMP : 5.3
Laravel : 5.8.x

<b>MAMPがmacに入っている前提で進めます</b>

##手順１：phpmyadminでデータベース作成

phpmyadminでDBを作っておきます。
今回は`Laravel`としました。

##手順２：MAMPの情報を控える
アプリを起動したら開かれるwebページに乗っていますね。

![スクリーンショット 2019-11-20 18.49.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472701/1390eb64-6a47-3c1e-e96d-a75a0f63291d.png)

このSocketが肝になります。

では、まず.envから修正しましょう。
##手順３：.envの修正

デフォルトだと以下のようになっています。

```
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USERNAME=root
DB_PASSWORD=
```

これを、MAMPの情報を元に、以下のように変えます。

```
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=8889
DB_SOCKET=/Applications/MAMP/tmp/mysql/mysql.sock
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=root
```
DB_SOCKETが新しく入り、その他各種情報も変えます。
`DB_DATABASE`は先ほど作ったLaravelデータベースを指定しています。

その次はdatabase.phpです。

##手順４：database.phpの修正

デフォルトのdatabase.phpはこうなっています。

```
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''),
```
それを、以下のように変えます。

```
'port' => env('DB_PORT', '8889'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', 'root'),
```

以上になります。

`php artisan migrate`でテーブル作れるかな...

![スクリーンショット 2019-11-20 18.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472701/d947eb67-f0c9-0f69-1a69-e302463a7bd6.png)

*<b>やったぜ</b>*

確認のために、phpmyadminを開きます。

![スクリーンショット 2019-11-20 18.47.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472701/138104d0-3502-50e2-333e-3a8a0ae0f7c2.png)

テーブルが作成されている＝DBと接続できている

よかったです😌
Blenderで指定したオブジェクト直下にあるオブジェクトの名前をprintする

Mayaで言うとこのlistRelatives -cはコレ
objectNameのところに指定したいオブジェクト名を入れるだけ

```
childrenList = bpy.data.objects['objectName'].children

for child in childrenList:
    print(child.name)
```

自分用メモ
[memo] my provision recipe

```shell
ssh root@xxx.xxx.xxx.xxx -A
sudo apt-get update -y
mkdir app ; cd app
sudo apt-get install rbenv ruby-build build-essential libssl-dev libmysqlclient-dev nodejs npm redis -y
git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
rbenv install 2.6.2
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
source ~/.bashrc
rbenv rehash
rbenv global 2.6.2
gem install bundler -v '1.17.2'
bundle install --path vendor/bundle -j4
sudo npm install n -g
sudo n stable
sudo apt purge -y nodejs npm
exec $SHELL -l
```
Windows 10 メモリ解放

# Windows 10 メモリ解放 by Microsoft 純正ツール

最近、Docker for Windows で遊んでいるのだが、起動しようとするとメモリ不足で失敗することがある。   
メモリ 8GB じゃ足りないかな・・・と思いつつ、色々試した結果、Microsoft 純正のメモリ解放ツールが秀逸だった。

## Resource Kit Tools の取得

以下のページより、Windows Server 2003 Resource Kit Tools をダウンロード  
https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=17657

## 実行ファイルをパスの通ったフォルダに格納

> 余分なものをインストールしたくなかったので、以下では 7-Zip を使って exe のみ取り出しているが、ZIPを解凍し、msi でインストールしてもよい。なお、その場合、実行ファイル（empty.exe）は以下に格納されている。  
> C:\Program Files (x86)\Windows Resource Kits\Tools

1. ダウンロードした rktools.exe を 7-Zip で開く
<img width="287" alt="rktool1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/d1e989bf-bb8c-92b5-7665-995c7b73cda7.png">

1. rktools.msi を 7-Zip で閲覧
<img width="403" alt="rktool2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/630bc0b3-f46f-1bfc-6c4a-08429d9e0c8e.png">


1. empty.exe を C:\Windows\system32 にコピー
<img width="415" alt="rktool3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/cc6f69df-a835-5eb5-12aa-6eae6388b5e9.png">


1. バッチファイルを作成
<img width="63" alt="rktool4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/bf337605-d3a0-8a7a-6f1a-b2794553064b.png">
内容は以下の通り。

```bat:empty.bat
@echo off
empty.exe *
```


## 実行結果

### before  
使用中メモリ：7.0 GB 
<img width="570" alt="rktool_exec_1before.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/8f494fb0-cdfa-bd6b-4915-80abf0021d0a.png">


### after  
使用中メモリ：5.6 GB  
20% の削減に成功！

<img width="571" alt="rktool_exec_3after.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/f6471750-4588-943f-9ce0-29aeb65216ba.png">


## 番外編：タスクスケジューラに登録

・・・と思ったが、任意に実行するだけで良いので以下のようにした。

## 番外編：バッチをタスクバーに固定

1. batch ファイル（empty.bat）を右クリックして、「ショートカットの作成」

1. 上記ショートカットのプロパティを開く

1. リンク先の設定  
「ショートカット」タブにある「リンク先」に以下の内容を設定  
C:\Windows\System32\cmd.exe /c [batchファイルのパス]  
<img width="312" alt="rktool_cmd_prop3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/b507af5e-8641-24fc-2ecc-28ef7d4f4420.png">


1. アイコンも変更（個人的嗜好）  
コマンドプロンプトのプロパティの「ショートカット」タブを開き、下の方にある「アイコンの変更」ボタンを押下。  
ここでアラートが挙がっても、無視して「OK」。  
「アイコンの変更」ダイアログボックスで、「このファイル内のアイコンを検索」に、ディスククリーンアップが存在する以下を設定  
%windir%\system32\cleanmgr.exe  
使われてない方の画像を選択
<img width="539" alt="rktool_cmd_prop4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/7617d308-2926-0d53-5bd7-ccd398eafeaa.png">


1. 名前の変更（個人的嗜好）
「全般」タブにて、ショートカットの名前を変更 
<img width="313" alt="rktool_cmd_prop5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/d510e341-cb51-386c-77a1-19669d1179a2.png">


1. 「OK」でプロパティを閉じる

1. ショートカットを右クリックして「タスクバーにピン留めする」

![last.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/533310/7b9bbe2f-c36f-0296-de82-a43acaa90d63.png)

これでもう大丈夫！

---
Pythonで株式システムトレードのストラテジーを評価してみた。

システムトレードでは、過去の株価データに基づいて、ストラテジーを検証します。

例えば、以下の検証結果は、とある順張りの検証結果です。
![【分析結果】_名前なし__7順張り250日20日_20191118_pdf（2___12ページ）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256260/57ee7bfe-4f89-419e-099b-8a580f3baa09.jpeg)

しかし、それは一つのシナリオでの評価にしか過ぎません。

そこで、出来上がったストラテジーの勝率、利益率、損益率、資金量で複数回シミュレーションしたらどのような結果になるかPythonを使って評価してみました。

```
#ライブラリーの導入
import pandas as pd
import matplotlib.pyplot as plt
import random

#評価用の関数
#asset 初期資本
#bet 資本の何％を投入するか
#probability 勝率 
#win 平均利益率
#loss 平均損率
#transaction 取引回数
def sim(asset, bet, probability, win, loss, transaction):
  result = []
  for i in range(transaction):

#乱数が勝率以下なら勝ち
    if random.random() < probability:

#資産は、投入した資産かける平均利益率分増える。
#今回は複利ですが、このあたりを変更すれば単利にできます。
      asset = asset + (asset * bet * win)

#負けた場合、投入した資産かける平均損率分減少する。      
    else:
      asset = asset - (asset * bet * loss)

#取引結果をリストに格納する。   
    result.append(asset)    

  return result

#評価用の関数２
def mon(asset, bet, probability, win, loss, transaction=100, test=1):
  df = pd.DataFrame()

#試行回数分、評価用関数を呼び出し、データフレームに格納する。
  for i in range(test):
    df[i] = sim(asset, bet, probability, win, loss, transaction)

#グラフ表示
#補助線用の設定
  xmin = -3
  xmax = transaction

#ブラフサイズの設定
  plt.figure(figsize=(25, 15), dpi=50)
  plt.plot(df)

#補助線の設定
  plt.hlines([asset], xmin, xmax, "blue")
  plt.show()

#統計要素の表示
  print(df.iloc[transaction - 1].describe())

```

```
#資金量300、リスク20%、勝率61.54％　平均利益率5.83％　平均損率4.63％　トレード回数250回、試行回数300回で、検証してみる。
mon(300, 0.2, 0.6154, 0.0583, 0.0463, 250, 300)
```
![Untitled11_ipynb_-_Colaboratory.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256260/5ed46c0e-5cd1-7743-d0e9-2daf831ee27c.jpeg)

こうしてみると、取引回数50回程度まで利益が上がらないケースもあることがわかります。

別のストラテジー（逆張り）では、

![Untitled11_ipynb_-_Colaboratory.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256260/73534646-6fab-65b2-fbb4-e28ecc733872.jpeg)

でした。

こちらのほうが安定して資産が増えて行きます。

今回は出来上がったストラテジーから勝率や平均利益率などの値を取り出しているので、
統計的な妥当性があるかどうかはわかりません。

皆さんはどう思いますか？
Raspberry Pi Zero W をベクトルタイルサーバにするまで

## Raspbian イメージをダウンロード
Raspbian Buster Lite Minimum image based on Debian Buster のイメージをダウンロードします．

今回の検証作業では，`2019-09-26-raspbian-buster-lite.zip` を使いました．

## unzip して img ファイルを得る
上記の`2019-09-26-raspbian-buster-lite.zip`を unzip して `2019-09-26-raspbian-buster-lite.img`を入手しました．

なお， zip ファイルでは 433MB であったところ， img ファイルは 2.1GB 程度になっていました．

## microSD カードに img を書き込む
私は macOS を使ってこの作業をしています．買ってきた 32GB の microSD カードをアダプタに入れて USB で接続すると， `/Volumes/NO NAME` に MS-DOS(FAT32) 形式で 31.09GB のディスク領域がマウントされました．これを対象に，コマンドラインベースで書き込みの作業を行なったところ，次のとおりです．

1. `diskutil list` を実行することで，私の計算機環境では，`/dev/disk2`（ディスク）あるいは`/dev/disk2s1`（パーティション）が microSD であることを確認しました．
2. `diskutil unmountDisk /dev/disk2` でアンマウントしました．
3. `sudo dd bs=1m if=/Users/hfu/Downloads/2019-09-26-raspbian-buster-lite.img of=/dev/rdisk2 conv=sync`を実行し，イメージを microSD ドライブに書き込みました．この書き込み作業には，まとまった時間がかかりました．また `rdisk` と `r` を付して作業をしています．
4. 書き込み終了後に，`sudo diskutil eject /dev/rdisk2` で microSD をアンマウントし，取り外し可能にします．

なお，このイメージ書き込み時点で，書き込み先のディスクの使用領域は 264.3MB でした．

## WiFi 経由で Raspberry Pi に接続可能になるようにする．
Raspberry Pi Zero W は WiFi 経由でのみリモートログイン可能ですが， WiFi アクセスポイントの情報を Zero W に知らせておくことが必要です．そのためには， `/Volumes/boot/wpa_supplicant.conf` を作成し，次のような内容を書き込んでおくと良いです．

```
country=JP
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
  ssid="あなたの SSID"
  psk="あなたの WiFi パスワード"
  key_mgmt=WPA-PSK
}
```

ただし，`/wpa_supplicant.conf` は， Zero W のブートごとにシステムに反映されて，ファイル自身はなくなるように見えています．

このため，`/wpa_supplicant.conf` のコピーを `/wpa_supplicant.conf_` といった名前で作っておき，あとで再利用できるように工夫しています．

## リモートログイン
上記の設定まで済ませてから， Zero W をブートし，同じ WiFi ネットワークにぶら下がった端末から，次のようにして Zero W に接続します．

```zsh
$ ssh pi@raspberrypi.local
```

### とりあえずパスワード変更，要すればマシン名変更
```zsh
$ sudo raspi-config
```
Change User Password でパスワードを変更します．

必要に応じて，マシン名も変更します．同じ WiFi ネットワークに複数台の Raspberry Pi を使用する場合には，マシン名を変更してリブートし，新しいマシン名で再度ログインする必要があると思います．

### ホスト OS を更新する
```zsh
sudo apt update
sudo apt upgrade
```

### Docker を入れるために必要なツールを入れる
```zsh
sudo apt install curl git tmux
```

### スワップファイルを増やす
Raspberry Pi Zero W の場合，メモリが小さいので， microSD カードがダメージを受けそうなことは覚悟しつつ，スワップファイルを増やします．

すなわち，`sudo vi /etc/dphys-swapfile`して，`CONF_SWAPSIZE=100`であるところを，`CONF_SWAPSIZE=2048`くらいにしておきます．これで，スワップ領域が2GB確保されます．

### Docker をインストールする
```zsh
$ curl -fsSL https://get.docker.com -o get-docker.sh
$ chmod u+x get-docker.sh
$ ./get-docker.sh
$ sudo usermod -aG docker pi
```

### UNVT の Docker イメージを実行する
例えば，次のような感じです．UNVT の中の作業については，原稿を改めます．

```zsh
docker run -ti --rm unvt/koji
```
Zephyr + STM32F769 Discovery Kit > Timer > 2秒周期でLEDを点滅する実装

```txt:動作環境
Ubuntu 18.04 LTS
STM32F769 Discovery Kit (以下、STM32F769)
Zephyr 2.1.0-rc1
```

### 概要

- KernelのTimer機能を使う
- LEDのサンプルblinkyプロジェクトをベースとする

### 参考

- [Docs / Latest » API Reference » Kernel Services » Timers](https://docs.zephyrproject.org/latest/reference/kernel/timing/timers.html)
    - v2.1.0-rc1の最新版

### 手順

1. blinkyプロジェクトをコピー (wrk_blinky_timerとする)
    - `cp -rp samples/basic/blinky samples/basic/wrk_blinky_timer`
2. src/main.cを後述のようにする
3. `west build -p auto -b stm32f769i_disco samples/basic/wrk_blinky_timer`
4. `west flash`

以下はmain.cをTimer使用にしたもの。

```src/main.c
/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
Nov.20, 2019 change to timer driven 
	- use timer instead of k_sleep() in while()
	- branched from [blinky] project
*/

#include <zephyr.h>
#include <device.h>
#include <drivers/gpio.h>

#define LED_PORT	DT_ALIAS_LED0_GPIOS_CONTROLLER
#define LED		DT_ALIAS_LED0_GPIOS_PIN

struct device *dev;

struct k_timer my_timer;
void my_expiry_function(struct k_timer *timer_id)
{
	static u32_t cnt = 0;

	gpio_pin_write(dev, LED, cnt % 2);
	cnt++;
}

void main(void)
{
	dev = device_get_binding(LED_PORT);
	gpio_pin_configure(dev, LED, GPIO_DIR_OUT);

	k_timer_init(&my_timer, my_expiry_function, NULL);
	k_timer_start(&my_timer, K_SECONDS(1), K_SECONDS(1)); // first duration=1s, interval=1s

	while (1) {
		//
	}
}
```

### 結果

画面左下のLED(青色ボタンの右側の点灯しているLED)が2秒周期で点滅する。

![IMG_1361.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/244b8212-150d-e345-76fe-5e9153519dba.jpeg)



### 備考

- devの定義の仕方がいまいちだが、タイマーの練習としてとりあず
ディレクトリ移動の手法

普通は`cd`コマンドのみでこと足りるが、他にも覚えておくと便利なコマンドがある。
#`pushd`、`dirs`と`popd`コマンド
##ディレクトリのスタックへの保存
```
pushd [NAME]
```
`pushd`コマンドを利用すると、カレントディレクトリをスタックに保存して、NAMEディレクトリに移動する。
スタックに保存されたディレクトリは`dirs`コマンドにより確認できる。

```
dirs
```
オプションを以下に示す。

- `-l` -> すべてのディレクトリをフルパスで示す。
- `-p` -> １行に１要素で示す。
- `-v` -> 番号を付して示す。
- `-c` -> ディレクトリスタックを空にする。

##スタックを利用したディレクトリ移動
`pushd`コマンドのみでスタックの上位2ディレクトリを交換する。
`pushd +N`とするとN番のディレクトリが先頭に来るようスタックが循環する。
また、`popd`コマンドを利用するとディレクトリを順次スタックからおろしていくことになる。

#ハッシュコマンドを利用した便利なディレクトリ移動
ハッシュテーブルにディレクトリのパスを登録することによって簡単にディレクトリを移動することができる。

```
$hash -d ho=~/Documents/hoge
$cd ~ho
$pwd
 ~/Documents/hoge
$cd ~
$pwd
 ~
$ ~ho
$pwd
 ~/Documents/hoge
```

ハッシュから消去するときは`unhash -d`を用いる。
courseraの字幕を読みやすくする.py

courseraの字幕をターミナルで読むのに読みやすくしたくて作りました。やったことは｢。」を「。」と改行を２つにreplaceしました。


```python:convert.py

import sys

args = sys.argv
f = open(args[1])
data = f.read()
f.close()
print(data.replace('。', '。' + '\n\n'))
```

```terminal:実行方法
python convert.py subtitle.txt
```


[before]
ああああああああああああああああああああああああああああああああああああああああああああ。いいいいいいいいいいいいいいいいいいいいいいいいいいい。うううううううううううううううううううううううううううううううううううううううううう。えええええええええええええええええええええええええ。おおおおおおおおおおおおおおおおおおおおおおおおおお。

[after]
ああああああああああああああああああああああああああああああああああああああああああああ。

いいいいいいいいいいいいいいいいいいいいいいいいいいい。

うううううううううううううううううううううううううううううううううううううううううう。

えええええええええええええええええええええええええ。

おおおおおおおおおおおおおおおおおおおおおおおおおお。
tif画像を連続で読み込んで、テキストのQRコードの内容を書き出し

QRコードシリーズ

exeをクリックすると同階層以下の、ファイルをなめて、tifファイルをすべて、QR読み込みし、テキストに書き出すツール。

↓これの続きです
ーーー
画面表示（ｽｸﾘｰﾝｼｮｯﾄ）から、QRｺｰﾄﾞを読み込んで、ﾃﾞｺｰﾄﾞするC#の単体ｱﾌﾟﾘ⇒テキスト書き出し版
https://qiita.com/santarou6/items/9a26c28828c1dd1a6556
ーーー

```c#:tiff_qr_decode.cs

//c:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe /reference:QRCodeEncoderDecoderLibrary.dll /target:winexe tiff_qr_decode.cs

using System;
using System.Windows.Forms;
using System.Drawing;
using QRCodeEncoderDecoderLibrary;

public class tiff_qr_decode
{
 public static void Main(string[] args)
 {
    QRDecoder	QRCodeDecoder;
    Bitmap		QRCodeInputImage;
    QRCodeDecoder = new QRDecoder();

    DateTime dt = DateTime.Now;
    string dt_s = dt.ToString("yyyyMMdd_HHmmss");
    System.IO.File.WriteAllText(@".\" + dt_s + ".txt", dt_s + Environment.NewLine);

    string appPath = System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase;

    System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(appPath);
    System.IO.FileInfo[] files = di.GetFiles("*.tif", System.IO.SearchOption.AllDirectories);

    foreach (System.IO.FileInfo f in files)
    {
        System.IO.File.AppendAllText(@".\" + dt_s + ".txt", f.FullName);
        System.IO.File.AppendAllText(@".\" + dt_s + ".txt", "\t");

        QRCodeInputImage = new Bitmap(f.FullName,true);

        byte[][] DataByteArray = QRCodeDecoder.ImageDecoder(QRCodeInputImage);


        //string Result = System.Text.Encoding.GetEncoding(932).GetString(DataByteArray[0]);
        string Result = System.Text.Encoding.UTF8.GetString(DataByteArray[0]);
        //string Result = System.Text.Encoding.GetEncoding(51932).GetString(DataByteArray[0]);

        //ビジネスロジック  
        //string str1 = Result.Replace("ω", "　");
        //str1 = str1.Replace("Ω", "\t");
        string str1 = Result;

        System.IO.File.AppendAllText(@".\" + dt_s + ".txt", str1);
        System.IO.File.AppendAllText(@".\" + dt_s + ".txt", Environment.NewLine);

    }

 }

}
```

注：
集めるファイルがtifではなく、jpgの場合は、
途中の、GetFilesで読んでいるファイルを
"*.tif"を、"*.jpg"にするだけでよいと思います
Ansibleに入門する

# 今回の目標

- Dockerを導入したLinux環境上で、Ansibleを導入したDockerイメージをビルドします
- コンテナの中でplaybookを実行して、ホストOSのファイル一覧を取得します

# Dockerイメージの作成

Dockerfileを作ります。vimなど便利そうなツールは入れておきます。

```dockerfile
FROM centos:8

RUN yum -y install epel-release && \
    yum -y update && \
    yum -y reinstall glibc-common && \
    yum -y install which vim net-tools glibc-langpack-en langpacks-ja python36 openssh-clients passwd sshpass && \
    rm -f /etc/localtime && \
    ln -fs /usr/share/zoneinfo/Asia/Tokyo /etc/localtime && \
    pip3 install ansible

RUN mkdir /etc/ansible && \
    chmod 777 /etc/ansible && \
    touch /etc/ansible/hosts && \
    chmod 666 /etc/ansible/hosts

ENV LANG="ja_JP.utf8"
```

ビルド＆実行します。

```bash
docker build -t ansible .
docker run -it --rm ansible bash
```


# Ansibleを実行する準備

インベントリファイルを用意します（デフォルトで/etc/ansible/hosts）。
コンテナ内からホストOSを操作するようにします。

```
172.17.0.1

[all:vars]
ansible_ssh_user=myuser
ansible_ssh_pass=mypassword
```

playbookを用意します。ホストOS上のディレクトリのファイルを検索して出力します。

```yaml
- hosts: all
  tasks:
    - name: find
      find:
        paths: /home/myuser/mydirectory
        recurse: true
      register: result
    - name: debug
      debug: var=result
```

# 実行


```bash
# 一度、sshログインしてknown_hostsに入れておく
ssh myuser@172.17.0.1

# playbookを実行する
ansible-playbook myplaybook.yaml
```

JSON形式で出力されました。

```json
PLAY [all] ***********************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************
ok: [172.17.0.1]

TASK [find directory] ************************************************************************************************************************************************************************
ok: [172.17.0.1]

TASK [debug] *********************************************************************************************************************************************************************************
ok: [172.17.0.1] => {
    "result": {
        "changed": false,
        "examined": 26,
        "failed": false,
        "files": [
            {
                "atime": 1573551290.6783524,
                "ctime": 1573551252.5081663,
                "dev": 64768,
                "gid": 1000,
以下省略
```
初心者によるプログラミング学習ログ 164日目

# 100日チャレンジの164日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

164日目は

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>164日目<br><br>今回もwebサイトコーディング課題<br><br>調べながらだからなかなかすすまんな〜<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a> <a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1196898756265857024?ref_src=twsrc%5Etfw">November 19, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#Slack がリッチテキストになって 引用/コードブロックからの改行が難しくなった -> 3連続エンターだ

時は西暦2019年11月。
環境はMac App。日本語の設定などによっても動作が変わるかもしれないが未確認。

# 改行からの脱出

ShiftとかCommandとかの組み合わせじゃなくて 連続エンター！

![image](https://user-images.githubusercontent.com/13635059/69209570-10540680-0b9b-11ea-81da-ed5820a40efa.png)

ちなみに冒頭の引用から、さらに上にフラットな文字の挿入は、いまのUI的に難しいかもしれない。

# 冒頭への改行挿入

引用ボタンを押していちど解除するしか無いのだろうか。

と思ったらこちらは、上に改行を入力してからDeleteキーでいけた。

![image](https://user-images.githubusercontent.com/13635059/69209619-41ccd200-0b9b-11ea-984e-dccbe3876ac3.png)

![image](https://user-images.githubusercontent.com/13635059/69209660-5d37dd00-0b9b-11ea-8cf4-63ccf5f100ae.png)
![image](https://user-images.githubusercontent.com/13635059/69209661-5dd07380-0b9b-11ea-9ac3-cf703c21d11d.png)

# テキストエリアに標準規格を！

emoji 3,0 とかみたいに

Rich Textrform 2.3 みたいな


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2744

# ref
[Slack の WYSIWYG を無効にしたい - Qiita](https://qiita.com/tdkn/items/2e12707b7a44fa8ee087)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
papermill × Jupyter Notebookでドキュメント化された解析ワークフローを作る

[昨日の記事](https://qiita.com/antiplastics/private/1f2221332ea509af3328#ケース3-レポート)でも書いたように、ワークフローに文章や画像を関連づけさせたいのだが、[Papermill](https://papermill.readthedocs.io/en/latest/)というJupyter Notebookをバッチ実行するためのPythonパッケージがあったので、これを使ってワークフローを構築した。

ここでは1細胞RNA-Seqのデータ**data/input.csv**と、ラベル情報**data/label.csv**というファイルに対して、複数の次元圧縮を試すというタスクを一度に行った。

なお、RをJupyter notebookで使えるようにするために、IRkernelのインストールと、.ipynbファイルのkernelspecのところを以下のように書き換えた。

```json
  "kernelspec": {
   "display_name": "R",
   "language": "R",
   "name": "ir"
  },
```

あとは、

```bash
jupyter notebook workflow.ipynb
```

で、ノートブックを起動して、上から順にひたすら次元圧縮を試すノートブックを作り込んだ後に、入力、出力ファイルの場所や、圧縮次元数を後からPapermillの引数として渡せるように書いたら、以下のようにPapermillを実行した。


```bash
papermill workflow.ipynb output/papermill/output.ipynb \
-p infile data/input.csv -p infile2 data/label.csv -p  \
outdir output/papermill -p pca_ndim 3 -p nmf_ndim 4  \
-p mds_ndim 4 -p lda_ndim 3 -p som_ndim 2 -p isomap_ndim 2 \
-p lle_ndim 2 -p dmap_ndim 4 -p tsne_ndim 2 -p umap_ndim 2 \
-p tumap_ndim 2 -p fatlas2_ndim 2
```

これにより、output/papermillのところに、次元圧縮の結果ファイルやoutput.ipynbというノートブックが出力されるようになる。papermillで指定されたパラメーターはノートブックに埋め込まれているのがわかる。

https://github.com/kokitsuyuzaki/workflow_benchmark/blob/master/output/papermill/output.ipynb
https://colab.research.google.com/github/kokitsuyuzaki/workflow_benchmark/blob/master/output/papermill/output.ipynb

![スクリーンショット 2019-11-25 11.59.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/e18d2c3b-2583-13dd-5304-d11cb6423684.png)

![スクリーンショット 2019-11-25 11.59.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/c8a57dad-a874-d696-4bd1-cc6791202f86.png)

![スクリーンショット 2019-11-25 12.00.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/5bc22cd0-bb2a-288a-3d89-5151433f9d1c.png)

以下のように出力されたほうのノートブックを起動しておくと、実行途中の様子を確認できるのも便利。

```bash
jupyter notebook output/papermill/output.ipynb
```

ただし、[昨日の記事](https://qiita.com/antiplastics/private/1f2221332ea509af3328#ケース2-試行錯誤)でも書いたように、実データではパラメーターチューニングしたいのと、パラメーターの値次第ではコケるため、この書き方だと全計算をやり直す必要が出てくるので、各次元圧縮手法ごとにノートブック化&Dockerコンテナ化して、複数のパラメーターごとに分散処理するような使い方のほうがいいかもしれない。

## 参考
https://qiita.com/hrappuccino/items/d4961e1e42c82c52ef64
https://qiita.com/noko_qii/items/62a7f70fceb6153620f4
qを試してみた

### qとは

[q](#https://github.com/harelba/q)とはcsv、tsvなどのファイルをデータベーステーブルのように扱い、それらに対してSQLを実行するというものです。

類似のツールとしてAWSが提供する[Athena](#https://aws.amazon.com/jp/athena/)などがありますが、開発用PCで捌けるような比較的少数のデータに対してサクッとSQLを使いたい方などには`q`は向いているかもしれません。

### インストール

[開発元が公表しているインストール手段](#http://harelba.github.io/q/install.html)として`Mac OS`、`Windows`、`Linux`と大方のOSに対応しているようです。
また[Dockerイメージ](#https://hub.docker.com/r/eiryu/q-text-as-data)、[Python API](#https://github.com/harelba/q/blob/generic-injected-streams/PYTHON-API.markdown)としても公開されています。

### 使用例

以降では`Docker`、`Python`を使った簡単な`q`のサンプルを記載します。
データにはアヤメのデータを使用します。

カラムは左から`がく片の長さ`、`がく片の幅`、`花びらの長さ`、`花びらの幅`となリます。

```sh
$ docker run --rm -it -v `pwd`:/w -w /w jupyter/datascience-notebook python -c '
from sklearn.datasets import load_iris

iris = load_iris()
data = iris.data[:15]
text = "\n".join([",".join([str(scalar) for scalar in scalars]) for scalars in data])

columns = ["SepalLength", "SepalWidth", "PetalLength", "PetalWidth"]
columntext = ",".join(columns)

with open("data.csv", "w", encoding="utf-8") as f:
    f.write(columntext + "\n")
    f.write(text)
'
$ cat data.csv
SepalLength,SepalWidth,PetalLength,PetalWidth
5.1,3.5,1.4,0.2
4.9,3.0,1.4,0.2
4.7,3.2,1.3,0.2
4.6,3.1,1.5,0.2
5.0,3.6,1.4,0.2
5.4,3.9,1.7,0.4
4.6,3.4,1.4,0.3
5.0,3.4,1.5,0.2
4.4,2.9,1.4,0.2
4.9,3.1,1.5,0.1
5.4,3.7,1.5,0.2
4.8,3.4,1.6,0.2
4.8,3.0,1.4,0.1
4.3,3.0,1.1,0.1
5.8,4.0,1.2,0.2
```

以降では`がく片の長さ`が`5.0`以上かつ、`花びらの長さ`が`1.5`以上という条件でデータを取得します。

- CLI

```sh
$ docker run --rm -it -v `pwd`:/w -w /w eiryu/q-text-as-data -H -d ',' 'select * from data.csv where SepalLength >= 5.0 and PetalLength >= 1.5'
5.4,3.9,1.7,0.4
5.0,3.4,1.5,0.2
5.4,3.7,1.5,0.2
```

- Python

コンテナ化したいので、下記の`Dockerfile`をビルドします。

```Dockerfile
FROM python:latest

ENV PYTHONPATH /usr/local/src:$PYTHONPATH 
WORKDIR /tmp/q

RUN set -eux && \
    git init && \
    git config core.sparsecheckout true && \
    git remote add origin https://github.com/harelba/q.git && \
    echo bin > .git/info/sparse-checkout && \
    git pull origin master && \
    pip install six && \
    cp -p bin/q /usr/local/src/qtextasdata.py
```

イメージをビルドし、スクリプト実行します。

```sh
$ docker build -t qpy .
$ docker run --rm -it -v `pwd`:/w -w /w qpy python -c '
from qtextasdata import QTextAsData, QInputParams

q = QTextAsData()
stmt = "select * from data.csv where SepalLength >= 5.0 and PetalLength >= 1.5"
input_params = QInputParams(delimiter=",", skip_header=True)

r = q.execute(stmt, input_params)
if r.status != "ok":
    raise BaseException("status: " + r.status)

for data in r.data:
    print(*data, sep=",")
'
5.4,3.9,1.7,0.4
5.0,3.4,1.5,0.2
5.4,3.7,1.5,0.2
```

CLI、Pythonどちらとも同様に同じ結果が取得されていると思います。

### 最後に

上記ではqの簡単な紹介を行いました、後から考えてみるとSQLというインターフェースに拘らなければPandasでも同様のことが実現できそうです。。。

機械学習の予測結果のデバッグ用に使用できればと思います。
BEMについて

命名規則であるBEMについて書こうと思います。

# BEMとは

BEMは、厳格なクラスの命名規則が特徴です。
BEMはBlock、Element、Modifierの頭文字を取ったもので
ページを構成する要素をBlock、Element、Modifierのどれかに当てはめてクラスを命名します。

## BEMを使用するメリット
* クラスの命名が簡単になる
* 要素の再利用がしやすくなる

## Block、Element、Modifierの各要素について

### Block
Blockとは、ある要素の大元となるブロック要素です。
Blockを起点にElementやModifierは、この命名されます。

Blockの命名には名詞を使用します。

### Element
Elementとは、Blockに属する子要素です。
1つ以上のElementによって、Blockは構成されています。

Elementの命名には名詞を使用します。

### Modifier
Modifierとは、Blockまたは、Elementに特別な修飾をする要素です。

Modifierの命名には形容詞を使用します。