OmniAICreator/Qiita-1.07M huggingface dataset:
2 文字列操作1 Dif:6 ABC197 A：「AtCoder　凡人が『緑』になるための精選50問詳細解説」サンプル

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

前：https://qiita.com/sano192/items/eb2c9cbee6ec4dc79aaf
次：https://qiita.com/sano192/items/4432b669a04e69287c05

https://atcoder.jp/contests/abc197/tasks/abc197_a

**【目標】**
・文字列の扱い方を身につける

**【概要】**
こちらも「1 入力と出力」同様、よくあるA問題。pythonにおける文字列の扱い方を覚えよう。

**【方針】**
文字列について、pythonでは先頭の文字が「0文字目」、その次が「1文字目」、...と数えられる。
(“ABC”であれば0文字目は”A”、1文字目は"B"、2文字目は”C”となる)

解き方は文字列を受け取り、1文字目、2文字目、0文字目の順に連結して出力するだけ。

**【実装】**
まず文字列を受け取る(入力の受け取りがわからない人は「1 入力と出力」を参照してほしい)

```python:
S=input()
```

次に1文字目、2文字目、0文字目の順に連結したものを作る。
例えば1文字目を取り出したいときはS[1]のように記載する。
(S=”ABC"ならS[1]は”B")

連結したいときは+で繋げばOK。
(”ABC”=”A”+”B”+”C”)

```python:
ans=S[1]+S[2]+S[0]
```

1文字目、2文字目、０文字目の順に連結した答えをans(=answer)に格納する。

最後にansを出力する。

```python:
print(ans)
```

**【コード全文】**

```python:
S=input()
ans=S[1]+S[2]+S[0]
print(ans)
```

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

前：https://qiita.com/sano192/items/eb2c9cbee6ec4dc79aaf
次：https://qiita.com/sano192/items/4432b669a04e69287c05
Ubuntu環境を新しく作ったときにやること（備忘録・随時更新）

## 日本語入力

```bash
$ sudo apt install fcitx-mozc
```

## ホームディレクトリを英語に

```bash
$ sudo apt install xdg-user-dirs-gtk
$ LANG=C xdg-user-dirs-gtk-update
```

## 「CapsLock」と「Ctrl」を入れ替える

```bash
$ sudo vim /etc/default/keyboard
```
以下の設定を追加

```bash
XKBOPTIONS="ctrl:nocaps"
```

## プログラミングフォントの導入

ファイルをダウンロード

https://myrica.estable.jp/

```
sudo cp MyricaM.TTC /usr/share/fonts/truetype/
fc-cache -fv
```

## escキーでIMEをOFFにできるように

```bash
$ vim ~/.config/fcitx/conf
```

```bash
InactivateKey=ESCAPE CTRL_[
```

Mac + Google日本語入力の場合は「環境設定」→「一般タブ」→「キー設定の選択」に以下を追加

* モード:入力文字なし
* 入力キー: Escape
* コマンド: キャンセル後IMEを無効化

## （Lubuntuで）superキー+十字キーでウィンドウを上下左右に並べる

```bash
$ vim ~/.config/openbox/rc.xml
```

`<keyboard>`内に以下を追加。

```xml
    <!--
        Lubuntu specific.
        Keybindings for window tiling
    -->
    <!--
        # HalfLeftScreen
    -->
    <keybind key="W-Left">
      <action name="UnmaximizeFull"/>
      <action name="MoveResizeTo">
        <x>0</x>
        <y>0</y>
        <height>100%</height>
        <width>50%</width>
      </action>
    </keybind>
    <!--
        # HalfRightScreen
    -->
    <keybind key="W-Right">
      <action name="UnmaximizeFull"/>
      <action name="MoveResizeTo">
        <x>-0</x>
        <y>0</y>
        <height>100%</height>
        <width>50%</width>
      </action>
    </keybind>
    <!--
        # HalfUpperScreen
    -->
    <keybind key="W-Up">
      <action name="UnmaximizeFull"/>
      <action name="MoveResizeTo">
        <x>0</x>
        <y>0</y>
        <width>100%</width>
        <height>50%</height>
      </action>
    </keybind>
    <!--
        # HalfLowerScreen
    -->
    <keybind key="W-Down">
      <action name="UnmaximizeFull"/>
      <action name="MoveResizeTo">
        <x>0</x>
        <y>-0</y>
        <width>100%</width>
        <height>50%</height>
      </action>
    </keybind>
    <!--  Lubuntu specific : Keybindings -->
```


## Gitの認証情報を安全に保存（パスワードを毎回入力しなくていいように）

```bash
$ sudo apt-get install libsecret-1-0 libsecret-1-dev
$ cd /usr/share/doc/git/contrib/credential/libsecret
$ sudo make
$ git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
```

### 参考

* https://qiita.com/RayDoe/items/ea945a3b6583d5c01d1e
* https://xvideos.hatenablog.com/entry/ubuntu_setup
* https://www.yokoweb.net/2019/08/07/ubuntu-18_04-desktop-caps-ctrl/
* https://qiita.com/iberianpig/items/f43afb9d5ec0e2509695
* https://qiita.com/Tebasaki314/items/da230ccc9ac891f4ba25
[08] PowerShell実践例 ... 複数のPowerShellスクリプトを並列実行する


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/0b0605257ad39bc22895|


# はじめに

ある PowerShell スクリプトから、マルチプロセス (== バックグラウンド) で 2つの PowerShell スクリプトを並列実行させたときの実装を書き残しておく.
図や Bashスクリプト にすると次である.

ここでは並列実行される「Sub1」と「Sub2」の呼び出し処理についてである.
なお、呼び出し元である「Main」における「Sub1」と「Sub2」の終了待ちコードについては記載しない.

**シーケンス図**

```plantuml
@startuml
participant Main

create Sub1
Main ->> Sub1 : new
activate Sub1

create Sub2
Main ->> Sub2 : new　　　         
activate Sub2

Sub1 --> Main
deactivate Sub1

Sub2 --> Main
deactivate Sub2

note over Main: Wait
@enduml
```

**Bashコード**

```bash
./sub1.ps1 引数 &
$PID1=$!

./sub2.ps1 引数 &
$PID2=$!

wait $PID1 $PID2
```

# 実装

## 前提条件

ここでは次のようにする.

・プロセス「Sub1」に該当するコードを「sub1.ps1」とする
・プロセス「Sub2」に該当するコードを「sub1.ps2」とする


## 1. 「Main」から「Sub1」を別プロセスとして呼び出す

「Sub1」の引数として、作業ディレクトリ($W)のパスを渡す

```powershell
# 「Sub1」に引数 $W を渡して別プロセスとして実行する.
$W = 'C:\work'
# Start-Process が別プロセスでの呼び出しとなる. Bash での「&」に該当する
$CLI1 = "Start-Process powershell -ArgumentList .\sub1.ps1, {0}" -f $W
# Bash での eval $CLI1 である. 今回は戻り値を受け取るようにした
$local:RET1 = Invoke-Expression $CLI1
```

## 2. 「Main」から「Sub2」を別プロセスとして呼び出す

「Sub2」の引数として、作業ディレクトリ($W)のパスを渡す

```powershell
# 「Sub2」に引数 $W を渡して別プロセスとして実行する.
$W = 'C:\work'
# Start-Process が別プロセスでの呼び出しとなる. Bash での「&」に該当する
$CLI2 = "Start-Process powershell -ArgumentList .\sub2.ps1, {0}" -f $W
# Bash での eval $CLI2 である. 今回は戻り値を受け取るようにした
$local:RET2 = Invoke-Expression $CLI2
```

## 3. 「Main」で「Sub1」と「Sub2」の終了を待つ

このときは次のような実装をした

```
・「Sub1」および「Sub2」は、ジョブが終了したら Git リポジトリに結果を Push する.

・「Main」は 同 Git リポジトリを一定周期で監視する

・「Main」は待機時間の上限に逹したら、「Sub1」「Sub2」を強制停止させる

・「Main」では、「Sub1」「Sub2」が発生させた例外を捕捉するようにしている
```

　

## コード全文

```powershell
# 「Sub1」に引数 $W を渡して別プロセスとして実行する.
$W = 'C:\work'
# Start-Process が別プロセスでの呼び出しとなる. Bash での「&」に該当する
$CLI1 = "Start-Process powershell -ArgumentList .\sub1.ps1, {0}" -f $W
# Bash での eval $CLI1 である. 今回は戻り値を受け取るようにした
$local:RET1 = Invoke-Expression $CLI1

# 「Sub2」に引数 $W を渡して別プロセスとして実行する.
$W = 'C:\work'
# Start-Process が別プロセスでの呼び出しとなる. Bash での「&」に該当する
$CLI2 = "Start-Process powershell -ArgumentList .\sub2.ps1, {0}" -f $W
# Bash での eval $CLI2 である. 今回は戻り値を受け取るようにした
$local:RET2 = Invoke-Expression $CLI2

## 3. 「Main」で「Sub1」と「Sub2」の終了を待つ
<#
・「Sub1」および「Sub2」は、ジョブが終了したら Git リポジトリに結果を Push する.

・「Main」は 同 Git リポジトリを一定周期で監視する

・「Main」は待機時間の上限に逹したら、「Sub1」「Sub2」を強制停止させる

・「Main」では、「Sub1」「Sub2」が発生させた例外を捕捉するようにしている
#>


```
[OutSystems]BDDFramework Client SideのAPI実行

最近追加された、OutSystemsのClient Actionに対してユニットテストを書けるモジュール、BDDFramework Client Side。
このモジュールにも、BDDFrameworkと同じREST APIが提供されていて、外部から自動実行させることができます。

# 確認環境
Personal Environment(Version 11.12.0 (Build 30002))
Service Studio (Version 11.11.9)
[BDDFramework Client Side](https://www.outsystems.com/forge/component-overview/10917/bddframework-client-side) (Version 1.0.0)

# REST APIでのテスト動作の仕組み
以下の図で操作の流れを説明します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/54130a13-7b11-ed93-3854-e6373a3175f0.png)

①：利用者が、TestRunner_APIモジュールにあるREST APIに実行をリクエスト
②：REST APIは、内部でTestRunner_Ext ExtensionにあるActionを起動
③：Actionは、PuppeteerSharpというライブラリを経由してChromiumをサーバー上で操作
④：渡されたパラメーターからテスト対象画面のURLを決定し、Chromiumに開くことでテストを実行する。実行が完了したことを検知すると、テストスイートのJavaScriptオブジェクトをJSONに変換する関数を実行して結果を取り出す

# API実行方法
## 事前準備
BDDFrameworkClientSideをブラウザでプレビューすると、Welcome Screenが以下の通り開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/d184baa5-99d5-f62a-0dc8-70577a8c4e08.png)

テストをAPI経由で実行するためには、この画面でChromiumをサーバーにインストールしておく必要があります。
インストール作業はボタンを押すだけ。背後で、必要なファイルのダウンロードと保存が行われます。

一度ダウンロードしておけば、Welcome画面の「Chromium Status」が「Chromium is correctly installed.」に変わるのでわかります。

## API
Forgeからインストールしたアプリケーション内に、TestRunner_APIというモジュールがあります。
このモジュールのLogicタブ > Integrationsフォルダ > RESTの下に、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/500549c2-df54-bb08-4a82-94c79f506852.png)

というAPI。
2つありますが、処理はほぼ同じ。ここでは、v2の方のインターフェースを見ていきます。

なんで出たばかりのモジュールにv1とv2の2バージョンのAPIがあるのかというと、（Client Sideではない）BDDFrameworkに合わせたものと思われます。

BDDFramework APIのバージョンの違いについては、以下を参照してください。
[API V2](https://qiita.com/jyunji_watanabe/items/5081deefecefbca63896#api-v2)

## パラメータの確認
ここでは、動作確認に必要な分だけ見ていきます。

- TestESpace：BDDFramework Client Sideを利用して作成した「テストケースを含むモジュール名」
- TestSuiteScreen：上記モジュール内で、実行したい「テストスイート画面名」

必須なのは上記2つのみ。

APIのURLは、

    https://OutSystems環境のホスト/TestRunner_API/rest/v2/BDDTestRunner/「テストケースを含むモジュール名」/「テストスイート画面名」

TestESpaceとTestSuiteScreen以外のパラメータはheader渡しであるため、HTTPリクエストのヘッダーに詰めて渡す。テストするときはPostmanとかFiddlerが便利ですね。API動作確認が目的であれば、指定不要です。

実行結果はJSONで返ってきます。テストスイート内での成功ケース数、失敗ケース数、各ケースのidやDescriptionなど。

# PEでの動作について
API経由でのテスト実行は、Personal Environmentではサポートされていません。
ドキュメントによると、Chromiumをサーバーにインストールする権限がないためとのこと。

Chromiumのダウンロードは、TestRunner_Ext ExtensionのDownloadChromium Actionで行います。このActionはPuppeteerSharpを使っています。実はUltimatePDFという別のForgeコンポーネントもこれを使っていて、そちらはTempフォルダにダウンロードすることで権限問題を回避しているようです。つまり、この方法を取れば、BDDFramework Client SideをPersonal Environmentで実行することは不可能ではないことに。

# 関連
[Client Action用のBDDFrameworkのチュートリアル](https://qiita.com/jyunji_watanabe/items/3c5e1f40bf9b00925fc9)
SQL WHERE句で集約関数を使う

Every Qiita #26
のんびり独学初学者投稿 26日目
今回は・・・
sqlの基本を復習した時の備忘録です。

###指定カラムの平均値よりも高いレコードを選択したい
ポートフォリオ作成の中で上記のようなデータのみを取得したい時に少しはまったのでメモ程度に残しておきます。
データはサンプルとして下記のような状態とします。

**stationeryテーブル**

| name | price |
| ---- | ---- |
| 鉛筆　| 100 |
| ハサミ　| 200 |
| ホッチキス　| 250 | 
| クレヨン | 400 |
| 消しゴム | 180 |
| のり | 170 |
| ノート | 300 |

この中から平均金額より高い文房具のみを取得します。
「平均値を出してwhereで絞り込めばいいんだね。了解。」

```sql
SELECT name, price FROM  stationery WHERE price > AVG(price);
```
・・・エラーなんだが。なんで？
->あ、WHEREに集合関数は使えないです・・・:cry:

そんなときにサブクエリを使ってみましょう！

```sql
SELECT name, price FROM  stationery WHERE price > (SELECT AVG(price) FROM stationery);
```
| name | price |
| ---- | ---- |
| ホッチキス　| 250 | 
| クレヨン | 400 |
| ノート | 300 |

単一の値を取得する（今回は平均金額)場合のサブクエリをスカラ・サブクエリというみたいです。
SQLの理解浅すぎますね・・・頑張ります！
画像の表示サイズを変形させずに揃える方法

## 解決したい問題
Railsでレシピを投稿できるアプリケーションを作成中、360×260の大きさでレシピ画像を表示したかったのですが、イメージタグにサイズ指定をしただけだと、縦長の画像をアップロードした際、画像が変形してしまいました。

```erb:xxxx.erb
<%= attachment_image_tag @recipe, :recipe_image, size: '360x260', format:'jpeg' %>
```
※画像アップロードにはrefileを使用しています

この画像をアップロードすると↓　　　　　　　　　　　変形してしまう↓
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1591612/eac3023f-5442-c5be-983e-2bda1c62cea8.png" width=40%>　　　　　　　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1591612/29728222-2cb2-4360-6f4e-c5d23e9f2faf.png" width=40%>

この問題を解決してくれる便利なCSSプロパティがあったのでご紹介します！

## 解決方法
#### object-fitプロパティを使う！

```erb:xxxx.erb
<div class="img-container">
  <%= attachment_image_tag @recipe, :recipe_image, format:'jpeg' %>
</div>
```

```css:application.css
.img-container {
  width: 360px;
  height: 260px;
}
.img-container img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
```
画像の幅と高さを指定して、`object-fit: cover;`を追加するだけで中央でトリミングされました！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1591612/39f475a6-6a94-7eb9-5be5-906432d1d0e8.png" width=40%>
object-fitプロパティではcover以外に、縦横比を保持してボックスに収まるようにリサイズしてくれる`contain`や、リサイズせずにそのまま画像を表示する`none`などの値も使えます。
希望の表示形式に合わせて使い分けしてみてください！
Gunicornの設定ファイルの書き方

## はじめに
DjangoやFlaskなどのPythonアプリケーションを動かすwsgiサーバ、Gunicornの設定ファイルの書き方についてまとめてみました。

Gunicornの設定ファイルはPythonのスクリプトとして、各種設定を変数や関数として列挙していく形となる。
中身はPythonスクリプトなので通常のソースコードと同じように、ライブラリをimportしたり、Pythonのプログラムコードを記述することも可能。


## 環境
- Python 3.9
- Gunicorn 20.1

## 設定ファイル
Gunicornでよく使う設定値としては、下記のようなものがある。

```python:settings.py
#
# Gunicorn config file
#
wsgi_app = 'hogeapp.wsgi:application'

# Server Mechanics
#========================================
# current directory
chdir = '/work/python/gunic/gu'

# daemon mode
daemon = False

# enviroment variables
raw_env = [
    'ENV_TYPE=dev',
    'HOGEHOGE_KEY=xxxxxxxxxxxxxxxxxxxxxxxxx'
]

# Server Socket
#========================================
bind = '0.0.0.0:8000'

# Worker Processes
#========================================
workers = 2

#  Logging
#========================================
# access log
accesslog = '/work/python/gunic/gu/logs/access.log'
access_log_format = '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'

# gunicorn log
errorlog = '-'
loglevel = 'info'
```

#### wsgi_app
wsgiのアプリケーションオブジェクト名。`module_name:value`形式でWSGIモジュールを指定する。

#### chdir
Gunicornプロセスが動作する際のカレントディレクトリ。
WSGIアプリケーションの起点となるホームディレクトリを設定しておく。

#### daemon
デーモン(バックグラウンド)モードで起動するか否かの設定値。
`True`ではバックグラウンドでデーモンとして動作するが、`False`ではフォアグラウンドでの動作となる。

#### raw_env
Gunicornのプロセスで使用する環境変数を指定する。WSGIのPythonアプリケーションで使用することもできるため、アプリ内で必要な環境変数類はここで定義する。
`KEY=VALUE`形式の文字列で配列で記述する。

#### bind
GunicornのListenポートとして待ち受けるポートを記載。
`ネットワーク：ポート`の形で指定する。

#### workers
WSGIのワーカープロセス数を指定する。

#### accesslog
Gunicornのアクセスログのファイル名を指定する。`-`を指定すると標準出力に出力される。
これはApacheやnginxのログようなクライアントからのリクエストに関するアクセスログとなる。

#### access_log_format
アクセスログのフォーマット形式。
設定できるパラメータ変数は[公式ドキュメント](https://docs.gunicorn.org/en/stable/settings.html#access-log-format)を参照。
LTSVやJSON(ndjson)形式でログを書き出したい場合は、ここで各フォーマットに適合した形式で設定することで行うことができる。

#### errorlog
Gunicornログのファイル名。`-`を指定すると標準出力に出力される。
`errorlog`という名前になっているが、エラーだけでなくGunicorn本体の動作全般のログとなる。

#### loglevel
errorlog のログレベルを指定する。
指定可能なレベルは、`debug`、`info`、`warning`、`error`、`critical`が指定可能。


## 設定ファイルの使い方
### 通常
gunicornコマンドに、`--config`オプションで作成した設定ファイルを指定することで、使用することができる。

```
$ gunicorn --config /path/to/app/settings.py
```

gunicornコマンドは`--config`オプションと併せて任意のオプションも利用可能。
設定ファイル内で設定された項目と重複して指定した場合、オプション引数側が優先されるため、これを利用して設定値を部分的に差し替えたりすることも可能。

```
$ gunicorn --config /path/to/app/settings.py --chdir /path/to/dev/app
```


### 仮想環境(venv)を利用する場合
Gunicornに限ったことでは無いが、仮想環境(venv)にインストールしたコマンドを利用するには、仮想環境ディレクトリ内にあるGunicornコマンドを利用する。
今回の場合、仮想環境内のgunicornを利用するには、仮想環境ディレクトリ内にあるgunicornコマンドを実行することで、使用することができる。
この場合、Gunicornで実行するアプリケーションも仮想環境の構成を利用して起動される。

```
$ /path/to/venv/bin/gunicorn --config /path/to/app/settings.py
```

## 参考
[Settings — Gunicorn 20.1.0 documentation](https://docs.gunicorn.org/en/stable/settings.html)
Grover Mixers for QAOA

# Grover Mixer QAOA
Grover Mixer QAOA (GM-QAOA)は、組み合わせ最適化問題を解く量子アルゴリズムであるQAOAを、
**制約付き**最適化問題に拡張したアルゴリズムです。

GM-QAOAの論文
https://arxiv.org/abs/2006.00354

なお、QAOAについては、
https://dojo.qulacs.org/ja/latest/notebooks/5.3_quantum_approximate_optimazation_algorithm.html

QAOAで制約付き組み合わせ最適化問題を解く場合、コストハミルトニアン$H_{C}$に、制約違反に対するペナルティーを課す項$H_{penalty}$
を追加した $H_{C} + K*H_{penalty}$を新たなコストハミルトニアンとして設定して最適化することが普通です。
係数$K$が小さすぎると制約違反の解が出力されてしまいますし、大きすぎると制約遵守ばかりを気にして肝心の$H_{C}$が低くない解を出力してしまいます。
$K$は経験的に設定するしかないことが多く、なかなか難しいです。

GM-QAOAでは、解の探索空間を、制約を満たす範囲に限定することが出来ます。
コストハミルトニアンは$H_{C}$をそのまま使えます。

# GM-QAOAの原理

通常のQAOAでは、自明な基底状態を持つハミルトニアン(Mixerハミルトニアン)$H_{mixer}$の元での時間発展$e^{-i\beta H_{mixer}}$と、
コストハミルトニアン$H_{C}$のもとでの時間発展$e^{-i\gamma H_{C}}$を交互に行います。
Mixerハミルトニアンには、問題に関する情報は一切教えられていないため、制約違反となる解も探索してしまうことがあります。

GM-QAOAでは、$H_{mixer}$に制約を教えます。
今、探索空間全体が$n$量子ビットで表現できたとします :  $S = [0,1]^{\otimes n}$
このうち、制約を満たすもの全体の空間を$F$とします。 : $F \subseteq S$
$F$の元$|x \rangle$のうち、最もコスト$H_{C}(|x \rangle)$が低いものがこの問題の解です。

$F$の全ての元$|x \rangle$に対する均等重ね合わせ状態を$|F \rangle$とします。
 $|F \rangle = \sum_{x \in F} |x \rangle$
(規格化係数は省略します）
このとき、GM-QAOAは以下のようなアルゴリズムです。

・初期状態としては、$|F \rangle$を用いる。これはゲート$U_{S}$で準備できるとする：$|F \rangle = U_{S}|0...0 \rangle$
・時間発展は、$H_{mixer} = |F \rangle \langle F|$のもとでの時間発展$U_{M} = e^{-i\beta |F \rangle \langle F|}$を用いる。
コストハミルトニアンの元での時間発展はQAOA同様に$U_{P} = e^{-i\gamma H_{C}}$とする。
両者を交互に繰り返す
・コストハミルトニアンの期待値を測定し、最小となるように、変分パラメータ$\beta, \gamma$を古典ソルバーでアップデート。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878664/4a0165d3-b7eb-e114-b2b3-73e6cd49822c.png)


初期状態は制約を満たすものだけで構成されており、$|F \rangle \langle F|$は制約を満たすもの全体の空間への射影演算子[^1]なので、
この時間発展で制約の"外へ出る"ことはありません。[^2]
よって、探索空間は制約の範囲内に限定されます。

上記のような、「解空間への射影」という技はGroverのアルゴリズムにも見られるため、Grover mixer QAOA という名前がついているようです。

# GM-QAOAの注意点

弱点としては、$|F \rangle$を用意するのに必要な計算量が大きい場合は実用上使えません。
論文では多項式時間が求められるとありますが、多項式時間といっても様々なので、実際はケース・バイ・ケースかと思います。
Groverのアルゴリズムでも、Grover演算子が重くて実機で使えないということはよくあります。
オリジナルのQAOAはNISQでも動くように出来るだけゲートを浅くしたアルゴリズムですが、GM-QAOAはGroverの系譜が入っているのでゲートが深くなる場合があり、NISQとlong-termの**悪いところ取り**になる可能性もあります。

# まとめ
GM-QAOAについて論文を読んでみた。制約付き最適化に有効である。

[^1]: 作用するのは$U_{M} = e^{-i\beta |F \rangle \langle F|}$であって、$|F \rangle \langle F|$じゃないよね？と思うかもしれません。そのとおりです。が、行列指数関数$e^{A}$はたかだか$A$の累乗の和であることと、射影演算子$P$の累乗は再び$P$であることを考えると、$U_{M} = e^{-i\beta |F \rangle \langle F|}$は$|F \rangle \langle F|$とそっくりに振る舞います。

[^2]: コストハミルトニアンのもとでの時間発展で制約の外へ出ることがありえる気がしますが・・・。それでも、次のミキサーハミルトニアンの作用で再び制約を満たす空間へ射影される＝”引き戻してくれる”のでしょうか。
Raspberry pi でmoonlight-embeddedをコンパイルする手順

moonlight-embeddedはGeforceExperienceの機能でゲームを遠隔起動してプレイできる便利なアレです。
なんかよくわかんないけど、Raspberrypi3b+でmoonlight-embeddedが動かなくなったので、アホな貴様らのためにメモ書きしておく。

1.必要パッケージのインストール
まずは、moonlight-embeddedを動作させるのに必要なパッケージのインストールを行います。
【参考】
https://github.com/moonlight-stream/moonlight-embedded/wiki/Compilation

```
sudo apt-get install libopus0
sudo apt-get install libexpat1
sudo apt-get install libasound2
sudo apt-get install libudev0
sudo apt-get install libavahi-client3
sudo apt-get install libcurl4
sudo apt-get install libevdev2
sudo apt-get install rbp-userland-osmc 
sudo apt-get install libraspberrypi0 
sudo apt-get install libssl-dev
sudo apt-get install libopus-dev
sudo apt-get install libasound2-dev
sudo apt-get install libudev-dev
sudo apt-get install libavahi-client-dev
sudo apt-get install libcurl4-openssl-dev
sudo apt-get install libevdev-dev
sudo apt-get install libexpat1-dev
sudo apt-get install libpulse-dev
sudo apt-get install uuid-dev
sudo apt-get install cmake
sudo apt-get install gcc
sudo apt-get install g++
sudo apt-get install rbp-userland-dev-osmc
sudo apt-get install libraspberrypi-dev
sudo apt-get install fakeroot
sudo apt-get install debhelper
```

2.moonlight-embedded本体のインストール
[ソースの取得]
```git clone https://github.com/irtimmer/moonlight-embedded.git```
[make]
```cd moonlight-embedded
git submodule update --init --recursive
mkdir build
cd build/
cmake ../
make
sudo make install```

2021/08/06 追記
[ペアリング]
ホスト側でGeforceExperienceを起動しろ。
```moonlight pair```
ここで出てきた4桁の数字をホストマシンに表示されたGeforceExperienceの小窓に打ち込め。

もし、ここでlibgamestream.so.4が見つからないと言われたらmoonlight-embeddedのディレクトリで
```sudo ldconfig```
を実行しろ。

[起動]
```moonlight stream```

[終了]
Steamを終了するか下記のコマンドを打ち込め。
```moonlight quit```

これでできる。
かもしれないよ。知らないけど。
contenteditableでいい感じにキャレットを上下移動する

# contenteditable="true" "false"を入れ子にするといい感じに移動できる

- 文字列のindexをとって移動する？
- left座標を頑張ってとって移動する？
- でも途中で`<i>`とか、キャレットを当てたくない箇所もあったりする…
- `<b>, <u>, <h2>`なども考えねば…

など普通に実装しようとすると、contenteditableでキャレットを上下移動するのは結構悩ましい問題です。

実はcontenteditableはtrueとfalseを入れ子にした状態で、`contenteditable="true"`の行から上下移動すると、自動的にfalseのDOMを飛ばし、次のtrueのDOMのいい感じの位置（left位置。そこに文章がなければ、飛びたいleft位置に最も近い文字の文末）にキャレットを送ってくれます。

もうややこしいカーソル制御のコードは一切必要ありません！やった！


## 例
こんな感じでtrueとfalseを入れ子にしたHTMLを用意します。

```HTML
<div contenteditable="false">
  <i>checkbox</i>
  <p contenteditable="true">吾輩は猫である。</p>
</div>
<div contenteditable="false">
  <i>・</i>
  <p contenteditable="true">名前はまだ無い。</p>
</div>
<div contenteditable="false">
  <i>・</i>
  <p contenteditable="true">どこで生れたかとんと見当がつかぬ。</p>
</div>
（以下略）
```

### GIF1
最下段の文章の「ある事は│」の位置から、キャレットを上に移動した図（見やすくするため、pタグにboderをつけています）
![3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80956/63eb9f84-87e9-9265-a093-63e538ac1bc4.gif)


### GIF2
最下段の文章の末尾「知った│」の位置から、キャレットを上に移動した図
![4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80956/c4210d8e-6468-ca41-cd40-0fede018363d.gif)



意外と知られていなさそうだったので、contenteditableの闇にやむなく溺れているときの助けになればと思います。
UITextFieldをタップ時、任意のTextを追加する。

#完成形はこんな感じ
<img width="150" alt="F7736CD1-C3D0-4E3B-8689-68E68B9CE3CE_1_201_a.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1466343/c2e35742-e8e8-d9ad-9aca-556745717ffd.jpeg">

#機能説明
* 撤去する日付のUITextFieldをタップした時に、`年月日`が表示されます。

#コードと簡単解説

* `.addTarget(target: Any?, action: Selector, for: UIControl.Event)`を用います。

* `UIControl.Event`の箇所には、UITextFieldをタップした時に`action`の処理を使いたいので,`.allTouchEvents`を今回使用しています。

* `action`の処理は、UITextFieldをタップした時にUITextField.Textが空だったら、年月日をUITextField.Textに表示します。

* なぜ、UITextField.Textが空の時なのかは、希望の入力値を入力した後にUITextFieldをタップしたらUITextField.textが「年月日」だけになってしまいますので、それを防ぐ為です。

```Swift

  @IBOutlet weak var deadlineDayTextField: UITextField!

  override func viewDidLoad() {
           super.viewDidLoad()

  deadlineDayTextField.addTarget(self, action: #selector(addYearMonthDay), for: .allTouchEvents) 

  }
  
      @objc func addYearMonthDay(_ sender:UITextField){
        
        if sender.text == ""{
            
            sender.text = "年月日"
            
        }
        
    } 
```

# 終わり
今日は、年月日を入力する時に何度も「年月日」を入力したくなくて、簡単ですが書いてみました。
ご指摘、ご質問などありましたら、コメントまでお願い致します。
DockerはSysFsを自動的に読み取り専用でマウントするらしい

# 背景
おうちDockerSwarmクラスタを立てようとしていたところ不思議に思ったことが出たので調べてみました。仕様書を見たというものではないですが、そういう挙動をするようだ、というメモです。(更に詳しい仕様をご存知の方は教えてくれると助かります)
**注: 7/31から2ヶ月寝かせたままだった記事です、詳細はもう覚えていません...**

# 疑問に思ったこと
ここに、RPi-Exporterという、ホスト側の温度を取得してPrometheusのメトリクスExporterがあります。

https://github.com/lukasmalkmus/rpi_exporter

これを Dockerコンテナ化したものに、 Docker-ARM-Exporterというものがあります。

https://github.com/carlosedp/docker-arm_exporter

そしてこの DockerArmExporterの実行例を見てみると、タイムゾーン、現在時刻、ノード名を読み取るだけで、肝心の 温度情報部分?をバインドしていませんでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254984/7f3504ed-09a2-26e2-04a4-0313424980af.png)

このコンテナ、とりあえず試すだけなら、バインドしなくとも動く気がしたので、何もバインドせずに動かしてみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254984/6937acf5-3a33-4bab-2e6f-804e539fbfac.png)

rpi_cpu_temperature_celsiusの項目が、リロードすると変動することからホスト温度が確かに読み取りできているようです。 何もバインドしなくて読み取れるってなんでだ?? これが今回の疑問点です。

## どうやってホストの温度を読み出している?
そこでソースコードを見たところ、`ioutil.ReadFile("/sys/class/thermal/thermal_zone0/temp")` との1文があり、これを読み出すことで温度が取得できているようでした。

https://github.com/lukasmalkmus/rpi_exporter/blob/5372e0aa9edb1466e9abe031237c3ec632bbacf8/collector/cpu.go#L41

# Debian/Stretchコンテナで検証
なにか特殊な細工がされているわけではないことを確認するため、debian:stretchコンテナを起動して読み取れるか確認してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254984/c43ea308-ff72-dc95-f7bc-5f099e27b1b3.png)
これでも読み取りできました。デフォルトでマウントされている、ということで間違いなさそうです。

# 他に湧いた疑問
デフォルトでマウントされているので温度を読み取れるというのはわかった、けど他にも気になることがある。

## そもそも/sys/classって何?
/sys/classはデバイスへのシンボリックリンクが配置されるディレクトリとなっているようです。
https://www.wdic.org/w/TECH//sys/class

## 他には何がマウントされてるの?
他にも色々マウントされてるみたいです。
https://qiita.com/sato4557/items/b15f325bd735eb340da5

## これって書き込めるの?
読み取り専用としてマウントされるようです。
https://forums.docker.com/t/unable-to-mount-sys-inside-the-container-with-rw-access-in-unprivileged-mode/97043
実際試しても書き込めませんでした。

## セキュリティとかどうなの?
少しリスクはあるかもしれません
https://container-security.dev/security/sensitive-file-mount.html

# 結論
Dockerコンテナは何もボリュームをマウントしていなくてもシステムの一部が読み取れる状態で稼働している。書き込みはできないが、なにか攻撃のヒントが出てくる可能性も無くもないので用心に越したことはない。
[Rails]PrefixとURIパターンについて

# ありがとうございます
まずはじめにですが、
先ほど、過去に投稿したものについて、大変ありがたくご指摘いただきました。
返事の方法がイマイチわからず、改めて御礼申し上げます。
@shiozaki さんありがとうございます！勉強になりました！

# はじめに
本記事では、PrefixとURIパターンについて、説明いたします。
先日に、ルーティングネストでケアレスミスをし、
エラー対処に何時間と費やしてしまいました。
先日投稿したものも後ほどご覧ください。

https://qiita.com/mkato1013/items/74ed504d51e3f91e81c1

改めて、詳しく説明したいと思い投稿します。

# Prefixとは
パスが入った変数のようなもので、
どのページに遷移したいかをパスとしてコードに記述する場合は、
末尾に「_path」を記載する必要があります。

#URIパターン
ルーティングのパスを表し、
このパスにてページに遷移した際に、指定のコントローラーとアクションで処理が実行されます。
ここにURIパターンに記載されているものは、遷移後のURLとほぼ同じです。

# rails routesにて確認
例えですが、実際にrails routesしたものを添付します。

![PrefixとURIパターン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1768158/f0178320-063c-3e01-ecec-1486a275e872.png)

やや文字が小さいかもしれないです。すみません。

左から、
1番目:Prefix
2番目:HTTPメソッド
3番目:URIパターン
4番目:各テーブルのコントローラーとそれに対するアクションたち

使い方の例としては、

```erb
<%= link_to "by #{prototype.user.name}", user_path(prototype.user), class: "card__user" %>
```
などと記述をします。
「user_path(prototype.user)」は、画像でいうところの一番下の行を使用しており、
一番右を見るとおり、「users#show」。
つまり、ユーザー情報ページに遷移するためのパスということになります。

ちなみに、適当なユーザー情報のページに遷移した場合、
URLは以下の通りになります。
http://localhost:3000/users/3
*「3」は3番目にユーザー登録したため、レコードにidが3となっており、「3」と表示されております。

ちなみに、users#showのURIパターンは、`「/users/:id(.:format)」`

*`URLの最後の記載とほぼ同じです。`*

また、
user_path(prototype.user)の`(prototype.user)`は、
誰のユーザー情報に遷移するのかを示すところになっています。

今回では、
「プロトタイプを投稿したユーザー(prototype.user)」の
「ユーザー情報に遷移user_path」するパス。ということです。

# ルーティングネストによるケアレスミス
先日の投稿と内容はやや被ります。

https://qiita.com/mkato1013/items/74ed504d51e3f91e81c1

```ruby
  resources :prototypes
  resources :prototypes do
    resources :comments, only: :create
  end
  resources :users, only: :show
```

```ruby
  resources :prototypes
  resources :prototypes do
    resources :comments, only: :create
    resources :users, only: :show
  end
```

この２つは、usersをネストしているか、していないかという違いです。

`ネストしているかどうかでrails routesで記載されるものが違います。`

つまり、ルーティングには気をつけろ！ということです。

# 終わりに
ネストのミスについては、ルーティングのエラーの一つとして挙げられるのではないでしょうか。
今後も気をつけて学習を進めます。

また、はじめに書きましたが、
ご指摘をいただけるということは非常にありがたくと感じております。
右も左もわからず行動し投稿し始めたことによって学べることを今回身をもって知ることができました。

これからもやってみようと思った時から行動し、アウトプットを積極的に行うよう心がけます。

それでは、引き続きがんばります！！
ubuntu18.04環境で、pyqt5を使いつつopencv-pythonをインストールすると、その後にqtを使用する際にエラーが発生した。

ubuntu18.04環境で、pyqt5を使いつつopencv-pythonをインストールすると、その後にqtを使用する際にエラーが発生した。

```
QObject::moveToThread: Current thread (0x56125f604920) is not the object's thread (0x561262d82a40).
Cannot move to target thread (0x56125f604920)

qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "/home/ubuntu/.pyenv/versions/taichofu_env/lib/python3.6/site-packages/cv2/qt/plugins" even though it was found.
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

Available platform plugins are: xcb, eglfs, linuxfb, minimal, minimalegl, offscreen, vnc, wayland-egl, wayland, wayland-xcomposite-egl, wayland-xcomposite-glx, webgl.

```

以下を参考にさせていただき解決
> [QtとOpenCVの両方をインストールするとエラーが発生する[Python]](https://blog.nplpl.com/421)
>どうやら双方にGUI機能が含まれているから競合しているらしい？なので、
$ pip uninstall -y opencv-python
opencv-python をアンインストールして、
$ pip install opencv-python-headless
GUI機能を含まない、OpenCVのヘッドレス版をインストールすると正常に動作しました。


# 参考
[QtとOpenCVの両方をインストールするとエラーが発生する[Python]](https://blog.nplpl.com/421)
[`qt.qpa.plugin: Could not load the Qt platform plugin "xcb" in "" even though it was found.` というエラーが起きたときの対処](https://qiita.com/fukasawah/items/99219e1ff7d08915952f)
SQLの実行計画のインデックス表記を調べたけど、細かいところがわからなかった

SQLのパフォーマンスチューニングをしていたのですが、
explainで実行計画をみていて、なんとなく解消できるんだけど
後輩にうまく説明できないところを調べてみました。(結局まだちゃんと理解していないですが...)

ちなみに遅い原因は複合インデックスが設定されていないことでした。

## 実行計画をみてみる

とりあえず実行計画をみる。(select文はサンプル)

```tsx
select * from user from name = "サンプル" and age < 20
```

```tsx
explain select * from user from name = "サンプル" and age < 20
```

Extraのところに、indexの使用状況が書いています。ケースとしては大体以下の3つをよくみます。

- Using index
- Using where
- Using index condition

今回の遅いケースはUsing index conditionでした。

複合インデックスが効いていないことはなんとなくわかったのですが、そういえばUsing index conditionってなんだっけと。

公式をちょっと調べてもすぐに出てこなかったので、一旦別の記事で調べてみることに。

[https://stackoverflow.com/questions/28759576/mysql-using-index-condition-vs-using-where-using-index](https://stackoverflow.com/questions/28759576/mysql-using-index-condition-vs-using-where-using-index)
[https://qiita.com/aidy91614/items/f17ab862986e9e5cdea6](https://qiita.com/aidy91614/items/f17ab862986e9e5cdea6)

Using index conditionはインデックスは一部効いているのですが、検索対象のカラムを網羅していないので、SQLが遅くなってしまうという理解です。

Using index >   Using Where
Using index > Using Index Condition

と感じで良いかと。

Using whereについては結局ちゃんとまだ理解できていないです。
MySQLの公式に以下のような説明があります。

[https://dev.mysql.com/doc/refman/8.0/en/explain-output.html#explain_extra](https://dev.mysql.com/doc/refman/8.0/en/explain-output.html#explain_extra)

> Using where` (JSON property: `attached_condition`)

> A `WHERE` clause is used to restrict which rows to match against the next table or send to the client. Unless you specifically intend to fetch or examine all rows from the table, you may have something wrong in your query if the `Extra` value is not `Using where` and the table join type is `[ALL](https://dev.mysql.com/doc/refman/8.0/en/explain-output.html#jointype_all)` or `[index](https://dev.mysql.com/doc/refman/8.0/en/explain-output.html#jointype_index)`.
- `Using where` has no direct counterpart in JSON-formatted output; the `attached_condition` property contains any `WHERE` condition used.


読んだけど、よくわかりませんでした...
SQLでwhere句使っているよ。くらいの認識で良いのでしょうか。
ArcGIS OnlineにShibboleth IdPでSSO設定する際のメモ

# 概要
ArcGIS OnlineはSAML認証に対応しており、Shibboleth IdPとの認証連携も可能となっている。


# 設定メモ
基本的には[ESRI社のドキュメント](https://doc.arcgis.com/ja/arcgis-online/administer/configure-shibboleth.htm)に従って設定するが、注意点や変更可能な点がある。

## ログインボタンの設定
ArcGIS Onlineのログイン画面にSAMLログイン用のボタンを表示する際のテキストを設定できる。ここで漢字などのマルチバイト文字を利用すると、ログインボタンが動作しない。

## エンティティIDの指定
Shibboleth IdPとShibboleth SPの組み合わせの場合、一般的にエンティティIDには 

```
<PolicyRequirementRule xsi:type="Requester" value="https://sp.example.com/shibboleth-sp" />
```
のようなにURLを指定するが、ArcGIS Onlineの場合は、 スキームのないFQDNで指定する。

```diff:conf/attribute-filter.xml 
    <AttributeFilterPolicy id="ArcGIS">
-       <PolicyRequirementRule xsi:type="Requester" value="[The Entity ID of your ArcGIS Online organization]" />
+       <PolicyRequirementRule xsi:type="Requester" value="your-id.maps.arcgis.com" />
```

## NameIDの指定
ArcGIS Onlineで利用するユーザIDとして、Shibboleth IdPからNameIDを送出する必要がある。ちなみにePTIDを利用しようとするとArcGIS Online側で不正とみなされ、ログインが失敗する。

以下の設定では、NameIDとしてuidまたはemailを利用できるよう定義している。

```diff:conf/saml-nameid.xml
        <util:list id="shibboleth.SAML2NameIDGenerators">
            <ref bean="shibboleth.SAML2TransientGenerator" />
+               <bean parent="shibboleth.SAML2AttributeSourcedGenerator"
+                   p:omitQualifiers="true"
+                   p:format="urn:oasis:names:tc:SAML:1.1:nameid-format:username"
+                   p:attributeSourceIds="#{ {'uid'} }" />
+
+               <bean parent="shibboleth.SAML2AttributeSourcedGenerator"
+                   p:omitQualifiers="true"
+                   p:format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
+                   p:attributeSourceIds="#{ {'mail'} }" />
        </util:list>
```

特定のサービスでどの属性値をNameIDとして利用するか、RelyingPartyOverridesとして設定する。
relyingPartyIdsで指定したエンティティIDのサービスについて設定が上書きされるため、ArcGIS OnlineのエンティティIDを指定する。ここではemailを利用する設定だが、**p:nameIDFormatPrecedence**の値を、先で定義した**p:format**に合わせて変えることで変更可能。

```diff:conf/relying-party.xml
        <util:list id="shibboleth.RelyingPartyOverrides">
+           <bean parent="RelyingPartyByName" c:relyingPartyIds="your-id.maps.arcgis.com">
+               <property name="profileConfigurations">
+                   <list>
+                       <bean parent="SAML2.SSO"
+                           p:nameIDFormatPrecedence="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
+                           p:encryptAssertions="false" />
+                   </list>
+               </property>
+           </bean>
        </util:list>
```

## attribute-filterの設定
ArcGIS OnlineへのSSOにはmail属性が必須のため送出する必要があるが、givenNameは任意となっている。前項のようにNameIDとしてmailを利用する場合は、attribute-filterの記述は下記のようになる。

```diff:conf/attribute-filter.xml
+       <AttributeFilterPolicy id="ArcGISOnline">
+           <PolicyRequirementRule xsi:type="Requester" value="your-id.maps.arcgis.com" />
+           <!--<AttributeRule attributeID="givenName" permitAny="true" />-->
+           <AttributeRule attributeID="mail" permitAny="true" />
+       </AttributeFilterPolicy>
    </AttributeFilterPolicyGroup>
```
[06] PowerShell実践例 ... curlコマンドを使う


|本シリーズのトップページ|
|:--|
|https://qiita.com/robozushi10/items/0b0605257ad39bc22895|

# はじめに

REST API などの操作で curl コマンドを使用する頻度が高い.

PowerShell には invoke-webrequest コマンドが curl に相当するようだが、Linux ベースの curl とはオプションが異なっており困惑する.

そこで私は 別途 curl を配置して Linux と同じオプションにすることが多いので、ご紹介する


　

# 環境

```
Windows 10 Pro
PowerShell バージョン 6系
```


# 処理概要

次の 1〜3 の処理をする

```
1. https://curl.se/download.html からポータブル形式の curl をダウンロードする

2. 上記 1 でダウンロードした curl.exe を配置する

3. バッチの中から上記 2 の curl.exe を使用する
```

# 詳細

## 1. https://curl.se/download.html からポータブル形式の curl をダウンロードする

https://curl.se/download.html から、次をダウンロード入手する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1246056/fdde7e0a-f97a-70a2-7ece-e90cf45432a3.png)

　

## 2. 上記 1 でダウンロードした curl.exe を配置する

今回は次のように配置した.
環境変数 PATH が通っているところに置くかどうかは各自ご自由に.

```powershell
C:\Program Files\curl-7.66.0-win64-mingw\bin\curl.exe
```

　

## 3. バッチの中から上記 2 の curl.exe を使用する

Jenkins に対して命令を出す場合を例にする

```powershell
# 実行時のコマンドとパラメータが複雑なので, Bash でいう「eval $CLI」相当で実行する

# 実行コマンドと引数の書式を組み立てる
$CLI = "&'C:\Program Files\curl-7.66.0-win64-mingw\bin\curl' -f -v -X POST --user '<ユーザ名>:<APIキー>' http://<IP>:<ポート>/job/<ジョブ名>/buildWithParameters"

# コマンドとして評価する. Invoke-Expression が eval コマンドに相当する.
# 出力ログがうるさいので /dev/null 相当に捨てている
Invoke-Expression $CLI | Out-Null
```

　

以上.




# 参考にしたサイト

|URL|
|:--|
|https://ascii.jp/elem/000/004/021/4021036/|
【javascript】全角数字を半角数字に変換

数字に限定すれば変換用のマップを組まなくても良い。

#コード
お好きなので

```javascript
const fullnums = '０１２３４５６７８９';
const reFullnums = new RegExp('['+fullnums+']','g');

const toHalfnums = text => text.replace(reFullnums, m=>fullnums.indexOf(m));

console.log(toHalfnums('あ３６９あ'));		// 'あ369あ'
console.log(toHalfnums('７'));		// '7'
```

```javascript
const fullnums = '０１２３４５６７８９';
const toHalfnums = text => text.replace(/[０-９]/g, m=>fullnums.indexOf(m));
```


```javascript
const toHalfnums = text => text.replace(/[０-９]/g, m=>'０１２３４５６７８９'.indexOf(m));
```
ffmpeg-pythonで動画をトリミング（切抜き）

[前回](https://qiita.com/cress_cc/items/cf76fdeb6fabe9d3a893)の続きのつもりでしたが、簡単すぎて思いの外やることがありませんでした。

`input.mp4`の開始5秒後を起点に30秒間を切り抜いて`output.mp4`として出力するなら以下のような感じ。

```python:
import ffmpeg

stream = ffmpeg.input("input.mp4", ss=5, t=30).output("output.mp4")
ffmpeg.run(stream)
```

もちろん`ss=`や`t=`に変数を渡してやってもいいし、何なら小数渡しちゃってもＯＫ。
gem bullet導入（N＋１問題を分かりやすくするため）

# なんで導入しようと思ったのか

アプリケーションを作成中にN＋1問題を可視化できるにして分かりやすくするような便利な機能ないかな～と探してみましたところタイトルのgemを見つけてこれは便利だと思いましたので、備忘録として使い方を記述していきたいと思います。

# そもそもN＋1問題って？

Mysqlなどのデータベースからデータを読み込む際に余計にデータを読み込んでしまうことです。
分かりやすく例えるなら、商品を買おうと思ってレジにもっていったら一つ一つ商品をスキャンしていくイメージですね。
アプリケーションの動作がもっさりするなどの弊害があるため基本的にこの問題はなくしたほうが良いです。

# 導入

以下のコードを```Gemfile```に記述すれば大丈夫です。

```Gemfile
grop :development do
 Gem 'bullet'
end
```

あとは```bundle install```して下のコマンドを記述すれば準備は完了です

```
bundle exec rails g bullet:install
```

<a href='https://github.com/flyerhzm/bullet#run-in-tests'>公式テキスト</a>を見てみましたらどうやらほかにもいろいろと設定ができるらしいですか今回は省略します。

# デフォルトで設定されている内容
上記のコマンドで、```config/environments/↑上記のコマンドで、config/environments/development.rbにデフォルトで以下の様なコードが追加されました。

```development.rb
Rails.application.configure do
  # ここから
  config.after_initialize do
    Bullet.enable        = true
    Bullet.alert         = true
    Bullet.bullet_logger = true
    Bullet.console       = true
  # Bullet.growl         = true デフォルトでコメントアウトされてる
    Bullet.rails_logger  = true
    Bullet.add_footer    = true
  end
  # ここまでが追加される。以下、同ファイルにもとから入っていた内容は省略
end
```

<a href='https://github.com/flyerhzm/bullet#configuration'>bulletの詳細な設定項目一覧</a>←こちらにて各項目の設定内容についての確認ができます。

以上です。
GitHubの草は抜ける？!

　今回はただの気づきを記事にしておきます。GitHubに関することです。

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

　リモートリポジトリにpushした日付に、上の画像のような緑色が表示される現象のことを「草が生える」と呼ぶことを少し前に知りました。

##草が抜けた上に薄くなった？！

　この草に関することなのですが、僕は最近以下のような現象が起きていたことに気づいたのです。

- 過去の日付の草が抜けている
- 過去の日付の草の濃さが変わっている

　もともと草が生えていた日付から草が綺麗さっぱりなくなった現象と、もともと濃かった草が薄くなった現象が起きたのです。

　上の画像を見ればわかるように、4月15日にログインしてから、数日間草が全く生えていないことになっています。これはもともと生えていた草が抜けたのです。
　また以前はもっと濃い色の日付が多かったのですが、気づけば全体的に色が薄くなっていたのです。

##草が抜けた原因

　ではなぜこのようなことが起きたのでしょうか。草がなくなった原因はおそらくご想像の通りです。
　もともとリモートリポジトリで管理していたアプリを複数個自分で削除したのです。
　未来で何をしようが過去の記録は残るものだと思っていたのですが、どうやらアプリを消したら草も消えるみたいです。

##草が薄くなった原因

　では草が薄くなった原因は何だと言えるでしょうか。答えは、たった1日だけ濃い色になっている7月25日に隠されています。
　僕はこの日丸1日かけて、サーバーサイドの実装の流れを復習するために、簡易的なアプリを1個作り上げました。HTML&CSSはもともと作っていたアプリからコピペしていたので、コードの記述量は膨大です。7月25日の草をよく見てみると「59 contributions」と表示されています。要はたった1日でめちゃくちゃpushしまくったということです。
　この次の日に、過去の日付の草が薄くなっていたのです。つまり草の濃さは、GitHubの規格であらかじめ決められているわけはなく、そのユーザーの1日あたりのpush量の相対値から決まるということでしょう。



<br>

　僕の場合はあまり関係ありませんでしたが、GitHubの草が原因で就職活動で落とされたという話も耳にしました。

　アプリも消したら草も消えることや、1日でpushしすぎたら過去の草の濃さも変わるということを頭に入れてもいいかもしれません。

　もし僕が間違ったことを言っているのであればご指摘ください!
分配律の覚え方

分配律は直感では理解や記憶が難しいですが、
「独身の論理式が優先される」という感覚だけ覚えておけば再現できます。
分配律をストーリーで脳に定着させましょう。

なお、独身論理式とは、分配律で$p\lor (q\land r)$とかの、小さい塊の$p$とかの論理式を勝手に僕が名付けた名前です。q,rはカップルです。

## 独身論理式がANDで繋がりたい場合

$p$という独身の論理式がいました。
世間にはカップルばかりが溢れています。
$p$は$\land$でつながりたいと切に願いますが、なかなかチャンスがありません。

そんな時、$p$に転機が！！
目の前に$\lor$で結ばれたカップルの$q$と$r$が通り過ぎました。

```math
q\lor r
```

$p\lor q$ 「うふふ、私たち、$\lor$カップルとしてお似合いよね！」

$p$は激昂します。

$ p$「なんてやつだ！俺がずっと独身だというのに！俺もまぜてくれ！」

激しい化学反応により爆発が起き、皆が目を覚ますと、、、


```math
p\land (q\lor r)=(p\land q)\lor(p\land r)

```

こうなってました。

$p$「嘘だろ、俺$\land$で$q$または$r$とつながっちまった！」

そこに、天から論理式の神の啓示が！

論理式の神「pくんはかねてから独身でしたね。ずっと$\land$で繋がりたいと言っていたみたいなので、独身を耐えに耐えたpくんの希望を優先して、q,rと$\land$でくっつけときました。」

$p$「天の恵みだ。。あなたのお名前は？」

論理式の神「分配律とでも読んでくれ、ほほほ。ほなさいなら。」

声は既に聞こえなくなった。これが、分配律である。

## 独身論理式がORで繋がりたい場合

それから１０００年後、$\lor$で繋がりたい論理式$s$がいた。
目の前を熱々カップル$t\land u$が通りすぎた。

以下全く同様。。。

```math
p\lor (q\land r)=(p\lor q)\land(p\lor r)

```



はい、述語論理の分配律、記憶に残せましたでしょうか？
お読みいただきありがとうございました。
水曜人工知能のテストなので寝ます。それではごきげんよう。
Unity Standalone File Browser がMac OSで動作しなくなった件

# Unity Standalone File Browserとは

[Unity Standalone File Browser](https://github.com/gkngkc/UnityStandaloneFileBrowser)はUnityでFile Dialogを出したいときに便利に使えるライブラリであり、Windows, MacOS, Linuxのいずれでも使えるため人気が高いです。

# Mac OSで動作しなくなった

しかし、いつの間にかMac OSで動かなくなっているのに気づきました。必死で調べてみたところ、[issue #109](https://github.com/gkngkc/UnityStandaloneFileBrowser/issues/109) で同じ現象の人がいるのに気づいたので、どうも私がやらかしたわけではないようです。Windowsでは問題ないのですが、M1 MacもiMac2014も動かなくなっています。

とはいえ、時期的に現象の発生はM1 Mac発売の後のような気がしたので、Build設定を変えて試したところ、Build Settings>PC, Mac & Linux Standalone > Architecture > "Intel 64-bit" だけは問題なく動き、"Apple silicon"または"Intel 64-bit + Apple silicon"では動作しないことがわかりました。ということで、このライブラリをMac OSで使う必要がある人は、"Intel 64-bit"でビルドするしか今のところ解はなさそうです。

# 考察

MacOS用は StandaloneFileBrowser.bundleというディレクトリの下にDLLのようなものが存在しています。これは多分XCodeでビルドされたと思われます。でもって、現状(2021/7/31)は"Intel 64-bit" 以外のアーキテクチャではこのDLLを見つけることができないようす。適当にXCodeでリビルドしたり色々やってみても解決しなかったのですが、下記記事を見つけたのでもうちょっと頑張ってみたいと思います。

https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary
JiraのJQLで日付範囲を指定する際の罠

Jiraのフィルターで日付範囲を指定したい場合は多いと思います。

例えば作成日が2021/07/01~2021/07/31の課題を抽出する場合、以下のようなJQLを使用するでしょう。

```
created >= 2021-07-01 AND created <= 2021-07-31
```
しかし、このJQLでは2021-07-31に作成された課題が抽出されません。
これはJQLで時間まで指定しなかった場合は内部的に2021-07-31 00:00:00と解釈されてしまうためです。

正しく指定するには

```
created >= "2021-07-01 00:00" AND created <= "2021-07-31 23:59"
```

のように時間、分まで指定する必要があります。

意外と目検で検証しないと気付けない罠なのでご注意ください。

#### 参考
https://community.atlassian.com/t5/Jira-questions/How-to-filter-issues-by-date-range/qaq-p/972574
UnityのLocalizationPackageでビルド後にロケールが変更されない不具合

#　検証環境 

Unity2020.3.9f1、Localization-1.0.0-pre.10で検証しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1804036/299abdb3-b14a-be83-c6eb-f11a6db60e05.png)

# 現象(問題: build後のロケールが英語にならない)

https://qiita.com/YoshitakaAtarashi/items/5f7543808a5d9935c8fe

問題が発生していたプロジェクトについて、この記事の手順でLocalizationの環境を一から作り直し、テキストを少しづつLocalizeしていきました。テキスト数が少ない間はロケールが英語に変更され問題が発生しないのですが、ある数を超えるとbuild後のロケールが英語にならない問題が発生しました。Unityの内部的にはLocaleの設定(en,jp)が見つけられずnullを返していることが問題のようです。

# 解決方法

気まぐれで下図のようにLocalization Scene Controlsを設定したら、上記現象が発生していたプロジェクトでもbuild後のロケールが英語になりました。Active Localeがnullでもある程度は頑張ってくれるのだけど、ある数を超えると諦めてしまうというような不具合？のようですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1804036/78e36bf3-4dcb-a6e8-78f5-fd9fe14de180.png)

# 最後に

これで本当に解決しているのかまだ半信半疑なのですが、検索した範囲ではLocalization関連の記事にこのような情報はなく、似たような現象に悩まされている人に向けては役に立つかもしれないので共有させていただきました。

# 追記(7/31 23:30)

　時々変な現象が発生してはDiscardしたりバージョンを戻したりして、結果としてはビルド後でも完全に英語版が表示できるようになりました。LocalizationパッケージはPreviewなので、いつまたおかしくなるかわかりませんが、とりあえず約束していた仕事が果たせて安心しました。
git-secretsでセキュリティ対策

##はじめに
AWSが提供しているgit-secretsを導入して、AWSの機密情報を誤ってGitHubにあげないように設定します。
一度設定するとこれからも、わざわざ設定しなくて済むように導入していきます。

よろしくお願いします。

##git-secretsとは

git-secretsとはAWSが提供しているツールで、コードをコミットするときにパスワードだと推定されるような文字列が含まれていると、処理を中断してくれます。
つまりはうっかりミスを指摘してくれます。

##git-secrets導入

ターミナルからHomebrewを経由してgit-secretsを導入します。

```terminal:ターミナル
% cd ~/ #ホームディレクトリに移動
% brew install git-secrets
```

続いてアプリケーションに適用します。

```terminal:ターミナル
% cd アプリケーション名 #開発中のアプリに移動
% git secrets --install
```

次に「Access key ID」や「Secret access key」などのアップロードしたくないAWS関連の秘密情報を一括で設定します。
下記のコマンドを開発中のアプリケーションで実行します。

```terminal:ターミナル
% git secrets --register-aws --global
```

どのような設定がされているか気になる人は下記のコマンドで内容を表示できます。
様々な正規表現を用いて設定していることがわかります。

```terminal:ターミナル
% git secrets --list

# ⬇️上記コマンドを実施すると、以下の内容が表示されます
secrets.providers git secrets --aws-provider
secrets.patterns [A-Z0-9]{20}
secrets.patterns ("|')?(AWS|aws|Aws)?_?(SECRET|secret|Secret)?_?(ACCESS|access|Access)?_?(KEY|key|Key)("|')?\s*(:|=>|=)\s*("|')?[A-Za-z0-9/\+=]{40}("|')?
secrets.patterns ("|')?(AWS|aws|Aws)?_?(ACCOUNT|account|Account)_?(ID|id|Id)?("|')?\s*(:|=>|=)\s*("|')?[0-9]{4}\-?[0-9]{4}\-?[0-9]{4}("|')?
secrets.allowed AKIAIOSFODNN7EXAMPLE
secrets.allowed wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

これで「git secrets --install」したリポジトリで、「git commit」コマンドを実行したときに秘密情報が含まれていないかチェックされるようになりました。

##可視化ツール GitHub Desktopの場合

可視化ツールのGitHub Desktopを仕様している場合さらに設定が必要になります。
下記のコマンドで適用できます。

```terminal:ターミナル
% sudo cp /usr/local/bin/git-secrets /Applications/GitHub\ Desktop.app/Contents/Resources/app/git/bin/git-secrets
```

もし「No such file or directory」というエラーが出る場合は、GitHub Desktopのバージョンが古いことが原因かもしれません。
下記のコマンドを実行しましょう。

```terminal:ターミナル
% sudo cp /usr/local/bin/git-secrets /Applications/GitHub\ Desktop.app/Contents/Resources/git/bin/git-secrets
```

##自動に適用されるようにする
これから作成するリポジトリには今回のように毎回設定せずに、自動でgit-secretsが適用されるようにします。
下記コマンドを実行します。

```terminal:ターミナル
% git secrets --install ~/.git-templates/git-secrets
% git config --global init.templatedir '~/.git-templates/git-secrets'
```

これで今後作成するアプリケーションはわざわざgit-secretsを適用させる作業する必要はありません。

##最後に
GitHubにうっかり鍵をプッシュしてしまうのはかなり危険ですので、万が一のことを考えて導入はしておいた方がいいですね。
TomcatとApacheの連携


別サーバに設置したTomcatとApacheを連携させる。
特定のディレクトリにアクセスされたら、Tomcatサーバに転送するという感じ。


#前提
Apache Server version: Apache/2.4.6 (CentOS)
Apache Tomcat Version 8.5.68
CentOS Linux release 7.5.1804 (Core)：ApacheもTomcatも

#LoadModuleの設定
/etc/httpd/conf.modules.d : モジュール定義ファイル格納場所
上記ディレクトリ内00-proxy.confにて
デフォルトでいろんなファイルがあるが、それらの違いは何か。

```bash:/etc/httpd/conf.modules.d
-rw-r--r--. 1 root root 3739 Nov 16  2020 00-base.conf
-rw-r--r--. 1 root root  139 Nov 16  2020 00-dav.conf
-rw-r--r--. 1 root root   41 Nov 16  2020 00-lua.conf
-rw-r--r--. 1 root root  742 Nov 16  2020 00-mpm.conf
-rw-r--r--. 1 root root  957 Nov 16  2020 00-proxy.conf
-rw-r--r--. 1 root root   88 Nov 16  2020 00-systemd.conf
-rw-r--r--. 1 root root  451 Nov 16  2020 01-cgi.conf
```
答えはこちらを参考にした。

https://qiita.com/MasahitoShinoda/items/336b09efcc82aab1a2c6

どうやら機能ごとに組み込むモジュールをそれぞれの設定ファイル(.confファイル)にて定義するために機能ごとの.confファイルがあるとのこと。ただ、どう使うかは割と使用者にゆだねられてるっぽい。
またbase.confとconf/http.confの意義が結構似通ってるらしく、以下のように混乱してる人もいるっぽい。

https://access.redhat.com/discussions/2837881

とりあえず今回はリバプロとしての機能を使うため00-proxy.confの設定を確認する。
以下mod_proxy.soとmod_proxy_ajp.soがproxy利用するときに必要のよう。
＊デフォルトで設定されていた。

```bash:/etc/httpd/conf.modules.d/00-proxy.conf
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
```

またこのconf.modules.dディレクトリ内のファイルがきちんと読み込まれる必要がある。
/etc/httpd/conf/httpd.conf内にてIncludeされてることを確認する。
＊これもデフォルトで設定されている。

```bash:/etc/httpd/conf/httpd.conf
Include conf.modules.d/*.conf
```


#httpdの転送設定
ProxyPassディレクトリとProxyPassReverseディレクトリでの設定が必要。
httpd.confにて設定する。

```bash:/etc/httpd/httpd.conf
ProxyPass /tomcat9/ ajp://10.10.10.10:8009/
ProxyPassReverse /tomcat9/ ajp://10.10.10.10:8009/
```

上記だとhttp://\<ApacheサーバのIP\>/tomcat9/ だと10.10.10.10をもったTomcatサーバに8009ポートを使ってAJPプロトコルを用いてリクエストを転送することになる。

#Tomcatの待ち受け設定

またこのとき選択するポートはtomcatサーバにて定義する。

```bash:/conf/server.conf
    <Connector protocol="AJP/1.3"
               address="0.0.0.0"
               port="8009"
               redirectPort="8443"
                secretRequired="false" />
```

デフォルトだとコメントアウトされてる（<!-- --\>で囲われてる）ので、消してあげるだけ。
ちなみに各項目の意味は以下の通り。
protocol = "AJP/1.3" ：プロトコルはAJPを使う
address="0.0.0.0"　：サーバの待ち受けアドレスを定義する。
　0.0.0.0が意味するのは、tomcatサーバが持ってる全IPアドレスで待ち受けるということを意味する。特定IPだけの場合は個別に設定する。
port = "8009" ：接続ポートを8009に設定する。
redirectPort = "8443"：8009で接続された通信を8443にリダイレクトする。
secretRequired = false：
[Tomcat 9.0.31](https://tomcat.apache.org/tomcat-9.0-doc/changelog.html#Tomcat_9.0.31_(markt))からデフォルトでtrueになっているアトリビュート。
これがtrueになってるとサーバへの接続時に文字列を一致させる必要がある。
ただ、今回はTomcatのバージョンが8.5なので、不要だったよう。

#接続試験

上記設定後、ApacheサーバIP/tomcat9/に接続すると確かにTomcatのホーム画面が表示された。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606424/6e00d25f-2f61-5c6b-08ba-92010fb345cc.png)
unrecognized selector sent to instance のエラー解消

##背景

youtube動画を参考にしmp3を再生するコードを書き実行すと、
unrecognized selector sent to instance　というエラーが。。
どうやら再生時間を表示操作するスライダーが上手く繋がっていない模様。


##エラー内容

Thread 1: "-[Audio2.ViewController updateSlider]: unrecognized selector sent to instance 0x7fc13b509030"

![スクリーンショット 2021-07-31 15.20.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1830232/ae253ba0-d8aa-8ab6-6cc5-277e470e1ce9.png)

##原因
旧バージョンの書き方が原因

##コード

####修正前（エラーコード）
```
class ViewController: UIViewController {

//((省略))

        Slider.maximumValue = Float(audioPlayer.duration)
        _ = Timer.scheduledTimer(timeInterval: 0.1,
                                 target: self,
                                 selector: Selector(("updateSlider")),
                                 userInfo: nil,
                                 repeats: true)
 
//((省略))

    func updateSlider(){
        Slider.value = Float(audioPlayer.currentTime)
        NSLog("HI")
    }
}
```

####修正後
```
class ViewController: UIViewController {

//((省略))

        Slider.maximumValue = Float(audioPlayer.duration)
        _ = Timer.scheduledTimer(timeInterval: 0.1,
                                 target: self,
                                 selector: #selector(updateSlider),
                                 userInfo: nil,
                                 repeats: true)
 
//((省略))

    @objc func updateSlider(){
        Slider.value = Float(audioPlayer.currentTime)
        NSLog("HI")
    }
}
```
Progateで作ったWebアプリをDjangoで作ってみる2！ Part5 -データベース編-

# 目標物の確認

ProgateのNode.jsコースで作ったブログアプリと同じものをDjangoで作ってみます。

Djangoでのアプリ開発の一連の流れを整理するために記していきます。

**完成イメージ**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/147877a6-1b3a-25e2-7956-720596125802.png)

#models.py

**models.py**ファイルの作成を進めていきます。

今回作成するブログに使う情報は、タイトル、要約、本文、カテゴリーの4つです。

BlogModelというclassを定義して、**models**モジュールの中の**Model**クラスを継承させるために、BlogModelの中で``models.Model``というコードを書きます（☆1）。

ブログのタイトルは**CharField**を定義しました。**CharField**は短めの文字列情報を扱うフィールドです。**CharField**を作成するときは``Max_length``（最大文字数）という引数を設定します。今回は最大100文字とします（☆2）。

要約と本文は**TextField**を定義します。**TextField**はCharFieldと同じイメージで長めの文字列情報を扱うときに使います（☆3）。

最後のカテゴリーはまた、**CharField**です。ですが、さっきのタイトルと異なり、``choices=CATEGORY``という引数が入っています。右の表示がhtmlファイル上で表示される項目、左の表示がhtmlファイル上で表示される項目です。つまり、``CATEGORY = (('all', '全員'), ('limited', '会員限定'))``の左側は機械が理解できる項目で、右側が人が理解できる項目です

```python:blogapp/blog/models.py
from django.db import models # ☆1

CATEGORY = (('all', '全員'), ('limited', '会員限定')) # ☆4

class BlogModel(models.Model): # ☆1
    title = models.CharField(max_length=100) # ☆2
    summary = models.TextField() # ☆3
    content = models.TextField() # ☆3
    category = models.CharField( # ☆4
        max_length=50, 
        choices=CATEGORY)
    
    def __str__(self):
        return self.title
```

マイグレーションしていきます。

```console
> python manage.py makemigrations
> python manage.py migrate
```

#admin.py

**admin.py**ファイルにコードを追加し、管理画面に**BlogModel**を表示させることも忘れずに。

```python:blogapp/blog/admin.py
from django.contrib import admin
from .models import BlogModel

admin.site.register(BlogModel)
```

#ブログ記事の追加

最後に管理者ツールから**BlogModel**を選択して、個々の記事を入れていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/b06b3721-2c6b-1899-aced-be0fad92f73a.png)
[Ruby on rails] 改行の反映　form_withで入力

<h2>やりたいこと</h2>
<h6>改行も反映させたい！！！！！</h6>

<h4>現状</h4>

form-withで改行して入力しても、
反映されない！

![スクリーンショット 2021-07-31 21.16.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/32e03bd7-46f2-000d-d56a-4b5d4ebb770f.png)
![スクリーンショット 2021-07-31 21.16.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/ef03cfd2-242f-236b-70d9-32ca09ae3f60.png)

```
<div class="form-group">
        <%= f.label :introduction,"自己紹介" %><br />
        <%= f.text_area :introduction, autofocus: true,class:"form-control" %>
</div>
```

```
<div class="col-md-8 ml-5" style="margin-top:1em;">
  <h6>Introduction</h6>
  <p><%= user.introduction %></p>
</div>
```

<h4>改善後</h4>

![スクリーンショット 2021-07-31 21.21.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633266/ccbd7a3e-a3e2-defe-5457-85150e66f42c.png)

<h6>こう書くと、改行される！！！</h6>

safe_joinの部分です。

```
<div class="col-md-8 ml-5" style="margin-top:1em;">
  <h6>Introduction</h6>
  <p><%=safe_join(user.introduction.split("\n"),tag(:br)) %></p>
</div>
```