OmniAICreator/Qiita-1.07M huggingface dataset:
ガウス混合モデルのEMアルゴリズム[統計学的機械学習]

#モチベーション
課題

#問題設定
複数のガウス分布から生成される物を最尤推定したい！

#乱数生成

```python
import numpy as np 
import math
import matplotlib.pyplot as plt

np.random.seed(0)

def data_generate(n):
  return (np.random.randn(n)
  + np.where(np.random.rand(n) > 0.3, 2., -2.))
```

```python
aa = np.histogram(data_generate(1000), bins =50)
a_bins = aa[1]
a_hist = aa[0]
X1 = []
for i in range(1, len(a_bins)):
    X1.append((a_bins[i-1]+a_bins[i])/2)
plt.bar(X1,a_hist, width=0.05)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628578/7a86396a-ef92-e191-d3c7-3e97654fe54b.png)


#正規分布の定義

```python
def nomal_distribution(x , mu, dev):
    c = (2 * math.pi * math.pow(dev, 2)) ** (-1/2)
    a = (-(x-mu)**2)/(2 * (dev**2) )
    return c * math.exp(a)
```

#EMアルゴリズム
EのQを最大化

```python
def ita(xi, mu, dev, m = m):
    s = 0
    for i in range(m):
        s += w[i] * nomal_distribution(xi, mu[i], dev[i])
    n = []
    for l in range(m):
        n.append(w[l] * nomal_distribution(xi, mu[l], dev[l])/s)
    return n #m行列

def E (x, mu, dev, m = m, data_size = data_size):
    Q = 0
    for i in range(data_size):
        for j in m:
            Q += ita(x[i], mu, dev)[j] * ( math.ln(w[j]) + math.ln(nomal_distribution(xi, mu[j], dev[j])) )
    
    return Q

def M(x, mu, dev, d,  m = m, data_size = data_size):
    n = 0
    a = 0
    aa = 0
    for i in range(data_size):
        n += np.array(ita(x[i], mu, dev))
        a += (np.array(ita(x[i], mu, dev)) * x[i])
        aa += np.array(ita(x[i], mu, dev)) * (( x[i] - mu) ** 2) 

    w1 = (1/data_size)*n
    mu1 = [ a[j]/n[j] for j in range(m) ] 
    dev1 = [math.sqrt( aa[j]/(d*n[j]) ) for j in range(m)]  

    return w1, mu1, dev1
```

#グラフ化

```python
def probability_distribution(xi, w1, mu1, dev1):
    p = 0
    pro = []
    for j in range(m):
        p +=  w1[j] * nomal_distribution(xi, mu1[j], dev1[j])
    return p
```

```python
epoc = 30
m = 3
data_size = 1000
mu = np.random.uniform(-1, 1, m)
w = [0.2,0.2,0.6]
dev = np.random.uniform(-0.2, 0.2, m)
x = data_generate(data_size)
w1, mu1, dev1 =  M(x, mu, dev, 1)
for num in range(epoc):
    w1, mu1, dev1 = M(x, mu1, dev1, 1)

xx = np.linspace(-10, 10, 100)
pp0 = [probability_distribution(xx[i] ,w, mu, dev) for i in range(len(xx))]   
pp = [probability_distribution(xx[i] ,w1, mu1, dev1) for i in range(len(xx))]   
plt.scatter(xx,pp, c='red')
#plt.scatter(xx,pp0, c = 'blue')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628578/ac3758c3-ce1f-1acf-b747-14ec5b20fc87.png)
Laravelで環境(開発環境と本番環境等)ごとに異なる値を定義する

# 目次
Laravelの記事一覧は下記
[PHPフレームワークLaravelの使い方](https://qiita.com/toontoon/items/c4d0371e504c37f6576e)

# Laravelバージョン
動作確認はLaravel Framework 7.19.1で行っています

# 環境(開発環境と本番環境等)ごとに異なる値
データベースの接続先とかメールの送信元等、開発環境と本番環境で異なる値にしたいことがあります
それを実現するためにわざわざif文を書く必要はありません

# 前提条件
[eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)](https://qiita.com/toontoon/items/76fa7f8845b20776077c)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています

# envファイルの作成
(1) envファイル作成
/sample/.envがすでに存在していると思います
/sample/.envをコピーして/sample/.env.localという名前のファイルにします

(2) 値の追記
/sample/.envに下記を追記
`SAMPLE_KEY=SAMPLE_VALUE_PRD`

/sample/.env.localに下記を追記
`SAMPLE_KEY=SAMPLE_VALUE_LOCAL`

# configファイルの作成
(1) /sample/config/sample.phpを作成

```sample.php
<?php

return [
    'sampleKey' => env('SAMPLE_KEY'),
];

```
env('SAMPLE_KEY')で先ほどenvファイルに追記したSAMPLE_KEYの値が取れます

# Controllerにメソッド追加
(1) /sample/app/Http/Controllers/SampleController.phpにsettingメソッドを追記

```
    public function setting()
    {
        $data = ['key' => config('sample.sampleKey')];
        return view('sample.setting', $data);
    }
```
config('sample.sampleKey')で先ほどconfig/sample.phpに書いたsampleKey要素を取得できます
なぜここでenv('SAMPLE_KEY')ではなく、config('sample.sampleKey')で値を取得するのかは後述します

(2) /sample/routes/web.phpに下記を追記
`Route::get('sample/setting', 'SampleController@setting');`


# viewの作成
 /sample/resources/views/sample/setting.blade.phpファイル作成

```setting.blade.php
<html>
    <head>
        <title>sample</title>
    </head>
    <body>
        {{$key}}
    </body>
</html>
```

# 動作確認

apacheのhttpd.confに下記を追記
もしapacheにmod_envモジュールをインストールしていない方は、mod_envモジュールをインストールしてください

```httpd.conf
SetEnv APP_ENV local
```

apache再起動してアクセス
`http://localhost/laravelSample/sample/setting`

実行結果

```
SAMPLE_VALUE_LOCAL
```

先ほど追記したSetEnvをコメントにする

```httpd.conf
#SetEnv APP_ENV local
```

apache再起動してアクセス
`http://localhost/laravelSample/sample/setting`

実行結果

```
SAMPLE_VALUE_PRD
```

このようにapacheに設定した環境変数APP_ENVの値が.envファイルの接尾辞となり、
Laravelアプリケーションで読み込まれる.envファイルを変えることができます

# configのキャッシュ
(1) コマンドラインで 
`cd sample`
`php artisan config:cache`
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/bootstrap/cache/config.phpが現れます

/sample/config配下のファイルが/sample/bootstrap/cache/config.php一つにまとめられました
Laravelは/sample/bootstrap/cache/config.phpを読むようになります
これによりアプリケーションの処理速度があがります

(2) コマンドラインで 
`cd sample`
`php artisan config:clear`
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
eclipseプロジェクトを右クリック→リフレッシュ
/sample/bootstrap/cache/config.phpが消えました

(3) Controllerでconfig関数を使った理由
先ほどControllerでenv('SAMPLE_KEY')ではなく、config('sample.sampleKey')で値を取得しました
その理由は
bootstrap/cache/config.phpをつくると、env関数の呼び出しはすべてnullを返すようになるLaravelの仕様のためです
したがって、.envファイルに記載した値は一度configファイルの配列に設定して、Controller以降ではconfig関数を使用して取得することになります

開発時は`php artisan config:cache`を実行することはないと思います
しかし、本番環境では`php artisan config:cache`を実行してデプロイすることになると思います
ABC168の復習

#ABC168
参加はできませんでしたが、問題を解きたいと思います。

##[A - ∴ (Therefore)](https://atcoder.jp/contests/abc168/tasks/abc168_a)
問題文はAtCoderを参照してください。

- 条件分岐１回のみ

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<cmath>
#include<cstdio>
#define rep(i,n) for(int i=0; i<(n); ++i)
using namespace std;
using ll =long long;
using P = pair<int,int>;

int main(int argc, const char * argv[]) {
    int n;
    cin >> n;
    
    n=n%10;
    switch (n) {
        case 3:
            cout << "bon" << endl;
            break;
        case 0:
        case 1:
        case 6:
        case 8:
            cout << "pon" << endl;
            break;
        case 2:
        case 4:
        case 5:
        case 7:
        case 9:
            cout << "hon" << endl;
            break;
        default:
            break;
    }
    
    return 0;
}
```

##[B - ... (Triple Dots)](https://atcoder.jp/contests/abc168/tasks/abc168_b)
問題文はAtCoderを参照してください。

- 条件分岐１回のみ

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<cmath>
#include<cstdio>
#define rep(i,n) for(int i=0; i<(n); ++i)
using namespace std;
using ll =long long;
using P = pair<int,int>;

int main(int argc, const char * argv[]) {
    int k;
    string s;
    cin >> k >> s;
    
    if(s.length() <= k){
        cout << s << endl;
    }else{
        cout << s.substr(0, k) << "..." <<  endl;
    }

    return 0;
}
```

##[C - : (Colon)](https://atcoder.jp/contests/abc168/tasks/abc168_c)
問題文はAtCoderを参照してください。

- 余弦定理 a2=b2+c2−2bccosA
- 少数の精度を設定 setprecision(20)

```C++:C++
#include<iostream>
#include<vector>
#include<algorithm>
#include<iomanip>
#include<utility>
#include<iomanip>
#include<map>
#include<cmath>
#include<cstdio>
#define rep(i,n) for(int i=0; i<(n); ++i)
#define pai 3.1415926535897932384
using namespace std;
using ll =long long;
using P = pair<int,int>;

int main(int argc, const char * argv[]) {
    double a, b, h, m;
    cin >> a >> b >> h >> m;
    
    long double deg = abs((30.0 * h + 0.5 * m) - (6.0 * m));
    if(deg > 180) deg = 360 - deg;
    long double rad = deg * (pai/180.0);
    long double c = a*a + b*b - 2.0 * a * b * cos(rad);
    
    cout << setprecision(20) << sqrtl(c) << endl;

    return 0;
}
```
GitHub Actions、Circle CI比較メモ

2020/5/19 時点の情報です。

Circle CIの無料プランとGitHubのTeamsプランの場合のGitHub Actionsを比較しました。

誤っている箇所があるかもしれませんので、正確な情報は公式ドキュメントを確認してください。

## GitHub Actions
https://github.co.jp/features/actions

- ~~Teamであれば10000クレジット/月 (10000分の実行時間)~~
    - 2020/4/15 に 3000クレジット/月 に変更になっていました
    - https://github.blog/2020-04-14-github-is-now-free-for-teams/?utm_medium=social&utm_content=1586880139
- 最大20のワークフローの並列実行が可能
- ~~定期実行ができるのはデフォルトのブランチのみ~~ ※コメント欄にブランチを指定した定期実行方法について記載いただきました
- 指定したディレクトリに差分があった場合のみワークフローを実行する機能がある
  - monorepoの場合、無駄なCIを回さなくて済む）
  - https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#onpushpull_requestpaths
- Dockerイメージのレイヤキャッシュの追加可能
- 無料分を超えた場合は従量課金、Linux実行時間1分辺り$0.008

## Circle CI
https://circleci.com/ja/pricing/

- 2500クレジット/週 
  - (無料プランのイメージを利用すると250分/週の実行時間。よって月1000~1250?）
- 最大1つのジョブ実行
- どのブランチでも定期実行ができる
- ディレクトリに差分があった場合のみ実行する機能はない
- 無料プランではDockerイメージのレイヤキャッシュはサポートしていない
- 追加クレジットは$15で25000クレジット購入可能(?)


# 参考文献
https://qiita.com/reireias/items/04b167fed442bca05de1
https://qiita.com/ma2muratomonori/items/52599fad1c2d2d644f30#docker%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8%E3%82%92%E5%AE%9A%E6%9C%9F%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B
CanvasLMSに外部アプリ「ZOOM」を追加する

#環境
ubuntu18.04
[Github](https://github.com/instructure/canvas-lms)

#実施
[こちら](https://applications.zoom.us/home/lti/rich/credential)よりzoomにログインし、`LTIキー`と`LTIシークレット`をコピーする。
<img width="1437" alt="スクリーンショット 2020-05-19 1.10.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620216/54366516-e53c-b461-ccc8-7eba8165ca8a.png">


Canvasの外部アプリ追加画面を表示する。
<img width="1437" alt="スクリーンショット 2020-05-19 1.04.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620216/4ea54098-e095-9fc2-636e-8770c4c376f3.png">
「+ App」を押下し、「Paste XML」を選択する。
<img width="1437" alt="スクリーンショット 2020-05-19 1.18.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620216/77855fd0-b4a2-0a80-2686-9b8fd06b0d19.png">
「Name」に`Zoom`、「Consumer Key」にコピーした`LTIキー`、「Shared Secret」にコピーした`LTIシークレット`を入力する。
「XML Configuration」に以下を入力し、「Submit」を押下する。

```xml:XMLConfiguration
<?xml version="1.0" encoding="UTF-8"?>
<cartridge_basiclti_link xmlns="http://www.imsglobal.org/xsd/imslticc_v1p0" xmlns:blti = "http://www.imsglobal.org/xsd/imsbasiclti_v1p0" xmlns:lticm ="http://www.imsglobal.org/xsd/imslticm_v1p0" xmlns:lticp ="http://www.imsglobal.org/xsd/imslticp_v1p0" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www.imsglobal.org/xsd/imslticc_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticc_v1p0.xsd http://www.imsglobal.org/xsd/imsbasiclti_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imsbasiclti_v1p0.xsd http://www.imsglobal.org/xsd/imslticm_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticm_v1p0.xsd http://www.imsglobal.org/xsd/imslticp_v1p0 http://www.imsglobal.org/xsd/lti/ltiv1p0/imslticp_v1p0.xsd"><blti:launch_url>https://applications.zoom.us/lti/rich</blti:launch_url> <blti:title>Attendance</blti:title> <blti:description><!-- [CDATA[Schedule/List Zoom Meeting]] --></blti:description> <blti:extensions platform="canvas.instructure.com"> <lticm:property name="tool_id">Zoom</lticm:property> <lticm:property name="privacy_level">public</lticm:property> <lticm:property name="text">Zoom</lticm:property> <lticm:options name="course_navigation"> <lticm:property name="default">disabled</lticm:property> <lticm:property name="visibility">public</lticm:property> <lticm:property name="enabled">true</lticm:property> </lticm:options> </blti:extensions> </cartridge_basiclti_link>
```
追加後に、「Zoom」の設定より`Placements`を押下する。
<img width="1437" alt="スクリーンショット 2020-05-19 1.29.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620216/e1d1e86a-7090-c06e-2a73-20309e8d55dd.png">

画面に、以下が表示されていれば完了。
<img width="1437" alt="スクリーンショット 2020-05-19 1.30.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620216/9cd1f9bd-a417-5ed3-caae-4d5e006c164a.png">


※サイドバーに追加したい場合は、ナビゲーションタブから「Zoom」を有効にする。
【Rails】date_selectのクラス指定

#最初に 
hamlでdate_selectを使用した際クラスを付与できなかったため、クラス指定の仕方を備忘録として残します。

## date_selectとは

https://gyazo.com/29cf6b960c4c2391a24e70069a9d8659
こんな感じでドロップダウン形式の生年月日のフォームを自動で生成してくれるのがdate_select。

ちなみにデフォルトだとこんな感じ。
https://gyazo.com/4100a51de9a365f337e142bad0d7507b

最初form_forのselect_boxを使用しており、年、月、日と3つフォームを生成してオプションつけて、データをまとめて保存する様にして、、、と生年月日のフォームを実装するまでに時間がかかったため、
早く知っておきたかった。。（泣）
https://gyazo.com/0bd5ca777d38932db77858cd64f87448
今後はこの便利すぎるdate_selectを使用していきます。


## 使用方法
```
collection_select(オブジェクト名, メソッド名, 要素の配列, value属性の項目, テキストの項目 [, オプション or HTML属性 or イベント属性])
```
##手順
1.コードの記載（今回はコントローラーで＠adreess変数に空のハッシュを代入済み、カラムはbirthdayを想定します。）

```html.haml
= form_for (@address) do |f|
  = f.date_select :birthday
```
これでフォーム自体は使用できます。

2.オプションの追加

```html.haml
= form_for (@address) do |f|
  = f.date_select :birthday, use_month_numbers: true, start_year: 1970, end_year: Time.now.year, prompt:"--"
```
use_month_numbers: true,　→　月の表示を数字に。デフォルトだと英語表記。

start_year: 1970,　→　選択肢として何年からスタートするかを指定。デフォルトだと10年前からになる。

end_year: Time.now.year,　→　選択肢の終わりの年を現在に指定。

prompt:"--"　→　セレクトボックスのデフォルトで表示される文字を”ーー”に指定。デフォルトだと現在の日付が適用される。（これ個人的におすすめ！）

3.クラスの指定

```html.haml
= form_for (@address) do |f|
  = f.date_select :birthday, use_month_numbers: true, start_year: 1970, end_year: Time.now.year, prompt:"--", class:"main__box__bottom__content__group3__box__barthday__box"
```

これでクラスの付与完了！と思いきや、cssが反応しない。検証で調べてみるとクラスが指定されていないということがわかった。最初これでなぜクラスが当たらないのか謎でした。
ソースコードを調べてると、option(use_month_numbers:やprompt：)は第3引数に設定し、html_options(classなどのhtml/css)は第4引数に設定するようです。
https://railsdoc.com/form
要は指定する場所が決められているということで、上記の場合だと第3引数でクラス指定をしていることになり反映されなかったのが原因です。

なので第3引数と第4引数を{}で別々に括ると、

```html.haml
= form_for (@address) do |f|
  = f.date_select :birthday, {use_month_numbers: true, start_year: 1970, end_year: Time.now.year, prompt:"--"},
{class:"main__box__bottom__content__group3__box__barthday__box"}
```
これでクラスが付与されました！
ちなみにオプションなし、クラスのみ指定（第4引数のみ指定）したい場合は、

```html.haml
= f.date_select :birthday, {},　{class:"main__box__bottom__content__group3__box__barthday__box"}
```

カラムと第4引数の間に空の{}を設けることによりクラスが付与されます！

###参考文献

・https://railsdoc.com/form
・https://qiita.com/nakanoyoshiki/items/e87a6238f8febbeb208a
tty script コマンドでLinuxサーバ作業を他者に共有

## 

## AさんのターミナルにBさんの操作ログを表示する手順

Aさんのターミナル

```
$ tty
/dev/pts/4
```

Bさんのターミナル

```
$ echo "hoge" > /dev/pts/4
$ script -fq /dev/pts/4
```

これで、以後Bさんのターミナル作業すべてがAさんのターミナルに表示されるようになります。

## コマンド説明
### tty コマンド
```
    自分の標準入力に接続されている端末のファイル名を出力する。
```
（man ttyの一部抜粋）

### script コマンド
```
    script は端末に表示されたものすべての写し (typescript) を作成する。
    引き数 file が指定されると、 script はすべての記録を file に保存する。
    ファイル名が与えられなければ、写しは typescript というファイルに保存される。

    オプション
        -f    書き込みをするごとに出力をフラッシュする。
        -q    寡黙な動作にする。
```
（man scriptの一部抜粋）

## 参考サイト
* [標準入力・標準出力ってなに? - Qiita](https://qiita.com/angel_p_57/items/03582181e9f7a69f8168)  
tty, pty, pts の説明が図で示されていて理解しやすい
* [TTYとは (Tele-TYpewriter) ティーティーワイ： - IT用語辞典バイナリ](https://www.sophia-it.com/content/TTY)
* [ttyについて ttyやptsってなんぞ？ - それマグで！](https://takuya-1st.hatenablog.jp/entry/20101024/1287947368)
* [ttyとかptsとかについて確認してみる - Qiita](https://qiita.com/toshihirock/items/22de12f99b5c40365369)
* [ttyとptsとptmxとpty - tweeeetyのぶろぐ的めも](https://www.tweeeety.blog/entry/2014/05/23/175129)
Qiitaで画像アップロード時に ![Bad Request]() で失敗する時は、ブラウザを変えてみる

（2020.5.20 追記：Safariでの画像アップロードの不具合は直ってました。）

Qiitaで画像ファイルのアップロードがうまく出来なかったんで、その対処法を記しておきます。（2020.5.19現在）

Safariでダメな時は、Chromeにしてみる！

<img width="600" alt="qiita_uploading-0.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26536/38ced74c-1315-84e3-3bc7-bc1e7062fbc0.png">
Safariで画像ファイルをアップロードすると、しばらく `![uploading-0]()`が続き、

<img width="600" alt="qiita_bad_request.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26536/b454922b-0d08-35df-f259-efc06c223b2f.png">
ついには、`![Bad Request]()`

とエラー表示されて失敗し、アップロードできませんでした。

ちなみに、
•[Qiitaで画像アップロード時、Bad Requestとエラーになるときの対応方法](https://qiita.com/RyoheiTomiyama/items/990469764d982bdf5f8b)
に載っていた「スーパーリロード」でもダメでした。

また、Qiitaでは初回は画像のアップロード用量制限制限がある、というものでもありませんでした。（Chromeでできたので。）

で、救われたのはこちらのツイート↓でした！
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Qiitaで画像アップロードが動かない件、Chromeではオケ。Safariだとだめみたい。<br><br>🙆‍♂️ Chrome<br>🙅‍♂️ Safari<br><br>Safari で投稿に対して画像をアップロードすると [Bad Request] になってしまう。</p>&mdash; Tomoki Kobayashi (@temoki) <a href="https://twitter.com/temoki/status/1253619553491316737?ref_src=twsrc%5Etfw">April 24, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

ブラウザをSafariからChromeに変えてみたら、あっさり成功！

なんか、時々この不具合が出るみたいですね。
Chromeでページ全体のキャプチャが撮りたい

# 悩み
ページ全体のキャプチャ／スクショが撮りたいのに、1ページに収まっていない！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/692091b7-f4e2-6abf-e6c7-2c70e72b8fd4.png)

# そんなときは
「**Full Page Screen Capture**」

# 追加方法
[Chrome ウェブストアの拡張機能ページ](https://chrome.google.com/webstore/category/extensions?hl=ja)にアクセス
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/e2828f81-982c-f68e-3615-b3e6f74e6771.png)

左上の入力欄に「Full Page Screen Capture」と入力し、検索してください。
見つかりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/9f72d287-594c-f9b8-90f1-3d84cfc97c33.png)

右上の「Chromeに追加」ボタンを押すと、確認ダイアログが出てきますので、追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/2fd5c914-5134-aca1-6f9c-69639a860e72.png)

ダウンロードが始まって…楽しげなページが表示されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/e89fe40a-bbb5-4e24-5d34-23bf6876bac5.png)


# 動作確認
右上にカメラアイコンが表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/bf150090-ae8e-b9bd-32d4-6a09d9cab1bc.png)

これを押すと、パックマンみたいなのが出てきて、キャプチャが開始されます！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/422a75c2-d30e-bb7e-8a70-0da48888417c.png)

無事、ページ全体のキャプチャが撮れました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/b758dee1-3037-897c-04e7-66a516586e1c.png)

画像を右クリックすると、pngやPDFにして保存できます。
設定でjpgも選択できます。
Cloud Foundryにおけるpush, restage, restartの違い

# 前提
## droplet
以下の3つを詰めたtarballのこと

- stack
  - OSが入ったプリビルドされたファイルシステム（イメージ的にはDockerのOS image的な？）
  - 例えばcflinuxfs3などがあり、これはUbuntu Bionic 18.04ベースのファイルシステム
- buildpack
  - app用のフレームワークとランタイムを提供する
- appのソースコード

# push, restage, restart違い
## push
- appを停止し新しいdropletをコンパイルして起動する
- dropletは最新のappのソースコードを用いてコンパイルされる
- サービスのバインドやappが使用する環境変数を追加した場合は設定が適用される

## restage
- appを停止し新しいdropletをコンパイルして起動する
- dropletは既存のappのソースコードを用いてコンパイルされるため、appのソースコードは更新されない
- サービスのバインドやapp, buildpack用の環境変数を追加した場合は設定が適用される

## restart
- appを停止しコンパイル済みのdropletを使って起動する
- サービスのバインドやapp用の環境変数を追加した場合は設定が適用されるが、buildpack用の環境変数を追加した場合はrestageを行って適用する必要がある

# 比較

|比較項目|push|restage|restart|
|:-:|:-:|:-:|:-:|
|droplet|コンパイルし直して起動|コンパイルし直して起動|コンパイル済みのものを起動|
|appのソースコードの更新|更新される|更新されない|更新されない|
|buildpackの更新|更新される|更新される|更新されない|
|サービスのバインド・app用の環境変数設定の適用|適用される|適用される|適用される|
|buildpack用の環境変数の適用|適用される|適用される|適用されない|

# 参考
- [Starting, Restarting, and Restaging Apps | Cloud Foundry Docs](https://docs.cloudfoundry.org/devguide/deploy-apps/start-restart-restage.html)
- [cloud - What is difference between Restage and Restart in PCF - Stack Overflow](https://stackoverflow.com/questions/50475750/what-is-difference-between-restage-and-restart-in-pcf)
- [cloudfoundry - Difference between cf push and cf restage - Stack Overflow](https://stackoverflow.com/questions/56784031/difference-between-cf-push-and-cf-restage)
tf.kerasのTextVectorizationとsentencepiece組み合わせ

#1.概要
[tensorflow2.2.0が利用可能](https://github.com/tensorflow/tensorflow/releases)を眺めている最中に[TextVectorization](https://www.tensorflow.org/api_docs/python/tf/keras/layers/experimental/preprocessing/TextVectorization)を発見。
[当該機能を紹介されている方のブログ](https://note.com/hroy/n/ncb1469281410)もあった。

>TextVectorizationは若干の制約はありますが、TokenizationからID変換までを一気にやってくれるという、ものぐさな人にピッタリの便利Layerになっています。

とのことで、手軽にモデル作成するなら[huggingface/transformers](https://github.com/huggingface/transformers)が良いと思っているけれど、この機能もとても便利そう。
TextVectorizationとsentencepieceを組み合わせれば、
・日本語の処理のためのtokenization
・単語⇔ID変換
・入力用長さ揃え
・tf-idfやone-hotに切り替えたりもなど
を後ろでやってもらい、いきなり層が作れるのでは？と思い試してみることに。
textCNNやったりも。今回はembedding+conv1Dと、TF-IDF densely-connected の２つを作成。※TextVectorizationとsentencepieceの組み合わせは上記のブログでも示唆されていた。

##TextVectorizationの引数概要

```python
tf.keras.layers.experimental.preprocessing.TextVectorization(
    max_tokens=None, 
    standardize=LOWER_AND_STRIP_PUNCTUATION,
    split=SPLIT_ON_WHITESPACE, 
    ngrams=None, 
    output_mode=INT,
    output_sequence_length=None, 
    pad_to_max_tokens=True, 
    **kwargs
)
```
「split=~~」に自分が切りたいように単語分割する関数をtf.stringを入出力としてかませれば実行してくれる。（デフォルトは英語なのでスペースで区切る=SPLIT_ON_WHITESPACE）
他にもngramも作ってくれたり,output_modeで考えそうな出し方（one-hot,tf-idfなど）も選択可能になっている。


#2.実行環境
* Google colaboratory
* [全体コード](https://colab.research.google.com/drive/1FICwBVmGolM0r3LO7RZ1bgsDE6uodBEE)


#3.工夫点
以下、[公式のcolabファイル](https://colab.research.google.com/drive/1RvCnR7h0_l4Ekn5vINWToI9TNJdpUZB3#scrollTo=E_PbRj4lvVed)をもとに、いくつか変更した部分を説明

##工夫点1：tensorflowのバージョン
普通にtensorflowをインストールすると、最新の2.3.~がインストールされてしまい、後述のSentencepieceTokenizerがエラーになってしまう。

    !pip install tensorflow==2.2.0


##工夫点2：sentencepieceの適用部分

```python
!pip install tf_sentencepiece
!pip install sentencepiece
import sentencepiece as spm
spm.SentencePieceTrainer.train('--model_prefix=m2 --input=abst.txt --vocab_size=2000 --normalization_rule_name=nfkc_cf')

```

でmodelファイルを作って、tensorflow_textでモデルを読み込む際に、sentencepieceではutf8ですべてエンコードされているので、普通にそのまま　model='モデル名' で読み込めず、gfile.GFile('モデル名','rb').read()と読み込む必要があった点。

```python
mod = gfile.GFile('m2.model', 'rb').read()
s2 = text.SentencepieceTokenizer(model=mod,out_type=tf.string)

def segment_by_spm(input_data):
    text = s2.tokenize(input_data)
    return text

```


#その他
* 最初のテキスト準備の時点でスペース区切りで分かち書きされたファイルを準備すれば上のような工夫はいらなくなるけれど、普通の文書をそのまま突っ込めるのは良いと思う。
* sentencepieceの他にmecabなどでも実行できるように加えたい。
* tensorflow_text にはいろんなtokenizationの関数があったので、これも使ってみたい。
RPA Express

##RPA
Robotic Process Automation（ ロボティック・プロセス・オートメーション）の略。
→単純作業を簡単に自動化
・コーディングが出来なくても、業務の自動化を行うことが出来るツール

##マクロ
コンピューターの操作を自動化するための機能
自動化の際に、記録されるプログラム自体

##VBA
Visual Basic for Applicationsの略で、Microsoftのアプリケーションの拡張機能
マクロのプログラムを記述するための言語

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506079/7d580f56-e5ba-e87d-b2e8-54eaa0d2fc7f.png)

#RPAでできること
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506079/6c9763ba-4361-09ab-6456-87b6a2aba304.png)

#RPAツール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506079/f3fb3d42-f62e-bbfe-f9df-66a5ab6c8ca8.png)

#RPA Express Starter
・商業的な制限なしに誰でも自由に利用可
　プラットフォーム料金、ライセンス料、料金は一切なく、無料
・日本語に対応
・プログラミング知識は不要
・オブジェクト認識（ウェブページを構成しているHTMLといった裏の構造を読みとること）
　画像認識の両方に対応

#機能
レコーダー機能
コード不要の自動化
デスクトップとウェブの自動化
組み込みOCR
ドラッグ&ドロップビルダー
アプリケーション操作
Excel操作
マウス、キーボード操作

>参考
[RPAとVBAを徹底比較！違いや特徴・どちらを使うべきかを網羅](https://rpatimes.jp/rpa/knowledge/147/)
[【2019年】Work Fusionの『RPA Express(エクスプレス）』とは？無料で使えるRPAツール](https://rpatimes.jp/rpa/knowledge/2564/)
[RPA Express使ってみた](https://www.cresco.co.jp/blog/entry/11565/)

###備考
AutoHotKey
 ショートカットキーを作れる
 マウスのスクロールイベントが有る（確かautoitにはない）
 画像認識できる

UiPath
 ![https___qiita-image-store.s3.amazonaws.com_0_154110_33613bf9-ead1-7b91-0e30-dffc3c798311.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506079/2e18bb58-9f9a-d76a-298d-09959147c44d.png)
Fortran Monthly Call: May 2020の議事録

2020年5月14日 02:00 PM (US Eastern Daylight Time)に，Fortranコミュニティのプロジェクトについて話し合うミーティングが行われました．
日本時間だと午前3時で参加が難しかったので参加はしませんでしたが，議事録が公開されていたので，許可をもらい，訳してみました．

出席者については敬称略．

（2020年5月19日追記）タグのfortran-langは，ミーティングを開催したFortran-lang community projectを指しています．

# 現状

- 2019年10月，OndrejがJ3のproposalの経過を追い，コミュニティからのフィードバックを得るためのGithubリポジトリを立てたことが始まり．
    - いくつかの提案がGitHub上でなされ，それらについて2020年2月のミーティングで議論された[^feb]．
- 2019年12月には，Fortran Standard Library (stdlib)のリポジトリが立てられ，fortran-langのGitHubに置かれた．
- 2020年1月，DominikがFortranパッケージマネージャ（fpm）のアイデアをstdlibリポジトリのissueで提案し，Ondrejが動き始めた[^fpmrepo]．Bradが参加し，彼がfpmを率いている．現状は，Fortranのみのプロジェクト[^pure]をビルド，テスト，実行できる最小のバージョンである．
- 2020年4月，[Webサイト](https://fortran-lang.org/)を作った．

[^feb]: J3 Meetings #221, February 24 - 28, 2020, Las Vegas, NV, USA. Documents[https://j3-fortran.org/doc/meeting/221] and Minutes[https://j3-fortran.org/doc/year/20/minutes221.txt].
[^fpmrepo]: https://github.com/fortran-lang/fpm
[^pure]: 原文ではa pure Fortran projectと書かれている．「純粋な」という訳はしっくりこない（pure subroutine/functionを想起させる）ので，Fortranのみのと訳している．

# Stdlib
## 現状
現在，SciPyと同様の科学計算・数値計算用ユーティリティに焦点を当てている（Jeremie，Ondrej）

## 何が足りないか
**よいドキュメント**[^whatmissing]

- 我々は当初，仕様に焦点を当てていた．しかし，使い勝手のよいドキュメントが不足しており，必要性が高い．
- Melissaは，これを改善するための提案を行った[^182]．
- Steveは，使い勝手のよいドキュメントとは，実装者が書くものではなく，実装者と会話でき，実装者に質問を投げかけられるユーザが書くべきだと提案した．
- Zaakは，FORD，MKdocsについて議論した．これらはAPIドキュメントに適しているが，ドキュメンテーション文字列（docstring）以外のテキストを追加することもできる．

我々にはユーザが必要である．


[^whatmissing]: 訳者注）これは議事録に書かれた意見であり，議論をまとめると，足りないのは「ドキュメントとユーザ」ということになる．
[^182]: https://github.com/fortran-lang/stdlib/issues/182

# fpm
## 次のステップ
Fortranのみのリモートリポジトリをビルドするためにgetする機能

## 長期的な展望
ローカルでビルドされたFortranのみのソースにない非Fortranの依存関係を解決するために，Conda/Mambaからバイナリ配布できるようにする．

- Spackに頼らないのですか？（Gary）
- Spackはビルドを手伝ってはくれず，パッケージのメンテナは，Pythonスクリプトを書く必要がある．ここ(https://github.com/fortran-lang/fpm/issues/79) を見てください．（Ondrej）
- fpmは，ユーザがビルドシステムの設定で悩まないよう，プロジェクトの構造を標準化することを目指している（Brad）


ここでは多くの議論が行われていたが，fpmとその周辺についてさらに多くの専門的な議論が必要である．これは難しい課題である．

# Website

## 最も不足している，あるいは不完全
- **学習ページ**
Fortranでプログラミングを始める人にとって，実践的な手順に従った，頼りにできる場所となる必要がある．
- Cray compilerのリストの修正 -> Cray (HPE)
- Fortran 90 Listへの投稿


# コンパイラ
## Flang
(Gary)

- LLVMのFortranフロントエンド．
- 現状は，パーサ[^flang]が動いているが，コードはまだコンパイルされない．
- F2003とF2008のほとんどをサポートしている．
- NVIDIA, ARM, AMDが最大の支援者．
- コミュニティ開発者の助けが必要．


[^flang]: 原文にはparser (and something more)とあるので，パーサより先の機能もあって動いているようだが，省略した．

## LFortran
(Ondrej)
LLVMベースの対話型Fortranコンパイラ．
### 次のステップ
- ユーザを獲得し，Fortran 95水準のFortranプロジェクトをコンパイルできるよう機能を実装する．
- コミュニティ開発者の助けが必要．


ACM Fortran Forumのコンパイラリストをチェックする．

# FortranCon 2020
- これまでのところ，よいabstractが投稿されてきているが，空きはまだある．(Arjen)
- Bradがfpmについてのabstractを投稿した．
    - junior presentationからselected presentationに移動させましょう
- いくつかのabstractを投稿予定
    - LFortran (Ondrej)
    - stdlib (Jeremieに依頼)
    - fortran-langプロジェクト
CentOS 7 で PostgreSQL の開発パッケージがインストールできなくなったら

CentOS 7 で PostgreSQL 開発元 Yum リポジトリを使って PostgreSQL 11、12 の開発パッケージ `postgresql*-devel` をインストールしようとすると、これまで発生していなかった依存関係のエラーが発生するようになっています。

```shell-session
# yum -y install postgresql12-devel
(省略)
Error: Package: postgresql12-devel-12.3-1PGDG.rhel7.x86_64 (pgdg12)
           Requires: llvm-toolset-7-clang >= 4.0.1
Error: Package: postgresql12-devel-12.3-1PGDG.rhel7.x86_64 (pgdg12)
           Requires: llvm5.0-devel >= 5.0
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest
```

これは、2020 年 5 月リリースの PostgreSQL 11.8、12.3 から開発パッケージが OS 標準の Yum リポジトリに含まれていない LLVM 関連のパッケージに依存するようになったためです。

この問題は EPEL、SCL の Yum リポジトリを追加すれば解消します。

```shell-session
# yum -y install epel-release centos-release-scl
(省略)
Installed:
  centos-release-scl.noarch 0:2-3.el7.centos     epel-release.noarch 0:7-11

Complete!
```

これで開発パッケージをインストールできるようになります。
プログラミングの学習で行き詰まったときの考えること

円滑に開発を行うために必要なことの1つにプログラミングの学習をスムーズに行うことがすごく大切なことだと思いました。どんなに時間があっても、どんなに学習環境が整っていてもエラーでつまづいたり、自分の思うような結果を導き出せないときに必要なことをわたしの独自の見解をまとめてみました。

```
① 何がわからないのかを明確にする
② どうしてそれがわからないのか理由(原因)をはっきりさせる
③ 着実でかつ必要な小さいハードルを探す
```

# 何がわからないのかを明確にする
エラーの場合はどうしてそのエラーになるかをはっきりする必要があります。エラー文を読んでそのエラー内容が何を示しているのか検索をかけて同じようなエラーで悩んでいる人はどうやってそれを解消したのかなどを調べてその時点でわかればその問題はそれで解決です^_^

ただ、もしわからなくて結果的に解決するために長引いてしまう場合は一度その負のスパイラルから抜けて**どうしてそれがわからないのか理由をはっきりさせる**ことが必要です。

# どうしてそれがわからないのか理由(原因)をはっきりさせる
どうしてそれがわからないのか、例えば初心者のときに```Gemfile```に記述する内容をコマンドだと勘違いをして一生懸命ターミナルに打ち込んでいたことがありました。つまりその問題のわからない理由は**知識不足**によるものです。

もう一つ例にあげるとエラー文を何度も検索にかけていました。複数件膨大な関連記事が表示されてどれが正しい情報なのかわからないときがあります。さらに詳細に検索をかける必要があったのですが何がエラーの原因なのかわからない...

どうしてわからないのか幾度と経験をすることでわかったことはエラー文に詳細なエラー情報が書いてあることでした。これはプログラミングを始めたばかりのことですが、「エラー ＝ 迷路突入」と勝手に解釈していたため丁寧な説明があるのにも関わらずその説明を見ていなかったことが原因でした。

# 着実でかつ必要な小さいハードルを探す
では次にどうしたらいいのかなぁ...と考えたときに自分の学習計画を再度立て直すことでした。例えばDjangoで個人アプリを作りたいときに思うように実装したい機能がエラーになってしまう。と思い例に倣い、わたしがどうしてわからないのか考えたところ、**「これまで学習した内容よりもっと詳細な情報が掲載されている書籍などで基礎学習した方がいい！」**という結論に達しました。

わたし自身、個人的にプログラミング学習の中でもったいないと思うことは継続をやめてしまうことと、モチベーション低下により、本来プログラミングに割ける時間を怠惰に過ごしてしまうことだと思いました。わたしの経験談でエラーを解消するためだけに色々と調べていた時間で一冊の書籍を通して学習できるほどの時間と同等の時間を浪費していたことに気づきました。

実際にそのときのエラーは基礎学習の不十分によるものだったのですぐに**自分は何がわからないのか**がわかっていた場合にストレスなく超えられたハードルなのかなぁ...とあとあと感じました。

そしてそれはもちもん闇雲ではなく、時間がかかっても方向性を見失わない内容で必要な努力になることが自分の頭で理解できてることが大切なことだと思いました(^_−)☆
ID番号がkeyだった場合のStructの書き方

ちょっとはまったので、メモ。

```
{
    "success": 1,
    "return": {
        "182": {
            "currency_pair": "btc_jpy",
            "action": "bid",
            "amount": 0.03,
            "price": 56000,
            "fee": 0,
            "your_action": "ask",
            "bonus": 1.6,
            "timestamp": 1402018713,
            "comment" : "demo"
        }
    }
}
```

上記のようなJSONデータをStructで取得したい。
しかしながら"182"の部分がID番号で固定では無いため、やり方がわからなかった。

```
type GetTradeAPIResponse struct {
	ApiResponse
	Return map[string]GetTradeResponse `json:"return"`
}

type ApiResponse struct {
	Success int    `json:"success"`
	Error   string `json:"error"`
}

type GetTradeResponse struct {
	CurrencyPair string  `json:"currency_pair"`
	Action       string  `json:"action"`
	Amount       float64 `json:"amount"`
	Price        float64 `json:"price"`
	Fee          float64 `json:"fee"`
	YourAction   string  `json:"your_action"`
	Bonus        float64 `json:"bonus"`
	Timestamp    int64     `json:"timestamp"`
	Comment      string  `json:"comment"`
}
```

上記のように定義することにより、取得ができました。

# 参考
[Mapping JSON returned by REST API containing dynamic keys to a struct in Golang
](https://stackoverflow.com/questions/35122105/mapping-json-returned-by-rest-api-containing-dynamic-keys-to-a-struct-in-golang)

以上です。
いいねやQiitaやTwitterのフォローいただけると励みになります！
他にも方法がありましたら、コメントお待ちしております。
宜しくお願いします〜
route 書き方の違い

#どこかでパラメータ付きURLを生成する

```
$url = route('users.edit', ['user' => $user->id]);
$url = route('users.edit', ['user' => $user]);
```
第二引数のuserがidでもmodelでも動く理由

##**結論**
route関数を司るDatabase/eloquent/Model.phpにある**$primarykeyで決定する**
$primarykeにidが代入されているため```['user' => $user]```と書いてもidが参照され、取ることができる
![スクリーンショット 2020-05-18 23.43.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536474/7085b334-4992-469b-1ba7-9aacb7c270b8.png)

#ここまでの過程
どこかでroute関数を定義する。

```indexController.php
public function index ()
    {
        route();
    }
        
```
このrouteを⌘+クリックすると
laravelのhelper関数が集約されてるところに飛ぶ
ここではフォーマットを整えるぐらい

```helpers.php
function route($name, $parameters = [], $absolute = true)
    {
        return app('url')->route($name, $parameters, $absolute);
    }
```
次にこのapp->のrouteが何かを辿る

ここでは```getByName```はよくて、```toRoute```に飛びます

```UrlGenerater.php
public function route($name, $parameters = [], $absolute = true)
    {
        if (! is_null($route = $this->routes->getByName($name))) {
            return $this->toRoute($route, $parameters, $absolute);
        }

        throw new InvalidArgumentException("Route [{$name}] not defined.");
    }
```


次に```routeUrl```はいいので、```formatParameters```に飛びます

```UrlGenerater.php
protected function toRoute($route, $parameters, $absolute)
    {
        return $this->routeUrl()->to(
            $route, $this->formatParameters($parameters), $absolute
        );
    }
```
肝心なのは```getRouteKey()```です。

```UrlGenerater.php
public function formatParameters($parameters)
    {
        $parameters = Arr::wrap($parameters);

        foreach ($parameters as $key => $parameter) {
            if ($parameter instanceof UrlRoutable) {
                $parameters[$key] = $parameter->getRouteKey();
            }
        }

        return $parameters;
    }
```
コメントアウトされている様にmodelのkeyでvalueをget
そして、UrlRoutabeleがinterfaceされてます。
この親はDatabase/eloquent/Model.phpになるのでそこで、結論が定義されてます。

```UrlRoutable.php

interface UrlRoutable
{
    /**
     * Get the value of the model's route key.
     *
     * @return mixed
     */
    public function getRouteKey();
```


##2番目の書き方の注意であり前提
①tableにidが設定されていること
②結論の$primarykeyでidが定義されていること
【小ネタ】Salesforce DevEditionのデータストレージの制限について

# Developer Editionのデータ容量
　DeveloperEditionのデータストレージの使用制限はいくつか知っていますか？
答えは5.0MBです。それでは、Dev組織には約2500レコードしか入れることが出来ないのでしょうか？
答えはNoです。

# Dev組織のデータストレージ使用率を約500%にしてみた
<img width="752" alt="pic1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394418/279522a3-850c-425f-5ea0-b7c6c03e104b.png">

組織のデータ容量制限を超えるデータを1トランザクションでインサートする場合、レコードインサートが成功します。そのため、使用制限ギリギリまでの2500レコード＋ガバナ制限の10000レコード＝12500レコードを保存しておくことが出来ます。

ちなみに、この状態でレコードインサートしようとすると

`storage limit exceeded`
のエラーが発生して、新規のレコード作成ができません。

# 結論
　何の役に立つのか分かりませんが、Dev組織で制限よりも多くのデータを使用して、動作検証してみたくなった際の参考にしてください。
(動作検証のために10万件くらいまで使用できる環境が欲しいです。1週間で削除されるとかでいいのでお願いします。)
[Flutter]一番シンプルなカウントダウンタイマーの作り方

# はじめに
quiver.asyncライブラリのCountDownTimerクラスを利用して、シンプルなカウントダウンタイマーを実装してみました。

# 完成図
時間が余ったので、カウントダウンに合わせて小さくなるピーターパン症候群のおじさんもつけました。
![画面収録 2020-05-19 0.13.57.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135663/4519b9ae-2862-3000-605c-d3b26aa582fb.gif)


# 参考サイト
- 公式ドキュメント
 - [quiver.async](https://api.flutter.dev/flutter/quiver.async/quiver.async-library.html)
 - [CountDownTimer](https://api.flutter.dev/flutter/quiver.async/CountdownTimer-class.html)
- stack overflow
 - [Flutter Countdown Timer](https://stackoverflow.com/questions/54610121/flutter-countdown-timer/54611581)

# 実装

```dart:main.dart
import 'package:flutter/material.dart';
import 'package:quiver/async.dart'; // ①quiver.asyncライブラリを利用

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Countdown',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // ②カウントを示すインスタンス変数
  int _start = 10;
  int _current = 10;

  // ③ カウントダウン処理を行う関数を定義
  void startTimer() {
    CountdownTimer countDownTimer = new CountdownTimer(
      new Duration(seconds: _start), //初期値
      new Duration(seconds: 1), // 減らす幅
    );

    var sub = countDownTimer.listen(null);
    sub.onData((duration) {
      setState(() {
        _current = _start - duration.elapsed.inSeconds; //毎秒減らしていく
      });
    });

    // ④終了時の処理
    sub.onDone(() {
      print("Done");
      sub.cancel();
      _current = 10;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            // ⑤現在のカウントを表示
            Text(
              "$_current秒",
              style: Theme.of(context).textTheme.display1,
            ),
            // ⑥カウントに合わせて小さくなるおじさんを表示
            Container(
              child: Image.network(
                'https://3.bp.blogspot.com/-QxAapI2H1Pk/VhSAsJpLPhI/AAAAAAAAzG0/80qjXfZlomk/s800/peterpan_syndrome.png',
                width: _current.toDouble() * 20,
                height: _current.toDouble() * 20,
              ),
            ),
            // ⑦カウントダウン関数を実行するボタン
            RaisedButton(
              onPressed: () {
                startTimer();
              },
              child: Text("start"),
            ),
          ],
        ),
      ),
    );
  }
}


```
PostmanのVisualizeを使う

PostmanのVisualizeを使う。
[Postman](https://www.getpostman.com/)

<!--more-->

PostmanでAPIにリクエストをしたり、APIのレスポンスをテストすることは大体できたので、今度はvisualizeの機能を試していきます。

過去の記事はこちら
- [PostmanでAPIリクエストを作る](https://connvoi.com/tech/2019/11/24/make-request-with-postman/)
- [Postmanを使ってAPIのテストをする](https://connvoi.com/tech/2019/11/25/test-postman/)


## Postmanのvisualizeとは

ざっと説明するとAPIのレスポンスにhtmlをくっつけて表示できる機能で、これがPostmanのアプリ単体うごく感じです。
YoutubeのAPIを例に使ってやっていきます。

[Visualize API responses](https://learning.postman.com/docs/postman/sending-api-requests/visualizer/#try-it-out)

内容はこの記事とほぼ一緒です。

## 前準備

YoutubeのAPIを使うために、Youtube DATAAPIのappidを取得します。
これは公式ページの通りで大丈夫。

[Youtube DATA APIの概要](https://developers.google.com/youtube/v3/getting-started?hl=ja)

## Youtube APIへのリクエストを作る

APIのリクエストを作る手順でYoutubeへのアクセスできるリクエストを作ります。
クエリはdeadby daylightの最新日時順でソートするリクエストを作りました。
YOUR_APP_IDの部分に取得したAPPIDを入れます。

作成されたリクエストでJsonで結果が取れればOKです。

<a data-flickr-embed="true" href="https://www.flickr.com/photos/kyagyao/49909215716/in/datetaken/" title="スクリーンショット 2020-05-18 23.51.34"><img src="https://live.staticflickr.com/65535/49909215716_70de5e38b0_z.jpg" width="640" height="505" alt="スクリーンショット 2020-05-18 23.51.34"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>
## Visualize用のテンプレートを作る

テストコードを書いた時と同様にtestタブに行って、テンプレートと取得結果のマッピングを書きます。
response.jsonで取得したデータを下層に辿るのはドットでつなげばオーケーなので以下のように書きました。

``` javascript
var template = `
    <table>
        <tr bgcolor="coffee">
            <th>Title</th>
            <th>Thumb</th>
        </tr>

        {{#each response.items}}
           <tr bgcolor="white">
                <td>{{snippet.title}}</td>
                <td><img src="{{snippet.thumbnails.default.url}}"></td>
            </tr>
        {{/each}}
    </table>
`;

// Set visualizer
pm.visualizer.set(template, {
    // Pass the response body parsed as JSON as `data`
    response: pm.response.json()
});
```

## Visualizeの確認

templateを書いた状態で取得結果のjsonの上にあるvisualizeのボタンをクリックします。
うまくいけば検索結果がテーブルで表示されていると思います。

<a data-flickr-embed="true" href="https://www.flickr.com/photos/kyagyao/49909215701/in/datetaken/" title="スクリーンショット 2020-05-18 23.52.04"><img src="https://live.staticflickr.com/65535/49909215701_00fc764df8_z.jpg"  alt="スクリーンショット 2020-05-18 23.52.04"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>


Postman公式のページにいくと、Bootstrapを読み込んで綺麗に表示させていたりするチュートリアルも合ったりするので、参考にするといいかも。

API開発した確認フェーズにこれを一回設定しておくと便利そうだなと思ったのと、まだ調べてないけど、それぞれのテストコード、テンプレートファイルを共有もできるっぽいので、
このPostmanのテスト全部通ったらOK、確認はVisualizeでやって！みたいな感じの仕事の回し方ができそう。

結構面倒そうな機能だったんだけど、かなり簡単にできたので、もうちょっと早く試してみればよかったな。
PostmanでAPIのテストをする

## PostmanでAPIのテストをする

APIのリクエストは作れるようになったので、今度はAPIのレスポンスからテストを書いていきます。

<!--more-->

## テストの作成

テストする際は作成したRequestのtestsというタブを開きます。テスト入力用のテキストエリアと、横にサンプルのスニペットが表示されるので、Status Code 200と、Response time is less than 200msをクリック。テストエディタの中にjsのテストコードが入るので、そのままSendボタンを押します。

<a data-flickr-embed="true" href="https://www.flickr.com/photos/kyagyao/49111060447/in/dateposted/" title="スクリーンショット 2019-11-24 1.28.16"><img src="https://live.staticflickr.com/65535/49111060447_0e08296bb2_k.jpg" alt="スクリーンショット 2019-11-24 1.28.16"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>

リクエストが実行されると、Test Resultsのタブにテストの結果が表示される。

## テストの書き方

だいたいここに書いてある通り  
[tests-example](https://learning.getpostman.com/docs/postman/scripts/test-examples/)

``` js
    //ある要素がa,bというkeyを持っているか
    pm.test("Checking if object contains any ONE of the keys", function () {
        pm.expect({a: 1, b: 2}).to.have.any.keys('a', 'b');
    });
```

```js
    //値が100かどうか
    pm.test("Check response value", function () {
        var jsonData = pm.response.json();
        pm.expect(jsonData.value).to.eql(100);
    });
```

## テストの例

試しにレスポンスのcitynameがTokyoにマッチするか？というテストを書いてみる。

```js
pm.test("CitynameがTokyoかどうかテストする", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData['city']['name']).to.match(/Tokyo/);
    console.log(jsonData['city']['name']);
});
```

正規表現を使いたいときはmatchを使います。また、postmanアプリ左下のターミナルっぽいのを押すとconsole.logが確認できる。

テスト自体もJSでかけるし、基本的なものは画面右からクリックするだけで追加できるし、そもそもテスト環境を別に用意する必要がないので、楽ちん。
Postmanを使ってAPIへのリクエストを試す

Postmanを使ってAPIへのリクエストを試す
[Postman](https://www.getpostman.com/)

## Postmanとは

API開発における、設計、テスト、ドキュメントの作成などを行ってくれる便利ツール
いわゆるAPIマネージメントツールというやつ。

## インストール

Mac, Windowsのappとコマンドラインから動かすSDKもある。今回はMac版の奴を使う

- [getpostman.com/installation-and-updates](https://learning.getpostman.com/docs/postman/launching-postman/installation-and-updates/)

## APIのリクエストを作成する

全体の流れはこんな感じで、簡単。

1. 左側にある New CollectionでCollectionを作成。
2. CollectionのAdd requestをクリック
3. 作成したRequestのタブが出てくるので、APIのurl、パラメーターを入力
4. Sendボタンを押して、実際にリクエストをする。

<a data-flickr-embed="true" href="https://www.flickr.com/photos/kyagyao/49105240932/in/dateposted/" title="スクリーンショット 2019-11-23 0.06.18"><img src="https://live.staticflickr.com/65535/49105240932_964911e4c1_k.jpg" alt="スクリーンショット 2019-11-23 0.06.18"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>

画像は[openweatherapi](https://openweathermap.org/)を叩いてる結果です。同じことを試したい場合はopenweatherapiでアカウント登録後APPIDを取得して、postmanのYOURAPPIDの所に入力してください。  
GETパラメータの入力はurlを直接でもURLの下にあるエディタでも可能で、POSTメソッドも選択可能。便利。

APIを開発している時にちょっとレスポンスを確認したい時とかに便利。Postman自体はリクエストだけでなく、テストとその自動化もできるのでその辺もまとめていく。
Mac PHP 出力を改行する

# 目的

- 出力内容に改行をつける方法をまとめる

# 実施環境

- 下記のサービスにてブラウザ上で実行した。
    - [paiza.io](https://paiza.io/projects/nHmsVLuX9kEybNsetTz7Tg) 

# 例

- 下記を実行する。(ちなみにMac OSで`\`を入力する方法は「option」 + 「¥」を同時に押下する。)

    ```php
    //出力文字の最後に改行を入れたい場合(一行での出力はあまり意味がないがforeachなどの繰り返し時処理を確認したい時に役立つ)
    echo '出力したい文字'."\n";
    //下記の様に出力される(末尾に改行が入るため通常の出力では変化なし)
    // 出力したい文字

    //出力文字の途中で改行を入れたい場合
    echo '出力したい文字A'."\n".'出力したい文字B';
    //下記の様に出力される
    // 出力したい文字A
    // 出力したい文字B
    ```
ブランチ2種類

## 統合ブランチ
リリース版が何時でも作成可能なようしておくためのブランチ
トピックブランチの分岐元としても使用し、安定した状態を保っておくことが重要
## トピックブランチ
機能追加やバグ修正といったある課題に関する作業を行うために作成するブランチ
複数の課題に関する作業を同時に行う時は、その数だけトピックブランチが作成される
有効期間が短いサービス アカウント認証情報の作成しAPIを実行してみる

#はじめに
[以前の記事](https://qiita.com/atsumjp/items/9e623edab1f7ab08fa6e)の続きです。

Service Accountの権限でAPIを実行する際、テンポラリのアクセストークンを取得してそのトークンで認証認可を行いますが、curlコマンドで期限を設定してトークン発行してみます。

マニュアルとしては以下にになります。
https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials?hl=ja#sa-credentials-delegated-chain

#やってみる
[以前の記事](https://qiita.com/atsumjp/items/9e623edab1f7ab08fa6e)通りに環境を構築する。ただし赤枠のIAM RoleはStorage Adminに変更する。確認がシンプルになるので。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78184/2ce99136-4586-a0c2-6583-8d845702eb40.png)

アクセストークンを作成する。lifetimeとして300秒を指定する。権限自体は、Google Accountの権限を「-H "Authorization: Bearer」で指定する。expireTimeが設定されたアクセストークンが返される。

```
$ curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $(gcloud config config-helper --format=json | jq -M -r '.credential.access_token')" --data '{"delegates":[],"scope":["https://www.googleapis.com/auth/cloud-platform"],"lifetime":"300s"}' https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/impersonate-sa@PROJECTID.iam.gserviceaccount.com:generateAccessToken

{
  "accessToken": "ya29.c.KoACywdSv_9HHqVsRelOtuhIOhDKDXdrtGth8GC1JRBsVtRdantYmT6dHs0QgQqOYHYj_mjeF3OKAE9yR5eBXCJkAXhFvpceMAyJVt31X-k2s8wfLdJ2elsChV6FdRDlrKuBcf47_CODus2UPAwvUzVoCCUugoo_6NqX7MML6FsCFIXW_qMN0jqQYQllHjG0gqzsuTrgeRBuA1UL4c1hRDR759tiSXExWWp5V9CU6qsXFPYsv7RGkbC_pINwaOpLF7IEzg0ow9H38lIOsBYJyKCMuB-GIuu-U9YsIfE6KzEn0tZxlTx3b_lTc3aFpJBhPz0By33E61V-************",
  "expireTime": "2020-05-18T03:28:36Z"
}
```

作成したアクセストークンを指定して、GCSのバケット情報を確認する。

```
$ curl -H "Authorization: Bearer ya29.c.********************************" https://www.googleapis.com/storage/v1/b/sample_aaaaabbbbbcccccc/o
{
  "kind": "storage#objects",
  "items": [
    {
      "kind": "storage#object",
      "id": "sample_aaaaabbbbbcccccc/README-cloudshell.txt/1582881792887319",
```

300秒後、再度確認するとアクセストークンの期限が切れていて失敗する。

```
$ curl -H "Authorization: Bearer ya29.c.********************************" https://www.googleapis.com/storage/v1/b/sample_aaaaabbbbbcccccc/o
{
  "error": {
    "code": 401,
    "message": "Invalid Credentials",
```
PowerShell 基礎知識

###バッチファイルの実行
```powershell:hoge.ps1
Start-Process -FilePath C:\hoge.bat 
```
※実行したいファイルのパスが環境変数に設定されていれば、ファイル名のみで実行できる

以下オプション。
-FilePath　""で実行ファイルのパス指定ができる
-ArgumentList　実行ファイルへ渡す引数を指定できる
-Wait　実行中の処理が完了するまでPowerShellを待機させる
-NoNewWindow　処理実行の際に別ウィンドウを立ち上げない
【Objective-C】UIAlertControllerでダイアログを表示する方法

#UIAlertControllerとは？
UIAlertControllerとは下記画像のようなダイアログを表示するためのクラスです。
今回はこのクラスを使い、Objective-Cでダイアログの実装を行う方法を紹介していきます。
<img width="331" alt="スクリーンショット 2020-05-18 23.53.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/357475/dc14e288-a9fc-6329-ba32-ce10353071eb.png">


#サンプルコード

```objective_c
//下記のように記述する事で、UIAlertControllerを初期化します。
//alertControllerWithTitleに指定した文字列が太文字で表示されます。
//messageに指定した文字列が小見出し的な感じで、小文字で表示されます。
 UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"UIAlertControllerStyle.Alert" message:@"iOS8" preferredStyle:UIAlertControllerStyleAlert];

//下記のコードでボタンを追加します。また{}内に記述された処理がボタン押下時の処理なります。
 [alertController addAction:[UIAlertAction actionWithTitle:@"はい" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
  //ボタンがタップされた際の処理
  }]];

[alertController addAction:[UIAlertAction actionWithTitle:@"いいえ" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
  //ボタンがタップされた際の処理
  }]];

//下記のコードでダイアログを表示します。
[self presentViewController:alertController animated:YES completion:nil];
```
Laravel Telescopeのタイムゾーンを強制的に日本時間にする

LaravelのTelescopeにおいて、タイムゾーンを指定してるにもかかわらず日本時間表示ができなかったので、強制的に変えてみました!


localTime()を下記のように修正

```vendor/laravel/telescope/resources/js/base.js
        localTime(time) {
            return moment.tz(time,'Asia/Tokyo')
                .format('YYYY-MM-DD HH:mm:ss');
        },

```

```
   cd /LARAVEL_PATH/vendor/telescope
   npm run prod 
   cd /LARAVEL_PATH
   php artisan telescope:publish --force
```

cross-envをインストールする必要あり
ない場合は

```
npm install cross-env
```

以上です(^^)
ホームポジションから動かないためのコマンド操作

#はじめに
コマンドを打つ時、今までは矢印キーをほぼ100%使ってきました。
矢印キーを使わずにホームポジションを守りつつコマンドを進めていくためのコマンドをまとめてみました。

#便利コマンド操作まとめ
###●＜カーソルの移動＞
```ctrl + b```：1文字戻る
```ctrl + f```：1文字進む

※矢印キーは極力使わない
→ホームポジションを保つため

###●＜行頭へ移動＞
```ctrl + a```
###●＜文末へ　移動＞
```ctrl + a```
###●＜単語ごとの移動＞
```esc + b```：（カーソルの乗った）単語の先頭
```esc + f```：（カーソルの乗った）単語の最後

###●＜単語ごとの削除＞
```ctrl + w```:（カーソルの乗った）単語の削除

###●＜コマンドのカットとヤンク（ペースト）＞
```ctrl + k```：カーソルの位置から文末までを削除
```ctrl + u```：カーソルの位置から行頭までを削除
```ctrl + y```：最後に削除した内容をペースト

#トラブル対処法

###●＜画面をスッキリさせる＞
```ctrl + l```または```$ clear```で不要な情報を消して画面を一度きれいにしてくれる

#補完機能
###●＜bashの補完機能＞

・```Tabキー```：ecの時点でのTabキーでechoを補完してくれる
→コマンドを全て打つ手間を省くことが出来る

#コマンド履歴
###●＜履歴の操作＞
```ctrl + p```または```↑```：1つ前のコマンド
（pはprevious）

```ctrl + n```または```⇩```：1つ後のコマンド
（nはnext）

###●＜打ったコマンドの検索＞
```ctrl + r```：コマンド
railsアプリでホームのビューを指定する[root]

#rootについて
railsのアプリでメイン画面を指定したい時があるかと思います。
そんな時にroutes.rbにrootを指定するだけで簡単に指定できます。

```config/routes.rb
root to: "コントローラー名#アクション名"
```
これでメイン画面を指定できます。

例を書いてみます。
posts_controllerのindexアクションのビューをメイン画面に指定したいときは、

```config/routes.rb
root to: "posts#index"
```
と記載します。

この場合、posts_controllerにindexアクションを書かなくても、app/views/posts/index.html.erbさえあればビューとして表示することが可能です。

最後までご覧いただきありがとうございます。