OmniAICreator/Qiita-1.07M huggingface dataset:
Pandasの基礎　DataFrameの生成


DataFrameとはPandasで扱う種類のデータ構造。
引数にSeriesを渡すと生成できる。


```Python
pd.DataFrame([Series1, Series2, .....])
```

また、バリューにリスト方を持った辞書型を用いても生成可能。
注意点としては、リスト型の長さは同じでないといけない。

```Python
data = {"fruits": ["apple", "orange", "banana"], 
          "year": [2018, 2019, 2020], 
          "season": [11, 2, all]}
df = pd.DataFrame(data)
display(df)
```

#出力結果

![スクリーンショット 2021-07-13 21.40.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1736279/09d111c7-c9f5-a441-dec3-eff49ac89d62.png)
配列をそのままターミナルに表示するためには


配列`numbers = [1, 3, 5]`を
そのままターミナルに出力させようとしたが表示されないので、
間違えていた部分をまとめました。

文字列か否かを、頭の中で整理できていない時があるので注意したいと思います。

**誤①**

``` .rb
numbers = [1, 3, 5]
puts numbers 
```
(出力)

```
1
3
5
```
　　

**誤②**

```.rb
numbers = [1, 3, 5]
puts "numbers" 
```

(出力)

```
numbers
```
　　

**正**

```.ruby
numbers = [1, 3, 5]
puts "numbers" + numbers.to_s
```
(出力)

```
numbers[1, 3, 5]
```
Python仮想環境のDjangoアプリをWindowsタスクスケジューラに登録するにはコマンドを && で接続する

## はじめに

Python仮想環境上で動作するDjangoアプリをWindowsサーバ上のタスクスケジューラで常時動作させるTipsをご紹介いたします

* ＯＳ：Windows10 Pro または Windows Server 2016 / 2019

## 結論

バッチコマンドファイル内に以下のコマンドを `&&` 接続子でつないで記述します

|SEQ|コマンド                            |
|:-:|---------------------------------|
| 1 |Python仮想環境のアクティベーションコマンド |
| 2 |Djangoアプリサーバの実行コマンド        |

* `&&` 接続子：プロセスの実行が完了してから次のプロセスを実行します
    * まずPython仮想環境のアクティベーションの終わるのを待ってから、Djangoアプリサーバの実行を行うようになります

## 例

* ¥¥windows-server001¥dev¥django¥webSite¥runsurver.bat

```bat:runsurver.bat
C:\dev\django\venv\Scripts\activate.bat && python C:\dev\django\webSite\manage.py runserver 0.0.0.0:7000
```

このバッチコマンドファイルの実行をWindowsタスクスケジューラに登録し実行します
これで、Python仮想環境上で動作するDjangoアプリをWindows上にて動作させ続けることができます

* 環境

|Pyhon仮想環境パス   |Djangoアプリケーションパス |アクセス許可ポート|
|------------------|---------------------|-------------|
|C:¥dev¥django¥venv|C:¥dev¥django¥webSite|7000         |

* バッチコマンド 

|WindowsコマンドプロンプトでのPython仮想環境アクティベーションコマンド|Djangoアプリを全IPクライントからの7000番ポートでHTTPリクエストを受け付けて実行|
|-----------------------------------------------------|-------------------------------------------------------------|
|C:¥dev¥django¥venv¥Scripts¥activate.bat|C:¥dev¥django¥webSite¥manage.py runserver 0.0.0.0:7000|

* ご参考まで：Powershellの場合
    * `C:¥dev¥django¥venv¥Scripts¥activate.bat` が `C:¥dev¥django¥venv¥Scripts¥activate.ps1`　になります

以上
`python3 -m pip install PyQt5`実行時にエラー

`python3 -m pip install PyQt5`実行時にエラー

```
$ python3 -m pip install PyQt5
Collecting pyqt5
  Using cached https://files.pythonhosted.org/packages/8e/a4/d5e4bf99dd50134c88b95e926d7b81aad2473b47fde5e3e4eac2c69a8942/PyQt5-5.15.4.tar.gz
  Installing build dependencies ... done
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "/home/ubuntu/.pyenv/versions/3.6.9/lib/python3.6/tokenize.py", line 452, in open
        buffer = _builtin_open(filename, 'rb')
    FileNotFoundError: [Errno 2] No such file or directory: '/tmp/pip-install-7xm7lesh/pyqt5/setup.py'
    
    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /tmp/pip-install-7xm7lesh/pyqt5/
```

以下で解決

```
pip3 install --upgrade pip
python3 -m pip install PyQt5
```
MPLAB X IDE 旧バージョンをダウンロードする方法

## 手順

1. 公式サイトへアクセス
MPLAB® X IDE | Microchip Technology
https://www.microchip.com/en-us/development-tools-tools-and-software/mplab-x-ide

2. ページ中程にあるGo to Download Archive をクリック
![スクリーンショット 2021-07-13 210415.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760146/9ee41ef7-8955-0c21-6141-88e33188b65d.jpeg)

3. 欲しいバージョンのリンクを**右クリック** 
(画面上は例としてwindows用5.45を選択)
![スクリーンショット 2021-07-13 210717.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760146/9c2bb796-7859-17db-0593-09f704bef882.jpeg)

4. 「名前をつけてリンク先を保存」をクリック
![スクリーンショット 2021-07-13 211038.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760146/e8ee654a-61dc-37b7-7df0-559ab9a6c805.jpeg)

5. 任意で保存する場所を選択し、保存ボタンをクリック
![スクリーンショット 2021-07-13 211433.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760146/7d41f242-d968-80b6-ef27-2d4f56b0615d.jpeg)

6. ブラウザ画面下にダウンロードの表示が出るので＾ボタンをクリックし、**継続**をクリック
![スクリーンショット 2021-07-13 211712.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760146/bc92595b-8bab-b832-15f5-bca568bbf385.jpeg)

7. ダウンロードが完了するまで待ちましょう。
8.  完了
![スクリーンショット 2021-07-13 212338.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760146/8568a362-3e5b-4fec-78fc-2be0886d4dac.jpeg)

## 過程ではまったこと
過去バージョンのダウンロードリンクをクリックしても反応ないので、[wayback machine](https://archive.org/web/)で過去の最新バージョンのリンクからダウンロードを試みてもリンク切れで駄目でした。

リンク切れページがこれまたおしゃれで
![スクリーンショット 2021-07-13 231440.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1760146/53cb4391-63f5-9cee-7af4-540ed666a896.jpeg)


404 page not found
I screamed ソフトクリームが逆さまになってる画像が表示された。
私が叫んだ。

## 謝辞
いつも親切にしてくださる職場の皆様
素晴らしいソフトウェアを快く共有してくださる方々、潤沢な情報を共有してくださるネット上の方々に感謝。
本当にありがとうございます。
rs232の実験メモ1

# rs232サポート機器の実装について


自作のマイコン機器の送信データをrs232ポート越しにOSに認識させるようにしたい。
EUSARTを内蔵していない廉価なPICマイコンを使用するので、詳細を調べる必要がある。

## マイコン側に必要な仕様

### 速度と同期方式
|速度|ビット取扱|
|-|-|-|
|38.4kbps (実装予定の速度)|8N1, 調歩同期, LSB-first|
仕様上は上記以外の速度もサポートされている。

### 電気仕様
rs232は負論理のバスである。

|論理ビット|呼称|電圧|
|-|-|-|
|0|space|+3〜+15[V]|
|1|mark|-3〜-15[V]|

対向するrs-232のポートはアイドル時に mark (即ち負電圧)を送信し続けるという仕様であるため、今回のように半二重通信のみ必要とするケースでは、自身が負電圧を送信したい際に対向ポートの電圧を利用する事ができる。[^1]

### バスのタイミングチャート

0x2B = 0b0010-1011 の送信時、TTLレベルの送信側は Startビット(Low), 0x2B(正論理かつLSB-first), Stopビット(Hi)を送るが、この際にバス側の電気レベルが以下になるように回路を組む必要がある。

![rs232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606167/f351de98-aef6-680a-65b0-55a95f630aa5.png)

[^1]: キーワード: half-duplex operation, parasitic capacitance, parasitic voltage
Gitにてgit: ‘secrets’ is not a git command. See ‘git --help’.のエラーが出た時

こんにちは

最近はSourceTreeと言うツールを使っているのですが、




そこにおいて作業中に初コミットした時にエラーが。。。

```
git: ‘secrets’ is not a git command. See ‘git --help’.
```

直訳すると「git: 'secrets' は git のコマンドではありません。git --help'を参照してください。」と




正直全く意味がわかりません。笑




調べてみると
・git-secretsがコミットの邪魔をしている
・ターミナルにてローカルリポジトリ内の.git/hooksにある、commit-msg, pre-commit, prepare-commit-msgを削除する必要がある
・git-secretsをインストール/アンインストール




まずなんですがAWS等で不正利用されないように
git-secretsが必要になってくるみたいです(詳しいことは分かりませんが)



これに対して
「あっそういえば自分過去にAWSでデプロイしたな」と思い浮かべ、これだと思い直ちにgit-secretsの設定をしましたが、うまくいかず、、、



自分の中でググって同じページを何回も見返したりしましたが、解決せずの繰り返しでした。




そこでなんとなくgit-secretsの場所を確認してみることに

```
＄　which git-secrets
/usr/local/bin/git-secrets
```

/usr/local/bin/の中にgit-secretsが存在しており




SourceTree側の設定を確認したところ
「内蔵のgit」になっていることが確認でき、すぐさま「システムのgit」へ変更




この際の注意点ですが、ちゃんと/usr/local/bin/gitで指定するように！




改めてcommitした所、成功！！！！




今回の原因といたしましてはソースツリー側のファイルの指定が誤っていたことが原因でした。

もちろん前半で上げた原因もございますが
自分はこれで解決致しました。

SourceTreeを使うエンジニアさんは登竜門の可能性大です！笑
pyenvをシェルスクリプトから使いたい

pyenvをシェルスクリプトから使いたい時がある、
pyenvを有効化するためには`source ~/.bashrc`を実行する必要があるので、スクリプトは以下のようになることが多い。

```
source ~/.bashrc

pyenv activate myenv
python -V
pyenv deactivate

pyenv activate myenv3.6.9
python -V
pyenv deactivate

pyenv activate myenv3.7.7
python -V
pyenv deactivate
```

しかし、これをそのまま`bash test.sh`のように実行するとエラーになる

```
$ bash test.sh

Failed to activate virtualenv.

Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.

Python 3.9.1

Failed to deactivate virtualenv.

Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.


Failed to activate virtualenv.

Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.

Python 3.9.1

Failed to deactivate virtualenv.

Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.


Failed to activate virtualenv.

Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.

Python 3.9.1

Failed to deactivate virtualenv.

Perhaps pyenv-virtualenv has not been loaded into your shell properly.
Please restart current shell and try again.
```

これは`source`がシェルスクリプトの中で有効になっていないためのようで、
`source test.sh`で実行するとOK

```
$ source test.sh
pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.
Python 3.9.1
pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.
Python 3.6.9
pyenv-virtualenv: prompt changing will be removed from future release. configure `export PYENV_VIRTUALENV_DISABLE_PROMPT=1' to simulate the behavior.
Python 3.7.7
```
未経験入社1ヶ月でJava silver11に合格した話【合格体験記】

##はじめに
IT業界未経験で４月に入社して、1ヶ月ほどでJava silverに合格できたので、勉強方法や過程など書き残していきます。
##勉強期間
勉強開始：2021年3月上旬
合格：2021年4月下旬
入社前から勉強はしていたので、2ヶ月弱ほどで合格できました。
##勉強前の自分のレベル
Javaとか勉強したことがない。
HTMLとかCSSなどのフロントの言語を書いたことあるくらい。

Javaど素人の状態で挑戦がスタートしました。
##使った参考書
https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Silver%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-815/dp/4295007625/ref=asc_df_4295007625/?tag=jpgo-22&linkCode=df0&hvadid=342700130622&hvpos=&hvnetw=g&hvrand=10359434607073053707&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009244&hvtargid=pla-830348236008&psc=1&th=1&psc=1

いわゆる黒本です。使ったのはこの1冊と、あとは会社の研修でJavaを触ったくらいです。
##合格までの道のり
Java bronzeかJava silverを研修期間中に取らないといけなかったので、bronzeとsilverは試験範囲が被っているところが多いということもあり、Java silverを受けようと決めました。
###勉強開始！
まずはJavaの雰囲気を味わおうと思って、2021年3月上旬に黒本を買って1周しました。
ただ、出てくる単語の全てが初めて聞くものばかりだったので、1周目は本当に辛かったです…。
3月は前職の有給消化期間ということもあり、1日に2章分は最低でも進もうと決めて黒本を進めていました。
###入社
2021年4月に入社しました。入社してからはJavaの研修漬けの毎日となりました。
ただ、3月に黒本を勉強していたこともあり、研修では他の同期と比べてロケットスタートを切れた感じはしました。（すぐに追いつかれたけど…）
研修を受けていくことでJavaの基礎は身についたなと思いました。
##具体的な勉強法
###黒本をとりあえず1周する
出てくる単語やコードなどを、とりあえず見たことあるレベルまで持っていこうと思いました。
1周目が1番しんどかったです。ここさえ乗り越えれば、あとは繰り返すのみ！

###黒本の１１章の部分までを繰り返し解く
 わからなかった問題や、理解ができていない問題にチェックをつけながら、ひたすら繰り返しました。
あとは、なぜその答えになるのかを、自分で理由づけできるようになるまで、解説等を読み込みました。

###黒本の模擬試験を解く
これだけ繰り返したんだから大丈夫だろう！と思って挑んだ模擬試験。
1周目は全くできませんでした…。
正直なところ折れそうになりましたが、できるようになるまで繰り返し解きました。
##試験本番
テストセンターで受けました。脳が元気なうちに…と思って朝の9時半に受けましたが、もう少し遅い時間の方が精神的にゆとりができましたね^^;
実際に問題を解いていくと、黒本と全く同じ問題が結構出ました。
ロジックが全く同じで変数名を変えただけとか、何なら変数名が同じものもあったような…。

結果、83％の正答率で合格できました。
ド忘れしたものもあったので、８５％は取れたかなといったところです。
##まとめ
本当に黒本をやり込むだけで合格できます。
ただ、答えの丸暗記では応用問題に対応できないので、「なぜその答えになるのか」ということを意識して、学習を進めるべきかなと思います。

この記事が少しでも勉強の手助けになることを祈っています。。
【Rails】閲覧数の表示を実装してみた

####My Profile
プログラミング学習歴②ヶ月目のアカウントです！
プログラミングスクールで学んだ内容や自分が躓いた箇所等のアウトプットの為に発信しています。
また、プログラミング初学者の方にわかりやすく、簡潔にまとめて情報共有できればと考えています。
もし、投稿した記事の中に誤り等ございましたら、コメント欄でご教授いただけると幸いです。　



#対象者

* 閲覧数を表示させたい方


#目的

* 閲覧数を表示させる機能を実装する

#実際の手順と実例
###1.前提
本の内容を投稿するSNSを作成しています。
詳細ページに閲覧数を表示します！

Book（model）
books table
books controller

User model 
users table
users controller


###2.モデルの準備
bookとuserと１対Nの関係になる「閲覧数」モデルを作成します。

まずテーブルとモデルを準備します。

```
rails g model ViewCount book_id:integer, user_id:integer
```

###3.それぞれのアソシエーション

user.rb

`````
has_many :view_counts, dependent: :destroy
````

book.rb

````
has_many :view_counts, dependent: :destroy
````
view_count.rb

````
belongs_to :user
belongs_to :book
```

###4.コントローラーへ追記
今回は閲覧数を表示したい場所に属するコントローラーに追記していきます。ここでは投稿されたbookがどのくらい見られているか表示したいのでbooks controllerに追記します。

```` 
  def show
    @book_detail = Book.find(params[:id])
    unless ViewCount.find_by(user_id: current_user.id, book_id: @book_detail.id)
      current_user.view_counts.create(book_id: @book_detail.id)
    end
  end
```

###5.Viewページへ追記

````` show.html.erb
<p class="view-count">👀数: <%= @book_detail.view_counts.count %></p>
`````

これを貼り付ければ詳細ページに閲覧数が表示できます！！！
ubuntuでpyenv使用を試みるもpythonバージョンが切り替わらない


`~/.bashrc` に pyenv の設定を書くとき、以下の設定する記事をよくみかけるが

```
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init -)"' >> ~/.bashrc
```

[公式のgithub](https://github.com/pyenv/pyenv#installation)を参照し、以下のように更新

```
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bashrc
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(pyenv init --path)"' >> ~/.bashrc
```

その後、以下を実行すると切り替わった

```
source ~/.bashrc
```

# 参考
[https://github.com/pyenv/pyenv#installation](https://github.com/pyenv/pyenv#installation)
GCP BigQueryのデータを特定時点に切り戻す（PITR）

いわゆる**ポイントインタイムリストア（Point In Time Restore、PITR）**等と呼ばれるようなデータを特定地点に切り戻す機能が、GCP BigQueryでも使えることを知ったので試してみます。BigQueryでは**タイムトラベル**と呼ばれる機能のようです。

基本的に下記ドキュメントの通りですが、実際にやってみます。

https://cloud.google.com/bigquery/docs/time-travel

## 環境
2021/07/13時点のGCP BigQueryを使っています。

## テストデータの作成
`sandbox`というデータセットを作っておいて、適当なテーブルを作ります。

```sql
CREATE TABLE sandbox.sushi (
  id INT,
  name STRING,
  updated_at DATETIME
);
```

### 正しいデータの作成
適当なテストデータを作成します。なんでも良いんですが、CLOUD SHELLターミナルで下記コマンドを実行して適当なデータを生成しました。

```sh
$ seq 1 10 | while read -r i; do
  bq query --use_legacy_sql=false "INSERT into sandbox.sushi VALUES ($i, 'まぐろ$i', DATETIME_TRUNC(CURRENT_DATETIME('Asia/Tokyo'), SECOND));"
  echo $i; sleep 1;
done
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/6895e86a-df96-d35d-4f8b-fec3145c64d8.png)

`まぐろ`がたくさん入っています。この状態のデータが正しい状態、つまり切り戻し先の状態だとしましょう。

### 間違ったデータの挿入
ここで間違ったデータとして1件更新しました。

```sql
UPDATE sandbox.sushi
SET name = 'たまご', updated_at = CURRENT_DATETIME('Asia/Tokyo')
WHERE id = 8
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/0d622702-30cb-5f1b-64fb-99c78c652d75.png)

id=8に、間違った`たまご`が混入しました。

今回は20時09分(`'2021-07-13 20:09:00'`)に不具合かなにか起きて、それより前に生成されたデータは正しくて、それ以降に更新されたデータが間違っている、という状況を想定します。`updated_at`というカラムがあって、それで切り分けができるイメージです。

## 正しいデータを確認
**`FOR SYSTEM_TIME AS OF`** 構文を使えば、特定の時点のデータをSELECTできます。

```sql
SELECT *
FROM sandbox.sushi
  FOR SYSTEM_TIME AS OF TIMESTAMP('2021-07-13 20:09:00', 'Asia/Tokyo')
ORDER BY id
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/f35d837f-17b1-4ab7-4aa9-4042f24cab9b.png)

正しい`まぐろ8`のデータが得られました。

## 正しいデータの復元
上記`SELECT`結果をDMLに使うなどいくつか方法はありますが、`$ bq cp`コマンドを使えば特定のタイムスタンプのテーブルを取って来ることができます。

切り戻したい時点のタイムスタンプが必要ですが、これもBigQueryで取得できます。

```sql
SELECT UNIX_MILLIS(TIMESTAMP('2021-07-13 20:09:00', 'Asia/Tokyo'))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/43c74c71-7b68-4ee9-9d96-eee1c927eeb1.png)

`1626174540000`が得られたので、これをスナップショットデコレータとして付与したコマンドをCLOUD SHELLで実行します。

```sh
$ bq cp sandbox.sushi@1626174540000 sandbox.sushi_restored
```

確認してみます。

```sql
SELECT * FROM sandbox.sushi_restored ORDER BY id
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50391/1aded8f2-18d8-60b7-be5d-547871271d61.png)

正しいデータの時点のテーブルが作られました。

このまま切り戻してしまってOKならば、`ALTER TABLE ... RENAME TO ...`で差し替えます。実は[2021年5月にできるようになったばかりらしい最新の機能](https://dev.classmethod.jp/articles/bigquery-alter-table-rename-to/)です。

```sql
ALTER TABLE sandbox.sushi RENAME TO sushi_mistake;
ALTER TABLE sandbox.sushi_restored RENAME TO sushi;
```

これで切り戻しが完了しました。

```sql
SELECT * FROM sandbox.sushi ORDER BY id
```

## まとめ
BigQueryのデータを特定時点に切り戻すことができました。注意点として、過去7日間しかデータは保持されないようなので注意が必要です。

## 参考
- [ポイントインタイム リストア \(PITR\) \- Azure SQL Managed Instance \| Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/azure-sql/managed-instance/point-in-time-restore?tabs=azure-portal)
AtCoderログ：0016 - ABC 209 C

# 問題：[ABC 209 C - Not Equal](https://atcoder.jp/contests/abc209/tasks/abc209_c)

## 問題文
> 長さ $N$ の整数列 $C$ が与えられます。以下の条件を全て満たす長さ $N$ の整数列 $A$ の個数を求めてください。
> ・$1 \le A_i \le C_i~(1 \le i \le N)$
> ・$A_i \ne A_j~(1 \le i < j \le N)$
> ただし、答えは非常に大きくなる可能性があるので、$(10^9+7)$ で割った余りを出力してください。

## 制約
> ・$1 \le N \le 2 \times 10^5$
> ・$1 \le C_i \le 10^9$
> ・入力は全て整数

# 回答 (AC)

例えば $N=2, C_1=3, C_2=4$ の場合、条件に適する整数列は $(1,2)$, $(1,3)$, $(1,4)$, $(2,1)$, $(2,3)$, $(2,4)$, $(3,1)$, $(3,2)$, $(3,4)$ の $9$ 通りです。同様にして全ての場合を列挙するアプローチが考えられますが、列挙するには数列の各要素をループさせる必要があり、2つ目の制約条件 $1 \le C_i \le 10^9$ からこのアプローチは厳しいことがわかります。

そこで数式で計算することを考えます。さきほどの例の場合、$A_1$ の選び方は $1,2,3$ の $3$ 通り、$A_2$ の選び方は $1,2,3,4$ から $A_1$ として選んだ $1$ 通りを抜いた $3$ 通りとなるので、合計は $3 \times 3 =9$ 通りとなります。つまり $(C_1-0)\times(C_2-1)\times(C_3-0)\times \cdots$ を計算すれば良さそうに見えます。

ところがこの方法ではうまくいかないことがあります。例えば(先ほどとよく似た) $N=2, C_1=4, C_2=3$ の場合。数式による解法では $4 \times 2=8$ 通りとなるはずですが、実際に列挙してみると $(1,2)$, $(1,3)$, $(2,1)$, $(2,3)$, $(3,1)$, $(3,2)$, $(4,1)$, $(4,2)$, $(4,3)$ の $9$ 通りとなってしまい、どこかおかしいです。

詳しく調べると、例えば $A_1=1$ を選んだ場合には $A_2$ の選択肢は(期待通り) $2$ 通りですが、$A_1=4$ を選んでしまうと $A_2$ の選択肢は $1,2,3$ の $3$ 通りがあり、ここで違いが生じています。この違いは、前者で選んだ $A_1=1$ は $A_2$ の選択肢に含まれている数字であるのに対し、後者で選んだ $A_1=4$ は $A_2$ の選択肢に含まれていない数字であることです。上記の計算式では、$A_2$ の選択肢は $A_1$ で選ばれた数字取り除いて考えたため、後者のようなケースに対応できていないのです。

「$A_1$ で選んだ数字が $A_2$ の選択肢に必ず含まれている」ようにするには、$C_1 \le C_2$ である必要があります (上記の $N=2, C_4, C_2=3$ はこの条件を満たしていないため違いが生じました)。同様に「$A_1, A_2$ で選んだ数字が $A_3$ の選択肢に必ず含まれている」必要もあり、これは $C_1, C_2 \le 
C_3$ という条件で表すことができます (まとめて $C_1 \le C_2 \le C_3$ となります)。さらに同様に考えることで、上記の計算式を使用するには $C_1 \le C_2 \le \dots \le C_N$ という条件が必要です。

コーディングにおいては、整数列を c() で受け取った後、c を昇順 (小さい順に) になるようにソートすれば上の条件を満たします。このとき求める場合の数は c.at(0) * (c.at(1)-1) * (c.at(2)-2) * ... * (c.at(n-1)-(n-1)) となります。なお、途中で c.at(i)<i となった場合、その桁の選択肢がないことを意味するので、最終的な答えは 0 になります。また、実際の計算では各項を掛けるごとに $\bmod{(10^7+9)}$ を計算することで、答えが膨大になることを避けることができます。

以上から、コードは以下のようになります。私の[提出コード](https://atcoder.jp/contests/abc209/submissions/24125372)も同じ方針でした。

```C++:abc209c.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int n;
  cin >> n;
 
  vector<int> c(n);
  for ( int i=0; i<n; i++ ) {
    cin >> c.at(i);
  }
  sort( c.begin(), c.end() );
  
  int64_t answer = 1, MOD = pow(10,9)+7;
  for ( int i=0; i<n; i++ ) {
    if ( c.at(i)<i ) {
      answer = 0;
      break;
    }
    answer = answer*(c.at(i)-i)%MOD;
  }
 
  cout << answer << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc209/tasks/abc209_c/editorial) → [公式解説](https://atcoder.jp/contests/abc209/editorial/2228)
回答と同じ方針でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc209/tasks/abc209_c/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2021/07/11/153920)
回答と同じ方針でした。

# リンク
- 前の記事 → [AtCoderログ：0015 - ABC 209 B](https://qiita.com/RoadLynton/items/bada7fcc7741dd563775)
- 次の記事 → [AtCoderログ：0017 - ABC 069 B](https://qiita.com/RoadLynton/items/b5453cc46676fcaec6b4)
FlutterのUserAccountsDrawerHeaderのcurrentAccountPictureの画像をギャラリーから選択する

<h1>環境</h1>
flutter2.2.3

<h1>手順</h1>
pubspec.yamlに下記を追加します。

```
image_picker: ^0.8.1+3
```
<hr>
実装ファイルで下記をインポートします。

```
import 'dart:io';
import 'package:image_picker/image_picker.dart';
```

<hr>
実装dartファイルのState内で下記を実装します。

```
  File? _image;
  final picker = ImagePicker();

  Future getImageFromGallery() async {
    final pickedFile = await picker.getImage(source: ImageSource.gallery);

    setState(() {
      _image = File(pickedFile!.path);
    });
  }

```
<hr>
実装dartファイルのUserAccountsDrawerHeader内で下記プロパティを実装します。

```
currentAccountPicture: GestureDetector(
 onTap: () => getImageFromGallery(),
 child: CircleAvatar(
  backgroundColor: Colors.black54,
  child: _image == null
  ? Icon(Icons.photo_camera, color: Colors.white)
  : Image.file(_image!),
 ),
)
```
<hr>
エミュレータでギャラリーに画像を準備する手順
<hr>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/4ad0dae3-0243-5bad-fd88-82f3b66e3129.png)
<hr>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/92c39c90-e988-a583-a187-b3da0ad0acc5.png)
<hr>
ここでpngファイルなどをドラッグ&ドロップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/9ebcd4f8-ce53-03bf-5bdc-964dff1a7b44.png)

<h1>デモ</h1>
![0713.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630191/64b4f57c-2a43-34ec-1693-33e919010f2e.gif)
[Minecraft]一括採掘プラグインVeinMinerの導入[Spigot 1.17]

# 経緯
運営しているminecraftサーバーに一括破壊系プラグイン、VeinMinerを導入してみた。
少しハマったところがあったので、記録しておきます。

## 環境
- minecraft version : 1.17
- Spigot 1.17
- Ubuntu 20.04

## 1. VeinMinerのダウンロード
VeinMinerのプラグインページ
[VeinMiner | SpigotMC - High Performance Minecraft](https://www.spigotmc.org/resources/veinminer.12038/)
このページの右上の`Downlad Now`のファイルは`Forge用のversion`なので間違えないように。これをダウンロードしても動きません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1759992/dd40658c-4a80-a6d6-0548-e39ffbaaa642.png)

少し下の方に行くと、`Choco`さんという方が作った`Bukkit用のversion`のVeinMinerに飛ぶリンクがあるので、ここからダウンロードします。
[GitHub - 2008Choco/VeinMiner: Bukkit/Spigot plugin. Aims to recreate the Forge mod, VeinMiner, in an efficient, flexible and feature-filled way](https://github.com/2008Choco/VeinMiner)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1759992/aa76c44f-9bea-1a1b-60f0-895ea54f7f2e.png)

ここから、`VeinMiner-Bukkit-1.17.9.jar`をダウンロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1759992/b21d90fd-0072-079b-6436-5b9e6a344673.png)

これをサーバーのplugins/ディレクトリに移動させます。
サーバーを再起動したら完了です。

## 2. 使い方
スニークしながら鉱石（石炭など）を壊すと、隣接する同じ種類の鉱石が一括で採掘されます。

## ver1.17で追加されたブロックを追加する
1.17versionで新しくディープスレート系の鉱石が追加されましたが、デフォルトのVeinMinerでは未対応です。新しく追加された鉱石を破壊可能にするためには、コマンドで追加してあげる必要があります。
VeinMinerのGithubで、丁寧に1.17用の追加コマンドをサポートしてくれています。
[Releases · 2008Choco/VeinMiner · GitHub](https://github.com/2008Choco/VeinMiner/releases)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1759992/f2791f94-3234-951b-e8b1-c7aa51f522b0.png)

minecraft内のコマンドで、
`/vm blocklist add pickaxe add minecraft:copper_ore`
を入力すると、新しく追加された銅鉱石が採掘対象となる。
同じように、他のブロックも追加しておくといいと思います。

```bash
# ディープスレートの石炭、銅、ダイヤモンド、エメラルド、金、鉄、ラピスラズリ
/vm blocklist add pickaxe add minecraft:deepslate_coal_ore
/vm blocklist add pickaxe add minecraft:deepslate_copper_ore
/vm blocklist add pickaxe add minecraft:deepslate_diamond_ore
/vm blocklist add pickaxe add minecraft:deepslate_emerald_ore
/vm blocklist add pickaxe add minecraft:deepslate_gold_ore
/vm blocklist add pickaxe add minecraft:deepslate_iron_ore
/vm blocklist add pickaxe add minecraft:deepslate_lapis_ore
```

以上です！
良いマイクラライフを。
AWS Lambdaのコールドスタートについて

アクセス増に応じて、同時に処理できる数が増えていきます。

####作成済みのLambda
初期処理不要

####追加されたLambda
初期処理必要
※関数実行までに、コンテナ作成→パッケージのロード→ランタイム起動・初期化

＝コールドスタート

##対応方法について
###①コールドスタートの処理を短くする対応
・パッケージのサイズを小さくする
・Lambdaのメモリを増やしていく（メモリを増やすと、CPUの性能が上がり、処理時間が短くなる）
　※メモリ増やすと、1ミリ秒のコストは上がるが、処理時間が短くなる。一概にコスト増とはいえない。

###②設定「Provisioned Concurrensy:準備済みの同時実行数」を使用。別途コスト
常時、初期処理済みのLambdaを、XXX個用意しておくことが可能
MySQLのtoo longというエラー

```
== 20210713102632 DeviseCreateUsers: migrating ================================
-- create_table(:users)
   -> 0.0447s
-- add_index(:users, :email, {:unique=>true})
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Specified key was too long; max key length is 767 bytes
```

migrationファイルを編集し、db:migrateを実行した所 too long というMySQLのエラー・・

こちら(https://qiita.com/terufumi1122/items/9ea764618eba01144e09) を参考に、
以下のファイルを新規作成しました。
ファイル内容もコピペ

場所：config/initializer配下
ファイル名：mysql.rb

```
require 'active_record/connection_adapters/abstract_mysql_adapter'

module ActiveRecord
  module ConnectionAdapters
    class AbstractMysqlAdapter
      NATIVE_DATABASE_TYPES[:string] = { :name => "varchar", :limit => 191 }
    end
  end
end
```

⇒アプリを作る一番最初に、文字コードutf8mb4をutf8に変更しています。
　文字コードによって1文字のバイト数が異なります。
　恐らく新規作成したファイルで制限のバイト数を変更しているため、エラーが解消出来るものと思います。
　(よく分かっていない)

前回エラーが出た際は確かこの方法で解決しました。
ですが再度エラーが。

```
== 20210713102632 DeviseCreateUsers: migrating ================================
-- create_table(:users)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:

Mysql2::Error: Table 'users' already exists

```

既にユーザーテーブルはあるよ！との事。
確かにsequel proで確認するとユーザーテーブルがカラム名なども仕様通りに作れていました。

途中でエラーが出ているのに、何でテーブル作れているんでしょう。
何だか不安になりますが、テーブルや中身は問題がなさそうなので、次に行きます。
ROS プログラムからパッケージのパス取得 (Python/C++)

### はじめに

ROSでプログラムからパッケージのパスを取得する方法を記載します。
roslibというライブラリーを使うとそのようなことができるみたいです。

### プログラム

- Pythonでパッケージのパス取得

```get_path.py
#!/usr/bin/python3

import roslib.packages

pkg_name = 'roslib'

path = roslib.packages.get_pkg_dir(pkg_name)

print(path)
```

```bash:実行結果
$ rosrun get_package_path get_path.py
/opt/ros/noetic/share/roslib
```

- c++でパッケージのパス取得

```get_path.cpp
#include <ros/package.h>
#include <iostream>

int main(int argc, char** argv) {

  std::string package = "roslib";

  std::string path = ros::package::getPath(package); 

  std::cout << path << std::endl;

  return 0;
}

```

- 上記c++プログラムのcmakeファイル(※roslib依存)

```cmake:CMakeLists.txt
cmake_minimum_required(VERSION 3.0.2)
project(get_ros_package_path)

find_package(catkin REQUIRED roslib)

catkin_package(
)

include_directories(
  ${catkin_INCLUDE_DIRS}
)

add_executable(get_path src/get_path.cpp)
target_link_libraries(get_path
  ${catkin_LIBRARIES}
)
```

```bash:実行結果
$ rosrun get_package_path get_path
/opt/ros/noetic/share/roslib
```
未経験からCCNA取得までの道のり　ver９

🚩ルーティングプロトコル
・RIP(Routing Information Protocol)

・OSPF(Open Shortest Path First)

・EIGRP(Enhanced Interior Gateway Routing Protocol)

・BGP(Border Gateway Protocol)

・IS-IS(Intermediate System to Intermediate System)

CCNAの試験で出るのは残念ながらOSPFだけ！
簡単な特徴や比較ぐらいは理解しておく！それくらいは問われる

今回はOSPFについて！

🚩OSPF
特徴
・さまざまなメーカーのルータで使用可能
・リンクステート型のプロトコル
・ルーティングプロトコルのトラフィック量を軽減
・コンバージェンスが速い
・VLSM対応
・ネットワークを階層化できる
・メトリックとしてコストを使用する
・ルーティング認証をサポートしてる

OSPFはリンクステート型に分類されるルーティングプロトコル！
ディスタンスベクタ型のルーティングプロトコル(RIP)はルーティングテーブルの情報をルータ間で交換しますが、リンクステート型のルーティングプロトコルは各ルータのIPアドレスなどのインターフェイスの情報（リンクステート）を交換します。
この交換する情報を LSA(Link State Advertisement)といい、ネットワーク内のOSPFが動作している他のルータに通知する。

OSPFでは、各ルータがネットワークのトポロジを記録した LSDB(Link State DateBase)と呼ばれるデータベースを持っている。
各ルータから収集したLSAはこのDBに格納され各ルータで同一の内容になる！
OSPFでは、トポロジ内の各ルータはルータIDによって識別される！

LSDBを元にSPFアルゴリズムを使用してSPFツリーという最短経路ツリーを作成して最短経路をルーティングテーブルに登録する！

ディスタンスベクタ型と異なり、隣接ルータの生存確認のためにHelloパケットだけを送信するため、トラフィック量を軽減することができる！

各ルータがSPFツリーから最短けいろをルーティングテーブルに登録しているため、変更があっても各ルータが変更箇所を認識してそれぞれで経路の再計算を行うため、隣から隣に定期的にルーティングアップデータを送って変更を伝えるディスタンスベクタ型日比べて、高速コンバージェンスが可能になる！

ただ各ルータがデータベースを持ち、そこから計算を行うため、メモリやCPUへの負担がRIPより大きくなるというデメリットがあります。

次回は、OSPFのネイバー登録の条件とマルチアクセスの場合の挙動についてアウトプットします！！
[Unity3D] マリオ６４やモンハンなどのカメラ視点からのキー入力の向きに移動する方法

######説明
マリオ６４やモンハンなどのカメラ視点からのキー入力の向きに移動するスクリプトです。




カメラにアタッチ

```cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/* ###########################################################################################
 * カメラ追尾 
 * 
 * 
 * 
 * 
  #############################################################################################*/

public class Camera_Tracking : MonoBehaviour
{

    public GameObject playerObject;                     //追尾 オブジェクト
    public Vector2 rotationSpeed = new Vector2(3,3);    //回転速度
    private Vector2 lastMousePosition;                  //最後のマウス座標
    private Vector3 lastTargetPosition;                 //最後の追尾オブジェクトの座標


    private float zoom;

    void Start()
    {
        zoom = 0.0f;
        lastMousePosition.x = 0;
        lastMousePosition.y = 0;

        lastTargetPosition = playerObject.transform.position;
    }

    void Update()
    {

        Rotate();
        Zoom();
    }


    void Rotate()
    {
        transform.position += playerObject.transform.position - lastTargetPosition;
        lastTargetPosition = playerObject.transform.position;
 
        Vector2 nowMouseValue;
        nowMouseValue .x = Input.GetAxisRaw("Mouse X");
        nowMouseValue.y = Input.GetAxisRaw("Mouse Y");

        Vector3 newAngle = Vector3.zero;
        newAngle.x = rotationSpeed.x * nowMouseValue.x;
        newAngle.y = rotationSpeed.y * nowMouseValue.y;

        transform.RotateAround(playerObject.transform.position, Vector3.up, newAngle.x);
        transform.RotateAround(playerObject.transform.position, transform.right, -newAngle.y);
    }

    //拡大縮小
    void Zoom()
    {
        zoom = Input.GetAxis("Mouse ScrollWheel");
        Vector3 offset = new Vector3(0, 0, 0);
        Vector3 pos = playerObject.transform.position - transform.position;

        if (zoom > 0)
        {
            offset = pos.normalized * 1;
        }
        else if (zoom < 0)
        {
            offset = -pos.normalized * 1;

        }
        transform.position = transform.position + offset;
    }
}

```

プレイヤーにアタッチ

```cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;


/* ###########################################################################################
 * プレイヤー移動
 * 
 * 
 * 
 * 
  #############################################################################################*/

public class moveControl : MonoBehaviour
{
    private Rigidbody rb;
    private Vector3 moveForward;
    public float moveSpeed;

    float inputHorizontal = 0;
    float inputVertical = 0;

    private void FixedUpdate()
    {
        rb.AddForce(moveForward.normalized * moveSpeed);
    }

    void Start()
    {
        rb = GetComponent<Rigidbody>();
    }

    void Update()
    {
        inputHorizontal = Input.GetAxisRaw("Horizontal");
        inputVertical = Input.GetAxisRaw("Vertical");

        Vector3 cameraForward = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized;
        moveForward = cameraForward * inputVertical + Camera.main.transform.right * inputHorizontal;
    }
}

```
React Hooksの10種類を理解する（Basic: useState）

# React Hooksの10種類を理解する（Basic: useState）
## useStateの基本

- `useState` とは、state（状態）のvalueと、stateを更新するための関数を返すhooksである。

### 通常のReact

```javascript
class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
    this.state = {temperature: ''};
  }

  handleChange(e) {
    this.setState({temperature: e.target.value});
  }

  render() {
    const temperature = this.state.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature:</legend>
        <input value={temperature}
               onChange={this.handleChange} />
      </fieldset>
    );
  }
}
```

上記のcalculatorクラスの場合、初回で `temperature` の値は空白となっており、その状態を設定している。この値を更新する場合は、inputの `onChange` にて`handleChange` 関数を立ち上げて、`setState` 関数によって、`temperature` の値をを更新している。これを、`useState` を使用すると、以下のようになる。

### React Hooksを用いたCalculatorクラス

- React HooksとTypeScriptを用いてcomponentを作成しています。

```javascript
const TemperatureInput = () => {
  const [temperature, setTemperature] = useState<number>(); // ※1
  return (
    <fieldset>
      <legend>Enter temperature:</legend>
      <input
        value={temperature}
        onChange={(value: number) => setTemperature(value)}
      />
    </fieldset>
  )
}
```

- `useState` で状態管理することによって、`constructor` と `handleChange` (update)の部分を一気にまとめて管理することができるようになる。これによって、コード量も減るので、よりわかりやすくなった。
- (※1) useStateを定義してあげるときには、setState部分は、stateに `set` を付け加えてあげれば、基本的には大丈夫かと思います。

## state の遅延初期化

- もし、初期のstateが、単純な値を設定をしないのであれば、関数を渡すことも可能となっている。初回のrender時にのみ実行される。

```javascript
const TemperatureInput = () => {
  const [temperature, setTemperature] = useState<number>((value: number) => {
    if (value <= 5 && value >= -5) {
      return 0;
    } else {
      return value;
    }
  });
  return (
    <fieldset>
      <legend>Enter temperature:</legend>
      <input
        value={temperature}
        onChange={(value: nuber) => setTemperature(value)}
      />
    </fieldset>
  )
}
```

## state 更新の回避

- state更新時に、現在の値と同じだった場合は、更新が回避されて処理が終了される。
- もしrender中に高度な計算をしている場合は、`useMemo` を使用すると良い。

## reference

- [フック API リファレンス](https://ja.reactjs.org/docs/hooks-reference.html)
- [すごいReactフック8選](https://qiita.com/baby-degu/items/52dbb382bbaf6c43e2db)
トランザクションのステータスが分かりづらいのでメモ書き

この記事はUiPathブログ発信チャレンジ2021サマーの13日目の記事です。

UiPathでOrchestratorを導入して、調子にのってキューを使ってみよう！と思って登録してみたものの、トランザクションの見方がちょっと分からなくて（ジョブのイメージで見ていた・・・）、困ってました。

諸々、初期値のまま作ったので、リトライが設定されていたので、勝手に再実行されまくってトランザクションがわけのわからない状態に・・・。
暫くして、ステータスの見方が分かった時、とっても嬉しかったので備忘録に<(_ _)>
![トランザクションステータスの説明.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356722/9512f0b2-0b98-204d-9a6a-f17b5200c51c.png)
htmlの中にhtmlを埋め込む

# HTMLにHTMLを埋め込んでみる
簡単だしすぐにできるけど，結構埋め込みや，他のところのサイトを持ってくることも需要があると思うので，なるべく簡潔に書いて記録しておく．

# index.htmlの中にindex2.htmlを埋め込みたい！
CSSとかの体裁部分は省きます．一応heightやwidthは書いたけど．

```index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>html_in_html</title>
    </head>
    <body>
        <h1>htmlの中にhtmlを埋め込む</h1>

        <!--外部ファイルを読み込むiframe要素-->
        <h1>iframe要素の使用例</h1>
        <iframe src="index2.html" width="500" height="500"></iframe>
    </body>
</html>
```

```index2.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>html_in_html2</title>
        <link rel="stylesheet" type="text/css" href="./no title_files/style.css">
        <link rel="preconnect" href="https://fonts.googleapis.com/">
        <link rel="preconnect" href="https://fonts.gstatic.com/" crossorigin="">
    </head>
    <body>
　　　　　　　　　　　　　　　　<!-- 中身を書く -->
    </body>
</html>
```

これだけでできる！index.htmlの中に，```<iframe src="[URL]"></iframe>```を入れるだけで，簡単に読み込むこともできるし，その場での画面調整も結構簡単にできる．

活用していこう！
attached?を使って、プロフィール画像を区別する

#はじめに

新規登録の際にプロフィール画像を登録するように設定しました。

しかし写真なんて載せられないユーザーもいると思うのでバリデーションをかけませんでした。

なので投稿した際にプロフィール画像がある人は画像は表示され、ない人はこちらで用意した画像が表示されるようにしたいと思います。

#前提

```user.rb
class User < ApplicationRecord
has_one_attached :avatar

  with_options presence: true do
    #バリデーション省略
  end

end
```

今回はuserモデルにavatarというファイル名をつけました。

```review.rb
class Review < ApplicationRecord
 belongs_to :user
  

  with_options presence: true do
   #バリデーション省略
  end
end
```

![スクリーンショット 2021-07-13 19.13.31（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/11a9f9ae-8ef1-4713-0a40-060a46e836af.png)

このような形で新規登録画面に画像を登録してもらうようにします。

![default-icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1264460/11a76ca8-e35b-a99d-d049-7e00aa11e4b0.png)

この画像をあらかじめ`app>asset>images>default-icon.png`として入れておきました。





#新規登録の際に保存した画像を表示

保存した画像をブラウザ上で表示させるために、ビューファイルに画像を表示させるコードを記述します。

表示させるために**image_tagメソッド**を使用します。

image_tagメソッドでは、複雑なRailsのディレクトリパスを指定しなくても、モデルから画像ファイルを呼び出して引数に記述するだけで、画像を表示するimg要素を生成します。

```erb
<%= image_tag モデル.画像ファイル %>
<%= image_tag user.avatar %>

ファイルからの呼び出しの場合
app/assets/ディレクトリ下の画像ファイルパスでも指定できる
<%= image_tag 画像ファイルのパス %>
<%= image_tag "default-icon.png" %>
``` 

あとは条件分岐で画像がある時、画像がないときの記述が必要です。

#attached?メソッド

レコードにファイルが添付されているかどうかで、trueかfalseを返すメソッドです。

```erb
<%if review.user.avatar.attached?%>
　　　画像があった場合はこっちの記述
　　　　<%else%>
　　　画像がない場合がこっちの記述
<%end%>
```

```.erb
<%if review.user.avatar.attached?%>
　　　  <%= image_tag user.avatar %>
　　　　<%else%>
　　  　<%= image_tag "default-icon.png" %>
<%end%>
```

このような記述になります。

よくプロフィール画像をクリックしたらプロフィールに遷移する事ができますがその場合は下記になります。

```erb
<%if review.user.avatar.attached?%>
    <%=link_to (image_tag review.user.avatar, class: "user-img"), "#" %>
  <%else%>
    <%=link_to (image_tag 'default-icon.png' , class: "user-img"), "#" %>
<%end%>
```
まっさらなUbuntu20.04環境へのpyenvインストールメモ

# 概要
Ubuntu20.04に脱Anacondaのpython環境を作る必要がでてきたが、【インストールメディアを用いて作成した】まっさらなUbuntuへの環境構築に少々てこずったのでメモを残しておく。
参考にしたサイトは末尾に記載。


## 作業項目

- ライブラリのインストール
- pyenvのインストール
- 環境変数の設定
- OS標準のpythonコマンドへのシンボリックリンク作成
- pythonのインストール
- pythonバージョンの切り替え


### ライブラリインストール

各種ライブラリをインストールする。


```
sudo apt install git gcc make zlib1g-dev libffi-dev libbz2-dev libssl-dev libreadline-dev libsqlite3-dev python3-tk tk-dev
```

### pyenvのインストール

pyenvをホームディレクトリにインストール。

```
git clone https://github.com/pyenv/pyenv.git ~/.pyenv
git clone https://github.com/pyenv/pyenv-update.git ~/.pyenv/plugins/pyenv-update
```



### 環境変数の設定

ホームディレクトリ直下の.bash_profileに、pyenv用の環境変数を追記する。
.bash_profileは、なければ作成する。

```
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# for pyenv(python)
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
```

はじめ、eval行の引数に「-」（ハイフン）を指定していたのだが、「--path)」に変更したら後述するpythonバージョン切り替えができるようになった。ここで２時間くらい無駄にしてしまった。。


### OS標準のpythonコマンドへのシンボリックリンク作成

Ubuntu20.04標準のpythonは「/usr/bin/python3」しかなく「python」コマンドが通らないため、pyenvでのpython切り替え(systemへの切り替え）がうまくいかないことがある模様。そのため、pythonコマンドが通るようにシンボリックリンクを作成する。

```
ln -s /usr/bin/python3 /usr/bin/python
```

参考サイト（githubのissue）には下記のworkaroundも書いてあった。どちらの対応でもよさそう。

```
sudo apt install python-is-python3
```

### pythonのインストール

今回は、2021/7/13時点で最新の3.9.6をインストールする。

```
pyenv install 3.9.6
```

### pythonバージョンの切り替え

python3.9.6への切り替え。

```
pyenv global 3.9.6
pyenv rehash
pyenv versions
```
```
   system
 * 3.9.6 (set by PYENV_VERSION environment variable)
```

別コマンドでもpythonバージョンを確認。

```
python --version
```

```
Python 3.9.6
```

ちゃんと3.9.6に切り替わっていることが確認できたらOK。


このあとは、pipenvインストールして仮想環境を作ってと。
以上。



## 参考サイト
Python 3.xの環境構築【Ubuntu 20.04】
https://note.com/mokuichi/n/n627eb6773aad
pyenv(github)
https://github.com/pyenv/pyenv
pyenv(github -> issue)
https://github.com/pyenv/pyenv/issues/1613
メタゲノム解析とは

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/3364.html)から移行中です。
元記事：2018/11/12 公開 メタゲノム解析って？
</font>

　次世代シーケンサー（NGS）を使った研究において、メタゲノム解析は最もホットな手法の一つなのではないでしょうか。弊社も単一のサービス紹介ページを作成しております。

>[メタゲノム解析サービス](https://www.pictbio.com/service/metagenome)

　今回はメタゲノム解析ってつまり何か、何をしているのか、というところをお話しようと思います。

#メタゲノム解析
　メタゲノムとは、文字通り複数ゲノムのことを言います。例えば、ファージにより感染した細胞にはファージと宿主の DNA があるかと思いますが、この細胞を使ってゲノムシーケンスを行えば、メタゲノムシーンスになります。

　最近では、メタゲノムといえば環境メタゲノムのことを指すほど環境メタゲノムが人気です。

#環境メタゲノム
　環境メタゲノムとは、環境サンプルをとってきて、環境内に存在するすべてのゲノム配列を解析するメタゲノムです。

　先の例とは異なり、生物種はもっと多く、且、特定されていない状態でデータが得られます。土、水、空気や、生物の腸内、口腔内など、対象は多岐にわたります。面白いものでは、植物の表面から訪れている昆虫などの生物を特定しようという研究がありました。

#データ解析では何をしているか
　アライメントにより配列がどの生物種から得られたか、ゲノムのどこから得たものかを計算します。
 
　アライメントのデータベースには対象の生物種の配列を使用します。環境メタゲノムでは、何がいるかわからないため全ての生物の既知配列を使用します。データもデータベースも量が多いため、計算時間の短縮として、16SrRNA 配列のみを取り出したり、配列をクラスタリングでまとめて代表配列のみアライメントに使うことがあります。

　アライメントだけでも、環境にいた生物や遺伝子が何だったかがわかりますが、その後、量的関係を見る為の計算やサンプル間の相関を見る為の統計を行ったりします。量的なものを見る場合は、元配列が長いとシーケンス量も増える為、その長さを使ってノーマライズを行ったり、ターゲットシーケンスをした場合は配列のコピー数などを考慮します。

#解析で何がわかるのか
　環境メタゲノムでは、その環境内にいる生物種を網羅的に取得することができます。また、環境内にある遺伝子も同様です。

　ノーマライズが可能なデータの場合は、生物の量的関係も見ることができます。RNAを取得した場合では、環境内で発現している遺伝子がわかり、発現量も見ることができます。

　サンプル間の違いで特徴を見ると面白いかもしれません。また、サンプルからすぐに配列を取り出すことで、培養ができないような生物の配列もとることができます。そのため、温泉など、特殊環境から有用な生物や物質を見つける手法としても有用です。
NGSにおける遺伝子発現量の解析方法

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/2554.html)から移行中です。
元記事：2017/05/29 公開 次世代シーケンサーでの遺伝子発現量解析
</font>

　次世代シーケンサーにおける遺伝子発現量解析はRNA-Seqとよく呼ばれています。「Seq」とある通り、蛍光強度を見るのではなくシーケンス配列を取得するものになります。

　今回はこの配列から「どのように発現量を計算するのか」をお話いたします。

#1. マッピング
　次世代シーケンサーから取得した数百baseのシーケンス配列（リード）は、それぞれゲノム上のどの位置から取得されたのかわからない状態でファイルに保存されます。そのため、先ずゲノム配列と比較して由来箇所を特定するマッピング計算を行います。

#2. カウント
　由来がわかったら、次はゲノムのエクソンに該当する位置にマップされたリード数をエクソンごとに計上します（タグ数）。その後、遺伝子毎に集計されたエクソンごとのリード数を合計したものが遺伝子のタグ数となります。

#3. ノーマライズ
　発現量はさらに計算を行うこととなります。発現量計算の方法は遺伝子の様々な要因に対して考慮されたものが開発されております。今回は多く用いられているRPM、RPKM、FPKMの手法をご案内いたします。

###RPM
　Reads Per Million mapped reads の略です。サンプルごとに取得されるシーケンス量が異なることを考慮し、マップしたシーケンスが100万配列としたときのリード量に換算しています。つまり、算出した発現量で**サンプル間比較**が可能になります。

###RPKM
　Reads Per Kilobase of exon per Million mapped reads の略です。RPMのサンプル間に加え、遺伝子の長さが長いほどシーケンスが取得されることを考慮し、遺伝子長を1Kとしたときのリード量に換算しています。つまり、算出した発現量で**遺伝子間比較が可能**になります。

###FPKM
　Fragments Per Kilobase of exon per Million mapped reads の略です。考え方はRPKMと同じですが、リードからフラグメントに代わっています。

　リードはフラグメント断片から数百baseをシーケンスしたものです。例えば、ペアシーケンスをした場合1フラグメントから2シーケンス取れるわけですが、これが2エクソンに分かれてマップした際、カウント数はRPKMでは2リードとなるところFPKMでは1フラグメントとなります。
マッピングツール – ローカルアライメント –

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/1676.html)から移行中です。
元記事：2016/12/16 公開 マッピングツール – ローカルアライメント –
</font>


　アライメントについての記事を投稿いたしましたが、今回はそのロジックを用いているツールの内、ローカルアライメントを行うものをいくつか、それぞれの特徴とともにご紹介いたします。

>シーケンスアライメントの計算
>https://qiita.com/PictBio/items/c3698987fcec06b6e8da

###ローカルアライメント
配列の一部を比較する。

例）リファレンスゲノムの一部とシーケンスリードを比較して、リードのゲノム上の位置を決定する。

#BWA

+ DNA マッピングツール。ギャップアライメントに対応しているため InDel を許容する。
+ バージョンアップしたことで長めのショートリードでもアライメントできるようになった。
+ ペアリードのフラグメントサイズを計算してくれる。目的に合わせてメソッドを選ぶ必要がある。

|メソッド  |特徴  |
|---|---|
|backtrack  |70-100bp Illumina リードに対応したショートリード用メソッド。  |
|SW  |1Mbp までのリードに対応。ギャップが多いデータに強い（らしい）。  |
|MEM  |1Mbp までのリードに対応。SW より高速とのこと。これらの3メソッドの中で一番新しい。  |

#Bowtie
+ DNA マッピングツール。他のツールが呼び出して使用することが多い。
+ バージョン2以上のものがリリースされているが、1も残っている。2以降はリードの長さ制限がなくなったため、アセンブルしたコンティグなどの長い配列をクエリとして使いたいときも計算が可能。
+ マルチトップヒットがあった場合のランダム振り分けが苦手。

バージョンの違い

|バージョン  |内容  |
|---|---|
|1まで  |1Kbp までのリードに対応。  |
|2以降  |リード長に制限はないが基本的にはショートリード用のアルゴリズムを搭載。ギャップアライメントに対応しているため InDel を許容する。  |

#Bismark

+ DNA マッピングツール。バイサルファイト試薬によって変換された塩基を含むリードのマッピングに対応。
+ Bowtie を呼び出して使用する。リファレンスを塩基変換したものを用意し、スコアの高い結果のマップパターンを採用する。
+ マップ結果からメチル化計算を行うところまで行ってくれるため、パイプラインソフトともいえる。

#TopHat
+ RNA マッピングツール。junction を考慮したアライメントに対応。
+ Bowtie を呼び出して使用し、アライメント結果を RNA データ用に計算している。

　ここでご紹介したツールはとてもメジャーなものなので、皆さまも名前を聞いたことがあるのではないでしょうか？これらはいずれも BWT（Burrows-Wheeler Transform）というアルゴリズムでアライメント計算の高速化を実現したものになります。

　マッピングはNGS解析において最も用いられる手法であり、解析のクオリティを決定するといえるほど重要な計算です。そのため、大量データを扱うにあたっての速度やクオリティなどのバランスを調整した計算アルゴリズムや、それを搭載したツールが数多く開発されております。先ほどの BWT のほかに有名なものでは Read Hash、Genome Hash といったアルゴリズムが知られています。

　自身の持っている「シーケンスデータの特徴」や「どんな情報を得たい」のかによってツールを選択してみてはいかがでしょうか。
ActionMailer::Previewで作成したデータをrollbackする

## 概要
previewのたびにレコードを作成するのは嫌だ。
buildしたものを使うことで回避できそうだが`ActiveRecord_Associations_CollectionProxy`に対し`order`を使っている部分があるとDBを探しにいってしまい、空配列が返ってしまう。
`order`ではなく`sort_by`を使うとindexが効かなくなる
なので一旦レコードを作成してしまい、メールをrenderした後にrollbackする。

## 方法
`config/initializers/mailer_previews.rb`

```ruby
module RollbackingAfterPreview
  def preview
    ActiveRecord::Base.transaction do
      super
      raise ActiveRecord::Rollback
    end
  end
end

Rails.application.config.after_initialize do
  class Rails::MailersController
    prepend RollbackingAfterPreview
  end
end
```

## 参考
[ruby on rails - How to avoid ActionMailer::Preview committing data to development database? - Stack Overflow](https://stackoverflow.com/questions/21950950/how-to-avoid-actionmailerpreview-committing-data-to-development-database/60154367#60154367)
ホモポリマーの解析

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/1505.html)から移行中です。
元記事：2016/04/14 公開 ホモポリマーの解析 : MiSeq
</font>

　シーケンサーはホモポリマーを読むのが苦手という弱点があります。

次世代シーケンサー「MiSeq」 はこの点に強いと紹介されており（[こちら](http://jp.illumina.com/systems/miseq/system.html)）、我々も実際にMiseqのデータを扱うことが多いので今回ホモポリマーに着目してみました。

　サンプルは、ある生物（クローン）の腸内 18S メタゲノムです。

　解析の際、ホストのゲノムが大量に得られました。ホストはクローンのため、理論的には得られたホストゲノムは配列が一致します。データ処理は次のように行い、それぞれのまとまりをOTU とし、カウントを行いました。

1. トリミング
2. アセンブル（ペアリードマージ）
3. キメラ除去
4. Unique（100%一致する配列をまとめる）処理

　結果、 OTU が大量に生成されました。配列を見てみると、数塩基の違いでまとまらなかったことが原因のようです。

#マルチプルアライメントで確認
　具体的にどういったところにシーケンスエラーが起こりやすいか、確認してみました。リードは読み始め、読み終わりはクオリティが下がる傾向にあるため、中間のマルチプルアライメントを取り出してみます。

ホスト由来 18S リード（中間部）のマルチプルアライメント「高 Simirality (98%<)」
![高 Simirality](https://www.pictbio.com/wp-content/uploads/tips/eb603961e353709fcbb3cfe0d6b4adc3.png)

　円でしるしを付けた箇所がシーケンスエラーの可能性が高い配列です。傾向としては、連続した塩基やその周囲で起こっているように見られます。

ホスト由来 18S リード（中間部）のマルチプルアライメント「低 Simirality (96%<)」
![低 Simirality](https://www.pictbio.com/wp-content/uploads/tips/406b5e2bd60786657f2b0daede4fea4f.png)

　同じく繰り返し配列やその周辺に見られる様子です。水色で示している箇所は同じ部位に複数見られたものを表しています。

　配列を得るまでのどの段階でこのようになるかはわかりませんが、情報解析時にはこれらの結果をふまえて計算することになります。

#ミスマッチをどう扱うか
　ではメタゲノム解析でクラスタリングする際、いくつまでのミスマッチを許容すべきなのでしょうか。

　Unique にした時点のホスト OTU 数が 983 あったのですが、この個体はクローンなので “1” OTU にまとまることを目指します。

 Simirality 基準で OTU を段階的にまとめてみます。縦軸に OTU 数、横軸に Simirality をまとめる際の値をとると、以下のグラフになります。

OTU と Simirality の相関グラフ
![OTU Simirality](https://www.pictbio.com/wp-content/uploads/tips/b20c06f97bc6498857cd618e79b4b000.png)

　フラグメントサイズ 420bp のサンプルですが、グラフから Simirality 0.91 の時点で一つの OTU になりそうです。38bp 、または、10% までミスマッチを許容する設定になります。

　かなり緩い設定となってしまいますが、ざっくりとした優占種を調べたいときは、影響は少ないかと思います。一方、レアな個体や、ある種に近い未知の個体を調べる際には、問題が出てきてしまう可能性があります。用途によってこの値を調整することが重要と考えられます。
Latex For Mac 書体と文字サイズ

## 和文書体
- 明朝体　　　`{\mcfamily … }`または`textmc{ … }`
- ゴシック体　`{\gtfamily … }`または`textgi{ … }`

![和文書体](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1758523/e853c77a-a5f4-dce3-6f85-2360bc5961b3.png)

## 欧文書体
- ローマン体　-本文- `\textrm{Roman}`
- 太字 `\textbf{Boldface}`
- イタリック体　-斜体- `\textit{Italic}`
- イタリック体代用 `\textsl{Slanted}`
- サンセリフ　-見出し- `\textsl{Sans Serif}`
- タイプライター風フォント `\texttt{Typewriter:}`
- 見出し `\textsc{Small Caps}`

![欧文書体](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1758523/a8b2b4b2-73b2-37fc-d399-275742af8960.png)

## 文字サイズ
- tiny:5ポイント `\tiny`
- scriptsize:7ポイント `\scriptsize }
- footnotesize:8ポイント `\footnotesize `
- small:9ポイント `\small`
- normalsize:10ポイント `\normalsize`
- large:12ポイント `\large`
- Large:14ポイント `\Large`
- LARGE:17.28ポイント `\LARGE`
- huge:20.74ポイント `\huge`
- Huge:24.88ポイント `\Huge`

![文字サイズ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1758523/488a618a-e688-1dad-2a3e-4e4bbac88bf2.png)
Faviconについて

# はじめに
インターン先でFaviconの差し替えをしたら、思った以上にFaviconの知識がなかった。
タスクを進める中で調べた内容をまとめる。

# Faviconとは
ブラウザで複数のページを開いたとき、タブに表示されるアイコンのこと。
Faviconという名前の由来が **Favorite Icon** だったことも初耳。
![スクリーンショット 2021-07-13 15.34.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748993/61640689-1cfc-58ec-cd12-9ad58249fbde.png)

# サイズ
以下の二つが主らしい。

- 16px × 16px
ブラウザのタブ部分で使用。

- 32px × 32px
Retina対応ブラウザのタブ部分で使用。
なお、RetinaはApple社が開発した高画質ディスプレイを指す。

16px × 16px の画像と 32px × 32px の画像二つから、両方のサイズに対応したFavicon（マルチアイコン）を作ることもできるが、詳しい内容は[後ほど](#マルチアイコンの作成方法)記述する。

他に 24px × 24px や 180px × 180px などのサイズが存在。
ただ 180px × 180px くらいの大きさになると、タブではなくスマホのホーム画面上のショートカットアイコン（ウェブクリップアイコン）として用いられる。

# ファイル形式
基本的には **.ico** だが、ブラウザによっては **.png** や **.gif** も利用可能。

### Chrome / Firefox / Safari / Opera / Edge
上記の形式のいずれにも対応している。
### Internet Explorer
バージョンによって対応形式が異なり、IE11以上であれば **.png** と **.gif** も使えるが、それ以外では **.ico** のみ。
ただし Internet Explorer のサポートは2022年に停止される予定で、Microsoft Edge が主流となるらしい。

# マルチアイコンの作成方法
探すと色々なツールが見つかったが、今回は [**Image Magick**](https://imagemagick.org/index.php) を使った。
フォーマット変更やサイズ変更などをコンソールから実行できるソフトで、20年以上前からあるっぽいので驚き。

以下のコマンドから Homebrew でインストールした。

```
brew install imagemagick
``` 
favicon化したい元の画像 favicon.png を用意し、次のコマンドで 16px × 16px と 32px × 32px のマルチアイコン favicon.ico を作成した。
`auto-resize`オプションには複数のサイズを指定でき、それらに対応したマルチアイコンが生成される。

```
convert favicon.png -define icon:auto-resize=16,32 favicon.ico
```


# 設置方法
プロジェクトのディレクトリに使用する faviconファイルを置いたら、html の linkタグで設定する。
## .png形式の場合

```
<link rel="icon" type="image/png" href="ファイルパス"/>
```

## .gif形式の場合
```
<link rel="icon" type="image/gif" href="ファイルパス">
```

## .ico 形式の場合
対応ブラウザに応じた記述をしなければいけないので注意。
### Internet Explorer

##### IE11以上

```
<link rel="icon" href="ファイルパス"/>
```

##### IE9以上

```
# 以下のどちらか
<link rel="icon" href="ファイルパス" type="image/x-icon"/>
<link rel="icon" href="ファイルパス" type="mage/vnd.microsoft.icon"/>
```

##### IE8以下
```
<link rel="shortcut icon" href="ファイルパス">
```

### Chrome / Firefox / Safari / Opera / Edge
上記の記述方法のいずれでも良い。

# おわりに
Faviconにここまで悩むとは思っていなかった。
初めてちゃんと調べたけれど、今まで闇雲に扱ってきたことを反省。

# 参考

- https://www.i-ryo.com/entry/2021/04/14/054602
-　https://sdesignlabo.com/web/favicon/
- https://wemo.tech/1712
- https://glatchdesign.com/blog/settings-favicon/
- https://blogs.windows.com/japan/2021/05/19/the-future-of-internet-explorer-on-windows-10-is-in-microsoft-edge/
- https://miuxmiu.me/post-212/
- https://glatchdesign.com/blog/settings-favicon/
- https://note.com/34san_/n/na2eec52af710
ペアシーケンス時の方向情報

<font size="+3" color="#AAA">
[PictBio HP「解析メモ」](https://www.pictbio.com/tips/2998.html)から移行中です。
元記事：2018/10/30 公開 ペアシーケンス時の方向の情報はどう使うか
</font>

　同じ配列断片から複数個所シーケンスを行う手法を使うとデータ解析の時に、お互いのシーケンスデータのシーケンス方向も情報になります。

>[同じ断片から複数個所シーケンスする利点についてはこちら](https://qiita.com/PictBio/items/b9598a2ad72573a1f735)

#ペアシーケンスの方向とは
　同じ断片から複数シーケンスをとると、１本目のシーケンス方向に対し N 本目のシーケンスの方向は同方向、または、逆方向かといったことが考えられれます。

　アライメント計算ツールを使う際に、２本ペアのシーケンスアプリケーションによるシーケンスデータに対応している場合、方向の設定をオプションで指定する時があります。その際によく見る設定値は次のようなものがあります。（「–」シーケンス、「>/<」方向、「=」配列）
 

###fr（forward-reverse）
```
––––>        <––––
================== 
```

###ff（forward-forward）
```
––––>        ––––>
================== 
```

###rf（reverse-forward）
```
<––––        ––––>
================== 
```

　これはペアの方向の関係性をあらわしています。

　fr と rf の違いは、前者が断片の内側に向かってシーケンスされている、後者が逆に外側に向かってシーケンスしているかの違いになります。（ツールによっては独自の設定がある可能性があるため、よく確認する必要があります。）

#マッピングの正確性をさらに上げる
　リファレンスに対しマッピングする際に、ペアのリードの方向関係がオプションの設定に一致すると、スコアを上げるなどの計算の補正に情報が使われます。

#検出変異の精度が上がる
　その他にも、このマッピング情報を使って、リファレンスに対し設定と異なる方向関係でアライメントが行われていたら、逆位が考えられます。また、前回もお話した転座などでも境目の予測に使うことができます。

#シーケンスアプリケーションの方向の例
　シーケンサーによってロジックが異なるので Paired-End イコール fr の方向ではありません。

|シーケンサー  |アプリケーション  |方向  |
|---|---|---|
|Illumina MiSeq  |Paired-End  |fr  |
|Illumina MiSeq  |Mate Pair  |rf  |
|Ion Torrent  |Paired-End  |fr  |
|Ion Torrent  |Mate Pair  |rf  |
|Roche 454  |Paired-End  |ff  |