OmniAICreator/Qiita-1.07M huggingface dataset:
Capistranoによる自動デプロイエラー（Rails）：Missing encryption key to decrypt file with. Ask your team for your master key and write it to

# 手動デプロイできたのに、自動デプロイができない！！！

そんでもって、master.keyがないエラーが表示されるんですけど、どうすればいいんだ！！！

となる方いると思います。


下記をすれば改善するので、早速取り組みましょう

## Master.keyがないエラー（　Missing encryption key to decrypt file with. Ask your team for your master key and write it to　）
このエラーが表示されたということは、『  本番環境にあるmaster.keyをうまく読み込めていない  』ことを意味します。

```
rake stdout: Nothing written
rake stderr: Missing encryption key to decrypt file with. Ask your team for your master key and write it to /var/○○○（アプリを格納しているディレクトリ名）/○○○（アプリ名）/releases/20200121124714/config/master.key or put it in the ENV['RAILS_MASTER_KEY'].
```

なので現状として可能性は二つです。

- master.keyを作成していない。
- master.keyを作成する場所が間違っている。

ここまで作業を進めている人は,master.keyを作成しているはずです。
＞つまり、master.keyの作成場所をまちがている可能性が高いです。
＞作成していない人も解説しますので、このまま読み進めてください。

```
# 誤解が生まれやすいmaster.keyの作成場所

✖︎ アプリ名＞config＞master.key　　　　　　 #こっちだとエラー
○ アプリ名＞shared＞config＞master.key　　#正しい作成場所

```
おそらく、上記のようにmaster.keyの作成場所に誤りがある可能性が高いです。
ですから、

```:ターミナル（EC2）
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ cd shared 
[ec2-user@ip-172-31-23-189 shared ]$ cd config
[ec2-user@ip-172-31-23-189 config ]$ ls
＞ここでmaster.keyがない場合、 master.keyを作成してください。
```
master.keyを作成する場合、、、

```:ターミナル（ローカル）
アプリ名 $ vi config/master.key
＞master.keyを中身がわかります。ここでコピーしましょう
＞間違っても編集しないようにしましょう
```
EC2にmaster.keyを作成しましょう

```:ターミナル（EC2）
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ cd shared/config
[ec2-user@ip-172-31-23-189 config ]$ vi master.key
＞編集画面が出るので
＞ローカルのmaster.keyをコピペします。
＞:wpで保存しましょう
```
あとは、deploy.rbにmaster.keyを読み込ます設定をします。
下記を追加してください

```ruby:deploy.rb
set :linked_files, fetch(:linked_files, []).push("config/master.key")
```

これで改善します

```
# アプリケーションのディレクトリで実行する
$ bundle exec cap production deploy
```
価格比較サイトの最安値更新通知をPower Automateで作る

HTML解析して通知系も3本目です。
今回はとある商品価格比較サイトで、目的とする商品の現在価格を定期通知してくれるFlowをご紹介します。

参考：https://qiita.com/h-nagao/items/fdbfcf4a7dae6373a224
# 準備
## データ保存場所
SharePointに商品名と、そのURL、購入の判断基準額(criteria)、そして現在の最安値(currentPrice)を含むリストを用意しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/5513841a-3081-fbb4-617e-127ea4ca1755.png)

Urlがハイパーリンク列、criteriaとcurrentPriceは数値型です。

## 解析対象
商品のページのHTMLを見てみると、今回も非常にやさしい形で現在の最安値が表示されていました。
```<span class="priceTxt">...``` の部分です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/aa744c5b-a93e-2c3a-f91e-5c1bdec04229.png)

Videoの更新通知の時と同じ要領で、価格の文字列を抜き出してあげます。

```
int(replace(split(split(body('HTTP'),'<span class="priceTxt">&yen;')?[1],'</span>')?[0],',',''))
```
最初のsplitは、上に書いている<span ...>での分割です。円マークは**＆yen;**で指定しないといけません。
2個目のsplitは、<span>の閉じ部分、</span>での分割です。ここまでの2回splitで**150,956**という文字列が取得できました。
あとは**replace**関数で、1000の位のカンマを取り除いて、最後にintで整数にします。

# Flowの全体
コアな処理は上記の、現在の最安値取得で完了しています。
あとはリストに保存している現在値や基準額との差をとって通知を行いましょう。

今回はリストのアイテムの最初だけを使うので、以下のような引き算をしています。
※実際には複数アイテムを確認すると思いますので、その時はループの変数を使ってください。

```
int(sub(variables('lowestprice'),body('Get_items')?['value']?[0]?['criteria']))　#これで基準との差額計算

int(sub(variables('lowestprice'),body('Get_items')?['value']?[0]?['currentPrice']))　#これで前回との差額計算
```

「最初のアイテムだけ使っている」というのは、**body('Get_items')?['value']?[0]**に表れています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/142d5b81-2045-b8d2-9c8e-6527fdbfc6e5.png)

これで完了です。
実際に動かすと、このような感じで通知がきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/2e760422-6ad2-8b65-ee2b-be7a4d1c42aa.png)

基準額を達成したら即ぽちりましょう！

# おわり
HTMLを解析していろんな生活の役にたつ通知を自分でつくることができます。
とにかくとりたい値の前後でsplitしてみることからはじめましょう！少しHTMLを見る必要はありますが、慣れればすいすいと行くと思います。

なお、HTTPアクションはほかのアクションで置き換えることも可能です。
以下のリンク先を参考にしてみてください。
https://qiita.com/h-nagao/items/65f498d9d4e4f1a5fa50
ナメられないエディタ

究極的には使いやすいと感じるものであれば何でもいいんですが、
世の中にはたくさんのエディタがあり「どれを使ったらいいか分からない」という方もいらっしゃると思うので
土曜日テイストでエディタをご紹介していきます。

# 結論

現役のフロントエンドエンジニアの立場から
ナメられないエディタを挙げるとしたら **VS Code** が適切だと思います。

これはもう知ってる人からすると
何の面白味もない回答で、それほどいまの時代ダントツの人気を誇ってます。

# 理由

で、これだけだとつまんないので土曜日らしくもう少し深掘りすると
VS Codeが適切だとする理由が3つあります。

## 1. State of JS 2019 の結果

1つめの理由は State of JS 2019の結果です。
State of JSとは、全世界の2万人以上の開発者にアンケートをとってその年のトレンドなどをまとめたWebサイトで
そこのエディタに関する質問でVS Codeが**ぶっちぎりの1位**でした。

![text_editors (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/35b1a371-b7ce-6d25-ddef-b13880727ff5.png)

利用者が多いということは
それだけメンテされやすい、情報が多いということ。

つまり、私たちフロントエンジニアは
エディタの設定とか不具合に時間を消費することなく
開発に集中できるということだと思います。

よく、新しい技術が出た時に、
「この拡張子はエディタが対応していない！（悲）」ってことがあるんですけど
VS Codeだったらいち早く対応すると思います。

Reactも出始めは対応してないエディタがありました。 ※jsxという拡張子にエディタが対応していない
それと同じようなことが今後もあると思います。


## 2. 昨今のTypeScriptブーム

2つの理由は昨今のTypeScriptブームです。
TypeScriptはMicrosoftが開発していて、VSCodeもMicrosoftが開発しているので
TypeScriptが最も使いやすいエディタと言えます。

具体的には、TypeScriptって日々バージョンアップしていて、
例えばいまだとv3ですが、仮にv4とか出て新しい記法が使えるようになったときに
VS Codeは他のエディタよりも先に補完機能とか効いた状態で使えると思います。

## 3. 世界のギークも使っている

3つめの理由はギークも使っているということで
例えばvaadinという世界でも有数のOSSのチームがあるんですが
そこのコミッターもVSCodeを使っていました。

![cp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/82880334-b98f-f659-d754-aef7985fa969.png)

また、日本だとmizchiさんもVSCodeを使われているようです。

![スクリーンショット 2020-01-21 0.17.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/47b95bea-3fca-e72b-2636-ad8743457a2c.png)

ある意味これが一番説得力があって、
すいもあまいも経験したギークが使っているエディタということは
それだけ高品質であるということの裏付けにもなります。

# エディタ一覧表

![名称未設定-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124296/9e1659ac-93bf-a47d-0245-26296c9be51d.png)

まとめるとこんな感じです。
ちなみに私は IntelliJ を使っているのですが、
もともと VS Code が出る前から使っていたというのと、
仕事柄PHPとかJavaとか、フロント以外のプログラムを触ることがあるのでちょっと重たいんですけどIntelliJを使っています。

# 最後に

まあ、なんでもいいんだけど
まだ何にも染まってないならVS Codeでクセをつけておくと良いとという話でした。

動画では「**ナメられるエディタ**」と「**イジれないエディタ**」についても解説しています。
是非ご覧ください。

[![ナメられないエディタ](http://i3.ytimg.com/vi/2G7hIyNq6EI/maxresdefault.jpg)](https://youtu.be/2G7hIyNq6EI)

# 余談

私が新卒で入った会社は、「リッチなエディタを使うと楽して成長しない」という謎理論があり、
[TeraPad](https://tera-net.com/library/tpad.html)を使わされていました。

あの当時、TVCMや電車の中吊りで宣伝されるブランドサイトは
TeraPadで書かれていました..（）

そんな意味のない体育会的発想はもはや無意味です。
私たちフロントエンドエンジニアは創造的な作業に集中するために
モダンなエディタを使った方がいいです。
Swift：NSTabViewControllerのツールバーのアイテムを中央寄せ

環境設定のウィンドウを作る時に`NSTabViewController`を使っていたけれど，他のアプリでツールバーのアイテムが中央寄せになっていたのがかっこよかったので真似ようと思い，やり方を調査した

```swift:NSTabViewControllerのサブクラス内
override func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
    var array = super.toolbarDefaultItemIdentifiers(toolbar)
    array.insert(NSToolbarItem.Identifier.flexibleSpace, at: 0)
    array.append(NSToolbarItem.Identifier.flexibleSpace)
    return array
}
```
要は`.flexibleSpace`ってやつをツールバーのアイテムの両端に足せば良いみたい．

## 左寄せ状態
![スクリーンショット 2020-01-21 23.50.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/becbcfe4-f5fd-d2ca-de9f-cab6f114a6e9.png)

## 中央寄せ状態
![スクリーンショット 2020-01-21 23.50.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67153/6f9d053d-bb4c-e936-45bf-3d929784bb23.png)

## 参考
[macOS NSTabViewController centered tab icons](https://stackoverflow.com/questions/51209353/macos-nstabviewcontroller-centered-tab-icons)
pythonの二次元辞書を宣言・初期化する

## 動作環境
Windows10
PyCharm
python3.7

# やりたいこと
pythonの辞書型を二次元で初期化したい。

## コード
```python
def main():
    dic = {"a": 0, "b": 0, "c": 0}
    char_dic = {"a": 0, "b": 0, "c": 0}
    char_dic["a"] = dict(dic)
    char_dic["b"] = dict(dic)
    char_dic["c"] = dict(dic)

    # 任意の文字の次の文字の数を数える処理（二次元辞書が必要）
    string = "aacbbb"
    for i, n in enumerate(string):
        if i + 1 == len(string):
            break
        char_dic[string[i]][string[i + 1]] += 1

    for key, value in char_dic.items():
        for kk, vv in char_dic[key].items():
            print(str(key) + " ... " + str(kk) + " ... " + str(vv))


if __name__ == "__main__":
    main()

# 実行結果
a ... a ... 1
a ... b ... 0
a ... c ... 1
b ... a ... 0
b ... b ... 2
b ... c ... 0
c ... a ... 0
c ... b ... 1
c ... c ... 0
```

# 二次元辞書を0で初期化する
for文を使わない場合で、以下のように１つ１つ辞書のvalueを取得できます。
abcは、辞書のkeyです。二次元辞書を0で初期化していることを確認します。

```python3
    dic = {"a": 0, "b": 0, "c": 0}
    char_dic = {"a": 0, "b": 0, "c": 0}
    char_dic["a"] = dict(dic)
    char_dic["b"] = dict(dic)
    char_dic["c"] = dict(dic)

    print(char_dic["a"]["a"])
    print(char_dic["a"]["b"])
    print(char_dic["a"]["c"])
    print(char_dic["b"]["a"])
    print(char_dic["b"]["b"])
    print(char_dic["b"]["c"])
    print(char_dic["c"]["a"])
    print(char_dic["c"]["b"])
    print(char_dic["c"]["c"])
```

## おまけ
pythonの二次元の辞書は、json形式で利用できます。
辞書のことを連想配列とかハッシュとかいいます。
Mac Catalina で perl cpan が "EXTERN.h" が見つからなくて失敗するときの対処法

Mac の Catalina (試したバージョンは10.15.2) 上の pre-install されている /usr/bin/cpan でいろんなモジュールをインストールしたとき、以下のようなエラーが発生してハマった。

    XXXX.xs:XX:XX:fatal error: 'EXTERN.h' file not found
    #include <EXTERN.h>
             ^~~~~~~~~~
    1 error generated.

例えば、DBD::SQLite とか Text::CSV_XS とかでエラーが出る。

色々探し回ってたが解を見つけられずにいたが、ついに解決方法を見つけた。

* https://rt.cpan.org/Public/Bug/Display.html?id=127028

結局、ExtUtils::MakeMaker を 7.36 以降にアップデートすれば良い。

    cpan ExtUtils::MakeMaker

これで、上記のエラーは解消される。
Android Studio

![AndroidStudio1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513367/0e13c900-58fe-c3d9-fe09-49063c066c6d.jpeg)
![AndroidStudio2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513367/887ae11b-944a-1238-2e08-715047bed610.jpeg)
![AndroidStudio3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513367/996c0ad3-fb1a-fb11-a380-db70299ddd28.jpeg)
C#の基礎知識 No.1

今後必要になってくると思うので、Microsoftが出しているチュートリアルの内容を議事録としてまとめました。

#文字列の処理
二つの方法がある。

```c#:Foobar.cs
string friend = "Tom";
Console.WriteLine("Hello" + friend);
```
この方法だとエラーを吐くことなく出力が可能ではあるが、一回一回「+」を入れなければならないので面倒。
そのため、

```c#:Foobar.cs
string friend = "Tom";
Console.WriteLine($"Hello {friend}");
```
でも同じ結果が出力される。
文字列の開始引用符の前に`$`を入れることにより、文字列内に変数が入れることが可能。

#文字列の追加操作
####トリミング
無駄な空白がある文字列のトリミングを行うことも可能。

```c#:Foobar.cs
// 以下のような変数を定義すると
string food = "     apple     ";
Console.WriteLine($"[{food}]");

// このように出力される
→ [     apple     ]
```
そのため、Trimメソッドを用いる

```c#:Foobar.cs
string trimFood = food.Trim();
Console.WriteLine($"[{trimFood}]");

→ [apple]

// 先頭のみトリミング
trimFood = food.TrimStart();
Console.WriteLine($"[{trimFood}]");

→ [apple     ]

// 末尾のみトリミング
trimFood = food.TrimEnd();
Console.WriteLine($"[{trimFood}]");

→ [     apple]
```
####置き換え
文字列を置き換えすることも可能。

```c#:Foobar.cs
string fav = "Like Movie";
Console.WriteLine(fav);

→ Like Movie

//置き換えを行う時はReplaceメソッドを使用する
fav = fav.Replace("Movie", "Running");
Console.WriteLine(fav);

→ Like Running
```
####文字サイズ変更
全てを大文字・小文字に変換することも可能。

```c#:Foovar.cs
Console.WriteLine(fav.ToUpper());

→ LIKE RUNNING

Console.WriteLine(fav.ToLower());

→ like runnning

```
#文字列の検索
文字列内に検索文字列が含まれているかどうかを調べることが可能。
出力は`True`か`False`のどちらかによる`boolean型`
メソッドは3種類あり各々に違いがある。

`Containts` : 文字列のどこかに検索文字列があればTrueを返し、なければFalseを返す
`StartsWith` : 文字列の先頭に検索文字列があればTrueを返す
`EndsWith` : 文字列の末尾に検索文字列があればTrueを返す

```c#:Foobar.cs
string intro = "I have no friends, but live strongly";
// Contains
Console.WriteLine(intro.Containts("friends"));
Console.WriteLine(intro.Containts("foods"));

// StartsWith
Console.WriteLine(intro.StartsWith("I"));
Console.WriteLine(intro.StartsWith("friends"));

// EndsWith
Console.WriteLine(intro.EndsWith("stringly"));
Console.WriteLine(intro.EndsWith("friends"));

→ True
→ False

→ True
→ False

→ True
→ False
```
Rubyのプログラミングスキルを向上させるコツ

##リファクタリングのクセづけ
コードを書き終わったら、必ず、どこかリファクタリング出来ないか研究することをクセづける。

コードが**９行から１行になることもある。**
恐らく、プロのエンジニアには必須スキル！

##テストの開発サイクルについて
1. 先にテストを書いて**失敗させる。**
2. テストが成功するような簡単なテストをひとつ試してみる
3. リファクタリングする。

- [x] 基礎はめちゃくちゃ大事。
- [x] なぜなら基礎的なことはどんなにプロエンジニアになっても、基礎だけは使い続けるものだから。
[GCP]Cloud FunctionsでWebアプリを作成する手順（Python + Flask）

# はじめに
Flaskをさわれる人向けに、Cloud Functionsを用いた超単純なWebアプリの作成・公開・削除方法をまとめています。

# 手順
## 1. Cloud Shell起動
https://console.cloud.google.com にアクセスし、画面右上にあるプロンプトのアイコン（下図でいう左から2番目）をクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/9cd55a27-8138-c797-29da-33b2006b7456.png)

その後、Cloud Shellが表示されますので以下のコマンドを実行してください。

```
gcloud config set project <プロジェクト名>
```

するとプロンプトにプロジェクト名が追加されます。

```
username@cloudshell:~ (プロジェクト名)$
```

プロジェクトについて不明な方は以下をご覧ください。
https://cloud.google.com/resource-manager/docs/creating-managing-projects?hl=ja

## 2. ファイル構成
Cloud Shellで以下のようなファイル構成で作成します。

```
root/
|--main.py
|--templates/
      |--index.html
```

## 3. main.pyの作成
`main.py`を作成してください。
`port=80` の部分を変更しても80番ポートでしか接続できませんでした。

```python:main.py
from flask import render_template, Flask

app = Flask(__name__)

@app.route("/", methods=["GET", "POST"])
def webapp(request):
    return render_template('index.html')

if __name__ == "__main__":
    app.run(debug=False, host='0.0.0.0', port=80)
```

## 4. index.htmlの作成
`index.html`を作成してください。

```html
<html>
    <head>
    </head>
    <body>
        hello
    </body>
</html>
```

## 5. デプロイ
Cloud Shellで`main.py`と同じフォルダに移動したのち、以下のコマンドを実行してください。
`deploy`の後ろには`main.py`に記載した最初に呼び出したい関数名を記載してください。
今回は関数名を`webapp`にしたので以下のようなコマンドになります。

```sh
gcloud beta functions deploy webapp --runtime python37 --trigger-http
```

リージョンを指定する場合は`--region=asia-northeast1`をつけます。

デプロイコマンドの詳細は以下に記載されています。
https://cloud.google.com/functions/docs/deploying/filesystem?hl=ja

## 6. 公開したWebアプリの表示
デプロイ完了するとCloud Shellにメッセージが表示されますが、その中に`httpsTrigger`という記載があります。
ここに公開されたWebアプリのURLが表示されますのでブラウザで接続してください。

```
httpsTrigger:
  url: https://us-central1-<プロジェクト名>.cloudfunctions.net/webapp
```

すると今回の場合は「hello」と表示されたページが見えます。

## 7. 公開したWebアプリの削除
https://console.cloud.google.com にアクセスし、[Cloud Functions]をクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/d464717c-67eb-bb60-6f82-1e34e46d46fd.png)

すると先ほど公開したWebアプリが表示されますので、左側のチェックボックスにチェックを入れ、画面上部の[削除]をクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402872/2defe648-c8a8-8ea1-e023-847f0fd0a195.png)

これで削除完了です。
Nuxt.jsでページ遷移時のtransitionが動かないとき

## 事象
Nuxt.jsでページ遷移時のtransitionを設定する際は、このように書くと普通動きます。
[ルーティング - NuxtJS](https://ja.nuxtjs.org/guide/routing/#%E3%82%B0%E3%83%AD%E3%83%BC%E3%83%90%E3%83%AB%E3%81%AA%E8%A8%AD%E5%AE%9A)

```css
.page-enter-active, .page-leave-active {
  transition: opacity .5s;
}
.page-enter, .page-leave-to {
  opacity: 0;
}
```
しかし、開発サーバー上ではうまく動いてるんですが、generateしたりproductionモードで動作させるとどうも動かなくなる。。。

## 解決法
`/* purgecss start ignore */`と`/* purgecss end ignore */`でくくる。

```css
/* purgecss start ignore */
.page-enter-active, .page-leave-active {
  transition: opacity .5s;
}
.page-enter, .page-leave-to {
  opacity: 0;
}
/* purgecss end ignore */
```
手っ取り早いのはこれだけど他にも解決方法は色々ある。

- [Developmint/nuxt-purgecss: Drop superfluous CSS! A neat PurgeCSS wrapper for Nuxt.js](https://github.com/Developmint/nuxt-purgecss#options)
- [purgecss-docs/whitelisting.md at master · FullHuman/purgecss-docs](https://github.com/FullHuman/purgecss-docs/blob/master/whitelisting.md)
- [Controlling File Size - Tailwind CSS](https://tailwindcss.com/docs/controlling-file-size/)

## 原因
tailwindCSS-moduleを使っていたため発生してしまっていました。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Tailwind CSS is now a command away from your NuxtJS project ✨<br><br>Install the module and get:<br>🗃️ Automatic files creation<br>🧹 PurgeCSS included<br>🚀 PostCSS preset env to stage 1 <a href="https://t.co/IJkPYApxyT">https://t.co/IJkPYApxyT</a></p>&mdash; Nuxt.js (@nuxt_js) <a href="https://twitter.com/nuxt_js/status/1138463642423312391?ref_src=twsrc%5Etfw">June 11, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

tailwindCSS-moduleにはPurgeCSSがincludeされていて、
https://github.com/nuxt-community/tailwindcss-module

特に設定しないとPurgeCSSは本番では動作し、開発サーバー上では動作しない設定になっています。
https://github.com/nuxt-community/tailwindcss-module/blob/master/lib/module.js#L5

そのため、動的にセットされるこのtransitionのクラスが開発サーバーではpurgeされず、本番でpurgeされてしまうため発生してしまっていたようでした。
めでたし。
基本情報技術者　テクノロジ系　第7章 セキュリティ①

[基本情報技術者試験](https://qiita.com/savaniased/items/d3f94da4f087e178cb69)
こちらより

どうも内容が長いので
分割して投稿する方向に変えます。

# 情報セキュリティ
情報セキュリティのCIAととばれる
考慮すべき事柄があります。

## 機密性
秘密を保

## 完全性
改竄、破壊を受けない

## 可用性
権限があればいつでも使える。

# 情報セキュリティ活動を行う組織

## JPCERT/CC(JPCERTコーディネーションセンタ)
セキュリティインシデントの窓口

## J-CSIP(サイバー情報共有イニシアティブ)
セキュリティ情報共有体勢

## NISC(内閣サイバーセキュリティセンタ)


## JVN(japan vulnerability notes)
日本の静寂性情報ポータルサイト

## CSIRT
国

# 暗号技術

## 共通暗号方式
暗号化と復号に同じ鍵を用いる

## 公開鍵方式
暗号化と復号に別の鍵を用いる

# 鍵の危殆化
鍵が盗まれたり
運や総当たりで鍵を当ててしまうなど

危なくなること
JavaScriptの関数のかきかた！

#はじめに
やっと初投稿。1ヶ月前くらいにアカウントを作ってみたものの書くこともなく放置状態だった（正確には最初にこれから頑張る！的な投稿をしたが「それ技術系の記事じゃねーだろ」と運営に言われ非公開になっております）。今の状況としては、Web系エンジニアに必要なスキルの修得を目指してとりあえずProgateの各コースを進めているところ。その中で自分が慣れ親しんだCやJava（長くやってるだけでスキルが高いわけではない）とJavaScriptでは関数の定義の仕方が結構違う感じがしたのでメモ的な感じで投稿してみる。初投稿だしいいよねこんな感じで。
#Cの関数
例えば、2つの整数を引数にもち、和を戻り値として返すadd関数を宣言してみる。

```c

int add(int x,int y){
　return x + y;
}
```

#JavaScriptの関数
対して、JavaSciprtでこのadd関数を書くとこうなる。

```js
const add = (x,y) => {
　return x + y;
};
```

#まとめ
こうして並べてみるとやはりかなり違うことがわかる。引数のところに型名いらないし、関数を定数（変数）に代入してたり。言語が違うんだから書き方が違うのは当たり前なんだけど、CとJavaってここらへんの書き方はわりと似てたからまた一つ新しいことが学べていい気分。Webエンジニアへの道のりは果てしないけど頑張ろう・・・！
これからもこんな感じでゆる～く投稿していこうと思うのでどうぞよしなに。
sympy,wolframalphaで「センター試験2020 数学I第1問 配点25[1] 」(2次不等式) をやってみたい

何かいい方法ないですか?

(参考)数学I問題
https://www.asahicom.jp/edu/center-exam/shiken2019/pdf34MQhg2kGR/suugaku1_01.pdf
(参考)センター試験解答速報2020＜予備校の東進 ＜「問われている内容は難しくない」そうです。
https://www.toshin.com/center/sp/

#wolframalphaでやってみたい
アイウ=====================
a^2-2*a-8 < 0
https://www.wolframalpha.com/input/?i=a%5E2-2*a-8+%3C+0&lang=ja
解-2<a<4
エオ=====================
?
カキ=====================
?
クケコサシ=====================
(a^2-2*a-8)*b+a=0,a=sqrt(3) 
https://www.wolframalpha.com/input/?i=%28a%5E2-2*a-8%29*b%2Ba%3D0%2Ca%3Dsqrt%283%29+&lang=ja
解b = (5 sqrt(3))/13 - 6/13
スセソ=========================
abs((a^2-2*a-8)*1+a+(a^2-2*a-8)*(-1)+a)=1,a<0 
https://www.wolframalpha.com/input/?i=abs%28%28a%5E2-2*a-8%29*1%2Ba%2B%28a%5E2-2*a-8%29*%28-1%29%2Ba%29%3D1%2Ca%3C0+&lang=ja
解a = -1/2
タチツテト=========================
(a^2-2*a-8)*x+a,a = -1/2,-2<=x<=2
https://www.wolframalpha.com/input/?i=%28a%5E2-2*a-8%29*x%2Ba%2Ca+%3D+-1%2F2%2C-2%3C%3Dx%3C%3D2&lang=ja
標準の計算時間制限を超えました...
タチツテト=========================
y=((-1/2)**2-2*(-1/2)-8)*x-1/2,-2<=x<=2
https://www.wolframalpha.com/input/?i=y%3D%28%28-1%2F2%29**2-2*%28-1%2F2%29-8%29*x-1%2F2%2C-2%3C%3Dx%3C%3D2&lang=ja
整数解x = -2, y = 13
整数解x = 2, y = -14

#Sympy onlineでやってみたい
(参考)SymPy Live
https://live.sympy.org/
アイウ=====================
solve(x**2-2*x-8 < 0)
print(solve(x**2-2*x-8 < 0))
(-2 < x) & (x < 4)
エオ===========================



カキ============================



クケコサシ=====================
solve([(x**2-2*x-8)*y+x,x-sqrt(3)],[x, y])
print(solve([(x**2-2*x-8)*y+x,x-sqrt(3)],[x, y]))
[(sqrt(3), -6/13 + 5*sqrt(3)/13)]




#Sympy pythonでやってみたい
作業中
Go for文の"_"の使い方

golangのfor文を勉強していて

"_"の意味を理解したのでまとめておきます。

結論から言いますと

**インデックス番号を表示する必要がない場合に**
**"_"を使います。**

```main.go
package main

import "fmt"

func main(){

    //スライス作成
	l := []string{"jave", "python", "go"}

    //インデックス番号とスライスの要素を表示
	for i:=0; i < len(l); i++{
		fmt.Println(i, l[i])
	}
    //スライスの要素だけを表示
	for  _, v := range l{
		fmt.Println(v)
	}

    //"_"を使わずに要素を表示させようとすると
    for  v := range l{
		fmt.Println(v)
	}
    //インデックス番号が表示される
    //"_"でインデックス番号を埋める必要がある
 

    //map作成
	m := map[string]int{"apple": 100, "banana":200}

    //mapのキーと値を表示	
	for k, v := range m{
		fmt.Println(k, v)
	}

    //mapのキーを表示
	for k := range m{
		fmt.Println(k)
	}

    //mapの値を表示
	for _, v := range m{
		fmt.Println(v)
	}
}
```
エンジニアに必要な何かとは【番外編】

###【エンジニアにとって必要なものとは何か？】

過去2回の投稿で、VBAの技術的なことについて記述してきたが、ちょっと趣向を変えて、
本記事では、SIerになって1年保守運用を経験してきて、エンジニアに必要な要素について触れていきたいと思う。

過去記事
***
>[VBAフォーム、DB接続クラス化入門](https://qiita.com/triple321jhango/items/14efb6adf157b3d3e5b1)
>[オブジェクト指向（プロパティ、メソッド）をポケモンを使って考えてみる](https://qiita.com/triple321jhango/items/7bec426174a23e23bc48)

###1.継続力
***
まず何と言っても継続する力、これは必須条件だと思う。
何を継続するか？

- <b>コードを書くこと</b>
- <b>わからないことをググること</b>
- <b>動画学習等でInputすること</b>

私の尊敬する野球解説者の野村克也さんこと、ノムさんは「まずは1日努力する」という言葉を用いている。
1日努力して、次の日もやってみる。それが1週間続き、1ヶ月が経つと、それは「努力」が「習慣」に変わる。
今日はやらなくていいか、と思う日ほどやることを継続する。
次第に、継続することが習慣となり、逆にやらないと気持ち悪く感じる。
そうやって自然と継続する力は身につくものと思っている。
イコール、数ヶ月、数年たったころに、初めはわからなかったことが、わかるようになっている。
これからプログラミングを学ぼうと思っている方には、習慣づけるということをぜひやってほしいと思う。ちなみになぜInputは動画学習かというと、その方が頭に入っていきやすいからだ。
初めのうちは調べても全くぴんと来ない。[udemy](https://www.udemy.com/ja/)等で、格安に学べる動画学習サイトがあるので、これを見て勉強した方が圧倒的に早い。

###2.会話力(コミュニケーションスキル)
***
エンジニアなら誰もが口にする、コミュニケーションスキル。これは本当に大事だ。
元々サービス業的なことをやっていた私はこのコミュニケーションには自信があったのだが、ことエンジニアにとってのコミュニケーションとは、ただしゃべれれば良いものではない。
以下の要素が非常に重要になってくる。

- <b>意思疎通確認</b>
- <b>理由を説明できる</b> 

意思疎通確認については、その言葉通りだが、お互いが間違いなく同じ認識でいること、これが大前提である。
<b>「Aさんは1の認識だった。」</b>
<b>「Bさんは10の認識だった。」</b>
これはあってはならない。

不明点は「これこれこういう動きをさせたら、DBに問い合わせを行い、存在すれば、数字をセットするが、存在しなかった場合はエラーメッセージの認識で合ってますか？」と、こう言った会話が必要になってくる。
曖昧な認識のまま話が終わってしまうと、後々~~面倒~~、「そんな仕様でOkにしたつもりはない」
など、仕様から見直し、再度開発に着手しなければいけないという無駄な工数を踏むことになりかねない。
そういう意味で、<b>意思疎通確認</b>とは非常に大事なのだ。

次に<b>「理由を説明できる」</b>だが、
私も未だに感覚で物事をやってしまいがちな部分があるので、それを常々反省しているのだが、
やったからには必ず理由があるはずだ。

- なぜ、そうしたのか？
- そうする必要があったのか？

先輩には常に問われます。
初めのころこそ、応えられないことが多かったが、最近はしっかり理由を説明できるようにはなってきた。

会話例①：
>先輩「このマスタ、削除依頼があったけど、なんでこっちのマスタも消したの？」
>私「このマスタは削除依頼のマスタと連動関係にあって、消しとかないとユーザーにとって不必要なメッセージが出ちゃうので消しました。」

会話例②：

>クライアント「ここにこの数値を入力しても先へ進めないんだけどなんで？」
>私「そこの入力値はDB上にある〇〇という承認データがあるかどうか問い合わせをしているのですが、DB上のデータを確認する限り、その入力値はまだ承認されていないので、申請⇒承認を行ってください。」

など、要求内容にはないが、不都合がある場合にはそれにも対応するという理由のため、作業したと説明ができればなんら問題はない、(もちろん他に影響がないことも想定して)
クライアント側からの質問に対しても、根拠を説明することで納得を得られる。
逆に何の根拠もなく説明すると納得を得られない。

こういう意味で会話力・コミュニケーションスキルというのは非常に重要であると思っている。
私は開発に携わったことがないので、開発に関する技術は劣っているかとは思うが、保守運用を経験することで、このコミュニケーションスキルというものが身についたと思っている。

###【最後に】
ここまで、エンジニアにとっての必要な何か？を解説していたが、いかがだったでしょうか？
私は上記2つの要素はエンジニアにとって必要な何か、だと思っています。
もちろん技術力は必要だとは思うが、技術力だけではこれからのエンジニアは生き残れないのでは、とも思っている。（私の場合はまだまだ技術力が足らないので、これからも継続してプログラミングにいそしみたいと思っています…）
【小ネタ】環境ごとにアプリアイコンを変更する方法【iOS】

# モチベーション
「どれを確認すればよい？」
検証端末に複数の環境のアプリをいれて動作確認をするというのはよくある話だと思いますが、確認する役割の人や確認依頼者がわかりやすいようにする。

- 確認者がアプリ名は分けているけど時々間違う
- 依頼者がスキーマ分けているのに時々間違う

というようなことを防ぐ。

# 対象

- 開発フェーズがある程度進んでしまっている *1
- `Build Config`で環境分けはしている
- リソース管理ライブラリは使ってない
- `Assets.xcassets`ファイルでアイコン定義をしている

対象がちょっと限られていますが、同時に付け加えられるなら可能です。
新規開発の場合はリソース管理系のライブラリの導入を検討した方が良いかと思います。

*1 リソース管理ライブラリなどを適用するには総合的に現実的ではないという状況

# やりかた
1.`Assets.xcassets`に必要な環境のイメージセットを`New iOS APP icon`を選択し追加

*New iOS App icon*
![スクリーンショット 2020-01-21 22.30.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103494/e8a9ceea-96ba-4b24-cfed-e112e38d229d.png)

*追加後*
![スクリーンショット 2020-01-21 22.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103494/72228306-9adb-e96c-dac9-a301083f00b8.png)

2.追加したイメージセットに環境ごとのアイコンをセット。Dev用、Qa用など
〜省略〜

3.`Build Settings`の`Asset Catalog App Icon Set Name`/`Asset Catalog App Icon Set Name`に対応したイメージセット名を記載。
![スクリーンショット 2020-01-21 22.33.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103494/c12f461d-2932-9c05-dbea-ce37c3711aee.png)

以上で完成。
本番環境(production)で、CSSの変更が反映されない時の解決方法

本番環境でCSSの変更が適応されないときは、以下のコマンドを実行すれば解決。

```
bundle exec rake assets:precompile RAILS_ENV=production
```


参考記事：https://programming-beginner-zeroichi.jp/articles/19
【Rails】devise実装後のユーザー新規登録時のエラー[ArgumentError in Users::RegistrationsController#create]

#概要
Railsアプリにて、ログイン機能を実装するために`gem 'devise'`を利用。
users/sign_upからユーザーの新規登録を行ったところエラーが発生した。

# エラー文
```ruby
ArgumentError in Users::RegistrationsController#create

wrong number of arguments (given 0, expected 1)

app/controllers/users/registrations_controller.rb:13:in `create'

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to @user, notice: 'User was successfully created.'
    else
      render :new
  end
```

`wrong number of arguments (given 0, expected 1)`は
引数が１つ渡されるはずなのに０になってますよ。ということでコントローラーでcreateアクションがうまくできていない。

#結論

`has_secure_password` `password_digest`を使っていたから。
`devise`導入時は`has_secure_password` `password_digest`を使ったセキュアパスワード設定は行わない。
代わりに`encrypt_password`をテーブルカラムに追加することでセキュアパスワード設定ができる。

#今回の解決までの流れ

参考：http://ja.voidcc.com/question/p-zenkcgoo-cv.html

調べると`has_secure_password`がいらないという情報があったので、userモデルから消しました。

すると、同じようにユーザーの新規登録をすると異なるエラーメッセージが出ました。
`password_digest`についてエラーが出ている模様。

```ruby
ActiveRecord::NotNullViolation in Users::RegistrationsController#create

PG::NotNullViolation: ERROR: null value in column "password_digest" violates not-null 
constraint DETAIL: Failing row contains (5, test, test@a.com, test@a.com, null, null,
 2020-01-21 01:37:23.23543, 2020-01-21 01:37:23.23543,
$2a$11$mFFmw7JD8nrrm3hbz/LUQeFwRPYjjBNKIRAjVuRBNXUM57v2JeeI6, null, null, null).
: INSERT INTO "users" ("name", "email", "profile", "created_at", "updated_at",
 "encrypted_password") VALUES ($1, $2, $3, $4, $5, $6) RETURNING "id"
```

`password_digest`は`devise`導入前にセキュアパスワード設定のために用意していたカラムです。
調べてみると`devise`を使用するときは`devise`が`password_digest`の代わりに`encrypt_password`を作ってくれるので、password_digest`はいらないことがわかりました。

確かに`devise`の導入を行っている際にコマンド

```
$ rails generate devise user
```

を実行し、作られるマイグレーションファイルに`encrypt_password`が入っていました。

```schema.rb
class AddDeviseToUsers < ActiveRecord::Migration[5.2]
  def self.up
    change_table :users do |t|
      ## Database authenticatable
      t.string :encrypted_password, null: false, default: ""
(省略)
end
```

今回はこのままマイグレーション実行していたのですが、既にusersテーブルに`password_digest`カラムがあったため上書きされず、`encrypted_password`は反映されてませんでした。
`encrypted_password`について調べずにマイグレーション実行していたことを反省・・・

ということで、`password_digest`カラムを削除してから、マイグレーションをやり直してエラーは解決しました。

もう一度結論ですが、`devise`を利用してパスワードをハッシュ化し、セキュアパスワード設定をするにはカラムに`password_digest`ではなく`encrypt_password`を使うことになります。

他にもusers/newでcreateされるユーザーは`devise`管理化の
controllers/users/registrations_controller.rbのnewやcreateメソッドに従って挙動するので、
controllers/users/users_controller.rbのnewやcreateメソッドは不要になるなど
`devise`を実装することで不要になるものはいくつかあります。

参考：http://genestream.hatenablog.com/entry/2014/10/28/110934
[Welcome to nginx on the Amazon Linux AMI!]nginxサーバにアプリケーションをアップロードした時に起こるルーティングエラーの解決例

#1.エラーの様子
まずエラーまでの流れですが、ローカル環境でエラーもなく、GitHubへのcommit,pushをし、EC2サーバー(nginx)上に自動デプロイが終わった後にElastic id(個人のipアドレスに紐付け済みの公開用ipアドレス)に接続したところ下記のような画面が表示されました。

<出てきたエラー文>
<img width="1276" alt="スクリーンショット 2020-01-21 21.34.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/d047b2a7-4736-52b1-d33c-5df27713e3d0.png">


<出て欲しい画面>
<img width="1276" alt="スクリーンショット 2020-01-21 22.05.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/e8cd14cf-c71c-2a84-1219-37a0a479c62a.png">


#2.どんなエラー？
自分が設定したアプリケーションのアドレスではなく、nginxのホームに接続してしまうというエラーになっています。


#3.エラーの原因
ネットサーバーまでのルーティングの設定エラーです

見つけ方としては、エラーまでの流れで説明した通り、ローカル環境でエラーを出していないため、本番環境のルーティングの設定ミスだとわかります。

#4.解決方法
本番環境のルーティングに関する箇所を調べて打ち忘れ打ち間違いを修正します。
具体的には下記の原因が考えられます

①開発したファイルの中のconfig/locals/unicorn.rbの記載ミス
②config/deploy/production.rbの記載ミス
③config/deploy/deploy.rbの記載ミス
④nginxの設定の記載ミス(EC2サーバにログインして`[ec2-user@ip-172-xx-xx-xxx ~]$ sudo vim /etc/nginx/conf.d/rails.conf`とコマンドを打つことで確認できます）

そして今回筆者は④で下記のように設定していました。
<間違った設定>
<img width="1280" alt="スクリーンショット 2020-01-21 22.23.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/47bba5db-9873-f615-7a6a-c5694a0e7fee.png">

よくよく見るとこの中の'sever_name'に余計な文字が入っており間違っています。
設定にはElastic idだけで良いので正しくは下記の通りとなるべきでした。
<正しい設定>
<img width="1280" alt="スクリーンショット 2020-01-21 22.23.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/6a91ef36-3ce1-3e68-1248-7f1ee01bb011.png">

こちらを修正したところ、検索の箇所にElastic id（13.112.68.204）を打つことで正しいアプリケーションのサイトに飛ぶよう設定することができました。

※ここまでのルーティングのチェックでローカルのファイルに変更などが生じている可能性があるため、GitHubのcommit忘れの確認と、自動deploy（またはpull origine masterコマンド）を行っておきましょう。更新忘れてるかもと思ったら、この更新作業は何度コマンドしても大丈夫なのでとりあえず行ってみましょう。
LinuxでプロセスのRunキュー待ち時間を測定してみた


[Linuxでスケジューリングポリシーを指定してプロセスを起動する](https://qiita.com/yamato_karino/items/892443eabf1a84192849) で起動したCPUバウンドなSCHED_FIFOプロセスのRunキュー待ち時間を測定してみます。

Runキュー待ち時間の取得にあたり、以下のページを参考にしました。
https://yohei-a.hatenablog.jp/entry/20150806/1438869775

CPUバウンドなFIFOプロセスの/proc/PID/schedstat を1秒空けて取得した結果。
2列目がRunキュー待ち時間。単位ナノ秒。

> 1. time spent on the cpu
> 2. time spent waiting on a runqueue
> 3. # of timeslices run on this cpu

( https://www.kernel.org/doc/html/latest/scheduler/sched-stats.html より)

```
[ec2-user@ip-172-21-0-185 ~]$ sudo cat /proc/27629/schedstat ; sleep 1; sudo cat /proc/27629/schedstat
1585551572096 83397623426 1669
1586504089039 83449107507 1670
```

51ミリ秒ほどですね。
3列目、タイムスライスが1というところから、Context Switchが1回しか起きていない？ようで、まさにリアルタイムプロセス。


下は、同時に走らせていたCPUバウンドなSCHED_OTHERプロセスの/proc/PID/schedstat を1秒空けて取得した結果。

```
[ec2-user@ip-172-21-0-185 ~]$ sudo cat /proc/28585/schedstat ; sleep 1; sudo cat /proc/28585/schedstat
28229659566 570788962732 8601
28291651447 571746971282 8620
```

約958ミリ秒。SCHED_FIFOのプロセスが走っていた時間ほぼずっとRunキューにいたことが分かります。

## SCHED_OTHER のプロセスをkillして測定
SCHED_OTHER のプロセスをkillして、他にCPUを大量に使うプロセスがない状態でSCHED_FIFOのRunキュー待ち時間を測定した見たところ、約50ミリ秒という結果になりました。(コマンド出力結果はありません)
ということは、SCHED_FIFOのyesプロセスがCPUを使っていない時間でのみSCHED_OTHERのyesプロセスが走れていたんですね。
オブジェクトのサイズを等倍にしたい

軸の中央の四角をマウスドラッグすれば等倍でサイズ変更することができる
<img width="196" alt="スクリーンショット 2020-01-21 22.25.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/493c2cce-3959-585e-8ebc-0095cc97bd51.png">
<img width="335" alt="スクリーンショット 2020-01-21 22.27.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/dffa60d6-f87e-6169-d60a-445ff7727b38.png">
<img width="182" alt="スクリーンショット 2020-01-21 22.28.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191635/b89e939b-14d7-29b1-bca8-0d7bc886bf9b.png">
MVCとはなんなのか

Ruby on Rails初心者として、自分自身の理解を整理したいのでまとめたいと思います。
何か認識違いがあれば、ご指摘いただければ幸いです。

# MVCとは
UI(ユーザインタフェース)を持つソフトウエアのアーキテクチャの一種。
画面に表示する部分(UI)は、アプリケーション固有のデータや処理の扱いの性質が異なるため、画面の表示とアプリケーションのデータに関する部分を混ぜて記述してしまうと、コードが複雑化してしまい、保守性が悪くなってしまいます。

そこで、アプリケーション固有のデータの部分、画面を表示させるUIの部分、この2つをつなぎ合わせる制御の部分の3つに分けて管理をしやすくしようというものです。

###M(model)
アプリケーション固有のデータや処理の扱いの部分
・データベースへの保存、読み込み、永続化を担当する。

### V(View)
UIに関わる部分
・HTTPレスポンスの中身を実際に組み立てて、画面を表示する。

### C(Controller)
ModelとViewを統合的に制御する部分
・ブラウザからのリクエストを受けて適切なレスポンスを作成するための制御を行う。

# MVCのメリット
・それぞれが専門的な分野になるため、一つ一つの仕様変更がしやすくなる。
・分野ごとに得意な人が開発を進められる。

# まとめ
MVCアーキテクチャを使うことによって複雑化するコードをそれぞれの3つの分野に分けることで単純化し、管理しやすくすることで、それぞれが得意な分野に分かれて開発できるようになり、作業しやすい環境が生まれるということ（と感じました）。
ページ遷移で、真っ白な画面が表示された

###事象
Reactで作ったWebページをスマホで確認していたところ、とあるページ遷移で、真っ白な画面が表示された。
「ホワイトアウト」と呼ばれる現象。

###処理内容
「componentDidMount」のタイミングで、<a href="https://developer.mozilla.org/ja/docs/Web/API/Fetch_API">Fetch API</a>を使ってデータ取得。
タイムアウト時間を過ぎたら、fetch処理をキャンセルさせようとした。

###コード
```fetch.js
// after render
componentDidMount(){

    const controller = new AbortController();
    
    const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
    // 2秒後にfetchキャンセル
    wait(2000).then(() => {
        controller.abort();
    });
    
    fetch('https://hogehoge.com/send', {
        mode: 'cors',
        method: 'POST',
        signal: controller.signal,  // controllerが持つsignalをfetchに渡す
        header: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(JSONdata),
    }).then((data) => {
        // 応答が得られた場合の処理
    }).catch((error) => {
        // fetchキャンセルの場合、ここに入る
        // errorはundefined
    });
}
```
###どこに問題があったか
「AbortController」をサポートしていないバージョンの「Chrome for Android」による読み込み。
この時の「Chrome for Android」のバージョンは「55」。
Chromeでの「AbortController」サポートは「66」以降になる。
https://developer.mozilla.org/en-US/docs/Web/API/AbortController
EntityFrameworkでunion

# Union

```C#
class ItemA
{
    public long Id;
    public string Name;
    public int Category;
}

class ItemB
{
    public long Id;
    public int Type;
}

```

上記二つのテーブルをunionするパターン

まずunionの結果となるクラスを作成する必要があります

```C#
class UnionFormat
{
    public long ItemAId;
    public long ItemBId;
    public string Name;
    public int Category;
    public int Type;
}
```

実際にunionしますが、クエリが発行されるのはToListが実行されたタイミングです。

```C#
//ItemAのテーブル
 IQueryable<UnionFormat> ItemAQuery = db.ItemAs.Select(x =>
  new UnionFormat
  {
    ItemAId = x.Id,
    Name = x.Name,
    Category = x.Category,
    // unionするためになにか値を指定する必要がある 
    ItemBId = 0,
    Type = 0,
  });

//ItemBのテーブル
 IQueryable<UnionFormat> ItemBQuery = db.ItemBs.Select(x =>
  new UnionFormat
  {
    ItemAId = 0,
    Name = "",
    Category = 0, 
    ItemBId = x.Id,
    Type = x.Type,
  });

// クエリ発行、.Unionで何個でもテーブルを連結できます。
List<UnionFormat> unionResult = ItemAQuery.Union(ItemBQuery).ToList();
```
neovim で　youcompletemeをつかう

Installation
Step 1
Install [YouCompleteMe](https://github.com/Valloric/YouCompleteMe).

Step 2

https://github.com/neovim/neovim/tree/master/contrib/YouCompleteMe

.ycm_extra_conf.pyの内容を書き換える。
cpしてもよし。

```
cp contrib/YouCompleteMe/ycm_extra_conf.py .ycm_extra_conf.py
echo .ycm_extra_conf.py >> .git/info/exclude
```

(Step3)
次のように怒られたらpipでneovimをいれる。
>YouCompleteMe unavailable: unable to load Python.

```
pip install neovim
```
【github】空のリポジトリを作ろう 初学者用

#githubって？
[githubはこちら](https://github.co.jp/)
ここでは説明しないので、各自調べましょう（出だしから投げやり）

###この記事の前提
 - githubへのアカウント登録が終わっていること

では、この記事の目的である空のリポジトリを作っていきましょう

#githubで空のリポジトリを作ろう
1. まずはgithubホームページからサインインして、最初のページの左上に下記のようなボタンがあるのでクリック（リポジトリ作成開始）

|![create repository01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/a58b65f9-81c5-e514-3a8d-7b9826146c20.png)|
|:-:|

|![create repository00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/2fee866a-e901-41fb-240c-9ace02cad416.png)|
|:-:|
---
1. Repository nameに「GitTest」と入力（リポジトリの名前を決める、好きな名前でよい）
2. Privateにチェックを入れ、非公開設定で作成する（公開したい場合は後から変更できるよ）
3. Create repositoryと書かれた緑色のボタンを押す

|![create repository02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/8752c15d-7691-cd96-b3ab-5ed091a98563.png)|
|:-:|
---
1. create a new fileをクリック（新しいファイルを作って始めようと言われています）

|![create repository03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/db0f6f1b-fb2a-a2fa-ac3f-eba4f1ea3140.png)|
|:-:|
---
1. 下線部に「test」と入力（好きな名前でよい、すぐに消します）

|![create repository04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/5d30eac4-085d-0cd5-1ba8-87da43f48ddb.png)|
|:-:|
---
1. 下のほうにあるCommit new fileをクリック
- （コミットはざっくり言うと保存するということで、ゲームでいうセーブ的なやつ）

|![create repository05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/85206483-e9f5-27ad-f187-7d08ef0bad33.png)|
|:-:|
---
1. 作ったファイル名をクリック

|![create repository06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/3e06cf89-862e-30a8-f662-10d142c2fa37.png)|
|:-:|
---
1. ゴミ箱マークをクリック

|![create repository07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/d3020f00-aeb6-7557-36ee-1273f9024895.png)|
|:-:|
---
1. 下のほうにあるCommit changesをクリック（ここでは変更を保存する、つまり削除したことを保存する）

|![create repository08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/9803f33d-0585-1f78-5360-06242ec392d9.png)
|:-:|
---
- **空でまっさらなリポジトリが完成**

|![create repository09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/660d5071-ee30-85bd-5200-df18315150f9.png)|
|:-:|

#おまけ
**リポジトリのURLをコピーしよう**
1. Clone or downloadの緑色のボタンをクリック
2. コピーのマークをクリックするとコピー完了

|![create repository10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570931/3d1133ed-7d6e-9a97-49f1-295c4b78b08b.png)|
|:-:|
docker環境で db:migrate:resetしたいとき( seed_fuも)

###dbをリセットしたいとき
dockerを触り始めたばかりのときは停止させたdockerを再起動するのにも手こずりますので初歩的な手順。
大体rails のコマンド前にdocker-composeをつけるだけですが。

```
docker-compose exec コンテナ名 bin/rails db:migrate:reset
```

コンテナは停止させなくて良いです
なぜならそのコンテナに対してmigrateリセットするからです

```
docker-compose exec コンテナ名 bin/rails db:migrate
```

seed_fuを使用していたら下記コマンド

```
docker-compose exec コンテナ名 bin/rails db:seed_fu
```

docker-composeのときはymlファイルを参照するのでコンテナIDではなくコンテナ名を記述してください。

##PGerrorが出てresetできないとき
データベースに接続している場合だとresetできないので

```
docker-compose restart
```

しましょう
Node.js用QualityForward SDKを使ってテストフェーズを作成する

[QualityForward](http://bit.ly/37A78L3)はクラウドベースのテスト管理サービスです。APIを公開しており、テスト管理に関するデータのCRUD操作ができるようになっています。SDKとしてはNode.js、Python、そしてGoogle Apps Scriptを作成中です。

Node.js SDKについてはデータの取得系は一通り実装されています。今回はデータの追加、テストフェーズの作成について紹介します。

## QualityForward用Node.js SDKを使う

Node.js SDKは[goofmint/qualityforward-node](https://github.com/goofmint/qualityforward-node)にて公開しています。npmで公開していますので、インストールは簡単です。

```
npm i qualityforward -S
```

## 初期化

初期化はAPIキーを適用して行います。

```js
client = new QualityForward('YOUR_API_KEY');
```

## テストフェーズの作成

まずテストフェーズオブジェクトを作成します。

```js
const testPhase: TestPhase = client.TestPhase();
```

## 値を設定する

次に値を設定します。プロジェクトID、名前、開始日、終了日は必須です。

```py
testPhase.project_id = 748;
testPhase.name = 'test';
testPhase.start_on = new Date();
testPhase.end_on = new Date();
```

さらに例えばBTS連携としてRedmineを用いる場合には次のように登録します。

```js
testPhase.bug_tracking_system = 'redmine';                   // redmineまたはjiraを指定
testPhase.redmine_base_url = 'https://example.com';          // ベースURL
testPhase.redmine_issues_url = 'https://example.com';        // バグ曲線、グラフデータ取得用URL
testPhase.redmine_latest_issues_url = 'https://example.com'; // 最近のインシデント取得用URL
```

## テストスイートバージョンを登録する

テストフェーズと連携するテストスイートバージョンを指定します。これは複数登録可能です。

```js
const tsv = client.TestSuiteVersion();
tsv.id = 13290;
testPhase.test_suite_versions.push(tsv);
```

## 保存する

最後に保存します。問題があればエラーが発生するので、try〜catchで捕捉できます。

```js
await testPhase.save();
console.log(testPhase.id);
```

## まとめ

既存のシステムからテストケースを移行する際にAPIを利用できます。入力が面倒な場合、APIを使えば一気に処理できますので、Node.jsを社内システムで使っている場合には試してみてください。

[QualityForward](http://bit.ly/37A78L3)
WordPressでプラグインをインストールできない時の対処法

最近仕事でWordPressでサイト開発をしているのですが、プラグインを停止、削除後、再度インストールしたくてContact Form 7のプラグインをいじっていたところ、以下のような画面が出てホスト名とFTPユーザー名、FTPパスワードなどを聞いてきたのでした。
![スクリーンショット 2020-01-21 13.22.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322356/56cf9bbb-c70b-ff3e-8b42-341110ded48a.png)
ローカルで開発をしていた時には見たことがなかったものだったので調べてみたところ、
直接`wp-config.php`に下記の記述を追加
`define('FS_METHOD', 'direct');`
したらインストールできるようだった。
しかし、新たに問題が発生。
インストールボタンを押すと **インストールに失敗しました: ディレクトリを作成できませんでした。** 
というメッセージが表示された。

どうもwp-content内にあるpluginやthemeディレクトリの権限をいじるも変化なし。
よくよくみると、**wp-content内にupgradeディレクトリないやん!**
と気がつきwp-contentディレクトリで`mkdir upgrade`をし作成。
その後、インストールは無事通過。。。ﾄﾎﾎ

追記
>どうやら以下3つのディレクトリの書き込み権限がいるらしい。
　ワードプレスのルート/wp-content/upgrade
　ワードプレスのルート/wp-content/themes
　ワードプレスのルート/wp-content/plugins
http://wordpressoboegaki.seesaa.net/article/370770336.html 

小一時間奮闘していたんですが、上の文言をみてようやく気がつきました。
【swift】画像を指定した比率でトリミングする【TOCropViewController】

#使用するライブラリ

[TOCropViewController](https://github.com/TimOliver/TOCropViewController)
>ユーザーがUIImageオブジェクトの一部を切り取ることができるiOS用のView Controllerを提供します。


#目標
1.ボタンをタップすると、`UIImagePickerController`が起動する。
2.トリミングしたい画像をpickし、`UIImagePicker`を閉じる。
3.配置した`UIImageView`と同じ大きさにトリミングできる`CropViewController`が起動する。
4.トリミングを完了すると、`UIImageView`にトリミング編集した画像が反映する。

(実装例)
![20200121_214939.GIF](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376004/be1ec78e-1a6a-0489-444f-efef385feac5.gif)

#サンプルコード

```swift

//imageViewをストーリーボード上に配置（適当なsize）
@IBOutlet weak var imageView: UIImageView!

var image:UIImage?

//ボタンを押すとimagePickerが表示され、トリミングしたい画像を選ぶ。
@IBAction func presentCropViewButton(_ sender: UIButton) {

        setImagePicker()
}

func setImagePicker(){

        let picker = UIImagePickerController()
        picker.sourceType = .photoLibrary
        picker.delegate = self
        present(picker, animated: true, completion: nil)
}

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {

        guard let pickerImage = (info[UIImagePickerController.InfoKey.originalImage] as? UIImage) else { return }

        //CropViewControllerを初期化する。pickerImageを指定する。
        let cropController = CropViewController(croppingStyle: .default, image: pickerImage)

        cropController.delegate = self
        
        //AspectRatioのサイズをimageViewのサイズに合わせる。
        cropController.customAspectRatio = imageView.frame.size

        //今回は使わない、余計なボタン等を非表示にする。
        cropController.aspectRatioPickerButtonHidden = true
        cropController.resetAspectRatioEnabled = false
        cropController.rotateButtonsHidden = true

        //cropBoxのサイズを固定する。
        cropController.cropView.cropBoxResizeEnabled = false
        
        //pickerを閉じたら、cropControllerを表示する。
        picker.dismiss(animated: true) {
            
            self.present(cropController, animated: true, completion: nil)
        }
}

func cropViewController(_ cropViewController: CropViewController, didCropToCircularImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
        //トリミング編集が終えたら、呼び出される。
        updateImageViewWithImage(image, fromCropViewController: cropViewController)
}
    
func updateImageViewWithImage(_ image: UIImage, fromCropViewController cropViewController: CropViewController) {
        //トリミングした画像をimageViewのimageに代入する。
        self.imageView.image = image
            
        cropViewController.dismiss(animated: true, completion: nil)
}
```

#参考文献
- https://qiita.com/mcz9mm/items/8ea88b512038d75c0609
- https://github.com/TimOliver/TOCropViewController
サクラエディタでファイル名を数字順でGrepする方法

#ファイル名の数字順Grepの方法
　サクラエディタのGrepは、そこそこ便利で使っている人も多いと思います。
　しかし「完璧」になんでもこなせるわけではありません。

　そのひとつに「ファイル名がエクスプローラーと同じ順番にならない」という問題があります。

　Windows XP SP1 以降では、ファイル名は「数字順ソート」のような並び順になります。
　```0,1,2 ... 8,9,10,11 ... 98,99,100,101```
　という風に桁数の小さい数字から順番に並ぶようになりました。

　しかしサクラエディタのGrepでは、伝統的な文字列の辞書順で並びます。
　これだと0から101の数字のファイル名を与えると
　```0,1,10,100,101,11,12 ... 19,2,20,21... 28,29,3,30,31 ... 98,99```
　というふうに並びます。

　場合によってはGrep結果を見るのが大変になってしまいます。

　「*.txt」とかでGrepするとそうなりますが、場合によっては少し工夫すると、数字順「風」に並べることができます。

##ファイル名の指定を工夫する
　サクラエディタの「ファイル」の部分は複数のワイルドカードが使えます。
　ここでは半角スペースで区切っていますが、```,```や```;```で区切ることもできます。
　この複数個のワイルドカードは、左側から順に一覧を取得してその中で文字列ソートされます。
　そこで　```?.txt ??.txt ???.txt```　の順番に指定すると、1桁のファイル、2桁のファイル、3桁のファイル、の順番に検索することができます。
　これで```1.txt 9.txt 10.txt 11.txt``` のようなファイル名に対応できます。

　もしファイル名が```abc.txt abc2.txt abc3.txt abc9.txt abc10.txt abc11.txt```であれば、
　```abc.txt abc?.txt abc??.txt```のように指定すればOKです。

##日付順

　数字の部分が「2か所」以上ある場合は、桁数での制御だけでは、うまく検索することはできません。
　```? ?? ```だけで順番をちゃんと制御することは無理っぽいです。
　ちょっと対応が面倒くさいですが、無理やりできないこともないです。
　そこでGrepを1年を2回に分けます。

　※サクラエディタのGrepの「ファイル」の部分には恐らく260文字まで入力できます。

　一回目：```2019-1-?.txt 2019-1-??.txt 2019-2-?.txt 2019-2-??.txt 2019-3-?.txt 2019-3-??.txt 2019-4-?.txt 2019-4-??.txt 2019-5-?.txt 2019-5-??.txt 2019-6-?.txt 2019-6-??.txt ```
　二回目：```2019-7-?.txt 2019-7-??.txt 2019-8-?.txt 2019-8-??.txt 2019-9-?.txt 2019-9-??.txt 2019-10-?.txt 2019-10-??.txt 2019-11-?.txt 2019-11-??.txt 2019-12-?.txt 2019-12-??.txt```
　このように[1-12]を直接指定することで、なんとかそれっぽい順番でGrepすることができます。

　複数年(2017-2020)で簡易的ですが月順さえ並んでいればいいなら
　```2017-?-*.txt 2017-??-*.txt 2018-?-*.txt 2018-??-*.txt 2019-?-*.txt 2019-??-*.txt 2020-?-*.txt 2020-??-*.txt```
　こんな感じにGrepすることもできます。

##発想の転換、結果を並び替える

　Grepする順番を細かく制御することは難しいですが、Grep結果を「ソート」することはできます。
　Grepの結果出力形式を「ノーマル」にします。
　正規表現置換などを使用して「ファイル名」を「0パディング」に加工します。

```
C:\folder\calendar\2019-10-1.txt  [UTF-8]
C:\folder\calendar\2019-10-10.txt  [UTF-8]
C:\folder\calendar\2019-10-31.txt  [UTF-8]
C:\folder\calendar\2019-10-9.txt  [UTF-8]
C:\folder\calendar\2019-11-1.txt  [UTF-8]
C:\folder\calendar\2019-12-1.txt  [UTF-8]
C:\folder\calendar\2019-12-31.txt  [UTF-8]
C:\folder\calendar\2019-9-31.txt  [UTF-8]
```
・月の0パディング置換「```calendar\\20(.{2})-([0-9])-([0-9]*)\.txt```」→「```calendar\\20$1-0$2-$3.txt```」
・日の0パディング置換「```calendar\\20(.{2})-([0-9]{2})-([0-9])\.txt```」→「```calendar\\20$1-$2-0$3.txt```」
・Grep結果の範囲選択
・サクラエディタの機能「選択行の昇順ソート(Alt+A)」

```
C:\folder\calendar\2019-09-31.txt  [UTF-8]
C:\folder\calendar\2019-10-01.txt  [UTF-8]
C:\folder\calendar\2019-10-09.txt  [UTF-8]
C:\folder\calendar\2019-10-10.txt  [UTF-8]
C:\folder\calendar\2019-10-31.txt  [UTF-8]
C:\folder\calendar\2019-11-01.txt  [UTF-8]
C:\folder\calendar\2019-12-01.txt  [UTF-8]
C:\folder\calendar\2019-12-31.txt  [UTF-8]
```
・タグジャンプを復活させたいなら```-0([1-9])```を```-$1```などに置換して、ファイル名を戻す。

　ということをすれば、ファイル名順になります。

　また「数字順ソート」マクロを作るか探してきて使えば、一発で並び替えできる場合もあります。
IE JScript脆弱性の対策についてのメモ

## 概要
JVNで2020年1月20日に公開された「[JVNVU#90794960
Microsoft Internet Explorer の JScript スクリプトエンジンにおけるメモリ破損の脆弱性](https://jvn.jp/vu/JVNVU90794960/index.html)」で紹介されている、影響の軽減策について調べたメモ

この脆弱性を突く攻撃が既に確認されたとMSが発表しており、[JVN](https://jvn.jp/vu/JVNVU90794960/index.html)や[IPA](https://www.ipa.go.jp/security/ciadr/vul/20200120-ms.html)でもステータスが <FONT COLOR=red><B>「緊急」</B></FONT> となっています。


## そもそも
IE以外のブラウザ使用を考えなさいと[米CISA](https://www.us-cert.gov/ncas/current-activity/2020/01/17/microsoft-releases-security-advisory-internet-explorer)も言っています。



## ワークアラウンドと解説
そうは言ってもIE以外使えん、みたいな環境もあると思います。<FONT COLOR=GREY>(主にエンタープライズ)</FONT>
その場合は発表されている回避策を実施します。
64bitシステムについては、以下のコマンドを実行することが推奨されています。

```
takeown /f %windir%\system32\jscript.dll
cacls %windir%\system32\jscript.dll /E /P everyone:N

takeown /f %windir%\syswow64\jscript.dll
cacls %windir%\syswow64\jscript.dll everyone:N
```

これを実行することにより、すべてのユーザーが`jscript.dll`にアクセスできなくなります。

### takeown
ファイルやフォルダの所有者を調べるためのコマンド
`takeown`コマンド自体が、何かを変更するわけではないです。

| オプション |   内容   |
| :--: | :------: |
|  /f  |   ファイルやフォルダを指定   |

`takeown /f %windir%\system32\jscript.dll`で、`jscript.dll`の所有者を表示します。


### cacls
ファイルのアクセス制御を変更するためのコマンド

| オプション |   内容   |
| :--: | :------: |
|  /E  |   ACLを置き換えずにアクセス権を編集する   |
|  /P username:ACL  |   usernameに指定したアクセス権を与える   |
|  /R username  |   /Eオプションで与えたusernameに対するアクセス権を失効させる   |


| アクセス権 |       意味       |
| :--: | :--------------: |
|  N   |       なし       |
|  W   |     書き込み     |
|  R   |     読み取り     |
|  C   |       変更       |
|  F   | フルコントロール |

`cacls %windir%\system32\jscript.dll /E /P everyone:N` で、`jscript.dll`に対するアクセス権を全員に対して「なし」に設定します。

## パッチ適用時の注意
Windows Updateなどでパッチを適用する際、上で行った権限の変更をもとに戻す必要があります。
パッチを適用する前に、以下のコマンドを実行します。

```
cacls %windir%\system32\jscript.dll /E /R everyone
cacls %windir%\syswow64\jscript.dll /E /R everyone
```

2020/01/21現在、この脆弱性に対するセキュリティパッチは出ていません。
次回の月例パッチ(02/11)のタイミングで修正が入る見込みです。

## 補足
JVNには「Microsoft によると、IE11、IE10、IE9 は、本脆弱性の影響を受けない `jscript9.dll` をデフォルトで使用しています。」と書いてあります。
しかし、後方互換性のために`jscript.dll`も残されています。
思わぬ攻撃スクリプト実行を防ぐためにも、回避策を実施しておくことを推奨します。

## 参考
* [ADV200001 | Microsoft Guidance on Scripting Engine Memory Corruption Vulnerability](https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/ADV200001)
本番環境のエラー表示を攻略する

本番環境でのいつものお決まりのエラー表示
[![Image from Gyazo](https://i.gyazo.com/8e0700d903c146a08d6f435cb2d06742.png)](https://gyazo.com/8e0700d903c146a08d6f435cb2d06742)

# おおん？
# なにがエラーなのかさっぱりわからん

となるところですが
これ実はデフォルト設定なんです

普段からおなじみのエラー表示にしてみたいと思います。

```config/environments/production.rb
config.consider_all_requests_local       = true #デフォルトはfalseになっている
```
デプロイをし直すと

[![Image from Gyazo](https://i.gyazo.com/b000f373903126f74ec6c136df04849c.png)](https://gyazo.com/b000f373903126f74ec6c136df04849c)

# なんとおなじみのエラー表示が！！！

これなら何とかなりそうかも
EC2のマウント先をAmazon S3にする方法



# 目的

EC2インスタンスのマウントをEBSではなく、S３にする方法について調査してまとめました。

## S3にとマウントする方法について

S3にマウントする方法について、インターネットで調査しましたが、ネットユーザーの意見から以下３つの方法が有力候補となるらしいです。

AWS純正のサービスを利用する方法
- AWS Storage

Apacheライセンス/GPLライセンスで公開されているフリーソフトウェアを利用する方法 
- Googfy
- S3fs


AWS Storage Gatewayは、標準的なストレージプロトコルを利用してAWSのストレージサービスへの アクセスを可能にするAWS標準サービスです。標準的なプロトコル（NFSなど）を用いて、S3をバックエンドとしたファイルストレージとして利用することができます。

Goofyと、S3fsは、S3バケットをLinuxのファイルシステムにマウントするためのソフトウェアであり、これを用いることでユーザーはS3 バケットをファイルシステムのように使用することができます。 Googyは、Apache Liscense 2.0ライセンスであり、S3fsはGNU GPL version 2のライセンスであります。基本的には使用や配布に伴うトラブルは自己責任となっております。
Githubの公開情報（copyright情報）によりますと、Goofyは、Ka-Hing Cheung氏によって、S3fsはRandy Rizun氏によって作成されました。


- Storage Gatewayに関するネット情報
  - https://dev.classmethod.jp/etc/storage-gateway-20181122/
  - https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-aws-storage-gateway
  - https://qiita.com/hiroeorz@github/items/e167a6ae6d863a38a79a
  - https://www.denet.ad.jp/technology/2019/02/storage-gatewaypc.html

- Goofyに関するネット情報
  - https://github.com/kahing/goofys/blob/master/README.md
  - https://gb-j.com/column/goofys/
  - https://qiita.com/shicky1121/items/e19b50308c79e5a6081e


- S3FSに関するネット情報
  - https://gb-j.com/column/goofys/
  - https://qiita.com/mint/items/16f72a6c129d3af8d38e
  - https://gitlab.udev.se/open-source/s3fs/blob/8.x-3.x/README.txt


# で、どれが良いのか？

## Goofy vs. S3FS

様々なサイトを比較したところ、ベンチマークの結果はgoofyが圧勝でした。著作者側のGithubのコメント（README）を確認したところ、S3FSを開発したRandy Rizun氏のコメントでは、Goofyを```similar to s3fs but has better performance and less POSIX compatibility```と表現しており、Goofyを開発したKa-Hing Cheung氏は以下のような検証結果をのせていました。
(とてもスポーツマンシップに則っていると少し感動してしまいました。プログラム開発の世界ではこれが普通なんですかね・・・)。著作者同士のコメントを信頼するに、どうやらフリーソフトを持ちいた場合は、Goofyの方が良さそうです。


![bench.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482612/c01342b4-cd89-7b43-0775-16c8d29a0c55.png)


## Googy vs. Storage Gateway

ちょっと待ってて
別のテーブルのIDの続きから連番を振る

```sql:updateno.sql
UPDATE NOTABLE2 
SET NO = (rownum + (SELECT MAX(NO) FROM NOTABLE))
```
Oracleでテーブル1の連番の続きからテーブル2の連番を振る。
連番を振るテーブルの順はINSERTした順でOKという前提。

[5-28 update文で連番に更新](https://oraclesqlpuzzle.ninja-web.net/5-28.html)