OmniAICreator/Qiita-1.07M huggingface dataset:
Prototype 継承と ES2015+ の Class がどう違うのか分からなかったので調べた

最近、 JavaScript Modules 形式で提供されていない Prototype 継承された Class を継承した上で JavaScript Modules として使いたいなぁと思い、
これまで Prototype 継承なんか一切触れてこなかったので色々調べた結果をメモ程度ですがまとめます。

「Prototype 継承って何？」とか「Class の使い方」とかの話は出ません。

---

難しい話は何もないのですが（むしろ難しい話が class 構文により省かれたのですが）、
ES2015+ の Class は Prototype 継承の糖衣構文だそうなので、特に何も意識せず Class 構文で継承することが出来ました。

以下では createjs の Shape を継承しています。
継承元 Class で元々の関数の挙動が上書きされている場合はいじってあげる必要があったりするのかも。

```js
const Shape = window.createjs.Shape

class MyShape extends Shape {
  toString(){
    return `[object ${this.constructor.name}]`
  }
}

const myShape = new MyShape()
myShape.toString() // => "[object MyShape]"
```

`ES2015+ の Class 式 == Prototype 継承` と理解しておけば良さそう。という雑感です。

---

調べる際参考にさせて頂いた記事:

- [class \- JavaScript \| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/class)
- [\[JavaScript\] そんな継承はイヤだ \- クラス定義 \- オブジェクト作成 \- Qiita](https://qiita.com/LightSpeedC/items/d307d809ecf2710bd957)
- [Class構文について \- JS\.next](http://js-next.hatenablog.com/entry/2014/11/01/034607)
[読書メモ] プロダクションレディマイクロサービス

# 目的
どのようにすれば本番運用に対応した（プロダクションレディ）マイクロサービビスを作れるか？UberのSREとして働いているSusan J.Fowlerからそのエッセンスを学ぶ。
Q1. まず、そもそもマイクロサービスって何でしたっけ？
Q2. 本番運用に対応したマイクロサービスを構築するのに必要なことは？
Q3. 


# キーワード
モノリス、マイクロサービス、マイクロサービスが従うべき標準、マイクロサービスエコシステム、コンウェイの法則


# マイクロサービスとは
- 多くの有名企業がモノリシックなアプリケーションの構築を止め、マイクロサービスアーキテクチャを採用してきた
- 今日のアプリケーションは論理的には、3つの要素に分解できる ー ***フロントエンド（クライアントサイド）、バックエンド、データストア***
- アプリケーションはいくつかの機能から構成される。これらの機能を一つのコードとして構築するのが***モノリス***。そうではなくて、機能毎に独立したコンポーネント（マイクロサービス）として構築し、それらを組み合わせることにより、アプリケーションを実現するのが***マイクロサービスアーキテクチャ***
- マイクロサービスは、1つのことだけを非常によくこなす小さなアプリケーション
- 個々のマイクロサービスに、自律性、独立性、自己完結性を与える
- 通常マイクロサービスアーキテクチャを採用する企業は、1つのアプリケーションを作り上げたあと、スケーラビリティの限界にぶつかり、組織的な課題に直面してからそうする
- モノリスの分割の手順、
    - コンポーネント化してマイクロサービスを切り出す
    - 個々のマイクロサービスに担当チームを設ける
    - インフラストラクチャチームの編成
- 一連のマイクロサービスが全体としてうまく機能するために、インフラストラクチャと、各マイクロサービスが備えるべき標準が必要
- マイクロサービスはインターフェースと実装を分離することにより、実装の自由度を得ることができる（プログラミング言語、ミドルウェア、データストア）
- マイクロサービスエコシステム（マイクロサービスが適切に動作するために必要な環境）
![ms4.png](https://qiita-image-store.s3.amazonaws.com/0/49827/30053284-f9d2-9486-f31a-0d7d5b946c06.png)
https://www.susanjfowler.com/blog/2016/12/18/the-four-layers-of-microservice-architecture

    - レイヤ1 : ハードウェア
    - レイヤ2 : 通信
        - 通信プロトコル（RPC, REST) 
        - サービスディスカバリ、サービスレジストリ、負荷分散
    - レイヤ3 : アプリケーションプラットフォーム
        - マイクロサービスに依存しないすべての内部ツール、サービスを含んでいる
        - 開発プロセス、デプロイソリューション、ロギング監視
    - レイヤ4 : マイクロサービス
- マイクロサービスはもっとも単純なものでもかなり複雑なシステムになる （***基盤が重要である***）

# 本番対応するとは
- マイクロサービスアーキテクチャを採用すると、開発者にはかなりの自由が与えられるが、全体の可用性を確保するためには、個々のマイクロサービスが、アーキテクチャ、運用、組織をめぐる高い標準を満たす必要がある
- 標準化の目標は可用性
- 本番対応できるアプリケーションやサービスとは、本番トラフィックを任せられる信頼のあるアプリケーション、サービス
- 8つの原則 ー 安定性、信頼性、スケーラビリティ、対障害性、大惨事対応、パフォーマンス、監視、ドキュメント

# 本番対応の8つの標準
## 安定性
- 安定性の要件
    - 安定した開発サイクル
    - 安定したデプロイプロセス
    - 安定した導入、非推奨手続き
## 信頼性
- 信頼性の要件
    - 確実なデプロイプロセス
    - 依存関係の障害に対処するための計画、影響の緩和と障害からの保護
    - 確実なルーティングと健全性チェック
## スケーラビリティ
- スケーラビリティは、並行性とパーティション分割を必要とするが、この2つをモノリスで実現するのは難しい
- スケーラビリティの要件
    - 質的、量的な成長の判断基準
    - リソースのボトルネックと要件の明確化
    - バーストトラフィックの対応
    - 依存関係のスケーリング
    - データストアのスケーリング
-

## パフォーマンス
- マイクロサービスがどれくらい効率よくリクエストを処理するか
- コストが高いネットワーク呼び出しを大量に行うマイクロサービスは、パフォーマンスが高いとは言えない
## 対障害性
- 単一障害点を明確にして解決する
- 障害の検出、修正戦略を用意する
- 
## 大惨事対応
## 監視
## ドキュメント
RabbitMQをPython3から利用する。

# RabbitMQのインストール
```bash:インスト―ル
yum install rabbitmq-server.noarch
```

# RabbitMQの起動
```bash:インスト―ル
systemctl start rabbitmq-server
```

# プログラム実行環境インストール
```bash:インストール
yum install epel-release
yum install python34 python34-pip
pip3 install pika
```

# プログラムを配置
```python3:send.py
#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='hello')

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()
```

```python3:recive.py
#!/usr/bin/env python
import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()

channel.queue_declare(queue='hello')

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)

channel.basic_consume(callback,
                      queue='hello',
                      auto_ack=True)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
```

# プログラム実行
※receive.py用のターミナルを起動して実行

```console:receive.py実行
python34 receive.py
```

※send.py用のターミナルを起動して実行。

```console:send.py実行
python34 send.py
```

# 実行結果
こんな感じになる。
①receive.py起動（キュー監視開始）

```console:キュー監視開始
[root@devenv rabbitmq]# python34 receive.py
 [*] Waiting for messages. To exit press CTRL+C
```

②send.py起動（キュープッシュ）※何回か実行するといいかも。

```console:キュープッシュ
[root@devenv rabbitmq]# python34 send.py
 [x] Sent 'Hello World!'
```

③キュー監視側はこうなる。

```console:キュー監視側はキューがあると、自動で拾ってコンソールに表示する。
[root@devenv rabbitmq]# python receive.py
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received b'Hello World!'
 [x] Received b'Hello World!'
 [x] Received b'Hello World!'
 [x] Received b'Hello World!'
 ```
UbuntuでSambaの接続ができなくて焦った件（ufwとeno1)

# Sambaにアクセスできない

自宅でubuntu 15.10で立てていたSambaのサーバに突然アクセスできなかった・・
自分の忘備録として原因と対処をメモ

# そもそもSSHもできない(ufw設定ミス)

Sambaにアクセスできない原因を探ろうとsshでのアクセスを試みると、そもそもsshもできない。
ただ、pingは通るので、NWは生きているっぽい。いろいろ調べたところ、数日前に導入したufwの設定が漏れて要るっぽい

# ufwとは
Uncomplicated FireWallでファイヤーウォール設定ツール。設定の実態はおなじみiptablesだけども、コマンドがより分かりやすくなっている。
どうも、ufwを有効にしたと同時に、iptablesの設定が変わってしまったよう。

なので、ufwからsshとSambaを有効にしてあげる。

```
$ sudo ufw allow ssh
$ sudo ufw allow samba
$ sudo ufw app list
利用可能なアプリケーション:
  OpenSSH
  Samba

```

ポート番号など意識しなくても、アプリケーション名でコマンド一発設定で楽ちん。
あと、この操作だけで設定反映されて再起動後も設定が有効となる。

ちなみに、上記でどんな設定が反映されるかは以下のファイルに定義されている

```
$ cat /etc/ufw/applications.d/openssh-server
[OpenSSH]
title=Secure shell server, an rshd replacement
description=OpenSSH is a free implementation of the Secure Shell protocol.
ports=22/tcp
```

```
$ cat /etc/ufw/applications.d/samba
[Samba]
title=LanManager-like file and printer server for Unix
description=The Samba software suite is a collection of programs that implements the SMB/CIFS protocol for unix systems, allowing you to serve files and printers to Windows, NT, OS/2 and DOS clients. This protocol is sometimes also referred to as the LanManager or NetBIOS protocol.
ports=137,138/udp|139,445/tcp
tamura-y@tamubuntu:~$
```

これで通るはずが・・・

# SSHはできたけど・・・(interface名)

上記でsshは通るようになった。あと、NetBiosでの名前引きもできた。でも、肝心のSamabへのアクセスができない。
で、ここまでくると、Samabの設定ぐらいしか疑いようがない。で、設定を見てみるとこんな設定が。

```
# The specific set of interfaces / networks to bind to
# This can be either the interface name or an IP address/netmask;
# interface names are normally preferred
interfaces = 127.0.0.0/8 192.168.1.0/24 eth0
```

あれ、interface名って、eth0だっけ、と確認してみると

```
$ ifconfig
eno1      Link encap:イーサネット  ハードウェアアドレス xx:xx:xx:xx:xx:xx
          inetアドレス:192.168.1.xxx  ブロードキャスト:192.168.1.255  マスク:255.255.255.0
```

ちがうじゃん。
どうも、アップデートで変わったみたいです・・・はい。
[Network interface name changes after update to 15.10 - udev changes](https://askubuntu.com/questions/689070/network-interface-name-changes-after-update-to-15-10-udev-changes)

なので、smb.cnfのインターフェース名を変更。

```
# The specific set of interfaces / networks to bind to
# This can be either the interface name or an IP address/netmask;
# interface names are normally preferred
interfaces = 127.0.0.0/8 192.168.1.0/24 eno1
```

でめでたく復活！
AWS CLIのセットアップ(Windows)

AWS CLIが使えるようになるまでのステップのメモ

# AWS-CLIのダウンロード(Windows 64bit)

まずCLIを以下からダウンロードしてインストールする
https://s3.amazonaws.com/aws-cli/AWSCLI64.msi

# AWSコンソールでIAM userを作る
IAMに行く
https://console.aws.amazon.com/iam/home

[ユーザーを追加]をクリック
![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/3b88038e-f16f-9dd3-5714-6a89d65b7ce1.png)

ユーザー追加画面で、ユーザー名や、アクセスの種類、パスワードなどに関する設定をする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/396e4970-5b6d-c172-773b-0fb199a68b6a.png)

[次]をクリックすると、アクセス権設定画面となる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/79727263-62b2-0a7d-ffa1-6b80ad47d59d.png)

グループがまだなければ、[グループの作成]をクリックする

グループの作成名前と権限をつける。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/bbd4984b-4a6e-0a7e-059b-8b6dd1c82bba.png)

[次のステップ：確認]をクリックする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/4e813402-4206-de01-8752-c3b4ed57e63e.png)

[ユーザーの作成]をクリック

![image.png](https://qiita-image-store.s3.amazonaws.com/0/170905/98aa44eb-c73a-65ad-9b57-490b3bc78d0b.png)

これでユーザーが完成。

# CLIをセットアップする（IAMユーザーをひもづける）

```
aws configure
```

すると、以下のように対話式にAcesss KeyやSecret Access Keyを聞いてくるので、先ほど作ったユーザーのものを入力していく。

region nameは、東京リージョンなら ap-northeast-1 を指定する

```
AWS Access Key ID [****************GWGA]: AKIAIAXOUEXYY47GIWAQ
AWS Secret Access Key [****************Teuw]: XBSDASD645487DFBKDLSKJFIE8ERI6EREW
Default region name [None]: ap-northeast-1
Default output format [None]:json
```

(値はもちろんダミー)


これで CLIを利用可能となった。
hyperappのwebpack用テンプレート

こんにちは、鈴木です。[Hyperapp](https://github.com/hyperapp/hyperapp)でウェブアプリケーションを作るためのテンプレートのようなものを作ったので、それの話です。
https://github.com/sosukesuzuki/hyperapp-boilerplate にて公開しています。動くものは[コレ](https://sosukesuzuki.github.io/hyperapp-boilerplate)。

## 使ったもの
* hyperapp
* webpack
* eslint
* stylus
* pug
* babel
* CSSModules
* JSX

おおまかにはこんな感じです。自分の好きなものをぶち込みました。html-webpack-pluginでpugをindex.htmlにしていて、stylus-loaderとstyle-loaderとcss-loaderでStylusでCSSModulesしています。[vamboo](https://vamboo.net)とスタイル周りは同じ感じです。


## 使い方
GH-Pagesでデプロイしてる関係で、masterブランチにはindex.htmlとbundle.jsをおいていて、ソースコードはsrcブランチにおいているので、それだけ考慮してもらえれれば大丈夫かなと思います。

```
git clone git@github.com:sosukesuzuki/hyperapp-boilerplate.git

cd hyperapp-boilerplate

git co src

rm -r .git

yarn

yarn run start
```
これでwebpack-dev-serverがlocalhost:8080で起動します。

## 使ってね
srcブランチにソースコードがあるんで、見てね。ハッカソンにでも出たら自分で使ってみようかなぁと思っています。個人的にhyperappの用途として、プロダクションで使うことは考えていなくて、ハッカソンや、一人で遊ぶ時にぱぱっとものを作れることしか考えていないので、その要件を満たす感じにしかしていないです。今後、routerとかの設定はしてもいいかもしれないですね。
先頭に$があってもコピペ実行できるようにする。

コピペ厨になるとインストールとかで気持ちよく一発でコピペして実行とかしたい。

でも、解説でよくあるのがこれ。先頭に$が着いているため、エラーで止まってしまう。
複数行だと行ごとにコピーを繰り返すことに。

```bash
$ cd /tmp
$ wget --no-check-certificate https://github.com/kohkimakimoto/execmysql/tarball/master -O - | tar xzv
cd /tmp
-bash: $: command not found

```

そりゃテキストに貼り付けて、$を消せばいいんだけどね。少々めんどう。(vim なら ggCtrl+vGd　手がつりそう)

そこで、\$があってもコマンドが継続されるように\$コマンドを作ってしまう。

```bash
echo -e '#!/bin/bash\n\neval "$@"' | sudo tee /usr/bin/$ && sudo chmod +x /usr/bin/$
```

ただし、以下の#の場合は駄目。どうみてもコメント。＃書き換えもうまく行かなかったし、コメントアウトとの区別がつかないのは危険なかんじ？

```
# yum install git
```

$から始まる文字はbashで予約されているので、
今のところ邪魔してないようですが、自己責任でどうぞ。よいコピペライフを。
[読書メモ]Pattern-Oriented Software Architecture Volume 4 - Layers(Pg. 185)

# Introduction
プログラムをレイヤーに分ける意味は以下の二つがある。
1. プログラム全体の理解を助ける
2. レイヤーごとの開発を可能にして、開発効率を上げる

## 1. プログラム全体の理解を助ける
_（これは書いてあったことじゃないです。）_

例えば、美容院（レイヤーに分けている例）と床屋（レイヤーに分けていない例）で対比します。
自分が小学生の時に行っていた床屋では、散髪するそれぞれの椅子の前に髪を洗い流す台がありました。
自分が今行っている美容院では、散髪する椅子と髪を洗い流す台が別々のスペースにあります。

ちょっと無理やり感ありますが、床屋の場合だとお店に入った瞬間には何をおこなのかわかりづらいですね。
椅子の目の前に洗面台があります。洗面台があるので、そこで髪を洗うのだろうということはわかります。
しかし、以下のような憶測を可能にしてしまいます。
 ```
1. 切った髪が床に散らばると片付けるのが面倒だから、洗面台に頭を向けて切るのか？
 2. 髪切る時に手に髪がついちゃうと施術がしづらくなるので、施術者が髪を手から洗い落とすために使うのか？
 ```

その反面、美容院は散髪スペースには余計なものがないので変な憶測をうむ余地がありません。

## 2. レイヤーごとの開発を可能にして、開発効率を上げる
先ほどの美容院と床屋の対比を使いまわします。

例えば洗面台を最新のものにしたいとします。
床屋（レイヤーに分けていない例）では、散髪スペースと洗面台の場所が分かれていません。そのため、洗面台を改修するとなると散髪スペースも工事に巻き込まれてしまいます。お店を休む必要がありますね。

しかし、美容院（レイヤーに分けている例）の場合はどうでしょうか。
散髪スペースと洗面台が分かれているので、洗面台を改修しても散髪を行うことは可能です。
レイヤーを分けると、お店の一部の改修と営業を同時に行うことができるというわけです。

# How?
さて、レイヤーを分ける時に注意しないといけないことがあります。
レイヤーはむやみに分けても意味がありません。

多すぎると開発効率を下げるばかりか、（レイヤー間で位置が異なる場合）パフォーマンスの悪化を引き起こすこともあります。（ネットワーク通信が増えてしまうため）
少なすぎると並行して開発を行うことができなくなるので、レイヤーに分ける本質的な目的を達成できません。

## レイヤーを分ける指標
通常は以下の指標をいくつか複合してレイヤーを分ける
1. ハードウェア間の物理的な距離
    => RemoteとLocalを分ける
2. 変更頻度
    => viewはpersistenceに比べて頻繁に変更されるため分ける
3. Abstraction dimension（抽象化した時の対象で分ける？）
    => View/Application Logic/ Persistenceで分ける。表現とロジックとデータで分けている様子
4. Granularity dimension（粒度で分ける？）
    => Business object / Business process で分ける。ドメインのデータとその処理で分ける。
現在開発中のAndroidで言えばdomain/modelとdomain/interactorで分ける？
    - model：データの値自体を表現する。（例えばAgeオブジェクトは18才以下か否かを表現する）
    - interactor：データのビジネス的な意味を解釈する。（例えば18才以下か否かがサービス的に意味するところ、つまりアプリの機能をある程度制限しなければならないことを解釈する。）

## レイヤー間の取り決め
レイヤー間はinterfaceを用いてやりとりを行う。 :bookmark: __（Explicit interface）__
レイヤー内でinterfaceの実装を完結する。 :bookmark: __（Encapsulated implementation）__
:bookmark: __Bridge__ or :bookmark: __Object Adapter__ を用いて、インターフェースと実装をつなぐ。

低レイヤー（DBアクセスなど）は高レイヤー（ビューなど）の機能に頼ってはいけない。
参照が許されるのは、高レイヤーから低レイヤーの方向のみ。

例えば以下の二つのレイヤーしかない場合を想定します。
1. ビューレイヤー
2. DBレイヤー


この場合ビューからDBレイヤーにアクセスするためには、DBレイヤーのinterfaceに対して問い合わせを行います。
DBレイヤーからビューにリクエストの応答を返すときは、リスナー等を用いてリスポンスを返します。 :bookmark: __（Observer, Commands, Messages）__
高レイヤーへの参照が許されていないため、ビューレイヤーのinterfaceに問い合わせを行うことは許されていないためです。

この制限がある理由としては以下の２点です。
- 構造が複雑に絡み合ってしまうため
- 低レイヤーの移植を可能にするため

# What's next? 
Explicit Interfaceについて！

※ :bookmark: は関連のあるパターンを示しています。
[読書メモ]Pattern-Oriented Software Architecture Volume 4

# What? なんの本なのか？
４部作ある最後のシリーズ。
分散システムを題材にして、アーキテクチャパターンを説明している。
アーキテクチャパターンはそれぞれで独立したものではなく、相互に関連したものであることを説明している。
その上で関連度の高いパターンをまとめて紹介している。

# Why? なぜこの本を読むのか？
目的：より綺麗なコードを書けるようになるため。

前回までのリファクタリングでコードの木の整形方法を勉強した。
ただし、一本一本の木を整形するだけでは必ずしも（プロジェクト全体で見たときに）綺麗なコードにはならない。
なぜなら森全体を意識しないと個別最適の結果、全体で見たときに辻褄が合わない可能性があるためである。

そのため、アーキテクチャを勉強することで森全体の整形？整備の仕方を勉強することにする。

## 知ってるとできるは違う。できると理解してるも違う。
そもそもアーキテクチャはプログラム構造についての抽象化したパターンであり、コードリーディング時の大いなる補助になります。
そのため新しいコンテクストへの順応がよりスムーズになります。

自分に話を引きつけてみると、クリーンアーキテクチャについては仕事（現在開発中のAndroid開発）では使える程度になったと思います。
ただ、使えるだけじゃダメです。
よく「知っていることと、できることは違う」と言いますが、「できることと、理解している」ことも違います。

プログラミングをしていると、なんかよくわからないけど、できてることってたくさんあります。
クリーンアーキテクチャに関しても、なんとなく現在開発中のコンテクストだったらどう書けばいいのかわかります。
しかしそれは現在開発中のプロダクト内でできているだけで、理論の本質を理解していません。
そのため新しいコンテクストになればアーキテクチャに基づいた開発などできません。それどころか、今の状態だと新しいコンテクストへの順応もそれほどスムーズにいくとは思えません。

なぜそうするのかということを理解するのはとても大事なことで、そこの根本的な理解があればこそ環境の変化に柔軟に対応できます。さらに、既知の知識をもとにした新しいアイデアの創出も可能になります。

なので、今回この本を読んでなぜそのアーキテクチャにするのかということを理解し、さらなる開発力の向上に役立てようと思っています。
gitignore備忘録

#git管理下のファイルを無視する

gitで複数人管理を行う時、ローカル環境が異なるために、管理ファイルをあえて無視したい。
例えば、sqlのユーザー名やパスが違う。（ほんとは直打ちやばい？）
そんな時は以下のコマンドを使う。


方法

```
git update-index --assume-unchanged [ファイル名]
```
この設定を取り消すには次のようにします。

```
git update-index --no-assume-unchanged [ファイル名]
```
携帯電話ネットワークの仕組み(1) 

# はじめに
仕事などで所謂モバイルに携わっている人は多々いるとは思いますが、モバイルが繋がっているその先を理解できている人は多くはないのでしょうか。
私もその一人であり、実務上支障はないものも昨今5Gなどで界隈が盛り上がる前にせめて4Gまでの最低限の知識を持っておくために、『携帯電話はなぜつながるのか　第2版』を読んだ備忘を以下に残しておきます。

# 携帯電話の通信の流れ(概要)
それぞれのノードの詳細な役割は一旦置いておいて携帯電話は以下のように通信が行われています。
それぞれの簡単な役割も合わせて記載しておきます(詳細はいつか記載するときがくるはずです…)。
<img src="https://qiita-image-store.s3.amazonaws.com/0/47227/181bcef1-bcab-0581-55f7-a73eadfdf133.jpeg" width=50%>

### 基地局
皆さんご存じの街中にいっぱいあるアンテナの事です(移動基地局等もあり)。1つの基地局のカバー範囲をセルと呼びますが、
基地局の乱立であったりで干渉が起こるのはこのセル間の干渉ですね。基地局はノードビル以降の中核的なネットワークであるコアネットワークと繋がっていきます。
### ノードビル(小・大)
携帯電話ネットワークの中核をなすコアネットワークです。ノードビルの規模により構成は異なりますが、以下のような機器・機能を持っています。
- 単純に通信のみならず携帯端末が基地局間を移動しても通信を維持するハンドオーバー等を処理する無線ネットワーク制御装置(RNC:Radio Network Controller)。
- 発側の携帯電話から送られてきた着側の電話番号より、その人がどこにいるのかを探すなどの機能を司る加入者(パケット)交換機。
- 加入者交換機が通話相手がどこにいるのかを問い合わせるデータベースのようなホームメモリ。

# 通話がどのように実現されているのか
皆さんが通話ボタンを押したとき(発呼したとき)、携帯電話と基地局・ノードビルの間では以下のようなやりとりが行われています。
1. 端末Aが発呼する事により、基地局に制御情報が送られる(通話元・通話先情報など。合わせて契約者認証も行われる)。
2. 無線基地局が情報を受け取り、通話先と接続するためにさらに加入者交換機に渡す。
3. 加入者交換機が通話相手(端末B)の加入者交換機・所属エリア(位置登録エリア)をホームメモリ(ユーザ情報データベースにようなもの)に問い合わせる。
4. 3で見つけた相手のエリアの加入者交換機にAの発呼情報を送る。
5. Bの加入者交換機が基地局を経由してBを呼び出す。
6. 通話が確立する。

# ホームメモリについて
ホームメモリは固定回線のようなどこにいるのかが常に分かっている回線にはない携帯電話ネットワークのための処理装置です。
それでは常に移動し続ける携帯電話を捕捉し続ける事を可能にしているホームメモリはどのように実現されているのでしょうか。
ホームメモリはユーザがどこにいるかを位置登録エリアと呼ばれる単位で登録しています。1つの位置登録エリアはピンポイントに特定の基地局がカバーするセルというわけではなくいくつかのセルを1つにまとめた結構広い範囲になっています(数十エリアで日本全国をカバーしています)。
<img width=60% alt="キャプチャ.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/47227/cfd98fe0-cdb7-01cc-2314-4593b721de35.jpeg">

そしてホームメモリの更新は携帯電話が電波を掴んだタイミングだけでなく、この位置登録エリア間を移動した場合にも行われています。
基地局は報知情報と呼ばれる自分がどの位置登録エリア内にいるのかを知らせるための情報を発信しており、携帯電話側では最寄りの基地局から受信した報知情報によって自分が属する位置登録エリアが変わったことに気付くことができます。移動したことに気付いた携帯電話は自分が新しい位置登録エリアに所属した事を基地局に対して伝えることで、コアネットワーク側のホームメモリの更新が行われます。

また、当たり前ですがホームメモリは電話番号などによって担当するノードを分割・複製するなどして、莫大な数の携帯電話を捌ききれるように負荷分散されています。

# 加入者交換機による端末の呼び出し(ページング)
ホームメモリから相手の電話がどの位置登録エリアにいるのかが分かりましたので、後は実際に呼び出しを行います。もちろん位置登録エリアはそれなりに広い範囲ですので、ピンポイントにセルを特定する事はできません。ですので、呼び出しの際は位置登録エリア内の全ての基地局から一斉に呼び出しが行われます。この方法をページングと呼び、ページング用の通信路であるページング・チャネルも整備されています。
<img width=70% alt="キャプチャ.JPG" src="https://qiita-image-store.s3.amazonaws.com/0/47227/f29ac8f8-fb4a-911d-e86f-5ed63b5700c1.jpeg">

# 最後に
今回は簡単になぜ携帯電話が繋がるのかの概要を書かせて頂きました。
参考にさせて頂いた【[携帯電話はなぜつながるのか 第2版 知っておきたいモバイル音声&データ通信の基礎知識](https://www.amazon.co.jp/dp/B00J4AX55E/)】は技術的な深い部分まで触れられており、今回の内容はまだまだ携帯電話についての表面をなぞっただけの内容です。
自分の中でかみ砕ければもう少し掘り下げて記載していこうと思いますので、期待せずにお待ち頂ければと思います。
Qiita ハック with Python#1

Pythonを使ってQiitaをいじる実験です。親記事: https://qiita.com/_____/items/d2d52823ea8ef763e3a7

# トークンの取得、チェック

Qiitaが提供している開発者用ダッシュボード https://qiita.com/settings/applications にWebブラウザでログインして、`read_qiita`, `write_qiita` の権限をもつトークンを発行してもらう。トークンは、このタイミングでしか表示されないのできちんとどこかに保存する。

以下のようなプログラムを発行して、トークンを使って自分の情報が取得できることを確認する。

```python
import urllib, urllib.parse, urllib.request
import json

token = 'XXXXXXX'
myname = '_____'

opener = urllib.request.build_opener()
opener.addheaders = [('Authorization', 'Bearer {}'.format(token)),]
urllib.request.install_opener(opener)

def api_authcheck():
  url = "https://qiita.com/api/v2/authenticated_user"
  data = (json.load(urllib.request.urlopen(url)))
  assert (data['id'] == myname)

if __name__ == '__main__':
  api_authcheck()
```

# 全投稿記事のダンプ

Qiitaやめたいときは自分の投稿をダンプしたいところ。自分の投稿記事が100を超えるとページネーションが必要( https://qiita.com/api/v2/docs#get-apiv2authenticated_useritems )だが、大多数のユーザには以下のプログラムで十分だろう。

```python
def dump_allposts():
  url = "https://qiita.com/api/v2/authenticated_user/items?per_page=100"
  data = json.load(urllib.request.urlopen(url))
  ret = [(x['id'], x['title'], x['body']) for x in data]
  return ret

if __name__ == '__main__':
  posts = dump_allposts()
  for p in posts:
    print(p[0],p[1])
```

これでいつでもQiitaをやめられるね！


# 最近の投稿の統計を監視

新規投稿したら、閲覧数やLikeなどが気になるところ。こんなプログラムを書いて、slack連携してみては？

```python
def print_mypoststats():
  url = "https://qiita.com/api/v2/authenticated_user/items?per_page=10"
  data = json.load(urllib.request.urlopen(url))
  posts = [(x['page_views_count'], x['likes_count'], x['comments_count'], x['title']) for x in data]
  for post in posts:
    #print ("{}views,{}likes,{}comments {}".format(*post))
    print ("{1:3d} Likes,{2:2d}comments {3}".format(*post))

if __name__ == '__main__':
  print_mypoststats()
```

閲覧数はAPI仕様では取得できるようなんだけど、実際には`None`が入っていて取得できない。Qiita運営に要望出してもいいかもしれないなあ。
LINE＠を使ってみる


# 事前準備
## アカウント開設～公開

1. 以下のサイトからアカウント登録をする。

<https://entry-at.line.me/>

![LINE@_register](https://qiita-image-store.s3.amazonaws.com/0/233979/a25f4100-0cc9-476e-ad88-588e3c16d355.jpeg)

2. LINE@ MANAGERにログインし、プロフィール設定をする。

<https://admin-official.line.me>

![LINE@_profile](https://qiita-image-store.s3.amazonaws.com/0/233979/595c7264-fca3-b826-a394-fea296a22c85.jpeg)

以上で完了！
このページからメッセージの投稿はもちろん、クーポンやポイントカードなどの発行が可能です。

LINE@アカウントの管理は、スマホアプリからも可能です。

* Google Play Store
[![GooglePlay.png](https://qiita-image-store.s3.amazonaws.com/0/233979/725c38af-1148-f11e-f413-4df6a8c59e42.png)](https://play.google.com/store/apps/details?id=com.linecorp.lineat.android&hl=ja)

* App Store
[![AppStore.png](https://qiita-image-store.s3.amazonaws.com/0/233979/ad21c345-4530-c0bc-f3f3-3710d7938b0f.png)](https://itunes.apple.com/jp/app/line/id958585781?mt=8)
NEMのアドレスがマルチシグであるかを確認するコード

#使い方
python3が必要です。
引数(NEMADDRSS)に入れたアドレスのマルチシグ状況を返します。

```
$ python app.py NEMADDRESS
{'cosignatoriesCount': 2, 'minCosignatories': 2}
```
cosignatoriesCount: マルチシグの署名者の数
minCosignatories: 最低限必要な署名の数
上記例は、マルチシグ署名アドレスが２つあり、そのうち２つが署名しなければ送金できない。

# コード
```app.py
import json
import requests
import random
import sys

argvs = sys.argv

# 接続するノードを選択
def apiRequest(path, param, value):
    nisList = ['78.47.162.99', '47.91.94.195', '138.201.186.71', '89.107.56.153', '47.254.134.237']
    nis = nisList[random.randrange(len(nisList))]
    r = requests.get("http://{}:7890".format(nis) + path + param + value)
    f = json.loads(r.text)
    return f

# apiでアカウントデータを取得
def getAccountData(nemAddress):
    path = "/account/get"
    result = apiRequest(path, "?address=", nemAddress)
    result = result['account']['multisigInfo']
    return result

print(getAccountData(argvs[1]))
```

# 参考
[NEM NIS API Version 1.22/ Requesting the account data](https://nemproject.github.io/#requesting-the-account-data)
[取引所などのアドレスと思われるもの一覧](http://free.userboard.net/t306-topic)
CoinCheckの盗難事件から学ぶ仮想通貨の管理


# 今回のCoinCheckの問題点その1

## コールドウォレットで管理していなかった = ホットウォレットで管理していた

### 1.ウォレットとは

ビットコインを初め、様々な仮想通貨はウォレットと呼ばれるもので管理します。

仮想通貨の多くはアドレスと呼ばれる27~34文字の英数字からなる口座番号のようなものを使用して取引を行い、それをブロックチェーン上に書き込むことでトラストレスで管理されます。

アドレスは公開鍵から生成され、また取引には秘密鍵による署名が必要になります。

アドレスに関して詳しく知りたい方は以下の記事を参照した方が良いでしょう。とても参考になります。

[0から仮想通貨を作るために知っておくべき技術【第1回アドレス編】](https://qiita.com/yoship1639/items/6dd0cc8623d7f3969d78)

さて、ウォレットではこの公開鍵と秘密鍵を管理することが大きな役割の一つとなります。


今回の盗難事件ではCoinCheckが管理していたウォレットの秘密鍵が盗まれてしまったため、ハッカー側が自由に取引可能となってしまったということになります。


### 2.ウォレットの管理場所

ではなぜ秘密鍵が盗まれてしまったのでしょうか。

その方法は秘密鍵を管理しているの場所(ウォレット)によって大きく異なります。

〇場所その1 : デスクトップ

〇場所その2 : Web

〇場所その3 : スマートフォン

〇場所その4 : 紙

〇場所その5 : ハードウェア

この内、インターネットと常に接続しているデスクトップ、Web、スマートフォンで管理されているウォレットをホットウォレットと呼ばれます。

また、紙とハードウェアのようなインターネットの接続を完全に遮断された場所で管理されているウォレットをコールドウォレットと呼びます。


ちなみに取引所のウォレット(取引所に置きっぱなし状態)も当然ホットウォレットとなります。


今回CoinCheckはホットウォレットで管理していたということが明るみに出たときは、驚きましたね。


インターネットに接続された場所でウォレットを管理するという事はとても危険だと再確認しました。


# 今回のCoinCheckの問題点(?)その2

## マルチシグに対応していなかった

### マルチシグとは

ウォレットがコールドウォレットなら解決できた問題なのでマルチシグをしていなかったという点を問題点に挙げるか悩ましいところですが、今回話題になったので取り上げます。


マルチシグ　=　multi signature の略ですね。

要は複数(multi)の署名(signature)を必要とするアドレスの事です。

普通のアドレスではそのアドレスの公開鍵と対になっている秘密鍵があれば取引は可能になります。

しかしマルチシグに対応したアドレスの場合、署名が複数必要になるため、その内署名をするための一つの秘密鍵が盗まれてしまったとしても、ハッカーによる取引は不可能ということになります。

取引するために必要な署名の数やどの秘密鍵による署名かというのは自分で設定できるため、ハッカーに対してセキュリティを飛躍的に高めることができます。

しかし、その分秘密鍵の管理リスクも増すため、これに皆対応すべきかどうかというのは難しい点ですね。



# 結論

今までさんざん言われてきている事ですがハードウォレットで管理しましょう。
取引所をトラストしてはいけません。
また、ハードウォレットは、正規の取扱店で購入しましょう。　

この事件で仮想通貨やっぱ怖いと思った方は、辞めるのも吉です。
ListViewのonItemClickについて

```java
onItemClick(AdapterView<?> parent, View view, int position, long id)
```
この```view```が何を受け取るのかわからなくて調べてみました

たとえば、以下のカスタムlayoutをListViewに適用するとします
![キャプチャ.JPG](https://qiita-image-store.s3.amazonaws.com/0/221077/2b901630-f039-7768-cbc9-9dd76283d4c2.jpeg)

すると、```view```の中身はLinearLayoutになります
moment.jsで「任意の日付から表示」を実装

日付データを扱うのが苦手な私にとって大変便利なライブラリーを発見しました。
その名も「moment.js」です。

[【Qiita】Moment.jsを使う](https://qiita.com/osakanafish/items/5ef636bbcb2c3ef94953)
[【公式サイト】](http://momentjs.com)
[【公式サイト】使い方](http://momentjs.com/docs/#/parsing/)

下記にソースを書きます。
タイトルの本題のソースは"box_05"のところです。
あとは便利なのでその他の機能についても試してみました。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
  <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script>
<script src="/js/moment.js"></script>
	<title>moment.jsについて</title>
</head>
<body>
<style>
* {
	margin: 0;
	padding: 0;
}
a {
  color: #285294;
}

div[class^="box_"]{
	background: #FA8072;
	margin-bottom: 5px;
}


</style>
<div class="box_01"></div>
<div class="box_02"></div>
<div class="box_03"></div>
<div class="box_04"></div>
<div class="box_05"></div>
<div class="box_06"></div>
<div class="box_07">ブログ記事タイトル</div>
<div class="box_08"></div>
<hr>
<script>
// 『今の時間の』Dateオブジェクトが返される
$(function(){
var now = moment();
	$('.box_01').text('【box01】' + now.toDate());
});

// 『今日の年月日にフォーマットする』
$(function(){
	var now = moment();
	var formatnow = now.format('YYYY年MM月DD日');
	$('.box_02').text('【box02】' + formatnow);
});

// 『任意に選んだ日付の文字列からDateオブジェクト』
$(function(){
	var shougatsu = moment('2018-01-08');
	var formatshougatsu = shougatsu.format('YYYY年MM月DD日');
	$('.box_03').text('【box03】' + formatshougatsu);
});


// 『diffメソッドを使って時間の差分を算出』
$(function(){
	var fromDate = moment();
	var toDate   = moment('2018-01-30 01:08');
	var diff = toDate.diff(fromDate,);
	$('.box_04').text('【box04】' + diff);
});

// 『diffメソッドを使ってオープンのお知らせを告知する装置』
$(function(){
	var fromDate = moment();
	var toDate   = moment('2018-02-01 00:00');
	var diff = toDate.diff(fromDate,);

	if(diff <= 0){
	$('.box_05').html('【box05】<strong>2月より新装開店オープンいたしました</strong>');
	}
});

// 『現在時刻を表示する』
setInterval(function(){
    $('.box_06').html('【box06】' + moment().format('LTS'));
}, 1000);


// 『登校日より一週間まではnewをつける』
$(function(){
	var oneday = moment('2018-01-25');
	var kigen = moment([2018,0,26]).add(7, 'days');
	//console.log(oneday);
	//console.log(kigen);
	var diff = kigen.diff(oneday);
	//console.log(diff);
	if(diff >= 0){
		$('.box_07').prepend('【box07】<strong>期限付きnewマーク付与</strong>');
	}
});

</script>
</body>
</html>
```

##追記（2018年11月25日）　CDNで利用の場合

```html
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/locale/ja.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.js"></script>
```
localeを日本に選択する。（何故かlocaleが先）、その次にライブラリーを読み込む。
[【公式】moment.js cdnjsページ](https://cdnjs.com/libraries/moment.js/)

実例集
[全89項目！Moment.js日付の操作＆比較・実例](https://blog.capilano-fw.com/?p=990#i-65)
Ubuntu 18.04LTSにLEMP+Ajenti環境構築

# Linux(Ubuntu) + nginx + MariaDB + PHPの設置

Ubuntu 18.04（Bionic）にLEMP環境とAjentiによる管理ツールを設置します。

## インストール

### 1-1, PHP7.2をインストール

Ondřej Surý氏のリポジトリを使用します。（必要に応じてパッケージを追加）

```shell
$ update-locale LC_ALL=C.UTF-8
$ apt install software-properties-common
$ add-apt-repository ppa:ondrej/php
$ apt update
$ apt upgrade
$ apt install -y php7.2-cli php7.2-fpm php7.2-curl php7.2-mbstring composer
```

### 1-2, nginxのインストール

[公式リポジトリ](http://nginx.org/ja/linux_packages.html)を使用しましょう。

まず、キーを登録します。

```shell
$ wget -q http://nginx.org/keys/nginx_signing.key -O- | sudo apt-key add -
```

次にリポジトリを登録します。

```deb:/etc/apt/sources.list.d/nginx.list
deb http://nginx.org/packages/ubuntu/ bionic nginx
deb-src http://nginx.org/packages/ubuntu/ bionic nginx
```

あとは、通常通りコマンドを実行するだけです。

```shell

apt update
apt install nginx
```

### 1-3, MariaDBのインストール

ここも、[公式リポジトリ](https://downloads.mariadb.org/mariadb/repositories/#mirror=yamagata-university&distro=Ubuntu&distro_release=bionic--ubuntu_bionic&version=10.3)に書いてあるように登録するだけです。

```shell
$ apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
$ add-apt-repository 'deb [arch=amd64,arm64,ppc64el] http://ftp.yz.yamagata-u.ac.jp/pub/dbms/mariadb/repo/10.3/ubuntu bionic main'
```

でインストール。

```shell
$ apt update
$ apt install mariadb-server
```

### 1-4, AjentiとAjenti-xのインストール

自動インストールできますが、トップページに書かれている方法でインストールするとAjenti2がインストールされてしまいます。こちらのバージョンはnginxの管理ツールなどが含まれていないため1.x系をインストールしましょう。うっかり2.xをインストールしてしまっていた場合は後述。

また、Ubuntu 18.04ではpython-imagingが通常ではインストール出来ないため、手動でインストールする必要があります。

```shell
$ apt upgrade
$ apt install python-pillow
$ wget http://security.ubuntu.com/ubuntu/pool/universe/p/pillow/python-imaging_4.1.1-3build2_all.deb
$ dpkg -i python-imaging_4.1.1-3build2_all.deb
$ wget -O- https://raw.github.com/ajenti/ajenti/1.x/scripts/install-ubuntu.sh | sudo sh
$ wget -O- https://raw.github.com/ajenti/ajenti/1.x/scripts/install-ubuntu.sh | sudo sh
```

ajenti本体のインストールが完了したら、動作確認をします。<https://localhost:8000/>に接続し、管理パネルが表示されることを確認してください。

ajenti-vをインストールします。こちらに管理ツールが含まれます。

```shell
apt-get install ajenti-v ajenti-v-nginx ajenti-v-mysql ajenti-v-php7.2-fpm
service ajenti restart
```

## 2, 設定を行う

<https://localhost:8000/>にアクセスして、ユーザ名root、パスワードadminでログインします。言うまでもなくこのままでは危険なので、「設定」のユーザの「以下と同期」をOSユーザーに変更し、「保存」ボタンを押します。すると、ユーザ一覧にユーザ名が追加されます。

ここで再起動する前に、忘れずに追加したユーザに権限を追加しましょう。ログインはできても、管理できない状態になります。その場合は、`/etc/ajenti/config.json`を編集してやり直してください。

## 3, トラブルシューティング

Ajenti2をインストールしてしまった場合、手動で削除する必要があります。

```sh
pip uninstall ajenti-panel ajenti.plugin.dashboard ajenti.plugin.settings ajenti.plugin.plugins ajenti-panel ajenti.plugin.dashboard ajenti.plugin.settings ajenti.plugin.plugins ajenti.plugin.filemanager ajenti.plugin.notepad ajenti.plugin.packages ajenti.plugin.services ajenti.plugin.terminal
apt remove ajenti*
rm -rf /etc/ajenti
apt purge ajenti
```
rails console入門

# rails consoleとは

irbというrailsを読み込んだ環境でrubyを実行できるツール。全部のモデルを参照することができる。

# 操作

## 起動のさせ方

```
rails c
```

## 閉じ方

```
exit
```

もしくは

```
quit
```

# modelの値を確認する

## rails cでconsoleの起動

```
rails c
```

## 変数に入れる

```ruby
@tasks = Task.all
```

@tasksにTaskのオブジェクトを入れる

## 値の取り出し

```ruby
puts @tasks.content
```

=>@tasksのcontent

# テーブルの内容を確認

```
Tomato.all #すべてのレコードを取得する
Tomato.find(1) #idが1のレコードを取得
Tomato.where('id< ?',3) #idが3より小さいレコードを取得
```
Chainerで推論実行するためにsnapshotをload_npzする時はpathの設定が必要

【追記】 `predictor`の前に`with chainer.using_config('train', False):`を設定しないと誤差伝番が実行されてしまうので注意


Chainerで推論実行する時は`chainer.serializers.load_npz()`でモデルを読み込む。`chainer.serializers.load_npz`で生成されたモデルと違い、`extensions.snapshot`で生成されたスナップショットからモデルを読み込む場合は注意が必要。

# 動作環境

- Chainer 3.2
- Python 3.5

# モデルの読み込み

`.model`ファイルは`chainer.serializers.load_npz`によって保存されたファイル。`.snapshot`は`extensions.snapshot`で生成されたファイルであるとする。`snapshot`のファイルはネットワークの情報以外にも色々と書き込まれており、推論実行に必要な部分を指定するには`path='updater/model:main/'`の設定が必要。以下は`args.model`（＝`.model`または`.snapshot`のパス）にどちらが格納されていても対応できるようにした一例。

```python3
    import chainer
    import chainer.links as L

    model = L.Classifier(適当なネットワークのクラス)

    name, ext = os.path.splitext(os.path.basename(args.model))
    load_path = ''
    if(ext == '.model'):
        print('model read')
    elif(ext == '.snapshot'):
        print('snapshot read')
        load_path = 'updater/model:main/'
    else:
        print('model read error')
        exit()

    chainer.serializers.load_npz(args.model, model, path=load_path)
```

# モデルによる推論実行

モデルを使用する場合は以下のようにする。`モデルの生成時にL.Classifier`を利用しているため、`predictor()`で呼び出せば推論実行が可能になる。コンフィグ設定も忘れずに。

```python3
    with chainer.using_config('train', False):
        y = model.predictor(xなどの適当な入力データ)
```

以上。
OpenStack Queens: Nova の新機能と廃止／廃止予定機能

# はじめに

[2018年２月末にリリース予定](https://releases.openstack.org/queens/index.html)の OpenStack Queens における Nova の新機能と廃止機能、廃止予定機能について調べてみました。
参考：https://docs.openstack.org/releasenotes/nova/unreleased.html

# 新機能

## ハイパーバイザ関連

### KVM/QEMU (Libvirt)

* **1ボリュームを複数のインスタンス (＝VM) で同時アタッチ可能に** (qemu<2.10 又は libvirt>3.10)
* **仮想 GPU 付インスタンス作成**に対応
* [StorPool](https://storpool.com/) ボリューム用クライアントドライバ追加

### XenServer

* **仮想 GPU 付インスタンス作成**に対応

### VMware

* **インスタンスの OSシャットダウン**に対応
* **コンソールログ**対応
* インスタンスのファームウェアを UEFI, BIOS から選択可能に (VMイメージ
  のメタデータ hw_firmware_type で指定)

## Nova API

* インスタンスのコールドマイグレーション API: **停止中インスタンスの移動先ホスト指定に対応** (地味に嬉しい)
* インスタンスマイグレーション API: ページネーション、日時フィルタリング対応、他
* インスタンス操作履歴 API: ページネーション対応
* インスタンス再構築 API: key_name, user_data パラメータ追加
* フレーバ API: description パラメータ追加

## Cells v2 関連

### Placement API

* ボディを持つ GET/PUT/POST 応答に last-modified ヘッダを追加。
* リソースプロバイダのツリー構造に対応
* GET /resource_providers: 応答の links セクションへの
  /resource_providers/{rp_uuid}/allocations リンク追加
* GET /allocation_candidates: 応答中のエントリ数制限、エントリのランダム化
* POST /allocations: １要求で複数 consumer UUID の設定／設定解除に対応
* PUT /allocations/{consumer_uuid}: JSON リクエストボディで key-value 型構造を使用するよう変更
  (GET /allocations/{consumer_uuid} のレスポンスボディに合わせた)

### Cells 管理コマンド

* nova-manage cell_v2 delete_cell コマンド: あるセルに削除すべきインスタンスマッピングが存在するが、そのセルの全インスタンスが既に削除されている場合、終了コード 4 を返すように変更
* nova-manage cell_v2 list_hosts コマンド追加。１セル又は全セル中のホスト一覧を表示
* nova-manage cell_v2 delete_host コマンド追加。１セルから１ホストを削除

## その他

* スケジューラ: 同スコアのホスト一覧のランダム化に対応
* スケジューラ: PCI デバイスの NUMA affinity ポリシーに対応。Nova の設定ファイル中でデバイス単位(又はデバイスエイリアス単位)の要求レベルを required(必須), legacy(可能なら必須), preferred(推奨) から選択可能に。
* インスタンス操作履歴: 記録される操作の種類を追加 (ボリューム関連操作、ロック操作、バックアップ関連操作)
* VNC コンソール: [VeNCrypt](http://sibecker.co.uk/vencrypt.html) (VNC プロトコルの TLS 拡張) に対応
* ネットワーク: Neutron で IP アドレスの部分フィルタリング拡張が利用可能な場合、Nova はIPv4/6 フィルタ付のインスタンス一覧を Neutron に送信
* 通知: サービス (＝Nova 中の各主要プロセス) 作成／削除通知に対応
* 通知: instalce.snapshot.{start, end} notification に snapshot_image_id を追加。

# 廃止予定機能

* **Windows / Hyper-V 2012 Server サポート** (←訂正しました)
* monkey_patch。コード改変無しで特定メソッドに Python のデコレータメソッドをつける機能だったが、テストされておらず互換性上の問題になっていた。
* nova-manage cell コマンド。Cells V1 用のコマンドだった。
* Nova 標準のリソースクラス (VCPU、メモリ、ディスク) による Ironic ノードのスケジューリング機能。代わりにカスタムリソースクラスを使用する事。
* Pike で廃止された Nova API 拡張機能関連 ACL。
* その他、細々とした設定ファイルのパラメータの廃止・変更

# 廃止機能

* Nova API
  * インスタンス作成／再構築 API: personality パラメータ削除
  * GET /limits API: 応答中の maxPersonality, maxPersonalitySize を廃止
  * クォータ API: ファイル挿入系クォータを廃止
* nova-manage の以下のサブコマンド:
  * quota
  * shell
  * project
  * account
  * logs
  * host
  * agent
* TrustedFilter スケジューリングフィルタ
* Nova API v2.1 で機能しなくなった api.fault 通知関連の設定パラメータ
* nova-idmapshift バイナリ
* その他、細々とした設定ファイルのパラメータの廃止・変更

# まとめ

Nova の更なるスケーラビリティ強化の為に最近導入された Nova Cells v2 関連強化、物理マシン管理サービス Ironic 用スケジューリング機能改革が続く一方で、１ボリュームの複数インスタンス接続や仮想 GPU 対応など、興味深い機能の追加もあります。Nova は OpenStack の最古参のコンポーネントの１つですが、今後も活発に開発が続くでしょう。
PDFから画像を抽出する方法

他の論文から図表や画像を引用する際にPDFファイルから抽出する方法．

1. 対象のPDF(e.g. example.pdf)をLibreOfficeで開きます（自動的にDrawで開かれるはず）
2. 各画像とかが見えるのを確認します
3. そのままOpenDocument形式(e.g. example.odg)で保存します。
4. 拡張子を.zipに変えます(e.g. example.odg -> example.zip)
5. 解凍します
6. Picturesフォルダの中に全部入っている

引用元：[PDF中の画像ファイルのみを抽出する](https://qiita.com/aokomoriuta/items/066b760a28da461531b6)
プログラミング言語を体系的にまとめる

# この記事の目的

プログラミング言語を体系的にまとめて言語の特性を大枠で理解するのに役立てたい。（勉強のためのものなので間違ってたり補足あったらコメントがほしい）

# インタプリタとコンパイラ

## インタプリタ

ソースコードを変換せずに直接実行するもの。長所はプログラムを作成している途中でも、とりあえず書かれた箇所まで実行させることができ、プログラマの期待通りの動作をしている場合も、期待通りの動作をしていない場合も、早期にそれを確認・発見し、そして修正後すばやく実行、再確認できる。短所は実行速度が遅い。

## コンパイラ

コンパイルという変換作業を行い、実行するもの。コンパイラ型言語では、コンパイルする前にソースコードをオブジェクトコードに翻訳しておくため、プログラムを解釈しながら実行するインタープリタ型言語と比較して、パフォーマンスに優れている。なお、オブジェクトコードはそのままでは実行できず、実行に必要なライブラリを結合して実行モジュールを生成する必要がある。このことをリンクと呼ぶ。

# スクリプト言語とマクロ言語

## スクリプト言語

スクリプト型言語は記述や実行を比較的簡易に行うことができる言語の総称である。非常に多くの場合、スクリプト言語はインタープリタ型言語であり、コンパイラ型言語に比べて実行までの処理の手間がかからないという特徴を持っている。また、他のプログラミング言語に比べると、英語のような自然言語に近い記述を用いてプログラミングすることが可能であり、習得が比較的容易であるとされる。

## マクロ言語

VBAなど計算などの処理を行うのに適した言語。

# 言語のタイプ

言語には大きくワケて命令型と宣言型があり、命令型はどう処理を行うかを指示するのに対して宣言型はその値がどういうものかを宣言するものになる。こういった言語の捉え方をプログラミングパラダイムといい、複数のパラダイムを持つ言語をマルチパラダイムの言語という。

## 命令型

### 手続き型

手続き型プログラミング（てつづきがたプログラミング、英: Procedural programming）は、「手続き呼び出し」の概念に基づくプログラミングパラダイムの一種。命令型プログラミングと同義に扱われることが多い。「手続き」はプロシージャ、ルーチン、サブルーチン、メソッド、関数（数学の関数とは異なる。）など様々な呼称があるが、実行すべき一連の計算ステップを持つものと定義できる。手続きはプログラム実行中の任意の時点で呼び出すことができ、他の手続きからの呼び出しも、自分自身からの呼び出し（再帰呼び出し）も含まれる。

### オブジェクト指向

オブジェクト指向（オブジェクトしこう）とは、オブジェクト同士の相互作用として、システムの振る舞いをとらえる考え方である。英語の object-oriented (直訳は、「対象物志向の」「目的重視の」という意味の形容詞) の日本語訳である。

オブジェクト指向の枠組みが持つ道具立ては、一般的で強力な記述能力を持つ。複雑なシステム記述、巨大なライブラリ（特に部品間で緊密で複雑な相互関係を持つもの）の記述においては、オブジェクト指向の考え方は必須である。

## 宣言型

### 関数型

何をもって関数型プログラミングとするか、関数型プログラミングを行っているコミュニティ内でも正確な定義や合意というものは存在しないが、一般的には、手続き型プログラミングがコマンド実行の列としてプログラムを記述していくのに対し、関数型プログラミングは複数の式を関数の適用によって組み合わせていくプログラミングスタイルである、ということは広く認められている。

### 論理型

プログラミングにおいて広く利用される手続き型言語ではコンピュータに対し「××をせよ」という具体的な指示を与えていくのに対し、論理型言語では「○○は××である」という定義を書き連ねる。そして「△△は××か？」とか「××なものを求めよ」という条件を与えると、それに見合う結果が返ってくるという言語である。

その特性ゆえに「8クイーン問題」のような、条件を決めると結果が確定する(が、具体的にどうやって求めるかは難しい)タイプの問題を非常に扱いやすいのであるが、先に手順が決まっていてその通りに動いて欲しいような処理は全くと言っていいほど書くことができない。現代主流言語の対極にあるような存在である。
Angularアプリで効果音を出す

Webアプリで独自の効果音を出したい話。
HTML内にタグを追記することなく、Typescript側だけで対応可。


```dialog.component.ts
export class DialogComponent implements OnInit {

//コンポーネントのメンバとしてHTMLAudioElementを作成
    private SoundWarning: HTMLAudioElement = new Audio('sound/warning1.mp3');

//コンポーネントの呼出段階で音源ファイルを読み込んでおく
    ngOnInit() {
        this.SoundWarning.load();
    }

//メソッドが実行された時に音を鳴らす
    openDialog(DialogMessage){
        ....
        this.SoundWarning.play();
        ....
    }
}
```
効果音ならす部分をサービス化するとか、もう少し凝ったこと出来るけど次回に回して、とりあえず忘備録。
base64の画像データから、ファイルサイズとタイプを抽出する。



```js
function base64ToFile(data) {
  try{
    let separetedDate = data.split(',');
    let mimeTypeData = separetedDate[0].match(/:(.*?);/);
    let mimeType = Array.isArray(mimeTypeData) ? mimeTypeData[0] : '';
    let decodedData = atob(separetedDate[1]);
    let dataLength = decodedData.length;
    let arrayBuffer = new ArrayBuffer(dataLength);
    let u8arr = new Uint8Array(arrayBuffer);

    for( let i = 0; i < dataLength; i +=1){
      u8arr[i] = decodedData.charCodeAt(i);
    }

    return new Blob([u8arr] , {type:mimeType});

  }catch (errors){
    console.log(errors);
    return new Blob([])
  }
}
```

`console.log（base64ToFile(data)）;`してみると、こんな感じで出力される。

<img width="344" alt="スクリーンショット 2018-01-27 11.42.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/206790/ad39b91c-ae62-e4da-a2e3-47827b4b588e.png">
AVSpeechSynthesizerで複数言語を話す


## 結論
**AVSpeechSynthesizerDelegateのdidFinishメソッドを使って言語を切り替え、読み上げる関数を使う**

## 環境
- macOS Sierra 10.12.6
- Swift4
- Xcode 9.2

## 読み上げ

AVSpeechSynthesizerを使うと、渡した文字列を読み上げてくれます。
使い方は次のように書きます。

```Swift

import AVFoundation

let syntherizer = AVSpeechSynthesizer()
let voice = AVSpeechSynthesisVoice(language: "ja-JP")
let utterance = AVSpeechUtterance(string: "おはよう")
utterance.voice = voice
syntherizer.speak(utterance)

```

使える言語はiPhoneにインストールされているもので、日本語は"ja-JP",英語は"en-US","en-AU"など、中国語は"zh-CN","zh-HK"など、国のなまりもと反映できるらしいです。
なお、指定した言葉に対して言語が合ってなければ、何も反応しません。


## 複数言語の読み上げ
例えば最初の文は英語で、次の文は日本語を読み上げる、という風にしたい場合があります。

例）Hello World こんにちは、世界

この時、最初に"Hello world"という文字列を渡して、英語を指定し、次に"こんにちは、世界"という文字列を渡して、日本語を指定すれば大丈夫だと思ってたんですが、読み終えたところで読み上げる関数をよびださないと最初の読み上げと重なって次の文が読み上げられませんでした。

結果的にAVSpeechSynthesizerDelegateのdidFinishメソッドを使って言語を切り替えることで対応できました
これは、didFinishつまり、読み上げが終わったときに呼ばれる関数です。この関数の中で次の読み上げの設定を行います。
また、そのままだと読み終える度に関数が呼ばれるので、２回め以降は止めるようにします。
ここでは、languageが日本語の場合は、終了するようにしています。

```swift
//Deleagte先を設定すること
extension ViewController:AVSpeechSynthesizerDelegate{
    
    func speechSynthesizer(_ synthesizer: AVSpeechSynthesizer, didFinish utterance: AVSpeechUtterance) {
        //連続で同じスピーチしない
        if utterance.voice!.language == language.ja.rawValue{
            return
        }
        
	let syntherizer = AVSpeechSynthesizer()
	let voice = AVSpeechSynthesisVoice(language: "ja-JP")
	let utterance = AVSpeechUtterance(string: "こんにちは、世界")
	utterance.voice = voice
	syntherizer.speak(utterance)
    }
}
```

## 最後に

スマートスピーカーの普及のため、音声UIが今後増えていき、これから音声APIを使う機会が増えるかもしれません

## 参考
- https://developer.apple.com/documentation/avfoundation/avspeechsynthesizer
Linux mintでKernelをアップグレードしたらハイバネートが効かなくなった

#なぜかkenel upgradeでハイバネートの挙動がおかしくなる

linux mint 18.2を使っていて、そろそろカーネルが古くなってきたので、upgradeをしました。

カーネルのアップデートは、アップデートマネージャから簡単に更新できるのですが、アップグレード後にハイバネート(hybernate)の機能が効かなくなったことに気づきました。これはノートPCには致命的です。単なるスリープとすると、メモリには通電されている状態ですが、ハイバーネートだと完全にメモリの内容HDDに書き出し完全に電源を落とすため、一切電力を消費せずノートPCのバッテリーを抜いても大丈夫なわけです。

今回、アップデートマネージャからkernelのバージョンアップを行い、hybernateをかけてみると、Hybernateまでは行くものの、復旧するときに黒い画面となり何の操作も聞かず、強制的にPCの電源を落とすしかない状況に陥りました。

様々なアップデートマネージャから選択可能な様々なバージョンのkenelを試してみましたが、どれも同じ状況でした。

#解決策
調べていたところ、この方の現象と同じことが分かりました。
https://jonathanmh.com/solved-linux-mint-18-not-waking-suspend-hibernate-lid-close/

そこのコメントに書かれていた、以下のサイトから、ukuu(Ubuntu Kernel Upgrade Utility)をインストールし、ukuu-gtkコマンドから
最新のカーネルをインストールしたところ正常に動作しました。どうやらLinux Mintだけではないようですね。
>Ubuntu 16.04, Ubuntu 17.04, Centos 7, Fedora 26, Linux Mint 18.2, opensuse 42.3

http://www.teejeetech.in/p/ukuu-kernel-upgrade-utility.html

実は、linux mint 18.2以前に他のバージョンのlinux mintでも同じ事象が発生し、
kernel upgradeは諦めていたのでスッキリしました。

※今までずっとhybernateを「ハイバーネート」と思っていましたが、「ハイバネート」記述することをこの記事を書いている時に知りました。
JavaでFizzBuzz

少しはコードを書けるようになってきたのでとりあえずFizzBuzzを書いてみました。


```Java:FizzBuzz.java
public class FizzBuzz{
    public static void main(String[] args){
        for(int i = 1; i < 101; i ++){
            String display;//表示する変数
            if(i % 3 == 0 && i % 5 == 0){
                display = "FizzBuzz";
            }else if(i % 3 == 0){
                display = "Fizz";
            }else if(i % 5 == 0){
                display = "Buzz";
            }else{
                //int型の変数「i」をString型に変換
                display = String.valueOf(i);
            }
            System.out.println(display);//表示
        }
    }
}
```
PHP の CLI でスクリーンの横幅と高さを取得するサンプル（罫線を引く）

PHP で、**シェル/ターミナル/コマンドラインの画面の横幅や高さを取得するサンプル**です。

「[シェルで`<HR>`（水平線）を表現する方法各種](https://qiita.com/KEINOS/items/70463cab45ba7d3bc82f)」を活用して、PHP で CLI アプリを作成する際に画面サイズ（１行の文字数と画面の行数）を取得できるようになります。

これにより画面横幅いっぱいの横線を描画したりできます。

## TL;DR（ポイント）

[シェルの `tput` コマンド](https://qiita.com/tags/tput)を PHP でパース（PHP 内から実行して、その結果を取得）します。

```php
<?php

$screen_width_default = 70;
$screen_width_system  = `tput cols`; // バッククォート注意。`exec` だと正常に取得できない

$screen_width = $screen_width_system ?: $screen_width_default;

echo srt_repeat('-', $screen_width), PHP_EOL;
```

## TS;DR


## サンプルで使われているユーザ関数

|関数名|内容|備考|
|:---|:---|:---|
|`get_hr()`|指定文字の罫線（１行ぶん繰り返した文字列）を返す|罫線の文字のデフォルトは'='|
|`get_screen_width()`|スクリーンの横幅（１行の文字数）を返す|取得できない場合はデフォルト値を返します|
|`get_screen_height()`|スクリーンの高さ（画面の行数）を返す|取得できない場合はデフォルト値を返します|
|`is_cli()`|CLI で実行しているか返す|呼び出し元がWEBサーバーの場合は`false`を返します|

## サンプル・コード

```sample_cli.php
<?php

/* サンプル */

echo get_hr() . PHP_EOL; //画面横幅いっぱいに横線を描画する
echo get_screen_width() . PHP_EOL; //ターミナルの横幅（１行の文字数）を出力
echo get_screen_height() . PHP_EOL; //ターミナルの高さ（画面の行数）を出力
echo (is_cli()) ? 'CLIです' . PHP_EOL : '<p>CLIではありません</p>' . PHP_EOL; //CLIの判断

/* 関数 */

function get_hr($hr_char = '=')
{
    $width = get_screen_width();

    if ('n/a' == $width) {
        return '<hr />';
    } else {
        return str_repeat($hr_char, $width);
    }
}

function get_screen_width()
{
    $default_width = 70; //デフォルト幅

    if (! is_cli()) {
        return 'n/a';
    }
    $width = trim(`tput cols`); //バッククォートであることに注意

    return is_numeric($width) ? (int) $width : $default_width;
}

function get_screen_height()
{
    $default_height = 40; //デフォルト幅

    if (! is_cli()) {
        return 'n/a';
    }
    $height= trim(`tput lines`); //バッククォートであることに注意

    return is_numeric($height) ? $height : $default_height;
}


function is_cli()
{
    return PHP_SAPI === 'cli' || empty($_SERVER['REMOTE_ADDR']);
}

```

### 出力結果

```
$ php ./sample_cli.php
================================================================================
86
24
CLIです
```

- 1行目：WEBからのアクセスの場合は "`<hr />`" が返されます
- 2行目：CLI からのアクセスの場合で**幅を取得できた場合**の横幅（１行の長さ）の値
- 3行目：CLI からのアクセスの場合で**高さを取得できた場合**の高さ（画面の行数）の値
- 4行目：CLI 経由での実行か否かの結果

### 検証済み環境
- macOS HighSierra： OSX 10.13.6
- `bash --version`： GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin17)
- `php -v`： PHP 7.2.6 (cli) (built: May 25 2018 06:18:43) ( NTS )
ディープラーニングでモックアップ画像からHTMLソースを生成する（入門編）

#概要
デザイナーが作ったモックアップ画像からコードを自動生成する、
<a href="https://github.com/emilwallner/Screenshot-to-code-in-Keras">Screenshot-to-code-in-Keras</a>
というプログラムが<a href="https://applech2.com/archives/20180112-turning-design-mockups-into-code-with-deep-learning.html">ニュース</a>になっていたので、
どのくらいの精度があるのか試していきます。

今回はクラウド上で行うのでPCは何でもOKです。
一応以下ではOSはAmazon Linux、Python のバージョンは2.7で行っています。

#準備1. Floydhub編

<a href="floydhub.com">Floydhub</a>というクラウドのサービスを利用していきます。

登録自体はメールアドレスだけで無料で簡単にできました。
（ただし無料プランだとGPU利用時間に制限があるようです）

登録後、ターミナルに以下のコマンドを打ちFloydhubにログインします。

```
pip install floyd-cli
floyd login
```

すると以下のように聞かれるので「y」と答えます。

```
Authentication token page will now open in your browser. Continue? [Y/n]: y
```

その次に「認証トークンを貼って」と言われるので、Floydhubの「CLI token」ページからトークンをコピペします（認証トークンはメールアドレスの確認を終えていないと出ません）。

```
Please copy and paste the authentication token.
This is an invisible field. Paste token and press ENTER:
```

これでFloydhubが使えるようになったので、
リポジトリをインストールしたい場所でgit cloneします。

```
git clone https://github.com/emilwallner/Screenshot-to-code-in-Keras
```

次にScreenshot-to-code-in-Keras/floydhubディレクトリに移動し、floyd initします。

```
cd Screenshot-to-code-in-Keras/floydhub
floyd init quick-start
```

これでFloydhub用の下準備は整いました。

#準備2. 画像編
次にモックアップ画像の準備ですが、今回試すバージョンはある程度決まったフォーマットにしか対応していないようなので、
とりあえずデフォルトで入っている画像をそのまま使用します。
![90.jpg](https://qiita-image-store.s3.amazonaws.com/0/123809/effe7fa6-af1e-7b29-d418-344e08b29004.jpeg)

#準備3. 実行ファイルの修正編
最後に、 実行するファイルであるScreenshot-to-code-in-Keras/floydhub/HTML/HTML.ipynbを2か所書き換えました。

一つ目は、190行目にある画像ファイル名。
今回使用する"90.jpg"に書き換えます。

```HTML.ipynb
190     "test_image = img_to_array(load_img('resources/images/90.jpg', target_size=(299, 299)))\n",
```

もう一つは、131行目にあるepochsの数字を増やして精度を高めます。

```HTML.ipynb
 131     "model.fit([image_data, X], y, batch_size=64, shuffle=False, epochs=300)"
```
※注意 300エポックだと実行に1時間40分くらいかかりました。下手すると無料時間分を超えてしまう可能性があるので、適宜調整してください。

これで準備は完了です。

#実行
floydhubディレクトリで以下のコマンドを実行するとインスタンスが立ち上がります。
（無料だと2時間しか使えないので終わったらシャットダウンすることをおすすめします）

```
floyd run --gpu --env tensorflow-1.4 --data emilwallner/datasets/imagetocode/2:data --mode jupyter
```

成功すると、ブラウザのFloydhubの「Jobs」ページにjobが追加されています。

![jobs.png](https://qiita-image-store.s3.amazonaws.com/0/123809/d4ce4db5-8188-6622-b480-e5f15ece0de4.png)

job内のoverviewタブの中からJupiter notebookにアクセスできるので、HTML.ipynbを探して開きます。

![jupiter.png](https://qiita-image-store.s3.amazonaws.com/0/123809/5ecfefce-f280-30cb-8752-c2d5564ec78a.png)

一番上のメニューの「cell」から「Run All」を選ぶと、スクリプトが実行されます。

300エポックはかなり時間がかかるので気長に待ちましょう。

#結果
以下のようなサイトが生成されました（<a href="https://jsfiddle.net/gptb9c8d/">jsfiddle</a>）。
![result.png](https://qiita-image-store.s3.amazonaws.com/0/123809/43bfd4fb-e718-d724-a8f6-c3155875eba5.png)

元の画像とは微妙に異なりますが、結構それっぽいものができました。
ソースを見てもあまり変なところはないようです。
エポック数をより増やせば、さらにモックのものに近づくと思われます。


今回はあらかじめ用意された画像を用いましたが、
好きな画像から生成できるバージョンもあるようなので、
気が向いたらまた試してみたいと思います。
【備忘録】SublimeText3からiTerm2を開く方法

SublimeTextでTerminalを開く方法はPackage ControlでTerminalをインストールすれば完了しますが、iTermを設定する方法が手こずりました。

### 目次
0. Package ControlでTerminalをインストール
0. User Settingsに`"terminal": "iTerm.sh"`を追記
0. Terminal.shを書き換え

### 実作業
0. Package ControlでTerminalをインストール  
cmd + shift + pでpackage Controlを呼び出しTerminalをインストールする。

0. User Settingsに`"terminal": "iTerm.sh"`を追記  
User Settingsに下記を追記する。
```sh
{
  "terminal": "iTerm.sh"
}
```

0. Terminal.shを書き換え
先ほどのインストールに成功していると下記ディレクトリが作成されている。
`/Users/ユーザー名/Library/Application Support/Sublime Text 3/Packages/Terminal/
`
その中の
```sh
Terminal.sh ← 書き換えるファイル
// ※下記ファイルは関係ありそうなファイルなのでメモとして残しておく
iTerm.sh
iTerm2-v3.sh
``` 
下記リンク先のiTerm.shをTermial.shと書き換える。
https://gist.github.com/gnachman/b9ae9cf06c44b5a95edf

### 終わりメモ
MacTerminalとかいうパッケージもあってそっちの方が簡単そうだなと思ったけど、生産終了したのかありませんでした。  
参考文献の通り、iTerm.shを上書きしても相変わらずだったので、Terminal.shにて対処しました。  
腑に落ちるやり方を見つけたら再度編集する予定でっす。

### 参考文献
http://t8m8.hateblo.jp/entry/2016/02/20/194950
https://qiita.com/hirokishirai/items/6b008623d1ea05b4d92e
JavaScriptの配列の最頻値を求めるコピペ

# 概要
JavaScriptって数値計算用の機能が貧弱ですよね。
「じゃあPython使う？」ってなっちゃっても良いんですけど、
漢にはどうしてもJSで頑張らなくちゃいけないときがあります。**GoogleAppsScript**みたいに。
(淑女の方にもそんな時あると思います)

特に**配列の要素の最頻値を返す**なんて超ありがちな処理をわざわざフルスクラッチで書かなくちゃいけなくなった時なんて殺意すら感じます。

なので今回は```Array```クラスに勝手に最頻値を返すメソッドを追加する技について書きたいと思います。
ネイティブ型の空間をぶち壊したくない型は素直に関数として定義して下さい。


## 環境
2018年1月現在普通のブラウザ
Node.js v8.9.4
2018年1月現在のGoogleAppsScript
などなど

# 実装
配列に入りうる中身によって2パターン作りました。

## 機能要件
* 要素に```Array```や連想配列のような```obj```が入ることが無い
* 返り値は最頻の値。
* 同数の場合はindexが若いものを返す。
* **GoogleAppsScript**のようなES6が使えない環境においても動作可能にする。

### 使い方
単純

```JavaScript:howtouse.js
Array.prototype.mode = ....中略

var samples = ["りんご","ばなな","りんご","みかん"]
samples.mode()
// "りんご"
```

## 一番堅実な実装(おすすめ)
* ```null```や```undefined```に対応。
    * 配列の要素数が0の時、nullを明示的に返さない。
* 型違い(```undefined```と```"undefined"```のような紛らわしい違いも含む)を別のものとして扱う
* 普通は気にしなくていいが非常に大きな配列を食わせるとパフォーマンスに影響する可能性あり。

```JavaScript:mode.js
Array.prototype.mode = function () {
    if (this.length === 0){
        //配列の個数が0だとエラーを返す。
        throw new Error("配列の長さが0のため最頻値が計算できません");
        //nullを返しても困らない時(配列の中にnullが無い時)はnullを返すように実装しても良い。
        //return null
    }
    //回数を記録する連想配列
    var counter = {}
    //本来の値を入れた辞書
    var nativeValues = {}

    //最頻値とその出現回数を挿入する変数
    var maxCounter = 0;
    var maxValue = null;
    
    for (var i = 0; i < this.length; i++) {
        //counterに存在しなければ作る。keyは型を区別する
        if (!counter[this[i] + "_" + typeof this[i]]) {
            counter[this[i] + "_" + typeof this[i]] = 0;
        }
        counter[this[i] + "_" + typeof this[i]]++;
        nativeValues[this[i] + "_" + typeof this[i]] = this[i];

    }
    for (var j = 0; j < Object.keys(counter).length; j++) {
        key = Object.keys(counter)[j];
        if (counter[key] > maxCounter) {
            maxCounter = counter[key];
            maxValue = nativeValues[key]
        }
    }
    return maxValue

}
```

## 細かいことを気にしない雑な実装
* 型違いの要素に非対応
* 極めて特殊な要素("2+3"とかevalして値が変わるもの)が来た時にバグる。
* 非常に細かいパフォーマンスの差を気にしない限り↑を使うのが堅実

```JavaScript:mode_zatsu.js
Array.prototype.mode = function() {
 var counter = {}
 var maxValue = null
 var maxCounter = 0;
 for (var i=0;i < this.length;i++){
   if (!counter[this[i]]){
     //存在しなかれば作る
     counter[this[i]] = 0
   }
   counter[this[i]]++;
   
   for (var j=0;j<Object.keys(counter).length;j++){
     key = Object.keys(counter)[j];
     if (counter[key] > maxCounter){
       maxValue = key
       maxCounter = counter[key]
     }
   }
 
 }

 return eval(maxValue)
 // 以下のようにすることで全て文字列で返すさらに雑な実装を実現可能
 //return maxValue 
}
```


# 今後の課題と感想
* ２次元配列やobjの入る配列のような多様な配列に対応<br>
ES6が動く環境なら```Symbol```型が使えるので簡単に作れそう。ただ、筆者は**GoogleAppsScript**で動かしたかったために、機能の限定とクソレガシーな書き方を余儀なくされた。悲しい。
* ES6が使えないと想像以上にしょうもないところでコケる。<br>
**GiigleAppsScript**の残念すぎる実行環境が悪い。おこ。