OmniAICreator/Qiita-1.07M huggingface dataset:
超!A&G+をFlashではなくHTML5で見られるようにする

みなさまこんにちは。
みなさまは数多くの声優さんが出演される"超!A&G"を見られているでしょうか？

https://www.agqr.jp

こちらが超!A&Gのトップページになります。

http://www.uniqueradio.jp/agplayerf/player3.php

そして、視聴ページはこちらになります。


視聴ページがSSL認証してないじゃん！

じゃなくて。この視聴ページ、まだFlashを採用しています。
なのでmacOSのSafariじゃ見られないし、ChromeでもわざわざFlashを有効にして見なければなりません。
<img width="722" alt="スクリーンショット 2019-09-17 17.42.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227415/19b0d1a2-1214-f923-0f64-2a0d26dfabcf.png">


そんなFlashも2020年末にAdobeが直々サポートを切ると言っています。

https://ja.wikipedia.org/wiki/Adobe_Flash

では、どうすればいいでしょうか？
そんな中、超!A&Gを配信している文化放送さんがこんなアプリを出しています。

https://play.google.com/store/apps/details?id=jp.mitene.ag

これ、中にただのWebViewが入っているだけです。
![Screenshot_20190917_174730_jp.mitene.ag.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227415/991cbe99-5e08-579f-cb77-90785e706ebb.jpeg)

とっても分かりやすいですね。
では、せっかくなのでAndroid Studioでapkの中身を覗いてみましょう。
![スクリーンショット 2019-09-17 17.51.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227415/6c8031ac-0d0f-1433-8137-c7761dd3a1c2.png)

表示されているページを探せばいいだけです。
編集→検索→パス内検索（Cmd+Shift+F）してあげましょう。

<img width="744" alt="スクリーンショット 2019-09-17 17.54.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227415/784b768a-b074-55ba-85a2-52e2a8e75964.png">

すると、こんなウィンドウが出るはずです。
<img width="744" alt="スクリーンショット 2019-09-17 17.55.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227415/cedf4be4-7f7b-554f-e50b-5aa171b92c6e.png">

それっぽいものを検索するために"https"と打ち込みました。
どうやら

    https://www.uniqueradio.jp/form/form4-sp.php

というURLで表示しているみたいですね。
早速Safariで表示させてみましょう！

あれれー？おかしいね？リダイレクトされちゃった。

![スクリーンショット 2019-09-17 18.01.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227415/3e7d4490-356c-854c-9b7e-0733743687e9.png)

じゃあ、スマートフォンではどうかな？
![Screenshot_20190917_180343_com.android.chrome.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227415/24dc48dc-9721-87c9-294f-b96e7642afdf.jpeg)

ちゃんと表示されました！
でも、パソコンで見られないと意味がないよね？

お気付きの方もいらっしゃると思います。
そうです、ユーザーエージェントを変えればいいのです！
<img width="1370" alt="スクリーンショット 2019-09-17 18.06.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227415/f50e8a41-d21a-0e02-3bd2-70d1e0f61419.png">
これで表示できるのです！

というわけでみんなもFlashではなく、HTML5を使っていこうね！！以上！！
Tensorflow 2.0.0rc0 + Tensorflow Probability 0.8.0rc0 -> Glow

# 前の話
[Tensorflow 2.0.0rc0 + Tensorflow Probability 0.8.0rc0 -> RealNVP(1)](https://qiita.com/MeguruMokke/items/79013aac9d1fd51d37da)
[Tensorflow 2.0.0rc0 + Tensorflow Probability 0.8.0rc0 -> RealNVP(2)](https://qiita.com/MeguruMokke/items/6d3beddce93af6cd7f66)


# 今回する話
**Glow x MNIST**

RealNVP を Glow にしてみます。

**tl;dr**
[Glow x MNIST notebook](https://github.com/MokkeMeguru/glow-realnvp-tutorial/blob/master/tips/glow_mnist.ipynb)
[repository](https://github.com/MokkeMeguru/glow-realnvp-tutorial)

# Invertible 1x1 conv
理論的な話は [Glow: Better Reversible Generative Modelsメモ](https://qiita.com/messefor/items/349c623ffac8bf36127d) を見て下さい。

RealNVP では Coupling Layer で Coupling の組み合わせの偏りを減らすために、Channel 軸方向に見て要素を反転していました。    
ここをGlowでは Invertible 1x1 conv という学習可能な Bijector に代替しました。やっていることは簡単に言うと入力 $x$ Tensor $[h, w, c]$ に対して、行列 $W$ $[c, c]$ をかけ合わせます。

$f(x)$ の式を簡単に示します。

```math
\begin{eqnarray*}
y &=& f(x) \\
  &=& Wx
\end{eqnarray*}
```

逆関数 $f^{-1}(x)$ は次のようになります。

```math
\begin{eqnarray*}
x &=& f^{-1}(x) \\
  &=& W^{-1} x
\end{eqnarray*}
```

よって $W$ の条件は、逆行列が存在することになります。このため Glow では W に回転行列を用いています。    
また $W$ の逆行列の計算は、直接的に行うとかなりコストがかかります。これを効率的に行うために、Glowでは LU 分解を用いています。私の実装でもこの例にもれずLU分解を使って逆行列を計算しています。

# Actnorm
理論的な話は [Glow: Better Reversible Generative Modelsメモ](https://qiita.com/messefor/items/349c623ffac8bf36127d) を見て下さい。

これは初期バッチに対して、Channel軸方向に正則化を行います。そしてその正則化のパラメータを初期重みとして学習を行います。

# 実装 & 訓練
[Tensorflow 2.0.0rc0 + Tensorflow Probability 0.8.0rc0 -> RealNVP(2)](https://qiita.com/MeguruMokke/items/6d3beddce93af6cd7f66)

と対して変わらないので割愛。[notebook](https://github.com/MokkeMeguru/glow-realnvp-tutorial/blob/master/tips/glow_mnist.ipynb) を見て下さい。

# 推論
右上は無視して大丈夫です。

上側は元のテストデータ(入力)
下側は入って正規分布になって戻ってきたデータ　$f^{−1}(f(x))$
右下は2つのデータを正規分布上で混ぜたもの、となっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147520/2846f19a-9e56-915d-6869-7d4dbcdbbe11.png)
サクラエディタのGrepでファイル・フォルダの除外

サクラエディタのGrepでファイルやフォルダを除外したいときのやり方。

Grep条件入力画面で「ファイル」に

```
*.* !除外したいファイルパターン #除外したいフォルダパターン
```

例. `.svn-base`ファイルを除外、`temp`フォルダを除外

```
*.* !.svn-base #temp
```
自分用メモ：scikit-learn、matplotlibで表す線形回帰

ライブラリインポート

```python
from sklearn.linear_model import LinearRegression
import numpy as np
import matplotlib.pyplot as plt
```
：グラフ用データ作成
X、yをランダムで２０個づつ生成

```python
X = np.random.rand(20)
y = np.random.rand(20)
```
Xを昇順、sklearnに渡しやすい形にリシェイプ

```python
X = np.sort(X).reshape(20,1)
X
```
中身は、こんなん。

```python
>>array([[0.00460232],
       [0.05499239],
       [0.07249879],
       [0.10357735],
       [0.12304941],
       [0.12399111],
       [0.21219358],
       [0.23241532],
       [0.2975664 ],
       [0.3241855 ],
       [0.33018194],
       [0.47777823],
       [0.51792399],
       [0.52408334],
       [0.69196947],
       [0.7926415 ],
       [0.79900541],
       [0.87883547],
       [0.9491404 ],
       [0.98766611]])
```
yも昇順

```python
y = np.sort(y)
y
>>array([0.0042209 , 0.13057395, 0.16788022, 0.17403799, 0.25919865,
       0.3030241 , 0.35839353, 0.39294163, 0.44227869, 0.46863275,
       0.54436167, 0.55472105, 0.57756643, 0.60124576, 0.66758224,
       0.69719244, 0.73952565, 0.81040396, 0.86517258, 0.95263727])
```
グラフ化

```python
plt.scatter(X,y)
```
![ダウンロード (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498754/6f5e1c19-3944-0e8f-e266-d4121ae0d292.png)

LinearRegression()でfit、表示。

```python
model = LinearRegression()
model.fit(X,y)
plt.plot(X, model.predict(X))
plt.scatter(X,y)
```
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498754/36f389d4-35ff-8f31-6798-2343864f4d68.png)

こんな感じで表示できる。
Project Euler 018, 067を解いてみる。「最大経路の和」

# Project Euler 018
[018](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2018)
>以下の三角形の頂点から下の行の隣接する数字を通って下まで移動するとき, その数値の和の最大値は23になる.
<pre>
   3
  7 4
 2 4 6
8 5 9 3
</pre>
この例では 3 + 7 + 4 + 9 = 23.
以下の三角形を頂点から下まで移動するとき, その最大の和を求めよ.
<pre>
              75
             95 64
            17 47 82
           18 35 87 10
          20 04 82 47 65
         19 01 23 75 03 34
        88 02 77 73 07 63 67
       99 65 04 28 06 16 70 92
      41 41 26 56 83 40 80 70 33
     41 48 72 33 47 32 37 16 94 29
    53 71 44 65 25 43 91 52 97 51 14
   70 11 33 28 77 73 17 78 39 68 17 57
  91 71 52 38 17 14 91 43 58 50 27 29 48
 63 66 04 68 89 53 67 30 73 16 69 87 40 31
04 62 98 27 23 09 70 98 73 93 38 53 60 04 23
</pre>
Problem 67 は同じ問題だが100行ある


->[次の問題](https://qiita.com/radiol/items/bdfa88f68bf946fb8f5a)
018と067は問題のサイズが異なるだけでアルゴリズムは同一なので一緒に解きます。
関数は018でも067でも解けるようにし、018の数列もテキストファイルから読み込むようにしました。

## 考え方
一番下とその上の段をまず考えてみます。
左端は
<pre>
 63
04 62
</pre>
となっていますが、合計が大きなルートを考えるのであれば必然的に`62`を選ぶことになります。
必ず62が選ばれるということは上段の`63`は実質`63+62=125`と考えることができます。
その他の数字も同様に、下段の数字の大きい方を選び上段に加算していくと
<pre>
125 164 102 95 112 123 165 128 166 109 122 147 100 54
</pre>
となります。ここからまた2個並んだ数字の大きい方を選んで一つ上の列に加算を繰り返していくことで、最上段に到達したときに最大の和を求めることができます。
処理としては、
上からn段目(n個の数値)で、端からi番目とi+1番目を比較し大きい方を選択する
→これをn-1回行う
→n-1個の数列ができる(n-1段目と同じ)
→n-1段目の数列にそれぞれ加算
これを繰り返していきます。

## コード
```Python:euler018.py
import numpy as np


def main018():
    file = 'p018_triangle.txt'
    print(solve_triangle_problem(file))


def main067():
    file = 'p067_triangle.txt'
    print(solve_triangle_problem(file))


def solve_triangle_problem(file: str):
    """load_triangleでロードした三角形から最大となる和を返す
    1つ下の段の2つから大きい方を上段に加算、
    これを繰り返すことで最大の和を返す
    Args:
        file: 問題の三角形を記載したtxt file
    Returns:
        int: 最大となる和
    """
    triangle_arr_list = load_triangle(file)  # 数列をtxt fileからload
    best_sum_list = [0] * triangle_arr_list[0].size  # 最大値を入れる配列を初期化
    for arr in triangle_arr_list:
        arr += best_sum_list  # 上段の数列に下段の数列の中から大きい方を加算
        # 加算した配列(n個)から大きい方を選んだ配列(n-1個)をbest_sum_arrとする
        best_sum_list = [arr[i] if arr[i] > arr[i + 1] else arr[i + 1] for i in range(len(arr) - 1)]
    return triangle_arr_list[-1][0]  # 最上段の数値を返す


def load_triangle(filepath: str) -> list:
    """txt fileから問題の三角形をロードする関数
    Args:
        filepath: file path
    Returns:
        list: int型の2次元配列、各段を格納
    """
    triangle_list = []
    with open(filepath) as file:
        for txt in file.readlines():
            txt = txt.strip()
            txt = txt.split(' ')
            txt = np.array([int(t) for t in txt], dtype=int)
            triangle_list.insert(0, txt)

    return triangle_list


if __name__ == '__main__':
    main018()
    main067()
```
Mac book proにて実行
`結果
1074
main018処理時間: 0.0005071163177490234 sec.
7273
main067処理時間: 0.0067751407623291016 sec.
`
Railsでpermitの引数に入れる値を条件によって変える

permitに渡す引数の値を条件によって変えたい、お作法的に正しいかは分からないが、そんな場面が出てきたので、paramsのメソッドを複数作ったり、複数用意したpermitをメソッド内で分岐する以外のやり方がないか考えたメモ。

permitに渡す用に配列を用意して、それをいじくるのが無難かなというところに落ち着いた。
イメージとしては以下のような感じで、共通のパラメータは最初から入れておいて、ifで必要な分を追加する。(パラメータは適当)

```ruby
def user_params
  attributes = [:name, :password]
  attributes.push(:role, :parent_user) if current_admin_user?
  params.require(:user).permit(attributes)
end
```

---

permitのソースを読むと、
>     def permit(*filters)
      params = self.class.new
      filters.flatten.each do |filter|
    (省略)

引数(filters)は可変長引数(引数を配列にして受け取る）になっている。
その上で、flattenを使ってからeachを使ってそれぞれの値をチェックしているため、配列にして渡したとしても結果は同じになる



ソース引用元：https://github.com/rails/rails/blob/66cabeda2c46c582d19738e1318be8d59584cc5b/actionpack/lib/action_controller/metal/strong_parameters.rb#L543

---

2019/12/13追記
配列で受け取るパラメータを追加しようとして少し詰まったため追記

ソースを読めば分かる事だったのだが、配列で受け取るパラメータの場合はハッシュで持っていないといけなかった

```
attributes = [:name, :password, { email: [] }]
```
stagingにあげるまでのコマンド

下記の内容一括実行コマンド

```
git checkout master && git fetch && git branch -D staging && git checkout -b staging origin/staging && git branch
```

### マスターブランチに行く

```
git checkout master
```

###リモートの差分を取り組む
```
git fetch
```

###手元のステージングブランチを削除
```
git branch -D staging
```

###最新のステージングブランチを取り入れる
```
git checkout -b staging origin/staging
```

###ブランチ名を確認
```
git branch
```

###マージする
```
git merge <ブランチ名>
```

###マージの画面に移り変わる
```
:wq
```

###プッシュする
```
git push origin staging
```
iOSのJavaScriptでサウンド(WebAudio)の再生開始が遅い

（Androidでは試してませんが、）iOSでAudio再生すると再生開始までタイムラグがあるようです。

測定してみました。

## ソースコード

Vue.jsで作ったのでこんな感じです。

測定は読み込みではなくてあくまで.play()部分です。

```vuejs
<template>
  <div>
    <button @click="beep">Beep</button>
  </div>
</template>

<script>
〜〜
methods: {
    beep: function() {
      const beep = new Audio('/sounds/Ping.wav');
      beep.addEventListener('play', (s) => {
        const tm = new Date();
        console.log(s.type, tm - start);
      });
      beep.addEventListener('ended', (s) => {
        const tm = new Date();
        console.log(s.type, tm - start);
      });
      const start = new Date();
      beep.play();
    }
〜〜
<script>
```

## 測定結果

Macでは再生開始までは0 msecや1 msecでほぼタイムラグがありませんが、iPhone8だと18〜20msecほどになりました。

なんとかならないものか...
個人的に超絶為になったので新人エンジニアに勧めたい記事まとめ

##はじめに
コードを綺麗に描く方法やプログラミングの勉強方法や考え方など、
個人的にとても為になって感謝している記事をまとめてみました。

##コード関連
[良いコードを書く技術（まとめ）]
(https://qiita.com/NoriakiOshita/items/e60ab5bb01b90d927ae5)

[Naming -名前付け-]
(https://qiita.com/Koki_jp/items/f3d3e824f98d182d4100)

[ソースコードを汚くするには？]
(https://blog.y-yuki.net/entry/2016/09/03/210156)

[ダメエンジニアの8つの特徴]
(https://blog.toshimaru.net/8/)

##勉強方法関連
[新しく言語を学ぶときに心がけていること]
(https://qiita.com/hiraike32/items/40ef06f85f6a63828985)

[深夜だから個人的なプログラミング学習方法を書くよ！]
(https://qiita.com/tao_s/items/b6fb2303e36f5909cc62)

[【まつもとゆきひろ氏　特別講演】20代エンジニアのためのプログラマー勉強法のまとめ 2019/3/30]
(https://qiita.com/motoki4917/items/40386dd7fbd70987cc1d)

[知識が無いからこそコードレビューで指摘をしよう]
(https://qiita.com/teshima/items/4eb1c7c09863e71d5ed0)

##考え方関連
[レガシープロジェクトを引き継いだ時、最初にするべき７つのこと]
(https://qiita.com/tonluqclml/items/a7ed2f94225ef8a37b8b)

[ハッピーな開発🎉をするための、プロジェクトにおける要件定義の役割]
(https://qiita.com/tatane616/items/736616be222befa4759f)

[[初心者]オブジェクト指向でなぜつくるのか]
(https://qiita.com/IZUMIRU/items/959b43dc9eb4f5cdc202)

[ビルドとデプロイとリリースの違いについて]
(https://qiita.com/shimajiri/items/e3c1f4a70b5b4c8b25fd)

##AWS
[(下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで]
(https://qiita.com/naoki_mochizuki/items/f795fe3e661a3349a7ce)

##Git
[君には1時間でGitについて知ってもらう(with VSCode)]
(https://qiita.com/jesus_isao/items/63557eba36819faa4ad9)

##技術書関連
[新人時代に読めば良かったと後悔するほど感謝した技術書4冊]
(https://qiita.com/kojimadev/items/0bf53b439f0cb4d1f7e3)

[成り上がりたくて必死に読んだ感謝の技術書6冊]
(https://qiita.com/kurkuru/items/97a90e3c267bd127af9b)

##ポエム関連
[不思議の国のSE用語]
(https://qiita.com/t_nakayama0714/items/478a8ed3a9ae143ad854)

[見たいエンジニアの職務経歴書の書き方]
(https://qiita.com/newta/items/77eb14b1d67bc7ef1980)
初心者６ヶ月目　git 修正系

### プッシュ後に先輩に修正しろと言われた場合
1.その修正が必要なブランチにいることを確認する
　　⇨いない場合はgit checkout <ブランチ名>でそのブランチに移動しましょう
2.指摘を受けたところを修正する
3.上記の修正に対応した過去のコミットを見つける
４.addする
５.コミットする
6.リベースする
7.ブランチ名を確認する
8.プッシュする

### 3.上記の修正に対応した過去のコミットを見つける
```
git log
```

### 5.コミットする
```
git commit --fixup <コミット番号>
```

### 6.リベースする
```
git rebase -i HEAD~<番号> --autosquash
```
※<番号を入れすぎると関係ないコミットも自分のコミット履歴として記録されちゃうため注意する>

### 7.ブランチ名を確認する
```
git branch
```

### 8.プッシュする
```
git push --force-with-lease origin <ブランチ名>
```

※自分メモです。
GNU Make入門 1/2

# はじめに
新卒 SE 見習い(投稿当時)のぷるぷえです。
全く違う仕事にアサインされたので、忘れないうちに文字に起こそうといったところです。

敷居を低くしようとした結果、抽象的な表現も散見します。予めご了承ください。
このエントリが私と同じ初心者 C 系プログラマーさんのエントリーになれば嬉しい限りです。

# 環境
Ubuntu Server 18.04.2 LTS
GNU Make 4.1

## 全体の流れ
以下の章立てで進めていきます。
尚、2つのエントリに分ける予定です。(いつか投稿します)
本エントリでは3章まで扱います。

1. make とは
2. 超絶簡単に makefile
3. 結構簡単に makefile　ここまで
4. C ファイルのコンパイル
5. 4 で作成した makefile の改良

# make とは
作業を自動化するツールのことです。
コマンド（echo とかgccとか）を自動化するプログラムを組んだ makefile を作成すると、いろんな操作がコマンド一つでポーンってできちゃいます。

## うれしいこと
- 単純作業の自動化
- 膨大なソースファイルを一気に実行
- 変更したファイルだけ差分コンパイル
- テストで必要

などなど。

# 超絶簡単に makefile
コマンドライン上に文字列を表示する「echo」コマンドを自動化します。
超絶簡単です。

## 1. makefile を作成
お使いのエディタで「makefile」という名前のファイルを作成してください。[^1]
Atom なら、Ctrl + N → Ctrl + Shift + L で makefile を選択します。

## 2. プログラムを書く
```makefile:makefile
all:
  echo Hello world!
```

## 3.実行
コンソールで「make」コマンドを打ちます。

```shell:makefile
$ make
echo Hello World!
Hello World!
```
表示されました。

# 結構簡単に makefile
ディレクトリのお掃除を自動化してみます。
こんなテキストファイルがあるとしましょう。

![qiita_make3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242292/fd68a8cd-e731-0e6f-6971-df30fb62877d.png)

フォルダ内には、rm.mk という makefile と C ファイル、そしてテキストファイルが2つ存在します。

ここを make コマンドで

![qiita_make4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242292/54db28f8-010d-bae5-abfd-54a55cdb8ae5.png)

こうしたい！
rm.mk と同一ディレクトリ上のテキストファイルをお掃除するのがゴール。

## 1. makefile を作成
テキストファイルを rm する makefile を作成するので、「rm.mk」としました。

## 2. プログラムを書く

```makefile:rm.mk
clean:; rm -f *.txt
```
ここで使われている「 * 」は、サフィックスを除いたターゲットの名前を指定する自動変数です。
*.txt は、任意のテキストファイルを対象にするという意味になります。

>サフィックス : 文字列やデータ列の末尾に付加され、何らかの意味を表す要素を指す。（[IT用語辞典さん](http://e-words.jp/w/%E3%82%B5%E3%83%95%E3%82%A3%E3%83%83%E3%82%AF%E3%82%B9.html)より）

## 3.実行
今回は、makefile というファイル名ではなく、「rm.mk」としたので、以下のように実行します。

```shell:rm.mk
$ make -f rm.mk
rm -f *.txt
```

make コマンドの -f オプションによって、そのあとに指定したファイル（rm.mk）を makefile として扱うことができます。

![qiita_make4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242292/0fca453d-6336-c197-14d3-0cd8bb08ac3c.png)

テキストファイルだけがすべて削除されました。
単純作業を自動化することがイメージできたと思います。

# さいごに
次回は、面倒な C ファイルのコンパイルを自動化します。
make っていいな、となるのはこれからですね。

# 参考文献
- GNU Make 第3版 - Robert Mecklenburg 著、矢吹 道郎 監訳、菊池 彰 訳

[^1]: 「makefile」や「Makefile」は、デフォルトで呼び出されます。拡張子が「.mk」の makefile は、make -f ~~.mk で呼び出します。
Laravel HomesteadでBAD GATEWAYが出る


## 原因

根本的な原因は良く分からないけど、`php-fpm` が起動しない状態になることがある模様。。

```
ps -ef | grep php-f
```
実行で、`php-fpm: master process (/etc/php/7.3/fpm/php-fpm.conf) ` が出ない場合、起動に失敗している。

※7.3以外が起動していても無効。
Nginxの設定ファイル（`/etc/nginx/sites-enabled/homestead.test`）内の`fastcgi_pass`に指定されているphpのバージョンの `php-fpm` が起動している必要がある。

```
fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
```

## 解決

```
sudo /etc/init.d/php7.3-fpm start
```
で `php-fpm` を自力で立ち上げると解決する（はず）。
よく使うgitいろいろ

## プログラミング６ヶ月のサル初心者がよく使うgitコマンド
### 1. チケットを渡されたら

マスターを更新する

```
git checkout master
```

```
Git pull origin master
```


### 2.ブランチを作って、そのブランチに行く
```
git branch
```

```
 Git checkout -b　<ブランチ名>
```

### 3.チケットの依頼内容に沿ってコードを書く...

### 4.コミットの準備をする
#####ファイルを全部選択する
```
git add .
```

#####処理内容ごとに区切って選択する
```
git add -p
```

### 5. コミットする
```
git commit -m '<コミット名>'
```

### 6. プッシュする準備をする
プッシュする際ブランチ名を入力する必要があるためここで持っている
ブランチ名を確認する

```
git branch
```

### 7.プッシュする
```
Git push origin <ブランチ名>
```
adobe XDでデザインデータをもらった後にコーディングするときに気を付けること（超初心者向け）

###初心者がXDを使うときに最初にしなければいけないこと

マークアップ言語を勉強していく中で、XDでデザインのカンプをもらって、それをもとにしてコーディングをしていくときがいつか訪れると思います。
（大体、初心者がマークアップの勉強を始めて、半年くらいで訪れると思う）

そんな時にまず初めに私なりにしなければいけないと思ったことを過去の自分に宛てるつもりで書いていこうと思います。
言わずもがなですがXDは最初に最新のものをインストールしておきましょう！
それでは始めます！

*******************************
####①まずは書き出しの方法を学習しよう！
サイトを作るうえで、サイトの中で使う写真を集める必要があります。
最初は「サイトに使う写真はどこから集めるんだ？？」となるかもしれません。
結論を言うと写真はXDのデザインカンプから直接、抽出します。
これを書き出しといいます。書き出しの方法は簡単です。書き出したい画像をクリックして
ctrl+E のショートカットを使うか、もしくは画像を選択してハンバーガーメニューから書き出しを選択するだけです。
この時に書き出しの形式にPNGやJPEGなどがありますが、JPEGは容量が軽くて画質がやや粗い画像を抽出できます。PNGは容量が多くて色彩のゆたかな画像を抽出できます。
特にこだわりがなければPNGでいいとおもいます。なんなら初心者にとってはどっちの形式を使ってもそんなに変わらないと思います。

※よくある疑問
書き出しをするときに目的の画像だけでなく、いらない画像まで一緒に保存されることがあります。操作に慣れていないとよく起きます。
例えば画像に重なっていたロゴも一緒に書き出しされて、一枚の画像になってしまうといったことです。

こなれてくると複数選択して一気に正確に書き出しできるのですが最初は、間違えて書き出すことも多くあったので、
初心者の方はマウスでXDのカンプの画像をドラックして、その画像以外何もないところに持ってきてから書き出しするとミスが減ります。

動かした画像はそのままだと困るのでctrl+Zで元に戻すといいでしょう。

*********

####②XDを使う時のスクロールの仕方を覚えておこう！
XDの操作はかなり独特です。
特に横方向へのスクロールはスクロール方法を知らないとできないと思います。
方法としてはshiftボタンを押しながらマウスホイールを動かすと横方向に動きます。
私も最初のほうはスクロール方法に大いに苦しめられました。
またctrlボタンを押しながらマウスホイールを回すと拡大と縮小ができます。
マウス押し込みでポインターが手の形になり画面をドラックで移動させれます。
XDはなかなか直感的な操作ができないので最初はショートカットを調べて操作方法を学んだほうが後々の効率はいいと思います。

****************

####③フォントを用意しよう！
adobe creative cloudを利用するとフォントを無料で追加して使うことができます。
フォントの設定は初心者にとってハードルが高いので最初はフォントを適当に選択してしますこともあると思います。
しかしフォントはデザインの印象を大きく変えるのでやはりこだわったほうがいいと思います。
コーディングするうえで必要なフォントはXDでデザインカンプを開いて左側にタブに環境にないフォントというのが出てくるので、フォント名をadobe fontsで調べます。（この時、環境にないフォントで出てきたフォント名とadobe fonts 上でのフォント名が微妙に違う時がありますが、あまり気にしなくていいです。

目当てのフォントを見つけたら、アクティベートしたあと、画面右上あたりにウェブプロジェクトに追加という項目があるので、クリックしてプロジェクト名をつけてください（プロジェクト名はわかりやすければ何でもいいです）
そのあとにHTMLのheadに選択したフォントを使うためのコードが出てるのでhead内にコピー＆ペーストしましょう。この時にcss内で記述するときのためのコードも出てくるのでメモ帳にでも書いておいてください。

例としてHTMLのヘッド内には
```
<script>
  (function(d) {
    var config = {
      kitId: 'ahg6syh',
      scriptTimeout: 3000,
      async: true
    },
    h=d.documentElement,t=setTimeout(function(){h.className=h.className.replace(/\bwf-loading\b/g,"")+" wf-inactive";},config.scriptTimeout),tk=d.createElement("script"),f=false,s=d.getElementsByTagName("script")[0],a;h.className+=" wf-loading";tk.src='https://use.typekit.net/'+config.kitId+'.js';tk.async=true;tk.onload=tk.onreadystatechange=function(){a=this.readyState;if(f||a&&a!="complete"&&a!="loaded")return;f=true;clearTimeout(t);try{Typekit.load(config)}catch(e){}};s.parentNode.insertBefore(tk,s)
  })(document);
</script>
```
またcssでは
```
font-family: yu-mincho-pr6, sans-serif;
font-style: normal;
font-weight: 400;
```

といったようなコードになります。

**************

####まとめ

まずXDを使う際には

XDのインストール→ショートカット及び操作を覚える→書き出しの方法を覚える→フォントをダウンロードする。

というような手順で進めていくとスムーズに進めていけると思います。

私自身がまだ初心者なので間違っているところやもっと効率的な方法があるかもしれませんが、何かお気づきの点があれば教えていただけるとありがたいです。

閲覧ありがとうございました。
Angular: SEO対策基本

#Angular: SEO対策

SPA（シングルページアプリケーション）はハッキリ言ってSEOフレンドリーではない。今のところ、ね。Angularで作成した場合最低限やっておくことを備忘録。

###環境

```
Angular CLI: 7.1.4
Node: 10.15.3
OS: win32 x64
Angular: 7.1.4

"@angular/material": "^7.3.4"
```

#robots.txtとsitemap.xmlを配置。

robots.txtと、

```
User-agent: *
Disallow: /admin/
Allow: /*
# allow google image bot to search all images
User-agent: Googlebot-Image
Disallow:
Allow: /*
# allow Google adsense bot on entire site
User-agent: Mediapartners-Google*
Disallow:
Allow: /*
User-agent: Twitterbot
Disallow:
Allow: /*
Sitemap: https://example.com/sitemap.xml
```

sitemap.xmlを、

```xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<url><loc>https://example.com</loc><priority>0.5</priority></url>
<url><loc>https://example.com/introduction</loc><priority>0.5</priority></url>
<url><loc>https://example.com/introductioneng</loc><priority>0.5</priority></url>
<url><loc>https://example.com/basics</loc><priority>0.5</priority></url>
・・・省略・・・
</urlset>
```
src配下に配置。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/ff807f7f-4ba4-fe0e-d0e8-efb72cae8e86.png)

####※ sitemap.xmlは[sitemap generator](https://www.xml-sitemaps.com/)や[sitemap Editor](http://www.sitemapxml.jp/)で作成できない。
にゃんとも困ったことに残念ながらrouterLinkにはgeneratorのクローラーが反応してくれない。トップページだけのsitemap.xmlしか出力してくれない。↓

```xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<url>
  <loc>https://example.com/</loc>
  <priority>1.0</priority>
</url>
</urlset>
```
<strong>sitemap.xmlは手作業で作るしかない。</strong>


###angular.jsonを編集
以下のように"src/robots.txt","src/sitemap.xml"をassetsの下に追記する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/29daf74d-0146-3e9b-8c78-497fc5912b02.png)


###polyfills.tsを編集
デフォルトでコメントアウトされているけど、以下の14行をコメントを外して有効化する。

```typescript
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/weak-map';
import 'core-js/es6/set';

```

最後にGoogle Search Consoleで諸々登録する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/08266658-18f4-f329-1e84-bd4b454c9c58.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307441/c4b70b9a-cdbf-4e1f-d4db-39f9bb2ebb1a.png)

以上
【Source Tree】で付けたタグを削除する方法

#Source Treeでタグを削除する方法
タグを付けたブランチを右クリックしても削除項目が見当たらず、どうやって削除するのか調べてみました。


Source Tree画面の左列（ワークスペースやブランチ名やがずらっと並んでいるところ）に**タグアイコン**があるので、ホバーをすると右に**表示**の文字が表示されるのでクリックします。


削除したい**タグ名**を選択して右クリックするとメニューが表示されるので**「○○○○を削除」**をクリックすれば削除完了です。

![グループ 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/486362/062c7b3a-5fcb-5268-a3f2-99bb5e036969.png)



##一言メモ
タグを初めて付け間違えたのでメモ用に残しておきます。
こういうのって失敗してはじめて必要とされる作業なので、普段使わないだけに気づきにくい点でもあった。
良い勉強になりました！
5秒でAtcoderを始めたいjs初心者のための標準入出力

#はじめに
- ~~誰もここまで初歩的なの求めてなさそうだが自分が困ったので書き起こし。~~
- 超初歩的知識で理解できるように書きました。配列と関数さえ知ってればよい
- 読むのが面倒くさいヒトは下まですっ飛ばして構いません。どうせ大したことは書いてない
- どこか間違ってるかもしれないがとりあえず動いたから大丈夫……だよね？
- Node.js利用。

#そもそも標準入出力とは何ぞや
ここで説明してもよいのだが、以下の記事が詳しいので丸投げする。→[@angel_p_57さんの記事](https://qiita.com/angel_p_57/items/03582181e9f7a69f8168)
読むのが面倒くさいヒトは「デフォルトで指定してあるデータの入り口と出口」って覚えとけば大した問題はない。

#で、どう使えばいいのよ
とりあえず[Welcome to AtCoder](https://atcoder.jp/contests/abs/tasks/practice_1)のサンプルコードを見るのが手っ取り早い。データの加工をする問題だが、内容は今は気にしないでおく。入出力だけ見る。
>以下引用

**入力**
入力は以下の形式で与えられる。

```
a
b c
s
```

**JavaScript(Node.js) での解答例**

```.js
// inputに入力データ全体が入る
function Main(input) {
	// 1行目がinput[0], 2行目がinput[1], …に入る
	input = input.split("\n");
	tmp = input[1].split(" ");
	//文字列から10進数に変換するときはparseIntを使います
	var a = parseInt(input[0], 10);
	var b = parseInt(tmp[0], 10);
	var c = parseInt(tmp[1], 10);
	var s = input[2];
	//出力
	console.log('%d %s',a+b+c,s);
}
//*この行以降は編集しないでください（標準入出力から一度に読み込み、Mainを呼び出します）
Main(require("fs").readFileSync("/dev/stdin", "utf8"));
```
>引用終わり。

###つまりどういう処理してんの？
#####2行目
`function Main(input)`~
15行目で読み込んであーだこーだするためにプログラム全体を関数`Main`に突っ込んでいる。引数`input`には実行時に標準入力から渡されたデータ全文が入る。もちろんそのままでは処理できないので、使えるように加工しなければならない。
#####4行目
`input = input.split("\n");`
標準入力から渡されたデータを改行(\nと表される)ごとに区切って配列に落とし込んでいる。
つまり、この状態では、`input`の中身が

```.js
[ 'a', 'b c', 's' ]
```
となっている。
#####5行目
`tmp = input[1].split(" ");`
4行目の状態だとbとcがくっついているので別々にする。変数`tmp`を定義し、`split`メソッドで`input[1]`の中身を空白で区切っている。
この状態では、`tmp`の中身が

```.js
[ 'b', 'c' ]
```
となっている。
#####7行目
`var a = parseInt(input[0], 10);`
変数`a`を定義し、`input[0]`の中身を10進数として入れている。(これが標準入力で与えられた「a」の中身)
たまたま計算しなければいけない問題だったからやってるだけなので、文字列のままでよければ`var a = input[0]`で良いし、なんなら`input[0]`のまま後のコードに入れてもいい（分かりにくいけど……）
#####8~10行目
7行目と同様。
#####12行目
`console.log()`で解答を出力している。そんだけ。簡潔。実際に問題を解くときにはここまでに定義した関数を使った処理もここに書き込もう。
#####15行目
`Main`関数内の処理を実行するところ。おまじないだと思って書いておこう。ぼくもよくわからない。
#まとめ
```.js
function Main(input) {
input = input.split("\n");//行ごとに分解して配列にする。一行の時は"\n"を" "にして三行目を消そう
適当な変数　= input[複数の要素がある行].split(" ");//複数の要素がある行が無いときはいらない
//省略。
var a = input[0];
//省略。使いやすいように他の変数を定義する

//本題の処理
console.log(解答);
}
Main(require("fs").readFileSync("/dev/stdin", "utf8"));//おまじない
```
###さいごに
間違ってるところがあったり分からないことがあったらどうぞコメントください。
【Java】再帰処理を使ってFizz Buzz問題を解いてみる

# はじめに

* 以前に「[【Java】Fizz Buzz問題を解いてみる](https://qiita.com/nkojima/items/e6400e997e7fcea5f504)」を投稿した後、もう少し別の書き方が出来ないかと考えていました。
* 「判定する数が1ずつ増えていく」という点に着目すると、再帰処理が使えそうだと思ったので試してみました。

# 作成したコード

* 最初の`if (end > 1) {...}`という条件分岐で、`end==1`の時にはこれ以上再帰処理に入らないようにしています。
 * 「最初のプレイヤーは『1』と数字を読み上げる」というFizzBuzzのルールに合致しています。

```FizzBuzz2.java
/**
 * 再帰処理を活用した方法。
 * @param end FizzBuzzを終える数。
 */
public static void useRecursion(int end) {
	if (end > 1) {
		useRecursion(end - 1);
	}

	if (end%3==0 && end%5==0) {
		System.out.println("Fizz Buzz");
	} else if (end%3==0) {
		System.out.println("Fizz");
	} else if (end%5==0) {
		System.out.println("Buzz");
	} else {
		System.out.println(end);
	}
}
```

```text:実行結果（※引数endに20を指定した時）
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
Fizz Buzz
16
17
Fizz
19
Buzz
```

# まとめ

* 再帰処理を活用してFizzBuzz問題を解くことができました。
* ただし引数`end`が大きくなると、再帰処理（再帰関数）の呼び出し回数も大きくなるため、スタックオーバーフローの危険性が出てくると思います。
WindowsでCRLFからLFに一括変換する

windowsでpowershellかgit-bashを使ってCRLFからLFに一括変換する方法を紹介しています。
(追記)gitで管理されている場合、もっと簡単な方法がありました。

# :question:発端

Windowsでdockerのコンテナをビルド、起動した所、以下の様なエラーが発生した。

```
standard_init_linux.go:190: exec user process caused "no such file or directory"
```

調べるとどうやら、コンテナにコピーした設定ファイルの改行コードがCRLFになっているためエラーが発生している模様。
（コンテナはLinuxベースなので改行コードがLFである必要があった）

そんな訳でWindows上でCRLFからLFに一括変換する方法を調べた

# (追記)Gitで管理されている場合

`.gitattributes`で改行コードを指定してファイルをチェックアウトしなおす事でまとめてLFにできます。
詳しい手順は以下の通りです。

まずは全てのファイルをコミットして差分が無い状態にします。
続いてリポジトリのルートに`.gitattributes`を追加し、各ファイルの改行コードを指定します。

```.gitattributes
* text=auto eol=lf
```

上記の意味は「gitがテキストファイルと判断するものは全て改行コードをLFとする」です。
詳しい記述方法は[こちら](https://qiita.com/nacam403/items/23511637335fc221bba2)の記事が分かりやすいです。

その後、CRLFになってしまっているファイルを一旦**削除**した後、
`git checkout -f`で復活させると改行コードがまとめてLFになっています。

これが一番簡単だしクローンするたびに再設定しなきゃいけないなんて事もないのでオススメです。

# Git-bashが使える場合

git-bashが使える場合、linuxのコマンドが使えるので簡単です。
以下のコマンドで、**カレントフォルダ以下のファイルをCRLFからLFに一括変換**できます。

```
find * -type f -exec sed -i "s/\\r\\n/\\n/g" {} \;
```

以下、コマンドの解説です。

* `find . -type f -exec {} \;`
  * カレントフォルダ以下のファイルを列挙します。
  * `-type f`でファイルのみに制限します。
  * `-exec`は列挙したファイルを別のコマンドに渡します。ここでは`sed`コマンドに渡しており、`{}`にはファイル名が埋め込まれます。`\;`はコマンドの終端を表すおまじないです。
* `sed -i "s/\\r\\n/\\n/g" [ファイル名]`
  * CRLFをLFに置換します。
  * `-i`を指定する事によりファイルを直接編集します。（付けない場合、処理結果が標準出力に出力されます）

# Git-bashが使えない場合

git-bashが使えない場合、Windows標準の機能でやる事になります。
今回はpowershellを使う事にします。
以下のコマンドで、**カレントフォルダ以下のファイルをCRLFからLFに一括変換**できます。

```powershell
Get-ChildItem -Recurse -File | ForEach-Object {((Get-Content $_.FullName -Raw) -replace "`r`n","`n") | Set-Content $_.FullName}
```

以下、コマンドの解説です。

* `Get-ChildItem -Recurse -File`
  * ファイルの一覧を取得します。
  * ここのオプションを変更すれば対象範囲を制御できるかと思います。
* `ForEach-Object { ... }`
  * 各ファイルに`{}`の中のコマンドを適応します。
  * `$_.FullName`にファイルパスが展開されます。
* `Get-Content $_.FullName -Raw`
  * ファイルを読みこみます。
  * `-Raw`を付与することで１つの文字列として読み込みます。付与しないと各行の配列として読み出されてしまい改行コードが失われてしまいます。
* ``"文字列" -replace "`r`n","`n"``
  * CRLFをLFに置換しています。
  * PowerShellのエスケープ文字は`` ` ``なので注意してください。（見慣れませんね）
* `Set-Content $_.FullName`
  * ファイルを書き込みます。

以上です。
PowerShellの書き方になれてなくて手間取りました:thermometer_face:
#Ruby インスタンスのメソッドを上書きして #Rails の current_user の update を禁止する例、的な。

もしくはインスタンスの特異メソッドをoverrideして、オープンクラス的なことをやる、的な。

```rb
user = User.first
user.define_singleton_method(:update, -> (*arg) { raise 'Unable update!' })

user.update
# RuntimeError: Unable update!
```

これを Rails の `@current_user`  に対してやれば、update を禁止できるのでは？

(目的については特に語らない)

# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
#GoogleChrome の Developer Tool で指定の Cookie を削除する

# Application > Cookies > URLを選ぶ > 削除したいCookieを選ぶ > 削除キー (MacならCommand+Deleteとか)

![image](https://user-images.githubusercontent.com/13635059/65014231-eee75c00-d958-11e9-8e8c-4cf3fccd3660.png)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
facebook graph apiで、特定のusernameの記事を指定件数だけ取得する方法。

#発端
instagramから画像を取得したいからAPIで取得した。

#早速
https://graph.facebook.com/v4.0/facebook_page_id/
?access_token=access_token
&fields=business_discovery.username(username)
{
    media.limit(50)
    {caption,children,permalink,media_url}
}

facebook_page_id, access_token, username
は皆さんの環境に合わせてね。

#説明
上３行は割愛。

media.limit(50)
そのusernameの投稿の先頭から50件を取得するよ！という意味。

{caption,children,permalink,media_url}
この辺は、利用する情報に応じて調べて変更してね。
javaでの空判定とnull判定はStringUtils.isNotBlankが便利

人によって書き方が揺れてる気がするからこれに統一したいナァとおもった。
Stringが空、またはスペースだけ、またはnullのときにfalse返してくれる。


StringUtils.isNotBlank(String str)

```
 StringUtils.isNotBlank(null)      = false
 StringUtils.isNotBlank("")        = false
 StringUtils.isNotBlank(" ")       = false
 StringUtils.isNotBlank("bob")     = true
 StringUtils.isNotBlank("  bob  ") = true
```

他にもたくさん便利なんあるね。
https://www.sejuku.net/blog/19323
↑侍ブログさんとかでまとめられてるけど、エンジニアの端くれとしてはぜひ積極的に公式をみていきたいよね
↓公式
https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/StringUtils.html
YouTube Data api v3をPythonから使って動画の閲覧数をごそっと取得する

# はじめに
動画IDとapi keyが必要となります。

api keyはgoogle developer consoleから取得し、環境変数にいれて使用します。
取得の方法については[google - 承認の認証情報を取得する](https://developers.google.com/youtube/registering_an_application?hl=ja)を参照してください。
(Oauthトークンを取得する必要はありません)

# 動画IDの取得
動画ページにて`https://www.youtube.com/watch?v=XXXXXX`の`XXXXXX`部分を取るのが簡単だと思いますが、そもそもごそっと取得しようとしているのでこれも自動でやろうと思います。


特定チャンネルの動画IDを集めるのであれば以下のような方法があります。
[YouTube Data api v3をPythonから使って特定のチャンネルの動画を取得する](https://qiita.com/yasudadesu/items/df76947f5b6ac955521f)

また、`google-api-client`の`search().list`メソッドを用いることで検索クエリによる動画の取得も可能です。
その場合は[qiita - PythonとYoutube Data API(v3)で再生数を取得する](https://qiita.com/funsuke/items/160684329ef29f2fbf65)という記事の方法の方が簡単だと思います。

```python
  videos_response = youtube.videos().list(
    part="id,snippet,statistics",
    id=options.id
  ).execute()
```

今回行なっていた特定チャンネルからの動画取得→再生数取得の場合は

- Youtube Data APIのPythonインターフェースにてそれにちょうど合致するものがない
- http request上で`id,snippet,statistics`を同時に指定するとエラー

となるため、それの回避策となります。

# 動画の閲覧数の取得
さて本題。
`videos.csv`は[YouTube Data api v3をPythonから使って特定のチャンネルの動画を取得する](https://qiita.com/yasudadesu/items/df76947f5b6ac955521f)にて出力した`csv`ファイルです。
そのため、動画idのSeriesであれば、なんでも大丈夫です。

```python
import os
import time
import requests

import pandas as pd


API_KEY = os.environ['API_KEY']
videos = pd.read_csv('videos.csv')
base_url = 'https://www.googleapis.com/youtube/v3'
stat_url = base_url + '/videos?key=%s&id=%s&part=statistics'

len_block = 50
video_ids_per_block = []
video_ids = videos.videoId.values

count = 0
end_flag = False
while not end_flag:
    start = count * len_block
    end = (count + 1) * len_block
    if end >= len(video_ids):
        end = len(video_ids)
        end_flag = True

    video_ids_per_block.append(','.join(video_ids[start:end]))
    
    count += 1

stats = []
for block in video_ids_per_block:
    time.sleep(30)
    response = requests.get(stat_url % (API_KEY, block))
    if response.status_code != 200:
        print('error')
        break
    result = response.json()
    stats.extend([item['statistics'] for item in result['items']])

pd.DataFrame(stats).to_csv('stats.csv', index=None)
```

途中の`len_block`などというのはごそっとバッチで取得するために、url内の`id`に`,`で結合した動画idを渡すためのものです。
一度に取得できる最大が50件なので、`len_block=50`としています。
#GoogleChrome の Developer Tool でネットワークログが見られない。画面をリロードしても何もない。なぜ？

# どうした？

![image](https://user-images.githubusercontent.com/13635059/65013810-8cda2700-d957-11e9-878d-d350e18bcf87.png)

# タブでは All を選び直そう

![image](https://user-images.githubusercontent.com/13635059/65013781-72a04900-d957-11e9-9840-98d3b40838b3.png)

# キーワードフィルタが入っていないか確認しよう

![image](https://user-images.githubusercontent.com/13635059/65013764-5ac8c500-d957-11e9-9aeb-7d53a77473c1.png)


# Original by Github issue

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








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
PyRevit + Python Revit Wrapper で覚えておいたほうがよい書き方①


Revit API でFamilyのTypeの情報を取りたいときは、FamilySymbolのクラスを使うことになります。

そこでは、少しPython特有の書き方が必要になります。
何度かハマって忘れてを繰り返しているので忘備録として残しておくことにします。

まず、Furnitureのカテゴリーのタイプだけをとります。ここで`is_not_type=True`にすると逆にインスタンスだけがとれます。

```python:collector_sample.py
from rpw import db
symbols = db.Collector(of_category="OST_Furniture", is_type=True)

```

この集めたコレクターのFamilyName、FamilyTypeName,Parameter(value), Parameter(string)の取り方を紹介します。


```python:collector_sample.py
from rpw import db
symbols = db.Collector(of_category="OST_Furniture", is_type=True)

for symbol in symbols:
    famName = symbol.FamilyName
    typeName = Element.Name.GetValue(symbol)
    parameter_value = Element.GetParameters(symbol, "Height")[0].AsValueString()
    parameter = Element.GetParameters(symbol, "Manufacturer")[0].AsString()

```
FamilyNameはシンプルにとれますが、タイプ名は、`Element.Name.GetValue(symbol)`という特殊な方法で取ります。同様にParameterの値もとれるのですが注意しないといけないのが、StringとValueを区別しているため、パラメータによって最後のAs～を変えないといけないところです。

またインスタンスを選択して、情報を得る場合の例も載せておきます。
まず、`revit.pick_rectangle()`でインスタンスを取得した後にその選択した`Id`を`revit.get_selection()`にappendします。こうすることで、`selection_rpw = ui.Selection()` が使用できるようになります。

```python:selection_sample.py
from rpw import ui
from pyrevit import revit
selection = revit.get_selection()
selection_list = revit.pick_rectangle()

for sel in selection_list:
    sel_id = sel.Id
    selection.append(sel_id)

if(selection_list):
    selection_rpw = ui.Selection()

for sel in selection_rpw:
    symbol = sel .get_symbol()
    family = sel .get_family()
    params = symbol.parameters.all
    param = symbol.parameters["SeatCount"].value
    print(symbol)
    print(family)
    print(param)
    print(params)
```
Revit Python Wrapperで取得したエレメントは、簡単にシンボルやファミリ、パラメータ情報を取得できます。
【Android】xmlのあれこれ注意点

## RelativeLayout
 - RelativeLayoutの中でtoEndOfなどを使うと、  
 LinearLayoutじゃなくても横並びにすることができる。  
 - RlativeLayoutのcenterHorizontal(true)で中央揃えができる。  
 ※matchではなくwrapで使う。

## EditText  
 - プレースホルダーに文字を入力しておきたい場合は、hintを使う。
   
```hoge.xml

<EditText
 android:id="@+id/login"
 android:layout_width="200dp"
 android:layout_height="40dp"
 android:hint="@string/login"
 android:textColor="@color/white"
 android:textColorHint="@color/clear_white" />
```

## 中央揃え  
 - center_verticalが効かないときは、layout_gravityをcenterにする。  

## エリアの分割  
 - 同じViewを2つ横並びに置きたいとき：layout_weight:1にして、Width=0にする。
 - 同じViewを2つ縦並びに置きたいとき：layout_weight:1にして、Height=0にする。  

## タブみたいなものを作りたい  
 - ViewPager/PagerTitleStripを使う。

## 文字の中央揃え  
 - gravity=centerにする。  
※hintの配置も変更可能。

## ボタンを丸くする  
 - drawableにshape.xmlを別途作成して、viewのbackgroundで参照する。  

```shape.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <!-- 枠線 width:線の幅、color:線の色 -->
    <stroke
        android:width="0.6dp"
        android:color="@color/white" />

</shape>
```
## 押下で文字色を反転させる（白→黒）  
 - drawableのhoge.xmlにselectorをつくって、textColorで参照する。  

```hoge.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:s="true" android:state_pressed="false" android:color="@color/black" />
        <item android:state_focused="true" android:state_pressed="true" android:color="@color/black" />
        <item android:state_focused="false" android:state_pressed="true" android:color="@color/black" />
        <item android:color="@color/white" />

</selector>

```
## 押下で画像を差し替える（活性カラー画像→非活性カラー画像）  
- drwableのhuga.xmlにselectorをつくって、srcで参照する。  

```huga.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 押下状態 -->
    <item
        android:state_pressed="true"
        android:drawable="@drawable/setting_click" />
    <!-- 通常状態 -->
    <item
        android:drawable="@drawable/setting" />
</selector>
```
エラー：Laravel : failed to open stream: Success _ error in auth

# エラー
```
Laravel : failed to open stream: Success _ error in auth
```
に遭遇した場合、以下を試してみましょう。
僕は２で解決しました。

# 解決
1. まずはキャッシュクリアしてみる： `php artisan cache:clear`
2. クラスの再生成： `composer dump-autoload -o`
3. プロジェクトの更新 `composer update`
4. マイグレーションをロールバック： `php artisan migrate:rollback`
pythonからAWS LambdaのヘッダにトレースIDを設定する手順

[AWS X-Rayで非同期メッセージをトレースする](https://qiita.com/yoshiyoshifujii/items/df18ff90b6332e0a56c6 'AWS X-Rayで非同期メッセージをトレースする') のPython版です。
ヘッダを設定する関数を作っておいてlambda実行前に割り込ませることで実現します。

- ヘッダ文字列'root='を忘れないこと
- register文字列のInvokeをinvokeにしないこと

が重要です(私が間違えたところ)

```python
import boto3

def before_send(request, **kwags):
  request.headers['x-amzn-trace-id'] = 'root=1-11111111-111111111111111111111111'

lmd = boto3.client('lambda')
lmd.meta.events.register('before-send.lambda.Invoke', before_send)
lmd.invoke(FunctionName='Function',Payload='')

```

レスポンスに以下のように指定したx-amzn-trace-idが含まれていれば成功。

```python
{'ResponseMetadata': 
  {'RequestId': '8631649f-6276-4278-bf9f-c20eaf74xxxx',
   'HTTPStatusCode': 200,
   'HTTPHeaders': {
    'date': 'Tue, 17 Sep 2019 05:54:56 GMT',
    'content-type': 'application/json',
    'content-length': '4',
    'connection': 'keep-alive',
    'x-amzn-requestid': '8631649f-6276-4278-bf9f-c20eaf74xxxx',
    'x-amzn-remapped-content-length': '0',
    'x-amz-executed-version': '$LATEST',
    'x-amzn-trace-id': 'root=1-11111111-111111111111111111111111;sampled=1'
   },
   'RetryAttempts': 0
  },
  'StatusCode': 200,
  'ExecutedVersion': '$LATEST',
  'Payload': <botocore.response.StreamingBody object at 0x7f94f16ba978>
}
```

先日[SQSもX-Rayのサポート対象](https://aws.amazon.com/jp/about-aws/whats-new/2019/08/aws-x-ray-now-supports-amazon-sqs/)になりましたが、早くlambdaも対象になってほしいですね。
【GAS】RPAを行う際の技術選定の指標【Cobit】

# なぜこの記事を書くに至ったのか
私は現在とある場所でRPAの部署に配属しています。
そこで、自動化？や業務改善のために人の手で行なっている部分をプログラムや、RPAツールでどうにかできないか？というお話がきたので、Google Apps Script(以降GAS)、RPAツールのCobitを使ってみて両者のメリット、デメリットを書いていきます。

# GAS vs Cobit
RPAにおいての問題点、課題の解決力を比較していきたいと思う。

###### ※これから記載することは主観です。

### 初心者でも扱いやすいのか？（新規開発、引き継ぎ等）
#### GAS ○
GASは非エンジニアが手軽に触れるように、環境構築などもなく、スクリプトエディタを開けばすぐに書ける。
日本語の記事もたくさんあるので、非エンジニアでもすんなり入っていけると思うのですが、やはり一応プログラミング言語を書くので、○
#### Cobit ◎
プログラミングが一切必要無い。ブラウザぽちぽち触るだけで、簡単にロボットが作れる。
サポートも日本語でリアルタイムで聞けるので、非エンジニアの方でもなんなく触れる。
よって◎

### 大規模開発は？
#### GAS ×
GASは１回の実行で６分しか稼働させられないので、大規模になってくると毎回タイムアウトになってしまうため×
#### Cobit △
Cobitは実行時間などは基本的になく、１回の実行時間などが特に明記されていないので、大規模開発を行うならGASよりはこっち。
けどそんな大規模ならCobitも頼りにならなそうなので△

### 定期実行
#### GAS △
定期実行は分単位など細かく設定できるのだが、90分/1日なので、MAX６分の関数を定期実行するのであれば、1日１5回以上定期実行しようとするとエラーになってしまう。
#### Cobit ◎
Cobitの場合定期実行の制限がなく、こちらも分単位で細かく設定できるので、1日の実行が多い場合はCobitを採用するのが良い

### Googleサービスとの連携
#### GAS ◎
当たり前だが、GASもGoogleのサービスなので、スプレッドシートやドライブへのアクセスが非常に簡単。
スプレッドシートの値を取得して何かしたい場合は少しコードを複雑に書く必要がある。

```js
// こんな感じ
function main() {
  var dnsSheet = SpreadsheetApp.getActiveSheet();

  var hoge = changeOneDimensionalArray(
    1,
    hoge,
    "シート1"
  );
}  

function findLastCol(sheetName, row) {
  var sheet = SpreadsheetApp.getActiveSheet(sheetName);

  var rowValues = sheet.getRange(row, 1, 1, sheet.getLastColumn()).getValues();

  rowValues = Array.prototype.concat.apply([], rowValues);

  const lastCol = rowValues.filter(String).length;

  return lastCol;
}

function findLastRow(sheetName, col) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);

  var colValues = sheet.getRange(1, col, sheet.getLastRow(), 1).getValues();

  const lastRow = colValues.filter(String).length;

  return lastRow;
}
```
スプレッドシートへの書き出しなどや、ドライブへの保存を主にするのであればGAS一択と言っていい
#### Cobit ○
認証させたアカウントが操作できるスプレッドシートやドライブへの操作ができる。
スプレッドシートへの書き出しを行いたい場合は、少しめんどくさい。
スプレッドシート間を行き来したりするのは本当にめんどくさい。

### スクレイピング
#### GAS △〜○
#### Cobit △〜○
これはケイスバイケースとしか言いようがないですね。
お話聞いて上記の条件に当てはめてみて話し合うしかないです。

### ２段階認証
#### GAS ×
#### Cobit ×
これは両方ともできないので、２段階認証のあるサイトをスクレイピングしたいと言われたら無理と答えましょう。
[一応Pythonではあるらしいです。](https://tanuhack.com/python/pr-2captcha/)


一応自分が調べた限りだとこんな感じでした。
この後もわかり次第随時更新していく予定です。
firebaseを用いて匿名認証からTwitterアカウントを後から繋げる

まずはコードから。
コピペで動くと思います！

```javascript

export const persistLoginWithTwitter = () => async dispatch => {
  var provider = new firebase.auth.TwitterAuthProvider();
  var anonymous_user = await firebase.auth().currentUser
  await anonymous_user.linkWithPopup(provider).then(function (usercred) {
  console.log('アカウントの紐付け成功')
 }, function (error) {
    console.log("Error upgrading anonymous account", error);
  });
}
```

これで普通に匿名ログイン中のユーザーをtwitterアカウントに繋げることができます。
注意するべきことは、
linkWithPopUp.then()　の内部において、usercred.userをしてもtwitterのuser情報は出てこないところです。


```javascript
var twitter_user = usercred.user.providerData[0]
```
こんな感じでtwitterのphotoURLとかdisplayNameが欲しいときは取り出します。
anonymousUserUpdateアクションで自分はdisplayNameとうが欲しかったので。。

実際にはこんな感じになりました。

```javascript
export const persistLoginWithTwitter = () => async dispatch => {
  var provider = new firebase.auth.TwitterAuthProvider();
  var anonymous_user = await firebase.auth().currentUser
  await anonymous_user.linkWithPopup(provider).then(function (usercred) {
    var twitter_user = usercred.user.providerData[0]
    console.log(user)
    console.log(user.photoURL)
    dispatch(anonymousUserUpdate(twitter_user, anonymous_user.uid))
  }, function (error) {
    console.log("Error upgrading anonymous account", error);
  });
}
```
【初心者ざっくりシリーズ】MongoDB Atlasのまとめ

#対象
初心者による、ざっくりした纏めです。
初心者で、ざっくりと理解したい方はお読み下さい。

#そもそもMongoDBとは？
NoSQL型のデータベースの１種類。
※参考
データベースには、RDB型とNoSQL型の２種類があります。簡単にいえば、RDB型が表の形でデータを保存するのに対し、NoSQL型は、例えば｛りんご:1,　みかん:2}など表ではない形でデータを保存します。

#MongoDB Atlasとは？
MongoDB社が提供する、オンラインで提供されるMongoDBの一つ。

#無料で使えるか？
Yes！！
但し、最初に世界中に存在するデータ保管庫のうち、無料であるものを設定する必要があります。

また、初期にクレジットカード等の登録の必要はありません。

#使い方は？
※参考
https://docs.atlas.mongodb.com/getting-started/#deploy-a-free-tier-cluster

詳細は上記にわかりやすく記されているので、この通りに設定頂ければ大丈夫だと思います。
以下に日本語でざっくりとステップを解説します。

###①MongoDBのアカウントを作成します
###②無料のデータベースを作成します
###③あなたのパソコンをデータベースへ接続を許可するため、IPアドレスを接続許可リストに加えます
###④今度は、あなたをデータベースにユーザーとして登録します

#最後に

初心者にわかりやすくするため多少言い切っている箇所もあります。
明らかに間違っている箇所がありましたら、ご指摘お願いします。
postを受け取るだけのサーバーを立てる

自分用メモ

```js:index.js

var http = require('http');

http.createServer(function(req, res) {
  if(req.method === 'GET') {
      // do something ;
 
  } else if(req.method === 'POST') {
      var data = '';
      req.on('data', function(chunk) {data += chunk}).on('end', function() {
           console.log(data);
           // res.end(html);
      })
  }
}).listen(6666); // portの番号

```

これを適当なところに配置して、 `$ node index.js ` すればlistenし続ける。
ので、 `localhost:6666 `に向かって適当にpostすれば良い。(ngrokで6666を外に向けても良い)
【忘備録】【CSS】【Bootstrap4】複数のボタンを中央寄せにする

### 書いた理由

- フォームのデザイン時に横並びの複数のボタンを配置する際、以下のようなイメージで、複数のボタンをボタングループにしたくないが、まとめて中央寄せにしたいとなった。![Form Image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27600/4d0dc799-213a-4f73-1884-a762413b21c5.jpeg)

- さっくり行けるかと思ったが、案外悩んだので忘れないように書いておくことにした。


### 結論
<p class="codepen" data-height="500" data-theme-id="0" data-default-tab="html,result" data-user="yui728" data-slug-hash="bGboaQE" style="height: 451px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Bootstrap4: Centering buttons not Button-Group">
  <span>See the Pen <a href="https://codepen.io/yui728/pen/bGboaQE/">
  Bootstrap4: Centering buttons not Button-Group</a> by Yui Nishimura (<a href="https://codepen.io/yui728">@yui728</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>

### 解説
#### 20行：`<div class="form-group row justify-content-center">`
- `form-group`：フォーム内の要素をグループ化
- `row`：グリッドレイアウトにおける行
- `justify-content-center`：flexboxレイアウトでコンテナ内部の要素を中央揃えにする

#### 21行：`<div>`
- 前述した`justify-content-center`で中央揃えにされる要素

#### 22行,23行：`<input type="submit"... />`,`<input type="button"... />`
- 中央揃えにしたいボタン

#### なぜ、`<div class="form-group row justify-content-center">`直下にて、`<div>`でもう一段階まとめなければならないか？
公式ドキュメントの[Flex：Justify content](https://getbootstrap.com/docs/4.3/utilities/flex/#justify-content)を見ると分かるように、`justify-content-center`で中央揃えとした場合は、直下コンテナ間のmarginが無視されるため。
CodePenで実験すると、確かに2つのボタン同士がくっついた状態になる。

<p class="codepen" data-height="500" data-theme-id="0" data-default-tab="html,result" data-user="yui728" data-slug-hash="ExYeXJv" 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="Bootstrap4: Centering buttons not Button-Group: if Div directly below Div with &amp;quot;row justify-content-center&amp;quot; class attribute is nothing">
  <span>See the Pen <a href="https://codepen.io/yui728/pen/ExYeXJv/">
  Bootstrap4: Centering buttons not Button-Group: if Div directly below Div with &quot;row justify-content-center&quot; class attribute is nothing</a> by Yui Nishimura (<a href="https://codepen.io/yui728">@yui728</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://production-assets.codepen.io/assets/embed/ei.js"></script>
HTMLをアプリにしてみる(Cordova)

# HTMLをアプリにしてくるものがあるらしい
- HTMLをアプリに変換してくれるツールがあるらしい。
- CordovaというものでApacheファミリーらしい。

ということで、インストールしてHelloWorldのapk実行までをやってみた。

## Cordovaをインストール

### 前提となるもの
- node
- npm

### node
個人的にはWindowsだったら、nodist。macだったら、nodebrewで入れておくのがおすすめ。
（今回はWindowsでやってます）

```
$ node --version
v11.13.0
```

```
$ npm --version
6.9.0
```

これができたら、npmでCordovaをインストールしてみる。

```
$ npm install -g cordova
```

インストールできたらCordovaコマンドを確認

```
$ cordova -version
9.0.0 (cordova-lib@9.0.1)
```


## まずはブラウザモードでHelloWorld

プロジェクトを作るディレクトリに移動して、プロジェクトを作る
（cdで、作るディレクトに移動しておいてください。今回は d:\var\labo\CordovaHello）


```
cd \var\labo
cordova create CordovaHello
```

できたら、ビルドしてみる。
今回はブラウザ版

```
cordova build browser
```

できたら、実行する。
ブラウザでCordovaのページが開いたら成功

```
$ cordova run browser
startPage = index.html
Static file server running @ http://localhost:8000/index.html
CTRL + C to shut down
200 /index.html (gzip)
200 /css/index.css (gzip)
200 /js/index.js (gzip)
200 /cordova.js (gzip)
200 /img/logo.png
200 /cordova_plugins.js
200 /favicon.ico (gzip)
```


## Androidビルド環境をつくる

### 必要なもの
それぞれインストール
- Android Stdio
- JDK

Windowsだと%JAVA_HOME%と%PATH%の設定確認
version確認しておくこと。

```
$ java -version
java version "1.8.0_221"
Java(TM) SE Runtime Environment (build 1.8.0_221-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode)
```

このあとビルドコマンドを打つのだが、JDKやAndroid studioの状況によりエラーがでたりする。
遭遇したのは
- Android SDK Build-tools は19以上が必要
- Android API 28がみつからない
とでたので、Android SDK Managerでポチポチと入れた。

```
$ cordova build android
Checking Java JDK and Android SDK versions
ANDROID_SDK_ROOT=undefined (recommended setting)
ANDROID_HOME=\Android\android-sdk (DEPRECATED)
Subproject Path: CordovaLib
Subproject Path: app
 
（中略）
 
BUILD SUCCESSFUL in XX
XX actionable tasks: XX up-to-date
Built the following apk(s):
        $ d:\var\labo\CordovaHello\platforms\android\app\build\outputs\apk\debug\app-debug.apk
```

これで、成功。
あとは、このapkをエミュレータなり、実機にインストールすればOK。

次回は、リンクタグで内外のサイトを行き来させてみる（たぶん）