OmniAICreator/Qiita-1.07M huggingface dataset:
Julia で下付き文字をインデックスに変換するマクロを書いてみた。

# TL;DR

+ 誰も使わないような有用性のないパッケージを作ってしまいました。
+ この記事も自己満足なポエムでしかなく、Julia を便利な道具として使いたい方には役に立ちません。

以上をご理解の上、問題がなければ続きをご覧ください。

# `@_`

こんなマクロを実装しました。

+ 下付き文字（例: `Fₙ`）をインデックス（例: `F[n]`）として parse する。
    + `@_ Fₙ = Fₙ₋₁ + Fₙ₋₂` は `F[n] = F[n-1] + F[n-2]` として解釈・評価される。 
+ 多次元配列にも対応。
    + `@_ Π₍ᵢ₎₍ⱼ₎` のように添え字のグループをかっこで括ると `Π[i, j]` のように解釈・評価される。

## インストール

```julia
(v1.x) pkg> add https://github.com/antimon2/Sub2Index.jl.git
```

## 具体例

```julia
julia> using Sub2Index

julia> F = ones(Int, 10);
julia> @_ for n = 3:10 Fₙ = Fₙ₋₁ + Fₙ₋₂ end;
       # equivalent to `for n = 3:10 F[n] = F[n-1] + F[n-2] end`
julia> F
10-element Array{Int64,1}:
  1
  1
  2
  3
  5
  8
 13
 21
 34
 55

julia> Π = zeros(Int, (10, 10));
julia> @_ for i = 1:10 Π₍ᵢ₎₍₁₎ = Π₍ᵢ₎₍ᵢ₎ = 1 end;
julia> @_ for i = 3:10, j = 2:i-1 Π₍ᵢ₎₍ⱼ₎ = Π₍ᵢ₋₁₎₍ⱼ₋₁₎ + Π₍ᵢ₋₁₎₍ⱼ₎ end;
julia> Π
10×10 Array{Int64,2}:
 1  0   0   0    0    0   0   0  0  0
 1  1   0   0    0    0   0   0  0  0
 1  2   1   0    0    0   0   0  0  0
 1  3   3   1    0    0   0   0  0  0
 1  4   6   4    1    0   0   0  0  0
 1  5  10  10    5    1   0   0  0  0
 1  6  15  20   15    6   1   0  0  0
 1  7  21  35   35   21   7   1  0  0
 1  8  28  56   70   56  28   8  1  0
 1  9  36  84  126  126  84  36  9  1

```

## 動作例

Binder で動作するものを公開しました。
↓
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/antimon2/Sub2Index.jl/master?filepath=example%2FExample.ipynb)


# どんなときに使えるか？

**有効な使い途はありません**（重要）。

理由は以下の通り：

+ 通常のインデクシングの表記（例: `F[n]`）の方がタイプ数が少なくて済みます。
+ 多次元の場合（例: `@_ Π₍ᵢ₎₍ⱼ₎`）は無駄に長くなり可読性も落ちます。
+ 何より、下付き文字として使用できる文字が非常に少ないです（`"₍₎₊₋₀₁₂₃₄₅₆₇₈₉₌ₐᵦᵪₑᵧₕᵢⱼₖₗₘₙₒₚᵩᵣᵨₛₔₜᵤᵥₓ"` の全38文字のみ）。

# じゃぁなんで作ったのか？

完全に自己満足です。

きっかけは、Twitterでの以下のやり取り↓を見て：

+ https://twitter.com/ValFadeev/status/1226645332630609922
+ https://twitter.com/opensourcesblog/status/1226791023008985088
+ https://twitter.com/ValFadeev/status/1226792101079388160
+ https://twitter.com/opensourcesblog/status/1226795499719733248
+ https://twitter.com/ValFadeev/status/1226797883455922176

![Wait_what_is_this_Is_it_the_Indices_of_Pi___Twitter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30400/4a622b6c-9d20-ebc7-b6ca-2f3b3d1fdddb.png)

でそこで参照されていた以下のStack Overflowの質問を見て：

+ [Use subscript as index in julia - Stack Overflow](https://stackoverflow.com/questions/49705173/use-subscript-as-index-in-julia)

「できるよ」「いや無理じゃね？」とか書かれていて、具体的な実験例とか実装例がなかったので。

ないなら自分でやってみよう、と思ってやってみてできたのでついカッとなって公開してしまった、というわけです。
公開はしましたが後悔はしていません。

## どうやって実装したのか？

詳細は [Github リポジトリ](https://github.com/antimon2/Sub2Index.jl) のソースを見てみてください。DocString 込で96行（うちDocStringだけで半分以上使ってます）。

簡単に説明すると：

+ 識別子として評価される前の Symbol を文字列操作して下付き文字の塊をインデクシングに変換

これだけ。  
もう少しだけ詳しく言うと、

+ Symbol を文字列に変換して変換して `Meta.parse()` に掛けて `Expr` に変換
+ `esc()` を通さないとスコープで参照できる識別子として識別できないので注意
+ 処理のメインは1つの関数（`AbstractString`/`Symbol`/`Expr`/その他のいずれかを受け取る各実装を多重定義）
+ `macro _(src)` は↑を呼ぶだけ

こんな感じです。
もし反応あればも少し詳しく解説します。

# 参照

+ [antimon2/Sub2Index.jl - Github](https://github.com/antimon2/Sub2Index.jl)
Codeforces Round #620 D. Shortest and Longest LIS

時間内にACできなかったので、解説通りに解いたアプローチ。

# 題意
- 1 to nの数列がある。
- これを入力の制約に従って好きに並べ替えてよい。
- 例えばn=4, <<>なら、1<2<4>3 でもよいし、 2 < 3 < 4 > 1
- この時、LISが最長および最短になるパターンを1つずつ示せ

#例:
example2が一番わかりやすい
制約: > > < > > <
最短の例: 7 6 4 5 3 1 2
最長の例: 3 2 1 6 5 4 7


# アプローチ: 最短のLIS
まず、初期値num = nとする。今の位置last = 0として、">"が見つかるまで操作する。
">"が見つかった場合、その位置から左にnumをlast埋めていく。(埋めるたび-1する)
次に、lastをi+1する。これは、次にうめなければいけない文字の左端だからである。
## 例
- [_ > _ > _ < _ > _ > _ < _ ] ind0を7で埋める
- [7 > 6 > _ < _ > _ > _ < _ ] ind1を6で埋める
- つぎは2つ先まで飛べるので
- [7 > 6 > 4 < 5 > _ > _ < _ ] ind2,3は右から大きい数を詰め、4, 5となる
- [7 > 6 > 4 < 5 > 3 > _ < _ ]
- 次は"<"を見つけるのでその先まで行き、文末なので大きい数を右端から埋める
- [7 > 6 > 4 < 5 > 3 > 1 < 2]


# アプローチ: 最長のLIS
まず、初期値num = 1とする。今の位置last = 0として、今度は"<"が見つかるまで操作する。つまり、単調減少区間を探す。
"<"が見つかった場合、その位置から左にnumをlast埋めていく。(埋めるたび+1する)
次に、lastをi+1する。これは、次にうめなければいけない文字の左端だからである。
## 例
- [_ > _ > _ < _ > _ > _ < _ ] 
- まず、最初は3つ先まで"<"を探す。この3つを1-3で埋める
- [3 > 2 > 1 < _ > _ > _ < _ ]
- 次は6つ目までまた飛べる。この３つを4-6で埋める
- [3 > 2 > 1 < 6 > 5 > 4 < 7 ]

```Python
import itertools
def countstrs(s):
    return [(k, len(list(g))) for k, g in itertools.groupby(s)]
def countstrs_withIndex(s):
    d = countstrs(s)
    r = []
    ind = 0
    for i in range(len(d)):
        r.append((d[i][0], d[i][1], ind))
        ind += d[i][1]
    return r

q = int(input())
for _ in range(q):
    inp = input().split()
    n = int(inp[0])
    s = inp[1]

    """
    制約: > > < > > <
    最短の例: 7 6 4 5 3 1 2
    最長の例: 3 2 1 6 5 4 7
    """
    # 最小LIS
    dat = [0] * n
    num, last = n, 0
    # 0文字目からなめる
    for i in range(n):
        # 文字列が最後までくる、あるいは、単調増加にできないなら、
        # (つまり、この区間は"<" = 単調増加をイメージしている)
        if i == n - 1 or s[i] == ">":
            # その区間をなるべく大きな数になるように埋める
            for j in range(i, last - 1, -1):
                dat[j] = str(num)
                num -= 1
            last = i + 1
    print(" ".join(dat))

    dat = [0] * n
    num, last = 1, 0
    for i in range(n):
        print(dat)
        if i == n - 1 or s[i] == "<":
            for j in range(i, last - 1, -1):
                dat[j] = str(num)
                num += 1
            last = i + 1
    print(" ".join(dat))
```
https://codeforces.com/contest/1304/submission/71175921
一度入れたJavaScriptライブラリは二度とアップデートされることはない

以下はCloudflareによるレポート、[JavaScript Libraries Are Almost Never Updated Once Installed](https://blog.cloudflare.com/javascript-libraries-are-almost-never-updated/)の日本語訳です。


# JavaScript Libraries Are Almost Never Updated Once Installed

Cloudflareは、WebページにJavaScriptやその他のフロントエンドリソースを配置するための一般的な方法である、[CDNJS](https://cdnjs.com/)を支援しています。
今回我々は、CDNJSチームの許可を得て、CDNJSへのリクエストから匿名化・集約されたデータを収集し、インターネットでWebサイトがどのように構築されているかを分析することにしました。
今回のエントリでは、ひとつの疑問に焦点を当てています。
すなわち、いちどJavaScriptライブラリをサイトにインストールしたあとで、ライブラリは更新されるでしょうか？

まずは地球上でもっとも人気のあるライブラリ、jQueryから始めましょう。
このチャートは、過去12か月間の、jQueryのバージョンごとのリクエスト数を表しています。

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/993c8a8e-80cd-19bd-8c8a-d9a651b3a556.png)


2019年5月2日のリリース以降、バージョン3.4.1のリクエスト数は着実に増加しています。
しかし、古いバージョンが減少しているということはありません。
バージョン3.2.1は、チャートのはじめには一日あたり3600万のリクエストがありましたが、一年の終わりには2900万リクエストとなり、20%減少しています。
しかしこれは、平均的なWebサイトは2～4年しか保たないという[リサーチ](http://informationr.net/ir/9-2/paper174.html#2002)の結果と一致しています。
バージョン3.4.1は着実に普及しつつありますが、しかしそれに伴って古いバージョンが減少するような傾向は全くありません。

ちなみにCDNJSに入っているjQueryの最も古いバージョンは、2013年5月25日にリリースされた1.10.0です。
これはいまだに一日平均10万件のリクエストがあり、それらを使っているサイトの人気も依然として衰えていないどころか、さらに高まっています。

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/cf2a0c1c-7415-173e-57b0-b002ea373034.png)


jQueryだけの特異な現象でないことを示すために、別のプロジェクト[TweenMax](https://greensock.com/tweenmax/)も見てみましょう。


![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/8e288885-d4fa-47da-2552-755bf4f894ad.png)

このパッケージは利用者がjQueryほど多くないため、データは一週間ごとの平均で平滑化されています。

バージョン1.20.4は1800万件のリクエストで始まり、1400万件で終わりました。
Webサイトの消滅割合と概ね同じ23%の減少です。
2.1.3の大きな成長は同時に、新バージョンのリリースが旧バージョンの人気にほとんど影響を与えないという明白な証拠を示しています。
2.1.3が2900万リクエストまで増加しても、旧バージョンへのリクエスト数は全く変わっていません。

![04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/94b1ff40-b1e5-9280-b415-d2bfbf08d994.png)


結果として言えることは、一度公開されたライブラリを使うWebサイトは永久に存在し続けるということです。
従って、Web基盤プラットフォームは、あらゆるWebをサポートするためには、どれほど古いライブラリでも無期限に提供し続けなければなりません。


Cloudflareは、最新のWebにコントリビュートすることに非常に興味を持っています。
ぜひコメントで提案してください。

# コメント欄

「CDNJS依存関係を自動でバージョンアップする[Renovate Bot](https://github.com/renovatebot/renovate/issues/5253)ってのを作ってる。」
「古いライブラリ使ってる人に通知するとか。」
「Wappalyzerみたいなかんじでバージョンが古いのを一目でわかるようにするとか。」
「`@major`みたいなセマンティックバージョンを提供するとか。」「マイナーバージョンで互換性なくすアプデしてくるライブラリを腐るほど見たからまあ無理だろ。」
「CDNが落ちてた時にローカルのライブラリを読ませてるんだけど、バージョン揃えるのが面倒。自動更新とかできない？」「ASP.NETだけど[そういうのはある](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/script-tag-helper?view=aspnetcore-3.1)。」「jQueryにもあった気がする。」


# 感想

要するに、継続的なんちゃらだとかリーンなんちゃらだとか言ってるのは業界の極一部でしかなく、大半のサイトは一度作ったらそれっきりということです。
実際そんな最前線を走り続けなければならないサイトなんてほとんどありませんからね。
GAFAMでも配信サービスでもない一般人のサイトが最新技術を駆使してます！なんて言われてもどうでもよくない？

コメントで言っているセマンティックバージョンは[これ](https://semver.org/lang/ja/)のことです。
ざっくり言うと『互換性の無いバージョンアップはメジャーバージョンを上げろ』ですが、これが守られているライブラリなんて存在しないことは周知のとおりです。

といってもさすがに今どきjQuery1は、さすがに古すぎますね。
jQuery2が出たのが2013年4月。
当時小学校に入った子供が既に中学生になっているほどの昔ですよ。

あと今回見せてるのはjQueryとTweenMaxだけなので、VueとかReactとか最近のやつもちょっと見てみたかったですね。
初心者がAnaconda環境構築をするには。(メモ)

#目的
環境構築の理解を深めたい。（また環境構築にてこずったので）

今まではHomebrewを使っていたが都度必要なライブラリをインストールするのが手間なのでまとめてあるプラットフォームを使ってみたいなーと思った。

#今までの理解
大まかにはbrewを作り、その上にAnaconda、pip等でインストールしていくと理解していた。


##Homebrew,pip,Anaconda,pyenv,venvって何？

- **Homebrew**: **Mac OS Xオペレーティングシステム上で**ソフトウェアの導入を管理するパッケージマネージャー。
これが**一番の土台**となると理解。

- **pyenv**:Pythonのバージョン管理を行う。簡単に切り替えができるためpyenvを通してPythonをインストールする。詳しくは以下。
「初心者でも分かる仮想環境構築」
https://qiita.com/Taka20200105/items/20cebb42a20301203d2e

- **pip**: **Pythonのパッケージマネージャー**。通常、パッケージはpipコマンドを使ってインストールする。(Rubyでいうジェムみたいなもの。)

- **Anaconda**:Python本体に加えて、データサイエンス向けのPythonパッケージを提供するプラットフォーム。CondaコマンドでAnacondaが管理・運用する専用のリポジトリからダウンロードし、Conda環境にインストールする。
 - 標準のPythonでは仮想環境の管理はvenvモジュールで行うが、Anacondaでは仮想環境もCondaコマンドで提供している。


##Anacondaの環境構築
Homebrew,pyenvはインストール済みなので割愛。

pyenv globalによって全てのディレクトリ で該当のバージョンが実行されるようにしている。

```py

#Anacondaのインストール
% pyenv install Anaconda3-2019.10
Downloading Anaconda3-2019.10-MacOSX-x86_64.sh...
-> https://repo.continuum.io/archive/Anaconda3-2019.10-MacOSX-x86_64.sh
Installing Anaconda3-2019.10-MacOSX-x86_64...
Installed Anaconda3-2019.10-MacOSX-x86_64 to /Users/.pyenv/versions/Anaconda3-2019.10

#バージョンの切り替え
% pyenv global Anaconda3-2019.10
% pyenv versions
  system
  3.8.0
* Anaconda3-2019.10 (set by /Users/uemura/.pyenv/version)
% pyenv global 3.8.0             
uemura@uemuratntonoAir python_machine_learnig % pyenv versions    
  system
* 3.8.0 (set by /Users/uemura/.pyenv/version)
  Anaconda3-2019.10

#バージョン変更が必ずpyenv rehashを行わなければならない。
#変更を保存できるのかな？
% pyenv rehash
#確認
% python -V   
Python 3.8.0

```

#感想
Homebrewをビルドしてその上にインストールしていくのだが、pyenvとかAnacondaをどのように立てていくのかを整理できた。今回の整理で理解が進み、現状の環境構築へのモヤモヤが晴れた。

1. Homebrewビルド ⇨pyenvでPythonをインストール ⇨venvで仮想環境構築 ⇨ライブラリ追加やPython実行。
2. Homebrewビルド ⇨pyenvで**Anaconda**をインストールする。
この方法だとライブラリ+Pythonのインストールを一括でできるので非常に便利だ。

一方で、HomebrewとAnacondaは非常に相性が悪いとの情報が多く見られた。Anacondaのインストール時は必ずpyenvでインストールする。

Anaconda使ってみよう。

##参考文献

HomebrewのインストールからpyenvでPythonのAnaconda環境構築までメモ
「https://qiita.com/aical/items/2d066801a7464a676994」

python Japan
「https://www.python.jp/install/anaconda/index.html」
gitにpushできなくなった際の対処法【git remote set-url】


直前にbitbucketにgitpushする様に設定を変更したら、githubにpushできなくなりました。


```git remote -v``` で現在の状態を確認。

```
github	git@github.com:shota0701nemoto/insta-clone-new2.git (fetch)
github	git@github.com:shota0701nemoto/insta-clone-new2.git (push)
heroku	https://git.heroku.com/insta-clone-new2.git (fetch)
heroku	https://git.heroku.com/insta-clone-new2.git (push)
origin	git@bitbucket.org:NemotoShogo/insta-clone-new2.git (fetch)
origin	git@bitbucket.org:NemotoShogo/insta-clone-new2.git (push)
```

githubのURLがなかったので、これではgit pushでgithubにあげることができませんね。



gitにpushできる様に変えます。

私の場合だと、こちらでいけます。

```
git remote set-url origin https://github.com/shota0701nemoto/insta-clone-new2.git
```

originの部分は任意で自由な名前で良いらしいです。

つまり、

```
git remote set-url origin https://github.com/ユーザー名/アプリ名.git
```

この様になります。


```git remote -v```で確認すると、


```
github	git@github.com:shota0701nemoto/insta-clone-new2.git (fetch)
github	git@github.com:shota0701nemoto/insta-clone-new2.git (push)
heroku	https://git.heroku.com/insta-clone-new2.git (fetch)
heroku	https://git.heroku.com/insta-clone-new2.git (push)
origin	https://github.com/shota0701nemoto/insta-clone-new2.git (fetch)
origin	https://github.com/shota0701nemoto/insta-clone-new2.git (push)
```


originという名前で設定されているので、これで

```
$git add -A

$git commit -m"メッセージ"

$git push
```

githubにpushできました。
Nuxt.jsのSSRでミドルウェアを使ってVuexに値をストアする方法

SSRのクライアントサイドでレンダリングされる前にstoreに保存するにはミドルウェアを使います。
そのときの参考に残します。
ここでは例にjwtをstoreに保存することをやってみます。普通はcookieとかに保存しますが一例として。

```javascript:nuxt.config.js
module.exports = {
//省略
router: {
　middleware: 'hoge' //ミドルウェアのファイル名
},
//省略
}
```

```javascript:middleware/hoge.js
export default async ({ store }) => {
  if (store.state.auth.token === null) {
    await store.dispatch('auth/setToken')
  }
}
```

```javascript:store/fuga.js
import axios from 'axios'

export const state = () => ({
  token: null
})

export const mutations = {
  login (state, token) {
    state.token = token
  }
}

export const actions = {
  async setToken ({ commit }) {
    await axios.post('http://api.your-site.com/v1/auth', {
      identifier: 'hogefuga@hoga.com',
      password: 'password'
    }).then(res =>
      commit('login', res.data.jwt)
    )
  }
}

```
【Rails】AWS Cloud9で環境構築

AWSのアカウントがある前提

- IAMユーザーでログインし、コンソール画面からcloud9を検索

- 「Create environment」をクリック 
[![Image from Gyazo](https://i.gyazo.com/b0e6c5a2aa7cf4f6c9c61adb4239985e.png)](https://gyazo.com/b0e6c5a2aa7cf4f6c9c61adb4239985e)

### bundlerを入れる

```
$ gem install bundler
```
バージョン確認

```
$ bundle -v
```

### rails newで開始
```
$ rails new . -d mysql --skip-turbolinks --skip-test --skip-coffee
```
こんなエラーが出て少しハマる・・・

```
$ bundele install

# 略

Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
```

→以下のコマンドを打つと解決

```
$ sudo yum install -y mysql-devel
```

### gemのインストール

```
$ bundle install --path vendor/bundle
```

### サーバー起動

```
$ bundle exec rails s
```


### cloud9でmysqlを走らせる（起動）

```
$ sudo service mysqld start
```
→ローカルで使うときの$ mysql.server startと同じ意味。

### DBの作成
```
$ bundle exec rails db:create
```

[![Image from Gyazo](https://i.gyazo.com/83fe7ed450a99ef7d35b9a2cfcb36d45.jpg)](https://gyazo.com/83fe7ed450a99ef7d35b9a2cfcb36d45)

## 補足：
AWS Cloud9 には、あらかじめイントールされている MySQL がある

以下のコマンドを入力して、MySQL がイントールされているか確認

```
$ mysql --version
```

## 参考にしたURL

[初めてのAWS Cloud9導入 - Qiita](https://qiita.com/tu-kun/items/d7b4f1fa19cc93bc5b75)

[AWS Cloud9でRuby on Railsを始める \| RemoNote](https://remonote.jp/aws-cloud9-ruby-on-rails)

[AWS Cloud9でRailsプロジェクト作成直後にぶつかる問題の対応方法 - Qiita](https://qiita.com/oke-py/items/81f5db332131e5d88cf4)

[AWS Cloud9でMySQLを利用する方法 - Qiita](https://qiita.com/acecrc/items/a72992a17968d3d9bc00)

[Railsでmysql2をインストールするときにハマったところ - Qiita](https://qiita.com/emahiro/items/1a63d676be9fc4975759)
Human Interface GuidelineにおけるModalのUIBarButtonItemの規則

iOS13になってから標準でmodalがiOSアプリ内でも使えるようになり、色々なアプリでmodalをみるようになったと思います。今回は凄いニッチな話ですが、UINavigationControllerで表示したmodalのUIBarButtonItemの命名規則についてまとめていきます。

## 想定する読者
- アプリ開発をしているUIデザイナー
- iOSエンジニア
- Human Interface Guidelinesを勉強したい人

## この記事のゴール
この記事を読んだ人・書いた僕自身が今後**理由なくして**modalのUIBarButtonItemの実装でHIGに従ってないアプリを作成しないこと

## そもそもmodalとは
[Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/ios/app-architecture/modality/)によると
> Modality is a design technique that presents content in a temporary mode that’s separate from the user's previous current context and requires an explicit action to exit. Presenting content modally can:

> Help people focus on a self-contained task or set of closely related options
Ensure that people receive and, if necessary, act on critical information

日本語訳すると

modalとはユーザーにとって、前のコンテキストとは別の一時的な状態でコンテンツを提示するデザイン手法であり、終了するには明示的なアクションが必要なものである。モーダルは

- 自己完結型のタスクまたは強い関連のある一連のタスクにユーザーが集中できるようにする
- 人々が重要な情報を受け取り、必要に応じて行動する

ものである。

つまり、簡潔に言うとモーダルは

- タスクを行うためのもの
- タスクを完了するか、放棄することで閉じるもの

であることがわかります。

## サンプル画像

いくつかAppleが出しているiOSアプリのnavigationBarのスクショを掲載します。
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176180/3d79ca21-dcc8-5b72-4eaa-98dae71b16c4.jpeg">
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176180/f4332730-cbee-0cca-886e-42d1bf1b1a69.jpeg">
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176180/731fbec4-9e16-b984-b928-012ecdfcb167.jpeg">
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176180/5384c4b8-ec5a-eed0-b771-2ec2cc613312.jpeg">
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176180/4e972f5f-9abb-5ed8-fbab-f51ae55dcae8.jpeg">
<img width="300" alt="ファイル名" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176180/3eda5160-2a4c-583e-0e67-33fc2039d3fa.jpeg">

## サンプル画像を見てわかること

### キャンセルボタンと完了を表すボタンのみ
どの画面にもキャンセルまたは完了（を意味するボタン）がついています。

### 完了と同じ意味なら「完了」でなくていい
完了の他にも「追加」「投稿」など完了の意味を内包していれば完了を使わなくても良さそうなのが読み取れます。

### アイコンは使っていない
僕は✖️のアイコンとかも使用すると勝手に思ってたんですが、Appleのアプリには存在しなさそうな雰囲気を感じます。
また、完了に似た「閉じる」のような文言も使ってないようです。

### キャンセルはfontWeightがregular
タスクを完了することが目的なのでタスクを完了せず離脱する場合はregularみたいです。

### 完了を表すボタンはfontWeightがbold
逆に完了する場合はboldを使うのが推奨されるみたいです。

## コードベースで見てみる
[Document](https://developer.apple.com/documentation/uikit/uibarbuttonitem/style)でもこれまでの話と同じことがより簡潔に述べれられています。(この部分はmodalだけの話ではないです)
)<img width="742" alt="スクリーンショット 2020-02-16 23.47.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176180/0725815e-344b-90e1-edef-0e4088897146.png">

なのでこれを実行すると下の画像のようにdone(完了とか)では勝手にboldになるし、plain(キャンセルとか)ではregularになります。
<img width="174" alt="スクリーンショット 2020-02-16 23.49.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176180/09edf7c8-cb4b-098e-8a00-104b6c850b4c.png">


自分の作成してるiOSアプリや普段利用しているアプリがどうなってるのか見てみると面白いかもしれません。
AppleScriptとJavaScript

MacのWindowを操作したいと思い、AppleScriptを書き始めてみましたが、いまどき、JavaScript(JXA)に主流が移っているらしく…。結局、JavaScriptで書くことにしました。

オブジェクトにプロパティがわからず、サンプルコードをひたすら検索していましたが、
スクリプトエディタには、各アプリケーションのライブラリドキュメントが付いていることにいまさらのように気づく始末…。

スクリプトエディタの「ウィンドウ」→「ライブラリ」を開くとみれます。

<img width="805" alt="スクリーンショット 2020-02-16 23.51.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171247/9211bb83-dbb6-cf1d-42de-c3b9170005be.png">
jQuery 仮サイト作成のbase ②　（自分用）

![ezgif.com-video-to-gif (2).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/547910/97f565b8-2068-f86f-e0d5-7be01e6050a2.gif)


###前回の続き：スライドショーについてのみ###

```html

  <div class="slick">
    <div class="single">
      <div><img src="image/802.jpg" alt=""></div>
      <div><img src="image/IMG_3943.jpg" alt=""></div>
      <div><img src="image/IMG_4259.jpg" alt=""></div>
      <div><img src="image/IMG_4926.jpg" alt=""></div>
      
    </div>
  </div>

```

```jquery.js

var page=0;
var lastPage =parseInt($(".single img").length-1);

  $(".single img").css("display","none");
  $(".single img").eq(page).css("display","block");  //pageを取得

function changePage(){
  $(".single img").fadeOut(1000);
  $(".single img").eq(page).fadeIn(1000);          //一旦1秒で画像間の接続時間
};

var Timer;
function startTimer(){
Timer =setInterval(function(){
  if(page === lastPage){
     page = 0;
     changePage();
  }else{
     page ++;
     changePage();
  };},4000);                        //一旦４秒で次画像へ
};
}

startTimer();
```


```styles.css

//cssは仮

.slick {
  width: 100%;
  height: 400px;
  position: relative;
  /* left: 0; */
  top: 260px;
 
}
.single {
  position: relative;
}
.single img {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  width: 100%;
}

```
AtCoder Beginner Contest 155 参戦記

# AtCoder Beginner Contest 155 参戦記

## [ABC155A - Poor](https://atcoder.jp/contests/abc155/tasks/abc155_a)

2分で突破. 書くだけ. 前回に引き続き、set での重複判定.

```python
ABC = list(map(int, input().split()))

if len(set(ABC)) == 2:
    print('Yes')
else:
    print('No')
```

## [ABC155B - Papers, Please](https://atcoder.jp/contests/abc155/tasks/abc155_b)

2分半で突破. 書くだけ.

```python
N = int(input())
A = list(map(int, input().split()))

for a in A:
    if a % 2 == 1:
        continue
    if a % 3 == 0 or a % 5 == 0:
        continue
    print('DENIED')
    exit()
print('APPROVED')
```

## [ABC155C - Poll](https://atcoder.jp/contests/abc155/tasks/abc155_c)

8分半で突破. 書くだけ……といいつつそれなりに時間がかかったけど(汗). C# 使いが壊滅状態と聞いて、AC した人のコードを眺めると 全員 string 配列のソートに自前の comparer を使っていたので、Mono は string の比較がヤバイのかなと思った.

```python
N = int(input())

d = {}
for _ in range(N):
    S = input()
    if S in d:
        d[S] += 1
    else:
        d[S] = 1

m = max(d.values())
for s in sorted(k for k in d if d[k] == m):
    print(s)
```

追記: C# で通している人、みんな自前の comparer を使ってソートしてたけど、標準の StringComparer.Ordinal (これは、実質的には C ランタイムの strcmp 関数の呼び出し)で通るなあ.

```cs
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var N = int.Parse(Console.ReadLine());

            var d = new Dictionary<string, int>();
            for (var i = 0; i < N; i++)
            {
                var S = Console.ReadLine();
                if (!d.ContainsKey(S)) d[S] = 0;
                d[S]++;
            }

            var m = d.Values.Max();
            var l = new List<string>();
            foreach (var kv in d)
            {
                if (kv.Value != m) continue;
                l.Add(kv.Key);
            }

            l.Sort(StringComparer.Ordinal);
            Console.WriteLine(string.Join("\n", l));
        }
    }
}
```

## [ABC155D - Pairs](https://atcoder.jp/contests/abc155/tasks/abc155_d)

敗退. Eの方が解いてる人が多いので、Eに行った. にぶたんかなあと思った.

## [ABC155E - Payment](https://atcoder.jp/contests/abc155/tasks/abc155_e)

敗退. 入力例1, 入力例2 は突破したものの、入力例3が243ではなく、249になってしまって、自分のロジックでうまく行かないパターンを考えていたけど思いつかなかった.

追記1: ぐぬぬ.

```python
N = input()

N = '0' + N
result = 0
carry = 0
for i in range(len(N) - 1, 0, -1):
    c = int(N[i]) + carry
    n = int(N[i - 1])
    if c < 5 or (c == 5 and n < 5):
        result += c
        carry = 0
    else:
        result += 10 - c
        carry = 1
result += carry
print(result)
```

追記2: クレバーにうまく行かないパターンを考えるのではなく、すべての桁でその桁の紙幣で払うのと上の桁の紙幣で払うの両方を試行して小さい方を取ればよかった……. これなら知性はいらなかった…….

```python
N = input()

a = 0  # その桁の紙幣で払う
b = 0  # 上の桁の紙幣で払う

t = int(N[-1])
a, b = a + t, a + (10 - t)

for i in range(len(N) - 2, -1, -1):
    t = int(N[i])
    a, b = min(a + t, b + (t + 1)), min(a + (10 - t), b + (10 - (t + 1)))
print(min(a, b + 1))
```
[tips]Checkra1n脱獄時にフリーズしたときの対処法

##脱獄してみた
ios13の脱獄ツールがリリースされたそうなので、脱獄してみた。
詳しい方から便利Tweaksをたくさん教えていただいて、非常に助かりました。
が、調子に乗っていろいろインストールしまくってたらrespring後にロック画面でフリーズした。

##症状
Tweakインストール後のrespringでフリーズ。ロック画面をカスタムするTweakだったのでおそらく対応してないiosのバージョンをインストールしてしまった。selioから該当するものをアンインストールしたいが、ロック画面でフリーズしてしまうのでそこまでたどり着けない。入獄するとcheckra1nがないのでsileoをいじれない。

##対処法
どうしようかと調べたところ、checkra1nにはセーフモードで起動できるオプションがあるらしい。

checkra1nを起動→Options→Safe Modeにチェックを入れる

checkra1nがある状態でセーフモード起動できるので、sileoで該当するTweakをアンインストール。

そしてSafe Modeのチェックを外して再脱獄。できた。

##まとめ
まだios13のjailbreakは歴史が浅いので対応しているTweakも少ないっぽい。
とりあえずインストールしてみるときはセーフモードでやるといいですね。

みなさまよい脱獄lifeを♡
AWSの既存のリソースをterraformで管理する

# 1. 概要
マネジメントコンソールから作成した既存のセキュリティグループをterraformで管理するようにしたので、その手順を記載します。
今回はterraformerを使ってimportしています。
tfstateファイルはS3に置くようにしています。

# 2. 前提条件
terraform、terraformer、aws configの設定は済んでいることとします。

※ terraformerのインストール方法や使い方は下記を参照して下さい。
https://github.com/GoogleCloudPlatform/terraformer

# 3. 手順
## 3.1 terraformのmain.tfファイルを作成する
```
$ vi main.tf
```
設定例)

```
terraform {
  required_version = "0.12.20"
}

provider "aws" {
  region  = "ap-northeast-1"
  version = "2.49.0"
}

terraform {
  backend "s3" {
    bucket = "hogehoge"
    key    = "hogehoge/terraform.tfstate"
    region = "ap-northeast-1"
  }
}
```

## 3.2 terraform initする
```
$ terraform init 
```
リソースを定義していないため、tfstateは作成されません。

## 3.3 terraformer importする
```
$ terraformer import aws --resources=sg --filter=aws_security_group=sg-093ffc7be63295434 --regions=ap-northeast-1
```
→コマンドを実行したディレクトリ配下に「generated/aws/sg/ap-northeast-1」ディレクトリが作成されます。
sg-093ffc7be63295434は、terraformで管理したいセキュリティグループのグループIDです。

## 3.4 作成されたterraform.tfstateのterraform_version を main.tfで指定しているバージョンに合わせる
```
$ vi generated/aws/sg/ap-northeast-1/terraform.tfstate
```
generated/aws/sg/ap-northeast-1/terraform.tfstateのterraform_versionは、terraformerのバージョンによって変わるようです。
こちらはterraformのバージョンと合わせる必要があります。

## 3.5 ディレクトリを移動する
```
$ cd generated/aws/sg/ap-northeast-1/
```

## 3.6 terraform state mv する
```
$ terraform state mv -state-out=../../../../terraform.tfstate 'aws_security_group.tfer--qiita_sg-002D-093ffc7be63295434' 'aws_security_group.qiita'
```

aws_security_group.tfer--qiita_sg-002D-093ffc7be63295434 → terrafomerでimportしたリソース名
aws_security_group.qiita → terrafomのリソース名

## 3.7 ディレクトリを移動する
```
$ cd ../../../../
```
terraform.tfstateが作成されているはずです。

## 3.8 terraform planで差分が出なくなるようにリソースを定義する
```
$ vi security_group.tf
```
generated/aws/sg/ap-northeast-1/security_group.tf を参考にすると良いです。

## 3.9 terraform planで差分が出ないことを確認する
```
$ terraform plan
```
差分が出なくなっていればterraformで管理出来ています。

# 4. まとめ
既にtfstateが存在しているscopeに既存のリソースをimportする場合は少し手順が変わります。
terraformerが対応していないリソースをimportしたい場合は、terraform importすれば良いと思います。
PythonでABC155のA~Cを解く

###はじめに
こんばんは、tax_freeです。[前回](https://qiita.com/taxfree_python/items/6a3cebdffd9e580aec9c)からレートが**28**上がりました。茶色まで半分。今回はA~Cの三完でした。前回の記事に初めての質問が来て嬉しかったので、質問たくさんしてくれると嬉しいです。

###A問題
[問題](https://atcoder.jp/contests/abc155/tasks/abc155_a)

**考えたこと**
いいかんじに場合分けの数を減らそうとしたけど、思いつかなかったのでごり押しで場合分けしただけです。

```python
a, b, c = map(int,input().split())

if a == b and a != c:
    print('Yes')
elif a == c and a != b:
    print('Yes')
elif b == c and a != b:
    print('Yes')
else:
    print('No')
```

###B問題
[問題](https://atcoder.jp/contests/abc155/tasks/abc155_b)
Bで少し考えてしまって時間をロスしたのが痛い

**考えたこと**
Aの要素全てが条件を満すかを調べています。cは3、5で割り切れた要素の数、dは偶数の個数です。

```python
n = int(input())
a = list(map(int,input().split()))

d = 0
c = 0
for i in a:
    if i % 2 == 0:
        if i % 3 == 0 or i % 5 ==0:
            c += 1
        else:
            print('DENIED')
            quit()
        d += 1
if c == d:
    print('APPROVED')
```

### C問題
[問題](https://atcoder.jp/contests/abc155/tasks/abc155_c)
TLE:1

**考えたこと**
全ての要素の回数を調べるための方法を考えた結果、複数のlistを作って、要素ごとにカウントしていくしかないと結論ができました。自分の中で。
その結果、あまりに汚いコードが生れてしまいました。

```python
n = int(input())
s = []
for i in range(n):
    s.append(input())

c = []
for j in s:
    if j not in c:
        c.append(j)

g = []
for t in c:
    g.append([s.count(t),t])
g.sort(reverse=True)
h = max(g)[0]
hh = []
for ii in range(len(g)):
    if g[ii][0] == h:
        hh.append(g[ii])
    else:
        break
hh.sort(key=lambda x: x[1])
ans = []
for k in range(len(hh)):
    print(hh[k][1])
```
重複なしで要素を数えるためのlist、要素の個数ごとにsortしたlist、要素の個数ごとにsortしたlistの最大値だけを集めたlist、そして、要素の個数ごとにsortしたlistの最大値だけを集めたlistをprintするためのlistが誕生しました。for t in cのように"in"を使うと計算量が激増するという知見を前々回くらいに得たはずなのに、"you can do it"と言いながら、submitしてました。TLE出ました。

**ACだったコード**
pythonの標準ライブラリのcollectionsを使います。

```python
import collections

n = int(input())
s = []
for i in range(n):
    s.append(input())

c = collections.Counter(s)
c_s = c.most_common()
m = c.most_common()[0][1]
ans = []
for j in range(len(c_s)):
    if c_s[j][1] != m:
        break
    else:
        ans.append(c_s[j][0])
ans.sort()
for t in ans:
    print(t)
```
c.most_common()でどの要素が何個あるかを調べることができます。

### まとめ
D、EはDPを感じたんですけど、どうなんでしょうか。期末テストも終わったのでDPとかアルゴリズムの勉強したいと思います。
おやすみなさい。また来週。
【 Unity 】ほしゆきトゥーンシェーダーの紹介

# ほしゆきトゥーンシェーダーの特徴

グローバルイルミネーションやHDRがお好きなかたにどうぞ！

![sc16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/b412741f-211e-3daf-4c46-cea3e2231b00.jpg)


## 作り始めたきっかけ

もとは2017年に制作していた自作ゲームで使われる予定だったが、諸事情により制作は中止。  
お蔵入りするのももったいないと考え、同じ年の冬にGithub上に公開をはじめ今に至る。

ちなみにそこで起こっていたことは....

![03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/a4c8ca09-c5e1-bb1a-201f-13b1b78bafa5.jpg)
![04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/ae689e7a-b2e0-d082-2069-3f7c3986c6e1.jpg)

> 「なんか暗くね...。」

![02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/3d715263-22b5-1c33-2e4c-3fd7e5a3a3bf.jpg)

> 「今度は光りだした」

![06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/c5a25cb0-fa51-9f44-fda1-32886eb58237.jpg)
![05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/2265a360-1641-956c-7989-a5c4092546d3.jpg)

> 「おお、標準アセットのトゥーンシェーダー意外にいけるやんけ」

![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/39e9ee63-9abc-cb99-277d-ea0c093c78fc.png)

> 「....」

(ちなみに画像はハードディスクの奥底からプロジェクト立ち上げて作った。再現きつかった...)


## 特徴

### グローバルイルミネーション

![ezgif-1-82a26630c197.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/8aefa02e-6d53-822a-47c1-b719e9e681c1.gif)
> [デモ動画](http://www.youtube.com/watch?v=dJnXeBCc034)
> イメージベースドレンダリングを利用したグローバルイルミネーションの例

Unityがいかにグローバルイルミネーションによる品質向上と効率化を謳っても、トゥーンシェーダー上ではうまくあつかえなかったりする。

ほしゆきトゥーンシェーダーでは、アンビエントライトに似た手法で解決。

また、Proxy Light Volumeやライトマップ、焼きこみにも対応しています。


### HDRと好相性

物理ベースマテリアルと同じく、直接光や間接光からの光がそのままモデルの明るさとなる。  
そのため周囲の明るさに自然にと馴染み、ブルームやトーンマッピングで四苦八苦する時間が、50%以下。


### セットアップが簡単

> ![スクリーンショット (413).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/8c550e26-f00b-5ded-e892-5ce1adcc1b3e.png)
> 右側のインスペクターに表示されているものが、マテリアルの設定項目

トゥーンシェーダーにありがちな、レイヤー分けやモデルの加工などの事前準備も不要。  
また、マテリアルのパラメーターも多くなく、標準マテリアルやMMDのものと近いため移植や調整が簡単におこなえます。

我慢や忍耐に対する反論としても有効。


### シェーダーカスタマイズも可能

> ![gif_animation_001.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/50544e88-e185-db4e-00d5-d5a69ddd70bf.gif)
> サーフェイスシェーダーを通してカスタマイズした例

「キャラにエフェクトを追加してほしい」  
こんな単純明快な要求から、コード解析を伴う複雑な作業に発展していくことがありえます。

付属のシェーダーはサーフェイスシェーダーによって実装されていて、右クリックで新しく作成することも可能。

また、いくつかの処理は関数化されており、機能の一部を既存のシェーダーに組み込むことができます。

## ギャラリー

それまで作ったものの紹介

![sc18.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/20301af7-c0dc-2b56-c22b-57894f3b662c.jpeg)


![screen_2048x1024_2017-12-09_14-47-16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/b5d771c1-69e0-be3a-5f54-8ffdd9b1e518.png)

![screen_3840x1920_2018-02-01_00-53-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/512142/82556ef5-eb09-1929-fa66-f176f3f23158.png)



## 今後の予定

基本設計が最新のものでも2018年であるがゆえにShader GraphやVFXなどの新機能との連携に課題がある。

今後は、LWRPやHDRPとの連携や、専用のレンダリングパイプラインの開発などを検討していく予定。

## ダウンロード

[https://github.com/Masterexa/HoshiyukiToonShader/releases](https://github.com/Masterexa/HoshiyukiToonShader/releases)
PEP-593 (Flexible function and variable annotations) を読んだよメモ

ある議論の流れで [PEP-593 (Flexible function and variable annotations)](https://www.python.org/dev/peps/pep-0593/) を読むことになったので、自分の理解をメモに残しておく。

## 概要

* [PEP-3107 (Function Annotations)](https://www.python.org/dev/peps/pep-3107) は Python の文法にアノテーションを導入した。その際、アノテーションの用途として型ヒントや DB クエリーのマッピング、RPS のマーシャリング情報などを挙げていた。
* [PEP-484 (Type Hints)](https://www.python.org/dev/peps/pep-0484) はアノテーション記法を使って型ヒントを実現する方法を導入した。いまやアノテーションの主たる利用方法であると言える。
* PEP-484 がデファクトスタンダードとなった今、型ヒント以外の用途にアノテーションを使いづらくなってしまった。
* そこで、アノテーションを再定義して型ヒントに加えて、さらに独自のメタデータも記述できるようにするよ。

## アプローチ

* 新たに `typing.Annotated` を追加する
* あるデータや関数に型 T とメタデータ x, y をアノテーションするときには `Annotated[T, x, y]` と書く
    * 先頭の要素は型とみなされる
* 型チェッカーは `T` を、メタデータを利用するツールやライブラリは `x` や `y` をそれぞれ参照すればよい
    * つまり、ツールやライブラリはサポートしていないアノテーションを無視してくれる

## 例

数値で、3-10 の範囲の値で、ctype では文字とみなされるような(架空の)アノテーション。

```py
Annotated[int, ValueRange(3, 10), ctype("char")]
```

## 感想

* `Annotated` って書きづらい。もっとラフに tuple で書きたかった…
* 実行時でもアノテーションの内容を取得できる(`get_type_hints()`)ので、これを使うライブラリやフレームワークが出てきそうな予感
* 乱用された結果、カオスなコードにならないことを祈りたい
* PEP-3107 (関数アノテーション)は紹介されているのに [PEP-526 (Syntax for Variable Annotations; 変数アノテーション)](https://www.python.org/dev/peps/pep-0526/) には一切言及がない。不憫な子…
    * もちろん関数だけでなく変数にもアノテーションできます。
* Sphinx でも対応しなくちゃ…
    * 引数や変数の説明をアノテーションできそうだけど、どう考えても書くのがだるいので流行らない気がする
    * [イシュー作っておいた](https://github.com/sphinx-doc/sphinx/issues/7165)。きっと明日の自分がやってくれる…。

```py
def hello(name: Annotated[str, Description("名前")],
          message: Annotated[str, Description("メッセージフォーマット")],
          language: Annotated[str, Description("言語")] = "ja"
          ) -> Annotated[None, Description("なし")]:
    ...
```
【Vuejs】axiosを使ってみる

公式ドキュメントを参考に試してみました。


公式ドキュメント#基本的な例
https://jp.vuejs.org/v2/cookbook/using-axios-to-consume-apis.html#%E5%9F%BA%E6%9C%AC%E7%9A%84%E3%81%AA%E4%BE%8B

##スタブ
スタブを用意するのが面倒なので公式ドキュメントにも載っている以下を利用します。
https://api.coindesk.com/v1/bpi/currentprice.json
こんな感じのJSONが返ってきます。
![Screenshot2020-02-16_21-31-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371771/99a69ada-f0c7-08e9-da46-2f70f90a77b0.png)

##作ったもの

```html:sample.html
<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Test</title>
</head>

<body>
    <style>
        .bpi.header {
            background-color: beige;
        }
        .bpi.even {
            background-color: azure;
        }
        .bpi.odd {
            background-color: beige;
        }
    </style>

    <div id="app">
        <div id="rawdata">
            <strong>rawdata :</strong><br>{{coindesk}}
        </div>
        <br>
        <div id="update_time">
            <strong>update_time :</strong>{{coindesk.time.updated}}
        </div>
        <div id="desc">
            <strong>disclaimer :</strong>
            {{coindesk.disclaimer}}
        </div>
        <div id="chartName">
            <strong>chartName :</strong>{{coindesk.chartName}}
        </div>

        <table>
            <tr class="bpi header">
                <th>No.</th>
                <th>code</th>
                <th>symbol</th>
                <th>rate</th>
                <th>description</th>
                <th>rate_float</th>
            </tr>
            <tr v-for="(e,key,index) in coindesk.bpi" v-bind:class="[index % 2 == 0 ? 'even' : 'odd']" class="bpi">
                <td>{{index+1}}</td>
                <td>{{e.code}}</td>
                <td>{{decode(e.symbol)}}</td>
                <td>{{e.rate}}</td>
                <td>{{e.description}}</td>
                <td>{{e.rate_float}}</td>
            </tr>
        </table>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script>
        var app = new Vue({
            el: "#app",
            data: {
                coindesk: null,
            },
            mounted() {
                axios
                    .get('https://api.coindesk.com/v1/bpi/currentprice.json')
                    //.then(response => (console.log( response.data)))
                    .then(response => (this.coindesk = response.data))
            },
            methods: {
                decode: function (str) {
                    return str;// TODO デコード結果を返したい
                }
            }
        })
    </script>
</body>
</html>
```

##実行結果
![Screenshot2020-02-16_23-02-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/371771/4e86aef5-054e-4e78-e8f1-f28625364228.png)

##ポイント

- 配列ではなくオブジェクトをv-forする場合はkey,indexの2つ必要だった。
- 公式ドキュメントだと`response => (this.info = response)`となっているけどAPI叩いた時のレスポンスは`response => (this.info = response.data)`の中にある。
- ライフサイクルはmountedでなくてもcreatedでも多分OK。
基本情報技術者　マネジメント系　第2章 プロジェクトマネジメント③


# ③サービストランジション、サービスオペレーション


## サービス資産及び構成管理
これの役割はITインフラを構成する要素について最新情報を管理することです。
下記の管理があります。

* 計画立案
* 識別
* 状態の監視
* コントロール
* 検証と監査

### CMDB
Configuration Management DataBase: 構成管理データベース
サービス資産及び構成管理の情報の記録をしています。


### CI
ConfigurationItem
サービス資産及び構成管理の対象となる要素

## 変更管理
変更手続きを定めることです。
RFCの検討から主に進めます。

下記の作業があります。

* 記録
* 受入
* 分類
* 計画立案
* 調整
* 評価

### RFC
Request For Change
ITインフラに変更を加える場合に提出する文書

## リリース及び展開管理
本番環境に投入すること

主な作業は以下です。

* 計画立案
* 設計、構築、設定
* 切り戻し計画
* テスト、リリースの受入
* 導入計画
* コミュニケーションと準備
* 配布とインストール

### メジャーリリース
新機能など大規模改修の場合

### マイナーリリース
バグ修正など小規模の場合

### 緊急リリース
セキュリティなど緊急の場合

## サービスデスク
最初の窓口

主な作業はこちらです。

* 質問、問合せ対応
* 情報提供
* サプライヤへの連絡
* 運用管理
* ITインフラの管理

## サービスデスクの形態

* 中央サービスデスク: 一箇所集中
* ローカルサービスデスク: 拠点ごと
* バーチャルサービスデスク: 複数拠点に設置し通信回線で相互に接続した形式

## インシデント管理
インシデント: 障害や事象

管理とはインシデント発生時に応急策を迅速に指示することです。

根本原因究明は後回しです。

下記の作業があります。

* 受付と記録
* 分類
* 照合
* 調査と判断
* 解決と復旧
* 終結
* 進捗の追跡を監視


## 問題管理
インシデントの根本原因解決

いきなりは修正はせず、一度提案してから
余計な悪影響が出ないか確認してから行います。

下記の作業があります。

* 問題の識別と記録
* 問題の分類を割当
* 問題の調査と診断
* 応急修正
* 解決と復旧
* 終結
* 進捗の追跡と監視

### プロアクティブ問題管理
予防的に問題管理を行う

### 既知のエラー
解決と復旧に至ってるエラー

### 未知のエラー
問題そのものがわかってない
Git概要

# 引用

https://www.atmarkit.co.jp/ait/series/3190/
https://www.ricksoft.jp/blog/archives/9483/
https://note.nkmk.me/git-config-setting/

# 3つの場所

- Gitリポジトリ
    - ファイルやディレクトリの状態を保存する領域
    - 実態は作業ディレクトリの中の「.gitディレクトリ」
- 作業ディレクトリ
    - ファイルの編集作業を行うディレクトリ
- ステージングエリア
    - 作業ディレクトリとGitリポジトリの中間に存在する領域。
    - コミットする準備ができたファイルはここに追加

# ファイルの状態

- tracked:追跡している
    - unmodified
        - スナップショットがリポジトリに保存されているファイル
    - modified
        - Gitが変更を追跡しているが変更がリポジトリに保存されていないファイル
    - staged
        - ステージングエリアに追加され、次回コミットの対象となっているファイル
- untracked:追跡していない

# コミット

- **コミットはその時点の全てのファイルの情報を持つ**
- Gitはコミット単位で変更履歴を管理し、以下の情報を登録する
    - リビジョン(SHA-1 ハッシュ)
    - Author(コミットを作成した人)
    - Committer(コミットを適用した人)
    - 全ファイルのツリー情報のスナップショット
    - 1つ前のコミットのリビジョン
- 差分は比較対象のコミット同士だけで可能

# ブランチ

- ブランチの実態は**「一連のコミット履歴」の最新のコミットを指すポインタ**である。
- HEADは基本的にカレントブランチを指す

| Gitブランチの操作  | イメージ |
|:-----------------|:------------------|
| 作成             | 最新コミット情報に目印をつける |
| コミット           | コミット情報を作成して目印を移動する |
| マージ             | 新しいコミット情報を造りそこに目印を移動する |
| 削除               | コミット情報から目印を失くすこと(コミット情報は削除しない) |

# Gitの設定

## ファイルの種類と場所(system, global,local)

|種類|対象範囲|場所|備考|
|:---|:---|:---|:---|
|system|システム全体|/etc/gitconfig|-|
|global|該当ユーザの全リポジトリ|~/.gitconfig|ホーム直下|
|local|該当リポジトリ|repository/.git/config|リポジトリの.git直下|

- system, global,localの順に読み込まれる。

## 設定の確認

- コマンドを実行した場所で有効になっている値が表示される。値が設定されていなければ何も表示されない。

```
git config <項目>

# 例
git config user.mail
example@example.com
```

- system, global,localそれぞれの設定値の確認にはオプションをつける

```
git config --system <項目>
git config --global <項目>
git config --local <項目>
```

※`--local`オプションはGitで管理されていない場所でコマンドを叩くとエラーになる

## 設定の一覧表示

- コマンドを実行した場所で有効になっている設定項目とその設定値が全て表示される

```
git config -l
```

- system global localのそれぞれの設定を個別に確認する場合はオプション付与

```
git config --local -l
git config --global -l
git config --system -l
```

## 設定の変更

- `git config <name> <value>`で各項目の設定を変更できる
- オプション無しだとlocalの設定が変更される
- globalやsystemの設定を変更したい場合はオプションをつける

```
git config <name> <value>  # ローカルの設定を変更
git config --global <name> <value>
git config --system <name> <value>
```

※Gitで管理されていない場所でオプション無しでコマンドを叩くとエラーになる

# SSH keysの作成

```
$ ssh-keygen -t rsa -b 4096 
```

- `-t`オプションで作成する鍵の暗号化形式を指定できる。rsaはデフォルト
- `-b`オプションで鍵の長さを指定
    - ssh-keygenのデフォルト値2,048ビット。GitHubの推奨は4,096ビット。
- 公開鍵の場所
    - ~/.ssh/id_rsa.pub
- 秘密鍵の場所
    - ~/.ssh/id_rsa
- 引用
    - https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000#ssh-keygen%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%A7%E9%8D%B5%E3%82%92%E7%94%9F%E6%88%90%E3%81%99%E3%82%8B

## 公開鍵の中身をコピーする

```
clip < ~/.ssh/id_rsa.pub
```
UnityのTileMapのすき間が大きく空いてしまう場合の調整方法

UnityのTileMapを使用してマップを作成する際に、ブロックとブロックの間が空いてしまう問題の解決に時間がかかったので備忘録としてメモ。

タイル同士のすき間が1ピクセル空いてしまうような問題はググると解決策が色々でていたのですが、自分が探していたのは違う問題でした。

# 原因
画像のSpriteModeはMultipleで、Pixel Per Unitを16にしていました。
SpriteEditorで、CellSizeは8にしていました。
この状態だとタイルマップを敷き詰めた時に1ブロックに対して半分くらいの大きさになってしまっていました。

# 解決方法
SpriteEditorのCellSizeの8は正しい設定だったので、Pixel Per Unitを8に修正しました。
この状態だとタイルマップをシーン上に並べた時に、想定しているブロックのサイズの2倍になってしまいました。
この大きさの調整は、ヒエラルキー上にある、タイルマップのScaleをx:0.5、y:0.5に設定したところ、意図した大きさになりました。
どこの値を変更するのかがわからずに地味に時間がかかってしまいました。

# 追記
テラテイルのアカウントを持っていないので回答していませんが、本記事と同じ問題を抱えている人が少なくとも1人はいたようなので記事にしました。

[Unity TileMap・Tile Paletteを使ってタイルを隙間なく並べる方法](https://teratail.com/questions/204269)
※2020年2月16日時点で回答がついていませんでした。
TypeError: validator is not a functionが解決しない

#とりあえず初心者向けの書籍を一冊購入。
とにかく写経でもいいから一通りのアプリを作成したいと動きをメモしつつとりあえず書き上げた。
さあ動かしてみよう

#しかしコンソールログに出たのは・・・
```
TypeError: validator is not a function
```

#いやいや読み込んでますけど汗
```js
var validator = require('express-validator');
// ～～～～～～
// (中略)
// ～～～～～～
app.use(validator());
```

※本当はvar使っちゃいけないけどとりあえず写経なので、
あとサンプルのソースと比較しやすいためこのままにしてます

#どこが違うのか比較しよう
ソースは同じ汗

となると、インストールしたモジュールのバージョンがちがうのか？

以下自分のpackage.json

```json:package.json
{
  "name": "mini-board-2",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "bookshelf": "^1.1.0",
    "cookie-parser": "~1.4.4",
    "debug": "~2.6.9",
    "ejs": "~2.6.1",
    "express": "~4.16.1",
    "express-session": "^1.17.0",
    "express-validator": "^6.4.0",
    "http-errors": "~1.6.3",
    "knex": "^0.20.9",
    "morgan": "~1.9.1",
    "mysql": "^2.18.1"
  }
}
```
以下サンプルのpackage.json

```json:package.json
{
  "name": "mini-board-2",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "bookshelf": "^0.13.3",
    "cookie-parser": "~1.4.3",
    "debug": "~2.6.9",
    "ejs": "~2.5.7",
    "express": "~4.16.0",
    "express-session": "^1.15.6",
    "express-validator": "^5.2.0",
    "http-errors": "~1.6.2",
    "knex": "^0.14.6",
    "morgan": "~1.9.0",
    "mysql": "^2.15.0"
  }
}
```

#全然違う
バージョンをそろえて、npm install

#通りました
```
$ npm start

> mini-board-2@0.0.0 start C:\Users\user\Desktop\mini_board_2
> node ./bin/www

GET / 302 118.593 ms - 56
GET /users 200 179.510 ms - 1242
GET /stylesheets/style.css 200 22.919 ms - 753
GET /favicon.ico 302 5.750 ms - 28
GET /users 304 9.479 ms - -
```

#原因は？
最初にいろんなパッケージをインストールする際、最新のパッケージをインストールしたためではないか。
本自体は昨年の５月に改訂されたがいろいろググるうちに自分と同じエラーを質問している方がいて、書き方が古いですよーみたいなことを言われている。
たしかに、ほかに出していたpaginationのエラーも今はこういう書き方ですよーみたいな内容の文章があった。

最新のNode.js情報を追いかけなければ。

#参考文献・サイト
・掌田 津耶乃 （2019/5/10）Node.js超入門[第2版] 秀和システム
・https://qiita.com/maitake9116/items/7825d90c09f3e2f87dea
・https://stackoverflow.com/questions/56711444/typeerror-validator-is-not-a-function-after-installing-and-requiring-express

#追伸
terat●ilで同じエラー質問したやりとりみてて安定のググレカス。
このサイトで回答するひとってこういうタイプ多くない？
インフラ/AWS 基礎知識①プロトコル　IPアドレス　サブネット　Ping

#はじめに
エンジニアとしての最低限のインフラ基礎知識をわかりやすくメモ用として記録する。
自分自身苦労した部分でもありますので参考になれば...

#OSI基本参照モデル(Open System Interconnection)
ネットワークの各装置が「どの層に属するか」「何を中継するのか」、ISO（国際標準機構）が７階層（レイヤー）にまとめたもの。

| 階層 | 階層名 | 概要 |
|--:|:--|:--|
| 7 | アプリケーション層 |アプリケーション間でのやりとりするデータ形式や内容を提供する|
| 6 | プレゼンテーション層 |データの表現形式の制御や変換を行う|
| 5 | セッション層 |プログラム間の会話単位の制御を行う|
| 4 | トランスポート層 |伝送するデータの順序やデータの紛失に対する誤り検出や回復処理等を規定する|
| 3 | ネットワーク層 |ルーティングや中継機能、コネクションの確立と解放などの規定する|
| 2 | データリンク層 |隣接するノード間での伝送制御手順を提供する|
| 1 | 物理層 |コネクタの形状やケーブルの材質、データを電気信号に変換する方法等規定する|

***＊ノードとは***
節点という意味があり、ネットワークに接続された機器やネットワークとネットワークを接続する機器のこと！
<img width="921" alt="スクリーンショット 2020-02-16 21.01.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/9826218c-bd0f-0ec2-3f22-c71353206f2c.png">

##Pingとは
通信相手との接続性を確認するコマンド

ネットワークやサーバーがつながらない時、つながりにくくなった時の問題切り分けで使用する。

#プロトコル
ネットワークではコンピュータ同士が通信する時の手順や約束事のことを言います

####TCP/IP階層モデル

|  | 名称 | 役割 | プロトコル |
|:--|:--|:--|:--|
| 4層 | アプリケーション層 | アプリケーション間のやり取り | HTTP、POP3、SMTP、FTP、DHCP, DNS, TFTP, IMAP4 |
| 3層 | トランスポート層 | プログラム間の通信、通信の制御 | TCP、UDP |
| 2層 | インターネット層 | インターネットワークでの通信 | IP、IPsec |
| 1層 | ネットワークインターフェイス層 | 同一ネットワーク上での通信、ハードウェア仕様など | Ethernet、PPP

#IPアドレス
インターネットに接続された装置間で通信を行うために必要な住所のようなもの
「通信したい相手」「通信してきた相手」の判別に利用される

192.168.1.1(10進数)
      ↓
11000000.10101000.00000001.00000001(2進数) <-- ８ビットずつ区切る

### DNS(Domain Name System)
インターネット上でドメイン名（IPアドレスに文字で別名付けたもの）を管理・運用するために開発されたシステム
DNSサーバーは***ドメイン名やホスト名などとIPアドレスを対応付け***する。
***例***
①www.  　　　　　②hogehoge. 　　③co.  　　④jp
①コンピュータの名前　②組織の名前　　③組織の種類　④国の名前

#クラスとサブネット
##IPアドレスのクラス
IPアドレスの３２ビットは、***ネットワーク部***と***ホスト部***で構成されます。端末やネットワーク機器を「どのネットワークに属するのか」「どのホスト（コンピュータ）か」を示す。
##クラス
クラスA：/8 => 255.0.0.0(（2^24） = 16777216ー2台) =>大規模
クラスB：/16 => 255.255.0.0(（2^16） = 65536ー2台)　=>中規模
クラスC：/24 => 255.255.255.0(（2^8） = 256−２台) =>小規模

##サブネットとは...
大きなネットワークの中にある小さなネットワーク。
これにより、インターネットからのアクセス制限をかける。
##利点
・余計な通信を発生させない
・ある程度のセキュリティ向上につながる

<img width="668" alt="スクリーンショット 2020-02-16 22.01.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522222/d13adc50-1511-07cd-854a-caeb02a1d406.png">
##サブネットマスクとは
####簡単にいうとサブネットを柔軟に決定できること！
####ネットワーク部（サブネット部含む）に１、　ホスト部に０を入れて区切りを設定する

例えば...
ある会社が３００台のパソコンのIPアドレスを用意したいが...
下の**クラスC**だと足りないので**クラスB**に上げないといけない...

クラスC：/24 => 255.255.255.0(（2^8） = 256−２台) =>小規模
クラスB：/16 => 255.255.0.0(（2^16） = 65536ー2台)　=>中規模

クラスBにあげた場合**６５０００以上ものをIPアドレスが余ってしまって無駄..**

そこでサブネットマスク！！
/23, /28,など

####10.0.0.0/23：10.0.0.0 ～ 10.0.1.254 (512台に付与)
####10.0.0.0/28：10.0.0.0 ～ 10.0.0.254 (14台に付与)
とできる
##補足①　CIDR（サイダー）/Classless inter-Domain Routingとは
###サブネットマスクを使ったIPアドレスの管理方法
サブネット導入でネットワーク部とホスト部の境界を、下位ビット側に柔軟に移動できるようになりました。さらに進めたものがCIDRで、８ビット単位で区切るクラスの枠を取り払い、最上位ビットから１ビット単位でネットワーク部とホスト部の境界を設定できる考え。
###CIDR表記とは
#####IPアドレスとサブネットマスクを一緒に表記する方法
##補足の補足② プレフィックス表記とは
まとめると「198.51.100.xxx/24」のような形でIPアドレスとサブネットマスクを表現する表記方法が「プレフィックス表記」です。
つまり
###「CIDR表記」と同じ意味。

##最後に
至らない部分がありましたら、よろしくお願いします。

####今度はネットワークを構成する装置をまとめたいと思います！
bundle install --path vendor/bundle で余計なコードをgit管理から除外するために。

## はじめに
```
$ bundle install --path vendor/bundle
```

私は普段、Railsアプリを作成する際に、gem のインストール先が Ruby 環境でなくプロジェクト毎に gem を管理できるようにvendor/bundleフォルダをインストールパスに指定してこのコマンドを実行しています。

ですが、vendor/bundle を .gitignore に設定していないと、すべての gem が git 管理されてしまい、 bundle install 後の git push がけっこう重くなったりしていました。それに、必要な gem は git 管理対象の Gemfile と Gemfile.lock に書いてあるので、vendor/bundle 配下にある gem 自体を git 管理する必要がそもそもありませんでした。

##対処法

vendor/bundle の git 管理から外すため、.gitignore に vendor/bundle を追記します。

```ruby:.gitignore
vendor/bundle
```


本来はアプリを作成して bundle install する前にこれをやっておけばよかったのですが、私の場合はこれをやらなかったので、もうひと手間必要になりました。

####1.ローカルで vendor/bundle を削除
```
$ rm -rf vendor
```
ローカル上の vendor/bundle 配下のディレクトリが全て消去されます。リモートとの差分を確認すると、削除した vendor/bundle 配下のディレクトリ等が赤字で表示されます。

```
$ git status
deleted:    vendor/bundle/~~~~~~~~~~~~
・
・
・
・
```


####2.変更した内容をリモート(GitHub)にpush
```
$ git add .
$ git commit -m "vendor/bundleの削除"
$ git push origin master
```
ローカルとリモートのコードの差分がなくなります。

####3.再度bundle installの実行
```
$ bundle install --path vendor/bundle
```
ローカル側に再び vendor/bundle が復活します。

####4.Git管理からの除外確認
```
$ git status
On branch master
nothing to commit, working tree clean
```
.gitignore 編集前は、 bundle install 後の git status で vendor/bundle 配下のディレクトリ等が大量に差分変更として表示していましたが、 git 管理から除外したため`working tree clean`の表示になりました。

今後はこのように gem を管理していこうという自分への戒めです。今回は以上となります。
[Nuxt.js]レイアウトをページによって切り替える

# [Nuxt.js]レイアウトをページによって切り替える

## 開発環境
```package.json
"dependencies": {
    "nuxt": "^2.0.0",
  }
```

## レイアウトの作成
Nuxt.jsではページで共通のレイアウトを作成する場合、layoutディレクトリのファイルを利用できます。
現在のところ（上記のバージョン）lauoutsディレクトリにはdefault.vueとerror.vueファイルがあります。一つのレイアウトに統一できる場合、default.vueを編集すると、自動でそのレイアウトが当たります。
　このレイアウトをページによっては違うデザインを当てたい、という場合は二つの方法を考えました。以下、その説明です。

## 方法１：レイアウトのファイルをもう一つ作成する
公式のドキュメントに書いてあるのですが（僕は最初あまり読んでなくて方法がわからなかった...）、そもそもページごとにレイアウトを利用するには、

```vue

export default {
  lauout: default
}
```
と明示する必要があります。では、なぜ記述がなくてもdefault.vueが呼び出されているのかというとdefault.vueの場合のみ、省略可であるためです。つまり、別のレイアウトを使いたいなぁと思った時は、layoutディレクトリにvueファイルを用意して、利用したいページで上記の記述をすれば良いのです。
注意点して、コンポーネントを利用する場合と違って**インポートをする必要がない**ことです。

## 方法２：条件によって表示非表示を切り替える
レイアウトの中身を条件によって切り替えるには`v-if`や`v-show`などを用います。
その条件とは、パスによって切り替えるか、ストアで何らかのフラグを立てるなど、様々な方法があるかと思います。レイアウトの切り替えのためにstateに新しく値を増やすのはお勧めできませんので、できれば何らかの処理と連動したトリガーを作れるのがベターかと思います。

## 方法１と２はどちらが良いのか
お察しの方もいるかと思いますが、１では別のファイルを作成しているため、全く違うレイアウトになったり、複数のページで利用するなどのケースにおいていいと思います。一方で、２の場合は、レイアウトを一部のみ変えたい場合や、同一ページ内で処理によってレイアウトを変えたい場合などに最適であるかと思います。

##最後に
僕もまだまだ勉強中なので補足、ご指摘等あればお願いします。
【MySQL】はじめてのクエリチューニング vol.4 インデックス以外のチューニング例

インデックス作成はクエリチューニングにおいて、劇的な改善が期待できる重要なものですが

それ以外にもチューニングする方法はあり〼

その一例

## 目次
1.データ型の見直し

2.必要なカラムのみ指定

3.サブクエリの見直し

4.IN を EXISTSに

5.DISTINCTをEXISTSに

6.ALLを使う

# データ型の見直し
テーブルに設定したデータ型と入力したデータのデータ型が異なっていた場合、

変更可能であればエラーにならず暗黙の型変換が行われ、その分時間がかかる

# 必要なカラムのみ指定
SELECT時に *(ワイルドカード)　を使っていると不要なカラムまで取得することになる

全てのカラムを取得したい場合も、カラム名に置き換える処理が内部で行われているので書いた方が良い

# サブクエリの見直し
・テーブル結合で書き換えられる場合もある

・EXISTSを使用したサブクエリの場合はテーブル結合よりEXSISTの方が早い場合もある

# IN を EXISTSに
・書き換えられる場合は、ワークテーブルが作られない分INより速い

・該当する値があった場合検索をストップ

・WHERE(結合キー)にインデックスが貼られていれば実テーブルを見にいかなくてよい

ただOracle、PostgreはINでも同じパフォーマンスを発揮できるようになってきている

# DISTINCTをEXISTSに
・ソートを回避できる分速くなる

# ALLを使う
・集合演算子(UNION INTERSECT EXCEPT)は必ず重複削除が行われる

・重複が発生しない(重複削除が不要な)場合はUNION ALL のようにALLを使う
Reactで.envがどうしても読めなかった時に試してみるといいかもしれないこと

Reactで環境変数を.envファイルから読み込みたかった時の話です。
どうにかした軌跡を置いておきます。

## TL;DR
- webpack.config.js内に設定を追加した
- dotenv-webpackはなんかのタイミングで入ってたけど、入ってなければ入れるとよいと思います
  - 僕はたぶんbabelかstorybook入れたとき入った

```webpack.config.js
const Dotenv = require('dotenv-webpack');

plugins: [
  new Dotenv()
],

// なんか言われたら
node: {
  fs: 'empty'
}
```

## ざっくり環境
- create-react-appした
- webpack-dev-serverで動かしてる
- .envのREACT_APP_HOGE_KEYがundefinedになる

## 経緯
公式に従って設定してみたのですが、どう頑張ってもundefinedになりました。
プロジェクトのルートに `.env` ファイルを作り、`REACT_APP_`から始まるものを定義すればいいよと書いてあります。適当にググってもそんな感じの内容が出てきます。
https://create-react-app.dev/docs/adding-custom-environment-variables/#adding-development-environment-variables-in-env

でもダメでした。

デフォで入ってるのでダメなら改めて自分で入れてみるかぁと思い調査。

## 結論
明示的に`dotenv-webpack`を利用することに。
公式: https://www.npmjs.com/package/dotenv-webpack
参考: [Can't resolve 'fs' https://megu-tech.hatenablog.com/entry/2019/10/09/170631](https://megu-tech.hatenablog.com/entry/2019/10/09/170631)

`webpack.config.js`に設定を追加。

```webpack.config.js
const Dotenv = require('dotenv-webpack');

plugins: [
  new Dotenv()
],

// なんか言われたら
node: {
  fs: 'empty'
}
```

で読めるようになりました。webpack絡みでなんか起きてるのかなと思いつつも学びきれてなさみです。