OmniAICreator/Qiita-1.07M huggingface dataset:
"failure to make TCP connection"でIBM CloudにNodeのアプリがデプロイできない

#はじめに

IBM Cloud（旧 Bluemix）にローカルでは動いていたNodeのアプリをデプロイしようとしたが、以下のエラーが出てデプロイに失敗していた

```
2017-09-13T11:01:23.75+0900 [HEALTH/0]   ERR healthcheck failed: failure to make TCP connection: dial tcp 10.254.1.74:8080: getsockopt: connection refused
2017-09-13T11:01:23.75+0900 [HEALTH/0]   ERR Exit status 4
2017-09-13T11:00:14.98+0900 [CELL/0]     ERR Timed out after 1m0s: health check never passed.
```

#原因（と思われるところ）

ポート番号を指定するところが悪かったみたい

```app.js
var http = require("http");
var express = require('express');
var bodyParser = require('body-parser');

//ベーシック認証
var basicAuth = require('basic-auth-connect');

var samples = require('./routes/samples');

var app=express();
app.use(bodyParser.json());
app.use(basicAuth('test','test'));
app.use(express.static(__dirname + '/public')); //setup static public directory
// app.use('/samples', samples);
app.use('/', samples);

//↓ここの部分！
var server_http=http.createServer(app).listen(3000, function() {
  console.log('Listening on port %d', server_http.address().port);
});
```

#解決方法

ここに"process.env.PORT ||" を追記した

```
var server_http=http.createServer(app).listen(3000, function() {
```
↓

```
var server_http=http.createServer(app).listen(process.env.PORT || 3000, function() {
```
一行しか変わっていませんが、修正後のコードです

```app.js
var http = require("http");
var express = require('express');
var bodyParser = require('body-parser');

//ベーシック認証
var basicAuth = require('basic-auth-connect');

var samples = require('./routes/samples');

var app=express();
app.use(bodyParser.json());
app.use(basicAuth('test','test'));
app.use(express.static(__dirname + '/public')); //setup static public directory
// app.use('/samples', samples);
app.use('/', samples);

//修正箇所
var server_http=http.createServer(app).listen(process.env.PORT || 3000, function() {
  console.log('Listening on port %d', server_http.address().port);
});
```

これでうまくいきました
IBM Cloud（旧 Bluemix）にデプロイする際にはポート番号固定ではうまくいかないようです。
このようにすると、ローカルで実行した際にはprocess.env.PORTが定義されていないので、ポート番号は3000番が指定され、Bluemixではprocess.env.PORTで取得したポート番号が指定されます（そうなるはずです）。

IBM Cloud（旧 Bluemix）でNodeのアプリを開発する際にはこちらの投稿が参考になると思います。
[BluemixにデプロイしたNode.jsアプリが起動しない！そんなときは、ローカル環境で確認しましょう](http://qiita.com/asmanabu/items/1aaf6ebb1023ddc25e9d)

#編集履歴
2017/12/11
記事内のBluemix→IBM Cloudに変更
（Bluemixの名称がIBM Cloudになったため）
ASTERIAで日付同士の差引きを求めるには？

どうも～プログラムに近い書き方じゃないとASTERIAを使えないマンです.
それだと, ASTERIAの本当の良さを引き出せないので, 頑張ってマッパーを覚えようとしています.
今日はタイトルにあるように, 日付同士の差引きを求め,　一週間以上開いたもの見つけたいと思います.

# DataCalcでは日付同士の計算はできない
[DateCalcで日付算出](https://support.asteria.com/hc/ja/articles/229087427-DateCalc%E3%81%A7%E6%97%A5%E4%BB%98%E7%AE%97%E5%87%BA)
このDateCalcは
2017/09/01 に±5日 のように使用することを期待され,
日付"同士"の計算に使用できないので注意.


# 1つのコンポーネントでは出来ないようだ
 公式の質問サイトに同じことが載ってあった
[日数を取得することは可能でしょうか？](https://forum.asteria.jp/viewtopic.php?f=2&t=294)
文字だけでわかりにくいのと, 投稿主のマッパーの勉強のために投稿.

```ダミーデータ
// 日付データ, 現在の日時
"2017-09-01T00:00:00.000 JST","2017-09-12T00:00:00.000 JST"    // 1週間以上間隔が開いてる
"2017-09-02T00:00:00.000 JST","2017-09-12T00:00:00.000 JST"    // 1週間以上間隔が開いてる
"2017-09-03T00:00:00.000 JST","2017-09-12T00:00:00.000 JST"    // 1週間以上間隔が開いてる
"2017-09-04T00:00:00.000 JST","2017-09-12T00:00:00.000 JST"    // 1週間以上間隔が開いてる
"2017-09-05T00:00:00.000 JST","2017-09-12T00:00:00.000 JST"    // 1週間以上間隔が開いてる
"2017-09-06T00:00:00.000 JST","2017-09-12T00:00:00.000 JST" 
"2017-09-07T00:00:00.000 JST","2017-09-12T00:00:00.000 JST" 
```

![ETL-20170912-1.png](https://qiita-image-store.s3.amazonaws.com/0/180419/9f980f04-1e0c-4cf6-468c-9eb1ac87f4d9.png)

>Minus(二つの日付の引き算) -> Abs(絶対値取得) -> Div(データ=86400000) -> Round(切り捨て)

データ型をDateTimeにするだけで、
差引きの結果がUNIX時間になるようです。これは便利。
constの絵にstrとあるので、数値型に変更しなければならいのか？と思いましたが**不要**のようです。
86400000は1000(ミリ)*60秒*60分*24時間のことで,　1日をミリ秒で表したものですね.

意外と簡単にできました.


# レイヤー定義の条件式はSQLのwhere句に相当する?
このことを知らなかったゆえ,いままでSQLで頑張って書いていたのさ！

![ETL-20170912-2.png](https://qiita-image-store.s3.amazonaws.com/0/180419/07b4c90a-3ce2-7ca3-aa99-bcfcbd4aa67f.png)
赤枠囲みの"レイヤー1"タブをダブルクリックすれば, レイヤー定義の変更画面がでます.
条件式に$を入力すれば, 補完の値を選択できます。

以下, 結果です。
![ETL-20170912-3.png](https://qiita-image-store.s3.amazonaws.com/0/180419/32cfb1c4-0fd9-850d-8304-fff10e92f312.png)

# 関数を自作できるだと？

>関数コレクションとして作成しておけばいつでも再利用できるので便利です。

関数コレクションなるものがあるらしいので作ってみた。
ここ参照→[マッパー関数を組み合わせて使うには](https://support.asteria.com/hc/ja/articles/115000298387-%E3%83%9E%E3%83%83%E3%83%91%E3%83%BC%E9%96%A2%E6%95%B0%E3%82%92%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A6%E4%BD%BF%E3%81%86%E3%81%AB%E3%81%AF)

![ETL-20170912-4.png](https://qiita-image-store.s3.amazonaws.com/0/180419/fe3e965b-d142-965c-cdd8-5c67c7e9b9bc.png)

赤枠のところが関数に関するものです.   
(右隣の外部変数やストリーム定義もつかったことないですね～)
作り方はいたって簡単! いつものマッパー同様作成し, 呼び出しはドラッグするだけです.

## 関数の発展
### ①入力値を制限できないのか？
if文やtry~catch文のように, 異常な値(今回の例では,Datime型以外のもの)が入力されたら,
はじくことができないのでしょうか？
知ってる方がいらっしゃいましたらご教示おねがしいます.

### ②レイヤーを組み合わせると複雑なことが出来る
現在は日付けの差引きだけですが, 
入力3とレイヤーを追加して,constの値をレイヤーごとに変更してあげれば
年, 月, 日. 時間・・・などいろんなパターンの日付差引き関数が作れそうですね。

### 追記(実際にやってみた)

![ETL-20170921-1.png](https://qiita-image-store.s3.amazonaws.com/0/180419/ec3dd498-ac73-52e7-93c5-539b80890e15.png)

変換->キーから値の変換 を使うと便利です. (Linuxのヒアドキュメントと同じ使い方ができる!!!これはすごい!!)
これにより入力3の値に応じて,　constの値を変化することができました.

また, 関数内だとマッパー関数しか使えないようです.
よって, 入力1・入力2のデータ型を判定するのはどうやら無理そうです.

月と年はミリ秒で表現すると一定ではないので、正確なものを作るのは大変です.


# まとめ
今日は単純なマッパーを使ってみましたが,　個人的にはこれがすごく癖があって最初困惑しました.
QiitaではASTERIAの情報がほとんど載ってないので,
初心者の方とか困っている方は多いのではないのか？と個人的には思います(私もその一人)
みんなで有益な情報を出し合いましょう!!!
PythonでWebアプリケーションを開発する手順

pythonでwebアプリケーションを作ろうと思い立ち、その手順をまとめました。
随時更新します。（MacOS Sierra ver10.12.4）

##pythonをインストール（2.7系をインストール）
https://www.python.org/downloads/

##pip（pythonのバージョン管理システム)のインストール
http://uxmilk.jp/12691

##django（PythonのWebフレームワーク）のインストール
http://www.sejuku.net/blog/28235

##django-admin.pyにPATHを通す
http://qiita.com/astronaughts/items/2cc6e8f18290e18a742d

↓MacOS標準のPythonのライブラリを見に行っているらしいので、そこにPATHを通す

```
sudo ln -s /Library/Frameworks/Python.framework/Versions/2.7/bin/django-admin.py /usr/local/bin/
```



###パーミッション設定
これをやらないと、pyファイルの保存でいちいちパスワード入力を求められたり、ファイル追加できなかったりする。

```
sudo chmod +x /usr/local/bin/django-admin.py
```

>**補足**
>/usr/local/を開く方法(mac)
>http://qiita.com/DarkLight_0/items/d257d4b8f27ad670f40d

##プロジェクトを作る
```
django-admin startproject mySite
```
```
python manage.py startapp myapp(mySiteとは違う名前で作ること)
```

「Polls アプリケーションをつくる」あたりから参考に。。。
https://docs.djangoproject.com/ja/1.11/intro/tutorial01/

##データベース接続
###MacにMySQLをインストールする
http://qiita.com/griffin3104/items/c7908359a3e3e18cd269

###Python3 + Django で MySQL に接続
http://qiita.com/aeas44/items/90c867aa2d02f9047ef0

###モデル作成からMySQLにテーブルを作る手順
こんな感じでモデルを記述

```py:myapp/models.py
from django.db import models

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
```

その後、↓を実行する
モデルの変更をマイグレーションの形で保存する（ディスク上のファイルに保存）

```
python manage.py makemigrations myapp
```

マイグレーションがどんなSQLを実行するのかを確認する（確認したい場合のみ）

```
python manage.py sqlmigrate polls 0001
```

モデルのテーブルをデータベースに作成する

```
python manage.py migrate
```

※ログイン画面、データベースとビューの連携の実装方法などを記載予定

##エラー解決メモ
###SyntaxError: Non-ASCII character '\xe3'
実行ファイルの冒頭に「# coding:utf-8」を記述すると直る

###macでLISTENとして使用しているポートを調べる方法
MySQLが使っているポート番号を調べたかったので。。。
http://qiita.com/yokozawa/items/dbcb3b31f9308e4dcefc

```
sudo lsof -i -P | grep "LISTEN"
```
Converting RealmSwift to Xcode9 / Swift 4 (workaround)


# Environment

Xcode:    9.0 GM Seed (9A235)
Swift:    4.0
Carthage: 0.25.0

(tried on 2017/9/12 PDT)

# Introduction

In your existing Xcode project, you might see this error if you convert swift version to 4.

![szegnokebjrzr529.png](https://qiita-image-store.s3.amazonaws.com/0/113115/fe3b14b7-9e74-0fb3-7af3-57e69967fdba.png)

Usually I must be able to use it through Carthage, but now I couldn’t.
It seems that the problem is RealmSwift doesn’t take measures against Swift 4 yet for Carthage.

So let me share how I fixed it.
This is just a workaround, I think the situation will turn better soon.

# Thanks in advance
https://stackoverflow.com/questions/44640852/how-can-i-use-realm-with-swift-4
https://ja.stackoverflow.com/questions/28951/realm%E3%81%8Cbuild-%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84

# Solution

Before that, confirm the xcodebuild version.

```bash
$ sudo xcode-select -s /Applications/Xcode9.app
$ xcodebuild -version
Xcode 9.0
Build version 9A235
```

## 1) Change swift version to 4
select TARGETS then move to Build Settings > Swift Language Version.

![1dy9bygj0ijrwwmi.png](https://qiita-image-store.s3.amazonaws.com/0/113115/ef3a8fce-a3bd-a746-8045-c8bfc753a8df.png)

Then choose Swift 4.

## 2) Build RealmSwift by yourself 

### For now, download RealmSwift manually

```bash
$ git clone --recursive https://github.com/realm/realm-cocoa.git
$ cd realm-cocoa
$ git checkout v2.10.0
```

### fetch submodule

```bash
// at root of realm-cocoa directory
$ git submodule update --init
```

### build using script, passing argument by devices you want

```bash
// build will fail if you forget the previous step
$ REALM_SWIFT_VERSION=4.0 sh build.sh ios-swift
```

It takes time.

※ Or you can choose the other devices.

```
// this is optional
$ REALM_SWIFT_VERSION=4.0 sh build.sh osx-swift
$ REALM_SWIFT_VERSION=4.0 sh build.sh watchos-swift
$ REALM_SWIFT_VERSION=4.0 sh build.sh tvos-swift
```

Gotcha! frameworks are produced in the directory `realm-cocoa/build/ios/swift-4.0`.

![スクリーンショット 2017-09-12 午後5.22.42.png](https://qiita-image-store.s3.amazonaws.com/0/113115/ef1d15f3-bcf3-cd1a-be05-3221e24330d0.png)

You only have to replace the old frameworks with the new stuff.

Well done! Error disappeared.
Mission completed.

# That's it!

In my small private projects, Conversion to Swift 4 was easy (Luckily I only have to fix NSAttributedStringKey and add @objc annotation before keyword `dynamic`. Xcode9 taught me everything I should do.)

Thanks for reading! Happy coding.
iOS11まとめ（利用者向け）

iOS11関連の情報をユーザ目線で特徴をさらっとまとめました

## iOS11概要

Appleより2017年6月のWWDC 17で発表された新OS。マルチタスキング機能、ファイルアプリケーション、ApplePencilの新しい使い方などの要素が特徴とされるらしい。 ~~9月19日に一般公開されるらしいが……？~~ 公開されましたね。現時点（2017年10月5日）ではiOS11.0.2が公開されてます。今後のアップデートも楽しみです。

## 特徴
* Files：ファイルの管理が簡単になるらしい
* Dock：アプリの切り替えがスワイプで簡単になるらしい
* マルチタスキング：iPadで特に便利になるらしい。2つのアプリをslide over/split viewで実行できるとか。複数実行が強力になることでiPadの利便性が向上する模様
* Apple Pencil：署名などが簡単にできるようになるらしい
* QuickTypeキーボード：iPhoneで片手キーボードに対応した他、切り替えが不要になって入力が簡単になったらしい
* AR：拡張現実と呼ばれるもので、カメラ越しにいろんな物体を配置して臨場感あふれる体験ができるらしい
* 写真：Live Photosに「ループ」「バウンス」「長時間露光」のモードができるのと、（操作方法の共有とかに使える）画面の録画ができるらしい
* カメラ：QRコードリーダがつくらしい
* App Store：UIがだいぶ変わるらしい
* iMessage、Apple Pay：小口送金とかが簡単にできるようになるらしい
* Siri：英語に男性の声が追加されたり、言語対応が拡張したらしい
* Apple Music：共有とかが簡単になるらしい
* コントロールセンター：コントロールを追加削除できるようになるらしい

![スクリーンショット 2017-09-13 10.30.34.png](https://qiita-image-store.s3.amazonaws.com/0/188222/6b7d80a1-3579-dfb3-4b94-5c50f42cba36.png "スクリーンショット 2017-09-13 10.30.34.png")


### 参考URL
https://www.gizmodo.jp/2017/06/ios11-ipad-wwdc.html
https://www.imobie.jp/support/the-new-function-of-ios-11.htm
特定IPアドレス群からのみアクセスを許可したいときのEC2インスタンスとロードバランサーのセキュリティグループの設定例


いつも混乱するのでメモ。

# やりたいこと

- ロードバランサーは特定のIPアドレス(xx.xx.xx.xx/xx)からのHTTPSアクセスのみ受け入れる。
- ロードバランサーはHTTPSアクセスを配下のインスタンスのHTTPポートに転送する。
- EC2インスタンスはロードバランサーからのHTTPアクセスのみ受け入れる。

# 設定

## ロードバランサー

|項目|値|
|---|---|
|名前|foo-lb|
|DNS名| foo-lb-xxxxxxxxx.ap-northeast-1.elb.amazonaws.com|
|ポート構成|443(HTTPS) を 80(HTTP)に転送|
|ソースセキュリティグループ|sg-aaaaaaaa, sg-xxxxxxxx|

## EC2インスタンス

|項目|値|
|---|---|
|名前|foo-server|
|IPv4パブリックIP| nnn.nnn.nnn.nnn|
|セキュリティグループ|sg-bbbbbbbb|

## セキュリティグループ

### sg-aaaaaaaa

(設定なし)

### sg-bbbbbbbb

|方向|プロトコル(ポート)|ソース/送信先|
|---|---|---|
|インバウンド|HTTP(80)| sg-aaaaaaaa|
|アウトバウンド|すべて| 0.0.0.0/0|

### sg-xxxxxxxx

|方向|プロトコル(ポート)|ソース/送信先|
|---|---|---|
|インバウンド|HTTPS(443)| xx.xx.xx.xx/xx|
|アウトバウンド|すべて| 0.0.0.0/0|

# 補足・注意点

- sg-aaaaaaaaのインバウンド(HTTPS)にxx.xx.xx.xx/xxを入れてもいいです。ここでは他でも同様のIP許可設定を行うことを想定し、IP許可用のセキュリティグループとしてsg-xxxxxxxxを作って流用できるようにしました。
- sg-xxxxxxxxのインバウンドの設定を増やせば複数のIPアドレス帯域にも対応できます。
- 誤ってロードバランサーからsg-aaaaaaaaを外すと、EC2インスタンスに設定されているsg-bbbbbbbbのインバウンドにsg-aaaaaaaaしか無いため、ロードバランサーからEC2インスタンスへのHTTPデータ転送ができなくなります。
- sg-aaaaaaaaのインバウンドのソースにsg-xxxxxxxxを入れてもxx.xx.xx.xx/xxからのアクセスは許可されません。ソースにセキュリティグループ自体を指定した場合は、ソースがそのセキュリティグループが指定されているインスタンスになるだけだからです。
- アクセス制限しない場合はsg-aaaaaaaaのインバウンド(HTTPS)に0.0.0.0/0を入れ、、ロードバランサーのソースセキュリティグループはsg-aaaaaaaaのみにします。
TensorFlowでkeras その5

#概要
TensorFlowでkerasやってみた。
flow_from_directoryとfit_generatorを使って、dogsとcatsを学習してみた。


#環境
windows 7 sp1 64bit
anaconda3
tensorflow 1.2

#サンプルコード

```
import os
from tensorflow.contrib.keras.python.keras.preprocessing.image import ImageDataGenerator
from tensorflow.contrib.keras.python.keras.models import Sequential, Model
from tensorflow.contrib.keras.python.keras.layers.convolutional import Convolution2D
from tensorflow.contrib.keras.python.keras.layers import Dense, Dropout, Activation, MaxPooling2D, Flatten, Conv2D
from tensorflow.contrib.keras.python.keras.optimizers import Adam

pwd = os.getcwd()
img_width, img_height = 128, 128
train_data_dir = pwd + '/train'
validation_data_dir = pwd + '/validation'
nb_train_samples = 2000
nb_validation_samples = 800
nb_epoch = 10
batch_size = 64
result_dir = pwd

if __name__ == '__main__':
	train_datagen = ImageDataGenerator(rescale = 1.0 / 255, shear_range = 0.2, zoom_range = 0.2, horizontal_flip = True)
	test_datagen = ImageDataGenerator(rescale = 1.0 / 255)
	train_generator = train_datagen.flow_from_directory(train_data_dir, target_size = (img_height, img_width), batch_size = batch_size, class_mode = 'categorical')
	validation_generator = test_datagen.flow_from_directory(validation_data_dir, target_size = (img_height, img_width), batch_size = batch_size, class_mode = 'categorical')
	model = Sequential()
	model.add(Convolution2D(32, 3, 3, input_shape = (img_height, img_width, 3)))
	model.add(Activation('relu'))
	model.add(MaxPooling2D(pool_size = (2, 2)))
	model.add(Convolution2D(64, 3, 3))
	model.add(Activation('relu'))
	model.add(MaxPooling2D(pool_size = (2, 2)))
	model.add(Flatten())
	model.add(Dense(64))
	model.add(Activation('relu'))
	model.add(Dropout(0.5))
	model.add(Dense(2))
	model.add(Activation('softmax'))
	model.compile(loss = 'categorical_crossentropy', optimizer = 'adam', metrics = ['accuracy'])
	model.fit_generator(train_generator, steps_per_epoch = nb_train_samples // batch_size, epochs = nb_epoch, validation_data = validation_generator, validation_steps = nb_validation_samples // batch_size)
	model.save_weights(os.path.join(result_dir, 'cnn4.h5'))

```
kona linux2.3 lightにPython3.6.1とPyQt5をインストールしてGUIアプリを動かす

本来の目的は「低スペPCで自作GUIアプリが動くか」というだけの確認．
Python3.6.1とPyQt5をインストールすれば目的達成のはずだったが，何故か転ばされまくったため手順を記録しておく．

Python3.6インストールの記事はAnacondaを使う方法[1]，pyenvを使う方法[2]，ソースからビルドする方法[3]と既に色々あるが，今回はPython3.6.1もPyQt5もソースからビルドした．
（恐らく禁じ手だが，apt-getやpipにパッケージがなかったので仕方なく）
>先駆者の方々：
[[1]インストール Python 3.6.1](http://qiita.com/glires/items/49e7740f40d9f68f7e7b)
[[2]Python3.6.0をUbuntu16.04に導入する。](http://qiita.com/Fendo181/items/912b65c4fcc3d701d53d)
[[3]Python3.xをインストール（ソースからコンパイル）for CentOS7.2](http://qiita.com/shadowhat/items/025c49df5e45d6c1b665)

#PC環境
さくらVPS
CPU: 仮想1core
RAM: 512MB
OS: kona linux2.3 light（GUIなのにメモリ消費が100MBを切る）

#やったこと
1. 下準備
2. Python3.6.1インストール
3. PyQt5インストール
4. アプリ実行確認

#1. 下準備
※インストール中のエラーをこれで解決したので，最初にやっておけば多分おｋ．
上記のpyenv利用例[2]にほとんど載ってたので，もしかしたらPython3.6.1インストール前にそれっぽいパッケージを全部突っ込むべきなのかもしれない．

- pip3を使いたいので，先にlibssl-devをインストール．これがないとSSL関係のエラーが起こる．Webでは「yum install openssl-develでおｋ」を非常に多く見かけるが，kona linuxにyumなんてものは無かった．

```
# aptitude install libssl-dev
```

- sqlite3を使いたいので，libsqlite3-devをインストール．記憶が曖昧だが，これがないとimport errorを起こしたような．

```
# aptitude install libsqlite3-dev
```

- Python3.6.1インストールに必要なzlib1g-devをインストール．

```
# aptitude install zlib1g-dev
```

- PyQt5に必要なqt5-defaultをインストール．これがないとPyQt5インストール時に怒られる．余談だが怒られた時「Qt qmake」の表示を見たので，インストールすべきはqt5-qmakeかなと思ったら，正解はqt5-defaultだったことにびっくり仰天．

```
# aptitude install qt5-default
```

#2. Python3.6.1インストール
- 公式サイトからpython3.6.1をダウンロードして解凍．[ダウンロードページ](https://www.python.org/downloads/release/python-361/)のGzipped source tarballがこちらで言うzip的な解釈なのか．ちょっと面倒だがURLをwgetコマンドで手打ち．

```
# wget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tgz
# tar -zxvf Python-3.6.1.tgz
```

- 出てきたフォルダ内でインスコ作業．付属のREADME.rstにはmake install前にmake testと書いてあるが，今回やってなかった（赤面）．

```
/Python-3.6.1# ./configure
/Python-3.6.1# make
/Python-3.6.1# make install
```


普通はpip3みたいなパッケージ管理を使って，PyQt5をインストールするのが王道．ただし今回は謎のエラーに詰まされたので，当初の予定通り手動でインストールする（半ギレ）．

#3. PyQt5インストール
公式ページを参考に．例えば，
>[PyQt 5.9 Reference Guide: Installing PyQt5](http://pyqt.sourceforge.net/Docs/PyQt5/installation.html)  
####Downloading SIP
SIP must be installed before building and using PyQt5. You can get the latest release of the SIP source code from https://www.riverbankcomputing.com/software/sip/download.


- SIPが必須らしいので，まずSIPをインストール．

```
# wget https://sourceforge.net/projects/pyqt/files/sip/sip-4.19.3/sip-4.19.3.tar.gz
# tar -zxvf sip-4.19.3.tar.gz

/sip-4.19.3# python3.6 configure.py
/sip-4.19.3# make
/sip-4.19.3# make install
```

- PyQt5本体のインストール．ライセンス承諾を求められたらyesを入力すればOK．

```
# wget https://sourceforge.net/projects/pyqt/files/PyQt5/PyQt-5.9/PyQt5_gpl-5.9.tar.gz
# tar -zxvf PyQt5_gpl-5.9.tar.gz

/PyQt5_gpl-5.9# python3.6 configure.py
/PyQt5_gpl-5.9# make
/PyQt5_gpl-5.9# make install
```

#4. アプリ実行確認
結論：動きますねぇ！
むしろ思った以上に負荷が小さいようで驚き．通信してるだけのアプリだから当たり前かもしれないが．

タスクマネージャ＋コンソール＋アプリの3段構えにも関わらずこのメモリ使用量というのはちょっと魅力的．
どうでもいいがkona linuxの背景画像オシャレ・・・オシャレじゃない？

![autota.png](https://qiita-image-store.s3.amazonaws.com/0/201962/5bac8384-aee5-870b-c58c-ab155b73b595.png)
Google Apps Scriptで指定時刻にメールを送信するシステムを作ってみた

# 概要
ある日、ふと思いました。メールを指定の時刻に自動的に送信できないかな、と。

そこで、今回はGoogle Apps Scriptを使ってGoogleアカウントから自動的にメールを送信してみることにします。


## Google Apps Script (GAS) とは
Google Apps Script (略：GAS) とは、Googleアプリやプラットフォーム（スプレッドシートやフォームなど）を自動的に扱えるようにするScriptです。
つまり、これを使えば、ドキュメントを元にメールを送信したり、スプレッドシートを元にカレンダーにイベントを作成することができます。とても便利！！

GASはJavaScriptにGoogle Appsを操作するためのAPIを備えた形なので、プログラミング初心者でも比較的取り組みやすいのが特長です。

詳細
https://developers.google.com/apps-script/


# メール自動送信システムの構築
今回は、メール自動送信システムを構築します。


## スプレッドシートの準備
まず、スプレッドシートを1枚用意します。
そのシートの1行目にはヘッダーを、2行目以降には自動送信したいメールを以下のように書きます。

![スプレッドシート、例](https://qiita-image-store.s3.amazonaws.com/0/109937/aa72c8ca-fa62-1e46-b00f-d20ec2cc7c97.png)

各項目の意味ですが、

| 項目名 | 書く内容 | 人が書く必要があるか |
| --- | --- | --- |
| to | 宛先 | ○ |
| title | メールのタイトル | ○ |
| description | メール本文 | ○ |
| send_mail | 送信予定日時（メールを送信したい日時） | ○ |
| sent_mail | 送信完了日時（実際に送信された日時） | ×（スクリプトで使用される） |

です。


## スクリプトファイルの準備
次に、GASを書くためのスクリプトファイルの用意します。
先ほど作成したスプレッドシート内メニューの「ツール」>>「スクリプトエディタ」を選択し、スクリプトファイルを作成します。

デフォルトで`コード.gs`が作成されるので、そこへセルの情報を元にメールを自動送信するためのスクリプトを書いていきます。


## スクリプトの中身
```コード.gs
function calledByCron() {
  var sheet = SpreadsheetApp.getActiveSheet();  // シートの取得
  var startRows = 2;  // 開始行数
  var sheetData = sheet.getSheetValues(startRows, 1, sheet.getLastRow(), sheet.getLastColumn());  // シートのデータを取得（2次元配列）
  var dtLimit = new Date();  // 現在時刻を取得
  
  // シートの各行ごとにデータを取り出す
  sheetData.forEach(function(value, index) {
    // 送信完了していない、かつ送信予定日時が現在時刻より前ならば、メールを送信する
    if (!value[4] && (new Date(value[3])).getTime() < dtLimit.getTime()) {
      MailApp.sendEmail(value[0], value[1], value[2]);  // メールを送信する
      sheet.getRange(startRows + index, 4 + 1).setValue(dtLimit);  // 送信完了日時をシートに書く
    }
  });
}
```

`calledByCron()`を実行すれば、メールが自動送信されるという形です。

なお、初回実行時にメールを自動的に送信する権限を許可するかを聞かれますので、許可しておいてください。


## 実行例
上述の例で、2017/09/12 14:56:55 に `calledByCron()`を実行した場合、スプレッドシートの`sent_time`列が以下のように変化します。

![スプレッドシート、実行結果](https://qiita-image-store.s3.amazonaws.com/0/109937/ea7f3b32-3fcd-ed01-6446-a83633c4c4db.png)

`sent_time`列の2行目に時刻が自動で入力されました。これは、2行目に設定したメールのみが送信されたという意味です。

で、確認のために送信されたメールをGmail上で開くと・・・
![自動送信されたメール](https://qiita-image-store.s3.amazonaws.com/0/109937/c910d5c1-b1e9-0089-c921-41f6d02aa172.png)

正常に2行目に設定したメールのみが送信されたことが確認できました。（3行目のメールは送信されないことも確認できました。）


## 実行の自動化
メールが送信されることが確認できたので、`calledByCron()`をトリガー設定して一定時間ごとに実行するようにすれば、自動送信されるようになります。

ただし、実際のメールの送信が最大で設定よりトリガー実行間隔分遅れる可能性がありますので、ご注意ください。
なお、設定可能トリガー実行間隔は、最小で1分毎（※記事執筆時）です。つまり、1分以内の遅延を許せるなら、この方法が有効となるわけです。


# おわりに
Google Apps for Business などGoogleサービスを活用している会社では、GASの使い方次第では大きなコスト削減の可能性を感じました。😃

一方で、当然ですがGoogle側の都合でサービスを変更・停止することがある（大抵、事前告知はあるようですが）ので、依存しすぎには注意したいですね。（とはいえ、やはり便利だから使ってしまいますが。）
GPSカー　シュミレータ その２

#概要
GPSで自動走行する、コンテストがある。
実機を借りて、アプリから操作する部門がある。
実機は無いので、シュミレータを作ってみた。
軌跡を取ってみた。

#写真

迷走してるけど、８の字、描いてる。
（なんかおかしい、座標系が狂ってる。）

![log.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/d38ce124-a39c-24ac-4bf1-2fb1e453a4da.jpeg)

#コマンドの履歴

```
w g l l l l l l l l l l l l l l l l l l l l a a a a a a a a a a a a a a a a a l a a a a a a a a r a a a a l r r r r r r r r r r r r r r r r r r r r a a a a a a a a a r a a l l l l l l l l l a a a a a a a a a a a a a a a a a a a a l a a a r l a a a a a a a a a a a a a a a a r a a a a a a a a l a a a r r r r r r r r r a a a a a l l l l l l l l l l l l l l l l l l l a a a a a l a a a a a a a a a a a a a a a r a a a a a a a l a a a r d e 

```

#GPSカーのコマンド

| コマンド    |       動作     |
|:-----------------|:------------------:|
|w|スタート地点とWaypointの座標値を送信する。|
|g|スタートのアピールをする。|
|s|停止する。|
|a|前進する。|
|p|ゆっくり前進する。|
|R|鋭く右に曲がる。|
|r|緩く右に曲がる。|
|L|鋭く左に曲がる。|
|l|緩く左に曲がる。|
|d|センターサークルに到着したアピールをする。|
|e|緊急停止する。|

以上
閲覧者の自己署名証明書 有効期限を出力

## 参考

* http://web.mit.edu/~geofft/web_scripts/detect.php
* http://lifescied.org/mod/mod_ssl.html

## 値

* `$_SERVER['SSL_CLIENT_V_END']` に 閲覧者の有効期限が入っている。

```php
function check_ssl_client_v_end() {
        if (empty($_SERVER['SSL_CLIENT_V_END'])) {
                //echo "no ssl";
                return false;
        }
        if (strtotime($_SERVER['SSL_CLIENT_V_END']) < strtotime("+3 month")) {
            echo "[warning] Your certificate will expire on ";
            echo date("Y-m-d D", strtotime($_SERVER['SSL_CLIENT_V_END']));
        }
}

check_ssl_client_v_end();
```
Wordpressで前の記事・次の記事がない場合の条件付き表示

通常はこのような感じ


```php
<div class="nav-links">
  <span class="nav-previous"><?= previous_post_link('%link', '古い記事へ'  )  ?></span>
  <span class="nav-next"    ><?= next_post_link    ('%link', '新しい記事へ')  ?></span>
</div>
```

それをこのように……

```php
<div class="nav-links">
  <span class="nav-previous"><?= get_previous_post() ? previous_post_link('%link', '古い記事へ'  ) : '古い記事へ'   ?></span>
  <span class="nav-next"    ><?= get_next_post()     ? next_post_link    ('%link', '新しい記事へ') : '新しい記事へ' ?></span>
</div>
```

リンク先があるとリンクが張られますが、ない場合はリンクなしテキストが表示されます。

```html
<div class="nav-links">
  <span class="nav-previous"><a href="....">古い記事へ</a></span>
  <span class="nav-next"    >新しい記事へ</span>
</div>
```

あとはCSSで飾り付けしてみてください。

```css
.nav-previous,
.nav-next {
  color: #ccc;
}

.nav-previous a,
.nav-next a{
  color: #ff3366;
}

```
論文まとめ：Learning from Simulated and Unsupervised Images through Adversarial Training

#はじめに
CVPR2017でBest AwardとなったAppleの論文「Learning from Simulated and Unsupervised Images through Adversarial Training」をまとめてみた。

arXivの論文はこちら
https://arxiv.org/abs/1612.07828
CVPRの論文はこちら
http://openaccess.thecvf.com/content_cvpr_2017/papers/Shrivastava_Learning_From_Simulated_CVPR_2017_paper.pdfhttp://openaccess.thecvf.com/content_cvpr_2017/papers/Shrivastava_Learning_From_Simulated_CVPR_2017_paper.pdf

既にGitHub上に幾つか論文が上がっている。例えばKerasのコードはこちら。
https://github.com/wayaai/SimGAN
#要点
ディープラーニングなどで学習させるには大規模なデータが必要だが、そのような注釈付きの画像を入手することは困難だ。画像を合成して水増しすることができれば解決策となるだろうが、合成された画像は本物と程遠い。この論文で提案するSimGANモデルは合成された画像を本物っぽくする。SimGANはRefinerが合成された画像を本物っぽくし、識別器が本物の画像か、あるいはrefineされた画像かを識別する。この仕組みはGANsに似ているが、以下の点で異なる。

- lossに自己正則化項を加える
- ピクセル単位でadversarial lossを求める
- 過去の識別器を学習させる

SimGANはこの仕組みによりMPⅡGaze データセットで state-of-the-artな結果を達成した。

#モデル
<img width="715" alt="simgan02.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/01ac98b2-ec12-ee92-f995-eee2af0fec30.png">
1.  simulatorで合成した画像（Synthetic）をRefinerに入力して本物っぽい画像（Refiened）を生成する。
2.  Discriminatorにはrefineした画像（Refiened）と本物の画像（Unlabeled real）とで作ったミニバッチを入力し、識別させる。
3.  Discriminatorではピクセルごとに交差エントロピーを求め学習させる
4.  RefinerはGANs誤差と自己正則化項とでlossを求め、学習させる
#識別器のloss
<img width="553" alt="simgan03.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/972cf235-8607-78cb-8fe0-1fdb535f34ef.png">
$\tilde{x}_i$はrefineされた画像、$y_j$は本物の画像。識別器のlossは通常のGANsと同様だが、交差エントロピーはピクセル単位で求め、それを総和する。
#refinerのloss
<img width="422" alt="simgan06.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/e8ee0fbd-4396-0894-3c09-e137e927c056.png">
１項目はGANsのGeneratorと同様の誤差。

２項目は自己正則化項。通常のGANsは「それっぽい画像であればどのようなものでも生成すればいい」が、simGANはラベルに沿った画像を生成する必要がある。例えば視線推定で利用する目の画像セットを考えると、右向き、左向き、正面向きなどのラベルに対して、その画像が存在する。右向きの合成画像をRefinerに入れて左向きの画像が出てくると困る。よってなんらかの制約が必要となる。これを自己正則化項で実現する。

まずSyntheticされた画像$x_i$に対しニューラルネットワーク等$\psi$で特徴空間へ変換する$\psi (x_i)$。一方でrefineされた画像$R_\theta (x_i)$も特徴空間へ変換する$\psi(R_\theta (x_i))$。この両者のL1ノルムをピクセル単位で求める。$|| \psi(R_\theta (x_i)) - \psi (x_i) ||$。

#過去のrefineされた画像で識別器を学習する
<img width="537" alt="simGAN_F4.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/0ee399c7-cddf-4e9f-77c1-06a5765034a6.png">
学習されているrefinerから得られるrefineされた画像だけでminibatchを形成すると、lossが発散するなどの問題が発生する。

学習を安定させるため、上図のように過去にrefineされた画像を溜め込み、これを含めたminibatchを形成する。

#視線推定における実験結果
<img width="1115" alt="simGAN_F5.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/0e5572e6-13b4-0ae3-8149-3e5101e6aa78.png">
MP2Gaze datasetを用いて視線推定の実験を行った。具体的にはsimGANの仕組みを用いて新たな画像を作成し、これを用いて視線推定を行った。その結果、state-of-the-artな性能を達成した。

上図において、左側が本物の画像、右側上段が合成された画像（Synthetic）。下段がrefineされた画像（refined）。無機的で過度に鮮明な合成画像がrefineされることにより、肌の質感や自然なノイズを得ている。また瞳の虹彩もそれっぽくなっている。また以下の表は他の主要な手法との比較。
<img width="553" alt="simGAN_T3.png" src="https://qiita-image-store.s3.amazonaws.com/0/116706/5ebdd714-e8db-7584-3086-d30821564f7f.png">
１列目が手法名、２列目はデータセットが本物画像(R)か合成画像(S)か。３列目は誤差率。refinerでrefineされた画像を用いたデータセットで学習したCNNの手法が最も性能がいい。

#結論
simGANの手法によりデータのラベルを維持しながら合成画像をより本物っぽくすることができた。その結果、このrefineされた画像を用いた学習手法はstate-of-the-artな性能を達成した。
rails tutorialのhas_secure_passwordメソッドについてのまとめ

第６章
has_secure_password

モデルにこのメソッドを追加すると、次のような機能が使えるようになります。

ハッシュ化したパスワードを、データベース内のpassword_digestという属性に保存できるようになる。
2つのペアの仮想的な属性 (passwordとpassword_confirmation) が使えるようになる。また、存在性と値が一致するかどうかのバリデーションも追加される。
authenticateメソッドが使えるようになる (引数の文字列がパスワードと一致するとUserオブジェクトを、間違っているとfalseを返すメソッド) 。
has_secure_passwordを使うには、1つだけ条件があります。それは、モデル内にpassword_digestという属性が含まれていること。

password_digestカラム用の適切なマイグレーションを生成します。マイグレーション名は自由に指定できますが、次に示すように、末尾をto_usersにしておくことをオススメします。こうしておくと、usersテーブルにカラムを追加するマイグレーションがRailsによって自動的に作成されるからです。add_password_digest_to_usersというマイグレーションファイルを生成するためには、次のコマンドを実行します。

$ rails generate migration add_password_digest_to_users password_digest:string

has_secure_passwordを使ってパスワードをハッシュ化するためには、ハッシュ関数であるbcryptが必要になります。bcryptをGemfileに追加します 。
gem bcrypt
brew cleanupでMacを掃除してストレージ容量を確保する方法

いつのまにかMacのドライブの容量が少なくなってきたなんてことがよくあると思います。
そんなときは、不要なファイルを削除する等の掃除をすると思いますが、`brew cleanup`を叩くとよいです。
このコマンドが何をするかというと、brewが管理している以前のバージョンのソフトウェアのキャッシュを削除します。
このコマンドを打つと、ズララっと羅列されて最後に削除したキャッシュの合計を表示します。
`-s`をつけると最新のキャッシュまで削除します。特に問題ないので自分はこのオプションを付けて実行しています。

![スクリーンショット 2017-03-02 00.51.07.png](https://qiita-image-store.s3.amazonaws.com/0/15319/a78e910c-4ac2-d097-0b2c-165b72326686.png)

![スクリーンショット 2017-03-02 00.51.19.png](https://qiita-image-store.s3.amazonaws.com/0/15319/0dbbbdfc-4500-4b5e-f8f3-c4a3aa2197fc.png)

![スクリーンショット 2017-03-02 00.51.31.png](https://qiita-image-store.s3.amazonaws.com/0/15319/5e6f667e-2c49-b420-dae9-2c0980c8b003.png)

はい、25GBのディスクスペースが空きました。

また、caskは以下で消せます。

```
$ brew cask cleanup --outdated
```
golangのurfave/cliを使って、なんちゃってオプションRequiredをやってみた

自作のcliツールを作る場合、オプション(引数)を使えるよう作成したりする時があると思います。
その場合、必須オプションを指定できると引数漏れなどが無くなり便利になったりします。
ただ、goで簡単にオプションを作成できるパッケージ [urfval/cli](https://github.com/urfave/cli) では、オプションの `Required` が指定できないようです。
調べてみるとやっぱり必須オプションの需要があるみたいで[issues](https://github.com/urfave/cli/issues/85)で議論はされていますね。
色々やり方はあるかと思いますが、ここでは備忘録としてなんちゃってRequiredの実装メモを残しておきます。

# やりたかったこと

* `--option, -op` を必須オプションとして指定したい
* `--` 無しのオプション、第一引数などを必須にしたい
* もし、必須のオプションが指定されていない場合はヘルプを自動で表示させて動作を終了したい

# ハイフンを付けるオプションを必須にしてみた

以下の場合 `--example, -e` が指定されていない場合はヘルプを表示して処理を終了します。
単純にデフォルトで `None` を指定していて、それに変更が無い場合はexitしています。

```go
package main

import (
	"fmt"
	"os"

	"github.com/urfave/cli"
)

func Action(c *cli.Context) {
	app := App()
	if c.String("example") == "None" {
		app.Run(os.Args)
		os.Exit(1)
	}
	fmt.Println(c.String("example"))
}

func App() *cli.App {
	app := cli.NewApp()
	app.Name = "example"
	app.Usage = "ハイフン引数をRequiredにする例"
	app.Version = "0.0.1"
	app.Author = "sky_jokerxx"
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "example, e",
			Value: "None",
			Usage: "引数例",
		},
	}
	return app
}

func main() {
	app := App()
	app.Action = Action
	app.Run(os.Args)
}
```

実行してみます。

```bash
$ go run example.go
NAME:
   example - 引数をRequiredにする例

USAGE:
   example [global options] command [command options] [arguments...]

VERSION:
   0.0.1

AUTHOR:
   sky_jockerxx

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --example value, -e value  引数例 (default: "None")
   --help, -h                 show help
   --version, -v              print the version
exit status 1
```

引数を指定していないので、ヘルプが表示されました。
試しに引数を指定してみます。

```bash
$ go run example.go --example hoge
hoge
```

# ハイフンが無いオプションを必須にしてみた

以下では、ハイフン無しの引数が指定されていない場合はヘルプを表示して処理を終了します。

```go
package main

import (
	"fmt"
	"os"

	"github.com/urfave/cli"
)

func Action(c *cli.Context) {
	app := App()
	if c.Args().Get(0) == "" {
		help := []string{"", "--help"}
		app.Run(help)
		os.Exit(1)
	}
	fmt.Println(c.Args().Get(0))
}

func App() *cli.App {
	app := cli.NewApp()
	app.Name = "example2"
	app.Usage = "ハイフン無し引数をRequiredにする例"
	app.Version = "0.0.1"
	app.Author = "sky_jokerxx"
	return app
}

func main() {
	app := App()
	app.Action = Action
	app.Run(os.Args)
}
```

実行してみます。

```bash
$ go run example2.go
NAME:
   example2 - ハイフン無し引数をRequiredにする例

USAGE:
   example2 [global options] command [command options] [arguments...]

VERSION:
   0.0.1

AUTHOR:
   sky_jokerxx

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --help, -h     show help
   --version, -v  print the version
exit status 1
```

引数を指定していないので、ヘルプが表示されました。
試しに引数を指定してみます。

```bash
$ go run example2.go hoge
hoge
```

一応、やりたい動作にはなりました :-)
ただ、必須分だけ処理を書いていく必要がありますね :-(
pam_passwdqcを使ってパスワード要件を設定する

##■目的
VMware ESXi 6のデフォルトパスワード要件を知りたかったし、何なら要件をいじりたかったんです。ちなみにLinuxパッケージでも提供されている内容なので、利活用は可能です。

##■やりかた
以下ファイルが設定ファイルになります。
catして中身を確認してみましょう。

```/etc/pam.d/passwd
password requisite /lib/security/$ISA/pam_passwdqc.so retry=3
 min=disabled,disabled,disabled,7,7
```
スペースで区分けされていますが、意味は大体こんな感じです。
>password　
>　⇒パスワード要件の設定をやりまっせ
>requisite　
>　⇒後ろの文の指定通りやなかったら、この下の処理にはいきまへんで
>/lib/security/$ISA/pam_passwdqc.so　
>　⇒このモジュール使ってパスワードの要件を決めまっせ
>retry=3 min=disabled,disabled,disabled,7,7
>　⇒モジュールの引数になりまっせ


こんな調子になるので、後ろのモジュール引数となるところをいじればいいわけです。たとえば、こんな指定ができます。

>min=N0,N1,N2,N3,N4
>> N0:　1文字クラス(※)パスワードの場合の最低パスワード長。0指定で無制限、disableで1文字クラスパスワードを使用不可。
> N1:　2文字クラスパスワードの場合の最低パスワード長。0指定で無制限、disableで2文字クラスパスワードを使用不可。
> N2:　passphraseオプション有効時の最低パスワード長。0指定で無制限、disableで使用不可。
> N3:　3文字クラスパスワードの場合の最低パスワード長。0指定で無制限、disableで3文字クラスパスワードを使用不可。
> N4:　4文字クラスパスワードの場合の最低パスワード長。0指定で無制限、disableで4文字クラスパスワードを使用不可。
>
>> ※文字クラス…文字の種類のこと。大文字英語、小文字英語、数字、特殊文字の組み合わせが文字列にいくら入っているかにてN文字クラスと呼称する(2文字クラス-> TKG8282  4文字クラス-> Tkg8@8@ )。
>
>max=N
>>N:パスワードの最大長。
>
passphrase=N
>>N:パスワードに必要な文字クラス数を固定します。0で非固定になります。
>
>retry=N
>>N:パスワード変更に失敗した際のリトライ回数。
>
>enforce=N
>>N:強いパスワードの強制。noneを指定すればどのユーザに対しても強制しない。usersを指定すれば、root以外のユーザには強制する。everyoneだとすべてのユーザに強制する。

…ということで、デフォルト設定は1~2文字クラスのパスワードは受け付けず、3~4文字クラスの7文字以上の文字を受け付けます。なお、パスワード変更に失敗しても、3回は再変更の機会が与えられます。

よって、このモジュール箇所を適当なオプションにて記載すれば、思い通りのパスワード設定要件になります。その他オプションは「■参考」内のman等にて確認ください。

<font size="1" >＃なお、その他にもこのモジュールでは特定文字列(admin,root,administrator等)は受け付けてくれません。何が該当するかは公開されていないようですが…（たぶんパッケージの中身をちゃんと読めばわかると思うけど大変）</font>


##■もうちょい詳しく（ドツボ）
ここまでは、/etc/pam.d/passwd　のモジュールの引数だけの話をしましたが、じゃあ他のパラメータって何？と思ったことがドツボの始まりでした。

本当に簡単に書きますが、そもそもこの　/etc/pam.d/　で始まるディレクトリ配下のものは、ユーザー認証のため用意されたPAM（Pluggable Authentication Modules）と呼ばれるモジュールにて実現されています。

そのPAMモジュールでは、以下記述ルールがあり、それにこの　/etc/pam.d/passwd　も乗っかってるというわけです。

```/etc/pam.d/配下のファイルの記載例
module_interface  control_flag  module_name  module_arguments
```
今回はあくまでこの「module_arguments」部分のみを議論しましたが、例えば「module_name」を今回の　/lib/security/$ISA/pam_passwdqc.so　から変更することも出来、その際にはまた別のオプション等で別の使い方ができるようになります。

詳しくはwebで。
＃これ以上の説明は勘弁してください



##■参考
man pam_passwdqc
https://linux.die.net/man/8/pam_passwdqc
http://www.yosbits.com/opensonar/rest/man/freebsd/man/ja/man8/pam_passwdqc.8.html

[RHEL]10.2. PAM 設定ファイルについて
https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system-level_authentication_guide/pam_configuration_files

今週のお題 - PAM の設定を理解する
http://www.usupi.org/sysad/105.html
Tomcatだとweb.xml内でプレースホルダ(${...})が使えるのです

長年Tomcatを使っていますが、（ふとしたことから）`web.xml`の中でプレースホルダ(`${...}`)が使えることを初めて知りました。
（Tomcat固有の設定ファイル(`server.xml`や`context.xml`)で使えるのは知っていましたが・・・）

> **Important:**
>
> **念のため・・プレースホルダは、Servlet APIの仕様ではありませんので、勘違いしないように！！**

# とりあえずプレースホルダを使ってみる

ここでは、セッションタイムアウト時間をプレースホルダ化しておき、システムプロパティから実際の値を取得してみます。

```xml:web.xml
<session-config>
    <session-timeout>${session.timeout}</session-timeout>
    <!-- ... -->
</session-config>

```

Tomcat起動時のVM引数として「`-Dsession.timeout=1`」を指定すると、セッションタイムアウト時間が1分になります。

# でも・・・デフォルト値の指定はできない

Tomcatが提供しているデフォルト実装では、プレースホルダの中にデフォルト値（プロパティ未定義時に適用する値を指定できません。（例えば、Spring Frameworkが提供しているプレースホルダ機能では、「`${プロパティ名:デフォルト値}`」という表現ができます）
そのため、Tomcat提供のプレースホルダ機能を使う場合は、「`$CATALINA_BASE/conf/catalina.properties`」または「システムプロパティ(`-Dプロパティ名=プロパティ値`)」に該当プロパティを定義しておかないと期待通りの動作になりません。

# そんな時は・・・Tomcatのデフォルト実装をカスタマイズする？

Tomcat起動時のVM引数として「`-Dorg.apache.tomcat.util.digester.PROPERTY_SOURCE=org.apache.tomcat.util.IntrospectionUtils.PropertySourceインタフェースの実装クラス`」を指定すると、指定したクラスがTomcatのデフォルト実装より優先的に使われます。

ためしに・・・Spring Frameworkが提供しているプレースホルダ機能でサポートされている「`${プロパティ名:デフォルト値}`」という表現を可能にするクラスを作成してTomcatに適用してみます。（**実装はかなり乱暴なので真似しないでくださいw**）


```xml:pom.xml
<!-- 開発用のプロジェクトにorg.apache.tomcat.util.IntrospectionUtils.PropertySourceが格納されているアーティファクトを追加 -->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-core</artifactId>
    <version>8.5.20</version>
    <scope>provided</scope>
</dependency>
```

```java:IntrospectionUtils.PropertySourceの実装クラス
package com.example.tomcat.propertysource;

import org.apache.tomcat.util.IntrospectionUtils;

public class CustomTomcatPropertySource implements IntrospectionUtils.PropertySource {
    @Override
    public String getProperty(String key) {
        String[] keyElements = key.split(":");
        if (keyElements.length == 2) {
            return System.getProperty(keyElements[0].trim(), keyElements[1].trim());
        }
        return null; // nullを返却するとTomcatのデフォ実装が利用される
    }

}
```

`org.apache.tomcat.util.IntrospectionUtils.PropertySource`インタフェースの実装クラスを格納したjarファイルを「`$CATALINA_BASE/lib`」ディレクトリに格納し、Tomcat起動時のVM引数に「`-Dorg.apache.tomcat.util.digester.PROPERTY_SOURCE=com.example.tomcat.propertysource.CustomTomcatPropertySource`」を指定します。


```xml:web.xml
<session-config>
    <session-timeout>${session.timeout:1}</session-timeout>
    <!-- ... -->
</session-config>
```

こうすることで、Tomcat上でプレースホルダに対するデフォルト値を指定することができるようになります。

# ってか`web.xml`としてはスキーマ違反ですw

ここまで紹介しておいてナンですが・・・ `<session-timeout>`は`web.xml`のXSD上ではInteger型なので、IDE上ではスキーマ違反のエラーが出てしまうので、かなり微妙ですね。

# まとめ

（やっぱりw）基本的には`web.xml`上でプレースホルダ（環境依存値）を扱わないようにするのがよさそうです。
（仮に）使うとしても・・・スキーマ違反になるような使い方はよろしくないので、`init-param`系のパラメータ値での利用にとどめておいた方よい気がします。

# 参考サイト

* http://tomcat.apache.org/tomcat-8.5-doc/config/index.html
* http://tomcat.apache.org/tomcat-8.5-doc/config/systemprops.html#Property_replacements
エクセルで「比例配分計算」をやってみた

(参考)生活や実務に役立つ高精度計算サイト＞TがT2とT1の値の間にある場合のSの値
http://keisan.casio.jp/exec/user/1448598153
入力
T=5
T1=0,S1=0
T2=10,S2=10
出力
S=5

```
(エクセル)
A1=0,B1=0
A2=5,B2="=$B$1+($B$3-$B$1)/($A$3-$A$1)*(-$A$1+A2)"
A3=10,B3=10
[TypeScript] 型推論がうまくいったりいかなかったりする話


## TL, DR

型推論わからん

## 本題

こういうインターフェイスと関数があるとする

```ts
interface Named<T> {
    name: T;
}

function getName<T>(obj: Named<T>): T {
    return obj.name;
}
```

この関数をこう呼び出すと、Tはstringとして推論される。これは期待通り。

```ts
// nameの型はstringになる
const name = getName({ name: "John" });
```

では、`Named<T>` から派生した型を引数として取り、その型をそのまま戻り値に含めたい場合にはどうなるかというと、下のような形になるはず。

```ts
function getWithName<T, S extends Named<T>>(obj: S): { name: T, obj: S } {
    return { name: obj.name, obj };
}
```

これをこう呼び出した場合、期待としてはこの場合もTはstringとして推論されてほしい。

```ts
// ret は { name: string, obj: { name: string, age: number } } になってほしい
const ret = getWithName({ name: "John", age: 25 });
```

しかし、期待に反してTは {} として推論されてしまう。
`{ name: string, age: 50 }` は `{ name: string }` からの派生であると同時に `{ name: {} }` からの派生でもある訳なので、理屈としては理解できる。

それではということで、下のようにしてみると、期待通りに推論されるようになる。

```ts
// 引数の型を S から S & Named<T> に変更する
function getWithName2<T, S extends Named<T>>(obj: S & Named<T>): { name: T, obj: S } {
    return { name: obj.name, obj };
}
```

```ts
// ret2 は、期待通り { name: string, obj: { name: string, age: number } } と推論される
const ret2 = getWithName2({ name: "John", age: 25 });
```

理屈の通った、意図した挙動にも思えるし、たまたまそうなっているだけにも思える。
この挙動を今後も期待してよいものかどうか、それがわからない。

例えば、TypeScript 2.0のころは、 `type Foo = "foo" | "bar" | string` のようなUNION TYPEは、書いた通りのUNION TYPEとして扱われていたが、2.1で型の単純化処理が実装されたことによって、単に string として扱われるようになった。

同じように、 `T2 extends T1` なら `T2 & T1` は `T2` と同値だよね、みたいな話になったらこの挙動は壊れるんじゃないかという気がする。

どうなんだろう。
【ownCloud】GoogleDriveを外部ストレージにする方法。

#あいさつ
どうもはじめまして。
owncloudをonecloudをずっと思っていた私です。
響きにてるので間違えるよね仕方ないよね...

#注意とか
1. この方法は 筆記当時(version:10.0.2.1) の時のものです。
最新版でリダイレクトのリンクとかが変わるかもしれません。
2. 誤字脱字があると思います。各位脳内変換をお願いします。
3. 初投稿です。至らぬ点しかないと思います。お許しください。

#本題

はい。そんなことより、題名通り、ownCloudの機能にある外部ストレージ機能を使って、GoogleDriveを外部ストレージにする方法を紹介します。

「そんなの、[公式のドキュメント](https://doc.owncloud.org/server/latest/admin_manual/configuration/files/external_storage/google.html)見ればする話じゃん。」
はい、そうです。それを見れば解決する...と思って実行してみたんですが、400エラー(リダイレクトエラー)が出ます。
原因は、リダイレクト先が間違っていること。
しかし、ドキュメント通りにしてもエラーが出る...

#方法
まず、ownCloudをサーバにインストールします。
そこら辺はすべて割愛します。
調べれば日本語で紹介されているサイトが見つかるかと思います。

次に、設定から 外部ストレージ を開きます。
開くと、上に「外部ストレージを有効化」にチェックを入れる。

これで、外部ストレージの追加ができます。

フォルダ名は何でもいいです。右のプルタブから「Google Drive」を選びます。

###クライアントID,シークレットコードを手に入れる
クライアントID,シークレットキーが必要になるので、[https://console.developers.google.com/](https://console.developers.google.com/)からプロジェクトを作ります。

プロジェクト名は何でもいいです。
作ったら 左のライブラリから Drive API を探してきて有効化します。

次に 左側にある認証情報 をクリックします。

認証情報の作成から 「OAuth クライアント ID」を選びます。
すると、「OAuth クライアント ID を作成するには、まず同意画面でサービス名を設定する必要があります。」と怒られるので、同意画面の作成をクリックします。

「ユーザーに表示するサービス名」の項目を適当に埋めて、保存します。

これでクライアントIDが作れるようになります。

クライアントIDの作成画面に行ったら「アプリケーションの種類」を「ウェブ アプリケーション」にします。

名前,承認済みの JavaScript 生成元,承認済みのリダイレクト URIは次のようにします。
*名前:何でもOK
*承認済みの JavaScript 生成元:サイトのリンク(例えば https://google.co.jp )
*承認済みのリダイレクト URI:

```
https://<自分のサイトのリンク>/owncloud/index.php/settings/admin
https://<自分のサイトのリンク>/owncloud/index.php/settings/admin?sectionid=storage
```

若しくは

```
https://<自分のサイトのリンク>/index.php/settings/admin
https://<自分のサイトのリンク>/index.php/settings/admin?sectionid=storage
```

とりあえず、インストールした環境に合わせてください。

公式ドキュメントでは
「
https://example.com/owncloud/index.php/settings/personal
https://example.com/owncloud/index.php/settings/admin
」
になっていますが、間違いです。これに気づくのに数日かかりました。

これで、下の作成をクリックしてクライアントID,シークレットコードをコピーしてインストールしたowncloud側で入力して アクセス許可 をすればOKです。

この件で困っていた人の役に立てたのなら幸いです。

#リンク
- [Cannot configure GoogleDrive as external Storage](https://github.com/owncloud/core/issues/27456)

これのおかげでストレージ化できた。

#更新
9/13 : リダイレクトのリンクの間違いの修正 / リダイレクトリンクの例を追加
Unityで良くあるミス（自戒）（泣）


## デバッグなどで雑にpublicな配列を作ってしまうケース

```hoge.cs

public int[] hogehogeArr = new int[] {15,20,30,40,42,80,120,200,800,1200,2000,8000,24000,843201,1143201,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

```

こういうのをほったらかして、色々配列を操作していると、
hogehogeArr[i]とかで参照する際、あるはずの値がとなれくて、エラーになる。

public で配列にしていると、インスペクタ上で値が保存されて、
配列数までおかしくなるので注意（泣）。

ちゃんと private int[]にしよ。。

あと、インスペクタに表示しないように下記も入れて置くといいです。汗

```hoge.cs
[HideInInspecter]
public int[] hogehogeArr =　//〜省略
```
※@Rwf-9DH3 さんご指摘ありがとうございます！m( _  _ )m

今日だけで２回ハマった汗



## Findで子を削除する場合

```hoge.cs

if (obj.transform.Find("ScissorsObj")) //対象があるか存在確認
{
    GameObject hasamiMarkObj = obj.transform.Find("ScissorsObj").gameObject;
    if (hasamiMarkObj)
    {
        Destroy(hasamiMarkObj);
    }
}


```

ポイントは```if (obj.transform.Find("ScissorsObj"))```
でチェックする必要がある。

あと、Instantiateとかで生成したオブジェクトは、デフォルトで名前の後ろに**(Clone)**と付いているので、
生成後リネームするの忘れないように。。

## マテリアルの色をスクリプトで変更してもどせなくなってしまう。。

```hoge.cs

if(instanceLeaf.GetComponent<Renderer>().sharedMaterial.HasProperty("_Color")){
    // 注意、エディタ上の色情報も変換されるのでもとに戻せない
    instanceLeaf.GetComponent<Renderer>().sharedMaterial.color = new Color(1f,1f,1f);
}
```

事前に元の色をとっておく。。

```hoge.cs
originalColor = GetComponent<Renderer>().sharedMaterial.color;
```
CFNとvue-cliでさくっとS3にSPAをホスティングするためのメモ

# S3の準備

CFNでS3のバケットを作る

~~~vue-s3.yaml
Resources:
  S3WebSiteSample:
    Type: "AWS::S3::Bucket"
    DependsOn: S3WebSiteSampleLog
    Properties: 
      BucketName: vue-website-sample
      LoggingConfiguration:
        DestinationBucketName:
          Ref: S3WebSiteSampleLog
        LogFilePrefix: logs/
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html

  S3WebSiteSampleLog:
    Type: "AWS::S3::Bucket"
    Properties: 
      AccessControl: LogDeliveryWrite
      BucketName: vue-website-sample-log

  S3WebSiteSampleBucketPolicy: 
    Type: "AWS::S3::BucketPolicy"
    Properties: 
      Bucket: 
        Ref: S3WebSiteSample
      PolicyDocument: 
        Statement: 
          - 
            Sid: "PublicReadForGetBucketObjects"
            Action: 
              - "s3:GetObject"
            Effect: "Allow"
            Resource: 
              Fn::Join: 
                - ""
                - 
                  - "arn:aws:s3:::"
                  - 
                    Ref: S3WebSiteSample
                  - "/*"
            Principal: "*"

~~~

`create-stack`してバケットを作る

~~~
$ aws cloudformation create-stack --stack-name vue-s3-website --template-body file://./vue-s3.yaml
~~~

# vue-cli

`vue-cli`でテンプレートプロジェクトを作成する。

~~~bash
$ npm install -g vue-cli 
$ vue init webpack my-project 
$ cd my-project/
$ npm run build 
~~~

S3へ配置

~~~
$ aws s3 sync dist/ s3://vue-website-sample/
~~~

# 確認

はいっ！

<img width="544" alt="スクリーンショット 2017-09-12 23.50.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/32184/fac73335-c942-db33-cdd7-f9a6fe8695fe.png">
for文の2重構造

[スッキリわかるJava入門](https://book.impress.co.jp/books/1113101090)にてJavaの勉強中です。
その中で出てきた項目についての備忘録。

## for文の中にfor文が入っている場合の処理

```java:Main.java
public class Main {

	public static void main(String[] args) {

		for (int i = 1; i < 4; i++) {
          //↓中の繰り返しが終わると「外側ループi周目終わり」を出力する処理に移行し、外側の繰り返しが1つ進む
			for(int j = 1; j < 4; j++) {
				System.out.println("外側ループ" + i + "周目" + "内側ループ" + j + "周目"); 
			}

			System.out.println("外側ループ" + i + "周目終わり"); 
		}
	}

}
```

処理結果は以下の通り。

```
外側ループ1周目内側ループ1周目
外側ループ1周目内側ループ2周目
外側ループ1周目内側ループ3周目
外側ループ1周目終わり
外側ループ2周目内側ループ1周目
外側ループ2周目内側ループ2周目
外側ループ2周目内側ループ3周目
外側ループ2周目終わり
外側ループ3周目内側ループ1周目
外側ループ3周目内側ループ2周目
外側ループ3周目内側ループ3周目
外側ループ3周目終わり
```

処理順としては、
1. 外側ループ開始
2. 内側ループを設定した回数繰り返す
3. 内側の処理が終わる
4. 内側の処理を抜け、最後の行の出力を行う。外側ループの処理が終わる。１に戻る
5. １〜４を外側ループで設定した回数繰り返す


落ち着いて考えるとどうってこと無いんですが、初見で「！？」となったのでメモ。
WKWebViewのストレージに関するメモ


### iOS 8

- WKWebViewが導入される。
- キャッシュは謎の場所に用意される。ユーザーは制御できない。
- ローカルストレージはない。

### iOS 9

- WKWebsiteDataStoreが導入される。
- ローカルストレージやオフラインキャッシュに対応し、キャッシュのクリアもできるようになった。
- WKWebsiteDataStoreはNSURLCacheを利用しており、最大容量はNSURLCache.sharedURLCacheの最大容量に従う。

### iOS 10

- WKWebsiteDataStoreが全面的に書き直され、NSURLCacheを利用しないようになった。
- 副作用として、最大容量の設定が不可能になった。
- WKWebViewは各アプリに所属するので、アプリの使用容量が数GBになることも。

### iOS 11

- WKWebView自体に大きな変化はないが、iOSの仕様変更として、キャッシュがアプリの使用容量に含まれなくなった。(betaの挙動のため、正式版でそのままになるのかどうかは不明)
- アプリからcookieの読み書きができるようになった。
あなたのansibleとserverspecの併用は間違っている！

# あなたの間違った使い方

## そもそも併用する動機が間違っている
「ansibleのコードが正しいか不安だから、serverspecでチェックする」という動機で併用する方がいますが、間違いです。
serverspecのコードが絶対に正しいと言えない限り、チェックすることは不可能です。

## ansibleとserverspecで同じ結果をチェックする
ansibleで、

```yaml:
- name: restart hogehoge.service
  systemd:
    name: hogehoge.service
    state: restarted
    daemon_reload: yes
    enabled: yes
  become: yes
```

と書いておいて、serverspecで、

```rb
describe process('hogehoge') do
  it { should be_running }
end
```
と**だけ**書くのも間違いです。

systemdモジュールはべき等性が保証されているため、serverspecでプロセス起動の有無をチェックすることは無意味です。
TDDの「不安をテストする」という金言を知ったなら、べき等の意味もおさえましょう。

もし、どうしてもserverspecでチェックするのであれば、プロセス起動以外にサービスが参照する設定ファイルの値を確認するべきです。
ただし、それらすべてのチェック項目はansibleで確認できてしまうことを覚えておいて下さい。
Gitの使い方メモ

##Gitをインストール
Terminalを開いて以下のコマンドを入力
`$ brew install git`

##バージョン管理したいフォルダにて
初期設定
`$ git init`
`$ git config --global user.name <ユーザー名>`
`$ git config --global user.email <メールアドレス>`

あとは
`$ git add .`
`$ git commit`
`$ git push`

herokuにプッシュする際は
`$ heroku login`
でログイン後、上記手順を通し最後に
`$ git push heroku branch_name`

変更点
`$ git diff`
Powershellコンソールエラーを非表示にする方法

PowerShell でスクリプトを書いていてエラーをコンソールに表示しない方法を
色々調べたが、中々解決できなかったので自分向けの備忘録も兼ねて投稿

## やりたいこと
- PowerShell でエラーをコンソールに表示しないようにする
- この方法を使用しても結果は $error に格納されている

## 作業
- コンソールにエラーを表示させない場合

```
PS> $ErrorActionPreference = "silentlycontinue"
```

- エラーを表示させるように戻す場合

```
PS> $ErrorActionPreference = "continue"
```

## 使用例
```
PS C:\Users\Administrator> ls -l
Get-ChildItem : パラメーター 'LiteralPath' の引数が指定されていません。型 'System.String[]' のパラメーターを指定し、再試行してください。
発生場所 行:1 文字:4
+ ls -l
+    ~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem]、ParameterBindingException
    + FullyQualifiedErrorId : MissingArgument,Microsoft.PowerShell.Commands.GetChildItemCommand

PS C:\Users\Administrator> $ErrorActionPreference = "silentlycontinue"
PS C:\Users\Administrator> ls -l
PS C:\Users\Administrator> $ErrorActionPreference = "continue"
PS C:\Users\Administrator> ls -l
Get-ChildItem : パラメーター 'LiteralPath' の引数が指定されていません。型 'System.String[]' のパラメーターを指定し、再試行してください。
発生場所 行:1 文字:4
+ ls -l
+    ~~
    + CategoryInfo          : InvalidArgument: (:) [Get-ChildItem]、ParameterBindingException
    + FullyQualifiedErrorId : MissingArgument,Microsoft.PowerShell.Commands.GetChildItemCommand
```

## 個人的感想
- ps1 のスクリプト内の処理でも使用できるので便利!!
- $変数 = command 2>&1 で変数に標準出力/標準エラー出力を格納したかったがコンソールに表示されてしまったので最後の手段として使用した

##  参考URL
- Powershell 7
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7#erroractionpreference

- Powershell 6
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-6#erroractionpreference

- Powershell 5.1
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-5.1#erroractionpreference

- Powershell 5.0
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-5.0#erroractionpreference

- Powershell 4.0
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-4.0#erroractionpreference

- Powershell 3.0
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-3.0#erroractionpreference
reactでfirebaseのrealtime databaseの状態をHOCで取得する

# 経緯
reactとfirebaseのrealtime database使って遊んでたら、reduxいらねーな、って気分になってきた。
これmeteorでも感じたやつだ。

# こんな気分で書ける
ライブラリでよくみるwithのやーつ。
connect的な名前の方がいいかな。

```js
const HogeContainer = withUserData(({ user, userData }) => (
  <div>
    {/* 何か */}
  </div>
))
```

# 何が幸せ？
`functional component` で書きたい。
class って書きたくない病。

# どうやるのか
authの変更とdatabaseの変更をlistenしてstateに落とすだけのクラスを作ってHOCで返す。

```js
const withUser = (WrappedComponent) => {
  return class UserObserver extends Component {
    state = {
      user: 'not_feached',
      owner: 'not_feached',
    }
    removeAuthListener = null
    removeOwnerListener = null

    componentDidMount() {
      this.removeAuthListener = firebase.auth().onAuthStateChanged(user => {
        this.setState({ ...this.state, user })

        if (!user) return
        this.removeOwnerListener = firebase.database().ref(`users/${user.uid}`).on('value', (snapshot) => {
          this.setState({ ...this.state, userData: snapshot.val() })
        })
      })
    }
    componentWillUnmount () {
      this.removeAuthListener && this.removeAuthListener()
      this.removeOwnerListener && this.removeOwnerListener()
    }

    render() {
      const { user, owner } = this.state

      return <WrappedComponent {...this.props} {...{ user, owner }} />
    }
  }
}
export default withUser
```

実際は、
Userはほとんどの画面で使うだろうから、RouterよりRoot側で観測させれば、別にHOCである必要もないのだけど、
他のnodeの変更を監視するのに使うと、使いたいときに `withHoge` を挟むだけで値が手に入るから楽ちん。