OmniAICreator/Qiita-1.07M huggingface dataset:
はじめてのKotlin:nullに対して型安全かどうかをためしてみよう

## はじめに

　**Null Safty** (nullに対して安全)というのはプログラミング言語において実行安全性を確保するために重要な指標となります。

　ここでは、 **Kotlin** (コトリン)がどれだけ **Null Safty**　なのかを実コードで調べてみます。

## nullの代入
　まずは不変変数にnullを代入してみましょう。変数が **null** を持つ可能性がある場合には、型宣言の型名のすぐ後ろに　**?**　記号を指定します。ここで、**?**　記号は **Safe Accessor** と呼ばれます。

```kotlin:null.で初期化するコード例
fun main(args: Array<String>) {
  //val hate Null: String = null //コンパイルエラー
  val expectNull: String? = null
  
  println( "expectNull is $expectNull ." )
}
```
　 **Safe Accessor** である **?** 記号を指定しない場合にはコンパイルエラーになります。このコンパイルエラーのおかげで実行時例外発生を抑止することができます。

```実行結果:コンパイルエラー
prog.kt:2:26: error: null can not be a value of a non-null type String
  val hateNull: String = null
                         ^
```
## nullの可能性のある値の代入
　さらに、ここでわざと **null** の可能性がある値を変数に代入してみます。

　代入時にある変数を評価するとき、**null**　であっても例外が発生しないようにするには変数の後ろに　**?**　記号を指定します。

```kotlin:nullの可能性がある値を代入するコード例
fun main(args: Array<String>) {
  var mayNullString: String? = null
  val length = mayNullString?.length
  //val length = mayNullString.length //コンパイルエラー発生

  println( "mayNullString's length is $length." )
}
```
```text:実行結果
mayNullString's length is null.
```
```text:?記号を指定しない場合のコンパイルエラー
prog.kt:4:29: error: only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
  val length = mayNullString.length //????
                            ^
```
##　期待する型を指定して不変変数を初期化
　次に、期待する型を指定して不変変数を初期化してみます。このような場合には　**as?**　キーワードを指定します。

```kotlin:期待する型の値でのみ初期化するコード例
fun main(args: Array<String>) {
  val someString = "Bording locations are "
  val expectInt: Int? = someString as? Int
  println( "expectInt is '$expectInt' ." )
  val expectString: String? = someString as? String
  println( "expectString is '$expectString' ." )
}
```
```text:実行結果
expectInt is 'null' .
expectString is 'Bording locations' .
```

## nullかどうかの判定

　次に　**null**　かどうかを判定してみます。　**null**　判定するということは、変数が　**null**　を持つことをゆるす必要があります。そのためには、型宣言の型名のすぐ後ろに　**?**　記号を指定します。

```kotlin:null判定するコード例
fun main(args: Array<String>) {
  var stringForJudge: String? = "indicate by white circles and from No.1 to 12."
  val lengthOfString = 
    if( stringForJudge != null ) stringForJudge.length else -99
  println( "lengthOfString is $lengthOfString ." )
}
```
```text:実行結果
lengthOfString is 46 .
```

## わざと例外が発生するように指定
　最後に　**null**　の場合に　**null**　安全ではなく、Javaのように普通に **NullPointerException** で例外が発生するようにわざと指定してみます。

　このような場合には、対象となる変数を　**!!**　記号で修飾します。

　また、　**null**　をゆるす場合には　**someString?.length**　のようにプロパティの前に　**?**　記号を付加します。ここで、　**?**　記号は　**Elvis operator**　 と呼ばれます。

```kotlin:コード例
fun main( args: Array<String>){
  var someString: String? = "ばあばとじいじ"
  val length1 = someString!!.length
  someString = null
  val length2 = someString?.length
  //val length2 = someString!!.length //例外発生

  println( "length1 is $length1.\nlength2 is $length2." )
}
```
```実行結果:length2の初期化で!!を指定した場合
Exception in thread "main" kotlin.KotlinNullPointerException
	at ProgKt.main(prog.kt:5)
```
```実行結果:length2の初期化で?を指定した場合
length1 is 7.
length2 is null.
```

以上です。いかがだったでしょうか？。Javaをご存じの方はいかに **Kotlin** が　**null**　に対して安全かがお分かりいただけたのではないでしょうか？。
table要素でIE, Edgeのみflexboxがうまく効かないとき

table要素や、その下のtbody, trなどにdisplay: flex;を当てて、レイアウトを複雑に組みたいという時がある。
他のブラウザなら大丈夫だけど、IE, Edgeだけflex: 1; などによるサイズの指定がうまく効かないときは、子要素のtdやthをdisplay: block;にしてあげるとうまくサイズが指定できることがある。
IEとEdgeはほかのブラウザとサイズ指定の優先順位が違うっぽい？
concrete5　公開前チェック

弊社でconcrete5案件を公開する前にチェックしている項目です。

備忘録、社内への共有も含め、書き残しておきます。

# 自動実行ジョブの設定
## sitemap.xmlの設定
sitemap.xmlは、自動実行ジョブで生成されます。最初の1回は、手動でポチっとしておきましょう。

# Faviconの設定
管理画面→基本→ブックマークアイコン

# プリティURLの設定
プリティURLの設定は、.htaccessに関わってくるので、開発環境と本番でサーバー設定が違う時などに備え、開発中はOFFにしています。従って、公開後にONすることを忘れずに…

# 旧URLからの転送設定
リニューアル案件かつ、同じドメインの場合、concrete5の設定で、以前のURLを引き継ぐ（３０１リダイレクト）ことができます。

ページ設定→場所→ページのURL

これで、リニューアル前に特定のページが大量のアクセスを誇っていたとしても、損なうことなく新しいページに転送できます。

リニューアル前にはあったけど、リニューアル後にはそのページないよ、って場合でも、近い情報を持つページに転送させることにより、ユーザビリティを損わずに済みます。

# デバッグモードの解除
開発中は便利なデバッグモードですが、本番公開後何かあった時にあのグレーの画面は確実に怒られるので、OFFを忘れないように。

# 適切なキャッシュの設定
開発中はキャッシュをオフっとくのがconcrete5流ですが、逆にオンにすることを忘れてもいけません…

だいたい私が関わる案件での設定は、

* ブロックキャッシュ　→　ON
* テーマCSSキャッシュ → OFF //　LESS使ってない
* 圧縮LESSキャッシュ → OFF // そもそもLESS使ってない
* CSS と Javascript キャッシュ → OFF //不用意に連結されて読み込み順変わると怖い…
* オーバーライドをキャッシュ → ON
* フルページキャッシュ → ON - 該当ページのブロックで許可されていれば

5.6系の頃からあるキャッシュ設定のみONにしてます。

# Google Analytics トラッキングコードの設定

管理画面→SEO→トラッキングコード

[タグマネージャーの場合は、こちらの記事](https://qiita.com/drafts/49d1753cb0dc3431d6da/edit)

# お問い合わせコンバージョンの設定
タグマネージャー使ってない場合は、外部フォームの確認画面に、CVタグを仕込みます

# まとめ
キャッシュとトラッキングコードあたりを押さえてれば、まあとりあえず大騒ぎにはなりません…　管理画面から設定できる項目もあるので、コード触らずとも、ディレクターさんレベルで解決できることもたくさんありますね。
Cognos Analytics 11.0.7 - コンテンツを上書きコピーした時の動作を変更するパラメーター

#概要
Cognosでは、本番環境と開発環境の区別なく、開発用フォルダと本番用フォルダを分けて運用している環境もあると思います。
開発フォルダで開発したレポートを、本番フォルダにコピーして本番リリースするような場合です。
Cognos Analyticsのデフォルトの動作では、この時、本番のレポートが上書きされると、レポートのIDが変更となるため、他のジョブなどでこのレポートを指定していると、ジョブも動作しなくなり、再設定が必要となります。

そのような再設定は面倒くさいので、本番レポートを上書きしてもIDが変更される事なく、ジョブの再設定も不要になる、というコピー時の動作変更が可能な素敵なオプションが、Cognos Analytics 11.0.7から実装されましたのでご紹介します。

#内容
例えば、こんな感じに「本番レポート」があり、「ジョブ」から1分に1回、PDF保存をスケジュール実行している環境があるとします。
「本番レポート」のIDは、*45です。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/c908f578-e50b-363a-756f-abfb315cfd32.png)

1分間に1回のPDF保存なので、6時39分の最新時刻のバージョンが保存されています。
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/c17a0ec8-5d5a-ad9e-c143-51f63abdb29c.png)

ここで、「開発中」フォルダにあった「開発中レポート1」を「本番レポート」という名称に変更し、先ほどの「本番レポート」に上書きで被せます。
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/59cc8627-7396-57e8-1895-3f0fb36a6252.png)

すると上書きされた「本番レポート」のIDが変更になります。*41になっています。
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/6b62a8c4-4076-04dc-d010-5275e29d34b8.png)

保存バージョンを見ると、きれいさっぱり無くなっていて、何分か待ってもジョブは動作せず、保存バージョンは作成されません。
つまり、ジョブからのリンクが切れてしまっているのですね。
![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/3ac79966-72b4-9bb6-fab6-b951ca58d60e.png)

実際にジョブを見てみると、この通り、「本番レポート」のエントリーが消えています。
![007.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/bd24a41e-089d-dece-3311-e27e23be879b.png)

これを再設定すれば直りますが、リリースの度にこの設定を行うのは面倒くさいですよね。

この上書き時の動作を変更するパラメーターが、以下となります。
ブラウザで、以下のURLにアクセスします。
http://cognoshostname:9300/bi/utils/ConfigSetter.html

Name: Portal.updateTargetObjectWhenOverwrite
Value: true
を指定し、submitをクリックすれば、Cognos再起動不要で10秒ほどで変更されます。

![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/265f104b-048c-6604-ad09-aea2b0882a97.png)

さてこの状態で、もう一度上書きをやってみます。

今はIDは*41の「本番レポート」です。
![008.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/cdff6d22-6dab-336a-98db-106a97b6c53e.png)

ジョブの設定も復活させましたので、最新時刻の6時47分のバージョンを持ちます。
![009.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/2bf40950-87bf-48d1-0876-a3b600724c23.png)

ここで「開発フォルダ」の「開発中レポート2」を「本番レポート」に名称変更します。
IDは、*92です。
![011.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/dee61a32-7a82-e3eb-77af-9e76d961753b.png)

「本番レポート」に上書きします。
![010.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/ec3cbaa6-bfe6-52d5-c09f-9a615896a3b0.png)

しかしながら「本番レポート」のIDは、*41のままで変更されません。
![012.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/8faa2a76-465f-1d66-8a93-fd7e0841a484.png)

ジョブからのリンクも切れないので、更新された最新時刻の6時49分バージョンを持ち、1分置きにさらに更新されていきます。
![013.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/84ff586a-989e-864e-2c98-755619a8455e.png)

という感じの動作ですね。
これは中々使える機能だと思いますので、是非知っておいて頂ければと思います。

#参考情報
**Administration – Changing the behaviour of Object Copying in #Cognos Analytics 11.0.7 (Release 7)**
https://www.ibm.com/communities/analytics/cognos-analytics-blog/administration-changing-the-behaviour-of-object-copying-in-cognos-analytics-11-0-7-release-7/
2017-10-04 Python2 > AAA_20170228_030000_BBB.png に N時間を足して返す実装 > re.findall() | datetime.datetime.strptime | datetime.timedelta() | .strftime() | .join() | timedelta(hour=9.5) | re.match(r'(.*_)(\d{8}_\d{6})(_.*)', filename).group

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
```

前回: [GNU coreutils > date > 20170228_23000という文字列(UTC)に9.5時間を追加してdateで識別する > echo "20170228_230000" | sed 's/_/+/g' | sed 's/0000/hours\+570minutes/g' | xargs date -d](https://qiita.com/7of9/items/839d5a766bea48d04589)


GNU dateでファイル名の日時を変換しようとしたが、どうもうまくいかないので断念。

Python実装に切り替えた。

### 参考

[Pythonで文字列からdatetimeオブジェクトを生成する(Python3.3)](https://qiita.com/BarutanGNE/items/b14bef93c004f90c0ce4)

情報感謝です。

[「12a345a67.8」から正規表現で、「12」と「345a67.8」をキャプチャ取得したい](https://ja.stackoverflow.com/questions/38411/12a345a67-8-%E3%81%8B%E3%82%89%E6%AD%A3%E8%A6%8F%E8%A1%A8%E7%8F%BE%E3%81%A7-12-%E3%81%A8-345a67-8-%E3%82%92%E3%82%AD%E3%83%A3%E3%83%97%E3%83%81%E3%83%A3%E5%8F%96%E5%BE%97%E3%81%97%E3%81%9F%E3%81%84)

良い課題の提供感謝です。

上記の変換をお試し実装したら、その実装方法が今回役に立ちました。
(re.findallの使用)

timedelta()は @shiracamus さんに教えていただきました。
（NOTE: そのコメントが検索できないため、リンクを貼ることができません。)

.join()も@@shiracamus さんに教えていただきました。(と思います)
（NOTE: そのコメントが検索できないため、リンクを貼ることができません。)

### code v0.1

```test_change_timezone_171004.py
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
import re
import datetime as dt
import sys

# on Python 2.6.6
# coding rule: PEP8

# v0.1 Oct. 03, 2017
#   - add STR_addhour()


def STR_addhour(asrc, timediff_hour):
    # input(asrc): e.g. [XXX_yyyymmdd_hhnnss_XXX.png]
    #
    wrk = re.findall(r'[^\s_,]+', asrc)
    yyyymmdd_hhnnss = wrk[1] + " " + wrk[2]
    #print(wrk)
    #print(yyyymmdd_hhnnss)
    #sys.exit()

    adt = dt.datetime.strptime(yyyymmdd_hhnnss, '%Y%m%d %H%M%S')
    adt = adt + dt.timedelta(0, timediff_hour * 60 * 60)
    res = adt.strftime('%Y%m%d_%H%M%S')
    res = '_'.join([wrk[0], res, wrk[3]])
    return res

SRCSTR = "AAA_20170228_030000_BBB.png"

for elem in 23, 9.5, 6, 5.0:
    dst = STR_addhour(SRCSTR, timediff_hour=elem)
    print(dst)

```

```txt:run
AAA_20170301_020000_BBB.png
AAA_20170228_123000_BBB.png
AAA_20170228_090000_BBB.png
AAA_20170228_080000_BBB.png
```


正規表現はまだ慣れていないので、間違いがあるかもしれません。
AWS EC2 スナップショットの作成

# スナップショットの作成

## インスタンスの停止

スナップショット作成時にはインスタンスの停止が推奨されます。
AWSのコンソールもしくは、OSからインスタンスを停止させます。

> 
```
使用中のアタッチ済みボリュームのスナップショットを取ることができます。
ただし、スナップショットでは、スナップショットコマンドを実行した時点で Amazon EBS ボリュームに書き込まれているデータのみがキャプチャされます。
そのため、アプリケーションやオペレーティングシステムによってキャッシュされたデータは除外される可能性があります。スナップショットを取る間、ボリュームへのすべてのファイルの書き込みを停止できれば、完全なスナップショットを取ることができます。
ただし、ボリュームへのすべてのファイルの書き込みを停止できない場合は、一貫した完全なスナップショットを取ることができるように、インスタンス内からボリュームをアンマウントし、スナップショットコマンドを実行して、ボリュームを再マウントします。
スナップショットのステータスが pending の間は、ボリュームを再マウントして使用できます。
```
[Amazon EBS スナップショットの作成](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/ebs-creating-snapshot.html "Amazon EBS スナップショットの作成")

### AWS EC2 コンソールから停止する場合

![Image 1.png](https://qiita-image-store.s3.amazonaws.com/0/88753/8204a9bb-6d45-be79-1d70-ee02f0924eda.png)

### OSから停止する場合

```bash
sudo shutdown -h now
```
など


## EBSの選択

AWS EC2 コンソールで画面下部に表示される「説明」からインスタンスに紐づくEBSを選択します。

![Image 2.png](https://qiita-image-store.s3.amazonaws.com/0/88753/59de2bff-8c53-fc12-c881-1a0533146c59.png)

## スナップショット作成

対象のEBSのスナップショットを作成します。
![Image 3.png](https://qiita-image-store.s3.amazonaws.com/0/88753/d5456408-54c1-87d1-c623-f76ade356e4f.png)

![Image 6.png](https://qiita-image-store.s3.amazonaws.com/0/88753/6bd8141c-f9cd-9e7b-7800-206e030f4d9e.png)

![Image 7.png](https://qiita-image-store.s3.amazonaws.com/0/88753/2387eb24-f79c-462b-3999-6a598c0e690b.png)

![Image 8.png](https://qiita-image-store.s3.amazonaws.com/0/88753/ce2f0081-6235-ffbd-147a-0239ebe8a39a.png)

t2.small 8GiB で 5分強で作成完了でした。
開始直後に少し、進捗状況を確認したのですが0%のままで気づいたら完了していました。

# 復元

スナップショットをもとにイメージを作成を作成し、新規インスタンスを立ち上げます。

## イメージ作成

![Image 10.png](https://qiita-image-store.s3.amazonaws.com/0/88753/72990ec8-2388-5670-a625-19d2fcec5502.png)

![Image 11.png](https://qiita-image-store.s3.amazonaws.com/0/88753/2d2c9014-e8eb-cd7b-344b-e84d38961fc5.png)

作成したイメージをもとに立ち上げれば復元完了です。

# 引用元
[Amazon EBS スナップショットの作成 - Amazon Elastic Compute Cloud](http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/ebs-creating-snapshot.html)
[スナップショットによるEC2インスタンスのバックアップとレストア ｜ Developers.IO](http://dev.classmethod.jp/cloud/aws/backup_and_restore_ec2_using_snapshot/)
UnityWebRequestでJSONをPOSTする方法

PythonではJSON形式が使いやすくてよく使います。今回UnityでJSONをサーバーにPOST送信する必要があり、躓いた部分を解説していきます。


作業環境:
PC : macOS Sierra バージョン10.12.6
サーバー : Python 2.7.10, Django 1.8.1
クライアント : Unity2017.1.0f3


###JSON作成
まずは送信するJSONのデータを作成します。UnityではJSONをアセット等でも作成できますが標準で使えるJsonUtilityが便利なので使います。JsonUtility.ToJsonはクラスのオブジェクトを入れればstring型でJSONを返してくれます。

```
[System.Serializable]
public class MyName{
	public string name;
}

public MyName myObject = new MyName();
myObject.name = "name";
string myjson = JsonUtility.ToJson(myObject);
```
現在myjsonの中身はこうなっています。

```
myjson = {"name":"name"}
```

ここから躓いたポイント

#間違ったやり方

```
UnityWebRequest request = UnityWebRequest.Post(url, myjson);
yield return request.Send();
```
基本文字列はこのように送信できるので同じ要領で送信できると思い込んで送ってしまいます。ですがこれで送ってしまうと中身が以下のようになってしまいます。


```
myjson = %7b%22name%22%3a%22name%22%7d
```
これだとサーバー側のPythonがJSONを認識出来ません。どうしてこうなってしまうのかというとPOST送信ではデータをURLに含めて送っていて、URLに使えない文字は変換されてしまうからです。JSONでは「{」「"」を必ず使うため文字が変えられてしまいます。

#正しいやり方

string型をbyte型配列に変換して送信します。UnityWebRequest.Post関数の引数はbyte型を受け取れないので以下のようにしてUnityWebRequestのPOSTインスタンスを作成し、UploadHandlerRawでbyte型のデータをuploadHandlerに追加することで送ることが出来ます。

```		
byte[] postData = System.Text.Encoding.UTF8.GetBytes (myjson);
var request = new UnityWebRequest(url, "POST");
request.uploadHandler = (UploadHandler)new UploadHandlerRaw(postData);
request.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
yield return request.Send();
```
UIAlertController生成を他クラスに切り分ける

以下の内容だと汎用性がなく、切り分ける意味がなさそうなので、改めて書き直しました。

UIAlertController生成を他クラスに切り分ける PART2
https://qiita.com/d-kawahara/items/fab8ab91dfd2e79ef005

### やってみたこと
普段からUIAlertControllerを使う際はコード量が多くなってしまっていたので、
今回、UIAlertControllerの生成を別クラスに切り出して使ってみました。

#### 生成クラスの作成
```
@implementation AleartHelper

- (UIAlertController *)createNewAleartController {
    UIAlertController *newAleartController = [UIAlertController
                                              alertControllerWithTitle:@"タイトル"
                                              message:@"メッセージ"
                                              preferredStyle:UIAlertControllerStyleAlert];
    
    UIAlertAction *cancelButton = [UIAlertAction
                                   actionWithTitle:@"キャンセル"
                                   style:UIAlertActionStyleDefault
                                   handler:^(UIAlertAction *action) {
                                       // 何かのアクション
                                   }];
    UIAlertAction *saveButton = [UIAlertAction
                                 actionWithTitle:@"保存"
                                 style:UIAlertActionStyleDefault
                                 handler:^(UIAlertAction *action) {
                                     // 何かのアクション
                                 }];
    
    [newAleartController addAction:cancelButton];
    [newAleartController addAction:saveButton];

    return newAleartController;
}
@end 
```

#### 受け取りと表示
```
#import "ViewController.h"
#import "AleartHelper.h"

@interface ViewController ()
@property (weak, nonatomic) UIAlertController *aleartController;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    AleartHelper *aleartHelper = [[AleartHelper alloc]init];
    self.aleartController = [aleartHelper createNewAleartController];

}

- (IBAction)aleart:(id)sender {
    [self presentViewController:self.aleartController animated:YES completion:nil];
}

@end

```

###まとめ
とりあえず切り分けてみましたが、アラートアクション結果の取得などを考えると、無理に切り分けなくても良いのかなと少し迷ってしまいました。
初歩的な知識ですが、備忘録として残しました。
Android 8 (Oreo) の EditText をタップするとクラッシュする

## 現象
Android 8.0.0 (Oreo) でかつ Support Library 26.x.x を使用しているときに EditText をタップするとクラッシュするようだ。

```
  java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.getBoundsOnScreen(android.graphics.Rect)' on a null object reference
    at android.app.assist.AssistStructure$WindowNode.<init>(AssistStructure.java:486)
    at android.app.assist.AssistStructure.<init>(AssistStructure.java:1912)
    at android.app.ActivityThread.handleRequestAssistContextExtras(ActivityThread.java:3035)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1807)
    at android.os.Handler.dispatchMessage(Handler.java:105)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6541)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
```

AOSP の issue にもなっていて、fixed になっているので、恐らく 8.0.1 で直るものだと思われる。

## ワークアラウンド
Widget.AppCompat.EditText の style を上書きしてしまうのが楽ならしい。

```
<style name="MyTheme" parent="@style/Nanika">
  ...
  <item name="editTextStyle">@style/EditTextStyle</item>
  ...
</style>

<style name="EditTextStyle" parent="@style/Widget.AppCompat.EditText">
  <item name="android:importantForAutofill" tools:ignore="NewApi">noExcludeDescendants</item>
</style>
```
## 参考文献
* https://issuetracker.google.com/issues/62834931
usacloudのイメージキャラクター「うさみん」をコンソールで愛でる方法

# usacloudイメージキャラクター 「うさみん」！！

さくらのクラウド CLIである[usacloud(ウサクラウド)](https://github.com/sacloud/usacloud)にイメージキャラクター「[うさみん](https://twitter.com/usamin_usacloud)」が誕生しました！！

![usamin-introduction.png](https://qiita-image-store.s3.amazonaws.com/0/20668/141e88d8-7f9e-273b-88ac-7caff5466529.png)

- うさみんのTwitterアカウント
    [https://twitter.com/usamin_usacloud](https://twitter.com/usamin_usacloud)

可愛いですね！愛でたいですよね？？

そんなわけで普段から[うさみん](https://twitter.com/usamin_usacloud)を愛でるために
コンソールにうさみんを召喚(背景画像の設定)しちゃいましょう！！

> ※以下ではmacOS上のコンソールでの設定手順となっていますが、
VS CodeやIntelliJなどお好みのエディタ/IDEでも同様の設定が行えるはずです。

# コンソールにうさみんを召喚する

## うさみん画像を取得&保存

まずは[以下の画像](https://qiita-image-store.s3.amazonaws.com/0/20668/fa0fc19e-6578-05e4-24a0-cb5721f8e563.jpeg)をローカルマシンに保存しておいてください。

![usamin-console-bg3.jpg](https://qiita-image-store.s3.amazonaws.com/0/20668/fa0fc19e-6578-05e4-24a0-cb5721f8e563.jpeg)

## コンソールのプロファイルを複製

既存のプロファイルをコピーして新しいプロファイルを作成し、そのプロファイルに対し背景画像を設定します。

コンソールを起動しメニューから「ターミナル」 -> 「環境設定」を開きます。
「プロファイル」タブからコピー元となるプロファイルを選択した上で「プロファイルを複製」を実行します。

文字色の関係上、Grassあたりをコピー元にするのがオススメです。

![console-setting.png](https://qiita-image-store.s3.amazonaws.com/0/20668/1a704a97-e400-9233-04ae-94349145ecee.png)

## 背景画像の設定

複製したプロファイルを選択し、背景画像を設定します。
プロファイルにはわかりやすい名前をつけておくと良いでしょう。

![set-image.png](https://qiita-image-store.s3.amazonaws.com/0/20668/28f616af-fb4a-ab96-e0a5-1f0cb13eb15c.png)

## 新しいプロファイルでコンソールを開く

背景画像を設定したプロファイルでコンソールを開いてみましょう。

コンソールのメニューから「新規ウィンドウ」または「新規タブ」を開き、背景画像を設定したプロファイルを選択します。

![open-window.png](https://qiita-image-store.s3.amazonaws.com/0/20668/f7e2c5e8-8620-1d06-7b8a-dbbd8123070a.png)


これで背景画像が設定されたコンソールが開くはずです。

![usamin_console.png](https://qiita-image-store.s3.amazonaws.com/0/20668/d54166f8-21f5-df7e-edf7-594855546320.png)

## 以上、あとは存分に愛でましょう！

あとは愛でるだけです。意味もなく`ls`や`uname`を実行しながら存分に愛でてください。

せっかくなので、愛でるついでにさくらのクラウドのCLIである「[usacloud](https://github.com/sacloud/usacloud)」を利用してみると[うさみん](https://twitter.com/usamin_usacloud)も喜ぶことでしょう。

以上です。

--- 

#### クレジット

うさみんのキャラクターデザインは[禎波ハヅキ(@kze_yoshi8)](https://twitter.com/kze_yoshi8)さんによるものです。
朝起きたらAmazon Elasticsearchから取得した検索結果でJson Parse Errorが起きた件

前日まで普通にAmazonElasticsearchの検索が使えたのに、朝急に

```
MultiJson::ParseError: 822: unexpected token at '�'
```

というエラーが頻発したので、その対処方法の共有です。

# 環境
- Amazon Elasticsearch
- Elasticsearch(ver２系、５系)
- elasticsearch-rails-5.0.4

# 事象
Elasticsearchから返ってきたjsonをparseしてエラー。
何が起きたのか？
以下確認手順を記載。

## 調査
- エラー発生箇所に「binding.pry」を入れてそもそもどんなjsonデータをparseしようとしてエラーになっているのか調査
<code>bundle open elasticsearch-transport</code>でエラーが起きていた箇所を確認。pryを使ってjsonの中身を確認


```elasticsearch-transport-5.0.4/lib/elasticsearch/transport/transport/serializer/multi_json.rb
module Elasticsearch
  module Transport
    module Transport
      module Serializer

        # An abstract class for implementing serializer implementations
        #
        module Base
          # @param transport [Object] The instance of transport which uses this serializer
          #
          def initialize(transport=nil)
            @transport = transport
          end
        end

        # A default JSON serializer (using [MultiJSON](http://rubygems.org/gems/multi_json))
        #
        class MultiJson
          include Base

          # De-serialize a Hash from JSON string
          #
          def load(string, options={}) 
            ::MultiJson.load(string, options) <<<<< ここのstringの中身を確認
          end

          # Serialize a Hash to JSON string
          #
          def dump(object, options={})
            ::MultiJson.dump(object, options)
          end
        end
      end
    end
  end
end

```

- 中身をみるとjsonデータでなく、何かエンコーディングされたような形式ものになっていた
- なぜそうなったのか・・・。AmazonElasticsearchの仕様変更でgzip形式返すようになった。

## 対応
Elasticsearchの接続を行っていた箇所に以下のような修正を追加

```
      Elasticsearch::Client.new(
        hosts: hosts,
        randomize_hosts: true,
        request_timeout: 10,
        reload_connections: false,
        sniffer_timeout: 3,
        reload_on_failure: false,
        transport_options: { headers: { 
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　content_type: 'application/json',
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　  　　　　　　　　"Accept-Encoding": "" <<<<< ここを追加
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 }
　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　 }, 
        log: true
      ) do |f|
        f.request :aws_signers_v4,
                   credentials: Aws::Credentials.new(ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']),
                   service_name: 'es',
                   region: 'ap-northeast-1'
        f.adapter Faraday.default_adapter
      end
```

[こちら](https://github.com/elastic/elasticsearch-ruby/issues/457#issuecomment-325859208)を参考にしました。

<追記> 自分が忘れないようにするためのメモ： elasticsearch-railsの方でHttp通信で使っているfaradayは「Accept-Encoding: gzip」 がデフォルトの設定らしい。
cpコマンドで不可視ファイルまでコピーする

`hoge`フォルダの中に`.htaccess`とかがあった場合以下だと`.htaccess`などは含まれない

```
$ cp -r hoge/* 対象のフォルダ
```

以下だと大丈夫

```
$ cp -r hoge/. 対象のフォルダ
```
Swift4でTimerを使う


5秒ごとにHelloと出力します。

```
Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) {_ in
    print("Hello")
}
```

従来のselectorを使った方法だと、対象のメソッドに `@objc` キーワードを付ける必要がありますが、このキーワード自体、4から非推奨になったようでビルド時に警告が出てしまいます。動くことは動きますが、今後はこちらの書き方に統一していった方が良さそうです。


参考(DispatchQueue):
https://qiita.com/lumbermill/items/7553a6ace26019f08bc6
Slackのメッセージを一括削除するPythonコード

Slackの一括削除機能が昔はあったそうですが今探すとarchiveページ自体消滅していたようで、
仕方ないのでAPIですぐできそうだったのでささっと書きました。（python2.7であまりに雑なコードですが）
generalはチャンネルごと作り直せないので掃除したいときなどに需要あるかもしれないのでここに置いておきます。
少しいじれば特定の人のメッセージだけ消すなどもできると思います。

トークンはこちらから取得してください
https://api.slack.com/custom-integrations/legacy-tokens

チャンネルIDはここに必要な情報を入れると見れます(general等チャンネル名とは違うので注意)
https://api.slack.com/methods/channels.info/test

Slackを見ながら実行するとどんどん消えていくのが見えて面白いです。（？）
当たり前ですが一旦消すと復旧はできませんので予めエクスポートするなど用法用量を守ってご利用ください。

```delete_slack_message.py
#coding: utf-8

import urllib
import urllib2
import json
import time

delete_url = "https://slack.com/api/chat.delete"
hist_url = "https://slack.com/api/channels.history"
token = '[yourtoken]'
channel = '[channel_id]'

delete_params = {'token':token,
          'channel':channel
}
hist_params = {'token':token,
          'channel':channel,
          'count' : '1000',
}

hist_params = urllib.urlencode(hist_params)

req = urllib2.Request(hist_url)
req.add_header('Content-Type', 'application/x-www-form-urlencoded')
req.add_data(hist_params)

res = urllib2.urlopen(req)

body = res.read()
data = json.loads(body)


for m in data["messages"]:
  delete_params['ts'] = m["ts"]
  enc_params = urllib.urlencode(delete_params)

  req = urllib2.Request(delete_url)
  req.add_header('Content-Type', 'application/x-www-form-urlencoded')
  req.add_data(enc_params)


  res = urllib2.urlopen(req)

  body = res.read()
  print(body)
  #連続で送りすぎるとエラーになるので1秒待機
  time.sleep(1)                 
```
node.jsめも


## macにnodebrewを導入してjsを実行する

homebrewが入っていない場合はインストールする。
以下は基本的に入っていないことを前提に記述

- nodebrewを入れる

```
$ brew install nodebrew
```
- node.jsの最新版をインストール

```
nodebrew install-binary latest
```

バージョンを指定するときはlatestの部分にバージョンを指定する
（バージョン確認は`nodebrew ls-remote`）

```
$ nodebrew install-binary latest
Fetching: https://nodejs.org/dist/v8.6.0/node-v8.6.0-darwin-x64.tar.gz
Warning: Failed to create the file
Warning: /Users/hoge/.nodebrew/src/v8.6.0/node-v8.6.0-darwin-x64.tar.gz: No
Warning: such file or directory
                                                                           0.0%
curl: (23) Failed writing body (0 != 941)
download failed: https://nodejs.org/dist/v8.6.0/node-v8.6.0-darwin-x64.tar.gz
```
とかなってインストールがうまくいかなかったときは
`$ mkdir -p ~/.nodebrew/src`
でディレクトリ作ってからやるとできるとおもいます

- 使用するバージョンを指定する

これやらないとcurrentってディレクトリができてなくてパス通すとき困った

```
$ nodebrew list  ← インストールされているバージョン確認
vX.X.X

current:...

$ nodebrew use vX.X.X
```

パス通す

```
$ echo 'export PATH=$PATH:$HOME/.nodebrew/current/bin' >> ~/.bash_profile
$ source ~/.bash_profile
```

これで`node`が使えるようになってると思うのであとは`OO.js`ファイルを作って動作させてみる
導入は雑で申し訳ないけど他のサイト見ていただければもっとちゃんと分かると思います‥

## 実行テスト

```test.js
class dog {
    constructor(name){
        this.Name = name
    }
    setName(name){
        this.Name = name
    }
    show(){
        console.log("吾輩は「" + this.Name + "」である"); 
    }
}

function main() {
    let d = new dog("たま");
    d.show();
    d.setName("ねこ");
    d.show()
}

main()
```

- 結果

```
$ node test.js
吾輩は「たま」である
吾輩は「ねこ」である
```
メンバ変数って定義できないのね

## 参考URL

https://qiita.com/akakuro43/items/600e7e4695588ab2958d
brewでhttpd24入れていたけどupgradeしたら動かなくなった時の対処法

## homebrew/apache/httpd24

- apache2.4が使いたくて `brew install httpd24` をインストールしていた
- `brew upgrade` したらapache動かなくなった

そんなときの対処法

### PHPでエラー

apacheのプロセス動きっぱなしで問題なく動作してると思ったら、ターミナルでPHPコマンド使えなくてやっと気づいた。
残ってるプロセス全部決して、apache起動しようとしたら起動できなくなった。

`Warning: Use httpd instead of deprecated homebrew/apache/httpd24`

`brew doctor` とかいろんなとこでエラーでまくり。

### なにが変わった？

homebrew/apache/httpd24がcoreへ移行されたhttpdに統合された
httpd24 -> httpd (coreのhttpdが2.4になった)

## 対処法

httpdとhttpd24をuninstallして入れ直すだけ。
ただ綺麗に消すのが面倒。

ここを参考に。

https://github.com/Homebrew/homebrew-core/issues/18732

抜粋

```
brew uninstall --ignore-dependencies httpd
brew uninstall --ignore-dependencies httpd24

mv /usr/local/var/apache2 /usr/local/var/httpd

brew untap homebrew/apache

brew install httpd

sudo brew services start httpd
```

apache2と `tap homebrew/apache` にさようなら。

## ついでにPHP入れ直す時

`--with-httpd`を使う。([参考](https://github.com/Homebrew/homebrew-php/issues/4493))
`--homebrew-apxs`はもう古い

`brew install homebrew/php/php72 --with-httpd`

### PHP動かなくなったってとき

#### PHPオプションの`xxx.so`がない

ビルドしてinstallする

`brew install homebrew/php/php72-igbinary --build-from-source`

#### PHPのコードがそのまま表示される

- httpd.conf確認して、libphpモジュールを読み込んでいるか確認する
- libphpモジュールが実際にあるか確認する
    - なかったら `brew reinstall php72 --with-httpd` でビルド
- httpd.confのPHP設定を確認

```
<FilesMatch .php$>
SetHandler application/x-httpd-php
</FilesMatch>
DirectoryIndex index.php index.html
```

`sudo apachectl restart`

して確認。
AWS Code Commitでgitリポジトリを作る

投稿日：2017-10-04

# はじめに
今回gitの環境を自分で初めて構築したのでその備忘録として記録しておきます。（これまではsvnを使用していたり、誰かの作ったgit環境で作業をしたりしていました）

# 前準備
前提条件とかの確認
この部分で読む意味があるかどうか判断してもらえればありがたい。

## やりたいこと
- AWS Code Commit を使用して git リポジトリの作成
- ローカルのwindows環境からアクセス

## 環境
- Amazon Linux AMI 2016.09-release
- Windows 8.1 Pro 64bit

## 前提知識
- 簡単なgit何それ程度の知識
分からない場合は以下などを参考にしてください 
[Git をはじめからていねいに](https://github.com/takanabe/introduction-to-git)

## 必要なもの
- AWSアカウント
- Windowsマシン（対応するgitがインストールできればOK）

# 実作業
# [AWS CodeCommit](https://console.aws.amazon.com/codecommit/) にアクセス
## AWS CodeCommit repository を作成
『リポジトリの作成』ボタンを押してリポジトリ名（100文字以内）を入れれば完了。説明は無くてもいい。
リポジトリ名も説明も後で変更可能。とはいえ、リポジトリ名を変えると色々とメンドクサイので変えない方がよい。

# SSH接続
※ root アカウントではSSH接続はできません。
※ IAMUserSSHKeys ポリシー、IAMReadOnlyAccess ポリシー、適切な AWS CodeCommit 管理ポリシーを IAM ユーザーにアタッチ
[詳細はこちら](http://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/setting-up-ssh-windows.html?icmpid=docs_acc_console_connect#setting-up-ssh-windows-account)

1. Git (1.7.9 以降）インストール
2. ssh-keygen を使用してパブリック/プライベートキーペアを作成
3. SSH パブリックキーを IAM ユーザーにアップロード
4. SSH 設定ファイル (drive:\Users\<user-name>\.ssh\config) を編集

```
Host git-codecommit.*.amazonaws.com
  User Your-IAM-SSH-Key-ID-Here
  IdentityFile ~/.ssh/Your-Private-Key-File-Name-Here
```

5．作業を行うコンピュータにリポジトリのクローンを作成
`git clone ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/<reponame>`

# 最後に
以上でローカルの作業環境からAWSにpushできるようになる
ここで一応費用面についても触れておく
## 無料範囲
- 最初の5人のアクティブユーザー（アクセスしないユーザーは関係なし）
- 無制限のリポジトリ
- 50 GB のストレージ/月
- 10,000 回の Git リクエスト/月

## 追加料金
- 追加ユーザー1人：1 USD/月（以下の特典が付く）

```
10 GB のストレージ/月
2000 件の Git リクエスト/月
```
- 0.06 USD/GB/月
- 0.001 USD/Git リクエスト

[料金の詳細はこちら](http://aws.amazon.com/codecommit/pricing/)

# 参考リンク
[AWS CodeCommit とは](http://docs.aws.amazon.com/ja_jp/codecommit/latest/userguide/welcome.html)
[Git をはじめからていねいに](https://github.com/takanabe/introduction-to-git)
[私家版 Git For Windowsのインストール手順](https://opcdiary.net/?page_id=27065)
[WS CodeCommit 料金](http://aws.amazon.com/codecommit/pricing/)
希望の党・第１次公認リストを整形して出力する

希望の党・第１次公認リストが載っているんですが、

- 産経ニュース - http://www.sankei.com/politics/amp/171003/plt1710030138-a.html

かなり見にくいので、見やすいように整形して出力するrubyスクリプトを書きました。
nokogiri使っていますので、bundler使用する場合は`Gemfile`に`gem "nokogiri"`と書いといてください。

ソースは以下です。

```ruby:hope.rb
require 'open-uri'
require 'nokogiri'

Member = Struct.new(:name, :search_url)

doc = Nokogiri::HTML(open('http://www.sankei.com/politics/amp/171003/plt1710030138-a.html'))
content = doc.css('article p').to_a.flatten.map(&:content).join

members = content.scan(/区?＝(.+?)（/).reduce([]) do |acum, match|
  name = match[0]
  acum << Member.new(name, "https://www.google.co.jp/search?q=#{name}")
end

tbody = members.map.with_index(1) do |m, i|
  <<-TR
    <tr>
      <td>#{i}</td>
      <td>#{m.name}</td>
      <td><a href="#{m.search_url}" target="_blank">#{m.search_url}</a></td>
    </tr>
  TR
end.join

puts <<HTML
<html>
  <head>
    <title>希望の党・第１次公認リスト</title>
  </head>
  <body>
    <h1>希望の党・第１次公認リスト</h1>
    <table>
      #{tbody}
    </table>
  </body>
</html>
HTML
```

`bundle exec ruby hope.rb`で実行すると標準出力にhtmlを吐き出します。次のような感じで適当にリダイレクトしてあげてください。

```
$ bundle exec ruby hope.rb > hope.html
```

名前と検索用URLのみです。選挙区は拾ってません。必要なら改造してみてください。完成物htmlだけに興味ある方は、自分のブログに貼り付けてありますので、そっちを見てください。

- [希望の党・第１次公認リスト](http://www.ohmyenter.com/%E5%B8%8C%E6%9C%9B%E3%81%AE%E5%85%9A-%E7%AC%AC%EF%BC%91%E6%AC%A1%E5%85%AC%E8%AA%8D%E3%83%AA%E3%82%B9%E3%83%88/)
GNU coreutils > date > 20170228_23000という文字列(UTC)に9.5時間を追加してdateで識別する > echo "20170228_230000" | sed 's/_/+/g' | sed 's/0000/hours\+570minutes/g' | xargs date -d

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
```

## 20170228_230000 という文字列をdateで 2017-02-28 23:00:00にする

```
$ echo "20170228_230000" | sed 's/_/+/g' | sed 's/0000/hours/g' | xargs date -d $1
Tue Feb 28 23:00:00 JST 2017
```

やっていることは以下。

- 20170228_230000を20170228+23hoursに変換
- dateに読みこませて2017-02-28 23:00:00という日時と認識

### link

https://unix.stackexchange.com/questions/56824/how-do-you-specify-a-format-for-the-input-to-date

GNU dateには入力日時のフォーマット指定はないようだ。

## 20170228_23000という文字列(UTC)に9.5時間を追加してdateで識別する

9.5時間 = 570分

```
$ echo "20170228_230000" | sed 's/_/+/g' | sed 's/0000/hours\+570minutes/g' | xargs date -d
Wed Mar  1 08:30:00 JST 2017
```

上記の文字列をyyyymmdd_hhnnssの書式で出力しようとすると失敗する。
Python実装の方がいいかもしれない。
TestObserver 的 assertResult 與 assertValue

如果用了這個 operator 的話，代表會期待待測對象一定會有 onComplete 的事件丟出來，否則就會造成錯誤。

如果期待這個 sequence 不應該被結束，就應該要使用 `.assertValue()`
更進一步要加上確認這個 sequence 不應該被結束的話，就可以再追加 `assertNotComplete()`
node + express で Graceful Shutdown 実装でハマったので共有

Node.js + [Express 4](http://expressjs.com/ja/) で graceful 対応でハマったので共有。

# ■なにが起こったのか

Ctrl+C で安全に終了するように実装したが、なぜか終了しない。


# ■結論

接続を切ってから終了する機能追加することで実現。

```js
var http = require('http');
var server = http.createServer(app);

function wireUpServer(/*httpServer*/ server) {
    var connections = {};
    server.on('connection', function(conn) {
        var key = conn.remoteAddress + ':' + conn.remotePort;
        connections[key] = conn;
        conn.on('close', function() {
            delete connections[key];
        });
    });

    server.destroy = function(cb) {
        server.close(cb);
        for (var key in connections)
            connections[key].destroy();
    };
}
wireUpServer(server);
```
（上記ソースは [no way to shutdown a server cleanly](https://github.com/socketio/socket.io/issues/1602) より）

としておいて、

```js
const gracefulShutdown = function() {
    server.destroy(() => {
        process.exit();
    });
};
process.on('SIGTERM', gracefulShutdown); // for kill
process.on('SIGINT', gracefulShutdown); // for Ctrl+C
```

とすることで実現できる。

なお、この場合の graceful とは下記である：

- Shutdown 開始したら新しい閲覧は受け付けない。
- まさにアクセス中のユーザがいたら強制切断する。
- DBなどは（接続がなくなるので）安全に終われるはず。



# ■下記だと何が問題なのか。

通常なら下記の方法でできそうである。

```js
const gracefulShutdown = function() {
    server.close(function () {
        process.exit();
    });
};
process.on('SIGTERM', gracefulShutdown); // for kill
process.on('SIGINT', gracefulShutdown); // for Ctrl+C
```

しかし、下記に遭遇する：

- Chrome で閲覧している場合、タブを落とすだけでなく、ブラウザ自体を落とすまでコネクションが繋がり続ける（内部的なconnection数がブラウザ自体を落とすまで減らない）。30秒ほど待てば終了するのだが、Chrome をリロードし続ける限りずっと繋がる（とはいえその間、新規のアクセスは防がれる）。 ※[no way to shutdown a server cleanly](https://github.com/socketio/socket.io/issues/1602) によれば SocketIO 側のバグのよう。
- curl でのアクセスなら期待通りの動き（レスポンスと同時に切断扱い）。

使えなくはないが、Chrome でテストしてて、終了のたびに30秒待たされたりとかやりづらいし、本番でアクティブにアクセスしてるユーザがいるとずっと終了できないので、この方法は使えない。


# ■何が起こっているのか

```js
server.close(function () {
    process.exit();
});
```

で渡したコールバックが実行されるのは、すべてのコネクションが終了したときである。
ちなみに今どれくらいのコネクションが繋がっているのかは下記を仕込むと解る。

```js:繋がっているコネクション数を知る方法
setInterval(() => {
    console.log(`++++++++++++++++++++++++ ${server._connections}`);
}, 500);
```
js(es6)でキーワード引数・デフォルト引数・型チェックをする方法


```js:

/* @flow */
type hogeOptions = {
  x?: string,
  y?: number,
}

const Hoge = ({ x = 'x', y = 1, }: hogeOptions = {}) => {
  console.log(`x = ${x}, y = ${y}`);
};

Hoge();
Hoge({x: 'xx'});
Haoge({y: 11});
//Hoge({y: 9});
```
【Vertica】ERROR 3587の対応

## 概要
- Verticaに実行しているインサート処理の際に、リソース不足に伴う下記のエラーが出た。

```
ERROR 3587: Insufficient resources to execute plan on pool general [Timedout waiting for resource request: Request exceeds limits: Memory(KB) Exceeded: Requested = xxxxxxx, Free = xxxxxxx (Limit = xxxxxxxx, Used = xxxxxxx) (queueing threshold)]
```

- SQLのチューニングやメモリをあげたり等、解決策は色々あるが、今回は工数も少なく暫定的な対応をしたのでそちらをメモに残す。,<br>(日本語記事が皆無だったので.....)

## 方法
#### **<font color="red">キューイングのタイムアウトの時間を延ばす</font>**
これだけ....

- 上記エラーは、リソース不足によりSQLを同時並行実行できなくなってしまい、キューに入ったクエリがタイムアウトの時間を越えて残っていることで発生するものと思われる。

## 手順
### 1. SQLを実行しているユーザが使っているpoolを調べる。
ユーザが使用しているpoolは<font color="red">usersテーブル</font>から確認できる。

```sql
 SELECT user_name, resource_pool FROM users WHERE user_name = 'hogehoge';
-[ RECORD 1 ]-----+-------------------------------------------------------
user_name         | hogehoge
resource_pool     | general
```

### 2. 対象のpoolのキューイングのタイムアウトの時間を調べる。

pool名を取得できたら、次は<font color="red">resource_poolsテーブル</font>から問題のキューのタイムアウトの設定を確認する。

```sql
select queuetimeout from resource_pools where name = 'hogehoge';
-[ RECORD 1 ]------------+------------------
name                     | hogehoge
queuetimeout             | 300

```

<font color="red">※ちなみに特に設定した覚えがないのであれば、デフォルトで**queuetimeout**は**300**が設定されている</font>

### 3. タイムアウトの制限を変更する
#### <font color="red">resource_pools</font>の対象の**pool**のレコードの<font color="red">queuetimeout</font>の値を変更することで、一旦はこのエラーを回避することができます。


```sql
CREATE EXTERNAL RESOURCE POOL hogehoge  
WITH (queuetimeout=3600);  
GO  
ALTER RESOURCE GOVERNOR RECONFIGURE;  
GO  
```

# さいごに...
### この対応はあくまで**<font color="red">工数も少なく暫定的な対応</font>**です

## 参考資料
- [定義済みリソースプールの種類](http://vertica-tech.ashisuto.co.jp/resource_pool/)
- [RESOURCE_QUEUES](http://vertica-tech.ashisuto.co.jp/resource-queue/)
- [IBM Support](http://www-01.ibm.com/support/docview.wss?uid=isg3T1016634)
- [Vertica](https://forum.vertica.com/discussion/210541/vertica-vjdbc-3587-error-insufficient-resources-to-execute-plan-on-pool-general)
Node.jsでのTwitter投稿をasync/awaitで書く


Node.jsでTwitter APIを使うときは[Twitter](https://www.npmjs.com/package/twitter)を使うのが多い気がするのですがサンプルだとasync/awaitやPromiseの例が無さそうだったので調べたらできたのでメモしておきます。(タイトルの表現が不安)

> [Node.js 8: util.promisify()](http://2ality.com/2017/05/util-promisify.html) この辺を使うかと思いきや使わずにできました。

## 通常だとコールバック地獄になっていく

なんでもいいんですけど、例として今回は **ツイートを検索(search/tweets)をして、その内容を自分のツイートとしてパクツイする機能**を作ります。

通常だと **`search/tweets`のメソッドを呼んだあとのコールバックで`statuses/update`を呼び出してその中のコールバック**で結果を見ます。

```app.js
'use strict';

const twitter = require('twitter');
const client = new twitter({
    consumer_key: '', // consumer keyを記入
    consumer_secret     : '', // consumer secretを記入
    access_token_key    : '', // access tokenを記入
    access_token_secret : '' // access token secretを記入
});

client.get('search/tweets', {q: 'node.js'}, (error, tweets, response) => {
    const text = tweets.statuses[0].text; //検索して引っかかった1件目のツイート本文
    client.post('statuses/update', {status: text}, (error, tw) => { //パクツイ
        if (error) {
            console.log(error);
            return;
        }
        console.log(`id: ${tw.id}, text: ${tw.text}`);
    });
});
```

## async/awaitで書くとスッキリ

[この辺](https://github.com/desmondmorris/node-twitter/blob/master/lib/twitter.js#L9)をみると内部ではrequestモジュールを使ってるみたいで、[requestモジュールがPromise対応](https://www.npmjs.com/package/request#promises--asyncawait)しているみたいなのでasync/awaitが使えました。

```app.js
'use strict';

const twitter = require('twitter');
const client = new twitter({
    consumer_key: '', // consumer keyを記入
    consumer_secret     : '', // consumer secretを記入
    access_token_key    : '', // access tokenを記入
    access_token_secret : '' // access token secretを記入
});
//async/awaitで表現
const main = async () => {
    const tweets = await client.get('search/tweets', {q: 'node.js'});
    const text = tweets.statuses[0].text; //検索して引っかかった1件目のツイート本文
    const res = await client.post('statuses/update', {status: text}); //パクツイ
}

main();
```
Laravel5.6: キャッシュや古いデータを削除したい

`storage/`内に更新日時が古いキャッシュファイルがあり、それを削除しようと思います。
ただ、なるべく手動ではなくArtisanコマンドでやります。
`php artisan list`で一覧表示した中から役に立ちそうなコマンドを調べてみました。

# 親記事
[Laravel 5.6で基本的なCRUDを作る - Qiita](http://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)


# 役に立つArtisanコマンド
以下のコマンドは全て頭に`php artisan`を付けなくてはなりません。
例: `php artisan view:clear`

## view:clear
- [ソースコード](https://github.com/laravel/framework/blob/5.6/src/Illuminate/Foundation/Console/ViewClearCommand.php)
- コマンド説明: Clear all compiled view files

ビューの表示は`storage\framework\views`内にキャッシュされています。
それらを全て削除します。
ビューを変更したのに反映されない場合はキャッシュが邪魔していると思われるので、これを実行するといいです。

## debugbar:clear
- [ソースコード](https://github.com/barryvdh/laravel-debugbar/blob/master/src/Console/ClearCommand.php)
- コマンド説明: Clear the Debugbar Storage

[laravel-debugbar](https://github.com/barryvdh/laravel-debugbar)を使っている場合、`storage\debugbar`内にキャッシュが保存されます。
それらを全て削除します。

## auth:clear-resets
- [ソースコード](https://github.com/laravel/framework/blob/5.6/src/Illuminate/Auth/Console/ClearResetsCommand.php)
- コマンド説明: Flush expired password reset tokens

登録ユーザーのパスワードリセットをする場合、データベースの`password_resets`テーブルに一時的に保存されます。
その中でリセットの制限時間が過ぎたレコードを削除します。


# 手動で削除したもの
## セッションファイル
セッションの保存先はファイルやクッキーやRedisなどいろいろ選べますが、ファイルを指定すると`storage/framework/sessions`に保存されます。
これを削除するコマンドが見当たらなかったので手動で削除しました。

# エラーログを日別に
エラーログは`storage/logs`に保存されます。
デフォルトのままでは全てのログがひとつのファイルに保存され、古いログも消えずにどんどん肥大化してしまうので、日別にファイルを分けるようにします。
環境設定ファイルの値を変更すると、最新の7日分だけログファイルが保存されるようになります。

```diff:.env
-LOG_CHANNEL=stack
+LOG_CHANNEL=daily
```

以前は`APP_LOG`という名前でしたが、変更されたようです。
設定の詳細は`config/logging.php`に書いてあります。
:link: [エラー処理](https://readouble.com/laravel/5.6/ja/errors.html#log-storage)
Python > regex > xxx_170614/processed_0614_06.png をCOMPOSITE/processed_0614_compo.pngに変換 | \1 : 最初に現れた部分正規表現に対する参照

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
```

前回: [Python2 > 文字列置換 > dictionary + 関数エイリアス(別名)使用 > png_170614/processed_06.pngをCOMPOSITE/processed_compo.pngに変換](https://qiita.com/7of9/items/91eefa204e1c1e9176d9)

今回は以下のような変換をする。

- 入力: xxx_170614/processed_0614_06.png
- 出力: COMPOSITE/processed_0614_compo.png
- 入力ディレクトリは様々
    - 例: xxx_170616
    - 例: xxx_170619
- `_06_.png`の部分は`_2桁数字.png`という形式

### 参考

http://hodade.com/seiki/page.php?s_suuji4

`_\d{2}.png`を試した。
https://www.debuggex.com/r/Fvppl2aScKQpJ2lD


### code

https://ideone.com/Ud4Z3b

```py
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import sys
import re

# on Python 2.6.6
# coding rule: PEP8


def get_outputpath(srcpath):
    wrk = re.sub(r'_\d{2}.png', r'_compo.png', srcpath)
    wrk = re.sub(r'^.*/', r'COMPOSITE/', wrk)
    return wrk

SRCS = "xxx_170614/processed_0614_06.png",\
       "xxx_170616/processed_0616_06.png",\
       "xxx_170619/processed_0619_12.png",\
       "xxx_170620/processed_0620_18.png",\
       "xxx_170622/processed_0622_24.png",\

for elem in SRCS:
    print(elem, end="")
    res = get_outputpath(elem)
    print(" to", res)

```

```txt:run
xxx_170614/processed_0614_06.png to COMPOSITE/processed_0614_compo.png
xxx_170616/processed_0616_06.png to COMPOSITE/processed_0616_compo.png
xxx_170619/processed_0619_12.png to COMPOSITE/processed_0619_compo.png
xxx_170620/processed_0620_18.png to COMPOSITE/processed_0620_compo.png
xxx_170622/processed_0622_24.png to COMPOSITE/processed_0622_compo.png
```
GitLabのPrivateリポジトリにAndroidライブラリをデプロイする


[GitHubのPrivateリポジトリにAndroidライブラリをデプロイする](https://qiita.com/shimada_takuya/items/9e8b14ae19540f7ad0a4)の派生エントリです。あっちを読んでないと意味が分からない書き方をしたので、できたら読んできてください。

社内向けにライブラリを提供したい場合に、Gitリポジトリ内にMavenリポジトリなフォルダを作るのは有効な方法です。
ただし、リポジトリがPublicである必要があります。

ISMSとかそういう絡みの中で、うっかり「GitLabのプロジェクトの公開範囲は、InternalないしPrivateとする」みたいなルールを決めてしまうと、Mavenリポジトリの置き場所に困ってしまうわけですね。

そんなわけで、GitLabのPrivateなリポジトリに配置したMavenリポジトリからでも、Gradleのdependenciesにライブラリを読み込む話をします。

## それは元記事と同じでは

はい。基本的には課題も解決策も前述の記事とほとんど同じなのですが、[gradle-git-repo-plugin](https://github.com/layerhq/gradle-git-repo-plugin)の使い方で悩んだので、メモとして残しておきます。

## gradle-git-repo-pluginの設定

ひとまずこんな感じになりました。

```gradle:app/build.gradle
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.layer:gradle-git-repo-plugin:2.0.2'
    }
}

apply plugin: 'com.android.application'
apply plugin: 'git-repo'

repositories {
    git("git@local.gitlab.url:hoge/fuga.git", "anything.identifier.hoge.fuga", "master", "maven-repo")
}

```

`github()` 関数が使えるパターンと違って、`git()` 関数の何番目にどのパラメータを入れればいいのか、だいぶ悩まされました。

内部実装でいうと、[このへん](https://github.com/layerhq/gradle-git-repo-plugin/blob/4f84fb1/src/main/groovy/com/layer/gradle/gitrepo/GitRepoPlugin.groovy#L28-L31)↓です。

```groovy
project.repositories.metaClass.git = { String gitUrl, String name, String branch = "master", String type = "releases", def closure = null ->
    def orgDir = repositoryDir(project, name)
    addLocalRepo(project, ensureLocalRepo(project, orgDir, name, gitUrl, branch), type)
}
```

github版と読み比べたところ、次のようにすればいいことがわかりました。

```groovy
git("GitLabの普通のclone用URL", "適当な名前", "ブランチ名", "フォルダ名")
```

というわけで、こうなります。

```gradle:app/build.gradle
repositories {
    git("git@local.gitlab.url:hoge/fuga.git", "anything.identifier.hoge.fuga", "master", "maven-repo")
}
```

`"適当な名前"` ってなんだよ！？となりますが、テンポラリディレクトリ（デフォルトで`~/.gitRepos`）の中でclone先の名前として使われるだけです。他のライブラリと被らないようにFQDNか何かにしておくとよいでしょう。

## まとめ

Gradleプラグインの良い勉強になりました（震え声）
Thymeleaf 3.0.8以降ではパーサーレベルコメントが正しく閉じられていないと例外になるよう変更されました

Thymeleafのパーサーレベルコメントは、`<!--/*`から`*/-->`までがコメントと見なされ、出力されるHTMLには含まれません。

```html:Thymeleafテンプレートの例
<p>FOO1</p>
<!--/* ここがコメント */-->
<p>FOO2</p>
<p>FOO3</p>
<p>FOO4</p>
```

```html:出力されるHTMLの例
<p>FOO1</p>
<p>FOO2</p>
<p>FOO3</p>
<p>FOO4</p>
```

もし、`*/`を忘れるなどしてパーサーレベルコメントが正しく閉じられていなかった場合、Thymeleaf 3.0.7以前では`<!--/*`より後の内容が全てコメント内と見なされて、HTMLとして出力されないようになっていました。

```html:コメントが正しく閉じられていない例
<p>FOO1</p>
<!--/* 最後の"*/"が抜けているため、このコメントは正しく閉じられていない -->
<p>FOO2</p>
<p>FOO3</p>
<p>FOO4</p>
```

```html:出力されるHTMLの例（Thymeleaf3.0.7以前）
<p>FOO1</p>
```

これは挙動として分かりづらい（表示がおかしいのに例外も何も出ない）ので、Thymeleaf 3.0.8以降からは例外がスローされるようになりました。

```log:3.0.8以降で発生する例外
HTTPステータス 500 - Internal Server Error

Type Exception Report

メッセージ Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "ServletContext resource [/WEB-INF/templates/hello/index.html]")

説明 The server encountered an unexpected condition that prevented it from fulfilling the request.

例外
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "ServletContext resource [/WEB-INF/templates/hello/index.html]")
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:986)
        ...

原因
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "ServletContext resource [/WEB-INF/templates/hello/index.html]")
org.thymeleaf.templateparser.markup.AbstractMarkupTemplateParser.parse(AbstractMarkupTemplateParser.java:241)
...

原因
org.attoparser.ParseException: Unfinished block structure <!--/*...*/-->
	org.attoparser.MarkupParser.parseDocument(MarkupParser.java:393)
...

原因
java.io.IOException: Unfinished block structure <!--/*...*/-->
	org.thymeleaf.templateparser.reader.BlockAwareReader.read(BlockAwareReader.java:74)
        ...
注意 原因のすべてのスタックトレースは、のログに記録されています
```

実はコレ、僕がたまたま見つけて、IssueとしてThymeleafのGitHubに報告・提案したものです。

[[Improvement] Throwing exception when parser-level comment block is not closed #632](https://github.com/thymeleaf/thymeleaf/issues/632)

おそらく、本番環境のコードでパーサーレベルコメントが正しく閉じられていないことは無いとは思いますが、互換性のない破壊的変更なので、注意してください。
Python > r'_\d{2}'の「r」 > raw string記法 >  'r' を前置した文字列リテラル内ではバックスラッシュを特別扱いしません。

```txt:動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。
Python 2.6.6 (r266:84292, Aug 18 2016, 15:13:37) 
Python 3.6.0 on virtualenv
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
```

Python 2.6.6使用。

reパッケージで使う`r'_\d{2}'`などの「r」について。

https://docs.python.jp/3/library/re.html
> 正規表現パターンに Python の raw string 記法を使えばこの問題を解決できます。 'r' を前置した文字列リテラル内ではバックスラッシュを特別扱いしません。従って、 "\n" が改行一文字の入った文字列になるのに対して、 r"\n" は '\' と 'n' という二つの文字の入った文字列になります。通常、 Python コード中では、パターンをこの raw string 記法を使って表現します。

https://docs.python.jp/3/reference/lexical_analysis.html
> 文字列リテラルとバイト列リテラルの両方は、任意で文字 'r' または 'R' をプレフィックスに持つことができます; そのような文字列は raw strings と呼ばれ、バックスラッシュをリテラル文字として扱います。その結果、文字列リテラルでは raw 文字列中の '\U' と '\u' のエスケープは特別扱いされません。 Python 2.x の raw unicode リテラルが Python 3.x とは異なる振る舞いをするため、 'ur' 構文はサポートされません。


### link

検索難しいシリーズ

- [c言語 > N_マクロ > gettextのマクロ](https://qiita.com/7of9/items/77966bbc6491e05418c1)

- Lプリフィックス
    - https://qiita.com/7of9/items/afe192507bb4bdf1411e