OmniAICreator/Qiita-1.07M huggingface dataset:
screen とか tmux とかのススメ

# 概要

以下のような経験があり、現在困っている人向けの対策の紹介

```
計算専用のサーバーにログインし、オーバーナイトで解析プログラムを
走らせていると、たまに、サーバーから締め出される。
```

# 結論

`screen` または `tmux` を使う

# なぜ、締め出されるのか？

いろいろ原因は考えられるのだが、
おそらくは、ネットワークが切れてしまったということが考えられます。

自動で再接続されると、人間はきづかないケースがあるかと思いますが、
ネットワークが切れてしまうと、解析もとまってしまいます。

# なぜ、screen か tmux なのか？

他にもいくつか方法はありそうですが、
`screen` や `tmux` の方が、無難だと思います。

- デタッチ(解析は続きます)
- アタッチ(一度ログアウトしても、またログインして解析している状況を確認できます）

も簡単です。

# screen と tmux どちらがおすすめか？

好みでどうぞ、という感じですが、
まわりに使い方をしっている人がいるものからはじめてみるのもよいかもしれません。

screen の方が歴史は長いですが、tmux もそれなりに長く、
どちらも困ったことを調べるのには苦労しないのではないかと思います。

# 自分は

screen を長く使っている関係で、screenを使っていますが、
たまに、tmux や byobu なども使ってみています。

# その他

ちょっと長いのと、かなりマニアックな話ですが、バックアップについても考えてみては？

とりあえず、１次データだけでも、バックアップしはじめて、待っている間によんでいただければ。

* [データのバックアップの方法について考える - Qiita](https://qiita.com/manabuishiirb/items/0fe41573dbb360ddec63)
都道府県コードCSV JIS X0402

#本文
@tao_s さんの [国コード一覧CSV ISO 3166-1](https://qiita.com/tao_s/items/32b90a2751bfbdd585ea) に触発されて、都道府県コードのCSV形式データを共有します。X0402 のコードに "JP-" を前置すれば "[ISO 3166-2:JP](https://ja.wikipedia.org/wiki/ISO_3166-2:JP)" のコードになります（例: "JP-47" 沖縄県）

```csv:コードと名称
"Code","Name"
"01","北海道"
"02","青森県"
"03","岩手県"
"04","宮城県"
"05","秋田県"
"06","山形県"
"07","福島県"
"08","茨城県"
"09","栃木県"
"10","群馬県"
"11","埼玉県"
"12","千葉県"
"13","東京都"
"14","神奈川県"
"15","新潟県"
"16","富山県"
"17","石川県"
"18","福井県"
"19","山梨県"
"20","長野県"
"21","岐阜県"
"22","静岡県"
"23","愛知県"
"24","三重県"
"25","滋賀県"
"26","京都府"
"27","大阪府"
"28","兵庫県"
"29","奈良県"
"30","和歌山県"
"31","鳥取県"
"32","島根県"
"33","岡山県"
"34","広島県"
"35","山口県"
"36","徳島県"
"37","香川県"
"38","愛媛県"
"39","高知県"
"40","福岡県"
"41","佐賀県"
"42","長崎県"
"43","熊本県"
"44","大分県"
"45","宮崎県"
"46","鹿児島県"
"47","沖縄県"
```

```csv:コードと名称とよみ
"Code","Kanji","Katakana","Hiragana"
"01","北海道","ホッカイドウ","ほっかいどう"
"02","青森県","アオモリケン","あおもりけん"
"03","岩手県","イワテケン","いわてけん"
"04","宮城県","ミヤギケン","みやぎけん"
"05","秋田県","アキタケン","あきたけん"
"06","山形県","ヤマガタケン","やまがたけん"
"07","福島県","フクシマケン","ふくしまけん"
"08","茨城県","イバラキケン","いばらきけん"
"09","栃木県","トチギケン","とちぎけん"
"10","群馬県","グンマケン","ぐんまけん"
"11","埼玉県","サイタマケン","さいたまけん"
"12","千葉県","チバケン","ちばけん"
"13","東京都","トウキョウト","とうきょうと"
"14","神奈川県","カナガワケン","かながわけん"
"15","新潟県","ニイガタケン","にいがたけん"
"16","富山県","トヤマケン","とやまけん"
"17","石川県","イシカワケン","いしかわけん"
"18","福井県","フクイケン","ふくいけん"
"19","山梨県","ヤマナシケン","やまなしけん"
"20","長野県","ナガノケン","ながのけん"
"21","岐阜県","ギフケン","ぎふけん"
"22","静岡県","シズオカケン","しずおかけん"
"23","愛知県","アイチケン","あいちけん"
"24","三重県","ミエケン","みえけん"
"25","滋賀県","シガケン","しがけん"
"26","京都府","キョウトフ","きょうとふ"
"27","大阪府","オオサカフ","おおさかふ"
"28","兵庫県","ヒョウゴケン","ひょうごけん"
"29","奈良県","ナラケン","ならけん"
"30","和歌山県","ワカヤマケン","わかやまけん"
"31","鳥取県","トットリケン","とっとりけん"
"32","島根県","シマネケン","しまねけん"
"33","岡山県","オカヤマケン","おかやまけん"
"34","広島県","ヒロシマケン","ひろしまけん"
"35","山口県","ヤマグチケン","やまぐちけん"
"36","徳島県","トクシマケン","とくしまけん"
"37","香川県","カガワケン","かがわけん"
"38","愛媛県","エヒメケン","えひめけん"
"39","高知県","コウチケン","こうちけん"
"40","福岡県","フクオカケン","ふくおかけん"
"41","佐賀県","サガケン","さがけん"
"42","長崎県","ナガサキケン","ながさきけん"
"43","熊本県","クマモトケン","くまもとけん"
"44","大分県","オオイタケン","おおいたけん"
"45","宮崎県","ミヤザキケン","みやざきけん"
"46","鹿児島県","カゴシマケン","かごしまけん"
"47","沖縄県","オキナワケン","おきなわけん"
```
@nappa さんが [JIS X 0401 と都道府県の順番](https://qiita.com/nappa/items/ffaf1c7d7bbc9784a7f7) で言及しておられますが、都道府県入力UI上、コードの順番が利便性と繋がっているかといえば疑問です。
個人的に、ドロップダウンリスト（コンボボックス）から都道府県を選ばせるUIは面倒くさい...テキストボックスへ、漢字や読みを１文字入力すると候補を出してくれたり、自動補完してくれたり、せいぜいタイポを指摘してくれる程度のほうが有り難いです。区市町村以下はテキスト入力するのですし。

日本郵便のサイトで配布されている郵便番号データ "ken_all.csv" は有名ですが、次の記事にあるとおり"取扱注意"のようです。

- [KEN_ALL.CSV (郵便番号検索)の落とし穴](https://qiita.com/nanasess/items/0f0aeaa1f72f599b9142) @nanaseeさん
- [郵便番号や市区町村データを取り扱うときにはまったこと](https://qiita.com/_takwat/items/3a121656425fac7bb820) @_takwatさん

#ご参考

- [JIS検索](http://www.jisc.go.jp/app/jis/general/GnrJISSearch.html) 本家。中身も見られます。
- [ISO検索](https://www.iso.org/obp/ui/) 本家。中身については有償。一部は [無償公開](http://standards.iso.org/ittf/PubliclyAvailableStandards/)。
- [エンジニアが知っておいて損は無さそうなISOの標準規格たち](https://qiita.com/laqiiz/items/783c5442c49a91ef1a77) @laqiizさん
RSpecのallow_any_instance_ofでブロック指定するときは第一引数に注意

自分用メモ。
[リファレンス](https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance#block-implementation-is-passed-the-receiver-as-first-arg) に書いてあることそのまま

## ハマったこと

```app/models/user.rb
class User
  def recommended_books(limit: 3)
    RecommendationService.new(self).recommended_books(max_recommendation_size: limit)
  end
end
```

みたいなメソッドがあったとして、RecommendationServiceは外部サービスなので、テストには不便。
RecommendationServiceの内部実装も知らんので、User#recommended_booksをモックすることにした。

### これはOK

```ruby
user = create(:user)
allow(user).to receive(:recommended_books) do |args|
  create_list(:book, args[:limit])
end
```

### これはNG

```ruby
allow_any_instance_of(User).to receive(:recommended_books) do |args|
  create_list(:book, args[:limit])
end
```

args[:limit] がnil になってハマる！

## なんで？？？

### 第1引数は、レシーバーのオブジェクト！第2引数以降がメソッドの引数！

って[リファレンス](https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance#block-implementation-is-passed-the-receiver-as-first-arg)に書いてあった。

なので、

```ruby
allow_any_instance_of(User).to receive(:recommended_books) do |user, args|
  create_list(:book, args[:limit])
end
```

とすればよい。

## まとめ

[リファレンス](https://relishapp.com/rspec/rspec-mocks/docs/working-with-legacy-code/any-instance#block-implementation-is-passed-the-receiver-as-first-arg) はちゃんと読みましょう。
VirtualBoxで内部ネットワーク構築するとpingにDUP!が返ってくる問題

## 遭遇した事象
VirtualBoxでCentOS7を3台立て、内部ネットワークの設定をしてpingで疎通確認をしている時だった、、、

```
[root@node01 ~]# ping 192.168.10.12
PING 192.168.10.12 (192.168.10.12) 56(84) bytes of data.
64 bytes from 192.168.10.12: icmp_seq=1 ttl=64 time=0.690 ms
64 bytes from 192.168.10.12: icmp_seq=1 ttl=63 time=0.738 ms (DUP!)
64 bytes from 192.168.10.12: icmp_seq=1 ttl=64 time=1.18 ms (DUP!)
64 bytes from 192.168.10.12: icmp_seq=1 ttl=63 time=1.29 ms (DUP!)
From 192.168.10.10: icmp_seq=2 Redirect Host(New nexthop: 192.168.10.12)
From 192.168.10.10 icmp_seq=2 Redirect Host(New nexthop: 192.168.10.12)
```

ping応答が重複しているだと？誰がお返事しているんだろ、、、
あれこれ探ってみたところ、原因はポートフォワーディング機能が有効になっていたことだった。

ここでは例としてA,B,Cの3ノードがあり、例えばA->Bへpingを打つことを考える。
pingを受け取ったBは期待通りAに返答するのだが、Cもpingのパケット自体は受け取ることになる。このとき、受け取ったパケットはCに向けられたものではないから破棄すればよいのだが、ポートフォワーディング機能によってBに転送してしまう。
結果としてBは2回Aにping応答を返してしまうことになる。

## ポートフォワーディンの動作を確認する実験
実験として、上記例でBのNICを落とした状態でA->Bにpingを打ってみる。

```:ポートフォワーディングによるパケットの転送
[root@node01 ~]# ping 192.168.10.12
PING 192.168.10.12 (192.168.10.12) 56(84) bytes of data.
From 192.168.10.10: icmp_seq=2 Redirect Host(New nexthop: 192.168.10.12)
From 192.168.10.10 icmp_seq=2 Redirect Host(New nexthop: 192.168.10.12)
From 192.168.10.10: icmp_seq=3 Redirect Host(New nexthop: 192.168.10.12)
```

ほら、C(192.168.10.10)がB(192.168.10.12)に転送しているでしょ！

## ポートフォワーディング無効化の設定
ポートフォワーディングの無効化は簡単。

```bash:IPフォワーディングを無効化
sysctl -w net.ipv4.ip_forward=0 # net.ipv4.ip_forward = 0

# sysctlコマンド使えなければ下記でも可
echo 0 > /proc/sys/net/ipv4/ip_forward
```

設定後、無事にping DUP!が消えました。めでたしめでたし。
制限付きアクセスから回復するバッチを作った

突然ですが、以下の状態って結構あったりしますか？
![wlan2.png](https://qiita-image-store.s3.amazonaws.com/0/221393/bfe07239-c415-2443-9e8e-44b7fde662e4.png)
ないですか。そうですよねー。
日本だとこんな風にハングりませんよね。
おい、ここグアテマラ、バングラディシュのWiFiか？って感じになりませんか？
※大好きな国です。

こんな状態を解決するバッチを作ってみました。


```BAT:wlan.bat
@echo off

rem ---------------------------------
rem 作業ディレクトリ
set DIRPATH=C:\wlan

rem ping先アドレス
set PINGIP=<任意のどっか>

rem SSIDの指定
set SSID=<自分のSSID>

rem WLANインターフェィス名の指定
set WLANIF="ワイヤレス ネットワーク接続"

rem 実行ログ吐き出し有無(0無効or1有効)
set LOG=1
rem ---------------------------------

cd %DIRPATH%

rem 疎通テスト
ping -n 1 %PINGIP%

if ERRORLEVEL 1 (
	netsh wlan show interface > wlan.txt
	for /f "delims=" %%a in (wlan.txt) do (
		if "%%a"=="    SSID                   : %SSID%" (
			netsh int set int %WLANIF% disable
			netsh int set int %WLANIF% enable
			if "%LOG%" == "1" (
					echo 実行しました。%date% %time% >> log.log
			)
		exit 0
		)
	)
)

exit 0

```

やってることはシンプルで何らかの原因でハングっている状態ならば
無線IFを無効、有効にするだけです。
つまり、無線IFを無効、有効で直る症状でのみ有効なバッチです。

あとはWindowsのタスクスケジューラに登録すればOK。

登録は以下を参考に
https://qiita.com/Richard_Roe/items/44e16841f16ee40c6113
aws cloudformation package コマンドで自動的にS3にアップロードしてくれるリソース一覧


SAMでの利用がメインとなる`aws cloudformation package`コマンドですが、実は他にも色々なリソースをS3に自動アップロードしてくれます。

すぐ忘れてしまうので自分用メモということで以下にまとめておきます。

# TL;DR

aws cloudformation package便利！

# 対称読者

CloudFormationを利用してテンプレート以外のリソースをデプロイしている（したい）人

# 何ができる？

`aws cloudformation package`コマンドを利用するとテンプレート外のリソース（プログラムコード、ネストしているテンプレート、Swagger定義ファイル）をアップロードしてくれる

# 対応表

| Type | Property | Zip |
|---|---|---|
| AWS::Serverless::Function | CodeUri | true |
| AWS::Serverless::Api | DefinitionUri | false |
| AWS::ApiGateway::RestApi | BodyS3Location | false |
| AWS::Lambda::Function |Code | true |
| AWS::ElasticBeanstalk::ApplicationVersion | SourceBundle | true |
| AWS::CloudFormation::Stack | TemplateURL | false |


Type: CloudFormationテンプレートのリソースのタイプ
Property: CloudFormationテンプレートの対象タイプのプロパティ名
Zip: アップロード時にzip圧縮するかどうか

# 例

以下のようにテンプレートからの相対パスで記述する

```yaml:template.yml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: The AWS CloudFormation template for BSE Workflow
Resources:
	MyLambdaFunction:
		Type: AWS::Serverless::Function
		Properties:
			CodeUri: ./code
       		...
```

↓

```bash
$ aws cloudformation package \
	--s3-bucket [BucketName] \
	--s3-prefix [Prefix] \
	--template-file template.yml \
	--output-template-file .template.yml
$ cat .template.yml
AWSTemplateFormatVersion: 2010-09-09
Transform: AWS::Serverless-2016-10-31
Description: The AWS CloudFormation template for BSE Workflow
Resources:
	MyLambdaFunction:
		Type: AWS::Serverless::Function
		Properties:
			CodeUri: s3://[BucketName]/[Prefix]/[ファイルのハッシュ値]
       		...
```

※ --s3-prefixを指定しない場合はトップレベルにアップロードされる
※ --output-template-fileを指定しない場合は標準出力に出力される

# 参考

- [対称部分のソースコード](https://github.com/aws/aws-cli/blob/master/awscli/customizations/cloudformation/artifact_exporter.py)
- [How to create serverless applications using AWS SAM](https://github.com/awslabs/serverless-application-model/blob/master/HOWTO.md)
テストパターンの作成について

##テストパターンの重要性
　ソフトウェアの各テストを行う上でテストパターンは重要です。
テストパターンは少なければユースケースを網羅できず確認漏れが発生してしまいます。逆に多すぎるとテスト工数を圧迫してしまいます。重複を防ぎユースケースを網羅したテストパターンを作成しテストに使用していくことが重要です。
　QAとしてテスト業務をしているなかでテストパターン不足で不具合を発見できなかったことがあります。このとき、テストパターンの重要性を改めて認識しテストパターンの作成方法を見つめ直すきっかけになりました。


##テストパターンの作成について
　テストパターンは実際にユーザーが使用しているデータを分析してテストパターンを作成したり、そのまま使用すればユースーケースとして考慮されたテストパターンをテストに使用できます。しかし、ユーザーが使用しているデータには個人情報を含むケースが多いため、確認したりテストに使用することはできません。しかし、適当な値や偏ったテストパターンでテストするとBugを発見できないことがあります。
　そのため、今回は公に公開されている資料からテストパターンを作成していくことにしました。

　電話番号のテストパターンについてはテストケース作成前は実家の電話番号や職場の電話番号を知っている程度の知識でした。しかし、調べていくうちに総務省が定める[電気通信番号指定状況](http://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/number_shitei.html)というものがあり、その中に電話番号の指定法則や使用されている市外局番が記載されていることがわかりました。

　勤めている会社の代表や支店の電話番号を使用するという方法もありますが、偏ったテストケースになる場合があります。テストデータは可能な限り偏りがなくユースケースを網羅したテストパターンが必要です。


###テストデータの作成例
　先述したように電話番号の規則は総務省の電気通信番号指定状況に記載されています。

そこから以下のことが読み取れます。
電話番号は
国内プレックス「０」＋市外局番「１〜４桁」＋市内局番「１〜４」＋加入者番号「４桁」
という条件と
桁数は固定電話は１０桁、携帯電話やPHSは１１桁
という条件が読み取れます。

上記の条件から下記の電話番号のテストパターンが考えられます。
・03-XXXX-YYYY
・025-XXX-YYYY
・0250-XX-YYYY
・04998-X-YYYY
・090-XXXX-YYYY

　Yは加入者番号に当たるため、ゾロ目を除くランダムな数字を使用します。ゾロ目を使用しないのは数字の順番が間違って表示されたり登録されたりすることを発見しやすくするためです。
　Xには任意の数字を当てはめて使用できますが、上記総務省のHPに市外局番の一覧のPDFが添付されています。このPDFの中に使用されている市外局番と使用されていない市外局番が記載されています。このPDFの市外局番を使用することでユースケースに近いテストパターンを作成できます。


##最後に
　今回テストパターンについて書かせていただきました。
自分以外の人に何かを伝えることは難しいと改めて感じました。伝えるためには伝えることに対して知識を持ち理解していないといけません。また、伝えることを整理し伝えやすいように再構築しないといけません。これを何回も繰り返し、やっと伝えれる形になります。
　今回は貴重な経験をできたと思います。
　
読んでいただきありがとうございました。
powershell chatwork用 2.0系とそれ以上対応


# Chatworkにメッセージ投げる関数

Invoke-WebRequest 使えない2系にも一応対応した。

やっつけでやってる部分も有るので、汚い所はスルーで。


```powershell

## Chatwork用
$apitoken = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$roomid = "12345678"

$toAddress = "[To:XXXX] てすとさん"

$chatworkUri = "https://api.chatwork.com/v2/rooms/{0}/messages" -f $roomid


# chatwork通知
function SendChatworkMsg([string] $title, [string] $msg){
    # powershell 2.0 対応
    if($PSVersionTable.PSVersion.Major -ge 2){
        SendChatworkMsg_2 -title $title -msg $msg
	    return	
    }
    $toAddress = setToMsg
    if(![string]::IsNullOrEmpty($toAddress)){
        $msg = $toAddress + "`n" + $msg
    }

    $r = Invoke-WebRequest -Uri $chatworkUri `
         -Method POST `
         -Body @{"body" = "[info][title]$title[/title]$msg[/info]"} `
         -Headers @{"X-ChatWorkToken" = $apitoken}

}

# PS 2.0向け
function SendChatworkMsg_2{ 
    param( 
         [string] $title, [string] $msg
    ) 
 
    $toAddress = setToMsg
    if(![string]::IsNullOrEmpty($toAddress)){
        $msg = $toAddress + "`n" + $msg
    }

    $fields=new-object System.Collections.Specialized.NameValueCollection 
    $fields.Add("body","[info][title]$title[/title]$msg[/info]") 

    $wc = new-object System.Net.WebClient 
    $wc.Headers.Add("X-ChatWorkToken",$apitoken) 
    

     Try{ 
          #$wc.UploadValues($chatworkUri, $fields) 
          $res = $wc.UploadValues($chatworkUri, "POST", $fields) 
          #Write-Host $res
     } 
     Catch{ 
          throw $_ #rethrow the exception 
     } 
} 

function setToMsg{
    return $toAddress
}


#TEST
#SendChatworkMsg "TEST" "MSG"
#SendChatworkMsg_2 "TEST" "MSG"

```
%>%で試行錯誤する時はreturnで終わろう

# %>%って？

dplyr(厳密にはmagrittr)というライブラリを導入することで使えるRでパイプラインを実現する中置演算子。

```r
plot(density(iris$Sepal.Length))
```

は、

「iris(アヤメ)のSepal.Length(萼片長)についてdensityでカーネル密度を計算して、結果をplotする」

に相当するが、頭で考える流れとコードの流れが見事に逆であることが分かる。

これが%>%を使うと

```r
library(dplyr)

iris$Species %>%
  density %>%
  plot
```

と思考と調和的な流れでコーディングでき、%>%でほどよく改行でき、とても読み易くなりデバグも用意になる。。

もう少し詳しいところはkilometerさんが先日のTokyo.Rで綺麗に図解してくださったので、[そちら](https://speakerdeck.com/kilometer/66th-tokyo-dot-r-beginner-session2?slide=16)を参照して頂きたい。

# hoge %>% returnで便利に

コーディングしていると

この処理をなくしたい!
処理の順番を変えたい!

といったことが往々にして起きる。
最終行以外はコメントアウトやカットアンドペーストで一発だ。

しかし、最終行が対象になると手間が増える。
たとえば、アヤメデータをフィルタリングするため

```r
iris %>% 
  filter(Sepal.Length > 5) %>% #萼片長が5以上
  filter(Species == 'setosa' %>% #setosa種
```

とした時、やっぱSpeciesはフィルタリングしなくていいとなると

1. 3行目を消す(orコメントアウトする)
2. 2行目の末尾のパイプラインを消す(orコメントアウトする)

といったステップを踏むことになる(以下)。

```r
iris %>% 
  filter(Sepal.Length > 5) # %>% #萼片長が5以上
  # filter(Species == 'setosa' %>% #setosa種
```

ところが、予めreturnで終わっておくと以下のように3行目をコメントアウトするだけでよい。

```r
iris %>% 
  filter(Sepal.Length > 5) %>% #萼片長が5以上
  # filter(Species == 'setosa' %>% #setosa種
  return()
```

3行目をコメントアウトするだけでよい。

RStudioユーザーであればCtrl + Shift + Cで行をコメントアウトできるので便利だ。
しかも適切にインデントしてくれる。

# hoge %>% str %>% returnで更に便利に

strを使うと、オブジェクトの構造が分かる。
デバグに便利。

```r
iris %>%
  select(-Species) %>%
  scale() %>%
  lm(Sepal.Length ~ ., data = .)
```

は失敗する。
scaleの返り値がマトリクスで、データフレームではないからだ。

```r
iris %>%
  select(-Species) %>%
  scale() %>%
  lm(Sepal.Length ~ ., data = .) %>%
  str() %>%
  return()
```

としておくと、

```r
iris %>%
  select(-Species) %>%
  scale() %>%
  # lm(Sepal.Length ~ ., data = .) %>%
  str() %>%
  return()
```

任意行をコメントアウトした時の結果の構造を見ることができる。
そして、あ、scaleの返り値はmatrixなのかと気付くと,`as.data.frame %>%`を挿入して`str %>%`をコメントアウトすればいい。

```r
iris %>%
  select(-Species) %>%
  scale() %>%
  as.data.frame %>%
  lm(Sepal.Length ~ ., data = .) %>%
  # str() %>%
  return()
```

この長さのパイプラインでは大したことがないが、長くなればなるほど便利だ。

```r
iris %>%
  select(-Species) %>%
  # scale() %>%
  # as.data.frame %>%
  # lm(Sepal.Length ~ ., data = .) %>%
  str() %>%
  return()
```

とほとんどをコメントアウトして、うまくいっていることを確認したら一行ずつコメントアウトを取り消し、strを見ることを繰り返して最後にstrをコメントアウトするといったデバグができる。
MongoDBをバージョンを指定してインストールするメモ for Ubuntu 16.04


公式の[Install MongoDB Community Edition on Ubuntu](https://docs.mongodb.com/master/tutorial/install-mongodb-on-ubuntu/)をみながら進めます。Azureの仮想マシンのUbuntu16.04にMongoDBをインストールします。

以下のコマンドを実行していけば基本はOKですが少しエラーがでた。

* publivk keyの設定

```
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 2930ADAE8CAF5059EE73BB4B58712A2291FA4AD5
```

* Ubuntu 16.04でリストファイル作成

```
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/3.6 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.6.list
```

* ローカルパッケージの更新

```
sudo apt-get update
```

* MongoDBのインストール

最新が3.6.0らしいのでバージョンを指定してインストール。ここの数字を変えればバージョン指定でいけそう。

```
$ sudo apt-get install -y mongodb-org=3.6.0 mongodb-org-server=3.6.0 mongodb-org-shell=3.6.0 mongodb-org-mongos=3.6.0 mongodb-org-tools=3.6.0
```

エラーが出た。

```
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  mongodb-org mongodb-org-mongos mongodb-org-server mongodb-org-shell
  mongodb-org-tools
0 upgraded, 5 newly installed, 0 to remove and 201 not upgraded.
Need to get 66.8 MB of archives.
After this operation, 276 MB of additional disk space will be used.
WARNING: The following packages cannot be authenticated!
  mongodb-org-shell mongodb-org-server mongodb-org-mongos mongodb-org-tools
  mongodb-org
E: There were unauthenticated packages and -y was used without --allow-unauthenticated
```

`E: There were unauthenticated packages and -y was used without --allow-unauthenticated`とあるので`-y`を抜いたら無事にインストール出来ました。

```
$ sudo apt-get install mongodb-org=3.6.0 mongodb-org-server=3.6.0 mongodb-org-shell=3.6.0 mongodb-org-mongos=3.6.0 mongodb-org-tools=3.6.0

Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
  mongodb-org mongodb-org-mongos mongodb-org-server mongodb-org-shell
  mongodb-org-tools
0 upgraded, 5 newly installed, 0 to remove and 201 not upgraded.
Need to get 66.8 MB of archives.
After this operation, 276 MB of additional disk space will be used.
WARNING: The following packages cannot be authenticated!
  mongodb-org-shell mongodb-org-server mongodb-org-mongos mongodb-org-tools
  mongodb-org
Install these packages without verification? [y/N] ← yをタイプ
```

これで無事にインストール出来ました。

`mongod --version`でバージョン確認が出来ます。

```
$ mongod --version
db version v3.6.0
git version: a57d8e71e6998a2d0afde7edc11bd23e5661c915
OpenSSL version: OpenSSL 1.0.2g  1 Mar 2016
allocator: tcmalloc
modules: none
build environment:
    distmod: ubuntu1604
    distarch: x86_64
    target_arch: x86_64
```

起動

```
$ sudo service mongod start
```
PHP、GoogleCalendarAPIで特定の日時の予定が埋まっているかチェック

自分が運営しているハウススタジオの空き状況をGoogleカレンダーで管理しています。
予約入った際に自動でGoogleカレンダーに予定が入っているかチェック、予定が無ければ新規の予定を入れる、という処理を実装しました。

新規で予定を入れる、という部分は記事があったのでそれを参考にしました。
[Laravel と Google カレンダーを自動で同期](https://sukohi.blogspot.jp/2017/05/laravel-google.html)
ただ、特定の日時に予定が入っているかどうかチェックする方法が無かったので、ソースコードを掘ってみたりして実装したのでここにメモしておきます。

#手順
###１．Google Calendar API を使って読み込み、書き込み、削除ができるよう設定する

手順１については先ほども紹介したこちらの記事を参照ください。
[Laravel と Google カレンダーを自動で同期](https://sukohi.blogspot.jp/2017/05/laravel-google.html)

###2.Google Calendar APIを使って予定チェックの実装をする

#実装
`GoogleCalendar`クラスを作り、その中でGoogleCalendarAPIを使った実装をしています。
カレンダーがGoogleカレンダーから別のカレンダーに移行する可能性も鑑みて`CalendarInterface`を実装する形にしています。

なお、予定有無のチェックには[Freebusy](https://developers.google.com/google-apps/calendar/v3/reference/freebusy?hl=ja)というAPIを使います。

```php
use Asobiba\Domain\Models\Calendar\CalendarInterface;
use Google_Client;
use Google_Service_Calendar;
use Google_Service_Calendar_FreeBusyRequest;

class GoogleCalendar implements CalendarInterface
{

    private $client;
    private $service;
    private $calendarId;
    private $freebusyReq;

    public function __construct()
    {
        //先ほど紹介した記事を参考に共通で必要な準備部分をコンストラクタで行なっている
        $key_path = storage_path('json/google_api_secret_key.json');//指定ファイルへのフルパス
        putenv('GOOGLE_APPLICATION_CREDENTIALS='. $key_path);//カレントリクエスト実行時のみの環境変数を設定
        $this->client = new Google_Client();//クライアント作成
        $this->client->useApplicationDefaultCredentials();
        $this->client->addScope(Google_Service_Calendar::CALENDAR);//https://www.googleapis.com/auth/calendar
        $this->service = new \Google_Service_Calendar($this->client);
        $this->calendarId = env('GOOGLE_CALENDAR_ID');

    }


    public function isBusy(string $startDateTime,string $endDateTime): bool
    {
        //freebusy用のリクエスト作成(このパラメータはリファレンスに記載されているパラメータ
        //Google_Service_Calendar_FreeBusyRequestの基底クラスである、Google_Collectionの基底クラスであるGoogle_Modelのコンストラクタで、引数に与えられたパラメータをプロパティに設定しているっぽい
        $this->freebusyReq = new Google_Service_Calendar_FreeBusyRequest(
            [
                'timeMin' => $startDateTime,//ISO8601日付 (2004-02-12T15:19:21+00:00)
                'timeMax' => $endDateTime,
                'timeZone' => 'Asia/Tokyo',
                'items' => [
                    ['id' => $this->calendarId]
                ]
            ]
        );

        //Google_Service_Calendar_FreeBusyResponseが$resultに入る
        $result = $this->service->freebusy->query($this->freebusyReq);

        //Google_Service_Calendar_FreeBusyResponseのgetCalendars()メソッドでGoogle_Service_Calendar_FreeBusyCalendarの配列が取得できる。
　　　  //Google_Service_Calendar_FreeBusyCalendarのキーに自分のカレンダーIDを指定する
　　　　//getBusy()メソッドでbusyの値を取得できる。busyが空の配列([])だったら予定無し
        if($result->getCalendars()[$this->calendarId]->getBusy() === []){
            return false;
        }
        return true;
    }
}
```

busyの値を取得して予定有無を判定する部分がもう少しスマートに出来そうですが、とりあえずこれで出来ました。

`Google_Service_Calendar_FreeBusyRequest`のパラーメータを設定する時にクラス内のプロパティを探したのですが見当たらず少し迷いましたが、基底クラスを辿っていくことで理解することが出来ました。
ソース見るの大事だなって改めて思いました。

以上。
Visual Studio Code + Git Bash フォントとターミナルの設定(Windows環境)

# はじめに
Eclipce, Atom, ･･･, と様々なエディタを使ってきて今ではVSCを主として使っています。使い始めようと思ったポイントがショートカット一発でターミナルが開けて書いたコードをすぐに動かせるというところでした。
ところがある日のアップデート以来、ターミナルのフォントがとても見づらくなってしまっていました。
![プロンプト.png](https://qiita-image-store.s3.amazonaws.com/0/175135/653a9724-517c-5e92-3a19-e625ae479479.png)

フォントの間がスッカスカでコマンド実行結果が非常に読みづらい・・。
原因を調べる時間もなく、ひとまず放置して別窓でGit Bashやコマンドプロンプトを開いて使っていました。

# 原因と設定変更
```settings.json
"terminal.integrated.fontFamily": ""
```
上記の項目が未設定となっていた。この項目が未設定だと既定値が【editor.fontFamily】となってしまうようにアップデートされたことが原因でスッカスカのターミナルが表示されていたようです(editor.fontFamilyには個人的な好みで"Meiryo"を設定)。

プロンプトの表示用に使えそうなフォントを模索し、普段使っているGit Bashのフォントを使うことにし、以下のように記述を。

```settings.json
"terminal.integrated.fontFamily": "Lucida Console"
```

![プロンプト_フォント変更.png](https://qiita-image-store.s3.amazonaws.com/0/175135/58c12076-9bf9-6a2a-835f-1880cd1a1970.png)

劇的に見やすくなりましたた、おかえりプロンプト機能。

# ついでに
下記のような設定項目がありました。

```settings.json
"terminal.integrated.shell.windows": "C:\\Windows\\Sysnative\\cmd.exe"

```

これを編集するとVSCから開くターミナルを変更できるようです、早速以下のように編集を。

```settings.json
"terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe"
```

![プロンプト_bash.png](https://qiita-image-store.s3.amazonaws.com/0/175135/603c05a9-bfdc-5ca9-f9f2-2ec773949dcc.png)

Git BashがVSCから開くようになり、別窓作業とはお別れを告げました。

# まとめ
```settings.json
"terminal.integrated.fontFamily": "Lucida Console",　// ターミナルのフォント設定
"terminal.integrated.shell.windows": "C:\\Windows\\Sysnative\\cmd.exe" // 起動するターミナルの指定

```
マクロを使ってドキュメントやtypespecsを生成する

Elixirのマクロで普通にできたので書きます。

# はじめに

Elixirはモジュール内で以下のようにしてマクロで関数を定義できます。

```elixir
defmodule Sample do
  def unquote(:hoge)() do
    unquote(1)
  end
end
```

```iex
iex(1)> Sample.hoge()
1
```

どうも、

```elixir
def unquote(シンボル)() do
  unquote(式)
end
```

という処理が走っていればOKのようです。

# `Enum.each`で複数定義してみる

```elixir
defmodule Sample do
  [a: 1, b: 2, c: 3]
  |> Enum.each(fn {sym, num} ->
    def unquote(sym) do
      unquoite(num)
    end
  end)
end
```

```iex
iex(1)> Sample.a()
1
iex(1)> Sample.b()
2
iex(1)> Sample.c()
3
```

# ドキュメンテーション

次はドキュメンテーション込みで生成してみましょう。

exsファイルだとドキュメントがコンパイルされないようなので、`mix new sample`でもしてから`iex -S mix`すると楽だと思います。

```elixir
defmodule Sample do
  [a: 1, b: 2, c: 3]
  |> Enum.each(fn {sym, num} ->
    @doc ~s"""
    #{sym} returns #{num}.
    """
    def unquote(sym) do
      unquoite(num)
    end
  end)
end
```

```iex
iex(1)> h Sample.a()
a returns 1.
iex(2)> h Sample.b()
b returns 2.
iex(3)> h Sample.c()
c returns 3.
```

いい感じです。

# Typespecs

続いてtypespec

```elixir
defmodule Sample do
  [a: 1, b: 2, c: 3]
  |> Enum.each(fn {sym, num} ->
    @doc ~s"""
    #{sym} returns #{num}.
    """
    @spec unquote(unit)() :: number
    def unquote(sym) do
      unquoite(num)
    end
  end)
end
```

```iex
iex(1)> s Sample.a
@spec a() :: number()
iex(2)> s Sample.b
@spec b() :: number()
iex(3)> s Sample.c
@spec c() :: number()
```

いい感じです。`ex_doc`を入れて`mix docs`すればナイスなドキュメンテーションとtypespecが生成されることでしょう。
Ubuntuに最新のnginxをインストールする(Ubuntu 12.04)

# 環境
Ubuntu 12.04

# stableバージョンのnginxをインストール
参考: https://qiita.com/hiroq/items/420424bc500d89fd1cc8

```
# nginxサイトが配布するPGPキーを追加
curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -

# リポジトリを一覧に追加
VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo sh -c "echo \"deb http://nginx.org/packages/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list"
VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo sh -c "echo \"deb-src http://nginx.org/packages/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list"

# アップデート後、nginxをインストール
sudo apt-get update
sudo apt-get install nginx

# バージョンを確認
nginx -v
> nginx version: nginx/1.12.0
```

# mainlineバージョンのnginxをインストール
参考: https://gist.github.com/craigvantonder/729fc169ae087918e6de744f420adf8b

```
# nginxサイトが配布するPGPキーを追加
curl http://nginx.org/keys/nginx_signing.key | sudo apt-key add -

# リポジトリを一覧に追加
VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo sh -c "echo \"deb http://nginx.org/packages/mainline/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list"
VCNAME=`cat /etc/lsb-release | grep DISTRIB_CODENAME | cut -d= -f2` && sudo sh -c "echo \"deb-src http://nginx.org/packages/mainline/ubuntu/ $VCNAME nginx\" >> /etc/apt/sources.list"

# アップデート後、nginxをインストール
sudo apt-get update
sudo apt-get install nginx

# バージョンを確認
nginx -v
> nginx version: nginx/1.13.0
```

# おまけ: Nginxのアンインストール方法

参考: https://askubuntu.com/a/235349

```
sudo apt-get remove nginx nginx-common # Removes all but config files.
sudo apt-get purge nginx nginx-common # Removes everything.
sudo apt-get autoremove # After using any of the above commands, use this in order to remove dependencies used by nginx which are no longer required.
```
[ios]iPhone Xでも、TableViewのheaderを画面上に残らないようにする

TableViewのヘッダーはスクロールしても画面内に止まるようになっています。
それを無理やり画面に残らないようにする方法は下記の地道な方法があります。
[セクションヘッダが画面上に残らないようにする方法](http://anton0825.hatenablog.com/entry/20121008/1350463048)

```swift:safeAreaを考慮しない場合
private let sectionHeaderHeight: CGFloat = 8
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    /// sectionHeaderが上部に残らないようにする
    let offsetY = scrollView.contentOffset.y

    if offsetY <= sectionHeaderHeight && offsetY >= 0 {
        scrollView.contentInset = UIEdgeInsets(top: -offsetY, left: 0, bottom: 0, right: 0)
    } else if offsetY >= sectionHeaderHeight {
        scrollView.contentInset = UIEdgeInsets(top: -sectionHeaderHeight, left: 0, bottom: 0, right: 0)
    }
}
```

しかし、これだとiPhone Xの場合にsafeArea上で思った通りに動きません。

![before2.gif](https://qiita-image-store.s3.amazonaws.com/0/202533/c4fbf660-cdf7-06b0-05ea-b3d76c7fd044.gif)


tableViewにはios11から `safeAreaInsets` というものが追加されおり、この `safeAreaInsets` と `contentsInsets` を合算した `adjustedContentInset` を使ってヘッダー位置の調整を行なっています。
よって、上記サンプルのcontentOffsetにsafeAreaの概念を入れてあげます。

```swift:safeAreaを考慮したサンプル
private let sectionHeaderHeight: CGFloat = 8
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    /// sectionHeaderが上部に残らないようにする
    let offsetY = scrollView.contentOffset.y

    let safeAreaInset: CGFloat
    if #available(iOS 11.0, *) {
        safeAreaInset = scrollView.safeAreaInsets.top
    } else {
        safeAreaInset = 0
    }

    let top: CGFloat
    if offsetY > sectionHeaderHeight{
        /// 一番上のheaderの最下部が画面外へ出ている状態
        top = -(safeAreaInset + sectionHeaderHeight)
    } else if offsetY < -safeAreaInset {
        /// 初期状態からメニューを下に引っ張っている状態
        top = 0
    } else {
        /// safeArea内を一番上のheaderが移動している状態
        top = -(safeAreaInset + offsetY)
    }
    scrollView.contentInset = UIEdgeInsets(top: top, left: 0, bottom: 0, right: 0)
}
```

![after.gif](https://qiita-image-store.s3.amazonaws.com/0/202533/5389f7eb-3b0d-97ea-384e-fa402d1d231d.gif)
ClickHouse ReplicatedMergeTreeでレプリカ構成を作るまで

# はじめに

本記事では、前回に引き続いてClickHouseでレプリケーション構成を作るための設定について記載します。なお、ほぼ公式ドキュメントオンリーみたいな状態で自己流で作っていますのでもっと良いやり方があるかもしれません。

また本格運用前でとりあえず動いた！レベルの人間が書いた記事ですので鵜呑みにしないようにお願いします。

# ClickHouseのレプリケーション構成について

まず、ClickHouseのレプリケーションの設定はテーブル単位です。Zookeeperに分散構成を取るテーブルの情報を格納し、各サーバがそこにクエリキューを溜めていって、「俺も更新しなきゃ！」という該当シャードのサーバがいたらクエリを実行するような感じ…という気がします（妄想）。すごい大雑把な概念図は以下のような感じなんでしょうか。id=と書いてる部分は特に意味はありません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/209762/4caa9a81-1b30-c72a-fbf4-9cb1a2a8abf8.png)

テーブル全体が複数のシャード（任意の数）によって構成されていて、各ClickHouseのインスタンスがシャードに割り当たっています。config.xmlの中におもむろにシャード番号を設定します。
同一シャード番号のインスタンスは、同一のデータを持ちます。

シャーディングはともかくとして、単純なレプリケーションを組むのであれば、全ノード同じシャード番号を持つように構成すれば構成できます。

# 具体的な設定について

## zookeeper

まずはZooKeeperを立てます。これは同じサーバ上でも、あるいは他のサーバ上でもいいですし、既存でzookeeperを使われているのでしたらそのzookeeperを指定しても構いません。

zookeeperの構築については省略します。

## 設定(config.xml)

/etc/clickhouse-server/config.xmlの中を編集していきます。まずはzookeeperサーバを指定します。zookeeperセクションは既にあるので、書き換えましょう。

```xml:/etc/clickhouse-server/config.xml
    <zookeeper>
        <node index="1">
            <host>zookeeper001</host>
            <port>2181</port>
        </node>
        <node index="2">
            <host>zookeeper002</host>
            <port>2181</port>
        </node>
        <node index="3">
            <host>zookeeper003</host>
            <port>2181</port>
        </node>
    </zookeeper>
```

次に、自分のシャード番号を示すためにmacrosセクションを修正します。これはクエリの中で使えるマクロ、変数みたいなもので、それ自体に意味があるものではありません。setとshardとreplicaはそういう名前の変数というだけです。どう使うかは後々の説明になります。

1号機

```xml:/etc/clickhouse-server/config.xml
    <macros>
        <set>1</set>
        <shard>1</shard>
        <replica>clickhouse01</replica>
    </macros>
```

2号機

```xml:/etc/clickhouse-server/config.xml
    <macros>
        <set>1</set>
        <shard>1</shard>
        <replica>clickhouse02</replica>
    </macros>
```

あとは、ClickHouseを再起動します。なおreload呼んでも再起動します。

```
$ service clickhouse-server restart
```

## テーブル作成

レプリケーションを行うには、レプリケーションを想定したテーブルエンジンでテーブルを作成する必要があります。それが、[ReplicatedMergeTree](https://clickhouse.yandex/docs/en/table_engines/replication.html)になります。

CREATE TABLE文は以下の通りで、これを<font color="Red">全ノード</font>で個別に実行します。

```sql
CREATE TABLE rep_access_log_20171221 (
  log_date Date,
  url String,
  referrer String,
  ip String,
  ua String,
  created_at DateTime
) ENGINE = ReplicatedMergeTree('/clickhouse/tables/{set}-{shard}/rep_access_log' , '{replica}', log_date, (log_date, url, referrer, ip, ua, created_at), 8192)
```

カラム指定の部分については特にMergeTreeと変更はありませんが、エンジンの引数部分がかなり異なっています。

- 第1引数 zookeeper上で情報を保管するパスを指定します テーブル情報は/clickhouse/tables/1-1/rep_access_logに保管されることになります。`{set}`はClickhouseのクラスタセット番号を`{shard}`はシャード番号を表しています。1号機と2号機で全く同じパスになるので、イコール 全く同じデータが入るということになります。
- 第2引数 各ノードを表すための固有の文字列を入れます。とりあえずホスト名を入れとけばいいんじゃないでしょうかということで、`{replica}`にホスト名を入れています。
- 第3引数以降 あとはMergeTreeと同じ引数になります

これで、INSERTすると両方のClickHouseに保管されるようになります。また、一気に各日付のテーブルにSELECTを発行するには、MergeTableの際と同じようにMergeエンジンでテーブルを作成すればOKです。ReplicatedMergeはありません。

# 注意点

zookeeperが稼働し続けることが重要です。そのあたりの冗長性確保をサボると大変なことになりそう。
MATLAB での簡単 TCP/IP 通信 (Toolbox なし)

# 経緯
MATLABで刺激制御とオンライン自動解析系を組みたかったので調べた．
記録PCが刺激PCに命令を出す形で計測がスタートする．時間精度がいらない制御なら十分．

**クライアント側 (記録PC)**
計測担当のPC．刺激PC出して欲しい刺激のIDを送る．
IPはサーバー側PCに設定する．

```
clear all
jTcpObj = jtcp('request','192.168.1.1', 3000, 'timeout', 2000);
mssg = [];
for i = 1:10
	disp('-------------------')
	disp(['Send: ' num2str(i)])
	jtcp('write', jTcpObj, num2str(i));
	
	pause(1)
	while isempty(mssg)
		mssg = jtcp('read',jTcpObj);
	end
	disp(mssg)
	mssg = [];
end
jtcp('write', jTcpObj, 'quit');
jtcp('close',jTcpObj);
```


**サーバー側 (刺激PC)**
クライアントから刺激IDを受け取って表示する．

```
clear jTcpObj;
clearvars
i = 1;
disp('Waiting Access from client...')
jTcpObj = jtcp('accept', 3000, 'timeout', 30000);
disp(['Connected: ' jTcpObj.remoteHost])
mssg = [];
while true
    disp('---------------');
    disp(['trial: ' num2str(i) ', waiting stimID ...'])
    while isempty(mssg)
        mssg = jtcp('read',jTcpObj);                
    end
    jTcpObj.outputStream.flush;
    ids{i} = mssg;                
    if strcmp(mssg, 'quit')
        disp('Received "quit" closing socket...')
        jtcp('close',jTcpObj);
        break;        
    end      
    jtcp('write',jTcpObj,['Stim Server Received: "' mssg '"']);
    
    % stimuli
    disp(['"' mssg '" Start']);    
    pause(2)
    disp(['"' mssg '" Finished']);    

    i = i+1; mssg = []; 
end
disp('')
disp('Session Finished')
```
オブジェクトのプロパティ名に変数や文字列展開を使用する


ES6から`[]`で囲むことでオブジェクトのプロパティ名に変数や式を記述できるようです。
ただしオブジェクト初期化時のみ。

```Javascript
const hoge = "HOGE";
const obj = {
    [1 + 1]: "two",
    [hoge]: "just hoge",
    [`expand ${hoge}`]: "expand hoge"
};
console.log(JSON.stringify(obj,null,2));
```

```Javascript:結果
{
  "2": "two",
  "HOGE": "just hoge",
  "expand HOGE": "expand hoge"
}
```

[参考](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Object_initializer)
Polyphony のこれから：「鳥が卵から出ようとする」

鳥は卵の中からぬけ出ようと戦う。 卵は世界だ。 生まれようと欲するものは、 一つの世界を破壊しなければならない。

#安定版の提供

現時点の安定版は 0.3.2 だ。このバージョンではまだパイプライン化や for 文のunroll に対応していない。次のバージョン 0.3.3(Adagio) は近いうちに安定版として提供可能だろう。すでに紹介しているが次の機能が使える。

- import
- パイプライン化
- for 文の unroll

#次期バージョン

次のバージョン(0.3.4 Blue-notes) での大きな機能アップは II=2 時のパイプラインの実装の予定だ。場合によっては Tuple による同時性の記述が出来るようになるかもしれない。

- II=2 以上のパイプライン 実装
- Tuple による同時性記述 検討(実装)
- bit ライブラリ(検討)
- Python のインライン関数列挙(検討)

II=2 のパイプラインの実装をする際にはリソース分散による FMAX の向上を目指す。パイプライン化ではある処理をスケジューリング的に早く実行できるからと言って偏りがある状態にしてしまうと、結果として特定のステージに処理が集中してしまいその処理にすべての処理が引きずられてしまう。そこをうまく分散させてFMAX を向上させる。

時間の記述は、本来、Polyphony でサポートするものではないが、同時性だけは Tuple により自然にでき、かつ、便利な機能なので検討したいと思う。

bit ライブラリは RTL と Python との間の橋渡し的なライブラリになるだろう。抽象的な事が書けても、実際の RTL と親和性が無ければ高位合成としての立ち位置はただのシミューレション的なものになってしまう。

#次次期バージョン(Coda)

将来的にどのような機能を入れていけばよいか検討中である。

- 関数オブジェクト対応
- 柔軟なリソース対応
- 柔軟な配列(setitem/getitem)

関数オブジェクトはすでに内部的には実現しているのでそう難しくはないだろう。class のコンストラクタに class を渡せるようにするとライブラリとして柔軟性が増す。

リソースを柔軟に扱えるようにすると、より拡張性があがる。その為には内部的にリソースを柔軟に表現できる記述方法が必要になるかもしれない。掛算器の仮実装というのが最初のターゲットになる。

配列による表現がユーザに開放されるとキャッシュシステムを書く場合など便利に書けるようになるだろう。
#2018 年の Polyphony

Polyphony は実用的なアプリケーションを気軽に書けるところにまで成長した。今後は、コンパイラ自身の機能アップというより、何が書けるのか？にフォーカスしていく事になるだろう。
もう一つのLチカ

「もう一つの」というフレーズは、何かしらのメインラインがあった上に、今までスポットライトが当たっていないストーリの存在を見つけた。そんなキュレータの思いを伝える言葉のように読み取れる。

Lチカにそんな折り重なるようなストーリ性を見いだせるか？
#Vivado にモジュールとして組み込む

Polyphony で生成した Verilog-HDL を Vivado のIP Integrator のブロックデザインの中にに組み入れることは比較的容易にできる。

Add Module を使えば RTL を直接ブロック・デザインの中に配置できる。このモジュールを使う際の難点はバージョン管理がなされないことか？ Verilog-HDL を更新すれば、例えば Polyphony を起動してコンパイルし Verilog のファイルを更新すれば、もちろんVivado は気が付いてくれて再合成が必要なことを教えてくれる。ただ、IP-XACT とは違い IP Report のバージョンはそのままだ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/87ad16b4-7b3f-5386-c6d4-b177a2af3162.png)

RTL の文字デザインもなんとなくどんくさい。

#Vivado HLS ライクに組み込む

Vivado HLS のように IP-XACT をうまく作り、高位合成コンパイラを合成時に呼び出せないか？試しにやってみた。ついでにロゴも入れてみる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/e5329a66-2cdd-c61b-2a88-870d27519779.png)

少々強引なつくりなっているがウィザード画面も表示できLチカの間隔を変えることが出来る。ウィザードを閉じれば Polyphony によって新たに Verilog のソースが生成される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99921/29f6f00d-b26e-267e-c1f8-542faa445c5c.png)

Python3 とPolyphony が特定の場所にあること前提だがこの形式が使えれば Polyphony で生成する Verilog はより柔軟性を持つ。使用者は IP-XACT の使い方さえ分かっていればよい。

Python は次のディレクトリにあることを前提にしている。
C:/Users/ryos/AppData/Local/Programs/Python/Python36/python

使う際には、Windows 用の Python3.6 をインストールして polyphony を pip3 でインストールしたうえで環境に応じて IP-XACT 内の polyphony_compile.ttcl を書き直す必要があるので注意されたい。

IP-XACT は次の URL からダウンロード可能だ。
[polyphony_ip_blink.zip](https://goo.gl/Tri7FE)
【Python】MacにOpenCVとJupyter環境を構築【pyenv・virtualenv】

画像解析とか分析的なあれに興味がでたので。

pyenvとvirtualenvがインストールされている前提で進めます。

画像解析する用の環境作成

`pyenv install anaconda3-4.3.0`

`pyenv virtualenv anaconda3-4.3.0 image_anaconda3-4.3.0`

`pyenv local image_anaconda3-4.3.0`

`pyenv rehash`

`conda create -n py3 python=3.4 anaconda`

`source $PYENV_ROOT/versions/anaconda3-4.3.0/bin/activate py3`

`pip install opencv-python`

`jupyter notebook`

これでブラウザが起動しjupyterの画面が表示されればとりあえずOKらしい。
VMware > ゲストOS同士でのテキストのcopy, pasteができない状況 > ファイルドラッグ&ドロップは効く?

```txt:動作環境
VMware Workstation 12 Pro v12.5.7 build-5813279
```

VMwareで複数のウィンドウに分けて下記のようなOSを起動している時がある(例:1を１つのウィンドウに、2,3,4を別のウィンドウに)。

1. Windows 8.1 Pro (64bit)
2. CentOS 6.8
3. Ubuntu 16.04 LTS
4. Windows 7 Pro (32bit)

この状況でOS間のテキストcopy, pasteが効かなくなることが多い。
(VMware toolsはインストール済み)

対策としては以下の方法があるが、OSの再起動があり時間がかかる。
[VMware > ゲストOS同士の(テキスト,ファイル)コピペ失敗 > 原因と対処](https://qiita.com/7of9/items/1673dac1b4353a33ee7d)

別の方法として、以下を見つけた。

1. ファイルを作る
2. ファイルの中にcopy, pasteしたいテキストを用意する
3. ファイルをドラッグして、別のOSにコピーする
4. ファイルの中身からテキストを取り出す

これがいつでも使える方法かどうか。
2018年のベクトルタイルについて考える

# 引き続き、地理空間情報の提供者が一歩一歩進めるしかない
ベクトルタイル Advent Calendar をお読みいただき、ありがとうございました。また、ベクトルタイル Advent Calendar に貢献をいただいた皆様に、心から感謝します。ベクトルタイルについて、自分だけでは得られない新たな視座ができました。

また、自分で十九回書いてみて思ったのですが、私の知識は偏っているし、実践は足りません。引き続き、実際の行動が重要だと思います。人ができる行動は小さいことから、いかに効果的に行動していくかが重要なのだと思います。

ベクトルタイルについては、おそらく、地理空間情報の提供者が一歩一歩進めるしかありません。それが素直な良さに繋がることもあります。進んだだけ価値が出てきます。しかし、進めるべきことができる人の数は、限られています。引き続き、行動していきましょう。

# 書き残したもの
今回の Advent Calendar で書こうとして、書き残してしまったものが少しあります。少しだけ紹介し、今後に向けての頭出しとさせていいただきます。

## 量レベル q
ベクトルタイルの生産においては、データの量を様々な段階で評価する必要があります。ベクトルタイルの生産で出てくる量は、そのまま定量的に評価しては疲れてしまいますし、かといって 1024 や 10 といった大きな基数での「桁数」で評価してしまっては、本質的な傾向を見逃してしまうように思っています。そこで、ズームレベルをヒントとした、いわば「２を底とする『桁数』」である「量レベル q」というものを考え始めています。

概念および Ruby と JavaScript による実装は概ね[整理しました](https://github.com/hfu/advent-vt/wiki/量レベル-q-という考え方)し、実際の適用についても[書きかけ](https://github.com/hfu/advent-vt/wiki/量レベル-q-を使ったベクトルタイル時代の量の評価)ましたが、また別の機会に問うことができればと思っています。

## turf
[turf](http://turfjs.org) は良いですね。turf 自身はベクトルタイルとは独立であるし、私はベクトルタイルの生産と消費についてまず整理することをしたいと思うので、今回の Advent Calendar では扱うことができませんでしたが、いずれ問うことができればと思っています。

## PYAML: Place YAML
場所の情報をジオメトリと独立させて YAML で書く Place YAML という概念をずっと温めていますが、これも turf と同様、まとまって手を動かすことができていません。これについても、いずれ問うことができればと思っています。

# 良いお年を
【毎日プログラム講座】④webサイト作成のマックアップをしよう。

FromNowOnブログでは毎日1日1回webについての知識記事をあげています。
その記事では書ききれないコードをこちらで展開していきますのでご覧ください。

**ディレクトリー**
```　　　FromnowOnーHTML-index.html
　　　　　　　　　　　|                 
　　　　　　　　　　 CSS-main.css
　　　　　　　　　　　| 
　　　　　　　　　　 IMG-image1.png
　　　　　　　　　　       image1.png                      
```

```使用タグについて.
<h1>〜<h6>
<p>
<ul></ul>
<li></li>
<table></table>
<caption></caption>
<tr></tr>　
<th></th>
<td></td>
```
<h3>サンプルコード</h3>
```index.html

<!DOCTYPE html>
<html>
<head lang="ja">
    <meta charset="utf-8">
    <title>mini_FromNowON</title>
</head>
<body>
    <h1>mini_FromNowON</h1>
    <p>
        FromNowOnはオンラインプログラミングスクールです。<br>
        FromNowOnは『エラーを解決する能力を身につける』ことです。
    </p>
    <h2>毎日プログラム講座でwebについて学ぼう!</h2>
    <p>毎日プログラム講座ではwebの知識について毎日1回更新してお伝えしています。webページにはHTMLとCSSを利用してホームページを作成することができ、それにJSと言われるJavaScriptやPHPなどのプログラミング言語で動的なページを作成することやデータの保管などをすることでwebサービスを作成することができます。</p>
    <p>毎日プログラム講座で少しでもプログラミングの楽しさを知っていただければいいなと思って毎日1記事を載せています。</p>
    <p>FromNowOnは11月11日にオープンした新しいプログラミングスクールとなります。従来のプログラミングスクールより実践的な講義を行います。講義中にwebなどでしようしたいサンプルの使用方法や使えるようにする為の解決策などの提案までを行います。</p>
    <p>プログラミング言語は様々ですが毎日プログラム講座はよりわかりやすく進める為にまずは簡単なHTMLやCSSについて記述しています。わからないことはコメントやHPのお問い合わせよりご連絡いただければと思います。</p>
    <h3>プログラミング言語は誰でもできる。</h3>
    <p>FromNowOnではwebコースとIOSコースの2つのコースがあります。webコースはHTML,CSS,PHP,MySQL,Larvelまでを学習することができます。そしてIOSコースはappleが開発した新しいプログラミング言語です。そしてモダンで早く、わかりやすい言語でアプリ開発をするには初心者向けのプログラミング言語であり実用的でこれから期待されている言語です。</p>
    <h3>HTMLについて</h3>
    <p>HTMLは画面の構造を作るものです。そしてHTMLの記述にはタグというものを利用してコードを書いていきます。HTMLの書き方には1つのパターンしか基本的にはありません。開始タグと終了タグの中に文字を記載することでそのタグの中の字が指定することができます。webを理解するにはまずはHTMLをマスターすることが必要になるでしょう。</p>
    <h3>CSSについて</h3>
    <p>CSSはHTMLの兄弟みたいなものでHTMLと一緒に使うものです。CSSはデザインを作る為のものです。HTMLが構造ならCSSは肉付けといったところでしょうか。CSSでより見やすいHPを作成することができるようになります。</p>

    <table>
        <caption>プログラミングコース</caption>

        <tr>
            <th>WEBコース</th>
            <td>HTML,CSS,PHP,MySQL,LARVEL</td>
        </tr>

        <tr>
            <th>IOSコース</th>
            <td>XCODE,SWIFT,COCOAPOD</td>
        </tr>
    </table>



</body>
</html>
```

<h4>FromNowOnホームページはこちらからアクセスお願いします。</h4>
HP：https://onlinefromnowon.wixsite.com/fromnowon/blog
RailsでModelの中身が表示されてしまう

最近Ruby on Railsを勉強中です。

最近Railsチュートリアルを全部写経しました
https://medium.com/%E8%99%8E%E8%A6%96%E7%9C%88%E3%80%85%E3%81%A8/rails-%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB%E3%82%92%E5%85%A8%E9%83%A8%E3%82%84%E3%81%A3%E3%81%9F%E8%A9%B1-5cead29b43f1

初心者の自分が最初にハマったことを共有したいと思います

## <%= と <%の使い分けに注意しよう


Railsで開発中にModelからデータを取得してViewに渡して、Viewでごにょごにょしているときにハマりました。

<img width="1168" alt="スクリーンショット 2017-12-22 13.06.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/139360/66017699-8bc9-7f32-5bce-95acd362f201.png">


なぜか画面にModelの中身がまるまる表示されていました。
書いていたソースは下記になります。

```erb
<%= @articles.each do |article| %>

  <p>
    <%= link_to article.title, edit_articles_url(id: article.id) %>
    <%= article.created_at %>
    <%= link_to "Delete", articles_url(id: article.id), :method => :delete %>
  </p>

<% end %>

```

原因わかる方いらっしゃいますか？？


## 原因



原因は` <%= @articles.each do |article| %>` と書いていたことです。
`<% @articles.each do |article| %>`と書けば表示されなくなります。


## この際いろいろ調べて見た

https://qiita.com/chobi9999/items/a48e790952a0f183e91d

↑にあるとおり

```
<% 任意のコード %>
　　ここのコードは評価されるだけで結果をテンプレートに返さない。
　　重荷演算や制御構文の記述に利用。

<%= なんらかの値を返す式 %>
　　式の評価結果をテンプレートに挿入。

```

ほうほう、勉強になりました。
Mapbox GL JS はいつ 1.0 になるのだろう

[2014年7月には開発がされている姿が見られ](https://github.com/mapbox/mapbox-gl-js/graphs/contributors)、[執筆時点ですでに111回のリリースを行なっている](https://github.com/mapbox/mapbox-gl-js/releases) Mapbox GL JS ですが、執筆時点で最新のバージョン番号は 0.43.0 でしかありません。今後も breaking change を繰り返し、進歩を続けていく段階にあるということだと思います。

他方、gh:mapbox/mapbox-gl-js の Projects には、[GL JS v1](https://github.com/mapbox/mapbox-gl-js/projects/9) というプロジェクトがあります。最終更新が今年の6月30日になっており、おそらくは更新が停止しているプロジェクトです。このプロジェクトに含まれているシューには、すべて breaking change というタグがつけられています。

[breaking change というタグがつけられたイシュー](https://github.com/mapbox/mapbox-gl-js/issues?q=is%3Aopen+label%3A%22needs+discussion%22+sort%3Acomments-desc) は、執筆時点で 34 あります。なお、すでにクローズされたいシューの個数は 46 です。

Mapbox GL JS は、フロントエンドにおけるオープンソース最強のベクトルタイルウェブ地図ライブラリであり続けるでしょうが、そのバージョンが1になるためには、まだ数ヶ月以上、おそらく半年以上の時間がかかりそうです。
MacのExcelが重いときに実行するコマンド

以下をターミナルで実行します。

### 環境設定ファイルを削除

```
rm -rf ~/Library/Preferences/com.microsoft.Excel.plist
rm -rf ~/Library/Preferences/com.microsoft.office.plist
```

### キャッシュを削除

```
rm -rf ~/Library/Caches/Microsoft/
```
Spring Web MVCのControllerをkotlinに変更した際に@Autowired指定したコンポーネントがインジェクションされずnullになる件

元記事は[こちら](https://tono-n-chi.com/blog/2017/12/spring-mvc-java-to-kotlin/)。

下記のようなJavaのクラスがあったとします。

``` Java
@Controller
@Scope("request")
@RequestMapping("/foo/bar")
public class FooBarController: Foo() {
    @Autowired
    FooBarService fooBarService;

    @RequestMapping(method = RequestMethod.GET)
    public String foo() {
        return fooBarService.doSomething();
    }
}
```

これをkoilinに自動変換するとこうなります。

``` kotlin
@Controller
@Scope("request")
@RequestMapping("/foo/bar")
class FooBarController {
    @Autowired
    internal var fooBarService: FooBarService? = null

    @RequestMapping(method = arrayOf(RequestMethod.GET))
    fun foo(): String {
        return fooBarService!!.doSomething()
    }
}
```

このままだとfooBarServiceのAutowiredが効かずnullのままになってしまいます。

そこで、<a href="https://stackoverflow.com/questions/40075340/spring-autowired-in-kotlin">ここ</a>で回答されているように、

``` kotlin
@Controller
@Scope("request")
@RequestMapping("/foo/bar")
open class FooBarController(val fooBarService: FooBarService) {
    @RequestMapping(method = [RequestMethod.GET])
    open fun foo(): String {
        return fooBarService.doSomething()
    }
}
```

classとfunにopenをつけることでAutowiredが効くようになります。
ついでに@Autowiredを外してコンストラクタに移動させ、methodのarraysもブラケットにしてみました。
よりきれいですね。

## 追記

[ここ](https://kotlinlang.org/docs/reference/compiler-plugins.html#spring-support)に記載されているようにkotlin-springを使用すれば@Component継承アノテーションのついたクラスに自動的にopenを付与してくれるようです。

``` gradle
buildscript {
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-allopen:$kotlin_version"
    }
}

apply plugin: "kotlin-spring" // instead of "kotlin-allopen"
```
.yarncleanに手を加えないと、yamlが消えたりして困る

最新のyarnを利用していると問題なさそうだが、
今年11月以前のバージョンらへんだと困ります。

```zsh:error
ERROR in ./node_modules/css-loader!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-00654544","scoped":true,"hasInlineConfig":false}!./node_modules/sass-loader/lib/loader.js!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/App.vue
```

今回は、webpack利用時にvue-loaderがコケてしまうというもので、
.yarncleanに下記の修正を加えた上でnode_modulesを正す必要がありました。

```js:.yarnclean
.*.yml　// <- 削除する
*.yml　// <- 削除する

!svgo/.svgo.yml　// <- 追記する
```

# yarnのアップデート
そもそもyarnのアップデートは厄介です。
グローバルから削除して、最新のものを再インストールする必要があります。
その際、**セキュリティリスクあるのでnpmではインストールしないようにしましょう。**

> https://yarnpkg.com/ja/docs/install#windows-tab

インストールは下記のような手段があります。

## windows
- msiインストーラ
- chocolatey
- scoop

## mac
- homebrew <- アップデートが簡単なのでおすすめ
- macports
ベクトルタイルと三次元の関係

# 2次元・2.5次元・3次元・標高
現実的に用途が想定されるタイルデータには、2次元データ・2.5次元データ・3次元データ・標高データがあります。ここで、2.5次元データというのは、2次元データに高さ情報が属性として付加されたようなタイプのデータとお考えください。

それぞれについて、具体的な符号化方法は色々ありますが、おおまかな流れについて私が感じているのは次の通りです。

2次元・2.5次元のベクトルデータについては、[gh:mapbox/vector-tile-spec](https://github.com/mapbox/vector-tile-spec) をベースにデータの整備が進んでいます。2.5次元データの扱いの具体的な例については、https://www.mapbox.com/mapbox-gl-js/example/3d-buildings/ あたりをご覧ください。boolean 属性である extrude と、数値属性 height および min_height を使って建物を表現します。

3次元のベクトルデータについては、[gh:AnalyticalGraphicsInc/3d-tiles](https://github.com/AnalyticalGraphicsInc/3d-tiles) で検討が進んでいるところです。こちらは、より一般解を狙っていますが、計画が莫大であるため、なかなか一朝一夕に進捗するというものではありません。

# vector-tile-spec か 3d-tiles か
vector-tile-spec の代表的な実装は Mapbox GL JS であり、3d-tiles の代表的な実装は、Cesium です。これらの代表的なユースケースはそもそも大きくことなりますが、それでもなお、おそらく、両方が等しく盛り上がるということはありません。いずれかが先に市場を占有し、もう一方が市場を食われることになると思います。

ベクトルタイルに Cesium が対応するのか、Mapbox GL JS や Tangram が本格的に三次元に対応するのか、あるいは、そのような斜め対応は当面実現することはないと思っておけば良いのか、というところを読めると、面白いと思います。

「ウェブ地図」と「デジタル地球儀」という2つのコンテキストは、実際にはあまり交差することはないのが現状です。しかし、唯一三次元建物データでは、すでに接触が始まっています。3d-tiles でしか容易に扱えないような複雑な立体を表してもなお基本地図として成立するようなことが起こるのか、あるいはそのようなことは発生せず、3d-tiles はローカルな 3D モデルの提示のためのフォーマットに実質とどまるのか、データ事業の面から、方向性が定まるのかもしれません。

いま、この問題について、それほど速い動きは見えません。もうしばらくの間、悩ましい時期が続くかもしれません。

# Mapbox GL JS に terrain rendering が来る。ただし2次元で
Mapbox GL JS については、[Roadmap](https://www.mapbox.com/mapbox-gl-js/roadmap/) 情報が提供されています。本稿執筆時点では、「Client-side hillshade rendering [#3730](https://github.com/mapbox/mapbox-gl-js/issues/3730) [#4701](https://github.com/mapbox/mapbox-gl-js/issues/4701)」が Active な開発項目になっています。

これによると、terrain-rgb raster tiles つまり PNG 標高タイルを使って、陰影段彩を二次元にレンダリングする機能を加えようとしているみたいですね。地理院地図Globeは Cesium ベースで、PNG 標高タイルを使って標高を３次元で表示していますが、Mapbox GL JS にも、少し近い機能が実装されつつあるということになると思います。

この動きを遅いと見るか、早いと見るか、やや微妙なところです。三次元問題は、避けられるのであれば、もうしばらく避けて見るのも一つの手、2.5次元に特化して Mapbox GL JS で仕事をするのも一つの手、Cesium のシェア増大を助太刀するのも一つの手、かと私は思います。
Googleスプレッドシートのqueryを使おう

# Googleスプレッドシートのqueryとは
スプレッドシートに記入された値をSQLのように扱うことのできる関数です。
GoogleスプレッドシートにはありますがExcelにはない関数で、
これがちょっとしたデータ解析や管理表を作成する際に非常に便利です。

例えば、以下のように使います。

| A | B | C | D |
|:-----------------|:------------------|:------------------|:------------------|
| 日付 | 品目 | 仕入原価 | 個数 |
| 2/1 | なし | 30 | 1 |
| 2/1 | みかん | 10 | 8 |
| 2/1 | りんご | 50 | 7 |
| 2/2 | なし | 32 | 5 |
| 2/2 | みかん | 12 | 6 |
| 2/2 | りんご | 52 | 3 |
|～～～

このとき、品目（B列）が"なし"の仕入原価のみを取得する場合は以下のようにquery関数を使用します。
**`=query(A:D,"select C where B = 'なし'")`**

queryで取得した値は、当然、複数件あるわけですが、これは**セルに自動展開**されます。
実際のスクリーンショットを見たほうが早いです。

![queryスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/141209/4f820efd-1e61-77a3-60cf-aa59495b77af.png)

query関数の取得結果はセルに自動展開されますが、当然、この値を他の計算関数の入力に利用することもできます。
例えば、sum関数だとこんな感じです。

![スプレッドシートqueryイメージ3.png](https://qiita-image-store.s3.amazonaws.com/0/141209/316282b4-11cb-281b-375d-2b4652ed000a.png)

query関数の応用方法はいくらでもありますが、そのうちの1つが**入力値の条件を指定することができない関数への応用**です。
sum関数であれば、sumifやsumifs関数を利用することで合計した値に条件を設けることができますが、
"if"がない関数もたくさんあります。

# 無性に標準偏差を算出したい...したくない？
平均値だけでは値のばらつきがわからないので、標準偏差をだしたくなるときって誰にでもあると思います。
そんなときに使用するのが、**stdevp関数**ですが、この関数にはifなるものはなく、
範囲指定した値に条件を設けることができません。
前項の例でいえば、"なし"や"みかん"といった品目ごとに仕入原価の標準偏差を算出する場合、
データを品目ごとに手動でまとめる、といった作業が別途必要になります。

そんなときにquery関数を使えば、簡単に**品目を特定して標準偏差**の計算ができます。
**`=stdevp(query(A:D,"select C where B = 'なし'"))`**

![スクリーンショットquery.png](https://qiita-image-store.s3.amazonaws.com/0/141209/e98b96e5-be91-9a16-fdad-a017063b28b3.png)

ね、簡単でしょ？

# query関数に興味がでた人は
以下の記事を見るとさらにquery関数を応用できます。

[他のスプレッドシートから情報取得（importrange関数）](https://qiita.com/vankobe/items/2af21d4b1c3afed5fa82)
[複数シートの統合（importrange関数もあり）](https://qiita.com/ShishidoToru/items/e2b991fbf0f63710141c)

※importrange関数も超便利