OmniAICreator/Qiita-1.07M huggingface dataset:
12-08 drywetmidi

https://adventar.org/calendars/3353 8日目のエントリーです。

## what is drywetmidi?

drywetmidiは.NET Framework用に開発されたMIDIライブラリです。APIの一部はWinMM APIを利用しており、Windows専用になっています。Linux環境がメインである筆者はこのライブラリを使ったことがありませんが、drywetmidiには面白いAPIがあるので、かいつまんで紹介しようと思います。おそらく大部分はクロスプラットフォームで使えると思います。

drywetmidiはstrongly-typedなMIDIイベント表現を用いているもので、（先日[portmidiとrtmidiのエントリー](https://qiita.com/atsushieno/items/ad7042f2929f2f59b3ca)でも書きましたが）筆者はあまりこの種の表現が好きではないので、あまり使いたがることはないだろうと思います。ただし音楽編集のために作成された一連のAPIは面白いものなので、知っておいて損はないとも思っています。

## カスタムmetaイベントとカスタムチャンク

MIDIメッセージとしては機能的な意味をもたないのですが、metaイベントは楽曲のさまざまな情報をバイト列で含めることができます。典型的なmetaイベントとしては、作曲者情報や曲タイトルなどがあります。筆者が知っている例で面白いものとしては、Vocaloid 2 Editorが出力する`*.vsq`ファイルには歌詞に対応するmetaイベントが含まれていました（筆者が知る限りでは、その後Vocaloid 3の`*.xvsq`ではXML形式になり、Vocaloid 5ではJSON形式になっていました）。

metaイベントはイベント種別とバイナリデータ（バイト列）以上の定義は何もありません。たとえば文字列を含める場合でも、それがUTF-8エンコーディングなのか、それ以外の何かしらのエンコーディングなのかを知る術はありません。つまりmetaイベントのシリアライズ・デシリアライズは処理系次第ということです。

drywetmidiでは、metaイベントの種別（これは`FFh`の次の1バイトで識別されます）に対応するシリアライザ・デシリアライザを登録しておくことで、自動的に所定のオブジェクトとバイト列を相互変換できます。

また、標準MIDIファイル（SMF）にはヘッダチャンクとトラックチャンクのみ規定されていますが、カスタムチャンクを定義して含めることもできます。筆者はカスタムチャンクを必要とする場面に出くわしたことがないのですが、世の中にはそういう処理系もあるかもしれません。

## さまざまな時間表現

MIDI楽曲において重要な要素のひとつは、テンポとの関わりも考慮しつつ、時間をどのように表現するかです。楽曲における時間の表現は何通りか考えられるもので、SMFにおいてもTimeSignatureとTempoをどう指定するかが時間の計算に影響してきます。

drywetmidiでは時間の間隔をITimeSpanというインターフェースで表現しており、このインターフェースは時間に対する四則演算と`Clone()`のみ定義します。具体的には次のような時間表現があります。

- `MetricTimeSpan`: メートル法の世界における時間表現で、内容は.NETの`System.TimeSpan`型です。
- `MidiTimeSpan`: MIDIにおけるticksとして時間を表したものです。内容はlongの値のみです。
- `BarBeatTimeSpan`: 音楽的な小節番号と拍、さらにticksを用いて時間を表したものです。全ての構成要素が正の値である必要があります。
- `MathTimeSpan`: 時間に対する演算の結果として生成される時間表現です。
- `MusicalTimeSpan`: 音符の音楽的な表現（1/n分音符の倍数など）によって時間を表したものです。

これらのうちいくつかは楽曲のテンポの値やその変化によって値が変わってくるものであり、特定の種類の型に変換するためには`TempoMap`という楽曲中のテンポの変遷を表すオブジェクトを引数に渡してやる必要があります。以下のコードは`README.md`からの抜粋ですが、MIDIファイル上のticksで表された時間表現をミリ秒単位に変換するためにはテンポ情報が必要です。

```
TempoMap tempoMap = midiFile.GetTempoMap();
TimeSpan midiFileDuration = midiFile.GetTimedEvents()
                                    .LastOrDefault(e => e.Event is NoteOffEvent)
                                    ?.TimeAs<MetricTimeSpan>(tempoMap) ?? new MetricTimeSpan();
```

## MusicTheory

`Melanchall.DryWetMidi.MusicTheory`名前空間には、音楽理論に基づいて音階を定義したり計算したりするメンバーが定義されています。たとえば…

- `Note`: 音階名を定義したり音階を表現したりします
- `Interval`:  1度〜12度までの2音階の開きを表します
- `Scale`: `Note`と`Interval`をもとに調を定義します

今回は深入りしませんが、`Melanchall.DryWetMidi.Smf.Interaction`名前空間には、さらにコードの計算などを行うChordManagerなどが定義されているので、興味がある人は調べてみるとよいでしょう（よく作られる類のAPIではないかと思います）。

他にも、GM/GM2音色などが定義されたクラスもあります。

## Patterns/Actions

drywetmidiは高水準の音楽オブジェクトの編集のために作成されたライブラリのようで、「現在のコンテキスト」に大して、音符を加えたり、音符を移動したり、コードを設定したり、といったアクションと、その集合体であるパターンを表すAPIが定義されています。いわゆるDAWのようなものを作成したい場合に有用そうです。
セマンティックなマークアップについて考える

# セマンティックとは
IT用語としてのセマンティックはコンピュータに文書や情報の持つ意味を正確に解釈させ、文書の関連付けや情報収集などの処理を自動的に行わせる技術のことを指す。

# セマンティックなマークアップの目的
機械が文書構造を理解しやすい「マシンリーダブル」なコードを記述することが目的です。

# マシンリーダブルなマークアップをする利点
- 高齢者や障害者なども含めたあらゆる人が、どのような環境（うるさい場所や、暗い場所、逆に明るい場所など）においても柔軟にWebサイトを利用できる
- SEOが上がる

# セマンティックなマークアップの例
具体的な話をするとHTML5にはタグの種類が豊富にあります。
マシンリーダブルな文書構造を表現するために適切なタグでマークアップする必要があります。

以下の記事がすごく参考になります。
https://bsj-k.com/html5-semantic-markup/
Cursor の close 処理に Java7 の try-with-resources 文を使う

# 概要
Java7 で追加された **try-with-resources** 文を使って、データベースから値を取得する時に使う Cursor を close する処理を簡潔に書く方法を紹介します。

# try-with-resources 文を使うコード
```java
try (Cursor c = contentResolver.query(uri, projection, selection, selectionArgs, null)) {
    ... // (cursor を使う処理）
}
```

Content Provider からデータを取得するためのコードを try-with-resources 文 を使って書くと、上のようなコードになると思います。

try-with-resources 文では try の内側のブロックを抜ける時に自動的に Cursor#close() メソッドを呼び出すため、
明示的に close() を呼ぶ必要がなくなります。

# try-with-resources 文を使わないとどうなるか
try-with-resources 文を使わずに、try-finally 文でコードを書くと以下のようになります。

```java
Cursor c = contentResolver.query(uri, projection, selection, selectionArgs, null);
try {
    ... // (cursor を使う処理）
} finally {
    if (c != null) {
        c.close()
    }
}
```

finally 節を書く分コードが長くなります。
また、cursor が null でないことをチェックしてから close しなくてはならないので、
その分コードが長くなる上、null判定を忘れてNPEを起こす危険性もあります。

try-with-resources 文を使わない他の例として、以下のように try 文すら使わないコードがあります。

```java
Cursor c = contentResolver.query(uri, projection, selection, selectionArgs, null);
... // (cursor を使う処理） ★
if (c != null) {
    c.close()
}
```
この書き方には、もし★の箇所で例外が発生すると cursor が close されないという問題があります。
そのため、避けたほうがよいでしょう。

#まとめ
cursor を使うときは、try-with-resources 文で書くべきだと思います。
面倒な処理は気にする必要なく、簡潔なコードになりそうです。
Bcryptを使わないでパスワード暗号化したい

#初めに
Railsでbcryptを使えばパスワードの暗号化やユーザー登録時のpassword_confirmationを簡単に実装できる。


けど暗号化とかかっこいいので自分でもやってみたいということでbcryptを使わないでパスワードの暗号化をしたい。

#とりあえず

```
rails new secure
rails g model user name:string mail:string password:string
rails g controller users index show edit new
```

して準備完了


#普通に登録しログインできるようにする

```ruby:users_controller.rb

class UsersController < ApplicationController
  def index
    @users = User.all
  end

  def show
    @user = User.find params[:id]
  end

  def new
    @user = User.new
  end

  def create
    @user = User.create(user_params)
    if @user.save
      redirect_to users_path 
    else 
      render :new 
    end 
  end 

  def edit
    @user = User.find params[:id]
  end

  def update
    if User.update(user_params)
      redirect_to users_path
    else 
      render :edit
    end 
  end 

  private

  def user_params
    params.require(:user).permit(:name,:mail,:password)
  end 

end
```

あとはviewを適当に書けばOK

#とりあえずcryptをつかってみる


```ruby:crypt

irb(main):001:0> str = "hello world"
=> "hello world"
irb(main):002:0> p str.crypt("asdf")
"asodDSQaBIZi."
=> "asodDSQaBIZi."
```


といった感じでstr.crypt(salt)という構文で暗号化ができる。

このsaltの値をどうしようかと思うのですがとりあえず"secretkey"ってことにしときます。

users_helper.rbに

```ruby:users_helper.rb
module UsersHelper

    def secure_pass(password)
        secure_password = password.crypt("secretkey")
        return secure_password
    end
    
end
```

こう書いて

users_controller.rbのcreateを

```ruby:users_controller.rb
  def create
    password = user_params[:password]
    @user = User.create(user_params.merge(password: secure_pass(password)))
    if @user.save
      redirect_to users_path 
    else 
      render :new 
    end 
  end
```


みたいにすれば登録されるパスワードは暗号化されてる:sunny:


次にログイン機能で

とりあえずsessions_controllerを作って

```ruby:sessions_controller.rb
class SessionsController < ApplicationController
  include UsersHelper

  def new
  end

  def create 
    user = User.find_by(mail: params[:mail])
    if user.password == secure_pass(params[:password])
      session[:user_id] = user.id 
      redirect_to users_path
    else 
      render :new
    end 
  end

end
```

こんな感じにした

これでログインできるし登録されるパスワードの値はse64GVO8lvmmUみたいな感じで暗号化されてます。


あとはsaltの部分、今回はsecretkeyとしているところをどうしたらいいか


#追記

secretkeyをconfig/credentials.yml.encに保存しようとしたがうまくいかなくて困ってましたがWSLを使えばできるとアドバイスをもらいまして...

WSLを使って設定できるようになりました。(環境変数PATHが変なことなってて結構つまづいた…)



ということでwindowsにインストールしたubuntu上で

```
EDITOR="vi" rails credentials:edit
```

を行ってそこに

```
salt:
  salt_key: secretkey
```

みたいな感じで設定した

このsalt_keyの使い方は

```
Rails.application.credentials.salt[:salt_key]

```


みたいな感じで呼び出すことができます。


これを使ってusers_helper.rbに

```ruby:users_helper.rb
module UsersHelper

    def secure_pass(password)
        secure_password = password.crypt(Rails.application.credentials.salt[:salt_key])
        return secure_password
    end
    
end
```

こんな感じで書いて使うことができます:sunny:


教えてくださった方ありがとうございました。



#ちなみに

Bcryptを使うとgem install bcryptして
models/user.rbに

```ruby:user.rb
class User < ApplicationRecord
    has_secure_password
end
```

とかけばおわりとすごく簡単だしpassword_confirmationも実装してくれる
eosio.token コントラクトを解読してみる

イーサリアムの ERC20 と比較しながら、 `EOSIO` 公式の　`token` コントラクトを解説します。

## `eosio.token` の俯瞰
- イーサリアムの１つのコントラクトは１つのトークンであるのと違って、`eosio.token` の１つのコントラクトでは、複数のトークンを保持できます
- 下記の情報をマルチインデックステーブルに保持しています
    - トークン情報（symbol、発行量、最大発行量)を `stat` テーブルに保持する
    - アカウント毎の残高情報を `accounts` テーブルに保持する
- 送金履歴は、コントラクトと関連する `EOS` ブロックチェーンのアクションに相当するので、マルチインデックステーブルに保持しない

### `eosio.token` のアクション

| アクション       | 内容              |
| ----------- | --------------- |
| create      | 新しいトークンを作成する<br>**コントラクトの権限が必要** |
| issue       | トークンをアカウントに発行する<br>**トークンのオーナーだけ実行できる** |
| retire      | トークンの総量を減少する<br>**トークンのオーナーだけ実行できる**    |
| transfer    | トークンを送金する       |
| open        | 指定アカウントの残高０のデータを作成する             |
| close       | 指定アカウントの残高0のデータを削除する             |
| get_supply  | トークンの総量を取得する    |
| get_balance | 残高を取得する         |

## アクション詳細説明
### create
下記の情報を `stat` テーブルに登録する

- トークンのオーナーアカウント
- トークンの最大発行量
- トークンのカレント発行量

### issue
トークン最初作成された時点では、どのアカウントも残高を持っていません。
オーナーアカウントがトークンを発行することで、誰かに付与することが出来ます。

**このアクションは、トークンのオーナーだけ実行できる**

### retire
オーナーの残高を減少することで、トークンの総量を減少する。
イーサリアムの ERC20 のオプション関数 `burn` と相当する処理です。

**このアクションは、トークンのオーナーだけ実行できる**

### transfer
`from` から `to` に送金する

### open
指定したアカウントに対して、`accounts` テーブルに残高ゼロのデータを作成する。

推測ですが、多分サービス側またはウォレットアプリなどで表示する時に、残高ゼロでも表示したケースの為です。

### close
`open` の逆操作です。
指定したアカウントの残高がゼロの場合、`accounts`　テーブルからそのレコードを削除する。

`open` と同じく推測になりますが、もうそのトークンが要らない場合、こうすれば表示側が楽になります。

## 補足
- イーサリアム ERC20 のような `approve` 系の機能がありません
    - これは `EOS` の権限管理仕組みを活用できればできるじゃないかと思いましたが、権限の制御はコントラクトの詳細までを見てくれないので、おそらくできないので、やりたい場合は、やはり自分で実装するしかない

## アカウント毎の保存料金
- 送信履歴は `EOS` ブロックチェーンのアクションデータになるので、特に保存コストがかかりません
- アカウントが初回トークンをもらって（または上記の `open` アクションで）残高テーブルにレコードを追加する時、`RAM` を消費する為、料金がかかります
    - 2018 年 12 月の時点では、このコストは 2 円程度です

## `eosio.token` スマートコントラクトと `eosio.token` アカウントの関係
- `eosio.token`　スマートコントラクトは、`EOSIO` 公式で提供されているトークンのテンプレートです
- `eosio.token` アカウントは、メインネットの場合は、`eosio.token` スマートコントラクトがデプロイされているアカウントになります

### 補足
- **自分のトークンを発行したい場合は、`eosio.token` スマートコントラクトをメインネットにデプロイして、トークンを作成すれば良いです**
- 自分で発行したトークンをウォレットアプリに追加したい場合は、イーサリアムの ERC20 と同じく、所属しているアカウント名を指定する必要があります

## まとめ
イーサリアムの ERC20 と比べると機能面はまだ足りてないところがありますが、
エンドユーザー側の送金処理が無料でできるのは大きいですね。
【Unity(C#)】一気にゲームオブジェクトを消す方法

　　
　　
　　
この記事は

**『プログラミング完全未経験からUnityでの開発現場に迎え入れてもらえた世界一の幸せ者』**

の記事です。そのつもりでお読みください。
　　

##一気にゲームオブジェクトを消す



①消したいゲームオブジェクトにTagを付ける
②`FindGameObjectsWithTag(タグ名)`でTagのついたオブジェクトを配列にぶちこむ
③`foreach`で一気に消す！

できれば、消したいゲームオブジェクトはプレハブにしといた方が楽です。
プレハブなら大量にゲームオブジェクトを配置したとしてもTagを一気に変更できます。
(大量に配置している時点でプレハブは利用済みかと思いますが念のため．．．)


```C#

void AllDEstroy()
    {
        GameObject[] balls = GameObject.FindGameObjectsWithTag("Ball");

        foreach (GameObject ball_Soccer in balls)
        {
            Destroy(ball_Soccer);
        }
    }

```
`foreach`は繰り返しです。
配列`balls`の中身を`ball_Soccer`に何度も繰り返し入れています。

繰り返しで一気に消えるというのが初心者の私にはイメージしづらかったので
本当に繰り返しているのか確認してみました。

```C#
int count = 0;

    void Start()
    {
        AllDEstroy();
    }

    void AllDEstroy()
    {
        GameObject[] balls = GameObject.FindGameObjectsWithTag("Ball");

        foreach (GameObject ball_Soccer in balls)
        {
            Destroy(ball_Soccer);
            count++;  //ボールがDestroyされるたびにcountを1追加
            print(count);
        }
    }
```
　　
　　
ちゃんと繰り返していました。
![foreach count.png](https://qiita-image-store.s3.amazonaws.com/0/244071/92d9e08b-cc74-1dbe-006b-b6a3805e655a.png)

これはつまり、厳密にいうと同時ではないのでしょうか？
えらいひと教えてください。


---
2019/06/19 追記

##子のオブジェクトをまとめて取得

よく使うのでメモしときます。

```C#:取得したい子オブジェクトが存在する親オブジェクトにアタッチ
        foreach(Transform childrenTransform in this.gameObject.transform)
        {
            //一例として子のイメージコンポーネントを取得して色を変える
            image = childrenTransform.GetComponent<Image>();
            image.color = Color.yellow;
        }
```

上記のやり方をUpdat内で呼ぶと、何回もforeachのループを回して取得しに行くので
returnで抜ける処理も合わせるといいかも。

```C#
    Image image;

	void Update () {
        LightSelectedImage();
    }

    //選んだイメージを光らせる
    void LightSelectedImage()
    {
        //一度foreachを通ったらimageにはコンポーネントが入っている
        if (image != null)
        {
            return;
        }

        foreach(Transform childrenTransform in this.gameObject.transform)
        {
            
            image = childrenTransform.GetComponent<Image>();
            image.color = Color.yellow;
        }
    }
```
---
追記 2019/07/15
##マテリアルの一括取得
マテリアルの場合の一括取得は また別の方法になるのでメモしときます。

```C#:マテリアルを取得したいオブジェクトにアタッチ
    Material[] mr;

    void Start()
    {
        mr = this.gameObject.GetComponent<MeshRenderer>().materials;
    }

    public void GetMaterials()
    {
        for(int i = 0; i < mr.Length; i++)
        {
            // 例)Shaderの疑似bool値をオンに
            mr[i].SetFloat("_Enabled", 1);
        }
        
    }
```

`materials`で一括取得できるので、配列に突っ込めばforやforeachで取り出せます。

余談ですがMaterialの設定にたまにあるトグル(下記画像参照)は
Shaderでbool値をPropertyに追加することはできないため、
0 or 1の疑似表現(0ならFalse、1ならTrueみたいな)によって実装するみたいです。
![toggle.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/244071/606d3730-92c7-a8d2-dedc-5653821eff08.png)
BEM

# BEMとは
- block, element, modifierの頭文字
- Yandexで発案されたフロントエンドの命名手法
- CSSのクラス名に高い透明性を与え、他の開発者に意味を伝えやすくする
- 厳格で情報量が多いだけでなく、巨大なプロジェクトに適した命名規約である

# BEMの命名規則
## Block
BlockはElementとModifierの集合です。

検索フォームBlockの例
<img width="569" alt="スクリーンショット 2018-12-08 14.37.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/322875/60784b86-c3c5-4b0e-15a1-5e650c9534fc.png">

## Element
ElementはBlockを構成する要素です。

検索フォーム内のElementの例
<img width="711" alt="スクリーンショット 2018-12-08 14.37.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/322875/ab402f70-03d8-24e9-cb47-8ec1d711b2c6.png">

## Modifier
Modifierは、BlockまたはElementのバリエーションの違いです。
Searchボタンが押された際の振る舞いなどを表現するのがModifierになります。

検索フォームないのModifierの例
<img width="711" alt="スクリーンショット 2018-12-08 14.37.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/322875/51545f70-3b29-4f9f-6500-9eb2515291eb.png">

# BEMの記法
```
/*
Blockに対するCSSセレクタ
２語以上の命名にしたい場合は「-」を用いる
*/
.block {}
.block-name {}

/*
Elementに対するCSSセレクタ
BlockとElementを「__」で繋ぐ
*/
.block__element {}

/*
BlockのModifierに対するCSSセレクタ
BlockとModifierを「_」で繋ぐ
*/
.block_modifier {}

/*
Elementに対するCSSセレクタ
BlockとElementを「__」で繋ぎ、ElementとModifierを「_」で繋ぐ
*/
.block__element_modifier {}

```
GalaxyのHistory機能とは

# Historyについて

Galaxyを利用する上でHistoryはとても重要
![Screen Shot 2018-12-03 at 16.29.07.png](https://qiita-image-store.s3.amazonaws.com/0/213053/fb915241-782b-7362-3078-c5eeab13bfac.png)

## Historyの役割
Historyは次のような役割を担っている
###入力データの置き場所
解析を行うデータをGalaxyサーバーにアップロードすると、そのファイルはHistory上に配置される
![Screen Shot 2018-12-08 at 14.12.40.png](https://qiita-image-store.s3.amazonaws.com/0/213053/6758adab-e07f-f21b-832e-4d1ff8c0b5aa.png)

###出力データの置き場所
解析結果の出力データもHistory上に配置される
![Screen Shot 2018-12-08 at 14.13.42.png](https://qiita-image-store.s3.amazonaws.com/0/213053/850a0546-fa14-9197-a041-d10ebbafde63.png)

###解析ツール(Tool)による処理の履歴
どの入力ファイルにどの解析ツールを利用し、どのようなパラメータを与えてどの順番で解析を実行したかがHistory上に残る
Historyを利用する事で後から手順を全て確認することができる
Historyペインの履歴情報では見通しが悪い場合に、Historyペインの処理について詳細を一覧する事もできる
ペインの右上の⚙のマーク(History options)をクリック
![Screen Shot 2018-12-08 at 14.19.24.png](https://qiita-image-store.s3.amazonaws.com/0/213053/438b7a10-dff8-74ed-54ba-3dc319a00ac8.png)
ドロップダウンリストから"Show Structure"をクリックすると中央のペインに処理の詳細が表示される
(ヒストリーの項目数が大いと表示されるまでに時間がかかる)
![Screen Shot 2018-12-08 at 14.18.14.png](https://qiita-image-store.s3.amazonaws.com/0/213053/e51f42e2-eca0-c222-1e18-42f2b014a111.png)


###解析処理の状態表示
データのアップロードや解析処理の現在の状況を確認できる
処理待ち（灰色）、処理中（黄色）、処理終了（緑色)、処理時のエラー(赤色)等をHistory上の各パネルの色で確認する事ができる
![Screen Shot 2018-12-08 at 14.27.17.png](https://qiita-image-store.s3.amazonaws.com/0/213053/03cf7e72-3063-2303-33eb-c5db5562d2e2.png)


###解析処理のグループ分け
Historyを複数作成して切り替えることができるので、解析処理のグループ分けが行える
Historyペインの"View all histories"をクリックする
![Screen Shot 2018-12-08 at 14.13.42.png](https://qiita-image-store.s3.amazonaws.com/0/213053/b0e6f001-986b-1a65-ec24-90a07822453a.png)

現在存在するHistoryが表示される
![Screen Shot 2018-12-08 at 14.37.57.png](https://qiita-image-store.s3.amazonaws.com/0/213053/a7b68753-5cd8-b24f-7d57-f30362da964e.png)
多数存在する際は横方向にスクロールして表示可能

- 新たにHistoryを作成する場合には右上の"Create New"をクリック
- 既存の別のHistoryを選択する場合には、各Historyタブの"Switch to"をクリック

解析画面に戻るには上部メニューの"Analyze Data"をクリックする



###解析処理等の共有
Historyを他のユーザに公開したり、他のユーザーのHistoryをコピーする事ができる
###解析手順を元にしたWorkflowの作成
実行した解析処理を元にWorkflowを自動的に生成できる
一つのサンプルを元に処理を実行してWorkflowを作成し、他のサンプルで同じワークフローを利用する事が可能

というようにGalaxyを利用する上でHistoryの機能を理解しておく事がとても重要

History機能の詳細は[Galaxy TutorialsのHistories(英語)](https://galaxyproject.org/tutorials/histories/)を参照して欲しい

今回はここまで:smile:
VRChatで使われている3Dオーディオ技術

# はじめに
この記事は[VRChat Advent Calendar 2018](https://qiita.com/advent-calendar/2018/vrchat)の8日目の記事です。

こんにちは。クレウス(@kleus_balut )です。
VRChatユーザーで、最近は[VIVEBatteryInfo](https://kleusbalut.booth.pm/items/969809)というVRオーバーレイアプリケーションを開発しています。

VR開発では忘れられがちなオーディオの重要性について、VRChatでの体験をもとに3Dオーディオ技術の解説と、同種のソーシャルVRやVR体験施設で感じた点について、主にプレゼンスの観点で言及していきます。

※本記事に具体的なコードの記載はありません。
　体感を元にした、簡単な技術解説です。

## ONSP

VRChatでは[ONSP(Oculus Audio Spatializer Plugin)](https://developer.oculus.com/downloads/package/oculus-spatializer-unity/)というOculusがフリーで配布している3Dオーディオ技術が使われています。
ワールドの設定によりますが、デフォルトで良好な聞こえ方と思います。


特に日本国内のVR体験施設で感じたことですが、多くの場合、3DオーディオについてはUnityなどのゲームエンジン側VRサポートデフォルトのまま使っているように感じました。

3Dオーディオの質が悪いか、そもそも無効化されている場合は**VR上でのまともなコミュニケーションが難しい**と感じました。
体験型のコンテンツの場合はプレゼンスの剥がれに繋がり、ユーザー側が冷めてしまいます。

こうなるともう、ユーザーが同一の場所にいるのであれば、わざわざVR上で会話するのではなく、**HMDのヘッドフォンの隙間経由で直接話した方がマシ**という形になります。

このコンポーネントはOculusが開発したものですが、**Unity側でサポートしていればHTC VIVEでもWindowsMR(Immersive)でも使えます**。そこら辺も紛らわしいかも知れません。

###デスクトップモードでの聞こえ方の違い

VRChatをVRとデスクトップモード両方でプレイしたことがある方は感じておられるかもしれませんが、オーディオの聞こえ方が全く違います。
VRでは、真後ろから声をかけられたら、本当に真後ろから聞こえるように感じますが、**デスクトップモードではその違いが判りません**。

これは恐らく、デスクトップモードではONSPがうまく機能していないか、無効化されているためと思います。

VRでプレイに慣れている方が久しぶりにデスクトップモードで入ると会話しにくい事があると思いますが、その原因の根本はこれだと思っています。


## 音量

特にVR体験施設において、**音量が変更できないことによるプレゼンスの剥がれ**を感じました。

大音量で迫力を与えるという考え方もあると思うのですが、ひたすらに「うるさいだけ」で、たとえボイスチャットができるとしても、そもそものコンテンツの音量が大きすぎてまったく聞こえないという事がありました。

音量をユーザー側で調節できる仕組みは必要と感じました。

またソーシャルVRでは、ユーザー環境毎のマイクゲインの違いによる音量の差異もありますので、Discordで行えるような個別の音量調節も必要と思いました。

##まとめ

私自身、VRChatでVR空間上でコミュニケーションをとるまでは、音の聞こえ方がここまで重要だとは思いませんでした。
[Oculus Audio SDK](https://qiita.com/yanosen_jp/items/03de6ad02a05493f343b)について調べてみると、自然な音の聞こえ方をどのように再現しているかとても参考になります。

VRChatがいまや日常的なVRソーシャル、つまりインフラとなっているのは、この点も大きいのではないかと思います。

通常、VR開発というと、まず「映像ありき」という印象が強くあると感じていますし、実際映像だけでもでかなりの没入感を得られる技術と思います。
オーディオまで力を入れるのはなかなか大変とは思いますが、プレゼンスの向上には間違いなく繋がると思うので、VR開発されているかた・これから開発を検討されている方は、可能であればオーディオも考慮していただけると幸いです。

#参考
[VR におけるプレゼンスの維持と破壊](https://medium.com/@GOROman_1661/vr-%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%97%E3%83%AC%E3%82%BC%E3%83%B3%E3%82%B9%E3%81%AE%E7%B6%AD%E6%8C%81%E3%81%A8%E7%A0%B4%E5%A3%8A-5d9858f44ef6)
[バーチャル美少女「東雲めぐ」に“魂”を入れた技術とは？ Unite2018講演レポ](https://www.moguravr.com/shinonome-megu-unite2018/)
[Oculus Audio SDKについて調べてみた](https://qiita.com/yanosen_jp/items/03de6ad02a05493f343b)

#おわり
以上、`VRChatで使われている3Dオーディオ技術`でした。

明日は@ryou_Einさんです。

VRChat Advent Calendar 2018: https://qiita.com/advent-calendar/2018/vrchat


###おまけ
本日分は当初、自作ツールの解説を行おうと思っていたのですが、別のアドカレの私の記事と被る為、話題を変更しました。
自作ツールのVRオーバーレイはほとんど下記の記事で解説している仕組みですので、ご興味があればご覧ください。

VTuber Tech #1 Advent Calendar 2018 6日目 : [OBS向け放送プレビューVRオーバーレイをつくる](https://qiita.com/kleus_balut/items/a3f1c4632d3b5b8ab33f)
Unityの各シーンをモックデータで再生してくれる君

この記事は [KLab Engineer Advent Calendar 2018](https://qiita.com/advent-calendar/2018/klab) の8日目のエントリです。

はい。前日まで何も準備できてなかったほっへんです。
Unity2018のこと書くとかいいながら今回はUnityでプロジェクト開発した際に作ってみて便利だったツールを紹介します

# その名もUnityの各シーンをモックデータで再生してくれる君
（なげぇ

え？普通にシーンのPlayボタンを押せばよくね？って思ったあなた。甘いです！

https://github.com/luckin403/editor-play-starter
（サンプルもあるよ！

## どういうケースで使えるの？

Unityでプロジェクト開発をする場合、当然APIサーバを用意する訳ですがサーバ側の実装が終わってなかったり、初期化処理やログイン等の処理が最初のシーンにしかないあまりに以下ような経験を方もいらっしゃると思います

- 自分が作ったシーンの動作を確認するためにいちいち最初のシーンから再生する必要があるのがめんどい！！
- 自分のシーンを作ったはいいが遷移元のシーンがまだ実装中なので確認できない...
- サーバ側の実装はまだなのでモックデータで動かしたいけど、つなぎ込み時モック消したり、ビルドされたバイナリにモックデータ(デバッグ用コード)が含まれてほしくない...
- シーンの初期化処理はAwake/Startで行っているので、それより前にモックデータを注入したい

EditorPlayStarterはそれらの悩みを解決してくれます

## 使い方

まずは各データやプラグインの初期化処理、ログインリクエスト処理等を以下の箇所に記載します

https://github.com/luckin403/editor-play-starter/blob/master/Assets/Product/Script/Editor/EditorPlayStarter.cs#L40-L55

```EditorPlayStarter.cs
static void InitializeApp(Action loadMockDataScene)
{
    InitData();
    RequestLogin(loadMockDataScene);
}

static void InitData()
{
    // データを初期化したりー
}

static void RequestLogin(Action callback)
{
    // ログイン処理を行ったりー
    callback();
}
```

次に各シーンのモックデータの記述とシーンのロード処理を記述します
もしサーバの実装が完了している場合はここにHomeInfoを取得するために必要なリクエスト処理を記述します
ちなみに記述する場所はEditorスクリプトにあたるので__バイナリのビルド時には含まれません__！（ログインの箇所ももちろん同じ

https://github.com/luckin403/editor-play-starter/blob/master/Assets/Product/Script/Editor/EditorPlayStarter.cs#L23-L34

```EditorPlayStarter.cs
private static readonly Dictionary<string, Action> ReloadActionBySceneName = new Dictionary<string, Action>
{
    // ここにシーン名ごとのモックデータでのロード処理を書いてください
    {
        "Home",
        () =>
        {
            // モックデータ
            HomeSceneEntry.HofeInfo = new HomeInfo("プレイヤー名", "コメント", 99); // 今回は雑にstatic空間に...
            SceneManager.LoadSceneAsync("Home");
        }
    },
};
```

あとは↓のようなOnValidateを再生したいシーンの各HierarchyルートのGameObjectにアタッチします

https://github.com/luckin403/editor-play-starter/blob/master/Assets/Product/Script/BaseEntry.cs#L7-L13

```cs
void OnValidate()
{
    if (Application.isPlaying && UnityEditor.EditorPrefs.GetBool("MockReloadMode"))
    {
        gameObject.SetActive(false);
    }
}
```

あとはシーンを再生するだけ！

## 仕組み

EditorPlayStarterでは大きく２つのことをやっています

1. UnityのPlayボタンを検知してシーンの再ロード処理を行う
2. 再ロード直前に発火にするAwake/OnEnable/Startの暴発対策

1のPlayボタンイベントの検知については[ここ](https://github.com/luckin403/editor-play-starter/blob/master/Assets/Product/Script/Editor/EditorPlayStarter.cs#L101-L136)を読んでもらえれば一目瞭然だと思いますので割愛

2のAwake暴発ですがこれは
- `OnValidate`が__シーンが実行状態〜Awakeが発火するまでの間に唯一発火する__特殊なイベントであること
- `OnValidate`イベントはEditor上でしか発火しないこと
の２つの特性を使って、OnValidate時にGameObjectを非アクティブにすることでAwake暴発を防いでいます

## 使ってみて
プロジェクト初期開発時は各シーンが各プロジェクトメンバーによって並列で実装されるのでかなり便利だった印象です
またゲーム画面でありがちなインゲームのリザルトシーンは挙動を逐一確認するためにインゲームパートを終わらせなければいけないところをいろんなパターンのモックデータを用意することで素早く確認サイクルが回せた点も良かったと思います
OSM日本のマッピング状況を県別に比べてみた(2018年版)


[前回(2018/8)](https://qiita.com/higa4/items/4eabe1f18cc1ce32049f)は建物数が8月段階で既に対前年比135%とハイピッチで増えていたが、今回12月段階ではどうなっただろうか。以下シリーズ4回目の統計。

## 1.[都道府県別OSMマッピング状況表_20181208](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=0)

[2016年の表](https://docs.google.com/spreadsheets/d/1DUT0pCpLjb7JtO4tcN5NeTTHclHsRrQHOOhQBso04UM/edit?usp=sharing)と[2017年の表](https://docs.google.com/spreadsheets/d/1ZAjf7utJxXDBaPE26zoKJ8Xb1cQwoVsH9sISAjCFoTg/edit#gid=0)に2018年分を追加したものが[こちら](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=0)。M列以降が今回更新分。
![都道府県別OSMマッピング状況表_20181208 - Google スプレッドシート.png](https://qiita-image-store.s3.amazonaws.com/0/35320/a9f4382f-1afd-d329-ecd7-6d0c4c8f473d.png)

## 2.[概況](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=1497821190)
建物数については2017年末時点での対前年比130%に対して、今回150%とさらに2割増。
道路距離については2016年との比較になるが対前々年比103%と微増。主要な道路はかなり描き尽くされて、その更新や細かい道路（residential以下）・歩道の登録フェーズに入っている状態といえる。
amenityは前回8月に初めてカウントしたが、総数でわずかに減少しており、実際には全体が減ることは考えにくいので絶対数を評価するには集計ツールの安定性にやや不安な印象がある。

## 3.建物数
### 3.1 [マッピング済み建物数（絶対数）](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=1326225953)
![マッピング済み建物数.png](https://qiita-image-store.s3.amazonaws.com/0/35320/ca38fa6d-68f0-a3b9-a1ef-c3395bbfcfba.png)
トップは大差で北海道。2位の静岡も100万超え。以下愛知、大阪、神奈川といったところ。

### 3.2 [建物数伸び率](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=1055704425)
![OSM建物数伸び率.png](https://qiita-image-store.s3.amazonaws.com/0/35320/dadea501-f856-6171-cb41-0b680314344a.png)
これまであまりマッピングされていなかった地域（OSMer登場！）やクライシスマッピング対象域が上位に現れる。高知、青森、岡山、愛媛、佐賀、といったところ。豪雨被害マッピングの影響がありそう。

### 3.3 [建物コンプリート率（推定）](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=17169321)
![建物コンプリート率.png](https://qiita-image-store.s3.amazonaws.com/0/35320/84a445bf-9d86-a1e8-70c8-48677a0c22ac.png)
建物数は人口との相関があることが想定されるため、人口の半分の数が建物数というアバウトな仮説を立てた場合の建物マッピング達成率。北海道、静岡、鳥取、福島が相変わらずの4強。

## 4.道路距離
### 4.1 [道路コンプリート率（推定）](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=197437285)
![道路コンプリート率.png](https://qiita-image-store.s3.amazonaws.com/0/35320/47017ba8-0bb3-5ad0-4d4e-ca7dd079de31.png)
国や自治体の管理道路の総距離に対するOSM道路距離数の比率。主要道路はほぼ描き終えて、管理道路に入っていない住宅街道路、山道、歩道といったところがどれだけ描かれているか、という目安を表すのではないか。神奈川、大阪、静岡、京都、熊本といった順。

## 5.その他
### 5.1 [amenity密度](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=2124261809)
amenity数の集計にはイマイチ安定性を欠きPOI全体としてもshopなど多くのタグが抜けてはいるが、POIマッピングの進展状況を横比較する目安にはなりそう。人口1000人あたりのamenity数を密度と表現。
![poi_mitusudo.png](https://qiita-image-store.s3.amazonaws.com/0/35320/bde010b2-22df-d768-76df-bdf0ce05d0b4.png)
<del>奈良、広島、岩手、和歌山、東京、神奈川</del>京都、山形、鳥取、高知、滋賀、山梨といった順。建物や道路での順位とはやや異なる。
（2018/12/10 順位を誤っていたため訂正）



詳細分析してみたい方は[スプレッドシート](https://docs.google.com/spreadsheets/d/1eGxDcmGXKLj-UWIJHTvvYyWo1xFRnL2KGWOAv0Y6Jjs/edit#gid=0)をコピーしてご自由にどうぞ。CC0としています。
Logstash のプロキシ設定

# はじめに
Logstashのプロキシ設定方法は公式の記事ではあるのだが、日本語の記事で上手くいった事例がないので記録のために残しておきます

Elasticsearchですと下記のように、設定するので

```
set ES_JAVA_OPTS・・・・・
```
Logstashでも、このようにやるのかなと思ったのですが全然うまくいかなかったです

```
set LS_JAVA_OPTS・・・・・
```

# 設定方法
今回は、Logstash 6.5で行いました

下記のように設定します

```
export HTTP_PROXY=http://127.0.0.1:3128

bin/logstash-plugin install logstash-output-kafka
```

HTTPSの場合は下記のように設定します

```
export HTTPS_PROXY=http://127.0.0.1:3128

bin/logstash-plugin install logstash-output-kafka
```

※ずっと「https:/・・・・」と設定していて数分悩んでました

インストールされている確認

```
bin/logstash-plugin list
```

# 参考資料
公式の「Proxy Support」の通りにやれば、上手く行きます

[Working with plugins](https://www.elastic.co/guide/en/logstash/current/working-with-plugins.html)
自分用 golang emacs 開発環境 1st Step にゃ

## prep Install golangci-lint


```
$ cd ~/go
# go mod がないと install 出来ない
$ curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b $(go env GOPATH)/bin v1.20.0
# version その時その時で
```

```sh
# wite your golangci-lint configuration
$ touch ~/go/golangci-lint.yaml
```

eg (see [.golangci.example.yml](https://github.com/golangci/golangci-lint/blob/master/.golangci.example.yml))

```yaml
# This file contains all available configuration options
# with their default values.

# options for analysis running
run:
  # default concurrency is a available CPU number
  concurrency: 2

  # timeout for analysis, e.g. 30s, 5m, default is 1m
  timeout: 1m

linters:
  enable:
    - deadcode
    - errcheck
    - gosimple
    - govet
    - ineffassign
    - staticcheck
    - structcheck
    - typecheck
    - unused
    - varcheck
    - gocyclo
    - gosimple
  disable-all: true
  presets:
    - bugs
    - unused
  fast: false
```

## install emacs packages


```
M-x package-install flycheck
M-x package-install fly-golangci-lint
```

init.el

```emacs-lisp


;;; package install で生成されたもの
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(package-selected-packages
   (quote
	(go-mode flycheck-golangci-lint flycheck)))
 '(tool-bar-mode nil))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 )


;;; 公式サイトからコピペ
(eval-after-load 'flycheck
  '(add-hook 'flycheck-mode-hook #'flycheck-golangci-lint-setup))

(setq flycheck-golangci-lint-config "~/go/golangci-lint.yaml") ;; lint の設定ファイル
(add-hook 'go-mode-hook 'flycheck-mode) ;; go-modeでflycheckを利用するように
```



## Links

* [golangci-lint](https://github.com/golangci/golangci-lint)
* [emacsで快適なGo言語ライフを送るための設定](https://qiita.com/kod314/items/2232d480411c5c2ab002)
* [flycheck-gometalinterを利用して、EmacsでGoのシンタックスチェックや型チェックを行う](https://blog.shibayu36.org/entry/2017/10/16/193000) gometalinter の頃
CSS設計について考える

# CSS設計とは
CSSを記述する際のルールです。

# CSS設計が必要な理由
CSS設計を意識せずに記述すると様々な問題が起こります。
その問題を回避し「メンテナンス性の高いCSS」を実現するためにCSS設計が必要です。

## CSS設計を意識せずにスタイルを記述すると起こる問題
- 可読性が低く、何をしたいのかわからない
- 消して良いのか、残すべきものなのかわかりずらい
- 修正したら意図しない部分までスタイルが変更されてしまう
- スタイルの上書きが多用され、!importantを使わざるを得ない

## メンテナンス性の高いCSS
メンテナンス性の高いCSS設計のゴールとして、
Googleのエンジニアであるフィリップ・ウォルトン氏のブログ記事から引用すると次の４つが挙げられます。

- **予測しやすい**
- **再利用しやすい**
- **保守しやすい**
- **拡張しやすい**

# CSS設計の手法
CSS設計の手法は様々あり、各々のCSS設計の特性およびプロジェクトの規模・実装者の人数・スキルなどを考慮し適切に選定する必要があります。
以下ではCSS設計の手法を一部ですが紹介します。
各設計の詳細に関しては別記事で記載します。

- OOCSS
- BEM
    - https://qiita.com/kwsks22/items/472233007ea37acd188b
- SMACSS
- MCSS
- ECSS
- AMCSS
- RSCSS
- ITCSS
- FLOU
- APB CSS
WordpressのGutenbergを簡単に拡張できる「create-guten-block」を使ってみる

#はじめに
Wordpress 5.0のリリースと共にエディターが[Gutenberg](https://ja.wordpress.org/plugins/gutenberg/)になるのですが、既存のエディターに対してカスタマイズを施している場合、(テキストエディターのクイックタグでスタイルをあてている等）機能を拡張していく(ブロックを開発する)必要が出てきます。

そこで、Gutenbergの機能を簡単に拡張できる[create-guten-block](https://ahmadawais.com/create-guten-block-toolkit/)を使用してよかった点やイマイチな点等をまとめてみたいと思います。



##create-guten-block実装方法
やり方は[こちらの記事](https://qiita.com/ryo511/items/d6ad78fc8c7076116f8f)が詳しいです。


##良い点
###設定が比較的不要
create-guten-blockの場合、package.jsonにcgb-scriptsというライブラリをインストールするだけで他の依存するライブラリを一手に管理してくれます。もしcreate-guten-blockと同等の環境を作る場合、以下のライブラリを入れる必要が出てきます。

```package.json
...
"dependencies": {
    "autoprefixer": "^7.2.4",
    "babel-core": "^6.25.0",
    "babel-eslint": "^8.2.1",
    "babel-loader": "^7.1.1",
    "babel-preset-cgb": "^1.6.0",
    "cgb-dev-utils": "^1.5.0",
    "chalk": "^2.3.0",
    "cross-env": "^5.0.1",
    "cross-spawn": "^5.1.0",
    "eslint": "^4.15.0",
    "eslint-config-wordpress": "^2.0.0",
    "eslint-plugin-jest": "^21.6.1",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-react": "^7.5.1",
    "eslint-plugin-wordpress": "^0.1.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "filesize": "^3.5.11",
    "fs-extra": "^5.0.0",
    "gzip-size": "^4.1.0",
    "inquirer": "^5.0.0",
    "node-sass": "^4.7.2",
    "ora": "^1.3.0",
    "postcss-loader": "^2.0.10",
    "raw-loader": "^0.5.1",
    "resolve-pkg": "^1.0.0",
    "sass-loader": "^6.0.6",
    "shelljs": "^0.8.0",
    "style-loader": "^0.19.1",
    "update-notifier": "^2.3.0",
    "webpack": "^3.1.0"
  },
...
```

これだけ記述がされていると使用しているライブラリがわからず、どのライブラリが使わなくなったのか等の把握も難しくなってくるため、cgb-scriptsでひとまとめにされている点は良かったです。

###転用がしやすい
create-guten-blockはwordpressのプラグインを作成してgutenbergのカスタマイズを行います。そのため、他サイトに作成したプラグインをコピーして同じ機能が使えるという点が良いと思いました。

##イマイチな点
###プラグインのバージョン管理
自分の場合、一つのWordpressテンプレートディレクトリ(```wp-content/themes/```)に対してgitでバージョン管理を行っていたのですが、create-guten-blockは```wp-content/plugins/```のディレクトリに生成されるため、別途gitを用意してバージョン管理をする必要がありました。
そうなると、デプロイ時にテンプレートとプラグインでそれぞれpullする必要があるため、管理が面倒でした。

##参考
Gutenberg
https://ja.wordpress.org/plugins/gutenberg/
Gutenberg機能開発ドキュメント
https://wordpress.org/gutenberg/handbook/designers-developers/developers/
create-guten-block公式
https://ahmadawais.com/create-guten-block-toolkit/
create-guten-block Github
https://github.com/ahmadawais/create-guten-block
create-guten-block実装方法
https://qiita.com/ryo511/items/d6ad78fc8c7076116f8f
エンジニア1年生とその教育役にやってほしい僕が考えるエンジニア領域別適性診断

## 背景

エンジニア1年生は、自分がアプリケーション開発者を目指すべきか、インフラエンジニアになるべきか、どれともWEBデザイナーになるべきか、そういうのに悩むと思う。

やはり自分自身の能力が一番発揮される環境で生活するのが一番だと思う。
なので、IT業界のことをあまり知らないエンジニア1年生の人は、
`なんとなく会社に勧められたから`とか`これやってる人が多いから`とかじゃなくて、
ちゃんと自分自身の適性を判断するのが良い。

適性を判断するといっても、ダラダラ見極めようとしてはいけない。
長くて1ヶ月で判断したい。
1週間でも1日でも、短ければ短いほど有利だ。

その理由は以下だ。

- 判断が早ければ、その分その適性の領域の勉強時間を得られる
- 判断に時間をかけても、適性は正しいとは限らないし、歩む人生の中で変わる（小学校の時の夢と今の夢は異なるケースが多い）

というわけで、今回の記事ではどのようにして自分に適性のある領域を診断するのか？について書いていきたい。

## 話は変わるが。。。

小学校や中学校や高校で習う科目は、
英語、国語、数学、物理、化学、生物、日本史、世界史、地理、政治経済、書道、音楽、美術、体育、保健体育、倫理、プール、家庭科
場合によってはもっとあるかもしれない。

異常に多岐にわたる。
たとえば`数学なんて、何の役に立つのだ？`と疑問に思う人もいる。
そう、それは正解だ。
実際に役に立たない人が多いのである。

ではなぜ学ぶのか？
それは自分の適性を知るために他ならない。

いま生物学者として活躍している人は、もし学生時代に生物の授業に出会わなかったら、活躍できなかった可能性が高い。
他の科目と人生の関係も同じだ。

自分の適性を知るには、まずどんな領域があるかを知る必要がある。
これをエンジニアのケースに適応させる。

## まずは幅広いエンジニア領域を知る

エンジニア1年目の人は`自分のやっている領域外のエンジニアがどんな仕事をしているか知らない`ケースが多い。
つまり、まずは幅広いエンジニア領域を知ることが必要である。

これに一番適せるなのが、超小規模な簡単なWEBサイトをリリースすることである。
そしてここで最も重要なポイントは**難易度を最小限に下げる**とこである。
エンジニア領域別適性診断の目的は、技術習得ではなく**適性を知る**ことだからである。
以下に具体的な順序を書いていきたい。

## 1. 無料のクラウド開発環境を利用して、簡単なCRUD機能をつくる

まず初めに開発環境で躓くので、無理はしない。
無料（もしくは無料期間あり）のクラウド開発環境を利用するのが良い。
[AWS Cloud9](https://aws.amazon.com/jp/cloud9/)か[CodeAnywhere](https://codeanywhere.com/)がおすすめだ。

で、CRUD機能（基本的な機能である新規作成、参照、更新、削除）を作る。
このCRUD機能を一瞬で作れるのがRuby on Railsだ。
なので使用言語はRubyでフレームワークはRuby on Railsを進める。

## 2. 完成したソースコードを少しいじってみる

ここで、HTML, CSS, Rubyのコードを少しいじる。
`ここをこのように変えたらこう変化する`という感覚を少しだけ味わうのが良い。
ここで重要なのは**いじりすぎない**ことである。
ソースコードのカスタマイズに終わりはない。

## 3. AWS EC2でリリース

そして作成したソースを本番環境にリリースする。
無料期間のある[AWS Lightsail](https://aws.amazon.com/jp/lightsail/)がおすすめだ。

## 4. 診断結果発表

ここまでやると診断結果が見えてくる。私の考える結果は下記の通りだ。

### 目に見える部分をカスタマイズするのが面白かった人

`2. 完成したソースコードを少しいじってみる`の目に見える部分をカスタマイズすること、つまりHTMLやCSSをいじるのが面白かった人は**[フロントエンジニア](https://www.internetacademy.jp/it/programming/javascript.html)**に向いている。

### 目に見えない部分をカスタマイズするのが面白かった人

`2. 完成したソースコードを少しいじってみる`の目に見えない部分をカスタマイズすること、つまりRubyをいじるのが面白く、ロジカルなことが好きな人は**[サーバサイドエンジニア](https://paraft.jp/r000016001606)**に向いている。

### 本番環境リリースが面白かった人

`3. AWS EC2でリリース`が面白かった人は**[インフラエンジニア](https://mynavi-creator.jp/blog/article/the-role-of-infrastructure-engineer)**に向いている。

### これを使うユーザのことを考えるのが面白かった人

この流れの中で製造ではなく、利用者のことを考えた人もいると思う。
例えばこんな感じ。

- もっとこうしたら使いやすくなる
- こういう内容にしたらユーザは面白くなる
- こういう問い合わせがあるはずだから、こうしよう

こういう感じの人は**企画やサービス設計や[カスタマーサクセス](https://boxil.jp/mag/a4314/)**に向いている。

## 診断における注意点

1つに当てはまる人も、2つ以上に当てはまる人もいると思う。
そして向き不向きやスキキライは環境によって変化する。
なのでこの診断は最初の歩むべき方向性として参考にしてほしい。

つまり、`この診断結果だったから、ずっとこの道に進むべきだ`と考えないでほしいという意図です。

フロントエンジニアもサーバサイドエンジニアもインフラエンジニアも企画も、さらに細分化されていきます。

なので一番伝えたいことは、どんか仕事はあるのか、広く知ることが自分自身の能力を最大限発揮するための必要条件ということです。

## 参考サイト

ありがとうございました！参考になりました！

https://www.internetacademy.jp/it/programming/javascript.html
https://mynavi-creator.jp/blog/article/the-role-of-infrastructure-engineer
https://boxil.jp/mag/a4314/
Goで簡単なWebサーバーを立てる（何の変哲もなく）

### Goは簡単にWebサーバーを立てられる
標準パッケージのnet/httpを使うと、簡単にWebサーバーを立てられます。最小構成だとこんな感じ。

``` go:webServer.go
package main

import (
        "fmt"
        "net/http"
)

/*
        HTTPのリクエストを処理するハンドラです。
        こいつをhttp.HandleFuncでPathにマッピングします。
        funcと引数の名前は決まっていませんが、引数の型は固定です
*/
func Handler(w http.ResponseWriter, r *http.Request) {
        // httpRequestに対する処理を書きます。
        fmt.Fprintf(w, "Hello World\n")
}

func main() {
        // ルートにHandlerをマッピングします。
        http.HandleFunc("/", Handler)
        // ここでWebServer起動
        err := http.ListenAndServe(":80", nil)
        fmt.Println(err)
}

```

### ちょっと汎用的に
Goは関数をreturnできるので、こんな感じでいかがでしょうか。

``` go:webSerer.go
package main

import (
        "fmt"
        "net/http"
)

// httpRequestを処理するハンドラfuncを返します。
func GetHandler(fn func(h *http.Request) (string, int)) func(w http.ResponseWriter, r *http.Request) {
        return func(w http.ResponseWriter, r *http.Request) {
                // 渡した任意の関数を実行します。
                msg, status := fn(r)

                if status == http.StatusOK {
                        fmt.Fprintf(w, msg)
                        return
                }

                // ベーシック認証した場合を想定しています。
                if status == http.StatusUnauthorized {
                        w.Header().Set("WWW-Authenticate", `Basic realm="SECRET ZONE"`)
                        fmt.Fprintf(w, msg)
                        return
                }

                http.Error(w, msg, status)
                return
        }
}

// Pathと任意の関数（戻り値：表示文字列, httpステータス）をマッピング
func Map(path string, fn func(h *http.Request) (string, int)) {
        handler := returnHandler(fn)
        http.HandleFunc(path, handler)
}

// Webサーバー起動★
func Start() error {
        err := http.ListenAndServe(":80", nil)
        return err
}

func Hello(r *http.Request) (string, int) {
        return "Hello World\n", http.StatusOK
}

func main() {
        Map("/", Hello)
        err := Start()
        fmt.Println(err)
}
```

こうすると、表示したい文字列とhttpのステータス(int)を戻り値として持った、任意の関数をPathに対してマッピングすることが出来ます。
httpのステータスとしては、パッケージの中に、http.StatusOk, http.StatusBadRequest, http.Status... というシリーズがあるので、自分で用意する必要はありません。

### 参考
公式：https://golang.org/pkg/net/http/
ステータス：https://golang.org/src/net/http/status.go

Goは公式のドキュメントが分かりやすくていいですね。
Java 浮動小数点数の誤差に立ち向かう

**この記事のコードはJava SE8で書いています。**
# 背景
double型の変数を`==`で比較していたら、静的解析ツールでそれダメだよ、バグだよ指摘を受ける。
色々気になったので、浮動小数点数の扱い方法を（今さら）ちゃんと調べてみた。
# 先に結論
特にパフォーマンス気にしないのであれば、BigDecimal使おうね。
データベースとかの設計変えれるなら、桁ずらしてintやlongで扱ってもおｋ。
# 問題
まずはこいつを見てほしい。

**コード**

```java
	double doubleValue1 = 1.0d;
	double doubleValue2 = 0.9d;
	double resultValue = doubleValue1 - doubleValue2;

	System.out.println("doubleValue1: " + doubleValue1);
	System.out.println("doubleValue2: " +  doubleValue2);
	System.out.println(resultValue == 0.1d);
	System.out.println("減算結果: " + resultValue);
```

**実行結果**

```
	doubleValue1: 1.0
	doubleValue2: 0.9
	false
	減算結果: 0.09999999999999998
```

減算結果がえらいことになっている。

コンピュータは数字を2進数で扱っている。

しかし小数には`0.9`のように、2進数で表すと循環小数になっちゃうものがある。
コンピュータでは有限桁数の数しか扱えないので、適当な値に丸められ誤差が生じる。

微妙に`0.9`じゃない値で減算しているため、上記のような結果になっちゃう。
勘定系システムにおいては1円の誤差でも訴訟にまで発展しかねないので、大問題である。
# 解決策
[BigDecimal](https://docs.oracle.com/javase/jp/8/docs/api/java/math/BigDecimal.html)を使えば解決！

**コード**

```java
	BigDecimal bigDecimalValue1 = new BigDecimal("1.0");
	BigDecimal bigDecimalValue2 = new BigDecimal("0.9");
	BigDecimal bigDecimalResultValue = bigDecimalValue1.subtract(bigDecimalValue2);

	System.out.println("bigDecimalValue1: " + bigDecimalValue1);
	System.out.println("bigDecimalValue2: " + bigDecimalValue2);
	System.out.println(bigDecimalResultValue.equals(new BigDecimal("0.1")));
	System.out.println("減算結果: " + bigDecimalResultValue);
```

**実行結果**

```
	bigDecimalValue1: 1.0
	bigDecimalValue2: 0.9
	true
	減算結果: 0.1
```

BigDecimalでは小数部分を整数部分にシフトした形式で値を保持する。
全ての整数は有限な2進数で表現できるので、BigDecimalを使えば正確に浮動小数点数の演算、比較が可能。

メソッドは[公式リファレンス参照](https://docs.oracle.com/javase/jp/8/docs/api/java/math/BigDecimal.html)。
# 速度
BigDecimalは参照型なので、基本データ型の演算に比べると当然遅い。
確認してみよう。

**コード**

```java
	double doubleValue1 = 1.0d;
	double doubleValue2 = 0.9d;

	long startDouble = System.currentTimeMillis();

	// 1億回減算実施(double)
	for(int i = 0; i < 100_000_000 ; i++){
		double resultValue = doubleValue1 - doubleValue2;
	}

	long endDouble = System.currentTimeMillis();

	BigDecimal bigDecimalValue1 = new BigDecimal("1.0");
	BigDecimal bigDecimalValue2 = new BigDecimal("0.9");

	long startBigDecimal = System.currentTimeMillis();

	// 1億回減算実施(BigDecimal)
	for(int i = 0; i < 100_000_000 ; i++){
		BigDecimal bigDecimalResultValue = bigDecimalValue1.subtract(bigDecimalValue2);
	}

	long endBigDecimal = System.currentTimeMillis();

	System.out.println("double 計測結果: " + (endDouble - startDouble) + "ms");
	System.out.println("bigDecimal 計測結果: " + (endBigDecimal - startBigDecimal) + "ms");
```

**実行結果**

```
	double 計測結果: 3ms
	bigDecimal 計測結果: 314ms
```

結構差が出た。てか基本データ型ってやっぱり速いのね！

まあループがめちゃくちゃ多かったり、よっぽどパフォーマンスを要求される場合じゃなければBigDecimalで対応しても問題ないのかなーと個人的には思ってみたり。
# 逃げれたら逃げる
別に無理やり浮動小数点数を使わなくてもいい場合ってありますよね。

例えば体重を小数第1桁まで登録するシステムがあったとします。
インタフェース的には65.3kgとかで受け取っても、プログラムの上流部分で1個シフトさせて内部的に653とかで扱えば、普通にintで処理できます。煩わしい浮動小数点数処理から解放される！

ただデータベースのカラム定義とかにも影響するので、設計段階でしっかり決めるのが吉ですね～。
Delphi/C++Builder/RAD Studio 10.3 Rio のオンラインドキュメントをブラウザでピンポイントで探すための設定を作る

これは [Delphi Advent Calendar 2018 10日目](https://qiita.com/advent-calendar/2018/delphi) 向けの記事です。そして**[第36回エンバカデロ・デベロッパーキャンプ](https://www.embarcadero.com/jp/events-japan/developer-camp/program/tokyo) のライトニングトーク向けに準備しつつも当日披露しなかったネタの一つ**です。ライトニングトークの準備物と本記事のタイトルは微妙に違いますが。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/f411ee84-8a31-73f2-f4b0-7b1b80b42dd4.png)

# 課題：docwiki には複数バージョンのドキュメントが掲載されていて、Google検索などでは特定バージョンの情報を探しづらい

通常、なにかの情報を探すときは、ブラウザのアドレスバーにキーワードを入力して探します。しかしDelphi/C++Builderに関する情報を探そうとすると、自分が探したいバージョンの情報とは違う情報が検索結果一覧に出力されてしまう場合があります。理由は単純で docwiki.embarcadero.com には複数バージョンのドキュメントが掲載されているからです。

下記のスクリーンショットは"Delphi FireDAC サンプル"というキーワードで探した例です。ここでリストアップされているページはすべて 10.2 Tokyo のページです。10.3 Rio で開発する場合は、10.3 Rio の情報だけをピックアップしたいですよね？

![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/36559f05-d8b4-4a1d-e842-b52216a4f9dd.png)

かと言って"Delphi FireDAC サンプル Rio"というキーワードで探しても、やはり 10.3 Rio だけをピックアップできません。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/18749a2f-b3ed-ddbf-888b-837b4e3b424a.png)

なので、そういうノイズを除去したい場合は http://docwiki.embarcadero.com/ にアクセスして検索窓から検索すれば、以下のような結果が手に入ります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/149350/666e1cc0-a503-3cd9-b959-40985cd3962c.png)

しかしこのような検索を行うには、次の手順を踏むことになり、案外めんどくさいです。

1. http://docwiki.embarcadero.com/RADStudio/Rio/ja/メインページ にアクセスする
2. 検索窓でキーワード入力して検索する
3. 検索結果が手に入る


要するに、こういうことをやらずに目的の情報を探すことができれば効率的ですよね？

# 解決策：ブラウザを調整して、アドレスバーから docwiki.embarcadero.com を直接検索できるようにしょう

ブラウザの設定をカスタマイズすれば、アドレスバーから docwiki.embarcadero.com を直接検索できるようになります。手順が相当にショートカットできますよ。

そこで、ここでは Chrome と Firefox での設定方法を例示します。

## Chrome の場合

### 設定内容
1. Google Chrome のアドレスバーに chrome://settings/searchEngines と入力する。
2. 「その他の検索エンジン」の項目に次の内容を設定する。

|項目名|入力内容|意味|
|---|---|---|
|検索エンジンを追加|docwiki.embarcadero.com|検索の際にアドレスバーに表示される文字列です。|
|キーワード|Rio|この検索エンジンを利用する際に最初に入力する文字列を指定します。10.3 の検索キーワードとして、ここでは Rio と登録します。|
|URL|http://docwiki.embarcadero.com/RADStudio/Rio/j/index.php?search=%s |検索実行時のURL形式です。検索文字列を%sで指定します。|

### 動作確認
1. アドレスバーに Rioと入力してタブキーを押します
2. 続けて検索したいキーワードを入力します
3. そのキーワードの検索結果や、該当ページが表示されていれば設定完了です。

![R103_Search_docwiki_from_Chrome.gif](https://qiita-image-store.s3.amazonaws.com/0/149350/919366a3-d853-d23d-731a-8b479531a39d.gif)


## Firefox の場合

### 設定内容
1. http://docwiki.embarcadero.com/RADStudio/Rio/ja/Main_Page にアクセスする
2. ページ左上の検索窓で右クリックし、「この検索にキーワードを設定」を選ぶ
3. 使用したいキーワードを "Rio" と設定して保存する

### 動作確認
1. アドレスバーで Rio と入力し、さらにスペースを入力します
2. 検索キーワードを入力します
3. そのキーワードの検索結果や、該当ページが表示されていれば設定完了です。

![R103_Search_docwiki_from_Firefox.gif.gif](https://qiita-image-store.s3.amazonaws.com/0/149350/6e3abe9e-8454-64da-41d2-d0f58924a780.gif)
【Maven】リモートリポジトリにないjarをwarに組み込んでくれと言われた場合の対処法

# 状況
Mavenセントラルリポジトリや、インハウスリポジトリにはないjarを渡されて、
「このjarを使って、warを固めてくれ！」
と命じられた場合の対処法。

# 対処法
1. `mvn install:install-file`コマンドを実行して、ローカルリポジトリ（Windowsの場合、たいていは`C:\Users\ユーザー\.m2\repository`）に登録する。
2. pom.xmlにて、1で登録したjarを参照するように設定を行う。

具体的には、

* ローカルリポジトリに登録したいjarが`C:\lib\sample.jar`
* groupIdが`jp.co.nannany`
* artifactIdが`sample`
* versionが`2.5.0`

である場合には、以下のようなコマンドをたたく。
`mvn install:install-file -Dfile=/lib/sample1.jar -DgroupId=jp.co.nannany -DartifactId=sample -Dversion=2.5.0 -Dpackaging=jar`

また、ローカルリポジトリに登録したファイルを参照するようにpom.xmlの設定を修正する。

```
<dependency>
    <groupId>jp.co.nannany</groupId>
    <artifactId>sample</artifactId>
    <version>2.5.0</version>
</dependency>
```

これらを行った後で固めたwarファイルには、該当のjarに依存するようになっている。

# 参考
http://www.ne.jp/asahi/hishidama/home/tech/apache/maven/local.html

https://maven.apache.org/plugins/maven-install-plugin/install-file-mojo.html
MATLABとPythonのコード対応（行列編）

# まえがき
MATLABでコードを書いたり読んだりするときに「Pythonでこう書いてたやつはMATLABではどう書くのだ？」といつもなるので、まとめてみました。

今回は行列関連。Python側はNumPy的な内容となります。

# コメント
```python:Python
# コメント
```

```matlab:MATLAB
% コメント
```


# 行列のインデックス
numpyではC配列などと同じくインデックスは0始まりとなるが、matlabは1始まりとなるので注意

* PythonはCと同じく0始まりで、終端のインデックスはN-1となる。
* MATLABは1始まりで、終端のインデックスはNとなる。

（N ... 要素数）

```python:Python
x = np.array([1,2,3])

# x[0] ... 1
# x[1] ... 2
# x[2] ... 3
```

```matlab:MATLAB
x = [1 2 3];

% x(1) ... 1
% x(2) ... 2
% x(3) ... 3
```

# 行列の作成

## 行列を生成する
```python:Python
x = np.array([[1, 2, 3], [4, 5, 6]])

# array([[1, 2, 3],
#        [4, 5, 6]])
```

```matlab:MATLAB
x = [1 2 3; 4 5 6]

% x =
%      1     2     3
%      4     5     6
```

## すべての要素が0の行列を作成
```python:Python
x = np.zeros((3,4))

# array([[0., 0., 0., 0.],
#        [0., 0., 0., 0.],
#        [0., 0., 0., 0.]])
```

```matlab:MATLAB
x = zeros(3,4);

% x =
%      0     0     0     0
%      0     0     0     0
%      0     0     0     0
```

## すべての要素が1の行列を作成
```python:Python
np.ones((3,4))

# array([[1., 1., 1., 1.],
#        [1., 1., 1., 1.],
#        [1., 1., 1., 1.]])
```

```matlab:MATLAB
x = ones(3,4)

% x =
%      1     1     1     1
%      1     1     1     1
%      1     1     1     1
```

# 等間隔で連続値のベクトルを作成

## 間隔を指定
**numpyでは終端の値が含まれないが、matlabでは終端の値が含まれる**
という違いがあるので注意

```python:Python
# 0〜1の間を0.1間隔で
# ※終端の1は含まれない
x = np.arange(0, 1, 0.1)

# array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
```

```matlab:MATLAB
% 0〜1の間を0.1間隔で
% ※終端の1は含まれる
x = 0:0.1:1

% x =
%          0    0.1000    0.2000    0.3000    0.4000    0.5000    0.6000    0.7000    0.8000    0.9000    1.0000

```

### 間隔の指定を省略
間隔の指定を省略すると、python, matlab双方とも間隔1として動作する

```python:Python
x = np.arange(0, 10)
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
```

```matlab:MATLAB
x = 1:10

% x =
%      1     2     3     4     5     6     7     8     9    10
```

## 何等分するかを指定
```python:Python
# 0〜１の間を11等分で
x = np.linspace(0, 1, 11)

# array([0. , 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1. ])
```
↑ linspaceだとNumpyでも終端に指定した値が含まれる模様


```matlab:MATLAB
% 0〜1の間を11等分で
x = linspace(0, 1, 11)

% x =
%          0    0.1000    0.2000    0.3000    0.4000    0.5000    0.6000    0.7000    0.8000    0.9000    1.0000
```

# 行列要素へのアクセス


## 2次元以上の行列へのアクセス
```python:Python
x = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]])

# >> x[1, 2]
# 7
```

```matlab:MATLAB
x = [1 2 3 4; 5 6 7 8; 9 10 11 12];

% x(2, 3)
% ans =
%      7

```

## 範囲で指定
* pythonは終端の要素を含まないが、matlabは含む

```python:Python
>> x = np.array([1, 2, 3, 4, 5])
>> x[2:4]
array([3, 4])
```

```matlab:MATLAB
>> x = [1 2 3 4 5];
>> x(2:4)
ans =
     2     3     4
```

## 最後の要素を指定
### python:Python
* インデックスの-1 は、最後の要素を示す。
* 最後から2番目の要素は-2,、 最後から3番目の要素は-3　。。。（以下続く）

### matlab:MATLAB
* 「end」は最後の要素のインデックスを示す。
* 最後から2番目の要素は「end-1」と記述すればよい。

```python:Python
>> x = np.array([1, 2, 3, 4, 5])
>> x[-1]
5

>> x[-2]
4
```

```matlab:MATLAB
>> x = [1 2 3 4 5];
>> x(end)
ans =
     5

>> x(end-1)
ans =
     4
```

# おわりに
随時更新していきます
プロジェクトで迷子になったときにするべき３つのこと

# はじめに
今さらですが、プロジェクトマネジメントって大変ですよね。
プロジェクトにはメンバーがいて、お客さんや、あるいはユーザがいて、自分1人ではない色々な思惑や、予算や会社の制約が絡み合いうまくいかないときは本当にうまくいきません。

うまくいかないとき、PMは、本当につらいものです。
お客さんから責められますし、メンバーからも責められますし、会社からも責められます。

プロジェクトの成否は、そもそも、そのプロジェクトが置かれている環境、条件によるところも大きいですが、そこをおいといたとしても、うまくいくプロジェクトはうまくいくし、うまくいかないプロジェクトはうまくいかないものです。
プロジェクトで問題が発生したとき、あるいはリスクが顕在化しないようにするために、マネジメントの体形的な知識は身を助けてくれましたが、うまくいくためのマネジメントの根本ってシンプルなんだと感じています。

PMやリーダしている人で、プロジェクトが迷走しているなと感じたとき、そのプロジェクトをあきらめる前に、あるいは考えすぎて気に病む前に次の3つを試してみてください。

# １．とりあえずのゴールを設定する
プロジェクトで迷子になったとき、
**おそらく、そのプロジェクトのスケジュールは形骸化しています。**
ゴールに向かって進んでいる実感はなく、
当初見据えていたゴールまでの道筋はもはや見えず、の状態でしょう。

だからといって、WBSやTRMを見直す必要はありません。それは後回しにしましょう。そんな時間はないはずです。

管理の基本は5Sです。**切羽詰まったときは、整理と整頓だけでいいです。**
まずは、整理です。整理とは捨てることです。
**1ヵ月以内の短い期間内で、作業の区切りとなる"とりあえずのゴール"を設定し、それ以外のことは捨てます。**
例えば、優先度高だけの機能の疎通確認までをとりあえずのゴールにする、それ以外は一旦無視する。あるいは、とりあえず優先度の高い画面機能を動かすところまで実装し、それ以外のことは、一旦、思考から除外してしまいましょう。

# ２．やらないといけないことをリストアップする
プロジェクトで迷子になったとき、
**おそらく、そのプロジェクトのタスク管理は形骸化しています。**
タスク管理表やバックログ、スプリントボードには、ステータス更新されていない、あるいは、担当者の割当らていないストーリーやタスクのチケットが散乱し、必要なタスクも起票されていない状況でしょう。

**切羽詰まったときは、整理と整頓です。**
次は整頓です。整頓とは、必要なものを取り出せるようにすることです。
**１．で設定した、とりあえずのゴールまでに必要なこと"だけ"をリストに書き出しましょう。**
例えば、作らないといけない設計書でもいいですし、画面でも、モジュールの一覧でもいいと思います。設定した"とりあえずのゴール"に合う粒度で書き出せばいいです。

得意のExcel（Excelじゃなくてもいいですが）に、必要なことをとにかくリストアップしましょう。"とりあえずのゴール"であれば、やらなければいけないことは、そんなに多くならないはずです。
少し、気持ちが落ち着くはずです。

# ３．共有する
プロジェクトで迷子になったとき、
**おそらく、そのプロジェクト全体の士気が低下しています。**

メンバーは、プロジェクトの成否に対して興味を失い、課題に気づいても、報告する気力もなく、ただ目の前に振られたタスクをこなすだけの存在になっているでしょう。

でも、タスク管理が形骸化し、今、自分が取り掛かっているタスクがゴールに向かっているのかどうかの実感がなければ、やる気を失うのも仕方ないです。誰でもゴールが見えなければそうなってしまいます。

本来、目的意識を共有できれていれば、自然と誰かから課題の報告があがり、自発的にその解決策を考えたくなるものです。

なので、メンバー全員を集め、まずは、プロジェクトが迷走している現状を説明し、次に、状況を打開するための、
**１．で決めたとりあえずのゴール**と、
**２．で決めた、とりあえずやらないといけないこと**を共有しましょう。
そして、その場で、メンバーと話し合いながら、やらないといけないこと1ずつ、**担当と期日**を決めましょう。

やることと、期日が決まれば、プロジェクトは回り始めます。
**その日から毎日、ショートミーティングをします。**デイリースクラムでも、朝会、夕会でもなんでもいいです。
とりあえずとはいえ、ゴールに向かって進んでいる実感は、メンバーの士気を上げてくれます。

# さいごに
進捗遅れは、システム発注者の不安を募らせ、様々な注文、状況報告の要求が追加されていき、管理工数ばかりが増大し、報告のためだけのタスクに手を取られてしまう、なんてこともよくある話ですが、１～３までを実行し、プロジェクトが少しでも動きはじめると、そんな中でも心にゆとりができます。
おそらく、後手ばかりだった状況から、先手を考える余裕ができてくるはずです。

そうしたら、WBSやマスタスケジュールの立て直しに取り掛かりましょう。
とりあえずのゴールが達成されれば、その成功体験はさらにメンバーの士気を上げ、生産性も上がるはずです。
状況はさらに良くなるはずです。
<br>
・・・と書きつつも、私もうまくいかないこと多いです。でも、最終最後、どんなにうまくいかなくても、殺されることはないと開き直っています。
あと、プロジェクトには必ず期限があるので、時間がたてば必ず終わります。サグラダファミリアだって完成しましたし。

プロジェクトマネジメントには自分1人ではできないことを、みんなで達成する醍醐味があります。
PMやリーダを怖がらず、嫌いにならず、
チャンスがあればチャレンジしてみてください。