OmniAICreator/Qiita-1.07M huggingface dataset:
TypeChainを使ってタイプセーフなdappsフロントエンド👼

まずはこちらをご覧ください（[web3-jsのtsライブラリ](https://github.com/ethereum/web3.js/blob/043cb81d40ede0f6ef1889222c5671f9678e409e/packages/web3-eth-contract/types/index.d.ts#L48)より）

```web3.js/packages/web3-eth-contract/types/index.d.ts
export class Contract {
  // 中略

  methods: any;

  // 中略
}
```

ばかな、、、anyだと。。。

ということで今回は型付けが超絶貧弱な [web3-js](https://github.com/ethereum/web3.js/blob/1.x/packages/web3-eth-contract/types/index.d.ts#L48) を [ethereum-ts/TypeChain](https://github.com/ethereum-ts/TypeChain) というライブラリを使って型を付けていきます。

[Blockchain Advent Calendar](https://qiita.com/advent-calendar/2019/blockchain) 記事どうしようどうしようと迷い続けて最終的に超ニッチな所に行き着きましたwすいません。

## 使っているもの
- web3: 1.x系
- typechain-target-web3-v1: 1.0.4
- typechain: 1.0.3

## TypeChainとは?
[ethereum-ts](https://github.com/ethereum-ts) というグループ（開発者一人）が作っているSolidityから生成したコントラクトに型を付けてくれるライブラリのようです。

現在495スターで開発者一人でこれは素晴らしい。

## 使ってみる
truflleやethers.jsなどにも対応しているようですが、今回はフロントではweb3-jsを使っている想定で進めます。
また、コントラクトはtruffleを使って開発している想定です

### インストール
```bash
$ cd /path/to/truffle-dapps-root
$ npm install --save-dev typechain
$ npm install --save-dev typechain-target-web3-v1
```

### コントラクトの型定義ファイルをビルド
```bash
$ cd /path/to/truffle-dapps-root
$ npx npx typechain --target web3-v1  './build/**/*.json'
$ cd ./types/web3-v1-contracts
=> コントラクトの型定義ファイルができている
```

### フロントエンドアプリで使用
次は上で作った型定義ファイルをフロントエンドアプリに持っていき読み込ませましょう。
キャストが必要ですが、これで web3-js の Contract タイプに対して自作のコントラクトの型をつけることができます。

例として使用するコントラクト

```MyContract.sol
contract MyContract {
  uint256 value;

  function setValue(uint256 _value) external {
    value = _value;
  }

  function getValue() external view returns (uint256) {
    return value;
  }
}
```

ビルドされた型定義ファイル

```MyContract.d.ts
export class MyContract extends Contract {
  constructor(
    jsonInterface: any[],
    address?: string,
    options?: ContractOptions
  );
  clone(): MyContract;
  methods: {
    setValue(_value: number | string): TransactionObject<void>;

    getValue(): TransactionObject<string>;
  };
  events: {
    allEvents: (
      options?: EventOptions,
      cb?: Callback<EventLog>
    ) => EventEmitter;
  };
}
```

フロントエンドアプリ

```ts
import { MyContract } from './path/to/MyContract'; // 生成した型定義ファイル

const createMyContract: MyContract = () => {
  // apiについては
  return new web3.eth.Contract(abi, address) as MyContract;
);

// methodsに対して型が付与されている!!!
createMyContract().methods.setValue(10).send({
  from: window.web3.eth.defaultAccount,
});

createMyContract().methods.setValue(10).send({
  from: window.web3.eth.defaultAccount,
});

createMyContract().methods.setValue().call();
```

## タイプセーフなdappsライフを
型というものは素晴らしいものですね。
npmにパッケージとしてリリースして常に最新のビルドしたものを見ているようにしたり、シンボリックリンクでファイルを共有したり、すこし運用に工夫は必要ですが、これでdappsフロントエンドアプリのバグが減りそうです。

では良いお年を〜
【画像処理100本ノックに挑戦】独自の行列クラスを作る

# 何故自作するか
画像処理100本ノックに挑戦中です。全体の1/4くらいが終わったあたりでそろそろ行列演算が出来た方がよい予感がします。
普段はEigenというライブラリを使っているのですが、これを使うと負けた気がします。せっかくなので自作してみることにします。Eigenのインターフェースを参考にしていますが、100本ノックを乗り切る範囲での実装なのでクオリティは低いです。エラー処理も実装しません。

# コード
必要に応じて修正予定です(まだ引き算もない・・・)。

```c++
class Matrix
{
	int N, M;
	std::vector<std::vector<double>> a;
public:
	Matrix(int M, int N=1) : N{ N }, M{ M }, a(M, std::vector < double >(N) )
	{
	}
	void set(std::initializer_list<double> list)
	{
		int m = 0, n = 0;
		for ( auto&& v : list)
		{
			a[m][n++] = v;
			if (n == N)
			{
				n = 0, m++;
			}
		}
	}
	double& operator()(int i, int j)
	{
		return a[i][j];
	}
	void print()
	{
		for(int i=0; i<M; i++)
			for (int j = 0; j < N; j++)
			{
				std::cout << a[i][j];
				if (j == N - 1) std::cout << std::endl;
				else std::cout << " ";
			}
	}
	Matrix operator+(Matrix& mat) const 
	{
		Matrix ret(M,N);
		for(int i=0; i<M; i++)
			for (int j = 0; j < N; j++)
			{
				ret(i, j) = a[i][j] + mat(i, j);
			}
		return ret;
	}
	Matrix operator*(double val) const
	{
		Matrix ret(M, N);
		for (int i = 0; i < M; i++)
			for (int j = 0; j < N; j++)
			{
				ret(i, j) *= val;
			}
		return ret;
	}
	Matrix operator*(Matrix& mat) const
	{
		Matrix ret(M, mat.Get_MN().second);
		for (int i = 0; i < M; i++)
			for (int j = 0; j < mat.Get_MN().second; j++)
			{
				ret(i, j) = 0;
				for (int k = 0; k < N; k++) ret(i, j) += a[i][k] * mat(k, j);
			}
		return ret;
	}
	std::pair<int, int> Get_MN() const 
	{
		return std::pair<int, int>(M, N);
	}
};
```

# 使い方
```c++
int main()
{
	Matrix mat(2, 2);//2x2行列
	mat.set(
		{1, 2,
		 3, 4});//値をセット

	Matrix v(2);//2x1行列
	v.set(
		{
		 3,
		 4
		});
	( mat * v).print();//積をとって結果を表示
}
```
NASからファイルを取得してローカルのファイルを上書きするbat

#NASからファイルを取得してローカルのファイルを上書きするbat

##経緯
RPAでNASに置いてあるExcelファイルを取り込んで処理を行っているフローで、
よくExcelが開かなくなるような不具合（その後開こうとしても真っ白なExcelファイルが表示される）という話があって、
それなら試しにローカルに配置したものをRPAで取り込むように変えてやって見ませんかということで、
NASに配置している最新版をRPAがインストールされているローカル端末に持ってきて、
RPAで指定しているローカルなパスに上書きするようなバッチを作成した備忘です。

##作って見た感想
毎回ネットワークパスあたりでつまるなあと思い出した。
あとxcopyの確認メッセージも毎回忘れてる。。。。

```
@echo off
rem ★環境変数のローカル化により呼び出し元を汚染しないようにする
setlocal

rem
------------------------------------------------------------------------------------------------
rem RPA取込処理で使用するexcelファイルの最新版を取得する
rem 　最新版：\\XX.XX.XX.XX\ABCDEFG\001_ABCDE\002_FGHEIJ\
rem 　RPAで使用しているパス：ローカルパス
rem
------------------------------------------------------------------------------------------------

rem ★変数を宣言する
set latest_edition_folder_path=\\XX.XX.XX.XX\ABCDEFG\001_ABCDE\002_FGHEIJ\
set file_name=エクセルファイル名
set local_folder_path=C:\Users\xxx\Desktop\xxxxxx\xxxxxxxbat

rem ★バックアップファイル用の年月日時分秒を取得
set yyyy=%date:~,4%
set mm=%date:~5,2%
set dd=%date:~8,2%
set hh=%time:~0,2%
set mn=%time:~3,2%
set ss=%time:~6,2%

rem ★bkフォルダがない場合、bkフォルダを作成する
cd %local_folder_path%
if not exist bk mkdir bk

rem ★ローカルファイルを念のためバックアップを取得する
rem 　/d:コピー元の日付がコピー先を新しい場合のみコピーする
rem 　/y:コピー先にファイルが存在する場合上書き云々の確認メッセージを表示せず強制上書きする
if exist %local_folder_path%\%file_name% (
rem xcopyでよく聞かれる受け側のファイルですか、またディレクトリですかの回避のため、先頭に「echo f | 」を記載
echo f | xcopy /y %local_folder_path%\%file_name% %local_folder_path%\bk\%file_name% 
rem ★ローカルファイルのバックアップをリネームする
rename %local_folder_path%\bk\%file_name% %yyyy%%mm%%dd%%hh%%mn%%ss%_%file_name%
)

rem ★ローカル端末上にNドライブのネットワークパスを作成する
net use m: %latest_edition_folder_path%

rem ★作業ディレクトリをmドライブにする
m:

rem ★NASから最新版のファイルを取得する。
rem 　/d:コピー元の日付がコピー先を新しい場合のみコピーする
rem 　/y:コピー先にファイルが存在s売る場合上書き云々の確認メッセージを表示せず強制上書きする
rem xcopyでよく聞かれる受け側のファイルですか、またディレクトリですかの回避のため、先頭に「echo f | 」を記載
echo f | xcopy /d /y %file_name% %local_folder_path%\%file_name%

rem ★ローカル端末上に作成したNドライブのネットワークパスを削除する
net use m: /d /y

exit
```
無料のSanPDF Online Converter SDKデモ

日常業務では、PDFからWord、PDFから画像、その他のソフトウェアを使用する必要があります。 Webには多くの無料のオンラインPDF変換ツールがあります。 ただし、プログラムできる人は、好きなようにできます。 画像をPDFコードに実装するコードを記述します。 C＃プログラミングに精通している場合は、SanPDFを呼び出して無料のSDKインターフェイスを提供できます。 お気に入りのPDFコンバーターを実装します。
コードスニペット：

//pdf tool functions
        [DllImport("PDFTool.dll", CharSet = CharSet.Ansi, EntryPoint = "pdf_tool_init", CallingConvention = CallingConvention.Cdecl)]
        public static extern void pdf_tool_init(string server_path);
        [DllImport("PDFTool.dll", CharSet = CharSet.Ansi, EntryPoint = "pdf_tool_set_authorization_code", CallingConvention = CallingConvention.Cdecl)]
        public static extern void pdf_tool_set_authorization_code(string code);
        [DllImport("PDFTool.dll", CharSet = CharSet.Ansi, EntryPoint = "pdf_tool_get_authorization_request_code", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr pdf_tool_get_authorization_request_code();

   完全なコードエンジニアリングが必要な友人は、私のgithub URL:https://github.com/SarahAdamkk/SanPDF-SDKDemo にアクセスしてください
完全なsanpdf SDKデモコードパッケージをダウンロードします。
Wikipedia 読み上げ Android アプリを Jsoup + TextToSpeech で作った話

Android 開発初心者がアプリ開発をしてみた体験記です。なお、作成物はストア公開はしてないです

# やったこと
- Kotlin で Activity 三つのアプリ作成
- Jsoup を利用したウェブページのロード、DOM 操作
- TextToSpeech を利用した読み上げ機能

ソースコードはこちら: https://github.com/negito6/WikipediaSpeech-Android

# 動機と機能
Android の読み上げ機能を使ってウェブページ全体を読み上げようとすると、読み上げにはちょっと邪魔な文字列が沢山あります。特に Wikipedia でいうと、メニューにある各種リンクのテキストや、細かい数字が載った表などです。
また、（端末によってなのか知らないのですが） Chrome 上で｢全て選択｣をすると選択範囲が変更できないため、読み上げアプリにコピペする文字列として長い文章を選択しづらいです。

そこで、Wikipedia のページの文字列のうち、読んでほしいところだけを読み上げてくれるアプリを自作することに。

# 自分の Android 習熟度
（自己紹介みたいな話。）

仕事で数回、会社で出しているアプリに機能追加の仕事をしたことがあります。Android の初心者向けの本はバージョン3くらいの時代にさらっと読んだことがあるのですが、借り物の本だったし、概念を掴んだ程度。
いちからコードを作ってみたのは、勉強用に、activity のtemplate をちょっといじっただけのアプリをビルドしたことはありました。

それくらいの初心者感です。

# 技術的なメモ（感想）
## Android Studio
Android Studio をインストールしたのは通算で五回目くらいだと思うのですが、毎回変わっている気がしていつも困ります。今回はAVD Manager の場所が変わっていて、見つけるのに割と時間がかかりました。アプリ開発を始めるには、エミュレータのインストール、gradle sync、manifest など、相変わらず初心者にはハードルが高いなあと思います。
また、以前からLayout のGUI エディタがずっと苦手で、今回は新規アプリだし頑張ろうと思ってました。しかし、またしても挫折してしまいました。

## 言語 (Kotlin)
現在の仕事でも使っているKotlinを採用。コードは少ないし書きやすいと思います。Android に関する技術ブログなどは当然 Java がサンプルになっているものがまだまだ多いので、プログラミング学び始めで Android 開発をする人は苦労しそうだなーと。
公式ドキュメントやググって出てきた Java のコードをはっつけるときは、当然 IDE の変換機能を使います。単に貼り付けるとよくエラーが出ますが、そのときに、IDE の変換能力の問題ではないと強く信じることが大切だと学びました。なぜかというと、よく考えれば、名前の間違いか、挿入場所を間違えてることがほとんどだからです。

## Jsoup
適当にググって出てきたので使いました。なので、定番かどうかは分からないです。

ページのロードも簡単にかけたし、DOM 操作も JavaScript ライクに簡単に書けたので良かったです。

## TextToSpeech
読み上げを Start させてから状態変化によって呼ばれる callback を登録することができます。

エラー時に呼ばれる `onError` が二つあって、 `errorCode` が受け取れる方と受け取れない方があるのですが、なぜか `errorCode` が結局受け取れず、ここはまだうまくいっていません。

実装当初はエラーが発生して読み上げてくれないことがたくさん起きたのですが、おそらく読み上げできない文字列を含んでるんだろうと予測し、行を句点でひたすら分割することで乗り気っています。分解すると

- 読み上げたい文章を文字列の配列にして、一文ずつ渡す
- 現在読んでいる文のインデックスを外の変数に保持
- TextToSpeech に登録した finish のcallback がインデックスを一進める
- そのインデックスの文をまた読み上げる

ということをしています。どっかで詰まりそうなんですが、なぜか今のところきちんと回っています。気づいていないだけかも。

# その他
## Wikipedia の HTML
今回のアプリを作った視点からいうと、HTML の構造化が思ったよりもされてなくて面倒でした。MediaWiki? の何かがアップデートされてらすぐにこのアプリは動かなくなってしまいそうです。まあ、こんな用途に向けて作ってないと思うので、文句言う筋合いはありません。

## ストア公開観点
個人的にはアイコンが一番のハードルなのでやってないです。加えてデザインとか、複数の Android バージョン対応とか。個人開発で公開までやる人は尊敬します。
Terraform で CodePipeline を管理する場合の注意点

CodePipeline を作っていてでハマったことの備忘録。

## Terraform で管理する場合の注意点

* OAuth Token の差分が plan/apply のたびに発生する
    * API get-CodePipeline が OAuth Token を取得できないため、Terraform や他のどんなツールを使っても冪等にできない
        * `aws codepipeline get-codepipeline` を実行すると、 `****` という表示になって隠されている
        * 根本的な解決方法がなく、今も Open Issue になっている[\[1\]][1]
* GitHub webhook も定義する場合は、GitHub で発行した OAuth Token の scope に `admin:repo_hook` も必要[\[2\]][2]
* GitHub webhook は update できない
    * 一度作成したリソースを修正したい場合は、 taint してから apply する
* Custom Action を定義できない
    * これも API の制約で、 custom action を updade/get する手段がなく、 create/delete をする手段しか提供されていないため、どんなツールを使っても冪等に保つことができない
    * ユースケース) Action Provider に Jenkins Custom を定義する場合など
    * したがってコンソールか CLI をつかって定義することになる


## AWS Console or CLI で管理する場合の注意点

* AWSコンソール上から作業できないワークフローがある
    * (GitHub など外部の CVS の) OAuth トークンの登録 [\[3\]][3]
* 裏で暗黙的に作成されるリソースがある
    * GitHub webhook
        * GitHub のリポジトリに push されたときに AWS の Webhook 用エンドポイントを呼び出すためのもの
    * CodePipeline の webhook
        * GitHub => AWS CodePipeline を起動させるための Webhook エンドポイント
            * `https://codepipeline.ap-northeast-1.amazonaws.com/...`
        * `aws codepipeline list-webhooks` で確認できる。試行錯誤しているとゴミが残りがち

## 共通の注意点

* CodePipeline の定義を更新すると、実行中の action はすべてキャンセルされる
* (定義を変更せずに) CodePipeline で実行中のアクションを中止する方法はない
    * アクションを中止したい場合は CodePipeline の定義を変更する[\[4\]][4], [\[5\]][5]


## 参考

* [\[1\] https://github.com/terraform-providers/terraform-provider-aws/issues/2796][1]
* [\[2\] https://developer.github.com/v3/repos/hooks/#create-a-hook][2]
* [\[3\] https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/GitHub-create-personal-token-CLI.html][3]
* [\[4\] https://stackoverflow.com/questions/50925732/how-to-stop-an-execution-or-set-set-timeout-for-an-action-in-aws-codepipeline][4]
* [\[5\] https://qiita.com/hareku/items/90ed026256242c65e178][5]

[1]: https://github.com/terraform-providers/terraform-provider-aws/issues/2796
[2]: https://developer.github.com/v3/repos/hooks/#create-a-hook
[3]: https://docs.aws.amazon.com/ja_jp/codepipeline/latest/userguide/GitHub-create-personal-token-CLI.html
[4]: https://stackoverflow.com/questions/50925732/how-to-stop-an-execution-or-set-set-timeout-for-an-action-in-aws-codepipeline
[5]: https://qiita.com/hareku/items/90ed026256242c65e178
Amazon版でもアプリを出したいからQA？

### 1. はじめに
全てを知っているわけではないので憶測にはなりますが、新規アプリをリリースする際に、**Amazon版**にまで対応し、リリースをすることは少ないんじゃないかと思います。
iOS/Android版をリリースしてから運用フェーズで
「ちょっとAmazonでアプリを出したいんだけどQAしてくれない？」
と後追いでQA依頼され、困った経験から記事にしようと考えました。

同様の経験をされる方もいるはずなので、少しでもQAのお役に立てるよう、基本的なところ中心となりますが参考になればいいなと思います。

### 2. Amazon版QAについて
まず既にアプリはリリースされてるものとすると、リリース時同等の既存機能のチェックはする必要がないかなと思います。(このあたりはエンジニアさんとすり合わせを行いましょう！)
ですので、今回は下記の箇所をお話できればと思います。
・インストールについて
・課金検証
・その他
#### 2-1. インストールについて
まずAmazon版作業の際、最低限必要なものは下記となります。
**【Amazonアカウント】**
・Amazonのサイトからアカウント作成を行います。(手順は特に特殊なことはしないので割愛いたします。
・アカウントを端末に紐付けると「XXさんの1台目の端末」等表示されるので、アカウントの共用などは注意が必要です。
・最低でも2アカウント作っておくと便利です。

**【Amazon端末】**
・[Kindle端末](https://ja.wikipedia.org/wiki/Amazon_Kindle)を用意しましょう。
・Kindle端末は1GB未満の端末があるので、**もともとのアプリが低スペックに対応しているかがかなり重要です!**
していない場合、16bit対応を入れたり負荷対策を行う作業が発生します。

Amazon版アプリをインストールできる端末は主に**Kindle端末**と**Android端末**です。
なのでAndroidでの確認も必要と思うのでお忘れなく。

▼Amazon版インストールについての注意
< Kindle端末 >
　・QAを行う開発ビルドは必ず[ライブアプリテスト](https://developer.amazon.com/ja/docs/app-testing/live-app-testing-getting-started.html)からダウンロードしてください。
　　※テストの際に新規でテスターに登録された場合は、送られてくるメールからWeb上で利用規約に同意する必要があります。
　　![6404466-c24fbaa66fe81810deb26f6d2f63cdf51ab779e1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542716/91b95603-72ef-9318-7936-bc0047f016ad.png)
　　※アプリについてはリモートインストールも可能です

< Andoroid端末 >
　・Amazon App Storeアプリをインストールしてください。
　　・ブラウザで「Amazon App Store」と検索すると出てきます。Play Storeからインストールではないので注意が必要です。
　・Amazon App Storeアプリで「Amazon App Tester」を検索しインストールしてください。
　　・開発環境のアプリを使用する際に、このアプリが入っていないと起動できませんでした。。。

#### 2-2. 課金検証
課金の根幹処理的な部分はそれぞれ異なってくるので、
基本的なことは[こちら](https://developer.amazon.com/ja/docs/in-app-purchasing/iap-testing-overview.html)から確認するのが良いかなと思います。
ここでは実際やってみて、知らなかったこと等記載しようと思います。

・クレジットが紐付いたAmazonアカウントは必要無いが、アカウントに住所登録が必要となります。(請求書がちゃんと届くかどうか)
・課金する際はアプリストアを開きアプリストアライブラリを開いて該当アプリに「アプリテストからダウンロードされてません」のような注意書きがないか確認します。
　※注意書きが表示されていると、そもそも課金アイテムが表示されない場合があります。
・引き継ぎの際の有償通貨、無償通貨を引き継ぐかどうかの対応は、担当者に確認しましょう。
　**※AndroidとAmazon間は引き継ぐのかとかはしっかり聞いたほうが良いです。**
・海外のアイテムリストは韓国語、繁体字の対応がありませんでした。(テスト時：2018/06当時)
・テスト用の課金アイテム設定はくれぐれも本番に出ないように注意しましょう。

#### 2-3. その他
そもそもRAMが1GBの端末に対応していない場合は低スペック端末用の対応が必要になり
Amazon版のみならず、Android版にも影響が及びます。

・AndroidのOS別(対応しているもの)に、全機能を回っての基本挙動確認

影響範囲の確認として、上記対応を実施しました。
QAのみならず、画像系の変更や起動フローの変更など
不具合修正の影響が大きくなる場合、気づくのが遅れることでスケジュールを圧迫するため、早めに確認しておきましょう。

### 3. 最後に
私が経験した中には、特に大きな障害につながるものはありませんでしたが、
思ったよりも確認することは多く、出したいからホイっと出せるレベルでは無いなと感じました。
QA側でもAmazonアプリの仕組みを理解しつつ、チェックを行えれば品質としてより良くなります。
今回既にアプリがある状態から追加でAmazon版を出した経験で話しましたが、
完全新規でAmazon版を出す際のナレッジはないので、その時はまたTry&Errorしていこうと思います。
Spring-Batchのテストでハマった

# Spring-Batchのテストでハマった

## ハマった内容

- あるバッチにパラメーターを与えて実行する
- １回目は成功するのだが、２回目以降は実行できない

## ハマりの原因

- Spring-Batchにはジョブの実行結果を保存しておく機能がある
- ジョブ成功後に前回と同じパラメーターを与えて実行することはできない
  - [Spring Batch - Rerun Job with same Job Parameter
](https://stackoverflow.com/a/44432024/2565527)

```
Going by the concept of Job Instances and Job Executions in Spring Batch, 
you can't start a COMPLETED job instance again 
though you can launch same instance of job again & 
again till its not COMPLETE ( and few more job statuses ).

Job instance uniqueness is achieved by jobId & job parameters
```

- 別のエラーメッセージが表示されるためにこの話までたどり着くのに時間がかかった
- ~~なんだこのクソゴミ機能は…~~ 素晴らしい機能ですね
mockmockでmockの状態遷移をしてみる(上級編)

こんにちは、mockmockチームエンジニアのジホです。

## この記事は
mockmockアドベントカレンダー 20日目の記事です。
mockmockで複数のmock状態を連携させて遷移する方法をまとめます。

## やりたいこと
`指定時間経過による遷移`、`指定回数送信後による遷移`、`確率による遷移` を連携して状態遷移します！

## 手順
### プロジェクトを作成は[mockmockでmockの状態遷移をしてみる(初級編)](https://qiita.com/cheekykorkind/items/d26551b60109b78d1cdd)参考お願いします！

### mockステータスを設定の詳しい内容は[mockmockでmockの状態遷移をしてみる(中級編)](https://qiita.com/cheekykorkind/items/ab54f1f87dca61b324bc)参考お願いします！


### 構成した状態遷移図の説明
- `start_status`から5秒がすぎたら、`status2`に遷移します。
- `status2`から2回作業実行したら、`startu3`に遷移します。
- `status3`から70%の確率で最終状態である`terminate`に遷移します。または30%の確率で`startus2`に戻ります。
![statusIndex.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/093bab2d-9e1e-ca21-4d19-ad623f951859.gif)

### 初期状態`start_status`
5秒が過ぎたら2番目の状態`status2`に遷移するように設定しました。
![startStatus.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/ceba49a9-bcf1-ec3c-aae7-3d5c144e5b52.png)

### 2番目の状態`status2`
2回作業実行後、`status3`に遷移するように設定しました。
![startus2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/e4becd12-9e64-657c-eef3-8c11515fdea6.png)

### 3番目の状態`status3`
70%確率で`terminate`に、30%確率で`status2`に遷移するように設定しました。
30%にずっと当たるとぐるぐる回りますね。
![startus3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/7c9b471d-f364-0499-807f-7407d0715a8c.png)

## 結果を確認
`start_status`が5秒の間1回送信、その後`status2`が2回送信、その後、`status3`で70%の確率で`terminate`になりました。 
![result.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247584/ae4993d8-00a8-cb94-06df-c2a433d270f5.gif)




## まとめ
本記事では、mockmockで複数のmock状態を連携させて遷移する方法を作成しました。
複数のmock状態をいろいろ組み合わせると面白い状態を作れると思います。ぜひお試しください！

明日は @yukabeoka が `mockmockで大量のmockを一度に登録してみる` をご紹介します。


## 参考
https://console.mock-mock.com/docs/tutorials/simple_data
https://qiita.com/cheekykorkind/items/d26551b60109b78d1cdd
https://qiita.com/cheekykorkind/items/ab54f1f87dca61b324bc
シェルスクリプト 引数を扱う特殊パラメータ

結論：引数の受け渡しには、"$@" を使用するべき。

##### "$@" と $@ の比較
```bash:example1.sh
echo '[Case of "$@"]'
for arg in "$@"
do
  echo "$arg"
done

echo '[Case of $@]'
for arg in $@
do
  echo "$arg"
done
```

abc 'hello shell' '\*' と3つの引数を与えて実行します。
"\$@" では、意図したとおり、3つの引数が順に出力されています。
$@ では、'hello shell' が 'hello' と　'shell' の別々で出力されており、さらに '\*' がカレントディレクトリのファイル・ディレクトリの一覧を表示させるためのパスとして展開がされてしまっています。

```bash:result1.sh
$ ./example1.sh abc 'hello shell' '*'
[Case of "$@"]
abc
hello shell
*
[Case of $@]
abc
hello # hello shell が分断
shell
Downloads # * が展開され、カレントディレクトリ内のファイル・ディレクトリが表示
Documents
```

##### "$\*" と $\* の比較
```bash:example2.sh
echo '[Case of "$*"]'
for arg in "$*"
do
  echo "$arg"
done

echo '[Case of $*]'
for arg in $*
do
  echo "$arg"
done
```
同じく abc 'hello shell' '*' と3つの引数を与えて実行します。
"\$\*" では、すべての引数が1つにまとめられています。
\$\* では、$@ と同じく、'hello shell' が 'hello' と　'shell' の別々で出力されており、さらに '\*' がカレントディレクトリのファイル・ディレクトリの一覧を表示させるためのパスとして展開がされてしまっています。

```bash:result2.sh
$ ./example2.sh abc 'hello shell' '*'
[Case of "$*"]
abc hello shell * # すべての引数が1つにまとめられた
[Case of $*]
abc
hello
shell
Downloads # * が展開され、カレントディレクトリ内のファイル・ディレクトリが表示
Documents
```

すべての引数を echo する程度であれば、"\$\*" は便利かもしれませんが、基本的に引数を渡したりするには、"$@" を使うのが一般的なようです。
[Ansible] CoreOSに対してplaybookを実行する前に必要なこと

この記事は[Fringe81アドベントカレンダー2019](https://qiita.com/advent-calendar/2019/fringe81)の19日目の投稿です！
最近Ansibleを触る機会をいただいたのでその時に調べたことを書きます！

## Ansibleとは？
レッドハットが開発するオープンソースの構成管理ツール。
特徴を簡単にまとめると以下の3つです。

- Simple: ymlファイルで設定が読みやすい。
- Agentless: サーバー追加ごとにエージェントを追加する必要がない。 
- Powerful: モジュール群が豊富。

コントロールノードにAnsibleをインストールしファイルを用意するだけでコントロールノードからターゲットノードに対してSSH経由でタスクを送信することができます。(プッシュ型)

## CoreOSにplaybookを実行するときの注意点
CoreOSに対してplaybookを実行させたときにうまく動作しなかったので、いろいろ調べていたら、以下の一文を発見しました。
http://coreos.com/blog/managing-coreos-with-ansible.html


>　The target machine must have a Python interpreter for Ansible to be able to execute these modules and thus configure your machine.

> CoreOS is designed for running containers and does not ship with a Python interpreter. Additionally, it has no package manager to install Python. This presents a small chicken-and-egg problem.

> Luckily Ansible has a raw execution mode which bypasses Python modules and runs shell commands directly on a remote system. We will leverage this feature to bootstrap a lightweight Python interpreter onto our CoreOS hosts.

### 訳してみる
「ansibleではmoduleを実行するためにターゲットノードにpythonがインストールされている必要があるが、CoreOSはPythonが入っていないしPythonをインストールするためのパッケージマネージャーが存在しない。ただ、AnsibleにはPythonモジュールをバイパスし、リモートシステムでシェルコマンドを直接実行するraw実行モードがある。この機能を利用して、軽量のPythonインタープリターをCoreOSホストにブートストラップすることでmoduleを実行することが可能となる。」

途中ちょっとよくわからんとこあったけど `PythonインタープリターをCoreOSホストにブートストラップする` 必要があることはわかりました。笑
Blogにしたがって次の3つの手順でやることでCoreOSに対してplaybookを実行することができました！


### 1. inventoryファイルの `vars` に以下の項目を追加

```yml
[hoge]
core-01

[hoge:vars]
ansible_ssh_user=core
ansible_python_interpreter="PATH=/home/core/bin:$PATH python"
```


### 2. role: coreos-bootstrapをコントロールノードにinstall

```
$ ansible-galaxy install defunctzombie.coreos-bootstrap -p ./roles
```

### 3. playbookにroleを追加

```yml

---
- hosts: hoge
  gather_facts: False
  roles:
    - defunctzombie.coreos-bootstrap

```




### [おまけ] CoreOSのhostにdockerコマンドを実行したい時
ターゲットノードに対してdockerコマンドを実行したい場合はdocker-pyを対象のCoreOSにインストールするtaskを追加する必要があります。

```yml
- hosts: hoge
  gather_facts: False
  tasks:
    - name: docker-pyのインストール
      pip:
        name: docker-py
        executable: "/home/core/pypy/bin/pip"
```

## 参考文献
- http://coreos.com/blog/managing-coreos-with-ansible.html
- https://github.com/defunctzombie/ansible-coreos-bootstrap
github-pageにReact appをデプロイしてみた

## はじめに
Reactを勉強する上でGithub pageでReactアプリを公開できるのか気になったのがきっかけです。
> GitHub Pagesについて
> GitHub Pages は、GitHub のリポジトリから HTML、CSS、および JavaScript ファイル を直接取得し、任意でビルドプロセスを通じてファイルを実行し、ウェブサイトを公開できる静的なサイトホスティングサービスです。
> [GitHub 公式ヘルプ]https://help.github.com/ja/github/working-with-github-pages/about-github-pages


## 参考にしたサイト
- GitHub PagesにReactアプリをデプロイする方法 
 https://qiita.com/yuitnnn/items/11375ea29ec023d19fdf  
- React公式(INSTALLATION>新しいReactアプリを作る)  
https://ja.reactjs.org/docs/create-a-new-react-app.html  

## 環境
以下は私が行った環境です.

|name|version|
|:--:|:--:|
|Node|v10.14.2|
|npm|6.4.1|

2019/12/19現在ではReact公式サイトに
  
> あなたのマシンに Node >= 8.10 及び npm >= 5.6 の環境が必要です　　　　

と記載されていました.

## 手順
### 1.Reactアプリの作成
以下のコマンドを実行しました.  
今回は`react-pages`という名前のReactアプリを作成しています.

    $ npx create-react-app react-pages

### 2.gh-pagesのインストール

以下のコマンドで`gh-pages`をインストールします。
以下のコマンドでは`cd react-pages`で作成した`react-pages`フォルダまで移動し`gh-pages`をインストールしています。

    $ cd react-pages
    $ npm install gh-pages --save-dev

##### npm
Node.jsで利用するパッケージ管理ツール

##### gh-pages
GitHubのgh-pagesブランチ（または他の任意の場所）にファイルを公開するためのパッケージ

### 3.Reactアプリのpackage.jsonを修正
作成したReactアプリのpackage.jsonに以下の設定を追記してください.
ここで`"homepage"`に書いてあるURLの`[GitHub username]`,`[created repository name]`はそれぞれ自分が作成した名前をつけてください

```package.json

//...
"homepage": "https://[GitHub username].github.io/[created repository name]/",
"scripts": {
    "deploy": "npm run build && gh-pages -d build"
  },
//...

```

### 4.GitHubでRepositoryを作成
このときのリポジトリの名前は作成したReactアプリと異なっていても大丈夫です  
また、GitHubがPROアカウントではない場合はPublicでRepositoryを作成してください。

### 6.作成したアプリをデプロイ
以下のコードでデプロイします。また,実行する場所は作成したReactアプリ内で行ってください.以下の前半部分はリポジトリを作成したときに出てくる任意のフォルダーとリポジトリを接続し`README.md`をリポジトリへ追加しているものです.

    $ git init
    $ git add README.md
    $ git commit -m "first commit"
    $ git remote add origin 
    $ git@github.com:[GitHub username]/[Repository name].git
    $ git push -u origin master
    $ npm run deploy

### 5.GitHubPageの設定
作成したGigHubのリポジトリよりsettingへ移動,

![Screenshot from 2019-12-19 21-50-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/06554ff9-ccbf-88d0-9cdd-ec4ef7e919b6.png)

その後下へスクロールしGitHub Pages のSourceをgh-pages branchへ変更する.

![Screenshot from 2020-01-02 11-15-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/30561c64-237d-54c2-a908-0f1399d9ac2c.png)

## 結果
GitHubPages設定後表示もう一度GitHubPagesの設定場所へ移動し表示されているURLをクリック.  
以下のようなページが開かれていれば成功です.

![Screenshot from 2020-01-02 11-15-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256678/a8cafc58-5334-c76d-ea7a-c22dc7662da9.png)


## 最後に
デプロイの意味とか全然しらない初学者(私)でもちょっと調べたらできるもんだなぁと感激しました。
積極的にいろんなことにトライしてみようと思いました。
次はReactをつかって自分のポートフォリを作りたいと思います。
光彦「ボクなら自己紹介で犯人わかりますよ！」

# プロローグ
みなさんこんにちは。
今日は、ボクが考えた事件解決の助けとなる画期的な発明を紹介したいと思います。
それは…事件が起きる前の容疑者たちの会話を集めて、犯人と被害者を予測するシステムです！
AIについてはまだよくわからないけど、少年探偵団に不可能はありません！

# 目的
* 事件が起きる前に犯人と被害者を予測する

# 条件
* 対象とする事件は殺人事件
* ストーリー開始から事件が起きる前までの会話から犯人と被害者を予測する

# システム概要
* 言語はPython
* 機械学習に使うライブラリはkeras
* 形態素解析エンジンはjanome

# 実装の流れ
システム作成の手順を簡単に説明します。

* データ収集
コナンの単行本からひたすらデータを収集します。
事件が起きるまでの会話を全部拾うのはきつかったので、吹き出し10個分を学習データとして利用することにしました。
また、会話に登場する人物名が判定に影響を与えないように、全ての人物名を「田中」に変換しました。

* 形態素解析
収集したデータは日本語の文章となりますが、このままでは学習データとして使えないためデータ処理を行っていきます。
文章を単語区切りにすることで、このあと登場するベクトル化を可能にします。
例えば「すもももももももものうち」を「すもも/も/もも/も/もも/の/うち」のように区切ります。

* ベクトル化
janomeのdoc2vecを利用して文章をベクトルデータに変換します。
文章データを数値で表現することで、学習データとして利用できるようになりました。

* 学習
出来上がったベクトルデータに「犯人/被害者/一般人」のラベル付けを行い、学習を行います。

# 結果
学習データに対しては100%近い精度となりましたが、新規データへの精度はほとんど出ませんでした。

* 敗因：学習データが圧倒的に足りなかったです(28個)
 * 単行本の内容を手打ちでデータ化するのは思ったより大変な作業でした
 * 投稿日がせまってたので妥協しました
 * 漫画読むの優先した

よく言われますが、機械学習で一番大変なのは学習データを集めることです。
こんなことがしたい！と思ったときにすぐにデータが手に入ることは稀だと思うので、普段からデータにアンテナを張っておくことが大切だと思いました。
# おまけ
いろんなキャラクターのセリフを判定してみた結果です。
左から順に[一般人 被害者 犯人]の確率です。

* 吾輩は猫である
 * [0.506109   0.47779834 0.01609264]
* オッス！オラ悟空
 * [0.7559725  0.22846058 0.01556693]
* 僕ドラえもん
 * [0.6403506  0.3441662  0.01548317]
* 東中出身、涼宮ハルヒ。ただの人間には興味ありません。この中に宇宙人、未来人、異世界人、超能力者がいたら、あたしのところに来なさい。以上。
 * [0.2473547  0.69323796 0.05940729]
* 僕は新世界の神となる！
 * [0.28107646 <font color="Red">0.70111287</font> 0.01781074]
* あきらめたらそこで試合終了ですよ
 * [0.63113874 0.34889922 0.01996207]
* 何の成果も!!得られませんでした!!
 * [0.46731383 0.48855832 0.04412784]
* たった一つの真実見抜く、見た目は子ども、頭脳は大人、その名は名探偵コナン！
 * [0.50221133 0.47582945 0.02195918]

ほとんど一般人か被害者の確率にかたよってしまいました。
犯人の確率は高くても6%と低いですね、もしかしたら派手なセリフは犯人ではないと学習しているのかもしれません。

被害者の確率が最も高かったのはキラの「僕は新世界の神となる！」でしたね。

## 結論
夜神ライトは死ぬ
EC2とロードバランサでwebサービスを公開する

## はじめに
学生がAWSからサーバを借りてウェブサービスを公開する時、EC2 + 固定IPで公開する場合が多いかと思います。
ですが、AWSにはELB（Elastic Load Balancing）というサービスがあり、後述する理由でそれを使う方が良いです。せっかくなので，使ってみましょう
ここでは、EC2単体ではない一歩進んだWebサービス公開の方法を紹介します。



## ロードバランサ設置のメリット
WEBサーバが1台でもELBをおいた方がいい理由はこちら書かれています
- https://dev.classmethod.jp/cloud/aws/benefit_elb_with_one_ec2/

負荷分散目的で設置されるロードバランサですが、次の理由でサーバが1台でもロードバランサを設置した方が良いらしいです。

- インスタンス(仮想マシンのこと)の差し替えが容易
- ELB(ロードバランサのこと)のヘルスチェックで死活監視が可能。別のサービスで通知も可能に
- 無料SSL証明書（ドメイン証明書）が利用できる
- などなど

## AWSアカウントの準備
これまでは、クレジットカードが無ければAWSのアカウントを作ることはできませんでした。
でももし、あなたが学生ならば[AWS Educate](https://aws.amazon.com/jp/education/awseducate/)で、クレジットカード不要で無料枠のサービスを使うことができます。


## EC2インスタンスの準備
1. AWSのEC2コンソールを開く
2. 「インスタンスの作成」をクリック!
    ![スクリーンショット 2019-12-19 13.00.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355869/8254fc31-2945-0894-9bd6-74ef8b564f02.png)
3. 無料枠で使えるインスタンスを選択(ここでは、Amazon Linux 2 AMI (HVM), SSD Volume Type)
![スクリーンショット 2019-12-19 13.02.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355869/47abd5b2-f641-adff-ca1d-d8f18a9546a3.png)
3. インスタンスタイプはここではt2.microを選択
![スクリーンショット 2019-12-19 13.04.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355869/9d7f597b-d6b6-9a65-246b-9eff0e64ca29.png)
4. 次のステップはデフォルトで「次のステップ： ストレージの追加」をクリック
5. ステップ4: ストレージの追加 も設定はデフォルトで「次のステップ： タグの追加」をクリック
6. 以下のタグを設定したうえで、「次の手順: セキュリティグループの設定」をクリック

| キー | 値 |
|:--|:--|
| Name | (任意の名前) |

6. セキュリティグループの設定を以下のようにする(ルールの追加で追加できる)
   セキュリティーの警告が出るかもしれないが、「起動」を行う

|タイプ|プロトコル|ポート範囲|ソース|
|:-:|:-:|:-:|:-:|
|SSH|TCP|22|0.0.0.0/0|
| HTTP | TCP | 80 | 0.0.0.0/0 |

7. 新しいキーペアの作成で、SSHのためのキーペアを作成するを選択し、インスタンスを作成

## ロードバランサの設置
1. EC2コンソールを開く
2. 左側のメニューバーから「ロードバランサー」選択
3. 「ロードバランサーの作成」を選択する
4. 「Application Load Balancer」の「作成」をクリック
5. 名前は何か任意につけ、「リスナー」でHTTP 80番ポートとなっていることを確認。アベイラビリティーゾーン(AZ)では、先ほどのEC2があるところを選択。進むわからない場合はあとでも追加できるのでとりあえずどれかを選択。「セキュリティグループの設定」をクリック

6.「新しいセキュリティグループを作成する」 を選択し、任意のセキュリティーグループ名と、次のように設定し、「次の手順: ルーティングの設定」 をクリック

| タイプ | プロトコル | ポート範囲 | ソース |
|:--|:--|:--|:--|
| HTTP | TCP | 80 | 0.0.0.0/0 |

7.以下のように設定し、残りの設定はデフォルトのままで、「次の手順: ターゲットの登録」をクリック 

| ターゲットグループ | 名前 | ターゲットの種類 |
|:--|:--|:--|
| 新しいターゲットグループ |先ほどのセキュリティーグループ名|インスタンス

8.最初作ったEC2インスタンスを選択し、「登録済みに追加」。次の手順に進む
9 「作成」!

## サーバーアプリケーションのインストール

1. 先ほど作ったインスタンスにSSH接続
   - 「EC2ダッシュボード」->「接続」にssh接続の方法が書いてあります
2. 以下のコマンドでApacheをインストール・再起動

```
sudo yum -y install httpd
sudo service httpd start
```
## アクセス
3. まずはEC2のパブリックIP(EC2コンソールから確認)にアクセスしてみましょう
4.  次にロードバランサのDNS名でアクセスしてみましょう
5. `/var/www/html/`が公開ディレクトリです.何か置いてみましょう

## Route53を使用してELBにドメインを設定
というのをしたかったのですが、学生用のAWS Educateでの、Route 53で発行できる無料の新規ドメイン名がわからなかったので、やっていません。


## 終わりに
N番煎じだったり、セキュリティのあたりなど様々な設定をもっとしていかないといけないと思いますが、ひとまず一連の流れはこのようになります。
アイカツカードを読み取れ...!!!

##はじめに
- こちらの記事は[アイカツ！ Advent Calendar 2019](https://adventar.org/calendars/4521)の19日目の記事となります。SHINING LINE*をまた繋ぎます。よろしくお願いします。
- 公開が大幅に遅延したことをお詫び申し上げます。
- [前回(15日目)](https://qiita.com/ricotan_aikatsu/items/620fb78e4099847084be)からの続きとなります。まだご覧になられてない方はこちらを先に見るよう推奨します。
- 前日(18日目)の記事はsnofraさんによる[声優歴何年目で「アイカツ！」シリーズの声優になったのかWikipediaをスクレイピングして確かめる](https://qiita.com/snofra/items/f803a8d9149f4c871e6e)です。


##自己紹介と学習している言語

白石莉子と申します。角川ドワンゴ学園N高等学校通学コース代々木キャンパスプログラミングクラスに所属している高校二年生です。高校内では女児向けアニメ同好会を創設し運営をしております。学習言語はPython3です。過去にはHTMLとCSSを触っていました。

##本日のご紹介
- 前回やった事を基にLT資料を作成しました。弊学のプログラミングクラスでは定期的なLT大会が行われており前回のアドベントカレンダーを基に資料を作りましたのでご参考までにお願いします。スライドは[こちら](https://drive.google.com/file/d/1zm5NxybcL6qSsUYI3Pzbt0xYg6TOT2Gu/view?usp=sharing)からお願いします。ソースコードは[こちら](https://github.com/Girls-anime-lover/Aikatsu-QR-Slack-Post-Program)からどうぞ。

##15日目からのアップデート
- コード量を削減し新たなライブラリを使用します。それに伴い最低環境をpython3.5に設定します。
- python3.8の動作確認をしました。

##今後の展開と〆
- 旧カツ対応の兆しがあるが時間が取れるか心配
- 先にBS4をしなければならない
- コードを短縮できる知恵をくれたTAに感謝

マサカリ等御座いましたらコメントを送信していただくかTwiiterまでご連絡をいただきますと助かります。
最後まで見ていただき誠にありがとうございました。

次の日(20日目)はsnofraさんによる[ 「アイカツ！」キャラクター誕生日一覧](https://twitter.com/snofra0415/status/1207841944434442241)です。
Windows 10 proにDocker環境を構築する


# 全体の手順

1. PCスペックの確認
2. Hyper-Vの有効化
3. installerの取得
4. インストール

# PCスペックの確認

1. [Windows] - [設定] - [システム] -[バージョン情報]
2. 以下の条件を満たしていることを確認
    - システムの種類：64ビット
    - エディション： Windows10 Pro 


# Hyper-Vの有効化

1. [コントロールパネル]-[プログラム]-[windowsの機能の有効かまたは無効化] 
2. Hyper-Vを有効にする 
3. PCを再起動する 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239956/1da21051-c370-7c53-2d42-2c1f129eff23.png)

#Docker for windows をインストールする

installerをゲットするにははDocker Hubにログインが必要。
**IDはpublicリポジトリ名と合わせて表示されるので慎重に考えましょう。**

[Docker Hub](https://hub.docker.com/?overlay=onboarding)

アカウントを作成してsign inすると
Docker for windowsのインストール案内がでました。

設定は全てdefaultで進めて、install完了後に再起動。
再起動後にPowerShellを起動し、以下のコマンドを実行

```
docker --version
```

versionが表示されればinstall OKです

# 次回
- Dockerの起動
- コンテナの作成

# 参考リンク
[Install Docker Desktop on Windows](https://docs.docker.com/docker-for-windows/install/)
[Docker for Windowsをインストール](https://ops.jig-saw.com/techblog/docker-for-windows-install/)
Azure FunctionsとIoT Hubを使って下り方向制御(C2D)を実現するとき注意すること


本記事はAzure Advent Calendar 2019の20日目の記事になります。

# Azure IoT Hubと Functionsについて

Azure IoT HubとFunctionsを組み合わせ下り方向通信を行おうとしたところハマったので気を付けなければいけないことを記事にしました。参考になれば幸いです。

## 前提；IoT Hubについて
IoTを活用するために便利なAzureのPaaSとしてIoT Hubというものがあります。
https://azure.microsoft.com/ja-jp/services/iot-hub/
2019/12/20現在、「IoT デバイスと Azure 間の双方向通信を可能にするマネージド サービス」と紹介されています。
プロトコルとして以下をサポートしており、実行するためのSDKやサンプルコードがあらかじめ用意されています。

- HTTP
- MQTT
- AMQP

「双方向」ということなので、Raspberry PiなどのIoTデバイスから発生したセンサー情報を登録することができることは勿論、Azure側にて分析した結果を受信する（下り方向制御）ことができます。単体でデータの整形や処理、分析、可視化は行うことはできません。他のPaaSサービスと組み合わせることによって目的に応じたソリューションを簡単に作ることが出来ます。

## 前提；Functionsについて
IoT Hubと連携をするのに強力なPaaSとしてAzure Functionsというものがあります。
https://azure.microsoft.com/ja-jp/services/functions/
2019/12/20現在、「イベント ドリブン型のサーバーレス コンピューティングにとどまらない優れたプラットフォーム」と紹介されています。
通常仮想マシンを構築するとアプリケーションのインストール作業や、ファイヤーウォールなどのセキュリティの設定や運用のための監視設定などをきめ細やかに行う必要があります。しかしながらFunctionsではそのような複雑な構築や設定を行わず、プログラムを実行してくれる環境を提供してくれます。（俗にサーバーレスといいます。）

# 前提；Functionsにおけるバインドについて
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-triggers-bindings
Functionsを実行するうえ設定しなければいけないのが「トリガー」と「バインド」です。
「トリガー」がきっかけ、「バインド」が他のアプリやPaaSとの接続元／接続先になります。
例えば1分おきにBlob Storageに蓄積したデータをCosmosDBへ登録したい場合、以下のように設定を行う必要があります。

+ トリガー：1分おき(タイマー）
+ 入力バインド：Blob Storage
+ 出力バインド：CosmosDB

ちなみに以下のようにすると、HTTPのRequestに対してResponseを返す簡単なWebアプリができあがります。

+ トリガー:HTTP
+ 入力バインド:なし
+ 出力バインド:HTTP

## Functionsの出力バインドにIoT Hubを設定できない
ここまでの情報をつなぎ合わせるとFunctionsとIoT Hubを使って下り方向の制御を行いたい場合、出力バインドにIoT Hubを設定すれば、Functionsで行った処理結果をデバイスに通知できそうです。
実際以下の通り公式ドキュメントにIoT Hubを出力バインドに対応しており、設定できるサンプルコードも記載されています。
https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#supported-bindings
https://docs.microsoft.com/ja-jp/azure/azure-functions/functions-bindings-event-iot#output

しかしながらこの通りに実行すると、以下のようなエラーが表示されます。

```
Microsoft.Azure.EventHubs: Unauthorized access. 'Send' claim(s) are required to perform this operation
```

# Functionsの出力バインドとしてIoT Hubは対応していない

入力バインドにIoT Hubを設定することはできますが、出力バインドにIoT Hubを設定できないことを以下でMicrosoftのサポートエンジニアが回答しています。

https://github.com/Azure/Azure-Functions/issues/1351
https://social.msdn.microsoft.com/Forums/en-US/a7c9f563-9d7b-4194-b66c-64da30181520/azure-function-output-binding-iot-hub?forum=AzureFunctions

本件については、MicrosoftのContributorが認めており、ドキュメントを改修する予定であることを記載しています。（2019/12/20現在修正はされていないようです。）

https://github.com/MicrosoftDocs/azure-docs/issues/40125


# 下り方向制御を実現するためには

「バインド」を使わず、プログラムの中でIoT HubのC2D(Cloud-to-Device通信)を呼び出すことで実現できました。
具体的には、Functionsの中でSDKをインストールし、IoTHubのデバイスIDにおけるプライマリ接続文字列をプログラムの中に埋め込んでSDK経由でIoT HubのC2Dを実行すると実現できます。
(実現するコード補足予定です…まだ間に合ってないです、すみません)
インフラ更新で困った話（前編）

# はじめに

何の準備もしていなかったので最近の本番対応で困った話をするよ。
書いたら長くなったので今回は事象の説明までにとどめるよ！

今回ご紹介するのは**「インフラ更新」**案件での出来事。
クラウド環境が浸透している最近でもまだまだオンプレミス環境のニーズは多いです。
オンプレの場合、導入するサーバやネットワーク機器のサポート契約を結びます。
このサポート契約が切れるタイミングで機器を入れ替える（リプレースと呼ばれます）のです。
そんな案件で起こったお話。

# プロジェクト概要
とあるお客様でのインフラ更新。
対象はサーバ、L2SW、ファイアウォール。
自社で各機器を構築→お客様環境へ設置　ごく普通のプロジェクトだった。

# 何が起こった？
**ファイアウォールの向こう側へ通信できない。**


ファイアウォールをあまり知らない若手のあなた、大丈夫。
優しい説明に定評のある(?)Easymodeですよろしくお願いします。
ファイアウォールとは境界防御の製品です。なのでLAN・WANなどのネットワーク間に設置します。
![7008.tmp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542198/f559ec93-2e09-9f87-48aa-e89b1969f756.png)

今回構築したサーバはLAN-Bに設置。
そしてLAN-Aの端末たちへ通信できない・・・逆もしかり・・・。
ファイアウォールをまたいだ通信ができないと話にならないシステムだったため解決必須。
100回くらいping打ちました。

# 今回はここまで
何で上手くいかない？と思っている若手のあなた、考えてみましょう。
説明はかなり少なめにしていますが、ネットワークとはどういうものか、
ファイアウォールって何ができるの？どんな機能があるの？
みたいな視点で見るとここが原因かな～と当たりがつくと思います。
ちなみに原因は2つありました。

トラブったときっていつも勉強になるよね。
AWS CLIでAMIリージョン間コピーを行うコマンド

AWS CLIの初期設定は終わっているものとします。

## EC2:インスタンスID確認コマンド
まずはAMIを作成するEC2インスタンスを確認。
### タグ:Name、値がMyInstanceのインスタンスの情報を取得する場合
```
aws ec2 describe-instances --filters "Name=tag:Name,Values=MyInstance"
```
### インスタンスIDを指定して取得する場合
```
aws ec2 describe-instances --instance-ids {instance-id}
```

## AMI作成コマンド
```
aws ec2 create-image --instance-id {instanceID} --name {ami-name} --description {description} --reboot
```
{ami-name}は任意のAMI名。
AMI作成時はデータの整合性を保証するために再起動を行うのがデフォルトの動きになっている。--no-rebootを指定すると再起動しないが、データの整合性は保証されない。
コマンド実行すると新しいAMIのIDが返ってくる。

### AMIにタグを作る
```
aws ec2 create-tags --resources {ami-id} --tags Key={key-name},Value={key-value}
```

## AMIリージョン間コピー
```
aws ec2 copy-image --source-image-id {ami-id} --source-region {source-region-name} --region {region-name} --name {ami-name}
```
コマンドを実行すると新しいAMIのIDが返ってくる。

## AMI一覧確認コマンド
自分で作成したAMIの一覧

```
aws ec2 describe-images --owners self
```

## AMI削除コマンド

```
aws ec2 deregister-image --image-id {ami-id}
```

## 補足
別リージョンのAMIを操作する場合はコマンドに--region {RegionName} を付加しないとエラーとなる（指定しない場合aws configureで設定したデフォルトリージョンとなるため）。
2018年 東京国際ミュージック・マーケットで作った歌詞を動かすシステムの説明

# 概要
以前に開催されたTIMM 東京国際ミュージック・マーケットで歌手の人の映像を作った際に、急遽歌詞を出したいとのことで急いで作った歌詞をポンだし（ボタン押して歌に合わせる）のTouchDesigner作成事例を紹介です。
渋谷で歌っている人の前にスクリーンがあり、透けて見える形の映像でした。

その時に記録用の動画から切り取ったので綺麗な画像ではありませんが手前スクリーンです。
![r_chan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178523/209c61de-1999-9161-cc01-503f139a6755.png)
残念だったのは当日はスクリーンの設営状態が悪くダルンダルンに張られていたので、文字もすべて歪んでしまっています。（歌っているのはあーるちゃんで見えていませんが演奏は服部さんです、今はまったく関係ないですがよろしく＾＾　https://www.youtube.com/watch?v=aJiXpc1lK2k ）

当日ぶっつけ本番だったのでスクリーンが見える位置からMIDIPADでボタンを押して歌詞を進めていました、歌詞を間違えて歌われたりアドリブを入れられると焦ってしまうので落ち着いてボタンを押す必要があります。
#説明するノード
動き部分のノードはこれだけです。(右下のTOPは賑やかしなので今回は説明しません)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178523/d7d73687-099b-db3b-ddd8-3d33476b7c6b.png)
実際に大事なのは左上の table1 DAT と movifilein1 の画像の作り方だけです。

# 実際の動き
![qiita_gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178523/d9003269-96fd-d8f8-4ac4-229601272f6e.gif)
番号を選ぶことで移動します、移動中でも変化可能なので数字を飛ばしても戻しても問題ないです。

#仕組み
1.歌詞を並べた画像を 4096x4096で用意する(サイズは実際には何でもいいですが広すぎると埋めるの大変)
歌詞を並べるときに中心にしたい位置を画像全体の左上をx:0 y:0としてメモ（回転させるなら角度も必要）
2.table1 DATに画像の中心にする座標と角度 スケール(ズームのかわり) を動かしたい順番に書く
3.transformで table1 DATの数値の位置を中心にする
基本的には各種位置データを lag chopで補間していっているだけなので非常に簡単です。

DATはこんな感じです。iが0となっているところは x:2048 y:2048で 4096x4096 画像の中心をtransformの中心にするという意味で angleは45度に回してくださいってことです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178523/3574f5b5-3513-3956-1b78-997796a77733.png)

# 実際に作った歌詞の画像
初期状態の歌詞画像
Indexno:0はDATの最初を選んでいるのと同じなので、画像の中心x:2048 y:2048が真ん中です。angle:45なので画像も45度回転しているのがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178523/72f96fbb-313a-0d86-f88e-8929dd3a1686.png)

Indexno:1はDATの１番を選んでいるのと同じ x:1906 y:1385 anlge:0(まっすぐに戻す) という感じです。
「信じていてほしい」の歌詞が中心で回転していない状態で配置さます、キャプチャのサイズが適当で上にずれていますが実際には真ん中にあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178523/74a7ffb7-14d7-bd89-649e-e59d15e0b875.png)
※説明していませんが、scaleはズームの役割を果たしますので 大きくすると拡大されて小さくすると縮小されます、なので初期状態の時に小さくなっているのは scaleが x:0.5 y:0.5になっているからです。

# ペンギンがいることに気が付いた？
実は元々は歌詞を表示することを目的に考えていたネタではなく、様々な画像を配置したりする仕組みから画像をバンバン動かしていく為に作ってました。画像データなので何でも動かせますよね？
なので、色々と応用できてしまいます。

# ノードの詳細画像
DATからCHOPにして指定された i:番号 をConstant1で選択してます constant1につないでいる lag chopは初期値のまま
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178523/3e650af6-1fcf-c239-1934-c0c336783d53.png)

画像を動かしている部分の Transformノード i:0の場合はこんな数値を設定しています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178523/2fb119b0-7201-3ec6-72e9-826b391aad92.png)

# ファイルは用意できておりません
非常に簡単に出来るのでぜひ頑張ってみてほしいです。
文字単位でスペース区切りにするコマンド

## 問い
文字レベルseq2seqなど、文字列を文字単位で空白区切りにしたいことがある。
いちいちスクリプトを書くのは面倒なので、これをlinuxコマンドでやりたい。
※ pythonでは`' '.join(list(string))`でできる。

```text:input.txt
アンパンマングミRTA (^^)
パッケージ開封から全てのグミを取り出すまでのタイムを計測
オブラート及びグミに傷を付けてはならない
```
```text:stdout
ア ン パ ン マ ン グ ミ R T A _ ( ^ ^ )
パ ッ ケ ー ジ 開 封 か ら 全 て の グ ミ を 取 り 出 す ま で の タ イ ム を 計 測
オ ブ ラ ー ト 及 び グ ミ に 傷 を 付 け て は な ら な い
```

## 答え
`sed`で頑張る。もとからある半角スペースは`_`でエスケープ。

```shell
cat input.txt | sed -e 's/ /_/g' | sed -E 's/(.)/ \1/g' | sed -e 's/^ //g'
```
もうすこし賢い方法がありそう。
【UE4】シーケンスのコマンドライン書き出しの際に、指定したサイズで出力されない時

## 導入

UE4は [動画出力のためのコマンドライン引数](https://docs.unrealengine.com/ja/Engine/Sequencer/Workflow/RenderingCmdLine/index.html) というマニュアルページで、コマンドラインからSequenceを書き出す方法を載せてくれています。

マニュアルに書いてあるサンプルのコマンドを引用しますと、たとえばこちらは、サイズ・書き出しフォーマット指定・クオリティなどを引数で渡して書き出し方法を指定しています。

`"C:\Program Files (x86)\Epic Games\4.##\Engine\Binaries\Win64\UE4Editor.exe" "D:\Unreal Projects\SequencerTestBed\SequencerTestBed.uproject" /Game/TestRender/TestRender_Map -game -MovieSceneCaptureType="/Script/MovieSceneCapture.AutomatedLevelSequenceCapture" -LevelSequence="/Game/Test_Render/Test_Render_SQ" -MovieFrameRate=30 -noloadingscreen -resx=1280 -resy=720 -MovieFormat=JPG -MovieQuality=75
`

引数ごとの説明を読むと横幅は `-ResX` で、縦幅は `-ResY` で指定すると書いてあったので　`-ResX=2048 -ResY=2048` のように画像サイズを指定した引数を渡して書き出しを行ってみると、ディスプレイの最大サイズ？よりも大きいサイズで書き出すことができませんでした。

さきほどのサンプルだと `-resx=1280 -resy=1280` と小文字になっていたので、実はマニュアルが間違えてたのかなと思い小文字バージョンでもやってみたのですが、先ほどと同じく、画像サイズが期待されたサイズにはなりませんでした。

## 解決策

`-windowed` を引数で追加します。

[コマンドライン引数](https://docs.unrealengine.com/ja/Programming/Basics/CommandLineArguments/index.html) というマニュアルを見ると、「レンダリング」という項目があり、その中に`WINDOWED:Window モードでゲームの実行を設定する。`と書かれています。動画出力のための～～のマニュアルにはwindowedのことは書かれていませんでしたが、どうやらこちらのマニュアルも参考にしてオプションを決めてあげる必要があるのかもしれないです。もしかすると、プロジェクト設定やエディタ環境設定周りの設定も関係してるかも？？
Notch Post-FX がプレビューとレンダーで異なる場合の対処法

#経緯
Notch で作業している時、Streaks や Blur など一部の Post-FX で Viewport と実際のレンダーでかかり具合が変わる。
合わないとノート PC の時とかめっちゃやり難い。なんとかならんのかって思ってました。

#こうすればよい
Project -> Settings で設定画面を開き、Rendering タブを開きます。
Output Width, Height はプロジェクトで使う画面サイズを指定します。
そしてここが肝、Output Resizing を Scale / Filter Output To Window にする。
![Notch_OutputResizing2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308950/70f1731e-fed8-c3fe-702b-3e82825729bc.png)

さぁ、F9、F10 連打して確認してみてください。同じになっていると思います。

![Notch_P1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308950/6e8f0a84-7706-955a-e978-b782ce0fab97.png)
![Notch_P2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308950/c1f1a788-7eb6-a5c6-23c5-c1c021b5f4f4.png)

以上、お疲れ様でした。
APIとはどんなものかを理解したので書いてみる

# はじめに
初めまして、わったーと申します！
Qiitaは常日頃から利用させていただいているのですが投稿は初めてということで投稿する側の勝手など至らないところもあるかもしれませんがお手柔らかにお願いします。

この記事を書くに至った動機としては、最近会社の方で大きめなシステムの開発に携わらせていただく機会があり、今まで `API` として解釈していたものが覆ってとても感動したので書かせていただいております。

この記事の対象としては `エンジニアリングを学び始めたばかりでAPIという言葉も知らない人` `APIという言葉は知っているが、深く理解していない人` らへんを想定しています！

# 今までの解釈
今までの `API` に対する自分の解釈としては `アプリケーションの変数名やメソッド名を公開したもの` というものでした。

例えばLINEのMessaging APIであれば、メッセージを送信するメソッド名だったり、LINEの名前が格納されている変数であったり、といった感じです。

# そもそもAPIとは？
`API` とは `Application Programming Interface` の略です。

字面だけだとインターフェースという言葉がなかなか曲者で理解しにくくはありますが、よく耳にするであろう `UI(User Interface)` という言葉とセットにすると理解しやすいと思います。

`User Interface` はユーザーとアプリケーションの接点、すなわちユーザーが操作する場所のことですよね。

これに対して `Application Programming Interface` はアプリとのプログラミングによる接点、すなわちプログラミングによって操作する場所ということになります！

少しばかりロジックがおかしいですがそこはご愛嬌☺️

つまり自分の今までの解釈である `アプリケーションの変数名やメソッド名を公開したもの` というのは間違いではありません。

アプリケーションの変数名やメソッド名がわかっていてアクセスする権限があるのであればコードによってそのアプリケーションを操作することができますからね！

# 真のAPIとは？
「じゃあ一体APIとはなんなんだ」 「お前はこの記事で何を言いたいんだ」っていう話ですよね

随分大げさな言い方ですが `真のAPI` とは `データベースとアプリケーションの間に置かれ、アプリケーションからのリクエストに応じてデータベースからデータを取ってきてアプリケーションに返すもの` のことです！

少し長い説明になってしまったので図で表すと以下のようになります！![20191219_api.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412552/fda7a645-eca7-3ae5-13ee-9fafa35eac85.png)

これを見たら「なんでアプリから一気にデータベースにリクエストを送らないんだ？」と思う方もいらっしゃるかもしれません。

確かにこれが一つのプラットフォーム(Web, iOS, Android)で展開するアプリだったらアプリから一気にリクエストを送る方が手間は省けます。
しかし複数のプラットフォームで展開する場合、データベースとの通信部分を一箇所にすることで複数のプラットフォーム間で通信用のメソッドが統一され、アプリ側ではAPIのURLを叩けばいいだけになるので工数を削減することができます。
また、先に例に挙げたLINEなどのように他のアプリとの連携がしやすくなるというメリットもあります！

ということで今回は `API` とはについてお話しさせていただきました。
ここまでご覧いただきありがとうございます！
自分自身まだまだ未熟なので訂正、指摘等ございましたらコメントにてよろしくお願いします🙇‍♂️
もちろんその他ご意見ご要望ご質問等もお待ちしております！
それではまた次回の記事でお会いしましょう🙌
80点のwebデザインに必要なこと、不要なこと

私は最高のデザインを求めることよりも、使いやすくて結構カッコいいデザインを高速で作ることに興味があります。

またアパレルブランドのサイトなど「魅せる」を目的としたサイトではなく、ブログやサービス紹介、アプリなど「**伝える**」「**使う**」を目的としたサイトを作ることを目的として書いていきます。(魅せるサイトでシステムフォント固定とかあり得ないと思います）

記事は随時更新する予定で、当面はデザイン的なこととユーザビリティ的なことを同じ記事の中に書いていきますが、分量が多くなったら分割するかもしれません。

##必要なこと
####アイコンや画像の雰囲気を統一する
サイト内のアイコンや画像の雰囲気が統一されていると、まとまりが生まれます。
この点、イラストレーターなどで画像が作れる人は強いです。（私は作れません）

また画像やアイコンの色にまとまりを持たせることも重要です。
フリー素材等を使うにしても、雰囲気や色には気を配りましょう。

####ホバー時のエフェクト
リンクをホバーした時に何も変化が無いと、シンプルに使いにくいです。
ちょっと透過度をあげるとか、浮かせるとか、そのくらいの工夫が必要です。
`transition: 0.3s ease-out;`などで、エフェクトがかかるスピードも合わせて指定すると良いでしょう。

####ブラウザ標準のフォーム要素を変更
チェックボックス、ラジオボタン、ファイル選択など、ブラウザ標準のものはダサすぎます。
`label`と擬似要素、javascriptやjqueryなどを使ってカスタマイズするべきです。

####ヘッダーのロゴをリンクにする
ヘッダーのロゴがホーム画面へのリンクになっていないと使いづらいです。

####背景クリックでポップアップを閉じる
ポップアップ、モーダル、ドロワーメニューなどの背景のグレーになっている部分をクリックして閉じることができると使いやすいです。

####住所入力フォームは1つにまとめる
郵便番号上3桁、下4桁、都道府県、市区町村、番地のように細かく分けると使いづらいと思います。
郵便番号、それ以下。くらいに思い切って分けてしまっていいんじゃないでしょうか。
またデザインとは違いますが、郵便番号から住所を自動で判別するようにすると便利です。

##不要なこと
####大部分のアニメーション
アニメーションは、一部の例外を除いてユーザビリティを下げると考えています。
特にスクロールに伴うアニメーション（フェードインやパララックスなど）は個人的に嫌いです。
スクロールのスピードくらい自由にさせてほしいです。

####webフォント
ユーザーにとって一番見慣れているフォントはシステムフォントです。webフォントを使うにしても、見出しなど一部だけでOKです。
（異論が多そうですが、フォントってちゃんと選ぼうとするとやばいくらい奥が深いので。。webデザインの特徴は、フォントに関して80点の選択肢が始めから与えられていることです。）

####複雑なレイアウト
レイアウトを複雑にすると、やってる感は出るかもしれませんが、労力の割にはリターンが少ないです。
[note](https://note.com/)とか[サルワカ](https://saruwakakun.com/)とか、シンプルなレイアウトでもすごくいけてます。

####色をたくさん使う、色の選定に時間をかける
メインカラーを1色決めたら、あとは[配色ツール](http://photoshopvip.net/72189)を使って色を決めましょう。プロに任せるのが一番です。

##できると良いけど大変なこと
####画像の自作
文章より画像の方がわかりやすく伝えられる場面ってたくさんあるわけで、そういった時に画像を差し込むことができるのがwebの特徴の1つなんですけが、なかなか難しいですよね。

##個人的な好み
###好きなもの
####シングルカラム
コンテンツに集中できるので好きです。

###好きじゃないもの
####ハンバーガーメニュー
情報量が多い場合は使わざるを得ない部分がありますが、あんまり使いやすくないUIだと思っています。
タップするまで内容が見えないわけで。
押してほしいボタンは、ナビゲーションなどで常時表示させた方が良いと思っている派。

####目次
記事の目次って無くても良いような。
見出しと太字部分を流し読みすることに慣れているので。
早く本題に入ってくれって思います。
記事が長い場合には有用ですが、そもそも記事をもっと完結にできないか考えたいところ。

###気をつけたいこと
####固定ヘッダー
高さがあるヘッダーを固定してしまうとジャマになってしまいます。

###楽に実装するためのTIPS
グラフのような、データによって高さが変わる要素のことを考える

##その他
ニコニコした顔のマークはかわいい
[UE4]テクスチャインポート時のノーマルマップ判定をすり抜けろ

UE4はテクスチャをインポートする際、
**ある程度自動で適切な圧縮形式**にしてくれます。

例えば、ノーマルマップなんかはその最たる例で、
UE4が「あ、こいつノーマルマップだ」と判断すると、
BC5などのノーマルマップに適した圧縮形式に自動設定されます。
（むしろ勝手に設定が変わってて「？？」となった方もいらっしゃるかもしれません。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/c57a102e-86bb-7b7c-3ac0-594ef4a0c9da.png)




このノーマルマップの判定は、
NormalMapIdentification.cpp内の、
**DoesTextureLookLikelyToBeANormalMap()**という関数で行われています。

中身の実装を見てみると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/2f5ecbe2-c41d-be5a-ad91-7c1e9ae91ecb.png)
なるほど、ピクセルの色からベクトルを出して、
長さがおかしかったり、向きが逆向いてたりするものを判定しているのですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/5c65b5b5-8de5-cdcd-bcf6-f645a138e7a2.png)
そしてノーマルマップなら**大体{0,0,1}の方向を向いているはず**と考えて、
誤差の範囲内であればノーマルマップと見なすと、そういうことみたいです。

##ノーマルマップ判定をすり抜けよう
とはいえ実は、上の判定、
テクスチャの全ピクセルに対して行っているわけではありません。

判定を高速化するため、テクスチャを縦横16分割して**限られたピクセル**だけ判定を行っています。

へえ、なるほど。
であるならば……。

こういう、**判定されるピクセルだけ塗りつぶしたグリッド**を用意すれば……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/ca3ef4a6-a6da-1e91-90fc-853e902f279d.png)
![normal.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/404d326b-07fa-66fa-cf5c-5e8bbc77da68.gif)
なるほど、**ノーマルだと判定されていますね！**

……
……
……
であるならば……。
どんな画像でも上のグリッドを重ねてやれば……、


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/34150178-befd-f239-0337-2d64b9088749.png)
![normal2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/678c5ecb-23c8-6934-85ef-dd58e65eec94.gif)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/53336d46-3485-c774-89c5-8099f4574b27.png)
**本来ノーマルではないおかずさんをノーマルと判定させる**ことが可能ですね！

##高周波ノイズには気をつけよう
上のノーマルおかずさんはあくまでジョークですが、
ノーマル判定が**大体{0,0,1}の方向を向いているはず**という前提で判定されている事は気に留めておいても良いかもしれません。

例えば、以下のテクスチャは一見ノーマルマップに見えますが、
UE4はこのテクスチャをノーマルマップと判定しません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/4a7dd956-b9ff-5290-fc86-d81d1c94f76f.png)
なぜかというと、アップにするとわかるのですが、
以下のようなピクセルレベルの高周波ノイズが入っていると、
**平均値が{0,0,1}の方向から大きくズレてしまう**為です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/58275b98-c5df-b5cc-54e8-1f5a2058c869.png)
UE4のノーマルマップ判定はあくまで簡易的なものです。
自動で判定されていること、判定自体が厳密ではないことを気をつけて、
**正しいテクスチャ圧縮形式を設定**して頂けましたら幸いです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463796/887478cd-1c93-a344-3af2-ef73dea85304.png)
圧縮形式のチェックには**プロパティマトリクス**が便利ですね。



おしまい。
PythonでSelenium動かしてみた

昨年は出来なかったので、今年はやります！
簡単なことしか出来ないけど。。でも、やることに意味があると自分に言い聞かせてます。

# 本題
pythonとSeleniumがやりかったので色々調べた結果、フォームのチェックに使えそうだなと思って試してみました。
以前dockerとSeleniumで試してみましたが、うまく動かなかった苦い記憶もあるけど、せっかくpythonやっているからやってみようで始めました。
必要な物は下記の手順でインストール出来ます。
windowsでしか試していませんが、プラットフォーム関係なく簡単にインストールできると思います。

## インストール手順
### pythonのインストール
https://www.python.org/downloads/
### Seleniumのインストール
コマンドで`pip install Selenium`を実行
### webdriverのインストール
https://chromedriver.chromium.org/downloads

これらを使った結果はこんな感じです。

![search_results.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/91958/4559592f-e68c-7b05-714d-00e60cbccb22.png)

やったことは、inputに入力してボタンを押したときに結果を表示
最初、アラートを使った結果を表示する仕様にしたのですが、実行したらエラーで弾かれてしまった。
解決策は、[【Selenium】 UnexpectedAlertPresentExceptionが出るケースとその対応 - フリーランチ食べたい](https://blog.ikedaosushi.com/entry/2019/01/18/232326)
を参照してDOMに出力するようにしました。

実際のコード

```python
# PythonでSeleniumのwebdriverモジュールをインポート
from selenium import webdriver
//chromeを開く準備
driver = webdriver.Chrome('chromedriver.exeを置いた場所をフルパスで記載')
//アクセスするサイト
driver.get('ターゲットURL')

//name属性で検索
input = driver.find_element_by_name('user_name')
input.send_keys('a')
//IDがtestの要素をクリックさせる
driver.find_element_by_id('test').click()
//結果をpngで保存
driver.save_screenshot('search_results.png')
//ブラウザを閉じる
driver.quit()
```

## 総括
これだけで動きました。良かった。あまりにも簡単に動いたので、よりSeleniumが身近な物になっている感じがしました。
もっと使い方を調べて面倒な検証に役立てようと思います。
TouchDesignerの記事を書きたいけどERRORでGIFをアップできなくて動きが書けない

どうやら初投稿を終えないと画像サイズは 2Mまでと制限されるそうです 
かわりに　ERROR が出てしまいます。

2Mだと説明GIFが投稿できなくて続きが書けないので、いったんこれをアップします。
色んな人がこの記事を書いてると思いますが、一つ目がアップ出来たらすぐ削除しますので許してね。
【ImageMagick】GIFを元にping-pongループしたGIFを書き出す

GIFを元にping-pongループしたGIFを作りたいタイミングがあり、いろいろ調べてみたのですがすぐには分からずちょっと複雑だったので、メモとして残します。

`$ convert input.gif -coalesce -duplicate 1,-2-1 -quiet -layers OptimizePlus  -loop 0 output.gif`