OmniAICreator/Qiita-1.07M huggingface dataset:
vimのVisualモードで文字列の挿入・置換

なんとなくviを使っているものの、ちょっと普段と違うことをしようとすると忘れて毎回調べるので、必要そうなコマンドの覚え書き。

# Visualモードで文字列の挿入・置換

Visualモードでこんな風に選択した場合の文字列操作の色々は以下。

![スクリーンショット 2021-03-18 23.46.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/7ffd96de-a3b0-8bb0-e773-5a175be704c3.png)

### 文字列の選択範囲の前後に任意の文字列挿入
Visualモードで範囲選択後、以下の操作で選択した行に対する文字列挿入が可能。

* 選択範囲の前に文字列挿入
`I<挿入文字列>ESC`で選択範囲の前に文字挿入ができる

* 選択範囲の後ろに文字列挿入
`A<挿入文字列>ESC`で選択範囲の後ろに文字挿入

### 文字列の先頭／最後に任意の文字列挿入
shellファイルで、ある行の先頭に`#`を挿入してコメントアウトしたい場合とか役にたつ。

* 選択範囲の先頭行に文字列挿入

`:normal I<任意の文字列>Return`で選択範囲の先頭に文字列が挿入される。Visualモードで一部分だけ選択しても、その行が対象となる。

* 選択範囲の行最後に文字列挿入

`:normal A<任意の文字列>Return`で選択範囲の行の最後に文字列が挿入される。

### 選択範囲の置換・削除
Visualモードで範囲選択後、選択した範囲の置換・削除の方法。

* 任意の文字列で各行を置換
`c<置換文字列>ESC`でOK。viで通常つかう`cw`のような動き。各行に対して実行される。

* 選択範囲を一つの文字で置換
`r<置換文字>`で選択範囲がすべて<置換文字>で置き換わる。これも通常のviの動きと同じ。

* 削除
`d`で選択範囲が全て削除される。
pandas 統計量

```python
import pandas as pd
import numpy as np
```

```
df = pd.DataFrame({
    "category1" : ["A","A","A","B","B","B"],
    "column1" : np.array([5,4,6,9,11,13])
})
```
![スクリーンショット 2021-03-19 0.11.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698282/2b6769de-624e-de49-7bf9-44faea0f9c7a.png)

# 統計量

```python
df.describe()
```
![スクリーンショット 2021-03-19 0.12.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698282/0c999d09-f386-7b90-3b5e-ff5c0eddfb2b.png)

column1はcategoryでAとBに別れているが区別なく統計量が出るのは不便。

# groupby関数
category A,B で区別して統計量を得る。

```python
# category1でgroupを作る
group = df.groupby("category1")
# groupごとに関数処理する
print(group.mean()) # 平均

print(group.std(ddof = 1)) # 標準偏差
```

![スクリーンショット 2021-03-19 0.19.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698282/f6315e52-7caf-d75b-c098-3abbcfc50f64.png)

```python
group.describe() # groupごとに統計量の一括表示
```

![スクリーンショット 2021-03-19 0.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698282/235114e3-9c55-f88a-4571-4cc1b822cb7a.png)

# 地道に取り出す
```python
# Aを取り出す
df_A = df[df["category1"] == "A"]
# mean関数に通す
df_A["column1"].mean()
```

groupby便利。
データベーススペシャリスト対策（SQLの基本構文）

SQL問題を自分の中に定着させるために、パターンごとの問い合わせをまとめます。
※随時更新

###予約語の例
DISTINCT：重複を排除して表示する
CURRENT_DATE：現在の日付を返す
CURRENT_TIME：現在の時刻を返す
CURRENT_TIMESTAMP：現在の日付と時刻を返す


#####TABLE：社員マスター（社員番号、社員名、性別、生年月日）
###データ操作言語の基本４つ

```SQL
SELECT * FROM 社員マスター
INSERT INTO 社員マスター VALUES('001','佐藤　正','男','19900410')
UPDATE 社員マスター SET 生年月日='19900411' WHERE 社員番号='001'
DELETE FROM 社員マスター WHERE 社員番号='001'
```

###SELECT文の文法

```SQL
--1990年生まれの社員を遅く生まれた順に並べて６番目～１５番目を表示する
SELECT * FROM 社員マスター
    WHERE 生年月日 LIKE '1990%'
ORDER BY 生年月日 DESC LIMIT 10 OFFSET 5

--1990年生まれの社員を性別ごとに分けて20人以上いる場合のみ人数を表示する
SELECT 性別,COUNT(*) FROM 社員マスター
    WHERE 生年月日 LIKE '1990%'
GROUP BY 性別
HAVING COUNT(*) >= 20
```

###データ定義言語の例

```SQL
--社員番号を主キーとして社員マスターを作成する
CREATE TABLE 社員マスター(
    社員番号 integer,社員名 text,性別 text,生年月日 date,
    PRIMARY KEY(社員番号))

--[ユーザー名]の人に社員マスターのSELECT文を実行する権限を与える
GRANT SELECT ON 社員マスター TO [ユーザー名]
```


##副問合せの例
主問合せから１行ずつ副問合せにいき処理をする。

###男女それぞれの最年長の人を除く全ての社員を取り出す
#####TABLE：社員（社員番号、社員名、性別、生年月日）

```SQL
select 社員番号,社員名 from 社員 as S1
       where 生年月日 > (select MIN(生年月日) from 社員 as S2
             where S1.性別 = S2.性別);
```

ポイント
・MIN(生年月日)で最年長の人の生年月日を取得している
　生年月日なのでMAXではなくMINであることに注意
・副問合せのwhere句で性別の条件を入れている
　最年長ではない男性（Aさんとします）の行においては、まず副問合せで性別が男性という条件のもので最年長の生年月日を出し、それを主問合せに渡します。この際に主問合せの条件（２行目のwhere 生年月日）で、男性の最年長の生年月日と比べて大きいので条件を満たし、Aさんの社員番号と社員名が取得されます。
　逆に最年長の男性（Bさんとします）は、副問合せで自分の生年月日が取得され、それと主問合せで(where 自分の生年月日 > 自分の生年月日)となるので条件を満たさず、Bさんのデータは取得されません。女性として考えても同様なので、これによって男女それぞれの最年長の社員が除かれてデータが取得されます。

###FE資格を取っている社員の中でAPも取得しているか否かを抽出する
#####TABLE:社員取得資格（社員コード、資格）

|  社員コード   |          資格 | 
|:-------------|--------------:|
| S001         |            FE | 
| S001         |            AP |  
| S001         |            DB |       
| S002         |            FE |      
| S002         |            SM |  
| S003         |            FE | 
| S004         |            AP | 
| S005         |           NULL| 

```SQL
select 社員コード,A.資格 as 資格１,B.資格 as 資格２ 
       from 社員取得資格 as A
       LEFT OTHER JOIN 社員取得資格 as B
            on  A.社員コード = B.社員コード and A.資格 = 'FE' and B.資格 = 'AP'
       where A.資格 = 'FE'
      ;
```
ポイント
・キーは（社員コード、資格）の複合キー
・１つの資格列の中にFEとAPの取得情報があるため、それらを分離して表示するために自己結合する必要があります。さらに、AP取得情報のみを表示したいので結合するテーブルに資格がAPである条件も必要です。

|  社員コード   |          資格１ | 　資格２
|:-------------|--------------:|----:|
| S001         |            FE | AP|
| S001         |            AP | NULL|
| S001         |            DB | NULL|      
| S002         |            FE | NULL|     
| S002         |            SM | NULL| 
| S003         |            FE | NULL|
| S004         |            AP | NULL|
| S005         |           NULL| NULL|

・左外部結合により、上記表のように結合される列はそのまま残るため、FEを取得しているという条件で抽出しなければならないので、where句で指定すると結果がでます。

|  社員コード   |          資格１ | 　資格２
|:-------------|--------------:|----:|
| S001         |            FE | AP|     
| S002         |            FE | NULL|     
| S003         |            FE | NULL|
Gatan DigitalMicrograph (GMS3) 導入

##DigitalMicrograph導入
Gatan の DigitalMicrograph (DM) を導入。
v3.43のfree license版(2021.3)
v3.4以降でpythonと連携できるようになったことは聞いていたが、それ以外にもかなり機能が追加されていそう。
インストール時にできたDocumentationフォルダには見たことがないpdfファイルが多数。
MSA (Multivariate Statistical Analysis) やそのscriptが可能になった模様。
ぱっと見た感じtemDMのほうが高機能に思える。

##DM関連ソフト
######Gatan公式
https://www.gatan.com/products/tem-analysis/gatan-microscopy-suite-software
######HyperSpy
DMでpythonが使えるようにはなったが、pythonを使うならとりあえずこっちで試してみる。
多数のファイルフォーマットに対応しているので、いったんHyperSpyで読み込みフォーマット変換した後DMで強引に開く荒業が可能。

https://hyperspy.org/

######temDM
PCA (Principle Component Analysis) をベースとしてGUIに優れた高機能MSAが可能。HyperSpy の Machine Learning ではできない free rotation がとても使える。
これだけ高機能で無償なのが信じられない。

http://temdm.com/web/

######NiermannのHDF5 plugin
temDMを使うのであれば入れておく。

https://github.com/niermann/gms_plugin_hdf5

##script
######D. R. G. Mitchell
自分でscriptを書く時の参考になる。
SI (Spectrum Imaging) のライセンスがないとき、ここの SITools のお世話になる。
他にも DiffTools 等、参考になるだけでなく実際に使えるplugin, scriptが多数。

http://www.dmscripting.com/

######FELMI-ZFE
汎用的なものから特定用途まで多数のscriptを公開。scriptを探すときはここか上記のD. Mitchell氏のサイトのほぼ2択。この2つに無いときは自分で作ることを考えたほうが良い。

https://www.felmi-zfe.at/dm-script/

######Gatan公式
チュートリアル的なscript集。python関係のサンプルscriptが増えている。
Crop image to selection が地味に便利なのでインストール。他にも便利なものがあるかも。

https://www.gatan.com/resources/scripts-library?field_script_type_value%5B%5D=digital_micrograph_gatan&sort_by=field_date_value&sort_by=field_date_value&sort_order=DESC&sort_order=DESC
ESP32でBluetooth Key bordで嵌った事　もろもろ

こんにちは。

他人のコードをコピーして、コマンドとかよくわからないまま、物を作っている私のような人に、
ちょっとでも役に立つのならと思い、自分が回避できた問題を記載していきたいと思う。

arduinoに関するトラブルは、ちょっとググれば同じような問題に直面している人が数多くいて
そうした問題の回避方法はかなりヒットするのだが、
今回の問題は、英語サイトも含めてほとんどヒットせず
自力でやれる事をやってみたので、記録として残します。
　　
ESP32-BLE-Keyboardをつかってiphoneに接続すると、文字入力が出来なくなる。（画面のキーボードが表示されなくなる）
これは、既知の仕様（問題）です。

なので、ESP32とのコネクションを一時的に切るなどをしたいが、そこで嵌った
https://github.com/T-vK/ESP32-BLE-Keyboard

ESP32-BLE-Keyboardで、bluetoothをスタートさせるには、サンプルにもあるとおり

bleKeyboard.begin();でスタートさせるが、　これに対して

bleKeyboard.end();という関数もあるが、まったくこれが機能しない。

それもそのはず、BleKeyboard.cppの中をみてみると

void BleKeyboard::end(void)
{
}

となっていて、何も入っていない。

　うーむ。　これは困った。

ということでいろいろと、どうすればいいのか、調べてみた。

まず、ESP32を使うようになって、aruduinoからとの大きな違いにマルチタスクという言葉が出てくる。Bluetoothやwifiなどは、
マルチタスクで動いているので、メインの関数とは別のところで動いている

それを管理しているのが、FreeRTOS　というものらしい

なので、bleKeyboard.begin();で起動させたタスクを、止めればいいという事になる。

FreeRTOS　によると、起動したタスクは、vTaskDelete(NULL);というコマンドで止めれるらしい

なので、
void BleKeyboard::end(void)
{
　vTaskDelete(NULL);
}

としてみたが、ダメだった。　これを呼ぶと、無応答になってしまう。

なぜ、無応答なのか調べていったら、

bleKeyboard.begin()という関数は、BleKeyboard::taskServerを呼んでいる

この関数の一番最後に、vTaskDelay(portMAX_DELAY); //delay(portMAX_DELAY);

というのがある。portMAX_DELAYが何を意味しているのか、ググってみたけど、全くヒット

しなかった。通常は、時間を入れるようなので、1000を入れたところ、１秒でこの関数は終了したが

リセットを繰り返すようになってしまった。

起動したタスクが正常に終了していないのが原因と思い先ほどの

　vTaskDelete(NULL);

を入れたところ、リセットされず、プログラムは終了した。

しかし、まだ問題があった。　

タスクを終了しても、iphoneは、まだ　bleKeyboardとつながったままだった。

BleKeyboard::taskServerの前半を見てみると

BLEDevice::init(bleKeyboardInstance->deviceName);

という関数があったので

BLEDevice::deinit();

対になるように、この関数を入れたところ、

無事iphoneから、ESP32を切り離す事ができた

　bluetoothを無事停止する方法はわかったので、

こちらの意図したタイミングで、bluetoothが切れるように

vTaskDelay(portMAX_DELAY);があったところを

  //vTaskDelay(portMAX_DELAY); //delay(portMAX_DELAY);
 
  while(digitalRead(2)){
  vTaskDelay(1000);
  }

  BLEDevice::deinit();
  vTaskDelete(NULL);

とした。

適当に空いているI/Oを使って、タスクに指示を送る方法にした。
これで、メインループでI/O　２番をHIGHにしておけば、
bluetoothはつながったままになり、
好きなタイミングで、２番をLOWにすれば、
マルチタスクは終了できるようになった

再びつなぎたくなったら、bleKeyboard.begin()を走らせればOK

ここにたどりつくのに丸3日かかった

なお、BleKeyboard.cpp内でdigitalReadを有効にするために、
Arduino.h>を　include する事

以上
Amazon Aurora とは

## 勉強前イメージ

RDSの中の1つでmysqlとpostgresqlに互換性があるやつ

## 調査

### Amazon Aurora とは

Amazon RDSで利用可能なエンジンのタイプの1つで
マネージド型のリレーショナルデータベースサービスになります。

以下はRDSの作成画面ですが、MySQLやPostgreSQLに並んでAuroraがあります。

![1RDS · AWS Console - Google Chrome 2021-03-16 23.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/928f286e-332a-0dea-30d5-e51c02d178f0.png)


AuroraはMySQLに互換性があるバージョン、PostgreSQLに互換性があるバージョンを選ぶことができ
それぞれ数倍高速にアクセスできると言われています。

![2RDS · AWS Console - Google Chrome 2021-03-16 23.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/74f9b857-e1a3-7a5a-fe69-d8e2bccbf50e.png)


### Auroraの特徴

- スループットと拡張性

標準的なMySQLの5倍のスループット・PostgreSQLの3倍のスループットを実現。
また、簡単にスケールアップ・スケールダウンも行うことが出来ます。

- ストレージシステムの拡張性

データベースインスタンスごとに最大128TBまで自動的にスケールされ
耐障害性と自己修復機能も兼ね揃えています。

- 可用性

最大15個のリードレプリカやポイントインタイムリカバリー、
またs3へのバックアップや3つのAZでのレプリなど可用性が高いです

### Auroraの機能

- Aurora マルチマスター

master側に関しても1つだけではなく、複数用意し
1台ノードが落ちたとしても稼働することが出来ます。

![1RDS · AWS Console - Google Chrome 2021-03-16 23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/c27544f8-e19d-f2de-642d-f4d2d2c5e0b3.png)


- Aurora サーバレス

処理負荷が一定ではないようなケースに対応した、自動的にスケーリングが行われます

![2RDS · AWS Console - Google Chrome 2021-03-16 23.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/89e984f3-3592-12f4-aa13-055934a7c4f0.png)

- Aurora グローバルDB

リードレプリカのみ別リージョンに構成することが出来ます。

## 勉強後イメージ

なんとなく知ってたつもりでいたけど、
グローバルDBとかサーバレスとか機能を知らなかった。

## 参考

- [Amazon Aurora](https://aws.amazon.com/jp/rds/aurora/?aurora-whats-new.sort-by=item.additionalFields.postDateTime&aurora-whats-new.sort-order=desc)
- [Amazon Auroraデータベースの特徴](https://business.ntt-east.co.jp/content/cloudsolution/column-71.html)
- [【AWS】Amazon Auroraの特徴と長短を知る](https://www.acrovision.jp/service/aws/?p=1860)
7章でミスったところ振り返っておく

##経緯
６章以降から記事を1日でまとめられる量ではなくなってきたので
まとめ記事はネタ切れの時に復習用で作成していこうと思う。（自分の為にも必ず載せておきたい）
今回は、herokuにデプロイした後に気づいてしまったミスを再発防止のため
書いておこうと思う。

##当時
ユーザ登録機能量多いな。。
お、なんやかんや6時間くらいかかったけどおわったやん、
よし、ささっとadd commit merge pushして復習しよ。
![スクリーンショット 2021-03-18 23.38.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1188411/9be04fce-705f-2a5a-d9e5-b342e859f903.png)

herokuデプロイ後、ログインできるか確認してみる。

やべぇ、flashおかわりしてる。

![スクリーンショット 2021-03-18 23.54.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1188411/3e960744-1766-9a44-03c4-e64def41c7a0.png)

``app/views/layouts/application.html.erb``
速攻で修正
![スクリーンショット 2021-03-19 0.00.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1188411/0a82191e-91df-e4c7-71e4-ca26929a743f.png)
再びadd commit merge push


原因
rails testがうまく通れば大丈夫かーと慢心したこと。

##まとめ
些細なミスかもしれないが、チュートリアルでミスしといててよかった。今後の教訓にしようと誓う。

※未来の自分へ
最後くらいちゃんとブラウザでも確認しきりましょう。
Docker で binding.pry などの標準入力を "簡単に" 行う方法

# はじめに
Docker でアプリケーションのコンテナを起動中に `binding.pry` などのデバッガ (標準入力) を受け付けるようにする方法は調べるとすぐに出てきます。

```diff:docker-compose.yml
+ stdin_open: true
+ tty: true
```

```shell:shell
$ docker-compose up -d
$ docker ps                    # loop up the corresponding container ID
$ docker attach <CONTAINER_ID>
```

https://qiita.com/hb5kz/items/7c9d266480079910de5c

しかし、毎回コンテナ ID を調べるのは面倒なので、上記 3 つのコマンドを一発で実行するスクリプトを作ったので紹介します。

# スクリプトの設置
以下のスクリプトを `docker-server` というファイル名で保存し、パスが通っている場所に置きます。

```shell:docker-server
#!/bin/sh

docker-compose up -d
echo

# this must be executed after "docker-compose up -d"
# avoid making "docker ps" executed over and over again
DOCKER_PS=$(docker ps)

select_container() {
  echo "$DOCKER_PS" | fzf --tac --exact --no-sort | awk '{print $1}'
}

if [ -n "$1" ]; then
  if [ "$(echo "$DOCKER_PS" | awk '{print $2}' | grep -c $1)" -eq 0 ]; then
    echo "No such container"
    echo "Select a container manually after a few seconds..."
    echo
    sleep 2
    container_id=$(select_container $1)
  elif [ "$(echo "$DOCKER_PS" | awk '{print $2}' | grep -c $1)" -ge 2 ]; then
    echo "Too many containers found"
    echo "Select a container manually after a few seconds..."
    echo
    sleep 2
    container_id=$(select_container $1)
  else
    while read line
    do
      image=$(echo $line | awk '{print $2}' | grep $1)

      if [ -n "$image" ]; then
        container_id=$(echo $line | awk '{print $1}')
      fi
    done <<< "$(echo "$DOCKER_PS")"
  fi
else
  container_id=$(select_container $1)
fi

if [ -z "$container_id" ]; then
  echo "Canceled" >&2
  exit 1
elif [[ ! "$container_id" =~ ^[0-9a-f]+$ ]]; then
  echo "Error: Invalid container ID" >&2
  exit 2
fi

echo "Selected container info:"
echo "$DOCKER_PS" | head -1
echo "$DOCKER_PS" | grep $container_id
echo
echo "Attaching container $container_id"
echo

docker attach $container_id
```

https://github.com/noraworld/dotfiles/blob/cc2b8d8dc223f52dab7a5a16094031d68720802e/bin/src/general/docker-server

上記スクリプトに実行権限を与えます。

```shell:shell
$ chmod +x /path/to/docker-server
```

# 使い方
使い方は簡単です。

```shell:shell
$ docker-server
```

引数を与えなければ、fzf が起動し、Docker のコンテナ一覧が表示されます。アプリケーションのコンテナを選択し、エンターを押すと、そのコンテナを attach できます。

⚠ 事前に fzf のインストールが必要です。以下でインストールできます。

```shell:shell
$ brew install fzf        # macOS
$ sudo apt -y install fzf # Ubuntu
```

```shell:shell
$ docker-server app
```

引数としてイメージの名前の一部を与えて、一意にコンテナが定まれば fzf での選択を省略できます。上記の例ではイメージの名前に `app` が含まれていることを想定しています。

`Dockerfile` や `docker-compose.yml` の中身を編集しない限りはイメージ名が変わることはないと思うので、特定のプロジェクトで使用する場合はイメージ名さえ覚えておけば毎回コンテナを選択する必要もありません。

# コンテナの終了と detach
コンテナを終了する場合は `Ctrl+C` を押します。

コンテナを終了させずに、attach した Docker のコンテナから抜けたい場合 (detach したい場合) は、`Ctrl+P` を押した後、`Ctrl+Q` を押します。

あとでまた使う場合は `Ctrl+P` + `Ctrl+Q` で detach し、しばらく使わない場合は `Ctrl+C` でコンテナを終了させておくと良いでしょう。

# さいごに
これで Docker コンテナを起動するときにいちいちコンテナ名を調べなくても attach できるようになりました。

開発中は `binding.pry` などのデバッガをよく使うと思うので、基本的には `docker-compose up` ではなく `docker-server` を使うようにします。
とりあえず React + TypeScript で適当なサンプルページを作りたい ④

### これまで
前回
https://qiita.com/KennyKTA/items/a994a88107faa50c3548
前々回
https://qiita.com/KennyKTA/items/9e240cd90ecb86ea3ee5
前々々回
https://qiita.com/KennyKTA/items/c05c5047953777eeb5c4

### 今回やること

- React + Boot Strap によるグリッドシステムの実装を行う。（今回は絶対に、だ）

### 今回やらないこと

- 今のところ特になし

### 開発内容

ちょっとした技術的な不明点が出ている。設計段階では複数行にまたがる列があるのだが、これを実現する方法が見つかっていないのだ。初回で実施した設計上でいうと、オレンジのところが実現しにくい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626166/f2d733b8-9f9d-0fc7-585a-a95135d6cf21.png)

例えば、これらを分割して、こんな感じにしてしまえば今すぐにでも実装することができる。行内の列のサイズ指定を実施していって、行間での各breakpoint の数値の合計を同じにしていけばよいからだ。だが明らかにおかしいので別の方針を練る。@21/03/19
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626166/67c994e6-3b2e-62d6-0207-6d438fecffc2.png)

ちょっと試してみたらColコンポーネントの中にRowを複数配置することレイアウト可能だった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626166/64bc5afa-9fa1-4ea7-9279-bf950759224e.png)

これでデザインやサイズを加味しなければ論理的な配置は実装可能になるのでやってみよう。@21/03/22
あと、しょうもないけど、css のインポートを忘れてclassNameの指定が有効にならずに若干嵌ったので以降気を付けよう。

```App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
import { LanguageServiceMode } from 'typescript';
import { Button,Container,Row,Col,Card} from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

function App() {
  return (
    <Container className="block-example border border-dark">
      <Row className="block-example border border-dark">
        <Col className="block-example border border-dark">
          <Row className="block-example border border-dark">
            Row1 in Col1
          </Row>
          <Row className="block-example border border-dark">
            Row2 in Col1
          </Row>
        </Col>
        <Col className="block-example border border-dark">Col2</Col>
      </Row>
    </Container>
  );
}

export default App;
```


なんていうか、設計が実装しにくすぎだったのでもう少し簡素にした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626166/e85f542b-5aab-9a96-7262-239302965534.png)

```App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';
import { LanguageServiceMode } from 'typescript';
import { Button,Container,Row,Col,Card} from 'react-bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

function App() {
  const bdr: string = "block-example border border-dark";
  return (
    <Container className={bdr}>
      <Row className={bdr} id={"R0"}>
        <Col className={bdr} id={"C0-1"} md={1}>logo</Col>
        <Col className={bdr} id={"C0-2"}>search</Col>
      </Row>
      <Row className={bdr} id={"R1"}>
        <Col className={bdr} id={"C1-1"} md={1}>info</Col>
        <Col className={bdr} id={"C1-2"}>Body</Col>
        <Col className={bdr} id={"C1-3"} md={2}>
          <Row className={bdr} id={"C1-3_R0"}>ad</Row>
          <Row className={bdr} id={"C1-3_R1"}>cont</Row>
        </Col>
      </Row>
      <Row className={bdr} id={"R2"}>
        <Col> footer </Col>
      </Row>
    </Container>
  );
}
export default App;
```

これでBodyやinfoが記述されている部分をRow で分割していけば最初に求めていた形が実装可能だ。
とりあえずレイアウトに関してはやりたいことができるようになったので、いったんここまでにしようと思う。
RustのDieselでPostgresのMACADDR型を使う

# はじめに
最近、RustのDieselを使い始めました。
DieselはPostgres/MySQL/SQLiteに接続することができます。
今回、PostgresのMACADDR型を使う際に躓いたので、解決策を備忘録的に残しておきます。

# 困ったこと
以下のようにMACADDRを使うスキーマとモデルを定義しました。

```rust:up.sql
CREATE TABLE machines (
  id SERIAL PRIMARY KEY,
  name VARCHAR(20) NOT NULL,
  mac_address MACADDR NOT NULL,
  status_id INTEGER NOT NULL,
  create_at timestamptz NOT NULL DEFAULT current_timestamp,
  update_at timestamptz NOT NULL DEFAULT current_timestamp
);
```

```rust:model.rs
#[derive(Debug, Queryable)]
pub struct Machine {
    pub id: i32,
    pub name: String,
    pub mac_address: [u8; 6],
    pub status_id: i32,
    pub create_at: chrono::NaiveDateTime,
    pub update_at: chrono::NaiveDateTime,
}
```

全件SELECTする処理を書いて実行すると...

```rust
let machines = machines_schema::dsl::machines
    .load::<Machine>(&connection)
    .expect("Error loading machines");
for machine in &machines {
    println!("{:?}", machine);
}
```

```bash
$ cargo run
・
・
error[E0277]: the trait bound `[u8; 6]: Queryable<MacAddr, Pg>` is not satisfied
  --> src/main.rs:66:10
   |
66 |         .load::<Machine>(&connection)
   |          ^^^^ the trait `Queryable<MacAddr, Pg>` is not implemented for `[u8; 6]`
```

モデルにパースする際、MACADDRを[u8; 6]に変換する実装がない、というエラーです。
[Reference](https://docs.rs/diesel/1.4.6/diesel/pg/types/sql_types/struct.MacAddr.html)を見ると[u8; 6]への変換で正しそうです。

# 解決策
RustのDieselはfeaturesを指定することで使えるようになる機能があります。
例えば、timestamp等の時間に関わるものであれば「chrono」を追加する必要があります。

```toml:Cargo.toml
・
・

[dependencies]
diesel = { version = "1.4.6", features = ["postgres", "chrono"], default-features = false }
```

ネットワーク系も同様にfeatures「network-address」を追加する必要がありました。
（DieselのGitHubの[Cargo.toml](https://github.com/diesel-rs/diesel/blob/master/diesel/Cargo.toml)に一覧があるのでここから探しました...）

```toml:Cargo.toml
・
・

[dependencies]
diesel = { version = "1.4.6", features = ["postgres", "chrono", "network-address"], default-features = false }
```

これでもう1度動作させると、無事SELECTできました。

```bash
Machine { id: 1, name: "machineC", mac_address: [82, 66, 0, 26, 169, 68], status_id: 1, create_at: 2021-03-18T14:01:48.632112, update_at: 2021-03-18T14:01:48.632112 }
Machine { id: 3, name: "machineA", mac_address: [82, 66, 0, 26, 169, 68], status_id: 1, create_at: 2021-03-18T14:53:06.281686, update_at: 2021-03-18T14:53:06.281686 }
Machine { id: 4, name: "machineB", mac_address: [82, 66, 0, 26, 169, 69], status_id: 1, create_at: 2021-03-18T14:53:06.281686, update_at: 2021-03-18T14:53:06.281686 }
```

# まとめ
Dieselで「～ is not implemented for ～」というエラーが出た際はfeaturesを確認してみると良いよというお話でした。
機能を選択させることでCrateを軽くする設計でしょうね（必要なものだけ選択する）。

PS）
この記事を書く際に[Reference](https://docs.rs/diesel/1.4.6/diesel/pg/types/sql_types/struct.MacAddr.html)を見ていたら、先頭に「The MACADDR SQL type. This type can only be used with feature = "network-address"」と記載がありました...
Referenceはちゃんと読まないとだめですね。
RepaintngされているところをPaint flashingで見つけようの巻（Webの表示速度を意識する2）

#今読んでいる本。
[Webフロントエンド ハイパフォーマンス チューニング](https://www.amazon.co.jp/dp/B0728K5JZV/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)

気になったところをまとめていきたいと思い書きます。（前回からだいぶ空いてるけども）その2。
1回目：[idle速度の改善（Webの表示速度を意識する1)](https://qiita.com/naokikobashi/items/55b9d643f88215a656aa)
ーーーーーーーーーーーーーーーーーーー

最近はお仕事でマークアップをする時間がかなりあり、まだまだ速度とかには意識が向けていないレベルではありますが、少しずつ読んだり最初から読み返したりしてます！


##Repaintngとは？
webサイトの描画の過程の1部。
Loading、Scripting、Rendering、Paintingなどの、諸々を経てようやく描画をします。
さらに最後のpaintingの中で、特定の条件により再描画（repanting）が発生します。
例えばjsなどでstyleを再調整した場合など。
対象のstyleはcolorやbackground系、resizeなどなど。
またはpaintingの前段階のRenderngの中のlayoutが実行された場合も、その後段階のpaintingは再度実行されます。（いずれlayoutについてもまとめたい！）

で、repaintingが引き起こされると、そのあとの処理も再度実行されます。
= > こういうことが繰り返されると、webのパフォーマンスが落ちる要因となる場合があります。


##Paint flashing
そんなときにRepaintingを引き起こしている部分を調べるツール
として、Paint flashingという機能がChromeの設定の一つとして存在しています。


クロームの開発モードを開き、下の方のタブ「Renderng」から「Paint flashing」にチェックを入れます。
![スクリーンショット 2021-03-18 23.34.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287983/5c038a6f-cbad-e909-e94a-302f61fe4008.png)

その上でweb画面を操作してみます。
例えば　yahoo!japan。
https://www.yahoo.co.jp/
ブラウザのサイズを変更したり、マウスオーバー時に緑の枠ができる部分がrepaintingを行っているところのようです！

他のサイトでも、スクロール時に動きがひょいっと起こるようなコンテンツ、
アニメーションなどでも謙虚にわかります。
例えばgoogleのパフォーマンスチェックページなど。
https://googlechrome.github.io/devtools-samples/jank/
動いている四角形に常に緑枠が出ています。

今時はどんなサイトでも多少は緑枠はあると思われますが、
パフォーマンスを見直したい時の手掛かりになるとおもいます！
【SAP Data Warehouse Cloud】オンプレ OracleDBへの接続手順 ~その３~

当シリーズの締め。

https://qiita.com/sebastian85/items/7938850dc5546d7be3e2

https://qiita.com/sebastian85/items/914e7d03aaa863521334

Step.6~7やっていきます。

| Step.| 内容 |
|:-:|:-|
| 1 | DP Agentの入手  |
| 2 |  DP Agentのインストール |
| 3 |  IP許可リストの登録 |
| 4 |  DP Agentの設定 |
| 5 |  サードパーティのドライバアップロード |
| 6 |  DP Agentの疎通確認 |
| 7 |  データベースへの接続 |

# Step.6 DP Agentの疎通確認

前回までの手順が上手くいけば、DWCがオンプレ側のDP Agentを認識します。（パネルに「CONNECTED」と表示）
「…」ボタン→「編集」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/e8d48dd0-9c3b-38cb-29eb-f2e99d3cf267.png)

「OracleLogReaderAdapter」にチェックを入れ、「保存」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/f536290c-0904-aa4f-8492-f75f857d4356.png)

エージェントアダプタを有効にしようとしたところ、エラーが発生。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/6586f3be-564d-7170-0b75-549e72471a79.png)

JVMバージョンがojdbcファイルで機能していない可能性あり。　

対応方法としてDP Agentをインストールしたサーバにて、
「C:\usr\sap\dataprovagent\lib」フォルダへ「ojdbc8.jar」を入れます。（ojdbc8.jarはOracleからダウンロードする）

その後、DP Agentを再起動する。
するとエージェントアダプタ（OracleLogReaderAdapter）が有効になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/2e24dd1c-de8d-fc5e-b72a-602800fefdc3.png)



# Step.7 データベースへの接続

いよいよDWCからオンプレのOracleDBへ接続です。

DWCの「スペース管理」から「接続」セクションへ移動します。
「ローカル接続」にて「+」アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/1c61f0ac-ef89-8b3a-26d4-a31be859d190.png)


接続の作成ダイアログが開きます。
接続タイプで「Oracle」アイコンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/6882ca54-7267-00dd-736c-b8d99999b034.png)

任意のビジネス名と技術名を入力します。
データプロビジョニングエージェントは「Step4.DP Agentの設定」で設定した名前を選択します。

「次のステップ」ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/a471972e-2c36-3842-3770-cae8eea9cb53.png)


データベースへの接続情報を入力します。
ここではOracleDBの「tech1008」スキーマへ接続する情報を入力します。
（※スキーマ名は必ず大文字で入力してください。小文字だと接続できません。）

「接続を作成」ボタンをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/437f8dd9-4b6b-d662-9478-2cbe233d88df.png)


作成した接続情報を選択して、「接続をチェック」アイコンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/24d0eb53-39cb-439f-784d-adcda891716f.png)



警告となっていますが、接続が有効であることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/f935afc6-0303-9dce-fec4-3163894da9ea.png)



いよいよ最後の手順になります。

まずは確認。こちらはSQL Developerで見てるOracle側のテーブル。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/c3d57166-d514-2abb-263a-06b966f25682.png)




DWCにてデータビルダから「新しいグラフィックビュー」を開いて「ソース」を見ると、
OracleDBへの接続名が表示されます。（ちょっと感動）

接続名→ユーザ名→「Tables」の順に展開すると、OracleDB側にあるテーブル名が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/84561ec2-65f9-d410-9a93-b7416ddf62a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1064296/8db13bef-ec0e-1cac-04b9-668e539e8e8f.png)

あとはテーブルをキャンバスへドラッグ＆ドロップするとインポート・デプロイできるので、
リモートテーブルとして利用できます。（複製してもいいですね）

長かった。
お疲れ様です。
Nuxtで算出プロパティ（Computed）が更新されない問題

# どういうこと…？

Nuxt使ってる時点で、そのリアクタビリティにあぐらをかいている私たちは、時折[算出プロパティ（computed）](https://jp.vuejs.org/v2/guide/computed.html)が一向に更新されない事態に出くわし、途方にくれることがあります。

今回もそうでした。firestoreで既存コメントのアップデートをリッスンしていた私は、返り値を配列にぶっこんでも更新されないことに気が付きました。

ちょっと雑に再現しますが、こんな感じ。

```js
export default {
  data() {
    return {
      comments: [],
    },
  },
  computed: {
    filteredComments() {
      return this.comments.filter(c => !c.hidden);
    }
  },
  created() {
    this.comments = await getComments();
    firestore.collection('activities').doc('comment:update').onSnapshot({
      next: (snapshot) => {
        const data = snapshot.data();
        const index = _.findIndex(this.comments, c => c.id === data.id);
        this.comments[index] = data;
      }
    });
  }
}
```

「またか…」と溜息をついた私は、本腰入れて解決法を探りました。

# 変更が検知されてないね

で、わかったことは、Nuxt（Vue）側で、この変更を検知してないということでした。`watch`入れて見てみようが、`this.filteredComments`にセッターを定義して、改めて明示的に値をセットしようがダメ。

ただ、プロパティを直で入れてみると検知されます。だから、こんな感じにすれば大丈夫。

```js
this.comments[index].hidden = data.hidden;
```

でも、これだとプロパティが変わった時とかいちいち手を入れなければいけなくてバグの温床技術負債となること待ったなしなので、ひとまずこうしてみた。動いた。

```js
Object.keys(data).map(key => {
  this.comments[index][key] = data[key];
})
```

でも、これ、ちょっと信じがたいほどダサい。2021年に書くコードではない。そこで、きちんとドキュメントに当たりはじめました。

# 解決！

基本、ここに書いてあるとおりでした。

https://qiita.com/bobu_web/items/ec5a98d03758d12ad721

[Vueのドキュメントに詳細があって](https://jp.vuejs.org/v2/guide/reactivity.html#%E9%85%8D%E5%88%97%E3%81%AB%E9%96%A2%E3%81%97%E3%81%A6)、要するに、**「インデックスと一緒にアイテムを直接セットする場合」**は更新がリアクティブに検知されないのですね。

なので、`$set`を使って、このように実装してやりましょう。

```js
this.$set(this.comments, index, data);
```

見事解決です。みなさん、良いVueライフを。
「jQueryを使用した九九表の作成」を参考にWolframAlphaとSymPy Liveでやってみたい。

(オリジナルポスト)
https://qiita.com/toshiki6829/items/233ca8d8953979b7e3e6

#wikipediaで
https://ja.wikipedia.org/wiki/%E4%B9%9D%E4%B9%9D


#WolframAlphaで
https://ja.wolframalpha.com/input/?i=九九

#SymPy Liveで
(参考)
https://ja.stackoverflow.com/questions/71580/python-ver-3-9-で９ｘ９の2次元配列-リスト-を作って-そこに九九の表を格納し-格納後-表示したいのですが妙な結果が得られます


#numpy.ufunc.outerをみつけました。2021-03-24
(参考)九九の表を作成<numpy.ufunc.outer()<[NumPy] ユニバーサル関数
https://python.atelierkobato.com/universal/#outline__4_1
git push heroku main時のエラー

laravelで制作したものをherokuでデプロイしようと思い、git push heroku mainコマンドを実行した時のエラーを記載します。

````
remote:          In order to use the Auth::routes() method, please install the laravel/ui pa  
remote:          ckage.                                                                       
remote:                                                                                       
remote:        
remote:        Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1
remote:  !     WARNING: A post-autoload-dump script terminated with an error
remote: 
remote:  !     ERROR: Dependency installation failed!
remote:  !     
remote:  !     The 'composer install' process failed with an error. The cause
remote:  !     may be the download or installation of packages, or a pre- or
remote:  !     post-install hook (e.g. a 'post-install-cmd' item in 'scripts')
remote:  !     in your 'composer.json'.

````

最初は、ERROR: Dependency installation failed!という部分を注視していたのですが、解決できずにもう一度エラー文を見ていたら、その上に、please install the laravel/ui packageと書いてあるところを発見しました。
なので、下記コマンドを実行したら、エラーが解決しました。

````
composer require laravel/ui
````
A5:SQL Mk-2でMysqlのtriggerを設定しようとしたらエラーが発生

#はじめに

A5:SQL Mk-2をtriggerを設定しようとしたらエラーが発生した。
(結論として『delimiter 』がある場合は、実行できません)

#tigger設定
以下のtiggerを設定。

delimiter //
CREATE TRIGGER update_trigger_name AFTER
UPDATE
ON table_name FOR EACH ROW
BEGIN
    IF NEW.type <> OLD.type THEN
        INSERT INTO histories(id, update_date, type)
        VALUES (NEW.id, date(now()), NEW.type)
        ON DUPLICATE KEY UPDATE type = NEW.type;
    END IF;
END;//
delimiter ;

エラーが発生。
調べてみると、Mysqlのdelimiterは対応していないとのこと。
https://twitter.com/m_matsubara/status/1191378519370022914

結論：delimiterは使用したい場合は、コマンドで設定しましょう。

#おわり

A5:SQL Mk-2はプロジェクトでも大変お世話になっているので、
『delimiter』が使用できなくても使わせて頂きます。
便利なツールを無料で使わせて頂いて大変感謝しています。
[Rails] サイトマップを作成する

#サイトマップとは
サイトマップとは、サイト全体のページ構成を一覧でまとめてみれるページのことです。
サイトマップを作成することでユーザーや検索エンジンにサイトの内容をわかりやすく伝える役割を持ち、SEO対策にもなります。

#gemを導入する
今回は、 `sitemap_generator` を使っていきます。
`Gemfile` に以下を追記して `bundle install` をします。

```:Gemfile
gem 'sitemap_generator'
```

#サイトマップの設定ファイルを作成する
以下を実行すると、`config/sitemap.rb` に設定ファイルが作成されます。

```
$ bundle exec rails sitemap:install
```

以下を実行すると、`public/sitemap.xml.gz` が作成されます。

```
$ bundle exec rails sitemap:create
```

サイトマップはサイズが大きくなりやすいので `sitemap.xml.gz` はgit管理から外しておきます。

```:gitignore
# Ignore sitemap file
public/sitemap.xml.gz
```

##サイトマップの設定をする
先ほど作成した、 `config/sitemap.rb` にサイトマップとして生成したい内容を書いていきます。
addメソッドを使ってサイトマップに追加するページを指定していきます。（`root_path` はデフォルトで追加されています。）
[オプションの確認（github）](https://github.com/kjvarga/sitemap_generator)

```:config/sitemap.rb
SitemapGenerator::Sitemap.create do
  add '/home', :changefreq => 'daily', :priority => 0.9
  add '/contact_us', :changefreq => 'weekly'
end
SitemapGenerator::Sitemap.ping_search_engines
```

このままでは設定ファイルができただけなので、サイトマップの作成をするために以下のコマンドを実行します。
また、サイトマップの更新の際にも同じコマンドを実行します。

```
$ rails sitemap:refresh
```

#サイトマップの自動更新をする
サイトマップは定期的に更新する必要があるので自動更新されるようにします。
`gemfile` に以下を追記して `bundle install` をします。

```:Gemfile
gem 'whenever', require: false
```

次に、 `config/schedule.rb` を作成し、定期実行したい内容を書いていきます。
以下の例では毎日 `am3:00` にサイトマップの更新を実行する設定をしました。

```:config/schedule.rb
every 1.day, at: '3:00 am' do
  rake 'sitemap:refresh'
end
```

[参考にしたサイト](https://qiita.com/hirotakasasaki/items/2c183dee5d890d5ab57a)
herokuへのデプロイができない：runtime.txtのうっかり誤字

herokuでPython製アプリをデプロイするときには、runtime.txtにPythonのverを記載しておく必要がある。

>remote:  !     Requested runtime (python 3.9.2) is not available for this stack (heroku-20).

このエラーメッセージが出た時そんなバカな！と叫んだ。
>python-3.9.2 on all supported stacks
heroku

この通り、3.9.2はherokuではちゃんとサポートされてると書いてるのに！
これでしばらく頭を抱えて、ふと気づいた。

サポートされてる方
>python-3.9.2

されてない方。
>python 3.9.2

結論。-の入れ忘れに気をつけよう。（なおその時作ってたアプリはデプロイ成功しても中身がエラーを起こしていた。徒労感……
【Python】文字列・数値の出力について

Pythonの文字・数値の出力について簡単にまとめてみました。

1. 出力について
2. 文字列について
3. 数値について
4. 文字列と数値の違いについて
5. コメントについて

# 1. 出力について
文字や数値を出力(表示)させたい場合、[print( )]と記述し、括弧内に出力したい文字や数値を入力します。


# 2. 文字列について
文字を出力(表示)させたい場合、シングルクォテーション('')、またはダブルクォーテーション("")で、
出力(表示)させたい文字を囲む必要があります。(どちらで囲んでも出力結果は同じになります。)

```
print("Hello World")
=> Hello World

print('Hello World')
=> Hello World
```

# 3. 数値について
数値を出力(表示)させたい場合、文字列とは違いシングルクォテーション('')やダブルクォーテーション("")で
出力(表示)させたい文字を囲む必要がありません。
数値は「＋」や「ー」を用いて、足し算や引き算が可能で、数値や記号は「半角英数字」で記述します。

```
print(1)
=> 1

print(1 + 1)
=> 2

print(10 - 1)
=> 9
```

# 4. 文字列と数値の違いについて
例えば、「1 + 1」の計算結果「2」を出力する際に「"1 + 1"」のようにクォーテーションで囲んでしまうと、
文字列として「1 + 1」が出力(表示)されてしまいますので、文字列として出力したいのか、
数値として出力したいのかでクォーテーションの有無に注意しましょう。

```
print("1 + 1")
=> 1 + 1

print(1 + 1)
=> 2
```

# 5. コメントについて
行の始め(頭)に「#」を記述することで、その行はコメントとみなされます。
コメントはコードが実行される際に出力されないので、コードに関するメモとして残しておくことができます。

```
# コメントです。(表示されません)
print("1 + 1")
=> 1 + 1

# コメントです。(表示されません)
# print(1 + 1) 表示されません
```
<br>
Pythonの文字列と数値、コメントに関する簡単なまとめでした。
プログラミング初学者の方への参考となればと思います。
windows Chromeで開発環境へ自動ログイン(ちょっとだけ便利機能)

#はじめに

開発環境にsession保持時間が短い場合は、何度もログインする必要がある。
または、過去のプロジェクトでログイン後確認したい場合、IDやパスワードをDBから調べる必要がある。
（ほとんどの場合パスワードはハッシュ化されてわからない）
そのため、自動でログインするVBAをプロジェクトで１つは準備しておくとちょっとだけ便利機能。

#自動ログイン
```ChromeLogin.vbs
'設定 - ここから
Const email="【メールアドレス】"
Const pass="【パスワード】"
Const BWtime=2000 'ブラウザ表示2秒待機
Const Wtime=200 'キー入力0.2秒待機
'設定 - ここまで

Dim url
Dim ret
'ログインURL
url="http://localhost:8000/login"

On Error Resume Next
Set owsh = CreateObject("WScript.Shell")
If owsh Is Nothing Then
    Msgbox "1Error: Could not execute chrome.", vbOKOnly + vbCritical, "Error"
Else
    ret = owsh.Run("chrome"+" " + url, 1, False)
    WScript.Sleep(BWtime)
    owsh.SendKeys("{TAB}")
    WScript.Sleep(Wtime)
    PutInClipboardText(email)
    WScript.Sleep(Wtime)
    owsh.sendkeys("^v")
    WScript.Sleep(Wtime)
    owsh.SendKeys("{TAB}")
    WScript.Sleep(Wtime)
    PutInClipboardText(pass)
    WScript.Sleep(Wtime)
    owsh.sendkeys("^v")
    WScript.Sleep(Wtime)
    owsh.SendKeys("{TAB}")
    WScript.Sleep(Wtime)
    owsh.SendKeys("{ENTER}")
End If

Public Sub PutInClipboardText(ByVal str)
    Dim cmd
     
    cmd = "cmd /c ""echo " & str & "| clip"""
    CreateObject("WScript.Shell").Run cmd, 0
  End Sub
```

VBScriptでChromeを操作する場合は、コマンドでしか操作できない。
IEであればDOMを取得することができるので、IE限定であればもう少し複雑な判定や操作ができます。

#おわり
新規プロジェクト参加メンバーが毎回IDやパスワードを聞きにくると思うので、
どこかに残すか、いっそ自動ログインまで作ってしまったほうが楽ですよね。

#おまけ(読み飛ばしてOK)
最近は、windows+docker+laravelで開発することが多いため、

```dockerUp.bat
@echo off
docker-compose up -d
pause
```
```setup.bat
@echo off
docker-compose exec laravel_app /bin/bash -c "cd /var/www/html/laravel_app && composer install"
```
上記のようなbatを作るとすごく楽だった。
コマンドを開いて、毎回dockerを立ち上げる必要がない。
初回『.env』の設定は、初回のみ手動で設定。
一度設定すれば、『dockerUp.bat』『ChromeLogin.vbs』ですぐに作業が始められます。
[メモ] Animation

[![Image from Gyazo](https://i.gyazo.com/972a1ba64db9db61a9b2c328eaad7760.gif)](https://gyazo.com/972a1ba64db9db61a9b2c328eaad7760)

```
  .spinner {
    width: 40px;
    height: 40px;
    background-color: #333;
    margin: 100px auto;

    @include animation(
      $name: sk-rotateplane2,
      $duration: 1.2s,
      $iteration-count: infinite
    );
  }

  @keyframes sk-rotateplane2 {
    0% {
      transform: perspective(120px) rotateX(0);
    }
    50% {
      transform: perspective(120px) rotateX(-180deg) rotateY(0);
    }
    100% {
      transform: perspective(120px) rotateX(-180deg) rotateY(-180deg);
    }
  }
```
HTTPメソッドの理解

Railsにおけるルーティングについて調べていると、HTTPメソッドについて知る必要があると感じたのでまとめてみました。

#HTTPメソッドとは
HTTPリクエスト内に含まれるもので、8つが目的別で定義されています。これらのうちWebサイトを閲覧する際に主に使用されるHTTPメソッドは「GET」と「POST」の2つです。

| HTTPメソッド名 | 説明                                               |
| --------- | ------------------------------------------------ |
| HEAD      | HTTPヘッダーの情報のみを取得するメソッド。データの更新日時やサイズのみを取得する場合に使用。 |
| GET       | HTMLファイルや画像といったデータを取得する場合に使用。                    |
| POST      | フォームに入力した文字などのデータを転送する場合に使用。                     |
| PUT       | データをアップロードや更新する場合に使用。                            |
| DELETE    | 指定のデータを削除する場合に使用。                                |
| CONNECT   | Webサーバに接続するまでに別のサーバーを中継する場合に使用する。                |
| OPTIONS   | 利用できるHTTPメソッドを問い合わせる場合に使用。利用制限されているメソッドの確認に。     |
| TRACE     | WebブラウザとWebサーバーの経路の確認に使用。                        |

さまざまなメソッドがありますが、覚えておくべきは「GET」、「POST」、「PUT」、「DELETE」の4つでしょう。
また、「PUT」、「DELETE」、「CONNECT」や「TRACE」は、その性質から悪用される可能性があるため、Webサーバーが使用制限をかけている場合が多いといいます。

##「GET」と「POST」の違い
表には書きませんでしたが「GET」もデータを送信することができ、「POST」と同じように使用することができますが、送信方法の違いがあります。
「GET」で送信する場合、URLの後ろに送りたいデータを付与して送ります。一方、「POST」はHTTPリクエスト内のメッセージボディ内にデータを付与して送ります。
このため前者を利用した場合、送付データがWebブラウザの閲覧履歴（URLとして）に残ってしまいIDやパスワードが知られてしまいます。そのため、個人情報などをWebサーバーに送る場合には、機密性を考慮して「POST」が利用されます。

##「POST」と「PUT」の違い
「PUT」はURLで指定したデータがある場合は更新し、ない場合は「POST」のように新しく作り出します。
2つのメソッドの違いはURLの指定にあります。「POST」の場合はURLの決定権はクライアントではなくサーバー側にあります。
一方、「PUT」の場合はクライアントにURLの決定権があります。一般的に、クライアントがURLを決定できるということは色々と技術的な問題があるようなので、特別な事情がない限り「POST」を利用する方が好ましいといえます。

#おわりに
8種のメソッドのうち、よく使うメソッドはたった4種類だけですので、しっかり頭に入れておきたいです！

#参考
[イラスト図解式 この一冊で全部わかるWeb技術の基本](https://www.amazon.co.jp/gp/product/B06XNMMC9S/ref=ppx_yo_dt_b_d_asin_title_o05?ie=UTF8&psc=1)
[Web初心者のためのHTTP入門](https://myenigma.hatenablog.com/entry/2015/08/02/230752)
JS+JQueryでストップウォッチ

#はじめに
JS+JQueryを使うストップウォッチの作り方を説明します！
JS学習し始めの方におすすめのミニアプリです！
いくつかポイントを抑えれば簡単にできますので挑戦してみましょう！

#コード紹介
ストップウォッチのコードはこちらです！

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="ryuji0526" data-slug-hash="BaQgjmV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="BaQgjmV">
  <span>See the Pen <a href="https://codepen.io/ryuji0526/pen/BaQgjmV">
  BaQgjmV</a> by Ryuji Watanabe (<a href="https://codepen.io/ryuji0526">@ryuji0526</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

###ポイント1　経過時間の出し方

スタートボタン押した時の操作

```
 $("#start").click(function() {
    startTime = Date.now();
    runTimer();
  });　
```
スタートボタンを押した時の時間をDate.now()で取得します。



runTimer()

```
  function runTimer(){
    currentTime = Date.now();
    showTime();
    setTimeoutId = setTimeout(() => {
      runTimer();
    },10)
  }
```
スタート時間からの差を求めるためにをcurrentTimeで経過時間を保持します。
さらに、setTimeout()で10ミリ秒ごとに経過時間の更新とshowTime関数を実行します。



showTime()

```
  function showTime(){
    let d = new Date(currentTime - startTime + elapsedTime);
    const getMin = d.getMinutes();
    const getSec =d.getSeconds();
    const getMillisec = Math.floor(d.getMilliseconds() / 10);
    $("#timer").text(`${String(getMin).padStart(2,'0')}:${String(getSec).padStart(2,'0')}:${String(getMillisec).padStart(2,'0')}`);
  }
```

currentTimeからstartTime引くことで、スタートボタンを押してからの経過時間を求めることができます。
それをnew Dateクラスの引数に入れ、get~メソッドで、分、秒、ミリ秒をそれぞれgetしてテキストに埋め込めばよいのです！

###ポイント2 ストップ時の操作

ストップボタン押した時の操作

```
  $("#stop").click(function() {
    elapsedTime += currentTime - startTime;
    clearTimeout(setTimeoutId);
  });
```

2行目の
```
elapsedTime += currentTime - startTime;
```
は、ストップを押した後にスタートを押したとき、00:00:00から始まってしまうのを防ぐために用います。ストップ時に今までの経過時間を変数で保持します。

```

  function showTime(){
    let d = new Date(currentTime - startTime + elapsedTime);
    const getMin = d.getMinutes();
    const getSec =d.getSeconds();
    const getMillisec = Math.floor(d.getMilliseconds() / 10);
    $("#timer").text(`${String(getMin).padStart(2,'0')}:${String(getSec).padStart(2,'0')}:${String(getMillisec).padStart(2,'0')}`);
  }
```

そして、先ほどには記入を省きましたが、2行目の、new Date()で経過時間を求めるときに先程の変数を足してあげるとで、ストップした時間から新たにストップウォッチを動かすことができます。

#おわりに
以上が簡単なストップウォッチのコードと説明になります。
別の機能を追加したり、スタイルなども工夫して、もっと見やすく便利でオリジナルなストップウォッチを作ってみましょう！
規模の大きな学習用データセットには git submoduleを使う

以下の文章は、DVC(Data　Version Control) を使うようになる前に書いた文章です。
いまは、[Git LFS からDVC(Data Version Control) に移行した話](https://qiita.com/nonbiri15/items/54c1fac76a8af5e51fdf)のように考えていて、submodule の利用をしていません。そのことをご承知のうえ読んでください。


---------------------
機械学習のためのデータセットは、日に日に規模が大きくなりがちた。

それを単一のgit のリポジトリで管理しようとすると、git lfs を使っても管理しきれなくなってしまう。

そこで、大規模なデータセットを作る際に、git submodule を使おうというのが、この記事の主張だ。

## 単一のgit lfs のリポジトリで管理しようとすると問題になること。

- 単一のリポジトリのデータ容量が際限なく大きくなる。
- 大規模データセットを構築する小規模なデータセットの構造が見えなくなる。
- 大規模なデータセットでは、コミットログも巨大なものになってしまう。
- 品質を確認しきれた範囲と、作業中で品質を確認できていないものが同一のリポジトリに含まれる状況が生じやすい。
- git clone する際の負荷が際限なく大きくなってしまう。
- 構成する小規模なデータセットのアノテーションを修正したいとしよう。そのときに問題を生じやすい。
    - 単一の巨大なリポジトリをgit clone してからでないと、その小規模なデータセットのアノテーションを修正することができない。
    - リポジトリが巨大であればあるほど、複数の人で作業をするとconflictを生じやすくなる。
    - アノテーションにconflict を生じたときに、どちらのアノテーションが正しいのかを数値データをみて判断することは、ほぼ不可能。

## 結論
規模の大きな学習用データセットを作る時に、単一のリポジトリにしてはならない。


## 解決方法

- 子になる小規模データセットをそれぞれのgit のリポジトリにする。
- 親になるリポジトリを作る。
- 親になるリポジトリの中に、個々の小規模データセットを含めるフォルダを仮にsubmodules という名前で作る。
- 親になるリポジトリの中で`cd submodules` とする。
- そこで子になる小規模データセットのリポジトリをsubmoduleとして登録する。

```
$ git submodule add {追加するgitのリポジトリの指定}
```

このようにすることで、大規模データセットの構築を小規模データセットのリポジトリの登録に分解することができる。

## git submodule のコマンド類

`$ git submodule`
そのリポジトリにあるsubmodule の一覧とハッシュを表示する。

`$ git submodule update`

そのリポジトリにあるsubmoduleの設定を submodule を含んでいる側のリポジトリの設定を更新する。

`$ git submodule update --remote`
submodule の設定を、それぞれのsubmoduleの最新状況を、このリポジトリに取り込む。




## 利点

- 親のリポジトリの中では、個々の小規模データセットのリポジトリのリポジトリ名とどのコミットを参照するのかを記録するだけになります。
- 親のリポジトリのコミットの履歴が簡単になります。
- 個々の小規模のリポジトリの側では、データを利用可能になるまでの全ての作業をコミットログに含めても問題がありません。利用可能な水準に達していない段階では、親のリポジトリにgit submodule add をしなければよいだけの話です。
- submodule のフォルダの中にバージョン管理されていないファイルがあると、`$ git submodule` で状態を確認すると、バージョンされていない余分なファイルがあると通知してくれます。
    - そのため、バージョン管理されていないファイルによって挙動が違ってしまうなどの問題をなくすことができます。





## DVCの関連記事
[DVC(Data Version Control) を使って画像データセットを管理する](https://qiita.com/nonbiri15/items/d1447a119cd06a12e026)

[DVCでのデータの登録を複数人で行う場合の注意　ー 手順を間違えるとデータを失える ー](https://qiita.com/nonbiri15/items/ed0c44e3d74d9a584c9f)
@todayが時間の経過と共に変化

#はじめに
`@`を使ったメンションに一つ、使い方がよくわからないものがあります。

##今日を記録しておく？

`@today`と入力すると、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/302dd9f8-487a-c0ae-b5de-18523e641d07.png)
今日にメンションのようなものをつけることができます。
これ、時間が経つと、表示が変わってきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/741816/9f65a2fe-6d89-b6dd-f182-19de34603594.png)
先週の木曜日に`@today`と入力したものが、このように表示が変わっています。

##最後に
結局何に使うか、全くわからない…
【Swift】クロージャのキャプチャって？パート2

#はじめに
[パート１](https://qiita.com/REON/items/7926ad25660703f6165b)の続きです。

#ネスト関数とクロージャ
前回の例題をネスト関数で置き換えました。結果は全く同じです。

```swift
func maker(_ a: Int, _ b: Int) -> (() -> Int) {
    var localvar = 0
    func localfunc() -> Int {
        globalCount += 1 // globalCountは参照されるだけ
        localvar += b // localvar, bがキャプチャされる
        return localvar
    }
    return localfunc
}
```

#メソッドとイニシャライザ

通常の関数と同様に、クラスなどのメソッド、イニシャライザもクロージャとして扱うことかできます。

```swift
class Friend {
    let name: String
    init(name: String) {
        self.name = name
    }
    deinit {
        print("deinit", name)
    }
    func sayName() {
        print("私は\(name)です。")
    }
    func sayHello(to f: Friend) {
        print("こんにちは、\(f.name)さん\(name)です。")
    }
}
```
次のように実行してみます。

```swift
let clo1: (String) -> Friend = Friend.init
var clo2: (Friend) -> ()
do {
    let fr1 = clo1("花子")
    clo2 = fr1.sayHello(to:)
    fr1.sayName()
}
let fr2 = Friend(name: "太郎")
clo2(fr2)
clo2 = fr2.sayHello
}
```
出力結果は以下のようになります。

```swift 
私は花子です。
こんにちは、太郎さん花子です。
deinit 花子
```
まず、イニシャライザを定数clo1に代入し、これを使ってdo文のなかでインスタンスが生成できていることがわかります。次に変数clo2にクラスのインスタンスメソッドを代入していますが、do文から出ることによって定数fr1自体は消滅します。その後、clo2に引数を与えるとちゃんと実行できていることからdo文のなかで生成したインスタンスはまだ生存していることがわかります。変数clo2に別の値を代入するとこのインスタンスは解放されます。

#キャプチャリスト
ここまで、クロージャはその周辺のローカル変数をキャプチャして共有できることを説明してきました。一方、クロージャが元の変数と必ずしも値を共有しなくてもよい場合もあります。そのような場合、クロージャのインスタンスを生成する際に変数のコピーを作り、クロージャないでそのコピーの値を使うことができます。

```swift 
var a, b, c: () -> ()
do {
    var count = 0
    var name = "Objective-C"
    a = { []            in print("A: \(count), \(name)") }
    b = { [count]       in print("B: \(count), \(name)") }
    c = { [name, count] in print("C: \(count), \(name)") }
    count = 1
    name = "Swift"
}
a()
b()
c()
```
先頭に変数名を[]で囲んだものがつけられています。これをキャプチャリストといいます。この中に書き並べられた変数はクロージャの生成時にコピーが作成され、そのあとは元の変数の値に変更があっても影響されません。
出力結果は以下のようになります。

```swift 
A: 1, Swift
B: 0, Swift
C: 0, Objective-C
```

#おわりに
クロージャのキャプチャの説明は以上です。
めんどくさい人向けのWSL2構築方法

公式 → https://docs.microsoft.com/ja-jp/windows/wsl/install-win10
すべて上に書いてますが、それすら読みたくない人向け。
**PowerShellを管理者権限で開いて**、上から順番にやればOK

###### Windows Sub Systemを有効化
```bash
> dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```
###### 仮想マシン プラットフォームを有効化
```bash
> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```
1. 再起動する
2. "Windowsの機能"を開く（そのままWindowsボタン→検索で良い）
3. `Linux用Windowsサブシステム`と`仮想マシンプラットフォーム`にチェックが入っているか確認する。

###### 「Linuxカーネル更新プログラムパッケージ」をインストールする　
数クリックで終わります。
https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel
###### WSL2を規定として設定する
```bash
> wsl --set-default-version 2
```
1. URLからお好きなLinuxをインストールする
    https://aka.ms/wslstore
2. 起動する
3. UserNameとPasswordを設定する

お疲れさまです。
あとは見慣れたLinux環境ができているはずです。
Rustにおける同じ変数名での宣言(シャドーイング)とは？

# シャドーイングとは
* Rustでは、以前定義した変数と同じ名前の変数を新しく宣言できます。
* また新しい変数は、前の変数を覆い隠すような動作になります。

例

```Rust
fn main() {
    let x = 1;

    let x = x + 2;

    let x = x * 3;

    println!("The value of x is: {}", x);
}
```

* さてこれを実行するとどうなるでしょうか・・？

実行結果

```
❯ cargo run
   Compiling variables v0.1.0 (/Users/yoshitaka.koitabashi/Desktop/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 0.24s
     Running `target/debug/variables`
The value of x is: 9
```

解説

* 結果を見ると計算結果は、9を出力しています。
* 動きとしては、まずxを1という値に束縛します。
* 2番目のletでは、xを覆い隠し、元の値に2を加えることになるので、xの値は3になります。 
* 3番目のletでも、xを覆い隠し、2番目のxに3をかけるので、出力されるxの値は9になります。

## メリット

* このシャドーイングのおかげで、 異なる名前を思いつく必要がなくなるわけです。命名するのって大変なので非常に僕としては感謝ですね!

## おまけ
* そういえば最近知ったのですが、Rustプログラマのことを「Rustacean」と呼ぶそうで、これは[crustacean](https://en.wikipedia.org/wiki/Crustacean)からきてるそう。。

* ちなみに、Rustコミュニティの非公式マスコットがこれなので、なるほどとなりました笑

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/8e24e491-1954-e145-ed61-db794297a654.png)
【Laravel】LaravelでMVCの「M」にあたるモデルを作成する

```
$ docker-compose exec workspace php artisan make:model Product --migration
```

``docker-compose exec workspace``これでworkspaceコンテナへ向けてということ。

```
php artisan make:model
```
これで、モデルをつくってくださいね！ということ。
その後ろに、作りたいモデル名を記述する。
ここではProductテーブルを作成したいため、頭文字は大文字で``php artisan make:model Product``とする。

```
--migration
```
最後に上の``--migration``オプション、これを記述することでマイグレーションファイルも一緒に作成してくれる。
railsコントローラ制御について

__今回は、Railsのリダイレクトなど制御周りを学んだので、記述していきます( ＾∀＾)
まじで、画面見ながらじゃないと期待してる動作になってるか分からんバイ(T . T)__
#目的
コントローラーを制御できるようにして自分の期待した処理を出来るようにしよう！！
##redirect_to (元のページに戻す（リダイレクト）
通常ならアクション内の処理が終了すると、
アクションに対応した、ビューが表示されるが、__<font color="IndianRed">redirect_to</font>__メソッドを利用すると別のアクションを使用できます。
また、条件式なども組み込む事ができます。

```message_controller.rb
def index
  @message = Message.find(1) #index.html.erbが表示される。
end

def new
  redirect_to action: :index #new.html.erbは表示されず、indexアクションに処理が移り、index.html.erbが表示される。
end

def huga
  redirect_to action: :index unless @message.id == 1
#この場合は、条件式（unless）がfalseの時のみ、redirect_toが実行されます。
end



```
__action:__がキーになっており、__:index__がバリューになっています。
なので、バリューには、処理させたいアクションを指定してあげると、
指定したアクションの処理が作動します。
#before_action
このメソッドは、コントローラ内のアクション（メソッド）が実行される前に作動します。

```message_contoller.rb
before_action :hoge
#indexアクションの処理が作動する前に動きます。
#このコントローラは、before_actionメソッドにより、最初に、hogeメソッドが実行されます。

def index
  @message = Message.find(1) #index.html.erbが表示される。
end

def new
  redirect_to action: :index #new.html.erbは表示されず、indexアクションに処理が移り、index.html.erbが表示される。
end

def hoge
  puts "hellow"
end
```
上記のように、__<font color="IndianRed">before_action</font>__は
コントローラ内のアクションが、作動する前に実行されます。
この、__<font color="IndianRed">before_action</font>__メソッドには、オプションが付けられます。
__・特定のアクションのみ__<font color="IndianRed">before_action</font>__を使用したい場合__
__only: [:アクション名]__
例文

```message_contoller.rb
before_action :hoge, only: [:index]
#この場合、indexアクションの処理が呼ばれた場合は、before_actionメソッドが、発動し
#hogeアクションが最初に呼び出されます。

def index
  @message = Message.find(1) 
end

def new
  redirect_to action: :index
end

def hoge
  puts "hellow"
end
```
上記の①場合は、indexアクション（特定のアクション）が呼び出された時のみ、__<font color="IndianRed">before_action</font>__が発動します。
newアクションの時は、発動しません。
この二つのメソッドを組み合わせた場合下記のような事ができます
【Rails】なぜ、renderとredirectを使い分けるのか？【Ruby】

<h2></h2>
先に結論を書くと、renderとredirect_toは処理の流れが違うため、各メソッドのメリットが享受できるように使い分ける必要があります。
そのメリットについて書いていきます。

<h2>renderのメリット</h2>
renderのメリットはアクションで使用していたインスタンス変数を保持したまま、viewを描画できる点です。


```ruby:render
def index
  @books = Book.all
end

def show
  @book = Book.find_by(id: params[:id])
  if @book.nil?
    render action: "index"
  end
end
```

上の例では、通常アクションと同viewが呼び出されるところを、renderを使うことによってことでインスタンス変数(@book)をそのまま保持してviewを表示することができます。

また、renderを使う場合メッセージを表示する際に、使われるflashメソッドは「flash.now」を使用することが多いです。

通常のflashですと、次の次の画面が描画されるまでメッセージが表示され続けてしまい意図しない表示になってしまいますが、flash.nowでは次のアクションが呼び出されるまでで、メッセージが表示されます。

<h2>redirect_toのメリット</h2>
redirect_toの特徴はrenderと違って、再度リクエストをブラウザーに投げなおさせて、再度ルーティングさせる点です。
この処理により、別画面を描画する際に再度アクションを読み込むことができます。

再度ルーティングをし直すため、redirect_toで編集していたインスタンス変数を引き継いで利用できません。

が、再度ルーティングしなおすことで、renderのようにview表示に必要な処理をrender前に書く必要がなく、そのアクションに飛ばしてしまえるため、コードの可読性や保守性を向上させることができます。

```ruby:redirect_to
def index
  @books = Book.all
end

def show
  @book = Book.find_by(id: params[:id])
  if @book.nil?
    render action: "index"
  end
end
```

redirect_toでは、再度ルーティングしてもう一度アクションを呼び出すため、メッセージを表示させるメソッドはflashが使用されることが多いです。
flashとredirect_toの組み合わせによって、次描画される画面にのみメッセージを表示させることができます。

<h2>参考</h2>
railsガイド
https://railsguides.jp/layouts_and_rendering.html#redirect-to%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B