OmniAICreator/Qiita-1.07M huggingface dataset:
【画像処理100本ノックに挑戦】Q.1. チャネル入れ替え

# 使用したライブラリ
[【画像処理100本ノック】独自の画像入出力クラスを作る](https://qiita.com/jajagacchi/items/834e8425b84f94df8a49)

# Q.1. チャネル入れ替え

> 画像を読み込み、RGBをBGRの順に入れ替えよ。

まだチュートリアルって感じですね。

``` c++
int main()
{
	PPM ppm("imori.pnm");
	int width = ppm.Get_width();
	int height = ppm.Get_height();
	PPM ppm2(width, height);

	for(int j=0; j<height; j++)
		for (int i = 0; i < width; i++)
		{
			ppm2(i, j, 'b') = ppm(i, j, 'r');
			ppm2(i, j, 'g') = ppm(i, j, 'g');
			ppm2(i, j, 'r') = ppm(i, j, 'b');
		}

	ppm2.Flush("out.ppm");
	return 0;
}
```
左からそれぞれ入出力です。
![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/95730c93-ceeb-eb72-9a7a-1701776df8be.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/95b360d4-51a0-ad52-3b30-93c5f90be3af.png)
Heroku  に lwc のサンプルをデプロイしてみた

ほんのちょっとだけ試してみたものを載せてみます

## lwc-recipe-oss のクローン
サンプルとしてこれを使ってみます。

1. クローンしてパッケージをインストール

    ```
    $ git clone https://github.com/trailheadapps/lwc-recipes-oss.git
    $ cd lwc-recipes-oss
    $ npm install
    ```
2. ローカルで動かす

    ```
    $ npm run watch
    ```
![lwc-recipe-oss-local.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34297/0fe92aee-d44f-9b3a-4aaf-0feefcc5a7e3.png)

## heroku にプッシュしてみる
レシピにはすでに Procfile があったので、`git init` で Git 管理して動かせば行けそうです。

1. Git 管理の対象とする

    ```
    $ git init
    ```

2. Heroku のアプリを作成する

    ```
    $ heroku apps:create lwc-sample
    ```

3. Heroku のリモートリポジトリに登録する

    ```
    $ git remote add heroku https://git.heroku.com/lwc-sample.git
    ```

    とやったら`fatal: remote heroku already exists.`と出てきてしまっていました。
    すでに登録されているようだったので、気にせず次へいってみます。

4. Heroku にプッシュ

    ```
    $ git push heroku master
    ```

プッシュが終わったら `https://lwc-sample.herokuapp.com/` にアクセスします。

![lwc-recipe-oss-heroku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34297/1c277321-a3b3-d952-cf87-60a10e00ee81.png)

とまあ、本当に試しただけですが、ありもので上手く動きました。
【画像処理100本ノック】独自の画像入出力クラスを作る

# 背景
[画像処理100本ノック](https://qiita.com/yoyoyo_/items/2ef53f47f87dcf5d1e14)が面白そうなのでやってみることにしました。
基本的には配列操作しかしないだろうし、不慣れなOpenCVでやるよりも自分が使いやすいものを使いたい、ということで簡単な画像入出力クラスを作ってみました。

# PPM形式
作るのが簡単なのでPPM形式の画像を扱うことにします。PPM形式の画像は非常に単純な構造をしています。簡単なので説明は省略します。

# コード
100本ノックの画像はJPEGで与えられているので、ImageJを使ってPPMに変換します。PPM形式の仕様を完全に満たすのは面倒なので、ここではImageJでの読み書きに問題がない範囲で実装しました。なので、任意のPPM画像を読み込めるわけではないことに注意が必要です。また、エラーチェックも省略しています。

```c++
#include <iostream>
#include <stdio.h>

class PPM
{
private:
	int width;
	int height;
	int* R;
	int* G;
	int* B;
public:
	PPM(int width, int height)
	{
		this->width = width;
		this->height = height;
		R = new int[width * height];
		G = new int[width * height];
		B = new int[width * height];
	}
	PPM(const char* filename)
	{
		FILE* fp = fopen(filename, "rb");
		char tmp[256];
		fscanf(fp, "%s\n", tmp);
		if (fgetc(fp) == '#')//コメントありの場合
		{
			fseek(fp, -1, SEEK_CUR);
			while (fgetc(fp) != '\n');//読み飛ばす
		}
		else fseek(fp, -1, SEEK_CUR);
		fscanf(fp, "%d %d\n", &width,&height);
		fscanf(fp, "%s\n", tmp);
		R = new int[width * height];
		G = new int[width * height];
		B = new int[width * height];
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				R[i + width * j] = fgetc(fp);
				G[i + width * j] = fgetc(fp);
				B[i + width * j] = fgetc(fp);
			}
		fclose(fp);
	}
	int Get_width() const
	{
		return width;
	}
	int Get_height() const
	{
		return height;
	}

	int &operator()(int i, int j, char rgb)
	{
		if(rgb=='r') return R[i+width*j];
		if (rgb == 'g') return G[i + width * j];
		if (rgb == 'b') return B[i + width * j];
	}
	void Flush(const char *filename)
	{
		FILE* fp = fopen(filename, "wb");
		fprintf(fp, "P6\n");
		fprintf(fp, "%d %d\n", width, height);
		fprintf(fp, "255\n");
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				fputc(R[i + width * j], fp);
				fputc(G[i + width * j], fp);
				fputc(B[i + width * j], fp);
			}

		fclose(fp);
	}

	~PPM()
	{
		delete[] R;
		delete[] G;
		delete[] B;
	}
};

int main()
{
	PPM ppm("imori.pnm");
	
	int width = ppm.Get_width();
	int height = ppm.Get_height();
	PPM ppm2(width, height);
	for(int j=0; j<height; j++)
		for (int i = 0; i < width; i++)
		{
			ppm2(i, j, 'r') = ppm(i, j, 'r');
			ppm2(i, j, 'g') = ppm(i, j, 'g');
			ppm2(i, j, 'b') = ppm(i, j, 'b');
		}
	ppm2.Flush("iout.ppm");

	return 0;
}
```

問題があれば随時修正予定です。
EKSを本番環境で使う上で知っておいた方が良いこと（2019/12/12時点）

# はじめに
この記事はAmazon [EKS Advent Calendar 2019](https://qiita.com/advent-calendar/2019/amazon-eks) 12日目の記事です。 

この記事では実際に本番環境でEKSを使うために検証し、個人的にこれを先に知ってればよかったなと思うことを紹介していきます。これからEKS使う人や、検証中の方に参考になれば幸いです。

# 目次

- IPいっぱい使う問題
- Podごとにセキュリティグループ効かせられない問題
- タグを使ってVPCとかサブネットを認識しようとする問題
- Node "Not Ready"問題

# IPいっぱい使う問題

## aws-vpc-cni-k8s

まず一つ目にIPをいっぱい使う問題を紹介します。そのために前提となる`aws-vpc-cni-k8s`のことを少し説明します。

https://github.com/aws/amazon-vpc-cni-k8s

eksではデフォルトのcniで`aws-vpc-cni-k8s`と言うaws謹製のcniを利用します。このcniの特徴としてPodに振るIPを実際のサブネットで利用するIPを振ることにあります。なのでPodのIPに対して同一ネットワーク内であればIPを参照してPodにアクセスできます。

## セカンダリIPをPodに付与する

Podには実際にサブネットからIPが振られることを説明しました。ではどうやってその機能を行なっているのでしょうか？

AWSではセカンダリIPと言う機能が存在しEC2に複数個のIPを振ることができます。これを使ってセカンダリIPを用意してPodに実IPを振っています。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/MultipleIP.html

## 事前にセカンダリIPを取得する

セカンダリIPはPodが起動する際にサブネットから取得されるわけではありません。インスタンスの起動時にインスタンスタイプによって決められている量のIPを取得します。

https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max-pods.txt

参考までにm5.largeは29個のセカンダリIPを取得すると書いてあります。なのでm5.largeの起動時にプライマリIPで一個、セカンダリIPで29個IPがサブネットから振られることになり、合計30個のIPがサブネットから振られることになります。

## 改善策

https://github.com/aws/amazon-vpc-cni-k8s#cni-configuration-variables

改善するにはcniの環境変数を修正する必要があります。

# Podごとにセキュリティグループ効かせられない問題

次にPodごとにセキュリティグループ効かせられない問題を紹介します。

## セキュリティグループ

AWSではセキュリティグループと言うリソースが存在し、それをec2などのリソースに効かせることでRDSへのアクセスを制限したりすることができます。

AWSを使っていると大抵はRDSとインスタンス間のアクセスをセキュリティグループを用いて制限しているケースが多いです。（個人の観測）

## Podにセキュリティグループがつけれない？

PodはEC2の上で動いています（Fargateを除く）。なのでセキュリティグループは載っているEC2に依存することになります。EKSように管理されたEC2インスタンスにRDSへのアクセスを許可したり、Elasticcacheへのアクセスを許可したりでPodに対して制限をかけることが工夫しない限りできません。

## 改善策

改善策はこれと言うものはまだ見つかっていません。なのでcniのアップデートを待つ、セキュリティグループごとにNodeグループを作る、セキュリティグループに頼らない認証を用いるなどしなければなりません。

（個人的にはコンテナはどこでも動いて欲しいのでセキュリティグループに頼らない方法ができるとエレガントだと思っています。）

## めも

https://github.com/aws/containers-roadmap/issues/177

一応issueは立っているので解決されるんじゃないかなと思います。

# タグを使ってVPCとかサブネットを認識しようとする問題

次にAWSのリソースにつけられるタグを使ってEKSはVPCやサブネットの状態を認識しようとする問題を紹介します。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/network_reqs.html

## "kubernetes.io/cluster/<cluster-name>": "shared"

EKSではVPCとサブネットを認識するために`"kubernetes.io/cluster/<cluster-name>": "shared"`と言うタグをEKSマスター作成時に指定したVPCとサブネットに自動的につけます。

terraformを使っていると勝手にリソースが変更されるのでdiffが出てしまいあまりうれしくありません。

## elbやalbを立てるために

VPCやサブネットの認識の他にもELBを建てて良いサブネットかどうかを判断するためにもタグを必要とします。

https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/load-balancing.html

詳しくは上記のリンクをみてください。

## 改善策

ないです。

タグなのでEKSのことをよくわからない人が勝手に消したりしないように注意することが大事だと思います。（急にELB建てれなくなったとかありそうですね）

# Node "Not Ready"問題

次に紹介するのはNodeがNotReadyになってしまう問題です。以前に[EKS production ready! part1](https://medium.com/@sueken0117/eks-production-ready-part-1-8f08be5f873f)と言う記事をかきそちらで詳しく説明しているのでぜひそちらをみてください、

あらすじだけ説明すると、eviction policyがデフォルトだと設定されてないのでいつの間にかNodeがスケジュール不能な状態に陥ってしまう。と言うものです。

設定しないと割と深刻な状態になるのでぜひ[記事](https://medium.com/@sueken0117/eks-production-ready-part-1-8f08be5f873f)をみてください。



# まとめ

今回EKSを実践的に使う上で知っておいた方が良いことを書きました。他にも色々な問題はあると思いますのでぜひコメントなどで書いていただけると幸いです。

最後に、今回はEKSのあまり良くない点をピックアップしました。ただこのような問題をクリアすればあとは問題なく稼働します。今後ともEKSが発展していくことを楽しみにしています。

Twitter(https://twitter.com/Sueken51)
javaとは

まだまだ根強い活躍の場面が多い、javaについて書こうと思います。

# javaとは
C言語の構文を主に引き継いだプログラミング言語です、

汎用的でOSに依存しないためサーバーサイドでも活躍し
androidやガラケーでもアプリを組むことが可能です。

# javaの開発
開発にはJDK(Java Development Kit)を使用します。
Javaのサイトからダウンロードすることができます。

リンク先: [JDK](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)

# javaのメリット

* 汎用的でOSに依存しない
* オブジェクト指向である
* 処理速度が速い

など大きなメリットが特徴です。

## 汎用的でOSに依存しない
根本的にプラットフォームに依存しないので
OSに関係なく、Windows, Linuxなどで動作させることができる言語です。

## オブジェクト指向である
プログラムの管理を細かくできるので
チーム開発など効率が上がります。

## 処理速度が速い
起動にコンパイルを必要とするコンパイラ言語であるため
RubyやPHP, Pythonといった言語よりも処理速度が速いのが特徴です。

### コンパイラ言語
プログラムをコンピュータが理解できる形式に変換する言語です。
コンパイルする前にソースコードをオブジェクトコードに翻訳しておくため
インタープリタ型言語より早くできます。

### インタープリタ型言語
プログラムを解釈しながら実行する言語です。
しながらなのでコンパイラ言語と比べ若干遅くなります。

# Javaのデメリット

* コンパイル作業のためWebアプリケーションを起動する時間がかかります。
* Eclipse環境で使われることが多いので、事前準備や開発環境の設定多くなります。
* rubyやPHPの台頭も相まって学習環境が少ないです。
あんときの君津のアサ

###ミッション発動
2019年初秋、関東を襲った台風15号19号そして房総豪雨。その3つの自然災害の直後に君津市小糸川流域でのオルソ撮影のミッションが招集された。

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/ad4cd790-6d5a-035a-1184-8c57be9f8fce.jpeg)

固定翼による1000ヘクタールもの撮影。日頃回転翼でのUAV測量で10ヘクタール程度の飛行は経験しているが固定翼での広域撮影は初めて。もちろん私が飛ばすわけではなく補助員としての役割。
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/b5210711-dc60-90e5-010b-07be9523e079.jpeg)

前日にFacebook上にてアサインされたオペレータ1名と補助員2名、事前に用意されたのは
・Facebookメッセンジャーのグループ https://apps.apple.com/jp/app/messenger/id454638411
・maps.meでの地図（撮影エリア指定と被災箇所のマーキング）https://maps.me/
・Zello（インターネットトランシーバ）のグループリンク https://zello.com/


当日、メッセンジャーで打ち合わせた集合地点に向かう。オペレータのK氏（雪駄の傭兵）、補助員のO氏から事故渋滞の連絡や、指令からの指示が順次Zelloで入る。ともに運転中なのでシンプルなボイスコミュニケーションは安全運転に必須だ。（※道交法改正で、ながら運転は重罰に）ZelloならPTTスイッチ（話すときに押すボタン）の操作しかないし、ヘッドセットやカーオーディオと組み合わせればハンズフリーで操作できる。

集合時刻より早く着いた私は、本部に控えるF司令官に指示を仰ぎ、GoogleMapにて指示された崩落地点に向かう（※Zelloはスマホ、PCで使用可能）。小糸川の激流に削られた崩落地点で司令官に指示を仰ぎMappilaryにて写真を撮る（オープンなストリートビューアプリ）。

![3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/539556/359c60cb-b42b-591f-599c-42fccd0c09ce.jpeg)
https://www.mapillary.com/map/im/tfcuBz2DBxEjMScHpzdY7g

崩落個所撮影を終えた私は当初の集合地点にもどり、K氏とO氏の到着を待つのであった。

つづく（か？）
Cloud Runでbeegoアプリケーションをデプロイ

## はじめに
こんにちは、SREエンジニアやってます。@hayaosatoです。
今回はGCPのCloud Runの入門としてbeegoで作ったアプリケーションをデプロイしてみたいと思います。

## beego
beegoはGoのフルスタックなWebアプリケーションフレームワークで、beeというCLIツールがあり、Railsライクなフレームワークです。
今回CloudRunでデプロイするアプリケーションはこのbeegoで作成したアプリケーションをデプロイしたいと思います。
beegoコンテナのDockefileは以下のようになります。

```Dockerfile
FROM golang:1.13.5

ENV GOPATH $GOPATH:/go
ENV PATH $PATH:$GOPATH/bin
WORKDIR /go/src

RUN apt update &&\
  go get "github.com/go-sql-driver/mysql" &&\
  go get "github.com/beego/bee" &&\
  go get "github.com/astaxie/beego"

RUN bee new app
WORKDIR /go/src/app
CMD ["bee", "run"]
```
`bee new`でbeegoのアプリケーションを生成して、`bee run`でアプリケーションを実行します。

## GCP
続いて、先ほど作ったアプリケーションをCloud Runでデプロイしてみたいと思います。
Cloud RunにデプロイするためにはまずはContainer Registryにイメージをpushする必要があります。

### Container Registry
レジストリへのpushは以下のコマンドで実行できます。
> ホスト名はイメージがホストされている場所で、
- gcr.io
- us.gcr.io
- eu.gcr.io
- asia.gcr.io
のいずれかです。

```bash
$ gcloud auth configure-docker
$ docker build -t ${イメージ名} .
$ docker tag ${イメージ名} ${ホスト名}/${プロジェクトID}/${イメージ名}
$ docker push ${ホスト名}/${プロジェクトID}/${イメージ名}
```

### Cloud Run
さて、イメージのpushができたので次はCloud Runでデプロイしていきます。
Cloud Runのコンソール画面から`サービスを作成`を選択します。
![スクリーンショット 2019-12-12 22.42.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312728/53c33015-928f-3340-7056-bc35549018e5.png)

続いてコンテナイメージのURLには先ほどpushしたイメージを選択します。
リージョン、サービス名、認証を任意の値で設定します。
また、今回動かすbeegoアプリケーションはメモリがデフォルト値の256MiBでは足りないので512MiBに拡張しておきます。
そして、`作成`ボタンを押下する事でデプロイすることができます。
![スクリーンショット 2019-12-12 22.43.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312728/b6241b29-3378-85cf-bdca-bb8db34f4102.png)

## 結果
できました。
![スクリーンショット 2019-12-12 22.48.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/312728/2bb61637-1b4a-12f6-d4c5-1ee21d7efbf7.png)


## 参考
- [GCPドキュメント](https://cloud.google.com/docs/?hl=ja)
- [beego Introduction](https://beego.me/docs/intro/)
- [Cloud Runを爆速で触ってみる](https://medium.com/google-cloud-jp/cloud-run-%E3%82%92%E6%9C%80%E9%80%9F%E3%81%A7%E8%A7%A6%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B-6e42021307d4)
- [【Go活用事例】 安全運転支援サービスを支える 運用管理システム](https://speakerdeck.com/suhirotaka/gohuo-yong-shi-li-an-quan-yun-zhuan-zhi-yuan-sabisuwozhi-eru-yun-yong-guan-li-sisutemu)
- [BeegoによるWebアプリケーション開発① on docker](https://qiita.com/playTag55/items/f940a0eba24c53529bb4)
強化学習３４　連続したAgentの動画を作る

中学生から大学生のAI初学者を対象にしています。
強化学習２８を終了していることが前提です。

強化学習の途中で、例えば１００００ステップ毎にagentを保存して、
それを１回づつ連続して再生したいと思います。
こうすると、学習の成長過程が見やすいかなと。
Youtubeなどでみかける、だんだん上手になっていくというやつです。

chokozainerRLで強化学習をやると、こんな感じでフォルダが作られます。
![files.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190782/d1047d4d-52c7-3af8-c618-607a3e4a2017.png)
これを、順番毎に並べて読み込むのは、以下のようにやります。

```python
import os
import re
testdir='mydrive/OpenAI/CartPole/result_dqn_choko'
files = os.listdir(testdir)
files_dir = [f for f in files if os.path.isdir(os.path.join(testdir, f))]
agentList=[]
for f in files_dir:
  if re.search('_',f):
    f2=f.split('_')
    agentList.append([int(f2[0]),f])
agentList.sort()
```
Googleドライブがマウントされた状態でやります。
そのままsortすると、文字列としてのソートになるので、変な順番になります。なので、前方の数値だけを取り出してソートがかかるようにします。

envとagentが定義されているとして、以下のようにやります。

```python
from matplotlib import animation
import matplotlib.pyplot as plt

frames = []
for item in agentList:
  agent.load(testdir+'/'+item[1])
  obs = env.reset()
  done = False
  R = 0
  t = 0
  while not done and t < 200:
    frames.append(env.render(mode = 'rgb_array'))
    action = agent.act(obs)
    obs, r, done, _ = env.step(action)
    R += r
    t += 1
  print('test episode:', item[1], 'R:', R)
  agent.stop_episode()
env.close()
from IPython.display import HTML
plt.figure(figsize=(frames[0].shape[1]/72.0, frames[0].shape[0]/72.0),dpi=72)
patch = plt.imshow(frames[0])
plt.axis('off') 
def animate(i):
  patch.set_data(frames[i])
anim = animation.FuncAnimation(plt.gcf(), animate, frames=len(frames),interval=50)
anim.save(testdir+"grouth.mp4")
HTML(anim.to_jshtml())
```
Flutterを特定のバージョンに切り替える

## はじめに
Flutterのバージョンを切り替える際、channel単位ではない方法で特定のバージョンに切り替えたい場合（channelをアップデートしたくないときなど）があるかと思います。

## 【追記:おすすめ】fvmを使う方法
fvmという、flutterの環境を切り替えられるツールがGAになったようです。自分でも使っていますが非常に便利で、しかも切り替えも素早くできます。

https://github.com/leoafarias/fvm

こちらの記事が日本語でわかりやすいです。

https://qiita.com/Kurusu_ima/items/2dfd067f6e79f520198f


## fvmを使わない方法
以下のコマンドを使いましょう。

```bash
$ flutter version <バージョン番号> # flutter version 1.12.13+hotfix.6
```

利用できるバージョンのリストは`flutter version`コマンドから取得できます。

```bash
$ flutter version

v1.10.16
v1.10.15
v1.9.1+hotfix.6
v1.9.1+hotfix.5
v1.10.14
v1.10.13
・
・
```

このリストにないバージョンを取得したい場合、FlutterをGitHubからクローンしてきたのであればそのリポジトリのディレクトリで`git fetch`コマンドを打てば、現在FlutterのGitHubリポジトリ上にある全てのバージョンに切り替え可能になります。

```bash
$ cd /path/to/flutter-repostory # これは例です！
$ git fetch
```

fetch完了後、上記と同じように以下のコマンドでバージョンを切り替えられます。

```bash
$ flutter version <バージョン番号> # flutter version 1.12.13+hotfix.6
```
Microsoft Learn 12日目

*2019/12/16 タグ編集。

12月は、毎日 [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を受講していこうという記録。
※受講後に書き込むので公開に間に合わないこと多々あります(アドベントカレンダーの意味ｗ)

12/12 は
**Core Cloud Services - Azure portal を使用してサービスを管理する**
 - Azure の管理オプション
 - ポータルを操作する
 - 演習 - ペインを使用する
 - 演習 - Azure portal を使用する

を受講。以下、簡易メモ。

# Core Cloud Services - Azure portal を使用してサービスを管理する
## Azure の管理オプション
さまざまなツール、プラットフォームを使って Azure を構成、管理することができる。
コマンドラインで利用できる SDK、ツールなど多々ある。
### Azure Portal
あらゆる Web ブラウザーでアクセスできるパブリック Web サイト。
GUI ベースで操作できる。
あらゆる Azure サービスを作成、管理、監視できる。
リソースのデプロイ、管理、削除もできる。
ただ、反復的なタスクを自動化する方法は用意されていない。

### Azure PowerShell
Windows、Linux または macOS で実行するクロスプラットフォームバージョンの PowerShell である、Windows PowerShell または PowerShell Core 用にインストールできるモジュール。
Azure サブスクリプションに接続し、リソースを管理することができる。
モジュールインストール後、 `Connect-AzAccount` でアカウントにサインインできる。

### Azure Command Line Interface
Azure に接続して Azure リソース上で管理コマンドを実行することができるクロスプラットフォームのコマンドラインプログラム。
もちろん Windows, macOS, Linux で実行可能。
`az login` コマンドを使用してログインする。

### Azure Cloud Shell
Azure リソースを管理するために認証された、ブラウザーからアクセスできる対話型シェル。
Bash または PowerShell のうち作業に最適なシェル エクスペリエンスを選択できる。
どちらも Azure PowerShell / Azure CLI がサポートされている。

### Azure mobile app
iOS または Android を搭載したスマートフォンやタブレットから Azure のすべてのアカウントとリソースにアクセスし、管理し、監視することができる。
例えば、以下のような操作がモバイル端末からできる。

* サービスの現在の状態や重要なメトリックを確認する
* 最新の情報を受け取り、正常性に関する重要な問題があれば、警告を受ける
* 最新の Azure アラートを確認する
* 仮想マシンや Web アプリを開始、停止、再開する
* 仮想マシンに接続する

## ポータルを操作する
業務で使っているので、メモは省略。

## 演習 - ペインを使用する
演習なので、メモ略。

## 演習 - Azure portal を使用する
演習なので、メモ略。
５分でできるherokuが、実際3日かかってしまった話


#たった5分でDjangoアプリをherokuにデプロイする方法
https://qiita.com/kilhyungdoo/items/ae0b4d2970bc0937e884

まず環境差で死亡してましたですね*[MacOS環境構築あるある](https://qiita.com/masajiro/items/4aa44ad8250cd3629a88)

以下よんだらできたけど5分でできないのは謎エラーが突破できなかったし、pyenvが理解できてないからや*[MacでPythonインストールなら知っておきたい・いろは](https://qiita.com/masajiro/items/6d79205b79483d1ee00a)

久々にherokuにpushしようとしたら詰まった
http://nafuruby.hatenablog.com/entry/2014/10/18/004834

```
ssh -v heroku
```
でエラーだったけど

色々記事みるといきなりmasterにpushしようとしている記事あるけどもherokuの手順通りにやると以下のコマンドが抜けていた

```
$ heroku git:remote -a [your-app-name]
set git remote heroku to ssh://git@heroku.com/[your-app-name]
```
これで晴れてmasterにpushでき.....ない

error: src refspec master does not match anyがでる
https://qiita.com/yukari-n/items/e6107fe52772ef6a2df4

pipeline作らずになんかごちゃごちゃしてたから？[Heroku Pipeline概要](https://qiita.com/yo-iida/items/27af229aa6037790df97)

とりまgitでハマってるのかherokuでハマってるのか切り分けよう

てか「Heroku creat」コマンド でいきなりwebサイトできてるの草
herokuサイトからアプリ作成もできるしどっちがいいのか

#合わせて絶対に読みたい
PythonのWebアプリケーション（Django）を初心者にもわかりやすく解説【プロジェクト作成編】
http://qiita.com/carat_yoshizaki/items/f3c79e38b802c7fc8863

Djangoを最速でマスターする part1
https://qiita.com/gragragrao/items/373057783ba8856124f3
ぐぬぬ
middleman 〜簡易版Railsみたいなやつ〜


個人サイトでも作ろうかなーと思って、
でもWordPressやるのはコスト高いし、ブログはちょっと違うような気もするし・・、
HTMLをゴリゴリ書いていくのも、slimになれたおじさんにはストレスがマッハなので、いい方法がないか調べてたら **middleman** ってものがあった。

https://middlemanapp.com/jp/

## middleman とは

**middleman は静的サイトをRubyで作るためのフレームワークです。**
RubyOnRails と似ていて、Railsを知っている人には使いやすいものになってます。

**■ middlemanの雑イメージ**
![middleman_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113289/ba58f345-be01-e838-49e2-aaac27da6051.png)

運用的には、Rubyで書いたファイルをHTMLにビルドして、それをサーバにアップロードする感じですね。

## middleman のええとこ

- Rubyが使える
- slimが使える（gem使えるので）
- 共通テンプレートが作れる
- includeとかできる
- データファイル（yaml, json）の読み出しも簡単

すごく RubyOnRails の走り感があって、**RubyOnRailsの学習前段階で使えそうな感じ。**
Rails 難しいよー＼(^o^)／うわぁぁぁってなってる人は、middleman から入ってみてはどうでしょうか。

## インストール

- **Node.js** と **Ruby** をインストール
    この辺は割愛します。

- **middleman** をインストール

```
$ gem install middleman
```

## プロジェクト作成

- middleman のプロジェクト作成

```
$ cd [作業したいディレクトリ]
$ middleman init [プロジェクト名]
```

プロジェクトが出来ましたね。はい、次はフォルダ構成を見てみましょう。

**■ フォルダ構成**
![middleman_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113289/8d2015d6-bc0d-613e-8a5c-33e21877aabe.png)

Rails を小さくした感じ。ファイルやフォルダ数が少なくて、とてもシンプルです。


## サーバ起動

サーバ起動も出来ます。
**ただし、Railsに比べたら読み込みが遅い。**

- サーバ起動

```
$ cd [プロジェクト名]
$ middleman server
```

- http://localhost:4567 にアクセスするんだ

**■ ドン!!**
![middleman_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113289/eee001a4-88d5-8ea9-f425-c6d10af4ff0c.png)

このページが見えたらOKです。あとは、自由にカキカキしていきましょう。

## デプロイ

- ビルド

```
$ middleman build
```

プロジェクトのフォルダ内の**buildフォルダ**を確認してください。
htmlファイルが出来てますね。あとは、これをサーバにアップロードしましょう。

- デプロイ

環境によってご自由に。
**AWS S3の静的サイトホスティング** とか、**Firebase Hosting** がおすすめ。

## おまけ（middlemanの使い方）

#### 部分テンプレートの挿入

```hoge.slim
// Railsの書き方
= render "menu"
// middlemanの書き方 
= partial "menu"
```

> Railsと書き方が違って、戸惑ったので注意！！

#### dataの使い方

例）名前のリストを表示する場合

```data/users.yaml
- user_name: hoge
  mail_address: hoge@mail.com
  age: 30
- user_name: fuga
  mail_address: fuga@mail.com
  age: 45
```

```index.slim
ol
  - data.users.each do |user|
    li = user.user_name
```
Windowsでファイル一覧を簡単に取った後に、すごく簡単にファイルを操作する

(株)アウトソーシングテクノロジーの神谷と申します。普段はAWSだとかゼロトラストセキュリティだとか、様々な新しい技術のお仕事をしています。
でもね……

# 超初心者向け記事がデイリーランキング入り

ネタが無くて苦し紛れに投稿した記事 <a href="https://qiita.com/HyoKamiya/items/b5bfe6b1aa7ef7275fbe" target="_blink">Windowsでファイル一覧を簡単に取得する</a> がデイリーランキングに入りました。
こういう、入門者向け小ネタみたいなものにも需要があるのだなぁ、と思い知りました。
ので、今日はもうちょっと発展させて「超楽にファイルを整理する」やり方の基礎の基礎をやってみます。
いや、本当に**頭を使わずに(超重要)**楽～にファイルをアレコレする裏技でございます。

# 難しいことは文明の利器(エクセル)にやってもらう
いやーエクセルってクッソ便利なんですよ。
ということで、簡単に超らくちんにエクセルを絡めて何かやっちまおうぜっていうのが今回の記事です。正規表現なんてクソ面倒な事、やってられないんじゃあああ！！！

# 基本はmove(タグ)ファイル名A(タグ)ファイル名B
A列にひたすらmoveという文字列。B列に今のファイル名一覧、C列に加工後のファイル名一覧。
こういう状況が作れれば、あとはA列B列C列をコピーして、テキストファイルにペーストして、拡張子をbatに変換してダブルクリックしてやれば、ファイル名をらくらく操作できるのは前回お伝えしたとおりです。
ここで、更に一歩踏み込みましょう。

# 決められたファイルだけをmoveする
今、とりあえずA列にmoveと書いて、B列にファイル一覧をコピペしたものを容易しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/a61d19ce-15e9-58ea-1b20-8ad290fc2971.png)

C2に、以下のように記載します。
`="m_"&C2`
するとこうなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/94e0b5f2-a923-c713-125c-5bd0a57366bd.png)
どうだすごいだろう！で、C2をコピーしてC列全体にペーストしてやると……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/ff119482-d306-b2e6-a676-083b9be44efb.png)
C列の全てが、「m_元ファイル名」に変わります。これで更にフィルタリングをかけてあげたりできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/61562550-3c7f-4179-2576-10077f4dd140.png)
こうすれば
「肩の描き方の講座ファイルだけをリネームする」
という事が超簡単に出来るわけです。

# 更に発展させる
繰り返し書きますが、同じ事をしたいなら、正規表現を使えば出来ます。でもね、そんなの誰にでも出来る事じゃないんだよ。これなら誰にでも出来るんだよ。
楽にやりたいんだよ、楽に。
という事で、ちょい応用問題。
```
1.jpg
10.jpg
11.jpg
:
19.jpg
2.jpg
20.jpg
21.jpg
:
```
こんな糞フォルダを、
```
0001.jpg
0010.jpg
0011.jpg
:
0019.jpg
0002.jpg
0020.jpg
0021.jpg
:
```
とかに簡単にやれる方法です。
まず、A列は相変わらず全部moveでいいです。B列も、今のファイル一覧を貼り付けてくれればオッケー。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/3be824d5-452d-3b88-ec0f-17b5fbed298d.png)
C列をどう作るか？です。
まず、C2に以下を入力します。
`=int(LEFT(B2,LEN(B2)-4))`
すると……
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/cde85e0a-0018-2282-e454-6aaa5d2ca924.png)
取れた！JPGが取れた！
次に、桁数を合わせましょう。
C列を選択して右クリック→セルの書式選択です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/649ffd42-f343-a83b-3fb6-685196e64cbe.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/1831ade0-4a45-cddc-5f15-513a54520477.png)
ユーザー定義の種類に0000".jpg"と書きましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179231/8a5dc884-66f9-a3f8-eae2-2438fdf46009.png)
どーん！どうだ！あとはA列B列C列をテキストファイルにコピペして、そのファイルの拡張子をbatに変更してダブルクリックするだけで、全部のファイルが順番通りに並んでくれます。

# 同じこと、もっと簡単に出来る方法あるぜー
……なんて思ってるかた、甘い。甘いです。
我々がやりたいのは「頭を使わないでいろいろやる」です。そしてこれは、エクセルをある程度使いこなせる人間であれば、何だって出来るんじゃないかと思わせるだけの可能性を秘めた技の、ごくごく基本的な技なのです。

例えばエクセルのフィルタ機能を使ってリネームするファイルを絞ったりだとか、関数を使ってもっと変な変換条件をつけたりだとか。ここから見える可能性は無限大なのです。
そして、何より、エクセルさえあれば出来てしまう、というのが大きいです。コンパイラやらrubyやらを実行させてくれるような職場、なかなかありませんからね。

#最後に
よっし、これで1年間でqiita投稿10件というノルマはクリアだぜ。１件デイリーランキング入りしたのだから、給料アップしろって言えるのだぜ。頑張るなのだぜ。応援お願いするぜ。なのだ。
Intellijのおすすめプラグイン

### AceJump
vimのプラグインのようにコード上の任意の場所にジャンプできるようになるプラグイン。
爆速。
<img width="952" alt="スクリーンショット 2019-12-12 22.18.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/a1cf93c1-17a4-febd-54df-ec234cd7beda.png">



### CamelCase
変数名やクラス名をキャメル・スネークケースを変換する。
様々な種類のケースが用意されているので、どの言語にもだいたい対応できる。
<img width="332" alt="スクリーンショット 2019-12-12 22.20.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/0cb321aa-be2c-61e4-cebd-b0d37c7a84a1.png">
<img width="352" alt="スクリーンショット 2019-12-12 22.21.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/e70a1145-8b85-e4b6-8f92-7e3e67c1d698.png">


### FileWatchers
ファイルの変更を検知して好きなコマンドを走らせることができる。
例えばファイル変更にフックさせてテスト・フォーマッタを走らせるなど。

### GitToolBox
gitとより統合した機能を提供する。
行ごとに最後のコミット、編集者を表示させたり。
おすすめ。
<img width="634" alt="スクリーンショット 2019-12-12 22.23.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/7cfadc6d-fa8c-9513-4223-d35b0405b346.png">


### IdeaVim
IntellijのキーバインドをVimに変更する。
Vimは義務教育。

### Key Promoter X
Intellijで同じ操作を繰り返すと、それに対応するショートカットの存在を通知してくれる。
IIntellijはショートカットが多くて覚えるのが大変だが、自分がよく使う操作に対して適切にショートカットを教えてくれるので素晴らしい。
<img width="396" alt="スクリーンショット 2019-12-12 22.24.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/01323ea2-3ddd-7bb9-0ff7-f3ff185c91e7.png">


### Nyan Progress Bar
プログレスバーをNyanに変える。
かわいい。
<img width="446" alt="スクリーンショット 2019-12-12 22.25.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/7e408569-4557-0cae-00ab-a9b9d040f707.png">


### Rainbow Brackets
カッコをネストの深さに合わせて色を変更してくれる。
見やすい＆かっこいい。
<img width="650" alt="スクリーンショット 2019-12-12 22.27.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/6e006f8e-5ca7-dc8e-1a89-c7ad4c41fa7f.png">


### Relative Line Nubmbers
カーソルのある行からの差分行数を表示してくれる。
Vimを使っていると特定行数分〜をするみたいな操作が頻発するので、これがあるとわざわざ行を数えなくていい。
通常の行番号を消すことも可能。
Vim使いには必須。
<img width="90" alt="スクリーンショット 2019-12-12 22.28.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/ee049324-d536-63a9-3f38-d56281842450.png">
Kubernetes ホスティングを目指して、Magento2 ログを標準出力する

Magento2 の標準ログは monolog の StreamHandler をベースとした [Magento\Framework\Logger クラス](https://github.com/magento/magento2/tree/2.4-develop/lib/internal/Magento/Framework/Logger)によって制御されています。

この標準ロガークラスは、ログファイルを追加したり、拡張できたりと、各種拡張方法も公式ドキュメントで案内されています。ファイルでログを扱う分にはこれで不満があることはありません。

[Example - logging to a custom log file | Magento 2 Developer Documentation](https://devdocs.magento.com/guides/v2.3/config-guide/log/custom-logger-handler.html)

しかし、Kubernetes 等のコンテナホスティングをするためには、ログを標準出力に流す必要があります。この設定変更は di.xml で上書きする必要があります。

それを行ったサンプルが以下のモジュールです。
[kzkick2nd/magento2-stdout-logger](https://github.com/kzkick2nd/magento2-stdout-logger)

## magento2-stdout-logger モジュールを利用する
こちらのモジュール（ `Docker/` 以下）を`app/code/`に設置して有効にするとログが標準出力されるようになります。

行っている内容は monolog StreamHandler のBase クラスで出力先設定を `php://stdout` に書き換えて、標準ロガー Magento\Framework\Logger\Monolog のクラスを di.xml で上書きしたものです。

- [Base クラス上書き部分](https://github.com/kzkick2nd/magento2-stdout-logger/blob/master/Docker/LogStdout/Logger/Handler/Base.php#L50)
- [di.xml の定義](https://github.com/kzkick2nd/magento2-stdout-logger/blob/master/Docker/LogStdout/etc/di.xml)

## magento2-stdout-logger モジュールの有効化

### 1.`app/code`以下に上書きモジュールを設置します

<img width="165" alt="スクリーンショット 2019-12-12 22.10.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752/2d87294c-bf87-3cab-cb73-9113b7ccaed7.png">


### 2.モジュールを有効にします
```
$ bin/magento module:enable Docker_LogStdout
$ bin/magento setup:upgrade
$ bin/magento cache:clean
```

※ 公式ドキュメント「モジュールの有効化について」
[Enable or disable modules | Magento 2 Developer Documentation](https://devdocs.magento.com/guides/v2.3/install-gde/install/cli/install-cli-subcommands-enable.html)

### 3. ログが標準出力されます（docker-compose logs の例）
<img width="428" alt="スクリーンショット 2019-12-12 22.17.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/752/aadac6d4-fe62-9554-757e-50a6b61fcb84.png">
このモジュールでは標準出力にフォーマットを揃えず出力しているので、上記では Docker ベースイメージである httpd のログと混ざっています。出力フォーマットはこのモジュール内で調整すると良いでしょう。

## di.xml による上書き
Magento2 ではコアコードを変更しないで柔軟な拡張性を担保するため、 di.xml によってクラスを上書きする設計となっています。di.xml による Class 上書きについて詳しく知りたい方は以下のチュートリアルを実際にやってみるのが良いでしょう。

[Magentoのdi.xmlを理解しよう〜エクステンション開発上級編その３〜 | さくらのナレッジ](https://knowledge.sakura.ad.jp/21713/)
集まれ！擬似要素！ 

おはこんばんちは。とみぞーです。

今年は擬似要素についての投稿をいたします。
自分の中で迷子になることがあるので、私の中の整理として、投稿させていただきます！

# 擬似要素ってなんだっけ・・・？
まず、擬似要素とは、htmlの要素の特定の部分に対してスタイル付けをするために使用するものです。

# え！
お恥ずかしいながら、この記事を書くにあたり、再度調べていて「知らなかった！」というのがありました。
下記は「擬似クラス」というのですね。
`:link`、`:visited`、`:hover`、`:active` や、その他、`:nth-child(n)`、`:empty`、`:not`、`:enabled`、`:checked`など・・・

擬似クラスは何なのよ？というと、指定したもの全体に対して影響を与えるもので、
文書構造の範囲外にある情報や単体セレクタで表現できないものを選択するために導入された概念だそうです。
簡単にいうと、とある要素が特定の状態にある時に限定し、適用するセレクタであり、class属性との関連はなしです。
確かに、`:checked`とかは文書構造の範囲外ですもんね、、、なるほど、、、！
勉強になりました。
今度は擬似classについて記事を書きます・・・！

# 主な擬似要素
`::first-line` ブロックレベル要素の1行目に影響
`::first-letter` ブロックレベル要素の1文字目に影響
`::before` 要素の直前にコンテンツを追加する
`::after` 要素の直後にコンテンツを追加する

ふむふむ・・・

```
<div class="wrap">
  <p>text1</p>
  <p>text2</p>
  <p>text3</p>
</div>
```

上記のようなhtmlに、CSSを当ててみます。

```
.wrap {
  position: relative;
  p {
    &::before {
      content: 'B';
      display: block;
      color: red;
    }
    &::after {
      content: 'A';
      display: block;
      color: blue;
    }
  }
  &::first-line {
    content: '';
    display: block;
    color: pink;
  }
  &::first-letter {
    content: '';
    display: block;
    color: green;
  }
}
```

結果はこちらになります。
<img width="150" alt="結果画面.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316486/5ab546dc-c841-822c-d386-c1b562302a65.png">

pタグに設定した `::before` と `::after` にそれぞれ指定した「B」と「A」の文字は常に表示されています。
wrapクラスの `::first-line` ・ `::first-letter` のピンクと緑が意図する通りに表示されました。

# まとめ
擬似要素と擬似classの違いが、一番個人的に勉強になってしまいました・・・
もっと有意義なことをかけるように努力します！
シェルスクリプト local コマンド

シェル関数内でローカル関数を使いたい場合、local コマンドを使う。
もしグローバス変数と同じ変数名を定義する場合、local コマンドで定義するまでは、その変数はグローバル変数として扱われる。

```bash:local-example1.sh
i=1
func()
{
  echo $i  # 1
  local i
  i=5
  echo $i  # 5
}
func
echo $i  # 1
```

local コマンドが使えないシェルも存在するため、シェル関数内でサブシェルを使ってローカル変数を実現したほうが良いかもしれない。

```bash:local-example2.sh
i=1
func()
(
  echo $i  # 1
  i=5
  echo $i  # 5
)
func
echo $i  # 1
```
[メモ] Amazon EC2 で ユーザーデータ を用いた Windows Server の初期設定

毎度毎度 EC2 の Windows Server の初期設定が手間なので、自動化する方法を模索していました。

インスタンス作成時のユーザーデータで PowerShell スクリプトを実行できようですね。

パスワード `Z1(5zORN` は変更して使ってください。

参考: https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/WindowsGuide/ec2-windows-user-data.html
参考: https://stackoverflow.com/questions/9368305/disable-ie-security-on-windows-server-via-powershell
参考: https://forum.pulseway.com/topic/1940-install-firefox-with-powershell/

```plaintext
<powershell>
function Disable-InternetExplorerESC {
  $AdminKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
  $UserKey = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
  Set-ItemProperty -Path $AdminKey -Name "IsInstalled" -Value 0
  Set-ItemProperty -Path $UserKey -Name "IsInstalled" -Value 0
  Stop-Process -Name Explorer
  Write-Host "IE Enhanced Security Configuration (ESC) has been disabled." -ForegroundColor Green
}

Disable-InternetExplorerESC

net user Administrator "Z1(5zORN"

function Install-FireFox {
  # Silent Install Firefox 
  # Download URL: https://www.mozilla.org/en-US/firefox/all/

  # Path for the workdir
  $workdir = "c:\installer\"

  # Check if work directory exists if not create it

  If (Test-Path -Path $workdir -PathType Container)
  { Write-Host "$workdir already exists" -ForegroundColor Red}
  ELSE
  { New-Item -Path $workdir  -ItemType directory }

  # Download the installer

  $source = "https://download.mozilla.org/?product=firefox-latest&os=win64&lang=ja"
  $destination = "$workdir\firefox.exe"

  # Check if Invoke-Webrequest exists otherwise execute WebClient

  if (Get-Command 'Invoke-Webrequest')
  {
       Invoke-WebRequest $source -OutFile $destination
  }
  else
  {
      $WebClient = New-Object System.Net.WebClient
      $webclient.DownloadFile($source, $destination)
  }

  # Start the installation

  Start-Process -FilePath "$workdir\firefox.exe" -ArgumentList "/S"

  # Wait XX Seconds for the installation to finish

  Start-Sleep -s 35

  # Remove the installer

  rm -Force $workdir\firefox*
}

Install-FireFox

function Install-Choco {
  Set-ExecutionPolicy Bypass -Scope Process -Force
  [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
  iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
}

Install-Choco

# PowerShell Remoting を有効化
Enable-PSRemoting -SkipNetworkProfileCheck
# 任意ホストからの接続を許可
Set-Item WSMan:\localhost\Client\TrustedHosts -Value * -Force


</powershell>
```
Oracleお試しコマンド

# はじめに
勉強も兼ねてDockerでOracle環境を用意してそこから色々試してみる

## 環境構築
```sql:environment.sql
-- Oracle接続(コマンド プロンプト)
-- $ sqlplus sys/Oradoc_db1@ORCLCDB as sysdba

-- データベースキャラクタセット確認
SQL> select * from nls_database_parameters where parameter='NLS_CHARACTERSET';
-- 文字化け対応
-- $ echo 'export NLS_LANG=Japanese_Japan.AL32UTF8' >>~/.bash_profile
-- $ source ~/.bash_profile

-- システム時間(UTC)　※油断してたらJSTじゃなかった...
SQL> select SYSTIMESTAMP from dual;
-- OSのタイムゾーン変更(UTC⇒JST)
-- # ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime


-- セッション変更(PDB)
SQL> alter session set container=ORCLPDB1;

-- ユーザー作成
SQL> create user developer identified by password default tablespace users temporary tablespace temp;

-- 権限作成
SQL> grant dba to developer;
SQL> grant unlimited tablespace to developer;

-- ログイン
$ sqlplus developer/password@ORCLPDB1

-- テーブル作成
SQL> CREATE TABLE MSTKIND (
 KIND_CD CHAR(2) NOT NULL,
 KIND_NAME VARCHAR2(40),
 KIND_DATE DATE,
 PRIMARY KEY (KIND_CD)
);

SQL> CREATE TABLE MSTKIND2 (
 KIND_CD CHAR(2) NOT NULL,
 KIND_NAME VARCHAR2(40),
 KIND_DATE DATE,
 PRIMARY KEY (KIND_CD)
);


-- データ設定
SQL> INSERT INTO MSTKIND VALUES ('01', 'キジトラ', SYSDATE);
SQL> INSERT INTO MSTKIND VALUES ('02', 'キジトラ2', SYSDATE-1);
SQL> INSERT INTO MSTKIND VALUES ('04', '2021/03/04', SYSDATE-1);
SQL> INSERT INTO MSTKIND2 VALUES ('01', 'キジトラ', SYSDATE);
-- ★☆★昨日の日付をYYYY/MM/DD形式で挿入★☆★
SQL> INSERT INTO MSTKIND VALUES ('03', 'キジトラ3', TO_DATE(TO_CHAR(SYSDATE-1, 'YYYY/MM/DD'), 'YYYY/MM/DD'));

-- 日付形式のデータ取得
SQL> select * from MSTKIND
 WHERE KIND_NAME LIKE '____/__/__'
;

-- 別テーブルの値を使って設定
UPDATE MSTKIND T1
 SET T1.KIND_DATE =
  (SELECT KIND_DATE FROM MSTKIND2)
;



```
【参考サイト】
　◆Dockerを使って環境を汚さずOracle Databaseを触ってみる
　　https://qiita.com/kawakawaryuryu/items/ae51bee866a57f178fe5

## ユーザ操作
```sql:oraora_operation_user.sql

-- ユーザ削除
DROP USER [ユーザ名];

-- ユーザ削除　※テーブル作成していた場合、こちらでまとめて削除
DROP USER [ユーザ名] CASCADE;
```
【参考サイト】
　◆Oracleのユーザーを削除するDROP USER【SQL】
　　https://sql-oracle.com/?p=232


## キー情報操作
```sql:oraora_operation_key.sql

-- プライマリキーの削除
ALTER TABLE [テーブル名] DROP CONSTRAINT [プライマリキー名] CASCADE DROP INDEX

-- 外部キーの削除

```
【参考サイト】
　◆FOREIGN KEY 外部キー ON DELETE CASCADE の有無での動作確認
　　https://qiita.com/Papageno/items/0c685bfbce2d3af60fd4
　◆ORACLE | かなめのロジック
　　https://kanamelogic.com/category/oracle/page/2/


## お蔵入り

```sql:oraora.sql
-- 表領域作成
CREATE TABLESPACE USERS01 DATAFILE 'C:\oraclexe\app\oracle\oradata\XE\USERS01.dbf' SIZE 100M AUTOEXTEND ON NEXT 500K MAXSIZE UNLIMITED;

-- ユーザ作成
CREATE USER USER01 IDENTIFIED BY "USER01" DEFAULT TABLESPACE USERS01 TEMPORARY TABLESPACE TEMP;

-- 権限作成
GRANT DBA TO USER01;
GRANT UNLIMITED TABLESPACE TO USER01;

-- テーブル作成
CREATE TABLE MSTKIND (
 KIND_CD CHAR(2) NOT NULL,
 KIND_NAME VARCHAR2(40),
 KIND_DATE DATE,
 PRIMARY KEY (KIND_CD)
);

-- データ設定
INSERT INTO MSTKIND VALUES ('01', 'キジトラ', SYSDATE);
INSERT INTO MSTKIND VALUES ('02', 'キジトラ2', SYSDATE-1);
-- ★☆★昨日の日付をYYYY/MM/DD形式で挿入★☆★
INSERT INTO MSTKIND VALUES ('03', 'キジトラ3', TO_DATE(TO_CHAR(SYSDATE-1, 'YYYY/MM/DD'), 'YYYY/MM/DD'));
```
【参考サイト】
　◆Oracle Database Express Edition 11g Release 2 をインストールしてテーブルを作成してみる
　　https://www.doraxdora.com/blog/2017/08/31/post-2304/
約一年半ほどQtを使って感じたことなど

# 背景など

普段お世話になっているQt関連の記事へのお返しとして、何か[Qt Advent Calendar 2019](https://qiita.com/advent-calendar/2019/qt)に書きたいと思ったのですが、時間が取れなかったので、これまでQtを使って感じたことを残してみたいと思います。

私自身仕事としてのソフトの開発経験は長いのですが、Qtは初体験で理解しきれずに使っている点がほとんどです。ご容赦願います。

また一日遅れの上、技術的な事が何も無い記事になってしまい、申し訳ありません。

# 調査から環境構築、プロトタイプ作成まで

製品を開発するにあたり、Qtが使えそうか調査し、簡単なプロトタイプを作成するまでに感じたのは次のような点。

- 機能は多く十分。製品に採用されている実績からも、足りないものはなさそうだと思った。
- ただし、日本語の情報が少ない。公式ドキュメントでは機能や文法は分かるが、使いどころや設計のポイントが分からなかった。
- @task_jpさんや@hermit4さんを始めとする日本語の記事が大変参考になりました。

# 仕様検討から本格開発開始まで

仕様を検討して開発を始めると、機能としては存在しても以下のような細かな問題がありました。

- sshを使うよう設計したが、実装してみたら認証鍵方式限定だった。結果として仕様を変更した。
- 予め自作したタイル画像をローカルに持っておき、ネットのない環境で地図表示する必要がありましたが、どうやってもQtのタイル画像表示がネットのない環境では動かなかったので、タイル画像からの地図表示は自作に切り替えました。
- QtDesignerからだと機能しないスタイルシートが数か所あった。ソース内からsetStyleSheetすると機能する。
- QGraphicsViewが思ったより重かった。大量のラインを毎秒描き足して残す処理があるが、アイテムが多くなると急激に遅くなってしまうので、描き足す際に直前のラインと比較して、人間の目で見てわからない程度の違いなら描き足さず描き直すなど実装を工夫してアイテム数を減らした。
- OfficeをActiveX経由で操作してドキュメントを作る必要があるが、一部の引数が正常に動かず仕様を変えた。例えば、PowerPointでポリゴンを描こうとすると、座標が渡せない。

# 開発終了に向けて

後一ヶ月ほどで開発を終わらなければならない時期となり、試験やマニュアル作成の人員に実行ファイルを展開していますが、問題の報告、修正の確認の際、どの時点の実行ファイルか識別が必要になった。（本来Qtの問題ではありませんが）

これについては、Jenkinsを使い、SVNのリビジョン番号をexeのファイルバージョンに埋め込んでビルドする仕組みを自動化して対処しています。

# 最後に

繰り返しになりますが、全然技術的な事が書けずに申し訳ありません。開発が落ちついたら上に書いた問題なども整理して書きたいと思います。
アソシエーションの基礎　current_user

#ここでやりたいこと
1. **productを作った人とサイインしている人は常に同じ人物である**
 - create アクションをするときにcurrent_idと紐づいたproductを保存したい
2. **ProductモデルとUserモデルとcurrent_userをわかりやすく紐付けたい。下記のコードをアソシエーションを用いて簡単にしたい。**

コメントアウトしているのは最初に僕が1のことをやろうとして試したこと。**この時は=をイコールとして考えていました。**

```rb
def create
    @product = Product.new(product_params)
    #current_user.id = @product.user.id
    respond_to do |format|
      if @product.save
        format.html { redirect_to @product, notice: 'Product was successfully created.' }
        format.json { render :show, status: :created, location: @product }
      else
        format.html { render :new }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end
```

##今回触れること
- =について
- current_userの型について。そもそも型って何？
- アソシエーションを用いた紐付け


##「=」はイコールというよりは右辺を左辺に代入するという意味がつよい！
なのでこのコードも current_user持っているidをProductモデルのuser_idに代入すると考えられる。

```rb
@product.user_id = current_user.id 
```

##current_userの型(モデル)って何んだ?

型はクラスをつけて書くことで新しいものを作れる
 
 型の例

```rb
class ApplicationController < ActionController::Base
end
```

```rb
class Member < ApplicationRecord
end
```
stringやintegerも型ですね

ハッシュも型の一つで、型を確かめるにはclass.nameを打ってみるといいと思います！

```rb
a = "aaa"
=> "aaa"
> a.class.name
=> "String"
```
current_userの型を確かめたい！ただcurrent_userはrails cでは確認できないので、コントローラーなどで確認することにします。

current_userが使われているアクションなどで、 適当に　

```rb
a = current_user.class.name
puts a
```
とかやるとターミナルにcurrent_userの型が表示されます。ちなみにcurrent_userの型はUserでした！理解していなかった、、つまりcurrent_userは*Userモデル*なんですね

これがわかると**アソシエーションを結びつけることができる。**(UserモデルとProductモデルがhas_many :products, belongs_to :user になっている前提。またProductモデルにはuser_idがあり、リレーションを呼び出せる。)

##createを実際に変えてみる
この１行でいいんですね。current_userのidをProductモデルのuser_idに代入し、newする　
@product = current_user.products.new(product_params)
**ちなみにアソシエーションで持ってこれるのはidのみです。**

```rb
def create
    @product = current_user.products.new(product_params)
    respond_to do |format|
      if @product.save
        format.html { redirect_to @product, notice: 'Product was successfully created.' }
        format.json { render :show, status: :created, location: @product }
      else
        format.html { render :new }
        format.json { render json: @product.errors, status: :unprocessable_entity }
      end
    end
  end
```
2019年の振り返り

# 2019年の振り返り

こちらはノンプロ研のアドベントカレンダーの12日目になります。

https://adventar.org/calendars/4208

元々はGAS関係で書こうと思っていたのですが、書きたかったネタが思ったより難しく断念。
急遽振り返りに変更しました。

# 2019年はプログラミングの基礎が身についた年

昨年末に部署異動をしてから業務効率化のためにプログラミングを学び始めてちょうど約1年ぐらいです。
この1年でできることになった(作ったもの)を棚卸ししてみました。

- スプレッドシートの関数を超覚えた
- 正規表現
- GASのアプリケーションで入社時の適正検査、能力検査をウェブ化
    - HTML、CSSを少し
- GASでのAPI操作
    - Line BOT操作
    - Slack操作
    - カオナビからのデータ取得、等
- BigQueryの操作
    - GASを使ってスプレッドシートとBigQueryへのアップロード
- データポータルの操作
    - スプレッドシートとの連携
    - BigQuery
- Pythonでのスクレイピング
    - データ自動取得
    - 社内eラーニングの進捗度の自動取得
- その他、様々なPythonライブラリの操作
- Markdown


改めて振り返るとできるようになったこと多いなーって思います。


# プログラミングを学ぶためにやってよかったこと

- [GAS本の購入](https://www.amazon.co.jp/Google-Apps-Script%E5%AE%8C%E5%85%A8%E5%85%A5%E9%96%80-%EF%BD%9EGoogle-Suite%E3%81%AE%E6%9C%80%E6%96%B0%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%82%AC%E3%82%A4%E3%83%89%EF%BD%9E-ebook/dp/B07BNB1Z9L)
    - プログラミングの基礎はこの本で身につけたと思っています
- ノンプロ研への参加<br>
    - 皆さんに聞ける環境があったので、挫折することなく学べました
    - 所属しているだけでも刺激がもらえるし、GAS講座では本だけでは抜けてしまうような基礎的なことが身についた
- [PyQ](https://landing.pyq.jp/ml/?maf=1166_1191389.20227.0..1109682466.1576154838#)
    - 当時は意味がわからないまま勧めていましたが、最近Pythonをいじることが多くなって当時PyQで書いていたことが役立ってます
- ゴールデンウィークにPythonデータ分析の4日間講座を受けたこと
    - やっと最近活かせる業務をやり始めました


# プログラミングを学ぶためにもっとやればよかったこと

- もっと初期段階でのプロゲート
- 書籍の購入
    - 最近Pythonのデータ分析のための本を買ったのですが、WEBなどで欲しい情報がけ見るよりも、専門書で体系的に学んだほうが効率よく学べるなと再度実感

# プログラミングを学ぶのに試してよくなかったこと
- Udemyの購入
    - なぜかモチベーションが上がらず、未読がたまっています
- 専門書の電子書籍での購入
    - リファランスとしても学習としても紙のほうが好きでした

ここについては好み、個人差はあるので、あくまで私の場合は合わなかったなぁというだけです。
唯一、SeleniumのUdemyは購入してよかったなと思っています。

# 来年挑戦したいこと
- Pyhon、BigQueryを活用した本格的なデータ分析
    - 人や成果に関する分析
    - マーケティングに関する分析
- データの可視化
- APIをもっと自在に使えるようにする
    - データ取得系はできるけどアップデートの
- アプリケーションの開発
    - 貯めたデータを検索できるようなものを作りたい
  
最後のアプリケーションを作るとなるとPHPとかも学ばないといけないのかな？
PythonでやるとなるとDjangoとかかな？

社内での共有用には操作方法とか貯めているのですが、ブログ更新は全然できていない。
来年は同じ内容でアップデート頻度高めていこう！
いまさらCloud Functionを使ってSlack commandを実装してみた

## overview.
ただただ[公式のチュートリアル](https://cloud.google.com/functions/docs/tutorials/slack?hl=ja)をやってみただけの記事です。
Google Cloud PlatformのCloud FunctionsとGoogle Knowledge Graph Search APIを使ってSlush ComomandをPythonでデプロイしてみる。
SlackのSlush Commandを使ってGoogleのKnowledge Graph(人名とかを検索すると右側にwikiとかの要約が出てくるアレ)を取得できるようにする。
Slackで`/kg hoge`とポストするとhogeをGoogle検索しKnowledge Graphを結果として表示する。<- これを目指す

## 前提条件と準備
- GCPプロジェクトの課金が有効になっている(支払いアカウントに紐づいている)
- GCPのメニューからCloud Functionを有効化
- GCPメニューのAPIダッシュボードからGoogle Knowledge Graph Search APIを有効にしておく
    - **GCPメニュー** > **APIとサービス** > **ライブラリ**から
    - **認証情報** > **認証情報の作成** > **APIキー**でAPI keyを発行
    - このAPI keyをメモしておく
- Slackにスラッシュコマンドインテグレーションを追加
    - Slackの**メニュー** > **App管理** > **カスタムインテグレーション** > **Slackに追加**
    - コマンドを選択するの窓に`/kg`と入力して**スラッシュコマンドインテグレーションを追加する**
    - 遷移した画面で**トークン**の欄に表示されているトークンをメモしておく
    - **URL**は後で入力するので、ブラウザの画面はそのままにしてCloudFunctionの設定に移る


## Cloud Functionの設定
右上のアイコンからCloud Shell(GCPを操作するCLI)を起動。
![p1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135382/3483fa5d-fab4-833c-b8d8-b7d55009f25e.jpeg)

プロンプトが立ちががったら

```:CloudShell
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
```

をたたいてサンプルアプリのコードが入っているリポジトリをcloneする。

```:CloudShell
cd python-docs-samples/functions/slack/
```

でSlackのサンプルアプリのディレクトリへ移動。

中にあるconfig.jsonを編集して発行したAPI keyとSlush Commandのトークンを記入する。
編集はCloud Shellの右上のペンのアイコン(エディタを立ち上げる)を押すと別タブが立ち上がりwebエディタが起動するので、config.jsonにAPI keyとSlush Commandのトークンを記入。

```:config.json
{
"SLACK_TOKEN": "YOUR_SLACK_TOKEN",
"KG_API_KEY": "YOUR_KG_API_KEY",
}
```
config.jsonを編集したら`python-docs-samples/functions/slack/`で

```:CloudShell
gcloud functions deploy kg_search --runtime python37 --trigger-http
```
を実行するとサンプルコードとconfigの設定を元にSlackからのコマンドによるリクエストを受け取るエンドポイントと、リクエストを処理してSlackに送り返す関数をデプロイしてくれる。

完了すると**GCPメニュー** > Cloud Function**にkg_searchという名前の関数が作成されている。

## スラッシュコマンドインテグレーションの設定
準備で入力を保留していたインテグレーションの設定のURLの欄に下記のエンドポイントURL(コマンドを送信するURL)

```
https://YOUR_REGION-YOUR_PROJECT_ID.cloudfunctions.net/kg_search
```
を入力。YOUR_REGIONはGCPのリージョン、YOUR_PROJECT_IDはGCPのプロジェクトIDに置き換え。
kg_searchはデプロイしたCloud Functionの名前。(サンプルコードをそのままビルドしたならこの名前になるはず)
このエンドポイントURLはCloud Functionに作成された関数名をクリック > **編集**のURLのところに記載されているURLと同じ。

あとはコマンドの名前やアイコンなどは適当に設定して**インテグレーションの保存**。

## コマンドを実行してみる
試しに`/kg 安倍晋三`と入力して実行してみる。
![p5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135382/99aa9a5f-d126-9e08-9c2f-fb260d2581ff.png)

無事安倍総理のKnowledge Graph検索結果が返ってきました！
20代女性が使う最近流行りのStories(ストーリーズ)について、どういうシチュエーションで利用するのか聞いてみた。

この記事は[Digital Identity Creative Div. Advent Calendar 2019](https://adventar.org/calendars/4714)の12日目です。

InstagramやFacebookなどでおなじみのStories（ストーリーズ）機能ですが、**若い世代には人気**があります。通常の投稿とは異なる機能もあり、なかなか興味深いもの。

20代の女性で、実際に利用している人に話を聞いてみました。そこには、意外なほどいろいろなことを考えて投稿しているという実態が浮かんできたのです。

全2名の20代女性にきいてみた「ストーリーズ」機能について、詳しくみていきましょう

## Storiesの機能はすごい！24時間という時限式、テキストを埋め込める！ばえる！

InstagramとFacebookでは、すでにStoriesが利用できる状態です。作り方もかんたんなので、ここでは割愛。実際に作ってみたのがこちら。このストーリーズは40代のおっさんが投稿しているので、キラキラ度はありませんよ。

<img width="414" alt="IMG_2270.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237054/5dbe18db-6e6d-5598-e91a-c070c3f33890.png">
↑instagramのストーリーズ機能

<img width="414" alt="IMG_2259.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237054/d725087a-d3b0-71d1-0f7f-41bb302d6061.png">
↑Facebookのストーリーズ機能

全画面で写真や動画を見せることができ、枚数も複数枚表示可能。**写真に絵文字やスタンプを使ってばえさせたり、テキストを追加して意味ありげにしてみたりすることも日常茶飯事**です。

ここで重要なのは、24時間で消えるという時限式が、これらの行為を増幅させている、ということです。

## 24時間で消えることはメリットであるということ。ストーリーズはこう使え！

コンテンツとして考えると、24時間しか見れないというのは賞味期限の短い食べ物と同じ。一年でみたら1/365しか生きていないコンテンツになります。これではGoogle botすらクロールしてくれない可能性もあるのです。

しかし、ここにメリットが生まれます。

例1）
**いま渋谷にいるんだけど、誰か友達いないかしれっと聞きたい。**
↓
こんなとき、「マルキューのこのお店にあるこの服かわいい！」的なストーリーズを公開します。すると、フォローしている友達がそれをみて「お！いま渋谷にいるんだ！あたしも近くにいるから遊びにいこ！」というDMを送れます。こうして、無事に合流することができるのです。
<img width="414" alt="IMG_2274.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237054/2bdd0c6f-b837-480a-8e13-00f1caa4aa7b.png">
↑東京タワー近辺、六本木ヒルズけやき坂にいることが伝わる

しかも、**ストーリーズは24時間で消えるので、後で住所がバレちゃう！的な心配も緩和**されます。

例2)
**投稿するほどでもないけど、ストーリーズならいいかな的なゆるい投稿**

買ってないけどこれほしい！というようなアイテムをストーリーズに流したり。これにより「ほしい！」とPRせずとも、興味があることを伝えることができます。

投稿するには意外とパワーがかかります。しかし、**ストーリーズなら24時間で消えるので、気合を入れてキラキラしたテキストを打ち込む必要はありません。**最低限、写真だけを投稿すればいいのです。フォロワーさんだけに配信することが通常ですので、近況をさらっと伝えるのがとても楽になります。
<img width="414" alt="IMG_2275.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237054/1a2247b8-d49a-ecf2-07f8-1824fff2b6bd.png">
↑ランチのガパオライスをさらっとストーリーズに投稿

**24時間の時限式というのは、投稿の敷居を下げ、新たなコミュニケーション手段を生み出している、という素晴らしい機能**ということがよくわかります。

## 最後に

このブログを書いていてストーリーズに絵文字を追加することを「**デコる**」と書いてしまった昭和世代なおじさんですが、今は「**ばえる**」というのが普通です。**くれぐれもデコるとかインスタ映えとか**言ってはいけません。

そして、20代との会話は脳トレになるなと実感することも。「モヤる」や「わかりみ」など、さまざまな流行語を聞いたり使ってみたりすることで、脳が活性化してるな！という気がしないこともないです。

**○○年でインクが消えるペン**のように、あなたの今や、思っていること、伝えたい気持ちをぜひストーリーズに投稿してみましょう。なにが起きるかはあなた次第。


明日はみゆちゃんです。20代のキラキラしたアドベントカレンダーが楽しみですね。
gitlabから、sshを使って、git cloneできない（社内ネットワーク）ブラウザからは接続可能 (unable connect)

## 対応策
ブラウザから直接gitlabにアクセスできている場合、httpsからのアクセスは可能のため、sshを使わず、httpsでcloneできる。

## sshでcloneできない理由
社内ネットワークの場合、セキュリティ向上のため、ファイアウォールで、社外ネットワークからのポート（9418）制限をかけることがよくある。

また、社内ネットワークから社外ネットワークへのアクセスは、http(80)とhttps(443)ポート以外は許可していないことが多いため

##参考にさせていただいたサイト
[社内プロキシに虐げられてる人たちはVPSとか借りて社外にプロキシ立ててsshトンネルで繋ぐとウハウハですよってお話](https://qiita.com/kiida/items/37557a1029788afec98a)
InCaaaan:印鑑マシーンの作り方 超概要編

#InCaaaanとは？
[こちらの動画](https://youtu.be/5JPdSbyHNck)でどんなことができるかを解説しているのでご確認ください（雑）
ヒーローズリーグ広島予選にて、運良く？勝ち抜き、決勝で東京に行くも無冠に終わるという悔しさの反動で本記事を書きつつ、作品の説明よりもどう作られたか、を中心に書いていきます。

#全体的なシステム構成は？
<img width="963" alt="スクリーンショット 2019-12-06 12.33.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123800/52fac9f6-6cb3-b6ef-1f08-902e33b943a7.png">
##部下が使うツール
1. LINE上でWebを表示して精算申請を行う
	- **部1-1.**IBM CloudのNode-REDで、リクエストをうけたらHTMLコンテンツをレスポンスする
	- **部1-2.**LINE Front-end Frameworkを活用して、**部1-1**のコンテンツを表示する
2. LINE上でWebに入力されて、送信されたデータを扱う
	- **部2-1.**IBM CloudのNode-REDで、**部1**で申請されたリクエストを受信する。その後、Kintone APIを経由してKintone上に作成した帳票に保存する

##上司が使うツール

1. 電子型押印に申請があったことを通知する
	- **上1-1.**KintoneにWebhoookを設定し、レコードが追加されたWebhookでAWS API Gatewayを呼び出す
	- **上1-2.**AWS API GatewayからLamdaファンクションを呼び出し、リクエストに格納されているKintoneに保存されたレコードのレコードID、申請したユーザのLINE名、LINE ID、申請金額などを取得して、IBM CloudのNode-REDにデータをPOSTする
	- **上1-3.**IBM CloudのNode-REDでリクエストを受付、CloudMQTTを使ってレコードIDとLINE名をパブリッシュする
	- **上1-4.**M5StickCをCloudMQTTに接続し、特定のタイトルでパブリッシュされたメッセージを受信した場合に、メッセージをLCDに表示する
2. 押印するモーションで承認を行う
	- **上2-1.**M5StickCに加速度Y軸1.5Gの重力が加わると、CloudMQTTを使ってLCDに表示されているレコードIDとLINE名をパブリッシュする
	- **上2-2.**IBM CloudのNode-REDで特定のタイトルでパブリッシュされたメッセージを受信する。メッセージの受信後、ObnizのWebhookとKintone APIにリクエストを送信する
3. サーボモーターを動かし、物理的な印鑑を押す
	- **上3-1.**ObnizのWebhookで、サーボを動かすコマンドが書かれているプログラムを実行する
4. Kintoneのレコードを更新して、承認キーを付与する
	- **上4-1.**承認キーを発行して(承認キーの発行のメカニズムはブロックチェーン編を別途記事として書きます)、IBM CloudのNode-REDからKintone APIで対象のレコードに承認キーを設定して更新する。更新するレコードは**部2-1.**で登録されたレコードキーをデバイス、クラウドをまたがって引き継いでいる為、更新を可能としている。