OmniAICreator/Qiita-1.07M huggingface dataset:
Redux入門

#Reduxってなに？

ReduxとはReactと相性が良いフレームワークのことです。
Redux単体で利用することも可能ですが、ReactとReduxの組み合わせは鉄板でしょう。
stateを容易に管理することの出来るReduxですが、大規模なアプリケーションになればなるほど効果を発揮してくれそうです。

#Reduxアプリを構成する機能ってなに？

Reduxを使ったアプリはAction,Reducer、Storeによって構成されています。

##Actionとは

何がおきたのかという情報を持つオブジェクトです。

ActionをStoreへ送信（dispatch）すると、Storeのstateが変更されます。
stateの変更ではActionが必ず必要となります。
stateへ通じるルートを攻略する第一段階、まるで門番のような立ち位置の機能ですね。


```js
const action = {
  type: 'SET_wanko',
  text: 'トイプードル'
};
```

Actionではどういうタイプのアクションなのかを明示するためtypeプロパティが必要となります、他と区別できないと何がなんだかわからなくなりますもんね。

逆に言えばこのActionはその程度の情報しか持っておらず、どのようにstateを変更するのか知らない存在なのです。


##Reducerとは

上記したSET_wankoというタイプのアクション受けて、storeから受け取ったstateを変更して返す純粋関数です。
Reducer内では引数変更したり、API呼び出したり、Math.random()等の純粋関数以外の関数を呼び出してはいけません。
結果が毎回同一になるような操作しか扱えないのです。

stateをどう変更するのかactionでは決めれなかったことを指定しています。


```js
function triming(state = [], action) {
  switch (action.type) {
    case 'SET_wanko':
      return state.concat([{ text: action.text, completed: false }]);

    default:
      return state;
  }
}
```


##Storeとは

Storeとはアプリケーションの全てのstateを保持するオブジェクトです。

dispatchされたActionと保持するstateをreducerに渡してstate変更に一役買う立場の存在で、ボスのような風格ですね。
Storeの複製はダメです、ボスは一人だけなのです。
又、stateの変更は必ずActionを経由してください、バグの特定が困難になるのを防ぐためです。
ボスに会うためにはまず名乗って（Action type）からが礼儀ってもんです。


```js
// Action
const action = {
  type: 'SET_wanko',
  text: 'トイプードル'
};

// Reducer
function triming(state = [], action) {
  switch (action.type) {
    case 'SET_wanko':
      return state.concat([{ text: action.text, completed: false }]);

    default:
      return state;
  }
}

// Store
const store = Redux.createStore(triming);

// Actionをdispatchする
// Reducerであるtodosが実行され、Storeが保持しているstateが変更される。
store.dispatch(action);

// stateを取得する
console.log(store.getState()); 
```
React上でtailwindcssを使いたい！

## この記事について
今話題になってるらしいCSSフレームワークの「Tailwindcss」をReactで使ってみるためのまとめ。

##そもそもTailwindって
CSSフレームワークの一つです。
下のGifを見ればわかりやすいと思いますが、要素に対してclassを指定することでスタイルを適用できます。
https://tailwindcss.com/
![screen.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/fc45e921-3a98-0de4-ae6f-3605445134e3.gif)

## 開発環境
- VsCode
- create-react-appした状態
- npm 6.12.1

## インストール手順
###パッケージインストール
対象プロジェクトのpackage.jsonがあるフォルダで下記コマンドを実行。

```
npm install -D tailwindcss@npm:@tailwindcss/postcss7-compat @tailwindcss/postcss7-compat postcss@^7 autoprefixer@^9
```

```
npm install postcss-cli autoprefixer --save-dev
or
yarn add postcss-cli autoprefixer --save-dev
```

###styles.css作成
tailwindcssのいろいろをインポートした.cssファイルを作成します。

```styles.css
@tailwind base;

@tailwind components;

@tailwind utilities;
```

###package.jsonにビルド用のスクリプトを作成し実行

```package.json
"scripts": {
    "start": "react-scripts start",
    "build:tailwind":"tailwind build src/styles.css -o src/tailwind.css",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
```

```
npm run-script build:tailwind
```

そうすると、tailwind.cssが作成される。

###buildされたtailwind.cssを任意のファイルでインポート

```index.js
import './tailwind.css';
```

##動作確認
任意のコンポーネントに下記コードを張り付けて、正常にスタイルが適用されてるか確認します。

```App.js
import React from "react";

function App() {
  return (
    <div className="App">
      <div class="max-w-sm rounded overflow-hidden shadow-lg">
        <img
          class="w-full"
          src="https://source.unsplash.com/random/1600x900/"
          alt="Sunset in the mountains"
        ></img>
        <div class="px-6 py-4">
          <div class="font-bold text-xl mb-2">The Coldest Sunset</div>
          <p class="text-gray-700 text-base">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit.
            Voluptatibus quia, nulla! Maiores et perferendis eaque,
            exercitationem praesentium nihil.
          </p>
        </div>
        <div class="px-6 py-4">
          <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">
            #photography
          </span>
          <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2">
            #travel
          </span>
          <span class="inline-block bg-gray-200 rounded-full px-3 py-1 text-sm font-semibold text-gray-700">
            #winter
          </span>
        </div>
      </div>
    </div>
  );
}

export default App;
```

こんな感じになってたら成功です。
（画像はrandomでunsplashAPIから取ってきてるので変わってるはずです。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502798/61a3e193-9c4a-7e92-12c5-2a6cb657f4a1.png)

##最後に
bootstrapはなんも考えなくても適当にクラスつけてれば、いい感じのスタイルにできてたのに比べて、tailwindcssはしっかりCSS理解してクラスつけないとうまくいかんなーって所感です。
tailwindcss自体もうちょい勉強せんとなーって思いました。

また細かいtaiwindcssの使い方は記事にまとめます。

##参考記事
https://blog.logrocket.com/create-react-app-and-tailwindcss/
https://qiita.com/zzzzz/items/68461080515ec1012980
bootstrap スマホ対応を意識

## 参考サイト

http://preview.themeforest.net/item/sunastro-bootstrap-4x-mobile-html5-template/full_screen_preview/23860747?_ga=2.27479228.1279425199.1576327099-1572901211.1575218102

## jumbotron トップページするキャッチコピーのやつ && container

- container
  - pcは横並び
  - spは縦並び


## conainer


- container
幅によって横幅が変わるらしい

```
|  | Extra small |
|:--|:--|:--|:--|:--|:--|
| <576px | Small |
| ≥576px | Medium |
| ≥768px | Large |
| ≥992px | Extra large |
| ≥1200px |
| max-width | 100% | 540px | 720px | 960px | 1140px |
```

- .container-fluid 

横は常に100%

## グリッドシステム

- 下記を見ると`col`がスマホかな？

```
.col- (extra small devices - screen width less than 576px)
.col-sm- (small devices - screen width equal to or greater than 576px)
.col-md- (medium devices - screen width equal to or greater than 768px) # スマホ横幅は750pxでOKらしい 2018年の記事
.col-lg- (large devices - screen width equal to or greater than 992px)
.col-xl- (xlarge devices - screen width equal to or greater than 1200px) # macpro width 1400  1/2 700
```

- こんな感じで普通にやると

```html
<div class="container">
      <div class="row">
        <div class="col-sm-4">
          <h3>column</h3>
          <p>hello</p>
        </div>
        <div class="col-sm-4">
          <h3>head</h3>
          <p>hello</p>
        </div>
        <div class="col-sm-4">
         <h3>yahoo</h3>
         <p>hello</p>
        </div>
      </div>
```

- pc

![スクリーンショット 2019-12-14 17.20.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286971/81d95fb7-7567-beae-ad06-93746c7265b4.png)


- sp

spも
縦で表示されてしまう

![スクリーンショット 2019-12-14 17.22.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286971/c3ffe902-882c-7645-cda7-8fce7f4abce7.png)

- col-3を追加するとspの時も横になる

```html


 <div class="container">
      <div class="row">
        <div class="col-sm-4 col-3">
          <h3>column</h3>
          <p>hello</p>
        </div>
        <div class="col-sm-4 col-3">
          <h3>head</h3>
          <p>hello</p>
        </div>
        <div class="col-sm-4 col-3">
         <h3>yahoo</h3>
         <p>hello</p>
        </div>
      </div>
    </div>
```

![スクリーンショット 2019-12-14 17.23.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286971/b9335600-1207-4cab-a93f-7ba4964ac44e.png)



```html

 <div class="container">
      <div class="row">
        <div class="col">
          <h3>column</h3>
          <p>hello</p>
        </div>
        <div class="col">
          <h3>head</h3>
          <p>hello</p>
        </div>
        <div class="col">
         <h3>yahoo</h3>
         <p>hello</p>
        </div>
        <div class="col">
            <h3>head</h3>
            <p>hello</p>
          </div>
          <div class="col">
           <h3>yahoo</h3>
           <p>hello</p>
          </div>
      </div>
    </div>
```



## tutorial

https://www.w3schools.com/bootstrap4/bootstrap_containers.asp
PyTorchでChainerのTrainerを使えるライブラリ作った

　今月頭、PFNが研究開発で用いる深層学習フレームワークをChainerからPyTorchに移すことを[発表](https://preferred.jp/ja/news/pr20191205/)しました。これを機に自分が使うフレームワークもPyTorchに移行させるつもりですが、Chainerの使い勝手が良かったところを置いていくのが名残惜しいです。特に[Trainer](https://docs.chainer.org/en/stable/reference/generated/chainer.training.Trainer.html)とか。

　そこで、ChainerのTrainerを、PyTorchに持っていくことにしました！　こちらがそのライブラリです。
　[pytorch-trainer | PyTorch's Trainer like Chainer's Trainer](https://github.com/Hiroshiba/pytorch-trainer)

pipでインストールできます。

```bash
pip install git+https://github.com/Hiroshiba/pytorch-trainer
```


この記事では、Chainerをforkして作成したこのTrainerライブラリを紹介します。

## 特徴
　[MNISTを学習するサンプルコード](https://github.com/Hiroshiba/pytorch-trainer/blob/ead570f399a5d285dcf90661098d94800b1242dd/examples/train_mnist.py)を使って特徴を紹介していきます。

### ChainerのTrainerとほとんど同じインターフェースで扱える

 直感的に使えるようにするため、ChainerのTrainerと同じインターフェースにすることを目指しました。PyTorchのOptimizerがモデルを持てないので直接Trainerに与えること以外は、ほぼ同様に使えると思います。

```python
# Iterator
train_iter = pytorch_trainer.iterators.SerialIterator(train, batchsize)

# Updater
updater = training.updaters.StandardUpdater(
    train_iter, optimizer, model, device=device)

# Trainer
trainer = training.Trainer(updater, (epoch, 'epoch'), out=out)
``` 

### Reporterも使える
　Reporterも同じインターフェースで使えます。

```python
class Classifier(nn.Module):
    def __init__(self, predictor):
        super(Classifier, self).__init__()
        self.predictor = predictor

    def forward(self, x, t):
        y = self.predictor(x)
        loss = F.nll_loss(y, t)
        reporter.report({'loss': loss}, self)
        acc = accuracy(y, t)
        reporter.report({'accuracy': acc}, self)
        return loss
```

### Extensionも使える
　Evaluatorを含むExtensionを頑張って引き継ぎました。Scheduler関連は、PyTorch側に別のものがあるため移植していません。

```python
# Evaluator
trainer.extend(extensions.Evaluator(test_iter, model, device=device),
               call_before_training=True)

# Snapshot
trainer.extend(extensions.snapshot(n_retains=1, autoload=autoload),
               trigger=(frequency, 'epoch'))

# LogReport
trainer.extend(extensions.LogReport(), call_before_training=True)

# PlotReport
trainer.extend(
    extensions.PlotReport(['main/loss', 'validation/main/loss'],
                          'epoch', file_name='loss.png'),
    call_before_training=True)

# ProgressBar
trainer.extend(extensions.ProgressBar())
```

### 保存・読込ができる
　Trainerにあったserialize機能を全てPyTorch用に書き換えました。これにより、Trainerをまるごと保存して、あとから学習を再開することができます。

```python
# Resume
trainer.load_state_dict(torch.load(resume_pth))
```

---

　以上です。大体の学習タスクはTrainerで解決できると思います。インストールは以下のコマンドで可能です。

```bash
pip install git+https://github.com/Hiroshiba/pytorch-trainer
```

　PyTorchのDataLoaderが使えなかったり、Schedulerが使えなかったりと若干の不便が残っています（2020/05/24追記 Schedulerを追加しました）。私はPyTorchにあまり詳しくないので、ちょっとわかるって方はぜひ気軽にPullRequestを送ってください！
Docker Compose で AWX + Gitea 環境を作る

## はじめに

AWX は Docker Compose によるインストール方法をサポートしています。ただ、docker-compose.yml を用意して docker-compose コマンドを実行するのではなく、[ansible-playbook コマンドを使用する方法](https://github.com/ansible/awx/blob/devel/INSTALL.md#docker-compose)になっています。何故 docker-compose コマンドを使用しないのでしょうか？

また、AWX だけ準備できてもソースコードリポジトリのコンテナが無いと、Github 等の既存のサービスが必要です。環境次第では何らかのソースコードリポジトリをデプロイする必要があるでしょう。個人的には Github クローンの１つ、[Gitea](https://gitea.io/)がお勧めです。Go 言語で開発されており、GitLab より高速に動作します。

無いなら作ってしまいましょう、という事で、docker-compose.yml を用意するシェルスクリプトを作成しました。もっと良い方法があるのかも知れません。あればコメント欄で教えてください。

## 準備

1. docker-compose パッケージをインストールします。
   * [CentOS でのインストール例](https://github.com/NaturalHistoryMuseum/scratchpads2/wiki/Install-Docker-and-Docker-Compose-(Centos-7))
   * [Ubuntu でのインストール例](https://phoenixnap.com/kb/install-docker-compose-ubuntu)
2. docker サービスを起動します。
3. [こちら](https://gist.githubusercontent.com/yosshy/c46dc1aff3a81996c216b01924e791be/raw/2ea09dda55d5be0746d22ffe8bed3460895c8996/gen-dc-awx-gitea.sh) からシェルスクリプトをダウンロードします。
4. シェルスクリプトの冒頭にある変数を適切に変更します。
5. シェルスクリプトを実行して docker-compose.yml を作成します。

   ```
   $ bash gen-dc-awx-gitea.sh
   ```

6. docker-compose コマンドを実行します(1回目)

   ```
   $ sudo docker-compose up
   ```

   各コンテナの実行ログがコンソール上に表示されます。そのうち、AWX 用の DB マイグレーションが実行されるので、マイグレーションが終わるまで待ちます。
7. CTRL-C で一旦実行を止めます。
8. docker-compose コマンドを実行します(2回目)

   ```
   $ sudo docker-compose up -d
   ```

後はサービスにアクセスするだけです。

## 使用

デフォルトでは、以下のポートが使用されます。

* 443/TCP：AWX WebUI (HTTPS)
* 8443/TCP: Gitea WebUI (HTTPS)
* 10022/TCP: Gitea Git (SSH)

Gitea 画面の右上の sign-in をクリックすると、初回はサーバのセットアップ画面になります。デフォルト値は事前に docker-compose.yml で設定済みなので、ほとんど設定値を変更する必要はありませんが、管理者アカウントを追加するのであればこの画面で設定します。

## 利用上の注意

* AWX から見て Gitea のホスト名は gitea になります。ですので、AWX のプロジェクト登録時に Gitea 上の Git リポジトリを入力する際、URL のホスト名部分は Gitea の FQDN ではなく gitea にする必要があります。
UE4でのリニア→sRGB変換

小ネタです。

トーンマップより前のポストプロセスを編集しているシチュエーションで、一時的にリニアからsRGBにしたい時があります。

その際、下記のようにしているコードをたまに見かけますが、これは誤差が大きく、UE4が使っている変換とも違うため、最終的にリニアに戻して出力しても少しずれた絵が出てしまいます。
```
pow(color,1/2.2)
```
※誤差の詳細は参考に張ったリンク先のブログ記事がわかりやすいです

UE4が内部で使っている変換の実装は下記にあります
Engine\Shaders\Private\GammaCorrectionCommon.ush

この中にある、LinearToSrgbBranchlessやLinearToSrgbBranchingを参考にしたり、カスタムノード経由で使用するのがいいでしょう。

注意しなければならないのは、最終的な出力がsRGBとは限らないことです。SDRかHDRかで変換の仕方が変わりますし、SDRでもsRGBかRec709で違います。
これに関して、私は現在の状況をMPCに入力し、マテリアル内でそれを見て分岐するようにしています。

今回はメモがてら小ネタを書いてみましたが、色空間については自分もまだまだ知識不足なので、間違いなどあればご指摘頂けると助かります。

参考
[chilliant](http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html)
Google Playでアプリにタグが付けられるよ - 翻訳がないなんてあんまりだ

気づいたら、カテゴリーの他に、タグが最大5つ付けられるようになったGoogle Play。
評価の方法が変わった頃に追加されたのかもしれないが、ごく最近気付いたので、正確なところはわからない。

どの程度ASOに影響があるかわからないけど、タグが追加できるなら、すでにリリース済みのアプリにも付与しようぜ！…ということで、検討することに。

なお、リリース済みのAndroidアプリは[34タイトル](https://www.pro-japan.co.jp/sp/)ほどあるらしいんですよね…。

とりあえず、どんなタグがあるのか調べよう。

#誰かが一覧作ってるはず！
できれば自分では作りたくないよね。ってことで、ここは集合知にお伺いを立ててみるが、検索しても、それらしいものは見つからなかった。

Googleヘルプの[アプリまたはゲームのカテゴリとタグの選択](https://support.google.com/googleplay/android-developer/answer/113475)も見たけれど、カテゴリーの一覧はあってもタグの一覧はない…ひどい！ひどいじゃありませんか！:tired_face:

しかたない…コピペでリスト作ろうっと。

#簡単にコピペできなかった
多分、コピペで取り出せるよ。…と言ったのは誰だったのか。
![一列にペースト](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44795/5cc6f786-1e47-7994-e1bc-7316f60d1441.jpeg)
…。
HTML構造見てみるか。
![容赦ないHTML構造](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44795/b78b5053-ee0a-144a-7b9b-ed963c4ff1c0.jpeg)
謀ったなっ！謀ったな！Google！
なんで構造がリストなんだよ！

いや、間違ってはいないんだよ！間違ってないけど、コピペさせない意地悪されている気分… 。
なぜ、そこはTableでコーディングしないんだ…。

#説明文が全部英語！
ひとまず、手動でリストに整えたよ…[^手動でリスト] 。疲れたよ。
…説明文も取り込んでみよう。
[^手動でリスト]: これを書き終わった頃、DevToolsのConsole使えばいいんじゃね？と寝る前に思い浮かんだ。使わなくても知っておいた方が良い、という良い見本。

![中途半端に翻訳済](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44795/98b84bb2-f63a-5b83-145d-c51ecf2974c2.jpeg)
…。
なんでっ！なんで！そこは翻訳なしなんだよ！
関連タグは中途半端に翻訳されてるのに！
レビューも変な翻訳[^変な翻訳]してるのに！

[^変な翻訳]: 最近のGoogle翻訳はかなり精度が高いと思う。Google Play Consoleで表示される外国語のレビューは、自動翻訳されて表示されるのだが、なぜか悲しいほど精度が低い。

#俺たちのGoogle翻訳で日本語にする
不確かなタグをチョイスしたら恨まれそうだ。ここは、素直に翻訳かけていくしかない。

そして、やっぱりここも、俺たちの[Google翻訳](https://translate.google.co.jp/?hl=ja)！

…なんだけど、Google翻訳さんも完璧ではない。
ものすごく意味不明な日本語訳を教えてくれることがある。

そういう時に助けてもらってるのが、[みらい翻訳](https://miraitranslate.com/trial/)と[英辞郎](https://www.alc.co.jp/)。

みらい翻訳は、比較的お堅い文章の多い規約などの翻訳が上手い気がする。
それでも意味不明な翻訳になる時は、英辞郎さんで単語ごとに翻訳。

公式ヘルプの中には、たまーに綴りが間違っていて、原文がそのまま吐き出される事がある。
いろいろな方向から翻訳をかけると、いい感じの日本語になります（時間はかかる）。

それぞれの利点を生かして利用しよう。

#ヘンな翻訳付きリスト作った
[GooglePlayタグ一覧](https://docs.google.com/spreadsheets/d/17ct5s4lQavdGZpQUZ_nHU2eZl0M2XhCfpIM_SUybQPQ/edit?usp=sharing)

作ったんだけどね。作ったんだ。
でも問題ある。

Google Play Consoleではできる、絞り込みができないのが超面倒！
あと、やっぱり翻訳が微妙に変！でも直すの面倒！ここまで作るのに、約1人日かかった！
とりあえず、意味分かればいいよね！そのうち直すよ！

あと、たまに英語以外の単語が紛れていたんだが…あれはなんなのか。
がんばって翻訳かけたけど、結局意味不明なものがいくつかあった。

ちょっと面白いタグがあった。
**Truck racing**：トラックが主役のレーシングゲーム。…というもの。
Androidアプリには、個別にタグができるほど、トラックが主役のゲームが多いのかな？とか想像した。

会社で使っているアカウントのデーターをそのまま公開するのもアレなので、リストの内容を自分のアカウントに持ってきて、若干の手直しをした。
元のリストでは、関連タグが複数あってもひとつのセルに入れていたけれど、ひとキーワードひとセルにした。

日本語タグは14個、その他はすべて英語タグである。
128もタグあるのかよ…。

## 悲劇はいつでも起こる
![燃え尽きた人](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44795/2b3813d2-0fe1-0015-03f3-2931d99e7111.png)

この記事をUPした2日後。
…なんか、タグ、ない。

設定しようと思っていたタグが消えてるるるるるるーーーー…。
まーじーでーすーかー…。

**Logic puzzle**というタグが消えてました。ううううう。

外資系の会社は、切る時は思い切りが良いので、本当に…本当に…ううううう。
【Python】リスト 再利用しそうなコード


# リスト作成
## 空リスト
~~~
# 空リストを作成
empty = []　　　　　　#  []
## 任意の値・要素数で初期化
n = [0] * 10              #  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# 2次元配列（リストのリスト）を初期化
n = [[0] * 4 for i in range(3)]　　　#  [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
【注】
data=[[list(range(1,9))]*3]*3　# この形式だと同じものを参照することになるので下記に
data=[[list(range(1,9)) for i in range(3)]for i in range(3)]
~~~

## 連番リスト
list(range(開始, 終了, 増分))
## シャッフル
random.shuffle(リスト)

# 加工

## 抽出・切り出し
~~~
# スライス
# 最初は＋１され。最後はそのまま
a = [1,2,3,4,5,6,7,8,9]
print(a[1:4])　　　# [2, 3, 4]
~~~

## 取出し
~~~
d=[2]
print(d[0])　　　# 2

a = [[1],[2]]
print(a[0][0])　　# 1
~~~

## 追加
~~~
list.append(100)
~~~
list = list.append(row.split('-'))だとNG
'NoneType' object has no attribute 'append'

## 削除
~~~
list.remove(100)
~~~

## 結合
~~~
print（[1, 2, 3] + [4, 5, 6]）
~~~

# 操作

## カウント
~~~
d=[0, 0, 5, 0, 3, 0, 6, 0, 0]
print(d.count(0))　　　# 6
~~~

## 差分
~~~
set(リスト[i][j])-set(data[i])
~~~

## 要素同士の掛け合わせ他
~~~
li1 = [1, 3, 5]
li2 = [2, 4, 6]

combine = [x * y for (x, y) in zip(li1, li2)]
#  [2, 12, 30]
~~~

## コピー
1次元の場合、「list2=list1」とすると参照渡しのせいで、list2自体を書き換えてしまうとlist1も書き換えられるので、下記のように記述する。
2次元以上の場合は、このように記述できないのでdeepcopyを使う。

~~~
#  配列が1次元の場合
list2 = list1[:]
#  2次元以上の場合
import copy
list2 = copy.deepcopy(list1)
~~~

# おまけ
~~~
# for-rangeの注意
for x in range(3):　　　=for x in [0,1,2]:
for x in range(1,3+1):　=for x in [1,2,3]:

# 0/1入れ替え
a=abs(a-1)

# 別リストを元にソートする
ListA = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
ListB = [ 2,   1,   5,    0,   7,   3,   6,   4,   8]

Z = [x for y,x in sorted(zip(ListB,ListA))]
print(Z)  # ['d', 'b', 'a', 'f', 'h', 'c', 'g', 'e', 'i']

# フォルダリスト
import os

フォルダ="\\\\10.29.17.4\\RawData\\"

def フォルダリスト取得(フォルダ):
    path=フォルダ     # カレントディレクトリ内のファイル名
    files = os.listdir(path)
    files_dir = [f for f in files if os.path.isdir(os.path.join(path, f))]

    for i in files_dir:
        print(i)

フォルダリスト取得(フォルダ)

# ファイルリスト
import os

def ファイルリスト取得(フォルダ):
    ファイルリスト = os.listdir(フォルダ)     # カレントディレクトリ内のファイル名
    for i in ファイルリスト:
        item = i.split(".")
        if (item[1] == "CSV") & (i[:2]=="C0"):
            print(i)
        
ファイルリスト取得(フォルダ)

# サブフォルダ構造読み込み
import os

for folder, subfolders, files in os.walk(フォルダ):
    if subfolders==[]:
        print(folder)

# ファイルの有無判定
import os

if os.path.isfile(FileName)==False:
        return
~~~
Laravelで.envに問題がある場合はデプロイ時にエラーにする

# 前置き

今時のWebアプリケーション開発では、開発環境と本番環境はほとんど同じ構成になっている上、VCSで一元管理されているソースコードを自動デプロイツールでデプロイするので、デプロイ時に問題が起こることはなかなかありません。

ですが中にはどうしても開発環境と本番環境で同等にできず、その上VCSで管理することもできず、デプロイ時に問題を起こしがちなものもあります。

Laravelにおいては`.env`がそれです。このファイルは環境ごとに変わるデータを入れるのが目的のため開発環境と本番環境で同じものを使うことは基本的にできない上、APIのキー等の秘密情報を入れることも多く、VCSで管理することもできません。

```php:.env
# .envの一部。データベースの接続情報などが記載されている。
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
```

実際、`laravel new`して自動生成される`.gitignore`ではこのファイルが除外リストに入っています。

一度用意した後は頻繁に変更するものではありませんが、それでもたまにこのファイルに入れておきたいデータが増えることがあります。

そのような変更の後には`.env`を手動で変更した上でデプロイする必要があります。`.env`の変更を忘れると、場合によっては致命的な問題になります。外部の決済システムを変更した後、新しい決済システム用の認証情報がない場合、どうなるでしょう？

# 本題

今日は[Laravel Env Validator](https://github.com/melihovv/laravel-env-validator)と[Laravel Deployer](https://github.com/lorisleiva/laravel-deployer)を使ってこのような問題をできる限り防ぐための方法をご紹介します。

Laravel Env Validatorは、`.env`(というか環境変数自体)をLaravelのヴァリデーションルールを使ってヴァリデーションする機能を提供するパッケージです。

`config/laravel-env-validator.php`に以下のように記述して、

```php:config/laravel-env-validator.php
<?php

return [
    'rules' => [
        'APP_ENV' => 'in:local,production',
        'APP_KEY' => 'required',
        'APP_DEBUG' => 'boolean',
    ],
];
```

`php artisan config:env-validator`と実行すると、環境変数が検証され、たとえば上記の場合だと、`APP_ENV`がtestingだったり、`APP_KEY`が未設定の状態だったりすると以下のようなエラーを出します。

```
In EnvValidator.php line 31:

  The .env file has some problems. Please check config/laravel-env-validator.php
  The selected APP_ENV is invalid.
  The APP_KEY field is required.
```

注意としてはconfigとして記述するため、`Illuminate\Validation\Rule`のルールを使うようなことはできません。というか実際にはできないことはないのですが、`php artisan config:cache`でエラーになってしまうため実用的ではありません。シリアライズできないんですね。ですので複雑なルールを書くような場合は、カスタムルールを用意するのがよさそうです。

さて、これだけでも便利ですが、できればデプロイ時に自動でヴァリデーションさせたいところです。自動で防げるミスは防ぎたいですよね。

そこでLaravel Deployerで以下のように設定します。

まず、`php artisan config:env-validator`を実行するタスクをレシピに書きます。

```php:recipe/artisan-config-env-validator.php
<?php

namespace Deployer;

desc('validate .env');
task('artisan:config:env-validator', artisan('config:env-validator'));
```

次にこのレシピをincludeします。`config/deploy.php`は、`php artisan deploy:init`で事前に用意しておいてください。

```php:config/deploy.php
    'include' => [
        'recipe/artisan-config-env-validator.php',
    ],
```

最後に、このタスクを実行するよう設定します。

```php:config/deploy.php
        'ready' => [
            'artisan:storage:link',
            'artisan:view:clear',
            'artisan:cache:clear',
            'artisan:config:env-validator',
            'artisan:config:cache',
            'artisan:migrate',
        ],
```

`artisan:config:cache`の前に実行するのが肝です。config:cacheされた後は環境変数は読み込まれないため、環境変数を直接見ているLaravel Env Validatorのヴァリデーションは正常に動作しません。

後はその他必要なデプロイのための設定をして、デプロイするだけです。.envをヴァリデーションして問題なければデプロイが成功しますし、そうでなければ失敗します。これにより、適切なルールを用意している限り、.envの記述ミスで問題のあるデプロイをしてしまうことがなくなります。
ロケットっぽいのを作るか

#1.はじめに
SpaceXとかBlue Originとか再利用型ロケットを開発して打ち上げてます。
じゃ、cursesで作ってみますか。

#2.こんな感じ

<img width="989" alt="sx.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324221/270f7c75-f3ba-6662-7d39-4001a4bd1c90.png">

<img width="581" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324221/6438bb63-7092-7a6e-0f47-38b6ba2b7bc7.png">

打ち上がり、サブのロケットが降りてきます、そしてまた打ち上がります。

Ctl-C入れると終わります。

ソースは[ここ](https://github.com/araki-m/sx)

ベタがきなので、気が向いたらリファクタします。
プロジェクト起動したら画面真っ黒[Swift][Info.plist configuration "Default Configuration" for UIWindowSceneSessionRoleApplication contained UISceneDelegateClassName...]

## 状況
プロジェクトをビルドしたら

```
Info.plist configuration "Default Configuration" for UIWindowSceneSessionRoleApplication contained UISceneDelegateClassName key, but could not load class with name "TinderSwipeSample.SceneDelegate".
[WindowScene] There is no scene delegate set. A scene delegate class must be specified to use a main storyboard file.
```

こんなエラーとともに実機の画面が真っ黒に。。。。

- `is initial viewcontroller`は全てチェック入れている
- `TARGETS`->`Deployment info`->`Main Interface`の`Storyboard`を変更しても真っ黒なまま

## 原因
`SceneDelegate.swift`ファイルを消去してしまっていた
->`info.plist`で`Configuration Name`を`Default Configuration`にしている場合は消去してはいけないらしい
->以前は消去しても実行できていたのでverが新しいとこのバグが起きるかもしれません。はっきりとはわかりません

`SceneDelegate.swift`はSwiftUIで使うもの->`Storyboard`しか使わないから消してもいいやーと思っていました。皆さんも気をつけて。
(エラー文にはscene delegateがないよーみたいなこと書いてくれてるんですがね。。。)

## 参考
**・[SwiftUIを触って分かったこと：①初期画面の設定方法 - Qiita](https://qiita.com/rc_code/items/795ddadb98dfa09d10e6)**
ツリー構造のモデルの内容をQMLのListViewで表示する

# はじめに
この記事は [Qt Advent Calendar 2019](https://qiita.com/advent-calendar/2019/qt) の16日目の記事です。
タイトルどおりの内容で捻りも何も無いですが、QML側でDelegateModelを使うとListViewのdelegateプロパティが機能しなくなる辺りでちょっと残念な気持ちになったりしたので自分のメモ書き程度に。Qt5.6を使用しています。

# 実装
早速実装いきます。

## モデル
main.cppでモデルを構築してQML側へcontextPropertyとして登録しておきます。今回はモデルの中身にはこだわらないのでQStandardItemModelでささっと作っておきます。
モデルの中身をQML側から見るとこんなカンジです。

- {display: "item_1"}
    - {display: "item_1_1", decoration: Qt.red}
    - {display: "item_1_2", decoration: Qt.green}
    - (中略)
    - {display: "item_1_1000", decoration: Qt.darkCyan}
- {display: "item_2"}
    - {display: "item_2_1", decoration: Qt.red}
    - {display: "item_3_2", decoration: Qt.green}
    - (中略)
    - {display: "item_3_1000", decoration: Qt.darkCyan}
- (中略)
- {display: "item_100"}
    - {display: "item_100_1", decoration: Qt.red}
    - (後略)

```cpp:main.cpp
    // [1] サンプル用のツリー構造のモデルを作る
    QStandardItemModel model;
    for (int i = 0; i < 100; ++i) {
        auto row = new QStandardItem(QString("item_%1").arg(i+1));
        QList<QStandardItem*> children;
        for (int j = 0; j < 1000; ++j) {
            auto child = new QStandardItem(QString("item_%1_%2").arg(i+1).arg(j+1));
            child->setData(QColor(static_cast<Qt::GlobalColor>((j % 10) + Qt::red)), Qt::DecorationRole);
            children.append(child);
        }
        row->appendRows(children);
        model.appendRow(row);
    }
    view.rootContext()->setContextProperty("dataModel", &model);
    // [1] ここまで
```

## QML
ツリー構造の親子を見せるためにListViewを横並びに2つ並べました。
左の ListView で全親アイテムを表示し、左の ListView で選択されたアイテムの子アイテムを右の ListView に表示します。
ポイントは右の ListView の model プロパティに `DelegateModel` を使っているところで、 rootIndex プロパティによって元のモデルのどこを見せるのかを制御できます。 ~~QAbstractItemView::setRootIndexはどこに行ったんだよ~~
DelegateModel を使うと右の ListView の デリゲートは DelegateModel の delegate プロパティで指定することになります。 ListView の delegate プロパティにセットしたコンポーネントは使われないことに注意が必要です。

```qml:main.qml
// 右側のリスト
ListView {
    id: rightList
    Layout.fillHeight: true
    Layout.preferredWidth: 400
    // [2] modelにDelegateModelを使う
    model: DelegateModel {
        rootIndex: leftList.model.index(leftList.currentIndex, 0) // [2] rootIndex指定
        model: leftList.model
        delegate: rightDelegate // [2] DelegateModel.delegate でデリゲート指定
        onRootIndexChanged: rightList.positionViewAtBeginning()
    }
    // delegate: rightDelegate // [3] 効かない
    highlight: highlight
    highlightMoveDuration: 200
    Keys.onUpPressed: decrementCurrentIndex()
    Keys.onDownPressed: incrementCurrentIndex()
    Keys.onLeftPressed: leftList.focus = true
    keyNavigationWraps: true
}
```

# 実行結果
こうなります。100×1000で100000アイテム程度なら、中身も単純なのでストレスなく動きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11596/d686fbbd-3a96-717f-3324-e64b3fce34d8.png)

# ソースコード
ソースコードは [github](https://github.com/Atsushi4/qt_users_treemodel_qml) に公開しています。

# おわりに
QMLのListViewにDelegateModelを使用してrootIndexを指定すればツリー構造のデータを表示できます。 DelegateModel.modelIndex と DelegateModel.parentModelIndex を使うとファイルマネージャーのフォルダ移動のようなことも実装できるんじゃないかな、かな。
wordpressまとめ

##スラッグ

設定 
   - パーマリンク
      - 投稿名
へ変更

## メニュー出し分け
	管理メニュー
		外観 - メニュー
		
		出し分けするメニュー複数作成
		
	header.php
		
		if (is_user_logged_in()) {
			$args = array(
				'menu' => 'main-menu',
				'menu_class' => 'nav navbar-nav',
				'container' => false,
			);
		} else {
			$args = array(
				'menu' => 'menu-02',
				'menu_class' => 'nav navbar-nav',
				'container' => false,
			);
		}

		wp_nav_menu($args);
		
	※ ナビゲーションメニューのcss は　上記 menu_class で設定?

##サイドメニュー出し分け

###sidebar.phpと　sidebar-2.php (出し分け用複数 sidebarファイル用意)

sidebar-2.php に
<?php dynamic_sidebar('Side Widget 2'); ?>
書く

index or page or カスタムテンプレート

####出し分け
<?php get_sidebar(); ?>
<?php get_sidebar(2); ?>



##固定ページ テンプレート変更

下記両方ともslugの指定が必要

① テンプレート階層 page-{slug名}

page-{slug名}.php　ファイルをつくる

② 管理画面 テンプレートの指定から

template

/**
Template Name: 固定ページの新規テンプレート１
**/

で指定して

管理画面、テンプレートの選択で指定

## エスケープ
1. esc_url
2. esc_html
3. esc_attr


cssのurlに付加する文字列

 filemtime ( get_template_directory() . '/style.css' )

 更新時間 UNIX TIME ?ver=15555503967 ...
 style.css を更新する度に変化

    <time datetime="<?php echo esc_attr( get_the_date( DATE_W3C ) ); ?>">
    <?php echo esc_html( get_the_date() ); ?>
realsense-rosのインストールに躓いた話

realsense-rosのインストールに少し詰まったので備忘録です。

## 環境
Ubuntu 18.04 LTS
ROS melodic

##問題
[UbuntuでIntel Realsense D415を使えるようにするまで(ROSあり・なし両方)](https://qiita.com/kei_mo/items/c0387b7d277948451881)という記事を参考にrealsense-rosのインストールを進めていたのですが、`$ catkin_make clean`を実行したところ、下記のようなエラーが発生しました

```
CMake Error at /opt/ros/melodic/share/catkin/cmake/catkinConfig.cmake:83 (find_package):
  Could not find a package configuration file provided by
  "ddynamic_reconfigure" with any of the following names:

    ddynamic_reconfigureConfig.cmake
    ddynamic_reconfigure-config.cmake

  Add the installation prefix of "ddynamic_reconfigure" to CMAKE_PREFIX_PATH
  or set "ddynamic_reconfigure_DIR" to a directory containing one of the
  above files.  If "ddynamic_reconfigure" provides a separate development
  package or SDK, be sure it has been installed.
Call Stack (most recent call first):
  realsense-ros/realsense2_camera/CMakeLists.txt:8 (find_package)
```


##対策
[公式のissue](https://github.com/IntelRealSense/realsense-ros/issues/812)に対策が載っていました。


```
$ apt-get update 
$ apt-get install ros-melodic-ddynamic-reconfigure
```

対策後は特に問題も起きず、無事realsense-rosを実行できました。

## 参考
公式：https://github.com/IntelRealSense/realsense-ros#installation-instructions
データベース探索方法

##参考
「webエンジニアのためのデータベース技術実践入門」　（松信嘉範）

##検索手法
 - 線形探索 
　　　**O(N)の計算量** 
　　　初めから終わりまで順番に検索してデータを探す手法 
　　　検索にかかる時間は文書のサイズに依存する 

 - インデックス探索 
　　　**O(１)の計算量** 
　　　キーとペアで索引を作る 
　　　しかし、索引の桁数が違うため固定長フォーマットにできない 
　　　　→値をハッシュ関数にかけてハッシュ値で保存しておく 
　　　ハッシュ値が同じになる可能性があるので検知する仕組みは必要になる 

| ids | bite |
|:-:|:-:|
|  1 | 1バイト目  |
|  2 | 5バイト目  |
|  3 | 8バイト目  |
 

 - B+Treeインデックス  
　　　**O(log mN)の計算量**  
　　　ワーストケースでのアクセス回数が減らせる  
　　　RDBMSにおける事実上の標準  
**root**  

| ids | branch |
|:-:|:-:|
|  <20000 | ブランチ１ |
|  <40000 | ブランチ2 |
|  <60000 | ブランチ3 |

**ブランチ１**
 
| ids | leaf |
|:-:|:-:|
|  <5000  | リーフ１ |
|  <10000 | リーフ2 |
|  <15000 | リーフ3 |
|  <20000 | リーフ4 |




##更新コストのための最適化
 - 一時的にメモリに保存しておき一気に更新する（MYSQL）  
　　　問題点：インデックス更新ではデータ更新のコストは増える  
　　　ランダムライトよりはるかに効率がいい
 - 並列更新性能を高める  
　　　問題点：整合性を取るためにインデックスの組み替え処理が終わるまで一切の更新を許さない  
　　　パーティション表を作る  
　　　ロックフリーなアルゴリズムが提案されている
バリデーションとは

#バリデーションとは
-パスワードや氏名などの入力値が、保存される前に、その値が有効なものなのか調べる仕組みのことを言う。
-バリデーションは文字数や入力値が空であるなどの条件を指定して、使用することができる。

#例えば

```
validates :name;
```

この様に使うが、クラスメソッドに組み込まれていることが、見る限りだと多そう
LinuxでLANケーブルが抜けたかどうかをチェックする

LinuxでEthernetケーブルが抜けたかどうかを判断する方法。

ネットワークインターフェイス名がeth0の場合、

~~~
cat /sys/class/net/eth0/carrier
~~~

で表示される値で判断できる。0が断線状態。1が活線状態。
なのでこれを監視すれば簡単にケーブルの抜き差しが判断できる。

ただし、sysfsやprocfsなどではinotifyが使えない。なので自分でプログラムで判断する場合は
https://stackoverflow.com/questions/26672414/inotify-add-watch-fails-on-sys-class-net-eth0-operstate
にあるように、netlinkを使ってイベントを取得する必要がある。

ただ、ネットワークインターフェイスが複数ある場合、どのインターフェイスのLANケーブルが抜けたかわからない。
この場合、先に述べた/sys/class/net/eth0/carrierの値と組み合わせたりして判別する必要がある。

もっと良い方法がありそうと思って調べてみたけど、どうもこれだ、って方法が見つからない。

とりあえずこの方法でお茶を濁すことにする。
ZabbixでNode Exporter(Prometheus)の値を監視

Zabbix AdcentCalendar 2019の15日目の記事です。

Zabbixエージェントを使用しなくても、PrometheusのNode ExporterがインストールされているサーバーならZabbixで監視できるよというお話です。


# 追加されてきた機能

Zabbixでは、4.0以降でいくつかの機能が追加されていて、より多様な監視をZabbix標準の機能で実施することができるようになっています。

例えば、「HTTPエージェント」というタイプのアイテム(監視設定)を使用することで、HTTPリクエストを投げて、その結果をアイテムの値とすることができます。これによって、Webサービスなどを呼び出し、その結果内の文字列や値を取り出すことで、正常かどうかやメトリクスを取得することができるわけです。

また、Webサービスなどでは、レスポンスがJSON形式であるため、そこからより柔軟に値を取り出すための機能も強化されています。保存前処理と呼んでいますが、取得した値を加工してからアイテムの値として保存する機能です。
保存前処理の機能は、数値の計算や文字列の変換、先ほど挙げたJSONを加工するための[JSONPath](https://goessner.net/articles/JsonPath/)という機能にも対応したため、Webサービスから受け取った値から柔軟に必要な値のみ取り出して、数値だけであったり特定のアトリビュートの文字列の値を監視することができます。

他にも、Zabbix 4.4では、保存前処理にJavaScriptを使用できるようになったり、[Prometheus](https://prometheus.io/)用の機能拡張が行われています。

それらを活用することで、PrometheusのNode Expoterから情報を受け取って、それを通常のZabbixエージェントと同様に、サーバーの状態を監視することにも使うことができます。

# 監視設定してみよう

Zabbix 4.4では、PrometheusのNode Expoterに対応した監視テンプレートが用意されているので、それを使って監視してみます。

## 導入する環境

今回は、CentOS 8上にNode Exporterをインストールすることとします。
説明を簡単にするため、SELinuxはdisabledにしていますが、適切なポリシーを設定することを検討してください。

## Node Exporterのインストール

Node Exporterの実行ファイルをダウンロードして、/opt/node_exporterディレクトリ以下に配置します。

```shell-session
# wget https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz
# tar zxvf node_exporter-0.18.1.linux-amd64.tar.gz
# mv node_exporter-0.18.1.linux-amd64/ /opt/node_exporter
# ls /opt/node_exporter/
LICENSE  NOTICE  node_exporter
#
```

起動するユーザーを「prometheus」ユーザーにするため、ユーザーを作成します。

```shell-session
# useradd prometheus
```

ユーザーを作成したら、Node Exporterの実行ファイルの所有者をprometheusにしておきます。

```shell-session
# chown -R prometheus:prometheus /opt/node_exporter/
```

自動起動の設定も行います。

```shell-session
# vi /usr/lib/systemd/system/node_exporter.service
# systemctl daemon-reload
# systemctl start node_exporter
```

/usr/lib/systemd/system/node_exporter.serviceの内容は以下のような内容にしてみました。

```
[Unit]
Description=Node Exporter for Prometheus
Wants=network-online.target
After=network-online.target

[Service]
User=prometheus
ExecStart=/opt/node_exporter/node_exporter

[Install]
WantedBy=multi-user.target
```

デフォルトでは、node_exporterは、ポート番号9100で要求を受け付けているので、firewalldの設定でアクセス可能に設定します。

```
# firewall-cmd --add-port=9100/tcp --zone=public --permanent
# firewall-cmd --reload
```

## ホストの登録と監視用テンプレートのリンク

Zabbix上にホストを登録します。

![add-host.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101989/08254a53-5098-1127-5179-b38067d91146.png)


ホスト登録時に、テンプレートへのリンクも追加しておきます。
リンクさせるテンプレートは「Template OS Linux by Prom」です。

![add-host-temp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101989/3b645221-e7f1-8ad9-3edb-30e194cc7328.png)

Node Exporterに接続するためのポート番号などは、テンプレートのマクロに設定されているので、ホストによってポート番号を変更しているような場合は、ホストマクロに設定することで上書きして、それぞれのホストに合わせた情報での監視を行うことができるようになっているようです。

しばらくすると、「監視データ」->「最新データ」で、登録したホストを選択して表示させておくと、監視用の各アイテムの値が取得開始されます。

![item-data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101989/c65ddb8c-1e55-ac60-a2c9-31e8965a4f3f.png)


# 最後に

今回紹介したのはNode Exporterのみでしたが、今後、他のExporter用の監視テンプレートも作成できるかもしれません。
すでに他の方が作成されているかもしれませんが、私自身でも調べて作成できたらなと思ってます。

明日は、誰でしょう？
どなたかよろしくお願いします。
Cloud SQL Proxyをサービスアカウントキーなしで使う

こんにちは。[フューチャーアドベントカレンダー](https://qiita.com/advent-calendar/2019/future)の15日目のエントリーです。昨日は、[javasparrowさんのpygame2で1からゲームUIを作る！](https://qiita.com/javasparrow/items/4fb1784647f7d11061ac)でした。この記事を書くにあたり、何個かネタ選びをしましたが、なんだかんだ腑に落ちたことを書いていきます。

# Cloud SQLとGCEインスタンスを接続する方法
Cloud SQL Proxyを使うとき、[こちらの公式ドキュメント](https://cloud.google.com/sql/docs/postgres/connect-compute-engine?hl=ja#gce-connect-proxy)にあるような方法が検索すると多く使われているようです。こちらの方法を簡単にまとめると

- Cloud SQL Proxy専用のサービスアカウントを払い出す
- サービスアカウントの秘密鍵をJSONで発行する
- Cloud SQL Proxyを動かすインスタンスに上記で生成した秘密鍵を埋め込む

となります。今回、Cloud SQL Proxyの設定をAnsibleで行おうと上記設定を参考にしていました。しかし、こちらの方法だと秘密鍵の保存に困ります。スマートな方法があるのかもしれませんが、複数人で管理するのであれば、Gitで管理することも考えないといけなくなってしまいます。そもそも鍵をGit管理するあまりセキュアではありませんし、Ansible化するにあたりここは避けたいところです。
ここでは公式でも示されているサービスアカウントの秘密鍵を使わなくても、Cloud SQL Proxyを介してCloud SQLと接続する方法を紹介していきます。

## 今回のイメージ
今回のイメージは以下の赤枠部分を想定しています。が、Appレイヤーのことはひとまず考えていないので別のインスタンスにAppが存在していても大丈夫です。(きっとその方がいい)
![CloudSQLProxy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382465/06c59847-a59d-56c6-6624-16b011555ab5.png)

## 秘密鍵を作らないで接続する
今回は秘密鍵の作成を行わずにCloud SQL Proxyの設定を進めていきます。秘密鍵を作成する方法と比較できるようにステップを分けながら説明していきます。

### サービスアカウントの扱い
秘密鍵を作成する方法ではサービスアカウントはほとんど使っていませんでしたが、今回の方法ではProxyを使うインスタンスに対して作成したサービスアカウントをアタッチします。このサービスアカウントのロールは公式にもある

> - [Cloud SQL] > [Cloud SQL クライアント]
- [Cloud SQL] > [Cloud SQL 編集者]
- [Cloud SQL] > [Cloud SQL 管理者]

のいずれかを選択し、さらに今回は`[プロジェクト] > [編集者]`を付与します。(権限が広すぎると公式では言われていますが、ここでは気にしないことにします。)GCEにデフォルトでアタッチされるサービスアカウントのロールに明示的にCloud SQLのロールを足すイメージになります。

### 鍵を使わないCloud SQL Proxyの設定
基本的には公式に沿った方法になりますが、一部変わるので一通り書いてきます。
あとは、公式に沿ったような作成方法になりますが、若干記述内容が変わるので、こちらも順をおって書いていきます。

- Cloud SQL Proxyのインストール

```shell-session
# cd /root
# wget https://dl.google.com/cloudsql/cloud_sql_proxy.linux.amd64 -O cloud_sql_proxy >> /root/
# chmod +x /root/cloud_sql_proxy
# chown root:root /root/cloud_sql_proxy
# mv /root/cloud_sql_proxy /usr/bin/
```

- ソケットになるディレクトリを作成する

```shell-session
# mkdir /cloud_sql
# chown root:root /cloud_sql
# chmod 777 /cloud_sql
```

- Cloud SQL Proxyの起動  
  `<instance_connection_name>`はCloud SQLのインスタンス接続名を入力してください。

```shell-session
# cloud_sql_proxy -dir=/cloudsql -instances=<instance_connection_name> &
```

- Cloud SQL ProxyのSystemd化

```/etc/systemd/system/cloud_sql_proxy.service
[Unit]
Description = Cloud SQL Proxy Daemon
After = network.target
 
[Service]
ExecStart = /bin/cloud_sql_proxy -dir=/cloudsql -instances=<instance_connection_name>
ExecStop = /bin/kill ${MAINPID}
ExecReload = /bin/kill -HUP ${MAINPID}
Restart = always
Type = simple
LimitNOFILE=65536
 
[Install]
WantedBy = multi-user.target
```

- 自動起動設定

```shell-session
# systemctl start cloud_sql_proxy.service
# systemctl enable cloud_sql_proxy.service
```

以上の設定でCloud SQL Proxyのプロセスも起動して接続できるようになります。

## まとめ
IaCを徹底したいためにTerraformやAnsibleを使っていますが、セキュリティ的鍵に当たるものはGit管理したくないですし、一方で秘密鍵だけ自分でインスタンスに置いたとしても冪等性は担保できなくなるし、といった思いでやりました。個人的には秘密鍵を使うよりシンプルじゃん？とか思っています。
今回書いたものをAnsible化させて、さらにサービスアカウントの作成やインスタンスへのアタッチをTerraformでできたら自動化も冪等性も担保できます。

## 明日のアドベントカレンダー
明日のアドベントカレンダーは[Sinclair](https://qiita.com/Sinclair)さんの記事です！お楽しみに！
Yahoo! JAPAN Tech Conference 2019に参加しました

[公式](https://techconference.yahoo.co.jp/2019_shibuya/)
大変勉強になったのでメモ

##基調講演
* "SPEED"をテーマに意識改善した話
* 数千人の所帯での実行は凄い

##1. PayPayフリマ開発のチームと下地

* 下地
  * 開発環境をmake一発でセットアップできるようにする等
* チーム
  * ほぼすべてペアプロ、テストドリブンでの開発。
  * ペアは日ごとにローテ(1週間前考慮するツール自作)
  * 1件(1ストーリー)ごとに1人がテスト作成、その後もう1人が実装という流れで実施(交互に実施)
  * ペアプロした分コードレビューは省略、gitのpre pushでテスト通るかは確認している

ペアプロ未経験なので実演まで見せていただき大変勉強になりました。
手が半分になるのが不安でしたが、その後の懇親会で伺ったところ、状況によるだろうが十分価値がある、というお話でした。

* コード打つ時間より考えている時間のほうが長いので、手が半分になる影響はそこまでない
* レビュー削減やデバッグ時間考えるとペアプロのほうが早いと思う
* 特に新卒で入ってきたなどで効果大
* 一人で作業完結できるベテランだと話は変わるかも


##2. Z Lab Kubernetes運用を支える技術
* YahooはパブリッククラウドではなくOpenStack上でコンテナ運用
* 500クラスタ 8000ノードある
* クラスタサイズ増やせなかった時代から作ってるのでクラスタ多く
* リソース効率は悪いが、独立してアップデートかけられる利点がある
* クラスタ・ノードの即追加や定期アップデート、ノード復旧などの要件に答える必要あり
* k8s controller使って簡単に出来るようにした

聞いてはいましたが、かなり大規模じゃないと割に合わないですね…

##3. HTMLの新要素 portal での遷移
* aタグとiframeの合わせ技のような新タグ
* iframeの様にまず表示して、activateするとaタグのように遷移(URLバーの表示が実際に変わる)ということが出来る
* ページ遷移の体感速度を上げられる。遷移の白い画面を無くせる
* PayPayモール(検索結果→個別ページ)やYahooニュース(個別→個別)で適用
* ただし現状Chromeでしか使えない。
* PayPayモールの場合はもともとaタグで個別ページ遷移しているので、使える場合はportalを使うようにしている

体感でサクサク動くよう出来るのはかなり期待大。
chrome以外でも使えるようになるのが楽しみです。


##4. クロスユースプラットフォーム
特に面白いことなし
というか発表が間延びしすぎて全然内容に集中できなかった…

##5. 広告サイエンスにおける統計的機械学習技術のご紹介
* Yahooディスプレイアドネットワークの話
* CTR(Click throug rate)上げるため機械学習を使用
* デバイス、地域、性別、年齢、興味等 → 広告(候補)に対する予想クリック率を計算、高い広告を表示する(ランキング)
* ただ、この計算は実際とずれが生じる。
  * Ranking bias 過去データに基づく計算をするが、過去データ自体が上記のランキングの結果によるものなので、そこでバイアスがかかる(例え一様分布でも起きる)
  * Negative Bias 偏ったデータの学習によりモデルも偏る
* この特性を表現する指標として切断点を計算、これでランキング補正
* 結果 収益+6%, クリック率+8%

言われれば確かにそんなバイアスがかかるんだな、という気持ちになりますが、正直自分で気づいて補正は無理。
この手の仕事するときは専門家に頼む方が良い、という結論になりました。
データサイエンス部門があるYahooはその点凄いですね。

##6. CtoCフリマアプリの作り方 〜6ヶ月間のPayPayフリマ開発を支えた設計〜
####バックエンド

* ヤフオクからの流用ではなく18機能をスクラッチ開発
* 短期間 半年で開発 仕様1 開発4.5 テスト1.5
* キャンペーン打つので最初から高負荷前提
* テンプレート、ペアプロ等 並行開発
* ビジネスロジックとデータのプラットフォーム分割 … 並行開発、スケール可能
* クロスリスティング(ヤフオクのものをフリマで買える) … 検索同じシステム。フォーマット互換性つける＆対象見てDB叩き分け
* データやり取りはGraphQL

#### Android
* 60画面 10人3か月で作った。残業も最後の月でも平均10h程度
* ペアプロで開発
* Android Jetpack, マルチモジュール、DI Framework(Dragger)で効率化



##ポスターセッション
* 社内データからユーザー属性推定
  * ターゲティングで開封率・クリック率アップ、opt out率ダウン
  * データは既に社内に大量にあるとはいえ、やはり各部門からの拾い出しがかなり大変だったみたいです。
* 知恵袋の検索ランキング付け
  * オープンで競争し改善
  * クリック率が指標というのがちょっと雑(釣りタイトルを上位にすれば評価上げられる)な感あるが面白そう
GASとGitHubAPIで誰もアサインされていないissue一覧を出力する

# やりたいこと
誰もアサインされていないissueが溜まっていくので整理しようぜ。
GAS(GoogleAppsScript)でGitHubAPIを叩き、該当のissueをスプレッドシートに出力する。


# GitHubAPIを使う準備
- GitHubでアクセストークンを作成
- settings > Developer settings > Personal access tokens
- 「Generate new token」 ボタン押下
  - Note: 好きな名前
  - Select scopes: repoにチェック
- 作成後、表示されたアクセストークンを保存


# APIのURLを確認
https://developer.github.com/v3/issues/

APIのURL
`GET /repos/:owner/:repo/issues`

Parameters
- assignee: none
- state: open


# GASを作成
```issue.gs
function issue() {
  // GitHub アクセストークン
  var GITHUB_ACCESS_TOKEN = 'xxxxxx';
 // GitHub 組織名
  var GITHUB_OWNER = 'xxxxxx';
 // GitHub リポジトリ
  var GITHUB_REPO = 'xxxxxx';
  // API URL
  var GITHUB_API_URL = 'https://api.github.com/repos/' + GITHUB_OWNER + '/' + GITHUB_REPO + '/issues?assignee=none&state=open';
  // 出力するシートID
  var SHEET_ID = 'xxxxxxx';
  // 1pageのissue数
  var page_num = 30;
  var max_page = 100;
  
  var ss = SpreadsheetApp.openById(SHEET_ID);
  var sheet = ss.getSheets()[0];
  
  for(var page_cnt = 0; page_cnt < max_page; page_cnt++) {
    // APIアクセス
    var header = {
      "Authorization" : "token " + GITHUB_ACCESS_TOKEN
    };  
    var options = {
      "headers" : header,
    }
    var url = GITHUB_API_URL + "&page=" + (page_cnt+1);
    
    var response = UrlFetchApp.fetch(url, options);
    var issues = JSON.parse(response.getContentText());
    if (issues.length == 0) {
      break;
    }
    
    for(var index = 0; index < issues.length; index++) {
      var rows = index + 2 + page_cnt * page_num;
      // ID,件名,登録日
      sheet.getRange(rows, 1).setValue(issues[index]['number']);
      sheet.getRange(rows, 2).setValue(issues[index]['title']);
      sheet.getRange(rows, 3).setValue(issues[index]['created_at']);
      
    }
  }
}
```
Next.jsでcookieをシンプルに扱うことができるライブラリ nookies を紹介

# Next.jsでcookieを扱うのは大変
Next.jsなどのサーバーサイドレンダリング(以下SSR)をしているフレームワークでcookieを扱うのは面倒くさいですよね。
その理由の一つとして、同じコードでもSSRの場合とクライアントでレンダリングしている場合で挙動が違うということがあります。
例をお見せしましょう

#### クライアントでレンダリングしている場合
`console.log(document.cookie); // accessToken=test1234;`

#### SSRの場合
`console.log(document.cookie); // ReferenceError: document is not defined`

### 原因
クライアントサイド(ブラウザ)でレンダリングしている時は、ブラウザに保存されているcookieにアクセスできるが,
SSRの時はブラウザに保存されているcookieにアクセスできません。

### SSRの時にcookieを扱うには
SSRでcookieの情報はここに入っています

```tsx:index.tsx
const TestPage: NextPage<Props> = (props) => {
    return <div>test</div>
}

TestPage.getInitialProps(ctx) {
    // ここ
    console.log(ctx.req.headers.cookie) // accessToken=test1234;     

    return {};
}
```

同じライブラリをクライアントとSSRで共有していたりすると、条件分岐などが大変ですね
そんな時に nookies を使います
https://www.npmjs.com/package/nookies

# 使い方
以下の例で示すようにクライアントサイドの場合ctxを渡さずに、SSRならctxを渡せば、cookieをオブジェクトに整形して返してくれます。

```tool.ts
import { parseCookies } from 'nookies';
import { NextPageContext } from 'next';

export function printCookie(ctx?: NextPageContext) {
    const cookie = parseCookies(ctx);
    console.log(cookie) // { accessToken: 'test1234' }
}
```

また、cookieの追加もクライアントとSSR分け隔てなく行ってくれます

```set_cookie.ts
import { setCookie, destroyCookie } from 'nookies';
import { NextPageContext } from 'next';

export function setCookie(ctx?: NextPageContext, token: string) {
        setCookie(ctx, 'accessToken', token, {
            maxAge: 30 * 24 * 60 * 60,
        });
}

// ついでにcookie削除(動作確認してません)
export function destroyCookie(ctx?: NextPageContext) {
    destroyCookie(ctx, 'accessToken')
}
```

# ライブラリを読んでみた(箇条書きです！)
https://github.com/maticzav/nookies

```nookies/src/index.ts
const isBrowser = () => typeof window !== 'undefined' // 今の環境がSSRかクライアントサイドレンダリングか調べてるらしいです

.
.

if (ctx && ctx.req && ctx.req.headers && ctx.req.headers.cookie) { 
    return cookie.parse(ctx.req.headers.cookie as string, options) // SSRだったらctx.req.headers.cookieに入っているcookieをparseして返却
} 

.
.

if (isBrowser()) { 
   return cookie.parse(document.cookie, options) //クライアントだったらdocument.cookieにあるcookieをparseして返却
} 

.
.

ctx.res.setHeader('Set-Cookie', cookiesToSet) // SSRならレスポンスヘッダーにcookieをセットする

.
.

if (isBrowser()) { |
    document.cookie = cookie.serialize(name, value, options) // クライアントならクッキーをセット
}
```

# まとめ
以上です。いかがでしたでしょうか？
参考になりましたら幸いです。
db:migrateについて

勉強中に分からなくなったことをまとめて、あとで見返せる様に書いた。
今回はrailsで勉強をしていて、db:migrateが分からなdbかった。

#どんな時に使うのか
-railsで使用するデータベース構造を変更する時に使う
-①migration fileを作成する。
-②db:migrationコマンドを実行するとき

今回は②番
Railsだとマイグレーションファイルを実行することで、設計図を元にテーブルを作成したり、カラムを追加したりできる。

```
rails db:migrate
```
応用情報受けた(?)話①

#応用情報技術者試験とは

>応用情報技術者試験（おうようじょうほうぎじゅつしゃしけん、Applied Information Technology Engineer Examination、略号AP）は、情報処理の促進に関する法律第29条第1項の規定に基づき経済産業大臣が行う国家試験である情報処理技術者試験の一区分。 
対象者像は「高度 IT 人材となるために必要な応用的知識・技能をもち、高度IT 人材としての方向性を確立した者」。情報処理技術者試験制度のスキルレベル3（スキルレベルは1～4が設定されている。）に相当する
参考:wikipedia

#使用したテキスト
　- キタミ式イラストIT塾 応用情報技術者 平成31/01年 (情報処理技術者試験)
　きたみりゅうじ↓↓↓

![ダウンロード.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550190/751f0342-c06a-22ee-66c8-8ea16af767d4.jpeg)

　- 2019応用情報技術者午後問題の重点対策 (重点対策シリーズ)
　小口達夫↓↓↓

![緑本.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550190/af5d90a0-9bfb-97bd-f097-38786e75dfd2.jpeg)
　
　- 平成31年【春期】/01年【秋期】応用情報技術者 合格教本
　大滝 みや子↓↓↓


![参考書.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550190/bea1bae0-29bf-e5b8-9e63-e1abee50a434.jpeg)

#勉強時間
　- 数学を習熟しているかいないか、プログラミングの経験があるかなどで変わってきます。20時間の人もいれば500時間の人もいました。
　- 僕自身は200時間ちょい勉強しました。(数学はそんなに困らなかった)

#勉強方法
　- 数学以外はマインドマップを使って頭の中に入れました。
　　- [詳しい書き方](https://www.mindmap-school.jp/mindmap/mindmap-law/)
↓こんな感じのノートのまとめ方のこと 
![マインドマップ-nlpの道具箱-作-岡べ-まさみち.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550190/01cbc9a1-d10f-a0a5-41db-475e88f971db.jpeg)

　- **応用情報はとにかく過去問からの出題傾向が高い!!!**
　　- 特に過去3回分以前の過去問からの出題傾向が高いです。
　　- 午後問題は記述方式で過去問は無意味という人もいれば、有効という人もいて惑わされる思いますが、僕としては**めちゃくちゃ有効**です。資格だけ取りたいなら午前も午後も過去問→テキスト→過去問の流れが最強だと思います。
　　- なんと過去問はHPに転がっています。お金助かるぅ。
　　　-　[過去問](https://www.jitec.ipa.go.jp/1_04hanni_sukiru/_index_mondai.html)

#まとめ
　- 半年コツコツ勉強すれば未経験でも取れる資格だと思います。
　- 6割取れれば合格なので過去問やりまくれば短い期間からでもいけるかも(?)
　- 偉そうに記事書いておりますが、僕は台風19号のせいで試験会場変わったことを知らず、試験は受けれませんでしたが自信は大いにありました！！！
hg19での遺伝子配列情報をNCBIから取得する


研究をしているとhg19（human geneme version19）での遺伝子情報が要求される場合があります。hg19と最新版のhg38は配列情報はそう変わらないのでそのまま最新版の配列情報を入力してもよいですが、hg19でとられたエピゲノム情報等と比較する場合はやはり必要になってきます。

hg19の全ゲノム情報がほしい場合は[UCSC](http://hgdownload.cse.ucsc.edu/downloads.html#human "UCSC")のページから取得可能です。

今回は単純に特定の遺伝子のhg19配列情報だけを取得したいという場合でのやり方を紹介します。
以下のビデオをご参照ください。

[![Screen Shot 2019-12-15 at 19.52.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521610/eac36d8f-62ab-46b4-dc42-177e559d2463.png)](https://www.youtube.com/watch?v=2_IvhTYNFLY&t=5s)


ビデオ1分の時点で"~GRCh37.p13 Primary Assembly"を選択していますが、この部分でGRCh37.p13 Primary Assembly（≅hg19）のゲノムを指定したことになります。
そのあとは[Send to]からGenBankファイルをダウンロードして、[SnapGene（無料版）](https://www.snapgene.com/snapgene-viewer/)といったビューアーソフトで確認すればよいです。

以上です。ありがとうございました。

補足：
GRCh37.p13 Primary Assemblyとhg19はほぼ同じですが違いも多少あります。
両者の若干の違いについては[NGS Surfer's Wiki様の記事](https://cell-innovation.nig.ac.jp/surfers/GRCh37_Hg19_defference.html NGS Surfer's Wiki)をご覧ください。
ミトコンドリアの配列以外は配列座標のずれもないようなので、常染色体・性染色体を参照する限りは大丈夫そうです。
XAMPPを使ってローカル環境で仮想サーバーの構築

①XAMPPの起動
<img width="84" alt="スクリーンショット 2019-12-15 19.31.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/3f6fdac3-a34f-88d2-f5a0-2259f2d8db03.png">

②スタートボタンをクリック
<img width="516" alt="スクリーンショット 2019-12-15 19.31.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/2edfeafa-82f6-bc53-3ffb-6592b8b75f76.png">

③「Services」タブ →「Start All」をクリック
<img width="516" alt="スクリーンショット 2019-12-15 19.32.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/58e435b3-a230-d462-8d87-7f421a00664d.png">

③「Network」タブ →「localhost:8080」を選択 →「Enable」をクリック
<img width="516" alt="スクリーンショット 2019-12-15 19.32.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/1cdc8c49-5cbf-6d74-9f9e-6cabd2c9327a.png">

④「Volumes」タブ →「Mount」をクリック
<img width="516" alt="スクリーンショット 2019-12-15 19.32.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/5bec169f-c506-9100-6729-55b81772f660.png">

⑤Finderで仮想サーバーが出現する
<img width="366" alt="スクリーンショット 2019-12-15 19.33.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/f41da480-abe7-f991-3068-d3bc3eb4b8f1.png">

⑥「htdocs」がlocalhostのルートになる
<img width="779" alt="スクリーンショット 2019-12-15 19.33.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/07fbf661-74be-ded0-c5b6-9571081449b2.png">

⑦ブラウザのアドレス欄に「http://localhost:8080/」 で表示
<img width="799" alt="スクリーンショット 2019-12-15 19.31.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/314346/6ce017b7-4da7-c14d-1361-82cd793e5bf1.png">
create-react-appで作ったアプリがhttpsだと動かない

# 問題点
create-react-appで作成したアプリケーションにhttpsでアクセスすると、以下のようにエラーとなりました。
`SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.`
![d1fb5456080f4fbb895c367aae298593.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114715/999ad720-7d4a-0fa2-9caf-5c28f6c2afeb.jpeg)
httpだと問題なく動きます。
create-react-appで作ったアプリを試しにHerokuに上げてみたときに、この問題を踏みました。
# 原因
以下でIssuesが上がっていました。
https://github.com/facebook/create-react-app/issues/8075
https://github.com/facebook/create-react-app/pull/8079

WebSocketsを利用している箇所で、httpsの場合はwss(WebSockets over SSL)を利用しなくてはいけないところ、wsを利用してしまっているためのようです。

# 解決法
問題が発生しているときのpackage.jsonの依存関係は以下です。

```json:package.json
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-scripts": "3.3.0"
  }
```
react-scriptの3.3.0で発生している問題なので、3.2.0にバージョンダウンすると、一旦動作するようになります。

```
$ npm install react-scripts@3.2.0
```

react-scriptsのバージョン変更がpackage.jsonにも反映され、httpsでも動作するようになりました。

```json:package.json(更新後)
  "dependencies": {
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.4.0",
    "@testing-library/user-event": "^7.1.2",
    "react": "^16.12.0",
    "react-dom": "^16.12.0",
    "react-scripts": "3.2.0"
  }
```
![2cd9968afd83f4f2863a9ff10f724a74.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114715/5f4722c8-17fc-ed72-4739-60f029af351c.jpeg)


上記Issuesは、react-scriptの3.3.1で修正予定(2019/12/15時点)のようなので、バージョン下げは暫定対応とし、修正されたら3.3.1に上げるのがよいと思います。