OmniAICreator/Qiita-1.07M huggingface dataset:
ロゼッタコードを調べやすくするTampermonkeyScript

## 概要

[ロゼッタコード](http://rosettacode.org)にはいろんなプログラミング言語によるコードの書き方がストックされていますが、
任意の言語のみを調べたいときにはいささか不便なサイト構造となっています。

たとえば、Javaの日付時刻フォーマットを調べたいとき、
* http://rosettacode.org/wiki/Category:Java でJavaカテゴリに移動
* トピック一覧から Date_Format を選択し、http://rosettacode.org/wiki/Date_format へ移動
* Date_Formatページにある言語一覧リンクの中からJavaを選択し、見たい場所(http://rosettacode.org/wiki/Date_format#Java)へジャンプ

といった手順となり、目的のトピックページへ飛んでから、さらに目的の言語の場所にたどり着かないと、見たいコードが見られないということになり、ちょっとしたストレスを感じています（私が）。

以下のコードは、言語カテゴリーページを表示した時に、リンク先に言語名をハッシュとして追加してくれるTampermonkyスクリプト(Chrome拡張)です。

TampermonkeyScriptのインストールは[こちらのChrome-Webstore](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=ja)からどうぞ

```javascript
// ==UserScript==
// @name         ロゼッタさん
// @namespace    https://github.com/6in
// @version      0.1
// @description  ロゼッタコードの任意の言語だけを表示できるように、アンカーを編集する
// @author       https://github.com/6in
// @match        http://rosettacode.org/wiki/Category:*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    // Your code here...

    setTimeout( function() {
        // URLからどの言語カテゴリかを取得
        var url = window.location.href;
        var lang = url.split(':')[2];
        // アンカー一覧を取得
        var ancher = document.querySelectorAll('div.mw-category-group ul li a');
        // アンカーの末尾に言語名を付与
        [].forEach.call(ancher, function (a) {
            a.href = a.href + '#'+lang;
            // 別ウィンドウに表示
            a.target='LangFrame-' + lang;
        });
    },0);
})();
```

### 使い方

* Tampermonkeyスクリプトを適用します。
* http://rosettacode.org/にアクセスします。
* 上部にある検索ウィンドウで、検索したい言語(例: nim)を入力します。
* 検索結果として、カテゴリページ http://rosettacode.org/wiki/Category:Nim が表示されます。
* 上記のTamperMonkeyスクリプトが適用され、各トピックへのリンク先のURLに言語ハッシュが追加されます。
* 任意のトピックをクリックすると、**別タブ(ウィンドウ)**にそのトピックの指定言語版が表示されます。
* トピック用表示タブ(ウィンドウ)がフレーム名が固定となるので、トピックページを別ウィンドウにしておくと、色々と捗ります。

![nim_hash.png](https://qiita-image-store.s3.amazonaws.com/0/58872/b7d6cb5f-06aa-051e-5c49-2ec185471b02.png)

## まとめ？

簡単なTampermonkeyスクリプトでしたが、[言語がブレイクしそうな時](https://qiita.com/rigani/items/6e87c7cee6903ed65ed2#comment-274d27bdba79d92a379d)にRosettaCodeで「アノ言語でアレってどう書くの？」っていうのが、調べやすくなった気がします(当社比200%)
MySQLで誕生日から年齢を取得する

ユーザーの年齢を取得したいという場合に、DB上では誕生日を持っておいて、取得時に計算して年齢を出す、というのが一般的だと思います。

表示で使う際は、プログラム側で関数を作っておいて計算すればいいですが、分析用途やリストの出力のためにSQLでさくっと年齢を出したい！という場合に使える方法をご紹介します。

よりよい方法やバグ等ございましたら、アドバイスいただけると光栄です。

## 事前準備

年齢計算のクエリを投げるに当たって、テーブル・レコードを作成します。

### テーブル

今回は、友達の誕生日一覧のテーブルを作成します。

```sql
mysql> DESCRIBE friends;
+----------+------------------+------+-----+---------+-------+
| Field    | Type             | Null | Key | Default | Extra |
+----------+------------------+------+-----+---------+-------+
| id       | int(10) unsigned | NO   | PRI | NULL    |       |
| name     | varchar(100)     | YES  |     | NULL    |       |
| birthday | date             | YES  |     | NULL    |       |
+----------+------------------+------+-----+---------+-------+
```

### レコード

```sql
mysql> SELECT * FROM friends;
+----+-------+------------+
| id | name  | birthday   |
+----+-------+------------+
|  1 | Aaron | 1988-10-15 |
|  2 | Aimee | 1990-04-24 |
|  3 | Lily  | 1998-08-08 |
|  4 | Bryan | 1995-09-02 |
|  5 | Harry | 1993-05-12 |
|  7 | Jimmy | 1978-04-08 |
|  8 | Robin | 1999-01-11 |
|  9 | Sally | 1991-07-12 |
+----+-------+------------+
```

## 年齢を取得
誕生日から年齢を取得するには、TIMESTAMPDIFF() 関数を使用します。
引数は、結果を表現する単位、および差を求める 2 つの日付です。

>[MySQL 8.0 リファレンスマニュアル : : 日付の計算][LINK1]

今回は、「現在の日付」と「誕生日」の差分から、その「年数」を取得できればいいので以下のように使用します。

```sql
TIMESTAMPDIFF(YEAR, `birthday`, CURDATE()) AS age
```

それでは、これを使って先程の`friends`テーブルで、各友達の年齢を取得してみましょう。

```sql
mysql> SELECT id, name, birthday,
    -> TIMESTAMPDIFF(YEAR, `birthday`, CURDATE()) AS age
    -> FROM friends;
+----+-------+------------+------+
| id | name  | birthday   | age  |
+----+-------+------------+------+
|  1 | Aaron | 1988-10-15 |   29 |
|  2 | Aimee | 1990-04-24 |   27 |
|  3 | Lily  | 1998-08-08 |   19 |
|  4 | Bryan | 1995-09-02 |   22 |
|  5 | Harry | 1993-05-12 |   24 |
|  7 | Jimmy | 1978-04-08 |   39 |
|  8 | Robin | 1999-01-11 |   19 |
|  9 | Sally | 1991-07-12 |   26 |
+----+-------+------------+------+
```

結構シンプルに取り出せます。


## 気になったこと

ただ、これについて調べていると、以下のような取得の仕方が多くみられました。

```sql
(YEAR(CURDATE()) - YEAR(birthday)) - (RIGHT(CURDATE(), 5) < RIGHT(birthday, 5))
```

これは、
**「現在の日付と誕生日の年の差分を取得して、さらに誕生日に達していない場合は1を引く」**
って感じになっているんですが、なんでこっちの例が多いんでしょう…。

知っている方がいらっしゃれば、教えて頂きたいです。


### ※追記(2018/1/23)
コメントで参考になる記事を紹介頂いたので、共有させて頂きます。

>[まだ年齢計算で消耗してるの？][LINK3]

この記事によれば、生年月日から年齢を計算する簡単な計算式というのがあるそうです。

```text
年齢 = (今日の日付 - 誕生日) / 10000の小数点以下切捨て。
```

今回のTIMESTAMPDIFF()関数は、まさにこの式に当てはめて作られている関数です。

この計算式を知っていれば、
**「現在の日付と誕生日の年の差分を取得して、さらに誕生日に達していない場合は1を引く」**
という、面倒な計算をさわさわしなくても問題なさそうです。

※自治体などの法令のしばりなども関係はしてきますが、今回はそれを考えないものとします。



# 参考資料
- [MySQL 8.0 リファレンスマニュアル : : 日付の計算][LINK1]
- [まだ年齢計算で消耗してるの？][LINK3]
- [佐野裕のサーバ管理者日記 : : 生年月日から年齢を計算する簡単な計算式][LINK2]

[LINK1]:https://dev.mysql.com/doc/refman/8.0/ja/date-calculations.html
[LINK2]:http://itpro.nikkeibp.co.jp/article/Watcher/20070822/280097/
[LINK3]:https://qiita.com/kawasima/items/8fdd3939be151f33f7cf
Alexaスキル開発　〜iphone1台のテザリングで出先でも野良wifiを使わずネットワークに接続する〜

予約開始当日に招待申請したにもかかわらず2018年にはいって、やっとEcho Dotが手に入りました。
ということでこれからスキル開発をやっていきたいと思う。
Echo Dotはかなり小さいので、外出先でちょっといじりたいとき用にテザリングできるように設定しました。
（既に関連の記事はいくつか書かれていたのだけど、どれもスマホが2台必要みたいに書かれていたので、1台でできる方法を書きます。今回はiphoneの場合です。簡単）

※基本的なセットアップは[公式ページ](https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=202189140)を参照

1.上記のページではスマホなどにアプリをDLして設定する方法が書かれているが、PCで[ここ](https://alexa.amazon.co.jp)にアクセスする
2.下記左下の「設定」欄を選択
![Kobito.Ea0xjU.png](https://qiita-image-store.s3.amazonaws.com/0/41877/e16ebef9-3858-3234-dae4-0429a1fb2663.png "Kobito.Ea0xjU.png")
3.テザリングでネット接続したいEcho or Echo Dot端末を選択
4.「wifiの更新」（まだその端末に対してwifi設定一度もやったことない場合は違う文言かも）を選択すると下記のような表示になるはず。
![Kobito.gMV8ui.png](https://qiita-image-store.s3.amazonaws.com/0/41877/d96cd52e-1bdc-27c2-8341-eb7ca9c10c81.png "Kobito.gMV8ui.png")

5.iphoneの「設定」→「インターネット共有」からテザリングをONにしておく
6.手順に従いPCのwifiをAmazon-ESGにつなげる（これでPCとEcho DotがつながりEcho Dotの設定をPCで行うことができるようになる）
![Kobito.Ny8Asb.png](https://qiita-image-store.s3.amazonaws.com/0/41877/03dfd99b-8aee-2dff-ac8f-e42261116555.png "Kobito.Ny8Asb.png")
7.最後に、wifiネットワークを選択する画面（これはEcho Dotとどのwifiをつなげるかの選択になる）でiphoneのネットワークを選択する。僕の場合は、◯◯のiPhone（◯◯のところは自分の名前）になる。必要であれば（ていうか必要にした方が絶対良い）パスワードを入力して完了
Photos.frameworkで画像を保存して保存先を取得

## 概要
画像を保存するために、これまで`UIImageWriteToSavedPhotosAlbum`を利用していましたが保存先のURLが欲しくなったので他の方法を調査。
`ALAssetsLibrary`を利用すれば簡単に保存先が取得できるが、これはiOS9からdeprecated。
そのため`Photos.framework`を使う必要があったが、通常の方法ではパスが取得できなかった。

## 実装
参考 : [How to get the URL of an image just added in PHPhotoLibrary
](https://stackoverflow.com/questions/30196969/how-to-get-the-url-of-an-image-just-added-in-phphotolibrary)

```swift
var localId:String?
PHPhotoLibrary.shared().performChanges({
    let request = PHAssetChangeRequest.creationRequestForAsset(from: result)
    localId = request.placeholderForCreatedAsset?.localIdentifier
}, completionHandler: { (granted, error) in
    DispatchQueue.main.async {
        if let localId = localId {
            let results = PHAsset.fetchAssets(withLocalIdentifiers: [localId], options: nil)
            if results.count > 0 {
                let asset = results.firstObject
            }
        }
    }
})
```

ここまでやって、ようやくPHAssetを取得できるのであとは以下のようなextensionを使って取得する。なんでこんなに複雑になったのか・・・。

参考 : [How to get URL for a PHAsset?
](
https://stackoverflow.com/questions/38183613/how-to-get-url-for-a-phasset)
以下のコードを、例えば`PHAssetExtension.swift`などのファイルで保存するなり書くなり。

```swift
import Photos

extension PHAsset {

    func getURL(completionHandler : @escaping ((_ responseURL : URL?) -> Void)){
        if self.mediaType == .image {
            let options: PHContentEditingInputRequestOptions = PHContentEditingInputRequestOptions()
            options.canHandleAdjustmentData = {(adjustmeta: PHAdjustmentData) -> Bool in
                return true
            }
            self.requestContentEditingInput(with: options, completionHandler: {(contentEditingInput: PHContentEditingInput?, info: [AnyHashable : Any]) -> Void in
                completionHandler(contentEditingInput!.fullSizeImageURL as URL?)
            })
        } else if self.mediaType == .video {
            let options: PHVideoRequestOptions = PHVideoRequestOptions()
            options.version = .original
            PHImageManager.default().requestAVAsset(forVideo: self, options: options, resultHandler: {(asset: AVAsset?, audioMix: AVAudioMix?, info: [AnyHashable : Any]?) -> Void in
                if let urlAsset = asset as? AVURLAsset {
                    let localVideoUrl: URL = urlAsset.url as URL
                    completionHandler(localVideoUrl)
                } else {
                    completionHandler(nil)
                }
            })
        }
    }
}
```

## 追記
実際にはあとから`PHAsset`を復旧させるつもりでURLが欲しかったんですが、これで取れるのは画像の実態があるfile保存先URLだったのでちょっと違った。
そのため、`asset`の`localIdentifier`を保存して、そこから復旧する形に変更しました。
Growiのバックアップとリカバリの手順

GrowiというWikiシステムがありますが、万が一サーバーが故障した場合これまで蓄積したナレッジが失われてしまいます。
そんな悲しい事態になる前にバックアップとリカバリを試しておくことにします。
なお、手順やスクリプトは我流ですので正常に復旧できなくても責任は持ちません。自己責任でお願いします。

## バックアップ計画を立てる
バックアップ計画を以下のように設定しました。
* 毎日3:00にバックアップを保存する
* バックアップの保存期間は7日間
* バックアップ先はNAS(Synology DS216j)上のフォルダ
* バックアップは自動で行われる


## バックアップ先のマウント
バックアップ先のフォルダをCIFSマウントしておきます。cifsの接続パラメーターはNASによって若干変わることに留意しましょう。

```
# dnf install samba-client cifs-utils
# mkdir /mnt/backup
# mount.cifs -o "soft,vers=2.0,username=ユーザー名,password=パスワード" //NASのIPorFQDN/backup /mnt/backup
# touch /mnt/backup/testfile     ※バックアップ先にファイルを書き込めるか確認
# rm /mnt/backup/testfile
# cp -p /etc/fstab /etc/fstab.bak
# vi /etc/fstab
```

```:/etc/fstab
※追記
# NAS Mount
//NASのIPorFQDN/backup /mnt/backup soft,vers=2.0,username=ユーザー名,password=パスワード 0 0
```

## パラメーター設定をバックアップ
Growiパラメーター設定ファイルをバックアップします。この中にパスワードシード値も入っているので忘れずに保存しなければなりません。シード値を紛失した場合、**リカバリ後にGrowiにログインできなくなります。**
Growiのバージョンも控えておいたほうが良いです。

```
# cp -p /etc/sysconfig/growi /mnt/backup/growi-params
# echo "GROWI-VERSION=バージョン番号" >> /mnt/backup/growi-params
```


## バックアップタスクの作成
バックアップを自動化するためのタスクを作成します。

```shell-session:
# cd /root     ※任意の場所
# vi growi-backup.sh
# chmod u+x growi-backup.sh
# crontab -e
```

```:growi-backup.sh
#!/bin/bash
INSTALL_PATH=/root/growi     ※Growiの配置場所
BACKUP_PATH=/mnt/backup
TODAY=`date +"%Y%m%d"`

tar -C ${INSTALL_PATH}/public -cf ${BACKUP_PATH}/${TODAY}.tar uploads
mongodump -d growi --gzip --archive=/tmp/dbdump.gz --quiet
tar -C /tmp -uf ${BACKUP_PATH}/${TODAY}.tar dbdump.gz
gzip -f ${BACKUP_PATH}/${TODAY}.tar
rm -fR /tmp/dbdump.gz

find ${BACKUP_PATH} -name "*.tar.gz" -mtime +7 -delete
```

```:crontab
#追記
0 3 * * * /root/growi-backup.sh
```

以上でGrowiのバックアップ設定が完了です。あとは普通にGrowiを使いましょう。


## リカバリをしなければならなくなりました！
サービスしていたサーバーが完全に破損してしまいました。起動すらできません...
というシチュエーションを想定してリカバリ作業に入ります。


## Growiの空セットアップ
Growiを構築します。この時点ではGrowiを起動しないようにして下さい。
なお、バージョン情報とシード値はバックアップ元と同じものにする必要があります。

### 誤ってGrowiを起動してしまった場合
余分なDBが作成されてしまうため復旧に失敗します。次のコマンドでDBを削除して下さい。

```
# systemctl stop growi
# mongo
> use growi;
> db.dropDatabase();
> quit();
```

## バックアップデータの展開
バックアップデータをSCPなどを使ってサーバー上にコピーし、展開しておきます。

```
# tar xzf 20190630.tar.gz
```

## アップロードファイルの配置
バックアップデータから展開された`uploads`フォルダを配置します。

```
# mv uploads /root/growi/public/
```


## データベースのリカバリ
ダンプファイルから復元します。

```
# mongorestore --gzip --archive=dbdump.gz -d growi
```

## Growiの起動と確認
これでリカバリが完了しました。あとはGrowiを起動して動作確認を行いましょう。

```
# systemctl start growi
```
jQuery指定要素を加える時の場所指定


# jQueryの場所指定

## 通常(中の最後)

```
$("div.box").append(elem);
```

## 中の最初

```
$("div.box").prepend(elem);
```

## 隣接要素(前と後)

```
$("div.box").after(elem);
$("div.box").before(elem);
```
レールに乗った日付フォーマット

個人的なメモとして残しておく

## レールに乗った日付フォーマット


config/initilizersの下に`time_formats.rb` を作成する

作成したら下記のようにフォーマットを指定する

```ruby
Time::DATE_FORMATS[:default] = '%Y/%m/%d %H:%M'
Time::DATE_FORMATS[:datetime] = '%Y/%m/%d %H:%M'
Time::DATE_FORMATS[:date] = '%Y/%m/%d'
Time::DATE_FORMATS[:time] = '%H:%M:%S'
Date::DATE_FORMATS[:default] = '%Y/%m/%d'
```

ここまでできたらDBから取得した`create_at` とか`updated_at` との値に`.to_s` をつけるとフォーマットできます


自分はモバイルアプリにJsonを返すときにこの方法を使いました

```ruby

    def format_json result_list

      list = []

      result_list.each do |item|
        item = {
          id: item.id,
          title: item.title,
          icon: item.icon,
          make_user: item.make_user,
          created_at: item.created_at.to_s,
          updated_at: item.updated_at.to_s
        }

        list.push item
      end

      list
    end
```

誰かの力になれば
Javascriptで、階層的な連想配列を作りたい。


# 画像のsrcとaltを複数入れる配列を作りたくなった。

## 求めているもの

```js:tes.json
[
 { 
   src : 'hogee.jpg',
   alt : 'hodehode'
 },
 { 
   src : 'hogegege.jpg',
   alt : 'hodehode2'
 }
]
```

これを配列のように作る。

## 作り方

tempみたいな変数用意して、そこに作って、いれる。

```js
var data = {};
var temp = {};
temp.src = "hoge.jpg";
temp.alt = "hogehoge";
data[data.length] = temp;
```

これの繰り返し。

## 配列としてforeachにぶち込みたい

最終的にこれをやるから、この形式で格納したいのだと思う。

```js.js
Object.keys(data).forEach(function(key) {
  if(data[key].src){
     console.log(data[key].src);
     console.log(data[key].alt);
  }
});
```
What The Effectual Steps Are For Outsource Mobile App Development? 

Outsource mobile app development is the most appreciated method, admired by many of the businesses. Moreover, several businesses have been embracing a multi-source model for mobile app development. In multi-source model some of the work is outsourced outdoors, a portion of it is complemented by in-house team and rest is left to a hybrid cloud environment https://goo.gl/JiHRvj 

  ![outsource-app-development-banner.jpg](https://qiita-image-store.s3.amazonaws.com/0/178336/5330503b-cd1d-44a9-7a44-99c4619cee0d.jpeg)
ldapのログが欠損してるらしいログがmessagesに出てるのを見た

大分前のやつですが未投稿の下書きが多すぎるとかで投下。
こんな↓感じのログをみたので対応したことを記録しておきます。

```
$ sudo view /var/log/messages
Feb 29 03:45:37 ldap1 rsyslogd-2177: imuxsock begins to drop messages from pid 2319 due to rate-limiting
Feb 29 03:45:45 ldap1 rsyslogd-2177: imuxsock lost 5663 messages from pid 2319 due to rate-limiting
```

pidがldapでした。
これldapよりリモートからwafのログとか受けるときに致命的なやつかも？とも思ったんですが
影響するのはネットワーク経由で受けてるログではなくローカルのログっぽいです。

[(ヽ'ω`) < rsyslogでimuxsockなんとかってメッセージが出る - (ヽ´ω`) < *****](http://www.tsugihagi.net/entry/2014/09/29/111823)

当のldap.logをみるとindexついてないぜというのがいっぱい出てたのでindex追加対応などを行いログの量はだいぶ減ったんですがまだ出てたんで非同期にしてみました。（以下のようにマイナスつけてrsyslogリスタートしただけ）


```
$ diff /etc/rsyslog.conf{,.`date +%Y%m%d`}
81c81
< local4.*                                                -/var/log/ldap.log
---
> local4.*                                                /var/log/ldap.log
```

[OpenLDAPによるディレクトリサーバ運用（5）：ビシッと決めるチューニング：しっかり基本編 (3/3) - ＠IT](http://www.atmarkit.co.jp/ait/articles/1006/21/news102_3.html)

とりあえずこんなところで失礼します。
Elixir／Phoenixで列・テーブルを削除したらコード修正／削除をお忘れなく

mix ecto.migrate等で、列削除やテーブル削除をマイグレーションした際、以下は自動削除されないので、手動の修正／削除をお忘れなく

```
lib/【PJ名】_web/templates/【スキーマ名】/form.html.eex
lib/【PJ名】_web/templates/【スキーマ名】/index.html.eex
lib/【PJ名】_web/templates/【スキーマ名】/show.html.eex

lib/【PJ名】_web/views/【テーブル名】_view.ex

lib/【PJ名】_web/controllers/【テーブル名】_controller.ex

lib/【PJ名】_web/router.ex

lib/【PJ名】/【コンテキスト名※】/【コンテキスト名】.ex
lib/【PJ名】/【コンテキスト名※】/【スキーマ名】.ex

test/【PJ名】_web/controllers/【テーブル名】_controller_test.exs
test/【PJ名】/【コンテキスト名】/【コンテキスト名】_test.exs
```

なお、1つのコンテキスト名で、複数回のphx.gen.html／jsonを行うと、lib配下の【コンテキスト名】.exやtest配下の【コンテキスト名】.exsのファイルに、DB操作関数群がアペンドされるので、「alias 【PJ名】.【コンテキスト名】.【スキーマ名】」で始まり、次の「alias 【PJ名】.【コンテキスト名】.【スキーマ名】」が始まる前までを削除すること

※コンテキスト名＝mix phx.gen.html／jsonで最初に指定する引数
xlwings.App 簡易リファレンス

# はじめに

これは xlwings 0.11.5 [本家xlwings.Apps](http://docs.xlwings.org/en/stable/api.html#apps) [本家xlwings.App](http://docs.xlwings.org/en/stable/api.html#app) の簡易日本語リファレンスである。

# xlwings.Apps

Apps は全アプリ実行環境(Excelのインスタンス)を管理する。
VBA に相当するものはない？

```python
import xlwings as xw
apps = xw.apps        # アプリ実行環境管理インスタンスを返す
apps.active           # アクティブAppインスタンスを返す VBA:ActiveWindow
apps.add()            # 新規Appインスタンス作成し返す
apps.count            # Appインスタンス数を返す
apps[0]               # Appインスタンスを返す
apps(1)               # Appインスタンスを返す
```

# xlwings.App

App は単一のアプリ実行環境(Excelのインスタンス)を管理する。
[VBA:Application](https://msdn.microsoft.com/ja-jp/vba/excel-vba/articles/application-object-excel) に相当する。

```python
app = xw.App(visible=None, add_book=True) # 新規アプリ実行環境を作成する
app.activate(steal_focus=False)           # アクティブ実行環境にする

app.calculate()                 # 計算を行う
app.calculation                 # RW 計算動作を設定する 'manual' 'automatic' 'semiautomatic'

app.display_alerts              # RW 警告表示するか設定する

app.macro('マクロ名')            # VBAマクロ操作用のインスタンスを返す
app.selection                   # 選択している Range インスタンスを返す VBA:ActiveCell
app.books                       # xw.Books() を返す
app.range(...)                  # xw.Range(...) を返す

app.screen_updating             # RW 描画更新を行うか設定する
app.visible                     # RW 表示非表示 True False

app.hwnd                        # HWND を返す
app.pid                         # PID を返す
app.kill()                      # アプリ実行環境を強制終了させる
app.quit()                      # アプリ実行環境を終了させる

app.version                     # Excel のバージョンを返す
app.api                         # ネイティブインスタンスを返す
```

## マクロ呼び出し

App, Sheet, Book, Range は api プロパティーでネイティブインスタンスをマクロ引数にする事が出来る。

```python
bk = xw.Book()
fn = app.macro('Func')          # 厳密に指定する場合は 'ブック名!シート名.関数名' となるハズ
fn(bk.api, 'a1')
```

```vbnet
Function Func(bk as Workbook, cellname as String)
    ...
End Function
```

# その他

Excel 2010 において同じ xw.App インスタンスへの操作を繰り返すと OLE 操作が正しく行えないケースが発生した。 長時間安定動作が必要なケースではインスタンスを長く使わない事。
jQueryで読み込んでから処理を開始

## 何で読み込み完了後に処理を行うのか。
ブラウザは、HTMLを読みながら基本的に上から順に処理していく。
なので、scriptが先に書かれていて、HTMLのパーツ(DOM要素という。`<input type="text">`とか)の読み込みが終わっていないと、エラーを出してしまう。

こんな感じ。

```html
<html>
<head>
<script>
    document.testform.textbox.value="hoge";
</script>
</head>
<body>
    <form name="testform">
        <input type="text" name="textbox" value="" />
    </form>
</body>
</html>
```

## 読み込み完了後に処理したい場合の書き方
```html
<html>
<head>
<script>
    window.onload = function () {
        document.testform.textbox.value="hoge";
    };
</script>
</head>
<body>
    <form name="testform">
        <input type="text" name="textbox" value="" />
    </form>
</body>
</html>
```
こうすることで、onload(読み込み完了)後に実行される

## jQueryでもうちょっと細かく制御
jQueryで読み込み完了後に実行するように書こうとすると、以下の3パターンがある。

```js
$(function() {});
$(document).ready(function(){});
$(window).on('load', function() {});
```

ちなみに、少し古い記事だと`$(window).load(function () {});`が紹介されていたりもするが、こちらは非推奨とされている。バージョン3.0以降だと存在すらしないので注意。

このうち、`$(function() {});`は`$(document).ready(function(){});`の省略形なので実質は同じ。
では、`$(document).ready(function(){});`と`$(window).on('load', function() {});`で何が違うのか。

+ readyは、DOMが読み込まれた直後
+ loadは、ブラウザに表示された直後

となる。その違いを確認するには以下。

```html
<html>
<head>
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
$(window).on('load', function() {
    console.log("load");
});
$(document).ready(function(){
    console.log("ready");
});
</script>
</head>
<body>
    <img src="https://www.google.co.jp/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" />
</body>
</html>
```

Googleのロゴ画像を表示させるだけのHTMLで、それぞれの実行結果としてコンソールに文字列を表示している。
実行してみると、*ready* -> *load* の順で表示されるはずだ。

1. DOMの読み込み
2. ready実行
3. 画像読み込み
4. load実行

## 使い分け
では、jQueryの2種類はどう使い分けるのか。
自分は、 **明確な目的がある場合はload** とし、 **基本はready** という捉え方をしている。
実行順序の早さから、readyであれば重たい画像を読み込む場合でも影響を受けない。

しかし、**画像を読み込んでからでないと困る** というケースもある。
例えば、画像の大きさに合わせてdivの高さを変更したい、といった場合。
readyで書いてしまうと、プログラムが実行されるタイミングでは画像はまだ読み込めていないので、画像サイズの取得ができない。
こういった **読み込んだ後のものを使う** 場合はloadで、という感じだ。

## サンプル
いらないと思うけれど、Qiitaへの投稿と共にGitHubも使ってみることにしたので、サンプルソースを置いてみた。
[GitHub→](https://github.com/akihikoikeda/sample001)
RTL8196CのMIB


|アドレス|ポート|内容|サイズ|
|:--|:--|:--|:--|
|0xbb801100|0|OFFSET_IFINOCTETS|64bit|
|0xbb801108|0|OFFSET_IFINUCASTPKTS|32bit|
| | | |
|0xbb801180|1|OFFSET_IFINOCTETS|64bit|
|0xbb801188|1|OFFSET_IFINUCASTPKTS|32bit|
| | | |
|0xbb801800|0|OFFSET_IFOUTOCTETS|64bit|
|0xbb801808|0|OFFSET_IFOUTUCASTPKTS|32bit|
| | | |
|0xbb801880|1|OFFSET_IFOUTOCTETS|64bit|
|0xbb801888|1|OFFSET_IFOUTUCASTPKTS|32bit|
| | | |

CPU PORTのMIBは無いようです。

RTL8196Cのコードはbootのコード、REALTEKの2002のLinuxコード、REALTEKの2009のLinuxコード、OpenWRTのコードなどがありますが、bootのコードにはMIBの定義はありません。

mrubyから拾えるようにしてみました。定義は[mruby-rtlbm-rtl8196c](https://github.com/yamori813/mruby-rtlbm-rtl8196c)に入れました。
conoha sshd スタートアップスクリプト

conoha はサーバーをコピーすると sshd が一部リセットされる。


・ROOTログインの許可
・鍵認証しなくてもOKに

これは困る。非常に困る。
しかも絶対気づかんし。
ということでサーバーコピーする際に、スタートアップスクリプトに以下を追加

```

#cloud-config

runcmd:
  - sed -i /etc/ssh/sshd_config -e "s/PermitRootLogin yes/PermitRootLogin no/g"
  - sed -i /etc/ssh/sshd_config -e "s/PasswordAuthentication yes/PasswordAuthentication no/g"
  - systemctl restart sshd


```

上から順に
・ROOTログイン許可しないよ
・パスワードダメよ。鍵認証じゃなきゃダメよ。
・sshd再起動 (設定再読込だよ)

って感じ。
最新のCUDAでTensorflowを動かす(最終更新2018.4)

私的メモです．
文調も自分に言い聞かせる感じです．
とある人に見せて欲しいといわれたので公開しています．

***
mac対応の最新CuDNNは`cuDNN v7.0.4 (Nov 13, 2017), for CUDA 9.0`らしい
https://developer.nvidia.com/rdp/cudnn-download

そこで今回インストールするものは
1. CUDA -> v9.0
2. cuDNN -> v7.04
としよう


ここから`CUDA Toolkit 9.0 (Sept 2017)`をダウンロードしてインストール
https://developer.nvidia.com/cuda-toolkit-archive
ついでにシステム環境設定→CUDA→install Updateを実行


ここから（はじめにアクセスしたサイト）`cuDNN v7.0.4 (Nov 13, 2017), for CUDA 9.0`をダウンロード
https://developer.nvidia.com/rdp/cudnn-download
展開先ディレクトリで

    sudo mv cuda/include/* /usr/local/cuda/include/
    sudo mv cuda/lib/* /usr/local/cuda/lib/
を実行


ここでCUDAが対応するClangのバージョンを確認する．
CUDA 9.1だとXcode8.3.3らしい．今回は9.0だけど9.0については記載ないし8.3.3でいってみよう
http://docs.nvidia.com/cuda/cuda-installation-guide-mac-os-x/index.html


ここからCommand_Line_Tools_Xcode_8.3をダウンロード&インストール
https://developer.apple.com/download/more/
clangのバージョンを上記でインストールしたところにするために

    sudo xcode-select --switch /Library/Developer/CommandLineTools
を実行

#Tensorflowのインストール
    brew install bazel swig
    git clone https://github.com/tensorflow/tensorflow.git
    cd tensorflow

そうしたらここを参考にしてみよう
1.
https://gist.github.com/smitshilu/53cf9ff0fd6cdb64cca69a7e2827ed0f
Remove all align(sizeof(T)) from following filesをやる

2.
https://medium.com/@mattias.arro/installing-tensorflow-1-2-from-sources-with-gpu-support-on-macos-4f2c5cab8186
TensorFlow 1.2 / 1.3 expects a C library called OpenMP......をやる
つまり記事中の↓をやる
I commented out line 98 of tensorflow/third_party/gpus/cuda/BUILD.tpl, which contained linkopts = [“-lgomp”]

3.
CPUのMAVX等々と絡めてコンパイル

    ./configure
    bazel build --config=cuda --config=opt --copt=-mavx --copt=-mfma --copt=-mavx2 --copt=-msse4.1 --copt=-msse4.2 --action_env PATH --action_env LD_LIBRARY_PATH --action_env DYLD_LIBRARY_PATH //tensorflow/tools/pip_package:build_pip_package

最後にパッケージ化とインストール

    bazel-bin/tensorflow/tools/pip_package/build_pip_package  /tmp/tensorflow_pkg
    pip install /tmp/tensorflow_pkg/tensorflow-0.8.0rc0-py2-none-any.whl

ちなみにこれは気にしなくてもいいみたい
確保できるようになるまで使用量を少しずつ減らして（0.9倍ずつして），確保できるよになるまで続けるみたい

    2017-12-15 22:35:52.384597: E tensorflow/stream_executor/cuda/cuda_driver.cc:936] failed to allocate 11.88G (12755840000 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY
    2017-12-15 22:35:52.384718: E tensorflow/stream_executor/cuda/cuda_driver.cc:936] failed to allocate 10.69G (11480255488 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY
    2017-12-15 22:35:52.384815: E tensorflow/stream_executor/cuda/cuda_driver.cc:936] failed to allocate 9.62G (10332229632 bytes) from device: CUDA_ERROR_OUT_OF_MEMORY
[読書メモ]リファクタリング - タイプコードの置き換え（振る舞いに影響を与えるタイプコードの場合）- 2

# What? Stateパターンとは？
https://qiita.com/takutotacos/items/654e204d618d2059de7f
要はこれと似たことをやるためにあります。

↑をやりたいけど、タイプコードがオブジェクトの生存期間中に変化する時にこのパターンを使用します。
タイプコードの変更にも対応できる `サブクラス化`です。

# How? どうやるか？
```変更前.java
class Employee {
    static final int ENGINEER = 0;
    static final int SALESMAN = 1;
    static final int MANAGER = 2;

    private int type;

    public Employee(int type) {
        this.type = type;
    }

    int payAmount() {
        switch (type) {
            case ENGINEER: return monthlySalary;
            case SALESMAN: return monthlySalary + commission;
            case MANAGER : return monthlySalary + bonus;

        }
    }
}
```
上記のswitch文を取り除きたいです。そのために、以下のような実装を行います。

```変更後.java
class Employee {
    private EmployeeType type;

    int getType() {
        return type.getType();
    }

    void setType(int type) {
        this.type = EmployeeType.newType(type);
    }
}

abstract class EmployeeType {
    public static final int ENGINEER = 0;
    public static final int SALESMAN = 1;
    public static final int MANAGER = 2;

    static EmployeeType newType(int code) {
        switch (code) {
            case EmployeeType.ENGINEER: return new Engineer();
            case EmployeeType.SALESMAN: return new Salesman();
            case EmployeeType.MANAGER : return new Manager();
            default: throw new IllegalArgumentException("不正な従業員コード");
        }
    }

    abstract int getType();
}

public class Engineer extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.ENGINEER;
    }
}

class Salesman extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.SALESMAN;
    }
}

class Manager extends EmployeeType {
    @Override
    int getType() {
        return EmployeeType.MANAGER;
    }
}
```
この後に、給料計算ロジックをそれぞれのサブクラスに実装すればクライアントクラスからはオブジェクト生成以外では条件分岐がなくなりました。
これなら、サブクラスの種類を増やしてもロジックの実装を忘れることがなくなりそうですね。
オブジェクト生成時に、switch文にサブクラスを追加し忘れてもエラーを吐いて終了してくれるので実装忘れを認識しやすいというデバッグのしやすいプログラムになりました。
MMD4Mecanimをgithubに上げたら「DMCA takedown」が来た


[MMD4Mecanim](http://stereoarts.jp/)を使ったプロジェクトをgithubに公開リポジトリとして上げたら、[DMCA(デジタルミレニアム著作権法)](https://help.github.com/articles/dmca-takedown-policy/)に引っかかった

24時間以内に[履歴ごと削除](https://help.github.com/articles/removing-sensitive-data-from-a-repository/)しないとリポジトリが凍結されるとのこと


次回からはあらかじめignoreしておこう

```md:.gitignore
Assets/Libraries/MMD4Mecanim/
Assets/Libraries/MMD4Mecanim.meta
Assets/Libraries/BulletXNA/
Assets/Libraries/BulletXNA.meta
Assets/Models/Chara/MMD/
Assets/Models/Chara/MMD.meta
```

`MMD4Mecanim`と`BulletXNA`はignoreする
MMDモデルも文句をつけられると嫌なのでignoreする

![スクリーンショット 2018-01-23 14.45.11.png](https://qiita-image-store.s3.amazonaws.com/0/136286/c1b74f13-d3da-9978-f921-9ac50b703fb1.png "スクリーンショット 2018-01-23 14.45.11.png")
[読書メモ]リファクタリング - タイプコードの置き換え（振る舞いに影響を与えるタイプコードの場合）- 1

# （What）振る舞いに影響を与えるタイプコードとは？
例えば、こんな感じ。

```振る舞いに影響を与えるタイプコード.java
public int getPayAmount() {
    switch (getType()) {
        case ENGINEER:
            return getMonthlySalary();
        case SALESMAN:
            return getMonthlySalary() + getCommission();
        case MANAGER:
            return getMonthlySalary() + getBonus();
        default:
            return 0;
    }
}
```

タイプコードを判定し、それの結果によって異なるコードを実行している箇所です。
だいたい`if - else` や`switch`文が今回題材とする箇所に該当します。

こういうコードを見たらやりたいことは↓の通りです。
1. タイプコードをポリモーフィックな振る舞いを実現する継承構造で置き換える
2. ポリモーフィズムで条件分岐を置き換える


# （Why）なぜ置き換えるのか？
タイプコードの判定結果によってそれぞれ異なる処理をしている箇所を置き換えようとしているわけですが、これの利点は↓

```
★異なる条件での振る舞いについての知識をクライアントから取り除くことができる。
    => その結果、新たなバリエーションを追加する時には、バリエーションの追加だけで対応できるようになる。
    => ポリモーフィズムがないと、現在ある条件分岐全てを探して、それぞれ処理を追加しないといけない。
        => これは、追加漏れが発生する可能性を示唆し、不具合発生の温床となる
```

# （How）どう置き換えるのか？
## サブクラスによる置き換え

```変更前.java
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    switch (requestCode) {
        case REQUEST_CODE_FOR_EVALUATION_SEND:
　　　　　　　　　　　　　　　　　　　　　　　// 何かの処理
            break;
        case REQUEST_CODE_FOR_SMS_SEND_ACTIVITY:
　　　　　　　　　　　　　　　　　　　　　　　// 何かの処理
            break;
        case REQUEST_CODE_FOR_CAMERA_USAGE:
　　　　　　　　　　　　　　　　　　　　　　　// 何かの処理
            break;
        default:
    }
}
```

```変更後.java
class ActivityResult {
    public static final int REQUEST_CODE_FOR_EVALUATION_SEND = 1;
    public static final int REQUEST_CODE_FOR_SMS_SEND_ACTIVITY = 2;
    public static final int REQUEST_CODE_FOR_CAMERA_USAGE = 3;

    static ActivityResult create(int requestCode) {
        switch (requestCode) {
            case REQUEST_CODE_FOR_EVALUATION_SEND:
                return new ActivityResultEvaluationSend();
            case REQUEST_CODE_FOR_SMS_SEND_ACTIVITY:
                return new ActivityResultSmsSend();
            .. // 他のコードについても同様
        }
    }

    private ActivityResult() {}

    abstract int getRequestCode();
}

class ActivityResultEvaluationSend extends ActivityResult {
    @Override
    public int getRequestCode() {
        return ActivityResult.REQUEST_CODE_FOR_EVALUATION_SEND;
    }
}

class ActivityResultSmsSend extends ActivityResult {
    @Override
    public int getRequestCode() {
        return ActivityResult.REQUEST_CODE_FOR_SMS_SEND_ACTIVITY;
    }
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    ActivityResult result = ActivityResult.create(requestCode);
    // @todo resultに処理を実装する。
}
```
これで、サブクラスによる置き換えができました。
これはやりたかったことの最終形ではなく、この後にポリモーフィズムになったので各サブクラスにそれぞれの処理を実装することになります。
しかし、それは別で書こうと思います。
# xlwings 簡易リファレンス

# はじめに

[本家xlwingsドキュメント](http://docs.xlwings.org/en/stable/api.html#object-model) で十分なのと VBA との差があまり無い作りな為  VBA と Python を知っていたら資料的価値は高くない。 ただ VBA のメンテナンスで心が折れた事と Excel オジサンの如くこき使われたので、身の回りの人にもある程度把握出来るよう簡易リファレンスを残す事にした。 可能ならオジサンと立場を変わってもらえれば幸いである。

# 動作環境の用意

xlwings は Excel を OLE で操作するため動作には Excel が必要である、Excel を用意出来ない状況では openpyxl などを利用すると良いだろう。

xlwings を Windows 上で動作させるには xlwings pypiwin32 comtypes のモジュールが必要である、 Python のパスが通っている状態であれば次のようにすると良いだろう。 詳しくは [本家インストール説明](http://docs.xlwings.org/en/stable/installation.html#installation) を参照の事。

```bat
pip install xlwings pypiwin32 comtypes
```

実際に Excel から Python スクリプトを呼び出すには [本家アドイン説明](http://docs.xlwings.org/en/stable/addin.html#xlwings-addin) を参照の事。 [本家クイックスタート説明](http://docs.xlwings.org/en/stable/addin.html#workbook-config-xlwings-conf-sheet) は環境差を設定シートで指定する、複数環境で実行する際は煩雑になるのでお勧めしない。

Python からファイル選択ダイアログを表示させ呼び出し元 Excel ファイルを選択してしまうと **OLE が固まってしまう** 為、私はアドインもクイックスタートも使わず以下を利用している。 この python.bat 内では利用する Python の決定とモジュールの追加と実行結果表示を担っている。

```vbnet
Sub PythonGoing(cmd As String)
    cmd = "%COMSPEC% /C " & ThisWorkbook.Path & "\python.bat" & " " & cmd
    Dim wsh As Object
    Set wsh = CreateObject("WScript.Shell")
    wsh.Run cmd, 0, False
    Set wsh = Nothing
End Sub
```

* xlwings の RunPython を使った場合はログ出力等の位置が衝突するので複数実行は考慮していないと思われる。 この様なバッチはその問題も回避できると考えている。
* 複数実行時にはカットバッファを使用しないように注意の事。

# クラス索引

| クラス | 内容 |
|-------|------|
| [xlwings.App](https://qiita.com/m5knt/items/724358997c6f384ec385) | 実行環境(Excelインスタンス) |
| [xlwings.Book](https://qiita.com/m5knt/items/d0548ac34f7833c4eb33) | ワークブック |
| [xlwings.Sheet](https://qiita.com/m5knt/items/85d42c345fb6ce44d6dd) | ワークシート |
| [xlwings.Range](https://qiita.com/m5knt/items/a71faf6ff256f1d1ae5f) | 範囲 |
| [xlwings.Name](https://qiita.com/m5knt/items/13c7b6cf2c4b7ab06d4c) | 名前付き範囲 |
| [xlwings.Chart](http://docs.xlwings.org/en/stable/api.html#charts) | 本家チャート |
| [xlwings.Picture](http://docs.xlwings.org/en/stable/api.html#pictures) | 本家画像 |
| [xlwings.Shape](http://docs.xlwings.org/en/stable/api.html#shapes) | 本家シェイプ |

| 引数凡例 | 内容 |
|---------|-------|
| ...     | 何かしらの有効な指定を示している |
| 文字列   | 例程度の文字列 |
| 数値     | 例程度の数値 |
| 英単語   | 目的が理解出来る程度の単語で実際名とは限らない |

# VBA機能呼び出し

api プロパティがあるクラスはネイティブの機能を呼び出すことが可能である。 これにより xlwings がサポートしていない機能も利用する事が出来ので多くの VBA を Python と xlwings で置き換える事が出来る。 実際の Excel を利用するためバグも互換である。 ただ VBA のオブジェクトをラップしているだけなら VBA で良いと思われるだろう... **黙れ！**

例

```python
rng1 = xw.Range('a1')
rng2 = xw.Range('a2')
rng1.api.Copy(rng2.api)
```
VBA で利用される xl～ 等の定数は xw.constants.～ に定義されている。

# openpyxlから移行する時のヒント

## 使用範囲の取得

```python
# openpyxl
import openpyxl as px
wb = px.load_book('ブック名')
rows = wb['Sheet1'].rows

# xlwings
import xlwings as xw
wb = xw.Book('ブック名')
ws = wb.sheets['Sheet1']
ur = ws.api.UsedRange.Row + ws.api.UsedRange.Rows.Count
uc = ws.api.UsedRange.Column + ws.api.UsedRange.Columns.Count
rows = ws.range((1, 1), (ur, uc)).rows
```
[読書メモ]リファクタリング - タイプコードの置き換え（振る舞いに影響しないタイプコードの場合）

# （What）タイプコードとは何か？
```タイプコードを使っている.java
class Person {
  public static final int O = 0;
  public static final int A = 1;
  public static final int B = 2;
  public static final int AB = 3;

  private int bloodGroup;

  public Person(int bloodGroup) {
    this.bloodGroup = bloodGroup;
  }  
}

// ↓クライアントコード
public static void main(String[] args) {
  Person jason = new Person(Person.O);
}
```

例えば上のソースで`public static final`で指定されている値のこと。

# （Why）なぜ置き換えるのか？
例えば、さきほどの`タイプコードを使っている`で示したソースの例でいうと、`Person`クラスのコンストラクタには`int`型がくることは宣言されています。
しかし、それ以上の制約は与えられていません。

ソースを書いた人にとっては、`public static final`で宣言している値のどれかがくるのは明白ですがコンパイルする時には、例えば以下のように書いても正常にコンパイルできてしまいます。
```タイプコードだとプログラムの安全性が保証できない例.java
public static void main(String[] args) {
  Person jason = new Person(1000);
}
```

このコードは予想外の値を渡されているので、どこかでエラーを起こすでしょう。
しかしこの代入が行われた箇所では、バグに気づきません。
コンストラクタが求めている`int`型が渡されているためです。

逆に言えば、コンパイル時に型チェックをしてくれる言語であればタイプコードをクラスに置き換えることで、より安全なプログラムを作成することができます。
コンパイラによってチェックすることが可能になり、妥当なオブジェクトのみ作成されることが保証されるようになるからです。

# （How）タイプコードを置き換える方法？

## クラス（enum）による置き換え

```タイプコードをクラスで置き換える.java
enum BloodGroup {
    A, B, O, AB
}

public class Person {
    private BloodGroup bloodGroup;

    public Person(BloodGroup bloodGroup) {
        this.bloodGroup = bloodGroup;
    }
}

// ↓client code
public static void main(String[] args) {
    Person jake = new Person(BloodGroup.B);
}
```
RailsでRedisをセッションストアにして、SecureCookieを使う

`config/initializers/session_store.rb`
に以下のような記述を行う。

`development` では非Secure
`production` ではSecureとなる。

```ruby
# Be sure to restart your server when you modify this file.

#Rails.application.config.session_store :cookie_store, key: 'session'

session_key = '_my_application_session'
expires_in = 1.day
redis_server = {
  host: 'localhost',
  port: 6379,
  db: 0,
  namespace: 'session'
}

Rails.application.config.session_store(
  :redis_store,
  key: session_key,
  expires_in: expires_in,
  servers: redis_server,
  secure: Rails.env.production?
)

```
[読書メモ]Software Architecture Patterns - Layered Architecture

# Layered Architectureとは？
- ほとんどの業務アプリケーションで使われている。
- Androidチームでもこれの一種であるClean Architectureを採用している。

# 特徴
- プログラムをいくつかの層に分けます。それぞれの層はそれぞれ異なる役割を持ちます。
    - プレゼンテーション（View）層
    - ビジネスロジック層
    - Persistence層
    - DB層
    - <img title='sapr_0101.png' src='/attachments/ecc99d8a-d7b0-451e-a91a-57f9c86e8c6b' width="1127" data-meta='{"width":800,"height":500}'>
- 層の分離
    - それぞれの層へのアクセスを制限することで、変更に対応しやすくします。
        - 例えば使用するDBをMySQLからMongoに変更してもプレゼンテーション層のプログラムを変更する必要は無いです。なぜなら層をまたいでの問い合わせは、インターフェースを通して行われます。つまり、実装の詳細を知りません。そのため、実装の詳細が変更されてもインターフェースさえ同じなら呼び出し方法は変わらないからです。
        - また、ある層へのアクセスを隣り合う層からのみに限定していれば、影響範囲を最小限に抑えることもできます。（下図参照）
            - 例えば、DBから取得する型が変わったとします。その場合はPersistenceLayerで変更を吸収すれば、理論的にはPresentationLayer、BusinessLayerは修正する必要がないです。
            - <img title='sapr_0102.png' src='/attachments/820a8555-e621-480c-9066-53067910a0f3' width="1354" data-meta='{"width":800,"height":500}'>

# いいところ
- テスト効率が高い。
- 開発効率が高い。
    - 複雑すぎないから。
    - ほとんどの会社で採用されていて、よく知られたパターンだから。
# よくないところ
- パフォーマンスが低い
- スケーラビリティが低い
- アジリティが低い
- デプロイが容易じゃない

# 感想
悪いところたくさんあるけど、デファクトスタンダードなのでこれを知ってるだけで世界が広がりそう。
パフォーマンスに関しては、プログラミングが与える影響はほとんどない（マシン性能に寄るところが大きい）ってどこかで呼んだ気がするのであまりこの選択肢を選ばない理由にはなり得なそう。
スケーラビリティに関しては、開発効率の話とは違うことのようだったので要調査でした。

# 参考
[Software Architecture Patterns by Mark Richards](https://www.safaribooksonline.com/library/view/software-architecture-patterns/9781491971437/ch01.html)
[WIP][読書メモ]リファクタリング - コードの不吉な臭い

# どういうことか？
リファクタリングにはいつ行うべきかに関しては、かっちりとした定義がありません。
そのため、「こういう現象が起きていたら怪しい。」「こういう現象が起きないようにプログラミングする」という指針を持つことが幸せなエンジニアライフを送る鍵になりそうです。

ということで、以下に本書で提示されているコードの不吉な臭い（避けるべきコードの書き方）を列挙していきます。

# ランキング
## 1. 重複したコード
## 2. 長すぎるメソッド
## 3. 巨大なクラス
## 4. 長すぎるパラメータリスト
## 5. 変更の偏り
    一つのクラスが別々の理由でなんども変更されてしまう状況のこと。
    例えばDBを変更するたびにこの３つのメソッドを毎回修正している。さらに金融商品を追加するたびに、毎回この４つのメソッドを変更している。ということが同一クラス内で起きているのであれば、それは別々のメソッドに切り出すべきです。一つの変更に対して一つのクラスが対応するようにした方がいいです。
## 6. 変更の分散
    一つの変更で、あちこち改修する必要がある状況のこと。
    例えば階級によって給与を算出するメソッドがあるとします。switch文で対応する階級ごとの給与算出方法をクライアント側で実装しているとします。この時階級を一つ追加することになったとします。この時変更対象となるのは、クライアントとその階級を管理しているクラスです。なので、一つの変更が複数に波及してしまっていますね。これは、ポリモーフィズムを使えばクラスを一つ追加するだけで済みそうです。
## 7. 特製の横恋慕
    オブジェクト指向には、処理及び処理に必要なデータを一つにまとめてしまうという重要な思想があります。ある処理を行うために、他のクラスに対してgetメソッドをたくさん投げていたら怪しいです。
ただし、このオブジェクト指向の原則に当てはまらないパターンもいくつかあります。その場合の解決策はGoFのStrategyとVisitorパターンがあります。振る舞いを別のクラスとして管理することができるので、振る舞いに対する変更を一つのクラスで吸収できるという利点がある反面、複雑になりがちです。
## 8. データの群れ
    クラスのフィールドやメソッドの引数として頻繁にセットとなって現れるデータたちのことです。それらを見たら、フィールドの場合はクラスを定義することを、メソッドの引数の場合はパラメータオブジェクトを導入することを考えるべきです。

## 9. 基本データ型への執着
    基本データ型というのは`int, boolean`などのことです。ただの値を示しているやつですね。著者はこれを使うことに固執するよりも、その値が表すクラスを作成し、構造体としてデータを表すことを勧めています。

## 10. スイッチ文
    switch文は重複したコードを生み出す問題児です。switch文を見たら、ポリモーフィズムを使ってswitch文を置き換えられないか考えるべきです。ただし、今後も条件が追加されることがないような分岐に対してはこの限りではないです。

## 11. パラレル継承
## 12. 怠け者クラス
    拡張性を見越して作られたが、拡張要求が来なかったりしてそのクラス自体があまり大きな役割をしていない場合を指します。こういったクラスは葬り去りましょう。

## 13. 疑わしき一般化
## 14. 一時的属性
## 15. メッセージの連鎖

## 16. 仲介人
    オブジェクト指向の特徴として、カプセル化という概念があります。カプセル化はしばしば権限の委譲をもたらします。権限の委譲をしているオブジェクトを仲介人といいいます。仲介人としての仕事しかしていないオブジェクトは取り除くことを検討します。
## 17. 不適切な関係
## 18. クラスのインターフェース不一致
## 19. 未熟なクラスライブラリ
## 20. データクラス
    属性とget/setメソッドしかないクラス。これらのクラスは他のクラスからのアクセスを過剰に受けがちになる。
## 21. 相続拒否
    親クラスのフィールドやメソッドの一部しか使用されていないパターン。しかし、大きな問題になることは稀なので、不吉な臭いとしては軽い方。
## 22. コメント
    コメントは不吉な臭いではなく、いい香りです。しかし、コメントがないと理解できないコードというのは、不吉な臭いを発する前兆と考えることもできます。そのため、コメントの代わりにメソッドの抽出、メソッド名の変更を行うことで、コメントが不要になることがあります。
コメントをする内容としては、以下が後々役に立つコメントの内容です。
1. 不明点のメモ
2. なぜその処理をしたのか
[読書メモ]リファクタリング - Nullオブジェクトの導入

# （Why）なぜNullオブジェクトを導入するのか？
NPEはよく起こるエラーの一つです。
それを避けるため、以下のような記述がプロジェクト内でたくさん見られると思います。
```NPE回避.java
if (article != null) {
    doSomthing();
}
```

オブジェクト指向にはポリモーフィズムというものがあって、これは`オブジェクトのタイプに合わせて処理の呼び出しを変える`という条件分岐をなくすためにあります。
Nullチェックは↑の考えに反しているものですね。
それにNullチェックは何度も何度も出てくるので記述するのはつまらないし、ネストが深くなることもあるため読みづらくもあります。

これらの負を解消するために、Nullオブジェクトを導入します。
# （How）どうやるのか？
## 改修前
```改修前.java
public static void main(String[] args) {
    if (article.getImage() == null) {
        showImage("http://localhost:80/place_holder.png");
    } else {
        showImage(article.getImage().getUri());
    }
}

public class Article {
    Image image;

    public Image getImage() {
        return image;
    }
}

class Image {
    String uri;

    public String getUri() {
        return this.uri;
    }
}
```

クライアントがオブジェクトの状態によって処理を変えてしまっているので、ポリモーフィズムの良さを活かせていないですね。
Articleが持っているImageがnullのときの処理の方法をクライアントが知ってしまっているのもよくないですね。

## 改修後
```改修後.java
public class Article {
    Image image;

    public Image getImage() {
        return (image == null) ? Image.newNull() : image;
    }
}

class Image {
    String uri;

    public Image(String uri) {
        this.uri = uri;
    }

    public String getUri() {
        return this.uri;
    }

    protected Image(){}

    public static Image newNull() {
        return new NullImage();
    }
}

class NullImage extends Image {
    public NullImage() {
        super("http://localhost:80/place_holder.png");
    }
}

public static void main(String[] args) {
    showImage(article.getImage().getUri());
}
```
上記のコードで、クライアントコードから条件分岐が消えました。
また、nullの時の処理方法について知っているのがnullオブジェクトのみになりました。
[読書メモ]リファクタリング - 条件記述の分解

# （Why）条件記述をリファクタリングしたい理由
条件記述について書いているコードを見る時、以下の二つを意識する必要があります。
1. 何が起きるか
2. なぜそれが起きるか

つまり条件記述についてのコードを読むのは、脳内メモリを通常よりも多く占有してしまいます。
さらに良くないことに、コードで表現されているのは大抵の場合何が起きるかについてのみです。
そのため、読むのが難しくなってしまうのです。
この二つをコードの上からでも読み取れるようにリファクタリングするのが今回の目的です。

# （How）どうやるのか？
## Before
```.java
// ↓クライアントコード
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
    charge = quantity * winterRate + winterServiceCharge;
} else {
    charge = quantity * summerRate;
}
```

このコードはまず条件分岐のところで、`ある日付より前、もしくはある日付より後`だったらと宣言してます。
それがtrueだったら `charge = 量 * 何らかのpercent + 何らかのサービスチャージ` と宣言しています。
逆にfalseの場合は`charge = 量 * 何らかのpercent`と宣言しています。

何が起こっているのかはわかるのですが、意図が分かりづらいですね。

## After
```.java
// ↓クライアントコード
if (isSummer(date)) {
    charge = getSummerCharge(quantity);
} else {
    charge = getWinterCharge(quantity);
}

boolean isSummer(Date date) {
    return date.after(SUMMER_START) && date.before(SUMMER_END)
}
int getSummerCharge(int quantity) {
    return quantity * summerRate;
}
int getWinterCharge(int quantity) {
    return quantity * winterRate + winterServiceCharge;
}
```

このコードでは、条件分岐、chargeの算出方法それぞれをメソッドに切り出しています。
さらに、メソッド名に何をしているのかという意図を表明することで、クライアントのコードがかなり読みやすくなっています。

ソースコード中のコメントではwhyを書きなさいと言われたことがあります。
しかしこのようにメソッド切り出しなどで、そのコメントを代替できるとプログラムがより読みやすくなりそうです。
（メソッド切り出しなどで適切に意図が表明されていれば、クライアントコード自体の記述量が減ります。そのため理解しないといけないコードの量が少なくなります。切り出されたメソッド内の処理の妥当性は、また別途確認すれば良いので、そこはクライアントコード本体を理解するという段階では必要なくなっていますので）
[読書メモ]リファクタリング - フィールドによるサブクラスの置き換え

# What? そもそもサブクラスとは？
サブクラスは特性を追加したり、振る舞いを変えたりするために作るもの。
例えば、以下のようなケース。
```.java
abstract class Person {
  public abstract String getCode();
  public abstract boolean isMale();
}

class Male extends Person {
  @Override
  public String getCode() {
    return "M";
  }

  @Override
  public boolean isMale() {
    return true;
  }
}

class Female extends Person {
  @Override
  public String getCode() {
    return "F";
  }

  @Override
  public boolean isMale() {
    return false;
  }
}
```

この場合は、性別によって返すコードを変更するためにサブクラスが使われています。
親クラスにアクセサを定義し、サブクラスごとに異なる値を返しています。

# Why?
上記の例では、サブクラスがハードコードされた値をそれぞれ返しています。
これをConstant Methodパターンと言います。

Constant Methodしかないクラスは存在価値が低いです。
Constant Methodで返されるそれぞれの値を親クラスにフィールドを設置することで代替できます。

# How?

```基底クラス.java
class Person {
  String code;
  boolean isMale;
  
  private Person(String code, boolean isMale) {
    this.code = code;
    this.isMale = isMale;
  }

  static Person createMale() {
    return new Person("M", true);
  }
  
  static Person createFemale() {
    return new Person("F", false);
  }
}

// ↓client code
public static void main(String[] args) {
  Person karl = Person.createMale();
}
```
ag(The Silver Searcher)で検索しpecoで更に絞り込みnanoで該当行を開く

[agとpecoとvimの組み合わせ](https://qiita.com/fmy/items/b92254d14049996f6ec3)はあるのに、nanoがなさそうだったので。
けど、nanoさんあんまり需要ないのかな・・・

使ってる人あんまり見ないし、使ってたら珍しがられる。

```zsh:.zshrc
function agnano () {
    nano $(ag $@ | peco --query "$LBUFFER" | awk -F : '{print "+" $2 " " $1}')
}
```

## ポイント
nanoは `nano +<行数> <file名>` という引数を取るらしい。

だから、　`'{print "+" $2 " " $1}'` こうなる。

## 参考URL
https://qiita.com/fmy/items/b92254d14049996f6ec3
https://ubuntuforums.org/showthread.php?t=1005737
KFAS dlm パッケージの比較 [状態空間モデリング]

# KFAS, dlmパッケージについて
状態空間モデルのパッケージであるdlm, KFASパッケージについて日本語記事が少ないのでわかる範囲でまとめてみた。
間違ってる部分はコメントをお願いします。

## KFAS vs dlm
### KFASパッケージとdlmの主な違いについて
#### 1. 使用できる分布について
* dlmでは分布が正規分布しか選べない
* KFASではさまざまなものが選べる。
 
 * 以下5種を選ぶことが可能
 * 正規分布、ポアソン分布、2項分布、ガンマ分布、負の二項分布
 * 分布の詳細は[CRAN](https://cran.r-project.org/web/packages/KFAS/KFAS.pdf)をご覧ください。（p.16-p.17あたりにのってます）


#### 2. 予測できるものについて
* dlmでは回帰成分(dlmModReg)を用いた場合 将来予測ができない。
 * 信用区間が必要ない場合[こんな方法](https://stats.stackexchange.com/questions/5090/gaussian-state-space-forecasting-with-regression-effects)で1期先は予測できる。（カルマンフィルタを用いて1期先の状態を推定する）
* KFASでは可能

#### 3. 分散パラメーターの推定について
* dlm自動で可能
* KFASではARの係数等はupdate関数を別途記述する必要がある

主だった違いは以上のようになります。
時間があるときに予測周りと分散パラメータ周りの記事を書こうかなと思います。
[扱いにくいコードについて考える]条件分岐を単純化するために

# 条件分岐のせいで可読性が落ちるとき
条件分岐があると読みにくくなるパターンは以下のどれかだと思います。
1. 条件が何を意味しているのかわからない。
2. 条件分岐が連発して、ネストが深くなりすぎている。

# 条件分岐があることによる、可読性の低下を救う方法
条件分岐を単純化するための方法はいくつかあります。
これに対して、条件分岐を単純化するための方法は
1. 条件の意図を伝える
2. 以下のいずれか、またはいくつか組み合わせてネストを解消する。
    - アーリーリターン
    - ガード節
    - ポリモーフィズム

## 条件の意図を伝えるとは
まず、以下のコードを見てください。
```条件分岐の意図がわからないので、読みにくい
if (isNobodyInTheOffice() 
    && isOfficeHour() 
    && isPhoneRinging() 
    && person.isClosestToThePhone()) {
  person.stopWorking();
  person.getOffChair();
  person.moveToByThePhone();
  person.takeThePhone();
}
```

条件分岐の内容はメソッド名から内容がわかりやすいですが、条件分岐のところは非常にわかりにくいですね。
この理由は、条件が複数あること、意図がしていることがわからないことが挙げられると思います。（条件が複数なくても、意図がわからないと可読性が低い場合は後述）

上記のプログラムは、条件をメソッド化してしまい命名で意図をわかりやすくすると可読性が向上します。
```条件分岐の意図がわかるので、読みやすい
if (shouldTakePhoneCall()) {
  person.stopWorking();
  person.getOffChair();
  person.moveToByThePhone();
  person.takeThePhone();
}

private boolean shouldTakePhoneCall() {
    return isNobodyInTheOffice() 
            && isOfficeHour() 
            && isPhoneRinging() 
            && person.isClosestToThePhone();
}
```

なので、処理の意図がわかりにくい場所ではメソッド化して、意図を命名に反映しましょう。

### 条件が複数なくても可読性が低い条件分岐

```
if (user.house.capacity < invitees) {
  user.cancelPreparingHouse();
  user.call(restaurantA);
}
```

特に `>` `<` といった演算子は脳内で処理するのに時間がかかるので、可読性は低くなります。
これも、メソッド化して意図を命名に与えれば解決します。

```メソッド化して、適切な命名をすることで可読性向上
if (isCapacityOver(invitees)) {
    ....
}

private boolean isCapacityOver(int num) {
  user.house.capacity < num;
}
```

## アーリーリターンとガード節
以下のプログラムを見てください。
```ネストが深くてややこしい
double getPayment() {
  double result;
  if (isDead) {
    result = deadAmount();
  } else {
    if (isSeparated) {
      result = separatedAmount();
    } else {
      if (isRetired) {
        result = retireAmount();
      } else {
        result = normalAmount();
      }
    }
  }
  return result;
}
```

```ガード節適用
double getPayment() {
  if (isDead) return deadAmount();
  if (isSeparated) return separatedAmount();
  if (isRetired) return retireAmount();
  return normalAmount();
}
```
ガード節の考え方だと、if - else 構造が使われるべきなのは両者の処理が等しく起こりうる（重要な）時です。
そのため、上記のプログラムで言えば `normalAmount();`が通常系で、それ以外のより少ない確率で発生する処理に関してはアーリーリターンを行うことで異常系であることを示しています。

こうすることで、コードを読むときにどこが一番重要な処理なのかが明示的になり、コードリーディングに強弱をつけられるので負担が減りますね。
また、構文も `if (条件文) return 処理;`というふうに統一がとれているのでより読みやすいです。

## ポリモーフィズム
to be continued...
[読書メモ]リファクタリング - コレクションのカプセル化

# （Why）なぜカプセル化するのか？

以下の理由があります。
1. コレクションを保持するクラスが感知しないところで、クライアントがコレクションデータをできてしまう危険をなくすため
    - 例えば、コレクションの何らかの情報をクラス内部でキャッシュしていたりするときに外部から勝手に変更されると、情報に不整合が発生してしまいますね。
2. カプセル化しない場合は、オブジェクト内部の情報をクライアントに見せすぎているため


https://jmty.kibe.la/@takuto_sugita/528
コレクションのカプセル化も↑で書いたように、クラス内のデータ構造を必要以上に外部に見せないようにすることが目的という点では似ています。


例えば、コレクションをカプセル化していない場合、こんなコードが描かれてしまいます。
```コレクションのカプセル化していない
class Person {
  List<Course> courses;
}

class Course {
  String courseName;
  boolean isAdvanced;
}

// ↓クライアントコード
public static void main(String[] args) {
  Person jack = new Person();
  
  List<Course> courses = new ArrayList<>();
  courses.add(new Course("Java", true));
  courses.add(new Course("Ruby", true));
  courses.add(new Course("Android", false));
  courses.add(new Course("Rails", false));

  jack.setCourses(courses);

  Course python = new Course("Python", false);
  jack.getCourses().add(python);  
  
  Course cooking = new Course("Cooking", true);
  jack.getCourses().add(cooking);  
  jack.getCourses().remove(python);  
}

// ↓上級コースがどれくらいあるかを調べるためのクライアントコード
public int getCountAdvancedCourses(List<Course> courses) {
  int count = 0;

  for (Course c : courses) {
    if (c.isAdvanced()) count ++;
  }
  return count;
}
```

# （How）どうカプセル化するのか？
1. コレクションの操作を防止し、その構造についての不必要な詳細を隠蔽したものを返す
2. コレクションに対するsetメソッドは提供しない
3. 要素を追加・削除する操作が必要

↑のようにすることで、コレクションに対する操作を所有しているオブジェクトがコントロールできるようになります。

## 2. コレクションに対するsetメソッドは提供しない
## 3. 要素を追加・削除する操作が必要
コレクションを初期化する場合は、メソッド名を変更して、決してsetとして使わないという意図を伝える。例えば（initializeCourses(List<Course> courses)）というメソッド名にする。

もしくは、クライアントが単純にコレクションを作ってそれをsetメソッドに渡しているだけの場合は、追加メソッドを使わせることで解決する。
```メソッド名を変更して、setを排除する
public static void main(String[] args) {
  Person jack = new Person();
  
  List<Course> courses = new ArrayList<>();
  courses.add(new Course("Android", false));
  courses.add(new Course("Rails", false));

  jack.initializeCourses(courses);
```

```追加メソッドを使用させて、setを排除する
public static void main(String[] args) {
  Person jack = new Person();
  
  jack.addCourse(new Course("Java", true));
  jack.addCourse(new Course("Ruby", true));
```
## コレクションを変更不可能にする。
コレクションのgetメソッドを以下のように変更します。
```
public List<Course> getCourses() {
  return Collections.unmodifiableList(courses);
}
```

## 振る舞いをクラスに移動する
上級コースがどれくらいあるかを調べるためのコードはかつてはクライアントにありました。
しかし、使用しているデータはPersonクラスのもののみです。
つまり、メソッドをPersonクラスに移動するべきです。

```
class Person {
  int getCountAdvancedCourses() {
    int count = 0;

    for (Course c : courses) {
      if (c.isAdvanced()) count ++;
    }
    return count;
  }
}
```

また、コース数を取得するコードは可読性を求めて、以下のようにします。
```変更前
jack.getCourses().size();
```

```変更後
jack.getNumberOfCourses();

class Person {
  int getNumberOfCourses() {
    return courses.size();
  }
}
```

# 所感
プログラムのモジュール化は自分の思っている以上に可能なんだと痛感。
けどモジュール化するために考えすぎるより、何回も作って修正してっていうのをやったほうがいいなと思いました。
どんどん作ってレビューで指摘されたりしたほうが効率いいはず。