OmniAICreator/Qiita-1.07M huggingface dataset:
素因数分解が既に分かっている場合の約数列挙 (Python)

# はじめに

AtCoder等の競技プログラミング問題を解いているとき、「素因数分解は既に分かっているから、これを組み合わせて約数を生成したい」ということをやりたくなる場合があります。
その方法について、教わった&考えた内容をまとめました。

# 問題

このような問題を考えます。

> **問題**
> $N$ 個の整数からなる数列 $A$ があります。
> 数列 $A$ の積 $A_1 * A_2 * ... * A_N$ を $X$ とするとき、 $X$ の約数をすべて出力してください。

> **制約**

> * $N <= 2 * 10^5$
> * $A_i <= 2 * 10^5$
> * $X <= 10^{18}$

> **入力形式**

> ```
> N
> A1 ... AN
> ```


<details><summary>**Sample**</summary><div>

Input

```
3
2 2 3
```

Output

```
1
2
3
4
6
12
```
</div></details>

# 素朴な解法

素朴には、まず積 $X$ を求めてから、 $2$ ～ $\sqrt X$ の範囲で試し割りすればよいですが、
試し割りの計算量は $O(\sqrt N)$ のため、積 $X$ が巨大な場合に計算量が大きくなってしまいます。

# Xの素因数分解を求める

ここで、積 $X$ を直接求めるのではなく、 **積 $X$ の素因数分解** を求めることを考えます。
次の図で示すように、**自然数の掛け算は素因数のマージ** であることを利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155933/4ba8887d-aa7a-3a70-6970-e6e825fa84a6.png)


つまり、数列 $A$ の各要素ごとに素因数分解をし、その結果の **指数部を足し合わせる** ことでマージします。
これは $O(N * \sqrt {maxA})$ で求めることができ、今回の制約下で高速に求まります。

```python
from collections import defaultdict
def prime_factors_from_list(A):
    """
    数列Aの全要素を掛けた数の素因数分解を求めます。
    """
    # 数列Aの各要素を素因数分解しながらマージする。
    # 素因数の辞書を1つ用意し、各要素について素因数を発見するたびに追加していく。
    prime_factors = defaultdict(int)
    for a in A:
        tmp = a
        factor = 2
        while factor ** 2 <= a and tmp != 1:
            while tmp % factor == 0:
                a_is_prime = False
                prime_factors[factor] += 1
                tmp //= factor
            # 2,3,5,7,9...
            factor += (1 if factor == 2 else 2)
        if tmp != 1:
            prime_factors[tmp] += 1
    return prime_factors

print(prime_factors_from_list([12,15]))
""" (出力結果。 2^2 * 3^2 * 5^1 という素因数分解を表します。)
defaultdict(<class 'int'>, {2: 2, 3: 2, 5: 1})
"""
```

# 素因数分解から約数を列挙する

このようにして求めた積 $X$ の素因数分解から、約数リストを求めるにはどうすればよいでしょうか。

たとえば、 $12$ の素因数分解は $2^2 * 3^1$ であり、約数は $1,2,3,4,6,12$ の6つです。
これは次のように、 **各素因数についての、指数の選び方のパターン** と対応付けることができます。

$1 = 2^0 * 3^0$
$2 = 2^1 * 3^0$
$3 = 2^0 * 3^1$
$4 = 2^2 * 3^0$
$6 = 2^1 * 3^1$
$12 = 2^2 * 3^1$

素因数 $2$ の指数は $0,1,2$ の3通り、 $3$ の指数は $0,1$ の2通りなので、
$3*2=6$ 個の約数が得られています。

この考え方は、 **既知の約数それぞれに対して、今注目している素因数を掛けたものを求めて約数リストに追加する** という作業の繰り返しとして実装できます。

```python
def divisors_from_prime_factors(prime_factors, need_sort=True):
    """
    素因数分解から約数リストを生成します。(1とその数自身を含む)
    
    Parameters
    ---
    prime_factors
        素因数分解を表現した、タプルのリスト。
        p1^a1 * p2^a2 であれば、 [(p1,a1),(p2,a2)] 。
    need_sort
        Trueの場合、約数リストをソートして返します。
    """
    # 既知の約数リスト
    div = [1]
    for p,a in prime_factors:
        # 既知の約数それぞれに対して、
        # p^1倍, p^2倍, ... p^a倍 したものを計算して約数リストに追加する
        m = len(div)
        for i in range(m):
            for j in range(1, a+1):
                div.append(div[i] * p**j)
    if need_sort:
        div.sort()
    return div
```

# 完成

上記の関数を用いて、次のように冒頭の問題が解けました。

```python
n = int(input())
A = list(map(int, input().split())
prime_factors = prime_factors_from_list(A)
divisors = divisors_from_prime_factors(prime_factors.items())
print(*divisors, sep="\n")
```
tshark で (Pre)-Master-Secret を使用し TLS (SSL) 通信のキャプチャを decrypt する

手元に (Pre)-Master-Secret があるんだけど TLS (SSL) 通信を復号化したいと思うことはありませんか？しかもコマンドラインで。

ありますよね、そんな時は tls.keylog_file にファイルを指定してあげるだけ。以下の例では該当のオプションで (Pre)-Master-Secret のファイルを指定すると http の通信が見えるのがわかります。

```
$ tshark -2r ./test_http11.pcap -R "http"
$ tshark -2r ./test_http11.pcap -o tls.keylog_file:./pre_master_secret.txt -R "http"
    1   6.404119   10.0.11.20 → 10.0.11.115  HTTP 213 GET / HTTP/1.1
    2   6.405361  10.0.11.115 → 10.0.11.20   HTTP 514 HTTP/1.1 200 OK  (text/html)
```

ちなみに [--export-files](https://tshark.dev/export/export_tls/) というオプションもあって暗号化されたファイルの復元ができたりもします。tshark 有能。

```
$ mkdir obj
$ tshark -Qr ./test.pcap -o tls.keylog_file:./sessionsecrets.pms --export-objects http,./obj
$ ls ./obj/
%2f
$ file ./obj/%2f
./obj/%2f: HTML document, ASCII text
$ cat ./obj/%2f
<html>
    <body>
        <h1>Hello, World!</h1>
    </body>
</html>
```

参照: 
[How to use (pre)-master-secret log file with tshark](https://osqa-ask.wireshark.org/questions/46699/how-to-use-pre-master-secret-log-file-with-tshark)

[TLS Encrypted](https://tshark.dev/export/export_tls/)
FargateにSSMでログイン ~停止したコンテナをマネージドインスタンスから一括削除~

## 概要
AWS ECS の Fargateコンテナに対してSSM使用したログインを行うことができる。その際にコンテナを生成するごとにマネージドインスタンスに登録されるが、コンテナが終了しても自動では削除されないため、手動で削除行う必要があった

AWSコンソール画面からマネージドインスタンスを一括で削除できないため、CLIを通して一括削除するコマンドを作成してみた

SSMを使ったコンテナへのログイン方法等については下記を参照

- [Fargate containerにSession Managerでログインする](https://enokawa.hatenablog.jp/entry/2019/09/05/104545)
- [FargateコンテナにSSH ~SSMで接続&RDSにSSHポートフォワーディング~](https://qiita.com/omukaik/items/4b721a93c45180ce6dbe)


### マネージドインスタンス一覧取得コマンド
- https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-instance-information.html

```shell
$ aws ssm describe-instance-information
```


下記のようにJSONでレスポンスが返ってくる。 --filterにKeyを指定することで一覧取得時の条件を指定することが可能

```json
{
    "InstanceInformationList": [
        {
            "InstanceId": "<instanceId>",
            "PingStatus": "ConnectionLost",
            "LastPingDateTime": "2020-04-20T15:38:33.983000+09:00",
            "AgentVersion": "2.3.978.0",
            "IsLatestVersion": false,
            "PlatformType": "Linux",
            "PlatformName": "Debian GNU/Linux",
            "PlatformVersion": "8",
            "ActivationId": "<ActivationId>",
            "IamRole": "service-role/AmazonEC2RunCommandRoleForManagedInstances",
            "RegistrationDate": "2020-04-20T15:38:32.732000+09:00",
            "ResourceType": "ManagedInstance",
            "IPAddress": "<IPAddress>",
            "ComputerName": "<ComputerName>",
            "AssociationStatus": "Failed",
            "LastAssociationExecutionDate": "2020-04-20T16:48:59.672000+09:00",
            "AssociationOverview": {
                "DetailedStatus": "Failed",
                "InstanceAssociationStatusAggregatedCount": {
                    "Failed": 1,
                    "Pending": 1
                }
            }
        }
    ]
}
```

### 削除コマンド
- https://docs.aws.amazon.com/cli/latest/reference/ssm/deregister-managed-instance.html

--instance-id に取得した InstanceId を 指定することで一つずつ削除が可能

```shell
$ aws ssm deregister-managed-instance --instance-id <InstanceId>
```

### 一括削除コマンド
一覧取得ときにConnectionLostおよび、ManagedInstanceを対象とし、接続が切れたマネージドインスタンスを削除するコマンドを作成した。ActivationIdを --filter で指定することはできなかった。実行する際は誤った物を削除しないように注意すること

```shell
$ aws ssm describe-instance-information \
    --filters \
       "Key=PingStatus,Values=ConnectionLost" \
       "Key=ResourceType,Values=ManagedInstance" \
    | grep 'InstanceId' \
    | awk '{print $2}' \
    | sed -e 's/,//g' \
    | xargs -L 1 -I arg aws ssm deregister-managed-instance --instance-id arg
```
yukicoder contest 263 参戦記

# yukicoder contest 263 参戦記

## [A 1198 お菓子配り-1](https://yukicoder.me/problems/no/1198)

突破できず. どこが★1だよというツッコミどころしかない. N≤10<sup>25</sup> で int64 に収まらず、これだけでも★1ではないよなと思った. まあ、Python は int64 の値域を超えてても平気であるが. 数学問題なんだろうなあとは思ったけど、やっぱり解けなかった.

```python
N = int(input())

if N == 1 or N == 4 or N % 4 == 2:
    print(-1)
else:
    print(1)
```

## [B 1199 お菓子配り-2](https://yukicoder.me/problems/no/1199)

素直な DP. 偶数個取った時の最大値、奇数個取った時の最大値を更新してばいいだけ.

```python
from sys import stdin
readline = stdin.readline

N, M = map(int, readline().split())

odd, even = 0, 0
for _ in range(N):
    s = sum(map(int, readline().split()))
    t = odd
    odd = max(odd, even + s)
    even = max(even, t - s)
print(odd)
```
TwitterでimgurのURLと他のURLを同時に乗せる際、imgurのカードを優先して表示させる方法

※本記事は 2020/08/29 時点のTwitterの仕様をもとに書いています
# 背景
Unity製のゲームを投稿できるWebサービス「UnityRoom」で下記記事の通りに実装すれば、Twitterカードを通して画像つきのツイート機能を作れます。
[【Unity1Week】 WebGLで画像つきツイートをしたい！](https://unity-senpai.hatenablog.com/entry/2019/07/07/130111)
![バク天使フエル.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/a2569fdf-ec47-0da2-7dfb-b02b5b48fa0f.png)
# 問題
しかしツイートにUnityRoomのゲームページのURLも盛り込むと、Twitterはゲームページのカードを作ってしまいます。
![倍々くりまんじゅう.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/95d79414-c24b-7abe-0459-9517ffa8ac94.png)
#解決法
ゲームページのURLの代わりにTwitterの短縮URLを利用すれば、imgurのTwitterカードだけが作られます。
![キャプチャ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307985/c6631fb6-5d65-6935-9428-f25998ee0946.png)
短縮URLとは、どんな長さのURLでも11文字分のURLで置き換える事で、短い文字数でURLを扱えるようにしたものです。URLを呟くと自動で短縮URLに変換されますが、見た目では分からないようになっています。
## 短縮URLの発行の仕方
ゲームページのURLを一度Twitterに投稿し、つぶやかれたツイートのURLを右クリックして「リンク先のアドレスをコピー」します。すると、UnityRoomのURLとは違う「https://t.co/... 」という短縮URLを取得できます。これをツイート機能でつぶやかれるようにしましょう。
 ツイートをなるべく公開したくない場合は、[tosツイ](https://www.google.com/search?q=twitter+tos%E3%83%84%E3%82%A4)しましょう（@tosが凍結解除されているため、@nullや@xxxを使った方が無難かもしれません）。
SQL①~uno~

SQLはデータベース言語の一つで、データベースの定義や操作を行うことができるのよ。

##データベース

####リレーショナルデータベース(RDB)
列と行からなる。
`SQL`という言語で操作する。
RDBの主なオープンソースの製品
・MySQL
・MariaDB ...MySQLから派生
・PostgreSQL
RDBの主な商用の製品
・Oracle Database ...Oracle社
・SQL Server ...Microsoft社
・DB2 ...IBM社　　
<br>
####キー・バリュー型データストア(KVS)
検索に使うキーとバリュー(値)の組み合わせを保存する。
KVSの主なオープンソースの製品
・memchaed(メムキャッシュディー) 
・Redis(レディス) 
<br>

####オブジェクト指向型データベース(OODB)
データとそのデータを操作する処理をオブジェクトという単位にまとめて管理する。
<br>
####XMLデータベース(XMLDB)
XMLというデータ形式はインターネット上で、やりとりされるが、それを大量かつ高速に扱うことができる。
<br>

##SQLのルール
大文字・小文字は区別されない。but混ぜるのはやめよう。
文末にセミコロンをつける。
文字と日付はシングルクォーテーションで囲む。
<strong>単語はスペースか改行で区切る。</strong>
全角は✖︎　半角で書こう。


##RDBMS
データベースの中にテーブルという入れ物を作ってそこにデータを入れていく。
テーブルを複数作成できるよ。
テーブルは表形式になってるんだ。
テーブルの横の行のことを`レコード`
テーブルの縦の列のことを`フィールド`または`カラム`
と呼ぶよ。

####クエリ
データの更新、削除、取得、検索などの要求をデータベースに送信すること。

####データ型
テーブルを作成するときに`カラム`に指定した形式のデータしか入力できないように設定するんだけど、この時に設定するデータの形式をデータ型というんだ。

主な型
・文字列型
char型
varchar(バーキャラ)型
text型
<br>
・数値型
int型
　int unsigned ...符号なしにできるよ
tinyint型
　tinyint(1) ...真偽値を扱えるよ
float型
double型
<br>
・日付、時刻型
date型
datetime型
time型



<strong>続く.............</strong>
【Javascript】同じ変数を参照したときの同期を回避する方法

## 結論
以下のようにJSON.parseとJSON.stringfyを使ってuser1との関係性を切ればok

```javascript
const user1 = {
  name: "たろう",
  sex: "man",
};

let user2 = JSON.parse(JSON.stringify(user1));

user2.name = "はなこ";
user2.sex = "woman";

user1.name; // =>たろう
user2.name; // =>はなこ
```

##解説
変数に代入するときに忘れがちなポイントがあります。
それは
「変数には参照先の情報が入っているだけで、その中身は入っていない」
ということです。
たろう君について見てみましょう。

```javascript
const user1 = {
  name: "たろう",
  sex: "man",
};
```
user1にはオブジェクトではなく、「太郎君について書かれたオブジェクトへの参照」が入ります。

この事実を念頭に置いて次の行を見てみましょう。「太郎君について書かれたオブジェクト」をstringにして、そのあとJSON形式でオブジェクトに戻しています。

```javascript
let user2 = JSON.parse(JSON.stringify(user1));
```

このとき、user2には「太郎君について書かれたオブジェクトのコピーへの参照」が入ります。

コピーです。
つまり、user1とuser2が参照しているものは「値が同じなだけで全く別物のオブジェクト」です。したがってuser2の値をいくら変えようがuser1には影響を及ぼしません。逆も然りです。

もしこの行を

```javascript
let user2 = user1;
```
とした場合、user2には「太郎君について書かれたオブジェクトへの参照」が入ります。user1と全く同じものです。
つまり、user1とuser2は「1つのオブジェクト」を参照します。親友同士が同じ女性に恋をした感じで切ないですね。

この状況でuser2の値を変更するとどうなるでしょうか。

```javascript
const user1 = {
  name: "たろう",
  sex: "man",
};

let user2 = user1;

user2.name = "はなこ";

user1.name; // =>はなこ
user2.name; // =>はなこ
```
はい、user1も変わります。

##おわりに
user1とuser2を別々に扱いたい場合は最初に紹介したような方法で同期を回避しましょう。

###参考記事
[JavaScriptに参照渡し/値渡しなど存在しない](https://qiita.com/yuta0801/items/f8690a6e129c594de5fb)
[JavaScriptで変数にオブジェクトを代入したら参照先が同期されてしまう現象について](https://ajike.github.io/JavaScript%E3%81%A7%E5%A4%89%E6%95%B0%E3%81%AB%E4%BB%A3%E5%85%A5%E3%81%97%E3%81%9Fobject%E3%81%8C%E5%90%8C%E6%9C%9F%E3%81%95%E3%82%8C%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86%E7%8F%BE%E8%B1%A1%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/)
PHPで超簡易ルーティング

まずはじめに

「こんなんルーティングっていうのか？(´･_･`)」

というツッコミは、甘んじて受けます。**てか、推奨します。**

「推奨するの？(´･_･`)」

## やりたいこと

例えば

**/pages/index.php?page=1**

みたいなURLではなく

**/pages/1/**

で処理をしたい。ただそれだけ。
それだけですってば(´･_･`)

## .htaccess

プログラム単体でできるハナシではなく、サーバ側で、変なURLを受け付けても404にせずにindex.phpで処理をするように制御する必要があります。
そのために、.htaccessの設定をします。

```
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /pages/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /pages/index.php [L]
</IfModule>
```

実はコレ、Wordpressの.htaccessほぼそのままです。Wordpressをインストールしたディレクトリはこの設定によって、ルート下のindex.phpで全てのリクエストをさばくようになります。Wordpressという巨大システムの根幹はルーティングであるのだなあと、これを見ていると感じてしまいます。

## index.php

てなわけで。あらゆるリクエストがindex.phpで処理されるので、その際のURLを文字列として受け取って、処理して、パラメータとして使おうというわけです。

```php
<html>
<?php
  $url = $_SERVER['REQUEST_URI'];
  $url = str_replace("/pages/", "", $url);
  $url = str_replace("/", "", $url);
  
  if (ctype_digit($url)) {
    echo "ページ番号 → " . $url;
  } else {
    echo "数値以外";
  }
?>
</html>
```

受け取ったURL文字列から余計なものを置換で消したあとで、数値に変換する。ただ、それだけのプログラムです。

以上
【Swift】複数の非同期処理（ループ処理）の完了後に次の処理に移る方法（DispatchGroup）

#1. やりたいこと
API通信で非同期処理を実装する際に、複数の通信（ループ処理）がある場合に、最後までループ処理が完了した後にその結果を取り出す。

#2. 実装方法
　`DispatchGroup()`を使用した実装方法を示す。ここで、クロージャ_hoge_、_fuga_は通信処理である。 
　以下のスニペットで、`DispatchGroup()`がない状態を想定すると、「Sequence #4」は _hoge_ 、 _fuga_ のコールバック取得よりも先に実行される可能性が高いため、`Sequence #1 → 4 → 5 → 2 → 3`の順になる。
　`DispatchGroup()`を使用することで、`Sequence #1 → 4 → 2 → 3 → 5`の順になる。

　ポイントは、`dispatchGroup.enter()`と`dispatchGroup.leave()`が２回あること。
　最初の`enter()`でカウンターが＋１され、　_hoge_　処理が実行開始される。「Sequence #1」の通信が完了する頃には「Sequence #2」の通信を開始しているため、処理は「Sequence #2」の通信の結果を待たずに「Sequence #4」に移行するが、この時「Sequence #2」の位置の`enter()`によってカウンターが上がっているため、「Sequence #3」のコールバック完了まで「Sequence #5」に移行しない。

　なお、同様の機能を果たす実装方法は他にも考えられるが、検討した限りはこれが良いと思った。また、実際にはエラーに対する条件分岐などが入り込むが、この考え方を使用できる。

```swift
let dispatchGroup = DispatchGroup()
let dispatchqueue = DispatchQueue.global(qos: .userInitiated)

dispatchGroup.enter()
dispatchqueue.async {
   hoge { foos in
       // Sequence #1
       for foo in foos {
          dispatchGroup.enter()
               // Sequence #2
               fuga { bars in
                   dispatchGroup.leave()
                   // Sequence #3
               }                
       }
       // Sequence #4
       dispatchGroup.leave()
   }
}
dispatchGroup.notify(queue: dispatchqueue){
   // Sequence #5
}   
```

#3. 参考リンク
[Swiftで複数の非同期処理の完了時に処理を行う](https://qiita.com/shtnkgm/items/d9b78365a12b08d5bde1)
[DispatchQueueを使って容量のあるファイルをダウンロードする方法](https://creatorhiro.com/archives/1125)
【Rails】エラー文が出ないのに、データが保存できない

初投稿です。間違えなどありましたら、ご指摘ください。
######エラーが出ないのに、データが保存できない
個人的によく引っかかるため、投稿します。
解決の参考にしてください。

######解決策
modelファイルにoptional: trueを追加（belongs_toのあと）
(デフォルトでは、references型のカラムが空で保存できないようになっているから？)


######前提
taskモデル（作業）と、start_timeモデル（開始時間）を作りました。
開始時間をつけずに、作業を保存します。
ちなみに、start_timeにはtask_idが保存されるようにします

```
start_timeモデルのマイグレーションファイル
略
  t.references :task
略
```

保存できませんでした。

######修正した前と後


```
task.rb
修正前
略
  belongs_to :start_time
略
```


```
task.rb
修正後
略
belongs_to :start_time, optional: true
略
```

######まとめ

belongs_toで、optional: trueをつければ、空の値も保存できる。
モデルの記述ミスは見つけづらいですね。
Mac-Catalina COBOL

##### [> 1. インストール](https://qiita.com/shunogu/items/6851b222c6ca748424d9)
##### [> 2. プログラム実行](https://qiita.com/shunogu/items/3fd655248b30a0a2d89e)
##### [> 3. プログラムの基本構造](https://qiita.com/shunogu/items/a0cc0ddd3af7117c2b67)
##### [> 4. 変数で文字列を扱う](https://qiita.com/shunogu/items/a1b481e8431ae9b458a0)
##### [> 5. 変数で数値を扱う](https://qiita.com/shunogu/items/ced7d9a46c862800f01e)
##### [> 6. 集合項目](https://qiita.com/shunogu/items/157f5a4ad8c9ff6ed82d)
##### [> 7. 配列](https://qiita.com/shunogu/items/e584e95b7443fd47e168)
##### [> 8. 四則演算](https://qiita.com/shunogu/items/e021b1322a3af39d76d1)
##### [> 9. ACCEPTで入力受付](https://qiita.com/shunogu/items/7d6c95ae1b02e19ef61a)
##### [> 10. IFで条件分岐](https://qiita.com/shunogu/items/cf51eb5570e92e29cceb)
##### [> 11. EVALUATEで条件分岐](https://qiita.com/shunogu/items/accf74bab4edf1d3a161)
##### [> 12. PERFORMで条件分岐](https://qiita.com/shunogu/items/e46025ca9193d02d6bd5)
optional: trueをつけるその前に！デバッグの一例

## 概要
「ActiveRecord::RecordInvalid: Validation failed: Users must exist」というエラーが出たので検索をしていると、正しくなさそうな「optional: true」を使用した回避策が散見されたのでデバッグの流れを中心に書いてみました。
学習し始めは、自分でデバッグしようにも**何をすればいいのか分からない!**ということが多かったので何かの参考になれば嬉しいです。

## エラーの発生状況と原因
### エラーの発生状況
[ミニブログにコメントをつけるアプリ](https://mini-blog-with-comment-unction.herokuapp.com/)を作っている最中にコメントの投稿をsaveすると、一見正しく見えるのにsaveがfalseになっていた。

### 原因
アソシエーションが正しくなかった。

```ruby:user.rb
class User < ApplicationRecord
  has_many :blogs, dependent: :destroy
end
```

```ruby:blog.rb
class Blog < ApplicationRecord
  # 間違い
  belongs_to :users

　# 正しい
  belongs_to :user
end
```

## デバッグの流れ
### 1. save!を試す

saveがfalseになっていたのでsave!で強制セーブしてエラーを確認。
「Users must exist」をみた時点で複数形になっていることを気づくべきだった。

```zsh
pry(main)> blog = current_user.blogs.build(blog_params)
pry(main)> blog.save
=> false
pry(main)>blog.save!
ActiveRecord::RecordInvalid: Validation failed: Users must exist
```

### 2. エラーの中身を確認

```zsh
 @blog.save
=> false
[4] pry(#<BlogsController>)> @blog.errors
=> #<ActiveModel::Errors:0x00007f96e90695c8
 @base=#<Blog:0x00007f96ef23e528 id: nil, title: "a", body: "a", user_id: 1, created_at: nil, updated_at: nil>,
 @details={:users=>[{:error=>:blank}]},
 @messages={:users=>["must exist"]}>
```

### 3. optional: trueを付けてみた
検索結果にやたら出てきたので試してみると、保存に成功。
必要な値は揃っているので、データベースを確認しても全てのカラムが埋まっている。
しかし、裏技的で根本の問題は解決していないよね...

```ruby:models/blog.rb
class Blog < ApplicationRecord
  belongs_to :users, optional: true
end
```

### 4. belongs_toが複数形になっていることに気づく
アソシエーションは、一側を単数形、多側を複数形にしなければいけないので気をつけましょう。
[【Railsガイド】Active Record の関連付け](https://railsguides.jp/association_basics.html)

## 後書き
前にもこんなミスをやらかしていた気がしますが、久しぶりに一からコードを書いていたのでこういう部分でミスを多発していました(^^;
それにしても、エラーの出かたもoptional: trueで回避できることもなかなか面白い発見でした。
Gnu-COBOL プログラム実行

書き方は昔ながら古い「**正書法**」とその後導入された「**自由書式**」の2種類

## 正書法

- 厚手の紙に書かれたコードを[パンチカード](https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%B3%E3%83%81%E3%82%AB%E3%83%BC%E3%83%89)に転写してコンピュータに読み込ませるための書き方

```
1   12345678901234567890123456789012345678901234567890
2   ------ --A--+---------------------------- B ------
3   000000 IDENTIFICATION DIVISON.
4   000010 PROGRAM-ID.    HELLO.
5   000020 PROCEDURE      DIVISION.
6   000030 MAIN           SECTION.    
7   000040 DISPLAY        'hello world!'.
8   000050 STOP           RUN.
```

- **1列目から6列目**までは必ず「**行番号**」でなければいけない
- 7列目はその行の区分コード
- 8列目からコード
- コードの後にコメント

---

## 自由書式

```
IDENTIFICATION DIVISON.
PROGRAM-ID. HELLO.
PROCEDURE DIVISION.
  MAIN SECTION.    
    DISPLAY 'hello world!'.
    STOP RUN.
```

- 列の制約はない
- `EOF`は必ず改行
- インデントで整形(しなくてもコンパイルは通る)


## Hello Worldを表示する

#### `hello.cob`を作成

- 拡張子は`.cob`が一般的

```:hello.cob
IDENTIFICATION DIVISON.
PROGRAM-ID. HELLO.
PROCEDURE DIVISION.
  MAIN SECTION.
    DISPLAY 'hello world!'.
    STOP RUN.

```

#### コンパイルする

```
$ cobc -x --free hello.cob
```

|オプション|意味|
|---|---|
|**`-x`**|実行ファイルを作成|
|**`-free`**|自由書式で作成する|

`cobc` は 「COBOL Compiler」

<details><summary>コンパイルが成功</summary>
![スクリーンショット 2020-08-29 2.12.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320855/a62d8b39-38e6-2703-05f1-b1cebee3ad43.png)
エラーが出なければコンパイル成功<br>
実行ファイルが作成される
![スクリーンショット 2020-08-29 2.27.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320855/02fd1a7e-dd57-add7-027f-1df2280eb6ed.png)
<br><br><br>
</details>
<details><summary>エラーの場合</summary>
コンパイルが失敗し実行ファイルは作成されない
![スクリーンショット 2020-08-29 2.20.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320855/eebece61-b182-b7bf-51f8-53f2f56bfefe.png)
`hello.cob: 6: warning: line not terminated by a newline` -> ファイルの終端が改行ではない
`hello.cob: 1: error: syntax error, unexpected Identifier, expecting DIVISION` -> タイポ
</details>

---

#### 実行

```
$ ./hello
```

![スクリーンショット 2020-08-29 2.34.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320855/48d2252b-b4a4-70ea-1947-ae13c1550e70.png)
MPAndroidChartで棒グラフを作ったらx軸ラベルがなぜかずれた話

#はじめに
たまたま機会がありAndroid Studioを用いて簡単なアプリ開発を行いました。
その中でグラフを書きたいと思い調べたところ「MPAndroidChart」というライブラリを用いればいいことがわかり、いくつかのサイトを参考にしながら棒グラフを作りました。
しかしその中でx軸のラベル設定がうまくいかず小一時間ほど苦労したので、その過程と解決策を記しておきます。
(余力があれば後から実際動かした画像も貼りたいところです)

#困った部分

今回の問題に関係ない部分は大分端折っていますが、大枠は以下のような感じ。
こちらの記事を参考にさせていただいています。

『MPAndroidChartでシンプルな棒グラフの作成』
https://qiita.com/iKimishima/items/7fd192a074739cf5290b

``` MainActivity.java
public class MainActivity extends AppCompatActivity {

    protected BarChart chart;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        chart = (BarChart) findViewById(R.id.chart1);

        //表示データ取得
        BarData data = new BarData(getBarData());
        chart.setData(data);

        //X軸
        XAxis xAxis = chart.getXAxis();
        //X軸に表示するLabelのリスト(最初の""は原点の位置)
        final String[] labels = {"","りんご", "みかん", "もも"};
        xAxis.setValueFormatter(new IndexAxisValueFormatter(labels));

    }

}
```

特にこの最後のこの部分。

```
xAxis.setValueFormatter(new IndexAxisValueFormatter(labels));
```
ほかのサイト等でも、事前にString配列で定義したものをnew IndexAxisValueFormatterに引数として与えているわけですが、このままだとなぜか代入するデータによってうまく軸が表示されないことがありました。
（本来であれば３つの要素に対してりんご、みかん、もものラベルがつくはずが、なぜか３つの要素にみかん、もも、（ラベルなし）となってしまうという感じです。ただlabelsの内容によってはうまくいくこともありました）

#解決策
理由はともあれ、「とにかく早く動いてくれ～」という気持ちだったので、調べてみたところ以下のサイトに辿り着きました。

『MPAndroidChart - 棒グラフにラベルを追加する』
https://www.366service.com/jp/qa/94329e5e85f6eddc6886945506ec0759

ここではIndexAxisValueFormatterを使わずにフォーマッタを作成することでラベルを設定する、という解説があります。
使いたいクラスにLabelFormatterを突っ込み、setValueFormatterの引数をそれに合わせてやることでグラフは直りました。

``` hoge.java
//先ほどまで
xAxis.setValueFormatter(new IndexAxisValueFormatter(labels));
//更新後
xAxis.setValueFormatter(new LabelFormatter(labels));
```

``` fuga.java
 public class LabelFormatter implements IAxisValueFormatter {
    private final String[] mLabels;

    public LabelFormatter(String[] labels) {
        mLabels = labels;
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        return mLabels[(int) value];
    }
}
```


#結局のところ
なぜIndexAxisValueFormatterが意図した通りに動いてくれなかったのか、真相はよくわかりませんでした。
ライブラリのバージョンとかが関係していそうな気はするのですが……
意外とMPAndroidChart周りの記事が少なく、同じような壁に当たっている日本語のサイトを見つけなかったので、寄せ集めの知識ではありますが記事にさせていただきました。
実際のコードなどについては以下の記事を参照していただいたほうが確実かと思います。

グラフ関連は設定する項目が多い・かつ分かりやすくまとめられたものを見つけられなかったので、機会があれば自分で整理してみたいと思いました。

#大いに参考にさせていただいた記事様
『MPAndroidChartでシンプルな棒グラフの作成』
https://qiita.com/iKimishima/items/7fd192a074739cf5290b
『MPAndroidChart - 棒グラフにラベルを追加する』
https://www.366service.com/jp/qa/94329e5e85f6eddc6886945506ec0759
ファイル連番処理を間違えた際の修正(bashを用いて)

#ファイル連番処理を間違えた際の修正
先日、連番名（00001.jpg etc）のついた大量の画像が、ある画像を起点として、番号が一つずれ、
手で一つ一つ直すのが苦痛だと相談をしてきた後輩がいたので、手伝った時のメモです。

後輩はmacOSを使っていたので今回は修正にbashを使うことにしました。

まず、画像数は90000枚程度で、12000番目から画像が一枚抜けて、最後まで一つ番号がずれていた。
なのでforで繰り返し処理をして、正しいファイル名に修正する。

まずは、12000番目の間違ったファイル名の画像を別のフォルダにコピーする（※失敗した時取り返しがつかないため、作業のためのフォルダを作る、また全ての画像に対してバックアップをとっておく）

元々の画像があるフォルダ→main
バックアップ用フォルダ→backup
作業用フォルダ→folder
修正済みファイル格納フォルダ→fixed

最終的にスクリプトは以下のようになりました。

```bash:filenamefix.sh
mkdir folder; mkdir backup; mkdir fixed
cp -r main backup
cp -r main folder
for i in `seq 78000`
do
cp folder/$(($i+11999)).jpg fixed/$(($i+12000)).jpg
done

for i in `seq 11999`
do
i=`printf %05d $i`
cp folder/$i.jpg fixed/
done
```

##コマンド解説

+ mkdirはフォルダを作成するコマンドです。  
+ cpはファイルをコピーするコマンドです。  
+ forは繰り返し構文です。  
+ seqは連続番号の他、一定間隔置きに数字の列を出力するコマンドです。  
+ $(())はbashで計算を行う構文です。

##作業の流れ

まず各種フォルダを作成する

```bash

$ mkdir folder
$ mkdir backup
$ mkdir fixed
```

次にバックアップをとる

```bash
$ cp -r main backup
```

繰り返し処理を行う

```bash
$ for i in `seq 78000`
do
cp folder/$(($i+11999)).jpg fixed/$(($i+12000)).jpg
done
```
繰り返し処理では、iという変数をfor構文の中で定義し、seqを使って順番に一ずつ数字が代入される

```bash:例
$ for i in `seq 10`
do
echo $i
done

↓result
1
2
3
4
5
6
7
8
9
10
```
また$(())でファイル名のズレを計算後cpでコピーする
(※bashで変数を扱うときは変数名の前にドルマークが必要)

```bash:ファイル名のズレを計算
$ cp folder/$(($i+11999)).jpg fixed/$(($i+12000)).jpg
```

修正の必要のあるファイル数は合計で78000なので78000回繰り返せば良い。

```bash
$ for i in `seq 78000`
do
cp folder/$(($i+11999)).jpg fixed/$(($i+12000)).jpg
done
```
最後に元々問題のなかったファイルをfixedフォルダに統合する。
（※ちなみに、1から9999までのファイルにはゼロ埋めがされていたので、変数iに対しても1から9999まではゼロ埋めをする必要があった。→　printf %05d $i）

```bash
$ for i in `seq 11999`
do
i=`printf %05d $i`
cp folder/$i.jpg fixed/
done
```
以上で完了です。
作業にかかった時間は説明などを聞く時間も含めておよそ10分程度でした。
もし仮に一つ一つ手で付け直していたら一つのファイル名修正に約10秒かかるとして、
216時間かかることになるので、大変喜んでいました。
こういった作業をPCに不慣れな方でもサクッと解決できるアプリがあればいいなと思いました...
CygwinでOpenCVを入れる

C++で画像処理をするためにOpenCVを入れることにしました．
普段からCygwinを使用しているため，CygwinでOpenCVを入れようと思い色々なサイトで調べてみたのですが，Cygwinパッケージでインストールする方法がほとんど書かれていなかったので，備忘録もかねて書き残そうと思いました．

# 動作環境
Windows環境でOpenCV 3.4.1をインストールします．
（現在，OpenCV 4.4がありますが，Cygwinではサポートしていないようです）


# Cygwinのインストール
CygwinはWindowsにUNIXライクな環境を構築できるものらしいです．自分はもともとC，C++を使うためのgccやg++を使うためだけに入れていました．最近はmakeとかも重宝してます．

cygwinそのもののインストール，またgcc，g++パッケージのインストールについては他のサイトで多く解説されているのでそちらを参考にしていただけたらと思います．

# OpenCVパッケージのインストール
libopencv3.4というパッケージを選択し，インストールするバージョンを選択します（"Skip"の場合はインストールされません）．
![cygwin_opencv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404252/db05007c-3425-0ee2-273f-98781e40527e.png)

# 動作確認
パッケージを入れたら動作確認です．下のようなプログラムを実装し，コンパイルします．

```opencv_test.cpp
#include <opencv2/opencv.hpp>

int main(int argc, char* argv[]) {
	// 画像データを入れるオブジェクト
	cv::Mat image(256, 256, CV_8UC3);

	// テキストを描画する
	cv::String text = "Hello, world";
	cv::Point org(0, 100);
	int fontFace	 = cv::FONT_HERSHEY_SIMPLEX;
	double fontScale = 1.0;
	cv::Scalar color(0, 255, 127);		  // Blue, Green, Red
	cv::putText(image, text, org, fontFace, fontScale, color);

	// 画像を出力する
	cv::String path = "hello-world.png";
	cv::imwrite(path, image);

	return 0;
}
```

コンパイルする際，ライブラリをリンクする必要があります．
```
g++ cv_test.cpp -lopencv_core -lopencv_imgproc -lopencv_imgcodecs
```

プログラムを実行し，以下のようなファイルが出力されたら成功です．
![hello-world.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404252/f1348765-1ecc-bdb1-53df-d87c13ad1f3f.png)


OpenCV関連のライブラリは上の3つ以外にもたくさんあります．どのコマンドがどのライブラリに対応しているかいちいち確認するのも面倒なので，下のようにまとめてしまうのが良いと思います（makefileやCMakeを使ったほうがもっと楽だと思います）．

```
g++ cv_test.cpp -I/usr/local/include -L/usr/local/lib -lopencv_calib3d -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lopencv_ml -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_video -lopencv_videoio
```

# まとめ
CygwinでOpenCV 3.4.1をインストールする方法についてまとめました．OpenCVのインストールは結構苦労する印象でしたが，Cygwinのパッケージを使えば簡単にインストールできるんですね．
Linux (ユーザーとsu/sudoコマンドについて)

こちらではユーザーについて簡単に解説を行います。
<b>・一般ユーザ</b>
<b>・rootユーザ</b>
について、理解してください。

rootユーザは簡単に言うと管理者です。
ユーザのパスワードを変更したり、大事なファイルの変更を行ったり出来ます。
普段使う事はまずないと思います。
何かしらで必要になったタイミングで使用される認識です。

逆に一般ユーザは日常で作業する際に使用するでしょう。
普段使ってるのは、ここですね。

プロンプトでは下記のように見分ける事が出来ます。

```:rootの場合
#
```

```:一般ユーザの場合
$
```

とりあえず、一般ユーザとrootユーザがいるんだなと思って頂ければ問題ありません。
lpic101やる上では、とりあえず理屈も大事なので(覚えるの大変です)

ここからはコマンド<b>su</b>/<b>sudo</b>について、解説していきます。
suコマンドはユーザの切り替えの際に使用されるコマンドです。

たとえば、一般ユーザnekoからrootユーザに切り替えたい時
以下のようにsuコマンドを入力後に、rootユーザのパスワードを入力を行うと
rootユーザへの切り替えが行われます。

```
neko     $  su
パスワード:　　
```


パスワード入力後、rootでプロンプトが返ってきます。

```
neko     $  su
パスワード:
root     #
```

別のパターンで一般ユーザから一般ユーザで切り替えを行う場合は
su ユーザー名で入力を行い、パスワードの入力を行います。

```
neko     $   su inu
パスワード:
```

inuでプロンプトが返ってきます。

```
neko     $   su inu
パスワード:
inu      $
```


次はsudoコマンドです。
一時的にroot権限でコマンドを使用する事が出来ます。

このコマンドを使用するには、visudoを編集する必要があります。
rootじゃないと、編集を行う事は出来ませんので
suコマンドでrootユーザへの切り替えを行いましょう。

```
root   # visudo
```

英文で色々書いてますが
最後の行に　ユーザ名  ALL=(ALL)  ALL  と入力し
保存して閉じれば、sudoコマンドは使えます。

※ファイルの編集等を行う際に、エディタを使っています。
こちらに関してはまた別の機会に解説します。
oキーで入力開始、入力後はEscキー→:wqでファイルが保存されて閉じられます。


sudoコマンドですが
たとえば、root権限を持ちながらlsコマンドを実施したい時
sudo lsと入力すれば、そのようになるわけです。


・一般ユーザーとrootユーザーについて
・suとsudoについて

でした。

次は→<a href="https://qiita.com/larcmiya/items/190ab5773d0b5c4504fb">ユーザーの追加・削除について</a>
Rustのconst fnの制限がさらに緩和された(Rust 1.46.0)

[Rustのconst fn](https://qiita.com/block/items/38f9d41aa9b655fdc093)
[Rustのconst fnでabs](https://qiita.com/block/items/8a4aadd1f25c1ac9ad21)
[Rustのconst fnの制限が緩和された(Rust 1.33.0)](https://qiita.com/block/items/a7743ab456048db992f2)
[Rust 1.39.0でabsがconst fnになる](https://qiita.com/block/items/646c725289a8431383f9)
上記の記事の関連・続きみたいなものです。


# Rustのconst fnの制限がさらに緩和された
Rust 1.46.0で`const fn`の制限が更に緩和されました。

## 変更内容
下記が使用できるようになりました
- `if`, `if let`, `match`
- `while`, `while let`, `loop`
- `&&`演算子, `||`演算子

`for`は使用できないままですが変数は使用できるのでほぼ普通の関数と変わらない書き方ができるようになりました。

### `for`は使用できない
上で書きましたが`for`は使用できません。
しかし変数は使用できるのでn回ループみたいなことは`while`と`let`で代用できます。

#### 1~10までの合計を返す
```rust
const fn foo() -> i32 {
    let mut i = 1;
    let mut sum = 0;
    while i <= 10 {
        sum += i;
        i += 1;
    }
    sum
}
```

#### 引数で渡されたスライスの要素の合計を返す
```rust
const fn sum(a: &[i32]) -> i32 {
    let len = a.len();
    let mut i = 0;
    let mut s = 0;
    while i < len {
        s += a[i];
        i += 1;
    }
    s
}
```

## `abs`を書いてみる
過去に`abs`を書いていたので1.46.0でどうなったのか書きます

```rust
const fn abs(value: i32) -> i32 {
    if value >= 0 {
        value
    } else {
        -value
    }
}
```
普通の関数と変わらないです。

## 所感
ほぼ普通の関数と変わらない書き方ができるようになってきました。
シンプルな関数ならとりあえずconstつけといても困らないんじゃないでしょうか？
1.31.0や1.39.0のときみたいな苦労・工夫をしなくていいのはありがたいです。

## 参考
[Announcing Rust 1.46.0](https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html)
[Rust 1.46を早めに深掘り - OPTiM TECH BLOG](https://tech-blog.optim.co.jp/entry/2020/08/28/080000)
if文を使わずに1と2を入れ替える

「1か2のどちらかが入っている変数を受け取って、1なら2、2なら1を返したい」という状況がありました。

そんな時に使える、1と2を入れ替える便利な書き方を知ったのでメモ。



# 追記

コメントで指摘を受けて、もっと簡単な書き方がありました。

### 1と2を入れ替える

```python
n = 1
print(3-n) # 2
m = 2
print(3-m) # 1 
```

### 0と1を入れ替える

```python
n = 0
print(1-n) # 1
m = 1
print(1-m) # 0 
```

### 一般化
$x$が$n$と$n-1$のどちらかであるとき、

```math
\begin{eqnarray}
f(x) &=& 2n-1-x\\&=&\left\{
\begin{array}{ll}
n & (x = n-1) \\
n-1 & (x =n)
\end{array}\right.
\end{eqnarray}
```

証明するまでもなく自明。

というわけで、**ここまでの話で十分なので残りは読まなくていいです。**

# 読まなくていいやつ(元の記事)
元の記事を一応残しておきます。
## 1と2を入れ替える書き方

```python
n = 1
print(n%2+1) # 2
m = 2
print(m%2+1) # 1 
```
これだけ。

## 他の数字について考えてみよう

これだけじゃ記事にならないので、頭の体操として他の数字について考えてみる。

## 0と1を入れ替える

0と1を入れ替えることを考えてみよう。boolで扱うとかはなしで。

```python
n = 1
print((n+1)%2) # 0
m = 0
print((m+1)%2) # 1
```

できた。

## 2と3を入れ替える

同じように2を3、3を2に入れ替えてみる。

```python
n = 2
print((n+1)%2+2) # 3
m = 3
print((m+1)%2+2) # 2
```
## 3と4を入れ替える

3を4、4を3に入れ替えてみる。

```python
n = 3
print(n%2+3) # 4
m = 4
print(m%2+3) # 3 
```

### 一般化してみよう

$2n$と$2n-1$を入れ替える場合と$2n$と$2n+1$を入れ替える場合で計算式が変わる。

$2n$と$2n-1$を入れ替える場合

```math
\begin{eqnarray}
f(x) &=&x \bmod 2 +2n-1 \\&=& \left\{
\begin{array}{ll}
2n & (x = 2n-1) \\
2n-1 & (x =2n)
\end{array}
\right.
\end{eqnarray}
```

$2n$と$2n+1$を入れ替える場合

```math
\begin{eqnarray}
f(x) &=&(x+1) \bmod 2 +2n \\&=& \left\{
\begin{array}{ll}
2n & (x = 2n+1) \\
2n+1 & (x =2n)
\end{array}
\right.
\end{eqnarray}
```

~~適当に書きながら考えているので、もっと効率のいい書き方があるかもしれません。~~ありました（記事上部）。


# まとめ

迷ったらif文を使いましょう。
$emitで複数の値を親コンポーネントに渡す方法

### はじめに
子のコンポーネントから親コンポーネントに値を渡す場合は、emitを使用することが多いと思います。今回は、複数の値を渡したい時があったので、アウトプットとして記述します。
ちなみにemit自体の解説は割愛しますので、ご了承ください。


### サンプルコード

```Child.vue
<template>
  <div>
    <p>Child</p>
    <button @click="click">親にメッセージを渡す</button>
  </div>
</template>

<script>
export default {
  name: 'Child',
  data() {
    return {
      message1: 'メッセージ1',
      message2: 'メッセージ2',
    }
  },
  methods: {
    click() {
      this.$emit('click', this.message1, this.message2)
    },
  },
}
</script>
```
↑emitの第2引数以降にカンマ区切りで複数の値を渡してあげます。


```Parent.vue
<template>
  <div>
    <P>Parent</P>
    <child @click="click"></child>
  </div>
</template>

<script>
import Child from './Child'

export default {
  name: 'Parent',
  components: {
    Child,
  },
  methods: {
    click(...args) {
      console.log(args)
      // 出力　['メッセージ1','メッセージ2']
      const [message1, message2] = args
      console.log(message1,message2)
      // 出力 メッセージ1 メッセージ2
    },
  },
}
</script>
```

↑click関数の引数では、レスト構文を使用して、子から渡した複数の値を配列で受け取ることができます。
その後、分割代入を使用し、配列の要素一つずつを取り出して各々の変数に代入しています。
あとは、親コンポーネントで各自自由に使ってくださいませ🙇‍♂️
はい、以上になります。

### おわりに
短い記述になりますが、読んでくださりありがとうございます！
もし内容等に誤りがありましたら、ご指摘頂けると助かります。よろしくお願いいたします。
DifferenceKit で reload した時に Cell がうまく反映されない

[`DifferenceKit`](https://github.com/ra1028/DifferenceKit) という UITableView 及び UICollectionView の差分更新ライブラリを使用していた時に、CollectionView の追加 Section も含めた `changeSet` を reload した時に主に iOS11系で(iPhone8で確認)うまく Cell が表示されないという問題に遭遇していました。具体的な CollectionView の状態としては下記のような感じで、セクションアイテムが空ではない場合にのみセクションを追加していました。

- scrollDirection: `.horizontal`
- estimatedItemSize: `automaticSize`

## 解決策

解決策としては、CollectionView のセクションを常時設置するように変更し、reload では Cell のアイテムのみ batchUpdate で更新できるようにしたところ,iOS11系でもうまく Cell が表示されるようになりました。
`DifferenceKit` の問題なのか、システムの問題なのかは現在のところ不明なので、分かり次第追記したいと思います。
【個人的所感】QAエンジニアが現場で本当に求められているスキル

QAエンジニア採用担当の皆さん。
QAエンジニアの採用に苦労していませんか？採用には苦労していなかったとしても、メンバーが定着して安定した品質保証の業務を続けることは難しいと感じていませんか？

QAエンジニアの皆さん。
テスト業務が辛いなぁとか、なにかうまくいかないなぁとか、感じることはないでしょうか？

少なくとも私はここ１年、QAチームの立ち上げとチーム作りに奔走してきました。

そこで感じた、今の現場ではこんなスキルが必要だと感じた点を説明して、もし今悩んでいる人がいれば少しでも役に立つ記事になれば幸いです。


# 採用したい理想像と募集要項とのギャップ

QAエンジニアの募集要項と実際に求められているスキルには大きなギャップがあると思います。
例えば、転職サイトに掲載されているQAエンジニアの募集要項では以下のような記載があります。

```
『必須スキル』 
　• テスト設計とテスト実施の実務(5年以上) 
　• Webアプリケーションの知識 
```

```
【必須】 
web システムもしくはスマホアプリに関する分野でのテストプロセス全般 (計画/分析/設計/実施/品質評価) の業務経験 
```

```
必須 
　• テストの設計、ケース作成、実施のご経験 
　• 自社サービスの品質保証に本気で携わっていきたい方 
```


## 表向きの求められているスキル

**テストができること**

募集要項をみると、だいたいテスト関連の業務がこなせれば問題ないように見えます。
ただし、これには大きな落とし穴があります。

## 実際に求められているスキル

少し親切な募集要項がこちらです。

```
【必須要件】
■テストプロセスの新規作成、実行経験
■Web技術のテスト実務経験
■新機能に対するシステムテスト経験
■バグ分析からの改善策の提案、実行経験

【求める人物像】
■他部門とのコミュニケーションを円滑に進められる方
■臨機応変に物事に対応ができる方
```

テストだけではなさそうなことは、なんとなくわかります。ただし具体的にはどのようなスキルが求められているか、はっきりしません。
実際、全ての要件が見えている企業の方が少なく、テスト以外に求められていることがあっても何を身につければいいかは現場に入ってみないとわからないというのが現状だと思います。
例えば、テストをやればいいんだと思って入った職場でも、これできる？とかあれできるとかいろいろ求められて辛い思いをすることがあるんじゃないでしょうか？

そこで、私が考えている今のQAエンジニアに必要なスキルは以下の通りです。

* 全テストフェーズをこなせるテストスキル
* 適切なコミュニケーションスキル
* 一般的なITスキル
* テスト対象の知識
* 他職種の知識


# 全テストフェーズをこなせるテストスキル

大前提としてテストスキルは必須です。
具体的には以下のポイントを押さえておくといいと思います。

## 押さえておくべきポイント

### テスト実施

* テスト項目書の読み方
* バグ報告から対応完了までの流れ
* 優先順位の意味
* バグ報告時に必要な項目
* プロジェクト管理ツールの使い方
    * バグ管理ステータスの意味
* コミュニケーションツールの使い方

### テスト設計

* 画面設計書の読み方
    * 疑問点の洗い出し方法
* よく使うテスト技法
    * ブラックボックステスト
    * 同値クラステスト
    * 境界値テスト
* テスト観点の洗い出し方法
* テスト工数の見積もり方法
* 誰が読んでもわかるような日本語の文章を書く力

# 適切なコミュニケーションスキル

適切なコミュニケーションはQAエンジニアにとって非常に重要なスキルです。
テスト業務は１人で完結することはほとんどなく常に他職種の方とコミュニケーションをとる必要があります。

## 押さえておくべきポイント

* 入った部署のチャンネル一覧
    * どのような案件が動いていて、だれがどのようにコミュニケーションをとっているか把握します
* 進捗報告で必要な項目

# 一般的なITスキル

* Excelの使い方
* クライアントサーバシステムの概要

# テスト対象の知識

* Android、iOSの特徴
* 各デバイスのログの取り方

# 他職種の知識

* プランナーとは
    * 役割
    * 業務内容
* エンジニアとは
    * 役割
    * 業務内容
AWSのクラウドデータベースサービス

それぞれのクラウド事業者はユーザーの利用目的に合わせてさまざまなデータベースサービスを提供している。

OSやミドルウェアはクラウド事業者が管理しているので、ユーザーは短期間でデータベースを利用することができる。

以下は、AWSの場合の例である。

| Amazon RDS | Amazon DynamoDB | Amazon ElastiCache |  Amazon Redshift |
|:-----------:|:------------:|:------------:|:------------:|
| RDBMS(リレーショナルデータベースサービス)。| NoSQLサービス。リレーショナル機能は持たないが、高速で可能性が高い。        |インメモリキャッシュサービス。データベースへのクエリ結果をキャッシュするなどして、Webシステムの高速化を実現できる。    |データウェアハウスサービス。分析用途のデータ処理に特化している。    |
Ubuntu 向け Xymon クライアントインストール

```
# apt install xymon-client
```
インストール途中でXymonサーバのIPアドレスを聞かれるので、

![ubuntu_xymon.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70113/a4a6c9a1-5c07-6e20-f1c6-1a6cdc9acb94.jpeg)

IPアドレスを入力する。


Ubuntu 18.04で動作確認しました。


# ディスクとinodeの /snap/core/数値 が100%で赤くなるのを抑制したい

Xymonサーバ側のXymonホームディレクトリ/etc/analysis.cfg の
CLASS=linux 欄に、

```
    %^/snap/core/\d+$ IGNORE
```

```
    %^/snap/core/\d+$ IGNORE
```
を追加する。


# 設定ファイルのありか

XYMONSERVERS、CLIENTHOSTNAME、CLIENTOS、TMPFSSIZEの定義は
```
/etc/default/xymon-client
```
にある。
【Select2】ブラウザの"戻る"ボタン押下時にセレクトボックスの選択状態がズレる件について

こんにちは。

https://select2.org/

セレクトボックスのデザインやコンポーネントをリッチにする
select2プラグインについて、セレクトボックスを選択後に
ブラウザの戻るボタンで遷移をすると、実際の選択状況と
セレクトボックスボックスの表示がズレることがあったので、
改善できないか調査しました。



## 1.事象  
![wr2bh-5achk.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620553/94dade56-8d35-8a3c-5550-09f4b48bfc77.gif)


上記通り、"Language","age"で項目を選択して、ページ遷移を行った後に、
ブラウザの戻る機能で戻ってくると、"Language","age"共に"none"（初期値）が表示されているが、
セレクトボックスを開くと実際には"en-us","40"が選択されており、表示内容と実際の選択内容が
異なっている。



## 2.再現条件
PCのChromeブラウザで再現することを確認しています。
Google Chromeバージョン: 84.0.4147.135（Official Build） （64 ビット）
※バージョン70台から再現していた記憶があります
FireFoxやMac OS用Safari、iOS用Safari等では挙動に差はあるものの再現しませんでした。



## 3.解決
似たようなことを報告している方もいましたが、
すでに提示されている改善策では、自分の手元ではうまく動作しなかったため、ページの再読み込み時に
window.onload で保持している値を再選択するようにしたところ、うまいこと改善しました。

![l6huw-dn7a8.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620553/b5b52c86-df13-683f-3abd-2b34978d1194.gif)


ソース

```javascript

window.onload = function () {
var age = $("#age").val()
$("#age").val(age).trigger("change");

var Language = $("#Language").val()
$("#Language").val(Language).trigger("change");
}

```


###デモアプリ
https://myucy.herokuapp.com/select2


###デモアプリのソースコード
https://github.com/myucy/select2-browser-back-issue
【Nuxt.js】ユーザー認証付きログインページを作成してみた（登録なし）【勉強５】

# はじめに

自分が勉強した内容のまとめなので、正確性は保証しません。

[こちらのサイト](https://moneyhack.tech/09-nuxt/)にcodesandboxを埋め込んでいます。

実際の振る舞いを見ながらコードの確認ができるので非常に便利です。

https://moneyhack.tech/09-nuxt/

シンプルにcodesandboxめちゃくちゃおすすめなので、気になる方使ってみてください。

# ユーザー認証付きログインページの作成

今回は今まで学習してきた知識を用いてログインページを作成してみました。

ログイン後のページには、各ユーザーの名前が入ったユーザー独自のページを用意します。

ユーザー認証には Vuex のデータ管理、

ユーザー独自ページの作成にはパラメータの利用を用いて実装していきます。

# ログインページ完成像の確認

まずは最初に完成像を確認してみましょう。

[次のサイト](https://moneyhack.tech/09-nuxt/)にcodesandboxを埋め込んでいますので、実際の振る舞いをご確認ください。

https://moneyhack.tech/09-nuxt/

ユーザー ID には「sampleUser」、ユーザー PASS には「samplePass」を入力すると

sampleUser 専用のログイン後ページに遷移できることが確認できると思います。

# データ設計＆データ(store)実装

**データ設計**

Vuex の store に定義しておくデータの整理だけしておきましょう。

・user – ユーザー認証とリンク先の設定、ログイン後の表示に用いる。
・pass – ユーザー認証に用いる。

**データ(store)実装**

/store/index.js にデータの定義を行います。

今回のログインアプリには、ユーザー登録機能は実装しないため、ユーザーのデータは事前に入力しておきます。

    export const state = () => ({
        user: "sampleUser",
        pass: "samplePass"
    });

以上でデータ実装が完了です。

# 名前付きページの実装（パラメータ）

パラメータ利用のため、pages 配下を次のように設計します。

    pages
      - login
        - _user.vue
      - index.vue

\_user.vue がログイン後に遷移する名前付きページです。

次のようなコードになっており、受け取ったパラメータを表示しています。

```
<template>
<div>
    <p v-html="parameter">渡されたパラメータを表示</p>
    <nuxt-link to="/">Home Page</nuxt-link>
</div>
</template>

<script>
export default {
    data: function() {
    return {};
    },
    computed: {
    parameter: function() {
        return this.$route.params.user;
    }
    }
};
</script>
```

以上が名前付きページの実装です。

# ログインページの実装

ログインページに必要な機能としては以下の２機能です。

・ユーザー ID、ユーザー PASS の入力機能

・store に設定したデータとの照合機能

**入力機能の実装**

＜ template ＞の入力は次のようになっており、

```
<input type="text" v-model="inputUserId" placeholder="ユーザーID">
<input type="text" v-model="inputUserPass" placeholder="ユーザーPASS">
```

＜ script ＞のデータ定義は次のように実装しています。

```
data: function() {
  return {
    inputUserId: "",
    inputUserPass: ""
  };
},
```

**照合機能の実装**

＜ template ＞は次のように、ボタンでauthenticationイベントを発火しています。

    <button @click="authentication">ログイン</button>

＜ script ＞の認証は次のように実装しています。

```
methods: {
  authentication: function() {
    if (this.inputUserId === this.$store.state.user) {
      if (this.inputUserPass === this.$store.state.pass) {
        this.$router.push({ path: `/login/${this.$store.state.user}` });
      }
    }
  }
}
```

上記コードで、store からデータを引っ張ってきているのは次のコードです。

    this.$store.state.user

ユーザーに合わせた遷移を実装しているのが次のコードです。

    this.$router.push({ path: `/login/${this.$store.state.user}` });

router.push は意味合いとしては nuxt-link と同じです。

＜ script ＞内でページ遷移を実現したい場合には router.push を利用します。

詳しくは[こちらの公式](https://router.vuejs.org/ja/guide/essentials/navigation.html)を参考にしてください。

# おわり

簡単にですがログイン機能を実装してみました。

login フォルダをプライベートに設定するなどの機能追加は必要ですが、

ログイン機能の雰囲気は掴めたのではないでしょうか。

少しでも参考にしていただければ幸いです。お疲れ様でした。

[こちらのサイト](https://moneyhack.tech/)でNuxt.js解説しています！よかったらぜひ見ていってください！
Google OnAir Japanに参加しました - 2

* 開催日程
   * 2020年7月15日（水）〜9月9日（水）(日本時間)

* 場所
   * オンデマンド配信
   * セッション、デモなどを、いつでも好きな時に見ることができる

* 主催
   * Google Cloud

* 申し込み
   * https://cloud.withgoogle.com/next/sf/japan (日本語)

* 費用
   * 無料

## セッション - Cloud Firestore

### Cloud Firestoreとは
* 簡単に拡張できるサーバーレスデータベース
* カスタマイズ可能なセキュリティとデータ検証ルール
* リアルタイムデータ同期機能とオフラインモード
* モバイル、ウェブ、IoT、サーバーサイド言語向けの開発

### 実際に使った分のいを課金
* 無料: ストレージサイズに制限あり、アドホッケな利用
* 使用分課金: GB規模のストレージ、少なめの秒間リクエスト数
* ビジネス： PB規模のストレージ、秒間数千万リクエスト

### 利用ケース

ユーザーアプリケーションからCloud Firestoreへ直接接続

* バックエンド： ユーザアプリ -> サーバー -> Cloud Firestore
* 直接接続： ユーザアプリ -> Cloud Firestore


オフラインモードとデータのリアルタイム同期機能

* オフラインの時にクライアントローカルにデータをキャッシュ
* ネットワークが復旧したらCloudFirestoreと自動的に同期される

### Cloud Firestore で利用できる 2 つのモード
* Datastoreモード
    * サーバーやコンテナのワークロード用に毎秒数千万の書き込みまでスケーリング

* ネイティブモード
    * 百万台ものモバイル、ウェブ、IoT デバイスの同時接続までスケーリング
CarthageでRealmを導入する

## Carthageを使ってRealmをインストール

[Carthage公式](https://github.com/Carthage/Carthage)

わたしは`Homebrew`を使ってインストールしました。
それ以外の方法でインストールしたい場合は、上記の公式を確認してください。

#### Carthageインストール
```terminal
$ brew install carthage
```
#### Carthageファイルの作成
```terminal
$ touch Cartfile
```

#### Realmをインストール
作成したCartfileに以下を記述して保存します。

```terminal
github "realm/realm-cocoa"
```

Carthageを使ってReamlをインストールする。
※かなり時間がかかります。気長にお待ちください。

```terminal
$ carthage update --platform ios
```

## XcodeのプロジェクトにRealmを追加
`Build Phases` > `Run script` に以下と同じように記述する。
`Run script`がない場合は左上の`+`ボタンから作成してください。
![スクリーンショット 2020-08-28 22.45.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/c5288b54-45dc-2ba2-0dfa-04bd1b255c2a.png)


`General` > `Frameworks, Libraries, and Embadded Contents` に`Carthage`でインストールしたライブラリを追加する。
![スクリーンショット 2020-08-28 23.01.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/305854/4bdb1ecb-88c3-66aa-b781-298ee791f617.png)

`+`ボタンを押すとポップアップみたいなのが出るので、そちらから`/Carthage/Build/iOS`ディレクトリにあるライブラリを選択する。
`Embed`を`Do Not Embed`に変更する。（変更する理由は[こちらの記事](https://qiita.com/yanamura/items/7664de7cfa4310b0efe0)を参考に。）

以上で終了です。ビルドが通ることを確認してください！

#### 補足
個人開発の時はCarthageのディレクトはGitの管理から外しておくと良いと思います。
[Gitで特定のファイル・ディレクトリを管理から外す](https://qiita.com/_asa08_/items/902f134327fdd4b32fda)
[Markdown] ゲームライクなプログレスバーのUIで日課やタスクの進捗がみたい

## やりたかったこと
ゲームのクエストみたいにかっこいいUIで、自分のタスクを管理したかった！
jsonでデータを渡してあげるといい感じに進捗の割当とかを表示してくれる感じをイメージしてました。
下記のイメージのすごくかっこいいバージョン。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410015/16326fdf-5632-a50a-cd49-ae039e73225d.jpeg" width=50%>

## 見つけたもの
markdown形式で表示できる。
[progress-bar](https://github.com/fredericojordan/progress-bar "progress-bar")

プログレスバーで見つかったものはVBAやコンソール出力だったので、上記がイメージに合っていた！

## 作ったもの
下げてプッシュ
![progress](https://progress-bar.dev/40/?scale=100&suffix=回 "progress")
レッグレイズ
![progress](https://progress-bar.dev/70/?scale=100&suffix=回 "progress")
プランク
![progress](https://progress-bar.dev/80/?scale=100&suffix=回 "progress")
ワイドスクワット
![progress](https://progress-bar.dev/100/?scale=100&suffix=回 "progress")
マウンテンクライマー
![progress](https://progress-bar.dev/50/?scale=250&suffix=回 "progress")

## ToBe
- このプログレスバーを常に目入るところにおいておく
- ボタンを押したら増えたり減ったりしてほしい
- 登録を簡単にしたい
- 他のサービスのUIを参考に、自分でjavascriptで組んでみても面白いかも
Vue.jsのディレクティブについて

今日からVue.jsの学習を初めました。

初めてのjsのフレームワークでわからないことが多いのでまず現状知っているディレクティブについてアウトプットしようと思います。

##そもそもVue.jsとは

Vue.jsとはjavaScriptのフレームワークです。rubyでいうところのRuby on Railsと同じですかね。



特徴としましては`双方向データバインディング`だということです。


双方向データバインディングとはdataとUIを結びつけることを指します。dataが更新されるとUIも更新されUIが更新された場合でもdataが更新されます。


いわゆる動的ということでしょうか。。。

ここでいうUIとは例えば`div`のようなhtml要素を指して
dataはUIに結びつくモデルのことです。

こちらがUI

```HTML
  <div id="app">
  </div>

```

こちらがモデルにあたります。

```vuejs

var vm = new Vue({
    el: '#app',
    data: {
      name: 'taguchi'
    }
  });
```

こちらのvm変数がdataにあたるUIに結びつくモデルです。
**UIに結びつくモデルはよく View Model**と呼ばれるのでvmという辺数名にしたりすることが多いみたいです。



##ディレクティブとは？？

v-で始まる特別な属性のことです。

directive(指令)という名前の通り、何らかの指示を行うという仕組みです。


その中で3種類のディレクティブを学んだのでまとめます。

###v-onディレクティブ

```

<span v-on:click="deleteItem(index)" class="command">[x]</span>
```

v-onを属性として指定するとイベント発火の実行が可能になります。


deleteItemはこんな感じ。

```
deleteItem: function(index) {
        if (confirm('are you sure?')) {
          this.todos.splice(index, 1);
        }
      }
```

confirmメソッドでokを押すとdataの中にあるtodosをspliceで削除するという記述です。

###v-modelディレクティブ

v-modelは

input, select, textareaタグの双方向のデータバインディングを行えます。

```html:index.html

<input type="text" v-model="newItem">
```


```vue:main.js

newItem: '',
```

インプットの中身が記入されれば同時にdata側にも値が入ります。


###v-bindディレクティブ

 v-bind は HTML タグの属性を操作するために使用されていますね。

```vue:main.js

<span :class="{done: todo.isDone}">{{ todo.title }}</span>
```

**v-bindは:でシンプルにかけます。**

このようにtodo.isDoneだった時にclass="done"が適用されるようになります。


ここで疑問だったのがinputタグなんかもわざわざv-model使わなくてもv-bindで統一したらいいのでは無いかと思ったのですがそうするとv-bind:valueのようにtype属性によって指定を変えないといけないのでややこしくなってしまいます。


なのでinputタグなんかはv-modelを使用した方が良さそうです。
AWS DMSでDocumentDBをデータ移行元とするときの注意点

AWS DMS (Database Migration Service) で

1. DocumentDB -> DocumentDB
2. MongoDB -> DocumentDB

の2パターンでデータ移行を試してみた。

結論から書くと、1のパターンではCDC（継続的な変更のレプリケート）では動かなかったが、それ以外では動く。

AWSの公式ドキュメントを見ると、移行元としてMongoDBは記述されているがDocumentDBの記述は見つからない。しかし、DocumentDBはMongoDBの互換だから、ある程度は同じように動くようだ。


# 2020/08/31 追記

当初「AWS DMSはMongoDBからのデータ移行はできてもDocumentDBからはできない」というタイトルだったが、CDCを避ければDocumentDBを移行元としても実行できることがわかったので、記事の内容を訂正した。


# 手順

簡単に設定手順を書いておく。

前提

- 移行元と移行先は構築済み
- 移行元と移行先の両方と通信できるAWSのVPCがある
    - 通信できるというのは、セキュリティグループの適切な設定を含む
    - 以下手順のDMSレプリカインスタンスはこのVPC内に構築

手順

1. DMSレプリカインスタンス構築 （データ移行元と移行先に接続可能なセキュリティグループの設定が必要）
2. DMSレプリカインスタンスからデータ移行元に接続するためのソースエンドポイント設定
3. DMSレプリカインスタンスからデータ移行先に接続するためのターゲットエンドポイント設定 （[AWSのドキュメント](https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/target.docdb.tutorial.html#target.docdb.tutorial.04)に従い、DocumentDB接続用の証明書をダウンロードして、エンドポイントに設定が必要）
4. DMSマイグレーションタスク作成 （タスク作成時にレプリカインスタンス、ソースエンドポイント、ターゲットエンドポイントを指定）

AWSのドキュメントに詳細が書いてある。

[Walkthrough: Migrating from MongoDB to Amazon DocumentDB - AWS Database Migration Service](https://docs.aws.amazon.com/ja_jp/dms/latest/userguide/target.docdb.tutorial.html)


# 移行元にDocumentDBを指定した場合

ソースエンドポイントのエンジンとしてMongoDBを指定して、DocumentDBの接続情報を設定すればDocumentDBを移行元として使える。

ただし、マイグレーションタスク作成時に「既存のデータを移行して、継続的な変更をレプリケートする(CDC)」を選択すると、マイグレーション実行時にエラーが発生する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490207/6152a183-95cf-8d9b-c177-a4d3d36f2aa7.png)

エラーの内容は次のとおり。

```
Last failure message
Last Error Endpoint initialization failed. Task error notification received from subtask 0, thread 0 [reptask/replicationtask.c:2814] [1020401] Error executing command; Stream component failed at subtask 0, component st_0_3OQBMWWPDQOCVQ36IETQPRLPTPU2BUTTYOYJBJY ; Stream component 'st_0_3OQBMWWPDQOCVQ36IETQPRLPTPU2BUTTYOYJBJY' terminated [reptask/replicationtask.c:2821] [1020401] Stop Reason FATAL_ERROR Error Level FATAL
```
RE:VIEW starterで参考文献書く時の書き方まとめ。

#1. POSTDEFに載せる時。
##基本設定
###bib.reファイルの設定
contentsディレクトリ以下にbib.reファイルを作成し、以下のように参考文献を記述。
linsはID。

```
@<bib>[lins][キャプション]{..コメント..}
```

具体的にはこう。

```
= 参考文献

//bibpaper[lins][Lins, 1991]{
Refael D. Lins. A shared memory architecture for parallel study of
algorithums for cyclic reference_counting. Technical Report 92,
Computing Laboratory, The University of Kent at Canterbury , August
1991
//}
```

参考文献の例は参考URLからお借りしてます。

###catalog.ymlの設定。
catalog.ymlのPOSTDEFのところにbib.reを記載。

```
PREDEF:
  - chap00-preface.re

CHAPS:
  - chap01.re
  - chap02.re

APPENDIX:

POSTDEF:
  - chap99-postscript.re
  - bib.re
```

##引用側での記載
引用したい箇所に以下のように記述。

```
といった意見もあります@<bib>{linse}。
```
 
<br>
引用側は、PDF上ではこんな見栄え。あれ？ここから後ろのページに飛べるのかと思ったけど、飛べないみたいですね。

|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/400c61f1-9a3e-1fcc-f666-6c0b560698d5.png" width=70%>|
|:-:|

##POSTDEF側の見栄え
POSTDEFで設定した時の見栄え。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/fc923c75-9c9c-bde1-5e08-f2411282508a.png)

#2. APPENDIXに載せる時。
##基本設定
###bib.reファイルの設定
POSTDEFと同じ。

###catalog.ymlの設定。
catalog.ymlのAPPENDIXのところにbib.reを記載。

```
PREDEF:
  - chap00-preface.re

CHAPS:
  - chap01.re
  - chap02.re

APPENDIX:
  - bib.re
  
POSTDEF:
  - chap99-postscript.re

```

##引用側での記載
POSTDEFと同じ

##APPENDIX側の見栄え
APPENDIXで設定した時の見栄え。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/ff0b1139-52f7-6731-8c47-0577df115cb4.png)


#3. footnoteを使って脚注に記載
参考文献が少ない時やURLを載せたい時など、わざわざページを作らなくても脚注を使うと良さそう。

```
といった意見もあります@<fn>{lins}。

//footnote[lins][参考文献：Refael D. Lins. A shared memory architecture for parallel study of algorithums for cyclic reference_counting]
```
<br>
PDF上の見栄えはこんな感じ。こちらは*1のところからフッターにとべます。

|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/0c0dbf77-2294-eb68-97c1-01a53fc6234d.png" width=70%>|
|:-:|

フッターはこう。

|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/a4a620fc-f01f-387d-2a0c-09b027ed962c.png">|
|:-:|


2個重ねてもいいし、URLも貼れます。もちろん、yahooへもとべる。

```
といった意見もあります@<fn>{lins}@<fn>{yahoo}。

//footnote[lins][参考文献：Refael D. Lins. A shared memory architecture for parallel study of algorithums for cyclic reference_counting]
//footnote[yahoo][参考URL：@<href>{https://www.yahoo.co.jp/}]
```
<br>
引用側の見栄えはこう。

|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/f7e8b39b-41cc-2c93-dac2-a3454b8edb40.png" width=70%>|
|:-:|


フッターはこう。

|<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106215/737e1e0c-0ff8-d017-3e93-c4bc63c65a37.png">|
|:-:|


#まとめ
 - RE:VIEW starterで何か引用するときの引用元の載せ方についてまとめました。
    - POSTDEFに載せる方法
    - APPENDIXに載せる方法
    - footnoteを使って脚注に載せる方法

#参考URL
https://kenji-s.hatenadiary.org/entry/20110927/1317105278
https://kauplan.org/reviewstarter/reviewstarter-usersguide-20200827.pdf