OmniAICreator/Qiita-1.07M huggingface dataset:
Excel方眼紙のどこがまずいのか、アクセシビリティの観点から考えてみる

# 前置き

この記事は、[ドキュメンテーションと情報共有 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/documentation)と、[Webじゃないアクセシビリティ Advent Calendar 2018](https://adventar.org/calendars/3036)の、12/16分の投稿になります。

# はじめに

Excel方眼紙は、IT業界の様々なところで使われていますが、アクセシビリティという観点から見ると、もしかするとExcel方眼紙はよくないのではないかと思っています。

なお、私は一応晴眼者[^1]ですが、発達障がい当事者[^2]です。晴眼者でスクリーンリーダーを使っていないため、この文章は推測が主になりますがご容赦ください。

# Excel方眼紙とは？

お分かりの方、そして日々Excel方眼紙に泣かされている方も多いでしょうが、要は、スプレッドシートのセルの縦横の長さを均一にして、そこに文字や表などを配置していくドキュメント形式の一つです。
Excelのセルという縦横の制約が、Wordより使いやすいという側面があったりします。
ひどいと、セル1つに1文字という「ネ申Excel」も存在しており、[公務員が公開している「ネ申Excel」がビッグデータの時代において日本の生産性を下げていると主張する大学教授](https://togetter.com/li/469017)がいたり、とうとう[Excel方眼紙の問題が政治家にまで波及](https://togetter.com/li/1040541)したり、[Excel方眼紙についての議論を行う討論会](https://gihyo.jp/news/report/2017/10/0201)が開かれたりしています。

# Excel方眼紙のどこがいけないの？

前の紹介のところで上げた問題点は、上原哲太郎氏が、[「公務員が公開するネ申Excelが日本の生産性を落としている話」というTogetterまとめ](https://togetter.com/li/469017)で述べている以下の言葉から考える必要がありそうです。

> ## 別に公務員に限った話ではない
多分日本中のあちこちでExcelをただのワープロ、ただのPDF生産ツールとして使っているためにせっかく入力されたデータを再利用しようとしても手で加工する必要が生じたり、単に帳票作成ツールとして使っていて集計が手作業で行われていたりということが起きているのだろうと思います。これが事務の文化の問題だと思います。
**Excelはデータ処理と流通のためのツール** です。罫線などの機能はその集計結果を美しく見せるためにあるだけです。見かけにこだわるのではなくて、データの再利用性と業務の効率化にこだわれるようにシートがデザインできるように教育していかないと、生産性はいつまでたっても上がりません。

（強調は筆者による）

と、言いたいことをはっきり述べています。
問題なのは、これが2013年にまとめられたまとめだということです。

## アクセシビリティの観点から見ると？

前にも引用したとおり、Excelのデータは本来行と列でデータを表す「表」というデータ形式です。
視覚障がい者はスクリーンリーダーという、コンピューター内の表示を読み上げる支援機能を使います。
表というデータ形式は**スクリーンリーダーでも扱えるようになっていて、支援してくれる**ので、Excelのファイルは表というデータであると解釈して支援機能が動いてしまいます。
そうなると、視覚的に文書であるという「日本のアダルトマン将軍[^3]の共通認識」に従って書かれたExcel方眼紙は、**変な形の表データ**と認識されるでしょう。
そうなってしまうと、視覚障がい者や学習障がいをもつ発達障がい者で音声読み上げに頼っている人は、ドキュメントを書いた人の意図する形で理解できないことになってしまうのです。

## ビッグデータ活用の観点から見ると

「変な形の表データ」を理解できないのは、コンピューターも同じです。
スクレイピングしないとデータを理解・再利用できない表になってしまうと、ビッグデータ活用にも影響が出ると思われます。
分析する前に手作業でデータを解析するというのは、生産性を落としてしまうことに繋がってしまうのではないでしょうか。

# あ、これどこかで見た構図だな……

よくよく考えてみると、CSSが普及する前のテーブルレイアウトの問題と似た構図だと思うのです。
テーブルレイアウトは、比較的自由にデータを配置できるという点でよく使われました。
アクセシビリティの観点から表というデータ形式を転用するのはよくないという声は上がっていましたが、なかなか手を付けられませんでした。
そんな中、Googleなどのクローリングしてデータを収集する検索エンジンが登場すると、テーブルレイアウトを解析することは非常に大変であり、SEO対策が重要になってくると経済的要請からテーブルレイアウトは姿を消しました。
Excel方眼紙も、テーブルレイアウトの一種であると思っています。

# なぜ無くならないのか

それでも、Excel方眼紙をなくせない理由として、以下の2つがあると思っています。

1. Wordは欧文ワープロとして作られており、日本語文書を扱うのに使いづらかった
2. 追加のソフトウェアを入れさせてもらえない

とりわけ、2.の追加のソフトウェアを入れられないという問題は大きいと思っています。
それが、結果的にExcelをスイスのアーミーナイフのような何でも使える道具にしちゃっているところはあるかと。

# 結び

アクセシビリティとデータ再利用性の観点から、Excelを「データ処理と流通のためのツール」として使ってくれる人が増えることを祈っています。


[^1]: 普通に目が見える人のことを指します。
[^2]: 私は知能・言語能力の高い自閉スペクトラム障害と注意欠陥多動性障害の当事者です。
[^3]: 「日本のアダルトマン将軍」とは、いわゆる「ネトウヨ」が使う「普通の日本人成人男性」の誤訳ですが、ここでは「**普通の**日本人成人男性」、その中でも健常者を指す言葉として使っています。
LLH座標をENU座標に変換する

# 目的
***LLH***（緯度Lat(deg),経度Lon(deg),高さ Height(m))座標から
***ENU***（東East(m),北North(m),上Up(m):基準点からの相対距離)座標への変換。

# 結論
***Pymap3d***を使う。

参考
緯度経度、ECEF系、方位角・仰角などの座標変換に便利なプログラムPyMap3d
https://qiita.com/ina111/items/6e3c4d85036fd993d23c
pymap3d.enu module
https://scivision.github.io/pymap3d/enu.html

```
pip3 install pymap3d
```
numpyがうまくインポートできなかったときは一度アンイストールしてからapt-get で

```
pip3 uninstall numpy
sudo apt-get install python3-numpy
```



```python:llh2enu.py
import pymap3d as pm
base = [base_lat ,base_lon ,base_h] #deg,deg,m
rover =[rover_lat ,rover_lon ,rover_h ] #deg,deg,m
rover_enu = pm.enu.geodetic2enu(rover[0] ,rover[1] ,rover[2],base[0] ,base[1] ,base[2])#m,m,m
```
# 何がしたいのか？
話は以上ですが何に使いたかったのかと言うと

1.[llh座標をもとに圃場図をポリゴンSHPで作る。](https://qiita.com/m_take/items/bfa40e3bf2ed822f6de2)
↓
2.圃場図を見ながら基準線ABを引きA(lat,lon),B(lat,lon)のポイント座標を得る
↓
3.A(lat,lon),B(lat,lon)をポリゴンの属性レコードに追加
↓
4.[現場でポリゴン属性を呼び出す。](https://qiita.com/m_take/items/69880c44204f77f510af)
↓
5.その時点のroverのh高さを与える（田面は水平と仮定）hは楕円体高　つまりbase Height + rover Up
↓
6.***A(lat,lon,h),B(lat,lon,h)をA(e,n,u),B(e,n,u)に変換***←ここ
↓
7.基準線ABが決まり即[基準線に平行な線をガイダンスできる](https://qiita.com/m_take/items/da9119a9dc9660f96227)
CircleCIのバッヂをデフォルトで格好良くしたい！ - shield-style

## やりたいこと

CircleCIのデフォルトバッジが以下のような感じです。
<img width="128" alt="Screen Shot 2018-12-14 at 8.33.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/84451/61d47687-db81-41e3-a0ce-46c49a3b7b3b.png">


そこで、これをよく見かける以下shied-styleにする拡張機能を作りました。

<img width="195" alt="Screen Shot 2018-12-14 at 8.32.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/84451/95d85a77-0df8-322b-c2f1-b300110000ea.png">

（バッジを提供する多くのサービスがshield-styleなので、やっぱり整えたいですよね）

## 拡張機能

こんな感じに動きます

![circleci-shield-badge.gif](https://qiita-image-store.s3.amazonaws.com/0/84451/7f4f8cef-91d5-16f4-6e31-e3d2ffb2f56d.gif)

Chrome ウェブストア: <https://chrome.google.com/webstore/detail/circleci-shield-badge/mmfaohhdjcipkfogaanhaaoplbmkaefa>

GitHub: <https://github.com/nwtgck/circleci-shield-badge-chrome-extension>

仕組みはとても単純で、shield-styleのバッジもオプションでCirleCI側が提供してくれてます。
バッジのsvgのURLに`?style=shield`をつければいいだけです。
具体例：`https://circleci.com/gh/nwtgck/piping-server.svg?style=shield`
flutterを１からインストール


Flutterをインストールしてみました。インストールチェック機能が付いていたため簡単に終わりました。

丁度、FlutterアプリをWebアプリにできる「Hummingbird」が発表されたので、
この機能を試して終わりにしようとしていましたが、まだソースが公開されていませんでしたので、デモアプリの確認までしました。。

#環境
Windows10,androidエミュレータ,Flutter v1.0.0

flutter ダウンロード、インストール
https://flutter.io/docs/get-started/install
![2018-12-12 22_16_28-Window.png](https://qiita-image-store.s3.amazonaws.com/0/104300/8e8c861e-1791-a786-9b2a-30680cbe94e4.png)

#fluter doctor
解答して、flutter_console.batを開き、おもむろに```flutter dockter```で確認します。

```
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, v1.0.0, on Microsoft Windows [Version 10.0.17134.407], locale ja-JP)
[X] Android toolchain - develop for Android devices
    X Unable to locate Android SDK.
      Install Android Studio from: https://developer.android.com/studio/index.html
      On first launch it will assist you in installing the Android SDK components.
      (or visit https://flutter.io/setup/#android-setup for detailed instructions).
      If Android SDK has been installed to a custom location, set $ANDROID_HOME to that location.
      You may also want to add it to your PATH environment variable.

[!] Android Studio (not installed)
[!] VS Code, 64-bit edition (version 1.29.1)
[!] Connected device
    ! No devices available
```
#IDEとEditorをインストール
Android StudioとVisualStudio Codeが入っていないよ。と警告がでたのでインストールします。

VScodeはプラグインからflutterを検索してインストールします。
https://code.visualstudio.com/

# Android Studioのインストール
https://developer.android.com/studio/

ライセンスに同意が必要とでたので、以下を実行して、yesします。
```
flutter doctor --android-licenses
```

```flutter doctor```で再度確認します。
![2018-12-14 07_38_14-Window.png](https://qiita-image-store.s3.amazonaws.com/0/104300/42060017-5e4c-3860-ec15-c00b6efc6519.png)

#flutter plugin
flutter pluginが入っていないよ。と警告がでたのでインストールします。
Android Studioを起動して、設定のプラグインのBrowse repositoriesを選択してから、flutterを探します。

![2018-12-12 22_43_35-Window.png](https://qiita-image-store.s3.amazonaws.com/0/104300/bfaf1900-26fa-1e3a-cafb-68c105977fda.png)

#完了
この段階で、```fluter doctor```が全てグリーンになりました。

あとは、flutter projectを作成して、エミュレーターを立ち上げれば、デモアプリが起動します。
Android studioがあるので、VScodeはいらなかったかもしれません。

```flutter doctor```が強力すぎて、あまりにも簡単に終わってしまいました。
今後は、flutterでnoGUI環境で作ってみてできるか試してみたいです。
Amazon Sumerianのスクリプトをバージョン管理する

Amazon Sumerianのスクリプト(できればシーン全体)をバージョン管理したいと思ってSumerianのSlackで情報を探していたらあったので情報をメモしておく。

[参考にしたスレッド](https://amazonsumerian.slack.com/archives/C8AR6KC00/p1536674258000100)

# 公式のバージョン管理の方法

スレッドからの引用

```
There isn't currently a method to do version control, but stay tuned as it's an issue we're looking into solutions for. 
```

現状では公式のバージョン管理の方法はなさそうだがそのうち実装されそう。

# 暫定のバージョン管理の方法

スレッドからの引用

```
Hi, One of my colleagues found a way to export a scene using Ctrl + e.  This lets you generate a zip file.  I’ve managed to import that into another account (at the moment it’s another IAM user on same account) but needs a few tweaks to get it working.  To import, create a new scene and go to Import Assets and drop your exported zip file into the section top right.  This imports all your assets, but seems to lose the structure in the asset panel, but everything seems to be there.  You’ll need to enter your Cognito Pool Id as not copied over and also get rid of one of the default cameras as you can’t delete the original Default camera before importing.  Make sure if you have multiple cameras, that you set the correct one as default.  Other than that, the scene worked as expected.  Hope that helps
```

Ctrl + e で以下のようなダイアログが表示されシーンの構成をzipでダウンロードできる。

![sumerianexport.PNG](https://qiita-image-store.s3.amazonaws.com/0/16768/43ec9a5b-b000-5101-5ad2-6aef41c7db65.png)

試したみた感じバンドルでzipをダウンロードして新規作成したシーンにドラドラするとエンティティやアセットが復元された。
ただし、現状のエンティティやアセットに追加される感じなので前のカメラエンティティを消すなどの対応が必要そう。
設定ファイルやWebページのエクスポートについてはよくわからなかった。

ひとまずはこのzipファイルを保持しておけばシーンの復元はできそう。
もしくは、https://docs.aws.amazon.com/ja_jp/sumerian/latest/userguide/scene-snapshots.html のスナップショット機能を使うか。
JavaScript Array.map()/every()/some()

##動作確認環境
* Windows8.1
* Node.js 10.14.1

##Array.map() 
`map()`は、配列に対して使うことができるメソッド。
各要素に対してcallback関数を実行することができる。
また、結果を新しい配列として返す。このとき、もともとの配列には変更を加えない。

```js
var array = [1, 2, 3, 4];

var newArray = array.map(function(value){
  return value + 5;
});

console.log(newArray);    // [ 6, 7, 8, 9 ]
console.log(array);       // [ 1, 2, 3, 4 ]
```

###callback関数の引数
callback関数は3つの引数をとることができる。

```js
/**
value: 現在処理中の要素
index: 現在処理中の要素の配列内でのindex番号(省略可)
array: 現在このmapメソッドを実行中の配列(省略可)
**/
array.map(function(value, index, array){ });
```
以下、サンプル。

```js
var array = [1, 2, 3, 4];

var newArray = array.map(function(value, index, array){
  //一番最初の要素は変更を加えない
  if(index == 0){
    return value;
  }
  // 元の配列にも変更を加える
  array[index] = value * 2;
  return value  * 2;
});

console.log(newArray);    // [ 1, 4, 6, 8 ]
console.log(array);       // [ 1, 4, 6, 8 ]
```

##Array.every() 
配列に対して使うことができるメソッド。
配列の各要素に対してテストを行うcallback関数を実行でき、**すべての要素で**trueが返った場合に、every()の返り値がtrueとなる。
また、callback関数はmap()と同様のものを持つ。


```js
var array = [100, 50, 49, 39];

var result = array.every(function(value){
  return value < 100;
});

console.log(result);    // false
```

##Array.some() 
配列に対して使うことができるメソッド。
配列の各要素に対してテストを行うcallback関数を実行でき、**少なくとも一つの要素で**trueが返った場合に、some()の返り値がtrueとなる。
また、callback関数はmap()と同様のものを持つ。

```js
var array = [100, 50, 49, 39];

var result = array.some(function(value){
  return value < 100;
});

console.log(result);    // true
```
Python Django 環境セットアップ　3. Cloud Server (Azure IaaS編)


#はじめに
この記事では、Python Djangoのセットアップを書いてます




#手順メモ（サーバーIaaS編）

###クラウド環境を作る（アカウントを作る） *PaaSですでにアカウントを作っている人はこの手順をスキップ
以下の手順で作ると、無料で１２ヶ月使えます。（2018年12月時点）


- マイクロソフトアカウントがなければ、作成する
    - https://support.microsoft.com/ja-jp/help/4026324/microsoft-account-how-to-create
    - これを作っておくと後述のサービスが基本無料で使えます。他にもOfficeなどいろいろ無料特典があります
        - 無料のOffice環境(Optional)　https://office.live.com
- Visual Studio Subscriptionを作成する (Optional)
    - https://visualstudio.microsoft.com/ja/dev-essentials/
    - Azureだけ使う場合は不要だが、Azure以外にもいろいろ使えるのであとで便利
        - Azure 無料アカウント (1 年間の無料サービスを含む、最初の月は $200)
        - ユーザー 5 人まで使える、クラウド開発サービス 「Azure DevOps」の アカウント
            - タスク管理、リポジトリ、Pipeline、Build管理 などが作れます
        - Visual Studio App Center
            - モバイルアプリ向けのCI/CD環境、
- Azure を作る(Main)
    - https://azure.microsoft.com/ja-jp/free/
    - <font color = red>[注意]</font><b>クレジットカード入力が必要だが初期は課金が有効化されてない</b>
        - 本人確認のためにクレジットカードや電話番号が必要 （たくさん作れないように）
        - Azureはデフォルトではクレジットカードに課金されません（無料枠がなくなったらシステム停止）
        - Microsoft アカウントの設定画面から課金を有効にすることができる　
        - 設定サイト　https://account.microsoft.com/
        - 参考サイト　https://www.buildinsider.net/pr/microsoft/azure/dictionary02　


###無料の仮想マシンを作る
以下のサイトから、無料の仮想マシンが作れます
https://azuremarketplace.microsoft.com/en-us/marketplace/apps/microsoft.freeaccountvirtualmachine?tab=Overview
Azure free account users get up to 1500 free virtual machine hours each month.
Azure free account includes:

- 750 hours of B1 Standard Linux virtual machine
- 750 hours of B1 Standard Windows virtual machine
- 2 P6 (64GiB) managed disks

In order to create a free virtual machine with managed disk, you have to choose the correct parameters such as image, vm size and disk size. This offer helps you select these parameters. Virtual machines created through this offer are free only for users with free account benefits.



![image.png](https://qiita-image-store.s3.amazonaws.com/0/60530/c5e283c9-1443-9588-f284-8360f2d131db.png)

各項目を入れて、作成。HTTP/HTTPS/SSHを有効化

![image.png](https://qiita-image-store.s3.amazonaws.com/0/60530/be28483a-199c-6469-34c2-d291d5bc7a95.png)



しばらくすると仮想マシンが完成します。あとはSSHでログインして、Pythonをセットアップするだけ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/60530/ea8c10a4-400f-d55e-aefe-b95aac6c261c.png)


仮想マシンの概要タブから、SSHの接続情報が見れます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/60530/a06b2ea5-1c3c-d1d6-996e-9fbf9dd5a923.png)


UbuntuのPythonのバージョンが古いので注意

```
$ python3 --version
Python 3.5.2
$ python2 --version
Python 2.7.12
daisuke@FreeVM:~$ 
```


#関連記事
Python Django 環境セットアップ　1. Local PC
https://qiita.com/dms/items/61fade6b73fdc058703c

Python Django 環境セットアップ　2. Cloud Server (Azure PaaS編)
https://qiita.com/dms/items/042b2cebeb3b21f7121c

Python Django 環境セットアップ　3. Cloud Server (Azure IaaS編)
https://qiita.com/dms/items/6ff9ee4e7158810ee485
Scala(sbt)で統合テスト(機能テスト)を並行実行する方法のアイデア

# やりたいこと

外部ミドルウェア(ex: MySQL)に依存するような、いわゆるIntegration Testを並行実行したい。

# 問題

[sbtからすべてのテストを実行すると失敗する件 \- Yamashiro0217の日記](http://d.hatena.ne.jp/Yamashiro0217/20120522/1337691967)などで典型的な通り、外部ミドルウェアは基本的に同時に複数のテスト実行で共有できない。
そこで、並列に実行されるスレッドの数だけ外部ミドルウェアを立ち上げて、それぞれ同時に同じ外部ミドルウェアを2スレッド以上で使わないよう注意する必要がある。
ここで問題となるのが、テスト内部へ自分の実行が並列実行のX個中I個目である、ということを取得する方法がないことで、[sbtのコードを見る限り](https://github.com/sbt/sbt/blob/8af7a5acaef783b69d0f4c88d348ac3d90c753ad/testing/agent/src/main/java/sbt/ForkMain.java#L296-L315)テスト実行の並列化は`java.util.concurrent.Executor`へ完全に移譲されているためそれを取得する方法はおそらくない。
[並列でクラウドで実行するインフラのおかげで、以前のように遅いわけではない](http://d.hatena.ne.jp/yach/touch/20140424)としても、並列に実行した外部ミドルウェアを使って適切にテストを実行できないとしたら結局Integration Testは並列実行できない。

# 解決方法(のアイデア)

[java.util.concurrent.Executor](https://github.com/sbt/sbt/blob/8af7a5acaef783b69d0f4c88d348ac3d90c753ad/testing/agent/src/main/java/sbt/ForkMain.java#L213)を使う実装が変わらなければ、テストを実行するスレッドは`sbt test`実行開始時から終了時まで常に一定のはず。
テストは並列に行われるがobjectはすべてのスレッドで共有されることを利用して以下のようなコードを使う。

## コード

```scala
import org.scalatest._

import scala.collection.mutable.ArrayBuffer

class ThreadIndex {

  /**
   * Undeletable, mutable, does not contains duplicate thread numbers.
   */
  private[this] val indexedThreadNumbers: ArrayBuffer[Long] = ArrayBuffer.empty[Long]
  private[this] def invariantRule: Boolean = synchronized {
    indexedThreadNumbers.size == indexedThreadNumbers.toSet.size
  }

  def getThreadIndex: Long = {
    require(invariantRule)
    synchronized {
      val threadId = Thread.currentThread().getId
      val index = indexedThreadNumbers.indexOf(threadId)
      if (index == -1) {
        indexedThreadNumbers.append(threadId)
        indexedThreadNumbers.size - 1
      } else
        index
    }
  }.ensuring(invariantRule)
}

object GlobalThreadIndex extends ThreadIndex

class FirstSpec extends FunSpec with Matchers {

  it("最初のクラスのテスト1") {
    println(s"MySQLサーバ${GlobalThreadIndex.getThreadIndex}を使用開始")
    Thread.sleep(5 * 1000L)
    println(s"MySQLサーバ${GlobalThreadIndex.getThreadIndex}を使用終了")
  }

  it("最初のクラスのテスト2") {
    println(s"MySQLサーバ${GlobalThreadIndex.getThreadIndex}を使用開始")
    Thread.sleep(5 * 1000L)
    println(s"MySQLサーバ${GlobalThreadIndex.getThreadIndex}を使用終了")
  }

}

class SecondSpec extends FunSpec with Matchers {

  it("2つ目のクラスのテスト") {
    println(s"MySQLサーバ${GlobalThreadIndex.getThreadIndex}を使用開始")
    Thread.sleep(10 * 1000L)
    println(s"MySQLサーバ${GlobalThreadIndex.getThreadIndex}を使用終了")
  }
}
```

```
[info] SecondSpec:
MySQLサーバ0を使用開始
MySQLサーバ1を使用開始
MySQLサーバ1を使用終了
[info] FirstSpec:
[info] - 最初のクラスのテスト1
MySQLサーバ1を使用開始
MySQLサーバ0を使用終了
[info] - 2つ目のクラスのテスト
MySQLサーバ1を使用終了
[info] - 最初のクラスのテスト2
```

# 注意

1. 以下のコードは理論上これでうまく行くはずというレベルで最低限のテストしかしていません(プロダクトコードで同様のことをしてうまく行ったらこの注意書きは削除する予定です)。
2. sbt設定でforkを有効にした場合、各テストケースレベルで並列実行を有効にした場合などのテストはしていません。またテスト内でthreadをspawnした場合も同様です。ただ、非常にシンプルな機構なので自分がどのようにテストを並列実行をしているか理解しつつ使えば大丈夫なはずです。

# ロックのリストでは駄目なの？

ロックを使うと毎回開放しないと行けないのが手間です。このThreadIndex形式なら一意に自分の利用できる外部ミドルウェアのIndexがわかるのが利点です。
とはいえこの手法はテストの並行実行中に使われるスレッドが変わらないことが前提であり、ExecutorContextの実装に強く依存します。その手法のほうがより確実でよいかも。
Gitで過去コミットを含めたすべてのファイルのmd5sumを一覧にする

リリースされている物件のファイルだけをもらったけれど、それがいつ時点の物かがわからなかったので、gitで照会しようとしたときに使った。

```bash
#!/bin/bash
tgt=hash_list.txt

git rev-list --all | while read hash
do
        git checkout $hash
        find . -type f | grep -v \\.git | xargs md5sum | sed "s/^/$hash  /g" >> $tgt
done
```

1カラム目がコミットオブジェクトのハッシュ、2カラム目がファイルパス、3カラム目がファイルのmd5sumになっている。
愚直に1コミットずつcheckoutしてmd5sumをとっているので結構時間がかかるのが難点。
Vue.jsでコンポーネントのイベント名をキャメルケースにすると反応しない

地味にハマったのでメモ。


## 再現

htmlファイルのみで再現できます。
適当に保存して、ブラウザで開くと動作します。

ソースはGitGistにもアップしています。
https://gist.github.com/kai-kou/9b5b613918e107ca23682982c75d9467

```html:index.html
<html>
  <body>
    <div id="app">
      <custom-component
        :msg='msg'
        v-on:hello-hoge="msg = 'OK!!!'"
        v-on:helloHoge="msg = 'OK???'"
      />
    </div>

    <script type="text/x-template" id="custom-component">
      <div>
        <span>{{msg}}</span>
        <button v-on:click="$emit('hello-hoge')">これはOK！</button>
        <button v-on:click="$emit('helloHoge')">これはだめ！</button>
      </div>
    </script>

    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script>
      Vue.component("customComponent", {
        props: ["msg"],
        template: "#custom-component",
      })
    </script>

    <script>
      new Vue({
        el: "#app",
        data: {
          msg: 'hoge'
        },
      })
    </script>
  </body>
</html>
```

```helloHoge``` のボタンをクリックするとコンソールログに警告が出力されます。
開発環境ではこれが出力されず、少々ハマりました。。。


> vue.js:603 [Vue tip]: Event "hellohoge" is emitted in component <CustomComponent> but the handler is registered for "helloHoge". Note that HTML attributes are case-insensitive and you cannot use v-on to listen to camelCase events when using in-DOM templates. You should probably use "hello-hoge" instead of "helloHoge".

Google翻訳
>vue.js：603 [Vue tip]：イベント "hellohoge"がコンポーネント<CustomComponent>で生成されましたが、ハンドラーが "helloHoge"に登録されました。 HTML属性は大文字と小文字を区別しないため、DOM内のテンプレートを使用する場合はv-onを使用してcamelCaseイベントをリスンすることはできません。 おそらく、 "helloHoge"ではなく "hello-hoge"を使用するべきです。


## まとめ

複数言語で開発していると、もうどれでどう実装したら良いのかわからなくなってきます。


## 参考

camelCased custom event name is not working · Issue #4044 · vuejs/vue
https://github.com/vuejs/vue/issues/4044


VueのCDN版を使おう - やわらかVue.js
https://scrapbox.io/vue-yawaraka/Vue%E3%81%AECDN%E7%89%88%E3%82%92%E4%BD%BF%E3%81%8A%E3%81%86

コンポーネントの基本 — Vue.js
https://jp.vuejs.org/v2/guide/components.html

Vue.js の単一ファイルコンポーネント化をHTMLファイルで行う方法 | WriteIfElse
https://blog.bulkus.net/post/vue-htmlfile-components/
WireMockって何？ってところからFT書くまでの話 

今年の2月に転職してエンジニアになってからはや10ヶ月、去年の今頃はプログラムとなんの関係もない仕事をしていたわけでこの一年色々あったなあと振り返っています。インデントもわからなかったところから、今では中々に大きなプロジェクトに関わらせてもらうことができて存外の喜びを感じています。

って感じで今年のまとめ的な硬い感じなのはここまでしておきましょうー。第一回からしばらくご無沙汰だった記事の内容に入りたいと思います！

JavaのAPI開発をしていた僕がFT書いていた時のこと、こんなことをチームリーダーの人からお願いされました。

『WireMock使ってFT書いてくれる？』

Mockはわかるけどワイヤー？針金？

って感じに最初はなりました。WireMockでぐぐりまくること数分。APIの応答をモック化してくれるモックサーバーであることを知る僕。

Java以外でもよくあることだと思うのですが、APIを開発しているとその処理の途中で他のAPIを呼び出して応答を受け取る必要が出てくることがよくあります。例えば他社のAPIが持っている機能が必要なときなんかですね。

既存のシステムを借りることができて手間が減るのは良いことなのですが、開発する上で困ったことがあったりします。その呼び出したいAPIがまだデプロイされていないとFTなどのテストがそのままでは書けないということですね。

そこでこいつの出番です。呼び出したいAPIの応答をモック化してFTを通すことができます。

![スクリーンショット 2018-12-14 7.07.26.png](https://qiita-image-store.s3.amazonaws.com/0/245035/833c2dd6-acf3-9549-4f80-11a85d97b6fc.png)


方法ですがまずbuild.gradleに設定を入れます。（Spring、JUnit5前提でお願いします）

```
dependencies {
    testCompile("com.github.tomakehurst:wiremock:2.14.0")
}
```
（バーションは新しいものがあるかもしれません）

そして呼び出したいAPIの応答（モック値）をJSONで記述します。
test.json

```
"request": {
        "url": "/test/getTest",
        "method": "GET"
    },
    "response": {
        "status": 200,
        "body": "Test",
        "headers": {
            "Content-Type": "application/json"
        }
    }
```

resourcesフォルダ配下にstubsというフォルダを作成してtest.json
を配置します。

あとはFTのテストクラスに以下のアノテーション付与すればOKです。

```
@AutoConfigureWireMock(port = 9000, stub = "classpath:/stubs")
```

あとはApplication.ymlにlocalhostなどの設定があれば動くはずです。
WireMockを使うと意図的にアクセス時間を遅らせてタイムアウト想定のテストが書けたりとテストで便利なのと、JSONでモック値をそのままかけることが利点なようです。

使い始めたばかりでまだ自信ないのでおかしいところなどありましたらご指摘いただけると嬉しいです！
それではまた次の記事でお会いしましょう！
MySQL環境構築

# DockerでMySQL
docker-composeに挫折した。。。のでdocker runコマンドで。

## MySQL5.7のインストールと起動
**Docker Hub - MySQL**
[https://hub.docker.com/_/mysql/](https://hub.docker.com/_/mysql/)

```docker
docker run --name mysql57 -v /Users/hoge/etc/mysql57:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=rootpass -e MYSQL_USER=userpass -e MYSQL_PASSWORD=pass -p 3306:3306 -d mysql:5.7
```
ローカルの/Users/hoge/etc/mysql57ディレクトリの中にmy.cnfを入れておけば、読み込んでくれます。
MYSQL_ROOT_PASSWORDはrootのパスワード、--nameは任意の名前です。次回からこの名前で起動できます。
最初、「-p 3306:3306」の部分を省略していたのですが、省略すると全然MySQLにアクセスできず。。。必須？
下記コマンドでアクセスできます。「--protocol tcp」の指定がないと「ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)」のエラーが出てアクセスできませんでした。

```shell
mysql -u root -p --protocol tcp
```

## phpMyAdmin
インストールしたMySQLにつなげるphpMyAdminです。起動するとhttp://localhost:8080 でアクセスできます。

```docker
docker run --name myadmin57 -d --link mysql57:db -p 8080:80 phpmyadmin/phpmyadmin
```

## mroonga
こちらは環境変数とか関係ないようです。rootはパスワードなしで入れます。

```docker
docker run --name mroonga809 -v /Users/hoge/etc/mroonga809:/etc/mysql/conf.d -p 3306:3306 -d groonga/mroonga:mysql5724_mroonga809
```
PowerShellの便利なコマンド

### ファイル名の数字を加算（減算）してリネームする

「#"数字(3桁)"」で始まるファイル名を対象に、数字（3桁）に「13」を加算して「#"数字（3桁）"-XXX」にリネームする。

```powershell
$list = ls *.png | % {
    @{
        name = $_.Name;
        num = [Convert]::ToInt32(($_.Name -replace '#([0-9]{1,3}).*.png', '$1')) + 13
    }
}
$list | % { ren $_.name ("#{0:000}-XXX.png" -f $_.num) }
```
### ファイル名を一括してリネームする
拡張子が「.txt」のファイルを「.log」に変更する。

```powershell
ls *.txt | Rename-Item -newName {$_.Name -replace "\.txt`$",".log"}

ls  "TC*" | ren -NewName {$_.name -replace "TC","#"}
```

### ファイルを一括コピーする
拡張子が「.png」のファイルをカレントディレクトの「aaa」フォルダにコピーする。

```powershell
copy *.png aaa/
```

### 元のファイル名に昇順で数字を追加する
拡張子が「.png」をのファイルを対象に、ファイル名の先頭に"数字(2桁:0埋め）"を追加する。
参考元：https://blog.shibata.tech/entry/2015/11/18/185108


```powershell

ls *png | sort Name | % {$i = 1} { $NewName = "{0:00}_{1}" -f $i, $_.Name ; mv $_.Name $NewName; $i++ }
```
明日からDropbox Paperが使いたくなる5つの理由

## ねぇ君Dropbox Paper使ってる？
https://www.dropbox.com/ja/paper
もちろん使ってるよな？？？
流石にまだW●rdなんか使ってないよな笑
当たり前のことを聞いてしまって申し訳ない。

じゃあ我々が、**何でDropbox Paperに惚れ込んでいるのか**考えてみようじゃないか。
## え？！こんなに？！ 全俺が惚れ込んだ5つの理由とは？
### 1.Markdownで書くことができる。
なんて嬉しい！！！
面倒だった見出しやリストも一瞬ってわけだ！

多少の方言はあるが、**地方の女の子の方言が可愛い**みたいなもんだ。
むしろいい。
### 2.自動保存
最近当たり前になってきている自動保存。
当たり前がどれほど幸せか、実感した方がいい。

たま〜にW●rdを使うことがあるのだが、この機能に慣れているおかげ~~(せい)~~
でよくデータを吹き飛ばす。
### 3.同時編集
同時に編集できるの？！？！？！
すげぇ！！！
これでタイプミスしても「ここ誤字あるよ」っていう謎の指示がなくなるわけだ。

ただ完全に同時に編集すると、
`起きておきおきて起きて起きおお起き起きて起きておき`
のようになることがある。
メンヘラみたいで可愛い。
### 4.他のドキュメントへのリンクが神
使用シーンによって複数のドキュメントを作成する場合がある。
他のドキュメントを同時に見たい時、今までいちいち戻って開いてという面倒な作業をしていた。

それがなんと！
この子はリンクをも簡単に載せれるのだ！
> +ドキュメント名

これだけ。
嘘だと思うなら試してみるといい。
特別にもう一回リンクを貼っておくぞ。
https://www.dropbox.com/ja/paper
### 5.目次の自動生成
おいおい、嘘だと言ってくれよ。
正直ここまでできるやつだとは思ってなかった。
何気なくカーソルを左側に移動してみたらそこに奴はいた。

ほんとお世話になってます。はい。

## Dropbox Paperが気になってきたあなたへ。
ここまできたらもうあなたはDropbox Paperの虜になっているに違いない。
そんなあなたに、Dropbox Paperの親御さんの1人であるカピータさんが執筆した記事をシェアしておこう。
[15 Dropbox Paper hacks everyone should know](https://medium.com/@KaviRadh/15-dropbox-paper-hacks-everyone-should-know-5370546341fd)
なんと和訳まで用意してある。
[Dropbox Paperを使うときに知っておきたい15のヒント](https://navi.dropbox.jp/15-dropbox-paper-hacks-everyone-should-know)

良きドキュメントライフをあなたに。
メモ：Android では view にボーダーをつけるのに style を作らなくてはいけない。

個人的メモ。

iOS で view に border をつけるには
```
view.layer.borderColor = UIColor.black.cgColor
view.layer.borderWidth = 1
```

で、非常に簡単なのであるが、Android で view に Border をつけるには

```xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
   <solid android:color="@android:color/white" />
   <stroke android:width="1dip" 
           android:color="@android:color/black"/>
</shape>
```
みたいなスタイルを `res/drawable` 配下に作り (例えば border_rect.xml)、それを view の `background` に指定する。

```xml
<LinearLayout
    ...
    android:background="@drawable/border_rect"
    ...
/>
```

こういうのは、`android:borderWidth/borderColor` なんかを用意してくれればいいのにと思うなあ。

参照: https://stackoverflow.com/questions/3496269/how-do-i-put-a-border-around-an-android-textview
UnityのUTS等をテクスチャ側を動的に変更する

#まえおき
動的に影を出したかったということがあり
手段としてNormalPainterがあげられますが
テクスチャベースでブレンドできないかと考えShadingGradeMapを動的に変更したいと思いました。
UTS側をいじらずにやりたかったため、CustomRenderTextureを使用したわけです。

#本題
Unity2017.1から搭載されたCustomRenderTextureを利用して
テクスチャを動的に変更します

今回はShaderForgeを利用します。
Unlitでシェーダーを作成後

好きなようにテクスチャを作成します！
時間入れたりなんでも！
※Emission以外には入れないでね
![キャプチャ_waifu2x_art_noise3_scale_tta_1 (1).png](https://qiita-image-store.s3.amazonaws.com/0/308905/b5186056-ab46-915f-1e8f-d4f8bd0c400d.png)
コンパイル後
シェーダーのコードを開き
CGPROGRAM以下のこの部分を置き換えます！！
（簡単）
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/308905/c6e1155a-1c18-525e-efc5-724bfa679a23.png)

これでCustomRenderTexture用のシェーダーが完成しました。

マテリアルを作成しそのシェーダーを割り当てましょう

次にCustomRenderTextureを作成します。
Create→CustomRenderTexture

![キャプチャ_waifu2x_art_noise3_scale_tta_1.png](https://qiita-image-store.s3.amazonaws.com/0/308905/e6814a6f-caa9-b474-bd50-d7e984bc8cb5.png)
解像度等、パラメータはお好みで…
Materialに先程作成したマテリアルを適用すると完了です！！
シェーダーで動的に変更できるテクスチャが完成！！！

UTSのShadingGradeMapに割り当ててみます。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">CustomRanderTextureを用いて<br>UTSのShadingGaradeMapをブレンドする…<br>Timeline拡張につなげる予定…<br>これで動的なテクスチャベースの影ブレンドができるはず…<a href="https://t.co/N4NIDZkeUP">https://t.co/N4NIDZkeUP</a><a href="https://twitter.com/hashtag/UnityChan?src=hash&amp;ref_src=twsrc%5Etfw">#UnityChan</a> <a href="https://twitter.com/hashtag/unity3d?src=hash&amp;ref_src=twsrc%5Etfw">#unity3d</a> <a href="https://t.co/ywxJRl4iAl">pic.twitter.com/ywxJRl4iAl</a></p>&mdash; ゆず@c95 日 東 タ 17a (@Yuzu_Unity) <a href="https://twitter.com/Yuzu_Unity/status/1073415768681762816?ref_src=twsrc%5Etfw">2018年12月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

思った通りにできた！！！

#まとめ
この方法は
VRChat（主にシェーダーかけないけどShaderForgeなら扱える人、UVスクロールとかいろいろ簡単にできるね！）
VFXGraphにも使えるのかな？（いずれShaderGraphと統合されるので必要なくなりますが…）

Unityでの映像制作に関しては
Timelineを拡張することによりTimelineで動的に変更できるようにもなります。（作成中）

これは無限の可能性を感じる…

板ポリ×カメラ×RanderTextureでも出来ますが
これが一番いい感じがする
Haskellでオンラインジャッジに取り組むときの入出力（後編：標準出力への出し方）

「Haskellは競技プログラミングには向いている」と言われたりもするが、競プロやオンラインジャッジにHaskellで取り組もうとすると、最初は問題を解くよりも、「どうやって入力を受けて、出力すれば良いのか？」の方が分からなかったりする。
そんなときのためのメモ。今回は結果の標準出力への出し方。（前編の入力編は[こちら](https://qiita.com/TTsurutani/items/26220ac2c184de774658)）
# 例
前編で入力を処理可能なところまで変換した。

``` input.txt
3
10 20
30 40
50 60
```

``` sample6.hs
main = do
  _ : input <- lines <$> getContents
  print . map (map read . words) $ input
-- [[10,20],[30,40],[50,60]]
```
これを極々単純に各行の和をとって出力、とすると

``` sample7.hs
main = do
  _ : input <- lines <$> getContents
--let ans = map sum . map (map read . words) $ input
  let ans = map     (sum . map read . words) $ input
-- [30,70,110]
  print ans
```
- 外側のリストの各要素を`sum`するために`map`する（要は行単位で処理をする関数が`sum`の場所にくる）
- `map f . map g`は`map (f.g)`なので、このような形になる。
- ここからが本題。出来あがった計算結果のリストを一つづつ改行して出力したい。

``` sample7.hs
main = do
  _ : input <- lines <$> getContents
  let result = map (sum . map read . words) $ input
-- [30,70,110]
  mapM_ print result
-- 30
-- 70
-- 110
```
- リスト内の計算結果の出力には専ら`print`を使う
- `print :: Show a => a -> IO ()`
- `print`は`putStrLn.show`であるので`show`できる型なら無条件に出力して改行してくれる
- printを各要素に適用するには`map`ではなく`mapM_`を使う。なぜならば`print`はIOアクションを返すから
- `mapM_ :: (Monad m, Foldable t) => (a -> m b) -> t a -> m ()`
- ここで`m`は`IO`、`t`はリスト、`a`は`Int`であるので、`mapM_`の型は`(Int -> IO()) -> [Int] -> IO()`となる

``` StringOutput.hs
print "OK"
--- "OK"
putStrLn "OK"
-- OK
```
- ただし、出力する値が`String`の場合`print`を使用するとダブルクォーテーションが付いてしまうので、この場合は`putStrLn`を使う
- `putStrLn :: String -> IO ()`

# forM
`mapM`と引数の順序が異なるのみで、それ以外は全く同じの`forM`。
「すごいHaskellたのしく学ぼう!」では

``` forM.hs
main = do 
   colors <- forM [1,2,3,4] $ \a -> do 
     putStrLn $ "Which color do you associate with the number " ++ show a ++ "?"
     getLine 
   putStrLn "The colors that you associate with 1,2,3 and 4 are: "  
   mapM putStrLn colors
```
これは`mapM`で書くなら

``` mapM.hs
main = do 
   colors <- mapM f [1,2,3,4]
   putStrLn "The colors that you associate with 1,2,3 and 4 are: "  
   mapM putStrLn colors

f :: a -> IO String
f a =  do 
         putStrLn $ "Which color do you associate with the number " ++ show a ++ "?"
         getLine
```
実行結果はいずれも同じ。

``` result.txt
Which color do you associate with the number 1?
white
Which color do you associate with the number 2?
blue
Which color do you associate with the number 3?
red
Which color do you associate with the number 4?
orange
The colors that you associate with 1, 2, 3 and 4 are:
white
blue
red
orange 
```
「すごいH本」では訳注として「mapM と forM は関数とリスト、どちらの引数を長く書きたいかによって使い分けるのが良いでしょう。」と書かれている。
手続き的に引数に与える値を次々に変えては何かしたい、というようなときには`forM`がしっくりくる場合もある。
Xcodeサポートされているコードの種類

##はじめに
　iOSAppにおいてスキャン画面でスキャンされるコードを絞り込みたいのでその設定画面を作ることになりました。その際にXcodeでサポートされているコードの種類は１０種類あることが判明し、それぞれのコードはどんなところで使われているのだろうか？ということを調査していくことにしましたのでその結果を簡単にまとめます。

##サポートされているコードの種類とその概要
　以下の表に簡単にまとめましたのでiOSAppを開発する際にご参考になればと思います。
<img width="546" alt="名称未設定_numbers.png" src="https://qiita-image-store.s3.amazonaws.com/0/235810/47b7b9c8-cb99-27a5-6dd1-f62e1927e7b5.png">

##終わりに
　間違いがあるかも知れませんし、今後実装を始め、その中で気づいたことを更新していこうと思います。
　以下の記事を参考にさせていただきました！
　https://qiita.com/hkato193/items/c36a940c2929a124e416<
超簡単に数値を 1,234 1.2万 12.3万 123万 1,234万 1.23億 ... に整形する方法

この記事は第2のドワンゴ Advent Calendar 2018 18日目の記事です。
ドワンゴでニコニコ生放送のWebフロントエンジニアをやっています、 @misuken です。

まだ空きがあったので [14日目の React + TypeScript における ViewComponent の美しい合成技術](https://qiita.com/misuken/items/cd0e719df56eee9ffe1b) に続いての投稿します。

今回はニコニコ生放送でも使用されている、超簡単に数値を 1,234 1.2万 12.3万 123万 1,234万 1.23億 ... に整形する方法を紹介します。

## 処理

早速ですが超簡単なコードがこちらです。

```.js
function format(n, patterns) {
  const s = String(Math.abs(n));
  const pattern = patterns[(n < 0 ? "-" : "") + s.length] || (patterns[s.length] && `-${patterns[s.length]}`);
  return `${pattern ? pattern.replace(s.length < 10 ? /\d/g : /\d\d/g, pos => s[s.length - pos]): n}`;
}
```

## 整形パターン

使用するときは桁数に合わせて桁番号を記述したパターンを用意します。

```.js
const patterns = {
  1: "1",
  // 2桁の数値の 2桁目の数 + 1桁目の数 という意味になります
  2: "21",
  // 3桁の数値の 3桁目の数 + 2桁目の数 + 1桁目の数 という意味になります
  3: "321",
  4: "4,321",
  5: "5.4万",
  6: "65.4万",
  7: "765万",
  8: "8,765万",
  9: "9.87億",
  // 10桁目からは2桁で指定します
  10: "1009.08億",
  11: "111009億",
  12: "12,111009億",
  13: "13.1211兆",
  14: "1413.12兆",
  15: "151413兆",
  // 負の値も対応できますが省略しても機能します。
  // 省略時は正のフォーマットの頭に "-" が付いたものを使用します。
  "-2": "-21",
  // 好きな形式で自由に指定できます
  "-15": "マイナス151413兆12,111009億",
};
```

## 結果

実際に呼び出してみるとこうなります。

```.js
format(0, patterns); // 0
format(1, patterns); // 1
format(12, patterns); // 12
format(123, patterns); // 123
format(1234, patterns); // 1,234
format(12345, patterns); // 1.2万
format(123456, patterns); // 12.3万
format(1234567, patterns); // 123万
format(12345678, patterns); // 1,234万
format(123456789, patterns); // 1.23億
format(1234567890, patterns); // 12.3億
format(12345678901, patterns); // 123億
format(123456789012, patterns); // 1,234億
format(1234567890123, patterns); // 1.23兆
format(12345678901234, patterns); // 12.3兆
format(123456789012345, patterns); // 123兆

format(-12345678901234, patterns); // -12.3兆
format(-123456789012345, patterns); // マイナス123兆4,567億
// フォーマットが定義されていない桁数を指定すると文字列化されて返されます
format(-1234567890123456, patterns); // -1234567890123456
```

超簡単 ♪( ´θ`)ノ

## 解説

```.js
function format(n, patterns) {
  // 数値を整数の文字列にする
  const s = String(Math.abs(n));
  // 桁数に合わせてパターンを決定します(負の桁数のパターンが無い場合は、正の桁数のパターンを加工)
  const pattern = patterns[(n < 0 ? "-" : "") + s.length] || (patterns[s.length] && `-${patterns[s.length]}`);
  // パターン文字列の数字を正規表現でマッチさせて、
  // マッチした数字が指示する右からpos桁目の数字に置換します。
  // "1234"[2] で "3" を取得できる言語仕様と、10桁目から正規表現を切り替えるところがミソです。
  return `${pattern ? pattern.replace(s.length < 10 ? /\d/g : /\d\d/g, pos => s[s.length - pos]): n}`;
}
```

## まとめ

数値の桁数と、パターンに記述された対応する桁番号を上手に利用すると、超簡単な処理で自由度の高いフォーマットを実現できます。
ansibleでwith_itemに変数を渡そうとする場合はダブルクォートが必要

古いplaybookを実行したらうまく動かなくて、調べた時のめも

<!--more-->


```
- host: all
  vars:
    servers
      - ip :  AAAA
        hostname: serverA
        - ip : BBBB
        hostname: serverB
 tasks:
    - debug: var="{{item}}"
      with_item: servers
```

って書くと何かしらエラーになって動かないので、


```
  with_item: "{{ servers }}"
```

って書く必要がある。
二年ぐらい前に書いたplaybookとか再発掘すると結構これに当たるので覚えておく。

[https://github.com/ansible/ansible/issues/23496](https://github.com/ansible/ansible/issues/23496)
Makefileの依存関係中のパイプ記号について

以下のようにMakefileの依存関係[^1]中`|`[^2]記号が混じっていたので、その挙動について調査。

```makefile:Makefile

target: hoge fuga | piyo 
	command1
	command2
	...
```
GNU Makeのドキュメントの[4.3 Types of Prerequisites](https://www.gnu.org/software/make/manual/make.html#Prerequisite-Types)に説明が乗っていました。

`targets : normal-prerequisites | order-only-prerequisites`

どうやら`|`記号の以降の依存関係はorder-only-prerequisitesというらしい。

通常の依存関係(normal-prerequisites)は、それが存在しない、または更新されていたらtargetルールを実行するのに対し、
order-only-prerequisitesは、それが存在しない場合のみtargetルールを実行する（つまり更新を無視する）らしい。

公式ドキュメントでは、以下の様な例が示されている。

```makefile:Makefile
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)

$(OBJDIR)/%.o : %.c
        $(COMPILE.c) $(OUTPUT_OPTION) $<

all: $(OBJS)

$(OBJS): | $(OBJDIR)

$(OBJDIR):
        mkdir $(OBJDIR)

```

この例でいうと、「OBJDIRで指定されたディレクトリが存在しない場合だけ`mkdir $(OBJDIR)`を実行する」という挙動になる。



[^1]: Prerequisiteの訳（別に適切な訳があれば編集リクエストお願いします。）
[^2]: パイプ記号、pipe symbol、縦棒、バーティカルバー、vertical bar (ググラビリティ向上の為の注釈)
CircleCIを使ってAndroidアプリをデプロイゲートに自動でデプロイ【CirleCI 2.0】

みなさん、CircleCI使ってますか？
にわかエンジニアの私も、CircleCIは便利なので最近お世話になっています。

今回はAndroidアプリを作成する際に、git pushから自動でデプロイゲートへデプロイをしてくれる環境を構築しました。
今まではapkファイルを作成後に手動でデプロイゲートへアップしていましたが、gitへpushするだけで自動で実行されるようになったので非常に便利です！！
酔っ払いながら環境構築したので、忘れないうちにメモっておきます。

## まずはアプリのプロジェクトをGitHubかBitbucketにpush
今回はAndroidアプリを作成していることを想定しています。
作成しているアプリはGitHubかBitbucketのどちらかでバージョン管理しているものとします。

## CircleCIへログイン
とりあえず、CircleCIへログインしましょう。
アカウントを持っていない方はサインアップ。
GitHubかBitbucketのアカウントがあればすぐに使用できるので簡単です。
ログイン後は、自動でデプロイしたいアプリにチェックし、「Follow」を押しましょう。
![select app.jpg](https://qiita-image-store.s3.amazonaws.com/0/279032/950c6a5d-8d94-bc5c-5e75-20561277eaca.jpeg)

## CircleCIの環境変数を設定
プロジェクトの設定 -> Environment Variables -> Add Variables に、デプロイゲートのAPI Keyを設定しましょう。
今回、Key名は `DEPLOY_GATE_API_KEY` としています。
デプロイゲートのAPI Keyは、デプロイゲートのアカウント設定ページから確認できます。

![DEPLOY_GATE_API_KEY.jpg](https://qiita-image-store.s3.amazonaws.com/0/279032/de3df7f3-dfb8-4c9e-75f7-1ccc36241acd.jpeg)


## CircleCIの設定
Androidアプリのプロジェクトに、CircleCIの設定ファイルを追加します。
Androidアプリプロジェクトのルートディレクトリ（appとかgradleとか格納されているディレクトリ）に、`.circleci/config.yml` ファイルを作成します。
設定のサンプルは[公式にあがっています](https://circleci.com/docs/2.0/language-android/)。
これを参考に、下記のように修正します。（今回テストは実行していません）

```yml:.circleci/config.yml
version: 2
jobs:
  build:
    branches:
      only:
        - develop
    working_directory: ~/code
    docker:
      - image: circleci/android:api-25-alpha
    environment:
      JVM_OPTS: -Xmx3200m
    steps:
      - checkout
      - restore_cache:
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
      - run:
          name: Download Dependencies
          command: ./gradlew androidDependencies
      - save_cache:
          paths:
            - ~/.gradle
          key: jars-{{ checksum "build.gradle" }}-{{ checksum  "app/build.gradle" }}
      - run:
          name: Generate APK
          command: ./gradlew assembleDebug
      - run:
          name: Upload DeployGate
          command: curl -F "token=${DEPLOY_GATE_API_KEY}" -F "file=@app/build/outputs/apk/debug/app-debug.apk" -F "message=deployed" https://deploygate.com/api/users/デプロイゲートの登録名/apps
```

`デプロイゲートの登録名` は、各自修正してください。
今回は Bitbucketで `develop` ブランチにpushした場合のみデプロイゲートにデプロイされるようになっています。

以上です。
CI使えばいろいろできるので、今後も活用していこうと思います！
get post put deleteをするのが面倒だったので、guiで操作できるようにした

#get post put deleteをするのが面倒だったので、guiで操作できるようにした
下の画像が実際のやつです。
とりあえず、パラメータを表に打って適当にボタンを押せばできます。
<img width="1440" alt="Screen Shot 2018-12-14 at 2.38.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/195504/07aa2a59-e3f6-4b2c-ab9d-cf82438542cc.png">


```
git clone https://github.com/takashiAg/easycrud
cd easycrud
npm install 
npm start
```
Hyper-V + systemd-nspawnの開発環境を作る(1) ～ Windowsネットワーク設定 ～

# 概要

hyper-vでsystemd-nspawnの環境を作ってみます

今回想定する環境


- OS: Windows10 Pro
- 仮想化ソフト: Hyper-V
- ホストOS: Ubuntu18.04


下図のような想定です(outer側はDHCPサーバーがある状態です)

![hyper-v-systemd-nspawn.png](https://qiita-image-store.s3.amazonaws.com/0/106549/f6248d41-d7bb-0933-624a-f907b6ba5a7d.png)


# windows側ネットワーク設定

Hyper-Vの仮想スイッチマネージャーを選択します

![w1.png](https://qiita-image-store.s3.amazonaws.com/0/106549/18a84211-ace8-69f5-34aa-f50045e8de85.png)


outerスイッチを作成します
外部ネットワークをチェックします

![w2.png](https://qiita-image-store.s3.amazonaws.com/0/106549/b3ecd50e-d3dd-b24a-02ea-2b712fb620a1.png)


innerスイッチを作成します
内部ネットワークをチェックします

![w3.png](https://qiita-image-store.s3.amazonaws.com/0/106549/e81bc273-1262-f398-39b3-9a36c65604e4.png)


仮想マシンを作成します
ネットワークはとりあえずouterを指定して作ります

![w4.png](https://qiita-image-store.s3.amazonaws.com/0/106549/34fbc3dc-c520-4e71-4796-80a8256ee861.png)


仮想マシンが出来たらマシンを右クリック => 設定からネットワークアダプターを追加します

![w5.png](https://qiita-image-store.s3.amazonaws.com/0/106549/25c6eff4-5e68-485e-35fe-c36624fde6cf.png)


仮想スイッチはinnerを選びます

![w6.png](https://qiita-image-store.s3.amazonaws.com/0/106549/19ecf9bc-5c58-b31c-b31f-239b3312c359.png)


ブリッジインターフェイスを使うため `MACアドレスのスプーフィングを有効にする` にチェックします

![w7.png](https://qiita-image-store.s3.amazonaws.com/0/106549/fb3a6004-1bdd-8586-2d61-963423e1ea76.png)


次にWindows側のIP設定をするために `コントロール パネル\ネットワークとインターネット\ネットワークと共有センター` を開いて
innerアダプタを選択 

![w8.png](https://qiita-image-store.s3.amazonaws.com/0/106549/854782b6-71c1-2b7d-520d-34b88f2c9c9a.png)


プロパティ => `インターネットプロトコルバージョン4(TCP/IPv4)` を選択 => プロパティから以下のようにWindows側のIPを `10.100.0.1` にします

![w9.png](https://qiita-image-store.s3.amazonaws.com/0/106549/10e13e8b-d4ce-4b33-201e-ca05b940d676.png)


# Ubuntuのインストール

eth0がDHCPによりアドレスが取れていれば正常です

![u1.png](https://qiita-image-store.s3.amazonaws.com/0/106549/d8806919-ffb7-afd7-2da6-9708a1a9a216.png)

[次回](https://qiita.com/yaasita/items/228342cda57ad2d01bf3)
Redmine EasyGantt こりゃイージーですわ

# Easy Ganttとは？
Redmineのプラグインで、直観的にガントチャートを操作することができます！
チケットの開始日を変更したり！期限を伸ばしたり！進捗率を更新したり！
ということがドラッグ＆ドロップで簡単出来ます！

# 実際の動作
では、実際にどう操作できるのか見てみましょう。
![easygantt1.gif](https://qiita-image-store.s3.amazonaws.com/0/257408/4c0f961f-b4e0-f6c5-b1d4-3cadaed5b95b.gif)
・期間の移動
色の付いた帯の上をドラッグすると期間はそのままに移動することができます。
グレーの部分は休日になっていて、休日の期間を考慮して期間を維持ます。

・期間の拡張/縮小
帯の端をドラッグすると左側で開始日、右側で期限のみを変更することができます。
こちらも休日が考慮され、開始日、期日を休日のグレーゾーンに設定することはできません。

親子関係にあるチケットは子の期日に連動して拡張したり縮小していきます。

![easygantt2.gif](https://qiita-image-store.s3.amazonaws.com/0/257408/079011db-904a-a83d-a97c-85db49a494c6.gif)
・進捗の操作
帯の下に表示される三画をドラッグすると進捗率が操作できます。
子チケットの進捗率を変更し、保存ボタンを押すと親チケットの進捗率も更新されます。
また、期日が過ぎてるチケットは赤色で表示されます。

![easygantt3.gif](https://qiita-image-store.s3.amazonaws.com/0/257408/a5971d4d-1071-2686-d54b-90e19ba8fbf9.gif)
・チケットの関連付け
帯の端の半円をドラッグして線を出し、別のチケットの端につなげることでチケット同士を関連付けることができます。
関連付けることでチケットを連動して動かすことができます。

# 所感
ドラッグ＆ドロップで簡単に操作できるのでわかりやすい！
視覚的に期間を確認できるのと、休日を考慮していることで期間の設定ミスを防げる！
※祝日は別途設定が必要です。。。

プロジェクトの開始時にスケジュールを立てる時など、何度もやり直したくなることが多くあり、
RedmineのガントチャートやExcelに比べ、変更が容易なのでとても助かりました。
保存ボタンを押すと開始日、期日もチケットに反映されるので、チケットを1つ1つ変更していく手間も省けます。

是非皆さん触ってみて、体験してみてください！

https://www.easyredmine.jp/en/redmine-gantt-plugin
開発側と連携して、実装品質を改善した話

#この記事の目的
私は現在3つのタイトルのQA管理を行っております。直近開発側と連携して、QA前の実装品質を上げる取り組みを行った結果、QA/開発双方で対応工数が減り、さらに市場不具合を削減することができました。

この取り組みを通じて、QAチームと開発チームが連携して改善を進めることの重要性を強く感じたので、特に開発の方へ向けて、その内容をまとめます。

#QA前の実装品質向上に目を向けた背景
事の発端は、私の担当しているタイトルでQAコストがかかりすぎていたため、効率化を進めたいと思ったことから始まりました。まず、QA中の不具合数に着目してみると、他タイトルと比較しても、不具合数がかなり多かったため、QA中の不具合数を削減することで、テスト実行コストを減らすことにしました。

#取り組み内容
###開発によるQA前の簡易チェック導入
QA中の不具合数を削減するとなると、QA前の実装品質を高める必要があります。今回の対象タイトルでは、QA開始時にそもそも実装が整っていないことや、毎回発生するような不具合も一定数発生していたため、QA前に開発側で簡易的にチェックするフローを導入してもらうことにしました。

まずQA内でベースとなるチェックリストを作成し、それを基に開発側でアップデートしてもらう形にしました。施策によって、チェックポイントは変わるので、大まかにガチャ/レイドイベント/ショップなど数種類作成しました。
![5635796-31a8f946c510b12b4d23030abcdc2fabf1c77f17.png](https://qiita-image-store.s3.amazonaws.com/0/312027/90c1ca87-9855-e95c-d599-95a30388197d.png)

#導入結果
上記により、QA中の不具合数は導入から半年で60％以上減少し、当初課題に挙がっていたQA費用だけでなく、市場不具合数も大幅に削減することができ、期待以上の効果が得られました。
![5635797-17f53b8895dec147d99aa6db3fa583cbea1e3a43.png](https://qiita-image-store.s3.amazonaws.com/0/312027/c302c2e8-29bf-730c-6d34-97fd0f60b5aa.png)

|対象|削減率(月)|
|:----------|:----------------------|
|QA費用|-35%|
|市場不具合数|-40%|

また、この取り組みは他にも2つのタイトルで導入を開始し、今まで継続して取り組まれています。開発側へメリットを聞くと、やはり不具合対応コストが減り、品質も向上するという部分が大きいようです。

#工夫したこと
- **チェック項目のベースはQAチームで作成**
    - 開発側でチェックする文化がない場合、開発担当者でのチェック項目の洗い出しはそれだけでかなりの労力になると思います
    - 不具合の傾向なども把握しているQA側で作成した方がスピード感もあると思うので、QA側に依頼することをお勧めします
- **初めからチェック項目数を多くしすぎない**
    - 初めから100％のチェック項目を作ろうとすると、対応工数が大きくなってしまい、導入自体難しくなってしまいます
    - 最初はこれならすぐ終わりそうというくらいの項目数にしておいて、導入後少しずつアップデートしていく形がスムーズかと思います
- **初めから継続運用前提で進めない**
    - 確かにこの取り組みは開始1ヵ月程度で成果が出るものではないので、実際にチェックする担当者もまずやってみないと工数感などもわからないと思うので、最初はトライアルとして実施して、振り返りを行って、よければ次の対象を決めていくという前提でスタートしました

ただ、緩くしすぎてもスピード感が損なわれるため、導入が成功したら、状況管理を徹底し、小まめにアラートを投げられる体制に変えていく必要があります。

- **開発側にQA窓口の方を立てる**
    - QAチームからアラートを各開発担当者それぞれへ上げるのは、かなりの労力が必要になるため、開発側で窓口になる方を立てていただき、その方にQA側と課題感をすり合わせて、開発チーム内に落としてもらえると、QAは分析に集中でき、精度の高い改善提案が行えるようになります
- **向こう3ヵ月～半年の目標削減件数を合意しておく**
    - 導入が成功したら、直近の件数推移を基に、無理のない範囲で各施策担当者と目標件数を合意できると、その後目標からの上振れをトリガーとして、アラートが投げやすくなります
    - また設定した目標に対して、実績を振り返るというのも非常に重要です。今回は、各施策担当者へ1つのスプレッドシートに実績と振り返りをQA後に記載してもらいました。この運用はそれなりに工数はかかりますが、状況が可視化されるので、改善がスピードアップしました
![5635799-2f551d0506079cae0e8b8d04b62c9bce87bcb952.png](https://qiita-image-store.s3.amazonaws.com/0/312027/b6364bf9-bc13-760e-e95d-32f8431cf057.png)
- **件数推移や原因別の内訳を可視化して、週次定例で振り返り**
    - やはり最初は一部チェック項目がチェックされていなかったり、チェックはついているが、正しいチェックがされていないことが多く発生するので、最初はQAチームと週次など頻度高めに振り返りをすることで、早期にフローの課題を解消したり、チェックリストの拡充を加速させることができます
    - また、実際にチェック精度が高く、改善している開発担当者がいれば、QA側から共有してもらうようにして、全体の定例などでしっかり賞賛することも非常に重要です

以上が工夫してよかったと感じたポイントでした。

#さいごに
QAコストの効率化や品質改善は、QA部門で何とかするものだというイメージが強いと思いますが、開発工程で品質改善できると、QAだけでがんばるよりも圧倒的に早く、大きな効果を埋めると思います。ぜひQAと積極的に連携していただき、品質改善につなげていただけますと幸いです。
【Python】Bottleで手軽にLAN内やLAN外からアクセスできるページを用意

社内デモや勉強会等で軽く公開したい場合用のメモです。

## 軽量Webフレームワーク：Bottle
今回は、Django、Flaskと並び有名なPythonのWebフレームワーク Bottleを利用します。

1．「[bottle.py](https://bottlepy.org/bottle.py)」をダウンロードし、プログラムを実行したい任意のフォルダに格納する。
今回は簡単に以下のような配置で格納。
　├ bottle.py
　├ index.html
　└ main.py
　格納したソースはそれぞれ以下。

```python:main.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from bottle import route, run, template


@route('/')
def index():
    return template("index")


if __name__ == '__main__':
    run(host="localhost", port=8080, debug=True, reloader=True)
```

```html:index.html
<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <title>sample</title>
</head>
<body>
  <h1>sample</h1>
</body>
</html>
```

2．「main.py」を実行し、http://localhost:8080 にアクセスする

参考：
　[Bottle: Python Web Framework](http://bottlepy.org/docs/dev/index.html)
　[Pythonを始めるなら、１ファイルの軽量Webフレームワーク「Bottle」がおすすめ](http://mojix.org/2013/01/04/python-bottle)
　[PythonのWebフレームワーク６種をかんたんに紹介](http://mojix.org/2013/04/13/python-six-wafs)

## LAN内の端末からアクセスする
サンプルでは、localhost指定(localhostか127.0.0.1のみ)になっていたため、以下のように修正すればLAN内の端末からアクセス可能になります。

```python:main.py
    run(host="192.168.xxx.xxx", port=8080, debug=True, reloader=True)
```
→実行する端末のIPを調べて「host」に指定する。この場合はloalhost指定でのアクセスが出来なくなる。

```python:main.py
    run(host="0.0.0.0", port=8080, debug=True, reloader=True)
```
→「host」に"0.0.0.0"を指定すると、localhost指定か端末IP指定(http://192.168.xxx.xxx:8080/） でアクセス出来る。

## LAN外の端末からアクセスする
サクっと実現したいため「[ngrok](https://ngrok.com/)」を利用（もう少し気合を入れる場合はherokuとか。。。

1．ngrokのページへ行き、「Get started for free →」ボタンを押下、次画面にてライセンスの登録を行う
2．「Setup & Installation」に従いngrokをインストール
3. コンソール上で「./ngrok http 8080」を実行（例はUbuntuの場合
![無題.png](https://qiita-image-store.s3.amazonaws.com/0/140207/84cb07f0-b2f9-3b35-5a02-2fd166731636.png)
上記例の場合は、http://775ebd31.ngrok.io にアクセスすることでLAN外からアクセス可能（Freeプランの場合は、ngrokを起動するたびにURLが変わる

参考：
　[ngrokが便利すぎる](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)


## pyinstallerでexe化
pyinstallerでexe化しておくと取り回ししやすいかもしれない（上記のサンプルプログラムだと「--noconsole」オプションは指定せずにコンソール表示しておかないと何やってるかわからなく、、、

```sh
    pyinstaller main.py --onefile
```
以下のようにexeファイルが生成されるため、「main.exe」から見える場所に「index.html」を格納すれば、実行可能。
　├ dist
　│　└ main.exe
　├ bottle.py
　├ index.html
　└ main.py

以上。
Qiitaのメールアドレス認証に失敗する

## はじめに
この記事はロボP Advent Calendar 2018の13日目の記事です。
Qiitaのメールアドレスで詰まったので、解決した方法について書きます。

## 起こった問題
Qiitaから送られた認証用メールから認証ページにアクセスしても、「無効な認証キーです」といわれる。

## やったこと
######時間を空けて再度アクセスした
30分程間隔を空けて再度アクセスしてみたが、同じく「無効な認証キーです」といわれてしまった。
######メールアドレスを変えた
別のメールアドレスで再度認証を試みるも、同じように失敗した。

## 解決した方法
アクセスポイントを自宅のルーターからスマホのテザリングに変えたら認証に成功した。

IPアドレスを変更したタイミングで認証に成功しているので、認証サーバーが自分のipアドレスに対してアクセス制限をかけていたのかもしれない。
## 終わりに
解決方法を探すためにググってみたが、ネットにほとんど記事が上がっていなかった。ほとんどの人はQiitaのメールアドレス認証で失敗とかしないみたいです。
カーネル密度関数とは

#カーネル密度関数って聞いたことあるけど何？#
ヒストグラムなどの離散的な値を連続な値として補間ではなくて近似する関数
#基底関数は？#
ガウス関数や矩形、三角形とか色々
#B-splineと一緒じゃない？#
まぁそうだね
カスタマージャーニとは、多様化した消費者の行動モデル

# はじめに

Adventカレンダー「エンジニアのためのWebマーケティング」の13日目です。
サクッと読める記事を目標に。異論・ツッコミ大歓迎。
できるだけ専門用語を使わないように気をつけます。

それでは参りましょう

# カスタマージャーニーとは？

![StockSnap_S9OHYE25LP.jpg](https://qiita-image-store.s3.amazonaws.com/0/72413/7c065781-a724-5f78-74c4-26e05f73c284.jpeg)


僕が記事を書く前に、Marketoのサイトに非常にわかりやすい記事がありました。

*Marketo - [カスタマージャーニとは](https://jp.marketo.com/content/how-to-make-customer-journey.html)*

なので、エッセンスだけをかいつまんで。

## 顧客の行動はとても複雑化している

昔なら、「この広告を見たら買った」「このワードで検索したら買う人」のように単純なマーケティングの公式がありました。

しかし、顧客の目も肥え始め、SNSからなどで真偽が確かめやすい世の中になった今。単純な経路分析をするだけでは、購買欲を持った顧客を判定するのはとても難しくなってきています。

## 企業が思っているほど単純ではない

例えばこんなパターン・・・

1. 一度、Youtubeで出てきた動画広告を見ることで商品の存在を**初めて知る**
2. SNSで実際に口コミも目の当たりにし、**興味を持ち始める**
3. **自分で検索もして能動的に**情報を取るようになる
4. ブログで絶賛する記事を目にして、**アフィリエイトの広告経由で購入**

パッと見ただけでは、どの接触機会がキーになったのかわかりにくいですよね。
もしくは、全てピースが揃わないと買わなかったのかもしれない可能性もあります。

## 顧客を「動線」ではなく「機会」で評価する

「動線」と書くと、どうしても「自分が設計しているルート」のような見方をしてしまいます。しかし、冒頭でも書いたように現代の消費者は**「賢く、選別する眼も持ち、多様化」**してきています。

自分が想定していない接触機会が、思ってもいない販促効果を出している場合も考えられます。
また、100人の消費者がいたら、100通りのルートがあると考えるのが妥当です。

・・・となると、もはや動線設計は非常に複雑化していくことでしょう。

## いっそのこと「ある程度のターゲットを決める」

では逆に、「この接触機会を持ったユーザーは次にどんな行動を起こすのか」そういう目線で分析をしていきます。

実世界で例えると・・・

* 自分がお腹空いた時に商店街へ行ったら、どこのお店で食事をするか
* そこで食事をしたら次に行くのは喫茶店でコーヒー？
* それとも図書館に本を借りに行く？
* その後は服を買いに行って家路につくか

そういう想像をみなさんも実生活で休みの日のプランニングをすると思います。
じゃあ、もうコーヒー買いに来る人はどこから来るのか。
コーヒー飲んだらどこに次行くのか。
どんどん顧客目線になって考えていきます。

それをWebサイトに置き換えて、自分ならどうするか？を設計していきます。

・・・これ想像すると楽しそうですよね。

# 晴れたら動物園、雨が降ったら映画館にいくように・・・

人間はいつでも、**「もしこうなったらこうする」というのを無意識に**考えて生きています。

そんなケースバイケースを想定するような、

* 「自分ならどうするか」
* 「あの人ならどうするか」
* 「連れならどうするか」

そんな思考の先に見えてくる、「あ、じゃあここにコレあったらいいんじゃない！？」というルートが「カスタマージャーニー」かもしれません。

勿論、ツールを使ってその仮設が本当に正しいのかの検証も忘れずに。

# どうでもいい話

「ジャーニー」という言葉を聞くと、

親の世代は、「松本伊代」さんのことを想像し、
自分はというと、[「NANA」の劇中歌](https://www.youtube.com/watch?v=1YggBT4TzxQ)を思い出し、
マーケターの人は「カスタマージャーニー」のことを想像し、
競馬好きの友人は「ドリームジャーニー」のことを思い出すらしいです。

多様化社会・・・。

# おわりに

明日は、「動画広告」について触れていきます
開発合宿でのAWS構築　　　（インスタンス公開）

目的
●AWSのEC2の環境構築を作成できる事を前提としています。
　Elassticserchを使用してインスタンス公開を目的を目指し対応できる様にします。
前提条件
●AWSアカウントを所有すること
●できれば、プログラムの基礎知識があればなを可

注意事項１
●アカウント登録する際に無料枠を使用して最初はお試し頂ける事をお勧めします。
　私自身はそこを理解しないで対応したことで、重量制課金なので、無料枠でなく
　有料枠を知らないで使用した為、余り使用していない中、課金がされてしまいました。
　不明な点は必ずサポートに連絡する事をお勧めします。

今回の環境構築の内容について
・AWSアカウントの登録をします
・VPCの環境構築をします
・EC2の環境構築をします
・インスタンスの作成/選択をします
　※新規の場合は→新しいペアキーを作成を行います。
・Elassticserchの環境構築をします
・EC2の作成した環境に接続をします
　→作成したインスタンスに接続
　→リモートデスクトップで接続（自分で作成した公開したAWS環境に接続）
・EC2インスタンスにログインする
・pythonで今回作成して頂いた書籍管理システムにアクセスし
　検索した内容ページが表示されたら成功
  →事前にpythonのインストールは必要
　→Elassticserchのインデックスの設定が必要
　→公開するポートを事前に開けて設定しておく事が必要です
　　※443と8080ポート開放
備考
　アクセスし、表示されず、エラーが出た場合はmoduleの再実行が必要。
注意事項２
　今回使用したIEで画面表示をさせていましたが、うまく表示されませんでした。
　（検索も登録ボタンも反応しない）
　そのため、今回はクロームに変更し再度行ってみたら正常に表示されました。
　IEだとバージョンにもよりますが、表示がおかしくなる場合もあるので、
　その為、クロームを使用する事を推奨します。