OmniAICreator/Qiita-1.07M huggingface dataset:
【Node.js】zxcvbnを使ってパスワード強度をチェックする

「パスワード強度チェックするようなライブラリって何かあるのかな？」
と興味本位で調べてみたら`zxcvbn`というものが見つかったので、ご紹介。

# zxcvbnとは

Dropbox社製のパスワード強度チェッカーです。
Node.js以外にも色々な言語に対応したライブラリが作られています。

[dropbox/zxcvbn: Low\-Budget Password Strength Estimation](https://github.com/dropbox/zxcvbn)

# 準備

```bash
$ npm i zxcvbn
```

# 基本的な使い方

とりあえず`hogehoge`という文字列に対してパスワード強度をチェックしてみましょう。

```javascript
const zxcvbn = require('zxcvbn');

const result = zxcvbn('hogehoge');
console.log(result);
```

基本的な使い方はとても簡単ですね。
第2引数に入力を渡して更に細かい設定をすることも可能なようですが、今回は遊んでみたかっただけなので割愛させてください。

出力内容を見てみましょう。

```bash
{
  password: 'hogehoge',
  guesses: 20003,
  guesses_log10: 4.301095134950942,
  sequence: [
    {
      pattern: 'repeat',
      i: 0,
      j: 7,
      token: 'hogehoge',
      base_token: 'hoge',
      base_guesses: 10001,
      base_matches: [Array],
      repeat_count: 2,
      guesses: 20002,
      guesses_log10: 4.301073422940843
    }
  ],
  calc_time: 3, # zxcvbnが計算するのにかかった時間(ミリ秒) あんまり気にしなくていい
  crack_times_seconds: { # パスワードが特定されるまでにかかる時間(秒)
    # 4種類の攻撃パターンごとの想定時間
    # 基本的には`offline_fast_hashing_1e10_per_second`の値だけ見ておけばいいかも
    online_throttling_100_per_hour: 720108,
    online_no_throttling_10_per_second: 2000.3,
    offline_slow_hashing_1e4_per_second: 2.0003,
    offline_fast_hashing_1e10_per_second: 0.0000020003
  },
  crack_times_display: { # パスワードが特定されるまでにかかる時間(わかりやすい形式)
    online_throttling_100_per_hour: '8 days',
    online_no_throttling_10_per_second: '33 minutes',
    offline_slow_hashing_1e4_per_second: '2 seconds',
    offline_fast_hashing_1e10_per_second: 'less than a second'
  },
  score: 1, # 0 ~ 4でパスワード強度を評価する
  feedback: {
    warning: 'Repeats like "abcabcabc" are only slightly harder to guess than "abc"',
    suggestions: [
      'Add another word or two. Uncommon words are better.',
      'Avoid repeated words and characters'
    ]
  }
}
```

`crack_times_seconds`の4種類のパターンについては、公式ドキュメントには次のように記述してありました。

- **online_throttling_100_per_hour**

> online attack on a service that ratelimits password auth attempts.

- **online_no_throttling_10_per_second**

> online attack on a service that doesn't ratelimit, 
  or where an attacker has outsmarted ratelimiting.

- **offline_slow_hashing_1e4_per_second**

> offline attack. assumes multiple attackers, 
  proper user-unique salting, and a slow hash function 
  w/ moderate work factor, such as bcrypt, scrypt, PBKDF2.

- **offline_fast_hashing_1e10_per_second**

> offline attack with user-unique salting but a fast hash 
  function like SHA-1, SHA-256 or MD5. A wide range of 
  reasonable numbers anywhere from one billion - one trillion 
  guesses per second, depending on number of cores and machines. 
  ballparking at 10B/sec.

うーん、セキュリティって難しい！

# 参考

- [zxcvbn \- npm](https://www.npmjs.com/package/zxcvbn)
それ原因はKKDです、IBM Cloud処方しておきます

本ブログエントリは IBM Cloud Advent Calendar 2019 に参加しています。
12/11 分のネタです。経緯を説明する導入部分が長いですが・・・・
まあ、お付き合いください。
（技術者側からマーケティング側にアプローチする前提、となっています。
マーケティング側から見たアプローチ視点は、別に記載（予定））


#要約
「KKD」で動いている業種はいまだに多い。それを転換するために
仮説検証を、リアルタイムにだれでも分かりやすい形にデータを提示する
**だれでも** **無料**で行えるようにした。

#前提
今回のターゲット：小売業の実店舗での棚決定
（販売助成は除く）

実店舗の商圏マーケティング（＝マーケティングといいます）で最低限必要な機能は下記３つ。

１．お客様は、いま”本音”では、何を考えているのか
２．お客様は、これからなにを望むのか
３．そのお客様は、いま”どこ”にいるのか

上記３つの測定を実現するために最小限必要な
node-red　テンプレートを用意しました。

#(1)課題：マーケティングの特徴（私見）
**１．変化が速い。本当に早い。1年離れると全く違ったものになる。**
　新しい技術から見ると、**ほんとうに**参入できるチャンスがあふれています。
とくに、ビッグデータを分析する手法は求められています。

##２．根性論がまかりとおっている
　いまだに、地域にいるひとに何を感じているかを考えることなく、つまり、
お客様の感情を”無視”して、クーポンをばらまく、といったことを行っている。

あと、CM。お客様の感情を無視して流すので、嫌われている、とか
さまざまな事例があります。
なので、感情ビッグデータを分析する手法は積極的に求められています。

##３．根拠のない数字がまかり通っている
TV視聴率※１というニーズや売上とは直接には関係ない指標で、
コンテンツ(番組)が評価されている。
　[商品に関するTwitter上のコミュニケーションと販売実績の関連性分析](www.orsj.or.jp › archive2
)
そして、この数字で、棚（商品の販売できる場所と数量）が決定されている。

誤解を恐れずいうと・・・・
売上が上がると分かる確かな指標、お客様が欲しい！と思っているけど、ないという現状です。
なので、商品・サービスが売れると分かる情報、お客様が欲しい！と考えている
客観的な感情データが求められています。

※正確にはGRP：延べ視聴率
TV放送された番組の視聴率を合算した数字。広告費用等すべてこの数字が基本となります。


だからこそ、IBM Cloud 「Node-RED」の
**感情をリアルタイムに可視化するテンプレート**が活きる！と考えています。

一応、「Node-RED」とは、
「Node」を画面でつないだ「Flow」を作るだけでコーディングなしで
プログラムが作れるツールです。

#(2)感情をリアルタイムに可視化するテンプレート

１．お客様は、いま”本音”では、何を考えているのか
２．お客様は、これからなにを望むのか
３．そのお客様は、いま”どこ”にいるのか

が、「Node-RED」では、コピペレベル（動画をアップロードするくらいのスキルレベル）でできます（それができるようにデザインテンプレートを作りました）
このnode-redでマーケティングで使うAIの機能の最小化を図り、
**無料かつ簡易**につかえるようにしました。


上記2つを公開情報（SNS/twitter）の

a. 文字列から、”本音”では、何を考えているのか

b.画像から、　何を望んでいるのか（予測）

c.設定情報から、いま”どこ”にいるのか

を抽出するnode-red テンプレートを公開します。

#(3)テンプレート
とりあえず代表的なテンプレート（英語版）を紹介します。
日本語版を整備済次第、順次公開します。

A. 文字列から、”本音”では、何を考えているのか(1.)　
![スライド1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387051/ee88e548-34d4-711f-4809-f3eef1e82025.png)

　[コードはまずこちら](https://flows.nodered.org/flow/ddf4a54f57b8eb71ec04413e48964c34)
  くわしい解説は後で記載（予定）

B.画像から、　何を考えるのか（予測）(1.")
![スライド2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387051/26b31497-9653-755c-b964-fc9476c49cdd.png)

　[コードはこちら](https://github.com/miraimeisatu/AIimage)
  くわしい解説は後で記載（予定）

C.設定情報から、いま”どこ”にいるのか(2.)　
![スライド4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387051/00fd3908-4c1d-e9fd-454f-9718df991109.png)

　　[コードはまずこちら](https://flows.nodered.org/flow/210746ff118272e4f38a073108193049)
  くわしい解説は後で記載（予定）
(クソ記事) localhost上でHTTPSなnginxコンテナを動作させ、/etc/hostsで名前解決してGmail APIのOAuth2を通す

# TL;DR

できます。
できました。

# 必要なもの

* MacOS
* mkcert (brew install)
* docker for Mac
    * nginx:latest
* /etc/hostsに関する知識
* dockerに関する知識

# モチベ

* わざわざドメイン取ったりDNS管理したりする必要があり、ただの静的HTMLをHTTPS公開したいだけなのに無料で出来ない。馬鹿馬鹿しい。
* じゃあlocalhostに対して、公開ドメイン名をhostsでmapしてブラウザ騙せばいいよね
* 実際に やってみた
* できた
* なおOAuth Consent Screenとかドメイン所有権確認とかは、ちゃんとDNS触ったりしたので、実は認証取るのに完全無料じゃない可能性はある。

# やりかた

1. コンテンツを作る。( index.html )
1. nginx:latest をpullしてくる。
1. mkcert で localhost と 対象のドメイン名に対応する証明書を生成し、自分のMacにinstallする。
1. nginxを TCP/443 でLISTENさせ、証明書とTLS関連設定を持ったssl.confをCOPYし、ビルド
1. コンテンツのディレクトリをmountさせ、docker run
1. https://www.example.com/path/to/file.html みたいにアクセスしてみる
1. できた

# 続かない

とりあえず「できた」ことだけメモっとく。
プログラミングを始めて1年

Ubiregi Advent Calendar 2019 6日目です！

#なにこれ
今日は技術の話でもなく、そもそも開発のお仕事に（まだ）就いていない人が1年、プログラミング(RubyとちょっとRails)を楽しく続けることが出来ているのでそれに関する話を書きます。

##自己紹介
株式会社ユビレジの原と申します。カスタマーサクセス(CS)部に所属しております。仕事はお客さんとの調整事やらなんやらで仕事では全くプログラミングしていません。

##そもそもなんでプログラミングやり始めたのか
純粋に楽しそうだったからです。結構もういい歳ですが、本気でジョブチェンジをしたい。世間体のあり様で言えば、管理職にでもなって部下を指導するみたいな役割をこなさないといけないんじゃないかな〜とたまに思うこともあります。ですがそれが自分にとって本当にプラスになる生き方なのかと考えると不必要なストレスを抱えて生きるよりは、楽しく仕事できた方が良いかなーとも思います。

##いろんな言語がある中でなぜRuby？
単純にユビレジがRuby on Railsで動いている & 不明点あれば弊社開発チームに質問できる & 学んでいくうちにわかったことですが、直感的でわかりやすい言語だから あたりでしょうか。

##プログラミングは難しいとよく言われているけど実際どうだったか
プログラミングに限らないと思いますが、誰でも最初は難しいと感じるのではないでしょうか。
配列とかハッシュとか横文字がズラズラ出てきて、なんなんこれ？と。役立つんかいなと。
引数とか戻り値とかようわからん！と嘆いていました・・・。
わからん→ググる→理解する(言っていることがわからなければ社内で質問する)→1ヶ月ぐらいすると忘れている・・・の繰り返しでした。
噛めば噛むほど味が出るという訳ではないですが、時間を掛けて学んでいけばゆくゆくはできるようになるんじゃないかなと思います。
あと「プログラミング　勉強法」なんかでググると3ヶ月でプログラマーデビュー！みたいな広告を見ますが、私のようにまっさらな状態からのスタートだと厳しいんじゃないかなと思います。なんらかの言語を学んでいるとかならいけるのかな・・・。毎日8時間程度の学習時間を確保できるのであれば(羨望)
あとは楽しく学べているのか、習慣化出来ているのかぐらいですかね😇

##今までやってきたこと
###【2018年 12月〜2019年 1月】
・Rubyを学び始める。使った参考書は[ゼロからわかる Ruby 超入門](https://gihyo.jp/book/2018/978-4-297-10123-7)を使って基礎の基礎から始めました。入門書に関しては他にも色々あると思いますが、プログラミング自体を初めて学ぶ方にはオススメ！(コードエディタの説明とか役に立ちました)
###【2019年 2月〜6月】
・アプリ作成できることが最終目標なのだから、[Railsチュートリアル](https://railstutorial.jp)をやろうと奮い立ちました。しかし今思うとやや時期尚早だったなと。中身は2割ぐらいしか理解できず。とりあえず写経して動くものが作れるという体験をしました。
・チュートリアルの合間に[プロを目指す人のためのRuby入門](https://ruby-book.jnito.com)も並行して取り組みました。こちらは超入門と比較するとかなりボリュームがありますが、中身は親切丁寧に書かれているので、理解しながら読んでいけば成果は出るかと。ただし1度読んで写経したからと言ってすぐに使えるものでもないと思うので、忘れた頃に読み返すと良いかなーと思います。
###【2019年 7月~9月】
・検索すると兎にも角にもアプリを作るのがプログラミングを理解するのに一番の近道と言われているのでアプリ作成かなとは思うものの、チュートリアルの理解が微妙だし、もう一度Railsチュートリアルをログイン機構実装まで復習と写経を行いました。今度は中身を理解できるまで熟読と写経を行う。またすこーしだけ理解が進んだ。
###【2019年 10月〜11月】
・さあもういけるやろと意気込んでみたものの、やはりよくわからない・・・。
悩んだ時に見返していた[この記事](https://qiita.com/saboyutaka/items/1a8c40e105e93ac6856a)を見ると「チュートリアルやったら次は現場Rails見るといいんでないかい」とあったので素直に見ることにしました。これからですが。
※ちなみにこの記事に書いてある事は結構信憑性が高いと個人的に思っています。
・そして10月から[HackerRank](https://www.hackerrank.com/?utm_expid=.2u09ecQTSny1HV02SEVoCg.0&utm_referrer=)なるものを始めました。開発チームの方から良かったらどう？みたいな感じで。最初はどうかなーと思っていましたが、問題を解く日々が続いております。Rubyの復習にもなるし、算数やアルゴリズムの勉強にもなるので一石二鳥！

##この一年で購入したものや読んだ本
・MacBook Air 2016(中古)
本当はProの方がいいんですけど、プログラミングが続くかどうかわからなかったので日和ってしまった & 奥さんにめちゃ懇願してどうにか許しを得ての購入だった。でも軽いし持ち運び便利だから最初はAirでもいいんじゃなかろうか。確か7諭吉ぐらい。

・[ゼロからわかる Ruby 超入門](https://gihyo.jp/book/2018/978-4-297-10123-7)
・[プロを目指す人のためのRuby入門](https://ruby-book.jnito.com)
この2冊でRubyの大まかな部分を学習
・[プログラマーの数学](https://www.hyuki.com/math/)
ちょっと難しい箇所もありましたが、全体的にわかりやすく書かれていました。込み入った問題にどう取り組めば良いのかなどの考え方が参考になる
・[Webを支える技術](https://gihyo.jp/magazine/wdpress/plus/978-4-7741-4204-3)
HTTPとかRESTなどを知るため。この世界では鉄板の様です。
・[ベタープログラマー ―優れたプログラマになるための38の考え方とテクニック](https://www.oreilly.co.jp/books/9784873118208/)
会社でほぼ毎日お昼の時間に15分程度の読書会を行っており、そこで読みました。こういうプログラマーになりましょう！的な内容の本です。

まあまあ読んでいましたね😗いや少ないか・・・。まあ読めばいいってものじゃないし！

##今後の展望
1分でも早く仕事でプログラミングをやりたい！とは常々思っていますが、じゃあお前これやれやって言われてガッテン承知！とはいかないものです😭手っ取り早く認めてもらうには簡単でも良いから何らかのアプリが作成できてからですかね・・・。1年も経ったわけだし何か成果物欲しいところ(自分のモチベーションを上げるにも)。

##最後に
まだまだ頑張ります！
TreasureDataと文字化け

## 文字化けに遭遇
突然ですが、Treasure Data(以下TD)でPrestoクエリを実行したら文字化けしてしまっていた、なんてことありませんか？
![Screen Shot 2019-12-05 at 19.28.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544917/b3efacca-b990-43f4-c74a-c2a2e8438241.png)

## そもそも文字化けって
文字化けというと、UTF-8のファイルをShift-jisとして開いてしまったときに発生するイメージを持っているかと思います。
テキストエディタで文字コードを指定して開いてみます。

```
# UTF-8で開いた場合
col1,col2,col3
テスト１,テスト２,テスト３
```

```
# Shift-jisで開いた場合
col1,col2,col3
繝�繧ｹ繝茨ｼ�,繝�繧ｹ繝茨ｼ�,繝�繧ｹ繝茨ｼ�
```

想定通り文字化けしていますね。
これと同じことがTDへデータインポートする際に発生しているのです。


## Treasure Data の文字コード
TDはUTF-8でデータを保持しています。
そのため、例えばShift-jisのcsvファイルをTDへアップロードする場合は「Shift-jisのデータが対象だよ」と教えてあげる必要があり、正しく設定していればデータアップロード時にUTF-8へ自動変換してくれます。


## 意図的に文字化けを発生させてみる
UTF-8のファイルをアップロードして文字化けを発生させてみましょう。

TDコンソール(ブラウザ)でアップロードする場合、Advanced Settingsから文字コードを指定することができます。
![Screen Shot 2019-12-05 at 19.50.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544917/50de9ac1-78c0-a379-6980-480f9bfb3a90.png)

UTF-8のファイルなのですが、あえてShift-JISと設定してみます。
![Screen Shot 2019-12-05 at 19.46.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544917/5ee00595-fbfd-c1e2-5c34-90d26beb1e42.png)

すると先述のようにプレビュー時点で文字化けしてしまっています。もちろんこのままアップロードするとプレビュー通り文字化けした状態で格納されます。
![Screen Shot 2019-12-05 at 19.56.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/544917/a7278566-0ca7-fce9-3a36-035e7937e927.png)

## TDで文字化けが発生してしまったら
先述したように文字化けした状態でTDへデータをアップロードしてしまうと、文字コードは当然UTF-8なのですが、間違った文字が格納されている状態になっています。無理やり解釈した結果が入っているわけです。

事後対応としては対象レコードをDELETEしてから、正しくデータ投入し直す必要があります。
プレビューで確認してからデータアップロードできればよいのですが、業務の中で毎回プレビューを表示しチェックするのはなかなか難しいかと思います。

事前に十分なテストを実施し、文字化けが発生しないようにしましょう。

## ダウンロード結果のみが文字化けしている場合
TDコンソールにてPresto/Hiveクエリを実行すると結果をダウンロードすることができます。
現時点では文字コードがUTF-8の一択なので、ダウンロードしたファイルをShift-jisとして開いてしまい文字化けしているように見えてしまうことが考えられます。
その場合は、TD上では正しくデータが格納されているので、どの文字コードとして処理しているのか、落ち着いて整理してみてください。
Web入門（２）

#はじめに
**CSS**は一言でいうと、Webサイト上の文字・枠・背景などの見た目やそれらの配置を指定するための言語です。最初は「CSS は見栄えを変えることができるんだ」くらいの認識で構いません。CSS は HTML と合わせて用います。ちなみに CSS はCascading Style Sheetsの略です。

#書き方
CSS を用いてスタイルを指定する際には、まずどこをどのような見た目に変更するか決めます。

```sample.css
p { font-size : 40px; }
```

CSS の基本的な書き方は セレクタ {プロパティ名:値;} という構造になっています。セレクタには変更したい要素の名前を指定します。上の例ではp要素となっています。プロパティ名にはスタイルの種類を指定します。プロパティとは変更するスタイルの種類みたいなものです。例では文字の大きさとなっています。値にはプロパティをどのように変更するかを指定します。上の例では40pxとなっています。

一度に複数のプロパティを指定することもできます。その際、改行をしてもスタイルには影響がでません。コードが見やすくなるので、個人的には改行して書くことをおススメします。

```sample.css
/* 改行しない*/
p { font-size : 30px; color: red; height : 80px; }

/*改行した*/
p {
   font-size: 30px;
   color: red;
   height: 80px;
}
```

#基本的なプロパティとその使用例
###基本的なプロパティ一覧
<table border="1">
    <tr>
      <th>プロパティ</th>
      <th>説明</th>
    </tr>
    <tr>
      <td>width</td>
      <td>横幅の指定</td>
    </tr>
    <tr>
      <td>height</td>
      <td>高さの指定</td>
    </tr>
    <tr>
      <td>color</td>
      <td>文字の色の指定</td>
    </tr>
    <tr>
      <td>background</td>
      <td>背景関係をまとめて指定</td>
    </tr>
    <tr>
      <td>background-color</td>
      <td>背景の色を指定</td>
    </tr>
    <tr>
      <td>margin</td>
      <td>要素外の間隔の指定（余白のようなもの）</td>
    </tr>
    <tr>
      <td>padding</td>
      <td>要素内の間隔の指定（余白のようなもの）</td>
    </tr>
    <tr>
      <td>font</td>
      <td>フォント関係をまとめて指定</td>
    </tr>
    <tr>
      <td>font-size</td>
      <td>フォントの大きさ（文字の大きさ）を指定</td>
    </tr>
    <tr>
      <td>font-family</td>
      <td>フォントの種類の指定</td>
    </tr>
    <tr>
      <td>float</td>
      <td>要素を左右に寄せる</td>
    </tr>
  </table>
###使用例
以下の sample.html を用意しました。（比較し易くなるように予めbackground-colorに黄色を指定しています。）

```sample.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Sample</title>
    <link rel="stylesheet" href="sample.css">
</head>
<body>
    <p>こんにちは！</p>
</body>
</html>
```
![tempsnip1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526998/a7707beb-841c-9a3f-6f9e-7ff0a8fdc739.png)


このWebページに以下のCSSを適用させてみます。

```sample.css
/*背景を黄色、横幅を100px、高さを30pxにして、padding,marginを100px加える*/
p {
   width: 100px;
   height: 30px;
   padding: 100px;
   margin: 100px;
   background-color: yellow;
} 
```
![tem2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526998/0f2c1416-5079-fd35-3bc9-6f987899e864.png)
Webページが変化しました！
ここで、「margin」と「padding」の違いについて軽く触れておきます。
上のプロパティ一覧表にも書いてありますが、「margin」は**要素外**、「padding」は**要素内**に余白を追加します。下図のようなイメージです。
![tem.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526998/84396e2c-49fd-a3be-13d2-9e2151e95522.png)

次にfloatを適用させてみます。

```sample.css
/*p要素を右に寄せ、さらに背景を青色に変更*/
p {
   width: 100px;
   height: 30px;
   padding: 100px;
   margin: 100px;
   background-color: yellow;
/*要素を右に配置*/
   float: right;
}
```
![tem3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/526998/464e3fda-6df0-d77a-9496-5536a6bc1f79.png)
要素が右に移動しました！

##まとめ
* CSS は HTMLで記述した要素のスタイルを指定するための言語である。
* 「margin」は要素外、「padding」は要素内に余白を加える。
* floatプロパティを用いると要素を左右に移動させることができる。
[UE4]シミュレーションを利用してレイアウトしてみよう

UE4は**「Simulate Physics」**のチェックを入れるだけで、
とてもお手軽に物理シミュレーションを行うことが可能です。
<img width="332" alt="2019-12-05_19h44_50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/d11413b2-9242-b3a6-e709-44eb436a6488.png">
![sim.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/99e9f64c-32ca-163e-ca62-24db7627268d.gif)
このお手軽なシミュレーションを利用して、レイアウトとかに利用できたらいいのに……、
と思うことがありますよね。
![sim2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/c93b4a9c-0945-a04e-b16b-44484f49cfd0.gif)
シミュレーションが終わったら、オブジェクトを選択して
**「K」キー**を押してみて下さい。
![sim3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/e6dba31e-e9cd-86aa-93c8-77bef5490f35.gif)
こんな感じのメッセージが右下に出て、シミュレーション後の位置が保存されます。
![sim6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/504aa24a-01e8-7b73-2f94-c9de808fbf8b.gif)
なんとなくばら撒きたい、散らかしたい、というときに便利かもしれませんね。
GCPのGCEでContainerデプロイする方法

Dockerを利用し、GCPのVMインスタンスにデプロイする方法をまとめます。
前提
- Githubでプロジェクトを管理
- GithubのリポジトリにDockerファイルがある

# Overview
大まかな流れは以下の流れとなります。
1. Cloud BuildにPush
2. Container RegistryにPush
3. VMインスタンスをアップデート

# Cloud BuildにPush
Cloud Buildのページにてトリガーを作成。
また、Githubと接続を行う。

詳細はこちら
https://cloud.google.com/cloud-build/docs/?hl=ja

接続し、トリガー条件を設定。今回はmasterブランチが更新されるとbuild開始。

# Container RegistryにPush
Cloud BuildへのPushが成功すると自動的にContainer RegistryにもPushされます。
Pushされた最新のイメージの名前をコピー
[エリア]/[プロジェクトID]/[コンテナ名]:[タグ名]

##コマンドで行う場合
>gcloud builds list

でbuild一覧を取得し、StatusがSuccessであることを確認。

>gcloud container images list

でイメージ一覧を取得し、
>gcloud container images list-tags --format="get(digest)” [イメージ名]

でタグを取得。
最新版のタグを組み合わせて、
[イメージ名]@[タグ名(ハッシュ化)]
のフォーマットで保存

# VMインスタンスをアップデート
VMインスタンスのページにてターゲットとなるインスタンスを編集。
コピーしたコンテナイメージ名をコンテナイメージのテキストフィールドに入力し、保存。

## コマンドで行う場合
>gcloud compute instances list

でインスタンス名一覧を取得

>gcloud compute instances update-container [インスタンス名] --container-image [イメージ名]@[タグ名(ハッシュ化)]

先ほどコピーした[イメージ名]@[タグ名(ハッシュ化)]を利用し、上記コマンドを実行。
Windows10 , CentOSのデュアルブート

#はじめに
仮想環境だとリソースが不足しそうなのでデュアルブート構成にして動くようにしたかったのだけど、調べてみると Windowsが新しくなってからは修正適用で起動できなくなるなどのトラブルがある様です。デュアルブート部分を仮想環境で試してみます。

#環境
ホスト

- Windows 10 Home


仮想環境

- Virtual Box 6.0
- Windows 10 Enterprise Evaluation
- CentOS 8.0


仮想環境でうまく動いたらホストをデュアルブートにします。
#ホストの環境確認と事前準備

UEFIが有効かをPowerShellで確認します。*管理者での起動が必要です。
パーティションをPCの管理メニューから確認するだけでもできます。有効な場合はUEFI用のパーティションがあります。

```powershell:Confirm-SecureBootUEFI
PS C:\WINDOWS\system32> Confirm-SecureBootUEFI
True
PS C:\WINDOWS\system32>
```
この設定にあわせて Virtual BoxのVM設定を変更します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/060d33b8-ff97-1386-2d35-ac9b065a170e.png)


デュアルブートだとトラブルが多いようなので、Windowsの設定項目から「高速スタートアップ」を無効にしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/1a074837-2ddb-e766-f259-cebdf9ffe33e.png)


#デュアルブートインストール

- VMにWindows10を入れる
- 同じVMにディスクを追加する
- CentOSを入れる

CentOSインストール時にパーティションの設定で追加したディスクが Boot Deviceになっていることを確認します。なっていない場合、Set as Boot Deviceボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/7c00da05-ca7f-e8f8-e757-4c9915698364.png)

CentOSを入れたばかりなので、GRUB2が起動します。何度か試しましたが、リブートだと直前に起動したOSが起動してきます。シャットダウンだとDISK1にれたWindowsが起動します。普段はWindowsなのでLinuxが起動してきたときにもデフォルトではWindowsが起動するように GRUB2を変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262366/a340ffd1-c4cd-e22a-79dd-ddb5759c1a2c.png)

このメニューだと上から3番目なので、0,1,2 で 2を指定します。

```
# grub2-set-default 2
```

DISK2の CentOS を起動させるときはBIOSで選択する必要があるので、BIOSメニューを表示するキーを覚えておくといいです。Virtual BoxだとF12です。


#メモ

UEFIが有効な場合 MBRやPBRのddでの抜き出しでのファイル登録はする必要はありませんでした。別ディスクにして起動時にBIOSで選べる環境ならこの方法がトラブルもなさそうです。


#参考
[Windows 10 Evaluation Center](https://www.microsoft.com/ja-jp/evalcenter/evaluate-windows-10-enterprise)
[GRUB2設定ファイルのカスタマイズ](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/sec-customizing_the_grub_2_configuration_file)
研修ファシリテーションーIT技術研修を対象として知識・スキルを定着させるためにー

##一方向の研修

企業におけるIT研修は、一人の講師が教室前方に立ち、多人数の受講者に対して話を伝達するスタイルが横行している。講師が受講者に一方向に情報を伝えるだけでは、良質な学びにつながらない。

自社で実施している研修は、「情報の伝達（説明）」だけではないと考える人もいるかもしれない。

では、「情報の伝達」以外の要素はなにがあるのだろうか。「演習を実施してアウトプットしてもらう。」や「質問をして答えたもらう。」などだろうか。

これらの要素では、多人数の受講者を相手にした場合、受講者全体に効果的にフィードバックが行えず教育効果が薄くなりがちだ。

従前からの研修スタイルである、この一方向の研修は、決められた内容でかつ疑問が思いつかないものであったり、応用的要素が含まれない内容の場合は、効果的だと感じる。例えば、マニュアルの手順に則った調理工程を覚える。や、会計時のレジの操作方法　など。

IT技術研修で教える内容の場合、一方向の研修では対応が難しい。

## 研修でのファシリテーションの必要性

私は、今現在、新入社員を対象に、ITシステムの上流工程（要件定義や基本設計）を研修で教えている。

単に、図表（ユースケース図やアクティビティ図、ER図）の表記方（ルール）を伝達するだけであれば、一方向でもよいが、表記方を知っただけでは、開発現場では応用できない。

現場でも力を発揮してもらうには、演習などで実際に図を記述（アウトプット）してもらい、書き方にルール違反がないかというレベルから、システム導入するお客様の意図が反映できているかといったレベルまで、様々な視点で講師がフィードバックを行う。

上記内容は、従前の一方向の研修に少し手を加えたレベルでしかない。一人の講師 と 一人の受講者 間のコミュニケーションであり、それを周囲の受講者が傍観しているといった場面を何度も見てきた。周囲の受講者は、良い学びを得られているのか。疑問である。

そこでファシリテーションの出番である。

## 研修でのファシリテーションの適用

ファシリテーションのプロセスや必要なスキル一覧などは、ネット検索におまかせするすることにし、IT技術研修でファシリテーションを適用する場合に、使えそうなスキルをいくつかピックアップする。

### チームディスカッションへの参加を促す

一人の講師 から 一人の受講者へ、演習の回答に対してフィードバックを行ってしまうと、周囲の受講者への教育効果が薄れる可能性があることは前述である。
そのため、傍観する受講者が発生しないようにディスカッションの場を設け、コミュニケーションに参加するような、仕組みや声がけが必要になる。

ディスカッションが活性化するチーム人数や人間関係を考慮したチーム構成、発言順番を決めるためのルールや方法　を講師が準備しておく。

私が演習を実施する場合は、１チーム４名前後、チーム構成は多様性（年齢や部署などがバラバラ）をもたせられたらベスト。

発言が、なかなか出ない場合も予想される。その時には、単にどなたか発言してくださいという声がけでなはなく、ルールを決めて。自宅が近い方から発言する。とします。

それでも、なかなか発言しない方も存在する。そのような場合は、発言の心理的ハードルを下げることもする。例えば「いま感じていることを言葉にしてください。」や「頭にぼんやり思い描いていることでもよいので言ってみてくらださい。」など柔らかく受け止める姿勢を見せることも大切と考える。

### 様々な視点の意見を聞き出す

IT系研修で学習する内容には、状況により判断がことなる事柄が多く含まれる。

例えば、画面設計において、１画面で顧客情報と契約情報を入力させた方がよいのか２画面にわけるべきか。これは、システムを使う人の（業務内容やPCスキルなど）状況によって判断がわかれる。

こういった場合は、様々な視点での意見がでてこないと受講者は良い気付きをえられない。

そのため、全員への質問の投げかけはもちろんのこと、個々人へ異なる質問なげかけて様々な意見がでるようにディスカッションの場を導く必要がある。

### 聞いている全員が共通認識できるように

受講者へ発言を促したり、質問をして返ってきた言葉が、抽象的であったり曖昧であったりはたまたそれまでの研修で登場しない用語が出てきた場合、その言葉を受講者全員が理解・共通認識できるように、講師は表現し直しする必要がある。

受講者の言葉を、具体的にし、新しい用語は既存の用語で置き換えあられるようであれば置き換え、置き換えられないのであれば意味を説明する。

こうして講師が表現し直した内容が全員に通じたかを最後に確認する。



研修で適用しているいくつかのファシリテーションスキルを見てみた。皆さんはどのようなファシリテーションスキルを駆使して研修を進めているでしょうか。
時系列データで売上予測しようとしたときに参考になった記事

こんにちは、最近初めてグリコの売上予測ハッカソンで時系列データを扱ったのですがこれがむずかった。。。
最終的にコンペでは中の中の上ぐらいまではあげられたので、忘れないうちに助けていただいた記事たちをここにまとめておきたいと思います。

参考にさせていただいた記事の内容はざっくりまとめると以下のようになります。

- LightGBM
- LSTM
- RandomForest
- 遺伝的プログラミング
- 特徴量の作り方、データの見方
- statsmodelsの季節成分分解
- changefinderを利用した異常検知


## 記事まとめ一覧


#### - SIGNATE お弁当の売り上げをLightGBMで予測してみた

> https://qiita.com/chusan/items/d7b210243f3b646375ba

季節性のある時系列データをうまくLightGBMで分析できています。
トレンドを外して考えることで精度がよくなる一例で、RandomForestを使った特徴量選択の方法も記載してくださっており本当に助かりました。
このコードのおかげで中の中にたどりつくことができました。

#### - Pythonで時系列分析の練習（6）トレンド、季節性、残差に分解

>https://momonoki2017.blogspot.com/2018/03/python6.html

Statsmodelsを使ってデータをトレンド、季節性、残差に分ける方法が記載されています。これと上記のLightGBMを組み合わせることでまあまあな成績がでました。


#### - Kerasで多変量LSTM

> https://qiita.com/tizuo/items/b9af70e8cdc7fb69397f

kerasでやってみようとしたのですがあまり精度はよくなかったです。
予測したい年にいろいろハプニングが発生し、例年のようには売れなかったためkeras の lstmのような過去のデータのみ参照する手法はよくなかったと考えられます。
ですがLSTMを用いる際のデータ処理の方法について学べたのは面白かったです。

#### - LSTMで仮想通貨の価格予測をする

> https://qiita.com/licht110/items/f89c699cbdff05ec90de

こちらもkeras の LSTMです。LSTMをつかうにあたってCross Validationできるほどデータ数が多くなかったことも問題でした。（36ヶ月分しかありませんでした）


#### - 遺伝的プログラミングによる特徴量生成でLightGBMの精度向上【kaggle Advent Calendar 11日目】

> https://upura.hatenablog.com/entry/2018/12/11/000000

最終日に精度があがらず困っていたので、Upuraさんの記事を参考にして自分で手動で特徴量を大量に作ってみたところ、見事あがりました！しかしそれでも混戦から抜け出せなかったのでこれは最後の最後に取っておくべき手法なのだと感じました。
また説明力がないので自分的にはちょっと気持ち悪いとも感じてしまいました。


#### - Pythonによる時系列分析の基礎

>https://logics-of-blue.com/python-time-series-analysis/

こちらのLogics of blueさんによる記事も大変参考になりましたが、やはりLSTMと同じく、イレギュラーなハプニングに対応できず没となりました。

#### - 【随時更新】Kaggleテーブルデータコンペできっと役立つTipsまとめ

>https://naotaka1128.hatenadiary.jp/entry/kaggle-compe-tips

最終日に見つけた記事です。精度があがらず困っている中でこの記事を読み始めたのですが、もっとはやく気づけばよかったと思いました。。。

#### - 状態空間モデル

>https://logics-of-blue.com/%E7%8A%B6%E6%85%8B%E7%A9%BA%E9%96%93%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8%E3%81%AF/

Logics of blueさんによる状態空間モデルの解説です。もし仮に現在までのデータしか存在しないなかでこれからの予測をしなければいけないのなら、状態空間モデルが一番強いのかもしれません。

#### - 異常検知

>https://www.procrasist.com/entry/22-changefinder

python の changefinderを使って異常検知ができるときいて使ってみたのですが、パラメーター調整に主観が絡んでくるため没となりました。これが成功すれば売上が本来はうまくいくはずの月でも異常検知によって失敗することが予測できたかもしれない？


## でも結局はデータをしっかりみることが大事

よく言われていますが、EDA大事です。優勝者はちゃんとデータをみて、目的変数と相関が高い特徴量をひとつ見つけ、それで単回帰をまわすだけで群を抜いてトップに躍り出ていました。なのでまずはデータをみた上でそれに応じた手法を考えるべきなのだと痛感させられたコンペでした。
コーディング規約とリーダブルコード 

#コーディング規約とは
「コーディング規約」は多数のプログラマが参加するプロジェクトにおいて、プログラミング品質を均等にするために定める文書である。ルールを決めることで誰が書いても標準化されたプログラムがかける。
#リーダブルコードとは
誰が読んでもわかりやすく、美しいコードのこと。

**わかりやすくするために**
・名前に情報を詰め込む
・誤解されない名前
・インデントが整っており改行された美しいコード
・コメントは正確で簡潔に
・制御フローを読みやすくする
・巨大な式を分割する
AWS EC2になぜかS3のマウントができない（/xxx/xxx にアクセスできません）

## はじめに
* これは自分が実務で大いにハマった事象です。。。
* AWSを商用利用したのは初めてということもあり、初歩的なミスかもしれませんが、もしかしたら他にも苦しんでいる方がいるかもしれないので、ノウハウをシェアします。

## 事象
* 東京リージョンに作成したEC2を作成。
* データ領域として、S3をマウントしようと試みた。
    * [EC2インスタンスにS3をマウントする](https://qiita.com/shicky1121/items/e19b50308c79e5a6081e)　←こちらの記事のように設定をしました
* `s3fsコマンド`を導入し、マウントを行ったところ、一見うまく実行できたように見える。
    * `echo $?`による戻り値は0
* ところが`lsコマンド`や`dfコマンド`で状況を確認しようとすると、以下のエラーが出力される。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ ls -al /xxx/xxx
ls: reading directory /xxx/xxx: 入力/出力エラーです
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ df -k
df: /xxx/xxx にアクセスできません: Transport endpoint is not connected
・・・中略・・・
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo tail -3 /var/log/messages
Jan 15 17:54:02 ip-xxx-xxx-xxx-xxx dhclient[1355]: bound to xxx-xxx-xxx-xxx -- renewal in 1693 seconds.
Jan 15 17:59:31 ip-xxx-xxx-xxx-xxx s3fs: init $Rev: 367 $
Jan 15 17:59:35 ip-xxx-xxx-xxx-xxx s3fs: init $Rev: 367 $
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$
```

* **df: /xxx/xxx にアクセスできません: Transport endpoint is not connected**というメッセージでWeb検索しても、EC2にS3の許可をしているか？やバケット名は合っているか？という対処法が出てくる。
* 上記を再作成したり、何度も確認を行ったが、設定には問題がなさそう。

## 原因
* **EC2の時間が所属するリージョンの時間と異なった、もしくは大幅に時間がずれていた**ことで本事象が発生。
    * s3fsのデバッグ出力をする中でようやく発見しました

## 対処方法
* EC2のタイムゾーンをJapanにすることで解決。

```
[root@ip-xxx-xxx-xxx-xxx ~]# cat /etc/sysconfig/clock
ZONE="UTC"
UTC=true
[root@ip-xxx-xxx-xxx-xxx ~]# view /etc/sysconfig/clock
[root@ip-xxx-xxx-xxx-xxx ~]# cat /etc/sysconfig/clock
ZONE="Japan"
UTC=true
[root@ip-xxx-xxx-xxx-xxx ~]# ln -sf /usr/share/zoneinfo/Japan /etc/localtime
[root@ip-xxx-xxx-xxx-xxx ~]# reboot
```

* reboot終了後、`s3fsコマンド`でマウントを改めて実行したところ、問題なくS3がマウントされることを確認。
モデルとデータベースの関係

MVCモデルのM（モデル）についてまとめます。

# モデルとは何か？
モデルの一番の役割は、Railsの中でデータベースへのアクセスをはじめとする情報のやりとりに関する処理を担当しています。

# データベースとテーブルとは何か？
データベースはデータを保存する場所です。
テーブルはそれぞれのデータを整理し、振り分けたものです。
データベースはデータを保存するための箱、テーブルは収納場所でイメージすると少しわかりやすいと思います。

モデルは仕分け人、テーブルは引き出しのイメージです。
必要なデータの登録やデータの引き出しをモデルが担当します。

テーブルとモデルの関係性は、テーブルとモデルクラスの名前によって決定します。
これは、モデルの命名規則と関係しています。
モデルとテーブルを紐づけることでデータの登録、取り出しができます。
例）userモデル⇄userテーブル

# まとめ
モデルとデータベースの間では、モデルを通してデータベースにアクセスしてデータのやりとりをするためにあります。
npm がどうしてもエラーになる

# 😥 npmコマンドで様々なエラー
```
npm install
npm ci
npm run serve
npm run watch
npm run watch-poll
npm run build
npm run lint
```
などなど
## 🚀 １行で解決させる 
一般的な解決策としてnode_modulesとpackage-lock.jsonを消してキャッシュをクリアにし、
再度npmをインストールしたあと、実行しなおすという手があります🤔

```
jsモジュールを全部消し、npmのキャッシュをクリアした上で再度モジュールを入れ直す
rm -rf node_modules && rm package-lock.json && npm cache clear --force && npm cache clean --force && npm i

* 実行
npm run 〇〇
```
大抵のケースでは上記で解決できますが

そうでない場合もありますので他に遭遇した例を以下にソッと載せておきます。

### 例外① Sass Loader has been initialized using an options object that does not match the API schema というエラー
php 7.4
Laravel 6.8
node 12.13.1
npm 6.12.1

```
ERROR in ./resources/sass/app.scss
Module build failed (from ./node_modules/css-loader/index.js):
ModuleBuildError: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
ValidationError: Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
 - options has an unknown property 'outputStyle'. 
 - 
ERROR in ./resources/sass/app.scss (./node_modules/css-loader??ref--5-2!./node_modules/postcss-loader/src??postcss0!./node_modules/resolve-url-loader??ref--5-4!./node_modules/sass-loader/dist/cjs.js??ref--5-5!./resources/sass/app.scss)
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
ValidationError: Invalid options object. Sass Loader has been initialized using an options object that does not match the API schema.
```

#### 解決策
package.jsonのsass-loaderのバージョンが8などはエラーになるので7.1に修正する

```
npm uninstall --save-dev sass-loader
npm install --save-dev sass-loader@7.1.0
```
→ 参考(https://teratail.com/questions/242618)

## 🤕 それでも何かしらエラーが出てコマンドが実行できない場合

### ① nodeを入れ直したら解決できる場合

#### ⑴ 手動で入れる
まずは下記の公式サイトから自分のOSに合わせたnodeをダウンロードしてzipを解凍します。
https://nodejs.org/ja/download/

バージョンは最新ではなく推奨版をダウンロードするようにします。

その後、

```
rm -rf node_modules && rm package-lock.json
npm cache clear --force && npm cache clean --force
npm install
npm run 〇〇
```

### ② アクティビティモニタでnodeをkillしてやり直す(Mac)
ここまできて解決できない場合は、もう `node` が反抗期でクラッシュしている可能性があるので怒りを強制的に鎮めます。
Macに入っているアプリケーションの一つに `アクティビティモニタ` というものがあるのでまずは起動してください
![スクリーンショット 2020-11-21 20.49.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223280/86fae02e-429d-ac8d-8382-d56070a7e360.png)

![スクリーンショット 2021-02-02 16.48.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223280/88cca89b-f556-c884-348b-bafc64fc9c59.png)

`アクティビティモニタ` を開いたら右上の検索ボックスで `node`を検索し、
下の列で `node` を選択をしたうえで上にある ❌ ボタンで実行中のプロセスを切ります。
その上で `npm run 〇〇` をやり直してください。

おつかれさまでした！
[UE4] GeneralPurposeTweakを利用してエディターからシェーダーへ変数を渡す

シェーダー開発を行う上で、エディターから設定した値をシェーダーに渡したいケースがあるかと思います。
しかし受け渡しのコードを書くとなるとエンジンビルドも必要になりますし、少し手間がかかります。
そんなときに、GeneralPurposeTweakというコンソールコマンドに値を渡すと、
コマンド入力した数値をシェーダー側で利用することが可能です。

## GeneralPurposeTweakの設定方法
以下のようにアウトプットログでコマンドを実行するとfloatの数値を渡すことが可能です。
[ウィンドウ] > [デベロッパーツール] > [アウトプットログ] > **r.GeneralPurposeTweak [数値]**を入力
![2019-12-05_18h35_51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363894/fc4b1d2d-35b1-5734-d0d0-8b627f49aa3e.png)

## Shaderからの利用方法
Shader側からは、**View.GeneralPurposeTweak**として値を呼び出すことが可能です。
.usf内で以下のように分岐させることでデバッグなどを行うことが可能です。
![2019-12-05_18h48_26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363894/ba02ab53-3156-38a4-70b5-149d25ee3c5f.png)

## 他のパラメーターを追加したい場合
独自のコンソールコマンドを追加したい場合は以下ドキュメントをご確認ください。
**C++ のコンソール変数 | Unreal Engine ドキュメント**
https://docs.unrealengine.com/ja/Programming/Development/Tools/ConsoleManager/index.html

## さいごに
あくまで一時的な変数とすべきですが、開発時には非常に便利なので有効活用しましょう。
Donkey Carのプロポ対応(TIPS編)


Donkey Car操作を従来のジョイスティックを、RCカーのプロポでの操作をするための手順を、「その１　ハードウェア編」、「その２　ソフトウェア編」、そして「その３　セットアップ編」に分けて説明しましたが、今回はそのTIPS編を書いてみます。

その１　https://qiita.com/arigadget/items/2c465915b5fbde07196e 
その２　https://qiita.com/arigadget/items/51bf75e19cd395ac9b2f
その３　https://qiita.com/arigadget/items/9396451d6837bbbed79d



### エクスポーネンシャルカーブ

柏の葉のAIロボカーシンポジウムにて、スロットルをリニアではなく、エクスポーネンシャルカーブで変化させると操作しやすくなるとのプレゼンがありました。後日調べてみると、ボリューム（可変抵抗）のＡカーブに相当するもので、エレキギターやベースのボリュームに使われていて、人間の耳の特性に合っているとのことで、ジョイスティック操作にも当てはまるので不思議な気がします。

紹介されたプロポ(Jumper T16)には、スロットル値を変える機能があるとのことですが、自分は中間にいるArduinoにそのカーブをエミュレーションさせました。以下のスケッチは、アナログポート２番に接続されたボリュームの値を読んで、カーブの曲がり具合を変更できるようにしています。

```c
  if(channel_length[1] > base_value[1]){
    exponent = (float)analogRead(2);
    if(exponent > 10.0) {
      throttle_fvalue = fmap((float)throttle_range, (float)base_value[1], (float)THROTTLE_FORWARD_PWM, 0.0, 1.0);
      throttle_evalue = (pow(exponent, throttle_fvalue)-1.0) / (double)(exponent - 1.0);
      throttle_value = (int)(throttle_evalue * 32767.0);
    } else {  // forward linear line
      throttle_value = map(throttle_range, base_value[1], THROTTLE_FORWARD_PWM, 0, MAX_VALUE16);
    }
  } else {  // backward linear line
    throttle_value = map(throttle_range, THROTTLE_REVERSE_PWM, base_value[1], MIN_VALUE16, 0);
  }
```



ジョイスティックとRaspberry Piの構成においては、Donkey Car本体側を修正する方法を、mituhiromatuuraさんが以下に公開されており、自分も参考にさせていただきました。

##### DonkeyCar ジョイスティックのステアリングをエクスポネンシャル化
https://qiita.com/mituhiromatuura/items/b0c8ac54163d9cffd2d5


### ニュートラル時のデータ未採取のご利益

PCINTによるハードウェア割込みを使った場合、PWMの幅の測定誤差が4μsと非常に精度がいいため、ニュートラルの時にThrottle値が０になります。

ジョイスティックだと、なかなかニュートラル値にならないため、ずっとデータを取り続けています。学習データを取り終わって、机まで運んでいる映像まで取っているようなこともあるある。

controller.pyにこんなコメントが。

```python
    def on_throttle_changes(self):
        '''
        turn on recording when non zero throttle in the user mode.
        '''
        if self.auto_record_on_throttle:
            self.recording = (abs(self.throttle) > self.dead_zone and self.mode == 'user')

```

### 

### おわりに

プロポの記事はアドベントカレンダー始まる前に書いてしまい、ちょっとショボイ内容になってしましましたが、ぜひ最初の記事からお読みください。
Rails 6.0の "Active Storage's ImageProcessing transformer doesn't support :combine_options" という警告に対処する方法

## 困っていたこと

Rails 5.2時代にActiveStorageでこんなコードを書いていました。

```ruby
user.avatar.variant(
  combine_options: { 
    resize: "150^", 
    gravity: "Center", 
    crop: "150x150+0+0", 
    auto_orient: true  
  }
)
```

やっていることは縦長だったり横長だったりする画像を、中心で正方形に切り抜いて150x150サイズに縮小することです。（mini_magickを使用）

つまり、この画像↓を、
![3500x1500-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/ae311fa3-0c92-cd3a-f019-65e0d33de4ad.png)

こうするわけです↓
![3500x1500.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7465/e3be8d23-e383-886f-c9a3-a89aa0c8f43d.png)


このコードをRails 6.0に上げるとこんな警告が出ました。

```
DEPRECATION WARNING: Generating image variants will require the image_processing gem in Rails 6.1. Please add `gem 'image_processing', '~> 1.2'` to your Gemfile. 
```

なにやらimage_processing gemをインストールしろ、と言われているので、言われたとおりGemfileに追加します。

```ruby:Gemfile
gem 'image_processing', '~> 1.2'
```

```console
bundle install
```

すると、今度は警告の内容が次のように変わりました。

```
DEPRECATION WARNING: Active Storage's ImageProcessing transformer doesn't support :combine_options, as it always generates a single ImageMagick command. Passing :combine_options will not be supported in Rails 6.1.
```

こちらの警告は`:combine_options`はRails 6.1でサポートされなくなるぜ！と言われてるものの、具体的な修正方法がわかりません。

## 解決方法

[この警告が導入されたコミット](https://github.com/rails/rails/commit/697f4a93ad386f9fb7795f0ba68f815f16ebad0f)を確認した結果、どうやら`:combine_options`をなくしてこう書けば良いっぽいです。

```ruby
user.avatar.variant( 
  resize: "150^", 
  gravity: "Center", 
  crop: "150x150+0+0", 
  auto_orient: true  
)
```

これで警告が消え、画像の切り抜きもうまくいきました。

ただ、これがベストプラクティスかどうかは確信がないので、もっと良い解決策を知ってる人がいたらコメントお待ちしています！

## 追記：こんなやり方があった！
同僚の @aki77 が「こんなやり方がありますよー」と、もっと便利な書き方を教えてくれました。（どうもありがとう！）

> 確かもうちょっと簡単に書けるようになったはずと思って調べてみました。
多分↓で良さそう。

> user.avatar.variant(resize_to_fill: [150, 150])
https://edgeguides.rubyonrails.org/active_storage_overview.html#transforming-images

> carrierwaveでも同じだったなーと思ったら、あっちもimage_processing使ってるんですね。
https://github.com/carrierwaveuploader/carrierwave/blob/master/carrierwave.gemspec#L27

ということで、Rails 6ではこれだけでOKです！
（`auto_orient: true`もデフォルトでセットされます）

```ruby
user.avatar.variant(resize_to_fill: [150, 150])
```

めっちゃシンプルになりましたね！やったー🙌
Gitとは

##Gitとは
Gitとはプログラムソースなどの変更履歴を管理する分散型のバージョン管理システムのこと。
##Gitを使ったバージョン管理
Gitでは、ファイルの状態を好きなときに更新履歴として保存しておくことができる。そのため、一度編集したファイルを過去の状態に戻したり、編集箇所を示すことができる。また、古いファイルを元に編集したファイルで、他人の編集した最新ファイルを上書きしようとすると、サーバにアップロードした時に警告が出る。そのため、間違って他人の編集内容を上書きしてしまうといった失敗は起こらない。
Androidアプリ開発をしているときに思ったことや気づいたこと、感じたこと

　こんにちは。最近寒くなってきましたねー。僕は未だにジャンバーを着るタイミングがつかめませんw

<blockquote class="twitter-tweet"><a href="https://twitter.com/karmari3/status/1201076255359062017"/></blockquote>

アプリ開発をしている人しか分からないネタですw

- できるだけネットに頼りたくない
- 思うようなことができたらうれしい
- PCとノートの使い分け
- 次作るアプリの案が出てくる

### できるだけネットに頼りたくない
　初めてアプリを作る際や新しくプログラミング言語を学ぶときに僕は必ず参考書を買います。その中で必ずと言っていいほど参考書だけでは分からないところが出てきます。例えば、タイマー機能を実装したいという時はネットに頼ります。そういうのではなくて、自分の力で何とかなりそう、考え方を変えれば実現できそうという時にネットを頼りたくはないと感じます。それでも分からない！となるとインターネットに頼るんですが、やっぱり悔しいですね。僕の中ではネットは最終手段です。と言っても、しょっちゅう利用するんですが(笑)

### 思うようなことができたらうれしい
　誰しもが経験あると思います。こうなるだろうと自分で考えてコードを打ち、Shift+F10を押す。うまくいくと僕は「よっしゃー！」と声に出し更にはガッツポーズまで添えます(笑)。

### PCとノートの使い分け
　僕の場合はPCは設計書や確定している事項などしっかりしたものを残すために使い、ノートはその時に思いついたことや複雑な処理を考えるときなどメモ程度に扱います。どちらも共通して言えることは書く前に日付を記入するところです。

### 次作るアプリの案が出てくる
　常に頭の中でいろいろ考えているのですが、まだアプリが完成していないのに次はこのアプリ作ろうとか考えてしまいます(笑)。今考えているのはゲームセンターでゲットした景品の写真を保存するメモ帳的なアプリを考えています。僕自身よくゲームセンターに行くので、その時に取った景品やいくら使ったのか、どういう種類のUFOキャッチャーなのかなど保存しておきたいなーと思ったからです。まぁまだ日記アプリが終わってからですねー。

以上が僕がアプリ開発をしていて思ったこと、気づいたこと、感じたことでした。
windowsでlinux形式のパーミッションを設定してgitにファイルを上げる

# 背景
会社の開発端末はwindowsなんですが、そのPCでシェルスクリプトを書いてgithubに追加する必要がありました。
シェルスクリプトなので実行権限を付与(chmod +x)してからgitに追加したかったのですが、windows上でどう実行していいかわからず少し調べました。
単にgit bashでchmodをやってもダメらしいことがわかりました。

# 答え
git addのオプションでパーミッションをつけてstageするものがありました！

```bash:
git add --chmod=+x -- file.sh
```

あとはコミット＆プッシュするだけ。便利ですねー
よかったよかった。

linuxやmacなら

```bash:
chmod +x file.sh
```
これをやってからgit add -> git commit
でいいんですがね。

それでは。
ラズパイ4でsmbサーバ構築

べつに乗り換えたわけじゃないけど、ラズパイ4がまともに動くのがraspbianしかないので
しかたないのでこれで運用中。

#なんと、ssh サーバは動いていないのがデフォルトなの？
中の設定を見ようとしてsshでつなごうとしたらつながらない。
そこで

```
$ sudo systemctl status ssh  
```
ってやってみたらなんとサーバはお休み中。
しかたないので

```
$ sudo systemctl enable ssh
$ sudo systemctl start ssh
```

で起動。

```
pi@raspberrypi:~ $ sudo systemctl status ssh
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-12-05 18:51:29 JST; 4min 29s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
  Process: 2483 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
 Main PID: 2484 (sshd)
    Tasks: 1 (limit: 4915)
   Memory: 2.0M
   CGroup: /system.slice/ssh.service
           mq2484 /usr/sbin/sshd -D

12月 05 18:51:29 raspberrypi systemd[1]: Starting OpenBSD Secure Shell server...
12月 05 18:51:29 raspberrypi sshd[2484]: Server listening on 0.0.0.0 port 22.
12月 05 18:51:29 raspberrypi sshd[2484]: Server listening on :: port 22.
12月 05 18:51:29 raspberrypi systemd[1]: Started OpenBSD Secure Shell server.
12月 05 18:55:19 raspberrypi sshd[2542]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.50  user=pi
12月 05 18:55:21 raspberrypi sshd[2542]: Failed password for pi from 192.168.1.50 port 57083 ssh2
12月 05 18:55:27 raspberrypi sshd[2542]: Accepted password for pi from 192.168.1.50 port 57083 ssh2
12月 05 18:55:27 raspberrypi sshd[2542]: pam_unix(sshd:session): session opened for user pi by (uid=0)
```

んでもって、ファイル共有サービスをここで提供しようと思いまして、
32GBの小さなUSBフラッシュメモリを使いまして、ここに共有ファイルをためていくということをします。

もうすでにUSBメモリをマウントするところまでやっちゃったので、そこまでの過程が欲しい人は
どこかで探してください。

では共有方法ですが、やはりsambaが一番楽かとおもいますので、sambaを入れます。

#samba でアミーゴ

```
$ sudo apt-get install samba
```
でオーケーです。
あとは設定。
今回はUSBメモリをすべて使いますのでそれをマウントしておいて、

```
$ sudo chmod 755 /data
$ sudo chown -R pi:pi /data
```

として置いて、あとは設定ファイルを書き換えます。
うちの環境では以下のようにしました。

```:/etc/samba/smb.conf
   interfaces = 127.0.0.0/8 eth0 192.168.1.0/24
   bind interfaces only = yes
[share]
    comment = secret
    path=/data
    guest ok = no
    writable = yes
    valid users = pi
    browsable = no
    create mode =0775
    directory mode = 0775
```
今回は共有していますが、少し条件を厳しくしています。

で、あとはユーザ追加、

```
$ sudo smbpasswd -U pi -a
```

でパスワードを入力すれば桶。

最後にプロセスを再起動させます。

```
$ sudo systemctl restart smbd nmbd
```

これで、Windowsからファイル共有できます。
でも、USBメモリが2.0使っているので激遅です。
[UE4]HDRキューブマップ圧縮のすすめ

美しい天球などを表現するために、高解像度のHDRキューブマップを使いたい、
ということはよくありますよね。
<img width="790" alt="2019-12-04_23h51_36a.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/aa36678c-5391-82bd-0ff3-0bd8191a6492.png">
でももし2048*2048*6のキューブマップをHDRで持ったら……、
テクスチャサイズが**260MB**近くにもなっちゃいます。
HDR画像のデフォ設定は非圧縮なので、恐ろしいですね。
<img width="292" alt="2019-12-04_23h52_36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/9dd5aff9-2a83-c009-0410-3fafa278da83.png">
ですので、とりあえずHDRCompressedに設定しちゃいましょう。
<img width="293" alt="2019-12-04_23h55_26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/dc17f236-d4eb-d5ee-a1df-d7d62640b93d.png">
見た目さほど変わらないのに、30MBくらいまで圧縮できます。
（1/8のサイズになります）
<img width="290" alt="2019-12-04_23h55_32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/b552598a-439c-551b-910c-78b7326e0fb4.png">
こういう危ない子がいないか、たまに「LISTTEXTURES」でチェックしとくと、皆幸せになれると思います。
<img width="895" alt="2019-12-04_23h53_25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/5c05461a-6556-274c-99b9-0d9d8837a09f.png">
おしまい。
他のPJに移ってマネジメントでやったこと

本記事は、[サムザップ Advent Calendar 2019 #2](https://qiita.com/advent-calendar/2019/sumzap2) の12/4の記事です。

サムザップでエンジニアのマネージャをしている野口といいます。
以前にあるプロジェクトへ異動し、マネジメント関連のヘルプをしたときの話を振り返って書いてみようかなと思います。

# ヘルプに入った当初
まずはどんなプロジェクトなのかを把握しようとしました。
技術的な設計方針やツールの使い方など細かなポイントよりも、
ますどんな人たちがどんな環境でどのように開発しているのかを知ろうとしました。
（予備知識が全くなかったわけではありませんが、実際の現場をしっかりみるのは初めてでした）

 - 開発のフェーズ/進捗はどれくらいか
 - 作業はどのように起票され、管理されているか
 - チームの雰囲気や、コミュニケーションの方法はどんな感じか
 - それぞれの人となりとスキルをなんとなく知る
 - そして、チームはどのあたりに苦労してそうか

# 最初に注力することを決める
全体像と課題感がある程度把握できたので、次に最初にやるべきことを考えました。
状況を見て、チームの体制を特に変える必要はない/変えるべきでないと思ったので、
そのままの体制で**PJマイルストーンを達成できる、最大限パフォーマンスが出せる**よう、その目的に対して特に優先度が高いものをピックし、取り組むことにしました。

 - *リーダーメンバーのタスク棚卸し*

リーダーは、他セクションとの窓口だったり、周りの作業管理だったり、ちょっとした修正/反映依頼が積み重なったり、自身の実装タスクがあったりと負荷が上がりがちになっていました。
**本来 力を発揮してほしい役割により集中できる**よう、できるだけその他の作業を剥がしました。

 - *クリティカル・パスがどこか調査できる状態にする*

課題感のひとつとして、マイルストーンに対する作業管理ができていないというのがありました。各メンバーは日々バックログから作業をとって消化するというのを懸命にこなしてくれていましたが、日々起票されていく作業に対して、いまの進捗は問題ないのか、このスピード感で間に合いそうなのか、ゴールまでどれだけの量を消化すれば良いのか、が見えない状態になっていました。
そこで、タスクを精査/棚卸しし、現状の総量/日々の起票量と消化速度が分かるようにしました。バーンダウン等で可視化することで、スケジュールに対する進捗とチームパフォーマンスが測定できるようになりました。

 - *マイルストーンを達成できるよう、クリティカル・パスを調整する*

上記で調査してみると、下記2つの項目がマイルストーンにとってクリティカルになっていることがわかりました。
  - アウトゲーム周りの作業タスク量
  - 修正済みタスクの確認(デバッグ)期間

これらについて、タスクの優先度付け/棚卸し、人員体制、最終的にはスケジュールの調整をしてどうにか帳尻を合わせました。
また、**後々クリティカル・パスに影響を与えそうな不安要素を排除する**ように動きました。特にプロジェクトの特徴として、後から多量のフィードバックが発生することがあったため、開発の区切りに新しくマイルストーンを設定し、そこでレビューを受けて先んじてフィードバックを洗い出すようにしました。

 - *効率を上げ、パフォーマンスが出せるようにする（第一弾）*

チームに加入して最初に改善した方がいいなと思ったことのひとつに、「修正済みタスクのチェック用アプリが、たびたび開発の影響で突然動かなくなる」「日中にリーダーがそれを調査して直す」というところがありました。
これは上記に記載した2つのクリティカル・パスにとって非常に影響の大きい内容だったため、まず優先して対処することにしました。具体的には、開発環境とチェック環境を分け、チェック用のアプリは毎朝定期的にビルドされるようにしました。

# 継続的に確認して棚卸し
ざっくり整備してタスクの可視化とパフォーマンスを出せるようになり、実績値としてチームの開発速度が測れるようになりました。
しかし最初に1回やっただけでは意味がないため、日々の確認が必要です。速度はちゃんと出ているか、速度に対してタスク量は問題ないかなどを日々確認して、必要に応じて都度調整する必要があります。

# 今後を見据える
こちらは今もまだまだやることが残っていますが、今後のことも考えてチームを調整する必要があります。
例えば以下のような内容に気を配っています。
 - 特定の人に属人化しすぎないこと
　一時的に速度は落ちても一定分担させる
　イベント施策と不具合修正が被っても並行できるよう
- 後々の運用で困る内容は先に潰しておく　
　後に回すとだいたい直さ(せ)ない　ので優先度の高いものは先に直しておく


自分の振り返りのためにちょっとザックリ書きましたが、
何かが参考になれば幸いです。

明日は @RyotoKitajima さんの記事です。
WSUSに登録されない大量コンピュータを一括登録

#状況
Azure運用の初期にVMを諸々カスタマイズ後、Sysprepせず固めたイメージからVM追加したため、WSUSに登録されるコンピューターが別のコンピューターに上書きされていた。

#対応
VM別にWindowsUpdate用のクライアントIDをリセット
サーバ台数が3桁あるため、Active Directoryのグループポリシーを利用して配布、実行する。

### Reset-SusClientId.ps1

```powershell
net stop wuauserv

Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" -Name "SusClientId"
Remove-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" -Name "SusClientIdValidation"

net start wuauserv

(New-Object -ComObject "Microsoft.Update.AutoUpdate").DetectNow()
```

# グループポリシー
### ファイル配布
 * コンピューターの構成 -> 基本設定 -> Windowsの設定 -> ファイル
 * アクション: 更新
 * ソースファイル: \\{DC}\share\Reset-SusClientId.ps1
 * ターゲットフォルダー: C:\workspace

### タスクスケジュール
 * コンピューターの構成 -> 基本設定 -> コントロールパンネルの設定 -> タスク（即時タスク）
 * セキュリティオプション ユーザーアカウント: NT AUTHORITY\System
 * 操作: powershell.exe C:\workspace\Reset-SusClientId.ps1


# 残タスク
 * 追加したGPOを無効にするか、削除


#参考
 * [グループ ポリシーを使用して自動更新を構成する](https://docs.microsoft.com/ja-jp/security-updates/windowsupdateservices/18128102)
 * [Windows Server Update Services を使用したベスト プラクティス](https://docs.microsoft.com/ja-jp/security-updates/windowsupdateservices/18111610)
 * [Windows クライアント/サーバーで WSUS を再登録する方法](https://support.microsoft.com/ja-jp/help/555974)

 * [Windows Server 2016ではWSUSに認識させるwuaucltコマンドが使え無い。クライアントが表示されない](https://blog.putise.com/windows-server-2016%E3%81%A7%E3%81%AFwsus%E3%81%AB%E8%AA%8D%E8%AD%98%E3%81%95%E3%81%9B%E3%82%8Bwuauclt%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%8C%E4%BD%BF%E3%81%88%E7%84%A1%E3%81%84%E3%80%82/)
 * [WSUSにコンピュータが登録されない](http://memoonline.blog.fc2.com/blog-entry-152.html)
 * [【WSUS】コンピューターグループに所属しているクライアントを抽出する方法【自動でグループ設定する方法も】](https://workers-strategy.net/1381/)
意外と知らないMapの便利な使い方

# コレクションの利用
Javaでプログラミングを行う際には List, Map, Set などのコレクションを利用するのはほぼ必須といっても過言ではないかと思います。
その中でもMap はキー・バリュー形式でデータ管理を行えるため、データを事前に取得してMapに詰め込んでおき再利用するといったシーンで多く使われます。

特にJava8 から Stream API や ラムダ式、Optional 等が追加されコレクションがより使いやすくなりました。
ただこれらの追加機能の陰に隠れて実は便利なメソッドがたくさん追加されているのはご存知でしょうか。
今回はそんな便利なメソッドをいくつか紹介します。

## データが取得できない時に初期値をゲット！ (getOrDefaut)

会員コード毎にお店で使えるポイントを保持するMapがあったとします。

```java
Map<String, Integer> pointMap = new HashMap<>();
```

ある会員がポイントを保持していない場合0ポイントを返したいといったロジックの場合以下のように記述し取得することができます。

```java
int point = 0;

// ポイントを保持している場合ポイントを取得
if (pointMap.containsKey(code)) {
    point = pointMap.get(code);
}
```

いちいち判定するのは面倒だし美しくないですね。
そこで getOrDefault の出番です。

```java
int point = pointMap.getOrDefault(code, 0);
```

すっきりと1行で書けましたね。
マップに値が入っていない場合にはある値を取得したいという時にこのようなコードを書くことができます。

## 値を保持していない場合のみセット！ (putIfAbsent)

先程のポイント情報に対して、まだポイントを保持していない会員のみポイントを付与するというロジックを書くとします。

```java
// ポイントを保持していない場合ポイントを付与
if (!pointMap.containsKey(code)) {
    pointMap.put(code, point);
}
```

これを Java8からは以下のように書くことができます。

```java
pointMap.putIfAbsent(code, point);
```

このコードでは会員に紐づくポイントが無い場合にのみ point をセットする形になります。

## 値を保持していない場合初期値をセット！ (computeIfAbsent)
ある学生のテストの点数の履歴を追加して保持するMapがあったとします。

```java
Map<String, List<Integer>> scoreMap = new HashMap<>();
```

既に点数が保持されている学生がいる場合は、その点数の後に履歴として新しい点数を加えていきます。

```java
List<Integer> scores = scoreMap.get(code);

// 学生の点数がまだ記録されていない場合
if (scores == null) {
    // 新しい履歴用のリストを作成
    scores = new ArrayList<>();
    scoreMap.put(code, scores);
}

scores.add(score);
```

Mapから取得できなかった場合にいちいちListをセットし、そのListに点数を追加する必要があります。
これを computeIfAbsent を使うと以下のように書くことができます。

```java
scoreMap.computeIfAbsent(code, k -> new ArrayList<>()).add(score);
```

もし学生のテスト結果が1件も保持されていない場合には新しいListを作成し、既に結果がある場合は既にあるListを返します。
そのまま返されたListに点数を追加しているため1行で書くことができるようになります。

## 値が保持されている場合に値を操作！ (computeIfPresent)

授業に参加した学生の出席日数を保持するMapがあり、履修する生徒の学生コードと出席日数0がそれぞれ初期値で入っているとします。

```java
Map<String, Integer> attendanceMap = new HashMap<>();
```

授業を履修していないが学生が来た場合は無視し、履修している学生は出席日数を1増やすとします。

```java
if (attendanceMap.containsKey(code)) {
    attendanceMap.put(code, attendanceMap.get(code) + 1) ;
}
```

これを computeIfPresent を使用すると以下のように書くことができます。

```java
attendanceMap.computeIfPresent(code, (k, v) -> v + 1);
```

computeIfPresent では学生コードに該当する出席日数が存在しない場合には何も処理をせず、該当する学生がいる場合のみ値（出席日数）を増やすことができます。

## まとめ

Java8から Stream や ラムダ式など大きく機能が追加されましたが、実は便利な機能がその他にもたくさん増えていっています。
必要な時に必要なAPIをネットで探すのもよいですが、辞書を読んでみるように公式のAPIドキュメントを読んでみるのも面白いですよ。
OWASP ZAPの初期導入手順（ルート証明書の追加手順もあるよ）

## OWASP ZAP

OWASP ZAPを使う。

## 注意事項

OWASP ZAPをプロキシにした場合、アクセスしたサイトの証明書が全てOWASP ZAP製になるので（細かい原理は分からないけど。。）、OWASP ZAPのルート証明書を登録する必要がある。
※ "ルート証明書登録"項参照

※参考 https://www.pupha.net/archives/3610/

java の 1.8 が必要なので 1.8を入れる。（JDK11だと止められる）
※javaのversionじゃなくて、oracle版じゃない動かない・・・？
　とりあえず、起動時に誘導されるoracleのサイトから落としたJREで起動確認。
　adoptopenjdkだと起動しなかった


## ZAP起動まで

※参考 [脆弱性診断ツールOWASP ZAPのインストール手順](https://qiita.com/sangi/items/d159d1a0f28a68a4f34e)

## hosts設定

※参考 [OWASP ZAPの設定と使い方](https://qiita.com/sangi/items/ba7e3d39237045c9be36)

hosts（"C:\Windows\System32\drivers\etc\hosts"）に下記を追加
myserver.com 127.0.0.1
※ドメイン名は好みで

最終的にブラウザからアクセスする際、http://localhost へのアクセスだとプロキシ（#ZAP）経由でのアクセスをなぜか行っていくれないので、myserver.comへのアクセスを行う体にする。

## ブラウザのプロキシ設定

chrome用

`設定 > プライバシーとセキュリティ > システムの"パソコンのプロキシ設定を開く"``

windowsの設定フォームが起動するので、localhost, 18080 で設定する。

## ルート証明書登録

OWASP ZAPをプロキシにした場合、アクセスしたサイトの証明書が全てOWASP ZAP製になるので（細かい原理は分からないけど。。）、
OWASP ZAPのルート証明書を登録する必要がある(https://www.pupha.net/archives/3610/)

ZAPのルート証明書をchromeに入れておく必要がある。

### ZAP側作業

証明書の生成を行う。出力されるcrtファイルはブラウザへimportする用。

`ツール > オプション > ダイナミックSSL証明書 > 生成 > 上書きする > crtファイルを保存`

### chrome側作業

ZAP側作業で生成した証明書のimportを行う。

`設定 > 証明書の管理 > "信頼された発行機関"でインポート > zapで生成したファイルをインポートする`

### 動作確認

新しくchromeのウインドウを新しく開いて、https://myserver.com:3000/ へアクセスする。

HUDがどうこうっていうのが出てくるので、HUDを使わない方を選択する。

アドレスバーの左側が鍵アイコンになっていれば成功。
※鍵アイコンをクリックして"証明書(有効)"になっていれば成功。
誰も知らない?sonic_installerの話

# インストールしたSONiCを更新したい
SONiCの初期インストールにはONIEを使います。環境をきっちりセットアップすれば自動的にインストールさせることもできますし、そうじゃなければONIEのコンソールからコマンドを叩けばインストールできます。SONiCのインストールイメージはサーバに置いたりUSBメモリに入れてスイッチ本体に挿したりといった感じ。

では、SONiCがインストールされたスイッチに対して、新しいイメージに置き換えたい場合、どうするのがいいでしょうか?

# 公式wikiに示された手順
```
# sh ./sonic-broadcom.bin
```
上記はBroadcom用イメージの場合ですが、他のプラットフォームであってもファイル名が異なるだけで手順としては同じです。要するに、スイッチで動いているSONiC(この場合Linuxと読み替えていい)から参照できるファイルシステム上に更新用のイメージファイルを配置し、shに食わせれば更新される、というものです。

しかしこれはよろしくない。どこがよろしくないかというと、IPアドレスなどの設定が丸ごと初期化されてしまうのです。つまり、更新というより再インストールに近いということになります。

# どうしようもないときの手順
なんらかの不具合でSONiCの操作ができないようなケースでは、初期インストール時と同様にONIEを使ってインストール済みイメージを削除し、再度インストールすることになります。当然設定は初期化されます。再インストールです。

# どこにもドキュメントがないがおそらく推奨すべき手順
`sonic_installer`コマンドというものが用意されていて、これを使います。(Pythonで書かれています)

```
$ sudo sonic_installer install -y ./sonic-broadcom.bin
```
このコマンドは現在の設定内容(`config_db.json`)をバックアップするようになっています。SONiCは起動時に、バックアップされた設定が存在するかチェックして、あればその設定を使うようになっているため、更新後も設定が引き継がれます。

# それでも引き継がれないssh host key
`config_db.json`に描かれた設定は`sonic_installer`を使うことで更新後も引き続き利用することができます。が、ssh host keyはバックアップ対象外のため、SONiCを更新するとhost keyは別の値に差し変わってしまいます。つまり更新後にsshでログインしようとするとエラーを食らい。やむなく`ssh-keygen -R ホスト名`を実行することになってしまいます。

## patchを書いてみた
**(2020年2月10日追記: 下記のpatchは、現時点のmasterでは当たらなくなっています。代替手段については[SONiCのconfig-setup hookを使ってみる](https://qiita.com/masru0714/items/ef0980a69c62c80c7a6e)をご参照ください。)**
ssh host keyが引き継がれない問題は、`sonic_installer`とSONiCの起動スクリプト`rc.local`の合計2か所にパッチを当てることで解決します。

`sonic_installer`のパッチ (`src/sonic-utilities`で当てます)

```diff
diff --git a/sonic_installer/main.py b/sonic_installer/main.py
index b47703c..0caa67e 100644
--- a/sonic_installer/main.py
+++ b/sonic_installer/main.py
@@ -364,6 +364,9 @@ def install(url, force):
         run_command("rm -rf /host/old_config")
         # copy directories and preserve original file structure, attributes and associated metadata
         run_command("cp -ar /etc/sonic /host/old_config")
+        run_command("rm -rf /host/old_ssh")
+        # copy directories and preserve original file structure, attributes and associated metadata
+        run_command("cp -ar /etc/ssh /host/old_ssh")

     # Finally, sync filesystem
     run_command("sync;sync;sync")
```

`rc.local`のパッチ

```diff
diff --git a/files/image_config/platform/rc.local b/files/image_config/platform/
rc.local
index b74e9f40..03445a63 100755
--- a/files/image_config/platform/rc.local
+++ b/files/image_config/platform/rc.local
@@ -236,6 +236,10 @@ if [ -f $FIRST_BOOT_FILE ]; then
     else
         touch /tmp/pending_config_initialization
     fi
+    if [ -d /host/old_ssh ]; then
+        mv -f /host/old_ssh/* /etc/ssh/
+       rmdir /hoe/old_ssh
+    fi

     # Notify firstboot to Platform, to use it for reboot-cause
     touch /tmp/notify_firstboot_to_platform
```

どうやってるかは書いてある通りです。