OmniAICreator/Qiita-1.07M huggingface dataset:
【手抜き】STM32の使い方まとめ　番外. 「私、マクロを使えって言ったよね！？」

久しぶりの投稿です。
とっても短いページになる予定です。

#事の始まり

そろそろ後輩にいろいろ教えないとと思って、相変わらず手抜きの資料集めをしたのですが
PWM, Encoderモードについて、その値を構造体で直接いじっている記事が多すぎる…
やめてやめて～～

#Timer
というかこれに関する記事しかない。
###PWM
みなさん、PWMのDuty比を設定するときにどうしてますか？？
まさか `htim1->Instance->CCR1=<Duty>;`
とかしてないですよね？？

`__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, <duty>);`
ですよですよ？？

###Period
たまに、タイマのPeriod値（CubeMXで設定したタイマの最大の値）が欲しいときがあるでしょう。
この時は
`__HAL_TIM_GET_AUTORELOAD(&htim1);`
を使いましょう。

###Encoder mode
はい。一番事故ってる記事が多いのがこれ。
エンコーダ値の読み方がわからなかったからと
`cnt=htim1->Instance->CNT;`
って人が大多数！！

`__HAL_TIM_GET_COUNTER(htim1);`

ですね。。

###タイマについてのまとめ
それぞれの使用法について特化して書きましたが、実は上記のマクロは使い方に寄りません。
例えば、COUNTERはそのままカウンターのことですから、ただのカウントアップとして（HAL_TIM_Base_Start()）使う場合でも使いますし、
コンペアマッチモードではCOMPAREを使うでしょう。

また、もちろんSETがあれば、GETがありますし、vice versa。

#こんなこと言ってる理由
いや、構造体直接引っ張り出したらHAL Driverの意味を消失してるのでは。。
HALってなんでこんなにいろんな名前長いんだろーってのは、誰が読んでも何してるのかわかるため、ですよね？可読性というやつですか？
だから、直でレジスタをたたくようなところを関数なりマクロでコーディングしているわけですから、もうちょっとSTさんの意向をくみ取りましょう。

#注記
他の機能についても同じようにマクロがあるはずです。

HALのドキュメント[UM1725](https://www.st.com/resource/en/user_manual/dm00105879.pdf)(このリンクはforF4)では
機能ごとに分かれて、順に

- 設定用などの構造体
- 手順（ここが弱い）
- 関数
- マクロ・列挙体（構造体に代入する設定項目など）

が、並んでいます。
もし、やりたいことが、関数になかった場合はマクロを探してみてください。
逆に関数にある場合（割り込みの許可不許可など）は関数を積極的に使うようにします。

直接レジスタたたいたり、構造体をいじるならHALはいらないよね？

#相互リンク(随時更新@2020/03/09)
**【手抜き】STM32の使い方まとめ**
（まだない記事は今後変更の可能性があります）

- [0.STM32のご説明](https://qiita.com/nabeya11/items/9ee076933983ed7ae3b6)
- [1.STM32CubeIDEの導入とLチカ](https://qiita.com/nabeya11/items/0859271c1307d88d6891)
- 2.GPIOでデジタル入力
- [3.STM32CubeIDEの日本語化](https://qiita.com/nabeya11/items/fb6e0c4fe3156e307f6a)
- 4.STM32CubeIDEでGit
- 5.標準タイマを使う
- 6.タイマ割り込みで等時間制御
- 7.PWM波形の出力
- 8.I2CのMemWrite/Read()
- 8.Encoderモードの使い方
- 9.UART~送信:DMAとprintf少数表示まで~
- 10.MCSDKでブラシレスモータを回す
- 11.RS485
- 12.CAN
- 13.STM32CubeIDEでデバッグ
- [番外. 「私、マクロを使えって言ったよね！？」](https://qiita.com/nabeya11/items/c901c5c0ccd61f9cc01a)
- [番外.STM32CubeIDEと日本語の文字化け](https://qiita.com/nabeya11/items/beac1586510d357bf911)
[python]変数のメモリ消費量確認

この記事は[古川研究室 Advent_calendar](https://qiita.com/advent-calendar/2019/flab) 8日目の記事です。
本記事は古川研究室の学生が学習の一環として書いたものです。内容が曖昧であったり表現が多少異なったりする場合があります。

# はじめに

同じタスクの機械学習のアルゴリズムを比較する軸として、学習の安定性(初期値の依存度)・説明可能かどうか・(教師あり学習では正解率 (Accuracy)・適合率 (Precision)・再現率 (Recall)という指標もあります)そして、「計算量」があります。

メモリに載らないくらい計算量が大きくなりやすいアルゴリズムだと状況(時間・計算リソース)によっては採用しづらいですね. (ex: $\mathcal{O}(データ数^3)$ だと一回の学習のデータ数はせいぜい1000($1000^3=10 Billion \fallingdotseq 10GB$)に押さえないとですね. 

また、計算量が少なくても実装的にその計算になっていない場合もあります.

本記事では、pythonのプログラムのメモリ消費量を確認する方法を記します。


# No package
@shiracamus さんに何もimportなしにメモリサイズがわかる方法を明記していただいたので、ちゃっかり本文にも追記させていただきます。

```python
import numpy as np
N = 1000
D = 3
X = np.random.randn(N,D)
X.__sizeof__()
# 24112
```
番外:　変数以外のメモリ消費量確認方法

```python
X = [X]
X.__sizeof__()
# 48

def f():
  pass
f.__sizeof__()
# 112

class A():
  pass
A.__sizeof__()
#   File "<stdin>", line 1, in <module>
# TypeError: descriptor '__sizeof__' of 'object' object needs an argument
# 後述する sys.getsizeof()なら可能
```

# sys


```python
import sys
import numpy as np

N = 1000
D = 3
X = np.random.randn(N,D)
print(sys.getsizeof(X))
# 24112
```
ちなみに pytorchの場合は変数の後に.storage()をつけないとちゃんと持ってきくれません(一敗)

```python
import sys
import torch

N = 1000
D = 3
X = torch.randn(N,D)
print(sys.getsizeof(X))
# 72
print(sys.getsizeof(X.storage()))
# 12064
```


# memory_profiler

見たい変数ごとにsys.getsizeofを呼ぶのは骨がおれます。
そこでmemory_profiler です。標準パッケージではないのでインストールしてくる必要はあります。

ちなみに@profileで対象のメソッドの中身はpycharmのデバッグモードで止まってくれません(一敗)

```python

from memory_profiler import profile
import numpy as np

@profile()
def test():
    N = 10000000
    D = 3
    X = np.random.randn(N, D)

test()
    
```
とすると出力で

```sh

Line #    Mem usage    Increment   Line Contents
================================================
     5     62.3 MiB     62.3 MiB   @profile()
     6                             def test():
     7     62.3 MiB      0.0 MiB       N = 10000000
     8     62.3 MiB      0.0 MiB       D = 3
     9    291.2 MiB    228.9 MiB       X = np.random.randn(N, D)
```
をだしてくれます. 

Mem usageが Totalで, Incrementがその行で追加されたメモリ量です。
実装次第ではあまり信用ができないみたいですが、軽い確認には自分がこれを使っています。
MongoDBのレプリケーション概要と、高負荷になった時にやったことをまとめる

この記事は[ニフティグループ Advent Calendar 2019](https://qiita.com/advent-calendar/2019/nifty)の8日目の記事です。
7日目は@saikeiさんの[一人暮らしの寂しさを推しとIoTとLINE Botで解決した話](https://qiita.com/saikei/items/fd33f5ed898eb0ce1ca1)でした！


以前、担当しているサービスで一部の目立たない機能にMongoDBが使われている部分があり、しかもそこが高負荷になって閲覧に影響が出る事態が発生しました。
普段mongoを使っていない自分は冷や汗ダラダラ、これさえ知っておけばよかったのに！！ということをまとめたものが役に立てばいいなと公開していきます。

# mongoってなんなんだ
公式ドキュメントを読んだ方がよい！
https://docs.mongodb.com/

## mongoのレプリケーション構成
mongoはレプリケーションの機能が備わっており、1台が死んでも、他のサーバーがバックアップとして機能することができます。
ただし、読み書きの分散はなされず、純粋にデータのバックアップとしてのみ機能します。読み書きの分散をするには、別にシャーディングの設定が必要になります。
私のサービスでも前任の方がきっちりレプリケーションの設定をしてくれていました！

これも、正確には公式ドキュメントを読んだ方がよい！！！https://docs.mongodb.com/
ですが、全編英語なので、日本語でざっくり要約します。

### ざっくり
- Primary（読み書きがくるサーバー）とSecondary(バックアップ)がいる
- レプリケーションを行うには、最低3台が必要
    - 1台が死んでも、あとの2台でPrimaryを投票して決めなければいけないため
    - 最後に同期が完了しているものが、Primaryに昇格する
- レプリケーションは非同期
    -  PrimaryのOplog（どんな操作がなされたかのオペレーションログ）の内容を反映する
    -  非同期とはいえ、時間差は1秒〜最大数秒程度
- 自動フェイルオーバー
    - PrimaryやSecondaryはお互いの生き死にを監視し、Primaryが死ぬと自動でフェイルオーバーする

##### Primaryが死ぬとどうなってしまうのか
- Secondaryのうち、投票されたものがPrimaryに昇格し、ロールバックが発生する
   

# Primaryが高負荷になってしまい、切り離したいとき
mongoのコマンドラインから以下を叩く　※Primaryからしかできません
```rs.stepDown()
```
原因がアクセス数の増加などでの負荷ではなく、Primaryのサーバー自体に不具合が発生しており、一時的にSecondaryがPrimaryを務めることで解決できる問題の場合、このコマンドだけで解決できる場合があります。

# Primaryに入れないレベルの障害が発生し、SecondaryをPrimaryに昇格させたい時
基本的に、Primaryからでないと、PrimaryをSecondaryに降格できないのですが、Primaryが何らかの理由で操作できない状態になってしまった場合、
Secondaryから強制的にPrimaryを降格させることが可能です。
こちらの記事の手順でうまくいきました。https://www.greptips.com/posts/1257/


# レプリカセットのいずれかで、障害が発生したため切り離したいとき

```
cfg=rs.config()

// 切り離したいメンバーを除いて確認する
cfg.members = [cfg.members[1],cfg.members[2]]

// Priamryから操作している場合の設定反映
rs.reconfig(cfg)
// Secondaryから操作している場合の設定反映
rs.reconfig(cfg,{force:true})
```


# 困ったときのコマンド集
レプリケーションの設定を確認する
```rs.config()
```

レプリケーションの状態を見る
```rs.status()
```

最後にレプリケーションがされたのがいつかを確認する
```rs.printSlaveReplicationInfo()
```

mongoやそれが乗っているサーバー自体の不具合だと、以上のコマンドや対処法で一つ一つ丁寧に確認していけばなんとか問題が解決できるような気がします。

私が直面した問題の場合、アクセス負荷が急激に増大し、indexを貼っていなかったことでレプリカセットが順々にPrimaryになる→死ぬということを繰り返し、mongo自体にアクセスができないという最悪の状態になってしまいました😇
その際は、mongoへのアクセス元を遮断し、スペックアップ・indexの構築などを行なってから、mongoをサービスに復帰させるということを行いました。
どのDBを使っても言えることですがちゃんとindexは貼りましょうね！！！！

明日は、@kanishionori さんからレトロスペクティブの話か、AmazonForecastのお話が聞けそうです！楽しみですね！
Rails 新規アプリケーションの作成②


##書かれていること
- アプリケーションの作成とRailsの動き（続き）
1.モデル作成
2.テーブル作成
3.モデルから表示するレコードを取得
4.モデルから取得した内容を出力

- 終わりに

##アプリケーションの作成とRailsの動き（続き）
####1.モデル作成
```rails:ターミナル
rails g model 作りたいファイル名（コントローラーと同名がわかりやすい）
```
 tweets_controllerならtweet.rbになるようにファイル名を"tweet"とするなど


####2.テーブル作成
```マイグレーションファイル``` に作りたいテーブルの記述を行う

```ruby:例
class CreateTweets < ActiveRecord::Migration[5.2]
  def change
    create_table :tweets do |t|
      t.string :text #string型のtextというカラムを作成してね
      t.timestamps
    end
  end
end
```
- テーブルの記述ができたらターミナルで```rake db：migrate```する
- ```Sequel Pro```でカラムが記述通り作成されているか確認

#####記述ミスなどでカラムが思ったように作成されていなかったら
```rails:ターミナル
rake db:rollback
```
- これで、マイグレーションする前の状態になりました
- マイグレーションファイルに記述をし```rake db：migrate```すればOKです

#####SequelProにあるtweetsテーブルにレコードを作成
- モデルから表示するレコードを取得する方法を確認するため、今回はSequelProに直書きしちゃいます

####3.モデルファイルから表示するレコードを取得
```例 ```

```ruby:tweets_controller
class TweetsController < ApplicationController
  def index
    @tweets = Tweet.all
  end
end
```
- Tweetモデルから全てのレコード情報を呼び出して@tweetsに代入


####4.モデルから取得した内容を出力
- eachメソッドを使い一覧表示
- textの部分を変数にし、tweetsテーブルのtextカラムから引用してきたテキストを表示

```ruby:index.html.erb
###省略
<div class="contents">
#eachメソッドでコントローラで作成したTweet.allの変数＠tweetsを使用　
    <div class="message clearfix">
      <%= image_tag 'cat1.png' %>
      <div class="message_box">
        <p class="user_name">
          ユーザーネーム
        </p>
        <p class="text">
          <%= tweet.text %> #tweetテーブルのtextカラムの呼び出し
        </p>
      </div>
    </div>
  <% end %>
</div>

```
```rails s```コマンドでサーバーを起動して表示されるか確認

##終わりに
ここまでで新規作成は一通り完了です。
投稿や遷移など、新機能実装の時はルーティング→コントローラ→ビューの順で実装を行なっていきます。

プログラミングはど素人なため、記述内容で誤りなどございましたら、ご指摘いただけると幸いです。
【Mac コマンド】文字化けしたcsvファイルをクイックに確認する

# 前提

* nkfコマンドが使える
    * https://qiita.com/Atelier-Mirai/items/b2be50114443a628f586

# コマンド

```bash
head zenkoku.csv | nkf -w
```

結果

```
"住所CD","都道府県CD","市区町村CD","町域CD","郵便番号","事業所フラグ","廃止フラグ","都道府県","都道府県カナ","市区町村","市区町村カナ","町域","町域カナ","町域補足","京都通り名","字丁目","字丁目カナ","補足","事業所名","事業所名カナ","事業所住所","新住所CD"
60000000,1,1101,11010000,"060-0000",0,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク",,"　","（該当なし）",,,,,,,,
60840600,1,1101,11010000,"060-8406",1,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク",,"　","（該当なし）",,,,,"北海道テレビ放送　株式会社","ホツカイドウテレビホウソウ　カブシキカイシヤ","北１条西１丁目６番地",
60850400,1,1101,11010000,"060-8504",1,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク",,"　","（該当なし）",,,,,"富士通　株式会社　北海道支社","フジツウ　カブシキガイシヤ　ホツカイドウシシヤ","北２条西４丁目１番地札幌三井ＪＰビルディング",
60855200,1,1101,11010000,"060-8552",1,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク",,"　","（該当なし）",,,,,"損害保険ジャパン日本興亜　株式会社","ソンガイホケンジヤパンニツポンコウア　カブシキガイシヤ","北１条西６丁目２番地損保ジャパン日本興亜札幌ビル",
60860200,1,1101,11010000,"060-8602",1,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク",,"　","（該当なし）",,,,,"株式会社　朝日新聞社　北海道支社","カブシキカイシヤ　アサヒシンブンシヤ　ホツカイドウシシヤ","北１条西１丁目６番地さっぽろ創生スクエア９階",
60872100,1,1101,11010000,"060-8721",1,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク",,"　","（該当なし）",,,,,"大丸　株式会社　紙包材営業本部","ダイマル　カブシキガイシヤ　カミホウザイエイギヨウホンブ","北３条西１４丁目２番",
64863300,1,1101,11010000,"064-8633",1,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク",,"　","（該当なし）",,,,,"株式会社　ビッグ","カブシキガイシヤ　ビツグ","南４条西７丁目６番地ビッググループ本社ビル",
64856500,1,1101,11010000,"064-8565",1,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク",,"　","（該当なし）",,,,,"北海道トラック交通共済協同組合","ホツカイドウトラツクコウツウキヨウサイキヨウドウクミアイ","南９条西１丁目１番１１号",
64094100,1,1101,11010001,"064-0941",0,0,"北海道","ホッカイドウ","札幌市中央区","サッポロシチュウオウク","旭ケ丘","アサヒガオカ",,,,,,,,,

```

# 使っているデータ

* [住所データCSV【住所.jp】](http://jusyo.jp/csv/new.php)
LINEのチャットボットでできるUXデザイン

![07d726be-9792-42e6-acbb-dc77c0d20d5c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439086/12d3f805-1a25-b34e-ae6d-09ee97a1ba3c.png)



皆さんこんにちは！
ZEALSでコミュニケーションデザイナーをやっている森です。

ZEALSはチャットを通して商品の購入等を行う「チャットコマース」の会社なのですが、
現在、私はチャットのシナリオ設計を主に行っています！シナリオ設計といわれると難しいかもしれないのですが、
このチャットボットを使うユーザーのペルソナやその人がもつ課題を考え、それを解決するための会話を考えていて、
ざっくりいうと、ユーザーの課題解決、が仕事だと思っています！

さて、今日は、LINEでチャットボットを作る際にできるUXについてご紹介したいと思います。

#### クイックリプライ
クイックリプライは、特定のメッセージに対して最大13個のアクションを「クイックリプライボタン」として表示させることが可能です！
下の画像のように、ボタンを表示することができます。ちなみに、ボタンの中には絵文字や画像（小さめのアイコン）もいれることが可能です。選択肢が13個まで用意することができるので、たくさん選択肢がある場合などは、クイックリプライを使うことが多いです！
![503af62d-b8d3-472e-8a23-0bc193322cee.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439086/8d8d0958-6b03-aec8-75c3-d2caabba6678.png)

#### リッチメニュー
リッチメニューとは、トーク内の画面下部に表示される固定のメニューのことです。
分割されたリンク付きの画像を貼り合わせて構成されており、画像をタップすると、次のシナリオへの移行や
外部サイトへの誘導が可能になります。
様々なサイズがあり、画像は2500×1686ですが、ZEALSでは30パターンの画像サイズに適応しています。
先ほどお伝えしたクイックリプライでは、文字が小さくなってしまうのですが、リッチメニューだと視認性がよく、ボタンとしてのおしやすいので誰でも使いやすいのがポイントです。
![8de85781-6715-449a-b2db-ec107182c433.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439086/8b58c42d-c6e0-77dc-939f-35acb6f563f6.png)


#### イメージマップ
イメージマップメッセージでは、異なるアクションに結びつく複数のタップ領域が指定された画像を送信することができます。
画像内のタップ領域には、リダイレクトするリンクのURLや、ユーザーからbotに送られるテキストメッセージを指定することができます。
このタイプは様々な企業のLINEアカウントで送られているので、見たことがある方もいるのではないでしょうか。
１枚の画像が送られて、商品のリンクに遷移することができるタイプのものがよくあるのですが、シナリオを指定することもできます。
リッチメニューよりもサイズが大きいため（1040×1040）情報が多いときなどに使ったり、商材の画像を表示するときに使うのがおすすめです！
![28adb040-e2b1-41a6-af2e-6f83836ed642.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439086/f5993b3d-aafc-b731-8faf-8e687b576ff0.png)



#### フレックスメッセージ
Flex Messageは、CSS Flexible Box（CSS Flexbox）の基礎知識を使って、レイアウトを自由にカスタマイズできるメッセージです。
FlexコンテナがFlex Messageのボックスに対応し、FlexアイテムがFlex Messageのコンポーネントに対応しています。
ボタンの色や、テキストの色、画像サイズをなどを変更することができ、[LINE Bot Designer](https://developers.line.biz/ja/services/bot-designer/)を使うと、
プログラミンの知識がなくても簡単にかつ短時間で見た目のいいものを作ることができるのでおすすめです！
![f14b9570-0468-43dd-81ff-1e2dd81c34bd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439086/e070811a-3922-bb88-9726-b9a858e2a68b.png)


このように並べると、左から右に情報を流す形で情報提供が可能になります。
![74d86342-4f27-49cd-85c3-bf2767bce392.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439086/d3bce45b-053f-55c6-36cf-083335ecdbcd.png)


#### 最後に
いかがでしたでしょうか？他にもLINEでの表現はいろいろあるのですが、今回は普段私がよくつかうもので紹介させていただきました！
いろいろあるのですが、コミュニケーションデザイナーは、ユーザーに対してどのような見せ方が最適か、日々考えながらシナリオを作っています！
そんなZEALSでは、”日本をぶち上げる”というVISIONに向かって、コミュニケーションをつきつめて考える仲間を募集しております！
興味があればぜひ、ご連絡くださいませー！
Selenium WebDriverでHTTPステータスコードを確認したい

この記事は 弁護士ドットコム [Advent Calendar 2019 - Qiita](https://qiita.com/advent-calendar/2019/bengo4com) の10日目の記事です。


# はじめに
- この記事で利用されているサンプルコードは [こちら](https://github.com/tsuka611/example_selenium_status_code) に公開しています。
    - 動作確認などにご利用ください。
- 他の人のサーバに対して、むやみにプログラムを使ってアクセスしてはいけません。サンプルコードの取り扱いはご注意ください。

# Selenium WebDriverを利用してHTTPステータスコードって取得できるの？
- どうやらできないらしいです。
    - https://github.com/seleniumhq/selenium-google-code-issue-archive/issues/141
- また、方針としてそのような機能を作成することはなさそうです。
    - ユーザアクションのエミュレートではないのでスコープ外だよ！
    - ステータス確認したければ、普通のHttpClientで確認した方が良いよ！
    - Proxyサーバを前に立てて、そこでステータスを確認したら良いよ！
- ちなみにPuppeteerならできそうです。
    - https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#responsestatus

# パフォーマンスログからの取得を試みる
- いわゆる `開発者ツール` で表示されるアレです。
- ページ内で発生する通信の情報が記録されているため、そこからステータスコードの取得を試みます。

## WebDriver側の設定
- デフォルトだと、パフォーマンスログは取得されないので、設定を有効にする必要がある。
- サンプルだと [このへん](https://github.com/tsuka611/example_selenium_status_code/blob/master/src/status_get.rb#L15-L36)です。

```ruby
logging_prefs = {
  driver: 'ALL',
  server: 'OFF',
  browser: 'ALL',
  performance: 'ALL' # パフォーマンスログを有効に
}

caps = Selenium::WebDriver::Remote::Capabilities.new(
  browser_name: browser_name,
  javascript_enabled: true,
  css_selectors_enabled: true,
  takes_screenshot: true,
  native_events: true,
  proxy: nil,
  loggingPrefs: logging_prefs # ここで設定
)
``` 

## パフォーマンスログの取得
- WebDriverを利用してページアクセスを行なった際のパフォーマンスログを取得する。
    - WebDriverからログを取得すると、揮発してしまうようです。
    - 何度も利用する場合は、どこかに退避しておく必要があります。
- サンプルだと [このへん](https://github.com/tsuka611/example_selenium_status_code/blob/master/src/status_get.rb#L54-L58) とか [このへん](https://github.com/tsuka611/example_selenium_status_code/blob/master/src/status_get.rb#L72-L83) になります。

- パフォーマンスログは以下のようなイメージです。

```json

{  
  "message":{  
    "method":"Network.responseReceived", // ログの要素
    "params":{
        /* methodごとに異なるフォーマット */
    }
  },
  "webview":"9B690C508A0F351BED47CA889794059B"
}
```

- `Network.responseReceived` から、アドレスバーのURL（`driver.current_url`）に対する通信の記録を抽出します。
    - 記録されたレスポンスヘッダから、ステータスコードを取得することが可能です。

```ruby
  def extract_status_code current_url, logs
    logs.each do |log|
      next if log[:method] != 'Network.responseReceived'

      params = log[:params] || {}
      response = params[:response] || {}
      next if response[:url] != current_url

      return response[:status].to_i
    end
    0
  end
```
## パフォーマンスログからステータスコードが取得できないケース
- History APIなどでアドレスバーのURLが書き換わっているケース。
    - `driver.current_url` のURLで通信が発生していないため、データの抽出ができません。
- ホスト名が解決できないなど、対象のURLに対して通信が発生しないケース。
    - そもそもパフォーマンスログが積まれていません。
    - その場合の判定方法は [こちら](https://github.com/tsuka611/example_selenium_status_code/blob/master/src/status_get.rb#L61-L70) のようになります。

```ruby
def check_unreachable? current_url, logs
  logs.each do |log|
    next if log[:method] != 'Page.frameNavigated'

    params = log[:params] || {}
    frame = params[:frame] || {}
    return true if frame[:unreachableUrl] == current_url
  end
  false
end

```

# まとめ
- パフォーマンスログを利用すれば、ある程度ステータスコードの取得は可能。
    - ただし、取得できないケースもあり、過信は禁物。
- Puppeteerで代用可能であればそちらを利用した方が賢明。
FlutterのreleaseビルドでHTTP通信が使えないとき

# FlutterのreleaseビルドでHTTP通信が使えないとき

つい先日、debugモードでのビルドが正常に動いていたためreleaseモードでビルドして実行しようとした際に

```
[ERROR:flutter/lib/ui/ui_dart_state.cc(148)]
Unhandled Exception: SocketException: Failed host lookup: 'example.com/api/hogehoge'
(OS Error: No address associated with hostname, errno = 7)
```

といったエラーが出ました。

Failed host lookup(ホスト検索に失敗)と出ていたのでURLが間違えていたのかと思い確認してみるが間違えていなかった。

後ろのほうを見てみると、OS Error: No address associated with hostname(ホスト名に関連付けられたアドレスがありません)となっているため、もしかしたら権限回り？と思い調べてみました

## StackOverflowに同じようなError内容がありました。

[error when using https with flutter http.dart package](https://stackoverflow.com/questions/54728717/error-when-using-https-with-flutter-http-dart-package)

**ネットワークに接続するための権限がない**ので、権限を```android\app\src\main\AndroidManifest.xml```に書いてくださいとのことでした。

```xml
<manifest xmlns:android="http://".....>
    <uses-permission android:name="android.permission.INTERNET" /> <!--この行を追加してください！-->
    <application android:name=......>
        <activity .....>
            .....
        </activity>
    </application>
</manifest>

```

これでreleaseビルドでもhttp通信ができるようになりました！

### 参考ドキュメント
[Android developersドキュメント:ネットワークに接続する](https://developer.android.com/training/basics/network-ops/connecting.html)
FFT(高速フーリエ変換):実装のための数式と実装例

#FFTの原理および数式
[数式→実装]にフォーカスした記事がなかったので綴ります。
今回紹介するのはCooley–Tukey型FFTのradix-2という最もシンプルなものです。

まず、DFT(離散フーリエ変換)は次の式で表されます。
$$F(t) = \displaystyle \sum_{x=0}^{N-1}f(x) e^{-i \frac{2πtx}{N}} \qquad t=0,1,...,N-1\tag{1}$$
ここで、$N$は入力サイズで、**2の累乗に限定します。**
$W_N = e^{-i \frac{2π}{N}}$ とし、次のように書き換えます。
$$F(t) = \displaystyle \sum_{x=0}^{N-1}f(x) W_{N}^{tx}\qquad t=0,1,...,N-1\tag{2}$$
入力の偶数番目の要素のみでDFTを行ったものは次の式で表されます。
$$F_{even}(t) = \displaystyle \sum_{k=0}^{\frac{N}{2}-1}f(2k) W_\frac{N} {2}^{tk}\tag{3}$$
同様に、奇数番目の要素のみでDFTを行ったものは次の式で表されます。
$$F_{odd}(t) = \displaystyle \sum_{k=0}^{\frac{N}{2}-1}f(2k+1) W_\frac{N}{2}^{tk}\tag{4}$$
$(3)(4)$を用いることで、$(2)$は次のように書き換えることが出来ます。
$$F(t) = F_{even}(t) +W_N^t F_{odd}(t)\tag{5}$$
ここまでは、普通にDFTを偶奇に分けて変形しただけですね。さて、ここからがFFTの重要なポイントです。実は、$F_{even}(t)，F_{odd}(t)，W_N^t$は次のような周期性を持ちます。

$$F_{even}(t) = F_{even}(t+\frac{N}{2})\tag{6}$$
$$F_{odd}(t) = F_{odd}(t+\frac{N}{2})\tag{7}$$
$$W_N^t = -W_N^{t+\frac{N}{2}}\tag{8}$$


$(6)(7)(8)$を$(5)$に用いることで、最終的にDFTは次のように書き換えることが出来ます。

$$F(t) = F_{even}(t) +W_N^t F_{odd}(t)\qquad t=0,1,...,\frac{N}{2}-1\tag{9}$$
$$F(t+\frac{N}{2}) = F_{even}(t) - W_N^tF_{odd}(t)\qquad t=0,1,...,\frac{N}{2}-1\tag{10}$$

$F_{even}(t)$と$F_{odd}(t)$は共通なので、これらを求めると同時に$F(t)$と$F(t+\frac{N}{2})$が求まる訳ですね。これが計算量削減の仕組みです。

以上を踏まえて実装に移りましょう。
#FFTのプログラム
FFTの関数をPythonで書いてみます。
基本のアイデアはこうです。入力データを偶数要素と奇数要素に分け、$(3)(4)$のようにFFT(再帰)を行った後、$(9)(10)$を用いて0~(N/2)-1番目とN/2~N-1番目を計算します。よってFFTは再帰関数となります。

```python
def FFT(f):
    #f:サイズNの入力データ
    N = len(f)
    
    if N == 1:    #Nが1のときはそのまま入力データを返す
        return f[0]

    f_even = f[0:N:2]    #fの偶数番目の要素
    f_odd = f[1:N:2]    #fの奇数番目の要素
    F_even = FFT(f_even)    #(3)偶数番目の要素でFFT
    F_odd = FFT(f_odd)    #(4)偶数番目の要素でFFT

    W_N = np.exp(-1j * (2 * np.pi * np.arange(0, N // 2)) / N)    #tが0~N/2-1番目までのWを計算した配列

    F = np.zeros(N, dtype ='complex')    #FFTの出力
    F[0:N//2] = F_even + W_N * F_odd    #(9)を計算(t:0~N/2-1)
    F[N//2:N] = F_even - W_N * F_odd    #(10)を計算(t:N/2~N-1)

    return F
```
#動作確認
numpyのFFTと同じ出力が得られるか確認してみましょう。
次のようなパラメータで2つのsin波の合成波を作り、これを入力とします。

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

N = 64 #データ数
n = np.arange(N)
f1 = 2 #周期1
f2 = 5 #周期2
A1 = 3 #振幅1
A2 = 5 #振幅2
INPUT_f = A1 * np.sin(f1 * 2 * np.pi * (n/N)) + A2 * np.sin(f2 * 2 * np.pi * (n/N)) #2つのsin波の合成

#表示
plt.figure(figsize=(10, 5))
plt.style.use('seaborn')
plt.plot(INPUT_f)
```
![sin2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367616/4011dfb4-9eba-6efc-c1a2-9dbc58b72e1f.png)

FFTを実行します。FFTの出力は複素数のため、絶対値をかけて振幅成分を取り出し、可視化したものがこちらです。

```python
OUTPUT_F_numpy = np.fft.fft(INPUT_f)    #numpy版
OUTPUT_F_original = FFT(INPUT_f)    #自作版

plt.figure(figsize=(10, 5))

plt.subplot(1,2,1)    #振幅成分表示(numpy版)
plt.title('numpy_ver')
plt.plot(np.abs(OUTPUT_F_numpy))

plt.subplot(1,2,2)    #振幅成分表示(自作版)
plt.title('original')
plt.plot(np.abs(OUTPUT_F_original))
```

![ダウンロード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367616/877e6ed2-83b2-944e-c875-ba3cb583dc56.png)
無事同じ結果が得られました。
[AWS] Auto Scalingを理解しよう

#Auto Scalingでコスト最適化&高可用性
こんにちは．
1週間ぶりの更新です．


新しい案件を獲得したのですが，
開発環境は
AWSでした．
というか論理詰めで持って行きました．

本当にAWSが多いです．
クラウドベンダー一強と言っても過言では無い!!

やっぱりAmazonってすごいですよね．
今，サイバーマンデーっていうキャンペーンらしいんですけど，
ゲーミングチェアを買ってしまいました．
5000円OFFでゲット出来て，少しお特な気持ちになりました :)

とまあ，Amazon最強って話は置いておいて，

**Auto Scalling**
知ってます？
![autoscalliing.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/d63b924f-2917-3692-8427-4ec973df3248.jpeg)


コスト最適化をしてくれるサービスなんですが，
クライアント様にインフラコンサルなんかする時，話せると信頼度が一気に増します．

企業目線でサーバー費用を安くしてくれるエンジニアなら需要有り！！

この記事をインプットして，是非スキルの一環として持ち帰ってください


##Auto Scaling　チュートリアル
一言で言えば，
*コスト最適化*です
起動したインスタンスは複数のアベイラビリティゾーンで均等に配置される．
これならアベイラビリティゾーンの異常がおきてもへっちゃらな仕様．

EC2やECS，DynamoDBに対して行われます．

もう少し詳しくお話をすると，

需要に応じてインスタンスを自動的に増減させることが出来ます．
また，異常なインスタンスをヘルスチェックしてくれ，自動で切り離します．

もっと言うと，各サービスに対してイメージは以下の通り

EC2 -> インスタンス増減
EC2 スポットフリート -> 料金や容量の条件で中断されたインスタンスの自動置き換え
ECS -> 負荷に応じてサービス数を増減
DynamoDB -> 読み込み・書き込み容量を増減
Aurora -> リードレプリカの数を動的に増減

といった役割を持っています．

私たちがやることは，Auto scalingの中の
**起動設定**
**Auto Scaliingグループ**
これらの設定が必要になってきます

例えば，マネジメントコンソールからEC2を立ち上げると，
毎回左のダッシュボードに出てきます

さあ，具体的にみてみよう．

##起動設定
![スクリーンショット 2019-12-08 13.59.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/a6515d03-5397-bdaa-95d9-9429d728edc2.png)

どのようなインスタンスを起動しますか？
という設定ページ．
インスタンス設定とほぼ同じです．

*おさらい*
AMI ... 仮想空間を作るための核（linuxあたり選ぶのが無難）
インスタンスタイプ ... ユースケースに合わせてメモリやストレージを比較して選択
キーペア ... 安全にインスタンスにアクセス出来る鍵
SG ... ファイアウォールのルール設定(詳しくは[こちら](https://qiita.com/moyuta/items/78e50804e63d7ca70952))
IAMロール ... 管理者権限

##Auto Scalingグループ
ここでインスタンス数を維持したり，自動でスケーリングをしています．

![スクリーンショット 2019-12-08 14.17.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543591/651545e6-e671-b310-323c-9ea4cd0b715d.png)

やり方は，起動設定後にグループに名前を付け、実行するインスタンスの数を指定します．
注意点はリージョンを跨いでグループ設定出来ない事です．

##スケーリングのプラン
プランは3つあります
**手動スケーリング**...バッチ処理など高負荷な処理への対応
**動的スケーリング**...アクセス予測が出来ない時，cloud watchに基づいて対応
**スケジュールスケーリング** ... アクセス予測が可能な時，日時指定などして対応

##ELB配下のインスタンスをAuto Scalingにする
使用するELBを選択
⏬
ヘルスチェックのタイプをEC2 or ELBに設定

EC2の場合 ... ステータスがrunning以外になった時に異常とみなされる
ELBの場合 ... EC2の場合 + ELBヘルスチェックが異常な時，ひっかかる

ちなみに，Auto ScalingされたEC2を停止すると
ステータスは「**Terminate**」になります．異常と判断されない様にです．

これだけ覚えておけば完璧でしょう！！

コストパフォーマンス向上の為，是非お使いのインスタンスに設定してみてください．
ひさしぶりにcreate-react-appしたらテンプレートができなかった時の対処法

# 概要

ひさりぶりに create-react-app で React アプリの初期テンプレートを作ろうとしたら、テンプレートができなかったので、その対処法です。

# 発生条件

前にcreate-react-appをグローバルインストールしたことがある。

# 事象

create-react-appでテンプレートを作った時、package.jsonとnode_moduleぐらいしかできず、npm startができなかった。

create-react-appした時のログを見返すと、最後の方にこんなログが出ていた。

```
A template was not provided. This is likely because you're using an outdated version of create-react-app.
Please note that global installs of create-react-app are no longer supported.

```

# 解決策

公式ページ書いてある通り、(グローバルインストールした create-react-app をアンインストールして問題ない環境であれば) create-react-app を一度アンインストールする。
その後、npx create-react-app アプリ名で作成する。

```
npm uninstall -g create-react-app
npx create-react-app my-app
```

# ソース

https://create-react-app.dev/docs/getting-started/

> If you've previously installed create-react-app globally via npm install -g create-react-app, we recommend you uninstall the package using npm uninstall -g create-react-app to ensure that npx always uses the latest version.

# 参考

いつからこうなったのか不明ですが、2019/12/5にStack Overflowで質問が上がっていたので、割と最近かもしれないです。

Template not provided using create-react-app

https://stackoverflow.com/questions/59188624/template-not-provided-using-create-react-app

# 解決策の補足

なお、下記で[コメントいただいた情報](https://qiita.com/kijibato/items/ca74c6582141f3292240#comment-dc933d70f9fba01924ca)によると、アンインストールがうまくいかない場合があるようです。

その場合、MacやLinuxなどwhichコマンドがある環境であれば、ターミナル上で、

```
which create-react-app
```

と実行した時に、次のようなcreate-react-appのパスが表示されたら、

```
/usr/local/bin/create-react-app
```

それを削除するか移動させると解決する場合があるようです。(試す場合、必要に応じてバックアップなどしてください)
Docker for Mac で Docker Engine API (旧Remote API)を安全に使う

# はじめに

検索すると TCP で Docker Engine API (旧 Remote API) を利用する方法が出てきますが、平文のためポートへアクセスできれば誰でも Docker を操作できてしまいます。[^remote-api-tcp-danger]
[^remote-api-tcp-danger]: https://blog.ssrf.in/post/abusing-docker-remote-api/

(ブラウザからの攻撃は Same-Origin Policy 等でブロックされると思っていましたが、レスポンスが取得できないだけで、リクエスト自体はサーバに送信されるようです[^1])
[^1]: http://takapi86.hatenablog.com/entry/2017/09/10/212100

そのため TLS を利用する方法が望ましい[^tls-recommended]のですが、Linux 向けの dockerd 起動時に証明書を指定する方法しかなく、Mac 向けの情報は見当たりません。
[^tls-recommended]: https://docs.docker.com/engine/security/https/
この記事では Docker for Mac で TLS 通信、クライアント証明書を用いた認証を行う方法を説明します。

# 手順

## 証明書の作成[^socat-https]
[^socat-https]: http://www.dest-unreach.org/socat/doc/socat-openssltunnel.html

サーバのTLS証明書の他に、クライアントの証明書も作成します。

注意: 説明に不要な出力は省略しています。



```bash
# サーバ側の秘密鍵を作成
$ openssl genrsa -out server.key 4096

# サーバ側の公開鍵を作成
$ openssl req -new -key server.key -x509 -days 3653 -out server.crt
# Common Name は 127.0.0.1 などに設定してください
Common Name (eg, fully qualified host name) []:127.0.0.1

# サーバ側のpemを作成
$ cat server.key server.crt > server.pem

# クライアント側の秘密鍵を作成
$ openssl genrsa -out client.key 4096

# クライアント側の公開鍵を作成
$ openssl req -new -key client.key -x509 
# 何も入力しないとエラーになってしまうので、Country Name を JP に設定するなどしてください
Country Name (2 letter code) []:JP

# クライアント側のpemを作成
cat client.key client.crt > client.pem

# パーミッションの設定
chmod 600 server.key server.pem client.key client.pem
```

## プロキシの起動

Docker デーモンの Unix Socket をコンテナへマウントし、ソケットへ HTTPS 接続をプロキシします。[^socat-https][^socat-docker-socket]
[^socat-docker-socket]: https://forums.docker.com/t/remote-api-with-docker-for-mac-beta/15639/2
Macに`socat`入ってるよ、という人はそちらで実行しても大丈夫だと思います(未検証)。

```bash
docker run \
    --rm -v /var/run/docker.sock:/var/run/docker.sock \
    -v ${PWD}:/src \
    -p 0.0.0.0:2376:2376 \
    bobrik/socat \
    openssl-listen:2376,reuseaddr,cert=/src/server.pem,cafile=/src/client.crt,fork UNIX-CONNECT:/var/run/docker.sock
```
`-d` オブションなどをつけてもOKです。

# 確認

```bash
$ curl --cacert ./server.crt --key ./client.key --cert ./client.crt https://127.0.0.1:2376/containers/json
# JSON が出力されていれば成功です🎉
```
GoでGUIを作るFyne  というライブラリが楽しそうだよ、というご紹介

この記事は[Go4 Advent Calender](https://qiita.com/advent-calendar/2019/go4)の8日目の記事です。
前日の記事はこちらｰ  [7日目](https://qiita.com/nayuneko/items/dea02377b797c2a52053)
翌日の記事はこちら-  [9日目](https://qiita.com/keisukefunatsu/items/49b4145747f719807847)

# 筆者のGo歴
- 1年前までプログラミング関連の経験/知識なし
- Goは今年の5月から趣味で牛歩

# 前置き
- この記事は、Fyneというライブラリの簡易的な紹介のみ
- 極力間違いのないように調べたつもりだが、初学者なので鵜呑みには注意
- 間違いなどあればコメントや編集リクエスト頂けると泣いて喜びます

# [Fyne](https://fyne.io) とは
- GoでGUIアプリケーションを作成する際に利用できるライブラリ
- [OSS(Github)] (https://github.com/fyne-io/fyne)
- PureGo
- デザインがキレイ

## 今回は[公式のチュートリアル](https://fyne.io/develop/)を実行するまでご紹介
公式のチュートリアルは、すでに分かりやすくてシンプルです。
ただ、英語で記載されているので和訳しつつ紹介していきたいと思います。

### *ダウンロード*
「*あなたがWindows,macOS,LinuxかBSDを利用していて、既にGoのインストールが済んでいるなら、次のコマンドでFyneの全てをインストールすることができます*」

```console
$ go get fyne.io/fyne
```

「*そのコマンドが完了することで、あなたのGOPATH配下にFyneの開発パッケージの全てがインストールされます。Fyneのツールキットがどのような動作をするのか見てみたいなら、以下を実行することで私たちが用意したデモアプリをコンピュータ上で試すことができます*」

```console
$ go get fyne.io/fyne/cmd/fyne_demo
$ fyne_demo
```

「*これだけです。さあ、Fyne APIを使いあなただけのクロスプラットフォームGUIアプリケーションを作る方法を見てみましょう*」

### *初めてのFyneアプリを作りましょう*
「*シンプルなアプリを作るには、app.New()でアプリインスタンスを作成し、app.NewWindow()でウインドウを開くところからです。次に、SetContent()によりウインドウのメインコンテンツがウィジェットツリーとして定義されます。その後、ShowAndRun()を呼び出すことで、アプリのUIが表示されます*」

```go:UsingFunctions関数を使う場合
package main

import (
	"fyne.io/fyne/app"
	"fyne.io/fyne/widget"
)

func main() {
	a := app.New()

	w := a.NewWindow("Hello")
	w.SetContent(widget.NewVBox(
		widget.NewLabel("Hello Fyne!"),
		widget.NewButton("Quit", func() {
			a.Quit()
		}),
	))

	w.ShowAndRun()
}
```

```go:UsingStructs構造体を使う場合
package main

import (
	"fyne.io/fyne"
	"fyne.io/fyne/app"
	"fyne.io/fyne/widget"
)

func main() {
	a := app.New()

	w := a.NewWindow("Hello")
	w.SetContent(&widget.Box{Children: []fyne.CanvasObject{
		&widget.Label{Text: "Hello Fyne!"},
		&widget.Button{Text: "Quit", OnTapped: func() {
			a.Quit()
		}},
	}})

	w.ShowAndRun()
}
```

「*上記のコードを実行する(シンプルに行けば、go run hello.goと実行するはずです)と、次のようなウインドウが作成されます*」
![alt](https://fyne.io/develop/img/hello-normal.png)
「*明るい雰囲気にしたいのであれば、FYNE_THEME=light と設定するだけで次のようになります*」
![alt](https://fyne.io/develop/img/hello-light.png)
「*始めるには、たったこれだけです。完全なAPIドキュメントは、[GoDoc.org](https://godoc.org/fyne.io/fyne)で見ることができます*」

# ハマったこと
openGLのライブラリを利用している（？）、そのためにgccとか諸々必要になるらしい。
CentOS8で環境構築した時か、macOS Catalinaで環境構築した時か覚えてないけど、あれもないこれもないとエラーが出て困りました。
もし同じエラーでつまづいた場合は、とりあえず、エラーの中で足りないと言われているライブラリを環境のインストールコマンド(brew,yum,dnfなど)で工夫してみればなんとかなると思います。

# 後書き
正直、プライベートで色々とあって投稿が遅れました。
その上、予定では自作のGUIアプリをドヤ顔()で投稿するつもりだったのが、公式サイトマルパクリで終わっちゃいました。
ちょっとだけ触ってみた感じは、「簡単なGUIツールを作る」だけならコレ！みたいなイメージです。
悔しいので、忘れないぐらいの間には何かアウトプットを作成してまた投稿したいと思います。

# 追記(2019年12月13日)
現時点でFyneをインストールしただけでは、日本語フォントに対応してないようです。
julialoverさんが[こちら](https://qiita.com/julialover/items/39b2108c9170eb095090)の記事で説明と対応策を提示してくれています。
ありがたや......
Kotlin文法メモVer.1

# はじめに
Kolitnの文法メモです。
「reduce」実践で使ったーと同僚から聞いて、「reduceってなんだっけ？？」
ってなったので自分でも書いて覚えてみることにしました。

結論、[この記事](https://qiita.com/opengl-8080/items/36351dca891b6d9c9687#reduce ) にめちゃわかりやすく書いてあるのですが、自分でも手を動かしてみることに...

実行はAndroidStudioで試すには面倒だったので、
[KotlinのPlayGround](https://play.kotlinlang.org/) を使いました。

```kotlin
/**
 * You can edit, run, and share this code. 
 * play.kotlinlang.org 
 */

fun main() {
    val userList = arrayListOf(
        User(1, "札幌", "19990101", 170.00, 60.00),
		User(2, "函館", "19981018", 160.00, 66.00),
		User(3, "福島", "19990101", 176.02, 63.00),
		User(4, "新潟", "19990101", 155.00, 62.10),
		User(5, "府中", "19990101", 181.30, 60.40),
		User(6, "中山", "19990101", 149.00, 60.04),
		User(7, "京都", "19990101", 159.00, 67.20),
		User(8, "阪神", "19990101", 190.10, 89.50),
		User(9, "中京", "19990101", 178.20, 65.00)
    )

 	println(userList.map { it.name }.filter { it.contains("中") }.reduce { a,b -> "$a:$b" } )
    println(userList.map { Triple(it.name, it.height, it.weight) })
}

data class User(
	var id: Int,
    var name: String,
    var birthDay: String, // YYYYMMDD
    var height: Double,
    var weight: Double
)
```
    
### 実行結果

```
府中:中山:中京
[(札幌, 170.0, 60.0), (函館, 160.0, 66.0), (福島, 176.02, 63.0), (新潟, 155.0, 62.1), (府中, 181.3, 60.4), (中山, 149.0, 60.04), (京都, 159.0, 67.2), (阪神, 190.1, 89.5), (中京, 178.2, 65.0)
```

下のmapはmapでオブジェクトから特定の項目を抜き出したリストを再作成する処理を書いてみました。
(こういう処理は業務でたびたび使うけど、forループでやると地味に面倒..)

# まとめ
[公式](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/)
[Kotlin のコレクション使い方メモ](https://qiita.com/opengl-8080/items/36351dca891b6d9c9687)
[Kotlin文法 - 関数とラムダ](https://qiita.com/drafts/ff0d9c54c02b89fa8970/edit)

このあたり、読めばKotlinでどんなことをどう書けば良いかはわかるのですが、
やっぱり自分で書かないと実践で使えないので気になったものからでも使わないといけないですね..

### ついで
ふと、逆引きあればいいのになぁと思ったら、すでにありました...
[逆引きKotlin](http://kotlin-rev-solution.herokuapp.com/site/)

あと、Swiftでは同じようなのあるかと思ったら、クロージャがそうらしいですね..
参考: 
https://dev.classmethod.jp/smartphone/android/kotlin-swift-lambda/
https://qiita.com/edo_m18/items/1d93af7de75c6d415f19
ファイルを探したり、パーミッションの変更したり。。。

# ディレクトリ配下のシンボリックリンクを探す

```
$ find . -type l
```

# ディレクトリ配下のディレクトリのパーミッションを変更する

```
$ find . -type d -exec chmod 755 {} \;
```

# ディレクトリ配下のファイルのパーミッションを変更する

```
$ find . -type f -exec chmod 644 {} \;
```

# グループ変更

```
$ chgrp グループ名 ファイル名またはディレクトリ名
```

例えば、index.htmlのグループをapacheにする。

```
$ chgrp apache index.html
```
現在いるディレクトリ配下のファイルやディレクトリもまとめてapacheグループ変更する。

```
$ chgrp -R apache ./
```
「上位・下位分析」というインタビューなどの定性データをもとにユーザーの本質的なニーズを導き出す分析法 

この記事は「[株式会社エイチームフィナジーのAdvent Calendar 2019](https://qiita.com/advent-calendar/2019/ateam-finergy)」9日目の記事です。

今回はデザイン関係のお話になりますので、noteに寄稿した物をシェアさせていただきます。

↓こちらからお願いします。

[記「上位・下位分析」というインタビューなどの定性データをもとにユーザーの本質的なニーズを導き出す分析法 ](https://note.com/nyudai/n/nb3fac48ac1ae)
Twitterのトレンドを盛り上げるBotを作る

皆さんはTwitterのトレンドを盛り上げたい時ってありませんか？

そんな時に特定のタグから文章を生成して、自動ツイートするBotをPythonで作ってみましょう。


今回はTwitterから文を取ってきて文を作るところは省略します。
また、3回ほどアップデートしてますが、
一番最初のやつが簡単なのでそちらの解説をしてみようと思います。

#### 構文解析をする

まず、日本語から名詞を取り出す必要があります。今回は`janome` という構文解析ライブラリを使います。

`janome`は日本語を構文に分解してくれるツールで

```python
from janome.tokenizer import Tokenizer

tokenizer = Tokenizer()

sentence = '本日のゲストは和田さんでした。'

for token in tokenizer.tokenize(sentence):
    print(token)
    
# 本日	名詞,副詞可能,*,*,*,*,本日,ホンジツ,ホンジツ
# の	助詞,連体化,*,*,*,*,の,ノ,ノ
# ゲスト	名詞,一般,*,*,*,*,ゲスト,ゲスト,ゲスト
# は	助詞,係助詞,*,*,*,*,は,ハ,ワ
# 和田	名詞,固有名詞,人名,姓,*,*,和田,ワダ,ワダ
# さん	名詞,接尾,人名,*,*,*,さん,サン,サン
# でし	助動詞,*,*,*,特殊・デス,連用形,です,デシ,デシ
# た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
# 。	記号,句点,*,*,*,*,。,。,。
```

のように日本語を分解します。



#### 重複チェックをする

これで1ツイートを分解してもいいのですが、これだとノイズが混じる可能性があります。

なので、複数ツイートに同じ名詞が存在した場合にのみ文章を作るようにします。

> こういう人もいます。
> <img width="437" alt="スクリーンショット.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117659/5cb98818-e7ce-c509-d6f8-6e37f3bce1aa.png">

まず、重複抽出用のクラスです。

```python
class DuplicateChecker:
    
    def __init__(self, tokenier: Tokenizer):
        self.twitt_nouns = []
        self.tokenier = tokenier

    def extract_duplications(self) -> [str]:
        return [x for x in set(self.twitt_nouns) if self.twitt_nouns.count(x) > 1]

    def input_twitt(self, twitt: str):
        tokens = self.tokenier.tokenize(twitt)
        
        nouns = []
        buffer = None
        for token in tokens:
            if token.part_of_speech.count("名詞"):
                if buffer is None: 
                    buffer = ""
                buffer += token.surface
            else:
                if buffer is not None:
                    nouns.append(buffer)
                buffer = None
                    
                    
        self.twitt_nouns.extend(nouns)
```



これで、重複をチェックすると以下のようになります。



```python
tokenier = Tokenizer()
duplicateChecker = DuplicateChecker(tokenier)

duplicateChecker.input_twitt("縞模様に可能性を感じました")
duplicateChecker.input_twitt('もう可能性しか感じない')
duplicateChecker.input_twitt('可能性感じる')

nouns = duplicateChecker.extract_duplications()
nouns # ["可能性"]
```



(本番はさらにユーザーでもチェックをかけていました。)



#### 文生成

最後に抜き出した名詞から、文を作ります。（今回は適当です。）

```python
class SentenceGenerator:
    
    def __init__(self, nouns:[str]):
        self.nouns = nouns
        self.senence_base = ["{}は草", "{}大切", "{}", "{}ね", "{}だね", "{}!"]
        
    def generate(self) -> str:
        index:int = int(random.uniform(0, 200)) % len(self.senence_base)
        sentence = self.senence_base[index].format(self.nouns[0])
        return sentence
```

実行するとこんな感じになります。
<img width="480" alt="スクリーンショット 2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117659/0eaeec70-4918-133c-dce3-22e7018873d7.png">



#### まとめ

今回は無茶苦茶簡単なものを作ってみました。
もし、反響があったらどうアップデートしていったのか書こうと思います。
Groupieと生のRecyclerViewの比較

#どんな内容？
GroupieというRecyclerViewを簡単に便利に使えるライブラリを使ったので生のRecyclerViewとの比較をしました。
ソースは[こちら](https://github.com/kkt-yu/groupie_practice)。(開いたらついでにスターつけていってください)
![demo.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/476234/2fe23b65-5def-41b6-5aa7-fef9abb0f754.gif)

#環境
- Kotlin:1.3.61
- groupie:2.7.2
- アーキテクチャ:MVVM

#比較の概要
- 生のRecyclerViewで必要だったファイル
 1. Fragment
 2. ListのViewModel
 3. ListのAdapter
 4. ItemのViewHolder
 5. ItemのViewModel
- Groupieで必要だったファイル
 1. Fragment
 2. BindableItem
 3. ItemのViewModel

この時点でファイル数が減ってサイコー！
しかも、それに伴ってファイルの依存関係がシンプルになってサイコー！！

#Groupieのファイルでそれぞれ何をしているか
##Fragment
- もちろんxmlとの紐付け

```kotlin
override fun onCreateView(
    inflater: LayoutInflater, container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    binding = FragmentRecyclerViewBinding.inflate(inflater, container, false)
    return binding.root
}
```
- BindableItemとの紐付け

```kotlin
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    val adapter = GroupAdapter<GroupieViewHolder>()
    binding.recyclerView.adapter = adapter
    adapter.update(mutableListOf<Group>().apply {
        ViewList().list.forEach {
            add(GroupieItem(it))
        }
    })
}
```

##BindableItem
- Itemのxmlとの紐付け

```kotlin
override fun getLayout() = R.layout.recycler_item
```
- Itemのxmlとのbinding

```kotlin
override fun bind(viewBinding: RecyclerItemBinding, position: Int) {
    viewBinding.viewModel = ItemViewModel()
    viewBinding.viewModel?.item = item
}
```
- (必要なら)クリックリスナーの設定等のアイテム個別の処理

##ItemのViewModel
- viewにbindするためのあれやこれ(普通にViewModel)

#おわり
ファイルと依存関係減るだけで超楽！！！
とりあえず使うべき！！(サポートとか不安なら貢献しよう！)
macの困った時メモ

#特殊文字の入力方法を調べる方法
\バックスラッシュとか`呼び方わからないけどこれとか
メニューバーにある文字入力の「あ」みたいのをクリックして「キーボードビューワーを表示」すると
キーボードの画面が出てきて、shiftとかoptionを押した時の入力文字が見られる。

キーボードビューワーの表示がメニューにない場合は、
リンゴマークから「システム環境設定」を選び、「キーボード」の中にある「キーボードビューワーを表示」にチェックを入れる
ubuntuのネットワークマネージャーをraspberryシリーズで使う方法(VPN接続も可)

apt install -y network-manager
apt install -y network-manager-gnome
apt install -y network-manager-l2tp
apt install -y network-manager-l2tp-gnome
apt remove -y dhcpcd5
これでubuntuと同じ仕様でL2TPや中継機や色々やれます
【(集中すれば)３分で読める】Vimの魅力

# はじめに
AdventCarender9日目を務めます、DMM Webcampメンターの[@ayumuabe1434](https://qiita.com/ayumuabe1434)です！！

さてタイトルにもあるようにVimに関してです。
この記事は

「いろんなテキストエディタがあるけどどれがいいの？」

「Vimってよく聞くけどなにがいいの？」

と、なんのテキストエディタを使うか迷われている方対象の
**Vimに魅力を感じすぎてしまう記事**です。
といっても長いと読むのがめんどくさいので短くいきましょう！！

# メリット
## 自分だけのテキストエディタになる
vimは完璧に**自分好みのテキストエディタ**にすることができます。

デザインはもちろんのこと、プラグイン、ショートカットコマンドも
自分が動かしやすいものに変えることができます！

vimはとても育てがいのあるテキストエディタです！

例えば僕のVimなのですが、
始めはこんなVimが...
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/d47784c9-bdcb-4a25-6818-64c8e77419fe.png" width=75%>

なんということでしょう！設定ファイルをいじるだけで
こんなにもきれいになったじゃありませんか！()
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/0cde5f08-c28c-b727-3c06-d4d7d8aa3ed7.png" width=75%>

始めは素朴だったテキストエディタを自分で育てることができる快感は格別です！！!

## すべてコマンドでかたがつく
「マウスを使わない」というのはとても大きいです。

基本的にVimはターミナルで動かすので、
GitをVimだけで完結させることが可能です！

というかターミナルでやることへの移動がとても簡単！！

## どの環境でも使える
設定ファイルをGithubにあげておくと、
**他のどのパソコンでも** 自分の設定ファイルを落とし込むだけで
簡単に(5分もかからず)今まで慣れ親しんだvimを使うことができます！
場所を選ばないとは最高ですね！！

また、実は...

**他のテキストエディタのほとんどが
プラグインとしてvimのコマンドが使うことができます！！**

Atom, VScode, Sublime textはもちろん大抵のテキストエディタには
プラグインとして備わっています！

そしてなんと...

**Google検索もVimコマンドを使うことができます！**

またGoogleCromeの拡張機能でもVimのプラグインがあり、
Vimになれた人ならこれがめっちゃ便利...。

恐るべき...Vim...。
こんなに汎用性の高いVim...やらない理由が見当たらない...。


## コーディングの速度がとても早くなる
やはり自分好みの設定にすることでコーディングの速度は早くなります。
そして特に

- ドットコマンド
- オペレーター＋テキストオブジェクト

などのVim特有のコマンドによってコーディングの速度を数倍にしてくれます！

例えばドットコマンドとは何ぞやというと
**繰り返し処理を楽にしてくれるコマンド**です。

下のGIFをご覧ください。

![vim-dot-command.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/437352/b9495a84-76ce-59cc-6269-8b8a358a70d0.gif)


これはimgタグ3つまとめて画像の場所の指定を変えたい時ですね。
3回も同じ作業をするのはめんどくさい...。
そんな時は
**` . `を打つだけで少し前に行った作業を繰り返しおこなうことができます！**

...ん？これってすごいのか..？
いやめちゃめちゃ便利です！！
つまり
**ショートカットコマンドを簡単にその場で設定してその場で使える**
みたいなもんです！！(伝われ)

詳しくは参考ページに別のurl貼ってあるので見てみてください！


# デメリット
## なんせ使いこなすのが難しい
これ、これなんですよ。

Vimを使い始める人が最も挫折する原因。
唯一にして最大のデメリット。

vimは他のテキストエディタと違いすぐには使いこなせません。
使い方やコマンドなどを覚えていき、
自分の設定ファイルを育てていき、
それに慣れてから生産性がとてつもなく上がっていきます。

**なので
「今すぐにテキストエディタが欲しい！」
という人には向いていないかもしれません...。**


しかし自分のプログラミングの能力とともに成長してきた感はたまらないです。
(愛犬みたいなものですね(?))

# 最後に
いかがだったでしょうか。
勢いで書いた感は否めませんが少しでも
「Vimいいじゃん！」っておもっていただければ幸いです！
Vimの未来に幸あれ。


# 参考ページ
[どの環境でも同じパフォーマンスを発揮するdotfilesのsetting & setup](https://blog.dais0n.net/dotfiles_in_anywhere/)

[Vimのドットコマンドが便利っぽい](https://qiita.com/Kta-M/items/d8fbded37ad3140cfeb0)
[vim マクロの使い方](https://qiita.com/yuucu/items/74e3f93ea7dd06d2c1bb)

[Vimのテキストオブジェクトについてまとめた](https://qiita.com/kasei-san/items/143af11bb2559cf0e540)

[Chrome拡張機能のVimiumを使ってキーボードだけでブラウザを操作する](https://webrandum.net/vimium/)
AWS経験者がGCP Associate Cloud Engineerの資格を取ってみた

GCPの資格試験である「**Associate Cloud Engineer**」の試験に合格しました。
AWSを実務で1年半程度利用している私が、なぜGCPの資格試験を志し、何で勉強し、合格まで辿り着いたのかを纏めます。
実務ではAWSやってるけどGCP興味ある、っていう人はたくさんいると思うので、そのような方が読んでくれると嬉しいです。
# なぜGCP
GCPの資格試験を志した（それらしい）理由の説明をしようと思います。

以下に示すように、AWSに比べるとGCPのマーケットシェアはまだまだです。（AWSすごいですね）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250926/3f078db0-30aa-f752-c8dc-729b2eec4fec.png)
ただ、成長率は他を圧倒しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/250926/4fcff19f-e8f1-087d-28af-39d992534d81.png)
また、[Global Knowledgeの調査](https://www.globalknowledge.com/us-en/resources/resource-library/articles/top-paying-certifications/#1)によると、給与水準の高いITの資格トップは「**Google Certified Professional Cloud Architect**」です（あれ「AWS Certified Solutions Architect - *Professional*」は？）。GCPに対する注目度が高いことがわかると思います。

|順位|資格|平均年収|
|:-:|:-:|:-:|
|1|Google Certified Professional Cloud Architect|$139,529|
|2|PMP® - Project Management Professional|$135,798|
|3|Certified ScrumMaster®|$135,441|
|4|AWS Certified Solutions Architect - Associate|$132,840|
|5|AWS Certified Developer – Associate|$130,369|

クラウドサービスはそれぞれで強みがあるので、それらをうまく組み合わせるマルチクラウドへの流れが今後加速してくのかな、と思っています。
そんな背景があって、実務ではAWSしか利用していませんが、今後AWSを触れるだけでは、マルチクラウドへの流れについていけなくなりますし、AWS前提の思考になってしまいそうで、視野を拡げる、という意味で、GCPの勉強は必須だと考え、そのとっかかりとして資格を受験することを決意しました。（単純にAWSに飽きたっていう説もあります。）

# コンテンツ
勉強に利用したコンテンツです。
## 動画
**LinuxAcademy [約4時間]**
LinuxAcademyの「Google Cloud Certified Associate Cloud Engineer」を受講しました（私は課金していますが、無料枠があった気がします）。
1.5倍速にしてスキマ時間に聞き流していました。GCPはAWSと基本的には似たような部分が多いので、違うところにのみフォーカスしていました。
英語の勉強がてら活用していましたが、次に紹介する本だけで十分だったかな、と今では思います。
ただ、最後の模擬試験は雰囲気が実際の試験に似ているため、受験する価値あると思います（コマンドの順序を問うような細かすぎる問題もありましたが…）。

## 本
**[プログラマのためのGoogle Cloud Platform入門](https://www.shoeisha.co.jp/book/detail/9784798137148) [約3時間]**
読みながら一通りハンズオンをこなしました。
内容的には、GCPに限らずITの基礎知識から説明してくれていたりするので、復習にもなり、勉強になりました。
ハンズオンをGUIではなく、なるべくSDKを利用して進めるといいと思います。ちなみに受験までハンズオンはこれしかやってないです。

**[Google Cloud Platform　エンタープライズ設計ガイド](https://www.nikkeibp.co.jp/atclpubmkt/book/18/265910/) [約3時間]**
一通り読みました。
GCPの各サービスの概念や制限が分かりやすく説明されており、勉強になりました。
最後の方には、実際のユースケースと設計例が示されています。

## チートシート
**[1 行でわかる Google Cloud Platform](https://cloud.google.com/blog/ja/products/gcp/google-cloud-platform-paperprint)**
AWSと比較するとGCPのサービスはシンプルですが、とはいえ数はそこそこあります。
一覧としてサービスが纏まっているので、どのサービスをまだあまり理解できていないのかを確認するために利用したりしていました。

**[gcloud cheat sheet](http://www.openkb.info/2019/01/gcloud-cheat-sheet.html)**
LinuxAcademyの模擬試験を受験したときに、正しいコマンドを問われたりしたため、受験前日に急いで上記チートシートでコマンドを確認しました。実際の試験ではそこまで細かいコマンドは聞かれませんが、少なくともサービスごとの略称？（compute、app、...）は覚えておいた方がよいと思います。

# 試験
実際の試験の感想を述べようと思います。
出題範囲としては、[公式の認定試験ガイド](https://cloud.google.com/certification/guides/cloud-engineer/)にかなり近いです。
サービス単位でみると、

- IAM
- GCE
- GKE
- GAE
- Cloud Storage
- BigQuery

が多かった印象です。
割と細かいことも聞かれたりして、選択肢なしだと答えられないような問題も多かったですが、幸いなことに選択式です。
そもそも要件を満たしていない選択肢は省けますし、残った選択肢の中でも、さすがにそんなに面倒なことはさせないだろう、
という観点で見れば、結構な問題はGCPの知識がなくても解けてしまう気がします。
今回正直そのようなテクニックで解いてしまった部分もありますが、GCPを勉強するいいとっかかりにはなりましたし、結果的に合格することもできました。
今後もGCPの勉強を継続していきたいと思います。
YAMAHAルーターでIPv6 over IPv4サービスを使う

YAMAHAルーターでIPv6 over IPv4サービスを使う方法について。本稿では、IPv6 over IPv4サービスとしてHurricane Electric Free IPv6 Tunnel Brokerを利用する。

# 対象
ISPがIPv6サービスを提供していない環境向け。

ただ、Hurricane Electricのレイテンシーは大きいため(当方の環境だとTokyoのtunnelを使用してもwww.kame.netとのpingで300ms～)利用シーンは限定的かも。

# 前提
- staticなグローバルIPアドレスを持っていること。tunnelの設定に必須。

# ユーザー登録とトンネル設定

## ユーザー登録
Hurricane Electric Free IPv6 Tunnel Brokerは https://tunnelbroker.net/ から登録できる。Registerからどうぞ。

![ss01_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538068/f1b1259c-9337-9564-b19f-7bcf9e9a0bae.png)

## tunnelの作成
ユーザー登録後、ログインしCreate Regular Tunnelから。

![ss02_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538068/4364756f-110f-d0e3-be65-3b302c7a0402.png)

赤枠箇所にコチラ側のグローバルIPアドレスを指定する。

![ss03_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538068/2cffc611-ae67-2ba8-6f52-737e91d23edd.png)

最寄りのtunnelサーバーを指定する。そしてCreate Tunnelを押下。

![ss04_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538068/7980ebcf-aab6-2f23-2b3d-173129b43119.png)

# YAMAHAルーターの設定
## トンネル設定項目の確認
使用する値は下図の(1)(4)(5)。(5)の代わりに(6)を使う、あるいは(5)および(6)の併用も可能。(2)はpingの疎通にでも使って。

![ss06_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538068/73b8fc91-0f73-97ec-10b8-bf681a573ef2.png)

## ルーターのconfig
(1)(4)(5)をそれぞれ以下と仮定し

(1) 74.82.46.6
(4) 2001:470:**23**:beaf::2/64
(5) 2001:470:**24**:beaf::/64

```
# ゲートウェイの設定
ip route default gateway IPv4のゲートウェイのアドレス
ipv6 route default gateway tunnel 1
# LANインターフェイスの設定
ipv6 prefix 1 2001:470:24:beaf::/64
ip lan1 address 192.168.0.1/24
ipv6 lan1 address 2001:470:24:beaf::1/64
ipv6 lan1 prefix 2001:470:24:beaf::/64
ipv6 lan1 rtadv send 1
# WANインターフェイスの設定
ip lan2 address グローバルIPアドレス
ip lan2 nat descriptor 1
# VPNの設定
tunnel select 1
 description tunnel "IPv6 Tunnel Broker"
 tunnel encapsulation ipip
 tunnel endpoint address 192.168.0.1 74.82.46.6
 ipv6 tunnel address 2001:470:23:beaf::2/64
 ipv6 tunnel tcp mss limit auto
 tunnel enable 1
# NATの設定
nat descriptor type 1 masquerade
nat descriptor address outer 1 primary
nat descriptor address inner 1 auto
# DHCPの設定
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.0.2-192.168.0.254/24
# DNSの設定
dns service recursive
dns server プライマリDNSサーバー セカンダリDNSサーバー
dns notice order dhcp me
```

## 疎通確認

```
ping6 www.kame.net
```

クライアントサイドは https://ipv6-test.com/ でどうぞ。

## 解説

configのうち、このようにコチラ側のエンドポイントアドレスがローカルアドレスなのは、

```
 tunnel endpoint address 192.168.0.1 74.82.46.6
```

YAMAHAのページの説明に従ったもの。

> IPIPとNATを併用する場合、ローカルエンドポイントアドレスに「アドレス変換後のルーター自身のアドレス」を指定してください。

## 注意事項
(6)の/48プレフィックスでRAする場合は/64に分割しないといけない。アドバタイズはされるけどクライアント側が応じた動きをしない。

2001:470:cafe::/48が提供されるなら以下の要領でどうぞ。

```
ipv6 prefix 100 2001:470:cafe:100::/64
ipv6 prefix 200 2001:470:cafe:200::/64
ipv6 lan1 prefix 200 2001:470:cafe::/48
ipv6 lan1 rtadv send 100 200
```

# 参考
- https://network.yamaha.com/setting/router_firewall/ipv6/ipv4_mediated
- http://www.rtpro.yamaha.co.jp/RT/docs/ipip/index.html#setting4
- [IPv6 Tunnel Brokerを使ってIPv6ネイティブな環境を構築する](https://qiita.com/kazuhidet/items/b295d4932f478c488646)

qiitaで類似記事があることを確認せずに投稿してしまった..。恥ずかしい。
VuexですべてのStateを初期化する

# はじめに

ログアウトをしてもStateに値が残っているため、別のユーザでログインした際に前回の情報を参照できてしまうという問題の対策です。

```
"vuex": "3.1.1"
```

# やりかた

各モジュールにStateを初期化するAction、Mutationを作成しておくのが定番らしいのですが、面倒なので以下の関数を定義しておきます。

``` typescript
const RESET_STATE = 'RESET_STATE'

function createResetHandler(module: any, name: string) {
  const childModules = module.modules
  if (childModules) {
    for (const key of Object.keys(childModules)) {
      createResetHandler(childModules[key], `${name}/${key}`)
    }
  }

  // stateがないmoduleは初期化の必要がないので無視
  if (!module.state) {
    return
  }

  // NB: stateは関数で定義しておく
  if (typeof module.state !== 'function') {
    console.error(`Vuex module state of '${name}' is not a function`)
  }

  module.mutations = module.mutations || {}
  module.actions = module.actions || {}

  const mutation = (state: any) => {
    Object.assign(state, module.state())
  }
  module.mutations[RESET_STATE] = mutation

  // グローバルにアクションを定義する
  const action = {
    root: true,
    async handler(context: { commit: Function }) {
      context.commit(RESET_STATE)
    },
  }
  module.actions[RESET_STATE] = action
}

```

これをStoreを作成する前に実行しておく

``` typescript
const modules = {
  module1,
  module2,
  ...
}

for (const key of Object.keys(modules)) {
  createResetHandler(modules[key], key)
}
new Store<State>({ state, mutations, actions, modules })
```

## リセットするとき

``` typescript
logout({ dispatch }) {
  // --- ログアウト処理 ---
  dispatch(RESET_STATE, undefined, { root: true })
}
```

## 解説
**state**を関数にしておくことで`module.state()`を実行すると初期値が返されます。

`_actions = { RESET_STATE: [ function, function, function ... ] }`というようにStoreにアクションが登録されているので、`dispacth(RESET_STATE, undefined, { root: true })`ですべてのアクションが呼び出されます。

# まとめ

`RESET_STATE`に引数を渡せるようにして、特定のモジュールのみ初期化するということもできます。
けっこう重い処理なので使い所は要注意です。


# 参考
https://github.com/vuejs/vuex/issues/1118#issuecomment-439471054
macのショートカットキーについて

<h2>目的：テキスト入力を時短したい</h2>
<h3>問題</h3>
<p>テキスト入力の時に、カーソル移動を使うと、ホームポジションから手が離れて、すげーめんどくさい。</p>
<h3>解決策</h3>
<p>ショートカットキーあるんじゃね？</p>
<h3>具体例</h3>
<p>cotrol + f カーソル前進</p>
<p>cotrol + b カーソルバック</p>
<p>control + p カーソル上へ</p>
<p>control + n カーソル下へ</p>
<p>control + h delete</p>
<p>cotrol + d 右側の文字削除するやつ</p>
<p>cotrol + a 行頭へ</p>
<p>cotrol + e 行末へ</p>
<p>control + k 右側を行末まで削除</p>
<p>control + k カット</p>
<p>control + y ペースト</p>