OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptでトランプ遊び part 2

[part1](https://qiita.com/uniqode/items/9d15648af12c6074af98)の続きです。

本当はゲーム部分をもう少し追求したかったのですが、そこはデータの持ち方やIF設計が重要かと思うので、今日は表示部分について少し研究したいと思います。

まずは、前回同様にトランプのカードデッキ `cards` を準備します。下記をChromeのConsoleで実行してみてください。

```JavaScript
let cards={};
"ABCD".split("").forEach((u,i)=>{"123456789ABDE".split("").forEach((l,j)=>{cards["SHDC"[i]+"1234567890JQK"[j]]=String.fromCodePoint(`0x1F0${u}${l}`)})});
cards.J0 = String.fromCodePoint(0x1F0BF); // Red joker
cards.J1 = String.fromCodePoint(0x1F0DF); // White joker
```

次は表示する部分です。前回はハートやダイヤのカードも黒く表示されてしまっていました。そこで、今回は赤いカードは赤く表示したいと思います。

```JavaScript
const clog = (t)=>{
  let memo = {
    color : "",
    text : "",
    styles : [],
    add(color, card){
      if (this.color == color){
        this.text += card;
      }else{
        this.styles.push("font-size:xx-large;color:"+color+";");
        this.text += "%c" + card;
        this.color = color;
      }
    }
  };
  [...`${t}`].forEach((a)=>{
    if (a.match(/\ud83c[\udcb1-\udcce]/)){
      memo.add("red", a);
    }else{
      memo.add("black", a);
    }
  });
  console.log(memo.text, ...memo.styles);
};
```

`console.log` の第二引数以降にCSS Styleの配列を展開しています。第一引数のテキストには、Styleを切り替えたいタイミングで `%c` を挿入します。今回はフォントサイズとテキストカラーを指定していますが、バックグラウンドカラーを指定するなどすれば、ユーザー/デッキ/手札の表示分けに役立つかもしれませんね。

はい。では、カードを10枚引いてみましょう。赤い札は赤く表示されましたか？

```JavaScript
clog(Object.keys(cards).sort(()=>{return Math.random()-.5 }).slice(-10).map((c)=>cards[c]).join(""))
```

ちなみに、`console.log` で色を付ける方法は、これ以外にANSI Escape Codeを使う方法もあり、実はそちらも試したのですが、その場合font-sizeがキャンセルされてしまったため、挫折してしまいました。何か方法をご存知の方が居れば教えてください。

それでは、今回はここまで。
anyenv と nodenv で node.js バージョン管理、設定後に gulp の設定を修正（Mac）

様々なプログラム言語のバージョンを複数インストールしてバージョンを切替えて使用、管理できる anyenv というツールの存在を知り、node.js 管理の nodenv だけでなく、python、ruby なども pyenv、rbenv を anyenv でまとめて管理できるということで、便利そう！と思い、使ってみることにしました。 
現在まで node.js のバージョン管理には nodebrew を使っていました。
node.js 用はとしては、ndenv も nodenv 同様のことができて有名なようですが、あまりアップデートされていないとのことでしたので、node.jsの環境管理は nodenv を選択しました。
設定に苦労したのでメモをまとめておきます。

## Anyenv のインストール
anyenv:
https://github.com/anyenv/anyenv

git clone でルートに .anyenv を複製し、
.bash_profile にパスを通したあとにシェルを再起動

```
$ git clone https://github.com/anyenv/anyenv ~/.anyenv
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(anyenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
```

インストール後エラーメッセージが表示されてしまったので、

```
> \e[33mANYENV_DEFINITION_ROOT(/Users/USER_NAME/.config/anyenv/anyenv-install) doesn't exist. You can initialize it by:\e[0m
\e[33m> anyenv install --init\e[0m
```

エラーメッセージのとおりに再度 anyenv をインストール

```
$ anyenv install --init
```

anyenv でインストールできる **env を一覧表示する

```
$ anyenv install -l
```

## nodenv のインストール

nodenv:
https://github.com/nodenv/nodenv

anyenv で nodenv をインストール

```
$ anyenv install nodenv
```

## nodenvでの node.js バージョン管理

インストール可能な node.js のバージョン確認

```
$ nodenv install --list
```

Nodenv でバージョンを指定してインストール

```
$ nodenv install 11.12.0
```

インストール後にリハッシュする

```
$ nodenv rehash
```

### 各プロジェクトディレクトリでのバージョン設定
各プロジェクトディレクトリに移動し .node-versions （隠しファイル）にバージョンを記述すると、nodenvがバージョンを自動で切り替えてくれる

```
$ cd myproject
$ nodenv local 10.6.0
```

### グローバルの node.js を特定バージョンで有効化

```
$ nodenv global 11.12.0
```

グローバルの node.js バージョンを確認

```
$ nodenv global
11.12.0
```
現在のディレクトリの node.js バージョンを確認

```
$ node -v
v10.13.0
```
nodenv で管理されている node.js のバージョン一覧を表示

```
$ nodenv versions
* system => v10.13.0 (set by /Users/USER_NAME/.anyenv/envs/nodenv/version)
```

### nodebrewで管理していた 旧 node.js をアンインストール

```
nodebrew uninstall [version]
```
.bash_profile の nodebrew 用のパスの記述を削除

```
export PATH=$HOME/.nodebrew/current/bin:$PATH
```
## nodenv の設定
.bash_profile に nodenv 追記
シェルの再起動

```
$ echo 'eval "$(nodenv init -)"' >> ~/.bash_profile
$ exec $SHELL -l
```

.bash_profile の内容を確認

```
$ cat ~/.bash_profile
```

node.jsのバージョン確認

```
$ node -v
```

.bash_profileの記述を確認

```
$ cat ~/.bash_profile
```

nodenv の再ロード

```
$ nodenv init
```


### nodenv を使ってインストールした Node.js のアンストール

```
$ nodenv uninstall 6.0.0
```

## gulp の設定を修正

gulp
https://gulpjs.com/docs/en/getting-started/quick-start

nodenv をインストール後に、 gulp を使用しているプロジェクトのディレクトリで gulp を実行したところ、
command not found が表示されて gulp が動かなくなったので、設定を修正する
（パスが通っていないのが原因と思われるので、gulp を再インストールをせずにパスを通すだけで解決する可能性が高そう）

```
$ cd <myproject>
$ gulp
bash: gulp: command not found
```
### gulp の再インストール

npmをアップデート

```
$ npm install -g npm
```

すでにインストールされているグローバルの gulp ファイルを削除しておく
（sudo なしで実行したところエラーになったので sudo をつけて再度実行）

```
$ sudo npm rm --global gulp
```

gulpをグローバルにインストールする

```
$ sudo npm install --global gulp
```


command not found が表示されたプロジェクトのディレクトリに移動し、パスを通すコマンドを実行

```
$ cd <myproject>
$ export PATH=$PATH:./node_modules/.bin
```

gulpを実行

```
$ gulp
```

.bash_profile に追記しておく

```
$ echo 'export PATH=$PATH:./node_modules/.bin' >> ~/.bash_profile
```
pycryptoをインストールして失敗した時の忘備録

## This is 何？
Pythonで暗号化処理を取り入れる際に[pycrypto](https://pypi.org/project/pycrypto/)を採用してしくじっちゃったよっていう忘備録

## 別環境で動かない
ローカルで動いていたpycryptoを他環境に`pip install`した際に動かなかった。

## なぜ？
pycryptoは2013年にサポートが終了していて現在はpycryptoをforkして作られた[pycryptodome](https://pypi.org/project/pycryptodome/)というパッケージが推奨されているらしい(pycryptoからforkして作られているので互換性はあると...思う)

## 解決策
2通りあります

### pycryptoをpycryptodomeに置き換えたい

```
$ pip install pycryptodome
```

import先が`Crypto`パッケージになり、pycryptoをinstallしていた場合pycryptodomeと混在して危ないですよって公式アナウンスされていますね(pycryptoもCryptoパッケージをimportするため)。
検証してませんが事前に`pip uninstall pycrypto`しておけば大丈夫なのかな？
pycryptoをinstallしていない状態であれば基本こっちでいいと思います。

### pycryptoとpycryptodomeを共存させたい

```
$ pip install pycryptodomex
```

import先が`Cryptodome`になりpycryptoとpycryptodomeが共存できます。

## 反省
パッケージの最終バージョンの日付を確認するのって大事なんだなぁと身にしみました(小並感)。
Ethernetフレーム、IP、TCP、UDPヘッダ

# 知っているようで、普段気にしないこと。Ethernetフレーム、IP、TCP、UDPヘッダの構造

[概要1](https://drive.google.com/file/d/1JAwA0URtwdbCYoP-xkVIHUXFFVUglviI/view?usp=sharing)
[概要2](http://hrsk0310.mydns.jp:11377/webdav/webdav.share/Ether_TCPIPHeader.pdf)

## TCP,UDPのチェックサム
TCPヘッダ、UDPヘッダ＋データを１６ビット（２バイト）で保有

## IPv4のチェックサム
IPv4ヘッダを１６ビット（２バイト）で保有

## EthernetフレームのFrameCheckSequence
Ethnenetフレームを３２ビット（４バイト）で保有
・・・バーストエラーのチェック

Ethernetフレームがデータ長＜１５００バイトを考慮すると
TCP,UDPでは１５００バイト相当を１６ビットでチェックサムし
Ethernetフレーム全体で３２ビットでCRCしている。
戸締まりチェックリスト（紙）を Vue.js で作ったからもう安心

毎日の戸締まりって管理や点検の都合上、意外とデジタル化が難しいもので、紙でチェックしながら戸締まりしている現場もまだまだあると思います。

紙にチェックリストを作るのは、地味にめんどくさい作業でしかも定期的に発生しがちなので、ブラウザ上でさくっとやれる [tojimarist(仮)](https://snakada.github.io/tojimarist/) というものを作りました。Chrome でのみ動作確認しています。


## 作った経緯（はしりがき）

毎日の安全のために、アナログな戸締まりチェックリストを mac/Numbers で作成→印刷して使っていたのですけど、エクセルにあるような「別のセルを条件に条件付き書式を設定する」が仕様上不可なため土日の行に色をつけられないという問題に直面しました。

それで運用していると土日は空行にするべきところ、頭ぼんやりな月曜には気づかずついうっかり土日のところにペンで書き込んでしまって、あとで週末くらいになって辻褄が合わなくなってうわぁぁぁぁってなったんです。

それを解決するために Windows/Excel を起動するのも負けた気がするので Vue で作っちゃおうというのがこのプロジェクトのはじまりです。

せっかくなのでついでに祝日を自動取得して黒塗りしてやるようにしました。公休日を Google カレンダーとかで調べて、シートに反映するって作業が地味に面倒だったんですよね。これがあれば毎日のチェック作業しながら、もうちょいで休みだーなんて、ちょっとモチベーションあがるかもしれません。

いろいろとまとめたうえでまた投下するつもりなのですが意外といろいろ実装してしまったので、もう少しシンプルにしてからやろうと思います。

あとで忘れても困るので、経緯やざっくり構成だけでも書いておきます。コードは以下のリポジトリを参照していただくとして、解説等はまたの機会に是非。

## リポジトリ
https://github.com/snakada/tojimarist ([動くデモ](https://snakada.github.io/tojimarist/)）

## できること

1. 戸締まりチェックリストをブラウザ上で月単位で作成し、最終的には印刷して使います。
2. 戸締まりするチェック項目（玄関、キッチン、火元等）、を自由に追加・削除・ソートができます。
3. 設定したチェック項目は localStorage に保存します。
4. 何ヶ月分でもつくれます。運用としては3ヶ月毎に必要項目を点検しつつ印刷するイメージです。
5. 印刷用にある程度最適化しています。

# example

実際に動くものをここに置きました。
https://snakada.github.io/tojimarist/

## 主に使ったもの

* [Vue.js](https://jp.vuejs.org/index.html)
* [Vue CLI](https://cli.vuejs.org/)
* [Vuex](https://vuex.vuejs.org/ja/guide/)
* [vue-slicksort](https://www.npmjs.com/package/vue-slicksort)
* [vue-toasted](https://www.npmjs.com/package/vue-toasted)
* [dayjs](https://github.com/iamkun/dayjs)
* [japanese-holidays](https://www.npmjs.com/package/japanese-holidays)
* [Font Awesome](https://fontawesome.com/)
* [Bulma](https://bulma.io/)

## 構成（ざっくり）

```
├── App.vue               // アプリ
├── assets
├── components
│   ├── AddCheckItem.vue  // チェック項目追加フォーム
│   ├── AppHeader.vue     // アプリヘッダ（別になくてもいい）
│   ├── MainSection.vue   // メインセクション（印刷用紙の背景・コンテナ）
│   ├── PrintSheet.vue    // 印刷用紙（成果物、ここに設定がほとんど反映される）
│   ├── SidePanel.vue     // 設定パネル（チェック項目ソート等、いろいろ操作する）
│   └── YearMonths.vue    // 年月操作
├── main.js               // エントリ
└── store.js              // ステート管理
```

## 今後

ちょうどタイプスクリプトの勉強もしたかったので、戸締まりチェックリスト
tojimarist(仮) v0.2.0 とかやりたいです。もう少し余力あればに投下したいです。

本日は以上です。
二つの値を監視して一つの部品に反映するのSampleです。

二つの値を監視して一つの部品に反映するのSampleです。
見たほうが早いと思おうのでgif載せます。
Onsen UIとVue.jsを使っています。

#gif

![VueSamplemove1.gif](https://qiita-image-store.s3.amazonaws.com/0/133940/2560c007-6845-6704-a475-28c16c19d94b.gif)

行いたいと思っていたこと
・二つの入力がされたらボタンを押せるようにする。
・二つの入力がされたら、cssのクラスを適応する

#code

```App.vue
<template>
<v-ons-page>
  <p>
    <v-ons-input type="text" placeholder="ログインID" v-model="name"></v-ons-input>
  </p>
  <p>
    <v-ons-input type="password" placeholder="パスワード" v-model="passWord"></v-ons-input>
  </p>
  <div style="width:150px;" class="sample" v-bind:class="{ active: is_login }">!ログイン!</div>
  <v-ons-button v-bind:disabled="is_login != true">Tap</v-ons-button>
</v-ons-page>
</template>

<script>
export default {
  data() {
    return {
      name: '',
      passWord: ''
    }
  },
  computed: {
    is_login() {
      return this.name !== '' && this.passWord !== ''
    }
  }
}
</script>

<style>
.sample {
  font-family: "Hiragino Kaku Gothic Pro", Meiryo, sans-serif;
}

.active {
  background-color: red;
}
</style>
```

#行っていることPoint部分

###1
ここは最初からCSSの.sampleは指定しているけど、.activeクラスは入力によって切り替えるようにしています。
is_login()の内容がtrueで背景色を赤色にする.activeクラスをつけています。

```.vue
class="sample" v-bind:class="{ active: is_login }"

computed: {
    is_login() {
      return this.name !== '' && this.passWord !== ''
    }
  }

<style>
.sample {
  font-family: "Hiragino Kaku Gothic Pro", Meiryo, sans-serif;
}
.active {
  background-color: red;
}
</style>
```

###2
v-bind:disabled="trueだと押せなくなる指定なので、
is_login != trueと調整した書き方にしているだけです。
is_loginがtrueの時に押せるようにしたいため。
メソッドを足してそれようのもの作っても大丈夫です。

```.vue
"is_login != true"
```

#参考
https://qiita.com/dia/items/33549274ba504846a523
https://jp.vuejs.org/v2/guide/computed.html
https://jp.vuejs.org/v2/guide/class-and-style.html
AWS Lambdaで環境変数を設定・参照する方法【Node.js】

## AWS Lambdaで環境変数を設定・参照する方法【Node.js】
<img src="https://toshioakaneya.com/wp-content/uploads/2019/04/Screen-Shot-2019-04-01-at-23.19.38.png">
上の様なGUIがありますので、環境変数を記入します。

![Screen Shot 2019-04-01 at 23.28.56.png](https://qiita-image-store.s3.amazonaws.com/0/250231/a2f1f859-840c-5314-4a9b-cbc0646984a9.png)
これで完了です。
環境変数には`process.env`でアクセスできます。
`console.log(process.env.NODE_ENV)`
とすると、`"production"`と表示されるはずです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
Windowsで大文字／小文字が異なるファイル名のファイルを上書きしても元のファイル名のまま

これ以上簡潔なタイトルが思い浮かばなかった自分に落胆…orz

# 起きたこと
あるバッチプログラムが出力するファイルの名前に含まれる小文字を、
大文字に変えて出力するようにバッチプログラムを変更したのに、
なぜかファイル名が変わらなかった。

# 分かったこと
- 小文字ファイル名のファイルに対し、大文字ファイル名の同名ファイルで上書きすると、ファイル名は元の小文字のまま。
- 逆も同じ。（小文字⇒大文字　で　大文字のまま）

```
rem 小文字ファイル名の「aaa.txt」を作成
c:\temp>echo "before" > aaa.txt


rem 小文字ファイル名の「bbb.txt」を作成
c:\temp>echo "after" > bbb.txt


rem 確認
c:\temp>dir
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は 3C7A-85EC です

 c:\temp のディレクトリ

2019/04/01  23:19    <DIR>          .
2019/04/01  23:19    <DIR>          ..
2019/04/01  23:19                11 aaa.txt
2019/04/01  23:19                10 bbb.txt
               2 個のファイル                  21 バイト
               2 個のディレクトリ  169,053,376,512 バイトの空き領域


rem 「bbb.txt」を大文字ファイル名の「AAA.txt」としてコピー（上書き）
c:\temp>copy bbb.txt AAA.txt
AAA.txt を上書きしますか? (Yes/No/All): yes
        1 個のファイルをコピーしました。


rem 上書きしたのに「aaa.txt」のままだった
c:\temp>dir
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は 3C7A-85EC です

 c:\temp のディレクトリ

2019/04/01  23:19    <DIR>          .
2019/04/01  23:19    <DIR>          ..
2019/04/01  23:19                10 aaa.txt
2019/04/01  23:19                10 bbb.txt
               2 個のファイル                  20 バイト
               2 個のディレクトリ  169,078,181,888 バイトの空き領域


rem 念のため上書きされた「aaa.txt」の中身を確認
c:\temp>type aaa.txt
"after"


rem そもそもコマンドプロンプトでは大文字がすべて小文字に見えるだけかもしれないので
rem 念のため大文字ファイル名のファイルを作成
c:\temp>echo "uppercase" > CCC.txt


rem 確認…ちゃんと大文字「CCC.txt」だった
c:\temp>dir
 ドライブ C のボリューム ラベルは Windows です
 ボリューム シリアル番号は 3C7A-85EC です

 c:\temp のディレクトリ

2019/04/01  23:21    <DIR>          .
2019/04/01  23:21    <DIR>          ..
2019/04/01  23:19                10 aaa.txt
2019/04/01  23:19                10 bbb.txt
2019/04/01  23:21                14 CCC.txt
               3 個のファイル                  34 バイト
               2 個のディレクトリ  168,992,673,792 バイトの空き領域
```

Windowsでファイル名が大文字と小文字を区別しないのは知っていたのですが、
上書きされてもファイル名がキープされるのは知りませんでした。常識ですかね…？
オンプレミスの基幹システムをAWSに移行することになった話 2

# 最初にやったこと
割とやりたいことに近い本が2冊売っていたので社長に買ってもらい、平日は会社で仕事の合間に1時間ずつ読み進め、帰宅後は元気があれば30分〜120分読むという感じで進めました。

[Amazon Web Services 業務システム設計・移行ガイド (Informatics&IDEA)](https://www.amazon.co.jp/dp/4797392568/ref=cm_sw_r_tw_apa_i_UruOCb1ECZ1ZR)
<img src="https://qiita-image-store.s3.amazonaws.com/0/171074/3b5ea4cb-975d-840a-29ff-6c3634fa0d59.jpeg" width="250px">


[Amazon Web Services パターン別構築・運用ガイド 改訂第2版 (Informatics&IDEA) ](https://www.amazon.co.jp/dp/4797392576/ref=cm_sw_r_tw_apa_i_BwuOCbY5HT52B）
<img src="https://qiita-image-store.s3.amazonaws.com/0/171074/e06e6a5e-551c-bdce-06d5-a5bd0ef9f79a.jpeg" width="250px">


AWSのメリットやEC2やRDSといったメジャーなサービスを中心に、初学者にわかりやすいレベルで記載されており、基本的なAWSのサービス名や内容が理解出来ました。
2冊を読み切るのに大体1.5ヶ月ほどかかりました。（私は読むのが遅いので、早く読める人はもっと早い思います。）

# AWS構成図を作ってみた
インプットがある程度出来たので、アウトプットしてみようと思い手探りでAWS構成図を描いてみました。
![構成図part1.JPG](https://qiita-image-store.s3.amazonaws.com/0/171074/9ae4a500-16aa-2dc1-0723-603829295228.jpeg)

うちの基幹システムはまだそれほど大きな規模ではなく、使用人数も50人未満なのでとりあえずミニマムに、
でも今後の拡張が出来るようロードバランサを挟んでおくように構成しました。
障害対策を考えるならMulti-AZ構成にしたいところですが、ランニングコストを抑えるために切りました。

ただし、今後に複数台のWebサーバーに対応できるよう、画像ファイルやログファイルはS3に、セッションファイルはElastiCacheに保存するようにしています。
この構成図はあくまで2冊本を読んだくらいの知識で作った図なので、これでちゃんと動くのかどうかは不明です。

# AWSの企業無料相談会で意見を伺ってみた
「無料」という甘美な言葉に誘われ、とりあえず有識者に構成図を見ていただき意見を頂きました。
指摘された箇所は

* あまり知識がない状態で複雑な構成にすると運用が辛くなる
* なるべくAWS Elastic Beanstalk みたいな自動環境構成ツールを利用するべし
* WAFつけるべし
* ミドルウェアのバージョン更新なんかも考慮しておくべし

という辺り。
先日AWSomeDay2019にも初めて参加しましたが、
AWS的にはEC2やRDSといった細かい部品パーツを使うよりはフレームワークのようなサービス使うのを推奨していますね。

# 最終AWS構成図
そんなわけで最終的には欲張らずシンプルに、オンプレとあまり変わらない感じでとりあえずAWS化を目指すというところに着地しました。
社内サーバーと同じようにローカルipアドレスで接続します。
![AWS_part2.JPG](https://qiita-image-store.s3.amazonaws.com/0/171074/ecede7ed-7102-38a0-ab85-a65ecab517e0.jpeg)

 [オンプレミスの基幹システムをAWSに移行することになった話 3](https://qiita.com/Yosukemusi/items/b7df6cf546aca5add533)
ターミナルの$の前(プロンプト)を短くする

プロンプトは、変数PS1によって制御されているようなので、これを変更します。

## 変更前

```~/.bashrc
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
```

```
Username@PCname:~/Documents/dir1/dir2$ 
```

## ユーザー名を表示しない

```~/.bashrc
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}@\h:\w\$ '
fi
```

編集後、`source ~/.bashrc` もしくはターミナル再起動

```
@PCname:~/Documents/dir1/dir2$ 
```


## PC名を表示しない

```~/.bashrc
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@:\w\$ '
fi
```

編集後、`source ~/.bashrc` もしくはターミナル再起動

```
Username@:~/Documents/dir1/dir2$ 
```


## カレントディレクトリを表示しない

```~/.bashrc
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\$ '
fi
```

編集後、`source ~/.bashrc` もしくはターミナル再起動

```
Username@PCname:$ 
```


## 全部表示しない

```~/.bashrc
if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\$ '
fi
```

編集後、`source ~/.bashrc` もしくはターミナル再起動

```
$ 
```

## 参考

* https://qiita.com/fugee/items/8ccd0439cf197cfce0aa
* https://qiita.com/watertight/items/84568d0b6ef77e00dac0
js で完全一致をまとめてやりたい時

### 文字列の完全一致判定
言わずもがな `===` を使います。

```javascript
if (redFruit === 'apple') {
  console.log('リンゴです。');
}
```

### 文字列の部分一致判定
`test` が使えますね。

```javascript
if (/appl/.test(redFruit)) {
  console.log('たぶんリンゴです。');
}
```

### 文字列の完全一致をまとめて判定
こういう長い条件が...

```javascript
// isMyTaste: 好みかどうか
if (redFruit === 'apple' || redFruit === 'strawberry' || redFruit === 'rasberry' || isMyTaste) {
  console.log('個人的に美味しいと思う果物です。');
}
```

`test` の正規表現で `OR` を使うとまとめて判定できます。

```javascript
// isMyTaste: 好みかどうか
if (/^(apple|strawberry|rasberry)$/.test(redFruit) || isMyTaste) {
  console.log('個人的に美味しいと思う果物です。');
}
```

### 補足
`^` ... 文字列の先頭を表す
`$` ... 文字列の末尾を表す
`|` ... OR 
なので、`^` と `$` で判定したい文字列(パターン) をくくってあげて、`|` で完全一致判定をまとめて実行することができます。
Elasticsearchのタイムゾーン問題

## はじめに
Logstashを使ってElasticsearchにデータを入れるときにIndexと9時間ズレることで困ったことないですか？？
中身のデータの時刻情報と合わせる方法を備忘録として書いてみました。

## 利用バージョン
Elasticsearch 6.6.1
Logstash 6.6.1

## タイムゾーン問題とは
ElasticsearchのタイムゾーンはUTCで保持していて、ローカルのタイムゾーンに出来ない仕様になっています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/211371/d779e85d-37a9-e3d3-fd84-ca5348d30ee8.png)

主に以下の2点で困ります。
① Alerting(旧Watcher)で時間範囲指定でアラートを飛ばす時に9時間マイナスしてクエリを書く必要がある。
② Index名を`YYYY.MM.dd`とするとIndexが翌日AM9時に切り替わってしまい、ズレてしまう。
　※CuratorでIndexのBackup/Deleteする時にズレてしまい運用が複雑になってしまう。

```ruby:logstash.conf(sample)
output {
  elasticsearch {
    hosts => [ "ElasticsearchのIPアドレス:9200" ]
    index => "logstash-%{+YYYY.MM.dd}"
  }
}
```

## 解決策
この問題はlogstashのruby filterを使えば解決することが出来ます。
ruby filterは他filterでどうにも出来ない場合の最終手段というのがElastic社のスタンスみたいです。。
利用シーンが多いですがｗ

**【参考】**
・[ruby filter plugin][01]
・[Moving Custom Ruby Code out of the Logstash Pipeline][00]

以下のようにfilter句でruby filterを利用して日本のタイムゾーンで時刻を取得し
output句でElasticsearchのIndex名に利用することで回避することが可能になります。

```ruby:logstash.conf(sample)
filter {
  ruby {
    code => "event.set('[@metadata][local_time]',event.get('[@timestamp]').time.localtime.strftime('%Y-%m-%d'))"
  }
}

output {
  elasticsearch {
    hosts => [ "ElasticsearchのIPアドレス:9200" ]
    index => "logstash-%{[@metadata][local_time]}"
  }
}
```

- ruby filterの`event.set`で(field,value)を作成しています。(rubyのputs的な処理)
- field nameは`[@metadata][local_time]`としていますが、[@metadata]を付与することでElasticsearchにIndexingされないfieldにすることができます。
- ruby filterの`event.get`で[@timestamp]のfield nameを指定して、現時刻情報を拾っています。
- `.time.localtime`で[@timestamp]で取得した時刻をローカル時刻に変換しています。
- `.strftime('%Y-%m-%d')`で取得した時刻を文字列に変換しています。

**【参考】**
・[Event API][02]
・[ruby localtime(time class)][03]
・[ruby strftime(string from time)][04]

## まとめ
地味ですが、意外と役に立つのではないでしょうか^^


[00]: https://www.elastic.co/blog/moving-ruby-code-out-of-logstash-pipeline "Moving Custom Ruby Code out of the Logstash Pipeline"
[01]: https://www.elastic.co/guide/en/logstash/current/plugins-filters-ruby.html "ruby filter plugin"
[02]: https://www.elastic.co/guide/en/logstash/current/event-api.html "Event API"
[03]: http://pubs.opengroup.org/onlinepubs/009695399/functions/localtime.html "localtime"
[04]: http://pubs.opengroup.org/onlinepubs/009695399/functions/strftime.html "strftime"
Solidity 5.0 delegatecall()とcall()

#はじめに
Solidityには、コントラクトから別のコントラクトを呼び出す機能が有ります。
特に気をつける点として、delegatecall() と call() で、どのコントラクトにstorageされるかが変わります。

#delegate() / call()の動作確認

delegate()とcall()の引数は一つになります。
また、bool と bytes が返ってくることで、返り値を取得することができます。

```
<address>.delegatecall(bytes memory) returns (bool, bytes memory)
<address>.call(bytes memory) returns (bool, bytes memory)
```

さて、細かい説明はおいといて、まずはサンプルを動かしましょう。
動作を見たいときは、例えば[Remix](http://remix.ethereum.org/#optimize=false)で、下記を貼り付けていただけたら確認できます。

```Test.sol
pragma solidity ^0.5.0;

 contract Callee {
     uint256 public x;
     uint256 public y;

     function add(uint256 _x, uint256 _y) public returns(uint256, uint256) {
         x = _x + 1;
         y = _y + 1;
         return (x, y);
     }
 }
 
 contract Caller {
     uint256 public x;
     uint256 public y;
     uint256 public v;
     uint256 public w;
     address public callee;

     function setCallee(address _callee) public {
         callee = _callee;
     }

     function addCall(uint256 _x, uint256 _y) public {
         (bool success, bytes memory data) = callee.call(abi.encodeWithSignature("add(uint256,uint256)", _x, _y));
         require(success);
         (v, w) = bytesToUint256(data);
     }

     function addDelegateCall(uint256 _x, uint256 _y) public {
         (bool success, bytes memory data) = callee.delegatecall(abi.encodeWithSignature("add(uint256,uint256)", _x, _y));
         require(success);
         (v, w) = bytesToUint256(data);
     }
    
     function bytesToUint256(bytes memory _b) internal pure returns(uint256, uint256) {
         uint256 res1;
         uint256 res2;
         assembly {
             res1 := mload(add(_b, 32))
             res2 := mload(add(_b, 64))
         }
         return (res1, res2);
     }
}

```
#call()による呼び出し
上記の`addCall`で呼び出せます。
`addCall()`を呼び出すと、`Callee.x` `Callee.y`の値が更新され、返り値として`Caller.v` `Callar.w`の値が入ります。

例えば、`addCall(1, 2)`と呼び出すと、
Callee : `v=2` `w=3`
Caller : `x=0` `y=0` `v=2` `w=3`

となります。Callerに値が保存されず、Calleeのx,yが更新されます。

つまり、`call()`を呼び出すと、呼び出した先のコントラクトのStorageが更新されます。

#delegatecall()による呼び出し
上記の`addDelegateCall`で呼び出せます。

`addCall()`を呼び出すと、`Caller.x` `Caller.y`の値が更新され、返り値として`Caller.v` `Callar.w`の値が入ります。

例えば、`addDelegateCall(1, 2)`と呼び出すと、
Callee : `x=0` `y=0`
Caller : `x=2` `y=3` `v=2` `w=3`

となります。Calleeに値が保存されず、Callerのx,yが更新されます。

つまり、`delegatecall()`を呼び出すと、呼び出した元のコントラクトのStorageが更新されます。

#終わりに

delegatecall()とcall()のstorageの違いを、要約すると

- `call()`を呼び出すと、呼び出した先のコントラクトのStorageが更新されます。
- `delegatecall()`を呼び出すと、呼び出した元のコントラクトのStorageが更新されます。
GraphQL Enums import

Prisma API が自動で生成してくれた enum Type を schema.graphql で使用したい際は以下のように import してやればよい。

```graphql:schema.graphql
# import UserOrderByInput, PostOrderByInput, CommentOrderByInput from './generated/prisma.graphql'

type Query {
    users(query: String, first: Int, skip: Int, after: String, orderBy: UserOrderByInput): [User!]!
    posts(query: String, first: Int, skip: Int, after: String, orderBy: PostOrderByInput): [Post!]!
    myPosts(query: String, first: Int, skip: Int, after: String, orderBy: PostOrderByInput): [Post!]!
    comments(first: Int, skip: Int, after: String, orderBy: CommentOrderByInput): [Comment!]!
}
```

graphqlファイルのimport文はサポートされていないので、コメントアウトして隠す。こうするとこっそりパースが行われてimportできる。
GraphQL fragment

## fragment
fragment ⇒ どこでも使える Selection Set。クエリ時に Selection Set を強制することもできる。
例えば、以下のようなResolverを考える。

```javascript:User.js
const User = {
    email: {
        resolve(parent, args, { request }, info) {

　　　　　　 // JWT token 処理をして userId を取得
            const userId = getUserId(request, false)  

            // tokenをdecodeして取得した userId とDB内の userId が一致することを確認
            // つまりDB内の自分のemailだけ確認ができるということ
            if(userId && userId === parent.id) {      
                return parent.email
            } else {
                return null
            }
        }
    }
}
export { User as default }
```
ここで userId が一致することを確認しているが、これはGraphQLクエリの Selection Set に id が含まれていないと成り立たない。そこで、如何なる場合も Selection Set に id を強制的に含ませるように fragment を使用する。

```javascript:User.js
const User = {
    email: {
        fragment: 'fragment userId on User { id }',  // ここ！
        resolve(parent, args, { request }, info) {
            const userId = getUserId(request, false)
            if(userId && userId === parent.id) {
                return parent.email
            } else {
                return null
            }
        }
    }
}
export { User as default }
```

```javascript:resolvers/index.js
import { extractFragmentReplacements } from 'prisma-binding'
import Query from './Query'
import User from './User'

const resolvers = {
    Query
    User
}

// resolverファイルで定義したfragmentを抽出
const fragmentReplacements = extractFragmentReplacements(resolvers)

export { resolvers, fragmentReplacements }
```


```javascript:src/index.js
import '@babel/polyfill/noConflict'
import { GraphQLServer, PubSub } from 'graphql-yoga'
import db from './db'
import { resolvers, fragmentReplacements } from './resolvers/index'  // ここ！
import prisma from './prisma'

const pubsub = new PubSub()
const server = new GraphQLServer({
    typeDefs: './src/schema.graphql',
    resolvers,
    context(request) {
        return {
            db,
            pubsub,
            prisma,
            request
        }
    },
    fragmentReplacements   // ここ！
})

server.start({ port: process.env.PORT || 4000 }, () => {
    console.log('The server is up!')
})
```


```javascript:prisma.js
import { Prisma } from 'prisma-binding'
import { fragmentReplacements } from './resolvers/index'   // ここ！

const prisma = new Prisma({
    typeDefs: 'src/generated/prisma.graphql',
    endpoint: process.env.PRISMA_ENDPOINT,
    secret: process.env.PRISMA_SECRET,
    fragmentReplacements    // ここ！
})

export { prisma as default }
```

これで必ず id が含まれるようになる。
※ わざわざ resolvers/index.js を作成することで、src/index.js と prisma.js のどちらも fragmentReplacements をimportできるようにしている。importのループを避けるため。
はじめてのC++ 【32日目】

#はじめに
「令和」に決まりましたね。`大正` `昭和` `平成` `令和`　
賛否両論あると思いますが私は結構気に入ってます。
海外には `元号`という文化があるのかと思いましたが、現在は日本だけみたいだけみたいですね。
平成の間でロベール終わらせるように頑張る。

##Stock List
皆様のおかげで基本的なポインタを理解できたと思います。ありがとうございます。
今日は、スマートポインタの使い方を学ぼうとおもいます。
ロベールのC++で、クラスの動的確保の単元をやっていますが、 `new` `delete`が使われているので、スマートポインタを使って `delete` を使わないようにしようと思います。
###未解決
・メモリ  [メモリの話](https://qiita.com/yumetodo/items/067b2db266ae0779f030)　←今日はここやる
・静的メンバ [参照](https://qiita.com/yumetodo/items/b0ff58617f2733d4ffa1#%E9%9D%9Estatic%E3%81%A7%E9%9D%9Evirtual%E3%81%AA%E3%83%A1%E3%83%B3%E3%83%90%E9%96%A2%E6%95%B0%E3%82%92%E6%8C%81%E3%81%A6%E3%82%8B)
・`std::string`
・`i++`と`++i`の違い
・`nullptr`
・`std::vector`
・`std::array`
・`enum class`

・`std::quick_exit` [あとで読む](https://qiita.com/yumetodo/items/ba5bef7f64636ed2f439)
・初期化子
・みえる・みえない
・this
・標準規格と処理系
・`static_cast<int>(c)`　と `(int)c`　の違い
###解決
・`int const * const * const ** const * p`
・スマートポインタの使い方　`std::unique_ptr` や` std::shared_ptr`、`std::make_shared_ptr`


##ロベールのC++
クラスの単元が終わって新鮮な気持ち。文字列を扱うのがあまり得意でないことがこの前のAtcoderでわかったので、今の単元をやってると楽しい。
###stringクラス-2
前節では、文字列の代入、足し込み、出力などを行った。今節では、メンバ関数を使う。

```string4.cpp
#include <iostream>
#include <string>

int main(){
  while (true) {
    std::string line;

    std::cout << "なにか文章を入力してください > " << std::flush;
    getline(std::cin, line);
    //入力から1行拾い、それをstringオブジェクトに入れる関数
    if(line == "quit") {//stringクラスのオブジェクトは==演算子を使って文字列を比較できる。
      break;
    }

    std::string::size_type pos = line.rfind("。");
    //引数に指定した文字列をlineの松尾から検索する関数。
    //見つかったら、そのインデックスを返す。
    //見つからなかったら、std::string::nposを返す。
    if(pos == std::string::npos) {
      line += "あるね。";
    }else{
      line.insert(pos, "あるね");//insertは文字列の途中に文字列を挿入する関数。
    }
    std::cout << line << std::endl;

  }
}
```
<img width="478" alt="スクリーンショット 2019-04-01 22.35.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/298612/716e5671-8f00-f0f7-110a-44d85b38b2f4.png">
いまになって、 `std::`　をつけるメリットがわかった。 `using name space`だと、なにがなんだかわからなくなってとても読みにくいコードになる。ロベールの教科書も本当に読みづらい。
#終わりに
ブラックジャック作るの飽きてしまったので、新しいものを作ろうと思う。そこで、クラスを作ろうかな。
ブロック崩しあたりが、クラス作るのにちょうど良さそうなのでブロック崩しゲーム作ろうと思う。
LXDとは? 

# LXD とは?
- LXDはKVMやXenの代わりになるシステムコンテナ(Linux コンテナ.システムの他の部分とは分離された一連のプロセス)。
- コンテナで有名なDockerは、１アプリケーションを起動させることを目的としたアプリケーションコンテナ。
- Ｇｏ言語製のコンテナが他ハイパーバイザー
- ＬＸＣを使って複数のホスト上の複数のコンテナを管理する仕組み
- クライアントサーバーモデル
- 設定管理システム追加
- イメージ管理システム
- (クライアント）マルチプラットフォーム対応
- OpenStack Nova向けプラグイン

## LXC
Linuxのコンテナ機能を使うためのインターフェース
- Docker,systemdでも使われているカーネルのnamespaceやcgroupsなどを使用
- コンテナと呼ばれる軽量な仮想環境を構築
- ＣＰＵの仮想化支援機能が不要
- ＫＶＭに比べると、軌道が高速でイメージサイズが小さい
- 各種言語向けのバインディングが存在
- Linuxでしか動作しない


## Docker
- 主にアプリケーションコンテナを作る
- １コンテナ１プロセス
- 一度作ったら中身を変えない
（改定後）Oracle Master Sliver 12c　合格しました！

#本記事の目的
改定後のoraclesilver12cの受験対策記事があまりに少なく情報収集に苦戦した経験から、
これから受験を考える皆様の参考になればと思い記事を投稿させていただきます。


#自己紹介
- 入社以来インフラエンジニアを経験。（主にサーバー構築・保守）今年で6年目 。 
- oracle実務経験ほぼなし（数回保守作業をしたことある程度）
- 他の保有資格は、基本/応用情報技術者試験、AWSソリューションアーキテクトアソシエイト、Linucレベル1・2・3（304のみ）、oracle master blonze 12c

#受験結果
2019年3月に初受験で合格。（78%/64%） 
勉強時間は約1ヶ月半程度。平日はほぼ何もせず、予定が空いている土日でめちゃくちゃ詰め込みました。

#勉強方法
- まずは先輩方の受験対策記事を読む。（大変参考になりました。） 
 - [改訂後の Oracle Master Sliver 12c を受けてきました] (https://qiita.com/Aamat0san/items/08ac59fd8c962bd4fe87) 
 - [【改訂後】ORACLE MASTER Silver 12c 合格しました](https://qiita.com/Aamat0san/items/08ac59fd8c962bd4fe87)　
- 黒本を購入&oracle公式の試験内容チェックリストを参照し、黒本に記載されている試験対象範囲外の内容を確認。
 - [試験内容チェックリスト](https://education.oracle.com/ja/oracle-database-12c-administration/pexam_1Z0-062)
- 黒本の内容を読みつつ問題集とistudyに課金して問題演習。（←20k弱かかりました。。。）　
 - 黒本＆istudyの問題集については、正答率100%になるまで繰り返す。
- オラクルマスターへの道でさらに問題演習。（マルチテナントの問題は全て飛ばす）
 - [ORACLE MASTER Web問題集 | オラクルマスターへの道] (http://oraclemaster.info/exercise/) 
- 問題を演習を繰り返していく中で、黒本の内容ではよくわからなかったところ（DataPump/SQLLoaderやRMANを使用したバックアップリカバリなど）は以下OTNのoracle master対策のスライド・動画を見て理解を深めました。
 - [ORACLE MASTER対策](https://www.oracle.com/technetwork/jp/ondemand/database/db-basic/index.html#Content04)
 - **特に「ORACLE MASTER Silver Oracle Database 12c 傾向と対策」の動画は必ず見ることをお勧めします。（前編・後編二つあります。実際に似たような問題も出題されました。）**
- とどめで、白本（Silver11g）を購入し、知識を深める。<br>
※特に黒本よりも解説がかなり充実しているので、章末についている問題集は確認しましたが、白本はあくまで11gの内容なので12c特有の知識（12cではリスナーの登録はPMONではなくLREGが実施する、12cからのRESOURCEロールはUNLIMITED TABLESPACEシステム権限を保有しなくなったなど）がない状態で使用するのは危険だと思います。

#実際に受験してみての所感
- 先輩達の記事に書かれていた通り、かなり素直な問題が多かったです。<br>
- **必ず試験内容チェックリストを参照して、黒本に記載されている内容から試験範囲内容を取捨選択するようにしてください。（これがほんとに一番大事だと感じます！）**
- 基本的には試験はコマンドで出題されますので、各コマンドについてはできるだけ理解することをおすすめします。特に基本表圧縮/拡張行圧縮を指定する際のそれぞれのオプション・またその挙動はしっかり理解することをお勧めします。
- 個人的に苦戦したのはスケジューラーですが、問題演習で学んだ内容を丸暗記して臨みました。
- 黒本とistudyの問題演習で100%にしても合格は少し厳しいと思います。 OTNのスライドと動画を参照して理解を深めることをオススメします。個人的には白本はあまり意味なかったと思います。
- マルチテナントの問題が各問題集にありますが、全シカトでおｋ。（silverでは試験範囲外？goldではかなり問われるようですが。）
- 改訂後に追加項目となったDBaasについては完全無対策でいきました。（チェックリストに載ってるDBaas記事のリンクから飛んでもなぜか記事がみれない。）一問だけ当日でましたが無対策でも問題ないと思います。（ログイン画面には何が表示されるかみたいな問題でした。）

#今後
OSS-DB silverとCCNAを受験しようかと思います。
（oracle master goldは一旦逃げます笑）
UnityのAndroidビルド時に「Gradle prewarm failed」が発生する

# 環境

- macOS 10.14.3
- Unity 2018.3.3f

# 経緯

Unity 2018.2.2fで、Androidビルドは問題なくできていた。
Unityのバージョンを上げるためUnity Hub経由で2018.3.3fをインストールした。
すると、下記「Android SDK is outdated」エラーが発生するようになった。

![D1aLYB-V4AA8TXT.jpeg](https://qiita-image-store.s3.amazonaws.com/0/31032/a762daab-317c-3a12-2d4f-7fa33d483199.jpeg)

この状態で、「Update Android SDK」を押しても結果的に何も現象は変わらず、「Use Highest Installed」を押すとビルド自体は問題なく行われた。

常にこのダイアログが出るのが嫌だったので、SDK ManagerでSDKとToolsのバージョンアップを行った。
その結果「Android SDK Build-Tools 29-rc1」がインストールされた。

この状態でAndoridビルドを行うと「Gradle prewarm failed」のエラーが発生し、ビルドできない状態になった。Gradleを使用せず、Internalでのビルドを行うと成功する状態。

# 対応

SDK ManagerのSDK Toolsの画面で、いったんSDK Build-Toolsをアンインストールした。次に、「Show Package Details」にチェックを入れて、SDK Toolsの28.0.3を明示的にインストールした。
最初の「Android SDK is outdated」のエラーも出なくなり、Gradleでのビルドも成功するようになった。

<img width="765" alt="スクリーンショット 2019-04-01 22.08.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/31032/317ca28e-c0ac-5d88-b2ba-6c975c8b785d.png">

# 教訓

SDK Managerの「Show Package Details」を使うと、Toolsのバージョンを細かく指定可能。
約数の和を求める方法

##約数の和を求める方法
約数とは、ある整数や整式に対してそれを割り切ることのできる整数や整式のことです。
10なら、1、2、5、10となります。
約数の和を求める方法を以下に記述します。

```php
$num = 10; //与える数字
$a = 0;

// $i…与えられた数字を割る値
for($i=1; $i <= $num; $i++){
    // 余りが0の場合、$iは$numの約数となります
    if($num%$i==0){
        $a += $i;
    }
}
print $a;

```
実行結果：18
サーバーレス開発に必要な知識を体系化してみる（自分用）

# サーバーレス開発に必要な知識を体系化してみる
以前、サーバーレス開発としてAWSをLamdba周りを触ったので、自分なりに体系化して整理してみました。

AWSだとサーバーレス開発=Lambdaだと思っていましたが、試してみるといろいろな知識やサービスを利用します。
自分の知識の整理も兼ねて、サーバーレス開発に関する知識とその知識に対してAWSのサービスをマッピングしました。

自らの知識の整理なので、正しい説明よりも自分の言葉で書くようにしています。
プログラミングはPythonで行ったので、言語はPythonのみです。
※特に言語特有の内容はありません。

はじめにサーバーレス開発の知識のマインドマップと各要素の説明です。
次にAWSのサービスとサーバーレス開発の知識要素をマインドマップで紐づけました。

# サーバーレス開発の知識のマインドマップ
![サーバーレス開発 (2).png](https://qiita-image-store.s3.amazonaws.com/0/20217/d19a265d-bd89-d8ba-3d30-7b0222032bfe.png)


# 各要素の説明

## プログラミング

### Python
プログラミング言語の一種。インデントを強制することで可読性を向上させる。科学技術系でも人気があり、各種パッケージが豊富。


### パッケージ管理
特定の機能を再利用できるライブラリがパッケージとして公開されており、パッケージの追加、削除する仕組み。

#### pip
Pythonのパッケージ管理ツール。

## 開発環境
効率的にプログラミングを行うためのエディタや各種支援ツールが用意した環境。昨今はクラウドサービスとして提供されているものがある。

## データベース
### NoSQL
MySQLなどのリレーショナル・データベース以外の方式を指す。単純なデータ追加や参照などに特化したデータベースがあり、ドキュメント指向や列指向、グラフ特化など各方式に特化したプロダクトがある。

## オブジェクトストレージ
ファイルの保存先。ファイルのフォーマットを問わず保存することができる。またストレージにアクセスするためのAPIが用意されていることがある。
	
## サーバーレス
プログラマはサーバーの存在を意識せずコードを実行。書き方や実行時間などの制約はあるが、プログラマはサーバーの設定煩わしさやサーバー管理稼働を削減できる。
	
## バージョン管理
ファイルの変更履歴管理。機能の追加やバグが修正などを変更差分を記録し、リリースの世代管理を行う。

### Git
代表的なバージョン管理ツールの１つ。分散型バージョン管理の方式を利用している。

## 継続的インテグレーション(CI)
ソフトウエア開発プロセスを自動化することでソフトウェアの開発スピードを上げつつ、コードの品質を保証する取り組みを指す。

### ビルド
ソースコードをコンピュータ上で実行可能な状態にすること。コンパイル以外にトランスパイルもビルド工程に含まれる。

### テスト
プログラムの挙動の確認を行う。CIにおいては自動化されたテストを指す。

### デプロイ
ビルドしたプログラムを本番環境やステージング環境に配布する工程。デプロイによって改修内容がサービスに反映される。CIにおいてはデプロイも自動化する。

## 起動方式
###イベント通知方式
何かしらのイベント（ファイルのアップロード、ログの書き込みなど）をきっかけにプログラムを起動させる方式。イベント通知方式にはイベント発火と通知を管理する仕組みが必要。

### 定期実行方式
プログラムの実行する日時を設定し、実行する方式。実行時間を管理する仕組みが必要。

## WebAPI
Webの通信で情報の取得や登録などの機能を提供する仕組み。WebAPIを用いることで見た目の処理とデータの処理を分けることができる。また近年はAIなどによる特別は機能がWebAPIとして提供されている。

### REST
REST(REpresentational State Transfer)はWebサービスの設計モデルの一種。WebAPIのにおけるベストプラクティス的存在。データ取得はGETメソッド、データ登録はPOSTメソッドを使うなどのルールを決めている。

### 認証
WebAPIにおける認証。APIキーやOAuthなどを用いて不正アクセスを防ぐ。
	
## ログ
実行結果やエラー内容などを書き出すこと。ログの内容とイベント通知方式と組み合わせ、エラー時の通知などを行う。

# サーバーレス開発の知識とAWSのマインドマップ
![AWS.png](https://qiita-image-store.s3.amazonaws.com/0/20217/56dd2088-a1ba-f328-b8ff-38d231198ad2.png)

それぞれの知識は概ね上のマインドマップで繋がります。
サーバーレス開発も単体サービスでは成り立たず、組み合わせて利用しくことがわかりました。
サーバーレスは変化が激しいので、これからも学んで行こうと思います。

マインドマップの作成ではChrome拡張の[MindMap Tab](https://qiita.com/yoichiro6642/items/b465cbec2f3dcaaccdb0)を利用しました。
メンターとは？



# メンター制度って？
新入社員などの精神的なサポートをするために、専任者を設ける制度です。
仕事や生活の相談を受け、意見の収集やアドバイスを行います。
#### メンターとメンティ
メンター→先輩、アドバイスする人
メンティ→後輩・新人、相談する人

---
# メンター制度の目的は？
新人目線から見て「常に指示、監督される」のではなく、「要所要所でよきアドバイザーがいる」環境を作ることを目指します。
スタートラインに立ったメンターが最初に目指すところは「気軽に話せて頼れる先輩になる」ことです。

---
# 重要な要素
**メンティが安心して働くために大切な３要素**

---
#### 1.心理的に安全であること
心理的に安全であることは、「他者の反応に怯えたり羞恥心を感じることなく、自然体の自分を曝け出すことのできる環境や雰囲気がある」と言い換えられます。
メンターの役割で言えば「本音でなんでも話せる信頼関係作り」です。
心理的に安全な環境を作ることこそ、メンターの存在意義と言っていいでしょう。
参考：[Google re:Work - ガイド: 「効果的なチームとは何か」を知る - 心理的安全性を高める](https://rework.withgoogle.com/jp/guides/understanding-team-effectiveness/steps/foster-psychological-safety/)

---
#### 2.意見が「正しく」受け入れること
メンターとメンティが信頼関係を築く上で「受け入れられている」という感覚は非常に大切です。しかし、「全面的に味方になればいい」というではありません。

受け入れる、というのは
・甘やかす
・なんでも肯定する
のではなく、メンティの意見をまずは最後まで聞き、それを認めた上で、自分の考えやアドバイスを述べることです。

コントロールするのではなく、お互いの意見を受け入れ合い、メンターは経験から得られた良質なアドバイス与える。そして、そのアドバイスをもとにメンティが自分で考えて答えを発見する。そんな関係を目指しましょう。

---
#### 3.メンティの意見を引き出す環境
組織運営に於いて、人の意見を把握できることは非常に重要です。
そのためにはメンターが
「聞きまくる」「報告させる」
ではなく、メンティが
「伝えたい」「発信したい」
と思える環境を作ることが大切になってきます。
メンティが
「自分の思いがきちんと吸収されて、反映されている」
と思えるようにしましょう。
その環境さえ作れれば、意見を探ることに手間をかけずとも、メンティの方からなんでも報告してくれるようになっていきます。

---
# メンターがやること・やってはいけないこと

---
#### やること
・聞くことに徹する
・質問によって「気づき」を促す
・お互いに意見を尊重する
・自分で選択してもらう
・会話の内容は必ずお互い合意の上で報告する

---
#### やってはいけないこと
・意見を否定する
・説教をする
・監視する
・アドバイスに従わせる
・告げ口をする

---
#まとめると
**最高に信頼しあえる先輩・後輩の関係を作ろう！**
小ネタ　　buttonタグにv-onディレクティブ使うと、keyupイベントも付加してくれる

自分用備忘録。
buttonタグにv-onディレクティブを付加したら、keyupイベントも付加してくれるっていう話。
ソースコードはTypeScriptを使っています。

```sample.vue

<template>
     <button @click="click" autofocus>ボタン</button>    
</template>
<script lang="ts">
import { Component, Vue, Prop } from 'vue-property-decorator';

@Component
export default class TodoListAdd extends Vue {
    public click() {
        console.log("click!");
    }
}
</script>

```

autofocus属性をつけていると、ボタンにフォーカスが当たります。そのままエンターボタンを押したら、コンソールに「click!」が出力されます。
もちろんクリックしても同じ「click!」という文字列が出力されます。
僕のAWSのバイブル 〜Udemy感想その6〜

#概要
今日からエンジニアとして新社会人になりました
内定もらってから1年くらいUdemyでプログラミング学習(主にWeb系)をしていて、
修了した講座も増えてきたので感想を書いてます

今回はその６です
↓その１〜その５
[１:rails](https://qiita.com/Shinichiro_Matsuzawa/items/1d886c4af99421b17e83)、[2:rails](https://qiita.com/Shinichiro_Matsuzawa/items/48e053e81ee9badb6f1d)、[3:git](https://qiita.com/Shinichiro_Matsuzawa/items/bfc510a3d5ce389e22ab)、[4:sql](https://qiita.com/Shinichiro_Matsuzawa/items/560c5a0ba828006b4d2c)、[5:javascript](https://qiita.com/Shinichiro_Matsuzawa/items/c7b883cd652436816e86)

今回は初心者向けのAWSの講座を紹介します
説明は簡潔でわかりやすく、実際に手を動かしながら勉強できるためかーなり初心者に優しいです
>
実際に手を動かして AWS を学ぶことで０から１へを強力にサポート！

まさにその通りだと思います

#　使用した講座

[手を動かしながら2週間で学ぶ AWS 基本から応用まで](https://www.udemy.com/aws-14days/)

10時間程度の日本語の講座です
内容が１４セクションに別れており、1日１セクションずつ勉強すれば
タイトルにある通り14日間でAWSについて学べる内容になっています

僕も実際に14日間でやりました
初心者からでも無理のないペースだと思います

# 勉強した頃の自分
- AWSの名前は知っている
- cloud9を以前使ったのでアカウントもある
- cloud9以外は全く触ったことがない
- メンターからEC２とRDSでなんか作ってみるといいよと言われとりあえず講座やってみた

# 良かった点
- **すごーーーーーーーくわかりやすかった**

今まで紹介した講座もわかりやすかったと言っていたと思うのですが
こちらのAWSの講座はそれよりもわかりやすいです
ネットワークについての説明が上手だと思います

僕はあまりネットワークについて詳しくないですが何度も見返したり
途中でググったりすることなく理解できました

そういう意味で**とても初心者向け**だと思います

 - **1日分の量がライト**

1日分の動画がだいたい40分程度です
通学、通勤中に見終わる長さだと思います

なので学校への通学中に一回動画を見て、あとでもう一度動画を流しながら実際に手を動かしてみると言った方法で勉強しました

# 気になった点
- **ちょっと内容が少ない**

14日間で、とタイトルに入っていることもあり量はあまり多くないです
各セクションごとに宿題というか課題が設定されていますがそちらの解説などはありません
とても説明が上手な講師だったのでもっと内容を増やして欲しいと思いました

# まとめ
AWS初めて勉強する時に、僕の場合は
本は無機質な感じがしてあんまり頭に入ってきませんでした

この講座は実際に手を動かして設計をするのでとてもわかりやすいです
AWS全く触ったことないのならまず
「[手を動かしながら2週間で学ぶ AWS 基本から応用まで](https://www.udemy.com/aws-14days/)」
から勉強することをおすすめします
uGUIのButtonを使用する（備忘

UnityでuGUIのButtonって使用しますよね。

私はButtonを3D空間に配置して使用したいので、
Canvas（設定はWorld Space）を作ってしてButtonを配置するのですが、
Canvasが大きくてSceneで操作しにくいです。

そこで、Buttonを使用する際、Sceneで操作しやすいように行う設定を備忘のため記載。

> Canvas作成
> Render Mode を World Space に設定
> Pos X とPos Y を 0 に設定
> Width と Hight を 1 に設定
> Dynamic Pixels Per Unit を 10 に設定（Button の 文字がぼやけるため）

> Buttonを作成
> Scale の X、Y、Z を0.01に設定

> 後はお好みで位置、大きさの調整を行う。
SourceTreeを使ってみよう (導入編)

# 背景
・新しい現場でSourceTreeを使うことになったため、
  いろいろ使い方を覚えたい。

# やること
・SourceTreeをインストールする。
・Commitなどの一連の手順を試してみる。(次章)

# 内容

### インストール
[リンク](https://www.sourcetreeapp.com/)からインストーラをダウンロードする。
ダウンロードした「SourceTreeSetup-3.0.17.exe」を実行する。

### アカウントの作成
Atlassianのアカウントが要求されるので作成する。 (無料)
アカウント作成時にメールが転送される。
受診したメールの「Verify my email address」のボタンを押下する。
アカウントを作成するとAtlassianから情報提示が求められ「スキップ」「送信」ボタンがあるが、
アカウント作成の時点で目的は達成しているため「スキップ」を選択。

### インストール後続手順
SourceTreeのインストーラでAtlassianのボタンを選択
ログイン認証の画面でEメールアドレスとパスワードを入力
登録が完了しました！という画面が出ればインストールは完了

### 登録
ステップが「Install」から「Resistration」に遷移する。
詳細オプションで「改行の自動処理を設定する。(推奨)」にチェック。
(

残りはずっと「次へ」を選択。

### 付属インストール
初めてSourceTreeを選んだ場合「Git」と「Mercurial」の
インストールを問われる画面が出るかもしれない。
インストールしたい場合、「システム全体でなくSourceTree単独で使うためだけの内蔵用の〇〇〇をインストールする。」を選択。
不要な場合「〇〇〇は使いたくはない」を選択する。
#[自分用メモ]Prophetの使い方

#Prophetの使い方
###prophetをインストールする
!pip install fbprophet
### インポート
import io
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline
from fbprophet import Prophet

###型を指定してCSV読み込み
df = pd.read_csv('Query.csv',dtype = {'ds':'object','y':'int'})
###行削除
df.drop(index=[13,22])
## デフォルトの使い方
### 予測モデルの作成
model = Prophet()
model.fit(df)
### 予測期間の指定
future_df = model.make_future_dataframe(periods = 365)
### 予測の作成
forecast_df = model.predict(future_df)
### プロット
model.plot(forecast_df)


# 予測モデル
### 時系列 = トレンド + 周期性 + イベント

### パラメータが直感的に理解できる
#### 調整可能なパラメータ
#### ①線形トレンド 'linear' or 非線形トレンド 'logistic'
   ビジネスの時系列は基本的に非線形トレンド
   成長上限が決まっている
   成長初期段階では線形で近似できる
### ②変化点、変化点の数
### ③週周期と年周期
### ④イベント



# 非線形トレンドの指定
from fbprophet import Prophet
### 予測モデルの作成
model = Prophet(gwowth='logistic')
### df['cap']に上限を指定
df['cap'] = 8.5
### 予測モデルの作成
model.fit(df)
future_df = model.mke_future_dataframe(365*5)
future_df['cap'] = 8.5
forecast_df = model.predict(future_df)

## 新製品発表などトレンド変化
model = Prophet(changepoints=['2013-01-31']
model.fit(df)

### 等間隔に変化点を置いて推定
### n_changepoints=変化点の数
model = Prophet(n_changepoints=25)
model.fit(df)

### 週周期と年周期の指定
model = Prophet(weekly_seasonality=False,
                yearly_seasonality=True)
model.fit(df)

## 不定期イベント
#### イベント日を列挙したデータフレームを用意する
horiday,ds,lower,upper
24時間テレビ,2015-08-22,0,1
クリスマス,2015-12-25,-1,0
#### イベント日のデータフレームを渡す
model = Prophet(holidays=event_dataframe)
model.fit(df)


# 評価指標 
### MAPE(平均絶対パーセント誤差) 実績から何%外れているか？
### SHF

#diagnosticsは日本語で診断
from fbprophet import diagnostics

#精度検証をする。horizonに検証したい期間を入力する
cv = diagnostics.cross_validation(model, horizon='365 days')
cv.tail()

def cal_mape(df):
    return((df['yhat'] - df['y']).div(df['y']).abs().sum()*(1/len(df)))

def all_metrics(df):
    if 'yhat' not in df.columns:
        raise ValueError(
            'Please run Cross-Validation first before computing quality metrics.')

    me = (df['yhat'] - df['y']).sum()/len(df['yhat'])
    mse = (df['yhat'] - df['y']).pow(2).sum()/len(df)
    rmse = np.sqrt((df['yhat'] - df['y']).pow(2).sum()/len(df))
    mae = (df['yhat'] - df['y']).abs().sum()/len(df)
    mpe = (df['yhat'] - df['y']).div(df['y']).sum()*(1/len(df))
    mape = (df['yhat'] - df['y']).div(df['y']).abs().sum()*(1/len(df))

    return {'ME':me, 'MSE':mse, 'RMSE': rmse, 'MAE': mae, 'MPE': mpe, 'MAPE': mape}
  
all_metrics(cv)

#100日、150日、200日、250日のMAPEを算出する

def cal_some_mape(model):
    some_mape = pd.DataFrame(columns=['horizon','mape'])
    for i in range(100, 251, 50):
        horizon = str(i) + ' days'
        cv = diagnostics.cross_validation(model, horizon=horizon)
        mape = cal_mape(cv)
        series = pd.Series([i, mape], index=some_mape.columns)
        some_mape = some_mape.append(series, ignore_index=True)
    return some_mape
  
some_mape = cal_some_mape(model)
.htaccessを編集してリダイレクトする。

#ドラえも～ん！ページが404だよ～(泣
どうやらリンクが切れてしまっていてあるページにアクセスしようとすると404が返って来てしまうみたい。
新しいページを作るのは面倒だし、トップページを表示させるようにしたい…
でも、いちいち\<a\>タグを全て編集するのも面倒…
どうすれば良いの～(泣

#.htaccess編集して301リダイレクトしなよ
え？あの.htaccessって良くわからない英語がバーって書かれているアレ！？
そんなの編集出来ないよ…
イタッ、わかったよ～、なんとか出来るように調べるよ～(泣

##STEP1:`RewriteEngine on`する。
.htaccessの一番最初の行に書く「おまじない」みたいなもん。
Apacheのモジュールであるmod_rewriteを利用するときに使う宣言文らしい。

##STEP2:`RewriteRule`を書く。
`RewriteRule ^index/naiyo.html$ index/aruyo.html [R=301]`
みたいなヤツ、頭痛がするね…
でも日本語で説明すると簡単で
`URL書き換え アクセスされたURLの正規表現 リダイレクト先のURL [オプション配列]`
って感じ。

`RewriteRule ^index/naiyo.html$ index/aruyo.html [R=301]`
は
「index/naiyo.htmlにアクセスされたらindex/aruyo.htmlに301リダイレクトしますよ」
ってこと。

##STEP3:.htaccessをサーバーにアップロードしてWIN!
ね？簡単でしょ？？
でも、のび太くんは色々疑問があるみたいだね


###?1:正規表現ってなんや？
ググれ
と言ってものび太くんは泣いてしまうから、簡単に説明しよう。


.htaccessで使う正規表現は
ハットと呼ばれる`^`と、ドルと呼ばれる`$`の間に書くんだ

例えば`^page1$`という正規表現を書くと
`page`はミスマッチ
`page1`はマッチ
`page2`はミスマッチ
`page30`はミスマッチ
となる。


でもそれだけじゃ柔軟性が無いので
何でも良い1文字を表す`.`と、0文字以上を表す`*`、1文字以上を表す`+`を使っていく

例えば`^page.*`という正規表現を書くと
`page`はマッチ
`page1`はマッチ
`page2`はマッチ
`page30`はマッチ
となる。

そして`^page.+$`という正規表現を書くと
`page`はミスマッチ
`page1`はマッチ
`page2`はマッチ
`page30`はマッチ
となる。

`*`と`+`は挙動が少し違うから注意が必要！
あと`.`というものが存在するので、ドットを正規表現に含めたいときは`\.`という感じにエスケープしなければならない。

###?2:[オプション配列]の`R=301`ってなんや
簡単にいうとリダイレクト(redirect)の設定を指定しているんだ。
`R=301`は301リダイレクト、恒久的なページ移動の際の設定。
`R=302`は302リダイレクト、一時的なページ移動の際の設定。
基本的にはSEO的に301リダイレクトのほうがページ評価を引き継げるので`R=301`のほうが使われやすい。

他にも`L`や`QSA`などがあり
`L`はlastを表し、Rewrite判定の終了。
`QSA`はquery string appendを表し、クエリパラメータの変更や追加に使う。

複数のオプションを指定するときは
[R=301,L]みたいにカンマ区切りで書くと良い。
順番は関係無いよ。


#編集後記
入社初日で教えてもらったことを、ググりながら深掘りしたので記事書きました。
他にも「RewriteCond」やら「httpd.conf」やら色々あるみたいで、沼が深い！！
正規表現も徐々に慣れていかないとなぁ…
BigQueryとデータポータルの連携を試してみた

# 概要
- BigQueryのサンプルデータとDataStudioの連携を試してみた
- 結論としては、SQL投げてからグラフ化まですぐできる
- SQLかければ、すぐに可視化までできちゃう

# BigQuery
- BigQueryのTOP画面

1. データ追加をクリック
![SnapCrab_NoName_2019-4-1_20-6-48_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/148213/8a11f06c-682b-59dc-01da-d081a6a418c0.png)

2. 今回はサンプルデータの「US Residential Real Estate Data」を選択
![SnapCrab_NoName_2019-4-1_20-13-3_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/148213/22293fa0-b435-b57b-dcda-643caadc586e.png)

3. 各テーブルをクリックすると、スキーマも同一画面で確認できるので、確認しながらSQLを書くことが可能
![SnapCrab_NoName_2019-4-1_20-14-20_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/148213/a727e8a4-bde3-47de-c571-c0febc1b0adb.png)

4. とりあえず、テーブルの全データを引っ張ってみましたが、BigDataでこんなSQL書くと怒られそうですね。
5. ページ中断の「データポータルで調べる」をクリックするとデータポータルに遷移します。
![SnapCrab_NoName_2019-4-1_20-45-25_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/148213/f663a71c-6258-817a-3eee-4ca5ddad7e12.png)


# データポータル遷移後
1. 実際に、ZIPCode別のmin/MAXと四分位数を線グラフで書いてみました。
2. すべてGooglePlatform上で終わるし、クラウドですべて完結できるのがしゅごい
![SnapCrab_NoName_2019-4-1_20-52-40_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/148213/7094fa14-e21b-c8f1-3afc-f74dd496cee5.png)


# まとめ
- BigQuery→データポータルの連携は、データ分析するうえですごく有用に感じた
- 個人で試す程度なら無料枠内で十分遊べると思う
- ただし、BigQueryのすごいところはBigDataの処理の早さなのでやはりもっと大きなデータを試してみたいと思った


もし、よい可視化ツールがあれば教えていただけると喜びます！
MySQLを使ってCSVファイルをテーブルへインポートするコマンド〈個人用メモ〉

都道府県データ等を毎回入力するのは時間がかかりすぎるので、コマンドを実行することで大量のデータを一括でインポートしてくれます。

##順番にコマンドを実行してみよう

```
$ mysql -u root
```
mysqlへ入った後、インポートしたいテーブルのデータベースを指定する。

```
mysql> USE （データベース名を入れる）_development 
```
```
mysql>　LOAD DATA LOCAL INFILE '/Users/tripoodle/Downloads/areas.csv' INTO TABLE areas FIELDS TERMINATED BY ',' ENCLOSED BY '"' (id, name, created_at, updated_at); 
```
LOAD DATA LOCAL INFILE '(csvファイルが置いてあるディレクトリを指定)' INTO TABLE (テーブル名) FIELDS TERMINATED BY ',' ENCLOSED BY '"' ( (カラム名),(カラム名),(カラム名) );

これでテーブルにcsvの内容が全て入ったはずです！


---

####実は、、、
上のやり方ではnameカラムが入らなかったので、ENCLOSED BY '"'を消したら入りました。

```
mysql>　LOAD DATA LOCAL INFILE '/Users/yukookayasu/Downloads/areas.csv' INTO TABLE areas FIELDS TERMINATED BY ',' (id, name, created_at, updated_at);
```


####ちなみにcsvファイルは下記のようなものです。

```areas.csv
01,北海道
02,青森県
03,岩手県
04,宮城県
・
・
・
46,鹿児島県
47,沖縄県
```

以上です！
【要求定義の原則とプロセス】ワインバーグのシステム変革法(ソフトウェア文化を創る) - １５章

# 記事要約

- ソフトウェアと同じように、要件も「開発」するプロセスがある。
- ソフトウェア開発プロセスと要件開発プロセスは相互にフィードバックを受ける
- お客さんと開発エンジニアとの対話が大事。対話がなければエンジニアが要件に沿ったソフトウェアを作れない。

# 書籍情報
[Amazonリンク](https://www.amazon.co.jp/%E3%83%AF%E3%82%A4%E3%83%B3%E3%83%90%E3%83%BC%E3%82%B0%E3%81%AE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E5%A4%89%E9%9D%A9%E6%B3%95-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E6%96%87%E5%8C%96%E3%82%92%E5%89%B5%E3%82%8B-G-M-%E3%83%AF%E3%82%A4%E3%83%B3%E3%83%90%E3%83%BC%E3%82%B0/dp/4320029801)で出典と代えさせていただきます。

# 注意
この記事は自らの読書体験を可視化するためのものです。

記事タイトル内にある本の内容を正確に描写することは保証しません。

練習問題の本文は、改行を変更した箇所もありますが、文章は完全に引用しております。
※　問題解説は筆者の解釈です。本の中には書かれていません。

# 構成
タイトルの本全体および、章について自分なりのまとめを書いていきます。
その後、章末の「練習問題」を解きます。

# 本の概要
**ソフトウェア開発における品質と生産性向上のための環境をどう作るか**について書かれたもの。

全４巻のシリーズ構成となっており、この本は４巻目。

前３巻までで解説した管理ツールとしての考え方を用いて、
組織に健全なエンジニアリングマネジメント（本では工学管理と称していた）を将来にわたり継続できるようにするための方法を述べている。

# １５章の概要
この章では、要求定義の原則について述べられている。これは、１６章でプロセスを実施するための準備となる。

(p.302)　※太字は記事執筆者にて
>ソフトウェア工学は、**ある顧客もしくは顧客たちのために**、あるものを構築し運用し保守する役目を担っている。要求定義（要件）は顧客との関係や対応のほんの一部分にすぎないが、大切な部分である

これがソフトウェア開発のすべてであると思う。ユーザのためにやることがソフトウェアに携わる者のすべて。

そういうわけで、要件は最初に確定するものじゃなくて、開発を進めるなかで相互にフィードバックを受けて進化するものだ。

(p.302)
>ソフトウェアの第0法則：
> ソフトウェアがまともに動作する必要が無ければ、他のどんな要件も満たすことができる。

「いやいやそんなの意味ねーだろ！」と思ったが、そういうものなのかも。
それほど「要件」というものは管理が難しいし、だが真剣にやらないとダメなものだ。

# 練習問題
## 問題１
「ウォーターフォール・モデル」や、「ラピッド・プロトタイピング・モデル」のようなさまざまなソフトウェアプロセスモデルが、どのように時間とともに乖離を狭めるかを示す図を描け。
### 問題解説
「**要件はソフトウェア開発が進むにつれて製品と乖離が狭まる**」、と本章にあるので、具体的にどうなん？っていうのを聞いている。
### 自分の回答
ウォーターフォールモデルで考えた結果が以下。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/34636/4775dc14-e586-ad7f-84f4-3738405168c3.png)


## 問題２
要件原則のいくつかに違反したプロジェクトを想起せよ。その影響はどうだったか？そのプロジェクトはこうした影響をどのように補償しようとしたか？
### 問題解説
要件は最初から固定されてれば楽だが、そんなことは無い。変動が少なければそれだけ管理が楽だが、そんなプロジェクトに大した価値はない。

だいたい、ソフトウェア開発を舐めたクソな客が、「どんな家に住みたいか分からないけど、いい感じに作っといて。あ、ちなみに何人住むかはわからないから、以上」みたいなノリで言ってくる感じが満々。
### 自分の回答
仕様を決めるステークホルダーが顧客ではないプロジェクトがこんな感じだった。バカみたいに複雑なデータバリデーション仕様を決めておいて、超複雑なテストをやってしまい、想定の半分の機能しかリリースできなかった。

しかもリリースした機能も結局は「何のために作ったんだっけ？」という話になり、まるごと削除された。5000万円の工費がすべてムダ。

仕様策定からやりなおしになり、追加で1000万円使ってすべて作り直した。


## 問題３
プロトタイピングプロセスが要件乖離を狭めつづける収束的フィードバックをもたないとき、何が起こるか述べよ。できれば、読者自身の体験から例示せよ。開発を収束的にするために、そのプロセスに何ができるはずだったか？
### 問題解説
要件乖離を狭めないと、エンジニアが良かれと思ってどんどん機能を複雑にする傾向がある。
### 自分の回答
データ編集機能の要件定義をやるとき、コンフリクトが怖かったのでパターンをいくつも列挙した。でもそこに業務を知ってる人がいなかった。
コンフリクトが起きる可能性は、同時使用ユーザの数に大きく左右されるのに、ユーザビリティの考慮を業務を知らないエンジニア間で完結させた。

業務を知ってる人のフィードバックを受けていれば、複雑かつ全く使われることのない製品を作ることなどなかったのに。

## 問題４
誰かが、置き換えようとする古い事柄の経緯を十分尊重も配慮もせずに、何か新しいものを導入しようと無理押ししたような、読者の体験について述べよ。読者はその時どのように感じたか？どのように行動したか？読者自身この種の素人間違いを犯したことがあるか？他の人びとの反応はどうだったか？
### 問題解説
現行サービスへのリスペクトを持たずに取り替えると、当時の問題意識を失うぞ、という警告。
### 自分の回答
自分が自社サービスを作るときに、ちょうどオブジェクト指向を導入しようとした。一人で作ってたから他の人々の反応はわからなかったが、それまで作ってたモノリスがすべてぶち壊されて究極的に読みづらいソースコードになってしまった。