OmniAICreator/Qiita-1.07M huggingface dataset:
【JavaScript】関数とPromiseと、ときどきasync await


#関数の種類、早見表


| 名前 | ソースコード | 補足 |
|:-:|:-:|:-:|
| 名前付き関数  | function() 関数名 {}  |   |
| 匿名関数(関数式)  | const 関数名 = function() {}  |   |
| 高階関数 | function(関数) {関数} |  引数に関数をとる関数のこと。また、引数の関数をコールバック関数という。


##コールバック関数の課題

コールバック関数を使うと、ネストになりがち
↓
new Promise(()=>{}).thenで、ネストを解消
でも、行数が増えがち
↓
async (){ await }で、簡略化


#通信成功時と失敗時のコールバック関数


```javascript:
const 非同期関数 = function (成功時関数, 失敗時関数) {
  if (...) {
    成功時関数(成功res)
  } else {
    失敗時関数(失敗res)
  }
}
```



#Promise

```javascript:
new Promise (function (resolve, reject) {
  asynchronous(
    function(成功res) {
      resolve(成功res)
    },
    function(失敗res) {
      reject(失敗res)
    },
  )
})
```

axios

```javascript:
function getStatus () {
  return new Promise(function (resolve, reject) {
    axios.get("URL")
    .then(function(res) {
      resolve(res.status)
    }).catch(function(error) {
      reject(error.res.status)
    })
  })
}
```


#async await

```javascript:
async function () {
  try {
    const 成功res = await 非同期関数
    成功時処理
  } catch(失敗res) {
    失敗時処理
  }
}

```

axios

```javascript:
async function getStatus () {
  try {
    const res = await axios.get("URL")
    return res
  } catch(error) {
    return error
  }
}
```

上記のように、分かりやすく`try`も書いたが、いらなくても良い。
意外と意識されていないPostgreSQLのロックについて

開発でPostgreSQLを利用することはよくありますよね。
しかし、ロックについてしっかり理解している人は少ないと思います。

## PostgreSQLのロックの種類
まず、PostgreSQLのロックには以下のようなロックレベルがあります。

 - ACCESS SHARE
 - ROW SHARE
 - ROW EXCLUSIVE
 - SHARE UPDATE EXCLUSIVE
 - SHARE
 - SHARE ROW EXCLUSIVE
 - EXCLUSIVE
 - ACCESS EXCLUSIVE

それぞれについての詳しい内容は公式ドキュメントをご覧ください
https://www.postgresql.jp/document/12/html/explicit-locking.html

よく使うSQLだと例えば、
SELECT文はACCESS SHARE、INSERTやUPDATEはROW EXCLUSIVEにあたります。

## 競合するロック
ロックは以下の表の☓がの部分が競合します。

|                        | ACCESS SHARE | ROW SHARE | ROW EXCLUSIVE | SHARE UPDATE EXCLUSIVE | SHARE | SHARE ROW EXCLUSIVE | EXCLUSIVE | ACCESS EXCLUSIVE | 
| ---------------------- | :----------: | :-------: | :-----------: | :--------------------: | :---: | :-----------------: | :-------: | :--------------: | 
| ACCESS SHARE           |              |           |               |                        |       |                     |           | X                | 
| ROW SHARE              |              |           |               |                        |       |                     | X         | X                | 
| ROW EXCLUSIVE          |              |           |               |                        | X     | X                   | X         | X                | 
| SHARE UPDATE EXCLUSIVE |              |           |               | X                      | X     | X                   | X         | X                | 
| SHARE                  |              |           | X             | X                      | X     | X                   | X         | X                | 
| SHARE ROW EXCLUSIVE    |              |           | X             | X                      | X     | X                   | X         | X                | 
| EXCLUSIVE              |              | X         | X             | X                      | X     | X                   | X         | X                | 
| ACCESS EXCLUSIVE       | X            | X         | X             | X                      | X     | X                   | X         | X                | 


ACCESS EXCLUSIVEロック時に、ACCESS SHAREの実行はロックされ待ちが発生します。
しかし、ROW EXCLUSIVEロック時に、ACCESS SHAREの実行はロックされず実行することが可能です。


## 実際に実行してみる
### 競合なしパターン
```sql
BEGIN;

INSERT INTO hoge VALUES (1, 'hoge');
```
を実行して、ロック状況を見ると以下のようになります(pgAdminで確認してます。)
![postgresql_lock_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218021/76786719-5222-4669-22fe-f1cf23a1e72f.png)
RowExclusiveLockでロックされているのがわかると思います。
この状態で以下を実行すると実行可能なことがわかります。
実行する際にはさきほど実行したのとは別のセッションでお願いします。

```sql
SELECT * FROM hoge LIMIT 1;
```

### 競合ありパターン

```sql
BEGIN;

TRUNCATE TABLE hoge;
```
を実行して、ロック状況を見ると以下のようになります。
![postgresql_lock_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218021/c5b80330-3407-b2d6-ae33-155b22e831cf.png)
こちらはAccessExclusiveLockになっているのがわかると思います。
この状態でさきほどと同じ以下のSQLを実行してみてください。

```sql
SELECT * FROM hoge LIMIT 1;
```
おそらくすぐに実行されないと思います。
この状態でロックかけてる側のセッションで

```sql
ROLLBACK;
```
を実行するとSELECTの結果も返ってくると思います。

## まとめ
このように普段意外と意識していないかもしれませんが、しっかりとロックレベルがあります。
これを意識して開発するのは大事ですね。ロックレベルを意識的に上げたい場合などは明示的にロックをすることも可能なのでそのへんも意識していけるといいですね。
json2csvで出力したCSVファイルがExcelで文字化けしてしまう

## はじめに
以前まとめた、[【Node.js】JSON文字列をCSVファイルとして吐き出す](https://qiita.com/kum44/items/d11f97ecee3e46d3195d)という記事で、`json2csv`というモジュールを使用し、CSVファイルを正常に出力できたと思っていたのですが、ExcelでCSVファイルを開くと文字化けしてしまっていたので、修正を行いました。

## 結論
・`withBOM`オプションを`true`にする

## 解説
`json2csv`のドキュメントに`withBOM`オプションの説明が記載されていました。
>Unicode Support
Excel can display Unicode correctly (just setting the withBOM option to true). However, Excel can't save unicode so, if you perform any changes to the CSV and save it from Excel, the Unicode characters will not be displayed correctly.

[json2csv](https://github.com/zemirco/json2csv)

`withBOM`オプションを`true`にするだけで、ExcelではUnicodeを正しく表示できる、的なことが書かれていますね。
なので、インスタンス化時に`withBOM`オプションを付与してあげます。

```js:json2csvのインスタンス化
const json2csvParser = new Parser({fields, transforms, withBOM: true});
```
これで、Excelでも文字化けすることなく、正常にCSVファイルが表示できるかと思います。

### BOMって何だ？
「Byte Order Mark」の正式名称で、BOMが付与されたファイルは`Unicodeで書かれている`ことを証明しています。
しかし、Unicodeで書かれたファイル全てにBOMが付与されている訳ではありません。BOMがあってもなくてもどちらでもいいそうです。BOMが存在する理由は、絶対にこのファイルがUnicodeで書かれていることを示す必要がある場合があるからで、今回のExcelでCSVファイルを開く時などが該当します。
ExcelではBOMが付与されたCSVファイルでないと、文字コードが認識されずに文字化けを引き起こしてしまうのです。

## 参考
[バイトオーダマーク（英：Byte Order Mark）とは](https://wa3.i-3-i.info/word11430.html)
[簡単に文字化け回避！UNICODE (UTF-8) の CSV データを表示する方法](https://excel.nj-clucker.com/view-unicord-csv-data/)
【Golang】Go言語の基礎　構造体について①

Goにはオブジェクトと呼ばれるものはありません。したがって、クラスという概念が存在しないです。
その代わりに構造体というものがあり、オブジェクト指向のような書き方をすることが可能です。

まずは第一弾として構造体の書き方や初期化の方法などについてみていきます。

②では構造体の埋め込み（オブジェクト指向でいう継承のようなもの。Goには継承はありません。）について書いていこうと思ってます！

#構造体を使ってあれこれ書いてみる
構造体は type と structを用いて書くことができます。

```go

package main

import "fmt"

type Vertex struct {
	X int
	Y int //小文字のyにすると外部からアクセスできなくなる
	S string
}

func main() {
    //構造体の初期化
	v := Vertex{X: 1, Y: 2}
	fmt.Println(v) // => {1 2}

    //構造体のフィールドにアクセス
  	fmt.Println(v.X, v.Y) // => 1 2

    //中身を書き換える
	v.X = 100
	fmt.Println(v.X, v.Y) // => 100 2

    //このように一部の値を渡すこともできる。その場合、残りはデフォルトの値が入る。（intは0、stringは空文字）
	v2 := Vertex{X: 1}
	fmt.Println(v2) // => {1 0 }

    //構造体に書いてる順番通りに書いてフィールドの値を渡して初期化することもできる
	v3 := Vertex{1, 2, "huga"}
	fmt.Println(v3) // => {1 2 huga}

    //{}で空の構造体を宣言 それぞれの型のデフォルトの値が入る
	v4 := Vertex{}
	fmt.Println(v4) // => {0 0 }
	fmt.Printf("%T %v\n", v4, v4) // => main.Vertex {0 0 }

    //varで宣言だけした場合はv4と同じ構造体になる。mapやスライスは宣言だけした場合はnilになるので注意。
	var v5 Vertex 
	fmt.Println(v5) // =>{0 0 }
	fmt.Printf("%T %v\n", v5, v5) // =>main.Vertex {0 0 }

    //ポインタが返ってくる
	v6 := new(Vertex)
	fmt.Println(v6) // => &{0 0 }
	fmt.Printf("%T %v\n", v6, v6) // => *main.Vertex &{0 0 }

    //ポインタが返ってくる、この書き方だと一目でポインタが返ってくるとわかるのでこちらを使うことが多いようです！
	v7 := &Vertex{}
	fmt.Println(v7)	// => &{0 0 }
    fmt.Printf("%T %v\n", v7, v7) // => *main.Vertex &{0 0 }

}
```
＆を付けてアドレスで引数を渡すと最初に定義した値を書き換えることができる。

```go

package main

import "fmt"

type Vertex struct {
	X int
	Y int //yにするとアクセスできなくなる
	S string
}

func changeVertex(v Vertex) {
	v.X = 1000
}
func changeVertex2(v *Vertex) {
	v.X = 1000
}

func main() {
	v := Vertex{1, 2, "hoge"}
//値私なので、宣言した元の構造体は書き換わらない。
	changeVertex(v)
	fmt.Println(v) {1 2 hoge}

//ポインタ渡しなので元の構造体を書き換えることができる。
	v2 := &Vertex{1, 2, "hoge"}
	changeVertex2(v2)
	fmt.Println(v2)&{1000 2 hoge}
}
```

##なぜポインタ渡しを使うのか？
>・値渡しと違って、間接的に参照・操作できる

>・上で見たように値渡しだと関数の引数として構造体を渡した場合に、その構造体のコピーが生成されてしまい、元の構造体に影響を与えない。ポインタ渡しだと影響を与えることができる。

>・単純にORマッパーなどのライブラリがポインタを使うので使わざるを得ない

>・大きな構造体を値渡しするとコピー処理で性能が劣化する。 ポインタ渡しの場合には固定で8バイト>(64bit)/4バイト(32bit)なので性能が劣化しない。

引用元：[Golangのポインタ渡し初心者を卒業した](https://qiita.com/kotaonaga/items/4a93ec40718c279154f5)

との理由からのようです。初学者の自分にはいまいちピンときませんｗ
実践で使っていく中で腹で理解していけばいいと思っています。
とりあえずこんなことができるということをまずは頭に叩き込もうと思います！
JPAのOneToManyのdeleteがupdateになる

JPAのOneToManyのコレクションを削除をする場合、```CascadeType.REMOVE```や```orphanRemoval = true```を使用する。このとき、発行されるSQLは```delete```を期待するが```update```になってしまった。これの原因はエンティティ間の定義（```OneToMany```とか```JoinColumn```）がおかしい場合になるらしい。具体例を出せなくてアレだが https://stackoverflow.com/questions/17079649/jpa-orphanremoval-true-tries-to-update-not-delete とかが参考例になる、と思う。
next.jsをGAEにデプロイ

#概要
Google App Engine にnext.jsで実装したFrontendサービスをデプロイするための手順とポイントについてまとめます。
また、gcloud　SDKはローカル環境で利用可能な状態であることを想定します。

#package.json
最初にpackage.json内に記載のscriptをGCPにデプロイするために編集します。（これは必須ではありませんが開発効率向上のため設定）

```package.json
{
	"scripts": {
		"dev": "next",
		"build": "rm -rf ./build && NODE_ENV=production next build",
		"start": "next start",
		"deploy": "npm run build && gcloud app deploy",
		"export": "next export"
	},
	"dependencies":{

       '''''''''''''略'''''''''''''''''''

	}
}
```


デプロイのために書き加えた部分はbuildとdeployです。

まずbuildの部分ですが、nextの場合buildすると通常は.nextディレクトリ下にビルドされますが、GAEはこれを認識できないのでbuildフォルダを作成してその中にビルドファイルを入れるようにします。
次にdeployでは```nom run deploy```を実行してそのまままGAEへのデプロイも行うようにしてあります。

また、たまにstartのスクリプトを```next start -p 8080```としている記事を目にしますが、この記述はパフォーマンスの面で良くありません（スケーリング時、不必要に何度も実行されてしまう。）ので、次のapp.yamlの中のentrypointで記述するようにします。

#app.yaml

```app.yaml
service: front
runtime: nodejs12
entrypoint: next start -p $PORT
handlers:
- url: .*
  script: auto
```

今回はfrontendとbackendを分けているのでserviceにforntと記述しておくことでGAE内でのserviceとして独立させています。
entrypointの部分で```next start -p $PORT```と記述することでアプリ起動時のコードを設定できます。
アプリの起動時に entrypoint コマンドを実行することで、デフォルトの起動動作をオーバーライドすることができ、今回の場合だと環境変数PORTにポートを開いてアプリをスタートすることができます。
entorypointの記述が誤っているとHTTP500エラーが出てしまう場合があるので、entrypointに正しく記述をすることで修正できます。

あとはpackage.jsonで設定した```npm run deploy```を実行してあげることで自動的にGAEにデプロイされます。

#終わり
今回の例は自分の実行環境下での1例であり、あくまで参考程度にしていただけたらと思います。
間違っている部分等があればご指摘よろしくお願いします。
Docker開発環境でCapybaraを使ったブラウザテスト環境を構築する

##概要
docker開発環境でRSpecテスト環境を構築するやり方をまとめました。
初心者で独学なので間違っている部分やもっといいやり方があると思いますが、その時はご指摘頂けると嬉しいです。

以下の記事を参考にしました。
[Rails on DockerでRSpecのSystem testをSelenium Dockerを使ってやってみた。](https://qiita.com/at-946/items/e96eaf3f91a39d180eb3)

##はじめに
以前、[Dockerを使ったRails開発でブラウザテストが実行できない](https://qiita.com/na-tsune/items/05b00970cb733a893ce3)でブラウザテストのエラー解消の記事を投稿しましたが、
コメントを頂き、docker-composeを使ってchrome自体をサービスの一つとして動かせば、
Rails環境を汚さずに簡単にテストができるとアドバイスを頂きましたので試してみました。
ご指摘ありがとうございました！

##1.docker-compose.ymlにchromeのサービスを追加
使用するイメージはChromeが最初からインストールされたものである、standalone-chromeを使います。

```yml:docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/[app名]
    ports:
      - 3000:3000
    depends_on:
      - db
      - chrome　# ←追加
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
　# ↓追加
  chrome:
    image: selenium/standalone-chrome:latest
    ports:
      - 4444:4444
　# ↑追加
volumes:
  db-volume:
```

##2.RSpecの導入
rspec-railsのgemを追記します

```rb:Gemfile
group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'rspec-rails', '~> 4.0.1'  # 追加
  gem 'factory_bot_rails', '~>4.11'
end
```

gemをインストールします。

```
$ docker-compose build
```
※ビルドした後はコンテナの再起動を忘れずに

RSpecのインストール

```
$ docker-compose run web rails g rspec:install
```

次に、インストールすると作成されるファイルの中に、"rails_helper.rb"に設定を記述していきます。
RSpec実行時にdocker-seleniumのコンテナのブラウザを使用するように設定します。


```rb:/spec/rails_helper.rb
#~
Capybara.register_driver :remote_chrome do |app|
  url = "http://chrome:4444/wd/hub"
  caps = ::Selenium::WebDriver::Remote::Capabilities.chrome(
    "goog:chromeOptions" => {
      "args" => [
        "no-sandbox",
        "headless",
        "disable-gpu",
        "window-size=1680,1050"
      ]
    }
  )
  Capybara::Selenium::Driver.new(app, browser: :remote, url: url, desired_capabilities: caps)
end

#~

RSpec.configure do |config|
  
  config.before(:each, type: :system) do
    driven_by :rack_test
  end

  config.before(:each, type: :system, js: true) do
    driven_by :remote_chrome
    Capybara.server_host = IPSocket.getaddress(Socket.gethostname)
    Capybara.server_port = 4444
    Capybara.app_host = "http://#{Capybara.server_host}:#{Capybara.server_port}"
  end
#~
end
```

最後に`.rspec`を編集して、rails_helper.rbの設定を読み取るようにします。

```diff:.rspec
- --require spec_helper
+ --require rails_helper
```

以上です。

あとはテストを記述してテストを実行できるか確認してみます。

```
#コンテナ起動時
$ docker-compose exec web rspec [rspecテストファイルのpath]
```

テスト失敗時にブラウザのハードコピーを確認することができました。

![スクリーンショット 2020-09-22 22.30.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451281/867c8c09-acbe-1fcb-d7e2-63b7d69ae3d3.png)
Ubuntu 18.04にKallitheaを構築する

# 概要
KallitheaはGit と Mercurial に対応したオープンソース(GPLv3)のリポジトリホスティングソフトウェアです．
今回はそのKallitheaをubuntu上に構築していきます．

[Kallitheaとは](http://www.kallithea-users.jp/about/index.html)

# 環境
| Software | Version |
|-----|-----|
| ESXi | 6.7 |
| Ubuntu | 18.04 |

# パッケージのアップデート
```
sudo apt update
```

# インストール
## 1. パッケージのインストール
```
sudo apt install build-essential git libffi-dev python3-dev npm mercurial python3-pip
```
## 2. ディレクトリを作成
- 今回は/opt配下に構築していきます

```
# kallitheaとリポジトリ配置用のディレクトリ(repos)を作成
sudo mkdir -p /opt/kallithea/repos
# 書き込み可能なパーミッションに変更
sudo chmod -R 777 /opt/kallithea
```

## 3. kallitheaのインストール

```
# kallitheaディレクトリに移動
cd /opt/kallithea
# kallitheaをインストール
pip3 install kallithea
```

# 初期セットアップ
## 1. Kallithea構成ファイルの作成

```
# kallitheaディレクトリに移動
cd /opt/kallithea
# 構成ファイルの作成
kallithea-cli config-create my.ini
```
## 2. Kallitheaで使用するDBの作成

```
kallithea-cli db-create -c my.ini

#下記が聞かれる
Are you sure to destroy old database ? [y/n]y
Enter a valid absolute path to store repositories. All repositories in that path will be added automatically: /opt/kallithea/repos
Specify admin username:<管理者アカウントのユーザ名>
Specify admin password (min 6 chars):<パスワード>
Confirm password:<再度パスワード>
Specify admin email:<メールアドレス>
```

## 3. フロントエンドファイルの作成

```
kallithea-cli front-end-build
```

# Kallitheaの実行

```
# 起動
gearbox serve -c my.ini

# デーモン化
gearbox serve -c my.ini --daemon
```

- http://localhost:5000 でアクセスできる

- Port及びIPを変更したい場合はmy.iniの[server:main]セクションで変更する．

```
[server:main]
host = 127.0.0.1
port = 5000
```

# サブディレクトリで運用する
- Apacheでの設定例です．

## 1. Apacheの仮想ホストファイルの設定

- 仮想ホストファイルに下記を追記

```
<Location /kallithea >
  ProxyPass http://127.0.0.1:5000/kallithea
  ProxyPassReverse http://127.0.0.1:5000/kallithea
  SetEnvIf X-Url-Scheme https HTTPS=1
</Location>
```

## 2. my.iniファイルに設定を追記

- my.iniファイルの[app:main]セクションに下記を追記

```
[app:main]
use = egg:kallithea

# 下記を追記
filter-with = proxy-prefix
```

- 最終行に下記を追記

```
[filter:proxy-prefix]
use = egg:PasteDeploy#prefix
prefix = /kallithea
```

- http://<サーバアドレス>/kallitheaでアクセスできるようになる

# 参考
##### Kallitheaのインストール手順
[Kallithea Installation on Unix/Linux](https://kallithea.readthedocs.io/en/stable/installation.html)
Magics installの対処法

# 解決方法見つからなかった

## Magicsとは

MagicsはECMWFの気象プロットのソフトウェアでpythonとか直接アクセスしたりMetviewを使ってアクセスすることもできる。

## 機能
等圧線、風車、観測、衛星画像、シンボル、テキスト、軸、グラフのプロットをサポートしている。

GRIBのデータや、ガウスグリッド、等間隔グリッド、フィットデータをプロットできる


## インストール方法
```$ pip install Magics```
システムの依存関係があるので、Ubuntu 18.04だったらlibmagplus3v5をインストールしてください。
```$ sudo apt-get install libmagplus3v5```

ここから、エラーがでる。
コンテナは、ubuntuのこれを使っている
```gcr.io/deeplearning-platform-release/tf2-cpu.2-3```

以下のコマンドを打つとエラーが表示される

```
!python -m Magics selfcheck


Traceback (most recent call last):
  File "/opt/conda/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/opt/conda/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/opt/conda/lib/python3.7/site-packages/Magics/__main__.py", line 36, in <module>
    main()
  File "/opt/conda/lib/python3.7/site-packages/Magics/__main__.py", line 25, in main
    from . import macro
  File "/opt/conda/lib/python3.7/site-packages/Magics/macro.py", line 14, in <module>
    from . import Magics
  File "/opt/conda/lib/python3.7/site-packages/Magics/Magics.py", line 206, in <module>
    py_open = dll.py_open
  File "/opt/conda/lib/python3.7/ctypes/__init__.py", line 377, in __getattr__
    func = self.__getitem__(name)
  File "/opt/conda/lib/python3.7/ctypes/__init__.py", line 382, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: /usr/lib/x86_64-linux-gnu/libMagPlus.so.3: undefined symbol: py_open
```

py_openがないとなっているので、pipでインストール

```
pip install pyopen

エラーがでるので、これもやる
pip install netCDF4

やっとエラーが解消
!nosetests

もう一度トライしてみるがやっぱりエラー
python -m Magics selfcheck
```

インストールガイドはここ
https://confluence.ecmwf.int/display/MAGP/Installation+Guide

Magicsのバージョンはドキュメントだと4.0.0になっているのに、以下のpackageでは
1.5.0になっている。
https://pypi.org/project/Magics/
任意のディレクトリ内のファイル名を元に連番ファイルを作成するシェルスクリプト



日々発生するの**技術ネタ**、**アイデア**は**MarkDown書式**で適当に追加しておます。重要なのは全てにおいて**「スピード」**です。
  
僕のライフスタイル的に**MarkDownファイルの作成頻度がメチャ高い**のです。
  
## ファイル名を手入力するのが面倒くさい


MarkDownファイルを作成するたびにファイル名を手動で付けていたのですが、以下の課題が顕著に現れてきました。

- 命名におけるケアレスミスの発生
- ファイル名をつけるだけで、ちりつもで時間がかかる

という事で**任意のディレクトリ内のファイル名を元に連番ファイルを作成するシェルスクリプト**を作って自動化してみたいと思います。


今回作りたいファイルのフォーマットはコチラです。

**「年月日連番(3桁)-任意の文字列」**

自動化するのは**「年月日連番(3桁)」**部分です。


## 要件

- 日付はローカル日時
- 既に同名が存在すれば連番をインクリメント
- 連番は3桁固定で3桁満たない場合は0で埋める


## 日付はローカル日時

```shell
date=`date '+%Y%m%d'`
# 出力例 : 20200922
```

date関数を使って日付文字列を作成します。個人的にフォーマット先頭の`+`を忘れやすいです。


## 指定のディレクトリ内のファイル名リストを作成

今回の検索対象は`drafts/`ディレクトリ内且つMarkDownファイルのみです。

```shell
# draftsディレクトリ内を検索
dir='drafts/'

# 検索対象
target="$dir*.md"

# find関数で検索ファイルパスのリストを作成
files=`find $target -type f -maxdepth 0 -name $date*`
```
find関数を使って、指定した検索対象のファイルパスのリストを取得します。

### find関数の補足説明

```shell
-type f
```
`-type`オプションで**ファイルを検索対象**としています。(フォルダは対象外)


```
-maxdepth 0
```
`-maxdepth 0`オプションでサブフォルダは検索対象外としています。

```shell
-name $date*
```
`-name`オプションでファイル名のルールを加えて絞り込みます。


これでfiles変数に指定した日付のMarkDownファイルパスのリストが格納されました。



## 連番の作成

例 : `drafts/20200922004-hogehoge`

この「004」の部分。文字列15番目から3つの文字列を抽出します。


```shell
# 作成済み連番の最大値
max_serial=0
for filepath in $files;
do
  # 連番情報を抽出する
  serial_num_str=`echo ${filepath:15:3}`

  # 文字列を数字にキャスト
  serial_num=$(expr $serial_num_str)

  # 連番の最大値を保持
  if [ $max_serial -lt $serial_num ];then
    max_serial=$serial_num
  fi
done
```
ファイル名の連番を抽出して、最大値を取得します。


### 文字列を数値にキャストして比較

文字列のままだと数値の比較はできないので、数値にキャストします。

```shell
serial_num=$(expr $serial_num_str)
```
この部分で文字列(例:012)を数値(12)にキャストしています。

```shell
if [ $max_serial -lt $serial_num ];then
```

`-lt`を使って比較しています。 `if [ A -lt B ] ` AがBより小さかったらmax_serialを更新します。


## 連番をインクリメントしてファイル生成

```shell
new_id=$(expr $max_serial + 1)
```
先程のキャスト処理を使って使用する連番を決定します。


## 3桁に0埋めする

```shell
new_num=`printf %03d $new_id`
```
printf関数に引数でフォーマット(`%03d`)を指定して必要があれば0で埋めます。
**例:12 -> 012**


## 最後に

以下のgifアニメでは分かり辛いですが、シェルを実行するたびに連番ファイルが作成されるようになりました。

![](https://i.gyazo.com/af82264d71d6e8a4df06aaea5f7cec66.gif)

これで技術メモする時のMarkDown作成のストレスが減りそうです。


全ソースは[コチラ](https://gist.github.com/baobao/84a1853cc7d22269502024c4c8f01842)にアップしています。


## 参考サイト

- [ファイルなどを検索する！findコマンドの詳細まとめ【Linuxコマンド集】](https://eng-entrance.com/linux-command-find#-name)
pd.read_excelのsheet_nameでエクセルのシートが指定できない

エクセルからDataFrameとしてデータを読み込む際に使うread_excel関数だが、
リファレンスに載っているとおりsheet_nameでシート名を指定してもエラーにならないが正しくシートを取得できないことがあった。
（どのように指定しても１番目シートしか取得できなかった）

```Python
import pandas as pd  #version 0.20.0
df = pd.read_excel(input_path, sheet_name="Sheet2") #2番目のシートを読み込みたい
print(df) #なぜか1番目のシートの内容が出てくる
```

どうやら**pandas 0.20以前**の環境ではsheet_nameは機能せずsheetnameで指定するのが正しいらしい（なぜsheet_nameもキーワードとして使えるんだろう...）
ちなみにpandas 0.23ではsheetnameを使用すると警告が表示されるがsheetnameとsheet_name両方機能する。
最新版ではすでにsheetnameキーワードは削除されsheet_nameキーワードのみが使用できる状態となっていた。

```Python
df = pd.read_excel(input_path, sheetname="Sheet2") #ハイフンなしのsheetname
print(df) #ちゃんと2番目のシートが取得できた
```
ruby Hash#==の挙動について

ふとrubyにてHash同士の比較についてどこまで比較してるのか？と気になったので検証してみた。

結果としては公式のドキュメントに記載があるが
**自身と other が同じ数のキーを保持し、キーが eql? メソッドで比較して全て等しく、値が == メソッドで比較して全て等しい場合に真を返します。**

参考：[instance method Hash#==](https://docs.ruby-lang.org/ja/latest/method/Hash/i/=3d=3d.html)

という動作をするようだ、検証してみる。

```ruby
require 'securerandom'

keys   = Array.new
values = Array.new

# 1000個のテストデータを作成
1000.times do
  keys << SecureRandom.alphanumeric
end

1000.times do
  values << SecureRandom.base64(100)
end

# valueの中身がばらばらの比較
a = Hash.new
b = Hash.new
keys.each do |key|
  a[key] = values.sample
  b[key] = values.sample
end

puts a == b ? "match!!" : "unmatch..."

# valueの中身を同一にした比較
a = Hash.new
b = Hash.new
keys.each_with_index do |key, i|
  a[key] = values[i]
  b[key] = values[i]
end

puts a == b ? "match!!" : "unmatch..."
```

結果

```
$ >> ruby test.rb
unmatch...
match!!
```

ちゃんと比較してる模様、ちゃんと公式に書いてある通りだった。
Macのメニューバー設定トグル・System Events経由

```AppleScript:
tell application "System Preferences"
	set current pane to pane "com.apple.preference.general"
	repeat until window "一般" exists
		delay 0.2
	end repeat
	delay 0.5
	tell application "System Events" to click checkbox 5 of window 1 of process "System Preferences"
	quit
end tell
```

これも。姿を見せずに使えるようだ…
【試験合格記】AWS 認定 データベース – 専門知識(DBS-C01)

お疲れさまです。
表題の試験に合格したため記録として残したいと思います。

# 結果
合格(816点)

[AWS-Certified-Database-Specialty_Exam-Guide.pdf](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-database-specialty/AWS-Certified-Database-Specialty_Exam-Guide.pdf)

|分野|名称|割合|
|:-----------------|:-------------------|:-------------------|
|1|ワークロード固有のデータベース設計|26%|
|2|展開および移行|20%|
|3|管理および運用|18%|
|4|監視およびトラブルシューティング|18%|
|5|データベースセキュリティ|18%|

# 所有資格

| 資格名       |取得年月日 |
|:-----------------|:-------------------|
|AWS Certified Solutions Architect - Associate (SAA)|2018-06-14|
|AWS Certified SysOps Administrator - Associate (SOA)|2018-06-22|
|AWS Certified Developer - Associate (DVA)|2018-06-25|
|AWS Certified Solutions Architect - Professional (SAP)|2018-07-19|
|AWS Certified DevOps Engineer - Professional (DOP)| 2020-02-19| 
|AWS Certified Big Data - Speciality (BDS)| 2020-03-23| 
|AWS Certified Security - Speciality (SCS)| 2020-04-01| 
|AWS Certified Machine Learning - Speciality (MLS)| 2020-04-13| 
|AWS Certified Advanced Networking - Speciality (ANS)| 2020-04-27| 
|AWS Certified Cloud Practitioner (CLF)| 2020-04-27| 
|AWS Certified Database - Specialty (DBS)| 2020-09-22| 

# 事前知識
AuroraやElastiCacheを業務で建てることはよくあるので、そのへんのパラメータ周りは知ってます。
あとは過去に「エキスパートのためのMySQL[運用+管理]トラブルシューティングガイド」という書籍を読破したり、レンサバ運用で泣き叫んでるMySQLサーバのスロークエリを抽出したりパフォーマンスチューニングをしたり・・・といった程度で正直ひよっこレベルでした。

# 所感
学習期間は1ヶ月半くらいだったと思います。
難易度としては普段からDBサーバを触っているかいないかで大きく変動するのではないでしょうか。

また、この試験に限らず、DBリソース選定や面接などで「RDSとAuroraはどう違うのか」といった話はよく出るので体系的に理解しておくのがオススメです。

試験内容についてはどなたかのブログで書いてましたが、「セキュリティ専門」と「ネットワーク専門」の知識が正しく頭にあればそれだけで30%くらいのスコアを稼げると思います。
あとはRDSとAuroraの違いやディザスタリカバリ要件に対するアプローチ、それにDMSを使ったマイグレーションなどの最適解を導き出せると60%が見えてくるはずです。
残りの40%はNeptune、DynamoDB、Aurora Serverless、ElastiCacheといった雑多な周辺知識の特徴を抑えておけば合格ラインを超えられる可能性が出てくると思います。

# 学習範囲

- [サンプル問題](https://d1.awsstatic.com/ja_JP/training-and-certification/docs-database-specialty/AWS-Certified-Database-Specialty_Sample-Questions.pdf)
- 模擬試験
- [Exam Readiness: AWS Certified Database - Specialty](https://www.aws.training/Details/eLearning?id=47245)
- 各種ブラックベルト

# 受験者に向けたアドバイス
- セキュリティとネットワークのAWS認定で学んだ内容をしっかり振り返る
- RDS(MySQL, PostgreSQL, SQL Server, Oracle)それぞれができること、できないことを理解する
- Auroraも同じ
- DMSを使ったマイグレーションの手順やそれに頼らない別のアプローチを把握しておく
- DynamoDBはそれなりに出題された記憶があるので要復習
- IAMを使った権限管理やDBをふっ飛ばしたので巻き戻したい系のトラブルシューティングも重要

# まとめ
Kubernetesの資格を取ったあたりで試験勉強に飽きてしまいました。
データベース資格に関しては試験勉強をすることで身近な運用時のミスをカバーできる知識を得ることができるので、DBを触ったことがないという方も学んでみると色々と役に立つことがあるかもしれません。
特にインフラ屋にとってはDBが安定していないと睡眠時間が減ってしまうという問題もあるので是非取得を目指すとよいと思います。

年内に最後の資格であるAlexaを取得できるよう引き続き頑張ります。
正規表現の便利さに気付かされた話

# はじめに


- 本記事は正規表現を解説するものではありません
- 正規表現を使うとどれだけコード量が減るのかがわかります！


# クイズを出された

コミュニティ仲間A「最近サンプルコードの改変やぐぐってばかりで自分でコーディングしてないでしょ？ちょっとやってみ！」


**`<hoge1234>asna<hoge1234>nsasasa`という文字列を、
`asnansasasa`にするプログラムを書こう！**

`<>`とその中の文字列を削除せよということですね。

なんか正規表現を使えば解けそうねー、と直感的に理解しチャレンジしてみました。（そして失敗した）
試行錯誤の流れは正規表現を学んでから別記事にまとめようと考えています。

# 正規表現で解いた

なんとか教えてもらいながら正規表現で解きました。
JSで書いていますが言語選定に特に理由はありません。
Javaの入門書の1単元にちょこっと載ってたのを、さらーっと読んだことがあるだけの私では、うまく解けませんでしたが、
他の仲間に手取り足取り教わることで、なんとか書くことができました。
（もっと賢い方法はあるようなのですが私にはまだ理解しきれませんでした）


**4行ですね。**

```js

 let hoge = "<hoge1234>asna<hoge1234>nsasasa";
 const foo = /<[^>]*>/g
 
 hoge = hoge.replace(foo, "");
 
 console.log(hoge);

```

# 正規表現を使わずに解き直してみた

もし正規表現を使わなかったらどれだけ複雑なソースコードになるのか？
やってみました。

書き上げたあと、「もっと短縮できるでしょ」と言われましたが、
（なんなら `>` から始まり、 `...<hoge>...`と続く文字列だと大変なことが起きますが、）
ひとまずはこれで許して！


**19行です。**

```js
 const hoge = "<hoge1234>asna<hoge1234>nsasasa";
 const hoge2 = hoge.split("");
 
 for (let i = 0; i<hoge2.length; i++){
     const str = hoge2[i];
     if (str == "<"){
         for(let j = 0; j<hoge2.length; j++){
             const str2 = hoge2[j];
             if (str2 == ">"){
                 hoge2.splice(i, j + 1);
                 break;
             }
         }
     }
 }
 let hoge3 = "";
 for (let s of hoge2){
     hoge3 += s;
 }
 console.log(hoge3);

```

# さいごに

**今回のケースだと19行から4行に減りました。**

ロジックを考えるのもひとつの勉強になると思うので、
正規表現を使わずに書いてみるのはそれはそれでアリなのですが、

**どれだけ正規表現が便利かは思い知らされました。**

その価値をかみしめながら、正規表現を学ぼうと思います。
【初心者向け】GoogleChromeのリニューアルで目立つようになった黒い線を消す方法

#どうも7noteです。開発していると、意図していない場所に黒い太枠線がでてくるようになって、なんだこれって思ってました。こいつを消します。

どうも7noteです。
この記事は以下へ引っ越しました。

https://naruweb.com/coding/focus-border/
Ruby on Rails 環境構築(Windows10)で苦労したこと(SQLite3)

Railsのインストールがやっとできました。
苦労した点１つめをまとめます。

RubyとRailsをインストール後
Railsアプリを新規作成したところ、こんな感じのエラーがたくさんでました。

```
エラー: mingw32: キー "AD351C50AE085775EB59333B5F92EFC1A47D45A1" は不明です
・・・
エラー: データベース 'mingw64' は無効です (無効または破損したデータベース (PGP
鍵))
```

Gemfileで
`gem 'sqlite3', '~> 1.4'`
となっていたので
いろいろ修正してみたけれどだめ。

そこで
sqlite.dllをRubyのbinへ配置
node.jsのインストール
yarnのインストール
を行い

```
gem install sqlite3
```
を実施。それでもエラーが出てしまい・・
エラー内容をよく見てみると、こんな記述が・・

```
checking for sqlite3.h... no
sqlite3.h is missing. Install SQLite3 from　http://www.sqlite.org/ first.
```

sqlite3.hのチェックで引っかかっている？！

そこで、sqlite3.hをRubyのbinへ置き、引数にsqlite.hの場所、sqlite3.dllの場所を指定してgem install sqlite3を実行。

それでもエラーが出て・・
引数にsqlite3のバージョンまで指定するとうまくいきました。

こんな感じです。

```ruby:
gem install sqlite3 --version 1.3.13 --platform=ruby -- --with-sqlite3-include=C:\Ruby27-x64\bin --with-sqlite3-lib=C:\Ruby27-x64\bin
```

最後に
Gemfileを
`gem 'sqlite3', '~> 1.3.13'`
に修正して
`bundle install`
を実行。
Railsアプリの新規作成を再度行うと無事に作成できました。

### 環境
Windows10 home
[python] headless chromeのsend_keysでエラーが出た時の対処法

python seleniumでchromeをheadlessに動かしているとき、send_keysでエラーを吐いたので対処した方法を書きます。

chromeとchromedriver-binaryのバージョンを合わせたのにも関わらずsend_keysでエラーを吐きました。過去バージョンでは動いている記事もあったのですがなぜか動かない。このためだけにchromeのバージョンも下げるのは嫌なのでjavaを呼び出しました。

あくまで一例だと思いますの

```python:headlessじゃないとき
element = driver.find_element_by_name("password")
element.send_keys(""" password """)
```
これはnameタグでsend_keysを指定した方法です。これだとエラーを吐くので以下のようにしました。

```python:headless時
password = """ password """
driver.execute_script('document.getElementsByTagName("input")[3].value="%s";' % password)
```

name tagで"password"を指定するとエラーが起きたのでinputタグの4つ目を指定しています。

こんな感じでページ検証しながら合うところでdriver.execute_scriptを使用しjavaを動かすといいかもしれません。
SwiftでRealmを使用する方法について

#Realmをインストールする

Realmを使用するために、CocoaPodsを使用してインストールを行います。
PodFileに`pod 'RealmSwift'`を追記し、`pod install`でインストールします。

```
pod 'RealmSwift'
```

Swiftでは`import RealmSwift`でインポートします。

```
import RealmSwift
```

# モデル定義

`class モデル名: Object { }`でモデル定義を行います。
`@objc dynamic var`で、プロパティ定義を行います。


``` Swift:
import UIKit
import RealmSwift

class モデル名: Object {
    @objc dynamic var プロパティ名１ : 型名 = 初期値
    @objc dynamic var プロパティ名２ : 型名 = 初期値
}
```


# データの追加

`realm.add(モデル名(value: 値))`で、データを追加できます。
事前に、プロパティに対する値を入れている必要があります。

```
let realm = try! Realm()
        
let object = モデル名()
object.プロパティ名１ = 値１
object.プロパティ名２ = 値２

try! realm.write {
     realm.add(モデル名(value: object))
}
```

# データの更新
`.filter`等で対象のObjectを取得し、`write()`でデータの更新を行います。

```
let realm = try! Realm()

let results = realm.objects(dayList.self).filter("プロパティ名１ == 値１ AND プロパティ名２ == 値２").first

try! realm.write {
     results!.プロパティ名１ = 値３
}


```

# データの削除

`.filter`等で対象のObjectを取得し、`write()`でデータを削除を行います。
`.delete()`で対象のみ`deleteAll()`で全て削除します。


```

let realm = try! Realm()


let results = realm.objects(toDoList.self).filter("name == 'Michael Jeffrey Jordan'")

//
try! realm.write {
realm.delete(results)
}
```

# データが全くない場合初期値を追加する
データがない場合、データを読み込みに失敗します。
そのため、以下のようにして、データがない場合のみ初期値の追加をする必要があります。

```
let realm = try! Realm()

// データが１つもない場合
if realm.objects(モデル名().self).first == nil {
     let object = モデル名()
     object.プロパティ名１ = 値１
     object.プロパティ名２ = 値２

     try! realm.write {
          realm.add(モデル名(value: object))
     }
}
```

# モデルの変更をした場合
プロパティ名の追加等を行った場合、Realmの呼び出しでエラーになります。
そのため、変更があった場合スキーマの情報を更新させエラーが発生しないようにする必要があります。

```
// プロパティ名の変更があった場合、schemaVersionの値を変更する
let config = Realm.Configuration(
      schemaVersion: 1,
      migrationBlock: { migration, oldSchemaVersion in})
                
Realm.Configuration.defaultConfiguration = config
config = Realm.Configuration()
config.deleteRealmIfMigrationNeeded = true

```



# 参考
https://realm.io/jp/docs/swift/latest/
サーキットブレイカー？？？ってなんですの？

# はじめに
今お仕事させていただいてる場所でサーキットブレイカーの導入を任されたのですが、あまりにも知らなすぎていろいろ調べたので備忘録的にまとめます！

# サーキットブレイカーって？
簡単にいうと、、、

`マイクロサービス等でたくさんのクライアントからのリクエストを捌けずにエラーを返している時、そもそもサービスのリクエストそのものを遮断すること`

です。
もう少し具体的に表すと、、、
![スクリーンショット 2020-09-22 20.19.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/ee93dd53-0507-51f0-cf6d-76f20a85d95d.png)


この図のようにマイクロサービスを運用している時に特定のサーバが障害等の影響で動かなくなってしまった場合、動かないサーバに対してリクエストを送り続けてしまうとたくさんのリクエストがタイムアウトを待つということが起きてしまい、障害の影響範囲がさらに広がってしまいます。
そのような時に（特定のサーバに障害が起きていることがわかった時）そもそも障害を起こしているサーバに対するリクエストを送らずに自動的にエラーを返すようにすることで影響範囲を最小にするというデザインパターンの一つです。
![スクリーンショット 2020-09-22 20.26.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281558/3be9a2a0-bc07-ad34-3a78-cb67ad7cfa4a.png)

つまり

**「どうせエラーするんだったらリクエスト投げずにエラー返しちゃおうぜ！」**

みたいなそんな感じのノリだと思ってもらえるといいと思います。

# どうやって外部サーバが障害を起こしてることを検知するの？
ではどのようにして外部サーバが障害を起こしているのかを判別するのでしょうか？？？
実はそもそもサーキットブレイカーパターンには3つの状態が存在しています。
それは`Closed`・`Open`・`Half Open`の3つの状態です

| 状態名 | 内容 |
|-------|------|
| Close | 正常にリクエストが行われている状態 |
| Open | リクエストに対して正常にリクエストは送られず、固定でエラーを返している状態 |
| Half Open | Openの状態からCloseの状態に移行させるときの準備状態 |

（僕の感覚だとOpenが正常状態で、Closeが異常状態なのが普通な気がするんですが、、、まあ、おいておきますw）

そしてこの3つの状態があると知った上で考えると
`外部サーバが障害を起こしてることを検知する`->`Closeの状態からOpenの状態になる時の条件はなにか？`
というように言い換えることができます。
例えば、、、
「リクエストをを投げた時n回連続で特定のエラーが起きた時にOpen状態に移行させる」（n回の部分は要件によって変更）
ように設定することで、サーバの状態を管理します。

# どうやって設定するの？
設定する方法は大きく2つです
1, 外部リクエストを送っている箇所で各言語のライブラリなどを使って(goの場合は[gobreaker](https://github.com/sony/gobreaker)）サーキットブレイカーを実装する
2, [istio](https://istio.io/latest/docs/reference/config/networking/destination-rule/)などのサービスメッシュプラットフォームの機能を使用する

の２通りの実装があると思います。

# 終わりに
簡単にではありますが、サーキットブレイカーのまとめをさせてもらいました！
最近話題のマイクロサービスですが、サーキットブレイカーしかり、サービスメッシュしかり、分散トレーシングしかり、、、難しい単語が多すぎますよね汗

今後もマイクロサービスの流れは止まらないと思うので、個人としてもしっかりとキャッチアップをしていきたいですね
セキュリティのCIA

#【セキュリティのCIA】

セキュリティのCIAについて忘れないためにメモとして残します。

##セキュリティ

セキュリティには、機密性、完全性、可用性の３大要素がある。
クラウドコンピューティングでもセキュリティの対策が非常に重要である。

情報セキュリティについて、ISO/IEC27000で「情報の機密性、完全性、可用性を維持すること」と定義されている。

###・機密性（Confidentiality）

許された者だけが、情報にアクセスすることが可能な状態を確保すること。

対策）アイデンティティの認証、ディジタル暗号化、機密性の対策全般など。

###・完全性（Integrity）

破壊や改ざん、データ消去がされていない状態を確保すること。

対策）なりすまし防止対策、不正防止対策など。

###・可用性（Availability）

いつでも情報が中断などなく、データやシステムにアクセスできる状態を確保すること。

対策）ファイアウォールで不正な通信を遮断する、サーバへの攻撃に対する対策を立てるなど。
WordPressでS3に画像アップロードしてるけど画像の参照先はCDNにしたい

# はじめに
WordPressでこのプラグイン[^1]を用いてS3へ画像アップロードしてるのですが、負荷軽減のためCDNを介して配信するようにしています。
そのため、管理画面上や記事で使用する画像urlはその値にしたいと思います！

# 結論
書く場所はお任せしますが、どこかでdefineの値にCDNの配信URLを入れればOKです！

```php:config.php
/** CDNの配信URLである https://example.com に変更する. */
define('S3_UPLOADS_BUCKET_URL', 'https://example.com');
```

# 経緯
こちらの記事[^2]を参考にHerokuにWordPressを入れて、S3へのアップロードの設定をしてCDNの設定してから向き先を変えないとと思った次第です。

# こちらの記事[^2]を参考に作成している方へのオススメ解決法
## 1. CDN値を設定
以下のファイルに書くのがベストです。
https://github.com/PhilippHeuer/wordpress-heroku/blob/a534d98377574fd448fa7ebb9780186f4650a78a/config/plugins/wordpress/wordpress-s3uploads.php#L14

```php:config/plugins/wordpress/wordpress-s3uploads.php
if (!empty(getenv('AWS_S3_URL'))) {

    ...
    ...

    /**
     * CDNのURLがあれば変更する
     * @link https://github.com/humanmade/S3-Uploads#url-rewrites
     */
    if (getenv('AWS_S3_UPLOADS_BUCKET_URL') ?? '') {
        define('S3_UPLOADS_BUCKET_URL', getenv('AWS_S3_UPLOADS_BUCKET_URL'));
    }

} else {
    ...
    ...
}
```

## 2. Herokuに環境変数を設定
お好みの方法で設定してください。
### 設定方法1: Heroku管理画面にて

Herokuの管理画面 -> Settings Tab -> Reveal Config Vars にて設定。

- Key: AWS_S3_UPLOADS_BUCKET_URL
- Value: https://example.com

### 設定方法2: Terminalにて

下記コマンドを実行。

```
$ heroku config:set AWS_S3_UPLOADS_BUCKET_URL=https://example.com
```

# おわりに
無事にCDNへ向いてくれるようになりました。めでたしめでたし。



[^1]: [S3-Uploads](https://github.com/humanmade/S3-Uploads#url-rewrites)
[^2]: [驚くほど無料で一瞬でWordPressを用いたブログ環境を構築できた話](https://qiita.com/fuwamaki/items/8684003bb47197336645)
Ruby学習6

#演習で間違えた問題復習
現在、Ruby技術者認定試験silverを取得するべく勉強中です。
そろそろ試験なので、模擬試験で引っかかった部分を復習します。

##定数への破壊的メソッド
```ruby
HOGE = "hoge"
HOGE.gsub!("hoge", "piyo")
print HOGE
```
この出力結果に警告が出る（定数の変更が行われる為）と思ってが、違った。
警告文は、定数の「再代入」に対して行われるので、破壊的メソッドの呼び出しには警告なく値を変更できる。

##?を用いた文法

```ruby
p ?A
```
短いけど、なんだこれな文法。?の後の1文字を文字列で出力する。2文字以上書くとエラー。僕の脳では何に使うか全くわからない。

##クラスの継承

```ruby
class Hoge < Kernel ; end
```
これを実行するとエラーを吐くんですが、理由は、Kernelがモジュールだから。モジュールを継承するにはincludeを使う。

##to_iメソッド
```ruby
p "123abc".to_i
=> 123
```
文字列を整数にする、は理解してたものの、整数以外がある場合を把握していなかった。
整数以外が混ざっている場合、整数以外の1文字手前までを整数として出力する。
なので、"123abc123"to_iの場合でも出力するのは123。

##演算子||
```ruby
a = [1,2,3,4]
b = [1,3,5,7]

p a || b

=> [1,2,3,4]
```
出力が[1,2,3,4,5,7]だと思ったんですが、それは a | b　の場合。
a || b　の場合、aがtrueである時、bを評価せずにaを吐いて終わり。

##正規表現
```ruby
puts "0123456789-".delete("^13-56-")

=> 13456-
```
「deleteでマッチするのが1と、3から5と6と-だから、これを消せば良いのね、完全に理解した」←分かってない
正規表現に^が含まれたら「〇〇以外」になるので、上記にマッチした文字列「以外」を削除する。

##chrメソッド ordメソッド
```ruby
p 75.chr
p "K".ord

=> "K"
   75
```

chrメソッドは整数を文字コードとして文字変換
ordメソッドは逆に文字を文字コード対応の整数に変換

To_Be_Continued...
docker help 日本語訳

``docker help`` 実行時に表示されるドキュメントの日本語訳。

# 使用法:

```bash
docker [OPTIONS] COMMAND
```

自己完結型コンテナーランタイム

# オプション:

* --config string
  クライアント構成ファイルの場所(デフォルトは ``~/.docker`` )
* -c, --context string
  デーモンへの接続に使用するコンテキストの名前( ``DOCKER_HOST `` ``env`` ``var`` および ``docker context use`` で設定されたデフォルトのコンテキストをオーバーライドします)
* -D, -debug
  デバッグモードを有効にする
* -H, --host list
  接続するデーモンソケット
* -l, -log-level string
  ログレベルを設定します(デフォルトは ``info`` )
  * "debug"
  * "info"
  * "warn"
  * "error"
  * "fatal"
* --tls
  ``--tlsverify`` によって指定された TLS を使用します。
* --tlscacert string
  この CA のみが署名した信頼証明書(デフォルトは ``~/.docker/ca.pem`` )
* --tlscert string
  TLS 証明書ファイルへのパス(デフォルトは ``~/.docker/cert.pem`` )
* --tlskey string
  TLS キーファイルへのパス(デフォルトは ``~/.docker/key.pem`` )
* --tlsverify
  TLS を使用してリモートを確認する
* -v, --version
  バージョン情報を出力して終了

# 管理コマンド:

* app*
  Docker アプリケーション(Docker Inc., v0.8.0)
* builder
  ビルドを管理する
* buildx*
  BuildKit を使用してビルド(Docker Inc., v0.3.1-tp-docker)
* checkpoint
  チェックポイントを管理する
* config
  Docker 構成を管理する
* container
  コンテナを管理する
* context
  コンテキストを管理する
* image
  イメージを管理する
* manifest
  Docker イメージマニフェストとマニフェストリストを管理する
* network
  ネットワークを管理する
* node
  Swarm ノードを管理する
* plugin
  プラグインを管理する
* scan*
  Docker Scan(Docker Inc., v0.3.3)
* secret
  Docker シークレットを管理する
* service
  サービスを管理する
* stack
  Docker スタックを管理する
* swarm
  スウォームを管理する
* system
  Docker を管理する
* trust
  信頼する Docker イメージを管理する
* volume
  ボリュームを管理する

# コマンド:

* attach
  ローカルの標準入力、出力、およびエラーストリームを実行中のコンテナーにアタッチする
* [build](https://qiita.com/JhonnyBravo/items/87976fe9de47ed58b8b1)
  Dockerfile からイメージをビルドする
* commit
  変更を加えたコンテナーから新しいイメージを作成する
* cp
  コンテナーとローカルファイルシステム間でファイル / フォルダーをコピーする
* create
  新しいコンテナを作成する
* deploy
  新しいスタックをデプロイするか、既存のスタックを更新します
* diff
  コンテナーのファイルシステム上のファイルまたはディレクトリへの変更を検出する
* events
  サーバーからリアルタイムのイベントを取得する
* exec
  実行中のコンテナでコマンドを実行する
* export
  コンテナーのファイルシステムを tar アーカイブとしてエクスポートする
* history
  イメージの履歴を表示する
* images
  イメージを一覧表示する
* import
  tarball からコンテンツをインポートしてファイルシステムイメージを作成します
* info
  システム全体の情報を表示する
* inspect
  Docker オブジェクトに関する低レベルの情報を返す
* kill
  実行中の 1 つ以上のコンテナーを強制終了する
* load
  tar アーカイブまたは STDIN からイメージを読み込む
* login
  Docker レジストリにログインする
* logout
  Docker レジストリからログアウトする
* logs
  コンテナのログを取得する
* pause
  1 つ以上のコンテナ内のすべてのプロセスを一時停止します
* port
  コンテナのポートマッピングを一覧表示、またはポートマッピングを指定する。
* ps
  コンテナーの一覧表示
* pull
  レジストリからイメージまたはリポジトリを取得する
* push
  イメージまたはリポジトリをレジストリに登録する
* rename
  コンテナーの名前を変更する
* restart
  1 つ以上のコンテナを再起動します
* rm
  1 つ以上のコンテナーを削除する
* rmi
  1 つまたは複数のイメージを削除する
* [run](https://qiita.com/JhonnyBravo/items/eee5a91682f1d7c72f6e)
  新しいコンテナでコマンドを実行する
* save
  1 つ以上のイメージを tar アーカイブに保存します(デフォルトで STDOUT にストリーミングされます)
* search
  Docker Hub でイメージを検索する
* start
  停止している 1 つ以上のコンテナーを起動する
* stats
  コンテナのリソース使用状況統計のライブストリームを表示する
* stop
  実行中の 1 つ以上のコンテナーを停止する
* tag
  SOURCE_IMAGE を参照するタグ TARGET_IMAGE を作成します
* top
  コンテナの実行中のプロセスを表示する
* unpause
  1 つ以上のコンテナー内のすべてのプロセスの一時停止を解除します
* update
  1 つ以上のコンテナーの構成を更新する
* version
  Dockerの バージョン情報を表示する
* wait
  1 つ以上のコンテナーが停止するまでブロックし、その終了コードを出力します

コマンドの詳細については ``docker COMMAND --help`` を実行してください。
Elmのクラウド開発環境Ellieのショートカットキーまとめ

|  機能  | ショートカット  |
| ---- | ---- |
| Recompile | Ctrl+Shift+Enter |
| Package | Ctrl+Shift+p |
| Debug | Ctrl+Shift+d |
| Output | Ctrl+Shift+o |
| Settings | Ctrl+, |
| Reload Output | Ctrl+Shift+r |
| Logs | Ctrl+Shift+l |
| Save | Ctrl+s |  

ブラウザ等のショートカットキーと干渉している場合は動かないです

引用元: 
- https://github.com/ellie-app/ellie/issues/104
- https://github.com/ellie-app/ellie/blob/master/assets/src/Pages/Editor/Effects.elm#L360
pandasで2行目をカラム名にしたい

# pandasでのデータ読み込み時に困った
Excelシートを読み込む際に、1行目に邪魔な文字が入っていたので、カラム名が「Unnamed...」ばかりになった。

二行目からデータとして取得するためには、
1. 最初にデータを読み込み
2. データのカラム名を変更
といった処理が必要になりそうで、ダルイ。。

と思っていた矢先、先人の[Qiitaの記事](https://qiita.com/noca/items/966f4c5ae5eee8195fe0)を発見。
以下はその記事からの抜粋。

---
## 課題
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324917/21317914-5afb-8fd8-8018-61c9d5fd5554.png)

## 解決策
pandasの`skiprows`を使用して最初のいらない箇所をスキップしてExcelファイルを読み込む。


```python

df = pd.read_excel(excel_file_path, skiprows=2, header=[0, 1])
```
Mac の VirtualBox に Ubuntu Server 20.04 をインストールして SSH 接続する

# 環境

- Mac mini (macOS Catalina 10.15.6)
- Intel Core i7 3.2GHz, 32GB DDR4 
- VirtualBox 6.1.14
- Ubuntu Server 20.04.1 LTS

# 手順

## VirtualBox と Ubuntu Server のインストール
まずは VirtualBox をインストールする。

```
$ brew cask install virtualbox
```

次に、VirtualBox を起動して「新規」から仮想マシンを１つ新規作成する。仮想マシンの名前は「ubuntu-server-20.04」に設定。あとは、デフォルト設定のまま GUI をポチポチやるだけでいい。

「起動」アイコンを押して、あらかじめダウンロードしておいた [Ubuntu Server](https://jp.ubuntu.com/download) の iso ファイルを選択すると、インストールが始まる。

…と思ったのに、ここでコケた。
![スクリーンショット 2020-09-22 15.00.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/dd0743f5-d99c-5869-9879-7e6608be5a3f.png)
エラーは、
「/dev/loop2: Can't open blockdev」
「systemd[1]: Failed unmounting /cdrom.」

え？なんで？

何回試しても、この画面が出て仮想マシンが突如落ちる。
そして、次のようなエラーがポップアップされる。
![Screen Shot 2019-05-31 at 4.50.41 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/be336f02-ecf5-b180-1a7a-32bf7988ab16.png)
「You must specify a machine to start, using the command line....」

確かに Mac mini には DVD ドライブが付いてないから、unmounting でエラーが出るのかなァ……でも、仮想ドライブに iso ファイルを入れていて、実際にそこからインストーラが立ち上がってるわけだしなァ……などと考えながら、VirtualBox の GUI をあちこちいじっても直らず。

とりあえず、エラーの表示にしたがって、コマンドラインから仮想マシンを起動した。

```
$ VirtualBoxVM --startvm ubuntu-server-20.04 &
```

……なんかよく分からんけど、動いた。
正確には、先ほどの「Can't open blockdev」のエラーは表示されるが「unmounting」のエラーは出ず、そのままインストーラが走って、あっという間にインストール完了。
![スクリーンショット 2020-09-22 15.22.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667942/ef522d6f-70af-f339-fcc6-cab1e2d53b7b.png)
インストール後も、VirtualBox の「起動」ボタンを押してもうまく起動せず、コマンドラインからなら起動する。なぜそうなのかはいまだに分からない。

問題なく起動するから別にいいけど、理由が分からないのは気持ち悪いので、誰か教えてほしい。

## ポートフォワーディングの設定と SSH 接続
ホストOS（macOS）からゲストOS（Ubuntu Server）に SSH で接続するために、NAT のポートフォワーディング（IPマスカレード）を設定する。具体的には、ホスト OS の 2222 番ポートを通るパケットを、ゲスト OS の 22 番ポート（SSH ポート）に横流しするように設定する。

VirtualBox の「設定」→「ネットワーク」→「高度」→「ポートフォワーディング」を選択し、プロトコルに「TCP」、ホストポートに「2222」、ゲストポートに「22」を設定すればいい（名前は適当でいい）。

あるいは、以下のコマンドを叩いても設定できる。

```
$ VBoxManage modifyvm "ubuntu-server-20.04" --natpf1 "guestssh,tcp,,2222,,22"
```

そして、接続ポート 2222 を指定して SSH 接続する。

```
[hajime-f@borneo:~]$ ssh -p 2222 localhost
hajime-f@localhost's password:

...（中略）...

Last login: Tue Sep 22 09:49:22 2020
hajime-f@tonga:~$
```
無事に borneo から tonga に上陸できた（参考：[ホスト名に南の島の名前を付けるとおもしろいよ](https://qiita.com/hajime-f/items/2c10db500bc40d1f8e29)）。

たぶん、ホストとゲストで閉じたネットワークを構成するのではなくて、ゲストにアダプタを追加してプライベート IP を割り当て、```/etc/hosts``` で名前解決すれば、```$ ssh tonga``` で接続できるんだろうけど、面倒だからやめた。

同じ要領で、Ubuntu Server をもう一台セットアップして「bali」と名付けた。

この２台の仮想マシンを使って、次は Docker で遊んでみようと思う。
コマンドプロンプトでMySQLサーバーの起動やログインをする方法

<p>プログラミング学習の記録だよー:v_tone2:
<h2>MySQLサーバーの起動</h2>

まず、cmdを「管理者として実行」
黒い画面が出てきたら
MySQL server 8.0の場合：
--起動する
cmd>net start mySQL80

--停止する
cmd>net stop mySQL80

<h2>MySQLのログイン</h2>

今度は、「管理者として実行」じゃなくても良いですが、cmdを起動する

cmd>mysql -u(ユーザー名[例：root])　-p(パスワード)

ログアウトは

cmd>exit;

だけでOK～

以上だよお～
自分メモ～Excel：空白”でない”セルの数え方～

自分メモです、ピンポイントな内容です。
同じ悩みに直面したら参考いただけたらと。

### 背景
SQLの作成ツールをエクセルで自作したとき、
「入力のあった項目だけUPDATEする」
ということがしたかったのです。
そうすると先頭のカンマは
「自分より前の項目がすべて未入力の時だけつける」
としたかったのですが、その方法がうまくいかず。。。

### 結論
結果としては下記のようにしました（セル番号は例）
`IF(COUNTA($C$3:C7)-COUNTIF($C$3:C7,"")>0,",","")`

COUNTAで数式（UPDATE文の1項目を出しているセル）をカウントして、
COUNTIFの""で未入力（数式結果がブランク）との差を出して、
もし1件以上入力があった場合にカンマを出すようにしました。

### 試行錯誤
最初はCOUNTIFで楽勝と思って作業したのですが、
「ブランク以外」という条件がうまく指定できず断念。

ならばCOUNTAで一発じゃろと思ったら、
数式が入っているとブランクと判定されないらしく撃沈。

上手く複数範囲を一度に判定してくれる方法が見つからず、、、
結論の方法に至りました。


### 終わりに
何かの役に立てれば幸いです。
document.createElementより便利

忘れない内にメモ
今まで生のJSを使わないと行けない環境でDomをいじくり回したい時は

```javascript
var id = "hoge";
var text = "Lorem ipsum";
var header = document.createElement("h1");
header.setAttribute("id",id);
header.textContent = text;
// <h1 id="hoge">Lorem ipsum</h1>
```

とクッソ面倒な事をやってたけど

```javascript
var id = "hoge";
var text = "Lorem ipsum";
var parser = new DOMParser();
var temp = "<h1 id=" + id + ">" + text + "</h1>";
var doc = parser.parseFromString(temp, "text/html");
```

と簡潔に書けるらしい。

テンプレートリテラル使えるなら

```javascript
var id = "hoge";
var text = "Lorem ipsum";
var parser = new DOMParser();
var temp = `<h1 id="${id}">${text}</h1>`;
var doc = parser.parseFromString(temp, "text/html");
```

めっちゃ楽になる。
[競プロ] 累積和を利用したDPの高速化

競プロ初心者向け。
先日参加したAtcoderにて、DPの計算量を削減する方法を知り、とても感動したのでメモ。

## 問題
[Atcoder ABC 179 D-Leaping Tak](https://atcoder.jp/contests/abc179/tasks/abc179_d)
> 一列に並んだ Nマスから成るマス目があり、マスには左から順番に1,2,…,Nの番号がついています。
このマス目で暮らしている高橋君は、現在マス 1にいて、後述の方法で移動を繰り返してマスNへ行こうとしています。
10以下の整数 Kと、共通部分を持たないK個の区間 [L1,R1],[L2,R2],…,[LK,RK]
が与えられ、これらの区間の和集合をSとします。
ただし、区間 [l,r]は l以上 r以下の整数の集合を表します。

> - マスiにいるとき、Sから整数を 1つ選んで (dとする)、マス i+dに移動する。ただし、マス目の外に出るような移動を行ってはならない。

> 高橋君のために、マスNに行く方法の個数を 998244353で割った余りを求めてください。

## ナイーブな解き方
一見すると、以下のような単純なDPで解けそう！という風に見えます。

dp[i]: 位置iに到達する移動方法の数

```math
dp[i] = \sum_{s \in S}dp[i-s]
```

しかし、これだとdpテーブルの更新数(N) x Sの要素数(N) でN^2の計算量がかかってしまい、TLEエラーで通すことはできません。

## 高速化①
Sの要素が区間として与えられており、かつ区間同士で共通部分を持たないことに注目すると、
区間[Li, Ri]での移動はDP上のある区間の和と考えられます。
例: 区間[1, 5]の場合、 dp[i] = dp[i-1]+dp[i-2] + ... + dp[i-5]
これを利用すると、DPテーブルは下記のように書き換えられます。

```math
dp[i] = \sum_{lr \in S}\sum_{j \in [l,r]}(dp[i-j])
```
(lr:Sに含まれる一つの区間)

## 高速化②
高速化①で、区間和を愚直に求めようとするとやはり計算量Nのため、全体で計算量N^2のままです。そこで、累積和の考え方を使うことで、区間和の計算を高速化します。

累積和とは、数列上で最初の要素から特定の要素までの値を順々に足し合わせたもので、
累積和を利用することで、数列上の区間和を下記のように計算できます。

(数列Lのi~jまでの区間和) = ([jまでの累積和] - [iまでの累積和])

この方法によって、任意の区間和を定数時間で計算することができ、全体の計算量をNKに抑えることができます。
累積和をsdpで表すと、DPは下記のようになります。

```math
dp[i] = \sum_{lr \in S}(sdp[i-lr[r] - sdp[i-lr[l])
```

## 実装
pythonによる実装です。
dpの初期値(dp[0])は最初の場所へ行く方法の数なので1です。

```python
N, K = map(int, input().split())
LR = [list(map(int, input().split())) for _ in range(K)]
mod = 998244353

S = []
for k in range(K):
    for i in range(LR[k][0], LR[k][1] + 1):
        S.append(i)

dp = [0] * N # dpテーブル
sdp = [0] * (N+1) # dpテーブルの累積和

# DPの初期値を設定
dp[0] = 1
sdp[1] = 1

for n in range(1, N):
    for lr in LR:
        left = max(0, n - lr[1])
        right = max(0, n - lr[0] + 1)
        dp[n] += sdp[right] - sdp[left]
        dp[n] %= mod
    sdp[n+1] = (sdp[n] + dp[n]) % mod

res = dp[N-1]
print(res)
```

## まとめ
区間を利用したDPの計算と、累積和を利用した高速化という2つの概念が学べる良問でした。
D問題となると、単純なDPが実装できるだけではなく、計算量への意識が求められる、ということなのですね。
【Ruby】エラー文に出てくる例外クラスまとめ【NameErrorとかの意味 】

| エラー名 | エラー内容 |
|:-:|:-:|
|  NameError | 未定義のローカル変数/定数(又はprivateメソッド)とかを呼び出しちゃってる  |
| NoMethodError  | 存在しないメソッドを呼び出しちゃった時に発生  |
| TypeError  | 期待してたのと違う型(クラス)がメソッドの引数になってるよ！  |
| ArgumentError  | 引数の数・型が違う  |
| ZeroDivisionError  | 整数を0で割り算しようとしちゃった  |
| SystemStackError | システムスタックがあふれちゃてる。間違ってメソッド再帰呼び出しした場合など  |
| LoadError  |  requireやloadの実行に失敗したときに発生 |
| SyntaxError  | 構文エラー。 endない時とか  |
[UE4] OculusQuestでポストプロセスを使わないでビネット効果を再現してみる

# はじめに
VR酔いを軽減するために、ポストプロセスの[ビネット効果](https://docs.unrealengine.com/ja/Engine/Rendering/PostProcessEffects/Vignette/index.html)を使用して視野を制限したかったのですが、OulusQuestではパフォーマンス上の制約のため、ポストプロセスを使うのは厳しいです。
そこで、ポストプロセスを使用せずにビネット効果のようなものを疑似的に再現する方法を試してみました。
完成イメージは以下動画のような感じです。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ポストプロセスを使わずに疑似的にビネット効果を再現してみた <a href="https://t.co/dhSHy5TUjC">pic.twitter.com/dhSHy5TUjC</a></p>&mdash; 高浜 (@SatoshiTakahama) <a href="https://twitter.com/SatoshiTakahama/status/1308347232777691139?ref_src=twsrc%5Etfw">September 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 環境
Windows10
UnrealEngine 4.25.3

# 作り方
## マテリアルの作成
・コンテンツブラウザ上で、新規追加=>マテリアルを選択して生成し、名前をM_Vignetteに変更します。
・M_Vignetteの編集画面を起動し、マテリアルの設定を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/f6538526-96c8-2852-50a1-161227552024.png)
・M_Vignetteに以下のようにノードを追加します。中心を円状にくりぬいて、周囲をディザリングして中心から離れるほど濃くなるようにしています。DitherTemporalAAノードは、低コストで半透明っぽい効果を得られるのですが、自分のOulusQuest向け設定ではパフォーマンス優先のためTemporalAAは無効になっており、本来の効果は発揮できていません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/89b0bf7b-071b-7491-0a25-2601fecd7b46.png)

## パネルの作成
・プレイヤーのキャラクターのカメラの前面に、視野を制限するためのパネルを設置します。コンポーネントを追加からPlaneを選択し、カメラに追従するようにカメラの下に配置します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/6ed2702b-c05f-6c82-ad1d-5f71c1d4ad7d.png)
・パネルの位置と大きさは、動かしてみて適当な感じになるように調整します。マテリアルの所に、先ほど作成したM_Vignetteを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/7fe8777c-d48f-2399-9408-e3c3486e1e94.png)
・あとはキャラクターの動きに合わせてパネルの表示有効・無効を切り替えるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/7e5f9d00-6f8a-7d93-668a-52417eb1110d.png)

# 参考資料
・[第2回UE4勉強会 in 大阪 - マテリアル基礎・初級](https://www.slideshare.net/com044/ue4-80326829)
中心を円状にくりぬく方法、そのほかマテリアルの基礎知識について参考にさせていただきました。

・[[UE4] とりとめのないマテリアルネタ色々](http://monsho.blog63.fc2.com/blog-entry-148.html)
DitherTemporalAAについて参考にさせていただきました。
[UE4] ポストプロセスをBPから切り替える

# はじめに
BPからポストプロセスを動的に切り替える方法について、あまり情報が見当たらなかったので書いておきます。
UE4.25.3を使用しています。
今回の例では、キャラクターの移動中のみポストプロセスの[ビネット効果](https://docs.unrealengine.com/ja/Engine/Rendering/PostProcessEffects/Vignette/index.html)が効くようにしています。
ポストプロセスの切り替えは以下動画のような感じです。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ビネット効果で視野を制限することでVR酔いを軽減できるらしいので試してみたところ、FirstPersonCharacterの視点でも若干軽減されたような気がする<br>しかし、Mobile HDRを有効にしないとポストプロセスは効かないので、OculusQuestでは処理落ち発生してしまい使うのは厳しいかな <a href="https://t.co/pLKcRY3UVR">pic.twitter.com/pLKcRY3UVR</a></p>&mdash; 高浜 (@SatoshiTakahama) <a href="https://twitter.com/SatoshiTakahama/status/1307801522508460032?ref_src=twsrc%5Etfw">September 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 環境
Windows10
UnrealEngine 4.25.3

# 切り替える方法の例
以下はポストプロセスの有効・無効を切り替えている部分のBPの抜粋になります。
・処理の流れは、Camera => Get PostProcessSettings => PostProcessSettingsにメンバを設定 => Set PostProcessSettings
・"PostProcessSettingsにメンバを設定"ノードは、配置した後、右クリックでどの設定をピンに出すかを選ぶことで、任意のポストプロセスを設定することができます。今回はVignette Intensityを選択してビネット効果を切り替えています。
・画面上では"PostProcessSettingsにメンバを設定"ノードが2個ありますが、上側のノードは移動中にビネット効果を有効な設定に、下側はビネット効果を無効な設定にしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215278/30601ceb-2284-5f4d-dc37-95167bcf9541.png)