OmniAICreator/Qiita-1.07M huggingface dataset:
最近、PM2.5 多くなった???  PM2.5 測定 し、地図上にマッピングしてみました。

# 最近、空気が悪くなった????

PM2.5 測定してみました。
最近、いろいろな匂いがするので、気のせいか確かめたよ。

環境基準の、35μ

測定結果は、2.5μg と 環境省の測定値、2μ と、ほぼ同じ！！

## Sharp GP2Y1010AU0F Optical Dust Sensor PM2.5 測定

![44461514_2427029187313061_3096316634642513920_n.jpg](https://qiita-image-store.s3.amazonaws.com/0/77496/b51ce568-e550-c6b2-8074-abccea1f8daa.jpeg)


## こちらの情報を参考に作成
http://www.howmuchsnow.com/arduino/airquality/

```
Vo=289.11mV, DustDensity=0.71ug/m3
Vo=291.70mV, DustDensity=1.23ug/m3
Vo=298.34mV, DustDensity=2.56ug/m3
Vo=294.68mV, DustDensity=1.83ug/m3
Vo=292.97mV, DustDensity=1.48ug/m3
Vo=295.61mV, DustDensity=2.01ug/m3
Vo=290.43mV, DustDensity=0.98ug/m3
Vo=297.90mV, DustDensity=2.47ug/m3
Vo=295.41mV, DustDensity=1.97ug/m3
Vo=290.77mV, DustDensity=1.04ug/m3
Vo=293.85mV, DustDensity=1.66ug/m3
Vo=297.95mV, DustDensity=2.48ug/m3
Vo=296.92mV, DustDensity=2.28ug/m3
Vo=293.85mV, DustDensity=1.66ug/m3
Vo=290.53mV, DustDensity=1.00ug/m3
Vo=318.12mV, DustDensity=6.51ug/m3

```
# Voltage と、PM2.5濃度が比例してます。

![dustvoltage.jpg](https://qiita-image-store.s3.amazonaws.com/0/77496/011d9c17-ca85-120c-3025-aa688976b76c.jpeg)

# Data compared to air quality:

    3000 + = Very Bad
    1050-3000 = Bad
    300-1050 = Ordinary
    150-300 = Good
    75-150 = Very Good
    0-75 = Tiptop

# 測定結果を地図上にマッピングしてみた。

![pm25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/77496/ddb088cf-1549-fdf8-7d50-b71ea691d693.png)
メタプログラミングRuby第2版 まとめ

# memo
ほぼ個人的なまとめ、memoです。
+αの知見があったらコメントでください。
随時更新していきます。

## 第1章 頭文字M

### obj#instance_varibles
- そのオブジェクトに定義されているインスタンス変数を取得

```rb
class Test
  def initialize
    @instance_variable = 'test'
test.instance_variables #引数の期待無し
=> [:@instance_variable]
```

### attrメソッド
- attr_writer => インスタンス変数のsetterを用意
- attr_reader => インスタンス変数のgetterを用意
- attr_accessor => インスタンス変数のgetter,setterを用意

## 第2章 オブジェクトモデル

### オープンクラス
- 既存のクラスを拡張する実装方法
- メソッドの衝突に注意!!

```rb
#Classに同名のMethodが無いか確認する。下記メソッドの後に#grep/hoge/で探索
Class.methods #クラスのメソッド一覧
instance.instance_methods #クラスのインスタンスメソッド一覧
instance.public_methods #publicなメソッド一覧
instance.instance_public_methods #publicなインスタンスメソッド一覧
instance.methods(false) 
```

### Module#nesting

```rb
class Outer
  p Module.nesting
  module Inner
    p Module.nesting
  end
end
 
p Module.nesting

[Outer]
[Outer::Inner, Outer]
[]
```

### メソッド探索
- レシーバ
  - 呼び出すメソッドが属するオブジェクトのこと。ex my_string.reverseのmy_string
- 継承チェーン
  - クラスからスーパークラスへ、さらにそのスーパークラスからスーパークラスへ、その道筋が継承チェーン
- 探索を一言でまとめると「Rubyがレシーバのクラスに入り、メソッドを見つけるまで継承チェーンをたどること」
- この動きを「右へ一歩、それから上へ(one step to the right,then up)」ルールと呼ばれる
- 継承チェーン一覧#ancestors
  ```rb
  MySubclass.ancestors # => [MySubclass, MyClass, Object, Kernel, BasicObject]
  ```
- 継承にはモジュールも含まれる
  - include => そのクラスの真上
  - prepend => そのクラスの真下
- モジュールがすでにチェーンに存在している場合、二回目の挿入を無視
- Object include Kernel
  - Kernelをオープンクラスしてメソッドをつけたらどこでも使えるようになる。gemとかでは多い。けど危ない
- self => 現在のレシーバ => current_object
- private 
  - class内でself.private_mathodの呼び出しは出来ない。
  - private内ではレシーバがそのclassであるから(selfだと呼び出し先のobjectになってしまう。) 

### Refinements
- オープンクラスがモンキーパッチにならないような対策
- moduleの中で定義
- usingを使用した箇所からソースファイル終わりまで使えるようになる
- 限定的にパッチを当てることが出来る

  ```rb
  module StringExtentions
    refine String do
      def hoge
        p ''hoge
      end
    end
  end

  'page'.hoge => nomethod_error
  using StringExtentions
  'page'.hoge => hoge
  ```
- まだ定着していないかも

## 第3章 メソッド
### 動的メソッド
- define_methodで定義
### 動的ディスパッチ
- sendを使ってメソッドを呼び出す。
  ```rb
  obj.my_method(3)
  obj.send(:my_method,3)
  ```
- コードの実行時に呼び出すメソッドを決められる
- privateなメソッドも呼び出すことが出来る
- あまり理解できてない気がする

### grepにブロックを渡す
- matchにした要素に対してブロックを実行してくれる

### method_missing
- ゴーストメソッド
  - method_missingで定義されるrespond_toに反応しないメソッド
- respond_to_missing 
  - respond_toで呼び出しているメソッド
  - method_missingをorverrideする場合respond_to_missingも上書きしてrespond_toが正しく反応するようにすること
- バグ対策
  - method_missingできちんと定義時に分岐をさせて必要のないときにはsuperを呼ぶ

### ブランクスレート
- ゴーストメソッドを使った時既存の予期しないメソッドとぶつかってしまう事がある。
- そのようなバグに備え最低限のメソッドしか定義していない状態のこと
- そもそも継承元をBasicObject等にするといいかも
- undef_method 引数のメソッドを未定義にする

## 第四章 ブロック
XAMPP php.ini date.timezoneをAsia/Tokyoにする

#XAMPPのphp.ini編集でのつまずき。
##date.timezoneの変更が反映されない。
950行付近を編集。

```.ini
[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
date.timezone=Asia/Tokyo
```
![datetimezone.PNG](https://qiita-image-store.s3.amazonaws.com/0/247466/28f03a3f-7b70-0f4b-af7e-01f69c6ad291.png)
`"Asia/Tokyo"`のように`"`をつけてみたり再起動してみたりしましたが反映されず...。

##date.timezoneは2か所ある！
php.iniを下まで見たところ1935行目付近に下記のような記述を見つけたので編集。

```.ini
[Date]
; date.timezone=Europe/Berlin
date.timezone=Asia/Tokyo
```
![datetimezone_2.PNG](https://qiita-image-store.s3.amazonaws.com/0/247466/025a871b-4275-e496-58c7-a16d31acc903.png)
反映された！！！
初心者なりに頑張って解決できて達成感でいっぱいですw
【翻訳】makefile を作る時のルール (Rules of Makefiles)

GNU make の記事 [Rules of Makefiles](https://make.mad-scientist.net/papers/rules-of-makefiles/) の翻訳です。

-----

皮肉のようなタイトル（訳注：makefile の（文法上の）ルールとかけている）ですが、この記事では makefile を作るときに常に留意すべき非常に重要な規則を挙げています。これらのルールに従えば、あなたの makefile は簡潔かつ美しいものになるでしょう。さらに、単に makefile を保守・変更するだけでなく、あなたの人生をもっと楽しいものにします。

## 1. GNU make を使え

ポータブルな makefile を作ることに苦悩するのをやめて、ポータブルな ```make``` を使いましょう。

## 2. すべての ```.PHONY``` でないルールは、そのターゲット名どおりのファイルを更新しなければならない

すべてのコマンドスクリプトは ```../$@``` や ```$(notdir $@)```[^1] ではなく、```$@``` を触るようにしなければなりません。あなたと GNU make の約束です。
[^1]: 訳注：```$(notdir ...)``` 関数は、ファイルパスからディレクトリ部分を除外する関数

## 3. ターゲットがカレントディレクトリにビルドされれば、人生はシンプル

ソースディレクトリを基準にオブジェクトの位置を指定するのではなく、```VPATH``` を使ってオブジェクトディレクトリを基準に[ソースの位置を指定します](https://make.mad-scientist.net/papers/how-not-to-use-vpath/)（訳注：英文）。

## 4. 最小繰り返しの原則に従え

一つのファイル名を何度も書かないようにしてください。変数、パターンルール、自動変数、```make``` の組み込み関数を活用しましょう。

## 5. すべてのTABで始まる行（ただし前行の続きでない）はコマンドの一部であり、逆もまた真なり

TAB で始まらない行は、**絶対に**コマンドの一部ではありません。これは常に ```make``` の文法で解釈されます。
TAB で始まる行は、**常に**コマンドの一部です。これは常に ```make``` の文法で解釈されることはありません。
厳密にはこれは常に真ではありませんが、あなたは常に真であると考えるのが最善です。

なお、前行の続きの行は、最初の文字にかかわらず、常に前の行と同じタイプとなります。

## 6. ディレクトリを通常の依存対象に使わない

ディレクトリをターゲットの依存対象にするのが正しいという状況はほぼ存在しません。GNU make はディレクトリを他のファイルと同じように扱い、ディレクトリの更新日時が変更されていればターゲットをビルドします。しかしながら、ディレクトリの更新日時は、その中のファイルが追加・更新・削除されたときにも変更されます……。これはほとんどの場合、あなたの望む動作ではありません。
ただし、ディレクトリを[順序限定依存先](https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html)（訳注：英文）とすることは有用です。

以上です……今のところは。私がこの件について言いたいことはこれだけではありませんが、基本的かつ簡潔な規則の形式で表現できる点を考えることは簡単じゃありません。
ご提案があればどうぞ教えてください。
rails: AWS s3から画像を一括でダウンロードする

S3からローカルにdownloadするには send_fileメソッドが有名だけどコネクションが一回切りなので繰り返し文にして複数回するのは無理、つまりファイル一枚のみ。

それでS3側でファイルを圧縮してくれるgem zipline を発見しました。

```controller
include ActionController::Streaming
include Zipline
def s3all
      myBacket = 'backet-name'
      bucket = Aws::S3::Client.new(
             :region => 'ap-northeast-1',
              :access_key_id => 'AKIAxxxxxxxx',
              :secret_access_key => 'xxxxxxxxxxxxxxxx'
             )
      lists = []
      bucket.list_objects(:bucket => myBacket).contents.each do |b|
        lists.push(b)
      end
      lists.lazy.map do |list|
        s3_object = bucket.get_object(bucket: myBacket, key: list.key)
        [s3_object.body, list.key+".png"]
      end
```
これでbacket内のすべての画像をダウンロード出来ます。

```
bucket.list_objects(:bucket => myBacket, :prefix => "name_no#{@user.id}").contents.each do |b|
```
とかプレフィックスを利用する事もできる。

ただ、解凍時に警告が出るのはなぜなんだろうか？
mysql メモ


# ■コマンドラインからsqlを実行
`mysql -u[user] -p[password] -h[dbName] < sqlファイル`

# ■表示系
テーブル一覧
`show tables`

カラム一覧
`show columns from [tableName]`

VIEWの中身を確認
`show creaet view [viewName]`

# ■設定系

## 接続時間の確認
wait_timeoutの値を確認
デフォルトは8時間
`show global variables like '%wait%'`

```
+---------------------------------------------------+----------+
| Variable_name                                     | Value    |
+---------------------------------------------------+----------+
| innodb_lock_wait_timeout                          | 50       |
| innodb_spin_wait_delay                            | 6        |
| lock_wait_timeout                                 | 31536000 |
| performance_schema_events_waits_history_long_size | 10000    |
| performance_schema_events_waits_history_size      | 10       |
| wait_timeout                                      | 28800    |
+---------------------------------------------------+----------+
6 rows in set, 1 warning (0.25 sec)
```
【 Laravel 】LaravelのEloquentとPDOの実行時間を比較する

## 結論 
PDOの方がEloquentよりも5.7倍速い。

|#|実行時間|
|:---|:---|
|Eloquent|0.01072883605957秒|
|PDO|0.0018770694732666秒|

```php5
// Eloquent
$test = Test::whereBetween('id', [$start_id, $end_id])->get();

// PDO
$base = DB::connection()->getPdo()->prepare('SELECT * FROM test WHERE id BETWEEN :start_id AND :end_id');
$base->bindValue(':start_id', $start_id, PDO::PARAM_INT);
$base->bindValue(':end_id', $end_id, PDO::PARAM_INT);
$base->execute();
```
Swiftの変数スコープを調べる

コーディングを支える技術という本で、

> `python`では関数のネストを使った時に、その関数の対応表で見つからなかった場合、一つ上の関数の対応表を見にいくのではなく、グローバル対応表を見にいく挙動がある。

と書いてあったので、`Swift`ではどうだろう？と思ったので検証してみた。

```swift:scope.swift
import Cocoa

var str = "Hello, playground"

var x = "global"
func foo() {
    x = "foo"
    func bar() {
        print(x)
    }
    bar()
}
foo() // foo

```

**ちゃんと一つ上の関数の対応表を見に行っていた。**

あたりまえだけど以下のようにすると、globalと表示される。

```swift:scope.swift
import Cocoa

var str = "Hello, playground"

var x = "global"
func foo() {
    func bar() {
        print(x)
    }
    bar()
}
foo() // global

```
Ansibleの備忘録（環境分離編）

# Ansibleを環境毎に使い分ける

# やりたいこと
- 環境毎にansibleを使い分ける
  - dev /stg
- `verifi`ロールで実行環境のenvを表示させて確認する  



## 検証時のAnsibleディレクトリ構造とplaybook

```
├── bastion.yml
├── group_vars
│   ├── all
│   ├── env_dev
│   │   └── main.yml
│   ├── env_stg
│   │   └── main.yml
│   └── role_bastion
├── inventory
│   ├── dev
│   └── stg
└── roles
    └── verifi
        └── tasks
            └── main.yml
```


```bastion.yml
- hosts: role_bastion
  user: ubuntu
  become_method: sudo
  gather_facts: yes

  roles:
     - verifi
```


## 環境分離にinventoryを使う
今回はdevとstgをそれぞれ用意した。

- `inventory/dev`

```
[role_bastion]
localhost

[env_dev:children]
role_bastion
```

- `inventory/stg`

```
[role_bastion]
localhost

[env_stg:children]
role_bastion
```

## それぞれの環境名を変数をセットする


```/group_vars/env_dev/main.yml
---
env: dev
```


```group_vars/env_stg/main.yml
---
env: stg
```

## 環境毎の変数を参照しているか確認
inventoryでdev/stgを指定して出力を確認する

- devを指定して実行する
  - `$ ansible-playbook -i inventory/dev bastion.yml -D`

```
TASK [verifi : echo environment] ***********************************************************************
ok: [localhost] => (item=dev) => {
    "dev": "VARIABLE IS NOT DEFINED!",
    "item": "dev"
}
```

- stgを指定して実行する
  - `$ansible-playbook -i inventory/stg bastion.yml -D`

```
TASK [verifi : echo environment] ***********************************************************************
ok: [localhost] => (item=stg) => {
    "item": "stg",
    "stg": "VARIABLE IS NOT DEFINED!"
}
```

# まとめ
inventoryを使って、環境を指定してAnsibleを実行することができた。
これで、複数の環境をひとつのリポジトリでコード管理してプロビジョニングをすることができる。
[入門]Scalaで「Hello World!」してみた


## 環境構築

DockerでScala環境を作りました。バージョンは気にしていないです。
scriptsディレクトリをマウントしてローカルから編集できるようにしています。

```
├── Dockerfile
├── docker-compose.yml
└── scripts <空のディレクトリ>
```

```Docker:Dockerfile
FROM centos:7

# JVM
RUN yum -y install java-1.8.0-openjdk java-1.8.0-openjdk-devel

ENV JAVA_HOME /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.144-0.b01.el7_4.x86_64
ENV PATH $PATH:$JAVA_HOME/bin
ENV CLASSPATH .:$JAVA_HOME/jre/lib:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar

# Scala
WORKDIR /usr/local/lib
RUN yum -y install wget
RUN wget http://downloads.typesafe.com/scala/2.12.6/scala-2.12.6.tgz
RUN tar zxvf scala-2.12.6.tgz
RUN ln -s scala-2.12.6 scala

ENV SCALA_HOME=/usr/local/lib/scala
ENV PATH $PATH:$SCALA_HOME/bin

# sbt
RUN curl https://bintray.com/sbt/rpm/rpm | tee /etc/yum.repos.d/bintray-sbt-rpm.repo
RUN yum -y install sbt
RUN sbt

RUN mkdir -p /opt/scala
WORKDIR /opt/scala

CMD ["/bin/bash"]
```

```yml:docker-compose.yml
scala_sbt:
  container_name: scala_sbt
  build: .
  volumes:
    - ./scripts:/opt/scala
  tty: true
```

コンテナを作成して起動します。結構時間かかります。

```
docker-compose up -d
```

起動したコンテナに入ります。

```
docker-compose exec scala_sbt bash
```

もしくは

```
docker exec -it scala_sbt bash
```

scalaのREPL(対話型インタープリター)が起動できるか試してみます。


`scala`と打って、以下のように出ればOKです。

```
Welcome to Scala 2.12.6 (OpenJDK 64-Bit Server VM, Java 1.8.0_181).
Type in expressions for evaluation. Or try :help.

scala>
```

## Hello Worldプロジェクトの作成

まず、helloworldプロジェクトを作成します。

```
cd scripts
mkdir helloworld
cd helloworld
```

`build.sbt`を作成します。

```scala:build.sbt
name := "hello-world"

version := "1.0"

scalaVersion := "2.12.6"
```

sbtの標準的なディレクトリ構成の一部を作成します。

```
├── build.sbt
├── project
│   ├── build.properties
│   └── target
├── src
│   ├── main
│   │   ├── resources
│   │   └── scala
│   └── test
│       ├── resources
│       └── scala
└── target
```

今回はsrc以下のみ作成します。

```
mkdir -p src/{main,test}/{resources,scala}
```

最後に`src/main/scala/`に`HelloWorld.scala`を作成します。

```scala:HelloWorld.scala
object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello World!")
  }
}
```

ここまでで、ディレクトリ構成は以下のようになっています。

```
helloworld
├── build.sbt
└── src
    ├── main
    │   ├── resources
    │   └── scala
    │       └──HelloWorld.scala
    └── test
        ├── resources
        └── scala
```

## 実行

```
sbt run
```

Hello World!が出ればOKです。初回は少し時間かかります。

## 詰まった箇所

### docker-compose

docker-composeで`tty: true`としていないと、コンテナが起動しない。
詳しくは[こちら](https://inamuu.com/docker-compose%E3%81%A7%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%8C%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%AA%E3%81%84/)

### main関数

`args`の部分を省略して、以下のようにして`sbt run`したらエラー。

```scala:HelloWorld.scala
object HelloWorld {
  def main(): Unit = {
    println("Hello World!")
  }
}
```

```
[error] java.lang.RuntimeException: No main class detected.
[error]   at scala.sys.package$.error(package.scala:26)
[error] (Compile / bgRun) No main class detected.
```

また、`Unit`の部分は省略できるようです。
SourceTreeでremote: Invalid username or passwordが表示される

# 問題点

SourceTreeを使ってBitbucketからクローンしようと思ったら，URLがGitリポジトリと認識されない


# 動作環境
windows10
SourceTree x2.6.9.0
Git v.2.19.1

# 解決方法 その１

1. SourceTree閉じる
2. Userのディレクトリ以下にある\AppData\Local\Atlassian\SourceTree\内のpasswdファイルを消す
3. SourceTree起動してクローンする
4. アカウント情報を求められるので入力
5. おっけー！

#解決方法 その2
(2019/04/19追記)
githubのアカウント名（ID）を変えたところ，またエラーが起こるようになった...


1. 「ツール」「オプション」「認証」からGithubのアカウントを選択し，「編集」からトークンを再読み込みしておく
2. SourceTree閉じる
3. Userのディレクトリ以下にある\AppData\Local\Atlassian\SourceTree\内のpasswdファイルを消す
4. SourceTree起動してクローン（もしくはプッシュ，プル等）する
5. アカウント情報を求められるので，このときに表示されるユーザ名が変更後のユーザ名と異なっていることを確認し，一旦キャンセル
6. Userのディレクトリ以下にある\AppData\Local\Atlassian\SourceTree\内のuserhostsファイルを開く
7. "github.com"と書かれた行の下にあるユーザ名を変更後のものに変更し上書き保存
8. 再度クローンをしたときに求められるアカウント情報の欄に表示されるユーザ名が変更後のものになっていれば成功！





### 他にもいろんな解決手段があるみたい

- 再インストール
- ツール>オプション>認証から認証情報消す
- AtlassianにGoogleログインじゃなくてメールアドレスとパスワードでログインする
 

# 原因

SourceTree内での認証情報の管理，更新方法がよくないっぽい....
Pythonの async/await, asyncio の使い道

# Pythonの async/await, asyncio の使い道

Pythonのasync/awaitは、C#などと違って、全部一つのスレッド上でやるので、CPUバウンドな処理や、大きなファイルを保存するようなI/Oバウンドな処理を速くするのは無理。

通信を待ってる自分が何もしてない時間に他の処理をやりたいようなときに使える。

CPUバウンドなときはmultiprocessingやconcurrent.futures.ProccessPoolExecutorを使うべし

I/Oバウンドなときはconcurrent.futures.ThreadPoolExecutorを使うべき

## async await

このブログがわかりやすい
[ゆくゆくは有へと: Pythonの非同期通信（asyncioモジュール）入門を書きました](http://iuk.hateblo.jp/entry/2017/01/27/173449)

## async awaitでマルチプロセスやマルチスレッドを使う

`loop.run_in_executor`を使えば、`concurrent.futures.ThreadPoolExecutor`に渡した関数の完了を`await`することができる。
[Executing code in thread or process pools](https://docs.python.org/3/library/asyncio-eventloop.html#executing-code-in-thread-or-process-pools)
【AWS IoT】ボタン1クリックで「いまから帰るよ」を実現した

#はじめに
<img src="https://qiita-image-store.s3.amazonaws.com/0/104983/fc758cb1-4326-2aa0-4cec-66317c070239.png" width=40%>

皆さんは帰りの連絡を忘れてしまい、家の人に怒られてしまった経験が一度はあるんじゃないでしょうか。僕は何十回かあります。
特に既婚者の場合、奥さんの夕飯作りに多大な影響を与えますので、この連絡を忘れてしまうと死を招きかねません。

それなのに私たちはなぜ何度も失敗をくり返すのでしょうか。
原因はただ一つ。「めんどくさい:mask:」。
そんなこと言うと「LINEで1通送るだけじゃん！」と言われそうですが、もはやそれすらめんどい。私にはできない。

そんな時私が出会ったのが、「AWS IoT Enterprise Button」だったのです。
![IMG_3597.jpg](https://qiita-image-store.s3.amazonaws.com/0/104983/46a18186-a4f0-03b4-54a8-00000e800486.jpeg)

以前ボタンワンクリックで洗剤やティッシュなど日用品が注文できる、Amazon Dashというサービスが話題になったかと思います。このボタンは、形状はAmazon Dashのボタンとほぼ同じなのですが、違いとしてクリック時の処理を開発者が自由に記述できるようになっています。

ボタンワンクリックならさすがの私でも連絡できるはずですので、クリックすると帰宅メッセージがLINE通知されるプログラムを作ってみました。

#作ったもの
AWS IoT Enterprise Buttonはクリックの種別（シングル、ダブル、長押し）を通知することができるため、種別に応じて送信するメッセージを変えてみました。

■シングルクリック
![late.jpg](https://qiita-image-store.s3.amazonaws.com/0/104983/021f2c1f-46b8-a2d9-6923-284d80d0220e.jpeg)


■その他(ダブルクリック、長押し)
![now.jpg](https://qiita-image-store.s3.amazonaws.com/0/104983/57e56a32-62c2-5c6b-5de3-76ea035c0b8c.jpeg)

我ながらこれは便利！！IoT革命を起こしたと言っても過言ではないでしょう。
定時で帰れる日も残業で遅くなる日もこのボタン一つでバッチリです。
絵文字も使えますので、温もりを感じますね:relaxed:


#構成図
![AWS IoT.jpg](https://qiita-image-store.s3.amazonaws.com/0/104983/72d87ed9-07c1-03a9-beed-076fca971d9e.jpeg)

AWS IoT 1-Clickの設定画面で、AWS IoT Enterprise ButtonとLambda Functionを紐づけるイメージを持つと分かりやすいと思います。LINE通知の処理はIFTTTにお任せして、トリガーとなるWebHook URLをLambda Functionから叩きます。

#コード
Lambdaで動けばどの言語でも良いのですが、今回は勉強のため初めてGoを使ってみました。

```go:
package main

import (
	"context"
	"net/http"
	"io/ioutil"
	"fmt"
	"github.com/aws/aws-lambda-go/lambda"
)

type IoTButtonEvent struct {
	DeviceEvent struct {
		ButtonClicked struct {
			ClickType string `json:"clickType"`
		} `json:"buttonClicked"`
	} `json:"deviceEvent"`
}

func SendRequest(clickType string){
	var eventName string

	if clickType == "SINGLE" {
		eventName = "go_home_now"
	} else {
		eventName = "go_home_late"
	}

	const IftttKey = ""
	url := "https://maker.ifttt.com/trigger/" + eventName + "/with/key/" + IftttKey
	resp, err := http.Get(url)

	if err != nil {
		fmt.Println(err)
	}	

	byteArray, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(byteArray))

	defer resp.Body.Close()

}

func HandleRequest(ctx context.Context, event IoTButtonEvent){
	SendRequest(event.DeviceEvent.ButtonClicked.ClickType)
}

func main() {
	lambda.Start(HandleRequest)
}

```
おかしな部分あれば、ご指摘いただけるとありがたいです:pray:

#おわりに
めちゃくちゃ便利なボタンを作ったと喜んでいたところ、ふと気付いてしまいました。
「カバンに入れてたら押さない…。」

でも大丈夫。
こんな悩みを見通していたかのように、このボタンにはしっかり紐を通すための穴が付いているのです。

<img src="https://qiita-image-store.s3.amazonaws.com/0/104983/5b43e387-804d-7f96-3017-e0b248df863e.jpeg" width=30%>


これはクール。
Apple Watchの30000倍クール。
紐はそこらへんにあった充電ケーブルを使いました。
これを首からぶら下げて渋谷歩いたらモテること間違いなしですので、エンジニアの方はぜひ早めに購入することをオススメします。
CUIデバッグの手引き

# この記事について
大学の研究室の後輩に向けて書いたドキュメントに加筆したものです。プログラミング超初心者の人が急に巨大なプログラム（数万行～）のデバッグをやらされることになったとき[^1]に手引きになればと思い、公開しました。

# 背景となる問題意識
あまりにポエムなのでブログにまとめてます。
http://bluepost69-tech.hatenablog.com/entry/2017/11/16/191631

非情報系ではプログラミングの授業でデバッグのやり方を教えないので、問題意識を持っています。

## 想定している環境
* SSHでCUIしか使えない

実際の環境としては、SSH接続した先でfortran+MPIコードをデバッグするという形です。リモートで編集、実行まで行うので**IDEは使えない**という状況です。スパコンでシミュレーションをやる業界なら割とよくあると思います。

# 大原則：プログラムの気持ちになる
まず「**何が起こっているのか**」「**どこで止まっているのか**」を調べる。

* **エラーメッセージをよく読む**
* デバッグオプションをつけてコンパイルしてみる
* 適当なところにwrite文を挿入して実行してみる。
    * 怪しい変数はwrite文で出す
    * write文の内容が出力された箇所までは計算が終わっている。

（write文は適宜言語ごとに標準出力に出力するコマンドに置き換えてください。Cだとputsやprintf、pythonだとprintなど）

特にエラーメッセージを読まない人は本当に多いです。**「No such file」みたいな読めばわかるエラーを人に聞くのは恥ずべき事**だと思いましょう。

```
Fortran runtime error: Cannot open file 'hoga.txt'
```
*「先輩！なんか意味不明なエラーが出るんですけど！」
「cannotは中学1年生で習う英語だよ？中学校からやり直したら？」*

---

おおまかな場所を見つけたら、**プログラムの気持ちになるですよ！**

* 実行する計算を追ってみる。
* 要所要所で変数をwrite文で出力する。

**write文はプログラムに自身の状態を出力させる強力なツール**。（ただしログが大きくなるのでデバッグが終わったら削除しておく。そのために変更箇所には目印をコメントしておくとよい。）

# バグったな？と思ったら...代表的なバグとその対処法

1. 計算が回らない
    * コンパイルエラー
    * 実行時エラー
1. 計算は回るが終わらない
    * デッドロック
    * 無限ループ
1. 計算結果が明らかにおかしい

## 計算が回らない
### コンパイルエラー
コンパイル時にエラーが出る場合、コンパイラが直しきれない明らかな文法誤りがある。
一か所の誤りがコンパイルされないために芋づる式に誤りでない場所も指定されることがあるので、エラーメッセージをよく読んで原因を見極める。たいてい最初の方に根本原因がある。

読み切れないときは
``` gfortran smp.f90 > compile.log```
のようにリダイレクトしたり、
``` gfortran smp.f90 | less```
とlessにパイプして読む。

### 実行時エラー
原則としてコンパイルエラー同様、エラーメッセージをよく読む。ただしOSからのシグナルの場合、あまりあてにならないこともある。

SIG_SEGVが出力される場合、**セグメンテーションフォールト**(Segmentation fault）と呼ばれるバグに該当する。これは許可されていないメモリを参照した場合に出るエラーで、fortranの場合は**ほとんどが配列の引数の間違い**に起因する。（1～99がallocateされた配列x(1:99)でx(100)と指定するなど）。そんな馬鹿なことはないだろうと思うかもしれませんが、**変数を添え字に入れてたりすると変数が意図しない値になったりするのはよくあるんですよ**。

また、
・0での割り算を実行しようとした
・平方根sqrtの中身がマイナスになった
といった場合もSIG_SEGVになることがある。

## 計算は回るが終わらない
デッドロックと無限ループが代表的。並列数を1にしてバグが治ればデッドロック。

### デッドロック
（fortranでは）MPI特有の現象。プロセスが1対1で通信する場合、受け取る側がMPI_RECVを実行し送る側がMPI_SENDを実行しなければならないが、交互に通信する場合で両者がMPI_RECV状態になり計算が止まってしまうことがある。

対策としてはMPI_SENDRECVに書き換えるか、順番を入れ替える。これについては別記事で書きたい。

### 無限ループ
原則として**無限ループで条件を満たした時exitするようなコードは組まない**。exitが何らかの理由で実行されなかった場合や条件が満たされなかったとき、デバッグがややこしくなる。

やむを得ずwhileループを使う場合などは、上限を指定したループで条件を満たさないときにexitする形に変える。

```fortran:smp_ng01.f90
!これはダメな例
do while(flag)
! 処理
end do
```

```fortran:smp_ok01.f90
do i=1,N_LOOP_MAX
! 処理
   if(.NOT. flag) exit
   if(i== N_LOOP_MAX)
      ! まともな言語なら例外を投げるべき
      write(6,*) "Error: loop not ended!"
   end if
end do
```

## 計算結果が明らかにおかしい
計算過程を一つ一つ見る必要がある。

* 変数が思い通りの結果になっているか（0やNaNなど変な値が代入されていないか）
* 関数の引数がまちがっていないか（タイプミスで似た名前で宣言された別の変数が入っていることがある）

チェックしたい変数をwrite文で出力してみる。

# デバッグに使うツール
## grep
変数やサブルーチンがどのモジュールに書かれているのかを調べるのに使う。

例：fortran90ファイルの中で"hoge"がどのファイルに書かれているかを調べる
```grep -n "hoge" *.f90```

## emacsの検索機能
C-sで開いているファイルで検索をかけることができる。

## diff
2つのファイルを比較してどこが異なるかを出力する。作業結果をまとめるとき、バージョン間での比較に便利。

例：A.f90とB.f90の変更箇所を調べる
```diff A.f90 B.f90```

# 最後に
*このレベルのデバッグをろくに教えもしないで、配属間もない学生にコード管理をやらせる研究室はもれなくブラックなので、覚悟しましょう*[^2]。

[^1]: 信じられないことに、理系の理論シミュレーション系だと人不足で**しばしばこういうことがあります**。
[^2]: 特にB4ならその研究室に進学することは考え直したほうがいいです。
駅.Locky用の時刻表作成を自動化するぞ 1

# はじめに
- Pythonをそこそこ使えるようになりたい
- ただただ勉強するのも面白くないので、課題探し
- ちょうどその頃に近隣（京阪電車）のダイヤ改正
- [駅.Locky](http://eki.locky.jp/site/top)の時刻表が古くなり、手作業で時刻表データ作成
- 時刻表サイト ⇒ Pythonアプリ ⇒ 時刻表データ が出来たら一石二鳥！

# 調べてみた
- 駅.Lockyの時刻表データは、NextTrain形式の時刻表記述フォーマット
- [えきから時刻表](http://www.ekikara.jp/top.htm)→NextTrainデータ(tbl形式)[変換サイト](http://toshi-u.sakura.ne.jp/tt2tbl/ej2tbl.html)でTBLファイルを作ってみた
 ファイルがどういうものか理解できた（ファイル名の形式等も）

>
A:中之島行
B:淀屋橋行
a:区間急行()
b:準急()
c:急行()
d:特急()
e:ライナー
f:通勤準急()
g:通勤快急()
h:快速急行()
i:快速特急()洛楽
[MON][TUE][WED][THU][FRI]
京橋駅 京阪京阪本線 淀屋橋方面(下り) 平日
5:Aa22 B22 Bb30 Bb39 A40 B45 Bb54 A56
6:B01 Bb09 A10 Ba18 A20 Bb24 Bc31 A32 Bb38 A40 Bb42 Ba45 A47 Bc49 Bb56 Bd58
・・・

- 時刻表データをスクレイピングするのに、PythonだとBeautifulSoupかpandas
- pandasの方がTABLEデータの取得が容易に思えたのでライブラリは決定

# 開発環境（またどこかで備忘録書いておかねば）
- Python3.6（Anaconda）
- Visual Studio Code
- pandas

# 一先ず触ってみる
- pandasにURL渡してデータ根こそぎ抜き取る
 どんなデータが取れるのか理解（時刻表サイトと見比べ）

 ```python:sample.py
import pandas as pd
dfs = pd.read_html("http://ekikara.jp/newdata/ekijikoku/2706011/up1_27118011.htm")
for dfsData in dfs:
 print(dfsData.values)

 ```
>[['時 京橋\xa0[京阪]京阪本線\xa0三条方面(上り)\xa0平日 5 三10 三22 三40 出48 [急]出55 出59 6 出08 [急]出15 出18 [急]出27 出29 [区急]萱31 [準急]出37 萱38 出43 [特]出46 [準急]樟51 樟52 [特]出57 7 [準急]出00 枚02 [特]出07 ・・・

なるほど、それらしいデータは簡単に取れた
- [えきから時刻表](http://www.ekikara.jp/top.htm)だと色んなゴミ?まで拾うため、他のサイトも色々見てみた

# 時刻表サイト比べ
- えきから時刻表
- Navitime
- いつもNAVI
- ekitan
- 駅すぱあと
- Yahoo!

色々あるなぁ・・・。次は時刻表サイトのデータを比較してみます。
RxSwift UIAlertController を observable で表示

# RxSwift UIAlertController を observable で表示
やり方の例です。

## UIAlertActionに相当するオブジェクトを定義
UIAlertActionのクロージャ部分は、onNext処理を入れたいので、事前に代わりになるクラスか構造体を定義しておく。

```swift
struct AlertAction {
    var title: String
    var style: UIAlertActionStyle

    static func action(title: String, style: UIAlertActionStyle = .default) -> AlertAction {
        return AlertAction(title: title, style: style)
    }
}
```
## 表示部分
上で定義した構造体をUIAlertActionとしてUIAlertControllerにセットする。この時にクロージャ内の処理を定義すること。Observable生成の時でないとこの処理が作れないから事前に仮の構造体を利用しただけ。構造体を用いずにこの中でObserverとなるUIAlertActionを生成してもOK。
「return Disposables」内でUIAlertActionを閉じるのを忘れないように。

```swift
func showAlert(title: String?, message: String?, style: UIAlertControllerStyle, actions: [AlertAction]) -> Observable<Int>
{
    return Observable.create { observer in
        let alertController = UIAlertController(title: title, message: message, preferredStyle: style)

        actions.enumerated().forEach { index, action in
            let action = UIAlertAction(title: action.title, style: action.style) { _ in
                observer.onNext(index)
                observer.onCompleted()
            }
            alertController.addAction(action)
        }

        self.present(alertController, animated: true, completion: nil)

        return Disposables.create { alertController.dismiss(animated: true, completion: nil) }
    }
}
```

## 利用例
``` swift 
self.showAlert(title: "タイトル", message: "メッセージ", style: .alert,
 actions: [AlertAction.action(title: "no", style: .destructive), AlertAction.action(title: "yes")]
).subscribe(onNext: { selectedIndex in
    print(selectedIndex)
}).disposed(by: self.disposeBag)
```

[サンプル](https://github.com/katafuchix/UIAlert-RxSwift)

## 関連リンク
[UIAlertControllerをいかに簡易にまとめる事が大事かと考え作成してみました。](https://qiita.com/keisukeYamagishi/items/afcd6504c9b3022c6694#_reference-b4f6a390981749e8f4c0)
[UIAlertController をRxSwiftを使って拡張してみました。](https://qiita.com/keisukeYamagishi/items/ca5751553c2724288e9f)

[RxAlert](https://github.com/RxSwiftCommunity/RxAlert)
Swift4でJSONを読み書きする

## JSONDecoder/Encoder
Swift4から使えるようになったと噂のJSONDecoder/Encoderを使ってみました。StringとDataの変換があるせいでややこしく見えますが、`decoder.decode`と`encoder.encode`を使ってシンプルにデコード/エンコードができます。

```swift
// json = [["a":"1"],["b":"2"]]
let json = "[{\"a\":\"1\"},{\"b\":\"2\"}]".data(using: .utf8)!
let decoder = JSONDecoder()
let objs = try decoder.decode([[String:String]].self, from: json)
```

オブジェクト(Dictiynaryの配列,objs)を再びJSON(文字列)にします。

```swift
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(objs)

print(String(data: data, encoding: .utf8)!)
```

`.prettyPrinted`を指定すると以下のように整形されて出力されます。

```json
[
  {
    "a" : "1"
  },
  {
    "b" : "2"
  }
]
```

デコードの際に、取得するオブジェクトの型を指定する必要があります。そのため、構造が予めきちんと定義されている（把握できている）JSONでないと扱いが難しくなります（デコーダのカスタムを駆使すれば不可能ではなさそうですが…）。

## JSONSerialization

型がバラバラのJSONを扱う場合は、JSONSerializationの方がお手軽です。その代わり、細かくデータの整合性を確認していくのは大変ですが…。（下記例では強引に「as!」でキャストしていますが、実際にはもう少し丁寧にエラー処理をする必要があると思われます）

```swift
let json = "[{\"a\":\"str\"},{\"b\":2}]".data(using: .utf8)!
let o = try JSONSerialization.jsonObject(with: json)
let objs = o as! [[String:Any]]
let data = try JSONSerialization.data(withJSONObject: objs, options: .prettyPrinted)

print(String(data: data, encoding: String.Encoding.utf8) ?? "can't encode")
```

JSONSerializationについては下記の記事でも触れています。
https://qiita.com/lumbermill/items/6cd1c92909e7ae11a517
vim Scriptでfor i in <number>できないと思った人へ


まぁ昔の自分なのですが()
vim Scriptでは、`for i in`の後には*list型*がこないとダメなようです。
そのため*number*をそのままおいても意味がない。
そこで解決方法

# range()

`range()`を使えば、指定した範囲の数のlistを作ることができます。

```vim
range(1, 5) " -> [ 1, 2, 3, 4, 5]
range(-5, 1) " -> [ -5, -4, -3, -2, -1 ,0, 1]
```

これを応用すれば、

```vim
" <number>回繰り返したい時

for i in range(<number>)
```
とすることができます。

Pythonとかshellscriptと同じですね、よく考えたら。
なぜか忘れてしまっていたので一応共有
Capistranoを利用した自動デプロイでハマったエラー

## つまずいたところ
Capistranoを導入し、ローカルディレクトリでbundle exec cap production deployしてもデプロイされておらず、
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as 〜省略
Caused by:
Net::SSH::AuthenticationFailed: Authentication failed for user　〜省略
となり、起動しなかった。

##　対策①
調べてみたら、デプロイ前にunicornのkillが必要とのことだったので、
kill -QUIT `cat tmp/pids/unicorn.pid`　してみたら
「そのようなファイルやディレクトリはありません」
と怒られる。。

さらに調べると、Capistarnoを導入すると、unicorn.pidの所属するディレクトリが別の場所に移ってしまうため、 tmp/pids/unicorn.pid のようにパスを指定しても、Unicornのプロセスをkillできなくなるとのこと！！

そんな時は、
```$ ps aux | grep unicorn
```
でunicorn masterと表示されているプロセスがkillすべきものとのこと。
そしてその番号を
```kill -9 xxxx
```
killする！！！
とのことだったが、そもそもunicorn master の表記がなく、killしても「そのようなプロセスはありません」
と怒られる。。。。

そもそもkillすべきものはないようです。次の対策へ。。。


## 対策②

エラー文を振り返る。
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as 〜省略
Caused by:
Net::SSH::AuthenticationFailed: Authentication failed for user　〜省略

理由のところに注目。
Authentication とは認証なので、user~の認証がSSHでできていないですよ〜みたいな感じでしょうか。

おそらく認証が上手くいってない模様だったので、

awsからログアウトして、.sshフォルダに移動してから

```$ ssh-add ~/.ssh/xxxx.pem
```
することで解決しました！！

秘密鍵の設定はきちんとやったはずなのに、上手く権限の設定ができていなかったようで。
たまにあることで、その場合このようにすれば良いと教えてもらいました。

まだまだわからないことだらけで呆然とすることが多いですが、滅多にやる作業で備忘録として。
php-master-changes 2018-10-19

今日は一時ファイルを生成して掃除しないテストの修正、.gitignore の不要な指定の除去、phpize/configure が不要なファイルを生成することの修正、継承処理の修正、トップレベル定義の関数について分類を追加する修正があった！

# 2018-10-19
## weltling: Use C++ symbols, when C++11 or upper is compiled
- https://github.com/php/php-src/commit/322b97a19a3a06d7d66e6f74b4dc071384badf64
- zend_isnan()、zend_isinf()、zend_isfinite() について、C++11 以上でのコンパイルなら C++ のシンボルを使うよう修正
- C++ では isfinite()、isinf()、isnan() が std 名前空間に押し込まれているので、C++11 以上のソースがコンパイルされる際にこれらのシンボルを使えなくなる問題があり、[以前に修正されていた](https://github.com/php/php-src/commit/ad790bea2e4a8a25c79ceab964601f3785cd2bf1#diff-f662adf80ae7dd48825c8c2bb03480daL87)

## weltling: Revert "Use C++ symbols, when C++11 or upper is compiled"
- https://github.com/php/php-src/commit/f5bc049136f86b0e0613f4b92e86cd41457aedc9
- ↑なんかアカンかったらしくリバート
- GCC 5 と GCC 8 での違いが何か問題らしい

## petk: Fix tests/output/bug74815.phpt generating errors.log
- https://github.com/php/php-src/commit/de9f325c12d631d0fcbb90d0e5cf34235d9d6073
- [7.2~]
- プロジェクトのルートディレクトリへ errors.log を生成して掃除しないテストがあったので、掃除するよう修正

## petk: Remove outdated PEAR artefacts
- https://github.com/php/php-src/commit/00db0e7a0424ef23086557de1a1eda070596f05e
- かつては PEAR のインストール用に使われていたが、今は（pear.php.net からの phar ダウンロードになったので）使われていないファイルについて、.gitignore から除去

## petk: Fix [#77035](https://bugs.php.net/bug.php?id=77035): The phpize and ./configure create redundant .deps file
- https://github.com/php/php-src/commit/447b41f6bb1e9a5bdeac411277e21a55207123b0
- [7.1~]
- phpize と ./configure が無駄な .deps を生成するのを修正
- かつては automake で使われていたが、だいぶ前に使われなくなった

## petk: [ci skip] Update NEWS
- https://github.com/php/php-src/commit/2224277d7d7efb06adcb512427e299295876fb87
- [7.1~]
- ↑の修正をNEWSへ追記

## dstogov: Don't initialize static_member_tables during start-up, when inherit internal classes.
- https://github.com/php/php-src/commit/03384cae3c46254ccfd5d703b408a0f1d011ee3c
- 継承の処理を修正
- 内部クラス間での継承処理では、親子間で共有される静的メンバ表の再帰的な初期化を行わない、かな？
- 元々ユーザクラス間の継承だけでやっていた処理だが、[Immutable classes and op_arrays](https://qiita.com/sj-i/items/00df29fe32367eea3502#dstogov-immutable-clases-and-op_arrays) の時に[移動した](https://github.com/php/php-src/commit/c63fc5d5f19c58498108d1698055b2b442227eb3)のがまた調整された形

## dstogov: Mark "top-level" functions.
- https://github.com/php/php-src/commit/3fe698b90493cf9f61bb794b2eb61a1296052be7
- トップレベル定義の関数について分類を追加
SATySFiで可変な変数を使う

`let-mutable`で宣言する。参照するときは変数の頭に`!`をつける。
上書きして代入するときは`let () = 変数名 <- 新しい値`のような形で入れ直す。

```
@require: stdja

let-mutable count <- 0

let-inline \counter =
  let c = !count in
  let () = count <- !count + 1 in
  embed-string (arabic c)
in

document (|
  author = { Seiei MIYAGI };
  show-title = true;
  show-toc = false;
  title = { SATySFiで可変な変数を使う }
|) '<
 +p {
   \counter;
   \counter;
   \counter;
   \counter;
   \counter;
   \counter;
   \counter;
   \counter;
   \counter;
   \counter;
 }
>
```

### 実行結果

![Screenshot from 2018-10-20 11-54-53.png](https://qiita-image-store.s3.amazonaws.com/0/2074/37c38dcb-7863-eb22-4a7f-e81c55ce7976.png)
Listのgetterで隠蔽しろと叱られたのでカプセル化的なやつをワンライナーで書いてみる

#環境
開発をしていた際、チェックツールで
「getterのカプセル化というか隠蔽しろや」
みたいな感じで叱られた際の話です

探せば他のすごい方がもっといいコードを書いてそうな気もしますが
探し出せず・・・仕方なく自分で書いてみた結果になります。

ちなみに本記事はJava8を前提に書いております。

#早速
叱られたコードは下記のようなメンバーにListクラスを持ったクラスです。

```java

public class Hoge {
    private List<String> myList;

    public void setName(List<String> list) {
        this.myList = list;
    }

    public List<String> getMyList() {
        return myList;
    }
}
```

現場現場でチェックツール的なものが文化的に育っているんですよね。。
ツールを動かし叱られて初めて知るその現場の文化ｗ

ちなみに
？演算子使うな、とか内部クラス、内部インターフェースもダメ
というものから
メソッドは何行まで・・1行は何文字まで・・条件式は同時に何個まで・・
まぁ細かい文化だわｗ

でその中のひとつに今回の記事である隠蔽できてないよ警告があったわけで。

##とりあえず

```java

    public List<String> getMyList() {
        if(myList != null){
            return new ArrayList<>(myList);
        }else{
            return null;
        }
    }
```

こんな感じでとりあえずチェックツールを回避。
せめて null を許容しなかったら

```Java
    public List<String> getMyList() {
        return new ArrayList<>(myList);
    }
```

だけで良かったんだけど。

##ワンライナーで頑張る
チェックツールで他の警告を潰したところで上記の部分を再着手。
ただのSetterGetterしかないCでいう構造体のようなクラスに
if文は入れたくないよね。

ということで頑張ってみた結果、以下のようになりました。

```Java
    public List<String> getMyList() {
        return Optional.ofNullable(myList).filter(l -> l != null).map(v -> new ArrayList<>(v)).orElse(null);
    }
```

んー長いですねｗ
nullを許容するとこうなるのか・・・

> ただのSetterGetterしかないCでいう構造体のようなクラスに
> if文は入れたくないよね。

と書きましたが、filter結合子入ってるからif文と同じだろ？
という突っ込みは受け付けません。
※カバレージ(c1)的にはセーフかも？

## あとがき、とか
備忘録として書いてますが
誰か他の方に役立ってくれると幸いです。

他、参考にした記事です。
[JavaのGetterで参照を返すことについて](https://qiita.com/thtitech/items/023ad38331cedaa5c891)

以上ありがとうございました。
macにemacsを入れるときにつまずいたメモ

https://qiita.com/hnw/items/d7d71dfcfecff80ad8f1

これのとおりに

```
$ brew tap railwaycat/emacsmacport
```

これ打つと

```
Error: Git must be installed and in your PATH!
==> Installing git
Ignoring bindex-0.5.0 because its extensions are not built.  Try: gem pristine bindex --version 0.5.0
Ignoring byebug-10.0.2 because its extensions are not built.  Try: gem pristine byebug --version 10.0.2
Ignoring byebug-9.0.6 because its extensions are not built.  Try: gem pristine byebug --version 9.0.6
Warning: git 2.18.0 is already installed, it's just not linked
You can use `brew link git` to link this version.
Error: Git is unavailable
```

このエラー


```
brew link --overwrite git
```

```
Ignoring bindex-0.5.0 because its extensions are not built.  Try: gem pristine bindex --version 0.5.0
Ignoring byebug-10.0.2 because its extensions are not built.  Try: gem pristine byebug --version 10.0.2
Ignoring byebug-9.0.6 because its extensions are not built.  Try: gem pristine byebug --version 9.0.6
Linking /usr/local/Cellar/git/2.18.0... 
Error: Could not symlink share/man/man7/gitcli.7
```

やっぱこうなる

```
sudo chown -R $(whoami):admin /usr/local/share/man
```

これでwritableになるが

```
brew reinstall git
brew tap railwaycat/emacsmacport
```
```
Warning: git 2.18.0 is already installed and up-to-date
To reinstall 2.18.0, run `brew reinstall git`
Error: Git must be installed and in your PATH!
==> Installing git
Ignoring bindex-0.5.0 because its extensions are not built.  Try: gem pristine bindex --version 0.5.0
Ignoring byebug-10.0.2 because its extensions are not built.  Try: gem pristine byebug --version 10.0.2
Ignoring byebug-9.0.6 because its extensions are not built.  Try: gem pristine byebug --version 9.0.6
Warning: git 2.18.0 is already installed and up-to-date
To reinstall 2.18.0, run `brew reinstall git`
Error: Git is unavailable
```

やっぱりだめ

https://qiita.com/k315k1010/items/24beeb8d6a8cd64571c8

これやったら

```
brew tap railwaycat/emacsmacport
```

やっと成功
vba【多次元のdictionaryにキーが存在するかを調べる】

phpのissetのようなもの
vbaにはないので作りました。

```vb
Public Function isset(ByRef dic As Dictionary, ByVal KeyArr As Variant, Optional ByVal StartIndex As Integer) As Boolean
    On Error GoTo handler
    If dic.Exists(KeyArr(StartIndex)) Then
        If UBound(KeyArr) = StartIndex Then
            isset = True
        Else
            isset = isset(dic(KeyArr(StartIndex)), KeyArr, StartIndex + 1)
        End If
    Else
        isset = False
    End If
    Exit Function

handler:
    isset = False
End Function
```

呼び出し方

```vb
Private Sub testisset()
    Dim a As New Dictionary
    a.Add "b", New Dictionary
    a("b").Add "c", New Dictionary
    Debug.Print isset(a, Array("b", "c")) ' true
    Debug.Print isset(a, Array("b", "c", "d")) ' false
End Sub


```
現在時刻の取得方法まとめ

# 現在時刻の取得方法まとめ
どんな言語で実装しても現在時刻(ミリ秒まで)を取得したいときがしばしばあるので、
`yyyy/MM/dd HH:mm:ss.SSS`で標準出力する例をまとめておく。

## shell
`date`コマンドを使う。たぶん一番簡単。

```sh
date '+%Y/%m/%d %H:%M:%S.%3N'
```

## C# 
`System.DateTime.Now`を使うと簡単。

```cs
string now = System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss.fff");
System.Console.WriteLine(now);
```

## Java
`java.util.Calendar`を使う方法もあるけど、`java.text.SimpleDateFormat`を使うと簡単。

```java
String now = new java.text.SimpleDateFormat("yyyy/MM/dd HH:mm:ss.SSS").format(new java.util.Date());
System.out.println(now);
```

## Python
`datetime`を使う。`strftime`があるので整形も簡単。

```py
from datetime import datetime
now = datetime.now().strftime("%Y/%m/%d %H:%M:%S.%f")
print(now)
```

## JavaScript
`Date`オブジェクトを生成するだけなのに、いつも整形がめんどくさい。

```js
var now = new Date();
var now_str = now.getFullYear() + "/" + ("0"+(now.getMonth()+1)).slice(-2) + "/" + ("0"+now.getDate()).slice(-2) + " "+ ("0"+now.getHours()).slice(-2) + ":" + ("0"+now.getMinutes()).slice(-2) + ":" + ("0"+now.getSeconds()).slice(-2) + "." + ("00"+now.getMilliseconds()).slice(-3);
console.log(now_str);
```

## C
`gettimeofday()`を使えばマイクロ秒まで取得できる。
`printf`が使えるので整形は簡単だが、取得までがめんどくさい。

```c
#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#include <errno.h>

int main(void){
    struct tm *now; // 年/月/日/時/分/秒などのメンバを持つ構造体
    struct timeval total_usec; // 経過秒取得用変数
    int year, month, day, hour, min, sec, usec;

    /* 現在時刻(経過秒)取得 */
    if(gettimeofday(&total_usec, NULL) == -1){
        fprintf(stderr,"gettimeofday ERRNO=%d", errno);
        return -1;
    }

    /* 経過秒変換 */
    now = localtime(&total_usec.tv_sec); // 経過秒を日本時刻に変換
    year = now->tm_year+1900; //今年に変換
    month = now->tm_mon+1; //今月に変換
    day = now->tm_mday; //今日を取得
    hour = now->tm_hour;
    min = now->tm_min;
    sec = now->tm_sec;
    usec = total_usec.tv_usec; //マイクロ秒

    printf("%d/%02d/%02d %02d:%02d:%02d.%d\n",year,month,day,hour,min,sec,usec);
    return(0);
}
```

## Swift
```swift
import UIKit

let formatter = DateFormatter()
formatter.dateFormat = "yyyy/MM/dd HH:mm:ss.SSS"
print(formatter.string(from: Date()))
```

## SQL
`CURRENT_TIMESTAMP`関数を使う。引数は精度で`(6)`だとマイクロ秒まで取得できる。

```sql
SELECT CURRENT_TIMESTAMP(3);
```

整形する場合は、データベースごとに用意されている独自関数を利用する。

```sql:mysql
SELECT DATE_FORMAT(CURRENT_TIMESTAMP(3),'%Y/%m/%d %H:%i:%S.%f');
```

```sql:postgresql
SELECT TO_CHAR(CURRENT_TIMESTAMP(3), 'YYYY/MM/DD HH:MI:SS.MS');
```
Cloud Dataflowでworkerのメモリ使用量など追加のメトリクスを取得する

# 概要
[Cloud Dataflow](https://cloud.google.com/dataflow/)で、WorkerのGCEインスタンスにStackdriver Monitoring agentを起動し、追加のメトリクスを取得する。

Cloud Dataflowでジョブを起動するとジョブに関するメトリクスがStackdriver経由で収集されるが、workerとして起動されるGCEインスタンスのメモリ使用量やJVMに関するメトリクスはデフォルトでは見ることができない。

# 背景
「Dataflow、Python SDK、ストリーミング」の組み合わせでパイプラインを実行していたが、定期的に処理が停止してしまう問題が発生した。

原因として、メモリを使い切っている可能性があり、その調査のためにメモリ使用量を継続的に取得したかった。

ちなみに使っているapache-beamのPython SDKのバージョンは2.6.0および2.7.0。2.7.0にバージョンを上げたら問題が悪化したため（停止する頻度が高まった）、2.6.0に戻して使っている。

# 方法
[ドキュメント](https://cloud.google.com/dataflow/pipelines/stackdriver-monitoring#receive_worker_vm_metrics_from_stackdriver_name_short_monitoring_agent)にある通り、パイプラインの起動をオプションに`--experiments=enable_stackdriver_agent_metrics`を追加する。

Pythonの`PipelineOptions`あたりのオブジェクトから`--experiments`を設定するには、`DebugOptions`を使う必要があるっぽい。
https://github.com/apache/beam/blob/master/sdks/python/apache_beam/options/pipeline_options.py#L570


# 余談
最近のリリースでJVMのメトリクスも取れるようになったようです。（未検証）


以上です。
Windows10にOracle Clientをインストールするとき詰まった話

仕事でWindows 10が入った2台のマシンにOracle Client 12cをインストールしようとしたときに発生したことです。

## インストーラの検証実行に失敗する
インストーラを起動しインストール・タイプの管理者を選択し、次へをクリックすると。

> [INS-30131] インストーラの検証実行に必要な最初の手順が失敗しました。

と表示されて全く進めなくなる現象がありました。

### c$として共有
調べてみると、Cドライブ全体を「c$」として共有する設定に一時的に変更する解決策[^Cs]がありましたが、
一時的とはいえ危険すぎると判断しこの方法は結局行いませんでした。
ちなみに全く同じ環境の2台が用意されてて同時に作業をしていたのですが、何故か片方一台だけこの現象が発生しました。[^オラクルわからん]
### -ignoreSysPrereqsを付与して起動
次に発見した解決策がOracle Universal Installer(Setup.exe）を `-ignoreSysPrereqs` オプションを付与して起動する方法[^ignoreSysPrereqs]でした。この方法を行うと動作保証が無くなるのですが、すでに別のWindows 10のマシンにはセットアップされた状態で稼働していた[^じゃあ聞けば良かったのでは]ので問題無いと判断し、実行しました。
結論としては**ダメでした**。指定する際に誤字をやらかしているのか何度も見直したのですが結局わからないまま、次の手段を探すことにしました。
### OracleRemExecを停止してやり直す
Oracle Clientはインストールの際にOracleRemExecサービスを利用しているらしく、止まるべき所が正常に停止せず、一時フォルダをロックしたまま死んでいる可能性があるとのことで、早速調べてみました。

そのため [こちら](http://xsh842.cocolog-nifty.com/factor_b/2015/07/oracle-clientin.html) の方法を参考に、インストーラを一度終了させ、タスクマネージャーを起動してサービスタブを見てみると**そもそも該当サービスが存在しない**という。
そんな馬鹿なと思い、サービス管理ツールを開くをクリックしてもう一度見てみると**いました**それも起動中でした。
早速停止させようとするとそんなサービスは存在しないとエラーが表示され停止できないという。（じゃあなんで起動中かわかるんだよ）
ならもう存在しないなら再起動すれば勝手に消えるのでは？と考え、マシンを再起動してもう一度実行してみると何事も無かったように先に進めました。
困ったら再起動、以外と役に立つ手法かもしれません。[^とはいえ]

## PATHが取得できない
こちらは2台ある内の2台ともで発生したのでおそらくWindows 10特有の問題かもしれませんが、しばらく進めると前提条件のチェックの項目でPATHが長すぎるというなんとも意味不明[^PATH]なエラーが出たのですが、無視が可能なので無視して大丈夫です。

## PATHの設定に失敗する
PATHが取得できないのに無視して進めたから当たり前と思ったあなた、これ2台の内1台だけに発生したんですよ。
（それもさっきトラブルが発生したマシンとは別のマシン）
これに関してはPATHにインストール時にデフォルトの場所でインストールしたのであれば
`C:\app\[ユーザ名]\client\product\[バージョン]\client_1`
とかにインストールされているはずなのでそこから`bin`フォルダまでのPATHを指定してあげたら大丈夫だと思います。
（パスがうろ覚えですまんな）

## さいごに
すでにサーバーとの接続設定が済まされているtnsnames.ora等に入れ替えて、無事にSQLツール等からDBをOracle Client経由で操作可能になりました。
めでたしめでたし。~~Oracle Client 12c完全に理解した。~~


[^Cs]: このブログ方法 http://totech.hateblo.jp/entry/2015/02/16/225843
[^オラクルわからん]: わからん・・・Oracle Client何もかもわからん・・・・
[^ignoreSysPrereqs]: https://teratail.com/questions/23165 の回答の1つ
[^じゃあ聞けば良かったのでは]: Q.じゃあ聞けば良かったのでは？　A.セットアップを担当した数人のうち残ってた人は1人、本当に手段が思いつかなくなった時以外に聞かないと機嫌を損ねてしまう可能性があって・・・
[^とはいえ]: 希に再起動するとOSが死ぬというパターンもあるから頼り切るのは禁物かも？
[^PATH]: まっさらな環境なので4つ6つぐらいしか設定されていないので長いもクソもあるかよ
[図解]スタブとモックの違い

自分用備忘録。

どちらもテスト対象に依存関係が必要な場合のために使うダミーですが、違いをサクッとまとめました。

# モック
テスト対象からの出力を受けるダミー。

![image1.jpg](https://qiita-image-store.s3.amazonaws.com/0/145575/18953103-2a5a-121f-6b7c-489f2e0c4654.jpeg)

# スタブ
テスト対象に都合の良いデータを出力してくれるダミー。

![image2.jpg](https://qiita-image-store.s3.amazonaws.com/0/145575/3a0f8a12-291f-2f5b-deb5-6f7c8b2e8072.jpeg)
Jsonを手軽にFirebase Realtime Databaseへ保存する

# やりたいこと
ローカルで作成したjsonファイルをFirebase Realtime Databaseへ保存したい。

Web画面からFirebase Console => DatabaseでJsonをインポートで保存する事はできるが、Webは手順が多くて面倒。

nodejsからできるようなので試してみた。

```js
const request = require('request');
const firebase = require("firebase");
const config = require("../config.js");
const firebaseConfig = {
    databaseURL: config.firebase.databaseURL
};
firebase.initializeApp(firebaseConfig);

request('https://プロジェクトID.firebaseio.com/', (error, response) => {
    if (!error && response.statusCode == 200) {
        var json = require(`./送信したいJson.json`)
        firebase.database().ref('送信したいDBパス').set(json) //保存
        console.log("success!");
    }
    else {
        console.log("error!");
        console.log(error);
    }
    firebase.database().goOffline() //firebase接続を切る
})
```

無事保存できました。

本当はjsじゃなくてシェルスクリプトでやりたいので試してみよう。
varnishlogで特定のログのみ出力する方法

Varnishのログは、以下のコマンドを実行して確認できます。

※ 導入やデバッグまでの手順については、以下を参考にしてください


|[Varnishを自社メディアに導入しました - LCL Engineers' Blog](http://techblog.lclco.com/entry/2016/03/01/083235) ![](http://b.hatena.ne.jp/entry/image/http://techblog.lclco.com/entry/2016/03/01/083235)<BR>LCLで運営している「バスとりっぷ」というメディアに、キャッシュサーバとしてVarnishを導入しました。導入する上でハマった事・得たノウハウなどを... | ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89348/55964a49-2e29-e243-3f30-df1893dede9e.png)|
|:--|:-:|


```shell
$ varnishlog
```

実行後はリクエストが送られるたびにキャッシュ対象のパス毎のログが出力されます。
それらの中から特定の値を見つければよいのですが、1つのログの出力はとても多いため目視で探すのは非常に困難です。
また、必要のないfaviconや画像などのアセットなどのログも大量に出力されるので１画面に収まることは少ないと思います。

この場合、varnishlogのオプションを利用することで欲しい情報のみを出力するようにできます。
今回は、キャッシュの存在を確認する方法を例にして説明します。

### URLのみ出力する

URLは`ReqURL`のタグで設定されているため、このタグのみ出力するよう指定します。

```shell
$ varnishlog -i requrl

*   << BeReq    >> 36

*   << Request  >> 35
-   ReqURL         /hoge/

*   << Session  >> 34

*   << Request  >> 32800
-   ReqURL         /assets/hoge/pc/application-b9fdskjaflsdkjfec0db473f11ef2345a932ec9cc31aa23ualfhahiuhaf.css

*   << Session  >> 32799

*   << BeReq    >> 32801

*   << BeReq    >> 39

*   << Request  >> 38
-   ReqURL         /images/hoge/logo.png

*   << Session  >> 37

*   << BeReq    >> 131075

*   << Session  >> 131073

...
```

### RespHeaderタグのX-Cacheのみ出力する

URLに加えて、キャッシュフラグも表示します。
RespHeaderはいくつもの値が設定されているため、正規表現を使える`-I`で`X-Cache:`を含めます。

```shell
$ varnishlog -I "RespHeader:X-Cache:" -i requrl

*   << Request  >> 196616
-   ReqURL         /hoge/
-   RespHeader     X-Cache: HIT desktop

*   << Session  >> 196615

*   << Request  >> 47
-   ReqURL         /assets/hoge/pc/application-b9fdskjaflsdkjfec0db473f11ef2345a932ec9cc31aa23ualfhahiuhaf.css
-   RespHeader     X-Cache: HIT desktop

*   << Session  >> 46

*   << Request  >> 196618
-   ReqURL         /images/bustrip/logo.png
-   RespHeader     X-Cache: HIT desktop

*   << Session  >> 196617
```

### 特定のURLのみ出力する

上記で出力したい要件は満たせていますが、他のURLも出力されてしまってノイズが多いです。
そこで`/hoge/`のみを指定して出力するようにします。

```shell
$ varnishlog -I "RespHeader:X-Cache:" -i requrl -q "ReqUrl eq '/hoge/'"

*   << Request  >> 196627
-   ReqURL         /hoge/
-   RespHeader     X-Cache: HIT desktop
```


以上で必要なログのみ出力できるようになりました。

##### 補足

```shell
/hoge/
/images/hoge/img_sample.png
/hoge/?utm_source=fuga&utm_medium=referral&utm_content=nonews
```

これらを判別する際は正規表現を使うとよいです。

```shell
$ varnishlog -I "RespHeader:X-Cache:" -i requrl -q 'ReqUrl ~ "^\/hoge\/"'
```

他にも画像、アセットのみ除外はこのように書きます。

```
$ varnishlog -I "RespHeader:X-Cache:" -i requrl -q 'ReqUrl !~ "(jpg|jpeg|gif|png|bmp|assets)"'
```



クエリの種類：https://feryn.eu/blog/varnishlog-measure-varnish-cache-performance/#VSL_queries
textareaの大きさを自動調整

## 概要

入力量に応じて自動でtextareaのrowsを設定します。[前に書いた記事](https://qiita.com/ne_no_usa/items/32fe08c9417cb241bb92)だとうまくいかないことがあったので別の方法を考えました。

## 使い方

以下の内容を記した関数などをSetIntervalなどで定期的に呼び出すか、keyupイベント等のタイミングで呼び出してください。

## 自動で拡大する

### JQueryを使う場合

```JavaScript
const target = $("テキストエリアのIDなど");
const rawTarget = target.get(0);
let lineHeight = Number(target.attr("rows"));
while (rawTarget.scrollHeight > rawTarget.offsetHeight){
    lineHeight++;
    target.attr("rows", lineHeight);
}
```

### JQueryを使わない場合

```JavaScript
const target = document.getElementById("テキストアリアのID");
let lineHeight = Number(target.getAttribute("rows"));
while (target.scrollHeight > target.offsetHeight){
    lineHeight++;
    target.setAttribute("rows", lineHeight);
}
```

## 最大行数を設定して自動で拡大する

```JavaScript
const target = document.getElementById("テキストアリアのIDなど"); //jQueryの場合は target = $("～～").get(0); でOK
const maxLineHeight = 最大行数;
let lineHeight = Number(target.getAttribute("rows"));
while (Target.scrollHeight > Target.offsetHeight && lineHeight < maxLineHeight){
    lineHeight++;
    target.setAttribute("rows", lineHeight);
}
```
ExcelのRangeは配列と大体同じじゃない？


# 前記事の訂正

[去年のカレンダー](https://qiita.com/matumoto_onga/items/a39d701e7f1395499cea)で、
下記のような関数を使って、テーブルN行の値を、各変数に割り当てていました。

```vb
Call DD(AR(R,N),年,機械,連番,製品番号,製品名) 

Sub DD(AA, ParamArray AP())
    Dim J: For J = 0 To UBound(AP)
        AP(J) = AA(J + 1)
    Next J
End Sub

Function AR(R, Optional M = 0, Optional N = 0, Optional S = "")
    On Error Resume Next
    M = IFZS(M, MM(R))
    N = IFZS(N, R.Rows.Count)
    ReDim S(1 To N): Dim J: For J = 1 To N: S(J) = DI(R, M, J): Next J
    AR = S
End Function
```

しかし、Rangeと配列は同じように扱えることがわかったので、わざわざ配列にする必要はないので、
DDを捨てて下記の関数を使うようになりました。

```vb
Call DR(R,I,年,機械,連番,製品番号,製品名)

Sub DR(R, I, ParamArray PA())               ' DATA READ
    Dim J: For J = 0 To UBound(PA)
        PA(J) = DI(R, I, J + 1)
    Next J
End Sub
```

# やってみたら上手くいきました。
関数MI はWorksheetFunction.Matchの再定義で、RにはRangeが入るのが期待されるていますが、
[Excelでスピルを使う方法](https://qiita.com/matumoto_onga/items/562a3e2283e4e4b65ef6)で、一次元の配列を入れてみるとちゃんと値を返してくれました。
Rangeと配列は、大体同じじゃない？

```vb
Function TI(R, V, Optional S = "")  ' TABLE INDEX
    S = MI(R, V)               ' 配列にMatch が使えるなんて驚きだ！　　　　　　　
    If S <> "" Then S = S - 1  ' 配列にあわせるために-1

    TI = S
End Function

Function MI(R, V, Optional S = "")     ' MATCH INDEX
     On Error Resume Next
     S = WorksheetFunction.Match(V, R, 0)
     MI = S
End Function
```

# スピル時代のExcel VBA
次期Excelでスピルが有効になると、Rangeと配列が双方向にデータのやり取りが可能となり、
ユーザ定義関数が格段に書き易くなります。
無理にvslookupのような既存の関数を組み合わせてスパゲッティにするバッドノウハウよりも、
ユーザ定義関数をきれいに書くという作法を身に着けさせるように、
Excelの入門書を書き直す必要があるかと思います。

ではでは。