OmniAICreator/Qiita-1.07M huggingface dataset:
【追記】Node.jsでsocket.ioを使ってserialportの受信データをブラウザモニタリング

これは色々応用できそうなので最小構成を記事にしようかと

今回シリアルデータのソースはArduinoの赤外線リモコンの受信値をそのままUSBシリアルに流したものを利用したが
基本的にArduinoのなんらかのセンサーで受信した情報をSerial.println()で送ればなんにでも応用はできるんじゃないかと

前準備はこんな感じ

```terminal
mkdir serial_monitor
cd serial_monitor
npm init -y
npm install ejs serialport socket.io
```

その他にプロジェクトディレクトリにindex.jsとindex.ejsを作成し以下の様な内容

```js:index.js
const app = require('http').createServer(requestHandler);
const io = require('socket.io')(app);
const fs = require('fs');
const ejs = require('ejs');
const ip = "127.0.0.1";

const page = fs.readFileSync(__dirname + '/index.ejs', 'utf-8');

function requestHandler(req,res){
	var output = null;
	console.log(req.url);
	switch(req.url)
	{
		case '/':
			res.writeHead(200,{'Content-Type': 'text/html'});
			output = ejs.render(page,{ip:ip});
			break;
	}
	if(output !== null)
	{
		res.write(output);
	}
	res.end();
}

const serialport = require('serialport');
const portName = 'COM3';// /dev/ttyACM0, /dev/ttyUSB0などOSによって適宜選択
const sp = new serialport(portName,{
    baudRate: 9600,
    dataBits: 8,
    parity: 'none',
    stopBits: 1,
    flowControl: false,
});

const Readline = serialport.parsers.Readline;
const parser = new Readline();
sp.pipe(parser);

io.on('connection', (socket)=>{
	parser.on('data', (data)=>{
		console.log(data);
		socket.emit('status', { message: data });
	});
});

app.listen(3000);
console.log('Ready!');
```

```html:index.ejs
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="utf-8" />
	<title>TEST</title>
</head>
<body>
	<div id="message">message waiting...</div>
	<script type="text/javascript">
	</script>
	<script src="/socket.io/socket.io.js"></script>
	<script>
	var socket = io('http://<%=ip%>:3000');
	socket.on('status', (data)=>{
		document.getElementById('message').innerText = data.message.trim();
	});
	</script>
</body>
</html>
```

```terminal
node index.js
```
で実行しブラウザで開くと初期画面が表示され

![img_20190220.png](https://qiita-image-store.s3.amazonaws.com/0/314532/7551ce0c-c8d9-f44a-f440-ce162468a669.png)

↓シリアル信号を受信すると

![img_20190220(1).png](https://qiita-image-store.s3.amazonaws.com/0/314532/5701efae-3fd8-5a0e-c81e-f2c2d7c6194d.png)
のようにブラウザ画面にリアルタイムに受信情報が反映される

##【追記】
上記のコードを使用した場合ブラウザのリロードで際限なくparser.on('data',…)のイベントが積み重なってしまうため
(イベント発生毎にconsole.logを吐かせてたら酷い事になってた)
それに対しての修正案
disconnect字に適宜切断する事が必要だと分かったので受信系と通知系を分離するのが望ましいかと…

```diff:index.js
+var message=null;
// メイン受付用(双方向通信など送信、書き込み系処理はすべてこちらで行う)
+parser.on('data',masterReciever);
+function masterReciever(data){
+        console.log(data);
+        message=data;
+}
io.on('connection', (socket)=>{
-    parser.on('data', (data)=>{
-        console.log(data);
-        socket.emit('status', { message: data });
-    });
// Socket通信の為のシリアルレシーバー(状態の通知のみで書き込みなどは行わないこと)
+    parser.on('data',slaveReciever);
//   切断時Removeの為関数化
+    function slaveReciever(data){
+        console.log(data);
+        socket.emit('status', { message: message});
+    }
// ブラウザ切断時は必ずparser.on('data',…)イベントを解除する
+    socket.on('disconnect',()=>{
+        parser.removeListener('data',slaveReciever);
+    });
});
```
We're sorry, but something went wrong.の原因と解決策


###はじめに

Rails初心者です。

Mohave 10.14.3
Rails5.1

###エラー

![image.png](https://qiita-image-store.s3.amazonaws.com/0/288657/4f617d8f-6399-1571-c9c1-7283eb191a40.png)

###原因


form_tag(/login) doの、(/login)のURLに " " をつけ忘れていました。


```views/users/login_form.html.erb
<%= form_tag(/login) do %>
<p>メールアドレス</p>
<input name="email">
<p>パスワード</p>
<input name="password" type="password">
<% end %>
```

###解決策
URLに" "をつけ直したら、動きました。

```views/users/login_form.html.erb
form_tag("/login")
```



###メモ

初心者の凡ミスが誰かの役に立てたら幸いです。
副業としてのブログ運営

# 当Qiitaの目的
「ブログ収入で本業よりも稼ぐ」を目的とする。
目的達成までの道のりを記していき、最終的にはこのQiitaもブログ化・収益化する。

# 現状
メインで4つのブログを運営、5つ目を開始予定であり、SNSへの紐づけ、収益化、SEO対策は完了済み。
ただし、ブログ更新頻度は低迷し、それに伴いアクセス数は減少している。

# 課題
アクセス数がTo-beになっていない
　①SNSが駆使できていない
　②ブログの更新頻度が低い
　③ターゲティング選定が最適化されていない

# 施策
Pythonを用いてアクセス数をTo-beにする
　①SNSの運営を自動ブログ投稿の一部を自動化
　②ブログ投稿の一部を自動化
　③（オプショナル）オーディエンス分析によるターゲティング選定、及びプラットフォーム最適化

# アクションプラン
　①SNS運営の自動化
　　→[Twitterの自動化](https://qiita.com/deadhead13/items/ef909ef69277ef11b345)
　②ブログ投稿の一部を自動化
　　→ウェブスクレイピングでブログに投稿するための情報を収集
　　→上記情報をクレンジング
　　→Livedoorと繋げてクレンジングした情報を投稿
　③オーディエンス分析
　　→To be updated...
Gmailをメールクライアントにする

皆さんはすでにご存じですが、私は中年のおっさんなんで物忘れが激しい（禿しいともいいますが）ので、自分用の備忘録。


Gmailをメールクライアントにして、他のメールアカウントのメールを見るとき。

##用意するもの
　・おやつ用のバナナ（先生、バナナはおやつに入るんですかぁ？）
　・メールアカウント情報

##手順

gmailをあける。

設定を選ぶ。

![qiita001.jpg](https://qiita-image-store.s3.amazonaws.com/0/355500/2ddcd49e-4999-2f36-b704-286c6a95eab5.jpeg)

![qiita002.jpg](https://qiita-image-store.s3.amazonaws.com/0/355500/9d66ca10-08e3-c705-1d2e-8675614b9e01.jpeg)


「アカウントとインポート」を選ぶ。
![qiita003.jpg](https://qiita-image-store.s3.amazonaws.com/0/355500/a882680c-08d7-6ea7-3639-803bedcbda3d.jpeg)


受信したいメアドを入力する。

![qiita004.jpg](https://qiita-image-store.s3.amazonaws.com/0/355500/16c7eb20-60f9-03db-0cfd-6de6ac182a0a.jpeg)


ここで、おやつのバナナを食べる。



POP3を選んどく

![qiita005.jpg](https://qiita-image-store.s3.amazonaws.com/0/355500/7e348ca1-6e48-d923-0777-7243f6719efd.jpeg)

アカウント情報を入れとく
![qiita006.jpg](https://qiita-image-store.s3.amazonaws.com/0/355500/6b4a5b0b-3b18-ea5a-86b0-21c0bd70b58e.jpeg)

SSLを使うときは、当然ポート番号を９９５に変えておく。

これで、Gmailで他のアカウントのメールの受信ができる。


物忘れの多い、中年おやじの備忘録なんで、知ってる人はスルーしてください。
rubyでraiseのバックトレースを空にする（ベンチマーク付き）

# 概要

処理をバスッと切ってユーザーにエラーを表示させるようなシチュエーション、例えばAjaxのレスポンスなどで、ロールバックのことなんかも考えるとraiseを使うと便利だと思ったのですが、バックトレースが必要ないので、生成しないようにできたら多少でも軽くなるかなと思って調べてみた。

# コード

```rb
raise StandardError, 'そんなことしたらあかん！', []
```

raiseの3番目の引数に空の配列を渡すと生成されないっぽい。

https://docs.ruby-lang.org/ja/2.6.0/method/Kernel/m/raise.html

# Catch/Throw

Catch/Throwのことを思い出し試してみた。

ただ、catchの返り値が正常終了時はブロックの返り値、throwするとthrowした値というのが使い勝手が悪かったのと、railsのrescue_fromで処理できないのでアクションごとにごにょごにょ書かいないとダメなのがいまいちだった。

```rb
message = catch :error do
  throw :error,'そんなことしたらあかん！'

  # ここで何か処理をするとその返り値がmessageに入り`if message.nil?`がfalseに
end
```

# ベンチマーク

本当にバックトレースが生成されてないのか（かどうかはわからないが早くなってるかどうか）チェックしてみた。

```
                      user     system      total        real
Backtrace         0.098349   0.001307   0.099656 (  0.099900)
EmptyBacktrace    0.060658   0.000319   0.060977 (  0.061093)
Catch/Throw       0.032181   0.000067   0.032248 (  0.032283)

Backtrace         0.107247   0.001669   0.108916 (  0.109663)
EmptyBacktrace    0.062382   0.000346   0.062728 (  0.063138)
Catch/Throw       0.035800   0.000467   0.036267 (  0.036668)

                      user     system      total        real
Backtrace         0.102345   0.001523   0.103868 (  0.104327)
EmptyBacktrace    0.059909   0.000370   0.060279 (  0.060521)
Catch/Throw       0.032488   0.000130   0.032618 (  0.032768)
```

３回取ってみた感じはこんな感じ。やっぱりCatch/Throwの方が早いですね。ただ、空バックトレースも一定の効果はありそうです。

参考までにベンチマークのコードはこんな感じ。

```rb
require 'benchmark'

count = 100000
Benchmark.bm 15 do |r|
  r.report "Backtrace" do
    count.times do
      begin
        raise StandardError, 'FOOOOOOOOO'
      rescue

      end
    end
  end
  r.report "EmptyBacktrace" do
    count.times do
      begin
        raise StandardError, 'FOOOOOOOOO', []
      rescue

      end
    end
  end
  r.report "Catch/Throw" do
    count.times do
      catch :foo do
        throw :foo, 'FOOOOOOOOO'
      end
    end
  end
end
```

ベンチマークって平等にやるの意外に難しいですよね。問題に気づいたら教えてください。
SSHポートフォワードで多段RDP接続してみる

先日ちょっと必要になって調べたので、他にも記事はありますが書いて覚えるという意味でちょっと書いてみます。
#SSHポートフォワードとは
※あくまでイメージです
SSHでトンネルを掘ってその中に好きなもの（この場合RDP3389）を通す方法。
![スライド4.PNG](https://qiita-image-store.s3.amazonaws.com/0/297470/d3db7c1a-39d7-0793-ca60-1e3a4a7c7716.png)
図の例でいえばLinux2のセグメントにある他のマシンにもLinux2からアクセスできるのであればアクセス可能。
#必要なもの
1. クライアントPC(Windows1)
1. 踏み台になるPCとか(Linux1)
1. もう一回踏み台になるPCとか(Linux2)
1. 接続先PC(Windows2)

※SSH接続する際の証明書かパスワードは分かっていることとする、Windowsも同様

#とりあえず1段で試してみる
クライアントPCはWindowsなのでTeraTermを使います。
![2019-02-20.png](https://qiita-image-store.s3.amazonaws.com/0/297470/13d7008f-386e-20eb-3e3b-16397e8fa346.png)
OKをクリック
![2019-02-20 (1).png](https://qiita-image-store.s3.amazonaws.com/0/297470/18cca1c3-472d-4508-2e58-cf63f32eeebf.png)
上記のようにして1段目のLinux1にSSH接続しておく。
その後、もう一つTeraTermを開き、127.0.0.1:10022に接続。すると2段目の踏み台であるLinux2に繋がります。
![スライド1.PNG](https://qiita-image-store.s3.amazonaws.com/0/297470/b2106e88-e49e-84d3-a6dc-ac6678604a89.png)
SSHトンネルが通常の接続、青線がポートフォワードによるSSHです。
#では2段回で接続
さて、2段目のLinux2にダイレクトに行けたところでRDPは使えません。ではどうするか。
まず一回目は以下のようにします。先ほどと違うのは2段目のLinux2でなく1段目のLinux1自身を指しているところがミソです。
![2019-02-20 (2).png](https://qiita-image-store.s3.amazonaws.com/0/297470/ab4664d2-06cf-b19a-3ee8-3dd0961c8bfc.png)
OKをクリック
![2019-02-20 (1).png](https://qiita-image-store.s3.amazonaws.com/0/297470/91125c8a-ece6-cc29-f5bc-8c9455692e75.png)
次に上記設定で1段目のLinux1に接続します。
そして接続したLinux1上で以下のコマンドを叩きます。
※ホスト名等は環境によって合わせてください

Linux1上で
`ssh user@linux2 -L 13389:windows2:3389`

これでLinux1からLinux2へのトンネルが掘れました。
ここまでのイメージはこんな感じ。
![スライド2.PNG](https://qiita-image-store.s3.amazonaws.com/0/297470/528dcb56-7c25-462c-6d24-55450b956890.png)
さぁ、Windows1からリモートデスクトップクライアントを立ち上げ、127.0.0.1:13389に接続してみましょう。
![2019-02-20 (4).png](https://qiita-image-store.s3.amazonaws.com/0/297470/2f1fb5f9-8856-be11-04f7-b6cd2537c262.png)
できましたか？

動作イメージとしてはこんな感じです。
![スライド3.PNG](https://qiita-image-store.s3.amazonaws.com/0/297470/4702cb43-ea20-aa12-5aae-375f6c8cfb65.png)
Windows1の13389からLinux1の13389へ行き、Linux1の13389からWindows2への3389につながります。

出来ない場合はトンネルがつながっていないか、どこかで設定が間違っている場合があるので一個ずつ確認してみてください。

ちなみにこれはルーターでポートフォワードされていても問題ありません。
そのような場合は以下のようになります。

`ssh -i 証明書のパス user@ルーターのIP -p 待ち受けポート - L 13389:127.0.0.1:13389`
`ssh -i 証明書のパス user@linux2 -L 13389:windows2:3389`
![スライド5.PNG](https://qiita-image-store.s3.amazonaws.com/0/297470/574125f5-9c78-20a8-3829-b196a3e463d4.png)
CPI(レンタルサーバー)上でのPerl、Python、RubyのPathの調べ方

レンタルサーバーのCPI上でCGIを動かすときに
各言語のPathが必要になるかと思います。
CPI上でのPathの調べ方を記載します。

## 1.CPIコンソールにログインする
ユーザーポータルから、IDパスワードを入力してログインします。
<img width="824" alt="スクリーンショット 2019-02-20 11.37.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/42ad37c7-386d-876c-a7df-3661d2866a0e.png">

## 2.ウェブコントロールパネルを開く
ウェブコントロールパネルをクリックして、ウェブコントロールパネルを開きます。
<img width="1046" alt="スクリーンショット 2019-02-20 11.39.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/f4f21b2f-5b05-2822-6f07-f2c67a3af783.png">

## 3.お客様情報タブを開く
ウェブコントロールパネルを開いたら、お客様情報タブをクリックします。
<img width="471" alt="スクリーンショット 2019-02-20 11.42.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/4ed29a80-978d-343b-3093-fc7efb6cfe1b.png">

## 4.プログラムのパスとサーバーの情報を開く
プログラムのパスとサーバーの情報をクリックし、サーバー情報の画面を開きます。
<img width="473" alt="スクリーンショット 2019-02-20 11.45.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/ac36c932-bf5d-b54c-0866-ea7fab56b2ee.png">

## 5.Path情報を確認する
画面の中盤くらいにPathの情報があるので、必要な情報を確認します。
<img width="395" alt="スクリーンショット 2019-02-20 11.47.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/92989/0efa8864-3263-a58c-e4bf-da72dd64078f.png">

## そのほか
最新の情報は[公式オンラインサポート](http://storecart.secure.ne.jp/userinfo/server_info/server_info.php)を参照してください。
Equalsでの比較　

文字列比較の際にプチはまったので、今後のためにメモ

やりたかったことは、

・空の文字列に1文字ずつ文字を追加

・出来上がった文字列の１文字目を取り出し任意の文字と比較

簡単にコードをペタ

string input == null;
input += "1";
input += "2";

System.Console.WriteLine(input[0].Equals("1"));

=> False

動いてるけどほしい結果と違うのでなんでじゃろって思ってました。
エラーが出るわけではないので。

簡単なことでした。

input[0]で取り出した値は　char型になるので、比較対象を　'1' として char型にする。

ほかの言語でもたぶんそうなので
文字列比較の際にやっちゃいそうなのでメモに残しました。
「ソフトイーサ　PacketiX VPN入門」を読む, Ethernet(15)

ソフトイーサ　PacketiX VPN入門

![51SCEZ9KDAL._SX348_BO1,204,203,200_.jpg](https://qiita-image-store.s3.amazonaws.com/0/51423/01da5b8e-eb51-69fc-6e4d-43ec7b1db914.jpeg)
https://www.amazon.co.jp/dp/4777512037/


# SoftEther
SoftEther 1.0
https://www2.softether.jp/jp/vpn2/old/manual/

PacketiX VPN 2.0
https://www2.softether.jp/jp/vpn2/download/

SoftEther VPN Project
https://github.com/SoftEtherVPN

p.10
> PacketiX VPNは開発中はSoftEther 2.0という仮称が使われていました。そして製品版になったときに、PacketiX VPNという名称に変更されました。すなわち、PacketiX VPNはSoftEther 2.0と同じものです。

p.12
> PacketiX VPN Serverを動かしているコンピュータが停止すると、VPNが使えなくなるので、２４時間稼働しているサーバにインストールするのが好ましい

p.13
>無線LANカードがプロミスキャス・モードと呼ばれる機能をサポートしている

# ユーザ認証

## 匿名認証

## パスワード認証

## 固有証明書認証
クライアント証明書

p.127
>証明書作成ツールを使ってクライアント証明書を作ります。このときクライアント証明書と同時に秘密鍵も作られます。

p.129
- X509証明書ファイル(.cer), 秘密鍵ファイル(.key)
- PKCS#12ファイル(.p12

## 署名済み証明書認証

## Radius認証

## NTドメイン認証

# Appendix B セキュリティポリシー一覧
20個と記載されている。最新は22個。次の２つを追加。
https://ja.softether.org/4-docs/1-manual/3/3.5

>多重ログイン制限数
VoIP / QoS 対応機能の使用を禁止」


# 課題
すべての端末にServerとClientを導入し、n個の網を作れば、どの１台が故障しても網は維持できる。
この方法の課題を述べよ。

# 参考資料(reference)
SoftEtherを知る
https://qiita.com/kaizen_nagoya/items/7a4062f845ebb2539e25

softether on docker(作業中)
https://qiita.com/kaizen_nagoya/items/fd8778bc768f2be734e2

softether on docker(cantos)　作業中
https://qiita.com/kaizen_nagoya/items/8afc39c6a4b1d17d1f76

「ソフトイーサ　PacketiX VPN入門」を読む
https://qiita.com/kaizen_nagoya/items/3b1d330b2cddaacfa5b8

Ethernet 記事一覧　Ethernet(0)
https://qiita.com/kaizen_nagoya/items/88d35e99f74aefc98794

# 文書履歴(document history)
ver. 0.01 初稿 20190220 午前11時
ver. 0.02 追記 20190220 正午
ver. 0.03 ユーザ認証　追記 20190220 午後１時
ver. 0.04 セキュリティポリシー一覧 追記 20190220 夕方
ver. 0.05 ありがとう追記 20230611
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
Google Chromeで条件にマッチした履歴を削除

# TL;DR

* Google Chromeの履歴情報はMacなら`~/Library/Application Support/Google/Chrome/Default/History`にSQLite形式で保存されている
* これにsqlite3で接続すれば好きにデータを修正できる
* **以下の作業は自己責任で**

# はじめに

Google Chromeのアドレスバーに一度「似ているけれど違うURL」を叩いてしまい、それが履歴に保存されてしまった。その後、アドレスバーに目的のURLを入力しようとするたびに、「似ているけれど違うURL」が履歴からサジェストされ、間違えてそれを選ぶ事故が多発したので、Google Chromeの「全履歴削除」から、指定のURLを含む履歴を全削除しようとした。しかし、検索窓に何か入力するとインクリメンタルサーチで条件にマッチした履歴が表示されるのだが、それらを一括して削除する方法が見つからず、いちいちチェックボックスでちまちま削除しないといけないらしい。それは面倒だったので、履歴ファイルを直接いじって消すことにした。

# 履歴ファイルをsqlite3で開く

Google Chromeの履歴ファイルはMacなら`~/Library/Application Support/Google/Chrome/Default/History`にSQLite形式で保存されている。ちょっと接続してみよう。Macならsqlite3がデフォルトで入っているはず。念の為バックアップをとっておくこと。

```sh
$ cd ~/Library/Application\ Support/Google/Chrome/Defaul
$ cp History History.org
$ sqlite3 History
SQLite version 3.24.0 2018-06-04 14:10:15
Enter ".help" for usage hints.
```

これでHistoryに接続できた。後はSQL文で好き放題できる。例えばテーブル一覧はこんな感じ。Chromeが起動中だとデータベースがロックされており、
何かしようとしても`Error: database is locked`と出るので注意。

```sql
sqlite> .table
downloads                meta                     urls
downloads_slices         segment_usage            visit_source
downloads_url_chains     segments                 visits
keyword_search_terms     typed_url_sync_metadata
```

この内、履歴は`urls`に入っている。`urls`の中身を見てみる。

```sql
sqlite> PRAGMA TABLE_INFO(urls);
0|id|INTEGER|0||1
1|url|LONGVARCHAR|0||0
2|title|LONGVARCHAR|0||0
3|visit_count|INTEGER|1|0|0
4|typed_count|INTEGER|1|0|0
5|last_visit_time|INTEGER|1||0
6|hidden|INTEGER|1|0|0
```

`url`が所望のデータだ。他にも何回見たかとか、最後に閲覧したのはいつかとか保存している模様。例えば、Yahooへのアクセス記録を出力してみる。

```sql
sqlite> SELECT url FROM urls WHERE url LIKE '%yahoo%';
https://news.yahoo.co.jp/pickup/6314475
https://news.yahoo.co.jp/pickup/6314512
https://rdsig.yahoo.co.jp/_ylt=A2RhOBncumxc_EIAwmGJBtF7/RV=2/RE=1550715996/RH=cmRzaWcueWFob28uY28uanA-/RB=Tl1BEuHH.pmHl6nh8acKUaB5aNE-/RU=aHR0cHM6Ly9uZXdzLnlhaG9vLmNvLmpwL3BpY2t1cC82MzE0NTEyAA--/RK=0/RS=av1AssZWJzL41xBT_jN._wbvTLM-
https://rdsig.yahoo.co.jp/_ylt=A2RiVc_fumxc3QkAiziJBtF7/RV=2/RE=1550715999/RH=cmRzaWcueWFob28uY28uanA-/RB=Tl1BEuHH.pmHl6nh8acKUaB5aNE-/RU=aHR0cHM6Ly9uZXdzLnlhaG9vLmNvLmpwL3BpY2t1cC82MzE0NDc1AA--/RK=0/RS=eGNI.qh83kqwAWG8cKhbUYK1uSs-
https://www.yahoo.co.jp/
```

まっさらな状態から、Yahoo Newsをいくつか見たのだが、その情報が取れている。

さて、URLに「yahoo」を含む履歴をざっくり削除してしまおう。

```sql
sqlite> DELETE FROM urls WHERE url LIKE '%yahoo%';
sqlite> SELECT url FROM urls WHERE url LIKE '%yahoo%';
sqlite>
```

DELETE文を実行したあとは、URLに`yahoo`を含む履歴が消えた。Chromeを再起動して、履歴を調べみよう。
<img width="1075" alt="yahoo.png" src="https://qiita-image-store.s3.amazonaws.com/0/79744/f96105a0-d3bd-6c7a-d5f5-064ebcf2a15d.png">

うん。消えてますね。

# まとめ

Google Chromeで「条件にマッチする履歴を一括削除」機能がなかったようなので、sqlite3を叩いて直接消してみた。RubyないしPythonから触ろうかと思ったのだが、これくらいならsqlite3で直接SQL叩いた方が楽だった。これで、普段Twitterとかいつ、どのくらいの頻度で見ているかとか簡単に調べられるので、気になる人は試してみられたい

繰り返しになるが、実行するならくれぐれも自己責任で。
git for Windowsを使用していて認証情報をリセットする方法

仕事で使っているgithubのパスワードを定期的に変更する必要があるのだが、
変更したことでローカルからのアクセスができなくなってしまい、困ったことがあったのでメモ。

#git for Windowsでの認証情報の保存場所
自分はsshではなくユーザ名・パスワードで接続していた。
最初にcloneしてくるときにユーザー名・パスワードを求められるので入力するが、以降は記憶してくれているので入力する必要がない。
で、この記憶している場所がどこかというと、「Windows資格情報」である。.git配下とかじゃないのね・・という気持ち。

```
コントロール パネル->すべてのコントロール パネル項目->資格情報マネージャー
```

ここの汎用資格情報というところにgit:https://~という表示があるので、クリックすると編集or削除ができる。

お終い
Laravel チートシート　マイグレーション・モデル 編

# マイグレーション - php artisan

### 新規テーブル追加用のマイグレーションファイル作成
    php artisan make:migration create_%table_name%_table --create=%table_name%

### 既存テーブル カラム追加用のマイグレーションファイル作成
 ※ ファイル名にはカラム追加の意味add_columnsだけ記載すればいいと思う(何のカラムを追加したかとか入れると多く追加しとき対応できない)
 ※クラス名重複を避けるため yyyymmdd を追加するのがいいと思う

```
php artisan make:migration add_columns_to_%table_name%_yyyymmdd --table=%table_name%
```

### 既存テーブル カラム変更
```
php artisan make:migration change_columns_of_%table_name%_yyyymmdd  --table=%table_name%
```
ファイル内での記述は、

```php5
    $table->string('book_name', 255)->nullable()->change();
    $table->renameColumn('company', 'publish');

    $table->dropColumn('price');
```

### マイグレーション 実行
マイグレーションファイルはどんどん増えていくので、通し番号で階層管理する
実行するときは、下記のようにフォルダ指定する

```
    php artisan migrate --path=database/migrations/1
```

### マイグレーション 1回 戻す
    php artisan migrate:rollback --path=database/migrations/1

# マイグレーション - 問答無用でお世話になる型たち
```php
    $table->string('email', 255);
    $table->text('description');

    $table->integer('member_id');
    $table->smallinteger('birth_year');
    $table->tinyinteger('birth_month');

    $table->date('birthday');

    $table->boolean('is_sendable');
```

# マイグレーション - その他の型たちはこちらへ
https://readouble.com/laravel/5.5/ja/migrations.html

# マイグレーション - カラム属性

### 外部キー
```php
    //カラムの定義と外部キー制約の定義で2行になる
    //参照先のIDの型と合わさないとエラーになる
    $table->unsignedInteger('book_id');　　
    $table->foreign('book_id')->references('id')->on('books');
```

### Null許可
```php5
    $table->string('book_name', 255)->nullable();
```

### ユニーク
```php5
    $table->string('atuthor')->unique();
```

### デフォルト値
```php5
    $table->integer('price')->default('1000')
```



### created_at/updated_at/deleted_at
```php5
    $table->timestamps();
    $table->softDeletes();
```

### 正負無し
```php5
    $table->integer('book_no')->unsigned();
        または
    $table->unsignedInteger('book_no');
```

### コメント
```php
//いつ追加したか、フラグだったら内容入れとくと、
//テーブル定義書をリバースエンジで作るときも、運用も楽じゃないかなと思う
$table->tinyinteger('is_recess')->comment('2019/02/22, 休止フラグ, 0:稼働中 1:休止中')
```
# モデル 作成
    php artisan make:model books

# ソフトデリート
```php5
    use Illuminate\Database\Eloquent\SoftDeletes;
    class Books extends Model
    {
    	use SoftDeletes;
    
    }
```
Windows10で.NET3.5を展開するためにやったこと

# 1.担当プロダクトで発生したこと
 * そろそろ各ユーザ企業でWindows10の導入が本格化してきました。私の担当プロダクトでも
 　.NET3.5が必須ですが、ユーザ側でまだその対応が出来ていないとか、全体に適用しない等の
   状況もあるようで、とはいえ当該プロダクトでは設定しなければいけないので、その方法論です。

# 2.やったこと(サーバ側)
 * APサーバ(Windowsサーバ)にWindows10のメディアの中身をコピー
 * ファイル共有を設定。

# 3.やったこと(ローカルPC側)
 * サーバ側のパスに対してネットワークドライブを切る処理と.NET3.5の更新処理を行うスクリプトを作成。
 * 作成したスクリプトを管理者で実行。

# 4.参考にさせて頂いたサイト
 * https://www.projectgroup.info/tips/Windows/windows10_0029.html
 * https://blogs.technet.microsoft.com/askcorejp/2018/10/05/enable_net35_win10/
リクエストURLがないって言われる Udemy 【3日でできる】はじめての Django 入門　レクチャー33

だいぶご無沙汰になってしまってるコレ（）
今週中に攫おう。。。

# はじめに
[【3日でできる】はじめての Django 入門 ( Python 3 でウェブアプリを作って AWS EC2 で公開！）](https://www.udemy.com/django-beginner/)レクチャー33で「http://127.0.0.1:8000/posts/1」に飛ぼうとすると
『"GET /posts/1 HTTP/1.1" 404 2392』というエラーが出る。

# 結論
１系と２系の違いは辛い

## エラーを吐く書き方
```
path('posts/(?P<post_id>[0-9]+)/$' , views.post_detail ,name = "post_detail")
```

## 動作する書き方
```
path('posts/<int:post_id>' , views.post_detail ,name = "post_detail")
```

書き方がシンプルになってていいね！
Nginxとphp-fpmをsock接続するときphp-fpm.sockが消える件

Nginxとphp-fpmをポート接続からソケット接続にする場合

```diff:/etc/nginx/conf.d/*.conf(設定ファイル名は任意)
-fastcgi_pass  127.0.0.1:9000;
+fastcgi_pass  unix:/var/run/php-fpm/php-fpm.sock;
```

```diff:/etc/php-fpm.d/www.conf
-listen = 127.0.0.1:9000
+listen = /var/run/php-fpm/php-fpm.sock
```

とするのだけれども

```terminal
systemctl stop php-fpm
```

とphp-fpmサービスを停止した場合
/var/run/php-fpm/ディレクトリが丸ごと消失してしまうため
再度起動するとphp-fpm.sockファイルが再生成され
オーナー情報・パーミッション情報を変えていてもリセットされてしまい
サーバー再起動などで動かなくなってしまう問題がある

この問題は以下のように
listen.owner、listen.group、listen.modeを適切に指定する事により

```diff:/etc/php-fpm.d/www.conf
-;listen.owner = nobody 
-;listen.group = nobody
-;listen.mode = 0660
+listen.owner = nginx
+listen.group = nginx
+listen.mode = 0660
```

```terminal
systemctl stop php-fpm
systemctl start php-fpm
```
してもphp-fpm.sockファイルがnginx所有のファイルとして正しく生成され動作するようになる

php-fpmの実行ユーザーも変更する場合

```diff:/etc/php-fpm.d/www.conf
-user = apache
-group = apache
+user = nginx
+group = nginx
```

セッションにアクセスできなくなるので権限を変更

```terminal
chown -R nginx:nginx /var/lib/php/session/
```
gcloudコマンドよく使うやつ（随時更新）

## 全般

* プロジェクトの切り替え

```
$ gcloud config set project [プロジェクト名]
Updated property [core/project]. 
```

* 設定されているconfigの確認

```
$ gcloud config list
[core]
account = myAccount
project = myProject

Your active configuration is: [default]
```

## GAE(Google App Engine)

* gaeへのデプロイ
 `--no-promote`をつけないとトラフィック切り替えまで即座に行われる（デフォルト動作が`--promote`）。

```
$ gcloud app deploy [デプロイ定義ファイル] -v [バージョン] --no-promote
```
Rails tutorial 2章で躓いた箇所（「$ rails generate scaffold …」が実行できない）

railsチュートリアルの2章で躓いた箇所を記録しておきます。
Railsのバージョンは`Rails 5.1.6`です。

# エラー箇所

```
$ rails generate scaffold User name:string email:string
```

上記をすると、下記のようなエラーがおきてしまう。

# mysql2？？？

```
/usr/local/rvm/gems/ruby-2.4.1/gems/activerecord-5.1.6/lib/active_record/connection_adapters/connection_specification.rb:188:in `rescue in spec': Specified 'mysql2' for database adapter, but the gem is not loaded. Add `gem 'mysql2'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord). (Gem::LoadError)
```

どうやら`mysql2`が定義されていないとのこと。
ということでRailsチュートリアルがコピペしてね、と記述されてたコードを見てみることに。

```Gemfile.
source 'https://rubygems.org'

gem 'rails',        '5.1.6'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.7.0'

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

group :development do
  gem 'web-console',           '3.5.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.0.2'
  gem 'spring-watcher-listen', '2.0.1'
end

group :production do
  gem 'pg', '0.20.0'
end

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
```

この中に記載されている中の`sqlite3`を、`mysql2`に変更する必要がある。

```Gemfileを変更.
group :development, :test do
  gem 'mysql2', '~> 0.4.4'
  gem 'byebug',  '9.0.6', platform: :mri
end
```
からの`bundle install`を実行

```
$ bundle install --without production
```
<br/>
とりあえず`mysql2`にして、改めてエラーが出たコードを入力してみることに。


```
$ rails generate scaffold User name:string email:string
```

すると、ちゃんと実行されました！ﾔｯﾀｰ

# マイグレをしよう！

`$ rails generate scaffold User name:string email:string`が実行されたので、マイグレを実行することにします。

```
$ rails db:migrate
```
すると再びエラーが。。。

```
rails aborted!
ActiveRecord::NoDatabaseError: Unknown database 'toy_app_development'
```
どうやらデータベースがありませんよ（NoDatabaseError）、とのこと。
なのでデータベースを作成することに。

```
$ rails db:create
```
これでデータベースが作成されました。
再びマイグレートしたいと思います。

```
$ rails db:migrate
```

できたっ！！！！！！
多分これで解決すると思います。
Swiftで文字列の輪郭に線をつける

## 概要
Swiftで袋文字を実現したいという話を聞いて、調べたら実現方法がさっくり見つかったので残しておくことにした。 
[ブログから転記](http://www.macneko.com/entry/apply-outline-to-uilabel)

## 実現方法

`UILabel` の `extension` を定義して、そのメソッドを使うだけ。  
参考記事のままだとエラーになるのでよしなに修正してある。

```swift
extension UILabel{

    /// makeOutLine
    ///
    /// - Parameters:
    ///   - strokeWidth: 線の太さ。負数
    ///   - oulineColor: 線の色
    ///   - foregroundColor: 縁取りの中の色
    func makeOutLine(strokeWidth: CGFloat, oulineColor: UIColor, foregroundColor: UIColor) {
        let strokeTextAttributes = [
            .strokeColor : oulineColor,
            .foregroundColor : foregroundColor,
            .strokeWidth : strokeWidth,
            .font : self.font
        ] as [NSAttributedString.Key : Any]
        self.attributedText = NSMutableAttributedString(string: self.text ?? "", attributes: strokeTextAttributes)
    }
}
```

見た目があまり美しくないので、静的な用途であればIllustratorなどのアプリケーションでSVG書き出ししたものを使うと良い。

## Playground

Playgroundにコードをコピペして実行するとどんな感じが確認できる。

```swift
import UIKit

extension UILabel{

    /// makeOutLine
    ///
    /// - Parameters:
    ///   - strokeWidth: 線の太さ。負数
    ///   - oulineColor: 線の色
    ///   - foregroundColor: 縁取りの中の色
    func makeOutLine(strokeWidth: CGFloat, oulineColor: UIColor, foregroundColor: UIColor) {
        let strokeTextAttributes = [
            .strokeColor : oulineColor,
            .foregroundColor : foregroundColor,
            .strokeWidth : strokeWidth,
            .font : self.font
        ] as [NSAttributedString.Key : Any]
        self.attributedText = NSMutableAttributedString(string: self.text ?? "", attributes: strokeTextAttributes)
    }
}

let label = UILabel(frame: CGRect(x: 0, y: 0, width: 500, height: 60))
label.font = UIFont.boldSystemFont(ofSize: 50)
label.text = "我が家の猫は7.4kg"
label.makeOutLine(strokeWidth: -2.0, oulineColor: .white, foregroundColor: .blue)
```

キャプチャ
![uilabel-outline](https://user-images.githubusercontent.com/5406126/52771418-2f0bf680-3079-11e9-83d8-f89dc625dce0.png)

## おまけ
`NSAttributedString.Key` でいろいろ装飾できるので、ドキュメントを読むと面白い。
[NSAttributedString.Key](https://developer.apple.com/documentation/foundation/nsattributedstring/key)
  
iOSでチラシレイアウトも実現できる。需要はない。
[iOSでチラシっぽい価格レイアウトを再現してみた](http://www.macneko.com/entry/ios-flyer-price-layout)

## 参考
### 元ネタ
[Custom Label Effects in Swift 4](https://medium.com/@nimjea/custom-label-effects-in-swift-4-69ec12ba2178)

### 個人的に毎度読むスライド
最高  
[Mastering Textkit](https://speakerdeck.com/kishikawakatsumi/mastering-textkit-1)
Google App Script(GAS)でスプレッドシートに行を追加して永続化したい！

## やりたいこと

ログを保存していくように、単純にテーブルに行を追加していくだけのGoogle App Script(GAS)がほしいです。
よくやりそうなのに、ぱっと記事が見つからなかったので書きたいと思います。

## 手順

保存先になるスプレッドシートを作ります。
以下のようなURLになると思うので、URLの`"1mP...7I9Y"`の部分がIDになっていてあとでGASで使うので、メモっておきます。
（スプレッドシートごとに異なるIDになります）

<img width="978" alt="Screen Shot 2019-02-20 at 10.32.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/84451/fd5f58ff-40e9-37e6-805a-9ed47fb6ac49.png">

以下のような.gsを作成して保存します。(スクリプト内の`id`の部分は自分のものに書き換えましょう)

```js
// mainを実行するたびに行がどんどん増えていく
function main() {
  // ↓↓↓ ☆☆☆　ここは自分のIDに書き換えましょう
  var id = "1mP...7I9Y";
  // IDからスプレッドシートを取得
  var spreadsheet = SpreadsheetApp.openById(id);
  // 最初のシートを取得
  var sheet = spreadsheet.getSheets()[0];
  // 1行を追加
  sheet.appendRow([new Date(), "りんご", "オレンジ", "バナナ"]);
}

```

保存後、▶ボタンで、`main`を実行します。
最初の実行だと権限周りでGASが尋ねてくると思いますが、許可する感じのボタンを何回か押します。
許可の途中で、赤い⚠のマークが出る思いますが、[詳細]>[安全ではないページに移動]を押して突き進みます。
参考： [GAS→スプレッドシート 読み書きしてみた！ - lisz-works](https://www.lisz-works.com/entry/gas-rw-spreadsheet)
`#appendRow`: [Class Sheet  |  Apps Script  |  Google Developers](https://developers.google.com/apps-script/reference/spreadsheet/sheet#appendRow(Object))

### 実行結果

行の追記をしていく上記のGASを2回実行すると、以下のようになります。

<img width="623" alt="Screen Shot 2019-02-20 at 10.43.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/84451/dc25c325-ba83-9d87-be4d-5aa6d21e0b06.png">


~~恐らくこの方法だと、~~行が上書きされる心配もなく、行見出しなどを上に付けてても追加されていくはずです。
追記：見出しの行があっても無事に追記されました。
PHPの文字コードの変更に対応させる

charsetが[shift-jis]や[euc-jp]になっている場合。
php5.6からは、サポートしてくれない。

しかし、あらかじめデフォルトの文字コードを変更することで対応できる。

## PHPの文字コードの変更

### php.iniを探す
phpの環境で
phpinfo();を見る。

```
Configuration File (php.ini) Path
```
の右側にあるディレクトリにphp.iniがある

### php.iniを変更する

```ini
;default_charset = "UTF-8"
default_charset = "EUC-JP"
```

### 反映させる
phpやMAMPを再起動させれば反映されているはず。
私の環境では、これで文字化けが解決した。

## 参考
- [PHP 5.5 から 5.6 以上に上げると Shift_JIS や EUC-JP のサイトが文字化けする](https://qiita.com/phanect/items/550bc0a1c671a4b9a720)
- [php.iniの場所 php.iniの探し方](http://tweeeety.hateblo.jp/entry/20121218/1355802787)
プロキシ環境でのnikto2.1.5の利用方法

nikto2.1.5の利用時に、プロキシ設定でちょっとハマったためメモします。

### 現象
```  
$ wget http://www.cirt.net/nikto/nikto-current.tar.gz
$ tar -xzvf nikto-current.tar.gz 
$ cd nikto-2.1.5
$ perl nikto.pl -update
+ ERROR (): Unable to get www.cirt.net/nikto/UPDATES/2.1.5/versions.txt
```  
エラーが発生してUpdateに失敗します。

### 対策
```  
$ vim nikto.conf
変更前）
#PROXYHOST=127.0.0.1
#PROXYPORT=8080
変更後）
PROXYHOST=[プロキシホスト名]
PROXYPORT=8080
```  

### 再度実行
オプション "-useproxy" をつけてupdateを実行します。

```  
$ perl nikto.pl -update -useproxy
+ Retrieving 'nikto_cookies.plugin'
+ Retrieving 'db_tests'
+ Retrieving 'db_parked_strings'
+ Retrieving 'nikto_headers.plugin'
+ Retrieving 'nikto_report_csv.plugin'
+ Retrieving 'CHANGES.txt'
+ CIRT.net message: Please submit Nikto bugs to https://github.com/sullo/nikto
```  

正常にアップデートできました！

### 参考にさせていただいたサイト
* [無料のWEBサーバ(apache, http/https)セキュリティ診断ツール](https://qiita.com/end0tknr/items/e087c87d4f356c0516fc)
TypeTalkにAPIでメッセージを投稿する(botを使った方法)

# 概説
typetalkにメッセージを投稿するには、いくつかの方法があります。
公式ドキュメントは下記ですが、パっと見、どういう時にどの方法を使えばいいか、よくわかりませんでした。実際にやってみたり、調べてみたりした事をまとめます。
https://developer.nulab-inc.com/ja/docs/typetalk/

メッセージを投稿するAPIは、下記の通りhttpリクエストを投げるだけ。
https://developer.nulab-inc.com/ja/docs/typetalk/api/1/post-message/
ただ、誰のメッセージとして投稿させるかによって、認証の方法が異なってきます。
一番ゆるい認可レベルで投稿するのは、botに投稿させる方法。これが一番簡単です。

#botに投稿させる
Typetalk上にbotを作成し、そのbotに喋らせるのが一番楽チン。
自分や他の人に喋らせようとすると、本当にその人かどうかを認証したり、認可のプロセスを踏んだりするのが面倒です。
## bot作成
まずは、下記を参考にbotを作成します。
https://developer.nulab-inc.com/ja/docs/typetalk/#tttoken
## メッセージ投稿
「botの設定」画面に、「メッセージの取得と投稿の URL」という欄があるので、そこをめがけてPOSTしてあげればいいだけです。
フォームパラメータとして、"message=[投稿したい内容]"をつけてください。
同じbotの設定画面に「メッセージの投稿コマンドサンプル」もありますので、コピーしてそのままPowerShellで実行すれば投稿できます。
curlのサンプルは↓です。

```
curl -F "message=test" https://typetalk.com/api/v1/topics/:topicId?typetalkToken=:typetalkToken
```
- :topicId -> 投稿したいトピックのID(該当トピックのURL "https://typetalk.com/topics/" の次に入っている数字)
- :typetalkToken -> 「botの設定」画面にある「Typetalk Token」

# OAuth2.0を使用する方法
公式ドキュメントは下記です。
https://developer.nulab-inc.com/ja/docs/typetalk/auth/#oauth2

こっちは、botに喋らせるのではなく、自分や他の人など、既存ユーザに喋らせる方法です。
該当ユーザの発言としてトピックに載ります。
そのため、そのユーザとして投稿する権限を認可させるため、OAuthを使用します。
公式ドキュメントに記載されている内容は、OAuthを勉強しておかないと理解できない部分が多いので注意。

以前javaでサンプル作ったけど、なくしちゃったので掲載できないです、ごめんなさい。

# 最後に
会社とかで通知代わりに使うなら、botを使った方法で十分かと思います。
他のアプリとかで投げられたwebhookを受けてメッセージ出すとかね。Windows10ではcurlが実装されましたので、昔ながらのMS-DOSバッチからでも投稿できます。もちろんPowerShellからも。
Ruby on Rails アソシエーションに関する整理

##設定
Userのテーブルに`name`と`email`のカラム
Contact（問い合わせ）のテーブルに`title`と`content`のカラムがあるとする

```
rails g model User name:string email:integer
rails g model Contact title:string content:integer
```

##外部キーを設定する方法
「1人のユーザーから複数の問い合わせがくる」と考えられるので
contactsテーブルにuser_idを追加する。

```
rails g migration AddUserRefToContacts user:references
```

以下のMigrationファイルが生成される

```
class AddUserRefToContacts < ActiveRecord::Migration[5.1]
  def change
    add_reference :contacts, :user, foreign_key: true
  end
end
```

`rails db:migrate`を実行

テーブルに追加されているかを確認

```
t.bigint "user_id"
t.index ["user_id"], name: "index_contacts_on_user_id"
```

##アソシエーションの設定
`has_many` と` belongs_to`を利用する。

UserはContactを複数するできることから、app/models/user.rbに`has_many`を書き込む。

```
class Author < ApplicationRecord
  has_many :books
end
```
ContactはUserに依存するため、app/models/contact.rb` belongs_to`を書く

```
class Author < ApplicationRecord
  belongs_to :user
end
```
KiCadで特定レイヤーのアニュラリングを抜く

![via.png](https://qiita-image-store.s3.amazonaws.com/0/72075/5f4882bf-68a0-3bac-4c67-42b66c216d0f.png)

# 注意
この方法で実際製造してくれるか、狙い通りに作ってくれるかは業者によると思うので、もし何かあっても文句は言わないでください。(Fusion PCBに出したらとりあえず狙い通りに作ってくれました)

# 問題
KiCad (少なくとも5.0.2以前)はビアの未接続処理がありません。つまり全てのレイヤーにアニュラリングが入ります。
これは大抵の趣味レベル基板であれば別に問題ないのですが、BGAパッケージを配線しようとしたときに内層が狭くなって面倒になります。
1mmピッチで0.6/0.3mmビアを普通に置くとこんな感じになってしまいます。
![normal.png](https://qiita-image-store.s3.amazonaws.com/0/72075/27efee38-f922-8319-f055-545c7dcd42ae.png)


# 解決策
アニュラリングを抜くのではなく、アニュラリング極小のビアを置いて必要な部分だけ配線でアニュラリングを描きます。(タイトル詐欺)

例えば0.6/0.3のビアを置きたければ、0.31/0.3のビアを置いて、0.6mmの配線を必要なレイヤーに書き足します。このとき配線長を0にするとクリアランス判定が効かなくなるので、(0.01mm,0.01mm)長とかにするといいです。
![via2.png](https://qiita-image-store.s3.amazonaws.com/0/72075/afe3a6c7-9dd3-fc7d-6360-11a0f646a018.png)


マウスで書こうとすると大変なので、少なくとも最初の1個は一旦適当に書いてからEキーでプロパティ開いて数値を直接入力して作るといいです。(2個め以降はコピペ、接続する内層を変えたければ、プロパティからレイヤーを変える)ビアの中心からどちら方向に配線を伸ばしたかは適当なレイヤー(*.Userなど)に書いておくとわかりやすいです。
![ex.png](https://qiita-image-store.s3.amazonaws.com/0/72075/00260d2a-ad55-2c1d-7423-340ee7ccdb3c.png)

1mmピッチでビアを置いても普通に置くよりかなり余裕ができます。
![sol1.png](https://qiita-image-store.s3.amazonaws.com/0/72075/6a6331af-d21b-ad5c-d3f8-34ab6d79c850.png)

なおこの方法では出力されるガーバーは0.31mmのViaPadと0.6mmのConductorになります。

# 解決策2
[そういうフットプリント](https://forum.kicad.info/t/optimizing-annular-rings-of-vias-in-inner-layers/1514/4)を作って配置します。
例えばこんな感じ

```
(module via_with_in2_annular_ring (layer F.Cu) (tedit 5C6C9BC3)
  (fp_text reference AN_V** (at 0 0.5) (layer F.SilkS) hide
    (effects (font (size 0.2 0.2) (thickness 0.05)))
  )
  (fp_text value via_annular_th (at 0 -0.5) (layer F.Fab) hide
    (effects (font (size 0.2 0.2) (thickness 0.05)))
  )
  (pad 1 thru_hole circle (at 0 0) (size 0.6 0.6) (drill 0.3) (layers F&B.Cu))
  (pad 1 thru_hole circle (at 0 0) (size 0.6 0.6) (drill 0.3) (layers In2.Cu))
)
```

ただこの方法だとフットプリントのプロパティ開いたりすると普通のスルーホールに戻されるので注意が必要です。
トリックショートカットの作成

#トリックショートカットの作成

**[【ぜんぶポータブル】ポータル](https://qiita.com/jtFuruhata/items/f9788da8e480c646a2a9)**

**最終更新:2019年2月20日**

ここでは、相対パスで指定するショートカット「**トリックショートカット**（勝手に命名）」の作成について説明します。**フルパス指定しなきゃいけないショートカットなんて駆逐されてしまえ**ばいいとせんせは思います。

## 駆逐方法
![2019-02-20-13-29-44.png](https://qiita-image-store.s3.amazonaws.com/0/151581/d9a48330-e096-8b7c-a948-33fa6d7ff29d.png)
まずおもむろにショートカットを作成したいフォルダをWindowsエクスプローラーで開いて、「ホーム」→「新規」→「新しいアイテム」から「ショートカット」を選択します。
![2019-02-20-12-20-20.png](https://qiita-image-store.s3.amazonaws.com/0/151581/edd4e9c2-9120-7154-2d6f-2eb5d2fa02e2.png)
「ショートカットの作成」ダイアログ中`項目の場所を入力してください`欄に、

`%windir%\System32\rundll32.exe url.dll,FileProtocolHandler "apps\win\Code.cmd"`

を**まずはコピペして**ください。手入力しようと思っちゃダメだ。

このコピペした一文最後のダブルクォーテーションの中が、**ショートカットが存在するフォルダからの相対パスで指定する**ファイルの場所です。なお、この作り方ではコマンドライン引数を渡せませんので、そういう方は[下の参考文献](#%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE)でご確認ください。この例ではappsフォルダのwinフォルダのCode.cmdを指定していますのでもちろんこれがなければ何も起こりません、変更して「次へ」ボタンを押してください。
![2019-02-20-12-34-08.png](https://qiita-image-store.s3.amazonaws.com/0/151581/64add7b6-ce5e-f866-960f-c4371f57cb8f.png)
次に、`このショートカットの名前を入力してください`欄に適当な名前を入力して「完了」ボタンを押します。
![2019-02-20-12-40-11.png](https://qiita-image-store.s3.amazonaws.com/0/151581/fc047029-417b-4d97-e46f-942f141630a6.png)
ショートカットが作成されました。でももうちょっと操作しないといけません。作成したショットカットを選択して「ホーム」→「開く」にある「プロパティ」ボタンをクリックします。
![2019-02-20-13-05-56.png](https://qiita-image-store.s3.amazonaws.com/0/151581/5f69e2f9-8544-b2c9-d863-69e43dca8cb8.png)
最初は下の感じで開かれていると思いますが、まず`作業フォルダー`欄に書かれている文字を**全て削除**してください。
![2019-02-20-13-10-14.png](https://qiita-image-store.s3.amazonaws.com/0/151581/a4eb6857-5b7f-2a13-b52d-cd3579f54b43.png)
**アイコン気にしない方はこれで「OK」**です。でもやっぱさみしいので、「アイコンの変更」ボタンを押して、
![2019-02-20-13-08-32.png](https://qiita-image-store.s3.amazonaws.com/0/151581/6c51d86d-6609-cc9d-a0b5-2e1db3dcc632.png)
`このファイル内のアイコンを検索`欄を**おもむろにからっぽにして**から`下の一覧からアイコンを選択`欄をクリックすると
![2019-02-20-13-19-22.png](https://qiita-image-store.s3.amazonaws.com/0/151581/cdb222e1-7f3f-d661-d5c4-55325b4f9a83.png)
自動的にWindows標準のアイコンファイル一覧に飛んでくれるので、なんか適当なやつを選んで「OK」ボタンを押してください。ここはフルパス指定じゃないと参照できないんですよねぇ…
![2019-02-20-13-22-54.png](https://qiita-image-store.s3.amazonaws.com/0/151581/0fdfbadd-c069-7936-0111-8331cfde37b1.png)
以上の設定を確認して「OK」ボタンを押します。
![2019-02-20-13-24-05.png](https://qiita-image-store.s3.amazonaws.com/0/151581/81678cd1-af5a-5ebc-cc41-dca079bf0f67.png)
こんな感じで作っていってください。

## 別にバッチファイルでよくね？
だって**アイコン付けたいじゃないですかぁ**
ちゃんちゃん

## 参考文献
Windows Script Programming「ショートカットに相対パスを指定する。(その２)」
http://scripting.cocolog-nifty.com/blog/2010/03/post-b124.html
2019年2月20日閲覧
neovimのインストール

社内で配布されたvagrantのboxファイルから環境構築を行うときに
vim入れなおさないと・・・
となったため、手順を忘れないためにもメモしておきます

https://github.com/neovim/neovim/wiki/Building-Neovim


## cloneする

```
git clone https://github.com/neovim/neovim.git
```

## make(1回目)

makeを実行する
```
cd neovim
make
```

と、出ましたエラー。

```:error
/bin/sh: line 1: cmake: command not found
```

なので

```
yum install cmake
```

## make(2回目)

```
make
```

67%まで行ったけどエラー・・・

```:error
Could not find an 'unzip' program. Tried: unzip.
```

```
yum install unzip
```

## make(3回目)

```
make
```

いけた!!!!!

## インストール

```
make install
```

## 確認

```
nvim
```

開けた！バージョン0.4！（知らんうちに0.4が出てて余計嬉しい）

だがしかしbut、pythonは認識していない。

```
:echo has('python3')
```

## pythonのインストール

```
python --version
#=> Python 2.7.5
which python3
#=> 無し
```

```
cd /usr/bin
ls python*
```

```:text
lrwxrwxrwx  1 root root      9 Aug 17  2018 python -> python2.7
lrwxrwxrwx  1 root root      9 Aug 17  2018 python2 -> python2.7
-rwxr-xr-x  1 root root   7216 Jul 13  2018 python2.7
```

```
yum install python36
ls python*
```

```:text
lrwxrwxrwx 1 root root     9 Feb 20 10:34 python -> python2.7
lrwxrwxrwx 1 root root     9 Aug 17  2018 python2 -> python2.7
-rwxr-xr-x 1 root root  7216 Jul 13  2018 python2.7
lrwxrwxrwx 1 root root    18 Feb 20 10:12 python36 -> /usr/bin/python3.6
-rwxr-xr-x 2 root root 11408 Jan 27 01:55 python3.6
-rwxr-xr-x 2 root root 11408 Jan 27 01:55 python3.6m
```

```
ln -s python3.6 python3
```

## pipのインストール

```
yum search pip
yum install python36-pip
```

```
ln -s pip3.6 pip3
```

これでpip3が入った。

nvimを開き:checkhealthを実行すると設定手順が書いてある

```:text
## Python 3 provider (optional)
  - INFO: Disabled (g:loaded_python3_provider=1).  This might be due to some previous error.
  - INFO: Using: g:python3_host_prog = "/usr/bin/python3"
  - ERROR: "/usr/bin/python3" was not found.
  - INFO: Executable: Not found
  - ERROR: Detected pip upgrade failure: Python executable can import "pynvim" but not "neovim": /usr/bin/python3
    - ADVICE:
      - Use that Python version to reinstall "pynvim" and optionally "neovim".
          pip3 uninstall pynvim neovim
          pip3 install pynvim
          pip3 install neovim  # only if needed by third-party software
```

pip3でのuninstallが手順1のため試してみる。とエラー
バージョンがどうたら・・・でupgradeしろと。

```
pip3 install --upgrade pip
```

すると/usr/binからpip3が消えて、/usr/local/binにpip3が、、、
よくわからないが存在はするのでokとしてそのまま進めてみる

## pynvimのインストール

```
pip3 install pynvim
pip3 install neovim
```

## 確認

nvimにて

```vim
:echo has('python3')
#=> 1
```
JSON Patch

# Json Patchとは？

Jsonデータに対して追加、削除、移動、コピーなどを行える便利なクラス

例：

```
[
 
{ "op": "test", "path": "/a/b/c", "value": "foo" },
 
{ "op": "remove", "path": "/a/b/c" },
 
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
 
{ "op": "replace", "path": "/a/b/c", "value": 42 },
 
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
 
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
 
]
```

# op | add, remove, replace, move, copy

"op"には
"add","remove","replace","move","copy","test"のいずれかを利用

# AspNetCore.JsonPath

Microsoft.AspNetCore.JsonPatch　から利用可能


# 参照
https://janaks.com.np/implementing-json-patch-in-asp-net-core/
http://jsonpatch.com/
【ぜんぶポータブル】ポータル

# DEPRECATED　【ぜんぶポータブル】プロジェクトは終了しました
今はDockerの時代ですよね。[【ぜんぶポータブル】](https://github.com/jtFuruhata/zenbuHQ)プロジェクトはその昔、GNUベースの開発環境をプラットフォーム依存せずに、しかもインストールなしのポン付けで使えるようにすることを目指したものです。更新はしていませんが、個人的には今でもMSYS使いたいときは外付けSSDにセットアップしたこれを使っていますので、そこそこ便利には便利です。
もう継続開発はしていませんが、このプロジェクトを通して得られた**変態な知見**は、さらに変態感を増した上で **[etrobo環境](https://github.com/ETrobocon/etrobo/)** で活かされています。ぜひこちらの方をご高覧頂ければと思います。

# 【ぜんぶポータブル】ポータル
ここは、[北海道情報大学](http://www.do-johodai.ac.jp) 経営情報学部 システム情報学科の、主に僕の講義で使用するポータブル開発環境の構築資料を制作するにあたって、**どーせ講義資料をクローズドな場所において読まれないぐらいなら、ぐぐラビリティを高めた方がうちの学生にも届きやすいだろう**ということで、事前・事後学習向けのステップバイステップの資料と、そこからスピンオフした技術解説資料を、【ぜんぶポータブル】の旗印のもとにQiitaで公開しちゃおう、というものです。

「こうした方がもっと美しい」「これも書いてほしい」などありましたらコメント頂けるとテンション上がります、よろしくお願いします。

※完成したものから順次アップしてます、まだ大事なところがすっぽり抜けててすみません…

## ステップバイステップ
- [GitHubプライベートリポジトリの作成手順](https://qiita.com/jtFuruhata/items/0f28ebe5828005eae9b7)
    - GitHubのアカウント作成からプライベートリポジトリ作成までの手順です
- [SSHキーを作成してGitHubに登録する](https://qiita.com/jtFuruhata/items/d9d3a8edf1ecfe1c1d23)
    - SSHキーの作成からGitHubプライベートリポジトリをクローンするところまでの手順です
- VSCodeとGitHubプライベートリポジトリな環境の構築手順　`章立て再検討中`
    - Windows10向けに解説した、GitHubのアカウント作成からVSCodeインストールまでの入り口部分です

## トリックTips
- [Linux向けポータブル環境の基本](https://qiita.com/jtFuruhata/items/3bfc6a9fd7bf144ed081)
    - Debian系でポータブル環境を構築する上での基本的な考え方の解説です
- [MacでGitをポータブルインストールする](https://qiita.com/jtFuruhata/items/16ec19050f4557c423b3)
    - MacでGitに一時的なパスを通したターミナルを開く方法です
- [トリックショートカットの作成](https://qiita.com/jtFuruhata/items/58b5631ec27038aa1312)
    - Windows10でリンク先を相対パス指定するショートカットの作成手順です
- [ポータブル環境でVSCodeからGitHubプライベートリポジトリを使う](https://qiita.com/jtFuruhata/items/39166d9f1872076df503)
    - Windows10でGitHubプライベートリポジトリと同期するまでのスクリプト解説です
- [ファイル名が強制的に大文字になるときの対処](https://qiita.com/jtFuruhata/items/8d843009e5c4dad814c7)
    - ↑文字通りです

## よみもの
- [ポータブルデバイスの違いによるパフォーマンスの差](https://qiita.com/jtFuruhata/items/6e862cb4a28095f47fde)
    - やっぱSSDだよね…　という当たり前の結論に至るまでの壮大なストーリー
Overleafを使った日本語論文の作成

Overleafはウェブブラウザ上でtex文書を作成できるクラウドサービス．
texは環境構築が結構面倒なので（昔に比べりゃ楽になったが，時間がかかるのは変わらない），このサービスは非常にありがたい．
ただ，日本語論文を作成するにはちょっとひと手間必要になる．
以下，備忘録として日本語論文作成方法をメモする．

以下のページを参考：
http://doratex.hatenablog.jp/entry/20180503/1525338512

#プロジェクトの作成
まあ，まずはプロジェクトを作らないことには始まらないので，プロジェクトを作成．
Overleafそのものは日本語化されているので，これは簡単にできるはず．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/317916/88d1eb24-0ab4-0e5c-3ef6-53b28793b35f.png)
まあ，まずは空のプロジェクト作成でよいと思う．

作ると勝手にtexファイルも作ってくれる．
試しに日本語を打ち込んでみるが，エラーになって反映されてない．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/317916/e50cc274-ebf5-3b98-6f4c-d2878ac4d8e6.png)

ちなみにコンパイルは`Ctrl+s`でやってくれて，右側ペインに印刷イメージが表示される．
また右側ペインの上の「再編集」というボタンのプルダウンメニューでAuto Compileをオンにすると，手動でコンパイルしなくても都度勝手にコンパイルしてくれる．

#日本語入力の設定
左上の「メニュー」をクリックすると，プロジェクトの設定を触るメニューが現れる．
この中のコンパイラが標準では「pdfLatex」になっているが，これを「Latex」にする．

#latexmkrcの作成
次にプロジェクトに新しいファイルとしてlatexmkrcというファイルを作る．
中身は以下の通り．

```tex:latexmkrc
$latex = 'platex';
$bibtex = 'pbibtex';
$dvipdf = 'dvipdfmx %O -o %D %S';
$makeindex = 'mendex -U %O -o %D %S';
$pdf_mode = 3; 
```
Unicodeに対応させたいなら以下の通り。

```tex:latexmkrc
$latex = 'uplatex';
$bibtex = 'upbibtex';
$dvipdf = 'dvipdfmx %O -o %D %S';
$makeindex = 'mendex -U %O -o %D %S';
$pdf_mode = 3; 
```

この中身が意味しているものはよー分からんでも，とにかく上記のとおりに打つ．

これを作ったら，あとはソースファイルをコンパイルすれば日本語が表示される．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/317916/f0bd81b6-13b7-f353-9298-373d6ce95f2a.png)

ちなみに、上の図の例では、初期設定で入っている`\documentclass{article}`のままにしていますが、日本語を使った文書作成をするのであれば、`\documentclass{jsarticle}`とした方が良いです。
また、Unicodeを使うのであれば、`\documentclass[uplatex]{jsarticle}`としてください。

#ソースファイル内の設定
学会等で提供されているクラスファイルやフォーマットを使うことは多いだろう．
それらをOverleafのプロジェクトにそのままアップロードして，うまく使えればよいが，中には古いウィンドウズのTex環境下で作られていてうまく動かないこともある．
そんな場合には，次の点をチェックしてみるとよい．
###\documentclassの設定
ソースファイルの冒頭でクラスファイルを設定する際に，古いものだと以下のように記述していることがある．

```tex:
\documentclass[dviout]{xxxxx}
```
この`[dviout]`を`[dvipdfmx]`に書き換える必要がある．
（ちなみに，完全に余談だが，スタンドアロンのLinuxでtexworkを使ってたときは[xdvi]にしてた）

###ソースファイルのエンコード
アップロードをする際に，ソースファイルのエンコードがShift-jisやEUCだと日本語の文字化けが起こる．
なので，アップロードの際にはutf-8にエンコードしなおしておくこと．


#参考
以下は参考リンク


https://doratex.github.io/misc-files/excel2tabular/
表をtexのtablur形式に変換してくれるWebサービス．
エクセルからコピペできるので非常に便利．
ただ，あんまりエクセルで細かく加工したものを貼り付けるのは得策ではない．
あくまで「入力支援」としてセルの値の入力を助けてくれるものと考えて，細かなセルの加工や罫線の引き方の設定はtexで直接いじる方が

https://wiki.lyx.org/Windows/MetafileToEPSConverter
EMFやWMF（要はパワポで作った画像など）をEPSに変換してくれるアプリ
Webサービスで良いのがあればうれしいんだが，なかなか見つからない．
ということで，普段使うときは，このアプリをインストールしてつかってる．

# Error 対策
PNGやJPG画像を貼り付けようして`Cannot determine size of graphic`っていうエラーでうまく画像がはれなくなった。
ネットで調べると、スタンドアロンのTeX環境での対応方法の説明はあるんだけど、Overleafでそれらの方法をとることは無理そう。
どうしようか、、、、と悩みつつ、さらにネットで調べてると、[このページ](https://eqseqs.hatenablog.com/entry/2019/03/21/194617) に行きついた。
どうも名前に問題があったらしい。
今回のファイル名はWindowsの複数ファイルを一度にリネームすると勝手に連番を振ってくれる機能を使ってつけたファイル名なので、スペースであったり半角括弧がついたりしていた。
これらをすべてアンダーラインに置き換えたら正しく処理してくれるようになった。
centos gitを最新バージョンに上げる

https://qiita.com/suke/items/ee0033a2ee9e68eee13e
を参考にさせていただきながら手順を備忘録として自分でもメモしておく


## 既存のgitの削除

```
su -
yum remove git
```

## IUSリポジトリの登録

最新バージョンのものをyumで取得するための作業です

```
yum -y install https://centos7.iuscommunity.org/ius-release.rpm
```

そして、IUSはCentOSから正式に認証されているが、公式ではないのでデフォルトで使用されるリポジトリから外したほうがよいらしい　とのことなので

```
vi /etc/yum.repos.d/ius.repo
```


```:text
[ius]
...（略）...
enabled=0 #enabled=1から変更
...（略）...
```

## 最新のgitをインストール

```
yum install git --enablerepo=ius --disablerepo=base,epel,extras,updates
```

すると出ました。エラーが。

```:error
Requires: libsecret-1.so.0()(64bit)
```

こちらをしてから再度行うと解決しました

```
yum install libsecret
```


バージョン上がったー！！

```
git --version
#=> git version 2.16.5
```
Koinを使ってActivityやFragmentをInjectionする

Koinを使ってActivityやFragmentを注入する方法です。

# 前提とするシチュエーション
FluxのActionCreatorのようなクラスにおいて、
LifecycleOwnerとしてActivityやFragmentを注入しておき、
必要に応じてビジネスロジックを中断する事を想定しています。


# 実装

### Activityを注入するクラス

あくまで例ですが、LifecycleOwnerとしてActivityを注入したいケースは多々あるかと思います。

```kotlin
class ActionCreator(lifecycleOwner: LifecycleOwner) : LifecycleObserver {

    init {
        lifecycleOwner.lifecycle.addObserver(this)
    }
}
```

### Koin Module

Koin moduleの`factory`メソッドには引数`ParameterList`があります。Koin内で定義されたクラスです。動的に渡すパラメータを格納するList型のラッパーです。
この`ParameterList`からLifecycleOwnerを取り出すことにします。

```kotlin
module {
    factory { 
        ActionCreator(it.get<LifecycleOwner>() as LifecycleOwner)
    }
}
```

また、`ParameterList`は分解宣言に対応しているため、以下のような利用も可能です。

```kotlin
module {
    factory { (lifecycleOwner: LifecycleOwner) -> ActionCreator(lifecycleOwner) }
}
```

### Activity

ActivityではActionCreatorをinjectしますが、このとき自分(LifecycleOwner)を含んだ`ParameterList`を渡します。

```kotlin
class MainActivity : AppCompatActivity() {

    val actionCreator: ActionCreator by inject { parametersOf(this) }
}
```

# 拡張

冗長な記述を拡張関数でコンパクトにしてみます。

```kotlin
// for Activity
fun <R> R.defaultParameterDefinition(): ParameterDefinition
        where R: ComponentCallbacks, R: ComponentActivity {
    return { parametersOf(this) }
}
inline fun <reified T : Any, R> R.injectMySelf(name: String = "", scope: Scope? = null)
        where R: ComponentCallbacks, R: ComponentActivity
        = lazy { get<T>(name, scope, defaultParameterDefinition()) }

// for Fragment
fun <R> R.defaultParameterDefinition(): ParameterDefinition
        where R: ComponentCallbacks, R: LifecycleOwner {
    return { parametersOf(this) }
}
inline fun <reified T : Any, R> R.injectMySelf(name: String = "", scope: Scope? = null)
        where R: ComponentCallbacks, R: LifecycleOwner
        = lazy { get<T>(name, scope, defaultParameterDefinition()) }
```

`injectMySelf`は自分自身をinjectするプロパティデリゲートを生成します。

ActivityやFragmentでは以下のように利用できるはずです。

```kotlin
class MainActivity : AppCompatActivity() {

    val actionCreator: ActionCreator by injectMySelf()
}
```
JSUG勉強会 参加レポート


# 「JSUG勉強会 2019その2 Spring BootベースのDDDサンプル徹底解説！」

|[![thumbnail](http://image.slidesharecdn.com/ddd-sample-explained-190218045313/95/slide-1-1024.jpg)](https://www.slideshare.net/masuda220/ddd-sample-code-explained-in-java?fbclid=IwAR06AaVVzGrGuMKvRnmL0-RndnnVDxpg0g8j2lA_4tgfgtwtocgTczNK2Ks)|
|:-:|

2019/02/18（月） に開催された、  
[JSUG勉強会 2019その2](https://jsug.doorkeeper.jp/events/86655)  に参加しました。

## なぜ作ったか？
- 実アプリケーション並の具体例がほしかった
- コードが一番具体的に伝えることができる
- 質問が具体的になり、考え方の違いがハッキリする

## ドメイン駆動設計の具体例
- ビジネスルールが複雑さの原因
- 計算をモデリング
- 型指向でプログラミング  
…この３つが***ドメイン駆動設計の核心***

## 関心の分離
- 計算（ビジネスルール）を実行するモジュール群
- データを入出力するモジュール群  
  …この２つを分ける  
  　同じモジュール（ソースファイル）に「計算」と「入出力」を書かない 

## サンプルコード解説
["Isolating the Domain" サンプルコード（GitHub）](https://github.com/system-sekkei/isolating-the-domain)
[設計ガイドライン](https://github.com/masuda220/business-logic-patterns/wiki/%E8%A8%AD%E8%A8%88%E3%82%AC%E3%82%A4%E3%83%89%E3%83%A9%E3%82%A4%E3%83%B3)

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/65426/b50d5352-8ce8-8020-c1df-7a3b8628fe8c.png)|
|:-:|

## 給与計算
  - [isolating-the-domain/src/main/java/example/domain/model/payroll/Payroll.java](https://github.com/system-sekkei/isolating-the-domain/blob/master/src/main/java/example/domain/model/payroll/Payroll.java)
  - 計算ロジックのアグリゲートクラス

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/65426/d1e4d517-f1e9-767a-dcfd-0be60b1f4409.png)|
|:-:|

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/65426/00c39973-a8a7-fc80-9193-0611b2996755.png)|
|:-:|

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/65426/5e520e42-ccc9-ba5f-6533-f76e309b852a.png)|
|:-:|

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/65426/4a7f5c46-71d1-ca71-71cd-f3b1c2daa822.png)|
|:-:|

|![image.png](https://qiita-image-store.s3.amazonaws.com/0/65426/db7eea77-aee0-a8f1-9215-764be787306a.png)|
|:-:|

## ビジネスルールの設計ドキュメント（JIG）
[JIG (GitHub)](https://github.com/dddjava/Jig)

- コードから自動生成
- 設計レビューの補助(冶具）

## Q&A
- 大規模開発でオフショアするときの考え方について
  - 構造が固まった段階で、部分的にオフショア
  - 少人数で密にするのが理想  
  ※その他、多くの質疑応答がありました。

## その他
会場で「現場で役立つシステム設計の原則」を頂きました！

<img src="https://qiita-image-store.s3.amazonaws.com/0/65426/d553b4da-8d8c-38f1-ed07-7a7d161839dd.jpeg" width=25%>