OmniAICreator/Qiita-1.07M huggingface dataset:
クレジットカード決済用JavaScript準備②charge-formのidが設定されたフォームにsubmitイベント発火させるイベント直前でキャンセル



```rb:
const pay = () => {
  const form = document.getElementById("charge-form");
  form.addEventListener("submit", (e) => {
    e.preventDefault();
    console.log("フォーム送信時にイベント発火")
  });
};

window.addEventListener("load", pay);
```

const
-
１）変数宣言（再宣言・変数への再代入不可）
２）constはブロックスコープブロックとは、{ }で括られたなか限定
３）var,letより常にconstを使うことのがベスト

上のコードではページが読み込まれたタイミングで、まずid属性を使ってform要素を取得して変数formに入れます。

getElementById
-

getElementByIdは、任意のHTMLタグで指定したIDにマッチするドキュメント要素を取得するメソッドで、そのIDが書かれた場所を特定します。


addEventListener("submit",
-

submit イベントは、ユーザーが送信ボタン (<button> または <input type="submit">) を押したり、 Enter キーをフォーム内のフィールド (例えば <input type="text">) の編集中に押したりしたときに発生します。

続いてすぐに受け取った変数formをaddEventListenerメソッドを使ってイベント「submit」が発生したら処理を実行できるようにイベントリスナーを登録しています。

```rb:省略あり
form.addEventListener("submit", (e) 
```


```rb:省略なし
form.addEventListener("submit", function(e) 
```

処理の際に引数で変数e(※今回だと"submit"を(e)という変数に代入している)を渡していますが、これはEventオブジェクトが自動的に渡されます。
実行する処理の1行目にpreventDefaultメソッドを実行していますが、これはEventオブジェクトが標準で持っているメソッドで、実行するとデフォルトの動作をキャンセルすることができます。ここではフォームの送信をキャンセルするので、このメソッドを実行するとフォーム送信は行われません。

>参考：石戸 康平  Kohei Ishidoさま
>https://gray-code.com/javascript/execute-processing-when-submitting-the-form/

console.log
-

このメソッドは主に、渡された値をコンソールに表示するために使用します
querySelector

#DOMとは
本題の前に。
DOMとは、Document　Object Modelといいます。
Webブラウザは、HTMLファイルを読み込みWebページを表示しています。そのため、私達は、Webブラウザを見ることができます。
JSはHTMLを書き換えることができますが、直接は手を出すことができません。
そこでDOMを使って、文章を構造化して操作しています。
中身をツリー化しています。各要素のことをノードといいます。

DOM操作では、HTMLタグで表す要素(Element)を選択して操作します。
Elementとは、ノードを継承したオブジェクトです。
よく使われるのは、querySelector()とquerySelectorAll()です。

#cssセレクター
上記のメソッドは、CSSセレクターを引数として要素を選択します。
cssセレクターとは、cssで使われている要素を指します。

```index.js
document.querySelector('h1'); *タグの要素

document.querySelector('#form'); *id名

document.querySelector('.title'); *クラス名

document.querySelector('[src="image/images...."]'); *属性名の指定した要素

document.querySelector('.title p'); *セレクタ−のなかのセレクター
```

書き換えによく使われます。
phpMyAdmin で  「管理ユーザ(controluser)での接続に失敗」というエラーへの対策

次のエラーが出た時の対策です。
![phpmyadmin_error.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/87cff211-31f9-c3ce-5d86-a4a3f82e1de0.png)

```text
mysqli_real_connect(): (HY000/1698): Access denied for user 'phpmyadmin'@'local
host'

設定ファイルに定義されている管理ユーザ(controluser)での接続に失敗しました。
```

Ubuntu 21.04 の Nginx で確認しました。

次の情報を使って、ユーザーとデータベースを作成します。

```text:/etc/phpmyadmin/config-db.php
$dbuser='phpmyadmin';
$dbpass='secret';
$basepath='';
$dbname='phpmyadmin';
$dbserver='localhost';
$dbport='3306';
$dbtype='mysql';
```


```text
# mysql -uroot
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 73
Server version: 10.5.9-MariaDB-1 Ubuntu 21.04

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> create user 'phpmyadmin'@'localhost' identified by 'secret'; 
Query OK, 0 rows affected (0.036 sec)

MariaDB [(none)]> create schema phpmyadmin;
Query OK, 1 row affected (0.049 sec)

MariaDB [(none)]> grant all on phpmyadmin.* to 'phpmyadmin'@'localhost';
Query OK, 0 rows affected (0.038 sec)

MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.001 sec)

MariaDB [(none)]> exit
Bye
```

ユーザーとデータベースを作成後、phpMyAdmin にアクセスすると、次のメッセージが出ます。

```text
 phpMyAdmin 環境保管領域が完全に設定されていないため、いくつかの拡張機能が無効に
なっています。理由についてはこちらをご覧ください。
代わりにデータベースの操作タブを使って設定することもできます。
```

次の SQL でテーブルを作成します。

/usr/share/phpmyadmin/sql/create_tables.sql

```bash
mysql -uphpmyadmin -psecret phpmyadmin < /usr/share/phpmyadmin/sql/create_tables.sql
```
envchain + direnv で実現する安全な環境変数の保存方法

## envchain

- Mac の keychainにキーバリュー形式で値を保存してくれる。
- 従って、環境変数をファイルにベタガキしなくて良くなる！

```
$ envchain --set <namespace> <env>
```

📝 削除したい時には、「キーチェーンアクセス」アプリケーション上で削除する。envchainには削除コマンドが見当たらないので。

## direnv

- **所定のディレクトリに移動した際に自動で**`.envrc`ファイルを実行して環境変数がロードされ、そのディレクトリを出たら無効化される

以下の方法で設定できる。


(1)`.zshrc`ファイルを編集。

```zsh:.zshrc
export EDITOR=code
eval "$(direnv hook zsh)"
```

(2)所定のディレクトリで`$ direnv edit`を実行し、.evnrcファイルを編集する。.envrcの中では[このような関数](https://github.com/direnv/direnv/blob/master/man/direnv-stdlib.1.md)を使えるのでcheck it out。


## envchain + direnv で実現する安全な環境変数の保存方法

1. 有効にしたい環境変数を`$ envchain --set <namespace> <env>`でセット。
2. このnamespaceに含まれる環境変数を有効にしたいディレクトリのルートにおいて、`$direnv edit`を実行し`.envrc`ファイルを以下のように編集する。

```zsh:.envrc
direnv_load envchain <namespace> direnv dump

# If you want to use this in a nested envrc structure, this adds envs configured in the parent directory.
source_up ..
```

終わり！


<details>
<summary>追記</summary>

自分の手元では.env と.envrc を両方おくと、.envrc のみしか

</details>
capybara + seleniumの設定でdesired_capabilities/options属性がDEPRECATIONになった

# 遭遇したWARNING

`ruby3.0` 対応のため `selenium-webdriver` を `4.0.0.beta3` にアップデートしたところ、次のような DEPRECATION WARNING が発生しました。

```
[DEPRECATION] [:desired_capabilities] :desired_capabilities as a parameter for driver initialization is deprecated. Use :capabilities with an Array value of capabilities/options if necessary instead.
```

関連するPRはこちらのようです。

https://github.com/SeleniumHQ/selenium/pull/7832

要約すると、 `:desired_capabilities` 属性と `:options` 属性をどう使いわければよいか判断に迷うので、 `:capabilities` 属性に統一するとのことです。


# Capybaraの設定

以下は、Capybaraの設定の修正例です。

```diff
Capybara.register_driver :remote_chrome do |app|
  url = 'http://chrome:4444/wd/hub'
  capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
    'goog:chromeOptions' => {
      'args' => ['headless', 'disable-gpu', 'window-size=1920,1080'],
    },
  )
-  Capybara::Selenium::Driver.new(app, browser: :remote, url: url, desired_capabilities: capabilities)
+  Capybara::Selenium::Driver.new(app, browser: :remote, url: url, capabilities: capabilities)
end
```

これで、WARNINGが発生しなくなりました。
SwitchBotをWindows 10 から制御する


![swbo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/c3ba4752-bd4b-e516-1c3e-8edbd2b06280.gif)

#bluetoothから制御できる指ロボットです。
##コマンドを送ると横の切れ込みがボタンを押すためのメカが飛び出しスイッチを押してくれます。
コーヒーメーカー改造するか?色々に悩んだ末指ロボットを採用することにした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/740d5462-f7fb-8816-068f-b4aadefbe274.png)



携帯から動作することを確認して次にPCから動作の確認をする。
###Bleakのインストール

```.sh
pip install bleak
```
###メーカーの資料に詳細は、ありません。
##この指ロボットをハッキングします。
###1回スマートフォンで試験してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/d2c5ec56-f937-e92d-5dd6-1b0ab7ca1c18.png)
<b>WoHAND</b>の表示されているのがswitchBotです。
選択してStartボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/f8946e33-3248-e13d-0f72-a8e92d687bf5.png)
赤枠の数値をメモしてください。

##Source Code

```switchBot.py
import asyncio
import argparse
from bleak import *
def scan():
    async def run():
        devices = await BleakScanner.discover()
        for d in devices:
            if "D3:F8:8D" in d.address : # filter switch bot divices
                print(f"python switchbot.py -d {d.address}")
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run())
def switchBot(address):
    UUID = "cba20002-224d-11e6-9fb8-0002a5d5c51b"
    async def run(address, loop):
        async with BleakClient(address, loop=loop) as client:
            y = await client.read_gatt_char(UUID)
            await client.write_gatt_char(UUID, bytearray(b'\x57\x01\x00'))
    loop = asyncio.get_event_loop()
    loop.run_until_complete(run(address, loop))
def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('-s', '--scan', dest='scan', required=False, default=False, action='store_true',
                        help="Run Switchbot in scan mode - scan devices to control")
    parser.add_argument('-d', '--device', dest='device', required=False, default=None,
                        help="Specify the address of a device to control")
    opts, args = parser.parse_known_args(sys.argv[1:])
    if opts.scan:
        scan()
    elif opts.device:
        switchBot(opts.device)
if __name__ == '__main__':
    main()
```
##実行

```.sh
BLE0>python switchBot.py -h
usage: switchBot.py [-h] [-s] [-d DEVICE]

optional arguments:
  -h, --help            show this help message and exit
  -s, --scan            Run Switchbot in scan mode - scan devices to control
  -d DEVICE, --device DEVICE
                        Specify the address of a device to control
```
##アドレスの調査

```sh
BLE0>python switchBot.py -s
python switchBot.py -d D3:F8:8D:xx:xx:xx
```
##ゆびロボットの実行

```sh
python switchBot.py -d D3:F8:8D:xx:xx:xx
```

#実際のアプリケーション化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274715/dbbdd647-66a1-a660-c055-5817fa103ce1.png)
デプロイ後、「PUT」「DELETE」メソッドが実行できない

# 概要

ローカル環境では問題なく実行できたアプリが、Herokuにデプロイ後「DELETE」「PUT」メソッドが実行できないという事象が発生しました。

アプリケーションはspring-boot用いて作成しております。

# 環境　

OS: macOS Big Sur 11.2.3
JDK:14.0.1
Spring Boot 2.3.3
eclipse

# 結論(原因)

**デプロイ先で利用するapplication.properties内に、
「spring.mvc.hiddenmethod.filter.enabled=true」が記載されていなかった。**


# 対処法

デプロイ先で利用するapplication.properties内に、
「spring.mvc.hiddenmethod.filter.enabled=true」を追記します。

```
spring.datasource.url=jdbc:${DATABASE_URL}
spring.datasource.username=${DATABASE_USER}
spring.datasource.password=${DATABASE_PASS}
logging.level.jdbc=INFO
logging.level.jdbc.sqltiming=DEBUG
///追加
spring.mvc.hiddenmethod.filter.enabled=true
```


SpringBoot 2.1 までは、HiddenHttpMethodFilter がデフォルトで有効化されていたのですが、**SpringBoot 2.2以降デフォルトでオフになり、上記のように設定で有効にしないと「PUT」「DELETE」メソッドを扱うことができなくなったようです。**

ローカル環境で利用するapplication.properties内には、
「spring.mvc.hiddenmethod.filter.enabled=true」は記載されておりました。
ローカル環境では問題なく動作していたのはこれが原因でした。


参考
[SpringBoot2.2+ThymeleafでHTTP PUT/DELETE メソッドを扱う](https://qiita.com/kazuhiro1982/items/b8b9965fddf9c5507517)


**再度Herokuにデプロイし、「PUT」「DELETE」メソッドを試してみたところ、
正常に実行されました。**

# 追記
ちなみに「spring.mvc.hiddenmethod.filter.enabled=true」の記載がない状態でHerokuで「PUT」「DELETE」メソッドを実行すると、下記のように「POST」メソッドとして処理されます。

- 「PUT」メソッド


```
2021-04-22T05:24:40.286520+00:00 app[web.1]: /users
2021-04-22T05:24:40.681582+00:00 heroku[router]: at=info method=POST path="/users" host=snitch1.herokuapp.com request_id=“secret fwd="60.112.103.188" dyno=web.1 connect=1ms service=394ms status=302 bytes=393 protocol=https
```

- 「DELETE」メソッド

```
2021-04-22T05:30:02.509773+00:00 app[web.1]: /users
2021-04-22T05:30:02.561299+00:00 heroku[router]: at=info method=POST path="/users" host=snitch1.herokuapp.com request_id=e5d41ff7-3b77-4bc5-a4db-bdb185d40d30 fwd="60.112.103.188" dyno=web.1 connect=6ms service=59ms status=200 bytes=2456 protocol=https
```
gnuplottexを使おうとしてつまずいた点

#はじめに
この記事を参考にしてgnuplottexを使ったときに自分の環境だとつまずいた点がいくつかあったのでその解決方法を書いていきます

https://qiita.com/satl/items/0c11c8808b43f806ee21

#Windowsではshell-escapeを有効にしていても有効だと判定されない
どうやらgnuplottexではshell-escapeが有効になっているかどうかのチェックにUNIXコマンドを用いているためWindowsではチェックが失敗し、shell-escapeが有効ではないと判定されてしまいます。解決策としてはgnuplottexを読み込むときにmiktexのオプションをつけて読み込むことです。

```TeX
\usepackage[miktex]{gnuplottex}
```

このようにすれば問題なくコンパイルできるはずです。しかしこの解決策には問題があります。それはグローバルスコープの\ifmiktexがtrueになってしまい他のパッケージにmiktexのオプションが用意されていた場合有効になってしまい、予期しない動作をする可能性があることです。私は今のところ問題になったことはありませんが注意する必要があります。

他の解決策としては、WSLでコンパイルすることが考えられます。未検証ですがmiktexのオプションを指定せずに問題なくコンパイルできるはずです。

#latexmkを使ってコンパイルしたときに無限ループになりコンパイルが終わらない
これはgnuplottexの問題というよりgnuplotがtexファイルを生成するときに、秒単位のタイムスタンプをつけるためコンパイルごとにtexファイルが変更されたとlatexmkで判断されてしまうことが原因のようです。この問題は通常C:\Program Files\gnuplot\share\lua\に存在するgnuplot-tikz.luaのnotimestampをtrueに変更することで解決します。

```lua
  -- for regression tests etc. we can turn off the timestamp
  notimestamp = true,
```

#参考
https://tex.stackexchange.com/questions/294617/gnuplottex-and-shell-escape

https://tex.stackexchange.com/questions/579396/using-gnuplottex-causes-latexmk-to-compile-forever
本番環境(EC2)でYoutubeのAPI keyが読み込めない問題

##エラー内容

/production.log

```
Caught error forbidden: The request is missing a valid API key.
 Error - #<Google::Apis::ClientError: forbidden: The request is missing a valid API key.>
```

ローカル環境では`dotenv-rails`を使い、`.envファイル`の中に環境変数を定義してapiキーを管理していました。それがうまく読み込めずエラーになっているようです。


##解決方法
###①credentials.ymlにapi keyを定義する

```
EDITOR="vi" bin/rails credentials:edit
```

./credentials.yml

```
youtube:
  GOOGLE_API_KEY: xxxxxxxxxxxxxxxxxxxxxxxx
```

credentials.yml.encの中身は暗号化されているので`master.key`を使って施錠してあげる必要があります。

※シンボルの後は半角スペースを開けないとうまく保存できないので注意してください。

<br>
###②本番環境(EC2内)にRAILS_MASTER_KEY環境変数を定義する
credentials.yml.encを読み込むためにEC2内にmaster.keyを設定します。

./ec2-user

まずは`master.key`を設定するファイルの作成

```
sudo vim /etc/environment
```

<br>

`master.key`を定義します
./environment

```
RAILS_MASTER_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxx
```

<br>
###③コントローラーでapi kyeを読み込む

` Rails.application.credentials[:キー]`
でcredentials.yml.encを呼び込めます。

```
 GOOGLE_API_KEY = Rails.application.credentials.youtube[:GOOGLE_API_KEY]
```

うまく表示されました！

<br>

[チーム開発でのデプロイで注意すべき３つのポイント](https://techtechmedia.com/team-development-deploy/)
Nice Vibrations メモ

# プリセットの瞬間振動

``` C#
MMVibrationManager.Haptic(HapticTypes.LightImpact);
```
|HapticTypes  |iOS  |Android  |
|---|---|---|
|Selection |かなり弱い |弱い |
|LightImpact |弱い |弱い |
|MediumImpact |普通 |普通 |
|HeavyImpact |強い |強い |
|Rigid |普通（硬い） |弱い |
|Soft |弱い長い（柔らかい） |強い |
|Success |弱い→強い |強い |
|Warning |硬い→硬い |普通→普通 |
|Failure |普通→普通→普通→重い |普通→強い→強い→弱い |


# 瞬間振動

``` C#
MMVibrationManager.TransientHaptic(振動の強さ, 鋭さ);
```

| |イメージ|弱い振動 |強い振動  |
|--|--|--|--|
|滑らか（正弦波） |∿ |柔らかい |軽い |
|鋭い（矩形波） |W |重い |硬い |

未対応のAndroidでは全て 強い 瞬間振動になる。

# 継続振動

``` C#
MMVibrationManager.ContinuousHaptic(強さ, 鋭さ, 継続時間, HapticTypes.None, this);
//振動を変化させる
MMVibrationManager.UpdateContinuousHaptic(強さ, 鋭さ);
//停止
MMVibrationManager.StopContinuousHaptic();
```

未対応のAndroidでは振動しない。
Android固有の関数で代用する方法を紹介する。

``` C#
MMVibrationManager.AndroidVibrate( 継続時間(ミリ秒) , 強さ(0 ~ 255) );
```
上記の関数を利用するために、AndroidManifest.xml に下記を追加する。

``` xml
<uses-permission android:name="android.permission.VIBRATE" />
```

# 高度な振動
https://nice-vibrations-docs.moremountains.com/advanced-patterns.html

https://ahap.fancypixel.it/

未対応のAndroidでは振動しない。

# リンク

https://assetstore.unity.com/packages/tools/integration/nice-vibrations-haptic-feedback-for-mobile-gamepads-108559

https://nice-vibrations-docs.moremountains.com/index.html

https://apps.apple.com/jp/app/nice-vibrations/id1332347762
DoTween メモ

### 処理の遅延
``` C#
DOVirtual.DelayedCall(待機時間, () => 処理 ).SetLink(gameObject);
```

### 値の変動
``` C#
DOTween.To( () => 変動させる値, (value) => 変動させる値 = value, 最終的な値, 変動時間);
```

### 動作の再利用
``` C#
動作.Pause().SetAutoKill(false).SetLink(gameObject);
// 再生
動作.Restart();
```

### パラメータの再利用
``` C#
public static TweenParams pauseParams { get; } = new TweenParams();
tweenparams.Pause().SetAutoKill(false).SetLink(gameObject);

動作.SetAs(pauseParams);
```

### Easeing

https://easings.net/ja

### Set
``` C#
//動きの加減速
動作.SetEase(Ease.InSine);
//ループ
動作.SetLoop(-1, LoopType.Incremental );
//相対的な動作にする
動作.SetRelative();
//遅延
動作.SetDelay(1f);
```

### 再生・停止
``` C#
//一時停止
動作.Pause();
//再生
動作.Play();
//はじめから再生
動作.Restart();
//終了
動作.Complete();
//破壊（再生不可能になる）
動作.Kill();
```

### Sequence
動作を組み立てて、一つ複雑な動作を作れる。
Append で動作を加え、Join で動作を重ねられる。

``` C#
Sequence sequence = DOTween.Sequence();
sequence.Append( 動作 );
sequence.Join( 動作 ).Play();
```

### Callback
``` C#
//開始時に処理を実行
動作.OnStart(() => 処理 );
//更新時に処理を実行
動作.OnUpdate(() => 処理 );
//完了時に処理を実行
動作.OnComplete(() => 処理 );
```

### リンク
https://assetstore.unity.com/packages/tools/animation/dotween-hotween-v2-27676

http://dotween.demigiant.com/documentation.php
Heroku Rails導入時にはまったこと、zsh: parse error near `\n'など

Heroku mac M1で設定中に

```mac:terminal
heroku config:set RAILS_MASTER_KEY=<master key>

zsh: parse error near `\n'

```

↓解決 api/config/のmaster.keyをXXXXXXXX貼り付けること

```mac:terminal
heroku config:set RAILS_MASTER_KEY=XXXXXXXX

```
以上
よく使うgitコマンド集

# はじめに
簡単なgitコマンド集です。
SourcetreeやVSCodeなどのGUIツールでもある程度はできますが、コマンド操作が必要になった時のために思い出せるとよいなーと考え、書いてみました。

# 読者の想定
- gitの基本的な考えは理解している
  - リモートのリポジトリをローカルにクローンし、ブランチを切り替えながら作業することや、コミット・マージなどの単語はある程度わかる など

# コマンド
## コミット履歴を確認する
```
git log -3
```
- ちゃんと `git pull` できているか確認するときなどに。
- 上記のコマンドで最近の3コミットまで確認できる。（数字＝表示するコミット数）
- オプションなしの場合はずっと遡れる。
- コミット履歴の表示は `q` で抜ける。

## ブランチを切り替える
```
git checkout {branch}
```
- ブランチの移動。
- ローカルになくリモートにあるブランチをpullして切り替えたい場合も、これだけでOK。（remotes/origin/{branch}にする必要はない）

## ローカルブランチを作成する
```
git checkout -b {branch}
```
- 現行ブランチをベースにブランチ作成＆移動

## ローカルブランチを削除する
```
git branch -d {branch}
```
- 現行ブランチは削除できない。他のブランチに移動してから実行する。
- ローカルのブランチしか削除されない。リモートブランチを削除する場合は `git push origin :{branch}`

## ローカルブランチを確認する
```
git branch
```
- ローカルブランチの一覧と、現行ブランチを確認する。
- リモートブランチも含めて確認する場合は `git branch -a`
- ブランチ表示は `q` で抜ける。

## 変更をステージする
```
git add .
```
- ステージ→コミットの流れで変更がコミットされる。言い換えると、ステージされたものがコミットされる。
- すべての変更をステージしたい場合は上記のコマンド。ファイルごとにステージする場合は `git add {path}`

## ステージされた変更をコミットする
```
git commit -m '{message}'
```
- オプションなしでもコミットできるが、コミットメッセージを付ける習慣にしておくのがおすすめ。

## タグを付ける
```
git tag {tag} -m '{message}'
```
- 現行ブランチの最新コミットに対してタグ付けする。

## ローカルの変更をリモートに反映する
```
git push origin {branch}
git push origin {tag}
```
- ブランチの変更もタグの追加も同じコマンドでリモートに反映できる。
- `git push origin :{branch}` とコロンを付けるとリモートのブランチやタグを削除するコマンドになってしまうので注意。

## リモートの変更を取り込む
```
git pull
```
- 現行ブランチのリモートでの更新を取り込む。
- `git pull` ≒ `git fetch` + `git merge` ※厳密には異なるらしい

## ローカルの変更を取り消す
```
git checkout {path}
```
- ステージされていない（＝`git add`していない）変更を取り消す。
- ローカルの直前のコミットまでファイルを戻す。

## ローカルの変更を退避する
```
git stash
git stash save '{message}'
```
- ステージやコミットせずにローカルの変更を退避する。退避した後は直前のコミットの状態まで戻る。
- 退避したものは `git stash list` で確認できる。
- 退避したものを再度適用する場合は `git stash apply stash@{0}` など。

## 別のブランチをマージする
```
git merge {branch}
```
- 現行ブランチに、指定したブランチをマージする。
- マージコミットが発生する場合は、viのビューになってコミットメッセージの入力を求められる。
  - 詳細を説明する必要がなければ、そのまま `:wq` で終了すればOK。
- 競合した場合は競合したファイルを修正・保存して `git commit`
  - `git status` すると、次に何をすればよいかが指示される。
Tensorflowで複数GPUを使用する方法

## はじめに
本記事ではTensorflowで複数GPUを用いた計算を行うためにTensorflow2.0から使用可能となったtf.distribute.Strategyを用いた例を紹介します。

TensorflowオフィシャルにもGPUの割り当てに関した記事がありますが、こちらはの記事ではより簡潔に解説し、すぐ実装できるという趣旨で紹介していきます。

また、実際に利用される例としてDeep learningがほとんどだと思いますのでDeep learningの学習を例に解説していきます。

## Tensorflow Strategy
Tensorflow-gpuを用いたDeep learningの学習ではデフォルトでは単一のGPUが使われます。
マシンに複数のGPUを積んでいて、複数のGPUを用いて学習を行いたい場合、最も簡単な方法はTensorflow2.0から公開されたStrategyを使用します。
また、Strategyを用いた複数GPUの利用はTensorflow公式により推奨されているベストプラクティスです。

### 使用例

使用方法は非常に簡単でモデルのCompile、BuildをMirroredStrategyのスコープで括ってあげます。
これで複数GPUが適応されます。
今回使用したMirroredStrategy以外にもStrategyが利用でき、複数マシンやTPUへの分散もサポートされています。

https://www.tensorflow.org/guide/distributed_training?hl=ja

ちなみに、Strategyの裏側では、各GPUでモデルのコピーを実行し、それらの間で入力データを分割することで。データの並列処理を行なっています。

```python

strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
  inputs = tf.keras.layers.Input(shape=(1,))
  predictions = tf.keras.layers.Dense(1)(inputs)
  model = tf.keras.models.Model(inputs=inputs, outputs=predictions)
  model.compile(loss='mse',
                optimizer=tf.keras.optimizers.SGD(learning_rate=0.2))
model.fit( ... )

```

## 終わり
マルチGPUを用いてDNNに高速に学習させましょうー！

## 参考
https://www.tensorflow.org/guide/gpu?hl=ja
https://www.tensorflow.org/guide/distributed_training?hl=ja
[SwiftUI] NavigationViewの背景色を透明にする

# 必要なもの

[SwiftUI-Introspect](https://github.com/siteline/SwiftUI-Introspect)が必要になります。 SPMでインストールしてください。

# 実装方法

## UINavigationControllerを拡張

```UINavigationController+.swift
import UIKit

extension UINavigationController {

    func clearBackgroundColor() {
        topViewController?.view.backgroundColor = .clear
        topViewController?.parent?.view.backgroundColor = .clear
        topViewController?.parent?.parent?.view.backgroundColor = .clear
    }
}
```

## 遷移元画面

UINavigationControllerの背景色を透明にします。

```Hoge.swift
var body: some View {
    NavigationView {
        ZStack {
        }
    }
    .introspectNavigationController { navigationController in
        navigationController.clearBackgroundColor()
    }
}
```

## 遷移先画面

遷移先のViewControllerの背景色を透明にします。

```Fuga.swift
var body: some View {
    ZStack {
    }
    .introspectViewController { viewController in
        viewController.view.backgroundColor = .clear
    }
}
```
Javascript基礎メモその3

#関数
JavaScriptにおける関数とは、『いくつかの処理をまとめたもの』である。

>```javascript
const 定数名 = function() {
  //いくつかの処理をまとめたもの
};

定数の後にfunction()と書き{}の中にまとめたい処理を書。

>```javascript
const selfintroduction = function() {
  console.log("こんにちは");
  console.log("私はtakahashiです");
  console.log("40歳です");
};
self_introduction();

結果
こんにちは
私はtakahashiです
11歳です

最後の行のself_introduction()で関数を呼び出している。
関数の呼び出し方は 定数名() で呼び出す。
呼び出された関数は{}内の処理が実行される。

#アロー関数
関数の『function()』の部分を『()=>』(アロー関数）にしても関数を定義できる。
ES6から導入された新しい書き方である。

>```javascript
const self_introduction = () => {
  console.log("こんにちは");
  console.log("私はtakahashiです");
  console.log("40歳です");
};
self_introduction();

結果
こんにちは
私はtakahashiです
11歳です

#引数
引数とは関数を呼び出す時に値を渡すことで、処理をする時に渡した値を用いて処理をしてくれる。

>```javascript
const 定数名 = (引数名) => {
  //処理
};
定数名(値);
```
>```javascript
const self_introduction = (name) => {
  console.log("こんにちは");
  console.log(`私は${name}です`);
};
>
self_introduction("dai");
self_introduction("syou");
```

結果
こんにちは
私はdaiです
こんにちは
私はsyouです

関数を呼び出す時に渡した値を用いて処理してくれる。

#複数の引数
複数の引数を渡したい時には、　『,』（コンマ）で区切る。

>```javascript
const self_introduction = (name, age) => {
  console.log(`私は${name}です`);
  console.log(`${age}歳です`);
};
>
self_introduction("gotou", 17);
```

結果
私はgotoです
17歳です

self_introduction("gotou", 17); で name に "gotou" 、 age に 17 を渡している。

#戻り値
戻り値は、関数の処理結果を呼び出し元で受け取る。
『return』を使うと呼び出し元であたいを受け取れるようになる。
>```javascript
const 定数名 = () => {
  return 値;
};
```

>```javascript
const add = (a,b) => {
  return a + b;
};
>
const sum = add(1, 3); // add(1, 3);が return a + b;を呼び出している
console.log(sum);

結果
4

『add(1, 3)』で『return a + b;』を呼び出し『const sum』に代入している。

#戻り値（例）

>```javascript
const check = (number) => {
  return number % 2 === 0;
  //return後にある処理は行われない
  console.log("計算しました");
};

>console.log(check(6));
console.log(check(7));
```

結果
true
false

>```javascript
const check = (number) => {
  return number % 3 === 0; 
};
>
if (check(123)) {
  console.log("3の倍数です");
} else {
  console.log("3の倍数ではありません");
}
```

結果
3の倍数です

#スコープ
スコープとは定数や変数の使用できる範囲のことをいう。

>```javascript
const introduction = () => {
  const name = "dai";
  // 定数nameが使えるスコープ
};
  // 定数nameが使えないスコープ
```

>```javascript
if (条件式) {
  const name = "dai";
  // 定数nameが使えるスコープ
}
  // 定数nameが使えないスコープ
```

>```javascript
while (条件式) {
  const name = "dai";
  // 定数nameが使えるスコープ
}
  // 定数nameが使えないスコープ
```
[Rails]deleteとdestroyの違い

# はじめに
最近、destroyとdeleteの違いを理解したフリしていたことに気づきました。
これはいかん！！ということで、ここに備忘としてアウトプットします。


#deleteメソッド

条件に一致したレコードを、SQLを**直接実行することで**削除します。
つまり、**モデルを経由せずに削除していて関連づけしているレコードは削除されな**いわけです。

余談ですが、フォロー機能実装中に、Relationshipモデル（中間テーブル）を削除したくてdestroy使ったらUserも消えて、、、deleteメソッドには助けられました。

#destroyメソッド
destroyメソッドはモデルつまりActiveRecordを経由してるため、**関連したバリデーション機能も有効ですし、関連づけされたレコードの削除も行われます。**
ちなみに、こいつは削除に失敗したときに私が大好きなエラーは返してくれなくて、falseを返してくるので、エラーが欲しい人はdestroy!メソッドを使ってみてください。


#余談；uniq!の違いとuniqメソッドの違い

題名とは全く異なる余談です。（destroyとdestroy!で思い出したついでに）
uniqとuniq!の違いについてですが、これは上述したdestroyのような違いとは異なります。

uniq!メソッドは破壊的メソッドと呼ばれていて、元配列をそのまま加工します。
一方、uniqメソッドは元の配列を保存したまま、別の配列を用意して処理を行います。

```ruby
train = ["りんご", "りんご", "みかん", "ぶどう" ]
p train.uniq! #=>["りんご","みかん", "ぶどう" ]
p train     　#=>["りんご","みかん", "ぶどう" ] 元には戻らない！

train = ["りんご", "りんご", "みかん", "ぶどう" ]

p train.uniq #=>["りんご","みかん", "ぶどう" ]
p train      #=>["りんご","りんご","みかん", "ぶどう" ]　元どおり！
```

#終わりに
こうした小さな違いや基礎の部分を疎かにしてはいけないと、開発を通して感じました。応用よりも基礎、とにかく基礎を確実に定着させ、その上で応用、発展と成長していければと思いました。
Oracle DB起動時にエラーORA-01034・ORA-27101が出て起動しない

ORA-01034・ORA-27101が発生。

Google検索すると同じ現象で何件かヒットしますが。

sqlプラスにはいろうとすると別のエラーが
ORA-28056: Writing audit records to Windows Event Log failed

イベントビューワーを確認しようとしても、EVENT LOG Serviceも起動されておらず、手動で開始するもエラー。

手詰まりだったので、スナップショットから復元しようとしてもすぐに同じ現象に…。

結局、単純に仮想環境のディスクを使い切って、空き容量がなくなっていました。ディスクサイズを拡張して再起動したら、無事起動しました。

Windows Server 2012R2
Oracle 11gR2

誰かの気付きになれば😁
Terminalでmarkdownをプレビュー

CLIって美しいですよね。

Terminal用マークダウンビューアーの[glow](https://github.com/charmbracelet/glow)をinstallして試してみます。

https://github.com/charmbracelet/glow

```bash
$ brew install glow
```

## プレビュー
### ファイル名で開く
シンプルに`glow {FILE_NAME}`でok

```bash
$ glow tmux_cheat_sheet.md
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74186/a034a10d-4413-1da8-4b2f-4bce311c5a7c.png)

100倍読みやすくなってる。すばらしい。

ちなみに`glow`単体で実行すればmdファイル選べるをTUIが表示される。基本はCLIで使うのでこれはあんまり使っていない

### URLで開く
```bash
$ glow https://raw.githubusercontent.com/rust-lang/rust/master/README.md
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74186/405477a6-1be4-55d7-d9a1-6c98e6a11427.png)

### GitHub repoのREADME.mdを開く
↑GitHub repoを指定するだけでよかった

```bash
$ glow https://github.com/rust-lang/rust
```

## カスタマイズ
気になったところを修正します。長いファイルだとcatばりに出力されてしまうのが厳しい
`-p`オプションでpagerで開けるようですがデフォルトにしたい

以下でconfigファイルを編集（$EDITORが設定されてる必要あり）

```bash
$ glow config
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74186/6826156b-1e38-0c36-095b-bdd3ae16ddcb.png)
色々ありますが今回はデフォルトでpagerを使いたいので`pager: true`に変更

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74186/f10b673b-88da-1e6b-758f-bffc404945da.png)
lessで表示されました！$PAGER設定すれば好きなpagerでひらけます

## まとめ
markdownの読みやすさは異常
fish shell のvi キーバインドで、提案を C-f で受け入れる

# Autosuggestions(自動提案)
fish shell には、コマンド入力時にコマンド履歴から候補が表示(提案)されるというAutosuggestions という機能がある。

https://fishshell.com/docs/current/index.html#autosuggestions

デフォルトのEmacs キーバインディングではC-f で受け入れることができるのだが、Vi キーバインディングでは矢印キーの→を入力する必要がある。

矢印キーは遠いのでめんどうだ！

と思ったあなたは、次のコマンドを入力すると幸せになれる。

	bind -M insert \cf forward-char

この設定が気に入ったら、config.fish に登録しましょう。
この記事の中に書きました。

https://qiita.com/harupiyo/items/bcba079eb91d2941e156#%E8%A8%AD%E5%AE%9A%E3%82%92configfish-%E3%81%AB%E4%BF%9D%E5%AD%98%E3%81%99%E3%82%8B


🍺
fish shell にコマンドラインスタック機能を付ける

# コマンドラインスタック機能(push-line)
コマンドラインスタック機能とは、コマンドを打っている途中に他のコマンドを先に実行すべきだと気付いた時、一時的に入力を中断できる機能のこと。（他のコマンドを実行し終えたら入力を再開できる）

標準機能かと思ったのだがなかった。
そこでfisher コマンドを使って次のプラグインをインストール。

	fisher install ccyip/push-line.fish

これでAlt-q で入力中のコマンドを後回しにできる。（やってみて）

## vi keybindings でも同じことをやるには？

	bind -M insert \eq push_line
と入力すればよい。Alt-q で利用できる。(\e とはAlt のことで、\eq でAlt-q という意味)

## 設定をconfig.fish に保存する

こちらの設定と合わせてconfig.fish に保存する方法です。

https://qiita.com/harupiyo/items/55931d68b939e7a8a582

~/.config/fish/config.fish に次のように書いてください。

```
function fish_user_key_bindings
  bind -M insert \cf forward-char
  bind -M insert \eq push_line
end
```

### MEMO fish_user_key_bindings?
なお、function fish_user_key_bindings に書く理由は以下の通りです。

http://fish.rubikitch.com/bind/

>  ~/.config/fish/config.fish 内に
> 直接書かれた bind コマンドは
> 有効になりません。
> 
> なぜなら、
> デフォルトのキーバインドが設定される前に
> config.fish が読み込まれるからです。
> 
> 自分用のキーバインドを保存するためには、
> ***bind コマンドを
> fish_user_key_bindings オートロード関数 内に
> 書いてください。***
データベースの検索時間を1秒以内に抑える方法

##初めに

久しぶりにデータベース回りをコーディングしていたら、高速化で手こずったので覚書。
所謂、DBのチューニングで検索を高速化するための幾つかの方法になります。
そんなに大したことは書いておりません。
初歩的と言うか基本的なことですね。
参考になれば。

※あくまで高速化に特化した方法を書いておりますが、場合によってはデータの整合性が取れなくなるなどのリスクも発生しますので、ご了承ください。

##DB高速化の方法いくつか

###インデックスを貼る
　一応、基本なので詳細は省略します。ですが、貼り方にもコツが必要ですよね。沢山貼れば良いということでもないですし、かといって、検索項目が沢山ある場合は、あるだけ貼りたいし。。。トライアンドエラーで試すしかないですかね。

###集計値は予め集計しておく
　メインテーブルと合わせて、サブテーブルの集計値などを表示する場合は、その集計値を予め計算しておいて、メインテーブルのカラムに保存しておくと良いですね。クエリを呼び出すたびにいちいちGROUP BYをしていると遅くなりますからね。
　例えば、下記のツイッターで例えると、イイネテーブル（サブテーブル）の集計値をリアルタイムで集計して、ツイートテーブル（メインテーブル）のtweet_num_likeカラム（イイネの数）に反映しておくということかな。
　予め出来る処理は、出来るうちにやっておくということですね。

ツイートテーブル（メインテーブル）

|  カラム   |  説明        |
| ----      | ----        |
|  tweet_id |  ツイートid  |
|  contents |  コンテンツ  |
|  num_like | イイネの数  |

イイネテーブル（サブテーブル）

|  カラム   |  説明        |
| ----      | ----        |
|  tweet_id |  ツイートid  |
|  user_id  |  イイネしたユーザのuser_id  |

###サブデータを連結文字列として保存しておく
　場合によっては、サブテーブルのデータ一覧をメインテーブルに連結文字列として保存しておくのもありかなと思います。jsonなどでも良いかもしれませんね。サブテーブルを連結する必要がなくなるので、処理は速くなると思いますが、データ数が増えると容量のコストが増える？

メインテーブル

|  カラム               |  値        |
| ----                  | ----        |
|  data_id              |  id_1  |
|  contents             |  'aaaa'  |
|  subdata_param_string | 'param_1@param_2@…'  |

###検索条件（WHERE）で、他のテーブルを参照しない
　例えば、下記の様なケースで他のテーブルを参照する場合があると思います。

```search.sql
WHERE
  column_a IN (SELECT column_a_temp FROM table_1 WHERE ****)
```
これでも全く問題はないですが、INの中身を予め取得しておいて、値を指定してやるとより速くなります。

###1つのテーブルにデータをまとめておく
　色々なケースがあると思いますが、ある程度、リアルタイムでデータが欲しい場合は、テーブルの連結を行うと検索が遅くなるなと思いました。例えば、検索時間を1秒以内に抑えたい場合などにJOINを使うと、データが増えた場合に対応できなくなるなど。
　勿論、データ容量が増えたり、他のテーブルとデータが重複したりして管理が大変になるなどのデメリットもあると思いますが、結局、背に腹は代えられず、高速化のためにデータを１つのテーブルに集めておくというのも、場合によってはありかなと思います。

##まとめ
　まとめと致しましては、（当たり前の結論にはなりますが、）下記の様にSELECT, FROM, WHERE, ORDER BYのみで完結するようなシンプルなクエリを使用できるまで、データを作成しておくことが重要なのかなと思いました。やっぱりsimple is best.ですかね。
　勿論、高速化が正しいということではなく、上述しておりますが、データ重複などのデメリットも存在しますので、ケースによって使い分けるのが大事なのかなと思いました。他にも高速化の方法がありましたら、コメント頂けると幸いですm(_ _)m

  ```sample.sql
SELECT
  column_1,
  column_2
FROM
  table
WHERE
      column_a = ****
  AND column_b = ****
ORDER BY
  column_1,
  column_2;
  ```
WSL2にClispのインストール

WSL2にClispをインストールして使いたかったのでそれまでの手順です。

調べていたら、Emacsなども入れて操作するという導入方法はよく見つかりましたが、軽く触るぐらいなのでターミナルから操作する方法になります。

# 環境
* windows10 home
* WSL2
* ubuntu20.04 LTS

# インストール

ubuntuを開いて以下のコマンドをターミナルに入力するだけです。

```
 sudo apt install clisp
```
インストールできたらClispを起動します。

```
clisp
```

以下のようなのが出てきたらclipsを使うことができます。


```
   i i i i i i i       ooooo    o        ooooooo   ooooo   ooooo
  I I I I I I I      8     8   8           8     8     o  8    8
  I  \ `+' /  I      8         8           8     8        8    8
   \  `-+-'  /       8         8           8      ooooo   8oooo
    `-__|__-'        8         8           8           8  8
        |            8     o   8           8     o     8  8
  ------+------       ooooo    8oooooo  ooo8ooo   ooooo   8

Welcome to GNU CLISP 2.49.92 (2018-02-18) <http://clisp.org/>

Copyright (c) Bruno Haible, Michael Stoll 1992-1993
Copyright (c) Bruno Haible, Marcus Daniels 1994-1997
Copyright (c) Bruno Haible, Pierpaolo Bernardi, Sam Steingold 1998
Copyright (c) Bruno Haible, Sam Steingold 1999-2000
Copyright (c) Sam Steingold, Bruno Haible 2001-2018

Type :h and hit Enter for context help.

[1]>
```

# 終わり

手順としてはめちゃくちゃ簡単でした。その割に探すのに若干手間取りました。

調べ方の勉強も必要ですね。

Clispについては[こちら](https://clisp.sourceforge.io/)を参照してください。

## 参考

[Common Lispを触る（CLISP） - 気が向いたら書くやつ](https://soratobi96.hatenablog.com/entry/20190504/1556981919)
MacでRARファイルをコマンドラインで解凍する(unrar)

# はじめに
Macでは、標準でRARファイルを解凍することができません。そこでこの記事では`unrar`をインストールして、それを用いて解凍する方法を説明します。
こちらの環境は以下の通りです。

- macOS Big Sur 11.2.3 (Intel)
- Homebrew 3.1.3-52-g813f751-dirty
- UNRAR 6.01

# `unrar`のインストール
以下の記事にあるとおり、`brew install unrar`では現在インストールできないため、次のようにします。

```shell
$ brew install carlocab/personal/unrar
```

https://qiita.com/shimizumasaru/items/7e57bb5c506c0ae4eb80

# 解凍
使い方は`unrar`と叩いて出てくる説明を読めば良いですが、ここでは主なコマンドを説明します。

- `unrar x example.rar`: ディレクトリ構造を保持したままexample.rarを解凍します。基本的にこれを使っておけばよいと思います。
- `unrar e example.rar`: ディレクトリ構造を保持せずexample.rarを解凍します。もし同じ名前のファイルが別ディレクトリにある場合、上書きしても良いか聞かれます。

```
UNRAR 6.01 freeware      Copyright (c) 1993-2021 Alexander Roshal

Usage:     unrar <command> -<switch 1> -<switch N> <archive> <files...>
               <@listfiles...> <path_to_extract\>

<Commands>
  e             Extract files without archived paths
  l[t[a],b]     List archive contents [technical[all], bare]
  p             Print file to stdout
  t             Test archive files
  v[t[a],b]     Verbosely list archive contents [technical[all],bare]
  x             Extract files with full path

(以下略)
```
縦横幅がinline-block要素のように可変なものを中央配置させたい。CSS

👋こんにちは。僕は、watnowでUX/UIデザインをしています。
縦横幅がinline-block要素のように可変なものを中央配置させたいと悩んでいたらしれっとメンバーが教えてくれたのでそれを紹介します。
#結果とコード
モーダルで使用することが多いと思うのでそのスタイルで書いています。
![Screen Shot 2021-04-23 at 11.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369367/0403ea76-3310-2ad3-fd84-b326566e89ff.png)
![Screen Shot 2021-04-23 at 11.21.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369367/51644052-23f4-0ed2-018c-5cfeace55b35.png)
![Screen Shot 2021-04-23 at 11.23.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369367/22ef165f-a743-4260-d4a5-2e4b6765b843.png)

```hoge.css
.wrapper {
 display: flex;
 position: fixed;
 justify-content: center;
 align-items: center;
 background-color: rgba(26, 32, 35, 0.8);
 margin: auto;
 top: 0;
 bottom: 0;
 left: 0;
 right: 0;
}
.contents {
 min-width: 360px;
 max-width: 80%;
 height: auto;
 min-height: 360px;
 background-color: #fff;
 padding: 24px;
 display: inline-block;
}
```

#おわりに
[json to csv](https://jsontocsvconv.com/)というJSONをCSVに変換するツールをメンバーと作ってみたので是非使ってみてください。

https://twitter.com/watnows/status/1385182004782637056
Laravel Sanctum導入環境でブラウザ→認証不要なAPIへのアクセスがCSRFエラーで弾かれる

# 問題
LaravelでAPIを作っていて、後からSanctumでユーザー認証を導入しました。この結果、**認証の必要なAPIと必要のないオープンなAPIがあります**。この状況で検証環境に上げてブラウザーから認証の必要のないAPIへアクセスしたところ、突然CSRFエラーが出てアクセスできなくなりました。
実装したばかりの、認証の必要なAPIでエラーが出るならともかく、**認証とは関係のないAPIでエラーが出る**ってどういうこと！？😯

# 原因
- [Sanctumを導入する際に、APIに対してミドルウェアを仕込んだ](https://readouble.com/laravel/8.x/ja/sanctum.html#installation)と思います。このミドルウェアが、ブラウザからのアクセスの場合のみCSRFトークンのチェックを行うミドルウェアを呼び出す処理を行っています。
- つまりブラウザからのアクセスの時は**認証とは関係なく全APIにCSRFトークンのチェックが入ります**。

# 対処法
二通り考えられて、ブラウザ→認証不要なAPIへのアクセスも、ちゃんとCSRFトークン仕込んで対策するというのが一つ。/csrf-cookieにアクセスして云々ってやつですね。
もう一つは割り切って、オープンなAPIに関してはCSRF対策の除外設定にしてしまう手もあります。APIの性質にもよりますが、CLIアクセス受け付けるのであれば、ブラウザ経由だけ取り締まってもしょうがない部分もあるので、妥当なケースもあるかと。
やり方は[CSRF保護の項目](https://readouble.com/laravel/8.x/ja/csrf.html)に載っています。きっかけがSanctumなのでそっちを見がちですが、認証とCSRF保護は別物なので載ってません。注意。

>通常、これらの種類のルートはroutes/web.phpファイル中で、App\Providers\RouteServiceProviderがすべてのルートへ適用するwebミドルウェアグループの外側に配置する必要があります。**ただし、VerifyCsrfTokenミドルウェアの$exceptプロパティにURIを追加してルートを除外することもできます。**

```php
//
<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * CSRF検証から除外するURI
     *
     * @var array
     */
    protected $except = [
        //ここにCSRFトークンの検証をしないAPIのURLを指定
    ];
}
```

これで解決！🎉


# 🙏Laravel公式ドキュメント翻訳者への支援のお願い
Laravelの公式ドキュメントの日本語版である[ReaDouble.com](https://readouble.com/)を運営されている川瀬裕久氏が、広告収入の低下と持病の悪化のため、翻訳プロジェクトを継続することが困難になり、[GitHub sponsorsを募集しています。](https://github.com/sponsors/HiroKws) 日本のLaravelユーザーでここを見たことない人はいないと思うので、もし恩義を感じているならば是非支援のほどお願いします。私も支援させていただいております
ブラウザバックをトリガーにして、popstateイベントを発火させる方法

やっとやり方を理解したので、メモ程度に残しておきます。

# 結論
Q：ブラウザバックをトリガーにしてイベントを発火させるのに、必要なことは？
A：historyAPI と popstateイベント

◆historyAPIとは...
ブラウザの履歴を追加・更新することができるwebインターフェースのこと

◆popstateとは...
ブラウザの履歴が変更された場合に発火するイベントのこと

# 認識しておくべきこと

それは
　**対象としたい２画面間のブラウザバックでは、期待するタイミングでpopstateイベントは発火してくれない**
です。

なので、擬似的にブラウザバック時の履歴の変更を検知するようにします。

# 以下は実装イメージ
## やりたいこと
![スクリーンショット 2021-04-23 11.18.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668701/a9902761-53a6-5725-dfc1-07360eefdc92.png)
上記、右のA画面から左のZ画面へ遷移する際にpopstateイベントを発火させたい。


## popstateイベントが発火するまで

1. `http://z.jp` から `http://a.com` に遷移。

![スクリーンショット 2021-04-22 23.17.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668701/ff09f7cc-dd45-9267-a69d-2134bd757d84.png)


2. `http://a.com` のJavaScriptで、`history.pushState()` を実行し、履歴を追加する。
※この際、履歴上はpushしたURL（一番右のA画面）に移るが、historyAPIを使って履歴を変更した場合、画面ロードが走らないため、**画面はpush前のURLの画面（真ん中のA画面）が表示**されている。
![スクリーンショット 2021-04-22 23.17.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668701/67f16dd0-808c-1af3-22dc-d3551d151a6c.png)

`history.pushState`の挙動を整理すると
　・変化するもの：履歴, アドレスバーの値
　・変化しないもの：表示されている画面


3. ブラウザバックを行うと、履歴が前に戻るため、この履歴の変化を検知した`popstate`イベントが発火する。
![スクリーンショット 2021-04-22 23.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668701/25e0e4c9-57f3-c5fb-8761-fd66fa11b475.png)


# まとめ
この記事で一番伝えたかったことは。。。
本来は以下のイラストのタイミング↓でブラウザバックを検知したくても
![スクリーンショット 2021-04-23 11.18.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668701/a9902761-53a6-5725-dfc1-07360eefdc92.png)

実装するときは以下のタイミング↓でブラウザバックを検知する必要があるよ
![スクリーンショット 2021-04-22 23.17.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668701/25e0e4c9-57f3-c5fb-8761-fd66fa11b475.png)

ということを伝えたかったです。

自分はこの理解に時間がかかってしまったので、このメモが誰かの参考になれば、と思います。
最後まで読んで頂きありがとうございました！

# 参考サイト
[ブラウザの「戻る」ボタンをJavascriptで検知するイベント代替案](https://yutaihara.com/archives/512)
【環境構築】Eclipseでペアプログラミングをする

#目的

VSCodeではLiveshareができるのだから、eclipseとかでもできるのでは？という疑問から

eclipseでできないか調べてみたところsarosというオープンソースのリモートペアプロツールを発見

備忘録として環境設定方法を残す


##環境

- Mac
- Eclipse_2021-03


##状況
- Eclipse_2021-03は導入ずみ


##事前に準備すること

- スカイプのアカウントを作成
- Jabber アカウントを作成

###sarosを導入する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/1d2a5a5f-2f55-a796-7037-67dcbdf433b5.png)

###「ヘルプ＞eclipseマーケットプレース」を選択、sarosを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/3b593498-74ab-3c88-9f05-deae6ada6efb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/79bb5da7-930a-5bc2-55f8-8d98af13375b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/5e272b44-551f-acc5-0147-e20fffe2ddd8.png)

###作成したJabberアカウントの情報を入力
- 「次へを選択」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/880ea9e5-fef8-2866-46eb-020cb44e93db.png)

###全ての項目に✅ をつける
- 作成したskypeの名前を入力する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/9fffc897-25d6-7930-efee-df8a74c2e628.png)

###好きな色を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/321db8f3-b920-1a66-31a2-ed48d500228d.png)

###プロジェクトの共用を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/b140e8cf-0cf3-3feb-2f65-da4d82f23590.png)

###共有したいプロジェクトを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/1ad7f813-d93f-9e4d-571b-31aa9895d226.png)

###連絡先の追加を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/313771/31a11eae-31e4-5baa-06db-3ef0bb905c39.png)



参考にした記事（いつもありがとうございます）
---
https://github.com/saros-project/saros
UbuntuでCapsLockをCtrlにする

```
sudo vim /etc/default/keyboard
```

```sh:/etc/default/keyboard(変更前)
# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="jp"
XKBVARIANT=""
XKBOPTIONS=""

BACKSPACE="guess"
```

```sh:/etc/default/keyboard(変更後)
# KEYBOARD CONFIGURATION FILE

# Consult the keyboard(5) manual page.

XKBMODEL="pc105"
XKBLAYOUT="jp"
XKBVARIANT=""
XKBOPTIONS="ctrl:nocaps"

BACKSPACE="guess"
```
git でsshでエラーとなるときにconfigパスの設定方法について

```mac:terminal
ssh -T git@github.com

git@github.com: Permission denied (publickey).
```

ssh-add していないとのこと。

```mac:terminal
ssh -T git@github.com

git@github.com: Permission denied (publickey).
```

鍵しても、ssh-addを忘れていると上記エラーが出ることがあります。
まずは「ssh-add -l」して状態を確認。
読み込んでほしい秘密鍵のパスがちゃんと出てこればOKです。
出てこなければ、ssh-addする。

eval `ssh-agent`
ssh-add ~/.ssh/id_rsa


それでもだめなら

```mac:terminal
cat config
```

以下追加

```mac:terminal
cat config
Host github
  HostName github.com
  IdentityFile ~/.ssh/id_rsa_github #→ここの宛先を変更する
  User git
```

以上
JavaScript学習(ES6) 基礎編　~アロー関数とは？~

こちらではJavaScript学習の備忘録を記載しております。
プログラミング初心者、関心をお持ちの方々の参考になれば幸いです。
* * *
#### アロー関数とは？

アロー関数とは、下記のように 「**function( )**」を「**( )=>**」と書く、関数の記述方法のこと。
(上記以外は、定義方法、呼び出し方も以前と変わらず)
ES6から導入された新しい書き方で、functionを用いるよりシンプルに記述することができる。

```javascript:script.js
// ES6以前
const 定数名 = function() {
  // まとめたい処理
};

// アロー関数
const 定数名 = ()=> {
  // まとめたい処理
};
``` 

```javascript:script.js
const introduce = ()=> {
  console.log("こんにちは");
  console.log("私の名前は佐々木ですよ");
};

introduce();  // 関数を呼び出す

// 実行結果
こんにちは
私の名前は佐々木ですよ
``` 
#### 引数を受け取る

引数とは、関数に与える追加情報のようなもの。
関数を呼び出す時に一緒に値を渡すことで、関数の中でその値を利用することができる。

引数を受け取る関数を定義する際は、「**(引数名) =>**」と括弧の中に引数名を書くことで引数を受け取ることができる。

```javascript:script.js
const 定数名 = (引数名)=> {
  // まとめたい処理
};
``` 

#### 関数の呼び出し

引数を受け取る関数を呼び出すには、「**定数名(値)**」と書く。
関数は、指定した値を受け取り、その値は引数に代入される。

```javascript:script.js
const 定数名 = (引数名)=> {  // ①の呼び出しと一緒に、値が引数に代入される
  // まとめたい処理
};

定数名(値);  // ①関数の呼び出し
``` 


* * *
####おわりに
本当に最初の基本的な部分であります。
今後ともよろしくお願い致します！！
Docker Composeを使ってみる

# はじめに
`docker-compose up`でコンテナ起動できるのは知っているけど、じゃあその定義はどうやるのか？という疑問から
[前回](https://qiita.com/alpha083/items/601bffc4a0ac1978e116)に引き続き、今回も「自分でもやってみよう」という試み。


# Docker Composeについて
## Docker Composeとは
簡単に言うと、コンテナの作成や停止などの一連の操作をまとめて実行できるようにする仕組み。`docker-compose.yml` という定義ファイルを用意し、読み込ませることで実行できる。
特に複数コンテナを連動させるアプリケーションを開発する際に便利。

# Composeファイルを作成する
今回は「WordpressコンテナとMySqlコンテナを連動させる」ためのComposeファイルを作ってみる。

**docker-compose.ymlファイルを作成する**

```
type nul > docker-compose.yml
```

`docker-compose.yml`の中身は下記のようにする。
今回は最低限の記述しかしていない。

```
version: '3.8'

services:
  mysql:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: rootpass
      MYSQL_DATABASE: wordpressdb
      MYSQL_USER: hoge
      MYSQL_PASSWORD: hogehoge

  wordpress:
    depends_on:
      - mysql
    image: wordpress
    ports:
      - 8080:80
    restart: always
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_NAME: wordpressdb
      WORDPRESS_DB_USER: hoge
      WORDPRESS_DB_PASSWORD: hogehoge
```

冒頭の`version`はDocker Composeのバージョン（バージョンによって記法が違うことがあるので冒頭で指定する）。

`services`に必要なコンテナを定義し、その中にコンテナごとの詳細を記述していく。
`image`は起動するイメージ名、`ports`はポート指定、
`restart`は起動に失敗した際の再起動設定で、指定した`always`は再起動を繰り返す。
`environment`は環境変数の設定。

接続するネットワークを指定したい場合は`networks`を定義する。

wordpressの`depends_on`とは依存関係で、WordpressはMysqlに依存したサービスのため
必ずMysqlが先に起動・後に停止するように明示する。


**イメージのダウンロード**

`docker-compose pull`することで、`docker-compose.yml`に定義したサービスのイメージをまとめてpullできる。（※コンテナの起動はしない）

```
docker-compose pull

Pulling mysql     ...
Pulling wordpress ...
```

pullするサービスを指定したい場合は `docker-compose pull {service-name}`

もちろん別途個別にpullしてもOK。
その際は`docker-compose.yml`に定義するイメージを
pullしたものに合わせて記述する。

**コンテナを起動する**

すべてのコンテナを起動する場合は`docker-compose up`
`-d`オプションはデタッチモード指定で、
バックグラウンドでコンテナを起動することができる。

すると`docker-compose.yml`に定義した順にサービスが実行され、コンテナが起動する。

```
docker-compose up -d

Creating network "docker-compose_default" with the default driver
Creating docker-compose_mysql_1 ... done
Creating docker-compose_wordpress_1 ... done
```

実行するサービスを指定してコンテナ起動させたい場合は `docker-compose up -d {service-name}`

**サービスの稼働状態を確認する**

`State`が`Up`になっていれば、問題なくコンテナが起動している。

```
docker-compose ps

           Name                         Command               State          Ports
------------------------------------------------------------------------------------------
docker-compose_mysql_1       docker-entrypoint.sh mysqld      Up      3306/tcp, 33060/tcp
docker-compose_wordpress_1   docker-entrypoint.sh apach ...   Up      0.0.0.0:8080->80/tcp
```

WordpressにアクセスできればOK！

**サービスを停止する**

```
docker-compose stop
```

サービスを再起動するには、起動中であれば`restart`
停止中であれば`start`

`docker-compose.yml`を再実行したい場合は`up`

**サービスを終了する**

```
docker-compose down
```

##error establishing a database connection対処方法

Wordpressにアクセスした際に`error establishing a database connection`（データベース確立エラー）になる場合は、
`docker-compose.yml`で両サービス`restart: unless-stopped`に変更して試してみる。

※こちらの記事を参考にしました
[docker-compose wordpress mysql connection refused - Stack Overflow](https://stackoverflow.com/questions/34068671/docker-compose-wordpress-mysql-connection-refused)

---

お疲れさまでした！
JavaScript学習(ES6) 基礎編　~関数とは？~

こちらではJavaScript学習の備忘録を記載しております。
プログラミング初心者、関心をお持ちの方々の参考になれば幸いです。
* * *
#### 関数とは？

関数とは、『**様々な処理を1つにまとめて、名前をつけることができる**』もの。

処理を１つにまとめることで、同じ処理を何度も書く必要がなくなり、記述ミスが減り、別のプログラムに使い回すことも可能になる。
また関数は、受け取ったり、何らかの処理を行なった値を返すことも可能である。

#### function(関数)の定義

下記のように関数を用意することを、**関数を定義する**と呼ぶ。
**function**より後ろの部分が関数を表しており、定数に代入することで関数を定義している。

```javascript:script.js
const 定数名 = function() {
  // まとめたい処理
};
``` 

#### 関数の呼び出し

関数を定義しただけでは、その中の処理は実行されない。
処理を実行するためには、下記のように関数の定義に使用した定数名を用いて
**定数名( )**と記述する必要がある。
これを**関数の呼び出す**と言う。

```javascript:script.js
const introduce = function() {
  console.log("こんにちは");
  console.log("私の名前は佐々木ですよ");
};

introduce();  // 関数を呼び出す

// 実行結果
こんにちは
私の名前は佐々木ですよ
``` 

* * *
####おわりに
本当に最初の基本的な部分ですが、時間が空いちゃうと忘れてしまうので投稿しました。
今後ともよろしくお願い致します！！
errorメッセージ部分テンプレート作ってみた



```rb:app/controller/ordercontroller.rb
  def create
    @order = Order.new(order_params)
    # binding.pry
    if @order.valid?
      @order.save
      return redirect_to root_path
    else
      render 'index'
    end
  end

  private

  def order_params
    params.require(:order).permit(:price)
  end
```

部分テンプレートでindexでrenderで呼び出しました。

```rb:app/view/layouts/_error_messages.html.erb
<% if model.errors.any? %>
  <div class="error-alert">
    <ul>
      <% model.errors.full_messages.each do |message| %>
        <li class='error-message'><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>
```

結果
-
![20210423-110054.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/4a0ec944-9507-79a4-3945-bb497a024a27.png)


成功です。
AzureでもSSHキーペアを管理できるようになった！

#はじめに
2020年の冬あたりから、Linux VMの作成時に自動的にSSHのキーペアを生成・管理してくれる
「SSHキー」というサービスが出現しました。

#何が変わったの？
###今までは:
鍵認証を使ったSSH接続をするときは、
事前にクライアントで`ssh-keygen`などをつかってキーペアを作成し、VMの作成時に公開鍵を貼り付けなければいけませんでした。
###これからは:
VMの作成時に勝手にSSHのキーペアを生成して、AWSのKMSみたいに保管・管理してくれるようになりました。
→VMごとにキーペアを生成することもできるし、管理もしてくれて便利！

これまで通り、自分で生成した公開鍵をアップロードすることもできますし、パスワード認証を使用することもできます。

キーペアを生成する手順は、次の2通りあります。

1. Linux VMの作成時にキーペアを生成して、秘密鍵をダウンロードする
1. 事前にAzureポータルでキーペアを生成してからVMをつくる

なお、1.の方法では現在のところVMの作成時にエラーが頻発するようなので、参考程度にご覧くださいませ。

#やってみよう
###まずは1.の手順の「VMの作成時にキーペアを生成する」方法をかきます。

1. いつもの感じで仮想マシンの作成のページに行きます。
1. ウィザードの真ん中らへんの「管理者アカウント」の項目をご覧ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/618fb498-efdc-2747-f3ac-30b999f26f93.png)
「SSH公開キーのソース」という項目で「新しいキーの組の生成」を選択すると、VMを作成したときにAzureがキーペアを生成して、EC2みたいに秘密鍵のpemファイルをダウンロードすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/a9048e62-8c01-8c89-d0b9-d031f65a2a61.png)
他にも下に説明している2.の方法で事前に作っておいたキーペアを指定することもできますし、これまで通り`ssh-keygen`を使って生成したキーペアの公開鍵を貼り付けることもできます。

1. VMの作成を押すと、下のようなダイアログが出るので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/055ab473-548d-291f-dbf3-7ee4041611b6.png)
青いボタンの「秘密キーのダウンロードと...」をクリックするとpemファイルがダウンロードされます。
1. あとはpemファイルを使っていつものクライアントで鍵認証でVMに接続するだけ！

###2. 事前にキーペアを生成しておく
>この手順は、公式ドキュメントにも書かれているので 参考にしてくださいね！
https://docs.microsoft.com/ja-jp/azure/virtual-machines/ssh-keys-portal

1. Azureポータルの左側のメニューから「すべてのサービス」をクリックします。
1. 上の検索窓に「SSH」と入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/efbe18bf-5ed9-1e16-8637-f5599306aa81.png)
そうすると、「SSHキー」というサービスが出てくるので、クリックします。

3. そのまま上のほうの「+作成」をクリックします。
3. このような画面が出てくるので、各項目を埋めてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/54e33b29-93b7-2fa6-daf0-d5c4574e63e1.png)
「リソースグループ」は、**後にVMを作成するリソースグループと同じにしてしまうとエラーが出るので、SSHキー専用のリソースグループを作っておくことをおすすめします**。
(私はこのエラーで結構つまづきました...)

「キーの組名」はキーペアにつける お好きな名前を入力してください。

4.VMの作成を押すと、下のようなダイアログが出るので、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/ade77e6b-23bc-4ca4-d96a-d9885de6366c.png)

青いボタンの「秘密キーのダウンロードと...」をクリックするとpemファイルがダウンロードされます。
***
以上になります！
EC2みたいになったので便利になりましたね！

よいAzureライフを！
OculusQuestでMRTKするときの参考資料

# QuestでもMRTKを使いたい
Oculus IntegrationよりもUIがリッチなので、MRTKを使用する方法を調べてみました。

## GitHub
https://github.com/provencher/MRTK-Quest

## 日本語の環境設定記事

https://qiita.com/OKsaiyowa/items/ce7769816721ea351f05

https://note.com/npaka/n/n159027eb708c

## 環境設定動画(英語)
https://www.youtube.com/watch?v=rHQvQVHYMHw
基本的な関数の流れ

関数について自分なりの解釈

#なぜ関数を使うのか
関数とは、１つの処理をまとめてくれています。
例えば、税込み計算をしたいときがあったとします。

①りんごとバナナとメロンのそれぞれの計算をしたい。
②１つずつ計算するのは面倒だ。
③じゃ、税込み計算してくれる自動販売機を作ろう

こんな感じの流れでしょうか。

```index.js
 function total (price) {
   const tax = 0.08;
   return price + price * tax;
  }
```
これが、自動販売機になります。
ここでカッコがあります。これは、引数といいます。この部分を私の中では、コインの投入口だと思っています。
この引数は、関数スコープ内で使うことができます。

定数taxに消費税８％を代入します。
リターン（自動販売機でいう取り出し口）に計算結果を出力します。

これで、税込み計算を行ってくれる自動販売機はできました。

これが、引数（コイン）になります。

```index.js
console.log(total(2000));
```

2160円になるかなと思います。
基本的な関数はこの流れです。


消費税は８％じゃなくて、10％だよってなっても値を変えるだけになります。