OmniAICreator/Qiita-1.07M huggingface dataset:
PythonでFXの1分足データを5分足に変換

# 概要
[前回](https://qiita.com/yosukeueda33/items/76566a3eec6530fa8f76)は、[このサイト]()のFXデータをPythonでローソク足表示させてみました。データは1分足のものを使っていましたが、任意の分足に変換したいことがあったので、その実装コードを残しておきます。

# 環境
前回と同じく以下です。
* Python 3.6 on Anaconda
* Jupiter notebook on Anaconda

# 1分足データ表示
[このサイト](https://www.histdata.com/download-free-forex-historical-data/?/ascii/1-minute-bar-quotes/eurjpy/2019/11)のHISTDATA_COM_ASCII_EURJPY_M1_201911.zipをグラフ表示します。データダウンロード後、以下を実行させて下さい。

```python
import plotly.graph_objects as go

import pandas as pd
from datetime import datetime

df_one = df["2019-11-18": "2019-11-20"]

df_show = df_one

fig = go.Figure(data=[
    go.Candlestick(
        x=df_show.index,
        open=df_show.Open,
        high=df_show.High,
        low=df_show.Low,
        close=df_one.Close
    )
])

fig.show()
```
以下のように表示されます。
![newplot (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485117/15f987d1-5ddf-010e-3cb5-289d429bd08d.png)

# 1分足から5分足に変換
以下でresampleを使って5分足に変換出来ます。rateを10T、1Hなど変更すれば、任意の足に変換可能です。

```python
df_five = pd.DataFrame()
rule = "5T"
df_five["Open"] = df_one["Open"].resample(rule).first()
df_five["Close"] = df_one["Close"].resample(rule).last()
df_five["High"] = df_one["High"].resample(rule).max()
df_five["Low"] = df_one["Low"].resample(rule).min()
```


#5分足データ表示
以下を実行して下さい。

```python
df_show = df_five

fig = go.Figure(data=[
    go.Candlestick(
        x=df_show.index,
        open=df_show.Open,
        high=df_show.High,
        low=df_show.Low,
        close=df_show.Close
    )
])

fig.show()
```

以下のように表示されます。
![newplot (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485117/6dcd1aeb-87a7-b40d-23ab-1f866c99921e.png)

一分足と5分足で違いがよくわからないので、長さと先頭を見比べて見ましょう。
1分足は、、、

```python
print(df_one.shape)
print(df_one.head())

'''
output: 
(4319, 5)
                        Open     High      Low    Close  Volume
datetime                                                       
2019-11-18 00:00:00  120.360  120.371  120.360  120.368       0
2019-11-18 00:01:00  120.368  120.372  120.360  120.360       0
2019-11-18 00:02:00  120.361  120.362  120.360  120.360       0
2019-11-18 00:03:00  120.360  120.376  120.360  120.376       0
2019-11-18 00:04:00  120.377  120.380  120.374  120.376       0
'''
```

5分足は、、、

```python
print(df_five.shape)
print(df_five.head())

'''
output:
(864, 4)
                        Open    Close     High      Low
datetime                                               
2019-11-18 00:00:00  120.360  120.376  120.380  120.360
2019-11-18 00:05:00  120.376  120.382  120.387  120.369
2019-11-18 00:10:00  120.381  120.361  120.381  120.352
2019-11-18 00:15:00  120.361  120.354  120.365  120.341
2019-11-18 00:20:00  120.354  120.349  120.354  120.341
'''
```

たいたい5分の一のサイズになっていて、刻みも5分になってますね。いいのではないでしょうか。

以上！
機械学習チートシート（ベクトル、行列、画像、Python）

# はじめに
Python による 機械学習 に向けて、基礎レベルのプログラミングメモを作成しています。
内容はベクトル、行列、画像、Python などです。

Google Colaboratory（Jupyter Notebook） で作成しています。

HTML版
https://tshimizu8.github.io/MachineLearning_CheatSheet/0010_Vector_Matrix_List.html

.ipynb版
https://github.com/tshimizu8/MachineLearning_CheatSheet

# チートシートサンプル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78212/d9d68baf-652c-0ee8-e6fb-920e40bc9b38.png)

# おわりに
GoogleColaboratory（Jupyter Notebook） はコードの実験に便利です。
実験の記録を残せるのが良いです。
numpy、python等 の細かい動きには、驚きがあります。
約数の総和を求める

#はじめに
よくある話題ですが、
加算していく様子が少し面白かったので記事にしてみました。
#コード
```python:solve.py
import math 

def divSum(num) : 
    result = 0
    i = 2
    while i*i <= num: 
        if (num % i == 0): 
            if (i == (num // i)): 
                result += i 
            else : 
                result += i + num//i
        i += 1
    return int(1 + result + num) 

num = 12
print (divSum(num)) 

num = 9
print(divSum(num))

# 28
# 13
```
#説明
num = 12のとき、12の約数は1, 2, 3, 4, 6, 12です。
(2, 6), (3, 4)といった具合で(i, num/i)のペアを作って一度に加算しています。
最後のreturnは問題の条件によって

```python:example.py
return int(1 + result)
```
のように調整できます。

num = 9のとき、9の約数は1, 3, 9ですが、
先ほどの様にペアを作ってしまうと、(3, 3)となって
3を2回カウントするので、片方だけ加算する必要があります。
#補足
コメント欄で@konandoiruasaさんに
高速なプログラムを教えていただきました。
ありがとうございます🙇‍♂️
foreachをlistを使ってかっこよく取得する

##よく使う使い方

```
$fruitList = [
 '1'  => 'リンゴ',
 '2'  => 'レモン',
 '3'  => 'バナナ'
];

foreach($fruitList as $index => $name){
 dd($index. ':'. $name);
}
```
<img width="121" alt="Screenshot_1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325600/962ac67c-bf8b-3f8f-ae14-3876add04d4e.png">

####1:リンゴと出力されました。
一般的な使い方として、$key => $valueの形で使用します。

これが例えば、$valueのほうが配列になった場合を考えてみましょう。

##valueが配列の場合

###添字配列の場合

```
$fruitInfoList = [
 '1'  => ['リンゴ', '100円'],
 '2'  => ['レモン', '200円'],
 '3'  => ['バナナ', '300円']
];

foreach($fruitInfoList as $index => $fruitInfo){
 dd($index. ':'. $fruitInfo[0]. ':'. $fruitInfo[1]);
}
```

<img width="100" alt="Screenshot_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325600/4e748868-1f0d-804a-efb7-c3332e3d1775.png">

これでは、0と1という添字を書いて、取得するのはちょっとみにくいですね。
連想配列にしてみます。

###連想配列の場合

```
$fruitInfoList = [
 '1'  => [
    'name'  => 'リンゴ',
    'price' => '100円'
 ],
 '2'  => [
    'name'  => 'レモン',
    'price' => '200円'
 ],
 '3'  => [
    'name'  => 'バナナ',
    'price' => '300円'
 ],
];

foreach($fruitInfoList as $index => $fruitInfo){
 dd($index. ':'. $fruitInfo['name']. ':'. $fruitInfo['price']);
}
```

<img width="100" alt="Screenshot_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325600/12ac0047-974c-0224-8b41-6258eb227550.png">

取得の際は、nameとpriceと意味付けができて見やすくなりましたが、宣言する際が少し大変で、長いし冗長ですね。
list関数を使ってみましょう。

###listを使用した際

listは、定義された変数の順番に配列の要素が代入されます。さっそく見てみましょう
https://www.sejuku.net/blog/24406

```
$fruitList = [
 '1'  => ['リンゴ', '100円'],
 '2'  => ['レモン', '200円'],
 '3'  => ['バナナ', '300円'],
];

foreach($fruitList as $index => list($name, $price)){
 dd($index. ':'. $name. ':'. $price);
}
```

<img width="100" alt="Screenshot_2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325600/9c533fac-b2ab-4a96-fc5e-f7221da4127c.png">
だいぶすっきりしました。
foreachの中で、$fruitInfoと命名していたものが消えました。(変数を命名するのは難しいので、避けられるなら避けたほうが良いときもある）
TechAcademy(テックアカデミー)に通ったら、独学の苦労が全部なくなった話

突然ですが、
プログラミングを独学で勉強してはいませんか？

僕は現在大学３年生、
将来はエンジニアとして働きたくて
プログラミングを勉強しています。

勉強にお金をかけたくなかった理由から
プログラミングは全部独学でやっていましたが
それが大きな失敗でした・・・、、、

この記事では、僕がどうして独学に失敗したのか
また、プログラミングスクールに通うことで
どうやって失敗を成功に変えることが出来たのか。
僕と同じ悩みを持ちそうな方のために書いていきます。

## プログラミングは独学だとやばい

まずはじめに僕がプログラミングを始めた経緯からお話しします。

僕は現在大学３年生
都内の文系大学に通っています。

もちろんプログラミングの授業はゼロ
しかし将来はエンジニアになりたいと思い
プログラミングの勉強を１年前に開始しました（理由は割愛）

## 独学のデメリット：自分の位置がわからない

最初は独学で無料学習サイトや参考書を勉強して
プログラミングの基礎を学んでいましたが
途中から、自分はどのレベルにいるかがわからなくなりました。

僕は自分よりも出来る人のスキルにマイルストーンを置き
自分との差分を埋めていくことで成長を実感します。

しかし独学では、自分より出来る人もみつけられないですし
自分のレベルを教えてくれるメンター的存在もいません。

今はすんなり説明できますが
当時はそのことにすらわかっておらず
1年間ずっと独学で過ごしていました。

## 独学のデメリット：何も作れない

さらにやばいのがここから。
僕の独学は、全部環境が整理された状態で
プログラムを書く行為でした。

例えばProgateやドットインストールなど
すでに環境が構築されている中での勉強。
多少の理解度が上がっても１からサービスを作ることなんてできません。

でもそんなこと分からないんです。
だって初心者だもの・・・。
独学の恐ろしさは、自分でそのヤバさに気づけないことです。

## 心機一転：プログラミングスクールを検討し始めた。

このままじゃやばい・・・と本気で思い、
ついに僕は[プログラミングスクール](https://renew-career.com/magazine/unv-programming-school/)に通うことを決意しました。

当時お金をかけたくない僕でしたが
この時ばかりは、お金をかけないほうがやばい
そう思っていましたね。

絶対にお金を無駄にしないためにも
色々なスクールを検討しました。
テックアカデミーやテックキャンプ、コードキャンプに
ギークなんとか、超高額のスクールの無料体験にも参加しました。

もちろん口コミも全チェックです
その辺のブロガーさんが書いている
[プログラミングスクール比較](https://renew-career.com/magazine/unv-programming-school/)の記事を片っ端から読んでは
自分にぴったりのスクールはないかを必死に探していました。


そこで決めたのが「TechAcademy(テックアカデミー)」です。

## TechAcademy(テックアカデミー)に決めた理由

単純に、かけるお金と返ってくる内容が見合っていたからです。
（当時の僕の考え方）

僕は
・自分のレベルを教えてくれるメンター
・0からWebサービスを作れるスクール
・時間と場所に縛られないこと
この３つの条件でプログラミングスクールを探していました。

TechAcademy(テックアアデミー)は
・専属メンターが付いてくれる
・Webサービスを作る内容あり
・オリジナルWebサービス開発もサポートしてくれる
・オンラインだから時間も場所も自由
・しかも10万円で安い
という僕にはぴったりなスクールでした。

あくまで僕の求めるプログラミングスクールに合っていただけで
全員が全員に合っている訳ではありません。
スクールを考えている人は、自分がなりたい姿から逆算すると良いですね。

まぁでも、専属メンターはいた方が良いですし
WEBサービスも作れた方が良いです。オンラインの方がなんだかんだ楽です。
そうなるとテックアカデミーは、割と全員におすすめかもしれないですね（どっちやねん）

## TechAcademy(テックアカデミー)のコース

僕が選んだのは「PHP/Laravelコース」です。
理由は、Webサービスが作れるようになりたかったことと
今のレベルよりも若干高いレベルの力を身につけたかったことです。

コース選びは自由ですが
出来るか普段だな。と思うレベルを選ぶ方が良いですよ
そのほうが自分のキャップが外れて大きく成長できます。

## TechAcademy(テックアカデミー)の内容

内容は公式サイトや、[テックアカデミー体験ブログ](https://shibamasa26.com/techacademy/techacademy-review)とかを
見てもらうとわかりやすいですが、ざっくりこんな感じでした。

１週目：プログラミングの基礎勉強
２週目：Webサイト開発（HTML/CSS）
3週目：サービス開発（PHP/MySQL）
４週目：実践編：1個目のサービス開発
５週目：実践編：2個目のサービス開発
6週目：実践編：3個目のサービス開発
7週目：実践編：4個目のサービス開発
８週目：オリジナルサービス開発

見てわかるように、超実践的な内容です。
1ヶ月間はずっと0から1のサービス開発をしていました。
ずっと独学で苦労してきた僕にとってはありがたいことですね。

## プログラミングスクールに通って良かったこと

今回独学を諦めて、スクールに通いましたが
現役エンジニアの専属メンターとお話しできたり
オリジナルアプリを作れるようになったりと
ぶっちゃけ、エンジニアとして大きく成長できたと思います。

これも「お金をかけたくない」
というダサい考え方を捨てて
自分の成長に何が1番必要なのかを考えた結果だと思います。
本当に通って良かったと心から感じています。

## 独学で勉強している人に伝えたいこと

今回、僕は独学を捨てて、
プログラミングスクールを使って勉強しました。

僕自身、ずっと独学を続けていて
不安もありましたが、最初はやばいとすら感じませんでした

でも実際に自分が社会に出たら
エンジニアとして働ける自信はありますか？？？
僕はありませんでした。

自分のレベルを教えてくれる人がいることや
実際に０から1を作る経験をすることは非常に大切です。
これは僕が身をもって感じたことです。

もし同じように独学を続けていて
不安や悩みを感じている人は
一歩踏み出して、プログラミングスクールという新しい道を選んで見てください。
その行動が、きっとあなたを強く大きな人間に成長させてくれますよ。
新しく追加されるViewTreeLifecycleOwnerについて

プルリクをなんとなく見ていて発見して面白そうだったので書いてみました。 (まだ未リリースっぽいです)
https://android-review.googlesource.com/q/project:platform/frameworks/support+viewtreelifecycleowner

# ViewTreeLifecycleOwnerとは

ViewからLifecycleOwnerを取得できる仕組みです。
例えば以下のようにすることでLifecycleOwnerを取得できます。このLifecycleOwnerは直近のFragmentやActivityを取得できる形になります。
個人的にはCustomViewなどでライフサイクルを取得するのに便利なのではと思っています。

```kotlin
view.findViewTreeLifecycleOwner()
```

# どのように実現されるのか？


## ComponentActivity内


ルートのViewであるDecorViewに対してActivityをセットしています

```java
    @Override
    public void setContentView(@LayoutRes int layoutResID) {
        // Set the VTLO before setting the content view so that the inflation process
        // and attach listeners will see it already present
        ViewTreeLifecycleOwner.set(getWindow().getDecorView(), this);
        super.setContentView(layoutResID);
    }
```

## Fragment内

Fragmentでも同様にセットしています。

```java
    void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
...
            ViewTreeLifecycleOwner.set(mView, mViewLifecycleOwner);
```


## ViewTreeLifecycleOwner

**ViewTreeLifecycleOwnerではただ単純にタグに入れるだけです**

```java
    public static void set(@NonNull View view, @Nullable LifecycleOwner lifecycleOwner) {
        view.setTag(R.id.view_tree_lifecycle_owner, lifecycleOwner);
    }
```

どのようにLifecycleOwnerを取得するのか？
以下のように単純にparentをたどることで取得できるようです。

```java
    public static LifecycleOwner get(@NonNull View view) {
        LifecycleOwner found = (LifecycleOwner) view.getTag(R.id.view_tree_lifecycle_owner);
        if (found != null) return found;
        ViewParent parent = view.getParent();
        while (found == null && parent instanceof View) {
            final View parentView = (View) parent;
            found = (LifecycleOwner) parentView.getTag(R.id.view_tree_lifecycle_owner);
            parent = parentView.getParent();
        }
        return found;
    }
}
```
【ITインフラ基礎】学習メモ / ネットワーク用語編

参考書籍：
[イラスト図解でよくわかるITインフラの基礎知識](http://gihyo.jp/book/2018/978-4-7741-9600-8)
[IT用語辞典　e-words](http://e-words.jp/)
その他ウェブサイト

#LAN / WAN
###LAN(Local Area Network)
屋内や建物の敷地内に構築された区域限定ネットワーク。
家庭内や学校内、社内でLANが使われる。
一般的なLANはスター型のEthernetネットワーク。

###WAN(Wide Area Network)
地域間や遠隔地を結ぶネットワーク。LANとLANを相互接続するネットワーク。
家庭内ではインターネットがWANに当たる。
会社では、複数のオフィスを構えていた場合、各オフィスのLANを通信事業者が持っているWAN回線を利用して接続し、車内ネットワークを構築できる。

####一言まとめ：
LANは区域限定ネットワーク（狭い）、WANは地域間ネットワーク（広い）

#OSI参照モデルとTCP / IP階層モデル
ネットワークの通信は階層構造であり、階層ごとに通信プロトコルがある。

###階層構造
データを処理する対象と処理する方法が層ごとに決められており、順番に処理していく。

###通信プロトコル
通信をする上での決まりごと。
コンピューターや通信機器がデータをやり取りし合う際に、定められたプロトコルで通信を行う。
人間でいえば、片方が日本語で話し、もう片方が中国語で話していると意思の疎通が出来ないので、共通言語である英語を使いましょうという感じ。

##各階層の役割

OSI参照モデルは、通信の概念を７段階に分けたもの。
普段使っているネットワークはTCP / IP階層モデルを元に実装されている。

###OS参照モデル
| レイヤ | OSI参照モデル | 役割 |  
|----|---|---|---|
| ７  |アプリケーション層 |  アプリケーションごとの通信方法を定める|    
| ６  | プレゼンテーション層| 文字コードなどの表現方法を定める|
| ５  |セッション層  |  アプリケーション同士の通信の確立、切断を定める|
|４   | トランスポート層 | コンピュータ同士の信頼性のある通信方法について定める |   
|３   |ネットワーク層  | 端末間でのデータ通信、転送方法について定める |
|２   | データリンク層  |  直接物理接続された機器間のデータ通信、転送方法について定める |  
|１   | 物理層  |レイヤ２〜７の情報を電気、光信号にする方法を定める  |  

###TCP / IP階層モデル

| レイヤ | TCP / IP階層モデル | よく使うプロトコル |  
|----|---|---|
| ４ |アプリケーション層 | HTTP, DNS, POP3, SMTP, FTP, SSH|    
| ３  | トランスポート層層| TCP, UDP|
| ２  |インターネット層  | IPv4/IPv6, ICMP|
| 1   | ネットワークインターネット層 | イーサネット, PPP |   


#パケット
通信ネットワークを流れるデータの単位。
ネットワークは全ての通信をパケット単位で処理している。
パケット通信では、送信元と宛先があり、その端末の識別にIPアドレスを利用して通信を行う。

#IPアドレスとポート番号
TCP / IPネットワークの通信はIPアドレスだけでなく、ポート番号との組み合わせで識別される。

###ポート番号
TCP / IPにおいて同じコンピュータ内で複数のソフトウェアが動いていた際、どれと通信するか指定するための番号。IPアドレスがPC自体の識別に対し、さらにその中で動くソフトウェアを一つずつ識別する。

###IPv4とIPv6
IPアドレスのバージョン。もともとIPv4だけだったが、数が足りなくなってきたのでIPv6を追加
IPv6は１２８ビット（340澗: 兆の次の次の次の次の次の次の単位？）個ある。

#ロードバランサ
サーバーなどのシステムに対するトラフィックを分散させ、処理のバランスを調整する役割がある。これによりネットワーク上での個々のサーバーの負荷を減らすことができる。

#ファイアウォール
ウイルスからコンピューターを守るため、ネットワーク上を流れるパケットを管理者が設定したルールに基づいて監視し、通過や破棄を決定するもの。インターネットと社内ネットワークの境界に設置する。

###パケットフィルタリング型
パケットのIPアドレス、ポート番号を読み取り、フィルタリングルールに基づき通信の可否を決定する。

###アプリケーションゲートウェイ型
通信を中継するプロキシを利用する。

#VPN（Virtual Private Network)
インターネット上に仮想的な専用線を設け、セキュリティ上の安全な経路を使ってデータをやり取りすることができる。
これにより、遠隔地にあるネットワーク同士を接続して安全な通信を行える。
企業間ネットワークの拠点間接続などに使われ、あたかも自社ネットワーク内部の通信のように遠隔地との通信が行える。リモートで社内ネットワークにアクセス出来たりする。
#Rails で カラム名変更の migration ファイルの例

あーマイグレーションファイルを書くのが死ぬほど面倒だ

```
rails generate migration ChangeColumnNameUserFirstNameToGivenName
```

```rb
class ChangeColumnNameUserFirstNameToGivenName < ActiveRecord::Migration[5.2]
  def change
    # テーブル名は複数形で書く
    # 2番目に変更前のカラム名、3番目に変更後のカラム名を書く
    rename_column :users, :first_name, :given_name
  end
end

```

```
rails db:migrate
```

# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2857








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
闇落ち ダークサイド(Tor)にwebサイトを作るぞ[3/25/20サービス終了]

## そもそもtorってなんぞや

公式を見よ
[Tor Project](https://www.torproject.org/)

## 何がいるぞ
- Tor Browser
- Filezilla
- Daniel's hosting
- index.html

## いざ参る

1. [Tor Browser](https://www.torproject.org/download/)をインストールせよ
やり方は他で調べよ
<img width="993" alt="スクリーンショット 2019-12-22 12.34.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321327/a5c7ee18-9477-e7f2-fcbd-e6da49040482.png">


2. できたら[Daniel's hosting](http://dhosting4okcs22v.onion/index.php)(http://dhosting4okcs22v.onion/index.php) に**Tor Browser**(※これは.onionドメインであるぞ)でアクセスしようぞ
<img width="1440" alt="スクリーンショット 2019-12-22 12.04.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321327/b209b08a-224b-9500-fb1a-58dfee81c1eb.png">

3. アクセスしたら上部に**Register**とある。**username**と**パスワード**を入力し、他は特にいじらなくていいぞ。
<img width="1440" alt="スクリーンショット 2019-12-22 12.09.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321327/58e4954d-b74d-a1d8-106b-86ca696afd48.png">

4. 入力を終えてRegisterボタンを押すと**画面上部**に**アドレス**が表示されると思う
それがサイトのアドレスとなる

5. 次に画面上部にある**Login**でさきほど入力した情報を入力しようぞ

6. ここまできたら[Filezilla](https://filezilla-project.org/)をインストールしてローカルからリモートにデータを送る準備をするぞ

7. インストールできたら上部に**Host、Username、パスワード、ポート**とあるので入力していく。入力するものはLogin画面で入ったページ内にある**System Account**に書いています。**パスワード**は自分で決めたものだ
Filezilla上部
<img width="1196" alt="スクリーンショット 2019-12-22 12.17.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321327/96ecace7-866f-87cd-ced5-a3c7b81d0c6b.png">
Login画面
<img width="1390" alt="スクリーンショット 2019-12-22 12.18.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321327/0499767c-e277-140a-d131-7a14d02df961.png">

8. 入力を終えうまくいくと、画面右側にリモートサイトのファイルが現れる。その中から**「www」フォルダ**を見つけてみよ
<img width="600" alt="スクリーンショット 2019-12-22 12.24.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321327/4b77f712-3a26-1957-4cd1-6abf35602e5c.png">

9. その中に自分で用意した**html**等をぶち込んでから、クイック接続を行い4で生成された、アドレスにアクセスするとhtmlが表示されるはずだ
<img width="1440" alt="スクリーンショット 2019-12-22 1.09.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321327/429890ad-f08f-2525-c3a1-7673a0b03c1f.png">

## おわり
ダークサイドにようこそ...

## 追記[3/13/20]
3/10にDaniel's Hostingは攻撃を受け3/25に完全閉鎖する予定です
3/25日までFTPなどでアップロードしたデータなどは回収できるみたいです。
https://hosting.danwin1210.me/

> Update March 11th 06:00 AM UTC: private keys of hidden services are now copied and available in your /data/ directory. If you don't know your system account to connect via (S)FTP, it consists of the first 32 characters of your first onion address. If it was a v2 address, it's the full address (including .onion). Since yesterday I've got several messages asking me not to give up. The project in it's current state is a lot of work to maintain. I have many ideas on what to improve and which features to add. But after spending most of my time on answering mails or getting rid of just another 50+ scam sites every day, there is hardly any time for development. I may start another hosting project in the future, when I found time to improve the current platform. But it may take several months before I get there.
マンガでわかる Template Method

![409924ED-5226-4FF3-9175-1441BBC574AA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/40235ab5-6c0b-360f-2337-0ac6d6ea50e6.png)

「〇〇りっちなう」 うーん、どのぐらいの人に伝わるんだろう。わからなかったら、なんかそういう Twitter ボットがあるんだなと思っておいてください。

複数の似たプログラムを書く必要があるとき、コピーで作ってしまうと、変更差分にならなかった部分がまったく同じコードとして残ってきます。まるごと明日使い捨てるならコピーでもいいのですが、ある程度運用するものをコピーでやるのはまずいですね。

共通部分にもし修正が必要になったら、コピーの数だけ同じ修正を当てないといけません。だいたいそういうときって、どこか変更し忘れたり、そっくりそのまま同じ変更になってなかったりするんでよ。後で見たら、同じはずなのに互いに異なっているコードがあって、どれが正しいのかわからなくなったりします。

共通部分は同じソースコードを共有しましょう。

ってとき、よしならば共通関数ライブラリだ、ってやってしまうと、やっぱり同じ構造を維持できないじゃん、となるかもしれません。ライブラリをどのように呼び出すかは使用者の自由なので、ちょっとづつ違う変種が生まれる可能性は捨てきれないのです。

というわけでめもりーちゃんが提案してくれたのが、Template Method パターンです。

まず、全体の作りはできているけど、内部で使う処理の部分部分が歯抜けメソッド (指定できるなら、可視性は protected スコープ) になったような抽象クラスを設けます。それを継承する複数の子クラスの側で、それぞれの派生の都合に合わせてこの歯抜けを定義します。

そけっとさんの仕事の場合、Twitter API のお作法はどれも同じで、「送信対象の収集アルゴリズム」と「送信内容の決定」が、前回と今回で違う部分になります。

こうしておくと、全体的な保守のとき、抽象クラス側をいちどだけ修正すれば、どちらのボットも同じように直ります。将来また同じようなボットを作らないといけないときは、派生を追加すればすぐにできます。

Template Method パターンは、いわば、クラス数最少のフレームワークです。

これ、別解として、「どんな文字列に反応するか」と「どんな文字列を送るか」をパラメーターにして、ひとつのクラスで済ませるやり方も考えられます。

しかし、固定の文字列って、なんか一般化しきれてなさそうで不安になりません? もし反応するキーワードが複数あったら... もし送信内容に動的な変化を求められたら...

じゃあ文字列の代わりに、関数か Strategy を与えればどうか。はい、それはたしかに大正解の王道です。継承よりコンポジションを好む方が優れた設計でしたよね。ただ、トレードオフを考える必要があります。

関数の入出力型を厳密に表すことができる言語でないと、もしかしたら、実行時に壊れる関数が渡されているかもしれません。そもそも言語仕様に関数ポインタがない可能性だってあります。

なので言語によっては、「Strategy 抽象の定義」が余分に必要になるかもしれません。むしろ、「こんな入出力の関数ね」とアドホックにやると、分散したコードの意味が伝わりにくいので、あえて名前をつけて定義したほうが良いかも...

また、動的に組み合わせるということは、言語に関係なく、正しい組み合わせの関数を持たせたインスタンスの生成を行う責務が外部に発生します。よーし知識を Factory に持たせて...

うーん、だんだんアーキテクチャ宇宙飛行士感が出てきたぞ。

めもりーちゃんはすぐに、そこまでの柔軟性があったところで、どうせ後で生きてこないだろうと考えました。ささいなことだけど、問題に対して大げさすぎる方法はなんかやだ、って嗅覚が本能的にはたらくのです。（←「なんか」が当たるからやはりちょうぜつ)

Template Method なら、どの派生を `new` するかだけで使い分けられてお手軽、どんな振る舞いかのセットはハードコードなので、生成時に挙動を与える必要なし。こんなオマケ機能みたいな独立した部分で、ソースファイルを増やすのはやめとこう、って。

Template Method はフレームワークです。また同時に、よりハードコードに近いほうの妥協です。というかフレームワークはそもそも、柔軟性を犠牲にした、生産性や保守性の獲得ですよね。コンポジションによる柔軟性より、継承による硬直化をあえて選ぶのがこのパターンです。最良の戦略は場合による、ということに注意してください。
pd.mergeでindicatorを使おう

# 概要
pandasでmergeする際に`indicator`という引数があるのですが、とても便利であるにも関わらず使用している方が少ない気がするので布教したい目的の記事です。

[ドキュメント](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html)には以下のように記載があります。

>indicator : bool or str, default False
If True, adds a column to output DataFrame called “_merge” with information on the source of each row. If string, column with information on source of each row will be added to output DataFrame, and column will be named value of string. Information column is Categorical-type and takes on a value of “left_only” for observations whose merge key only appears in ‘left’ DataFrame, “right_only” for observations whose merge key only appears in ‘right’ DataFrame, and “both” if the observation’s merge key is found in both.

一般的にleft joinすると左側のデータにしか存在しないレコードはmergeの際に全部欠損になってしまいます。ですが、データ分析の際にはどのレコードには紐づいて、どのレコードには紐づかない、という紐付き具合などを見たいケースがよくあります。普通にmergeするとこれを確認するのが結構面倒だったり後で全然紐づいてないことに気づいて惨事になるのですがこの記事で紹介する`indicator`を用いるとこれが簡単に確認できるようになります。

普段分析する対象が自社内データだけで、全てのデータがkeyで完全に紐づくなら特に問題はないのですが、外部からよく知らないデータを引っ張ってきて自社保有データと紐付ける際などに重宝します。

具体例で見てみます。

# 具体例

自分が保有している身長データaに外から拾ってきた体重データbをくっつけるとします。

```python
a = pd.DataFrame({
    "ID" : [1, 2, 3, 4, 6],
    "name": ["Tom", "Bob", "Alex", "Mike", "John"],
    "heigt": [169, 173, 163, 170, 182]
})

b = pd.DataFrame({
    "ID" : [1, 2, 3, 4, 5],
    "weight": [65, 70, 72, 58, 61]
})
```

```python
a
```
<img width="139" alt="スクリーンショット 2019-12-22 11.58.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231357/bd4f5d17-630e-9029-e706-3a2a3b4883f9.png">

```python
b
```
<img width="102" alt="スクリーンショット 2019-12-22 11.58.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231357/153af3ef-eb2f-9157-98b1-e952bdc17cb6.png">

何も考えずに分析する場合、

```python
c = a.merge(b, on="ID", how="left")
# or
c = a.merge(b, on="ID", how="inner")
```
を目的に応じてやればいいと思います。

ここではbが外部から持ってきたデータなので以下のことが知りたいとします。

- aとbはどれぐらい紐づくのか?
- a(b)がくっつかないレコードの詳細を見たい

これを簡単に確認できるのが`indicator`オプションになります。
使用法は簡単で、以下のように`indicator=True`を追加するだけです。

(結合keyの重複確認についてはここでは触れません)

```python
c = a.merge(b, on="ID", how="outer", indicator=True)
c
```
<img width="251" alt="スクリーンショット 2019-12-22 12.14.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231357/138be9dc-acbc-2938-2683-25f994a548f2.png">

すると上記のように結合後データセットと共に`_merge`カラムが追加されます。
`_merge`カラムには`both`, `left_only`, `right_only`のいずれかの値が入っており、そのレコードがどこから来たレコードなのかを教えてくれます。あとはこのカラムを利用して、

```python
c_left_only = c[c["_merge"]=="left_only"]
c_left_only
```
<img width="244" alt="スクリーンショット 2019-12-22 12.21.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231357/cbe492f1-4051-e243-1415-be8df43cceb0.png">
とすると身長はあるけど体重はない人の一覧を取得することができます。

merge時にはhow="outer"にしておいて、後で目的に応じてこのように"_merge"の値でデータを抽出するのが便利です。


また、`indicator`はboolだけでなく、str型も対応しており、

```python
d = a.merge(b, on="ID", how="outer", indicator="flg_weight")
d
```

<img width="258" alt="スクリーンショット 2019-12-22 12.22.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231357/615658c7-c789-f7e8-22ca-5122cb6617a9.png">
`_merge`の部分を指定した文字列にすることができます。


便利な機能なのでぜひ使っていただきたいです！
それではよいデータ分析ライフを~~
JMeter Server 起動が java.rm.server.ExportException でFailするときのFix を考える

JMeter 関係のツールを作っているが、自動プロビジョンスクリプトを作成すると下記のエラーが発生して、JMeter サーバーが起動していないかった。

```bash
Dec 20, 2019 12:01:54 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
Server failed to start: java.rmi.server.ExportException: Listen failed on port: 0; nested exception is: 
        java.io.FileNotFoundException: rmi_keystore.jks (No such file or directory)
An error occurred: Listen failed on port: 0; nested exception is: 
        java.io.FileNotFoundException: rmi_keystore.jks (No such file or directory)
```

# 原因
この原因は、JMeter サーバーを起動すると、JMeter 5.2.1のデフォルトでは、Master/Slave で通信するときに使われるRMIのSSLのコンフィグらできていないから。

# 解決
下記の２つのブログが参考になる。

* [Mac から GCE 上の JMeter サーバークラスタを制御する](https://kawabatas.hatenablog.com/entry/2018/08/29/145210)
* [Apache JMeter on GCE 環境構築手順](https://qiita.com/ryo-sato/items/0edc5f975c49e6d905f8)

２つのブログは方式が違うが、この問題の解決策は２つで、SSL自体をDisableにするか、keystore を設定するかの２つ。keystoreに関しては作成用のcreate-rmi-keystore.sh といったようなファイルが存在するのでそれを使うことになるが、私のユースケースの場合、VNET上に展開されるVM同士の通信で使われるため、わざわざキーストアを設定してSSLを有効にすること（キーストアを作成して、それをスレーブ側に転送など）は面倒なので、SSL自体を使わないようにした。方法は簡単で、自分が使っている自動化スクリプトで、jmeter.property を上書きした。

```bash
# Disable Rmi SSL option
sed -i.bak -e "s/#server.rmi.ssl.disable=false/server.rmi.ssl.disable=true/" ${JMETER_HOME}/bin/jmeter.properties
```
これで無事動作完了。RMI系のコンフィグ項目は次のリンクのとおり

* [19.7 Remote hosts and RMI configuration](https://jmeter.apache.org/usermanual/properties_reference.html#remote)

めでたしめでたし。
スクラム開発未経験のチームが遭遇した６つの問題

## 背景
新しくアサインされた案件がスクラム開発で進行していた。
開発チームもそのタイミングで作られ、既存の開発メンバーから引き継ぎを受けて、徐々に一週間単位のスプリントでやれることを増やしていった。
開発チームはスクラム未経験のチームで、社外にスクラムマスターとプロダクトオーナーがいる状況。

## 遭遇した６つの問題

### 1．最初のスプリントで生産性が発揮できない
スクラム自体未経験だったり、チームとしての連携や、プロダクトそのものへの理解の無さなど、
さまざまな要因で生産性が発揮できませんでした。
スプリントの振り返り時に、そのスプリントでのタスクを十分にこなすことができない、ということが多かったです。

スクラム開発としては、これはしょうがない、というか、そういうものだと受け入れて、
なるべく１スプリントの流れを作れるように集中するべき時期ではあるそう。

### 2．ベロシティ(生産性)に焦点があたってしまう
どうしても生産性を出さないと、チームとしては居心地が悪いのか、
スプリント内のタスクをすべてそのスプリント中に終えようと、
**残業**したり、**テストなどが不十分の状態でフィードバックを得る場に持っていったり**など、
不健全な状態になってしまいました。

残業したら、体調崩す人や寝坊する人も出てきたり、
テストや動作確認などが不十分だと、あとでまたバグを直すことになるなど、
出戻りが多くなってしまいました。

### 3.完了(Done)の定義が弱い

PBIsがスプリントバックログにてタスク化され、開発チーム内で割り振られるのはいいのですが、
それらの完了の定義が明確化されていないことで問題が生じます。

何をもって完了したか、が不明確だと、
開発メンバーの作業に品質的な差が出たり、
最終的な成果物が、『顧客が触れる状態』ではなくなってしまい、価値が提供できない可能性があります。

エンドポイントをたたいて結果が返ってくればOK？
テストは？ドキュメントは？

これらが決まっていないと、上述のようにあとでバグを直すことになったり、
不必要な出戻りをすることが起こりえます。

### 4.チーム内にいるリーダーという存在による不和
リーダーが存在すると、責任の大きさがメンバーごとに差が出ます。
リーダーの働きが悪いと、「なんでリーダーなのにooをやってくれないんだ」
などとメンバーから文句が出たりして、雰囲気が悪くなったり、連携が取りにくくなったり、余計なことで開発に集中できなくなる原因にもなったりしました。

スクラムチームに上下関係は持ち込むべきではないというのはよく言われますが、そういった余計な問題が発生するからとのことらしいです。


### 5.チーム内でのスクラム開発に対する漠然感

最初、開発チームは、優先順位が暴力的に決まった(かのように見えていた)PBIsに対し、スプリントでそれをこなすだけの機械のようになっていました。

リモートワーク推奨の組織なだけに、Face to Faceのスプリント計画は行きたがらず、特定のメンバー(PMとPL)のみが赴いたり(そもそもPMやPLがいることがスクラムで推奨されていないことはいったん忘れて)、自分たちがこのスクラム開発をやるにあたってどうあるべきか、プロダクトに対してどういうスタンスで立ち向かうべきか、という部分がまとまっていなかったです。

不透明な部分が多いと、「スクラムってなんだっけ」、「どうするのがいいんだっけ」と、開発に集中できないので、
指針となるスクラム開発をやる意義を考えることは、チームとして必要だなと感じました。

それらを助けるのはスクラムマスターの責務でもあるのでしょう。


### 6.スクラムマスターの存在している意味がわからない

スクラム開発におけるよくある問題として、『スクラムマスターの存在意義がわからなくなること』というものがあります。
チームマネジメントをする存在ではないし、「MTGのファシリテーションくらいしかしてないんじゃないか？」
みたいな声が、実際にチーム内から出たりすることもありました。

スクラムマスターは、スクラム開発がうまくいくよう、
プロダクトオーナーと開発チーム、また、組織に対し責任を負います。

チームメンバーが自己管理し、各々でリーダーシップを発揮できるように、
サポートすることがスクラムマスターの役目です。

つまりチームがスクラム開発において集中できてないようであれば、その障壁を取り除いたり、
スクラム自体やツール導入の支援を行わなければなりません。

逆にそれらが行われていないのであれば、スクラムマスターは機能していないとも言えるでしょう。

## おわりに

アジャイル開発宣言のうち、『顧客との協調』という部分が個人的には一番本質的な部分なんじゃないかと思っており、そんな中、『生産性(ベロシティ)』や『上下関係』、『責任の所在』などに意識が向いてしまうと、アジャイルに則ったスクラム開発からは遠ざかってしまう気がします。

スクラムの背景にあるアジャイルの考えを確認し、自分たちのチームがどうあるべきなのかを、スクラムチーム全体で考えていけたなら、よりよい価値を提供できるのではないかと日々思っています。
Unity Oculus Quest ハンドトラッキングで5本の指でインタラクションさせる


ハンドトラッキングがサポートされたUnity の Oculus Integration アセットがきて早速試しました。
ハンドトラッキングのサンプルシーン HansInteractionTrainScene を実行するとハンドトラッキングでのインタラクションを試すことができます。
試すとわかる通り、人差し指以外の指ではボタンが反応しません。
https://developer.oculus.com/documentation/quest/latest/concepts/unity-sf-handtracking/
こちらのドキュメントを読むと、InteractableToolsSDKDriverにアタッチされているInteractableToolsCreatorが設定を行うオブジェクトだそうで、サンプルシーンのInteractableToolsCreatorを見ると左右RayToolとFingerTipPokeToolIndexのみが設定されています。
sizeを6に設定し、ほかすべてのFingerTipPokeToolプレハブをアタッチすればOKです。
なお、親指用のFingerTipPokeToolはないため、他の指のFingerTipPokeToolプレハブを　Ctrl + D で複製してFingerToFollowをThumbに設定すれば親指用のプレハブとなります。
これですべての指でインタラクションできるようになります。
あとHansプレハブがシーンに配置されていますがこれも必要で、配置されていないとFingerTipPokeToolが生成されません。
ですので、ご自身のシーンにフィンガーインタラクションのあるハンドトラッキングを配置するには、InteractableToolsSDKDriverとHansの2つのプレハブをペアで配置するようにしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17554/64102bb5-da8a-4b20-84ad-442e7361f6aa.png)
【C#】派生クラスにキャストで失敗

ベースクラスから派生クラスにキャストしようとしたときに、はまってしまったことをまとめておきます。

## 処理内容

メンバー変数を１つ保持しているベースクラス(CastBase.cs)と
１つ変数を追加した派生クラス(CastA.cs)を用意しました。

```c#
using UnityEngine;

/// <summary>
/// ベースクラス
/// </summary>
public class CastBase
{
    /// <summary>
    /// ベースクラスのメンバー変数
    /// </summary>
    public int BaseMemberNum;
}
```

```c#
/// <summary>
/// 派生クラス
/// </summary>
public class CastA : CastBase
{
    public int AMemberNum;
}
```



2つのクラスを使って、以下のような処理しました。（Unity上で動かしています。）
実行はTestMethod内のキャストで失敗し、null参照でエラーを吐いてしまいます。

```c#
using UnityEngine;

/// <summary>
/// メインクラス
/// </summary>
public class Main : MonoBehaviour
{
    void Start()
    {
        var castBase = new CastBase(); //ベースクラスでインスタンス化
        var castA = new CastBase();//ベースクラスでインスタンス化

        TestMethod(castBase, castA);
    }

    //ベースクラスを引数として受け渡すメソッド
    void TestMethod(CastBase castBase, CastBase castA)
    {
        Debug.Log(castBase.BaseMemberNum);

        var castedA = castA as CastA; //キャスト失敗。castedAにはnullが返ってきます。
        Debug.Log(castedA.BaseMemberNum); //null参照でエラー
        Debug.Log(castedA.AMemberNum);
    }
}
```

修正方法はcastAをインスタンス化するときにベースクラスではなく、
CastA型でインスタンス化する必要があります。
CastA型で宣言をし、あらかじめCastAの領域を確保しないとキャストに失敗してしまうようです。

```c#
using UnityEngine;

/// <summary>
/// メインクラス
/// </summary>
public class Main : MonoBehaviour
{
    void Start()
    {
        var castBase = new CastBase(); //ベースクラスでインスタンス化
        var castA = new CastA(); // CastA型でインスタンス化する

        TestMethod(castBase, castA);
    }

    void TestMethod(CastBase castBase, CastBase castA)
    {
        Debug.Log(castBase.BaseMemberNum);

        var castedA = castA as CastA;
        Debug.Log(castedA.BaseMemberNum);
        Debug.Log(castedA.AMemberNum);
    }
}
```

同じクラスに書かれると、なんてこともない問題ですが、実際に直面したのは、宣言とキャストする場所が離れてしまっていて、なかなか原因を発見することができませんでした。
メソッドに引数を与える ❏Vue.js❏

メソッドの引数に与えた数の倍数分カウントアップしていきます！

（例）３を与えるとこうなります。
↓
[![Screenshot from Gyazo](https://gyazo.com/de2fb4dd43c5f89a0f635b659a8f1484/raw)](https://gyazo.com/de2fb4dd43c5f89a0f635b659a8f1484)

<br>
開発環境はJSFiddle
https://qiita.com/ITmanbow/items/9ae48d37aa5b847f1b3b

```html:html
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<div id="app">
  <p>{{ number }}</p>
  <button @click="countUp(3)">カウントアップ</button>
</div>
```

```javascript:javascript
new Vue({
  el: "#app",
  data: {
    number: 0
  },
  methods: {
    countUp: function(times) {
      this.number += times;
    }
  }
})
```

①html側には引数3を与えます。
`@click="countUp(3)"`

②js側にはtimesとして引数を受け取ります。
`countUp: function(times)`

③引数分足します
`this.number += times;`

できあがり！

<br>
ではまた！
2019年人気アプリは？

令和元年となった２０１９年もそろそろおわり。来年はいよいよオリンピックイアー！
あっという間に月日がながれていきますが
スマホアプリにはどのような月日がながれているのでしょうか。
Android基準でここ１０年ぐらいの人気アプリを振り返ってみます。

#2010年の年間アプリ人気ランキング

1位はホームアプリ「ADW.Launcher（donut）」
2位は設定管理アプリ「MySetting」
3位はタスク管理アプリ「Advanced Task Killer」

ゲームアプリでは、
1位がアクションゲーム「Angry Birds」
2位がRPG「エルスの天秤（FREE）」
3位がRPG「魔王なんてたおしちゃうから！Lite」
4位がパズルゲーム「Tetris」
5位がアクションゲーム「侍魂（Samurai Spirits）」

情報：https://androider.jp/より

１０年前は初代Xperiaが発売された年で
アプリもスマホの未完成度をおぎなうようなツールがメインですね。
自分もそのころからXperiaをつかっていますが、Android端末自体が不安定すぎて
電話着信すらままならない状態でガラケー派からは、なんでAndroidつかっているの？とよく批判されました。
ゲームも「Tetris」がベスト５にはいるなどまだパッとしないですね。

AndroidOS:1.6

#みんなで決めるベストアプリ総選挙2012
1位 パズル＆ドラゴンズ
2位 漫画風製作所
3位 スマホ最適化のたしなみ

![パズドラ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/1ada999c-9128-6dff-01f3-745605c970d8.png)![mannga.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/a9e8da1c-53d3-aafa-d578-19877306235f.png)

このころにはスマホ利用が一般的になっておりiPhone派で大流行のアプリが周回遅れでAndroidにも登場するような流れとなっていました。
パズドラは2019年でも未だに根強いユーザーがのこっておりゲームの寿命の長さが伺えます。

ちなみにこの頃次便はXperiaSXを使っており手のひらサイズのスマホが人気でした。
AndroidOSも4.1となり、すこしずつ動作も安定してきました。

情報：アプリコ


#2014年流行アプリランキング

1位 白猫プロジェクト
2位 メルカリ
3位 LINEツムツム

Fril（フリル）やスマートニュースも、このころで情報系アプリも人気でした。
ちなみにLNEは２０１３年のTOP

![メルカリ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/27b5b033-cdba-363e-4c3b-15535337df15.png)![ツムツム.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/33b7d903-cc3d-4efc-1a69-20a89f8393a9.jpeg)![sumart.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/edd6f223-9a02-ae6c-ca1d-4b7ff0721cd8.png)

AndroidOS 5.0

情報：アプリ情報研究所


#2016年ベストアプリ

総合1位 AbemaTV
ゲーム１位 Pokémon GO
ベルトローカルアプリ　UberEATS	
ベストデザイン　C CHANNEL

![アベマ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/9a7b4b35-833d-8a0d-bb00-44ee2b9b66c1.png)![ポケモン.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/28fed23d-348f-4b23-1fdb-2459859b1592.jpeg)![c-channel.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/393c13e8-a34a-5d8d-27fd-80eb4bb85d4e.jpeg)


ながらスマホを一般的にしたポケモンGoは３年前の出来事だったのですね。
Android 7.1となり主要なアプリをつかうにはAndoridもiPhoneどちらでも関係なくなってきたころかとおもいます。スマホが、巨大化してきたのもこのころですね。

情報：Google Play

#Google Play「ベストオブ 2019」

いよいよ今年はどうでしょうか？

ユーザー投票部門＆生活お役立ち：PayPay
隠れた名作部門：スニーカーダンク - 人気・新作スニーカー情報アプリ
エンターテイメント：Mirrativ（ミラティブ）−スマホでかんたんゲーム配信&画面録画
ベスト５ゲーム：ドラゴンクエストウォーク

![paypay.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/e5369606-3a26-d5e9-231c-ae70b125ab52.png)![ミラティブ.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/dc439ef9-fd68-9b2d-e91a-e47f9cc4d76b.jpeg)![ドラクエ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92225/1587ed59-1afa-4edb-8902-37ca775c38cc.png)

個人的にはTikTokやYoutubeなど動画配信みるだけでは物足りなくなっており、自分も配信してみよっかなと日々かんがえているので、

Mirrativ（ミラティブ）−スマホでかんたんゲーム配信&画面録画
nana - 歌でつながる音楽コラボSNS

などの個人で配信する関連のアプリがランクインしているのことに共感できますね。。
来年は５Gもはじまるので、アプリの役割もおおきな変化があるかもしれませんね。

AndroidOS 9.0

情報https://play.google.com/store/apps/editorial_collection/promotion_topic_bestof2019_apps_hub?hl=ja
【Ruby】配列の要素を半角空白区切りで出力

配列の要素を半角空白区切りで出力したいときは、次のようにします。

```ruby
puts array.join(' ')
```

例：

```ruby
array = ["apple", "grape", "orange"]

puts array.join(' ')
# => apple grape orange
```

```ruby
array = ["1", "2", "3"]

puts array.join(' ')
# => 1 2 3
```

以上です。
AlexaスキルのアカウントリンクでLogin with Amazonを利用したAuthを通す所まで

## 困ったこと
Alexaスキル開発をしようと[チュートリアル](https://developer.amazon.com/ja-JP/docs/alexa/smarthome/steps-to-build-a-smart-home-skill.html)の手順に従っていたら、「アカウントリンク情報を提供する」セクションの説明が他と比べて不十分だったため、Amazon認証を利用するパターンの方法そこそこ時間を掛けて調べることになりました。

## 事前準備
Alexaスキル自体は作成済みとします。
(コードが完成していなくても、Lambdaのサービスエンドポイントなどの設定は済んでいるものとする)

## 実作業

### Login With Amazonのセキュリティプロファイル作成
詳細はこの[ドキュメント](https://developer.amazon.com/ja/docs/login-with-amazon/register-other-platforms-cbl-docs.html)が詳しいです。
1. [Login With Amazon Developer Center](https://login.amazon.com/)にアクセス
2. 左上Sign-In→DeveloperConsoleから自分のAmazonアカウントでログインする
3. 「セキュリティプロファイルを新規作成」から作成
4. 個人利用のスキルならプライバシー規約同意URLは適当で構いません(空値はNG)

### (Login With Amazon ウェブ設定)リダイレクトURLの設定
セキュリティプロファイルを作成したら、ウェブ設定タブを開きます。
「許可された返信URL」という欄があるので、そこにAlexaスキルアカウントリンクから `Alexaのリダイレクト先のURL` 項目にある3つのURLをコピーして載せます。
![スクリーンショット 2019-12-22 11.43.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224108/694cc783-44e4-e0d1-0ff3-59434b88706f.png)

<img width="1161" alt="スクリーンショット 2019-12-22 11.44.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224108/8f03ddf9-03b3-061e-8d8a-a856ff0f9434.png">


### (Alexaスキル側）セキュリティプロバイダー情報を登録する
![スクリーンショット 2019-12-22 11.39.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224108/692cdd2a-eefb-3c30-1e84-5242843b7eec.png)
アカウントリンクの画面で各項目の値を埋めていきます。
以下はAmazon認証を使う場合の入力値を載せています。

|項目名|入力値|
|---|---|
|認証画面のURI|https://www.amazon.com/ap/oa
|アクセストークンのURI|https://api.amazon.com/auth/o2.token
|ユーザーのクライアントID|Amazon認証ページのクライアントID
|ユーザーのシークレット|Amazon認証ページのシークレットID|
|ユーザーの認可スキーム|HTTP Basic認証|
|スコープ|profile


### 確認
[チュートリアル](https://developer.amazon.com/ja-JP/docs/alexa/smarthome/steps-to-build-a-smart-home-skill.html#provide-account-linking-information)に戻って、項「スキルをテストする」の手順に従ってスキルを有効化してください。

その際、Amazon認証が表示されれば認証設定は成功です。

![スクリーンショット 2019-12-22 11.48.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224108/d2218373-d44d-a55f-ff13-b930dd4f2ec5.png)
【Ruby】配列の要素の平均値を求める

配列`array`の平均値を求めるには、次のようにします。

```ruby
array.sum.fdiv(array.length)
```

**浮動小数点数の商**が得られる `Numeric#fdiv` メソッドを用いて、配列の要素の合計(sum)を配列の要素数(length)で割ることで平均値が算出できます。

※単純に `/` を用いて商を計算しようとすると、`整数 / 整数`の場合、**整商（整数の商）**になってしまい正しい計算ができません。

例えば `array = [2, 5]` のとき、

```ruby
array.sum.fdiv(array.length)
# => 3.5
```

ちなみに要素が文字列になっている場合は、`to_i`で整数型に変換してから計算すればOK。

例えば `array = ["2", "5"]` のとき、

```ruby
array.map!(&:to_i) # 配列の要素を整数型に変換
# => [2, 5]

array.sum.fdiv(array.length)
# => 3.5
```

以上です。

※いただいたコメントを元に内容を修正させていただきました。
　@scivolaさん、ご指摘いただきありがとうございました。
Microsoft Learn 22日目

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録。
※受講後に書き込むので公開に間に合わないこと多々あります(アドベントカレンダーの意味ｗ)

12/22 は
**Core Cloud Services - Azure ネットワークオプション**
 - Azure Load Balancer を使用したスケーリング

を受講。以下、簡易メモ。

# Core Cloud Services - Azure ネットワークオプション
## Azure Load Balancer を使用したスケーリング
### 可用性と高可用性とは
#### 可用性
サービスが中断なく稼働する長さを指す。
#### 高可用性
長期間起動して実行しているサービスを指す。

### 回復性とは
異常な状態でシステムが機能を維持できる能力を指す。
異常な状態には以下のようなものがある。
・自然災害
・ソフトウェアの更新やセキュリティ パッチの適用を含む、計画的および計画外のシステム メンテナンス。
・サイトへのトラフィックの急増
・分散型サービス拒否 (DDoS) 攻撃など、悪意のある第三者による脅威

### ロードバランサーとは
プール内の各システムにトラフィックを均等に分散させるもの。
ロードバランサーは、高可用性と回復性の両方を実現するのに役立つ。

### Azure Load Balancer とは
Microsoft が提供するロードバランサーサービスで、ユーザーのためにメンテナンスの面倒を見てくれる。
受信と送信のどちらのシナリオもサポートし、低遅延と高スループットを実現できる。
また、あらゆる伝送制御プロトコル (TCP) アプリケーションとユーザーデータグラムプロトコル (UDP) アプリケーションの数百万ものフローにスケールアップできる。

### Azure Application Gateway
Web アプリケーション用に設計されたロード バランサー。
トランスポートレベル (TCP) で Azure Load Balancer を使用し、高度な URL ベースのルーティング規則を適用していくつかの高度なシナリオをサポートしている。
すべてのトラフィックが HTTP の場合は、Azure Application Gateway を使用する方が適している可能性がある。

### DNS とは
わかりやすい名前をその IP アドレスにマップする方法。
インターネットの電話帳として考えることができる。
Android Studio を使った Flutter 開発で option(Alt) +  Enter が効かなくなったときの対処

# 対処方法

Android Studio → Preferences → Editor → Intentions → Dartにチェック → Quick assist powered by the Dart Analysis Server にチェック

(Preferences の検索欄に `assistant` を設定にたどり着くのが速い)

<img width="1037" alt="スクリーンショット 2019-12-22 午前11.14.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326574/b7bc9b8a-0a47-32fd-1806-b98e0365d88c.png">
 

# 参考

[Can't wrap widget list with new widget assist by Alt+Enter · Issue #2448 · flutter/flutter-intellij](https://github.com/flutter/flutter-intellij/issues/2448)

[VSCode: assists--quick-fixes](https://flutter.dev/docs/development/tools/vs-code#assists--quick-fixes)

[Android Studio: assists--quick-fixes](https://flutter.dev/docs/development/tools/android-studio#assists--quick-fixes)
使ってますか？KMS(Key Management Service)

今回はKMS(Key Management Service)についてご紹介します。
みなさんは、KMS使っていらっしゃいますでしょうか？
昨今、セキュリティに対して注目が集まっていますのでKMSの導入も検討してみてくださいね。

# Alibaba Cloud KMSとは
Alibaba Cloud KMS(Key Management Service)とは、暗号化されたKeyを作成・削除・管理するフルマネージドサービスです。
暗号鍵の機密性、整合性、可用性を保ちながら、コストも節約でき、他のAlibaba Cloudのサービスと連携出来ます。


# サービス内容
他社クラウドとほぼ似た内容だと思いますが、特徴と利用上のメリットを簡易的にまとめました。

## 特徴
**1.セキュアキーホスティング**
KMSは暗号化キーホスティングをサポートしています。
KMSでホストされる暗号化キーは、カスタマーマスターキー(CMK)と言います。
CMKを有効または無効にすることで、CMKのライフサイクルを管理することができます。

**2.BYOK**
KMSは、Bring Your Own Keys(BYOK)をサポートしています。
サポートしている内容としては、

* オンプレミスのキー管理インフラストラクチャ(KMI)へキーを設定する
* データ暗号化サービスをプロビジョニングおよび管理するハードウェアセキュリティモジュール(HSM)のキー

が挙げられます。
ただし、 KMSの管理対象HSMにインポートされたキーは、セキュリティで保護されたキー交換アルゴリズムが使用されているためエクスポートできないので注意が必要です。


**3.暗号化キーの自動ローテーション**
KMSのCMKは、複数のキーバージョンをサポートしており、CMKの複数のキーバージョンは相互関係はありません。
KMSは暗号化キーを自動的にローテーションしています。

**4.フルマネージドなHSM**
KMSはフルマネージドなHSMを提供しています。
HSMにキーをホストできるため、暗号操作をHSM内に保持して暗号セキュリティを保護できます。

**5.APIの提供**
CMKの状態だけでなく、CMKに対する操作(作成や削除、スケジューリングなど)をAPIで行うことができます。
詳細は[こちら](https://jp.alibabacloud.com/help/doc-detail/44211.htm)を参考にしてください。


**6.CMKエイリアス**
CMKは複数のエイリアスを持つことができます。
エイリアス名は１アカウントと地域で一意である必要があります。
CMKとエイリアスのマッピングは、APIで更新(UpdateAlias)することが可能です。
エイリアスは各リージョンに最大300個まで作成することが出来ます。

**7.リソースタグ**
他のAlibaba Cloudのサービスと同様に、リソースタグが対応しているのでKMSでの暗号化リソースの管理ができます。

## 利用上のメリット
* KMSはECS、ApsaraDB(RDS)、OSSと統合されています。
* KMSはRAMと統合されているため、RAMを介してさまざまなカスタムポリシーを作成できます。
* KMSはActionTrailと統合されているので、KMSの使用状況やOSSなどの他のサービスでのKMSの使用状況を確認することができます。

## SDK
2019年4月現在、提供されているSDKは以下の4つです。

* Java (JDK1.6以降)
* Python (Python2.x)
* PHP (バージョン： 5.3 / 5.4 / 5.5 / 5.6 / 7.0 / 7.1 )
* .NET (.NET Framework4.0以降)


# まとめ
証明書やKeyなどの重要な情報の暗号化と管理が出来るサービスは便利だと感じます。(地味に面倒な部分だと思うので。)
また、APIやSDKが提供されており取り扱いやすい仕組みが作られています。
PHPのSDKが準備されているのは良いなと思いました。
(個人的には.NET Coreへの対応もお願いしたい)


## 参考資料
[Alibaba Cloud Key Management Service(日本語)](https://jp.alibabacloud.com/product/key-management-service)
[Azure Key Vault](https://azure.microsoft.com/ja-jp/services/key-vault/)
[AWS Key Management Service](https://azure.microsoft.com/ja-jp/services/key-vault/)
[GCP CLOUD KEY MANAGEMENT SERVICE](https://cloud.google.com/kms/?hl=ja)
brown hack!!!


全然20日に投稿できませんでした、すみません・・・
brown hackと題してスマスピ拡張デバイス的なものを作成したのでざっくりまとめます。

##完成イメージ
![図3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115325/60b3bd54-9fe0-f25a-a12d-bd0e4970904e.jpeg)

brownの発話をセンサーで検知し連動して手をばたばたさせる的なイメージです

##完成系
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115325/44c13245-bacd-159c-d547-2239adfe7b8c.png)

<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/jxP1yszBur">https://t.co/jxP1yszBur</a></p>&mdash; まる (@hepppook) <a href="https://twitter.com/hepppook/status/1208580933562974208?ref_src=twsrc%5Etfw">December 22, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

挙動不審だし腕あんま動いてないし最終的に自分のサーボ音に反応しちゃってる気がするけど、
とりあえずセンサーに反応してる感じがするのでいったんは良しとしましょう。
（部屋きさなくてごめんなさい）

##材料
- Sound ESP32 v1 ×1 ※
- サーボモータ（TG9e）×2
- ローテーションサーボ（FS90R）×2
- コンデンサマイク（家に転がってたちっちゃめのやつ） ×1 
- その他、パーカ・リュック用の生地など

####※Sound ESP32 v1 について
@wamisnet さん作の基板です。※現在非売品

#####　主な特徴
- ESP32ベース
- 基板サイズは35×35mm
- sg90がそのままさせるサーボ専用のピン配列が6口
- MIC接続可能
- スピーカー接続可能（PCM5102）
- ディスプレイ（SSD1306）を搭載可能

![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115325/f9c55ef6-d64b-658e-4b34-cab91fd7e7d0.png)

私はよく顔面制作してるのですが、毎回色々うまくいかなくてつらいって話をしたら
顔面制作に便利な機能がつまった基板をつくってくれました！
（神！神！ありがとうございます）

SG90がこんなにぶっさせて、こんなに小型！でとても幸せなボードです。

##ギミック（と呼べるほどのものではない）
![IMG-6809.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115325/4f7f7150-18fc-9211-c77b-0229639af7e2.jpeg)


##配線
![IMG-6807.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115325/76f74b05-e9c4-ffc9-b52c-161189ece048.jpeg)

##プログラム
よくわからないけど、下記でとりあえずは動いた・・・

```c++:brownhack.ino
#include <ESP32Servo.h>

int micVal = 0;
int micOn = 0;
int threshold = 985;

Servo servoBR; //bottom-Rigth
Servo servoBL; //bottom-Left
Servo servoHR; //hand-Right
Servo servoHL; //hand-Left

void setup() {
  servoBR.attach(26); //servo1
  servoBL.attach(25); //servo2
  servoHR.attach(14); //servo3
  servoHL.attach(27); //servo4
}

void loop() {
  servoBR.attach(26);
  servoBL.attach(25);
  servoBR.write(90);
  servoBL.write(90);

  micVal = analogRead(34);  
  if(micVal > threshold){
    micOn = 1;
  } else {
    micOn = 0;
  }
  delay(1);

  if(micOn == 1){
    servoBR.write(0);
    servoBL.write(180);
    servoHand();
    delay(1);

    while(micOn == 1){
      servoBR.write(0);
      servoBL.write(180);
      micVal = analogRead(34);
      if(micVal > threshold){
        micOn = 1;
      } else {
        micOn = 0;
      }
      delay(1);
    }
  }
  
  if(micOn == 0) {
    servoBR.detach();
    servoBL.detach();
    delay(1);

    while(micOn == 0){
      micVal = analogRead(34);
      if(micVal > threshold){
        micOn = 1;
      } else {
        micOn = 0;
      }
      delay(1);
    }
  }
}

void servoHand() {
    servoHR.write(50);
    servoHL.write(100);
    delay(200);
    servoHR.write(150);
    servoHL.write(0);
    delay(200);
}

```


##反省など
サーボ音やはりうるさい
センサーの値とサーボの連動が思い通りになるようにどうにかしたい
距離センサーとかつけて障害物さけれたら
Sound ESP32の機能をもっとちゃんと使いたい、次は音声再生させたい
バッテリーで動かせるようにしたい
腕の機構をもっと安定させてたい
etc...

、、、というか成果物全然IoTしてないじゃん！！すみません！！
SpringのAutowiredはコンストラクタに書く

# 概要
SpringでDIをする時使うAutowiredのアノテーションは使いやすいし便利ですよね！
しかし、使い方が複数あり、どの使い方がいいのか迷うところではあります。
私はよくコンストラクタで使うのですが、そうなった経緯を整理したいと思います。

# Autowiredを設定できる方法
ざっくりと復習。Autowiredの設定方法は三種類あります。

## フィールドインジェクション 
フィールドに直接書くタイプの宣言方法です。

```java
public class A {
    @Autowired
    private B b;
}
```

## コンストラクタインジェクション
コンストラクタに書くタイプの宣言方法です。

```java
public class A {
    private final B b;

    @Autowired
    public A(B b) {
        this.b = b;
    }
}
```

## セッターインジェクション
セッターに書くタイプの宣言方法です。

```java
public class A {
   private B b;
   
   @Autowired
   public void setB(B b) {
       this.b = b;
   }
}
```

# なぜコンストラクタインジェクションを選ぶのか。

フィールドにfinalを使用することができて、不変性を担保できる。この理由が大きいですね。
こうすることで、処理の途中で書き換えられることがないので安全ですよね。
（保守で訳わからない人でもfinal書き換える時にコンパイルエラーになるから、わかる。本当に）
また、テストでnewしできるのが大きいですね。
テストでDIするか単なるnewで済ますのかを選択できるようになるのは、個人的に嬉しい。

# 逆にフィールドインジェクションを使用しているのはダメ
そもそも公式が非推奨としているものです。（たしか）
それを、わざわざ使用する意味はないでしょう。

サンプルソースとかでもフィールドインジェクションを使用しているのは信用しないようにしています。
そのぐらいダメだと個人的に思ってます。（すごく楽だけど）

# まとめ
どんなソースでもめんどくさがらずにコンストラクタインジェクションを使用しましょうね。
Node.jsで持続的 Cookie に対応する

# 発端

REST 使うコンソールアプリを TypeScript で書きたかったので、 Node.js と axios を使ってコードを書いていたのですが、ログイン操作や読み取り操作など毎回プロセスを起動して落とす設計にしたところ、 Permanent Cookie がプロセス終了とともに消滅してしまう状態でした。

## Permanent Cookie？

[mdn](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies) によると **セッション Cookie** と **持続的 Cookie** の二つがあると紹介しており、前者は有効期間の指定がないのでクライアントを終了すると消えるとあります（ECのカートのような一時的なセッションで使われる感じですかね）。そして後者は設定された有効期間までは存続すると読み取れそうです（ログイン用途で使えそう）。
実際試したところ、ブラウザや [iOS/macOSのAPI](https://developer.apple.com/documentation/foundation/urlsession) はプロセス再起動しても自動でCookieを付与してくれたのですが、Node.js + axios ではやってくれませんでした。どうやらディスクに保存するような別の仕組みが必要そうです。

# 対応方法

最悪デーモンプロセスが必要かもな、、と思いつつ調べたところ [tough-cookie](https://github.com/salesforce/tough-cookie) という強そうな名前のライブラリを見つけることができました。これ自体はディスクに保存しないのですが、ドキュメントを読んでみると [Store API](https://github.com/salesforce/tough-cookie#store-api) という仕組みがあることに気がつきます。

> The default is MemoryCookieStore which can be found in the lib/memstore.js file.

とても気になる文言です。 lib/ に FileCookieStore のような実装があればそれに切り替えるだけで実現できそうですが残念ながらありませんでした。

## 追加のライブラリを検索

もしかしたら誰かが実現しているかもと思い、次にGoogleで "tough-cookie file" と検索しようとしたところ、 [tough-cookie-filestore](https://github.com/mitsuru/tough-cookie-filestore) がサジェストされました。おお、これは試してみたい。

## コード

まず axios と tough-cookie をどう連携させるかという問題に直面するわけですが、以前 axios が同一プロセス内でも cookie を付与してリクエストを送ってくれないという別の問題に対処すべく [こちらの記事](https://qiita.com/grainrigi/items/007f1e4df7cb14831994) を読んでいたので、 cookiejar を使えばうまくいくことを運良く知っていました。

なので axios cookiejar で検索してみたわけですが今度は同じゆめみの @Ancient_Scapes さんの記事に使い方が書いてあったので時間短縮できました(助かる〜):  [axiosでrequestと同じようにjarを使えるようにする方法](https://qiita.com/Ancient_Scapes/items/63744a8f4237862477c0)

というわけで filestore のインスタンス作ってセットするだけでした。簡単。  

```typescript
import axios from 'axios';
import axiosCookiejarSupport from 'axios-cookiejar-support';
import { CookieJar } from 'tough-cookie';
import FileCookieStore from 'tough-cookie-filestore';

export const createClient = (baseURL: string, cookiePath: string) => {
  const filestore = new FileCookieStore(cookiePath);
  const jar = new CookieJar(filestore);
  axiosCookiejarSupport(axios);
  return axios.create({
    withCredentials: true,
    jar,
    baseURL
  });
};
```

TypeScriptでもバッチリでした。素晴らし。

注意事項としては、上記のコードではデフォルトで cookiePath に空のファイルがないとエラーになります。writeFileしておきましょう。

## 余談

cookiejar ってどういう意味なんだろと思いググってみたところ、 [weblioのページ](https://ejje.weblio.jp/content/cookiejar) が引っ掛かったのですが、

> クッキーが保存される瓶（時々お金が隠される）
  
という意味らしいです。時々お金が隠されるというところがとても気になります、海外のアニメ作品とかかな :thinking:
NimでnewSeqOfCapとsetLenを組み合わせて使うときの注意点

# 

## はじめに
Nimはメモリ管理を意識せずにプログラミングできるが、バックエンドにCやC++があるため、
凝ったことをしようとする時にはNimがメモリ割り当てをどうやってるか意識しないといけない場合があります。

この記事の結論を先に述べると、
「良く分からない人は`newSeqOfCap`と`setLen`を組み合わせて使わないようにしましょう。」

## 注意する例

### 問題
以下の(1),(2),(3)は何が出力されるでしょうか？

```nim
var
  seq1:seq[int]
  seq2:seq[int]
  seq3:seq[int]

seq1 = newSeq[int](10)

seq2 = newSeqUninitialized[int](10)

seq3 = newSeqOfCap[int](10)
seq3.setLen(10)


echo "seq1[0]:",seq1[0] # (1)
echo "seq2[0]:",seq2[0] # (2)
echo "seq3[0]:",seq3[0] # (3)
```

### 答え
(1) 0
(2) 不定
(3) 不定

### 解説
(1) `newSeq`で`seq`を生成すると割り当てられるメモリ領域は`seq`要素の型（今回はint型）の初期値に初期化されるため、0となります。
(2) `newSeqUninitialized`は名前の通り初期化されないため、割り当てられたメモリ領域に入ってる値は分かりません。（その代わり、`newSeq`に比べて高速です）
(3) 今回注意したいのは`newSeqOfCap`で、最初に確保したCapacity分のメモリ領域は初期化されません。`setLen`でseq長を伸ばした場合もメモリ再割り当てが起きない場合（最初のCapacityを超えない場合）は伸びた部分については初期化されません。

## 初期化されないことで問題が生じる例
先ほどのプログラムの前方に`seq`を何度も生成する処理を追加します。

```nim
var
  seq0:seq[int]

for i in 0..<10_000:
  seq0 = newSeq[int](100)
  for j in 0..<100:
    seq0[j] = 100

var
  seq1:seq[int]
  seq2:seq[int]
  seq3:seq[int]

seq1 = newSeq[int](10)

seq2 = newSeqUninitialized[int](10)

seq3 = newSeqOfCap[int](10)
seq3.setLen(10)

echo "seq1[0]:",seq1[0] # (1)
echo "seq2[0]:",seq2[0] # (2)
echo "seq3[0]:",seq3[0] # (3)
echo "seq3[1]:",seq3[1]

echo ""
seq3.setLen(1)
seq3.setLen(10)
echo "seq3[0]:",seq3[0]
echo "seq3[1]:",seq3[1]
```

この場合、環境によっては以下の結果となります。

```bash
seq1[0]:0
seq2[0]:100
seq3[0]:100
seq3[1]:100

seq3[0]:100
seq3[1]:0
```

`seq0`に割り当てられたメモリがGCで回収されて`seq2`や`seq3`に割り当てられたため、100が出力されたと考えられます。

ただ、`setLen`でseq長を短くした場合は、削られた部分は初期化されるようです。
そのため、`newSeq`のみを使っている場合には`setLen`でseq長を変更しても安全と言えそうです。

## まとめ
`newSeqOfCap`を`setLen`を組み合わせて使う場合には注意しましょう。

よく分からない場合は`newSeq`を使うか、`newSeqOfCap`で生成したseqに`setLen`は使わないようにしましょう。