OmniAICreator/Qiita-1.07M huggingface dataset:
スマホから家PCにsshしたい

#背景
ふとスマホ(android)から家PCにsshしたいと思った。
スマホから家PCをいじることができれば、外出先でもリッチな環境でちょっとした開発作業ができるのではないか。と。

#試したこと①直接接続
まずはスマホ→家PCに直接sshを試みてみた。とりあえず[ググって出てきた情報](http://jrkl.hatenablog.com/entry/ssh_connect1)を参考に色々設定を進めていったのだが壁にぶつかった。
当方IPv6プラスの通信環境でIODATAのルーターを使っているのだが、いろいろ調査したのだけれども外からアクセスがあったときにPCのローカルIPへ中継する設定ができなかった。ルーターのIPv6設定画面にポートを設定する項目が無い。[もしかしたらルーターによってはできるのかもしれないが](http://dotsukareta.blogspot.com/2018/01/v6portopen.html)、この辺りはよく分からん。

結局、直接接続するのは諦めて、別の方法を模索した。
調べているとどうやらポートフォワーディングというのが使えるらしい。

#試したこと②ポートフォワーディング
詳しい説明は他に譲るとして、要はポートフォワーディングをすることで外部から来た特定のポート番号宛のパケットを家PCへ転送することができる。これを利用すれば踏み台PCを用意して間接的に家PCにsshできる。実現するにはスマホと家PCからssh可能なPCが必要なのだけれど、これはGCP(GCE)を利用すればいける。しかもスペックを絞れば無料で運用可能。
![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267592/ad68c638-672c-b326-efb8-a69f6c6c4207.png)

###準備
* [GCP(GCE)の準備をする。](https://qiita.com/Brutus/items/22dfd31a681b67837a74)
無料で利用できる構成でインスタンスを立てる。
* スマホに[Termux](https://play.google.com/store/apps/details?id=com.termux&hl=ja)(あるいは他のLinuxエミュレーターやsshクライアント)を入れてGCPにsshできるようにする。
* 家PCからGCPにsshできるようにする。




###step1:
家PCからGCPにsshのトンネルを張る。具体的には次のことをする。
家PCに次のsshのconfigファイルがあったとして、

```
Host gcp
        HostName XXX.XXX.XXX.XXX
        User gcpuser
        IdentityFile ~/.ssh/gcpkey
        Port 11111
        TCPKeepAlive yes
        IdentitiesOnly yes
```
sshコマンド打つときに次のオプションを付ける。

```
ssh -R 22222:localhost:33333 gcp  
```
これでGCP上のlocalhost:22222に来た通信を家PC(YYY.YYY.YYY.YYY:33333)に飛ばせるようになった。

###step2:
スマホからGCP(XXX.XXX.XXX.XXX:11111)にssh。
そしたらそのままlocalhost:22222に向けてssh。。。で完了！
これでスマホから家PCにsshすることが出来た。


#備考
快適にキー入力できた方が良いので、Bluetooth接続のキーボードと[このアプリ](https://play.google.com/store/apps/details?id=jp.kcm.thumbctrl&hl=ja)もあった方がいい。Ctrl+CでコピーなどPCと遜色ないキーボード操作ができるようになる。多分iphoneにも似たようなのがある。

#問題
GCEの実体がアメリカにあるせいか挙動がラグい。スマホ→アメリカ→家PC→アメリカ→スマホ
の経路を辿るので文字入力したあと0.5秒経過くらいで画面に反映される。
使えないことはないがまぁまぁストレスなのでなにかしらの対策が必要かも。

#最後に
もっと良い方法あったら教えてね。
Ansibleの呼吸 壱ノ型 フィルター芸「テキストファイルが保存されているディレクトリパス抜き」 

この投稿は[Ansible 3 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/ansible3)の1日目の記事です。

一先ず空いていたので、古い日付から思いついたフィルター芸を投稿していってみようと思います。

特定の条件にマッチしたファイルの一覧から保存されているディレクトリパスを抜き出したい時があったりなかったりあったりします。
その時の簡単なフィルターです。

# ディレクトリ構成

こんな感じでtxtファイルが保存されています。

```
(venv) [root@localhost ansible]# tree tmp/
tmp/
├── dirA
│   └── testA.txt
├── dirB
│   └── testB.txt
├── dirC
│   └── dirD
│       └── testC.txt
└── testD.txt
```

このtxtファイルが保存されているディレクトリ情報を抜き出してみたいと思います。

# Playbook

Playbookはこんな感じです。

```yaml
---
- name: iti no kata playbook
  hosts: localhost
  gather_facts: no
  tasks:
    - name: find files
      find:
        paths: tmp/
        recurse: yes
      register: find_result

    - debug:
        msg: >-
          {{ item.path.split('/') | difference(data) | join('/') }}
      vars:
        data: >-
          {{ [-1]
            | map('extract', item.path.split('/'))
            | map('regex_search', '^.*txt$')
            | list
          }}
      loop: "{{ find_result.files }}"
      loop_control:
        label: "{{ item.path }}"
      when:
        - item.mode == "0644"
```

findで `tmp` ディレクトリ配下のファイル情報を取得して `loop` で結果を回します。
ここでは、条件としてファイルのパーミッションが `0644` になっていているものが対象で、マッチしたものは `data` 変数の処理に移ります。
`data` では `path` キーの値を `/` でsplitして正規表現でマッチしたものをリスト化して最後の要素を抜き出し `data` 変数に格納します。
最後に `path` を `/` でsplitした者に対して `difference` フィルターを使って `data` 情報とマッチしている値を削除し `/` でjoinしています。

これを実行してみます。

# playbook実行

```
(venv) [root@localhost ansible]# ansible-playbook main.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


PLAY [iti no kata playbook] *****************************************************************************************************************************************

TASK [find files] ***************************************************************************************************************************************************
ok: [localhost]

TASK [debug] ********************************************************************************************************************************************************
ok: [localhost] => (item=tmp/testD.txt) => {
    "msg": "tmp"
}
ok: [localhost] => (item=tmp/dirA/testA.txt) => {
    "msg": "tmp/dirA"
}
ok: [localhost] => (item=tmp/dirB/testB.txt) => {
    "msg": "tmp/dirB"
}
ok: [localhost] => (item=tmp/dirC/dirD/testC.txt) => {
    "msg": "tmp/dirC/dirD"
}

PLAY RECAP **********************************************************************************************************************************************************
localhost                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

各ファイルが保存されているディレクトリがmsgで表示されました :)
小心者が登壇してみて気づいた事

こんにちわ、 @m_kumanomi です。
Diverse Advent Calendar 2019の10日目の記事です。

昨日は[UnityプロジェクトをBitriseでアーカイブ](https://qiita.com/kiy0p0n/items/125e18a8d15d2ddf3b0f)するお話でした。
Bitriseは使っているものの設定とかよくわからんちんなのでワークフローなど学びなおしたい気持ちになりました。

# そもそもなんでこれを書こうと思ったのか
前置きとして僕はあまり登壇したことがありません。
しかしながら今年は2度ほど少し大きめのカンファレンスで登壇することができました。
そこで得た知見というか感想に近いものを書かせていただければと思います。

# 登壇に関して
あれ？こんな内容でもいいのかな・・・？と思うかもしれません。
いいんです！**あなたが当たり前に知っていることは、みんなは知らない**かもしれません。
誰か一人でも知らない人に届けばいいんです。そんな気持ちでやりましょう。

## 声にだして練習はしよう
実際に声に出して音読しましょう。思ったよりも早く終わってしまったりします。
早く終わった場合は本番では読むべき場所を飛ばしてしまったり、早口になってしまいます。
早く終わってしまった時のためにスライド後ろの方に**尺稼ぎとなるスライド**を差し込んでおいてもよいでしょう。

## 登壇して知る聞く側のうなずきのありがたみ
今回は**これが一番言いたい**ことです。
なんか勉強会でうなづくの恥ずかしいとかあるじゃないですか？
なにアイツうなづいてんだ？みたいな？
僕はありました。
でもあれがすごいありがたかったです。
緊張して視野が狭くなっている時に「ちゃんと発表届いてるなぁ」と気づき、心を落ち着かせる効果がありました。
自分はこれからは反応するようにしようと改める良い機会になりました。

## 笑いポイントのシーンの辛さ
場を和ませるために仕込んでおいた笑いポイントで、一切反応がないこともあります。
発表者は一人アウェーとも言える状況で発表するのですが、聞く側も一人発表を聞いているのです。
そうです、両者アウェーなのです。その状況で笑って良いのか？笑うポイントなのか？**聞き手も判断が難しいのです。**

- まずは小さな笑いポイントを仕込み笑っていいことを聞き手に伝える
- その後大きめの笑いポイントを仕込む

これが大事です。**前振り大事です**。

## 登壇したら何か言われるの？
登壇って緊張しますよね。**失敗したら嫌だなぁ**とか**内容が良くなかったって言われたら**とか考えてしまいます。

僕はすごく薄い内容で登壇してしまったと思うのですが、薄味のなかで旨味を見つけていただけたのか悲しい気持ちになる投稿や感想は一切なく好意的なものをいただけました。こうしてみては？やこういった内容も聞きたいなどの感想もいただけたのでとても良かったです。

## 登壇後の予期せぬ質問
どうみても自分より詳しい人から深掘りされる質問をされました。
その時は正直にこう答えましょう。
**「それはわからないのでご存知の方いましたら教えてください」**と。
勉強会にいる人で**その分野に精通している方**が大抵います。
その方からあとでフォローしてもらいましょう。賢い方は教え上手な方も多いです。

そして質問していただいた方に感謝しましょう。本当にありがたいことです。

## 登壇後の思わぬ汗
頭の変なところとかから汗が出ます。
ハンカチやタオルは持参しましょう。

# まとめ
まずは5分LTからはじめましょう。それでもすごく緊張します。
そもそもQiitaに記事書くのでさえ緊張します。やなこと書かれるかもしれない。噛みつかれるかもしれない。

でも結構みんな良い感想をくれます。悪いことを思っていても口に出したりする人はほぼいません。
大丈夫。

僕は発表したことによって聞く側として成長できたと思います。

# おまけ
Droidkaigiで登壇した際に後ほどyoutubeに投稿するためのカメラ撮影がありました。
<img width="1054" alt="スクリーンショット 2019-12-10 23.16.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170870/77d9c52e-8a8d-ebce-5078-7bf70b8c386a.png">
こちらを見ていただけるとわかるように誰も写っていません。
カメラの設置されているカンファレンスなどではあまりウロウロせず、定位置で発表することも大事なのだと気づきました。
ARKit3のCollaborative Sessionという機能

これは[Unity Advent Calender 2019](https://qiita.com/advent-calendar/2019/unity)の21日目の記事です

ARKit３で追加された新しいARの共有のサンプルの解説です

[https://github.com/Unity-Technologies/arfoundation-samples](https://github.com/Unity-Technologies/arfoundation-samples)
のARCollaborationDataのサンプルを実行した動画がこちら
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ブログ用<br>arkit3のCollaborative Sessionのサンプル実行動画 <a href="https://t.co/tDhRkBBqt7">pic.twitter.com/tDhRkBBqt7</a></p>&mdash; sada@VirtualxRえんじにゃ (@SAyanada9) <a href="https://twitter.com/SAyanada9/status/1207674694238953476?ref_src=twsrc%5Etfw">December 19, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 所感

割と早く位置合わせされてるしそこそこ実用的な気がする
一つ懸念があるとすればあまり特徴点がないところだと認識が遅くなりそうというところ
使える要件はiOS13以上のみなのでA12プロセッサが必要というわけではないです

## Appleのドキュメント
[Building Collaborative AR Experiences](https://developer.apple.com/videos/play/wwdc2019/610/)
[Creating a Collaborative Session](https://developer.apple.com/documentation/arkit/creating_a_collaborative_session?language=objc)
[collaborationEnabled](https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration/3152987-collaborationenabled?language=objc)
これによると最大４人が最適と書いてあります
ネットワーク的に最適なのかそれとも処理的に４人ぐらいが限界なのかはわからないです(ちなみにサンプルではBluetoothでP2P通信をしていた)



# (大雑把な)仕組み
Collaborative SessionというARKit3で追加された機能でARCollaborationDataというデータを共有している
## ARCollaborationDataとは
点群情報を保持し続けるオブジェクト
そのオブジェクトが他の人の点群情報をマージしたり出力したるする機能が付随している様なイメージ
## 少し詳しい仕組み
点群情報（便宜上点群情報というが、この情報の塊に正確には点群、自分の位置（点群等からの相対距離だと思われる）ReferencePoints（点群に紐つく位置、又の名をアンカー）が入っていると思われる）をp2p的に送信して、受信した時に自分が持ってる点群情報にマージ、重ね合わせをして複数端末の位置を共有するような感じ![05AWqSTDJZk8GPL71bbV1576689551-1576689607.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/c0119372-a2c7-7340-d56d-d0c662e56361.gif)



## ARWorldMapとの違い
### ARWorldMapの方は
- 空間ごと一度保存してからそれを送信（受信）する
- アンカーに加えて平面の情報なども保存（共有）する
- 単体の機能では端末の位置は共有しない（端末の位置はARWorldMapには保存されない）
- 一度ある程度空間を認識してから送信する必要がある
- あくまでStaticなものの共有（変わらない空間、場所）に向いている
- 端末同士の座標形は一致する（複数端末上で現実空間の同じ場所に原点がある）


に対して

### ARCollaborationDataの方は
- 都度都度空間情報を送信する
- 平面の情報などは共有せず、他端末の位置、アンカーのみ共有する
- 単体の機能で端末の位置を共有することができる（p2p的に送受信するSDKは別に必要(Photon等)）
- 主に動的に変わるものだけを共有することに特化（自分の位置や、増える物）
- 端末同士の座標形は一致しない（複数端末上で現実空間の同じ場所に原点がない）

# 端末の座標形の話
Collaborative Sessionの **端末同士の座標形は一致していない**
理由は点群（複数端末で共通な位置情報）を共有しその点群からの相対座標にある端末の位置を共有しているので下の図のように現実世界上の位置は一致しているがUnityでの座標は一致していない状態になるため座標系は一致していないことになります
![プレゼンテーション1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408473/6d5335fa-12b2-1c33-a989-8d1e885af98f.png)

### 位置を共有したARのゲーム等を作るにあたって
複数端末の位置（相対位置）が共有されてても座標形が一致（原点が現実世界上の座標の同じところにあるということ）してないとUnity上の同じ座標に物を生成してもARで通して見ると違うところにあるといったように場所が狂ってしまいます

なので現実世界上での共通の場所をそれぞれの端末の原点とする（すべてのオブジェクトをその共通の座標からの相対座標に設定する）と座標系が一致します

ここでARCollaborationDataのアンカー（ReferencePoints)を共有するという機能を使います
アンカーは現実世界上の取得した特徴点の上に設定することができるのでそのアンカーを共有することによって複数端末上で現実世界上の同じ位置のUnity上の座標が取れる様になります
その後、その場所をUnityでの原点にするような処理を行えば複数端末の座標形が一致します

原点の合わせ方については以前書いたこの記事が参考になります https://qiita.com/SAyanada9/items/806f202ccfc1ba55619a 

# まとめ
ARkit2のARWorldMapよりは位置を共有するのは楽にはなった（それでも少々使い辛い）ので使ってみるのも良いかもしれませんね
Kubuntu 19.10, 少しカストミズ

![Screenshot_20191207_202107.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548926/40024fd6-ee4b-759f-e763-27771b2f3376.png)

Global menu pluginとActiveWindowControlつかってます。
それで、タイトルバーいらないです。

ターミナルは、代々いつもKonsole使ってるけど今はCool-Retro-Term使ってます

後KonquerorとDolphinとKateとOkular

全部素晴らしいですね

これで、僕のQiitaの初めてのポーストです。

宜しくお願いいたします。

マシュ

もう一つ。。。
![Screenshot_20191210_231431.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/548926/3c2ddf50-6b0f-0698-0a7e-089a78987d6a.png)
クラッピー　スイッチハック

この記事は[クラッピーチャレンジアドベントカレンダー2019](https://adventar.org/calendars/4222?fbclid=IwAR1R5JARl-7czdiHFMoUmZYtWMbXm8eN3CwOjKe0BfUuxknZYhSFDaBdhRY) 12日目の記事になります。


クラッピーチャレンジに残された最後の秘境と言われる「帽子」
**#誰も言ってない**
![IMG_8362.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/fe208415-ca25-7ea9-7e90-51c59d647c94.jpeg)
その帽子の
![IMG_8360.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/ab4199be-08f3-b247-3a0a-d13005cc1903.jpeg)
四角い穴が、
　　　：
　　　：
　　　：
　　　：
　　　：
　　　：
　　　：
　　　：
　　　：
[スライドスイッチ](http://www.aitendo.com/product/10438)にジャストフィット
![IMG_8365.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/7da50508-f416-99a0-6929-76779a861260.jpeg)

キツ過ぎずユル過ぎず、あつらえたかのようにピッタリです。
これはもうただのライドスイッチではありません。**クラッピー用スライドスイッチ**です。

**しかも！**
帽子を一番下まで押し下げるとネジと帽子の縁でロックがかかり、スイッチが前に入らなくなります。
![IMG_8364.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/ae4b251a-5d8d-c955-9aea-d236a6e89a25.jpeg)

スイッチ部分が3mm角のものなら何でもフィットすると思いますが、
秋月電子通商やaitendoで手に入る**クラッピー用スライドスイッチ**は下記になります。

#秋月電子通商
[Ｓ－１２Ｄ０１－ＶＧ４](http://akizukidenshi.com/catalog/g/gP-08791/)
![IMG_8361.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/3c1b00d8-ba7e-a6ae-56b6-bc6c53386006.jpeg)

#aitendo

[SS12F16](http://www.aitendo.com/product/10438)
[ATD12F15G](http://www.aitendo.com/product/6991)
[ATD12F44G](http://www.aitendo.com/product/6992)
10個100円とありますが、店頭だと1つ10円～50円程度（日によって値段が違う）で購入できます


それでは良いクラッピーチャレンジを！
メディアクエリ　メモ

#HTML
```html:sp.html
<link rel="stylesheet" href="style.css" media="screen and (max-width:480px)">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
```
ブレークポイントが480pxの場合の記述です。

#CSS
```css:sp.css
@media screen and (min-width:480px) { 
    /*　画面サイズが480pxからはここを読み込む　*/
  p { 
    color:#ededed;
  }
}
```
勉強記録　14日目 〜オブジェクトの初期化〜 - Effective C++ 第3版 -

#　はじめに

Effective C++ 第3版の4項18ページから勉強していきます。
今回は、「オブジェクトの初期化」についです。

# Effective C++ 第3版 - 4項　オブジェクトは、使う前に初期化しよう -

## オブジェクトの初期化

### オブジェクトの初期化とは？

オブジェクトの初期化について、

```cpp
int x;

std::cout << x << std::endl;  // 0 or ?
```

のように書くと、xは、ある状況ではxは(0に)初期化され、別の状況では初期化されません。
また、

```cpp
typedef struct {
  int x;
  int y;
  int z;
} point_t;

point_t point;

std::cout << "point.x : " << point.x << std::endl;  // 0 or ?
std::cout << "point.y : " << point.y << std::endl;  // 0 or ?
std::cout << "point.z : " << point.z << std::endl;  // 0 or ?
```

のように書くと、pointのデータは、ある状況では(0に)初期化され、別の状況では初期化されない。

初期化されていないオブジェクトの値を呼びだそうとすると、結果は未定義の動作になります。
よくあるのは、たまたまそのオブジェクトの中にあった「でたらめな値」を読みだす動作をします。
それに気が付かないと、プログラムが不思議な動作をするようになり、つらいデバッグ作業をしなけらばいけなくなります。

オブジェクトがいつ初期化され、いつ初期化されないかについては、ちゃんとルールがあります。
しかし、そのルールはとても複雑です。
そのため、「オブジェクトは、使う前に必ず初期化する」というが良い。

組み込み型の初期化は、以下のようなものがある。

```cpp
int         x2   = 0;                   // intの初期化
const char* text = "A C-style string";  // ポインタの初期化
double      d;                          // 入力ストリームから
std::cout << "入力 : "; 
std::cin >> d;                          // の読み込みによる初期化
```

このように、「オブジェクトは、使う前に必ず初期化する」ことで、「でたらめな値」を読みだす動作を防ぐことができます。

以下に、勉強で使用したコードを示します。

### サンプルコード

```cpp:4_initialize_tutorial.cpp
#include <iostream>

// int は全ての状況で0に初期化されるわけではない。

typedef struct {
  int x;
  int y;
  int z;
} point_t;

int main(int argc, char* argv[]) {
  std::cout << "4_initialize_tutorial.cpp" << std::endl;
  int     x;
  point_t point;

  std::cout << "x : " << x << std::endl;
  std::cout << "point.x : " << point.x << std::endl;
  std::cout << "point.y : " << point.y << std::endl;
  std::cout << "point.z : " << point.z << std::endl;

  // ##############################################
  // いろいろな初期化
  int         x2   = 0;                   // intの初期化
  const char* text = "A C-style string";  // ポインタの初期化
  double      d;                          // 入力ストリームから
  std::cout << "入力 : "; 
  std::cin >> d;                          // の読み込みによる初期化

  std::cout << "x2 : " << x2 << std::endl;
  std::cout << "text : " << text << std::endl;
  std::cout << "d : " << d << std::endl;
}
```

### 実行結果

![4_initialize_tutorial.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/367151/5d2b4b04-b04f-ed49-a57e-11a3d3c082f3.png)


実行結果から分かるように、変数xは、「4197811」とよく分からない値を出力しています。

## 参考文献

・https://www.amazon.co.jp/gp/product/4621066099/ref=dbs_a_def_rwt_hsch_vapi_taft_p1_i0
振り返りのはじめに行うアイスブレイクを紹介します！

この記事は[All About Group（株式会社オールアバウト） Advent Calendar 2019](https://qiita.com/advent-calendar/2019/allabout)  10日目の記事です。

私たちはチーム開発をしており、1週間ごとに区切りとして振り返りをしています。振り返りをするときに組成したばっかりのチームだとなかなか意見が出にくいですよね。そういう状況を打破するためにアイスブレイクを最初にやります。今回は今までやったアイスブレイクを紹介します。（実際やってみた評価とこういうところがいいなあって思う観点を５段階で評価してます。）

## good and new

盛り上がり度: :star::star::star:
真新しい度: :star::star::star::star:

これは有名ですね。やり方は簡単で、今週あった、良かったこと、新しく始めたことを一言ずつ話します。仕事をしている面を多く見ているので聞いてみると、え！そんなことやってたの？とか、それは良いね！みたいなリアクションもでて、場の空気が柔らかくなります。慣れてるチームだと、今気になることも出てくる（携帯が見当たらないとか、子どもの様子が気になるとか）ので、今まで知らなかった色々な面を知れるのが良いと思っています。

## 1文字漢字

盛り上がり度: :star::star::star::star:
表現の広がり度: :star::star::star::star:

こちらはペンと付箋を使います。今週1週間を漢字1文字で表すと？という質問で書いてもらい、1人ずつ出します。やってみると漢字に落とし込むのが意外に難しく、でも話すと文字に込められた思いがバーーと出てくるのですごく盛り上がります。good and new に近いですがキャラが出るので個人的には1番気に入っています。

## 斜に構える、構えない

盛り上がり度: :star::star::star::star::star:
新たな発見度: :star::star::star::star::star:

一時期ネットでも話題になりましたが元ネタはこちらです：[斜にかまえる、かまえないを1分ごとに切り替えるとどうなるか :: デイリーポータルZ](https://dailyportalz.jp/kiji/sya_ni_kamaeru-kamaenai)

これ以外に難しいですね。普段どちらのスタンスにいるかっていうのもあるかと思います。どちらのスタンスにいても普段は使わない表現だったり観点だったりが出てくるので、終わった時には笑いとともに、なるほどー感がすごくあります。

## ○○用語 山手線ゲーム

盛り上がり度: :star::star::star::star:
学び度: :star::star::star::star::star:

テーマを設けた山手線ゲームです。参加者の知識と人数によるのでテーマ設定がなかなか難しいですが、頭の体操＆アイスブレイクとしては十分楽しめます。いままでやったテーマは **Laravel Collectionメソッド**、**Linuxコマンド**、**VSCodeショートカット** って具合に、業務にめちゃくちゃ密接なテーマで行いました。やってみると「あれ？なんだっけ？？」「なにそのコマンド！知らなかった！」なんてことも出るので、実は一番学びになります。

## 外国語発話

盛り上がり度: :star::star::star::star:
グローバル化度: :star::star::star::star:

オールアバウトにはベトナムに開発ラボがあります（[ベトナムからこんにちは！ オールアバウトのオフショアを牽引するラボ開発グループ](https://about.allabout.co.jp/koto/190613_01)）。
ちょうどラボに出張していたメンバーが帰ってきたタイミングだったので、ベトナム語を教えてもらって発音してみようってことでやってみました。といってもベトナム語は発音が難しいのでGoogle翻訳の音声をたよりに全員で発話するだけです。こっちで話すようなことをベトナム語でいったらどうなるんだろう？っていうことを翻訳にかけて音声を流す→みんなで発話するって感じです。当然慣れてないのでわからないんですけど、ラボにいってたメンバーからこの単語がこの意味ですね、なんてことも出てきて、なんとなく外国語を近くに感じられます。


いかがだったでしょうか？振り返りもただワークをするだけではなくてこういうアイスブレイクを最初に行うと、話も盛り上がって良いふりかえりができ、新しい発見もあるとおもいます。どれもお手軽にできるものばかりなので、気に入ったものがあったらやってみてください。
YugaByteDB(1) Rookv1.1で対応！YugaByteDBとは

この記事は「[RookだらけのAdvent Calender](https://qiita.com/advent-calendar/2019/rook)」10日目の記事です。

昨日、[Japan Rook Meetup](https://rook.connpass.com/event/152741/)が行われましたが、そちらでも紹介したYugaByteDBについて、何回かに分けて解説をしていきます。

# RookにおけるYugaByteDB対応とは
アドベントカレンダー1日目の「[Rookの概要とRook-Ceph](http://ututaq.hatenablog.com/entry/rook/01)」にもあったように、Rook自体はマルチなストレージプロバイダをオーケストレーションできるツールです。

その中でCephなどのSDSと異なり、データベースに近いプロバイダとして、以下3つがあります。

- Cassandra (http://cassandra.apache.org/)
- CockroachDB (https://www.cockroachlabs.com/)
- YugaByteDB (https://www.yugabyte.com/)

これらは分散KVSまたはRDBですが、Rookによりオーケストレーションが可能となっています。

## YugaByteDBにRookはどの程度本気なのか？
本日以降のアドベントカレンダーで各ストレージプロバイダを検証していく上で、これは重要な視点になるでしょう。

既にStableであるCephとEdgeFSと比較して、YugaByteDBやその他のプロバイダは明らかに違いが見られます。具体的にRookの公式ドキュメントを見てみましょう。

公式ドキュメントにある[YugaByteDBのCRD](https://rook.io/docs/rook/v1.1/yugabytedb-cluster-crd.html)の箇所を見てみましょう。ここにはRookのCRDの仕様が書かれていますが、

- kind: **YBCluster**

が一つあるだけです。

一方、Cephはどうか。[ここ](https://rook.io/docs/rook/v1.1/ceph-storage.html)にあるRookにおけるCeph Storageの概要に始まり、以下のCRDの仕様を確認することが出来ます。

- kind: **CephCluster**
- kind: **CephBlockPool**
- kind: **CephNFS**
- kind: **CephFilesystem**
- kind: **CephObjectStore**
- Kind: **ObjectBucketClaim**
- kind: **CephObjectStoreUser**

もちろんCephの多機能さに起因する部分はありますが、データベースのOperatorは良くあるSnapshotやリカバリの機能などがRook-YugaByteDBでは提供されていません。

この辺りの開発が進むかどうかが、RookにおけるYugaByteDB利用が拡がるかの鍵になってくることは間違いありません。

## Rookの競合は？
これは完全に私見ですが、Rookのストレージプロバイダ対応状況はAWS（に限らずクラウドプロバイダ）のサービスと比較すると少し見通しが立ってきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54853/e02f9e65-7000-159e-8f71-3cda6d14faad.png)

ストレージとしてはEBS/EFS/S3などをサポートし、Cassandraや分散型のデータベースサービスを提供しているAWSはクラウド上ではRookの上位互換です。

オンプレKubernetes上でのストレージプロバイダ管理でRookが優るようにも見えますが、これも今後次第かなという状況です。

# YugaByteDBとは
特徴は先日の発表資料から以下をご覧下さい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54853/349b0b37-1fa3-9725-76ae-c30f57b1628f.png)

[Google Cloud Spanner](https://cloud.google.com/spanner/?hl=ja)は非常に高性能なSQLサポートのデータベースですが、GCPでしか使えず、ロックインが発生します。

それに対し、オンプレミスや他のクラウドでSpannerと同等の機能と性能を実現しようとしているデータベースとして以下のようなものがあります。

- YugaByteDB
- CockroachDB
- TiDB

いずれのデータベースも膨大なノード数（100台から数百台規模）までスケールし、各種のコンポーネントをその上に展開することから、Kubernetesの力を借りてデプロイ・管理可能なことをうたっています。

## DBMSとしての特徴
Kuberntetesで展開可能な大規模スケールのデータベースとしては、CNCFでGraduationとなったVitessがあります。

このVitessとYugaByteDBは構造として大きく異なります。

**【Vitess】**

- 1つ以上のコーディネータを持ち、その下にシャーディング・インスタンスがぶら下がる形。
- シャーディング・インスタンスは（ほぼ）シンプルなMySQL。
- 各インスタンスが持つデータは分かれており、それぞれへのクエリをコーディネータが振り分ける。

**【YugaByteDB】**

- SQLエンジンと分散ストレージの2つのコンポーネントからなる。
- 分散ストレージはKVSとして実装されている。
- データはストレージ内で3重に冗長化される

YugaByteDBの構造に関しては明日以降に詳しく解説していきます。

# まとめ
さて、YugaByteDBとしての1日目となる本日はRookから見たYugaByteDB、そしてデータベースとしての構造の簡単な解説を行いました。

明日からは実際にRookを使ってYugaByteDBをインストールして、実際に使用感を試していきたいと思います。

よろしくお願いします。
VueCLIをインストール！ ❏Vue.js❏

Vue.jsを開発するにあたって、VueCLIをインストールしていきます。

<br>
#【手順0】Node.jsをダウンロード
既に入ってる人はスルー
公式からダウンロードします。

![ダウンロード (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529651/8aa20e4e-b278-23f1-e2f9-2b82499eb675.png)

>https://nodejs.org/ja/

<br>
#【手順１】VueCLIをインストール

```:ターミナル
$ npm install -g @vue/cli
```

`-g`はグローバルオプションで、このファイルだけでなく全体で使えるよーっていう意味です。

<br>
エラーが出た場合はこちらの記事を参考にしてみてください。
>https://qiita.com/okohs/items/ced3c3de30af1035242d

<br>
【確認】

```:ターミナル
$ vue --version

@vue/cli 4.1.1
```

<br>
#【手順２】新プロジェクトを作成

```:ターミナル
$ vue create manbowjs

Vue CLI v4.1.1
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)  #初心者はデフォルトでEnter
  Manually select features 
```

無事`manbowjs`ディレクトリができました。

<br>
#【手順３】開発用サーバーをたてる

```:ターミナル
$ npm run serve

 DONE  Compiled successfully in 3544ms                                                                                                                          22:41:36

  App running at:
  - Local:   http://localhost:8080/ 
  - Network: http://172.20.10.2:8080/

  Note that the development build is not optimized.
  To create a production build, run npm run build.
```

あとは開発するだけ！

<br>
ではまた！
Word VBA １行づつ余計な改行が入っている場合に1行だけ改行させるマクロ

Word ：空白行を一括削除するには
http://office-qa.com/Word/wd394.htm

というのをいつも使っていつも忘れるのでVBA化しました。
なんのことだかわからない人は紹介したサイトを見てください。
しかし

>※空白行は前の段落から数えて段落記号が2個以上あるからです。
>※13で置換するとレイアウトが崩れるため^pを指定します。

このあたり本当にどこに書いてあるんだ。。。
しかも改行と自分が言っているのは本当は段落記号らしい。
ちなみに元サイトは2つ以上の連続ですが、こちらは1つだけにしています。


```vb
Sub WordTwoLinesOnelineJpn()
' For Word 2007 Later
' 日本語用 For Japanese
With Selection
.EndKey Unit:=wdStory 'いったん文末に飛ばし、文頭に飛ばす
.HomeKey Unit:=wdStory
.Find.ClearFormatting '段落書式指定をクリア
.Find.Replacement.ClearFormatting 'Removes text and paragraph formatting from the text specified in a replace operation.
.Find.ClearAllFuzzyOptions 'Clears all nonspecific search options associated with Japanese text.
.Find.ClearHitHighlight
With .Find
.Text = "^13^13"
.Replacement.Text = "^p"
.Forward = True
.LanguageIDFarEast = wdJapanese '日本語以外では設定を変えるか省略する
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.MatchAllWordForms = False
.MatchSoundsLike = False
.MatchFuzzy = False
.MatchWildcards = True
'.Execute2007 'Selection.Find.Execute2007(FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward, Wrap, Format, ReplaceWith, Replace, MatchKashida, MatchDiacritics, MatchAlefHamza, MatchControl, MatchPrefix, MatchSuffix, MatchPhrase, IgnoreSpace, IgnorePunct)
.Execute Replace:=wdReplaceAll 'ここを外さない 'Selection.Find.Execute (FindText, MatchCase, MatchWholeWord, MatchWildcards, MatchSoundsLike, MatchAllWordForms, Forward, Wrap, Format, ReplaceWith, Replace, MatchKashida, MatchDiacritics, MatchAlefHamza, MatchControl)
End With
End With
End Sub
```
FORMAT 芸　リフレクション？

# FORTRAN の FORMAT はインタープリタ方式

Fortran の I/O の FORMAT は、実行時に解釈されるインタープリタ方式になっています。このため書式付き I/O が遅くなっていて、昔から難癖付けられています。人間が開いて見るのでなければバイナリで読み書きするのが無難でしょう。

ある時 FORTRAN の開発者である J. Backus が、 FORMAT の書式の解釈はコンパイル時に静的に確定されてもいいはずなのに、インタープリタ方式なったのは何故かと聞かれて、分かっていたが FORTRAN I の時にスケジュールが遅れて時間が足りなかったからだと答えています。[^1]



ところで FORTRAN77 以降 FORMAT は、FORMAT 文や文番号抜きに、READ/WRITE 文に直接文字列や文字変数として与えることが出来ます。 （FORTRAN66 でも、変数や定数に文字型はありませんが、変則的に可能でした。）

例：

``` fortran
write(6, '(f10.2)') x 
```

したがって、静的な言語である classical な FORTRAN でも FORMAT の所だけは、実行時に動的に自己書き換えを行うことが出来、いわゆる reflection（リフレクション＝内省？）が出来ます。微妙ですがｗ

以下に簡単な実例を示します。

## 実例 　
modern fortran 版ですが･･･

format を文字変数 fmt に入れています。内部ファイルへの write で文字列 fmt 自身を書き換えます。DO LOOP で fmt 中に１回目は十進数で、二回目以降は二進数のビット表示で書き出しています。

実は fmt 自身を書き換えるタイミングがよく分かっていませんが、一応動いていますｗ

### source program 
```fortran
    program Console1
        implicit none
        character(len=80) :: fmt = '(a, i1, a)'
        integer :: i
        print *, fmt
        do i = 2, 4
            write(fmt, fmt) '(a, b', i, ', a)' 
            print *, fmt
        end do    
    end program Console1
```

### intel fortran 出力
```
(a, i1, a)

(a, b2, a)

(a, b11, a)

(a, b        100, a)
```
### gfortran 出力
```
 (a, i1, a)
 (a, b2, a)
 (a, b11, a)
 (a, b        100, a)
```

[^1]: R. Wexelblat, editor. History of Programming Languages, ACM Monograph Series, Academic Press, 1981. p.70 ; http://www.softwarepreservation.org/projects/FORTRAN/paper/p68-lee.pdf （少し記憶違いがあって、Backus の指名で担当者が方便上のもので本当はコンパイルする意図だったが時間が無かったと答えています。）![format.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44522/51802efa-3270-8098-5737-ef8257268ff1.png)
Zabbixエージェント2を使ってみよう

Zabbix Advent Calendar 2019の10日目の記事です。

Zabbix関連のニュースをご覧になっていらっしゃる方は、「Zabbixエージェントが[Go言語](https://golang.org/)で書かれるようになった」とのニュースがあったことを覚えていらっしゃると思います。

Zabbix 4.4リリース時点では、旧来のC言語で記述されたZabbixエージェントが無くなったわけではなく、旧来のZabbixエージェントとZabbixエージェント2と呼ばれるGo言語で記述されたものの2つのエージェントが存在しています。また、現時点のリリースでは、Zabbixエージェント2は実験的(experimental)なリリースという状態です。

先日のオープンソースカンファレンスでもご紹介しましたが、その概要とインストールについてまとめておこうと思います。


# Zabbixエージェント2とは

Zabbixエージェント2というのは、既存のZabbixエージェントをGo言語を使用して書き直したエージェントです。
C言語の実装をそのままGo言語に移植したのではなく、設計の見直しを行って、これまでの課題を解決することも視野にいれて開発されました。

# これまでの課題

先日のZabbix Conference Japan 2019での説明では、旧来の以下の課題があると考えているようです。

- より高速な拡張にはC言語での実装が必要で敷居が高い
- アクティブチェックでは監視間隔のカスタマイズに対応していない
- アクティブチェックのプロセスがサーバーに対して1つしかない(処理並列度が低い)
- 他のプロセスやシステムからのイベントをエージェントで受け取ってサーバーに通知するような機能が無い


# 課題に対する対応状況

それらの課題に対して、現時点は以下のような改善が行われているそうです。

- Go言語での実装(C言語より簡単)
- TCPコネクション数の削減
- 同時実行性の改善
- 拡張を考慮したプラグインフレームワークとしての実装(長時間かかるスクリプトの実行などにも対応)
- 単一バイナリでの容易な配置

Zabbix Conference Japan 2019で発表され公開されている資料「[MAGIC OF THE NEW ZABBIX AGENT](https://assets.zabbix.com/img/zabconf2019_jp/presentations/10_zabconf2019.pdf)」もご参照ください。


# Zabbixエージェント2のインストール

それでは、早速使ってみましょう。
RHEL 8(CentOS 8)用であれば、公式のリポジトリからZabbixエージェント2のパッケージを取得できるので、Zabbixエージェントの代わりに、Zabbixエージェント2をインストールします。

もしも、すでにZabbixエージェントをインストール済みであったならば、一度アンインストールします。


```
# dnf remove zabbix-agent
```

Zabbixエージェント2をインストールするには、以下のようにコマンドを実行します。

```
# dnf install zabbix-agent2
```

Zabbixエージェント2の設定ファイルである/etc/zabbix/zabbix_agent2.conf内のHostnameやServer、ServerActiveなどの値が環境に合っているか確認します。基本的な設定は、以前のZabbixエージェントと同様です。将来的には、設定項目が追加されて、より柔軟な監視設定が可能となると思われます。

マニュアルを見ると、Zabbixエージェント2では、従来のZabbixエージェントの設定とは以下の部分が異なっているようです。

削除されたもの：

- AllowRoot
- HostInterface
- HostInterfaceItem
- LoadModule
- LoadModulePath
- StartAgents
- User

追加されたもの：

- ControlSocket
- Plugins
- StatusPort

追加されたものは、-Rオプションでのランタイムコマンド受付用ソケット、プラグインごとの設定追加、エージェントの状態を返却するためのポート番号などです。

詳細は、[マニュアル](https://www.zabbix.com/documentation/4.4/manual/concepts/agent2#configuration_file)をご参照ください。

設定が確認できたら、エージェントの起動と自動起動の設定を行います。

```
# systemctl start zabbix-agent2
# systemctl enable zabbix-agent2
```


# 注意点

旧来のZabbixエージェントと比較すると、設定から削除されていることからもお分かりの通り、ダイナミックライブラリを使用した機能拡張を使用することができません。また、AllowRootとUserを指定してrootユーザーで起動することもできません。
また、プラグインを追加して新しい監視対象や監視方法に対応するためには、プラグインのソースを追加してエージェントをビルドし直すことが必要です。

また、機能として、プラグインごとにタイムアウトの設定が可能になるような機能構成になってはいるようなのですが、現時点ではタイムアウトの設定としては、旧来のTimeoutのみとなっているように見えます。この部分は、正式リリース時には改善されるでしょう。


# 今後のリリース

Zabbix 4.4リリース時点では、UNIX系OSのみの対応となっています。Windows版は開発中だそうです。
また、C言語で記述されたライブラリにも一部依存しているので、Go言語だけで記述されたものではありません。

予定の段階ですが、次のLTSバージョンとなるZabbix 5.0で正式なリリースとなり、Windowsプラットフォームへも対応するそうです。現時点(2019/12/10)ではまだ公開されていませんが、[Zabbix 5.0のロードマップ](https://www.zabbix.com/roadmap#v5_0)を近日公開予定とのことですので、次バージョンがどうなるか興味のある方はウォッチしておいてください。

さてさて。明日は、誰でしょう？
どなたかよろしくお願いします。
configure オプションの --with と --enable の使い分け

オプションを追加したくなったらこれを読みましょう。
https://autotools.io/autoconf/arguments.html


`--with-X[=/path/to/x]`/`--without-X` は、X という**依存**(ライブラリ等)の場所を指定したり、そのライブラリを使わないことを指定します。
何かのライブラリを使わない結果として何かの機能が有効化／無効化されることはあるかもしれませんが、 X 自体は依存するものの名前で、機能の名前ではありません。

`--enable-Y`/`--disable-Y` は、Yという**機能**の有効／無効の指定をします。何かの機能を有効／無効にした結果として依存ライブラリが増えたり減ったりすることがあるかもしれませんが、Yは機能の名前であって依存の名前ではありません。

さて、Python をビルドする時の最適化オプションに `--enable-optimization`, `--with-lto` があるんですが、後者は `--enable-lto` にするべきだったなーとちょっと後悔しています。
一度間違えると、世界中にある Python をビルドするためのスクリプトがすでに `--with-lto` を使ってるかもしれないので、なかなか直せないんですよね。

なのでオプションを追加するときはよく考えましょう。
IT未経験者がVBAに手を出した話

はじめまして、わだいこと申します。
文章を書くのが苦手なのでまとまりがなく読みにくいかもしれませんがご了承ください。

##   私の状況 

スーパーでお肉を切る仕事から一転IT業界に入り現在は某センターで働いています。
そもそもパソコンなんて学生時代にネットサーフィンしていたのとレポートやらでエクセルやワードを使う程度で初歩的なものしかできません。

IT業界といっても業務はほとんど対人対応で実質サービス業と言ってもおかしくはありません。しかも夜勤もあるのですが夜勤は対人対応すらないので待機するだけに・・・
そんな中配属から四か月、先輩からVBAに興味ありませんかと言われ、最初はやんわりと断っていたがしばらく勤務が一緒になるとVBAをゴリ押されていたのに加え職場の個人用フォルダにVBAの教材が置かれていたので諦めて勉強を始めることに。


## VBA開始

最初はセルやブック、シートの指定方法から
Range(“A1”)、Cells(1,1)、Workbooks(“ファイル名”).Worksheets(“シート名”)
Offsetの使い方などからスタート
最初の方はセル指定してるのに何でうまくいかねえんだよ！ってなりましたがシート指定してなくて別ブックがアクティブになっていたという小ミスでした。

その後は変数の置き方やIfやCase、比較演算子、ユーザーフォームの使い方等基礎的なものを学んだところで課題を出されました。
問題は全部で3個

1.	作られている表をもとに行、列ごとの合計の算出、項目ごとの割合を算出し20％以下の場合セルの色を変更

2.	ユーザーフォームを用いて電卓の作成

3.	ユーザーフォームを作成し情報の取り込みと変更の反映

このうち2つやればいいと言われた自分はその日から課題に取り組む。
GWだったので業務もほとんどなく課題をやっていて躓いたのは合計の算出
SUMみたいに書けばええやろとドヤ顔して次の勤務で見せたところなんでこんな方法を・・・と言われる。
そして教えられたのは

For  n = 1 to 4
Cells(5,1) = Cells(5,1) + Cells(n,1)
Next n
という方法、説明を受けてようやく理解する。
Cells(5,1)が初期値0だとしてCells(1,1)を足してそこにCells(2,1)・・・と続いていくわけですね。
完全に理解したわ

一応二回の勤務で完成はさせて次の課題は電卓を選択し四則演算は難しいことないやろ～～とへらへらしていたら足し算だけ文字列判定されてしまい、1+1が11になってしまうくらいでしたね。いや本当ですよ。

だいたい課題終わらせるまで2週間くらいでしたかね、すると言われるわけですよ。
「今使ってるツールの改修をお願いします」
毎日使うツールで気に食わない、仕様上どうしても不具合が起こってしまうため気に食わないということでやることになりました。
最初の一か月はひたすらコードを読み解く。
作成者があまりコメントを残してくれなかったせいで調べながら夜勤の時に少しずつ進めていきました。
Left Right Mid Instrだなんだと知らねえよ！！なんだよこれって怒りながらやりました。
大まかには理解したのでいざ新規で作成し始めると意外と順調。

ツールを使う際の動きとしては
デスクトップに用意した情報を取り込み、手入力で番号を割り振る
割り振った番号で印刷用のSheet2に情報を書き写し印刷する。

これもうすぐ完成するなーなんて考えていたら甘かったです、機能として他のエクセルファイルから情報の取り込み、作成しているマクロのファイルの別シートに情報の反映、印刷、大きく分けてこの3個を作っていたのですが別シートへの反映のマクロ作成時に問題が起きました。

別ファイルの情報を取り込んだのがSheet1
Sheet1の情報を反映するのがSheet2ですがSheet1とSheet2で割り振った数字は同じなのにどうして反映されないのか
For n = 1 to 55
For l = 1 to 4
Set rFno = Worksheets(“Sheet1”).Range(“A:A”).Find(n)
If Not rFno Is Nothing Then
Worksheets(“Sheet2”).Range(“A:A”).Find(n).Offset(0,l).value = rFno.offset(0,l).value
End If
Next l
Next n
なんて見づらそうだなーって書いていた部分がうまくいっていない、なぜなのか何回もやり直したけれど家のパソコンではうまくいく。諦めかけたところで気が付きました。
書式設定が違うじゃないか。そのせいでFindに引っかからなかった。なので調べてマクロを動かしたら最初に書式を変更するようにしました。誰かがいじってしまってもいいように。

それからは順調で、調べながら印刷設定や条件付きでセルの一部を引用するようにしてようやく完成。大体二か月くらいでしょうか、夜勤の際にコツコツ進めて完成させましたが上司のチェックもありリリースされたのは一か月後でした。まあ社内用なのでそんなに細かく見られはしませんが上司のタスクが多く遅くなりました。

これで夜勤も落ち着けるなんて思っていたら現場のPCをWindows10にアップデートをする。その際にツールが動かなくなるかもしれないのでチェックと必要があれば改修してくれと指令が下りる。先輩曰くInsert(挿入)を使っていると不具合が起こる、ということなのでInsert部分を全部置き換えていた。
そして追加機能を付けてくれと言われる。Insertだけだから楽だと思っていたのに結局また読み解くことになりとりあえずマクロを読み解きノートにまとめたところ言われた機能を追加する部分が決定する。ここまで2週間、残りは一か月、間に合うか？と思いながらトライアンドエラーを繰り返し完成。

ツールの動作で必要なファイルの引用するディレクトリの変更、保存するファイルの保存先の変更、追加で条件を設定して結果として表示される要素の追加。

なんとか期日には間に合い業務の簡略化もでき評価されました(派遣先なので派遣元にはその評価はきっといっていない)
あとWin10で動かない理由はInsertじゃなくて参照設定の参照ツールに互換性のない物があっただけでした。

##最後に

今では自分用にマクロを組んでいたりしますが次はSQLに手を出してみようと思います。
会社から指定されているCCNAとかLPICもやらないといけないですが、何から手を付けていけばいいか全くわからないIT業界入ってようやく一年の初心者のお話でした。

なにかおすすめなどあれば教えてくださいお願いしますなんでも
【Java】Stream APIを使って複数のリストから条件を絞ったリストを生成する

#データ例
次のようなデータを用意します．

**Staffリスト**

|name|rollType|
|:--:|:------:|
|佐藤|1|
|鈴木|2|
|高橋|3|
|田中|4|
|伊藤|5|

**Rollリスト**

|rollType|owner|
|:------:|:---:|
|1|true|
|2|true|
|3|false|
|4|false|
|5|false|

DBではよく見る構造ではないでしょうか．
ownerがtrueであるrollTypeをもつStaffのリストが欲しい時，どうしますか？
「DBからINNER JOINで持って来いよ」と思いますが，今回は独立にリストが存在することを仮定します．

実際に用意したリストは次のようになります．

```java:list.java
List<Staff> staffList = Arrays.asList(
        new Staff("佐藤", 1), 
        new Staff("鈴木", 2), 
        new Staff("高橋", 3), 
        new Staff("田中", 4), 
        new Staff("伊藤", 5)
);

List<Roll> rollList = Arrays.asList(
        new Roll(1, true), 
        new Roll(2, true), 
        new Roll(3, false), 
        new Roll(4, false), 
        new Roll(5, false)
);
```
Staff，Rollは次のようなクラスです．

```java:SampleClass.java
private class Staff {
    private final String name;
    private final Integer rollType;

    public Staff(String name, Integer rollType) {
        this.name = name;
        this.rollType = rollType;
    }

    public String getName() {
        return this.name;
    }

    public Integer getRollType() {
        return this.rollType;
    }
}

private class Roll {
    private final Integer rollType;
    private final boolean owner;

    public Roll(Integer rollType, boolean owner) {
        this.rollType = rollType;
        this.owner = owner;
    }

    public Integer getRollType() {
        return this.rollType;
    }

    public boolean isOwner() {
        return this.owner;
    }
}
```

#実際に取ってくる
以下にテーマであるStream，比較対象としてfor文を用意します．

##for文での記法
```java:Main.java
for (Staff staff : StaffList) {
    for (Roll roll : RollList) {
        if (roll.isOwner()) {
            if (staff.getRollType() == roll.getRollType()) {
                System.out.println(staff.getName());
            }
        }
    }
}
```
わかりやすいですね．

##Streamでの記法
```java:Main.java
staffList.stream()
        .filter( // 1.
                staff ->
                        rollList.stream()
                                .filter(roll -> roll.isOwner()) //2.
                                .anyMatch(roll -> // 3.
                                        staff.getRollType() == roll.getRollType()
                                )
        )
        .forEach(staff -> System.out.println(staff.getName()));
```

簡単に解説すると，

1. 内部条件がtrueとなるStaffをfilterする
2. ownerがtrueであるRollリストを生成
3. Rollリスト内にStaffのrollTypeがあるならtrueを返す

となります．

実行結果はどちらも
>佐藤
鈴木

となります．

#実行時間の比較
それぞれの記法を用いて条件を満たす新たなリストを生成（forは空のリストに対するadd，StreamはCollectorを使用），
これを1000000回繰り返した時の実行時間は次のようになりました．

|記法|実行時間(ms)|
|:-:|:-:|
|For|135|
|Stream|889|

実に6倍の差がついていますね．
何度か試しましたが，この差が大きく縮まることはありませんでした（当たり前）．

もともとStreamが高速でないのに加え，filter内でいちいちStreamを生成しているのが大きく響いているのでしょう．

簡単なループならfor文よりstream派なのですが，ここまでパフォーマンスに差がでるのは考え物ですね．

#まとめ
Streamを用いて疑似的なINNER JOINを達成
filterを入れ子にすることでリストのリスト・・・といったものにも対応可能
パフォーマンスの観点からみてFor文をおとなしく使おう


もしこれと同等の操作をより高速にできる手法がありましたらコメントお願いします．

#参考文献
[Java Stream APIをいまさら入門](https://qiita.com/takumi-n/items/369dd3fcb9ccb8fcfa44)
[JavaのStreamで二つの配列から重複する要素を削除したり、独自クラスを色々する方法](https://www.aozora-blog.com/2018/12/09/post-1117/)
OpenSSLをビルドする for Windows (+ Visual Studio )

ちょうど[OpenSSL](https://www.openssl.org/)をビルドする機会があったので書いておく。

公式→[OpenSSL](https://www.openssl.org/) 
参考にしたサイト→[技術系備忘録​/C++​/OpenSSL​/ビルド方法](https://thinkridge.com/modules/xpwiki/?%E6%8A%80%E8%A1%93%E7%B3%BB%E5%82%99%E5%BF%98%E9%8C%B2%2FC%2B%2B%2FOpenSSL%2F%E3%83%93%E3%83%AB%E3%83%89%E6%96%B9%E6%B3%95)

- 必要なもの
    - Visual Studio 2019
        - Visual Studioのダウンロードは[ここ](https://visualstudio.microsoft.com/ja/downloads/)
    - Perl (個人的には [StrawberryPerl](http://strawberryperl.com/) 一択)
        - [ActiveState](https://www.activestate.com/) を推奨してるけれど、[StrawberryPerl](http://strawberryperl.com/) の方が色々都合がいい
        - というかActivePerlじゃなくてActiveStateになってたのね......
    - ~~[NASM](https://www.nasm.us/)~~
        - ~~アセンブラ使うとき用~~
        - ~~参考サイトだと必要かもしれないとか書いてあったけど、無くてOK~~

以上。後は基本的に必要なものとOpenSSLを用意して、ビルドするだけ。

- ビルド環境
   - Visual Studio 2019 
     - 最新のやつで大丈夫
     - 2017 でもビルドできるはずだけど試してない
   - Strawberry Perl
     - 最新のやつで大丈夫
   - OpenSSL
     - ver 1.1.1d 

1. Visual Studio 2019 をインストール
2. Strawberry Perl をインストール
3. OpenSSLSetup.bat という新規ファイルを作成する
4. 以下のテキストを OpenSSLSetup.bat に書き込んで保存する。
5. 「開発者コマンド プロンプト for VS 2019」を管理者権限で実行
6. OpenSSLSetup.batを実行する。おわり。

```OpenSSLSetup.bat
setlocal
cd /d %~dp0

@echo on

del openssl-1.1.1d.tar.gz
rd /s /q openssl-1.1.1d

:: powershell -Command "Invoke-WebRequest -Uri https://www.openssl.org/source/openssl-1.1.1d.tar.gz -OutFile openssl-1.1.1d.tar.gz"
wget https://www.openssl.org/source/openssl-1.1.1d.tar.gz
tar -xvf openssl-1.1.1d.tar.gz

cd ./openssl-1.1.1d

perl Configure VC-WIN32 --prefix=%CD%\x86 --openssldir=%CD%\ssl no-asm no-shared
nmake.exe install

perl Configure VC-WIN64A --prefix=%CD%\x64 --openssldir=%CD%\ssl no-asm no-shared
nmake.exe install

cmd /k
```

実行にはちょっと時間かかるかも。

VC-WIN32 ... x86 用オプション
VC-WIN64A ... x64 用オプション

Debugのビルドも作りたかったのだけど、うまくいかなかった……。
-d 指定してもダメ。
debug-VC-WIN64A とかやってもダメ。
何かそれっぽいこと書いてあるのに……。

投稿した瞬間だと、開発者コマンドプロンプトの事書き忘れてたので追記しときました。
参考になれば。
メイン開発者から外れてみて思ったこと

#MAヒーローズ・リーグ Advent Calendar 2019 11日目です。
ちょっと早いですが明日会社の行事があるので一日前の投稿しますのでご了承ください。
HappyBirthdayメッセージ待ってます(￣ー￣)ﾆﾔﾘ。

実は今年は初の試みをしました。
そのことについて書いてみたいと思います。
##今回はじめてメイン開発者をやりませんでした。
なぜかと言うとこれからの人材を生み出していくにはやはりガチで自分で組んでいるよりみんなで組んだほうが楽しいと思ったからです。
正直出場回は必ず言っていいほどメインで開発してきました。
苦しいけど楽しい。
だけど人は育ちませんOrz。
だからこそ今回はあえてメイン開発者から外れました。
大学生に覚えてもらいたいといった気持ちもあったので今回は良かったと思っています。
ハッカソン界赤い芸人こと高橋さん（@mobilebiz)さんや孤高の放浪人こと青島さんに助けていただきました。
感謝しております。

##メインを外れてみて感じたこと。

正直言うと組みたい魂がわんさかしてましたが大学生の彼らに任せてよかったと思います。
彼らにとってもいい勉強になればと思っていましたのであえて今回は助言に徹しました。
でも結局みんな忙しくなり今回もエントリー見合わせになりました。
でも、自分的には満足しています。
あることを除いては後ほどTwilioアドベントカレンダーにお詫びに行きます。
それまでは大垣Pythonハッカソンに参加した人はあの事件のことは内緒願います。

###皆思いは一緒です。楽しく面白いものが作れればいいと思います。ですがガチはしません。ゆるゆるでいいんです。

なぜこれを強調するのかと言うと身体を壊しては元も子もないからです。
自分は実は5年間脱落しました。
正直治療というのは苦しかありません。
自分の場合は拡散アナログという空腹時に飲むきつい薬を一生薬を飲み続けないといけないので大変です。
しかも辛いときはデパスに出てきてもらうという始末ですが。
それでもハッカソンは楽しいです。
来年も出ますが今年と同様メインには立たず支援側に回ろうと思います。
個人で一つ出せたらいいけど余裕が今のところないのでできるようになったら考えてみます。

<strong>みんなエンジョイMAですよ。</strong>
Firebase Cloud Storageのセキュリティルール書き方一覧

この記事は、[Firebase Advent Calendar 2019](https://qiita.com/advent-calendar/2019/firebase)の13日目の記事です。

Firebase Cloud Storageのセキュリティルール書き方のサンプルです。
Firestoreのセキュリティルールは度々書いていたのですが、Firebase Cloud Storageのセキュリティルールはあまり書いてなかったなと思い立ち調べみました

# 基本

基本的な構文はFirestoreのセキュリティルールと変わりません。
異なる点としては、制御できる権限がデータ追加の`write`とデータ閲覧の`read`のみです。 

```javascript
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true;
    }
  }
}
```

# ユーザー認証
## 認証の有無によるアクセス制限
Firebase Authenticationが参照できるため、authの有無で判別可能です

```javascript
// 認証済みユーザーのみ閲覧可能
match /internal/{imageId} {
  allow read: if request.auth != null;
}

// 自分のuserIdに属するbucketのみ閲覧可能
match /user/{userId}/{imageId} {
  allow read: if request.auth.uid == userId;
}
```


## ユーザーの属性によるアクセス制限
Firebase Cloud Storageのセキュリティルールの中から**Firestoreの情報にアクセスすることは出来ません**。
なので、Firestoreのセキュリティルールのようにget関数でユーザードキュメントを参照して、、、という記述は不可です。
もし、ユーザーのロールに合わせた権限を設定したい場合は、**Firebase Autenticationの[カスタムクレーム](https://firebase.google.com/docs/auth/admin/custom-claims?hl=ja)を使って設定した値から参照**しましょう。


```javascript

// 事前にFirebaseFunctionsのフックなどでAuth userの追加時に、admin, groupIDのカスタムクレームを設定している前提

// admin権限をもつユーザーのみ閲覧、書き込みできる
match /files/admin/{fileName} {
  allow read, write: if auth.token.admin === true;
}

// 特定のグループに属するユーザーのみ閲覧出来る
match /files/{groupId}/{fileName} {
  allow read: if resource.metadata.owner == request.auth.token.groupId;
}

```

# ファイルのバリデーション
パス名や、`request.resource`と`resource`を参照することでファイルサイズや種別など様々なバリデーションが行えます。
`request.resource`は新たに追加されるファイルの参照で、`resource`は既に同名のパスにあるファイルの参照です。


## ファイル名での制限
パスからファイル名を参照してファイル名のバリデーションが可能です。（この場合だと、`{fileName}`）

```javascript
// ファイル末尾が.txtのファイルのみ追加可能とする
match /text/{fileName} {
  allow write: if fileName.matches('.*\\.txt')
}
// ファイル名が30文字未満のファイルのみ追加可能とする
match /images/{fileName} {
  allow write: if fireName.size() < 30
}
```

## 上書き制限
`resource`を参照することで同名のファイルがある場合の書き込み制限が可能です。

```javascript
// 同名のファイルがない場合のみ追加可能
match /{imageId} {
  allow write: if resource == null
}
```

## サイズでの制限
`request.resource.size`でデータのサイズを取得できます。

```javascript
// 5MB以下のみ追加可能とする
match /{imageId} {
  allow write: if request.resource.size < 5 * 1024 * 1024
}
```
## 種別での制限
`request.resource.contentType`でデータの種別を取得できます。

```javascript
// image/pngのみ追加可能とする
match /png/{imageId} {
  allow write: if request.resource.contentType == 'image/png'
}

// image/*のみ追加可能とする
match /image/{imageId} {
  allow write: if request.resource.contentType.match("image/.*")
}
```


# 終わりに
以上、Firebase Cloud Storageのセキュリティルール書き方一覧でした。
次回自分で使うときには、こちらも設定していこうかなと思います。

# 参考
https://firebase.google.com/docs/reference/security/storage#resource
最近知ったHTMLタグ

こちらは[GEEK Inc. Advent Calendar 2019](https://adventar.org/calendars/3921) 10日目の記事です。

#はじめに
こんにちは、初投稿です。

マークアップする上では正しい文書構造で記述する必要がありますが、
業務で初めて知るタグがあったので、
色々調べた中で知っておいた方が良さそうなタグを少しピックアップしてまとめました。

【参考にさせていただいたページ】
> https://developer.mozilla.org/ja/docs/Web/HTML/Element
> https://www.w3schools.com/tags/tag_address.asp


## &lt;address&gt;
**連絡先の電話番号・メール・住所などを含めることを示す要素**
・要素の中のテキストは斜体で表示される。

**例**

```html
<address>
  <a>TEL: 080-xxxx-xxxx</a>
  <a>メールアドレス: xxx@mail.com</a>
</address>
```

## &lt;del&gt;
**ドキュメントから削除されたテキストであることを示す要素。取り消し線が引かれる**
・逆に、追加された文字列を示すのは```<ins>```で、こちらは下線が引かれます。

**例**

```html
<p>
  吾輩は<del>犬</del>である。
<p>
```
↓
**<p>吾輩は<del>犬</del>である。<p>**

なお、CSSでも以下の記述で取り消し線を引けるようです。

```css
text-decoration: line-through;
```

## &lt;blockquote&gt;
**引用・転載であることを示す要素**
・```cite```属性により引用元の文書のURL を、 ```<cite>``` 要素により引用元の文書のタイトルなどを明示可能。

**例**

```html
<blockquote cite="https://example.com/index.html">
  <p>我輩は猫である。名前はまだ無い。</p>
</blockquote>
```

## &lt;figure&gt;
**中の要素が図表やイラストなどのコンテンツであることを示す要素**
・```figcaption```タグにより、そのfigureのキャプションをつけることが出来る。

**例**

```html
<figure>
  <img src="graph.jpg" alt="図">
  <figcaption>これは図です。</figcaption>
</figure>
```

## &lt;time&gt;
**時刻や日付であることを示す要素**
・```datetime```属性で、日付や時刻を指定可能で、ここにはコンピュータで読み取れる正確な日付を入れることが出来る。

**例**

```html
<time datetime="2019-12-10T09:00">２０１９年12月１０日午前9時</time>
```


#終わりに

調べてみると色々あって改めて勉強になりました。
HTMLタグは新規追加や廃止やルールの変更がたまにあるので逐一取り入れていきたいです。


GEEKのアドベントカレンダー次回は、フロントエンドチームのtanigomeさんです！
[GEEK Inc. Advent Calendar 2019 - Adventar](https://adventar.org/calendars/3921)
react-isのバージョンには要注意

`react-is`のバージョン管理に失敗して、いろいろなトラブルに巻き込まれてしまいました。

## TL; DR

* `react-is`のバージョンは、`react`のバージョンと一致させる必要あり
* ただし、自動では保証されない
* yarnでバージョンダウンを行うのは、想像以上に面倒

## `react-is`って？

自分の記事で[以前に触れました](https://qiita.com/jkr_2255/items/cf4c9fffdd6501c95a78#react-is%E3%81%A8%E3%81%AF)が、あるオブジェクトが「Reactのコンポーネントかどうか」、そして「どのような種類のコンポーネントか」を、**オブジェクトの内部構造に直接触らずに**判定できるツール群です。

## トラブルの状況

React 16.9からdeprecatedの警告が強化されて、ライブラリとして入れているコンポーネントまで警告されるようになってしまったので、いったん`react`と`raect-dom`を`"^16.8.6 <16.9.0"`で止めることにしました。一方で、`react-is`は何の条件もかけずに放置していたら、`16.12.0`ぐらいまで上がっていました。

その結果、`React.memo`したコンポーネントの判定ができない状態に陥ってしまいました。いろいろ調べるうちに、`react`と`react-is`のバージョンの違いが問題だと思いあたりました。特に`peerDependency`などもかかっていなかったので、ずれても何も警告されませんでした。

## 戻すのも一苦労

ということで、`package.json`で`"react-is": "^16.8.6 <16.9.0"`と条件を明記して再インストールしたのですが、すでに`16.12.0`が入っていて、しかも`prop-types`など`react-is`に依存したライブラリがほかにもあったために、依存したライブラリには`16.12.0`が別途で入ってしまうという、ものすごく面倒な事態に陥ってしまいました。

`yarn upgrade`を行っても解決せず、結局「`yarn.lock`の直接書き換え」「`node_modules`の全消去」など強引な手段をとって、どうにか全部を`16.8.6`に統一することに成功しました。
Lark基本解説 (Python, Larkでシェルっぽいやつをつくる)

##まず
筆者はプログラミング初心者、かなり無知マンなので、様々な名称を知らず、"***なやつ"等曖昧な表現が用いられますがご容赦ください。

##やることとか
bashライクな書き方で動作するやつ(なんて言うのかしらない)をつくりたい！のでつくりました。

作成したプログラムは、例えば次のようなスクリプトを解析・実行して結果を返します

```
rand -s3 a b c + say def | replace e E
```

(結果は例えば`b a cdEf`のようになります)

この記事では、具体的な処理は割愛し、簡単にLarkの使い方を解説していこうと思います。

---

使用しているライブラリ
[Lark - a modern parsing library for Python](https://github.com/lark-parser/lark)

---

##文法規則ファイルの作成
まずパーサジェネレータに渡す、文法規則を記述したテキストファイルを作成します。
今回の場合は、
`script`は1つ以上の`chunk`が`join`で繋がれたもので、
`chunk`は1つ以上の`sentence`が`pipe`で繋がれたもので...
といった具合に記述していきます。

```:Grammar.lark
script : [chunk join] chunk

chunk : [(sentence pipe)+] sentence

sentence : command [space option] [(space arg)+] [/\n+/]

command : chars
        | ([chars] subshell [chars])+
option : "-" (chars|subshell)+
arg : chars
    | "'" allchars "'"
    | ([chars] subshell [chars])+

subshell : "(" script ")" [/\n+/]

chars : /[^\+\|\s\(\)']+/[/\n+/]
allchars : /[^']+/[/\n+/]
space : " "
join : [space] "+" [space]
pipe : [space] "|" [space]
```

##パーサの作成
パーサの作成の仕方です。先ほど作成したテキストファイルを読み込んで、Larkに渡すだけです。

```Python:パーサ作成部分
from lark import Lark

with open("Grammar.lark",encoding="utf-8") as grammar:
    LP = Lark(grammar.read(),start="script")
```

`Lark()`の第2引数`start=`には、いちばん外側の構成要素を書いておきます(たぶん)。

このパーサで試しに`rand -s3 a b c + say def | replace e E`を解析してみましょう。
解析結果ツリーの`pretty()`メソッドで、可読性を高く表示できますので、これを使いましょう。

```Python:パーサのテスト
tree = LP.parse("rand -s3 a b c + say def | replace e E")
print(tree.pretty())
```

```:結果
script
  chunk
    sentence
      command
        chars   rand
      space
      option
        chars   s3
      space
      arg
        chars   a
      space
      arg
        chars   b
      space
      arg
        chars   c
  join
    space
    space
  chunk
    sentence
      command
        chars   say
      space
      arg
        chars   def
    pipe
      space
      space
    sentence
      command
        chars   replace
      space
      arg
        chars   e
      space
      arg
        chars   E
```

(あれ？`space`なんかおかしくね？まいっか処理に使わないし...)
##トランスフォーマの作成
では、解析したツリーの様子に応じて処理を実行する部分を作っていきましょう。

```Python:トランスフォーマ作成部分
from lark import Transformer

class mytransformer(Transformer):
    def __init__(self): # 適宜使用する変数などを初期化
        self.var1 = None
        self.var2 = []

    def sentence(self,tree): # 第二引数を取るとsentence以深のツリーが使える!
        print("sentence") # example

    def command(self,tree):
        print("command")

    def option(self,tree):
        print("option")
```

`arg`や`chunk`などの処理は省略して記載しました。
`mytransformer`内で定義した`sentence`や`command`、`option`などは、**深度優先で**呼び出されます。なので、この例では
`command` -> `option` -> `sentence`といった順に処理が行われます。

トランスフォーマの使い方ですが、

```Python:トランスフォーマの使い方
tree = LP.parse("rand -s3 a b c + say def | replace e E")
mytransformer().transform(tree)
```

のようにして使用します。

##最後に
以上、簡単にLarkについて解説させて頂きました。

初心者がどうにかこうにか頑張ったものなので、誤り等あるかと思います。誤りを発見した場合はコメント等いただけると助かります。
設計書書くとき、シーケンス図ばかりになってる傾向について

# はじめに

最近、設計レビューをしてると、大量のシーケンス図が書かれた設計書をレビューの場に持ってこられるときがある。
構成としては、最初に適当なクラス図らしきものが1つあり、それ以外は百前後のシーケンス図がある、という感じ。

クラス図があるので、オブジェクト指向なのかと思いきや、とてもそうとは思えないクラス図で、そこからは何の設計意図も読み取れず、クラス図だけではレビューが成立しないことが多い。

クラス図と合わせて、百前後のシーケンスを見ていけば何となく分かるが、これだけ大量に見ないと分からないのって設計書なのか？と疑問に感じてるので、自分の考えをまとめてみる。


# ダメな静的構造図

静的構造図として、クラス図があるが、これがどう考えてもオブジェクト指向初心者、というか何もかじっていない人が描いたのが見え見え。
クラス名が、何とか制御とか、何とか管理とか。こういうクラス名がつく場合って、大抵の場合はオブジェクト指向になってなくて(あくまでも傾向であって絶対ではない)、処理を分解して抽出された物をクラスに当てはめてるだけ。当然、多重度も1対1ばかりになってしまっている。オブジェクト指向からほど遠い。

そして、クラスにはprivate属性のメンバー変数があるが、getterメソッドも併せて存在してる。そして、他のクラスからgetterを通してメンバー変数を取得させて、取得したクラスではif文とかで、何か判断して処理させてる。
隠蔽してないし、単なるグローバル変数と一緒。

これから読み取れる設計意図は、処理を分割しました、とあるグローバル変数相当のprivateメンバー変数はみんなでアクセスして使います、という意図かな(皮肉を込めて)。
この時点でレビューというより、教育モードに移行。


## 静的構造図のあるべき姿
クラス図は静的構造図なので、そのソフトウェアがどういう構造なのか、そして何を意図してそういう構造なのかを相手に伝える事が必要。
オブジェクト指向なら、データはここで保持し、そのデータに関する処理はそこで隠蔽されている、とかそういう事が図を通して理解出来ることが重要だと思う。クラス間の関係も、ロール名だったり、色々表現できるし、ここはデザインパターンの何とかパターンを用いるとかあれば、話もしやすい。

アプローチとしては、これから作ろうとしている対象は何か？というwhatをクラス図で表現できるとよい。クラス図を作成する際にどんな処理でというhowを考え過ぎると、処理が先行して抽出されてしまい、クラス図がおかしくなる傾向にあると思う。whatがクラス図で明確になったところで、それをどう作るのかというhowに取り掛かり、そこでデザインパターンやら駆使して、非機能要求だったり、保守性だったりを考慮して、テクニックを施せば良いと思う。
オブジェクト図を使って、クラス図を補足するのも良いだろう。


# ダメな動的構造図
で、静的構造の意図が読み取れないクラス図をベースに、こういう処理をするよっていうのがシーケンス図だけで表現されている。いつどのオブジェクトがgetter呼んで、何目的でその変数使うのかを、一生懸命シーケンス図で表現してる。レビューの効率が悪過ぎる。
それを指摘すると、じぁ、その変数の使用目的と、何に使うのかを整理しますって言われるが、いや、そもそもクラス構成がダメだからそれを整理しても、ゴチャゴチャなのがわかるだけだし、このまま実装してもテスト大変だし、バグまみれになる姿が容易に想像つく。保守性も悪く、仕様変更にも苦労するだろう。

## 動的構造図のあるべき姿
シーケンス図って、クラス図の様な静的構造図を元に、オブジェクト間の協調動作を表現して、この構造で設計が成立するか？を考えるもので、設計というよりは、クラス図を検証するという方が近いのではないかと思う。勿論、設計行為ではあるけれど、あくまでもどちらかと言えばという点で。
だから、大量のシーケンス図がある時点で、静的構造図で十分表現しきれてない、つまり設計が不十分なのだと思う。

動的構造図の一つに状態遷移図があるが、ちゃんと静的構造を書けてれば、どこに状態遷移が必要かはある程度明確になっているはず。処理先行で考えた適当なクラス図とシーケンス図からは、状態遷移が必要なことは見えてこないケースがほとんど。なぜならば、各クラスが持つメンバー変数がフラグとして使われ、それをシーケンス図で表現してるから、状態遷移で設計するという考えに行きつかないのだと思う。

# まとめ

オブジェクト指向をベースに話を進めてきたが、オブジェクト指向というより、そもそもの設計という事を知らないんだと思う。
新入社員の時から、この辺の教育をOJTでしっかりやっていかないと、ソフトウェア業界やばいと思う。
ソフトウェアは、素人が適当に作ってもそれっぽく動いてしまうっていうところがいい面でもあり、悪い面でもあると思う。
少なくとも、ソフトウェア業界でお金をもらって仕事してる以上はしっかり教育受けて(勉強して)、しっかりしたソフトウェアを作れるようにしないと。
Kali LinuxをVagrantで構築

## 概要
以前から興味のあったKali LinuxをVagrantで入れてみました。
基本的には公式の通りです。

## 環境
macOS Mojabe
Vagrant 2.2.3

## 作業
```
$ vagrant box add kalilinux/rolling
```
時間帯によって遅いかもしれません。
ボックスがダウンロード出来たら環境を作りたいディレクトリにて

```
$ vagrant init kalilinux/rolling
```
これでVagrantfileが作成されます。

```
$ vagrant up
```
この時点で上記コマンドを打つとVirtualBoxのUIがポップアップしKali Linuxの画面が表示されます。
なんでもKali toolsをGUIで使うことが多いためデフォルトはGUI表示するとのこと。

今回はheadlessで起動したいので、Vagrantfileを書き換えます。

```ruby:Vagrantfile(公式より）
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure("2") do |config|
  config.vm.box = "kalilinux/rolling"

  # Create a forwarded port
  config.vm.network "forwarded_port", guest: 80, host: 8080

  # Create a private network. In VirtualBox, this is a Host-Only network
  config.vm.network "private_network", ip: "192.168.33.10"

  # VirtualBox specific settings
  config.vm.provider "virtualbox" do |vb|
    # Hide the VirtualBox GUI when booting the machine
    vb.gui = false

    # Customize the amount of memory on the VM:
    vb.memory = "4096"
  end

  # Provision the machine with a shell script
  config.vm.provision "shell", inline: <<-SHELL
    apt-get update
    apt-get install -y crowbar
  SHELL
end
```

リロードで読み直すと入れました。
```
$ vagrant reload
  
$ vagrant ssh
Linux kali 5.3.0-kali2-amd64 #1 SMP Debian 5.3.9-3kali1 (2019-11-20) x86_64

The programs included with the Kali GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Kali GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
vagrant@kali:~$
```

## 参考
https://www.kali.org/news/announcing-kali-for-vagrant/