OmniAICreator/Qiita-1.07M huggingface dataset:
外付けSSDにUnity Hubのデータを保存したい(Mac) 【※未解決エラー有】

# Unity Hubでバージョン違いを複数インストールしてしまっているので、これをSSDに移動してPCのストレージ逼迫状態を改善したい！

![スクリーンショット 2019-08-17 17.36.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/22a6bf42-4ab2-9831-d06b-22ae656acbd0.png)

## 環境
PC: MacBook Air
購入したSSD: [My Passport Go 500GB](https://www.wd.com/ja-jp/products/portable-storage/my-passport-go-japan.html)

## 関連記事

[外付けSSDに圧迫データ(Unity Asset Storeフォルダ)をお引っ越し(Mac)](https://qiita.com/kana_omori/items/5f54f517a36dadf9fd64)

## 参照記事

[「attempt to write a readonly database」エラーの対処法](http://nakamura001.hatenablog.com/entry/20161127/1480246274)

[Fatal Error](https://forum.unity.com/threads/fatal-error.170787/)

[Fatal error during new project creation](https://forum.unity.com/threads/fatal-error-during-new-project-creation.674410/)

---

最初はSSDに今インストールしている各バージョンのデータを前回記事と同様にシンボリックリンクでどうにかSSDに置くことはできないかな、と思ったのですが、
調べて見たら、そもそものインストール先を外付けSSDにすれば良いだけでした..:older_man_tone1:

:baby_tone2:以下作業メモ:baby_tone2:

### その１
#### 外付けSSDにインストール先となるディレクトリを準備

まずはSSDにインストールデータを保存する領域を確保

- 外付けSSD(My Passport)をPCにつなぎ、Finderからその中に入って適当なディレクトリを作成する
（※今回は下記のように構成）

[My Passport]
　　L　[MacData]
　　　　L　[Unity]
　　　　　　L　[UnityInstall]


### その２
#### Unity Hubでインストール先をSSD配下に変更

次に、Unity Hubのインストール先の設定をSSDに作ったディレクトリに変更して保存します

- Unity Hubを起動し、右上の歯車マークから環境設定を開き、[一般]->[Unity エディターフォルダー]のインストール先を先ほど作成したSSD配下の[UnityInstall]にして保存


### その３
#### 新しいインストール先にインストール

今回は 2018.4.6f1 を一旦アンインストールして、インストールしなおしてみます

- インストール画面で インストール済みの2018.4.6f1 の右上メニューマークからアンインストールを実行

- アンインストールが完了したら、インストール画面で右上の[インストール]から、[2018.4.6f1]　を選択し、必要なモジュールを選択して、[実行]


### 確認作業
#### Unityで新しくインストールしなおしたバージョンを使って問題ないか確認

まずは新規プロジェクトの作成が問題ないことを確認

- Unity Hubのプロジェクト画面で[新規作成]から新しくインストールした[2018.4.6f1]を選択し、プロジェクト名を適当につけて[作成]

![スクリーンショット 2019-08-17 18.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/fea52d95-4f64-bb9e-0f1b-f827228f1ece.png)

... :scream_cat:エラー（チーン）

### Fatal error during new project creation

色々調べて見たのですが、どうやらまだ解決方法が見つかっていないエラーのようです、、
(cf [参照記事](https://qiita.com/kana_omori/items/8241ee236d097677e517#%E5%8F%82%E7%85%A7%E8%A8%98%E4%BA%8B))

`/Volumes/My Passport/UserName/Unity/UnityWorkspace/TEST_WD/Library/PackageCache/com.unity.textmeshpro@1.4.1/Editor Resources/Shaders`
の読み込みに場面でエラーが出てしまっているようなのですが、
パーミッションとかもディレクトリを遡って確認したのですが、特に他の読み込めている　SSD上のプロジェクトと変わりがなかったです。。

どうやら、外付けSSDで新規作成したプロジェクトを開こうとすると起こってしまうらしい。

試しに、一旦PC側に新規作成したプロジェクトを、SSDに移動してから開いたら問題なくプロジェクトをUnityで開けました！
（ちなみに、さっきエラーになってしまったプロジェクトを一旦PCにコピーして、再度SSDにコピーしなおしてから開いて見たけどやっぱりエラーでした。。そりゃそうか。。）

ちょっとめんどくさいけど、とりあえずのUnity運用は

```
PC側に新規プロジェクト作成
↓
Unity Hubプロジェクト画面のリストから一旦削除
↓
SSDにPC側で作ったプロジェクトを丸っとコピー、PC側のものはSSDにコピー後削除
↓
Unity Hubプロジェクト画面のリストにSSD側にコピーしてきたプロジェクトを指定して追加
```
とやるしかない。。。

---
##### :alien:振り返り:alien:
新しいインストール先へのインストールが結構時間かかって焦ったのですが、待っていたらインストールできました。（Wi-Fi環境のせいだったのかもです）

ちょっとめんどくさい手順にはなってしまいましたが、
今後PC容量をあまり気にせずにUnityプロジェクトを色々作れそうなのでとりあえずは良しとしますprz

以上！
nuxtのコードをGitHub Pagesにデプロイして上手くいかないときの対応

# 始めに
Nuxtは`nuxt generate`で静的ファイルを出力するためGitHub Pagesに配置できると思っていたのですが、意外とつまってしまったのでそれに関して記事にしました。

※バージョンによって挙動が違う気がするので注意してください。僕が試したときはNuxtのバージョンはv2.8.1でした。

# 結論
先に結論を言うと、gh-pagesモジュールでpushする場合は`gh-pages -d dist -t`にして、`-t`オプションをいれたら動きました。

# 背景と原因
基本的にGitHub Pagesのデプロイは以下のサイトを参考にしていました。

https://ja.nuxtjs.org/faq/github-pages/#リポジトリに-github-pages-をデプロイする

ビルドの設定は問題なかったのですが、デプロイの方でいつも使っている`gh-pages`にしたことで問題が起きました。具体的にはデプロイ先にアクセスすると生成された`_nuxt`ディレクトリ以下のファイルをみてくれませんでした。
どうやらGitHub Pagesは`_`が先頭についているものは無視されてしまうようで、`.nojekyll`を配置しないといけないようでした。

[NuxtプロジェクトをそのままGitHub Pagesに上げると_nuxt配下が404になる](https://ryonkmr.com/nuxt-project-needs-nojekyll-for-gh-pages)

ただ疑問なのは`nuxt generate`で生成されたファイルには`.nojekyll`がちゃんと入っており、これがpushされていれば何の問題もなかったのですが、なぜかpushされていませんでした。`gh-pages`側がドットファイルのpushをスキップしているようです。このドットファイルを含めてpushする方法がなかなか見つからず困っていましたが、どうやら`-t`オプションをつけるとやってくれるようです。（`yarn gh-pages -h`でコマンドを確認すると普通に載ってました）

[gh-pages with static html can't access file when it exists](https://stackoverflow.com/questions/39765059/gh-pages-with-static-html-cant-access-file-when-it-exists)

# 終わりに
`.nojekyll`がないから動かないという記事はよく見かけたのですが、`gh-pages`でpushする方法に関する記事は見つからなかったので記事にしました。誰かの役に立てれば幸いです。
WindowsのイベントログをKinesis Firehoseに送る

Windows ServerのイベントログをKinesis Firehoseに送りたかったので調べたら、 Amazon Kinesis Agent for Microsoft Windowsなるものがあった。[githubのリポジトリ](https://github.com/awslabs/kinesis-agent-windows)はスター数少ないし、[ダウンロードページ](https://s3-us-west-2.amazonaws.com/kinesis-agent-windows/downloads/index.html)は異様に淡白なUIだし不安になったが、ちゃんと動いたのでざっくりメモ。


# 公式ドキュメントなど
- https://docs.aws.amazon.com/ja_jp/kinesis-agent-windows/latest/userguide/getting-started.html
- https://github.com/awslabs/kinesis-agent-windows
- https://s3-us-west-2.amazonaws.com/kinesis-agent-windows/downloads/Kinesis-Agent-for-Windows-User-Guide.pdf
- https://s3-us-west-2.amazonaws.com/kinesis-agent-windows/downloads/index.html


# インストール
ダウンロードページではmsiでのインストールがrecommendedになってるけど、ドキュメントには別にそんなこと書いてないので、ワンライナーなPowershellで入れた。

```powershell
iex ((New-Object System.Net.WebClient).DownloadString('https://s3-us-west-2.amazonaws.com/kinesis-agent-windows/downloads/InstallKinesisAgent.ps1'))
```


# 設定ファイル
`%PROGRAMFILES%\Amazon\AWSKinesisTap`によしなに書いた`appsettings.json`を置けばいいらしい。

イベントログを投げ込む設定ファイルの例が転がってるのでそれを参考にjsonを用意する。
https://docs.aws.amazon.com/ja_jp/kinesis-agent-windows/latest/userguide/configuring-kaw-examples.html

```json
{
    "Sources": [
        {
            "Id": "SystemLogSource",
            "SourceType": "WindowsEventLogSource",
            "LogName": "Application",
            "Query": "*[System[(Level=1  or Level=2) and (EventID=260)]]" // 後述
        }
    ],
    "Sinks": [
        {
            "Id": "myKinesisFirehoseSink",
            "SinkType": "KinesisFirehose",
            "AccessKey": "", // FirehoseストリームがあるAWSアカウントのアクセスキー
            "SecretKey": "", // 同 シークレットキー
            "Region": "us-east-1", // Firehoseがあるリージョン
            "StreamName": "windows-event-log-stream-01" // 作ったFirehoseのストリーム名
        }
    ],
    "Pipes": [
        {
            "Id": "EventLogToFirehose",
            "SourceRef": "SystemLogSource", // SourceのIDに一致させる
            "SinkRef": "myKinesisFirehoseSink" // SinkのIDに一致させる
        }
    ],
    "SelfUpdate": 0
}
```

## イベントログのクエリ
イベントビューアーから、取りたいイベントログを取得するカスタムビューをポチポチ作ればクエリが表示される。
<img width="600px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130232/0beba966-6a88-cf96-f21e-552d59208c91.png">


## 複数ストリームを使う
`Souces`, `Sinks`, `Pipes`をそれぞれ増やせばいい。


# 起動
```powershell
Start-Service -Name AWSKinesisTap
Get-Service -Name AWSKinesisTap // 起動してるか確認
```


# トラブルシューティング
とにかく↓のログを見る。
`%PROGRAMDATA%\Amazon\AWSKinesisTap\logs`

送信に成功したときは特にログは出ないっぽいので、Kinesisのログなどで確認。
3つの数字を計算量O(N)でソートする

# 問題
(1, 2, 3)のユニークな数字だけのリストが与えられた時に、そのリストをO(N)でソートしなさい

Input: [3, 3, 2, 1, 3, 2, 1]
Output: [1, 1, 2, 2, 3, 3, 3]

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

# 回答

JavaScriptで回答する。
普通にソートすると。

```js
function sortNums(input){
    return array.sort()
}
```

とすれば良いように思えるがこれではO(NlogN)かかってしまう。このためsort関数は使えない。

何に着目すれば良いのかというとこの配列はユニークな３つの数字しか提供されないというところ。
1, 3は確実に配列の後ろ側に持っていけば良い。

配列の最初から数値を一つづつみていき、先頭からのポイントと末尾からのポイントと数値を交換すれば良い。

```js
function sortNums(input) {
    let left = 0
    let right = input.length - 1
    let i = 0
    while(i <= right) {
        if (input[i] === 1 && left < i) {
            const temp = input[i]
            input[i] = input[left]
            input[left] = temp
            left += 1
        } else if(input[i] === 3){
            const temp = input[i]
            input[i] = input[right]
            input[right] = temp
            right -= 1
        } else {
            i += 1
        }
    }
    return input
}
```

計算量: O(N)
メモリ: O(1)

# 補足

この問題はオランダ国旗問題とも言われ有名な問題である
http://parametron.blogspot.com/2010/05/blog-post.html
Bootstrap4+kaminariでページネーションの実装

#はじめに
Bootstrap4にページネーションの機能を実装する為のメモ。
ページネーションを実装しようと思い、kaminariを使ったが、bootstrapが上手く当たらなかったので、調べて実装しました。
備忘録として残しておきます
開発環境は、ポートフォリオ作成まとめの記事に記述してあるので、そちらを参照してください。

#gem'kaminari'の導入

```ruby:Gemfile
gem 'kaminari'
```
まずはkaminariを導入し、bundle installし、サーバーの再起動をします。

#controllerの修正
```ruby:items_controller.rb
def index
  @items = Item.page(params[:page]).per(5)
end
```
適宜コントローラーに上記の記述を追加。
今回は５個ずつ表示したいのでper(5)になっています。

#Viewの修正
こちらも適宜コンテンツの表示部分は書いてください。
肝心のページネーションの部分は

```ruby:index.rb
= paginate @items
```
で表示されると思います。
hamlを使っているのでerbを使っている場合は

```ruby:index.rb
<%= paginate @items %>
```
で行けると思います。

#bootstrapを適応させる
このままだと、素の状態でページネーション部分が表示されていると思うので、bootstrapを当てていきます。
公式に専用のものが用意されているので、今回はそちらを使っていきます。
以下のコマンドで出来ますが、hamlですので適宜変更してください。

```
$ kaminari:views bootstrap4 -e haml
```
これでviewファイルが作成され、表示が変化すると思います。
細かいこだわりがある方は、生成されたviewファイルを弄れば好きな様にできると思います。

#まとめ
一度しかkaminari使ったことが無かったですが、非常に簡単に実装する事が出来ました。
もし無かったらどうやって実装していくのか非常に気になるので余裕が出来たら勉強してみたいと思っています。
どなたかの参考になれば幸いです。

#参考サイト
https://www.d-wood.com/blog/2018/01/31_9456.html
[Laravel]ページへの初回遷移(ひとつ前のページとは違うページ)を判定する


```
public function sample(Request $request)
{
    if (Str::contains(url()->previous(), url()->current())){
        //ここに初回遷移時の処理
    }

    if (Str::before(url()->previous(), '?') === url()->current()){
        //ここに初回遷移時の処理
    }

    if (Str::contains(url()->previous(), $request->path())){
        //ここに初回遷移時の処理
    }
}
```

・Str::Contains(文字列, 検索文字列)
文字列の中に検索文字列が含まれているか判定する

・url()->previous()
ひとつ前の完全なURL

・url()->current()
クエリ文字列を除いた(?以降)現在のURL

・Str::before(文字列, 検索文字列)
文字列の中の検索文字列が現れる前までの文字列を抜き出す

・$request->path()
現在のpath
PythonとSeleniumでスクレイピングのようなこと

知り合いに、

「サブスク系のサービスの領収書を自動でダウンロードできないか？」

と言われて、なんかいけそうな気がしたのでPython入門がてらスクレイピングをしてみて、ダウンロードはできなかった話です

# 今回のお題

fre○eで毎月発行されている利用料の領収書を、自動でダウンロードする


# やったこと

**BeautifulSoupを利用してhtmlを解析して領収書のダウンロードリンクを収集してみる**
https://qiita.com/Azunyan1111/items/9b3d16428d2bcc7c9406

結果
fr○eeの認証越えられなかった。終了
でもPythonに入門できたからよかったよね


**Seleniumでブラウザを操作して物理で領収書のリンク収集してダウンロード**
https://qiita.com/edo_m18/items/ba7d8a95818e9c0552d9

結果
収集はできたがダウンロードができなかった、、。

#### 以下、収集するまでの方法

前提
mac(Pythonは入ってる)

準備

* Pythonのライブラリの管理モジュールっぽいpipをインストール
https://pip.pypa.io/en/stable/installing/

* ブラウザを操作するためにChromedriverをインストール
https://sites.google.com/a/chromium.org/chromedriver/downloads

`pip install selenium`

```py:getFromFre.py

# coding: UTF-8
from selenium import webdriver

# 設定
LoginURL = "https://accounts.secure.freee.co.jp/login"
URL = "https://secure.freee.co.jp/billing"

EMAIL = "ログインメールアドレス"
PASS = "パスワード"

# freeeから取得する処理
driver = webdriver.Chrome("./chromedriver") #ドライバーへのパスを記述

driver.get(LoginURL)

email = driver.find_element_by_name('email')
email.send_keys(EMAIL)

password = driver.find_element_by_name('password')
password.send_keys(PASS)

password.submit()

driver.get(URL)

aList = driver.find_elements_by_css_selector("a[href^='/billing/receipts']")

for a in aList:
    src = a.get_attribute("href")
    print(src)

driver.close()
driver.quit()
```

これ実行すれば領収書のURLは収集できた、、


### 参考

https://kurozumi.github.io/selenium-python/
https://qiita.com/kinpira/items/383b0fbee6bf229ea03d
zshで no match found のときの解決策

#### 問題
* zshでglob表現を含むコマンドをrunするときに以下のエラー

```
zsh: no matches found: 
```
#### 原因
* zshではマッチしないglob表現を含む場合no match error をprintしてコマンドをrunしなくなる。

####解決策
* ~/.zshrcに以下を記述して、source ~/.zshrc

```
setopt +o nomatch 
```

####参考
* [【shell】zshでno matches found。](https://shirusu-ni-tarazu.hatenablog.jp/entry/2013/01/18/034233)
* [How to get rid of “No match found” when running “rm *”
](https://unix.stackexchange.com/questions/310540/how-to-get-rid-of-no-match-found-when-running-rm)
plunkerで今日は

#概要

plunkerで今日は何日、やってみた。

#写真

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/07684937-ba83-f7ed-9125-b06dff6d09b7.png)


#成果物

https://embed.plnkr.co/pImiAfAKgELNXYTPXrvO/

以上。
～selfの扱い～　親クラス子クラスデコレータ

はちゃめちゃなプログラムだけどとりあえず動いたのでメモ

```python:test.py
class Parent(object):

    def start(self, one_string):
        self.a(one_string)
        self.b()

    def a(self, one_string):
        self.aa = one_string
        print('aa dec')

    def c(func):
        def c_wrapper(self):
            func(self)
            self.cc = 'ccc'
            print('cc dec')
        return c_wrapper

    def printing_in_parent(self):
        print(self.aa, self.bb, self.cc)
        self.printing_in_child_one_more()

class Child(Parent):

    @Parent.c
    def b(self):
        self.bb = 'bbb'
        print('bb dec')

    def printing_in_child(self):
        print(self.aa, self.bb, self.cc)
        self.printing_in_parent()

    def printing_in_child_one_more(self):
        print(self.aa, self.bb, self.cc)

c = Child()
c.start('aaa')
c.printing_in_child()
```

実行結果

```
aa dec
bb dec
cc dec
aaa bbb ccc
aaa bbb ccc
aaa bbb ccc

```
Material UIのrippleアニメーションを模倣してみた

# 

React用の[Material UI](https://material-ui.com/getting-started/usage/#quick-start)で実装できるボタン押下時のエフェクト。

[![Image from Gyazo](https://i.gyazo.com/d6379ac283bddd57a9ca4d1d7bd1abb0.gif)](https://gyazo.com/d6379ac283bddd57a9ca4d1d7bd1abb0)

クリックした地点から波紋が広がるようなアニメーションを見て

これはぜひ実装したい！

と思ったのでやってみた

# 作ったもの
[![Image from Gyazo](https://i.gyazo.com/2c3b66713db083ed25ef8bae85743f07.gif)](https://gyazo.com/2c3b66713db083ed25ef8bae85743f07)

コードはこちら
[CodeSandBox](https://codesandbox.io/s/mimic-material-ui-button-ripple-pzix1)

# buttonの構造
はこちら

``` html
<button class="base-root">
  <span class="label">button</span>
  <span class="ripple-root">
    // ↓buttonのmousedownで生成↓
    <span class="ripple-ripple ripple-rippleVisible">
      <span class="ripple-child ripple-childLeaving"></span>
    </span>
  </span>
</button>
```

class名は本家とちょっと変えたけど概ねこんな感じ

`ripple-childLeaving`はmouseup時に付くっぽい



# ripple-rippleの大きさ

rippleの大きさを見てみると
本家は三平方の定理的なさむしんぐを使っておっきな正方形を作ってるっぽいけど
~~めんどくさいので、適当に`base-root`の２倍でやってみる~~


と思ったけど普通に半径求めた

```js
// calculation
const rootWidth = rippleRoot.clientWidth;// buttonの幅
const rootHeight = rippleRoot.clientHeight;// buttonの高さ
const radius = Math.sqrt(Math.pow(rootWidth, 2) + Math.pow(rootHeight, 2));// 円の半径
const top = e.layerY - radius;
const left = e.layerX - radius;
rippleRipple.style.width = `${radius * 2}px`;
rippleRipple.style.height = `${radius * 2}px`;
rippleRipple.style.top = `${top}px`;
rippleRipple.style.left = `${left}px`;
```

これでクリックした地点を中心とした要素が作れた

# DOM操作
については何か言うことはない。

[コード見てくれ](https://codesandbox.io/s/mimic-material-ui-button-ripple-pzix1)

# 問題点

## 連続でクリックするとボタンが白くなっちゃう

### 本家
[![Image from Gyazo](https://i.gyazo.com/4339330eddad5ad2ccf6ac95b73daad0.gif)](https://gyazo.com/4339330eddad5ad2ccf6ac95b73daad0)

### 模倣
[![Image from Gyazo](https://i.gyazo.com/f58e809d1ab0fbf8c0bcc70b97398a84.gif)](https://gyazo.com/f58e809d1ab0fbf8c0bcc70b97398a84)

ので解決策知ってる人教えろくださいm(__)m

## `pulsate`を結局使わなかった

本家のコードやcssに時折`**-pulsate`という文字列があって、
keyframeも設定されてたからどこかで使うんじゃないかと思ってたんだけど
結局使わんかった
こちらもどこで使うのか知ってる人いたら教え(ry

ちなみにpulsateとは**どっくんどっくんする**的な意味っぽい
【Rubyメモ】ローカル変数と、グローバル変数の違い。そしてグローバル変数を避けるべき理由

#ローカル変数
ローカル変数には有効範囲があり、関数を飛び越えて使う事等は出来ません。 
変数にはローカルとグローバルが存在しますが、一般的にただ"変数"として呼ばれるもののは多くはローカル変数みたいです。 


例えば以下のプログラムでは一見すんなりと**「3」**が出力されそうなものですが、1を代入された**a**はメソッド外で作られたローカル変数の為、外部のメソッドや関数では使う事が出来ないのです。 
この場合 ```undefined local variable or method `a' for main:Object (NameError)``` というエラーが出ます。 

```
a = 1

def test 
    b = 2
    puts a + b
end

test()
```

#グローバル変数
ローカル変数は関数を飛び越えて使う事は出来ないのに対して、グローバル変数は自由にどこからでも使えます。 
Rubyの場合関数名の前に***$***をつける事で、グローバル変数として扱う事が可能です。 この場合エラーも出ず正常に ```3```が出力されます。 しかし、グローバル変数は一般的に避けるべきだと言われています。  

```
$a = 1

def test2
    b = 2
    puts $a + b
end

test2()
```

#グローバル変数を避けるべき理由
まだ自分も理解を深められていませんが、多くは***バグの温床になりやすい事***にあるようです。 小規模なプログラミングを一人で行っている立場では、たかが変数と思い無駄にグローバル変数を増やしたところで、動作や実装にはそこまで問題ないと思います。 しかしこれがよりスペックの劣るサーバーかつ、複数人によって操作を行われる環境に置かれると、グローバル変数はどこからでも操作することが出来てしまいます。 これによって誤って他の関数から書き換えられてしまったり、変数名が被ってしまい正常な動作を行わなくなってしまう場合があるようなのです。 

また厄介なのは、単なる構文の誤りとは別であるため、エラーメッセージが出ない場合があり、そうなると無数の変数からバグの原因を見つけなければなりません。 

プログラムが、グローバル変数を使わなければ正常に動作しないような設計である場合は、そのプログラムを改めて見つめ直すべきだと感じます。 といってもついつい使ってしまうのですが・・・（反省）
Python仮想環境の使い方

# はじめに

Pythonの仮想環境を整理した。

# 種類

Pythonのバージョン毎に仮想環境が二転三転・・・。

ざっくり分けると4系統にわかれるらしい。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Python仮想環境 <a href="https://t.co/T3vJ5VZcw0">https://t.co/T3vJ5VZcw0</a> <a href="https://twitter.com/mindmeister?ref_src=twsrc%5Etfw">@mindmeister</a>さんから</p>&mdash; kannkyo (@kannkyoshi) <a href="https://twitter.com/kannkyoshi/status/1162656285050884096?ref_src=twsrc%5Etfw">August 17, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

参考) 
https://qiita.com/ysdyt/items/5008e607343b940b3480
https://qiita.com/KRiver1/items/c1788e616b77a9bad4dd

めんどくせー。
なんだかなぁ。JavaScriptは `npm` で一発なんだが・・・。

とりあえず、それぞれのツールのシェアを調べてみよう。

pipでダウンロードできるパッケージについて過去1ヶ月のダウンロード数を調査した。

|Package Name| Downloads last month |
|:---|---:|
|virtualenv|9,719,732|
|pipenv|1,357,806|
|virtualenvwrapper|216,740|
|anaconda|7,642|
|pyenv|4,056|

参照元）https://pypistats.org/

これによるとまだまだ `virtualenv` が強いものの、新興勢力の`pipenv`がジワジワ伸びている感じ。

これは`pipenv`を使うべきかな。

# 使い方

公式ツールの `venv` と `virtualenv` 、それと新興勢力の`pipenv`をまとめる。

## venv 

[公式サイトの仮想環境の解説](https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments) によれば、こんな感じで実行する。

```shell
python3 -m venv <DIR>
source <DIR>/bin/activate
```

ただし、Windowsユーザの場合はsourceコマンドがないのでactivateスクリプトを実行すること。
batファイルなら、こう。

```text
<venv>\Scripts\activate.bat
```

Powershellならこう。

```text
<venv>\Scripts\Activate.ps1
```

## virtualenv

[公式サイトの仮想環境の解説](https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments) によれば、こんな感じで実行する。

```shell
virtualenv <DIR>
source <DIR>/bin/activate
```

ただし、Windowsユーザの場合はsourceコマンドがないのでactivateスクリプトを実行すること。

## pipenv 

[参考サイト](http://pynote.hatenablog.com/entry/pipenv-usage)によると、以下のコマンド2つでインタプリタのバージョンとパッケージのインストールをする。

```shell
pipenv --python <VERSION>
pipenv install <PACKAGE>
```

`npm`に似ているような似ていないようなインターフェース。
Active Storage　validation設定方法

ユーザー登録の際に、アバター画像添付を必須としたい場合のvalidationを学んだ備忘録

```user.rb
  has_one_attached :image
  validate :image_presence

  def image_presence
    if image.attached?
      if !image.content_type.in?(%('image/jpeg image/png'))
        errors.add(:image, 'にはjpegまたはpngファイルを添付してください')
      end
    else
      errors.add(:image, 'ファイルを添付してください')
    end
  end
```

画像が添付されていたら、それがjpegまたはpngファイルであるか確認、
画像が添付されていなかったらファイル添付を促すように実装しています。

# 参考
[ActiveStorageとバリデーションエラーの挙動](https://qiita.com/troter/items/da594391e9c4370eb65f)
carrierwave+S3のシークレットキー管理をcredentials.yml.encでやる一連の流れ

#はじめに
S3の導入でシークレットキーをcredentials.yml.enc（以下、credentials）で管理する手順の備忘録。
主にはcredentialsとmaster.keyを本番環境で使う為のまとめになると思います。
APIkeyも一度設定してしまえば、credentialsに書き込むだけで、出来るので参考になればと思います。


####開発環境
ポートフォリオサイトにて作業しています。
開発環境はそちらに書いてあるので、参照してください。

#現状
carrierwaveの設定から画像のアップロードを出来るところまでやっていきます。
S3のバケットは作成済みです。他の記事を参考にしてください。

##cledentialsへキーを書き込む
```
$ EDITOR=vim bin/rails credentials:edit
```
を打つとvimでの編集が可能です。

```
# aws:
#   access_key_id: 123
#   secret_access_key: 345
```
最初開くとこのように表示がされていると思います。
secrets.yml+bash_profileでの管理の時はaccess_key_idとsecret_access_keyは別々に記入していましたが、上記のような書き方をすることでまとめて書くことが出来るようになっています。
＃が付いているのはコメントアウトされているので、書き直すかコメントアウトを消して、任意の値を記入します。

記述が終了したら、コンソールで確認してみます。

```
$ rails c
Running via Spring preloader in process 67060
Loading development environment (Rails 5.2.3)
[1] pry(main)> Rails.application.credentials.aws[:access_key_id]
=> "先程入力した値"
```
これで表示されていればひとまず成功です。

##carrierwaveでの設定
```
Rails.application.secrets.aws_access_key_id
↓
Rails.application.credentials.aws[:access_key_id]
```
secrets.ymlでは上の表記になっていると思いますが、credentialsでは下のような記述にします。

##master.keyを本番環境で使える様にする
master.keyはデフォルトで.gitignoreに登録されている為、本番環境に存在しないので持っていく必要があります。

```
$ scp -i .ssh/example.pem AppName/config/master.yml ec2-user@xx.xxx.xxx.xx:/var/www/AppName/shared/config/
```
別の記事を参考にやりましたが、うまくいきません。/shared/config/のディレクトリーがないと言われたので、mkdirで作り、touchでmaster.keyを作り行けました。
:linked_filesにmaster.keyも入れておきます。私はこれの記述を忘れて、エラーが出て時間を食いました。
これについて調べましたが、いまいち理解が深くないので、ここでは割愛します。わかる方がいましたら教えて頂けると助かります、、、。

```ruby:deploy.rb
set :linked_files, fetch(:linked_files, []).push("config/master.key")
```
以上で、デプロイが完了したら投稿してみてください。私は以上の手順でうまくアップロード出来ました。

#まとめ
備忘録なので細かい設定の部分は省略しました。
このあたりのデプロイ関係は私が他記事にてまとめているので、見てみてください。
どなたかの参考になれば幸いです。
#参考サイト
https://qiita.com/yuuuking/items/53a37a2e998972be32b8
[GAS] GogleAppsScriptでClassもどき!

## Classとは
みたいな本格的なことは、誰かに任せるとして。

GASは、JSのバージョンが古いらしく

> prototypeに入れてくのが旧JSのclass実装

する必要がある。
(Pythonとかめっちゃ楽なのに・・・。ま、JSのせいではないか。)

## やってみた

```.js
var Human = function(name, height, weight) {
  this.name = name;
  this.height = height;
  this.weight = weight;

};

Human.prototype.sayHello = function() {
  Logger.log("Hello I'm " + this.name);
};

// BMIをセット
Human.prototype.setBMI = function() {
  Logger.log('setBMI')
  m_height = this.height/100;
  bmi = this.weight / (m_height * m_height)
  this.bmi = bmi;
};

// BMIを叫ぶ
Human.prototype.sayBMI = function() {
  Logger.log('sayBMI')
  if (this.bmi) {
    Logger.log('My BMI score is ' + this.bmi);
  } else {
    this.setBMI();
    Logger.log('My BMI score is ' + this.bmi);
  }
};

// 体重を変える
Human.prototype.changeWeight = function(diff) {
  this.weight = this.weight + diff;
}
```

```main.js
function main() {
  var
    satoshi = new Human('satoshi', 160, 75),
    masami = new Human('masami', 152, 54)
  ;

  satoshi.sayHello()
  masami.sayHello()
  
  Logger.log('---')

  masami.sayBMI()
  masami.changeWeight(-3)
  masami.setBMI()
  masami.sayBMI()
  
  Logger.log('---')
  
  satoshi.sayBMI()
}

```

結果は、こう!

```
> Hello I'm satoshi
> Hello I'm masami
> ---
> sayBMI
> setBMI
> My BMI score is 23.372576177285318
> setBMI
> sayBMI
> My BMI score is 22.07409972299169
> ---
> sayBMI
> setBMI
> My BMI score is 29.296874999999993
```

## 嬉しいこと
使いまわしが楽になる。
オブジェクトに対して、プロパティとメソッド持たせられるのは便利。

## 補足
完全初心者が、使えればOKだろ、レベルでやってみたやつです。
マサカリ飛ばしてもらってもOKです。
(が、大してまともなことも返せない可能性大です。すいません。)
本番環境でapp/assets/images以下の画像が表示されなかった時の対処法

ユーザー登録の際、アバターを設定しなかったユーザーのデフォルトアバター画像を
image_tag 'hoge.png'
で設定していたのですが、開発環境では画像表示されるのに本番環境では表示されなかった・・・泣

# 結論
```production.rb
config.assets.compile = true
```
config/environments/pruduction.rb内の
config.assets.compile = false  ⇨  trueへ変更したら表示されました！

# 背景
本番環境と開発環境では、プリコンパイルの手順が異なる。
通常本番環境ではアセットパイプラインを通る処理が自動実行されないので、
上記のように本番環境上でアセットパイプラインを自動で通るように設定を変更することで解決できる。

# 参考
[RAILS GUIDE アセットパイプライン](https://railsguides.jp/asset_pipeline.html)
[Rails初学者がつまずきやすい「アセットパイプライン」](https://www.transnet.ne.jp/2016/02/28/rails%E5%88%9D%E5%AD%A6%E8%80%85%E3%81%8C%E3%81%A4%E3%81%BE%E3%81%9A%E3%81%8Dcolnr%E3%80%8C%E3%82%A2%E3%82%BB%E3%83%83%E3%83%88%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3/)
Android端末の不要アプリをWindows Powershellから削除するメモ

powershell + adbコマンドでやってみます。
adbコマンド実行するには
[SDK PlatForm-tools](https://developer.android.com/studio/releases/platform-tools)ダウンロードして適当なところに置けばいいだけでした。

adb.exeのパスを通せばコマンドとして普通に使えますが、多分今日しか使わないのでパス通さずadb.exeのあるところで作業してます。
コマンド頭に```.\```ついてますがお気になさらず

発端は内臓ストレージの逼迫だったわけですが、
内臓ストレージの開放には余り効果がありませんでした。
むかつくアプリの削除はできますが、使ってないのでデータ量少なくて削除してもあんまり効果がありません。

#アプリのapkファイルバックアップ
めんどくさいので全部apkバックアップ
##apkファイルのパス一覧取得

```console
.\adb shell pm list packages -f | Select-string "package:.+\.apk" | % { $_.matches.Value -replace "^package:", ""  }
```
テキストファイルに保存

```console
.\adb shell pm list packages -f | Select-string "package:.+\.apk" | % { $_.matches.Value -replace "^package:", ""  } > packagepathlists.txt
```

##apkをまとめてpull

先ほどのテキストファイル使って「カレントディレクトリ\apklists」ディレクトリに保存します。

```console
>$packagelists = Get-Content ".\packagepathlists.txt"
>$packagelists | ForEach{ .\adb pull $_  .\apklists\ }
```

#無効化したアプリをまとめて削除

##無効化アプリのリスト

-dオプションで無効化したアプリだけリスティングできます。
'''package:(package name)'''な書式なので頭の'''package:```を削除します 
なんか空白行が出てきたので削除・・・。

```console
.\adb shell pm list packages -d | % { $_ -replace "^package:", ""  } | where-object { $_.trim() -ne "" }
```

##無効化アプリのリストを変数につっこんでまとめてuninstall
-kオプションをなくせばファイルごと消せるらしい(復帰不可能)
またはclear でファイルも消せるらしい

```cnosole
>$disableAppLists = .\adb shell pm list packages -d | % { $_ -replace "^package:", ""  } | where-object { $_.trim() -ne "" }
>$disableAppLists | ForEach { .\adb shell pm uninstall -k --user 0 $_ }
>$disableAppLists | ForEach { .\adb shell pm clear $_ }

```
Haskellのヒアドキュメントもどき

```haskell
someFunc :: IO ()
someFunc = putStrLn
  "\
   \Hello        Hello\n\
   \Hello        Hello\n\
   \  Hello\n\
   \    Hello    Hello\n\
   \Bye\
   \"
```

```:Output
↪ stack run
Hello        Hello
Hello        Hello
  Hello
    Hello    Hello
Bye
```
スマホの位置情報から到着15分前をBOTでLINEグループに送信させてみた

#作ったもの
　　友人との待ち合わせなどの際、車での移動を前提として「○○分に着くよ」というLINE送るのを
スマホの位置情報とGoogle Maps APIで計算して、LINEmessagingAPIで自動送信させるBOT

※自分の場合は毎日、職場の先輩を迎えに行って出勤しているのでその際、活用しています。

#動作環境
スマホ：Docomo P20pro【HW-01K】
サーバ：　Conoha VPS [1GB] 
webサーバ：nginx
開発言語：Python3
フレームワーク：Flask
DB：SQLite3
SSL証明書：Let's encrypt

スマホ使用アプリ：Tasker
使用API：Google Maps API、LINEmessagingAPI

#イメージ

![動作イメージ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/431024/1f13f324-d937-f593-c11f-f91e8893050b.png)



#動作手順
###　　スマホ動作

　　　　まずtaskerというタスクアプリをインストール
　　　　taskerの設定や使い方などは他サイトにたくさんの情報があるので省略。


　　　　まず良くある設定としてwi-fiの接続先を監視させています。
　　　　自宅のwi-fiに接続された時に、居場所として「自宅」をサーバに送信する。
　　　　そしてwi-fiから切断されたら、居場所として「外出」をサーバに送信しています。
　　　　それからBluetoothの監視をして車のカーナビとの接続で、居場所として「車」をサーバに送信。
　　　　
　　　　さらにここから、自分の場合は自分の勤務パターンをTasker側でも計算させて
　　　　仕事に行く時間なのか判定条件を第一条件にしています。
　　　　そして車のカーナビに接続されると車に乗った、という判定を第二条件に追加。
　　　　この勤務前、車に乗るという2つの条件をトリガーにしています。

　　　　この条件を満たした時に着火剤（トリガー）として一定の動作を繰り返します。

　　　　この後、taskerの動作は上記条件を満たす間は1分ごとに位置情報を取得して
　　　　サーバに取得した位置情報を送り続けるという動作をさせています。


###　　サーバ動作

　　　　サーバ側ではスマホからの受信とLineなどへの送信で主に2つのプログラムを動作させています。
　　　
　　　　【受信側】
　　　　スマホからの受信ではnginxとpythonをuwsgiをscketに接続しています。
　　　pythonでスマホから受け取った居場所や位置情報などの値をSQLiteに格納。
　　　
　　　また位置情報から指定された場所までの所要時間をGoogleMAPsAPIに投げて取得し、
　　　おおよその到着時間を計算してSQLiteに格納するところまでさせています。


　　　　【送信側】
　　　　送信側はデーモン化してサーバ起動時は常時起動となるように設定しています。
　　　　
　　　　まず、ここでも勤務パータンの計算。
　　　　勤務前の少し前の時間に位置情報や到着時刻などの値を初期化するようにしています。
　　　　その後、SQLiteの居場所が「車」に変わるまでwait。
　　　　居場所が「車」に変わるとLINEmessagingAPIで「家出た」を送信します。
　　　　そしてSQLiteの到着予定時間を取得して、１５分前になると再度LINEmessagingAPIで
　　　　その時の現在地と「到着予定時間〇:〇〇頃」を送信します。
LINE WORKSでメンバーからBotへのメッセージを受信し、Botに返信させるまで

こんにちは、@0yanです。今日もLINE WORKS APIを勉強しました。
今日は「メンバーからBotへのメッセージを受信し、Botに返信させるまで」です。



# 環境
Windows 10
Python 3.6.8
ngrok
Flask　0.12.2
lineworks 0.0.2



# やったこと
メンバーからのメッセージをBotで受け取り、ローカルサーバーに転送（=受信）。
受信したメッセージ（JSONデータ）のヘッダーからBot Noを取り出し、それをメンバーに送信（=返信）しました。
これ（↓）がイメージです。


##### イメージ図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373977/0f7ab968-2503-af6c-5036-dfe56816fc21.png)

メッセージの転送自体は、BotにCallback URL（今回はローカルサーバーを外部公開するためにngrokで生成したURL）を指定するだけなのでとても楽でした。



# 手順
1. Flaskでローカルサーバーを構築後、ngrokで外部公開（参考：[【備忘録】ngrokの使い方](https://qiita.com/0yan/items/0b84043f76102decda0a)）
2. [LINE WORKS Developer Console](https://developers.worksmobile.com/jp/console/)で、BotのCallback URLに1で得たURL/callbackを指定※httpsを使用
3. テスト（メンバーからBotにテキストメッセージを送信）


##### ローカルサーバーのコード
```python:app.py
# coding: utf-8

from flask import Flask
from flask import request
from lineworks import *


# LINE WORKS AIP情報
API_ID = ""
PRIVATE_KEY = ""
SERVER_API_CONSUMER_KEY = ""
SERVER_ID = ""
BOT_NO = ""
ACCOUNT_ID = ""
ROOM_ID = ""
DOMAIN_ID = ""


app = Flask(__name__)


talkbot = TalkBotApi(
    api_id=API_ID,
    private_key=PRIVATE_KEY,
    server_api_consumer_key=SERVER_API_CONSUMER_KEY,
    server_id=SERVER_ID,
    bot_no=BOT_NO,
    account_id=ACCOUNT_ID,
    room_id=ROOM_ID,
    domain_id=DOMAIN_ID
)


@app.route('/')
def index():
    return "Start.", 200


# POSTを正常に受け取れているかどうかの確認用
@app.route('/callback', methods=['POST'])
def callback():
    header = request.headers
    body = request.json
    if body["type"] == "message":
        talkbot.send_text_message(send_text=header["X-WORKS-BotNo"])
        return "", 200
    else:
        return "Error."


if __name__ == '__main__':
    app.run(host="127.0.0.1", port=5000)
```


##### Callback URLの指定場所
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373977/be29eb23-a46a-5a00-d548-d369bc1f22c8.png)


ローカルサーバーの外部公開が終わった後、Botに適当なテキストメッセージを送信し、返信メッセージ（BOT_NO）が来たら、Callback URLに指定したサーバーへのメッセージ転送（=受信）とBotからのメッセージ送信（=返信）は成功です。



# 参考
>[LINE WORKS 公式ドキュメント　メッセージ受信 -Callback形式](https://developers.worksmobile.com/jp/document/1005009?lang=ja)
配列の扱い方　(AIZU 6.7)　

#数列の反転

###vectorを使うメリットと使わないデメリットを知る

```c
#include<bits/stdc++.h>
using namespace std;

int main(){
    int n;
    vector <int> A(n);
    //vectorを使えば、要素数を定数ではなく変数nと置ける！
    
    cin >> n;
    for (int i=0; i<n; i++) cin >> A[i];
    
    for (int i=n-1; 0<i; i--) cout << A[i] << " ";
    cout << A[0] << endl;
    
    return 0;
}
```
#不足しているカードの発見

###bool型の使い道を知る
```c
#include<bits/stdc++.h>
using namespace std;

int main(){
    int n,num;
    char mark;
    bool cards[4][14];
    //カードの有無を調べるのにbool型は役に立つ！
    for (int i=0; i<4; i++)
        for (int j=1; j<14; j++)
            cards[i][j]=0;
    cin >> n;        
    for (int i=0; i<n; i++){
        cin >> mark >> num;
        if (mark=='S') cards[0][num]=1;
        if (mark=='H') cards[1][num]=1;
        if (mark=='C') cards[2][num]=1;
        if (mark=='D') cards[3][num]=1;
    }
    
    for (int i=0; i<4; i++){
        for (int j=1; j<14; j++){
            if (cards[i][j]==0) {
            //bool型の威力をここで発揮！
                if (i==0) cout << "S" << " " << j << endl;
                else if (i==1) cout << "H" << " " << j << endl;
                else if (i==2) cout << "C" << " " << j << endl;
                else cout << "D" << " " << j << endl;
            }
        }
    }
    return 0;
}
```
#公舎の入居者数

###多次元配列の扱い方を知る
```c
#include<bits/stdc++.h>
using namespace std;

int main(){
    int n,b,f,r,v;
    cin >> n;
    
    int A[5][4][11];
    for (int i=1; i<=4; i++)
        for (int j=1; j<=3; j++)
            for (int k=1; k<=10; k++)
                A[i][j][k]=0;
                
    for (int i=0; i<n; i++){
        cin >> b >> f >> r >> v;
        A[b][f][r]+=v;
    }
    
    for (int i=1; i<=4; i++){
        for (int j=1; j<=3; j++){
            for (int k=1; k<=10; k++){
                cout << " " << A[i][j][k];
            }cout << endl;
        }
    if (i!=4) cout << "####################" << endl;
    }
    
    return 0;
}
```
rspecで「あるメソッドが呼ばれたこと/呼ばれていないこと」をテストするやり方

# 環境

- Rails 5.2.3
- rspec 3.8.2

# やり方 その一

`before`で`allow(...).to receive(...)`して、
`it`で`expect(...).to have_received(...)`する。

```ruby
context 'when ...' do
  before do
    allow(Rails.logger).to receive(:error).with('error occurred')
  end

  it '...' do
    do_something
    expect(Rails.logger).to have_received(:error).with('error occurred').once
  end

  # 「呼ばれていないこと」を確認するためには、.to have_received を .not_to have_received にします。
  it '...' do
    do_something
    expect(Rails.logger).not_to have_received(:error).with('error occurred')
  end

end
```

controllerのmethodをmockする場合は、`allow(controller).to receive(:some_method).and_return(true)`でOK。

# やり方 その二

`before`で`expect(...).to receive(...)`するだけでも動きます（期待動作します）。
しかし、`rubocop-rspec`に`RSpec/ExpectInHook: Do not use expect in before hook`（「`before`ブロックで`expect`を使用するな」）
と怒られます。

```ruby
context 'when ...' do
  before do
    expect(Rails.logger).to receive(:error).with('some message').once
  end
end
```

なので `it` の中で定義したほうが良さそうです。

```ruby
context 'when ...' do
  it do
    expect(Rails.logger).to receive(:error).with('some message').once
    do_something
  end
end
```

しかし、↓のような感じで戻り値がある場合は、`have_received`が使えないので、このやり方（`before`に書くやり方）しかないように思うけど、何かいいやり方あるのかな？

```ruby
  before do
    result = AuthenticateUser.call(token)
    expect(AuthenticateUser).to receive(:call).with(token).and_return(result)
  end
```

# その他

以下のコードをモックする。

```ruby
order = Order.by(customer).ordered_today.not_paid.order(created_at: :desc).first
if order&.purchased_but_not_paid?
  @order = order
end
```

```ruby
before do
  order_class_double = class_double(Order)
  order_instance_double = instance_double(Order, id: 1)

  allow(Order).to receive(:by).and_return(order_class_double)
  allow(order_class_double).to receive(:ordered_today).and_return(order_class_double)
  allow(order_class_double).to receive(:not_paid).and_return(order_class_double)
  allow(order_class_double).to receive(:order).and_return(order_class_double)
  allow(order_class_double).to receive(:first).and_return(order_instance_double)
  allow(order_instance_double).to receive(:purchased_but_not_paid?).and_return(true)
end
```
メトリクスについての学習

# メトリクスについて
自分たちのテストや品質に対してどのような立ち位置なのかを判断するにあたって何かいい指標はないものかを思ったのが吉日で、品質メトリクスというものを学ぶことにした

# メトリクスとは
メトリクスとは、様々な活動を定量化し、その定量化したデータを管理に使えるように加工した指標のこと。
データを収集し、分析しやすいように計算した値のこと。

その中でも、品質やテストにかかわる品質メトリクスというものがある。

#品質メトリクス
レビューやテストを行うときに、どれぐらい実施すればいいのかいいのか判定するモノサシで、以下のものがある。

- レビュー品質メトリクス
- テスト品質メトリクス

##レビュー品質メトリクス

設計段階での作成する仕様書などをレビューしたときの、設計書やレビューの精度を評価する数値。

|メトリクス|計算式|
|---|---|
|レビュー工数密度|レビュー工数 / レビュー対象規模|
|レビュー指摘効率|レビュー指摘件数 / レビュー工数|
|ビュー指摘密度|レビュー指摘数 / レビュー対象規模|


###レビュー工数密度
システム規模に対しての文書をチェックするために費やした時間の割合。
システム規模に対してレビュー時間判断をするための数値。

短すぎると見落としが発生する可能性がある、多すぎるとプロセスが回っていないなどの問題がある可能性があるなどの指標となる。

###レビュー指摘密度（検出率）
システム規模に対してのレビューで指摘された数の割合。

仕様書やレビュープロセスの精度などを判断する。
システム規模が大きいのに指摘数が少ないと仕様書が完璧なのか見落としが多いのかなど。

###レビュー指摘効率
レビュー工数に対してどれだけの指摘数の割合。

仕様書やレビュープロセスの精度などが判断できる
レビュー時間が長いのに指摘がすくないなどがわかる。


##テスト品質メトリクス
テスト工程でのシステム（プログラム）の品質を評価する数値。


|メトリクス|計算式|
|---|---|
|テスト密度|テスト項目（ケース）数 / （修正や追加した）コード行数|
|バグ密度|不具合 / テスト項目（ケース）数|

###テスト密度
システムの規模に対してテスト項目（ケース）数の割合。
システムにの規模によるテスト項目数の妥当性などが判断できる。

###バグ密度
テストによって検出したバグの数の割合。
システム（プログラム）の品質やリスクなどの指標になる。


#考察というか悩みなど
システム規模っというのがでているが、これはどういうふうに計測するんだんろうか？
ページ数とかいうけど、無駄にページ数が多くてレビュー密度がさがったら意味がないと思うし。。。
経験的に大中小とか定性的にシステム規模を出すしかないのだろうか？


レビューした結果、誤字などの指摘などは指摘個数には入れるものなの？
そんなものまで入れると、ものすごく指摘個数があがって本質的なレビュー指摘のメトリクスから外れるんじゃないのかな？

バグ密度が、どうして分母が「テスト項目（ケース）数」なんだろうか？
なんとなく分母は**「（修正や追加した）コード行数」**じゃないのか？っと思っていたので見ているうちに、なんとなく **テスト密度 * バグ密度** でコードに対してのバグの割合となるので縦軸、横軸の表に表しやすいということなんじゃないか？ということで落ち着いた。
外付けSSDに圧迫データ(Unity Asset Storeフォルダ)をお引っ越し(Mac)

# UnityやらBlenderやらXcodeやらやら入れすぎてMacが危うく壊れそうになったので、外付けSSDを購入してストレージを圧迫しているデータのお引っ越しを敢行しました〜！)＞

![スクリーンショット 2019-08-17 15.18.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/56356b27-7e2e-7f75-485d-bf61bc69ca0f.png)

## 環境
PC: MacBook Air
購入したSSD: [My Passport Go 500GB](https://www.wd.com/ja-jp/products/portable-storage/my-passport-go-japan.html)

## 参照記事
[terminalでシンボリックリンクのはりかた(BackUpファイルなどを外付けHDDに指定する方法)](https://qiita.com/yasshcy/items/d11c268098f87633c259)
[Asset Storeのダウンロードフォルダを変更する](http://unitygeek.hatenablog.com/entry/2015/06/05/160146)
[【快適なMacライフ】シンボリックリンクを使って外付けHDDやSSDにデータを保管しよう](https://www.sakumamatata.com/2018/06/symboliclink.html)

---


:baby_tone2:以下作業手順:baby_tone2:

### その１
#### Unity Asset Storeのディレクトリを外付けSSDにコピー

まずはSSDにデータをコピー

- 外付けSSD(My Passport)をPCにつなぎ、Finderからその中に入って適当なディレクトリを作成する
（※今回は下記のように構成）

[My Passport]
　　L　[MacData]
　　　　L　[Unity]
　　　　　　L　[UnityData]

- 作成したら、[移動]->[ライブラリ]（Shift + Cmd + L）で、ライブラリに移動し、[Unity]の中にある[Asset Store-5.x]を丸っと、先ほど作ったSSDの[UnityData]配下にコピー、コピーできたら、ライブラリ配下の[Asset Store-5.x]は_を先頭につけてリネーム（あとで無事にお引っ越しできたら削除する）

- コピーしてきたSSDの[Asset Store-5.x]を右クリックし、[情報を見る]->[一般情報]->[場所]に書かれているパスを丸っとコピー

※[Asset Store]というフォルダもある場合、それはUnity4.x以前でダウンロードしたアセットが入っているので、同じように作業（私の環境にはなかったので省略しますorz）


### その２
#### terminalで外付けに入るには

次に、terminalで外付けにどうやって入れるかがわからなかったので、念のためterminalを開いて入ってみた

`cd "【先ほどコピーしたパス】"`
`cd "/Volumes/My Passport/MacData/Unity/UnityData/Asset Store-5.x"`

※　cd /Volumes/My Passport/MacData/Unity/UnityData/Asset Store-5.x　（""での囲いなし）だと、MyとPassportの間のスペースでとぎれちゃってうまくいかないので注意


### その３
#### 外付けSSDの方を参照できるようにシンボリックリンクを作成

terminalで今度はライブラリのUnity配下に移動
`cd ~/Library/Unity/`

pwdで、ライブラリのUnity配下にいることを確認してから、
`pwd`
/Users/【User Name】/Library/Unity

`ls -s "ソースパス" "リンク名"`
`ln -s "/Volumes/My Passport/MacData/Unity/UnityData/Asset Store-5.x" "/Users/【User Name】/Library/Unity/Asset Store-5.x`"

※これもパスを""で囲わないととぎれてうまくいかないので注意！

シンボリックリンクが貼れたら、
`cd Asset\ Store-5.x`
`pwd`
/Users/【User Name】/Library/Unity/Asset Store-5.x
となれば成功！

### 確認作業
#### Unityで実際に、Asset Storeでダウンロードして無事インポートできるか確認する

適当なAssetをダウンロードして、

![スクリーンショット 2019-08-17 16.32.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/b2b11887-b02b-2073-b044-0351279dcdd2.png)

ちゃんと、SSD配下に保存されてること確認！

![スクリーンショット 2019-08-17 16.34.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/62fcfbd4-2af2-1040-1153-a98699ba21c6.png)

インポート&配置もできた！！確認完了！
![スクリーンショット 2019-08-17 16.38.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/7a334d24-bdf5-bf3f-d2b9-865db62aed64.png)

なので、リネームしていたライブラリ配下の[_Asset Store-5.x]を削除してお引っ越し終了！

---
##### :alien:振り返り:alien:
引っ越し完了後、SSDを外してからストレージを見て見たら、なぜか逆に容量が増えていた、、、
（おそらく、確認作業で行なったAssetのインポート先はMacのストレージだったため、、）
~~プロジェクトの保存先もSSDにできるのか調べてやらないとな、と思いました。~~

~~以上！~~




PS
プロジェクトの保存先をSSDにするのはとっても簡単でした！
既存のプロジェクトフォルダを丸っとSSD配下にコピーしてきて、
Unity Hubの[リストに追加]からSSD配下のプロジェクトを追加して開くだけで大丈夫でした！

![スクリーンショット 2019-08-17 17.16.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463891/fbb6f0fe-fa89-0ca1-a5a8-23719a3413c9.png)

今度はUnityの各バージョンの保存先もSSDにできるのか調べてみようと思います！

以上！
【PHP】アルファベットと数字で組み合わされた文字列の並び替え

# 配列の並び替え

使用する関数
[usort](https://www.php.net/manual/ja/function.usort.php)
[strnatcmp](https://www.php.net/manual/ja/function.strnatcmp.php)

```sample.php
<?php
$arr = ["sample3", "sample1", "sample12"];
usort( $arr, "strnatcmp" );

print_r( $arr );

```

#### 出力結果

```
Array
(
    [0] => sample1
    [1] => sample3
    [2] => sample12
)
```

## 追記
頂いたコメントにもあるように
[sort関数](https://www.php.net/manual/ja/function.sort.php)でも並び替えができるようです。
Oculusの画面をPCにミラーリングする

Oculus標準のスマホへのWiFiのミラーリングがいまいちなので、いくつか試して見ました。USB接続でscrcpyを使う方法が一番安定してよかったのでメモしておきます。（WiFi環境でも使えますがここでは省略します）

# 利用するソフト

- [scrcpy](https://github.com/Genymobile/scrcpy)
- adb / Andorid Tools

# インストール方法

## MacOS

[brew](https://brew.sh/index_ja)のインストールが必要です。インストール済みであれば、ターミナルより以下コマンドにてインストールします。

```
brew cask install android-platform-tools    
brew install scrcpy
```

## Windows

adbを含んだビルド済みのバイナリーがあります。
https://github.com/Genymobile/scrcpy/releases

# 使い方

```
scrcpy
```

これだけで接続されているデバイスのスクリーンをミラー表示します。

<img width="494" alt="スクリーンショット_2019-08-17_16_47_03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/6651e3ae-90f1-0952-dd16-b9fc933cd334.png">


# Oculusの単眼のみのCrop

デモなどで画面を使う場合は両目の情報は必要無いので、画像の半分だけをcropして表示します。

<img width="494" alt="スクリーンショット_2019-08-17_16_46_19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14768/005c0544-b137-00b0-6f2c-b18bbfdea93f.png">


## Oculus Go

```
scrcpy --crop 1280:1240:1335:100
```

```
# 中心部分のみ（適当
scrcpy --crop 950:950:1435:250
```

## Oculus Quest

```
scrcpy --crop 1440:1400:1425:100
```
※未確認

# 簡単実行

以下よりmacos用のscrcpyを起動するだけのアプリを作ってみたので、ダウンロードできます。（上記のインストールが完了しているのが前提になります）

https://github.com/bellx2/scrcpyApp/archive/v1.0.zip

# その他オプション

録画、ビットレートの変更、フルスクリーン表示等も可能なので、詳しくはscrcpyのgithubを参照してください。

https://github.com/Genymobile/scrcpy
Qiitaで数式をインライン表示にしたときにうまく数式としてレンダリングされなかったときの対処メモ

# 概要
Qiitaで**数式をインライン**にしたときにうまくレンダリングされなかったときの対処メモです

### やりたいこと
インラインで　 $ MSE = \frac{\sum_{i=0}^{N-1} (\mathbf{y}_i - \hat{\mathbf{y}}\_i)^2}{N} $ 　な風に数式を書きたい


### コードブロックで数式を記述する場合

Tex記法で

```text:TeX記法
MSE = \frac{\sum_{i=0}^{N-1} (\mathbf{y}_i - \hat{\mathbf{y}}_i)^2}{N}
```
のようにしてコードブロック内に記述すると↓のように表示される。

```math
MSE = \frac{\sum_{i=0}^{N-1} (\mathbf{y}_i - \hat{\mathbf{y}}_i)^2}{N}
```

### インライン数式で記述する場合

\$ と \$ で数式挟んであげて、同じようにTex記法で記述する

```
$ MSE = \frac{\sum_{i=0}^{N-1} (\mathbf{y}_i - \hat{\mathbf{y}}_i)^2}{N} $
```

すると↓のように表示され数式にならない。

$ MSE = \frac{\sum_{i=0}^{N-1} (\mathbf{y}_i - \hat{\mathbf{y}}_i)^2}{N} $

そこで、↓のように<font color=blue>2つめの``\mathbf{y}_i``の``_``の前に"\\"をいれて``\_``のようにエスケープ</font>した

```text:2つめの"_"を"\_i"のようにエスケープ
$ MSE = \frac{\sum_{i=0}^{N-1} (\mathbf{y}_i - \hat{\mathbf{y}}\_i)^2}{N} $
```

すると、インラインでも期待したとおり表示された

$ MSE = \frac{\sum_{i=0}^{N-1} (\mathbf{y}_i - \hat{\mathbf{y}}\_i)^2}{N} $

（[参考](https://qiita.com/PlanetMeron/items/63ac58898541cbe81ada)記事のコメント欄を参考にさせていただきました、うまくいった理由はよく理解できていません。）

### 参考
[Qiitaの数式チートシート](https://qiita.com/PlanetMeron/items/63ac58898541cbe81ada)
CSS で乱数を使えるようにする

CSS だけで乱数を使うことはできません。仕様上、 `random(min, max);` のような関数もしくは類似する機能はないため、 CSS 以外の技術に頼らざるを得ないのが現状です。
大抵の場合は下記のいずれかでしょう。

* Sass のような CSS プリプロセッサ
* React にあるような CSS in JS
* サーバサイドレンダリング

もちろん、 JavaScript を使えば Pure CSS でも乱数を擬似的に使うことは可能です。今回はこれ。
ただ、 Pure CSS で開発するケースは極めて稀でしょうから、実用性はありません。

## デモ

`Reload` ボタンを押すごとに要素のスタイルが変化すれば成功です。

<p class="codepen" data-height="265" data-theme-id="dark" data-default-tab="css,result" data-user="mimonelu" data-slug-hash="gOYMmwQ" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="CSS Random Variable">
  <span>See the Pen <a href="https://codepen.io/mimonelu/pen/gOYMmwQ/">
  CSS Random Variable</a> by mimonelu (<a href="https://codepen.io/mimonelu">@mimonelu</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## コード

1 ファイルに収めてみましたが、 `link` タグによる外部スタイルシートでも問題なく動作します。

```html
<style>

p {
  background-color: rgb(var(--random_128_255), var(--random_128_255), var(--random_128_255));
  color: #var(--random_0_8)var(--random_0_8)var(--random_0_8);
  font-size: var(--random_10_30)px;
  padding: 16px;
}
p::before {
  content: "var(--random_1_6)";
}

</style>
<script>

;Array.prototype.slice.call(document.styleSheets).forEach(function (styleSheet) {
  Array.prototype.slice.call(styleSheet.cssRules).forEach(function (cssRule) {
    cssRule.style.cssText = cssRule.style.cssText.replace(/var\(\-\-random_(\d+)_(\d+)\)/g, function (a, b, c) {
      var min = parseInt(b, 10);
      var max = parseInt(c, 10);
      return Math.floor(Math.random() * (max - min + 1)) + min;
    });
  });
});

</script>
<p> is random number.</p>
```

## 説明

要するに `var(--random_MIN_MAX)` という変数（のふりをした文字列）を乱数に置換しているだけです。
本来は `random(MIN, MAX)` という関数形式にしたかったのですが、 `document.styleSheets` には「適用されたスタイル」すなわち「 Valid なスタイル」のみ格納されるらしく、 `random()` などという存在しない関数は Invalid となり無視されてしまうため、変数という形になりました。
つまり存在しない変数は Valid とみなされるようです。とは言え、 `color: #var(--random_0_9)var(--random_0_8)var(--random_0_8);` こんなのが Valid だとはとても思えませんが…実際存在する変数に置き換えても動作しないし🤔
しかしまぁ、関数形式だと `px` のような単位との組み合わせが難しくなるため、結果的には変数の方が良かったかなと。

## おわりに

何となく勢いで作ってしまったので、よりベターなアプローチがあるかどうかは調べていません。需要ないし。
しかもこれプロパティだけでしか使えないんですよね。 `:nth-child(random(1, 3))` みたいなこともしたいんですが、思い付かず。

ちなみに、 CSS 標準に乱数生成ルールを組み込むことについての難しさは [このあたり](https://github.com/w3c/csswg-drafts/issues/2826#issuecomment-455347690) が参考になると思います。
Randomクラスに間隔をもたせるには

Randomクラスをもちいて一定間隔ごとに数値を取り出すにはどうすればよいですか？
例えばRandom.Range(0f,100f)とした際に0,10,20,30…というように10の間隔ごとに数値を出すというような場合です。
Rails版 bugsnagの飼い方

# 環境

- Rails 5.2.3

# 参考サイト

- [Rails integration guide（Bugsnagのオフィシャルサイト）](https://docs.bugsnag.com/platforms/ruby/rails/)

# 手順

### 1. [bugsnag](https://www.bugsnag.com/)でユーザ登録。

### 2. 指示に従い環境を選ぶ（今回は、`Ruby`で`Rails`）

### 3. Gemfileに`bugsnag`を追加する。

```ruby:Gemfile
gem 'bugsnag'
```
```shell
bundle install
```

### 4. 指示に従い、以下のコマンドで`config/initializers/bugsnag.rb`を生成する。

```shell
rails generate bugsnag <YOUR_BUGSNAG_API_KEY>
```

尚、そのままではAPIキーがベタ書きされるので、以下のように環境変数から読み込むようにする。

```ruby:config/initializers/bugsnag.rb
# frozen_string_literal: true

Bugsnag.configure do |config|
  config.api_key = ENV['BUGSNAG_API_KEY']
end
```

### 5. production環境でだけ`bugsnag`のnotificationが飛ぶようにする。

```ruby:config/initializers/bugsnag.rb
# frozen_string_literal: true

Bugsnag.configure do |config|
  config.api_key = ENV['BUGSNAG_API_KEY']
  config.notify_release_stages = ['production']
end
```

> 参考: https://docs.bugsnag.com/platforms/ruby/rails/configuration-options/



### 6. エラーの報告

#### ここ（↑）までの設定で、rescue されていない例外は全て報告されるようになります。

> Reporting unhandled exceptions
>
> After completing installation and basic configuration, unhandled exceptions in your Rails app will be automatically reported to your Bugsnag dashboard.
>
> https://docs.bugsnag.com/platforms/ruby/rails/#reporting-unhandled-exceptions

#### 以下、rescue している箇所で bugsnag への通知を入れる例です。

```ruby
begin
  raise 'Something went wrong!'
rescue => exception
  Bugsnag.notify(exception)
  # 必要であれば、ここで何か処理を行う。
end
```

rescue の中で再度 raise する場合は、以下のように `skip_bugsnag` を挟む（そうしないと、再度 bugsnag に通知が飛びます）。

参考URL: https://docs.bugsnag.com/platforms/ruby/rails/#avoiding-re-notifying-exceptions

```ruby
begin
  raise 'Something went wrong!'
rescue => exception
  Bugsnag.notify(exception)
  exception.instance_eval { def skip_bugsnag; true; end }

  # Now this won't be sent a second time by the exception handlers
  raise exception
end
```
Java 11 で javax.annotation.Generated が見つからない問題

# 課題

gRPC のサンプルコードを Java 11 で動かそうとしたところ、コード生成はうまくいったものの、実行時に下記のようなエラーが出て止まってしまいました。

```
エラー: シンボルを見つけられません
@javax.annotation.Generated(
                 ^
  シンボル:   クラス Generated
  場所: パッケージ javax.annotation
```

# 解決策

[grpc/grpc-java](https://github.com/grpc/grpc-java) のイシュー [Java 11: cannot find symbol javax.annotation.Generated #5343](https://github.com/grpc/grpc-java/issues/5343) に書かれている通り、Javax Annotation APIを `dependencies` に追加します。（このイシュー自体は Java9 の条件分岐を入れたら動かなくなったという報告ですが、↓のように条件分岐を入れなければ動きます。）

```Gradle:build.gradle（抜粋）
dependencies {
    implementation 'io.grpc:grpc-netty-shaded:1.23.0'
    implementation 'io.grpc:grpc-protobuf:1.23.0'
    implementation 'io.grpc:grpc-stub:1.23.0'
    compile 'javax.annotation:javax.annotation-api:1.3.2'  // ← この行を追加
    testCompile group: 'junit', name: 'junit', version: '4.12'
}
```

Javax Annotation API の最新バージョンは Maven Repository でご確認ください。
https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
Progate HTML/CSS中級編①

未来電子テクノロジー（https://www.miraidenshi-tech.jp/intern-content/program/ ）
で、インターンをしているたくみです。
今回はこれまでに取り組んできたProgate HTML/CSSの中級編の一部をまとめてみました。
###ヘッダーとフッダーの使い方
```html

 <header></header>
 <div class="top-wrapper"></div>
 <footer></footer>
```
###背景画像の指定方法
```html
html・・・
<div>
<h1>Learn code</h1>
</div>

CSSの指定・・・
div{
height:〇〇px;
background-image:url(〇〇〇〇);
}
```
###画像の大きさの指定

```html
div{
background-image:url(〇〇〇〇)；
back-ground-size:cover;
}
```

```###テキストの配置方法

```html
text-align:left;
text-align:right;
text-align:center;
```

###最後に
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし誤りがあれば、修正するので、どんどん指摘してください。
【Java】ProcessのOutputStreamに書き込みを行うプログラムでwaitForしても終了しなくなる状況への対処

- [【Java】Processのstdinに入力する \- Qiita](https://qiita.com/wrongwrong/items/6c9dcc758c113f405518)

上記記事の内容をやっている時に発生した問題です。

# 問題
`Process`の`OutputStream(= stdin)`に書き込みを行ったところ、時間制限付きで`waitFor`しても終了しなくなりました。

```java:問題の出たコード
// Exceptionのtry-catchは外でやっている想定
Process process = new ProcessBuilder(commands).start();

// stdinへの書き込み
OutputStream os = process.getOutputStream();
os.write(multipartFile.getBytes());

boolean result = process.waitFor(5, TimeUnit.SECONDS);
```

# 対処 / 原因
`OutputStream`を閉じるようにしたところ解決したため、恐らく延々書き込み待ちするようになったことが原因だと思います。

```java:対処後
// Exceptionのtry-catchは外でやっている想定
Process process = new ProcessBuilder(commands).start();

// stdinへの書き込み
try (OutputStream os = process.getOutputStream()) {
  os.write(multipartFile.getBytes());
}

boolean result = process.waitFor(5, TimeUnit.SECONDS);
```
特定のFragmentが表示される時にAppBarLayoutとBottomNavigationViewを非表示にする

Navigationで画面遷移を実装している場合、こんなふうに実現できます。
Fragment側からActivityのリソースにアクセスする必要がないので、Fragmentの独立性が維持できていいですね。

```kotlin:MainActivity.kt
private fun setupBottomNavigationBar() {

    val navGraphIds =
        listOf(R.navigation.tab_1, R.navigation.tab_2, R.navigation.tab_3)

    val controller = bottomNavigation.setupWithNavController(
        navGraphIds = navGraphIds,
        fragmentManager = supportFragmentManager,
        containerId = R.id.nav_host_container,
        intent = intent
    )
    controller.observe(this, Observer { navController ->
        if (navController.graph.id == R.id.tab_1) {
            navController.addOnDestinationChangedListener { controller, destination, arguments ->
                val s = resources.getResourceName(destination.id)
                info { "resourceName:$s" }
		// tab1でFullScreenFragmentが表示される時に、AppBarLayoutとBottomNavigationViewを非表示
                if (destination.id == R.id.fullScreenFragment) {
                    bottomNavigation.visibility = View.GONE
                    toolbar.visibility = View.GONE
                    appBarLayout.setExpanded(false, true)
                } else {
                    bottomNavigation.visibility = View.VISIBLE
                    toolbar.visibility = View.VISIBLE
                    appBarLayout.setExpanded(true, true)
                }
            }
            setupActionBarWithNavController(navController)
        }
    })
    currentNavController = controller
}


```