OmniAICreator/Qiita-1.07M huggingface dataset:
【gnuplot小ワザまとめ】読み込んだファイルのプロパティを取得

#概要

測定等で得たデータをgnuplotで描画する上で便利だと思った`stats`についてまとめました
前回の記事↓
[【gnuplot小ワザまとめ】グラフを描画する際の位置指定方法(margin)](https://qiita.com/_shin_/items/38fc8dfd7dbc4226e64b)

#本題
読み込んだデータファイルをgnuplotで描画するときに、データの最大/最小に合わせて軸の範囲を自動的に変えて描画したいと思った(手動はめんどいので)

デフォルトの設定でもある程度自動で合わせてくれるがコレジャナイ感がある時がある

そんなときは`stats`コマンドでファイルを読み込むと最大値や最小値、平均、総データ数、標準偏差等を表示してくれる

<br/>
例えばこんなデータの場合、

```
gnuplot> pl "data1.dat" u 1:2 w lp
```

<img width="600" alt="data1_plt.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513034/84aafa79-1c6a-f576-5abf-e6fb2acb45fa.png">

僕の環境では最大値が軸の上限ギリギリになってしまった

手動で`set range[-2:6]`とやっても良いが、
まず、`stats`コマンドでファイルの詳細を取得すると...

```
gnuplot> stats "data1.dat" u 1:2

* FILE: 
  Records:           100  #総データ数
  Out of range:        0
  Invalid:             0
  Column headers:      0
  Blank:               0
  Data Blocks:         1

* COLUMNS:
  Mean:               0.0000  #1列目の平均  0.8180  #2列目の平均
  Std Dev:            5.8315              1.7579  
  Sample StdDev:      5.8609              1.7668
  Skewness:           0.0000              1.1884
  Kurtosis:           1.7998              3.2259
  Avg Dev:            5.0505              1.3627
  Sum:           1.24345e-14             81.8029
  Sum Sq.:         3400.6742            375.9459

  Mean Err.:          0.5832              0.1758
  Std Dev Err.:       0.4124              0.1243
  Skewness Err.:      0.2449              0.2449
  Kurtosis Err.:      0.4899              0.4899

  Minimum:          -10.0000 [  0]       -1.0847 [ 27]  #最小[何列目]
  Maximum:           10.0000 [ 99]        4.9915 [ 50]  #最大[何列目]
  Quartile:          -5.0505             -0.2859
  Median:             0.0000              0.3412
  Quartile:           5.0505              1.1445

  Linear Model:       y = -3.905e-18 x + 0.818
  Slope:              -3.905e-18 +- 0.03045
  Intercept:          0.818 +- 0.1776
  Correlation:        r = -1.295e-17
  Sum xy:             -3.109e-15
```
<br/>
取得されたプロパティはそれぞれ以下の変数に格納されている

|変数|説明|
|:-:|:-:|
| STATS_min_x | x軸の最小値 |
| STATS_max_x | x軸の最大値 |
| STATS_min_y | y軸の最小値 |
| STATS_max_x | y軸の最大値 |
| STATS_mean_x | x軸の平均 |
| STATS_mean_y | y軸の平均 |

他にも変数があるが、詳細はこちらを参考に
http://www.ss.scphys.kyoto-u.ac.jp/person/yonezawa/contents/program/gnuplot/stats.html

例えばこんな感じに使うと...

```
gnuplot> set yrange[STATS_min_y -1:STATS_max_y +1]  
gnuplot> pl "data1.dat" u 1:2 w lp
```

<img width="600" alt="data1_plt2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513034/eb7d3e49-f8c2-81b2-f67e-0c12c7f25790.png">

扱うデータのスケールにもよるが、レンジの指定の部分をもう少し複雑にすればより自動的にキレイな描画ができるかもしれない

#最後に

今回は最大/最小について取り上げたが、そのほかのパラメータも取得することができるので、gnuplotだけでもっと複雑な操作ができるかもしれない

#参考にしたサイト

http://www.ss.scphys.kyoto-u.ac.jp/person/yonezawa/contents/program/gnuplot/stats.html

有用な情報ありがとうございました
xonshの導入と使い方のメモ

# xonshとは
https://xon.sh/

xonsh(コンシュって呼んでる)はshellの一種でpythonをshell上で実行し、ファイル操作などを行うことができます。
クロスプラットフォームで駆動し、使い心地としては、jupyterのようなpythonのREPLに近いかたちでshellの操作が行なえます。
pythonが実行できる関係上、これまでのshellの様に無理やり1行で書いたりする必要がなく、変数などを用いての操作も可能です。

# 導入手順
公式がそれぞれのOSのインストールガイドを用意してくれてるので、それに従いましょう。

[linux](https://xon.sh/linux.html)
[mac](https://xon.sh/osx.html)
[windows](https://xon.sh/windows.html)

installがおわったら、terminal上で`xonsh`と打って実行できます。

# さっくり使い方

## 使い方編

python 文法は特になにも指定せずに書けます。

```python
print ("hello") # helloと表示される
```

enterと押すと自動的に改行されるので、複数行で書ける。

```python
for num range(1,10):
    print(num) # 1~ 9 の数字が順番に改行されて表示される。
```

xonshはshellの一種なので、コマンドを実行してそれを受け取って実行したりも出来ます。
以下は、現在の階層のファイル一覧を文字列でうけとって、一文字ずつ出力していきます。

```python
for file_name in $(ls):
    print(file_name)
```



## 設定編
自分のhome直下に `.xonshrc` というファイルを作成して、
そこにエイリアスや、起動時の処理を書けます。

```bash
aliases["ga"] = "git add"
aliases["gc"] = "git commit"
aliases["gp"] = "git push"
aliases["gpu"] = "git pull"
aliases["gcl"] = "git clone"
aliases["gb"] = "git branch"
aliases["gch"] = "git checkout"
```

一部ですが、僕は雑にgitのエイリアスを設定しています。


# 注意点
nvmとか、anaconda みたいな感じで、 .bashrcに処理が書かれるものは注意してください。
僕は .bashrcから xonshコマンドを実行して、ターミナルを開いたときにxonshを使えるようにしてました。

ただ、 anacondaなどのbashrcに処理を書き込むものをインストールした場合、 pathが指定される前に、xonshが実行されて、
おかしなことになったりします。

なので、インストールしたのに、xonsh上ではコマンドが打てなくて、 bash上では打てるということがある場合は、bashrcの中を確認してみましょう。


# 終わりに

よき、xonshライフを
電車のLCDを再現したアプリ「TrainLCD」をリリースしました

![FeatureImage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244632/67a92a5b-c338-1d46-bb63-a115bbfc1cf1.png)
~~今Play Storeで審査中なので「予定」。そのうちiOSでも使えるようにしてApp Storeにも審査出します。~~
Expo(React Native)でTrainLCDというアプリを作りました。
TrainLCDの宣伝だけだとあれなのでExpoはいいぞということを含めて書いていきます。
## TrainLCDとは？
![FireShot Capture 506 - TrainLCD - localhost.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244632/a81f6cc7-2b77-0e86-54c0-a3b06ecc705f.png)
さっき書いたとおり電車のLCDを再現したWeb・ネイティブアプリです。
Webの方は[https://trainlcd.tinykitten.me](https://trainlcd.tinykitten.me)です。
ただWebのほうじゃなくてネイティブアプリの方にシフトしていきたいなと思ってます。その方が多分リーチできるので。
ちなみにWebのほうはAngularで作りました。
## どうやって作ったのか？
[Expo](https://expo.io/)というReact Nativeを用いたプラットフォームを使いました。
[Expo](https://expo.io/)は、**審査不要で公開し、QRコードを専用アプリで読み取るだけでアプリを実行できるものです。**
控えめに言って最高。
## なぜアプリストアに申請したのか？
別にアプリストアに申請しないならWeb版で十分です。
ただ、この知名度の低いアプリをアプリストアに出せばもしかしたらもっとリーチするかもしれないという安直な考えです。
## どのように実現したのか？
そんな大層なことはしてないですが、位置情報をStationAPIというElixir+Phoenixで作ったGraphQL APIに最初の駅・路線情報を取るときに送りつけて（もちろん記録はしていません）、一度情報取ったら端末上で計算して表示してるだけです。
電池持ちとか地下鉄での動作はどうしようか考えてます。地下鉄対応は自分ひとりでなんとかなる問題じゃない気がする。
## さいごに
こんなクソ記事なのでそのうち炎上してボロクソ言われて限定公開に勝手にされるかもしれませんが。
Play Storeの審査が通ったら多分追記します。
## リポジトリ
[TrainLCDExpo](https://github.com/TinyKitten/TrainLCDExpo)
[StationAPI](https://github.com/TinyKitten/StationAPI)

## リンク
[Expo](https://expo.io/)

## 追記: 2019/11/06 14:20
[iPhone版](https://apps.apple.com/jp/app/trainlcd/id1486355943)審査通りました。~~Androidはまだ。~~

## 追記: 2019/11/08 12:42
[Android版](https://play.google.com/store/apps/details?id=me.tinykitten.trainlcd)も無事審査通過しました！
【UiPath】「繰り返しをブレーク」は「繰り返し(コレクションの各要素)」でのみ使用できる

公式ドキュメントにも記載されているし、「繰り返し(後判定)」などにブレークを置くとエラーになるので分かりやすい。

[[繰り返しをブレーク (Break)] アクティビティ](https://docs.uipath.com/studio/lang-ja/docs/the-break-activity)
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/67910f32-3ad6-c41f-0d82-f8f6924adcd7.png)

しかし、例えば以下のように繰り返しを入れ子にしても、エラーにならない。

* 繰り返し(コレクションの各要素)
	* 繰り返し(後判定)
		* ブレーク

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/47604068-dbc5-d518-d029-3670be0dac09.png)


こうした場合、内側の繰り返しも外側の繰り返しも一気にブレークされるので注意。
一般的なプログラム言語にはこういった仕様がない(はず)ので、プログラミング時と同じ感覚でブレークを使ってしまうと、思わぬところにはまってしまう…。
[TypeScript]Objectのプロパティチェックと自動型生成

※201911/06追記
npmに今回の内容をパッケージ化した[hasproperty-ts](https://www.npmjs.com/package/hasproperty-ts)を登録しました

# [TypeScript]Objectのプロパティチェックと自動型生成

※同じ記事を[こちら](https://ttis.croud.jp/?uuid=192031da-b226-41cf-a0f3-acd25b0af079)にも書いています

　TypeScriptでオブジェクトにプロパティが存在するかどうかを確認する場合には、inキーワードが使用できます。しかしinでメンバを判別しても前提の型情報が存在しないと、判別したプロパティを使用することが出来ません。これを解決する方法を紹介します。

## 1．エラーが出る例

```ts
function Test01(x:unknown){
  if(x instanceof Object && "foo" in x){
    console.log(x.foo); //Error
    console.log((<{foo:unknown}>x).foo); //OKだけど不便
  }
}
```

　xの型情報をunknownにした状態でfooがプロパティとして判定するためには、まずxのインスタンスがObjectかどうか判別する必要があります。Objectならばinキーワードを利用して、fooプロパティがあるかどうかを確認していきます。

　しかしメンバにxがあることが分かっても、ifブロックの中でのxの型はneverとされてしまい、fooを使用するとエラーとなってしまいます。fooがあると分かっていても、いったんオブジェクト側をキャストしないとメンバを使用することは出来ません。これはひじょうに不便な状態です。

## 2．そもそものinの用途

　そもそもTypeScriptでinを有効に使うためには、事前に前提となる型情報を与えておく必要があります。unionのように複数の候補の中から目的の型を選べるようにしておかなければなりません。

```ts
function Test02(x: { foo1: unknown,bar1:unknown } | { foo2: unknown,bar2:unknown }) {
  if ("foo1" in x) {
    console.log(x.foo1); //OK
    console.log(x.bar1); //OK
    console.log(x.foo2); //Error
    console.log(x.bar2); //Error
  }
}
```

## 3．プロパティチェックを使いやすくする

　このままでは面倒なので、プロパティのチェックと型の生成を同時に行うfunctionを作ってみます。

```ts
function hasProperty<K extends string>(
  x: unknown,
  name: K
): x is { [M in K]: unknown } {
  return x instanceof Object && name in x;
}

function Test03(x: unknown) {
  if (hasProperty(x, "foo")) {
    console.log(x.foo); //キャスト無しでFooが使える
  }
}
```

　hasPropertyが真を返すと、判定したプロパティを持つオブジェクトとして型が決定します。これで毎回手動でオブジェクト側の型をキャストする必要がなくなります。

## 4．複数同時にチェックできるようにする
　プロパティをまとめてチェック出来るように、nameを可変引数にします

```ts
function hasProperty2<K extends string>(
  x: unknown,
  ...name: K[]
): x is { [M in K]: unknown } {
  return (
    x instanceof Object && name.every(prop => prop in x)
  );
}

function Test04(x: unknown) {
  if (hasProperty2(x, "foo", "bar")) {
    console.log(x.foo); //Fooが使える
    console.log(x.bar); //Barが使える
  }
}
```

　これでオブジェクト側に余計なキャストをイチイチ書かなくとも、直接プロパティを扱えるようになりました。

## 5．まとめ

　プロパティの存在チェックと型の生成は標準でサポートされていても良さそうな気がしますが、無いなら自分で作れるのがTypeScriptの良いところです。
タッチディスプレイ gen4-uLCD-35DT > シリアルスレーブ動作 > タッチ検知の手順

```txt:動作環境
Ubuntu 18.04 LTS 
display module: gen4-uLCD-35DT 
  Workshop 4 IDE v4.5.0.17 (on Windows 10 Pro)
MCU: STM32F446 Nuclero-64
  STM32CubeIDE v1.0.1 (on Ubuntu 18.04 LTS)
```

## タッチ検知の手順

シリアルスレーブ(SPE Load)にした時にタッチ検知する手順をRS232Cシリアル通信ソフトで確認した。

下記のようだ。

1. TouchDetect()にて領域設定
2. TouchSet(mode=0)
3. TouchGet(mode=0)

## TouchGetの応答

### 押下して離す

1. 1 (PRESS)
2. 2 (RELEASE)
3. 0 (INVALID/NOTOUCH)


### 押下したまま

1. 1 (PRESS)
2. 3 (MOVING)
3. 離すまで手順2の状態


## 補足

Arduinoの実装例ではloop()においてTouchDetect()から処理をしていた。
この場合、loop()を何度も実行されるため、TouchDetect()からの処理が繰り返される。

一方で、RS232Cシリアル通信ソフトで確認したところでは、TouchGet()だけを繰り返し使えばいいと思った。
ディスプレイの設定初期化なども考慮した実装なのかもしれない。
Cloud ComposerでAirflow Workerに入る



Cloud ComposerのAirflow worker・schedulerは[GKE上で動いています](https://cloud.google.com/composer/docs/concepts/overview?hl=ja#architecture)。
ので、kubectlコマンドを使うことでAirflow Workerに入ることも出来ます。

# 対象
* Cloud Composer使っている人
* GKE/Kubernatesようわからん人


# 例


```
# ComposerのKubernatesクラスタの確認。わかっていれば不要
gcloud container clusters list
# (CLUSTER)・（LOCATION）は↑で調べたComposerのクラスタ、そのゾーン
gcloud container clusters get-credentials (CLUSTER) --zone=(LOCATION)
# podを見てみる
kubectl get pods --all-namespaces
# workerに入ってみる
# (NAMESPACE)はAirflow Workerのあるネームスペース、(PODNAME)は入りたいポッドの名前
kubectl exec --namespace=(NAMESPACE) (PODNAME) -c airflow-worker -it bash

```

# 何が嬉しいの
Airflowでは[Airlfow CLI](https://airflow.apache.org/cli.html#Sub-commands)を使うことでDAGやタスクインスタンスの状況を確認出来ます。
Composerでも[gcloud composerコマンドでAirflow CLI使うこと](https://cloud.google.com/composer/docs/how-to/accessing/airflow-cli?hl=en)が出来ますが、使えないサブコマンドが一部あります（※）。

Airflow Workerに入ってairflowコマンドを使うことで、Airflow CLIのサブコマンドを大体使うことが出来ます（※※）


※ 制限されているコマンドはバージョンで違います。また日本語のドキュメントの方には情報ないです
※※ resetdbとか使えない、使っても意味がないサブコマンドもあります
RSpec覚書

初めまして。
Rubyを始めて2年目、覚えること沢山あるので、忘れないようにメモです。
初心者的なこともあると思いますが、備忘録です。

### RSpecの評価は内側が優先
```ruby:
describe 'ダミーテスト' do
 before do
  allow(dummy_mock).to receive('2番手')
 end
 context '正常系' do
  before do
     allow(dummy_mock).to receive('1番手')
  end
 end
end
```
同じdummy_mockがあったら、内側、すなわち「1番手」の方が適用される。
これを使えば、「このテストケースの時だけ、モックは特別な値を返して欲しい」というのが実現できる。

### RSpecの実行順に注意
```ruby:失敗するパターン
describe 'ダミーテスト' do
 let(:request_params){{dummy: 'だみー'}}
 before do
  expect(request_params['dummy']).to ('ダミー')
 end
 context '正常系' do
  before do
     request_params['dummy'] = 'ダミー'
  end
 end
end
```
内側から評価されていくので、正常系のcontextの中のbefore実行後、describeの中のbeforeを実行と見えるが、どっこい。
1.expectを実行
2.変数「request_params」を探すとdescribeの直下にいるので、これを評価
なので、上記コードは失敗する。

```ruby:これは成功する
describe 'ダミーテスト' do
 let(:request_params){{dummy: 'だみー'}}
 context '正常系' do
  before do
     request_params['dummy'] = 'ダミー'
     expect(request_params['dummy']).to ('ダミー')
  end
 end
end
```
こうすれば、request_params['dummy']には「ダミー」が入り、成功する。

### contextは入れ子にできる
```ruby:
describe 'テスト' do
 context '正常系：' do
  context 'ユーザーがテスト会員の場合' do
  end
  context 'ユーザーがシステム管理者の場合' do
  end
 end
 context '異常系：' do
  context 'セッションが正しくない場合' do
  end
 end
end
```
テストケースを整理するのに便利。
SwiftのKVOでenumを監視できない問題と回避策

# 問題の概要

SwiftのKVOは便利ですが、Objective-Cランタイムによる動的ディスパッチを前提としているために、以下のような制約があります。

- 監視するクラスも監視されるクラスもNSObjectを継承する必要がある → structでは使えない
- 監視される変数はNSObjectと互換性のある型である必要がある → **enumなどでは使えない**

（参考リンク）
[Using Key-Value Observing in Swift - Apple Developer Documentation](https://developer.apple.com/documentation/swift/cocoa_design_patterns/using_key-value_observing_in_swift)
[KVO(Key-Value Observing) - Swiftで遊ぼう！](http://yataiblue.hatenablog.com/entry/2015/12/17/000000)
[Objective-C／データ型 - iPhoneアプリ開発の虎の巻](https://iphone-tora.sakura.ne.jp/kihon_datatype.html)

とはいえ、例えば、
『WebAPIの呼び出しステータス「読込中/完了/失敗」をKVOで監視したい』
とか、enumを監視したいケースは少なからずあります…

そして、実際にenumの監視をやってみると以下のような挙動になります。

# NGコード例

私はSwift 5.1で確認しましたが、5.0以前でも同様と思われます。

```swift:Playground
@objc enum Enum: Int {
    case A = 0
    case B
}
class Foo: NSObject {
    @objc dynamic var bar = Enum.A
}

let foo = Foo()
let observer = foo.observe(\.bar, options: [.new, .old]) { obj, change in
    print("old: \(change.oldValue) - new: \(change.newValue)")
    print("obj.bar.rawValue: \(obj.bar.rawValue)")
}
foo.bar = Enum.B
// old: nil - new: nil
// obj.bar.rawValue: 1
```

- `observe`のコールバック・クロージャーは実行されます。
- ただし、**`oldValue`および`newValue`を取得できず、nilになってしまいます。**
- 監視対象オブジェクトのプロパティ値は期待通りに取得できます。
- Objective-Cランタイムのエラーや警告は発生しません。

冒頭の制約を踏まえると仕様なのかも知れませんが、挙動はバグっぽいですね…

この件はSwift.orgにissueがあがっています。
https://bugs.swift.org/browse/SR-5872
※2019/11/04現在、プルリクは出ているようですがOPENの状態です。

# 回避コード例

enumを直接監視させずに、enumのrawValue（Int）を別途プロパティに定義して、そちらを監視させる方法が良さそうです。

```swift:Playground
enum Enum: Int {
    case A = 0
    case B
}
class Foo: NSObject {
    @objc dynamic var barRaw = Enum.A.rawValue
    var bar: Enum = Enum.A {
        didSet {
            barRaw = bar.rawValue
        }
    }
}

let foo = Foo()
let observer = foo.observe(\.barRaw, options: [.new, .old]) { obj, change in
    print("old: \(change.oldValue!) - new: \(change.newValue!)")
    print("obj.bar.rawValue: \(obj.bar.rawValue)")
}
foo.bar = Enum.B
// old: 0 - new: 1
// obj.bar.rawValue: 1
```

冗長ではありますが、期待通りの値を取得できました。
plunkerでtensorflow.js その17

#概要

plunkerでtensorflow.jsやってみた。
lstm使ってみた。
sin波、学習させてみた。

#サンプルコード


```

tf.setBackend('cpu');
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function draw(data, n) {
	var hc = n * 100 + 100;
	ctx.strokeStyle = "#f00";
	ctx.lineWidth = 1;
	ctx.moveTo(0, hc);
	for (var i = 1; i < 200; i++)
	{
		ctx.lineTo(i, hc - data[i] * 30);
	}
	ctx.stroke();
}

const model = tf.sequential();
model.add(tf.layers.lstm({ 
  units: 64,
  returnSequences: false,
  inputShape: [2, 1]
}));
model.add(tf.layers.dense({
  units: 1, 
  activation: "tanh"
}));
model.compile({
  optimizer: 'adam',
  loss: 'meanSquaredError'
});

const buf0 = [];
const buf1 = [];
b = [];
for (var i = 0; i < 200; i++)
{
	var x = i / 30.0;
	var y = Math.sin(x);
	b.push(y);
}
for (var i = 0; i < 197; i++)
{
	buf0.push([[b[i]], [b[i + 1]]]);
	buf1.push([b[i + 2]]);
}
draw(b, 0);

const xs = tf.tensor3d(buf0);
const ys = tf.tensor2d(buf1);
model.fit(xs, ys, {
	batchSize: 100,
	epochs: 100
}).then((d) => {
	var str = "loss = ";
	str += d.history.loss[0];
	alert(str);
	p = [];
	for (i = 0; i < 197; i++)
	{
		var x =  i / 30.0;
		var y0 = Math.sin(x);
		x =  (i + 1) / 30.0;
		var y1 = Math.sin(x);
		var pre = model.predict(tf.tensor3d([[[y0], [y1]]], [1, 2, 1]));
		var f = pre.dataSync();
		p.push(f);
	}
	draw(p, 1);
});


```

#成果物

https://embed.plnkr.co/AeikwCCQGZAhdKHZgebH/

#比較用
tanh
https://embed.plnkr.co/oVEtQXFPuAz2hLONXL4g/

以上。
org.slf4j.Loggerを使った拡張ロガーを作成するための忘備録

# 概要

org.slf4j.Loggerは汎用的に使用できるが、業務アプリではログ出力レベルの統一が必要。
そのためビジネスルールで定義したトレースレベルのみ出力する拡張ロガーを作成する。

# 拡張ロガークラス

org.slf4j.Loggerをラップした独自ロガークラスを作成する。
出力方法はorg.slf4j.Loggerに任せるだけ
Debugレベルは開発時のみ出力する。

```SystemLogger.java
/**
 * 
 */
package jp.co.product.system.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ログ出力共通クラス
 * 
 */
public class SystemLogger {

	private Logger logger;
	
	/**
	 * コンストラクタ
	 * 
	 * @param	cls	
	 * @see	org.slf4j.LoggerFactory#getLogger(Class)
	 */
	public SystemLogger(Class<?> cls) {
		logger = LoggerFactory.getLogger(cls);
	}
	
	/**
	 * エラー出力
	 * 
	 * @param	msg	ログ出力内容
	 * @see	org.slf4j.Logger#error(String)
	 */
	public void error(String msg) {
		logger.error(msg);
	}
	
	/**
	 * インフォメーション出力
	 * 
	 * @param	msg	ログ出力内容
	 * @see	org.slf4j.Logger#error(String)
	 */
	public void info(String msg) {
		logger.info(msg);
	}
	
	/**
	 * デバッグ出力
	 * 
	 * @param	msg	ログ出力内容
	 * @see	org.slf4j.Logger#error(String)
	 */
	public void debug(String msg) {
		if (logger.isDebugEnabled())
			logger.debug(msg);
	}
}

```

# log4j.properties

log4j.propertiesは通常通り。拡張ロガーを実装したクラスから出力できるように設定するだけ。

```log4j.properties
log4j.rootCategory=INFO, stdout

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - <%m>%n

log4j.logger.org.apache.activemq=ERROR
log4j.logger.org.springframework.batch=DEBUG
log4j.logger.org.springframework.transaction=INFO
log4j.logger.jp.co.product.system.batch=INFO

log4j.logger.test.jdbc=DEBUG
# for debugging datasource initialization
# log4j.category.test.jdbc=DEBUG
```

# 呼び出しクラス

拡張ロガークラスのインスタンスを生成しておき、使うだけ。
サンプルソースなのでインスタンスの生成がシングルトンになってない･･･（T＆T）

```ExampleItemWriter.java
package jp.co.product.system.batch.demo;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.item.ItemWriter;
import org.springframework.stereotype.Component;

import jp.co.product.system.common.SystemLogger;


/**
 * Dummy {@link ItemWriter} which only logs data it receives.
 */
@Component("writer")
public class ExampleItemWriter implements ItemWriter<Object> {

	//private static final Log log = LogFactory.getLog(SystemLoggerExampleItemWriter.class);
	private static final SystemLogger log = new SystemLogger(ExampleItemWriter.class);
	
	/**
	 * @see ItemWriter#write(java.util.List)
	 */
	public void write(List<? extends Object> data) throws Exception {
//		log.info(data);
		log.debug("debug" + data.toString());
		log.info("Info" + data.toString());
		log.error("error" + data.toString());
	}
}
```

# 検証環境
SpringBatchにて検証
実行時にslf4jのエラーが出力される。下記サイトを参照してslf4jのモジュール定義が必要
[GAE/Jで謎のSLF4JなWARNを退治する](https://qiita.com/rmiyayama/items/75bcdf98aa67534d1b5d)

```pom.xml
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.2</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.2</version>
</dependency>
```
GAS、ハマりポイント

# new Date
GMT +9:00 にどうしてもならんし、そもそも GMT でもない。
そんなとき確認するポイント
https://qiita.com/kawamurayuto/items/e98ce7f38cb572ae616a

スプレッドシート側にロケール情報を持っていて、そいつに引っ張られているんだね・・・・

# Session.getActiveUser().getEMail()
アクセスしてきたユーザのGmailアドレスを取得するためだけに存在する Sessionクラス。
`メニュー - 公開 - ウェブアプリケーションとして導入`
自分ユーザ権限 & 匿名　だと取れない。たとえ、Gmailアカウントでログイン中のブラウザからでも取れない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366986/3023e013-52f2-3b01-f097-33a87766e42c.png)
これだと取れない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366986/fcef1fd4-79e8-60b4-be84-bfe7f62ac208.png)
これなら取れる


随時追記していきます
初めての自作PC紹介

■なぜ自作PCを組もうとしたのか

仕事上、PCを持ち運びすることが多い＋切り替えが手間なので
これまでは、「VAIO Z」のフルスペックVerを持ち歩いていました。

が・・・

　・最近ちょっとモタつく
　・バッテリーやや膨らんでる気がする
　・開発環境が煩雑
　・お客様から「PCイジれないの？」と、たまに聞かれる

ということから

「よっしゃ、もうPC自作してやれ！」

と決断しました。

あと、BTO買おうとしたら見積もりが50万弱になって
「この金額帯だと、自作の方が結構安くなるよ！」とのアドバイスを鵜呑みにした
っていうのもあります。

■ざっくりとした方針

　金額：
　　　50万以内なら、嫁与信が通りやすい・・・
　スペック：
　　　CPUはなるべく新しいもの。メモリは64GB以上。OSはSSDに。
　　　出来たら、WiFiを内蔵したい。

■そして決まった構成＋実購入金額

【マザーボード】
　型番：ASRock Z390 Phantom Gaming 6
　購入店舗：Amazon(EC)
　金額：20,191円
　選定基準：
　　　・i9＋メモリ64Gが搭載可能
　　　・初心者に優しい大きなサイズ
　　　・無線WiFiが簡単に搭載（当機は、M.2WiFiに対応）
　　　・それなりに評判が良い（メーカー含め）

【PCケース】
　型番：CoolerMaster MasterCase H500M　MCM-H500M-IHNN-S00
　購入店舗：TSUKUMO(EC)
　金額：23,212円
　選定基準：
　　　・配線を考慮し、大きめなサイズ
　　　・ファン沢山付けれる（語彙力
　　　・部屋においてもストレス無い見た目

【電源】
　型番：Antec NeoECO GOLD NE750GOLD
　購入店舗：TSUKUMO(EC)
　金額：10,428円
　選定基準：
　　　・750W以上で、それなりに評判良い
　　　・正直良くわからん・・・
　
【CPU】
　型番：intel 9i 9900K
　購入店舗：ビックカメラ　アリオ八尾店
　金額：61,257円
　選定基準：
　　　・コンシューマ向けintel CPUで最強（語彙力
　　　・2～3年は継続利用出来るスペック

【CPUクーラー】
　型番：Corsair H150i PRO RGB
　購入店舗：Amazon(EC)
　金額：19,180円
　選定基準：
　　　・「i9はアッチアチやで！」という情報から簡易水冷
　　　・トラブル→CPU破損なので、メーカーと評判重視

【CPUグリス】
　型番：ARCTIC MX-4(4g)
　購入店舗：Amazon(EC)
　金額：999円
　選定基準：
　　　・吉田製作所(https://www.youtube.com/channel/UC9WJo5ZJVXMZiA5XV2jLx5Q)

【SSD】
　型番：CFD販売 CSSD-M2B1TPG3VNF
　購入店舗：TSUKUMO(EC)
　金額：21,578円
　選定基準：
　　　・OS＋αを入れるSSDなので1Tは一応・・・
　　　・OS入れるから、ある程度良いものをってことでCFD

【HDD】
　型番：WD40EZRZ-RT2 [4TB SATA600 5400]
　購入店舗：ビックカメラ　アリオ八尾店
　金額：9,581円
　選定基準：
　　　・ビックカメラでやすかったので、正直ノリ・・・

【メモリ】
　型番：G.Skill F4-3600C19D-32GSXWB(2セット購入)
　購入店舗：ドスパラ(EC)
　金額：32,980円
　選定基準：
　　　・価格comでの評判というかコスパ

【WiFi】
　型番：Intel Wirelss-AC9260NGW
　購入店舗：Amazon(EC)
　金額：5,450円
　選定基準：
　　　・Bluetoothも対応している
　　　・M.2 WiFiでアンテナロッドが付いているもので、安いやつ

【OS】
　型番：Windows10 Home
　購入店舗：ビックカメラ　アリオ八尾店
　金額：18,162円
　選定基準：
　　　・Hyper-Vで仮想化しようと思ったけど、正直ケチった(Vagrant+VirtualBoxでいけるか！ってやつ）

【グラボ】
　型番：未定
　購入店舗：未定
　金額：未定

◯その他
【静電気対策用手袋】
　購入店舗：Amazon(EC)
　金額：293円
　選定基準：
　　　・信じてはいけない、Amazonレビューを基準

【精密ドライバーセット】
　購入店舗：Amazon(EC)
　金額：1,799円
　選定基準：
　　　・信じてはいけない、Amazonレビューを基準

■苦労したところは？

　比較的ミスやトラブルは少なかったと思います。

　１．PCケース外での仮組み＋検証
　２．PCケースとの接続＋検証
　３．裏配線の検討

　って流れで進めたのですが
　２のマザボとPCケースの接続周りはちょっと手間取りました。
　取説には
　　「このマザボには、こう接続してね！」
　って記載が無いから
　「このケーブルは、こういう役目（だと思う）だから、この線が必要なはず・・・」
　みたいな感じで、一つずつ問題を消化していきました。

■結局、合計金額はどれくらいになった・・・？

【合計金額】
　225,110円(税込)※2019/11/5時点

グラボで15万くらい使う予定なので、37万くらいに着地かなと思います。

あとは、このPCに開発環境を構築して、Good開発ライフを過ごしたいと思います＼(^o^)／
いろんなアパレル・ブランドの商品をKibana で分析してみる

# Kibanaでなにする？

Kibanaでなにができるのか？受注の分析やログはいろんな記事があるのでここでは、Funnel　https://funnel-service.com/
のデータベースを使って分析してみる。

# Kibanaのインストールについて

KibanaとElasticsearchのバージョンを合わせておかないとKibanaが起動してくれないので注意。
yumでインストールする場合、インストールする時期が違ってKibanaのバージョンが上がっていた場合にちょっとめんどい。
というか、気が付かないので原因不明になっちゃう。


# Funnelのデータベースには何があるの？？

ブランド名、商品説明、クラス、価格が入っているのでそれを分析してみます。

# 準備

https://qiita.com/mokoenator/items/d2d0f914086c094b0bfc
この記事の通りにデータを入力していきます。

データの性質ですが、ブランドの新着をコツコツためてきた感じなので何らかの偏りがあります。
ZOZO、SHOPLISTはファッションのことがよくわかってない時期に入れてました。
（今もよくわかってません）



# 分析結果

## とりあえず全体

![192.168.0.113_5601_app_kibana (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185049/6c1d11ee-573f-32f5-2db8-3ca38394a894.png)
（なぜか中央値は　orderできないんですよね・・）

* TOPが一番多くて、WEGOが一番商品数が多いということが分かります。
* 価格帯は10000円以下がぶっちぎりです。
* ブランド毎の価格平均はWEGOが安いです。ONWARDは高いです。
* 180,000円ってなんだ！！:scream:


## 商品数が高めのfifthで分析

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185049/870cf517-3a7f-b00b-aa06-c81fe57d5ef5.png)

* 全体とくらべると、bag,skirtが上位に来ます。
* 価格帯は9000円以下です。


##　全体にたいして特定のキーワードで検索。

![192.168.0.113_5601_app_kibana (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185049/c6d76a52-2ac7-a5a8-768f-e7da082ef19b.png)

カシミヤで検索（カシミアは含まれません。カシミアとシノニム定義しておけばよかった:sob:）

* ONWARDがやっぱり高い
* Ailand sophilaも負けてません

## Ailand sophila　が気になるのでカシミヤでAiland sophilaで検索してなんの商品なのか突き止める

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185049/85a7dcf1-a9cd-3eff-e91e-5217b541540e.png)
これらしいので

Funnel　https://funnel-service.com/
で検索する
https://funnel-service.com/predictor.html?searchText=%E3%82%AB%E3%82%B7%E3%83%9F%E3%83%A4%E3%80%80Ailand+sophila&command=textSearch


![funnel-service.com_predictor.html_searchText=%E3%82%AB%E3%82%B7%E3%83%9F%E3%83%A4%E3%80%80Ailand+sophila&command=textSearch (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185049/ba20ed7a-7cf8-36c9-00da-797a28243d02.png)


カシミアのコート高いなぁ～:relaxed:!

# 感想

商品分析できてだからなんやねん？と思うのですが。
ブランド毎に性質の違いを知ったり、似ているブランドを見つけるのに役に立ちそうです。
受注と違って公開しているデータをもとに分析かけられるのでこれはこれで・・・
商品文章と商品画像の位置関係をもとに、「儲け」に関するデータを割り出せないかな・・:relaxed:
STM32F103 + Arduino_STM32 で タイマー

STM32F103のArduino開発環境として Arduino_STM32 を使っています。
今回はタイマー割り込みを使ってみます。

 Arduino_STM32 の元になった Leaflabs Maple に詳しいドキュメントがあります。
http://docs.leaflabs.com/static.leaflabs.com/pub/leaflabs/maple-docs/latest/lang/api/hardwaretimer.html#using-timer-interrupts

ここのサンプルコードはそのままでは動作しないので、少し直して動作確認しました。


```

// from http://docs.leaflabs.com/static.leaflabs.com/pub/leaflabs/maple-docs/latest/lang/api/hardwaretimer.html#using-timer-interrupts
#define LED_RATE 150000    // in microseconds; each 0.15sec trigger
#define BOARD_LED_PIN PC13
HardwareTimer ledtimer(2);  // timer 2

void setup() {
    pinMode(BOARD_LED_PIN, OUTPUT);
    ledtimer.pause();
    ledtimer.setPeriod(LED_RATE);
    ledtimer.setChannel1Mode(TIMER_OUTPUT_COMPARE);
    ledtimer.setCompare(TIMER_CH1, 1);  // Interrupt 1 count after each update
    ledtimer.attachCompare1Interrupt(handler_led);
    ledtimer.refresh();
    ledtimer.resume();
}

void loop(){
}

void handler_led(void){
    static int LEDstate = 0;
    digitalWrite( BOARD_LED_PIN,LEDstate);
    if ( 0 < LEDstate )
    { LEDstate = 0; } else { LEDstate = 1; }
```

cf.,「STM32F103 + Arduino_STM32 で Sleep」
https://qiita.com/nanbuwks/items/9abca51134226d5431da
Rails6対応のCentOS7をvagrant up一発で構築するVagrantfile

## 結論

```ruby:Vagrantfile
# -*- coding: utf-8 -*-

use_ruby_version = "2.6.6"
use_node_version = "12.13.0"

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"
  config.vm.network "forwarded_port", guest: 3000, host: 3000, host_ip: "127.0.0.1"
  config.vm.provider "virtualbox" do |vb|
  #   # Display the VirtualBox GUI when booting the machine
  #   vb.gui = true
  #
  #   # Customize the amount of memory on the VM:
  #   vb.memory = "1024"
  #   vb.customize ["modifyvm", :id, "--memory", "2048", "--cpus", "4", "--ioapic", "on"]
  end

  # システムのアップデート&必要パッケージのインストール
  config.vm.provision "shell", inline: <<-SHELL
    yum -y update &>/dev/null
    yum -y install gcc gcc-c++ make git openssl-devel readline-devel zlib-devel
    yum -y install automake libtool bzip2-devel sqlite-devel

    # install sqlite3.29
    curl https://www.sqlite.org/2019/sqlite-autoconf-3290000.tar.gz | tar zx -C /opt
    cd /opt/sqlite-autoconf-3290000 && ./configure --prefix=/opt/sqlite/sqlite3 && make -j4 && make install
  SHELL
  config.vm.provision "shell", privileged: false, inline: <<-SHELL
    if ! type anyenv &>/dev/null;then
      git clone https://github.com/anyenv/anyenv ~/.anyenv
      echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
      echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
      source ~/.bash_profile
      mkdir -p $(anyenv root)/plugins
      git clone https://github.com/znz/anyenv-update.git $(anyenv root)/plugins/anyenv-update
      anyenv install --force-init
    fi
    if ! type rbenv nodenv &> /dev/null;then
      anyenv install rbenv --skip-existing
      anyenv install nodenv --skip-existing
      source ~/.bash_profile
      touch $(nodenv root)/default-packages
    fi
    if ! type ruby &> /dev/null || ruby -e "exit RUBY_VERSION != '#{use_ruby_version}'";then
      anyenv update rbenv
      rbenv install #{use_ruby_version} --skip-existing
      rbenv global #{use_ruby_version}
    fi
    if ! type node &> /dev/null || [ $(node -v) != "v#{use_node_version}" ];then
      anyenv update nodenv
      touch $(nodenv root)/default-packages
      nodenv install #{use_node_version} --skip-existing
      nodenv global #{use_node_version}
    fi
    gem update --system --no-document
    gem install --no-document --force bundler
    gem install --no-document rails pry

    # install yarn for rails6
    curl -o- -L https://yarnpkg.com/install.sh | bash

    # configuration
    echo 'export BINDING=0.0.0.0' >> ~/.bash_profile
    bundle config build.sqlite3 --with-sqlite3-lib=/opt/sqlite/sqlite3/lib
    rbenv rehash
  SHELL
end
```

nodeやsqlite3のバージョンは詳しくなく適当なので気に食わない場合は各自で調整してください

参考:
[【Rails 6.0.0.rc2】rails s したら RAILS_ENV=development environment is not defined in config/webpacker.yml, falling back to production environment Exiting で怒られた。](https://qiita.com/jiko797torayo/items/4bfb65ffcb8a5de0de7a)
[CentOS環境でRails6.0をSQLite3 (>=3.8)で動かす](https://qiita.com/8zca/items/175efb0612070530d186)
LineグループにMelcoを招待してメールをLINEで共有する

問合せサイトの反響を、LINEで即時共有したいというニーズがあったので、Melcoで実装した。実装メモ。
https://line-email.dqc.jp


## 準備： Melcoと友達になっとく

Melcoと事前に友達になる。
https://qiita.com/puchida/items/907a3efc51491665fa26


## LINEグループを作る

LINEグループを作る際に、Melcoを招待する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/8789222c-b40b-1cd6-3c1e-44559956b3e0.png)

こんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/29edbf02-b3fb-b5cd-f5ad-b1d66f9a4267.png)

`melco`と話しかけると、転送用メアドが発行される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/394fd50c-3c91-25f2-45fa-b112c579ae5d.png)

このメアドに反響メールを転送するように設定すれば、反響メールがこのLINEグループに届く。ここに反響を共有したいメンバーを招待すれば、メンバー全員で反響を即座に共有できる
Kaggle関連まとめ

Kaggle攻略に役立つ情報集をまとめます。
(随時更新予定)

▪︎webサイト
https://naotaka1128.hatenadiary.jp/entry/kaggle-compe-tips

◼︎仕組み
カレーさんの解説分かりやすい
http://www.currypurin.com/entry/2018/02/21/011316


◾️本
Kaggleで勝つデータ分析の技術
https://www.amazon.co.jp/dp/B07YTDBC3Z/

◾️Booth
kaggleのチュートリアル第4版
https://booth.pm/ja/items/1567594

■slack
https://kaggler-ja.herokuapp.com

■discord
カレーさんの

■wiki
http://kaggler-ja-wiki.herokuapp.com/

■coursera
 https://ja.coursera.org/learn/competitive-data-science

◾️まとめ記事
kaggle api関連
https://qiita.com/uni-3/items/f1fdbeeddd08ca22c80f

https://qiita.com/shunkakinoki/items/1f58e218f8f6b31ad0bf
Serverlessでまず最初にほぼ確実にやること

deployしてあれ？できてないってなることがあるので書いておきます
（この記事は5秒で読めます）
Serverlessのawsのデフォルトの設定ではデプロイ先のリージョンが `us-east-1` バージニア北部になっています

CloudFormationのサービス画面で、ああーバージニアかあとリージョン変更したらやっぱりか！ってなる
なりません？

```
# serverless.yml
# 略
provider
  name: aws
  runtime: nodejs10.x
  region: ap-northeast-1 # これを追加
```

deploy時に指定する方法もあります
以下のように --regionでリージョン指定します
`$ sls deploy --region ap-northeast-1`

ymlに書かないと削除するときも --region指定しないとダメです
面倒なのでやっぱりymlに書きましょう

何回かバージニア北部にデプロイして音速で `$ sls remove` しているので、もう書いておきます

ちなみにCloudFormationのスタックを削除するのと `$ sls remove` は同じです
Melcoを使ってメールをLINEに転送する

IFTTTを利用した、メールからLINEへの転送は対応されなくなったらしい。
[Gmailがあらゆるサービス同士を連携させる「IFTTT」のサポートを打ち切る模様](https://gigazine.net/news/20190322-gmail-will-drop-ifttt/)

メールをLINE転送してくれるLineBotを作ったので利用法メモ。
https://line-email.dqc.jp

## Melcoと友達になる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/86360174-3013-2c7a-58bc-a87e66bf9751.png)
[ここから友達になる](https://line.me/R/ti/p/%40xfn8428u)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/c191ce4f-b5c5-ba5d-5eec-9784ac9af5f7.png)

こんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/4e63ca5f-1c6f-1394-35b0-8a9a093f5dab.png)


## 一言話しかける

一言話しかけると、転送用メアドが発行される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/ed2f609f-95e0-8350-fd91-903127bd2377.png)


## 転送用メアドをテストしてみる

実際に送ってみる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/d67d69e8-4ee2-ef62-1a7e-8510871d0ede.png)

下記のように転送表示されたら成功。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/255465/001b46f5-283d-db70-25b5-68ad0197a4ec.png)

このメアドを各種メール環境で転送設定すればよい。
リーダブルコードまとめ

## 変数名・メソッド名
* tmpは一時的な保管用途のみ
* スコープによる変数名の使い分け
  * 一時的なもの短い名前でも良い
  * メンバー変数、グローバル変数：長くても明示的な名前をつける

``` php
// どこからページを取ってくるのか？
// インターネットからであればFetchやDownloadを使う
public function getPage(url)
{
    //
}

class BinaryTrees
{
    private $size; // 何のサイズ？ height, numNodes など
}

class Thread
{
    // pause や killなどの使い分け 
    public function stop()
    {
      //
    }
}
```
  
## コメント

* 読み手の立場になって考える
* 既知の欠陥、定数の背景、クラス／関数の使い方／要約
* コメントは簡潔に
  * あいまいな代名詞を避ける
  * 関数の動作を正確に記述する
  * 入出力の実例を含める（コーナーケース）

## 比較式
* 条件式の書き方（例：年齢 >= 20）
  * 左：「調査対象」 変化する値
  * 右：「比較対象」 あまり変化しない
* 条件は否定形より肯定系
* 単純な条件もしくは関心を引く条件を先に書く
* 早めにreturnすることで、ネストを削除する

## コードの主要な「概念」を理解しやすくする
   
### 説明変数

式を表す変数
 
``` java
// line.split(":")[0].strip()がユーザ名を表すとする
if (line.split(":")[0].strip() == "root") {
    //
}

// 説明変数を使用した改善例
String userName = line.split(":")[0].strip();

if (userName == "root") {
    //
}
```

### 要約変数

大きなコードの塊を小さな名前に置き換えて、管理や把握を簡単にする変数のこと

``` java
if (request.user.id.equals(document.owner_id) {
    // ユーザはこの文書を編集できる
}
if (request.user.id != document.owner_id) {
    // 文書は読み取り専用
}
    
// 要約変数を使用した改善例
final boolean user_owns_document = request.user.id.equals(document.owner_id);
if (user_owns_document) {
    // ユーザはこの文書を編集できる
}
if (!user_owns_document) {
    // 文書は読み取り専用
}
```

### ド・モルガンの法則

``` java
if (!(file_exists && !is_protected)) Error("Sorry, could not read file.");

if (!file_exists || is_protected) Error("Sorry, couuld not read file.");
```

### 役に立たない一時変数は削除する
* 複雑な式を分解していない
* より明確になっていない
* 一度しか使っていない

### すべての変数の「スコープを縮める」
* 一度に考えなければいけない変数を減らす）
* 変数の変更箇所はできるだけ少なくする
* 変数を操作する場所が増えると、現在値の判断が難しくなる

## 下位問題を独立した関数にする
* 無関係の下位問題を積極的に見つけて抽出する
* 解決策を**簡単な**言葉で説明する
* プロジェクト固有のコードから汎用コードを分離し,一度に一つのタスクを行う
* コードをできる限り小さく軽量に維持する（不必要な機能／過剰な機能はもたせない）
* 関数の再利用、テスト、改善がしやすくなる

### 具体的な手段

1. 関数やコードブロックを見て「このコードの高レベルの目標は何か？」と自問する
2. コードの各行に対して「高レベルの目標に直接的に効果があるのか？あるいは、無関係の下位問題を解決しているのか？」と自問する
3. 無関係の下位問題を解決しているコードが相当量あれば、それらを抽出して別の関数にする

* 標準ライブラリ（必要に応じて自作のラッパーを作る）を利用する
* 自作のUtilityクラスを作成する
gitpod で graphics + C++ 開発環境を整備したいのメモ

最近流行り? のクラウド開発環境 gitpod 便利ですね.

Gitpodが最強過ぎる件について
https://qiita.com/mouse_484/items/394a4984f749cc201422

gitpodでjupyternotebookの開発環境を作る
https://qiita.com/ymmmtym/items/14de67dc64b3c47704e8

クラウドIDE「Gitpod」を試してみたら予想以上に使えそうだった
https://qiita.com/kai_kou/items/40a7a579f1bce31d6a16

github アカウントがあればすぐ試せます.


## C++ 開発

gitpod が他のクラウド IDE サービスと異なるところは, Docker による仮想環境に直接アクセスできるところです.

2019 年 11 月 4 日時点では, gitpod が動いている仮想環境には, 64 GB mem + 8 コア 16 thread の Broadwell Xeon 2.2 GHz マシン(OS は Ubuntu 19.04)が割り当たっており, C++ 開発環境としては十分でした.
(同時利用ユーザなどが多いと負荷が高くなるときもありました)

```
$ gcc -march=native -Q --help=target|grep march
  -march=                               broadwell
```

コンソールもありますので, VPS 的に普通の Linux として自由に使えます.

オフィシャルの紹介サイトでも, **みんな大好きレイトレーシング**の題材があります.

https://www.gitpod.io/blog/gitpod-launch/

### IDE 対応　

Improve C++ support #488
https://github.com/gitpod-io/gitpod/issues/488

コード補完などの issue は上がっています.

## グラフィックス環境

.jpg, .png ファイルなどは, Theia IDE 上でプレビューできます. 上記レイトレーシングの題材も, .png を出力して, それを IDE でプレビューしています.

コマンドラインから, `open` コマンド(gitpod 独自仕様?)でも IDE に表示できます.

.EXR など, 特殊なファイル形式はプレビューには対応していませんでした. gitpod の開発にコミットして対応したくなりますね.

### noVNC で対応

X11 など, グラフィカル表示は gitpod 用に設定された Docker イメージを使い, noVNC でブラウザに表示で対応するのがオフィシャルで紹介されています.

Getting a Virtual Desktop
https://www.gitpod.io/blog/gitpodify/

Developing native UI applications in Gitpod
https://medium.com/gitpod/developing-native-ui-applications-in-gitpod-15af2967c24e

## 料金

https://www.gitpod.io/pricing/

OSS 開発ですと月 100 時間までは無料です.
Unlimited でも 39 USD/month です. もう少し gitpod が動いている仮想環境がどれくらいの性能あるのかを試してみないとわかりませんが, C/C++ でグラフィックス/UI の開発環境をメインに使うのであれば, 64 GB mem + 8 コア環境が 39USD/month で使えるならリーズナブルではないでしょうか.


## その他

gitpod は TypeFox が作っているサービスです.

https://www.typefox.io/

特にプログラミング言語の開発環境の開発が得意な会社のようですね. Theia の開発も行なっています. 納得ですね.

オレオレ DSL が作れる Xtext も気になりますね.
https://www.eclipse.org/Xtext/
#PowerPlatform の新しいお仲間 Power Virtual Agents を触ってみた

Power Automate との連携についてはこちらの記事をご確認ください。
[ノーコードでBotが作れる Power Virtual Agents の Action が最強すぎて、素敵すぎたので、使い方をまとめました](https://qiita.com/rnakamuramartiny/items/16ce58a7af19f1e60693)

# Microsoft Ignite 2019
今まさにやっている、Microsoft Ignite 2019にて
Power Platform の新しい仲間として
Power Automate と
Power Virtual Agents が発表されました！
本投稿は、Power Virtual Agentsについてまとめています。

# 誰でもBOTが作れる時代がやってきた
いや、控えめに言ってこれですよ。
マジでやばいっすよこれ！

# はじめてつかうときは
https://powerva.microsoft.com/
ここからいけます。


# 画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/9341aff1-3242-01df-6274-fc8fe008d68e.png)
こんな感じになっています。
初期データとして、英語ではありますが、回答内容を試すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/10547720-a46f-759a-59be-f48b1fdf3f75.png)

# 作り方
Topicsから
New Topicをクリックすることで
質問内容を登録することができます。
※初めて作ったときは、デプロイに時間がかかるためグレーアウトしています。気長に待ちましょう。

# 質問内容
「お店の時間」、「お店の場所」、「注文」、「キャンセル」などといった単位で宣言をします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/77040525-fd0c-de42-c27b-4b651addb2d2.png)

# トリガー
お客さんが質問するような言葉を入力していきます。
この言葉を受けて、次に作成する処理が実行されるわけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/e7d389f2-2ccf-d143-6b21-bc281e571912.png)

# 処理
Go to authoring canvas からいけます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/1602dcb5-c928-8ce8-4eea-631c7c5157c4.png)

Microsoft Flowのように、ノーコードで宣言することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/04a6d11e-6be5-3a3c-d7fd-d6b597762f20.png)


# というわけで
完全ノーコードでBotができてしまうサービスができてしまいました。
これはマジでヤバイリリースです！
ぜひ皆さま試してみてください！！

# お試しBot
https://va.ai.dynamics.com/canvas?cci_bot_id=0ddbd513-280b-4a97-9159-97a0b2a85066&cci_tenant_id=1e331c3b-2af3-4bd1-921b-ade340f1285c
【見慣れない%記法】RubyのStringクラスのインスタンスメソッド`％`で幅を指定する方法

## はじめに
Rubyの`%`といえば、除算の余り、もしくは`%w(a, b, c)`のような配列作成だろうという２つのイメージを持っていました。

ただ、[こちらの記事]([rubyで掛け算九九の表示 - simanのブログ](http://simanman.hatenablog.com/entry/2013/04/15/192628))でsimanさんが書かれていたきれいな九九を出力するコードを見ていたところ、`%`で幅を指定されており、気になったため[Ruby2.6.0リファレンスマニュアル](https://docs.ruby-lang.org/ja/2.6.0/method/String/i/=25.html)を参照し、解読してみました。

## この記事が役に立つ方
- `%`は除算の余りだよね
- `%w（a, b, c)`で文字列の配列作れるよね
- …までしか`%`の使い方を知らないRuby初心者

## この記事のメリット
- `%`を用いた幅指定を体得出来る。

## 環境
-  OS： macOS Mojave version 10.14.6
* シェル： zsh
* 使用言語： Ruby 2.6.3

## 具体的な挙動
言葉で説明するより、コードを変えて見比べると意味がわかります。

今回は`%d``%5d`の２つの挙動の違いを見てみることにします。
※`d` は指示子。１０進数（Decimal Number）を指定。
　その他`b`で２進数、`x`で16進数なども指定出来る。

### 【例１】文字数の幅が１、指定する幅も１の場合

```ruby
x = (1..3).to_a

x.each do |i|
  print "%d" % [i]  #ここの %d で幅が1ということを指定。
end
```

⇣出力結果

```zsh
123 # 間にスペースはない。
```

### 【例２】文字数の幅が１，指定する幅が5の場合

```ruby
x = (1..3).to_a

x.each do |i|
  print "%5d" % [i]  #ここの %5d で幅が5ということを指定。
end
```

⇣出力結果

```zsh
    1    2    3 # 合計の幅が「５」なので、間に半角スペースが４つ分入る。
```

### 【例３】文字数の幅が３，指定する幅が1の場合

```ruby
x = (101..103).to_a

x.each do |i|
  print "%d" % [i]
end
```

⇣出力結果

```zsh
101102103 # 指定幅は「１」だが、文字数が「３」なので指定幅を超えて出力される。
```

### 【例４】文字数の幅が３，指定する幅が5の場合

```ruby
x = (101..103).to_a

x.each do |i|
  print "%5d" % [i]
end
```

⇣出力結果

```zsh
  101  102  103 ＃ 半角スペースが２つ分あることで可読性向上。
```

## おわりに
`%`だけでも色々な使い方があって面白いですね。
またひとつ勉強になりました。

まずは使えるかどうかは別として、存在を知る。
「なんかあったような気がする…ググろう。」とアンテナが立つ状態に持っていくことが大切ですね！

## 参考にさせて頂いたサイト（いつもありがとうございます）
[rubyで掛け算九九の表示 - simanのブログ](http://simanman.hatenablog.com/entry/2013/04/15/192628)
[instance method String#% (Ruby 2.6.0)](https://docs.ruby-lang.org/ja/2.6.0/method/String/i/=25.html)
プチコン4まとめ (8) 弾幕系にありそうな花火みたいな弾

[前回](https://qiita.com/yamachan360/items/96158ba2a924730b1ca4) に続き、プチコンっぽいシンプルなサンプルをご紹介します。

今回は以下のように花火みたいにパーッと開く、弾幕系のゲームにありそうな弾の動きをスプライトのアニメ設定で実装してみます。

![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/ac6fd6a1-e8ee-7d71-ad3b-631149937908.gif)

# サンプル その1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/0f6f64a7-bb6c-2c21-af67-4d6c0ba8da5b.png)

## アニメーションの事前定義

まず5～10行の FOR ループで、弾を動かすためのアニメーションを事前定義しています。一度に発射される弾の数を24として、それぞれ3種類づつ定義しているので、全部で72個のアニメーションが定義されることになります。

7行目の24個(ループで24回呼ばれるので)のアニメーションは、基本的な動きで、中心から24方向に真っすぐ弾が飛んでいきます。アニメーションの移動先となる弾の位置は、三角関数の COS/SIN で計算しています。

8行目の24個のアニメーションは、7行目とほぼ同じなのですが、速度が倍になっています。

9行目の24個のアニメーションは、やはり7行目をベースにしていますが、途中から角度が 15度 追加されますので、時計回りに回転が加わります。

## 実際に弾を発射する処理

12～21行の UNTIL ループが、実際に弾を発射するメイン部分です。

13行目では事前に定義した3種類のアニメーションのうち1つをランダムに選択し、また表示されるキャラクタもある範囲内でランダムに選択しています。

14行目では弾の発射位置(X座標とY座標)を、これもランダムで決めています。

15～19行の FOR ループが実際に24個の弾を発射している部分で、13～14行目で決めたランダム値を参照して、個々のスプライトを生成しています。

## 実行の様子

以下が実行の様子です。3種類のアニメーションしか用意していない割りには、よく動いているとおもいます。
![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/c594a9b6-0870-c87a-829d-1d948cfaed07.gif)

# サンプル その2

さて、アニメーションの機能が使えそうだとわかったところで、サンプルコードを改良してみましょう。

サンプル1と異なり、事前にアニメーションの定義をせず、スプライトごとにアニメーションを生成しています。これにより広がる範囲やスピードなど、変化する値を増やせ、結果としてバリエーション豊かな表示になることが期待できます。

## コードを見てみる

事前定義がないぶん、さきほどより短いコードで実装できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/9c9b0044-a26f-a369-c13d-8c0afda26c9a.png)

ポイントは13行目ですね。サンプル1で事前定義していた弾の移動アニメーションを、この行でスプライトごとに生成して設定しています。

なお8行目の RD は、弾が途中から時計回りや、反時計回りをするための変数です。RD はランダムに -15,0,15 の値のどれかになるので、アニメーション設定の後半の部分で、移動先を決定するときの角度に反映させています。

## 実行の様子

改めて、以下がサンプル2の実行の様子です。コードは短いですが、サンプル1よりバリエーションが豊富になっているのがわかるでしょうか。
![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/ac6fd6a1-e8ee-7d71-ad3b-631149937908.gif)
これに当たり判定のある自機を表示させるだけで、弾幕避け系のゲームが作れちゃいそうですねw

# というわけで

個人的にシューティングゲームが好きなので、それ系のサンプルのほうが、サクサク書ける気がします。見た目にも楽しいですし。

プチコンのアニメーション機能は便利で、特に弾が飛び交う弾幕系のゲームにはかなり向いている機能だと思います。ぜひいろいろ遊んで、プチコンの実力をどんどん引き出してあげてください。

それではまた！
[Google Chrome]アドレスバーの予測候補や履歴URLを削除する。

Chromeのアドレスバーで検索をすると予測候補や履歴URLが表示される。
人に見せられない履歴を削除したい。

##Chromeのアドレスバーの予測候補の削除方法
###1.ブックマークを削除する。
ブックマークのサイトが予測候補に表示される。
###2.Chromeの設定から閲覧履歴の削除をする。
「履歴」→「閲覧履歴データの削除」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396969/0a3d36d2-b642-7931-abe2-65e954260640.png)

※「詳細設定」の閲覧履歴を削除しても、予測候補が表示される。
pythonでDMM(FANZA)のAPIにリクエストを送信する方法

## もくじ

- きっかけ
- ソースコード

## きっかけ
アフィリエイトなんかではよく利用されているDMMのAPI。
これにpythonでリクエストを送信して検索結果を取得してみたいと思ってコードを書いてみたので、メモしておきます。
（実際に書いて利用したのは結構前です）

## ソースコード

同人作品情報を取得するサンプルです。

```
# dayUtil
import datetime
# htmlUtils
import requests
from urllib.request import urlopen
# JsonParser
import json

# リクエスト電文で使用するドメイン
DOMAIN = "https://api.dmm.com/affiliate/v3/ItemList"
# リクエスト電文で使用するAPI_ID
API_ID = "xxxxx"
# リクエスト電文で使用するAFFILIATE_ID
AFFILIATE_ID = "xxxxx"
# リクエスト電文で使用するSORT_VALUE
SORT_VALUE = "date"
# リクエスト電文で使用するOUTPUT
OUTPUT = "json"
# リクエスト電文で使用するSITE
SITE = "DMM.R18"

# ==================================================
# html生成
# ==================================================
def create():
    jsonObject = requestToApi(10, 30, "キーワード", "digital_doujin", "doujin")

# ==================================================
# APIへリクエスト送信
# ==================================================
def requestToApi(hitsNum, dateFromNum, keyword, floor, service):
    response = requests.get(createRequest(hitsNum, dateFromNum, keyword, floor, service))
    jsonObject = response.json()

    return jsonObject

# ==================================================
# リクエスト生成
# ==================================================
def createRequest(hitsNum, dateFromNum, keyword, floor, service):
    txt = DOMAIN + "?" \
    + createQueryParam("api_id", API_ID) + "&" \
    + createQueryParam("affiliate_id", AFFILIATE_ID) + "&" \
    + "hits=" + str(hitsNum) + "&" \
    + createQueryParam("sort", SORT_VALUE) + "&" \
    + createQueryParam("keyword", keyword) + "&" \
    + createDateTxt(dateFromNum) + "&" \
    + createQueryParam("output", OUTPUT) + "&" \
    + createQueryParam("site", SITE) + "&" \
    + createQueryParam("floor", floor) + "&" \
    + createQueryParam("service", service)

    return txt

# ==================================================
# クエリパラメータを生成
# ==================================================
def createQueryParam(key, value):
    return key + "=" + value
```
毎日ブログ八日目

今日やったこと
①Progate
JavaScript Ⅰ 終了
JavaScript Ⅱ 終了

繰り返し処理は、for whileの2つです。

②KROWL模写
https://magazine.krowl.jp/4876/
をやりました。ここのサイトのを練習すれば何にも見なくても書けそうですね。

同じ要素を分類することが第一ステップ

また、KROWLさんのテンプレCSSを利用することで楽に進められるので、これからも利用していきます。

明日は模写①、②を復習します。JavaScript Ⅲまで終わらします。
Pythonで決定木を可視化するまで

自宅PC環境で、scikit-learnのDecisionTreeClassfierで決定木を可視化するまでにやったことを記載します。

#前提

　OS：Windows 10 Home Edition
　Anaconda 3.7導入済み。

#導入手順

1. graphvizのインストール
1) "conda install graphviz"を実行する。
2) 環境変数PATHに"Anacondaインストールフォルダ\Library\bin\graphviz"を追加する。

2. pydotplusのインストール
1) "conda install pydotplus"を実行する。

3. python-graphvizのインストール
1) "conda install python-graphviz"を実行する。

それぞれ、conda installコマンドが異常終了していないことを確認する。
方法としては、
・conda installコマンド実行中にエラーメッセージが出てないことを目視で確認する。
・"echo %ERRORLEVEL%"の実行結果が0であることを確認する。
・"conda list パッケージ名"を実行して、インストール対象としたパッケージの名前が出力されることを確認する。
といったやり方があるかと思います。

#サンプル
##サンプルコード
```python
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
from sklearn.tree import export_graphviz
import pydotplus

df = pd.read_csv( 'D:/python/testdata.csv' )

src = df.drop( 'C', axis='columns' )
trgt = df['C']

clf = DecisionTreeClassifier( random_state = 0 )
clf.fit( src, trgt )

dot_data = export_graphviz(clf,
                feature_names=src.columns, 
                class_names=['T','F'], 
                filled=True, 
                rounded=True)

graph = pydotplus.graph_from_dot_data( dot_data )

graph.write_png( 'D:/python/tree.png' )
```
## テストデータ(testdata.csv)
```
A,B,C
-4,-8,T
-9,7,F
-1,3,F
2,1,T
5,-1,T
10,5,T
-8,-6,F
-9,-2,F
-8,-2,F
3,1,T
5,-6,T
4,-7,T
9,9,F
9,5,T
-5,6,F
5,9,F
9,3,T
2,-5,T
8,10,F
0,-6,T
```
※A>Bの場合にC='T'、A<Bの場合にC='F'となるように作ったデータです。

## 結果グラフ
![tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143537/81e37141-38b2-2a4f-61a9-5ed706fa0f50.png)

ちなみに、ここまでの環境構築内容だと、カラム名を日本語にした場合に文字化けします。
上記の例で、A⇒説明変数１、B⇒説明変数２、C⇒目的変数として同様の処理を実行させた結果は以下の通りです。
![tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143537/0aca25c6-59f2-8925-78db-193c9909663a.png)


## グラフ内で日本語を表示させるには…？
※scikit-learnをアップデートしたら元に戻ってしまいそうな方法ですが…。

『"Anacondaインストールフォルダ\pkgs\scikit-learn-0.21.2-py37h6288b17_0\Lib\site-packages\sklearn\tree\export.py"内でハードコーディングされているフォント名を変更する』という方法が使えます。

headメソッド内に以下の記述が2ヶ所あります。
「fontname=helvetica」

この、fontname=で指定されているフォント名を日本語フォント名に変更すればうまくいきます。
以下のグラフは、fontname=Meiryoに変更した上でグラフ作成した結果です。
上のグラフでは文字化けしていた部分が、正しく表示されています。
![tree.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/143537/580e3f26-2bb0-5959-6c9c-7275d0b4e40c.png)


ただ、このやり方だとフォント名に空白が含まれるとダメで、例えばfontname=Meiryo UIとすると処理が異常終了します。

#参考サイト
・[Python3でscikit-learnの決定木を日本語フォントで画像出力する方法のまとめ](https://own-search-and-study.xyz/2016/08/16/python3%E3%81%A7scikit-learn%E3%81%AE%E6%B1%BA%E5%AE%9A%E6%9C%A8%E3%82%92%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%95%E3%82%A9%E3%83%B3%E3%83%88%E3%81%A7%E7%94%BB%E5%83%8F%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B/)
・[Graphvizのコマンドで日本語が文字化けして困った(windows10)](https://qiita.com/lunar_sword3/items/4542dad7f807bb7d0fb5)

#関連リンク

・graphviz公式サイト
　https://www.graphviz.org/

・pydotplus公式サイト
　https://pypi.org/project/pydotplus/
certbot+lighttpdで常時SSLな静的サイトをささっと作る

完全に自分用メモ。普通はnginxとか使うよねｗ

---

## Lighttpdとcertbotインストール

```
sudo apt-get install lighttpd certbot
```


## certbotを設定

Lighttpdが80番ポートを使って動いているはずなので、 `--webroot` オプションを使うのがラク。

```
sudo certbot certonly --webroot
```

`Input the webroot for <ドメイン名>: (Enter 'c' to cancel):`

みたいな質問には `/var/www/html` と答えておけば

```
Waiting for verification...
Cleaning up challenges

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/<ドメイン名>/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/<ドメイン名>/privkey.pem
   Your cert will expire on 2020-02-02. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le


```

無事に証明書がもらえる。

## lighttpdのSSL有効化

```
cat /etc/letsencrypt/live/<ドメイン名>/cert.pem /etc/letsencrypt/live/<ドメイン名>/privkey.pem | sudo tee /etc/lighttpd/server.pem
sudo lighttpd-enable-mod ssl
sudo /etc/init.d/lighttpd restart
```

これで、 `/var/www/html` 配下のコンテンツがSSLでも配信できるようになっているはず

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74571/ae30f107-ce1e-84e8-114f-0910ca019042.png)

## 常時SSL化

https://redmine.lighttpd.net/projects/1/wiki/HowToRedirectHttpToHttps に書いてあるまんまなんだけど、

```
$HTTP["scheme"] == "http" { url.redirect = ("" => "https://${url.authority}${url.path}${qsa}") }
```

を `/etc/lighttpd/conf-enabled/10-ssl.conf` に追記して `/etc/init.d/lighttpd restart` するだけ。

手元から

```
$ curl -v http://<ドメイン名>/
```

して、301リダイレクトでhttpsが付いているURL指定になっていることを確認して、完了。