OmniAICreator/Qiita-1.07M huggingface dataset:
Nikto 2.1.6で脆弱性チェックをしてみる

セキュリティ勉強中です。脆弱性チェック、ちゃんとしていきたいですよね。

# はじめに
Nikto 2.1.6が現在のところ最新版です。
https://github.com/sullo/nikto/tree/2.1.6

脆弱性チェックしたいWebサーバにインストールし実行してみます。

# インストール方法
```shell
$ git clone https://github.com/sullo/nikto
$ cd nikto
$ git fetch --tags
$ git checkout -b {ブランチ名} refs/tags/2.1.6
$ cd program
$ perl nikto.pl
- ***** SSL support not available (see docs for SSL install) *****
- Nikto v2.1.6
---------------------------------------------------------------------------
(略)
```

# 使用方法
ローカルホストに対し脆弱性チェックを実行します。

```
$ perl ./nikto.pl -h 127.0.0.1 -C all
- ***** SSL support not available (see docs for SSL install) *****
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          127.0.0.1
+ Target Hostname:    127.0.0.1
+ Target Port:        80
+ Start Time:         2019-04-24 15:52:06 (GMT9)
---------------------------------------------------------------------------
+ Server: Apache/2.X.X (CentOS) PHP/7.X.XX
+ Server leaks inodes via ETags, header found with file /, fields: 0x16 0x5864c8524d6c6
+ The anti-clickjacking X-Frame-Options header is not present.
+ The X-XSS-Protection header is not defined. This header can hint to the user agent to protect against some forms of XSS
+ The X-Content-Type-Options header is not set. This could allow the user agent to render the content of the site in a different fashion to the MIME type
+ Apache/2.X.X appears to be outdated (current is at least Apache/2.4.12). Apache 2.0.65 (final release) and 2.2.29 are also current.
+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS, TRACE
+ OSVDB-877: HTTP TRACE method is active, suggesting the host is vulnerable to XST
+ OSVDB-3268: /icons/: Directory indexing found.
+ OSVDB-3233: /icons/README: Apache default file found.
+ 26146 requests: 0 error(s) and 9 item(s) reported on remote host
+ End Time:           2019-04-24 15:52:33 (GMT9) (27 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
```

こんな感じで脆弱性がリストアップされます。
それぞれ対応していって、こんな感じに減らしていきます。Apacheの対応策はこのあたりの記事が詳しかったです。

* [Apacheセキュリティ設定](https://qiita.com/bezeklik/items/1c4145652661cf5b2271)


```
$ perl ./nikto.pl -h 127.0.0.1 -C all
- ***** SSL support not available (see docs for SSL install) *****
- Nikto v2.1.6
---------------------------------------------------------------------------
+ Target IP:          127.0.0.1
+ Target Hostname:    127.0.0.1
+ Target Port:        80
+ Start Time:         2019-04-24 15:38:30 (GMT9)
---------------------------------------------------------------------------
+ Server: Apache
+ Server leaks inodes via ETags, header found with file /, fields: 0x16 0x5864c8524d6c6
+ Allowed HTTP Methods: GET, HEAD, POST, OPTIONS
+ 26147 requests: 0 error(s) and 2 item(s) reported on remote host
+ End Time:           2019-04-24 15:39:01 (GMT9) (31 seconds)
---------------------------------------------------------------------------
```

ETagsの対応方法はよくわからなかったです、ご存知の方、コメントいただけると幸いです。

# おわりに
最近NiktoもDockerコンテナ化されていて、DevSecOpsに導入しやすいようになってますね。弊社はまだSecの部分は自動化できていないですが、うまくこの辺りを使ってなんとかしたいです。
HTMLボタンを押したら遷移する

#HTMLボタンを押したら遷移する
4月で新人さんが入ってきているのと、化石のような書き方(*無駄なonclick)を見てクラっときたため、遷移ボタンについて残しておきます。
IE11/Chrome/Firefoxでの動作は確認しました(2019/04現在)。
caniuse.comでも大丈夫そうです。

##遷移だけする(フォームは送信しない)
```html
<a href="(URL)">
	<button type="button">(テキスト)</button>
</a>
```
メリット：
・マウスオーバーで遷移するURLがわかる
デメリット：
・aタグにあてたCSSが干渉する可能性がある

##フォームを送信して遷移する
```html
<button type="submit" formaction="(URL A)" name="button_a" >(テキスト)</button>
<button type="submit" formaction="(URL B)" name="button_b">(テキスト)</button>
```
メリット：
・送信ボタンごとに押した遷移先がHTML側で変えられる。

```html
<form method="post" id="(フォームID)">
    <input type="text" name="" value="my data"/>
</form>
<p>くぁwせdrftgyふじこlp</p>
<button type="submit" formaction="(URL A)" form="(フォームID)">(テキストA)</button>
<button type="submit" formaction="(URL B)" form="(フォームID)">(テキストB)</button>
```
メリット：
・form属性をbuttonタグに入れると、formの外にボタンが定義できる。

##今どきやめようぜ
```html
<button type="button" onclick="location.href='(URL)'">(テキスト)</button>
<input type="submit" value="(テキスト)">
```
・HTMLにJavaScriptを書くのは基本的にやめましょう。バグ調査で時間ロスするかもしれません。
・ボタンテキスト表示のために入れた<input type="submit/button">のvalue属性が送信されるのは無駄です。
クックパッドの海外展開におけるSREの役割と挑戦を読んだメモ

[クックパッドの海外展開におけるSREの役割と挑戦](https://logmi.jp/tech/articles/321120)を読んだ感想的なものです。

> 海外展開におけるSREの役割です
> クックパッドのSREの役割は、ユーザー体験の最大化とプロダクト開発のしやすいプラットフォームの開発
> ユーザーと開発者の幸せが僕たちの目的の本質

ゼミでもテーマが開発者を幸せにするには的なところあるけど、そこに+αでユーザが入ってくるんだな。
アジャイル開発宣言の原則でも **顧客満足を最優先し、
価値のあるソフトウェアを早く継続的に提供します** ってあるけどそのものだなと。

> プロダクションで発生したアラートはすべて日本のSREが受けて一次対応するという開発体制が敷かれているため

マジか( ﾟдﾟ )ｸﾜｯ!!

> プロダクトオーナーと開発者とSREの3者で、可用性の目標が握れていないこと

それそれ

> DDDや逆コンウェイの法則など、すでに概念として知っているものを実際に試せる

DDD?逆コンウェイの法則？？？調べるか。

> 僕が考える自律的なチームが成功するために必要な4つの鍵ですが、規律・自由・責任・最適化

fmfm

> 人はやりたいことをしている時に一番力を発揮すると考えており、また、組織として機能するには、全体として譲ることのできない制約が必要だと考えているからです

やりたくないことしてる時はモチベも低いしスピード感ないよね。

> Athenaでの検索は、ログが発生してから数分間、開発者がそのログを検索できないという問題がありました
> Athenaに加えてElasticsearchを導入して、直近のログ検索のみ、ElasticsearchとKibanaで行えるようにしました

なるほど。うちだとStackdriver loggingが割とリアルタイムに見れるけどフィルターがちょっと難しかったりするかな。
SQL書いて件数取りたいとかだとBQ使うけどdata flowで取り込まれるまでの数分の時間差がこれと同じ環境なんだろうな。
【zsh】g=git, d=docker,k=kubectlのような一文字aliasに補完をキかせる 


# はじめに
今まで`$ git`は`$ g` , `$ docker`は`$ d` といったように1文字aliasを登録していた。

また、zshの補完を強くするために[zsh-users/zsh-completions](https://github.com/zsh-users/zsh-completions)等を用いていた。

だがaliasにより縮めたコマンドにはzshの補完や、上記プラグインの補完が効かなかったので補完をきかせるようにした。

```shell:.zshrc
alias g='git'
compdef g=git
alias d='docker'
compdef d=docker
alias fig='docker-compose'
compdef fig=docker-compose
alias k='kubectl'
compdef k=kubectl
```
[dotfiles/.aliases.sh at 0a380bee3f3eac14d14a6295a862d42d838efefc · 2357gi/dotfiles](https://github.com/2357gi/dotfiles/blob/0a380bee3f3eac14d14a6295a862d42d838efefc/.aliases.sh#L18)

~~ちなみにcompdefにて登録すれば`alias g='git'`を記述する必要はない。~~
訂正: そんなことはなかった。失礼しました。



ちなみに.gitconfigに記載したaliasの設定もこれで拾ってくれます。好き。
[dotfiles/.gitconfig.local.template at master · 2357gi/dotfiles](https://github.com/2357gi/dotfiles/blob/master/.gitconfig.local.template#L11)


# おまけ　各種補完
### railsとかdockerとかgitとか幅広くいろいろ補完してくれるやつ
冒頭でも言及したやつ

```shell
$ brew install zsh-completions
```

```zsh:.zshrc
+ fpath=(/path/to/homebrew/share/zsh-completions $fpath)

+ autoload -U compinit
+ compinit -u
# 既に記述がある場合は適宜調整してね
```

### docker-composeの補完

```shell
$ mkdir -p ~/.zsh/completion
$ curl -L https://raw.githubusercontent.com/docker/compose/$(docker-compose version --short)/contrib/completion/zsh/_docker-compose > ~/.zsh/completion/_docker-compose
```

```zsh:.zshrc
　︙

+ fpath=(~/.zsh/completion $fpath)
```

### kubectlの補完

```zsh:.zshrc
+ source <(kubectl completion zsh)
```
これ中身おもろいです。
`kubectl completion zsh`で標準出力なので中身覗いてみてください
vim-better-whitespace で "Whitespace found, delete it?" と聞かれるようになった時の対処法

Vimで行末の無駄なスペースを削除してくれるプラグイン [vim-better-whitespace](https://github.com/ntpeters/vim-better-whitespace/) で、 `Whitespace found, delete it?` と確認を求められるようになってしまった時の対処法。

![confirm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35647/f730f57a-71e6-93cb-4c00-49f0f4dd7f93.png)

設定ファイルに以下の内容を追記することによって、確認無しで消してくれるようになる。

```vimscript

let g:strip_whitespace_confirm = 0
```

昔はこんな確認されること無かったんだけどな、と思って調べてみたら [Refactor #100](https://github.com/ntpeters/vim-better-whitespace/pull/100) というPull Requestの [このコミット](https://github.com/ntpeters/vim-better-whitespace/pull/100/commits/98b7902fab43a3aeb412192ba829d56a408baed1) で変更が入ったみたいだ。
【JavaScript】 JSで0埋めして桁数を揃える（ゼロパディング）

# やりたいこと
複数の数字の桁数を０で埋めて揃えたい

これを

```
1
2
3
...
98
99
100
```

こう！！
↓↓↓

```
001
002
003
...
098
099
100
```


# こうやる

```js:zero_padding.js
const minNumber = 1; // 最小値
const maxNumber = 100; // 最大値
const digitNumber = 3; // 桁数

const ZeroPadding = (number, digit) => {
  const zeros = Array(digit + 1).join(0); // 桁数分の'0'を文字列として生成 => 000
  const zerosJoinNumber = zeros + number; // 000の末尾にnumberを結合 => 0001 〜 000100
  const zeroPaddingNumber = zerosJoinNumber.slice(-digit); // 末尾から桁数分切り出す　=> 001 〜 100
  return zeroPaddingNumber;
};

// minNumber 〜 maxNumberの間でループ
for (let count = minNumber; count <= maxNumber; count++) {
  const result = ZeroPadding(count, digitNumber);
}

```

# 追記
コメントにて@altさんにスマートなやり方を教えて頂きました。
ありがとうございます、勉強になりました！

```js
console.log(...[...Array(100)].map((_, i) => `${i + 1}`.padStart(3, 0)));
```
Navigation+BottomNavigationViewでActivityにあるActionBarの戻るボタンを消す

Navigation+BottomNavigationViewの実装方法はこの記事がわかりやすいです。

[BottomNavigationView と Navigationを一緒に使う - Qiita](https://qiita.com/superman9387/items/d373c8bddfe2243a49a7)

これで実装したときに、最初に表示されるFragment以外ではActionbarに「←」ボタンが表示されてしまいます。

Activityの`setupActionBarWithNavController`にトップレベルのFragmentの`id`をセットした`AppBarConfigration`を渡すことで消せます。


```kotlin:MainActivity.kt
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Navigation.findNavController(this, R.id.nav_host_fragment).also {
            setupActionBarWithNavController(it,
                AppBarConfiguration(
                    //navigation.xmlに設定したidのセットを渡す
                    setOf(R.id.dest_home, R.id.dest_items)
                )
            )
            bottom_nav.setupWithNavController(it)
        }
    }
```
Kotlin、Dagger2、Architecture Componentという構成でDagger Missing Bindingに苛まれる！

#Kotlin、Dagger2、Architecture Component
この構成については、[Kotlin + Architecture Component + Dagger2によるAndroidアプリ設計](https://qiita.com/satorufujiwara/items/0f95ccfc3820d3ee1370)こちらが圧倒的に分かりやすいのでご参考までに。

んでだ、鼻歌交じりに開発してみると、
**ViewModelProvider.Factory cannot be provided without an @Provides-annotated method**
って急に怒られ出したので、悪戦苦闘してプンスカして、解決したので怒りの投稿。
約4日ハマりました。

##解決
kotlin_version = '1.3.30'
↓
kotlin_version = '1.3.21'
以上。
参考
https://youtrack.jetbrains.com/issue/KT-30979

30のバグなのか、それとも記法ややり方が変わったのか、その情報に到達できなかったので暫定対応ではあります。
そもそも情報が少なすぎて探すのに手間取ったっていうのが最大の要因でしたとさ。
Cognos Analytics レポートでcase文を使用する

#case文の使用
例えば製品ラインが「キャンプ用品」の時は、数量は「0」で表示したい、2013年は消費税8%で計算したい、など、特定の条件の時に数値を操作するcase文の使用方法を学習します。
![010.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/6a5fc993-dfbb-761a-d8ff-bb411673da84.jpeg)



#手順
レポートを新規に作成して、クロス集計を配置。
画像のように、行に「製品ライン」、列に「年」、クロス集計の交点に「数量」を配置。
![003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/ca247a47-995f-75fe-adf6-110e36f36423.jpeg)


レポートを実行すると以下のイメージ。
![004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/6fccf802-8fc4-bbed-e479-5816b328bfe4.jpeg)

例えば、「キャンプ用品」の数値は表示したくないとする。

「クエリー1」に移動し、「数量」をダブルクリックして以下のように編集する。
ここで、case文の中にある[製品ライン]は、赤枠の左から2番目のタブから[製品ライン]から持ってくる事で、「クエリー1」上で既に取得している「製品ライン」を再利用する事ができる。
**case
when [製品ライン] = 'キャンプ用品' then 0
else [販売 (クエリー)].[販売の実状].[数量]
end**
![006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/20a04c4e-f379-aab3-9ea3-621b79351c0a.jpeg)

レポートを実行すると、キャンプ用品の数値が0になっている。
![007.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/0fa58c1d-2045-cc79-f29e-196d9f175661.jpeg)

再度レポートのクエリー1の「数量」を編集し、2013年は消費税8%を計算する式を入れてみる。
case
when [製品ライン] = 'キャンプ用品' then 0
**when [年] = '2013' then [販売 (クエリー)].[販売の実状].[数量] * 1.08**
else [販売 (クエリー)].[販売の実状].[数量]
end
![008.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/93826d5a-d6bb-6e8c-c905-75562f1e237e.jpeg)

レポートを実行すると、2013年のデータは1.08倍されている。
![009.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/cd631e62-b1ad-6063-e182-9687fe23cda3.jpeg)

※参考
If文でも同じ様な条件分岐ができるが、条件が複雑な場合case文の方が書きやすい。
**if ([製品ライン] = 'キャンプ用品') then (0)
else if ([年] = '2013') then ([販売 (クエリー)].[販売の実状].[数量] * 1.08)
else ([販売 (クエリー)].[販売の実状].[数量])**


#自己学習記事一覧
**Cognos Analytics をエンドユーザーの方に自己学習して頂くためのサイト**
https://qiita.com/shinyama/items/95885c7246dc413b6448
LaravelのクエリビルダのOR条件をループで設定する

以下のようなSQLをクエリビルダで設定する場合

```
SELECT
 *
FROM
 table
WHERE
 (column1 like '%test%'
 OR column2 like '%test%'
 OR column3 like '%test%'
 OR column4 like '%test%'
 OR column5 like '%test%')
```

こんな感じでできたのでメモ

```
$columns = [
  'column1',
  'column2',
  'column3',
  'column4',
  'column5',
];

$query->where(function ($query) use ($columns, $data) {
  $i = 0;
  foreach ($columns as $column) {
    $where = (!$i) ? 'where' : 'orWhere';
    $i++;
    $query->$where("table.{$column}", 'like', '%' . $data . '%');
  }
});
```
plenvでPerl環境の構築 (with homebrew)

##目的
アプリケーションを動かすのに、Perlのモジュールをインストールする必要があった
もともと入っていたPerlはバージョンが古すぎてアプリケーションが動かなかった
ついでに新しめのバージョンにしてみた

普段はPerlはあんまり使っていない
何をやったか（やらかしたか）のメモ

##マシン環境
Mac mini(2018)
Mac OS Mojave

##手順
###plenvをHomebrewでインストール

```
$ brew update
$ brew install plenv
```

perl-buildはhomebrewで入れない(エラーになる）

```
$ git clone git://github.com/tokuhirom/Perl-Build.git ~/.plenv/plugins/perl-build/
```

Homebrewが以下を`.bash_profile`に書き加えろ、と指示してきたのでその通りにした。

```
if which plenv > /dev/null; then eval "$(plenv init -)"; fi
```
###cpanmのインストール

```
$ brew install cpanminus
```
この後、brewでインストールしたcpanmを一度アンインストールして、
plenvでインストールし直したらモジュールの移植ができなかったので、
改めてbrewでインストールをし直した

`.bash_profile`に以下を追加(homeフォルダにlocalという新しいフォルダができる）

```
export PERL_CPANM_OPT="--local-lib=~/local/lib/perl5"
export PERL5LIB=$HOME/local/lib/perl5/lib/perl5:$PERL5LIB;
```

###Perl別バージョンのインストール
5.29.10が最新だったけど、あえて安定性を考えて一つ前にしてみた

```
$ plenv install 5.28.2

plenv versions
* system (set by /Users/hoge/.plenv/version)
  5.28.2
```

###有効バージョンの変更
```
$ plenv global 5.28.2
$ plenv versions
  system
* 5.28.2 (set by /Users/hoge/.plenv/version)
```

###systemのperlに入れていたモジュールを移植
```
$ plenv migrate-modules system 5.28.2
```

##やってみて思ったこと
- plenvとhomebrewが混在している感がある
- 動けばいいのだけど、バージョン依存だと後で面倒？
- また気がついたら追記
【Go言語のフレームワークBeego】ORMの使い方

# BeegoのORマッパー

1. 準備  
データベース構造のモデルを用意
2. SELECT  
2. INSERT  
3. UPDATE
2. InsertOrUpdate
2. DELETE  


## 1. 準備  

- Userテーブル

|ID  |NAME  |
|----|------|
|1   |鈴木  |
|2   |佐藤  |

- Profileテーブル

|ID  |Age  |User  |
|----|------|---------|
|1   |鈴木  |1        |
|2   |佐藤  |2        |


```model.go
package main

import (
    "github.com/astaxie/beego/orm"
)

type User struct {
    Id          int
    Name        string
}

type Profile struct {
    Id          int
    Age         int16
    User        *User   `orm:"reverse(one)"` // Reverse relationship (optional)
}
```


```
Delete(interface{}) (int64, error)
LoadRelated(interface{}, string, …interface{}) (int64, error)
QueryM2M(interface{}, string) QueryM2Mer
QueryTable(interface{}) QuerySeter
Using(string) error
Begin() error
Commit() error
Rollback() error
Raw(string, …interface{}) RawSeter
Driver() Driver
}
```



- BeegoではQueryTableを使用してDBを操作するQuerySeterを作成する。
- QueryTableの引数は「”テーブル名”」または「モデルをNewしたもの」

```
o := orm.NewOrm()

// テーブル名直打ち
qs := o.QueryTable("user")

 - // モデル（Struct）を使った場合
user := new(User)
qs = o.QueryTable(user) // return a QuerySeter
```


## 2. SELECT  

```sample.go
// すべてのデータの場合
o := NewOrm()
var users []User
o.QueryTable("user").Filter("Id", 1).All(&users, "Id", "Name")

// 単一データの場合
var users []User
o.QueryTable("user").Filter("Id", 1).All(&users, "Id", "Name")
```

 - Filterは条件
 - QueryTableはテーブル名(モデルも使える)


## 3. Insert

- 単一行のINSERTの場合

はじめに各ORMの関数一覧と戻り値の型の確認
Insert(interface{}) (int64, error)
InsertMulti(int, interface{}) (int64, error)


```sample.go
o := orm.NewOrm()
var user User
user.Name = "谷岡"

id, err := o.Insert(&user) //戻り値のIdはint64
if err == nil {
    fmt.Println(id)
}
```
- 複数行のINSERTの場合

```sample.go
o := NewOrm()
users := []User{
    {Name: "slene"},
    {Name: "astaxie"},
    {Name: "unknown"},
    ...
}
successNums, err := o.InsertMulti(len(users), users)
```


## 4.UPDATE
はじめに各ORMの関数一覧と戻り値の型の確認
Update(interface{}, …string) (int64, error)

```
o := orm.NewOrm()
user := User{Id: 1}
if o.Read(&user) == nil {
    user.Name = "MyName"
     
    //戻り値のnumはint64
    if num, err := o.Update(&user); err == nil { 
        fmt.Println(num)
    }
}
```

##5 Insert or Update

```sample.go
o := NewOrm()
var user User
user.id = "1"
user.Name = "鈴木さん"
r, e := o.InsertOrUpdate(user) //モデルの値によって主キーを検索し、存在すれば更新、存在しなければ挿入処理を行う。
r, e := o.InsertOrUpdate(user, "name=鈴木君") //modelにない値の指定は第二引数で行う
```
`InsertOrUpdate()`を使用する場合注意点があり、structのormの記述にautoを入れると全て新規レコードとしてinsertされてしまいます。

```models.go
type Shikaku struct {
	// pkにautoは必要なし
	Shikaku_id           int64  `orm:"pk"` //ここにautoを設定しては行けない
	Shikaku_name         string `json:"shikakuName"`
```


## 6.DELETE
はじめに各ORMの関数一覧と戻り値の型の確認
Delete(interface{}) (int64, error)

```
o := NewOrm()
//戻り値のnumはint64
o.Delete(&User{Id: 1}) //userテーブルのIDが1のレコードを削除
```

## 生のSQLを書く方法
直接クエリを書く場合

```sample01.go
o := NewOrm()
var r orm.RawSeter
r = o.Raw("select user WHERE name = ?", "佐藤")
// r {[id:2, name:佐藤]}        |

```
別途まとめました
[BeegoのORMの使い方(RAWで生のSQLを書く)](https://qiita.com/ken0renaissance/items/458139aa6dde69a5f01b)

[URL:DMLの使い方（公式）](https://beego.me/docs/mvc/model/query.md)
円と線分の交差判定

# 円と線分の交差判定
Unityで使える円と線分の交差判定です。

## コード
```csharp:IsLineIntersectedCircle.cs
/// <summary>
/// 円と線分の交差判定
/// </summary>
private bool IsLineIntersectedCircle( Vector2 a, Vector2 b, Vector2 p, float radius )
{
	Vector2 ap = p - a;
	Vector2 ab = b - a;
	Vector2 bp = p - b;
	Vector2 normalAB = ab.normalized;

	float lenAX = Vector2.Dot( normalAB, ap );

	float shortestDistance = 0.0f;
	if ( lenAX < 0 )
	{
		shortestDistance = ap.magnitude;
	}
	else if( lenAX > ab.magnitude )
	{
		shortestDistance = bp.magnitude;
	}
	else
	{
		shortestDistance = Mathf.Abs(Vector3.Cross(normalAB, ap).magnitude);
	}

	Vector2 X = a + ab * lenAX;
	return shortestDistance < radius;
}
```
# 参考
http://mslabo.sakura.ne.jp/WordPress/make/processing逆引きリファレンス/円と線分の当たり判定を行うには/
51歳からのプログラム　備忘録　DBクエリ　Eloquent　get()  　first()

**Collection Object/ stdClass Object/ Model Object**
--

いつも迷うので備忘する。
DBクエリでのget(),first()と、Eloquentのget(),first()とで、取得できるデータの違い。
以下のような内容で検証。

・　DBクエリ　first()の結果
・　DBクエリ　get()の結果
・　Eloquent first()の結果
・　Eloquent get()の結果

・　DBクエリ　first()の結果イメージ
・　DBクエリ　get()の結果イメージ
・　Eloquent first()の結果イメージ
・　Eloquent get()の結果イメージ

<p>
DBクエリ　first()の結果
--
`$user=DB::table('users')->where('id',$id)->first();`

```
stdClass Object
(
    [id] => 2
    [user_id] => 2
    [name] => 
)
```
**取得**
`$user->id;`

DBクエリ　get()の結果
--
`DB::table('users')->where('id',$id)->get();`

```
Illuminate\Support\Collection Object
(
    [items:protected] => Array
        (
            [0] => stdClass Object
                (
                    [id] => 2
                    [user_id] => 2
                    [s_name] => 
                )
        )
)
```
**取得**
`foreach();`
`collectionメソッド`

Eloquent first()の結果
--
`User::where('id',$id)->first();`

```
App\User Object
(
    [attributes:protected] => Array
        (
            [id] => 2
            [user_id] => 2
            [s_name] =>
        )
)
```
**取得**
`$user->id`
`$user['id']`

Eloquent get()の結果
--
`User::where()->get()`

```
Illuminate\Database\Eloquent\Collection Object
(
    [attributes:protected] => Array
        (
            [id] => 2
            [user_id] => 2
            [s_name] =>
        )
)
```
**取得**
`foreach()`
`collectionメソッド`

**まとめ　イメージ的な**
--
`DB::table('users')->where('id',$id)->first();`
対象は1つなので、idとかの情報を`stdClass Object`に連想配列として格納。

```
stdClass --+-- [id]      -- 2
           +-- [user_id] -- 2
           +-- [name]    --
```
<p>
--


`DB::table('users')->where('id',$id)->get()　;`
対象は複数が前提
`連想配列を格納したstrClass Object`を、`Collection Object`に、`[item]`として入れる。

```
Collection --+-- [0]  --+-- stdClass --+-- [id]      -- 2
             +                         +-- [user_id] -- 2
             +                         +-- [name]    --
             +--([1])
```
<p>
--
`User::where('id',$id)->first();`
対象は１つなので、idなどの情報を\[attributes]\(属性)として、`モデルのインスタンスObject`に保持。
↓はインスタンスの表現方法がわからないので、イメージとしてclass User()。

```
class User()
{
  public $id=2;
  public $user_name=2;
  public $name=;
}
```
<p>
--
`User::where('id'.$id)->get();　`
対象は複数が前提
idとかの情報を、[attributes]（属性）として保持したインスタンスオブジェクトを、`Eloquent Collection`に格納する。
（`データを属性として格納したモデルObject`を、`Collection Object`に入れる）

↓はインスタンスのイメージの表現がわからないので、イメージとして`class User()`。

```
Eloquent Collection --+--class User(){ 
                      |                public $id       =2;
                      |                public $user_name=2;
                      |                public $name     =;
                      |              }
                      |
                      +--(class User(){})
```
検索対象が複数の時はcollectionで扱い、collectionメソッドが使える。
あってるかな？
配列のcollectionと、Eloquentのcollectionの違い、いつか調べられたらな。
JavaScriptのみで2~100までの素数判定するプログラムを作成

#はじめに
初めまして。ムラサカと申します。
記事の投稿は初めてで至らぬ点もあるかと思いますがよろしくお願いいたします。
※追記：プログラム内容を修正（2019 4/27）
###なぜ作ったのか
IT系の求人を探している中で事前課題として出題されているのを見かけたため、
技術的な能力の基準を満たすための要件として必須と思い着手することにしました。

###構成要素
構成としては入力フォームで数字のみの値を入力受付し、
checkボタンで判定。アラートで結果を返す構成にしました。

![FireShot Capture 033 -  - murasaka.github.io.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/268058/105aab79-3165-3a87-1edb-b0af11ccf068.png)

↓こちらが制作物になります。
https://murasaka.github.io/Prime-number-decision/

###悩んだところ（html）
```html:index.html
 <from>
        <label for="textForm">下記のフォームに素数を入力</label>
        <input type="number" id="textForm" maxlength="3">
 </from>
```



入力するにあたってinput typeを”number”にするか”tel”にするか少し悩みました。

”number”の場合：入力を数字に限定できるが、クリックの矢印操作でマイナスの値も入力できてしまう。
”tel”の場合   ：スマホで数字入力が容易だがPCだと文字列も入力できてしまい無条件で「例）kkkは素数です」と表示されてしまう。

もし、文字列を判定してしまった場合の違和感が大きかったので今回は”number”を使用。
マイナスの値に関しては0以下の場合、エラーを出すアラートを設定。
空文字の場合も同様にエラーのアラートを設定。

###課題(JavaScript)
JavaScriptの中身は入力された値を判定するためif文を用いていますが、
~~実際の素数判定は力技です。~~


以下、Scriptの中身ですが、

```javascript:index.html
     <script>

// ボタンの要素を取得
var button = document.getElementById("button");
var flag =0;

button.addEventListener("click", function(e) {
    e.preventDefault();
 // 入力フォームの値を取得
 var textForm = document.getElementById("textForm").value;

//空文字判定、100以上、1と等しい、0以下の場合アラート
 if (document.getElementById('textForm').value == ""||
     textForm >100 || textForm ==1 || textForm < 0)  {
    alert('エラー　2~100までの素数を入力してください');
    return false;
}else {
    //素数判定
        for( i = 2 ; i<textForm ; i++){
            if(textForm % i == 0){
                flag = 1;
                break;
            }
        }
     }
     //素数判定後、結果をアラートで表示した後に更新する
    if(flag == 0){
        alert(textForm + 'は素数です');
        location.reload();
    }else{
        alert(textForm + 'は素数ではありません');
        location.reload();
    }


});
    </script>
```
素数判定後、サイトを更新して初期の状態に戻しています。
 location.reload();を入れた理由としては一度判定した後、フラグがリセットされてないのか継続して正しく素数判定ができなかったため。

###最後に
まだまだ理解不足を感じていますが、ひとまず形として投稿させていただきました。
これからもアウトプットを続けていきたいと思います。
【Unity】オレオレContentSizeFitter

任意のタイミングでContentSizeFitter的に親のRectTransformを変更したかったので自作しました。

※ContentSizeFitterを含めuGUIの自動レイアウトについてはこちらの記事が分かりやすいです。
[【Unity】uGUIの自動レイアウトが分かりにくいと評判なので解説してみる](http://tsubakit1.hateblo.jp/entry/2017/05/14/163456)

なお、
・Fit Preffered Sizeしか対応してません。
・VerticalLayoutGroupのみ対応してます。

###コード
```C#:MyContentSizeFitter.cs
using UnityEngine;
using UnityEngine.UI;
using System.Linq;

[RequireComponent(typeof(VerticalLayoutGroup))]
[RequireComponent(typeof(RectTransform))]
public class MyContentSizeFitter : MonoBehaviour {

    [SerializeField] VerticalLayoutGroup _LayoutGroup;
    [SerializeField] RectTransform MyRect;
    [SerializeField] RectTransform[] ChildRects;

    [ContextMenu("InitSize")]
    public void InitSize()
    {
        float totalHeight = _LayoutGroup.padding.top + _LayoutGroup.padding.bottom;
        foreach (var item in ChildRects)
        {
            totalHeight += item.sizeDelta.y;
            totalHeight += _LayoutGroup.spacing;
        }
        MyRect.sizeDelta = new Vector2(MyRect.sizeDelta.x, totalHeight);
    }

    private void Reset()
    {
        MyRect = GetComponentInChildren<RectTransform>();
        //自身のRectTransformと子のLayoutElementでignoreLayoutのものは除外する
        ChildRects = GetComponentsInChildren<RectTransform>().Where(x=>x != MyRect).Where(x=>x.GetComponent<LayoutElement>() == null ? true : !x.GetComponent<LayoutElement>().ignoreLayout).ToArray();
        _LayoutGroup = GetComponent<VerticalLayoutGroup>();
    }
}

```

###エディターサンプル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237014/502f1d67-a07f-dd0a-7e3a-0016092415eb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237014/f9f5a260-3f19-dda9-59f9-858806edb943.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237014/3bac82ac-d13d-32f8-bdd4-89b333b5dde6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237014/62f2e24a-e464-5754-8d04-8795323d018a.png)


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Unity難しすぎて可変長無限スクロールビューをやるだけでとても大変だったよねっていう（やっとできた！！！！！！！） <a href="https://twitter.com/hashtag/Unity?src=hash&amp;ref_src=twsrc%5Etfw">#Unity</a> <a href="https://twitter.com/hashtag/indiedev?src=hash&amp;ref_src=twsrc%5Etfw">#indiedev</a> <a href="https://twitter.com/hashtag/IndieGame?src=hash&amp;ref_src=twsrc%5Etfw">#IndieGame</a> <a href="https://t.co/XypFdcm3Vo">pic.twitter.com/XypFdcm3Vo</a></p>&mdash; アズマゴロー@モンスター合成ハクスラ開発中 (@azumagoro) <a href="https://twitter.com/azumagoro/status/1120939003539156993?ref_src=twsrc%5Etfw">April 24, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">今日も元気にUnity... <a href="https://t.co/MrzorHMGKD">pic.twitter.com/MrzorHMGKD</a></p>&mdash; アズマゴロー@モンスター合成ハクスラ開発中 (@azumagoro) <a href="https://twitter.com/azumagoro/status/1120912307679154176?ref_src=twsrc%5Etfw">April 24, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
PostgreSQLのロングトランザクションが引き起こす問題と対処

ロングトランザクションが引き起こす問題についてのメモ

## ロングトランザクションが引き起こす問題

- スレーブ側のトランザクションが閉じられないとWALが適用されずレプリケーション遅延を引き起こす
- VACUUMによる不要領域の回収が阻害される
  - DBサイズが肥大化する（一度肥大化するとVACUUM FULLでしか戻せない)
     - pg_repackで対応可 (https://github.com/reorg/pg_repack)
  - 性能劣化に繋がる
  - slave側でhost_standby_feedbackが指定されている場合、slave側のトランザクションでmasterもvacuum出来なくなる
  - 長時間続く場合はXID周回エラーの可能性もある

## ロングトランザクション解決

```
ロングトランザクションの確認
=# select * from pg_stat_activity where 適当な条件;

terminate
=# select pg_terminate_backend(<pid>);
```

参考: https://qiita.com/yteraoka/items/90f61beb1ade1b002a54

## 根本対策

idle_in_transaction_session_timeout ...設定しよう！ (9.6+)

## 監視方法

* pg_statsinfo
* postgres_exporter + Grafana (https://github.com/wrouesnel/postgres_exporter)
    * これが簡単
    * pg_stat_activity_max_tx_duration をグラフ化して、閾値超過したらアラート飛ぶとかにしておく
* pg_stat_activity見るスクリプトを書く
ハッカーランクでの今週の学びをアウトプット（２）

##エラーハンドリング

```
try:
    print(int(S))#とりあえず実行。えらーが出ればexept以下実行
except:
    print("Bad String")

```

##エラーハンドリング２
```
class Calculator(object):
    def power(self, n, p):
        if n < 0 or p < 0:
            raise Exception('n and p should be non-negative')#raise で投げるエラーを定義できる、Exceptionはシステム終了以外の全ての組み込み例外の親クラス
        return n**p


myCalculator=Calculator()
T=int(input())
for i in range(T):
    n,p = map(int, input().split())
    try:
        ans=myCalculator.power(n,p)
        print(ans)
    except Exception as e:
        print(e)   
```
##文字列の反転
pythonの文字列は変更不可（タプルみたいな感じ）なので、反転するメソッドを使う時は、別物が生成されると考える

```
new_str = org_str[::-1]
print(new_str)
```
node.jsでWebスクレイピングを行い、選手名をcsvに出力する

初投稿ですm(_ _)m
読売ジャイアンツの支配下登録選手の一覧が必要になりました(私用で)。
そんなに数が多くないのでコピーして整形してペーストでもいいのですが、以前Webスクレイピングが思っていたよりも簡単にできる！という記事を見かけたのでやってみる事にしました。
初心者ですので内容はご容赦ください。

#### 対象サイト
http://npb.jp/bis/teams/rst_g.html

#### 参考にさせて頂いた記事
https://qiita.com/tokutatsu/items/5c0d8e9217555a7ac724
https://qiita.com/ta1nakamura/items/105db4de2980ff224de8

## スクレイピング
Node.jsのモジュール、cheerio-httpcliを使用しスクレイピングを行います。

https://www.npmjs.com/package/cheerio-httpcli

静的ページであればHTMLをjQeryのように扱うことができるので、初心者の私でも操作しやすいと思いこちらを選択しました。

## csvファイルに出力

csv-writerというモジュールを使用し、指定するcsvファイルにスクレイピングで取得した選手名を書き込みます。

https://www.npmjs.com/package/csv-writer

## やってみた

選手や監督名は`.rosterRegister`クラスでまとめられているので、その中のテキストを取得し、csvに出力します。

```javascript
const {createObjectCsvWriter} = require('csv-writer');
const client = require('cheerio-httpcli');

const csvFilePath = 'data.csv'
const csvWriter = createObjectCsvWriter({
    path: csvFilePath,
    header: [
        {id: 'name', title: 'NAME'}
    ],
    encoding:'utf8',
    append :false,
});

const players = [];

client.fetch('http://npb.jp/bis/teams/rst_g.html',)
    .then((result) => {
        // テキストを配列に格納
        result.$('.rosterRegister').each(function (idx) {
            const $player = result.$(this).text();
            players.push({name: $player});
        });
        // csvファイルに書き込み
        csvWriter.writeRecords(players)
            .then(() => {
                console.log('...書き込み完了');
            });

    })
    .catch((err) => {
        console.log(err);
    })
    .finally(() => {
        console.log('終了！');
    });
```

## 感想
本当に初心者の僕でも簡単にできた！
今回はやりたい事が単純で実装も楽々でしたが、もう少し拡張すれば選手のデータとかも取得し出力できそうだなと思いました。
色々動かしてみて遊んでみようかなと思います！
マルコフ連鎖モンテカルロ(MCMC)法とベイズ統計モデル#1【最尤推定法】

#データ解析のための統計モデリング入門(緑本)　
八章を読みながらノートをとっていく。

サンプルからパラメータを推定したい。
当てはまりの良い分布をみつけたい。
統計モデルの作成のための八章です。

まずMCMC法によるモデル作成の前に、(効率の良くない)最尤推定が比較として示されています。

本文はこんな場合を想定してスクリプトを書いていました。

**植物の種子の生存率を推定したい。
1本の植物から8個の種子を採取する。
採取の対象とした植物は20本
8個の種子のうち、種子が生存している個数を測定した。
この生存数の情報から生存率を推定する。**

仮にもデータが無いと話にならないので、二項分布でサンプルを生成していた。

```R
size <- 8
q.true <- 0.45
N.sample <- 20
#この本来分からないパラメータを、どれだけ正確に当てることができるのかが、モデルの精度になる。
data <- rbinom(N.sample, size = size, prob = q.true)
data
[1] 2 4 2 2 4 1 5 5 1 4 2 2 5 2 3 3 3 4 2 3
hist(data)
```
![hist.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/c79db3b9-7d2f-0a0b-be35-89b5fe9fd3ed.png)

**スクリプトの理解**
今回のrbinom関数は、
rbinom(20, 8, 0.45)
・20回の独立した試行を行った。
・0から8までの結果が起こるとする。
・二項分布の確率は0.45である。





二項分布はくじ引きやコインやサイコロなどでも使える。

```R
rbinom(50, 1, 0.0001)
#1万分の1で当たるくじを50枚購入した時、くじが当たっている確率。
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[37] 0 0 0 0 0 0 0 0 0 0 0 0 0 0
```
宝くじの購買意欲が掻き立てられる結果になりました。

#最尤推定法
```R
logL.binom <- function(qq)
{
	sum(dbinom(data, size, qq, log = TRUE))
}

q.hat <- mean(data) / size
delta.l <- 0.01
vq <- seq(0.25, 0.65, delta.l)
vlogL <- sapply(vq, logL.binom)
```
やっていることをplotで見てみます。

```R
plot(vq, vlogL)
```

![pl1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/c6056093-65c1-d8f9-0f29-21870b0cbd0c.png)

0.25から0.65までの区間でdataの中の要素一つ一つの確率密度を求めて、対数だから掛け算が足し算になるのでsumで合計して、全体の確率に直しているってことですね。
全体の確率はplotを見ると0.4っぽいです。

実際はどうでしょうか。

```R
q.hat <- mean(data) / size
[1] 0.40625
```
8個の種子の生存率なので、20個の生存数の平均値を8で割ってやります。
最尤推定で求めた種子の生存率は、0.40となりました。

今回は離散値なので最後に対数を戻して、総和で割って確率密度にします。
(ついでにplotしてしまいます)

```R
density.logL <- exp(vlogL) / sum(exp(vlogL))
plot(vq, density.logL)
```

![pl2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/16e082d8-0c80-1c19-e80a-2e0bc293f3c4.png)

合計が1のdensity.logLに直すことができました。
確率密度に直したので直感的に何割というのがわかりやすくなりました。

```
私ならこう書いてしまいます。
x_ziku <- seq(0.1,1.0,0.01)

kakuritu<-NULL
for (i in 1:length(x_ziku)){
  kaku2 <- prod(dbinom(data, 8, x_ziku[i]))
  kakuritu <- c(kakuritu,kaku2) 
}

plot(x_ziku,kakuritu)
```

**次回はMCMC法(メトロポリス法)について**
Modelで定義や関数などを書いていく最適な順番

Modelにbelong_toやvalidatesなどを書いていく順番を規則性を持たせて書いた方が良いという話を聞きました。たしかに、規則性を持たせて書いた方が統一感が出てプログラムも読みやすくなるのではないかと思いました。

何を参考に順番を決めていくのかは[Ruby on Rails ガイド](https://railsguides.jp/)が参考になるということでRuby on Rails ガイドに記載されているプログラムを見ながら最適であろう順番をまとめてみました。

```ruby
class Hoge < ApplicationRecord
  include Hoge::Hoge

  # アソシエーション系を書く
  belongs_to :hoge
  has_one :hoge
  has_many :hoge

  # rails guidesに記載されていなかったが、ここでgemなどの関数を呼び出しや他の定義を書く
  has_secure_password

  # AttributeMethodsモジュールを書く
  attribute_method_prefix 'hoge_'
  attribute_method_suffix '_hoge?'
  define_attribute_methods 'hoge'

  # attr_系を書く
  attr_accessor :hoge

  # バリデーション系を書く
  validates :hoge, presence: true

  # before_○○などのコールバック系を書く
  before_validation :hoge
  after_validation :hoge

  # rails guidesに順番は記載されていなかったがクラスメソッドに近いのでこの辺りが妥当と考えられる
  scope :hoge, -> { hoge(hoge: true) }

  def self.hoge
  end

  def hoge
  end

  private

  def hoge
  end
end
```

# 最後に
上記の順番は[Ruby on Rails ガイド](https://railsguides.jp/)の記述を参考に作成しました（一部は自分で考えた箇所もあります）。上記の順番よりも、この順番の方がこんなメリットがあって良いよ！という情報がありましたらコメントをいただけるとうれしいです。

# 参考文献
- [Ruby on Rails ガイド](https://railsguides.jp/)
Arduboyで遊ぼう

ちょっと暇な時間ができたので３年ほど前に買ったArduboyで何か作ろうと久々に[公式](https://arduboy.com)を見てみると[Arduboy2 Library](https://github.com/MLXXXp/Arduboy2)が増えてました。

![スクリーンショット 2019-04-17 14.42.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24378/1686846d-f0a9-ed84-861a-eaa05c065112.png)

基本的にArduboy LibraryとArduboy2 Libraryは互換性があるようだけど、[ドキュメント](https://mlxxxp.github.io/documents/Arduino/libraries/Arduboy2/Doxygen/html/index.html)に書いてある差分について簡単にまとめると下記のような感じ。

* Arduboy2はArduboyTunesサブクラスが削除され、[ArduboyPlaytune Library](https://github.com/Arduboy/ArduboyPlayTune)と[ArduboyTones　Library](https://github.com/Arduboy/ArduboyTones)として提供
* Timer1を使用していたArduboyTunesが基本機能から削除されたため、Timer1を使用するsetRGBled（）などが正常に動作するようになった
* EEPROMにaudio on/offを記憶する機能の追加
* PWMを使用せずRGBLEDを制御するdigitalWriteRGB（）を追加

# ゲームを作った際に少し調べたこと

## モノクロスプライトの作成
モノクロのドット絵を用意して下記のサイトで変換
　[ToChars](http://www.crait.net/tochars/)

ドット絵は下記のツールが便利
　[ミニドット絵メーカー](http://neutralx0.net/tool/dot2/)

## SEをつける
```
#include <ArduboyTones.h>
ArduboyTones sound(arduboy.audio.enabled);
sound.tone(< frequency>,<duration>);
```


## フォントを変更する
ライブラリで提供されているTinyfontの使い方

```
#include <Tinyfont.h>
Tinyfont tinyfont = Tinyfont(arduboy.sBuffer, Arduboy2::width(), Arduboy2::height());
tinyfont.print("Ping Pong");
```

8x8 dot 日本語フォントもあるけどメモリサイズと相談する必要あり
[8x8 dot 日本語フォント (8x8 dot Japanese font for Arduboy)](https://community.arduboy.com/t/8x8-dot-8x8-dot-japanese-font-for-arduboy/1938)
Kotlinの連結文字列

連結文字列、String Templatesの件。

**Convert concatenation to template**
の警告が出た際の自分用のまとめ

住所として
東京タワーの住所　：東京都港区芝公園４丁目２−８
増上寺の住所　　　：東京都港区芝公園４丁目７−３５（東京タワーの隣）

があった場合、
**東京都港区芝公園４丁目** は共通している。なので、

```Kotlin
//芝公園までの住所
val tokyoMetMinatoWardShibaKoen4 :String = "東京都港区芝公園４丁目"
//東京タワーの番地
val tokyoTower :String = "２−８"
//増上寺の番地
val zojojiTemple :String = "７−３５"

//東京タワーを出力
print("東京タワーの住所：" + tokyoMetMinatoWardShibaKoen4 + tokyoTower);

//増上寺を出力
print("増上寺の住所：" + tokyoMetMinatoWardShibaKoen4 + zojojiTemple);
```

かなりJavaの記述ですが、これでも問題なく出力はされる。
がしかし、警告が出た。。

「Convert concatenation to template」
「連結をテンプレートに変換する」
とのこと。以下の通りに変換

```Kotlin
//芝公園４丁目までの住所
val tokyoMetMinatoWardShibaKoen4 :String = "東京都港区芝公園４丁目"
//東京タワーの番地
val tokyoTower :String = "２−８"
//増上寺の番地
val zojojiTemple :String = "７−３５"

//東京タワーを出力
println("東京タワーの住所：$tokyoMetMinatoWardShibaKoen4$tokyoTower");

//増上寺を出力
println("増上寺の住所：$tokyoMetMinatoWardShibaKoen4$zojojiTemple");
```

Kotlinはこの書き方が基本みたいです。

**$**で変数を持ってこれるんですね！
かなりスッキリして見やすくなった！！

---
####雑談

たとえば、町田駅は。。
(東京都町田市原町田６丁目１２−２０)

```Kotlin
println("$kanagawaPref$MachidaCity...")
```

実際に **神奈川県町田市**でも郵便届くってよw
proftpdでSFTPを受ける

# 目的

下記目的のために、sshdではなくproftpdを使ってSFTPを受ける設定をします。

- バーチャルユーザーを使いたい
- ユーザーにSFTPはさせたいがコンソールとして使われたくない

# 設定内容
- OSはCentOS7系
- SFTPを受けるポートは8022番とする
- バーチャルユーザーを専用パスワードファイルで設定する
    - ユーザ /etc/ftppasswd
    - グループ /etc/ftpgroup
- バーチャルユーザーのホームディレクトリをROOTに見せる

# 手順
## 1.proftpdのインストール

CentOS7を前提にしますので、まずepelをインストールします

```
yum install epel-release
```

続いてproftpdのパッケージをインストールします

```
yum install proftpd proftpd-utils
```

## 2.設定変更

設定ファイルの変更内容です。

```/etc/proftpd.conf
# 下記コメントアウト解除
LoadModule mod_sftp.c

# 下記どこか任意の場所に追加
<IfModule mod_sftp.c>
    <VirtualHost 0.0.0.0>
        SFTPEngine on
        SFTPLog /var/log/sftp.log
        DefaultRoot                     ~

        # バーチャルユーザーの設定
        AuthUserFile                    /etc/ftppasswd
        AuthGroupFile                   /etc/ftpgroup
        AuthOrder                       mod_auth_file.c

        Port 8022
        
        # hostkeyをsshdから流用する場合の設定
        SFTPHostKey /etc/ssh/ssh_host_rsa_key

        # CiphersとDigestsの設定
        # 脆弱性の状況を見て調整する項目
        SFTPCiphers aes256-ctr aes192-ctr aes128-ctr blowfish-ctr 
        SFTPDigests hmac-sha2-256 hmac-sha2-512 hmac-ripemd160
    </VirtualHost>
</IfModule>
```

- SFTPの設定はVirtualHostでくくるのが重要です。くくらないとファイルのタイムスタンプ設定などで不具合が起きます。

hostkeyがそのままだとパーミッションエラーになるので、パーミッションを変更します。

```
chmod 600 /etc/ssh/ssh_host_rsa_key
```
- パーミッション変更してもsshdの挙動に問題はありませんが、気になるようでしたらproftpd用に生成してもよいと思います。

## 3.バーチャルユーザー生成

バーチャルユーザー[contents]をUID:1001のユーザに紐付ける場合のコマンドラインです。
ホームディレクトリは[/var/www/site/contents]とします。

```
ftpasswd --passwd --file=/etc/ftppasswd --name=contents --uid=1001 --gid=1001 --home=/var/www/site/contents --shell=/bin/bash
ftpasswd --group --file=/etc/ftpgroup --name=contents --gid=1001
```

## 4.起動

```
systemctl start proftpd
systemctl enable proftpd
```

以上で完了です。
なお、firewalld等の設定は別途行ってください。
Dockerのjwilder/nginx-proxyとは

Dockerでnginxのリバースプロキシの設定をして、一つのサーバー内で複数のサイトを立ち上げる時に、ネットで調べていたら以下のDockerイメージを見つけました。

【jwilder/nginx-proxy - Docker Hub】
https://hub.docker.com/r/jwilder/nginx-proxy

ただ私は、Dockerイメージの説明を見ても何もわからなかったのでこちらの事について簡単に調べてみました。

上記のページの説明では英文で以下のように書かれていました。

> nginx-proxy sets up a container running nginx and docker-gen.

直訳すると、
「nginx-proxyとdocker-genのコンテナをセットアップします。」
ということになると思いますが、nginx-proxyとdocker-genとは何でしょうか。

# nginx-proxyとdocker-genとは何か。
簡単に言うとdocker-genというものが、Nginxのリバースプロキシ(nginx-proxy)を生成したり、再起動などをしてくれる、ということのようです。

## nginx-proxyとは
nginx-proxyとは、Nginxによる、リバースプロキシということらしいのですがリバースプロキシとはなんでしょうか。

以下の記事によるとリバースプロキシとは
> Webサーバさんの身代わりになってホームページのファイルを返してくれるサーバさんのこと

ということのようで、
自分なりに解釈すると、
サーバーとブラウザの間に立って役割を果たすということらしいです。

【リバースプロキシ (reverse proxy)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典】
https://wa3.i-3-i.info/word1755.html

### サーバーとブラウザの間に立って役割を果たす役割とは

以下の記事によると、

> 
- Webサーバ内の画像などをリバースプロキシにキャッシュしておくことで、Webサーバへの負荷を軽減することができます。
- リバースプロキシがリクエストを待ち受け、その転送を複数のWebサーバに分散して行うことで負荷分散を実現する
- SSLを高速化するSSLオフローダとして利用

などいろいろありました。とてもわかりやすい。。。！！

【作って覚えるリバースプロキシ | 東北ギーク】
http://tech.respect-pal.jp/reverse_proxy_cooking/


## docker-genとは

次に、docker-genとは何か調べてみました。

Dockerイメージの「jwilder/nginx-proxy」の説明文に、英文で以下のことが書かれていました。

> docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.

直訳すると、「docker-genはnginx上で、リバースプロキシの設定をし、nginxの起動・停止時にリロードする」ということになると思います。

つまり上記で説明したリバースプロキシの設定をして、nginxの起動・停止時に、再起動もしてくれるということです。


# さいごに
なかなか便利そうなイメージですが使い方がまったくまだわからないので、後で、使い方を調べてちゃんと実践し、記事にしてみようと思いました。

# 参考
【jwilder/nginx-proxy - Docker Hub】
https://hub.docker.com/r/jwilder/nginx-proxy


【作って覚えるリバースプロキシ | 東北ギーク】
http://tech.respect-pal.jp/reverse_proxy_cooking/

【リバースプロキシ (reverse proxy)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典】
https://wa3.i-3-i.info/word1755.html
JavaScriptでグローバルIPを取得する(パブリックSTUNサーバーを利用)

## WebブラウザはSTUNクライアントを実装している
STUNサーバーを利用すれば、NATの外側のIPアドレスを調べることができる。
インターネットには一般公開されたSTUNサーバーが存在する。
Webブラウザは、STUNクライアントを実装している。
WebRTC APIを使ってSTUNで調べたIPアドレスを取得できる。

## ブラウザ互換性 
[WebRTC API ブラウザーの対応](https://developer.mozilla.org/ja/docs/Web/API/RTCPeerConnection#Browser_compatibility)
 
## パブリックSTUNサーバー
googleのパブリックSTUNサーバー`stun.l.google.com:19302`を利用する

---

```javascript
function getIPAddresses() {
  const S = "stun.l.google.com:19302";

  return new Promise(resolve => {
    const pc = new RTCPeerConnection({
      iceServers: [
        {
          urls: ["stun:" + S]
        }
      ]
    });

    const rslt = [];
    pc.onicecandidate = e => {
      if (!e.candidate) {
        return resolve(rslt);
      }
      const [ip, , , type] = e.candidate.candidate.split(" ", 8).slice(4);
      if (type == "srflx") {
        rslt.push(ip);
      }
    };

    pc.onnegotiationneeded = async () => {
      await pc.setLocalDescription(await pc.createOffer());
    };

    pc.createDataChannel("");
  });
}
```


- [ice candidateの書式 rfc 5245 S-15.1](https://tools.ietf.org/html/rfc5245#section-15.1)
  - ローカルアドレスは、type "host"で取得できる
  - type "srflx"は、server reflexiveという意味
- ice gatheringの終了判定
  - onicecandiateのe.candidate == null でcompleteの判別
  - onicegatheringstatechangeのcompleteでも判別可能
  - [onicegatheringstatechange VS onicecandidate with candidate==null · Issue #166 · w3c/webrtc-pc](https://github.com/w3c/webrtc-pc/issues/166)
- mediatrackかdatachannelが無いとiceGatheringが始まらない
- createDataChannelの第1引数は必須だが使用しないので""を指定
  - [RTCPeerConnection.createDataChannel() - Web APIs | MDN](https://developer.mozilla.org/enl-US/docs/Web/API/RTCPeerConnection/createDataChannel#Parameters)
GAEにコンテナ化されたアプリケーションをデプロイする(golang:ginを例に)

こんにちは。

A○Sの記事は世の中にごまんとありますが、GCP界隈に関しては、その記事が少ないので共有。

GCPと言えば、０までスケールインしてくれるという驚異のGAEではありますが、
デフォルトのruntimeではなく、コンテナで実行するときにハマりました。

結論を言ってしまえば、以下のシリコンバリーなUberのエンジニアに救われました。笑
すごくわかりやすかったです。
自分の名前をそのままドメインにしちゃうあたりの自己主張性がシリコンバレーで働くのに、きっと必要なことなんでしょうね。笑

[Uberエンジニアのブログ](https://graysonkoonce.com/deploying-to-google-app-engine-using-docker)

最低限のサンプルを公開しておりますので、よろしければ。

[サンプル]
(https://github.com/leica19/gcp-gin)

以上、よきコンテナ・ライフを！
【VBA】変数の宣言と代入を1行で行う

# VBAでは変数の宣言時に初期化兼代入ができない？
――長いこと、そう思っていました。
For文のカウンタもブロックスコープがないから事前に宣言するのに、行数増えて嫌だなって。
オブジェクトの変数ならアーリーバインディングで`Dim fso as New FileSystemObject`みたいに記述できるけど、Object型で宣言して`CreateObject(ProgID)`するレイトバインディングじゃどうしても複数行に跨るよなって。
まあ`New`してもコンストラクタに引数渡せないから、外から渡す値が必要な初期化処理は別の行になるんですけど。

元々Java屋なので、宣言と初期化が別の行なのは、すごく違和感があったんですよ。
それを見た目だけでも改善する記述法に今更出会えたので、同じことで不満を感じてる人に届けばいいな。

```vb
' 通常の書き方
Dim fso As FileSystemObject
Set fso = New FileSystemObject
Dim str As String
str = "ABC"

' 1行での書き方
Dim fso As FileSystemObject: Set fso = New FileSystemObject
Dim str As String: str = "ABC"

' ループカウンタの宣言も1行でできちゃう！
Dim i As Integer: For i = 0 To Ubound(Split("A/B/C", "/"))
Next

' For Eachでも大丈夫
Dim str As Variant: For Each str In Split("A/B/C", "/")
Next
```

`_`は行を分割する記号で、`:`は行を結合する記号です。[^1]

まあコンストラクタに引数渡せないから、オブジェクトで外から渡す値が必要な初期化処理は別の行になるんですけど。
あとブロックスコープが利いてるわけじゃないので、For文は1行で書いてもFor文抜けた後も変数生きてますけども。
ただ、個人的にはこの書き方のほうが最初にどこで出てきたのかがわかりやすいので、これに気付いてからはこう書いてます。

[^1]: [方法: コード内でステートメントを分割および連結する (Visual Basic)](https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/program-structure/how-to-break-and-combine-statements-in-code)
Git x AWS

## AWS sagemakerでgithubのリポジトリをそのまま使う
[参考](https://aws.amazon.com/jp/blogs/news/amazon-sagemaker-notebooks-now-support-git-integration-for-increased-persistence-collaboration-and-reproducibility/) を見てこの通りに進めれば良い。
結局、
インスタンスの作成→オプションでgitレポジトリを選択→登録してあるリポジトリを選択
だけで出来上がる。
カスタムjavascriptでPage pathからIDを切り取る

Google Tag Manager（以下GTM）の変数をカスタムJavascriptを使って自分で作るの巻。
今回やりたいことは、URLからIDを切り取ってGTMの変数にすること。

例）https://example.com/articles/1234
上記URLの「1234」という記事IDを変数にする方法です。

## 1.組み込み変数
GTMには組み込み変数が用意されていて、たいていのものはカバーできます。
Click Element、Click Classes、Click ID、Page Path、Page URL・・・etc
このあたりは扱いやすくよく利用する変数です。

これらの変数を使って、カスタムJavascriptでオリジナル変数を作っちゃおうが主題。
非エンジニアが書いていますので、優しく、温かく見守ってください♪
WEBエンジニアならスラスラ書けるんでしょうけど、GTMを利用しているWEB運営者でどれだけの人が書けるか...
ぐぐっても出てこないから社内備忘録を兼ねて記事にしました。

## 2.カスタムJavascript
**GTM　→　変数　→　ユーザー定義変数の「新規」　→　変数の設定　→　カスタムJavascript**
と進むと、下記の画面になり、自由にコードの記述が可能です。
![783ad4d72a0dd5304bb747bec3022681.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223154/26bd5fa3-a677-9f23-e12c-37fc8848f33e.png)


ここに下記のコードを書きます。

```javascript:カスタムJavascript
function(){
 var nowPath = {{Page Path}};
 var lastSlashPos = nowPath.lastIndexOf('/');
 return nowPath.substring(lastSlashPos + 1); 
}
```

>以下コードの説明。
例）https://example.com/articles/1234

>二行目の`{{Page Path}}`はGTMの組み込み変数です。これを改造していきます。
例の場合は`Page Path`は/articles/1234です。

>三行目は二行目で定義した`nowPath`の最後の`/`の順番を定義しています。
例の場合は、文字列の10番目になるので10です。

>四行目は二行目で定義した`nowPath`を三行目で計測した数値+1以降の文字列を切り取っています。
例の場合は、/articles/1234の11番目以降の文字列を切り取っています。

これをarticleIDと命名してあげればカスタム変数の完成。
Laravel Request Lifecycle 

```php


◆/public/index.php

require __DIR__.'/../vendor/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';  ①


$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); ②

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()③
);

$response->send();④

$kernel->terminate($request, $response);




◆①/bootstrap/app.php　service container初期化・

$app = new Illuminate\Foundation\Application(　　①-A
    realpath(__DIR__.'/../')
);

$app->singleton(　　　　　　　　　
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);

$app->singleton(　　　　　　　
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

◆①-A /Config/app.php

'providers' => [...]
★特に要注意：App\Providers\AppServiceProvider-bootにAPPの初期化操作 RouteServiceProvider-web/api　Middlewareをロード
 'aliases' => [...]



◆②/App/Http/Kernel.php

protected $bootstrappers = [
        \Illuminate\Foundation\Bootstrap\LoadEnvironmentVariables::class,
        \Illuminate\Foundation\Bootstrap\LoadConfiguration::class,
        \Illuminate\Foundation\Bootstrap\HandleExceptions::class,
        \Illuminate\Foundation\Bootstrap\RegisterFacades::class,
        \Illuminate\Foundation\Bootstrap\RegisterProviders::class,
        \Illuminate\Foundation\Bootstrap\BootProviders::class,
    ];

protected $middleware = [...]
protected $middlewareGroups = [...]
protected $routeMiddleware = [...] 


◆③④　Requestを受け取り、Responeを返す。
コマンドでよくみる「>」とか「>>」って何？？

# 結論から

- 「>」はファイルを上書き
- 「>>」はファイルに追記

※ **ファイルが存在しない場合はどちらも新規作成されます**

<br>
# 「>」してみる


test1.txtファイルにhijiと書き込む

```bash:
$ echo hiji > test1.txt
```



中身を確認

```bash:
$ cat test1.txt
hiji
```


次はhiza

```bash:
$ echo hiza > test1.txt
```


中身を確認

```bash:
$ cat test1.txt
hiza
```


**上書きされました** :relaxed:


<br>
# 「>>」してみる


test2.txtファイルにkurubushiと書き込む

```bash:
$ echo kurubushi >> test2.txt
```




中身を確認

```bash:
$ cat test2.txt
kurubushi
```


次はkakato

```bash:
$ echo kakato >> test2.txt
```


中身を確認

```bash:
$ cat test2.txt
kurubushi
kakato
```


**追記されました** :relaxed:
nginxの設定で暗号化通信をTLS1.2のみ許可する

## ▼主題

タイトルの通り、安全性を高めるためにTLS 1.2による通信のみを許可したい。

## ▼用語

### ●TLS

#### - 概要

Transport Layer Securityの略。
TCP/IPを使った様々なサーバとクライアントの通信で、セキュアなチャンネルを利用できるようにする仕組み。

#### - SSLとの違い

以前はSSLと呼ばれていたが、Netscape社が開発したSSLプロトコルをIETFへ移管するための標準化に伴って名称が変更された。
TLSはSSLの次世代規格であり、TLSはSSL 3.0をベースとしている。

## ▼nginxへの設定

### ●nginxの設定の変更

nginxの設定ファイルを修正する。
ファイル名やエディタはそれぞれの環境次第なので適宜読み替えてほしい。

```sh
$ sudo vi /etc/nginx/conf.d/virtual.conf
```

変更自体は簡単で、設定ファイル内の下記の部分で有効化したいバージョンを書くだけでOK。

```
# /etc/nginx/conf.d/virtual.conf

...
ssl_protocols TLSv1.1 TLSv1.2
...
```

### ●nginxへ設定の反映

nginxを再起動すれば読み込まれる。

```sh
$ sudo nginx -s reload
```

## ▼確認方法

OpenSSLをSSL/TLSクライアントとして利用して確認する。
TLS 1.2でセッションが確立でき、TLS 1.1でセッションが確立できなければ成功。

確認コマンドは下記

```
$ openssl s_client -connect your.domain:443 -tls1_2
$ openssl s_client -connect your.domain:443 -no_tls1_2
```

色々と表示されるが、セッションが確立できれば

```sh
# SSL handshake has read 3650 bytes and written 326 bytes
```

のように読み取りと書き込みが行われる。
セッションが確立できなければ読み取りも書き込みも0 bytesとなる。

## ▼参考記事

- [SSLとTLSの違いとは](https://ssl.sakura.ad.jp/column/ssl_tls/)
- [TLS (Transport Layer Security)とは](https://www.nic.ad.jp/ja/basics/terms/tls.html)
- [apache、nginxのSSL/TLSのバージョン選択](https://hacknote.jp/archives/36750/)
- [OpenSSLをSSL/TLSクライアントとして使ってみる](https://siguniang.wordpress.com/2014/08/09/openssl-as-ssl-client/)