OmniAICreator/Qiita-1.07M huggingface dataset:
【画像処理100本ノックに挑戦】Q.13. MAX-MINフィルタ

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

# Q.13. MAX-MINフィルタ
> MAX-MINフィルタ(3x3)を実装せよ。
MAX-MINフィルタとはフィルタ内の画素の最大値と最小値の差を出力するフィルタであり、エッジ検出のフィルタの一つである。 エッジ検出とは画像内の線を検出るすることであり、このような画像内の情報を抜き出す操作を特徴抽出と呼ぶ。 エッジ検出では多くの場合、グレースケール画像に対してフィルタリングを行う。

こういうフィルタがあることを初めて知りました。差を取るので微分フィルタっぽい動きをするのでしょう。やはりエッジ検出に使われるようです。微分フィルタと比べるとどうなんだろう？
Q.10のメディアンフィルタを少し改造すればOK。

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

	auto max_min = [&](const std::vector<std::vector<double>>& f)
	{
		std::vector < std::vector < double >> ret(width, std::vector<double>(height));
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				ret[i][j] = 0;
			}
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				std::vector<int> list;
				for (int di = -1; di <= 1; di++)
					for (int dj = -1; dj <= 1; dj++)
					{
						if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
						{
							list.push_back(f[i - di][j - dj]);
						}
						else
						{
							list.push_back(0);
						}
					}
				std::sort(list.begin(), list.end());
				ret[i][j] = (list[8]-list[0]);
			}
		return ret;
	};

	std::vector < std::vector < double >> arry(width, std::vector<double>(height));
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			int r = ppm(i, j, 'r');
			int g = ppm(i, j, 'g');
			int b = ppm(i, j, 'b');
			int y = (std::round)(0.2126 * r + 0.7152 * g + 0.0722 * b);
			arry[i][j] = y;
		}
	
	arry = max_min(arry);

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

	ppm2.Flush("out.ppm");
	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/8862a49f-678f-8c90-3aba-e665fc2acd6a.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/d6da9307-2136-8cdd-ca5d-9bc0022588b2.png)
無料のPaaS で LAMPスタック（実際はWIMP）をすぐ作る on Azure


# アカウント作成

アカウントを作成します。無料ですが、クレジットカードの登録が必要です。ただし、クレジットカードの情報を登録しても良いことに勝手に課金されることはありません。つまり、有料プランへの切り替えを明示的にしない限り、課金されません。どうやら本人認証のために登録するだけのようです。

### 手順
- Microsoft Account 作成 
- Microsoft Azure アカウント作成

参考サイト　https://azure.microsoft.com/ja-jp/free/

 

# Web App 作成

Web App を作成します。その際、フリープラン「F1」を選ぶことで半永久的に無料で、サーバーが使えることになります。この Web App 無料プランは、HTTPサーバーでもあり、アプリサーバーでもあり、さらに簡易的なデータベースもついています。
ランタイムは、PHPを選択します。プランは安いものでOK。

<img width="275" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/2da59c70-e9dd-e2d9-474d-73b5002931cf.png">
<img width="593" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/c0f27a11-fc3b-81fb-8eb3-b0d03fe8ce2a.png">


### 手順
- Web App Windows 版作成 
- 発行：　コード
- OS： Windows
- 課金：　フリープラン（F1）


ちなみに、OSをWindows にするのは、MySQL in App を使いたいため、です。
Linuxだとこのとおり、使えません

<img width="407" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/f7d22f5c-ec57-651b-e9e7-285481b378fb.png">




# Web App とパソコンの同期方法

Dropbox、Onedrive、Git、GitHubなどで、ソースコードを、AzureにDeployできるようにします
設定はデプロイセンターです。<img width="277" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/f98f81e9-862f-3d2b-1d8d-57ec081fee07.png">


おすすめの方法いくつか。

### チーム開発を行う場合
　＞　GitHubなどのリポジトリと直接つなぐ

### チーム開発を行い、かつ本番業務を行う
　＞　Azure DevOpsで、CI/CDを構築する

### 一人で開発する場合
　＞　FTPや、Dropboxなどで十分
　たぶん一番簡単です。Dropboxの「アプリ」というフォルダに「Azure」フォルダが自動で作成されます。この下にソースコードを置けばOK



# Web App のうえに、MySQLを作成

Web Appsができあがったら、ダッシュボードからMySQLをたちあげて、PHPMyAdminを開きます

<img width="724" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/756f5d5f-8596-e86b-b1d5-19747336c491.png">


この画面の、「Manage」というボタンは地味ですがこれを押すと、PHPMyAdminが立ち上がります

ですがたまにエラーになることがあります。。


理由は、Web Appsがフリープランのため、プロセスがおちてしまっているというやつです。


参照：　MySQL In AppでphpMyAdminに入れない→解決
https://www.ryuzoji.com/archives/2079


普通にアクセスすれば普通に画面が開きます。便利です。

<img width="595" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/79ab74a1-fe5b-3cac-8ef9-758622a0a0a1.png">

DBやテーブルを作って接続確認してみましょう。





User と、Password　は、Web Appsのコンソールから、設定テキストファイルを開くとわかります

<img width="716" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60530/f800ef80-bf13-0790-e025-0c891c18123b.png">
[小ネタ]VSCodeからSAMによるLambdaのローカル実行で「Error with child process: Building resource 'awsToolkitSamLocalResource'」がでて動かない場合の対処

# 要約
SAMの内部にあるpipのversionとローカルのpipのversionが合わないと動かない時があるので、ローカルのpipのversionを修正する必要がある。

# 実行環境

|項目名|バージョン|
|---|---|
|OS|MacOS High Sierra 10.13.6|
|VSCode|1.40.2|
|SAM|0.37.0|
|Python|3.7.3|
|pip|19.3.1(記事内で19.2.3に変更)|

# 問題
VSCodeの「Run Locally」からAWS Toolkitを使用してローカル環境で試験したい時に動かない場合があります。例えば以下のようなエラーです。

```python

Local invoke of SAM Application has ended.
Preparing to run app.lambda_handler locally...
Building SAM Application...
An error occurred trying to run SAM Application locally: Error with child process: Building resource 'awsToolkitSamLocalResource'
,Running PythonPipBuilder:ResolveDependencies
,Error: PythonPipBuilder:ResolveDependencies - Traceback (most recent call last):
  File "<string>", line 1, in <module>
TypeError: 'module' object is not callable

```

# 原因(おそらく)
SAMの方で起きていたIssueがVSCodeのAWS Toolkitではまだ解決していないみたいです。
[GitHub : sam build fails for python3.7 functions with pip==19.3 installed](https://github.com/awslabs/aws-sam-cli/issues/1461)
試しに同じ設定で、ターミナルから以下のコマンドで実行した場合はSAMとpipのverisonは同じでも問題ありませんでした。

```bash
$ sam local invoke HelloWorldFunction --event events/event.json
```

# 対処
一時的な対処とはなりますが、pipのversionを以下に修正するとVSCodeからでも正常に実行することが可能になります

```bash
$ pip install pip==19.2.3
```

pipのversion変更後にVSCodeから「Run Locally」したログ

```bash
Fetching lambci/lambda:python3.7 Docker container image......
Mounting /tmp/aws-toolkit-vscode/vsctkytL1AY/output/awsToolkitSamLocalResource as /var/task:ro,delegated inside runtime container

...(中略)...

{"statusCode":200,"body":"{\"message\": \"hello worldXXX\"}"}
```
reg-suitをCapybaraで試してみた

この記事はfusicアドベントカレンダー14日目の記事です。

関わっている案件で画像を取り扱うことがありました。
それの検証をするためにわざわざ画面を開いて、ダウンロードして目視確認して、、、

そんなめんどくさいことをやっていたのであります。
自動化できたらありがたいですね！

## reg-suit
AWS S3へ事前にアップロードされた画像ファイルを元にテストデータとをcircleci上などで比較し、差分を検証してくれるライブラリです。
https://github.com/reg-viz/reg-suit

導入の方法については、`npm i reg-suit`でいけます。

## 大まかな流れ

本家のデモでは

<img width="861" alt="スクリーンショット 2019-12-14 18.54.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397374/bafcb228-218a-fe23-a9fe-dd765f3d144d.png">

こんな流れで、実証しています。
しかし、私がやりたいことはダウンロードリンクを踏んで画像を保存し、その画像データ（おまけにSVG）を正解データと比較したいのです。
さらに、自分の場合、rubyのコードを使ってsvgファイルを動的に生成した後、ダウンロードする形だったのでそのままスクショではNGでした。

## さて、どうするか？
こうします。

<img width="763" alt="スクリーンショット 2019-12-14 19.11.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397374/631a3130-6330-5d9d-6d83-abf0e7dbb215.png">



Capybaraというe2eテストフレームワークを使って、実行します。
無理矢理感満載ですが、なんだかできちゃいそうですね。

## 実際に書いてみたコード

turnipを使ってます。

```test.feature
Scenario: svg画像をダウンロードできる
  Given svg画像を登録
  Then "svg画像リンクがあるURL"にアクセスする
  And "svg画像をダウンロード"のリンクをクリックする # ここでsvgデータを作成していた。
  And スクリーンショット
```

```test_feature.rb
 
step ':filenameを保存する' do |filename|
  page.save_screenshot "#{Rails.root}/directory_contains_actual_images/#{filename}.png", full: true
end
```

これで、一応、ファイルの保存が可能になります。
あとはreg-suitでここを読み取るように仕向ければ良いですね。

## 残りはというと
https://github.com/reg-viz/reg-puppeteer-demo#configure-reg-suit
で書いてある通りにすればOKです。
ぶっちゃけ、言い換えればcapture.jsの代わりをCapybaraで補うようにしただけです。
タイトル通りです！

ymlは

```config.yml
version: 2
jobs:
  build:
    docker:
      - image: circleci/ruby:2.6.4-node-browsers

    working_directory: ~/repo

# .... yarn installとかbundle installとか

    steps:
      - checkout
      - run: yarn install
      - run: bundle exec rspec
      - run: yarn run reg-suit run
```

へ置き変えればOKです。
specを実行するついでにダウンロード画像の検証もできるのでお得感はあるかもしれませんね。

## おわりに
アドカレ投稿ギリギリになってしまった。
ちょっと適当になったかもしれないので、あとで、実験用リポジトリをはるかもです。🙇‍♂️

明日は、[＠masayuki031](https://qiita.com/masayuki031)です。よろしくー！
VRoid Studioで着せ替え遊びをした話

 

※ この記事はVRoid初体験の“やってみた記事”です。


今回はVRoid Studioを利用して3Dモデルで遊んでみたいと思います。

やりたいことは

1. 衣装の着せ替え
2. ポーズを取って写真撮影

です。

それではやっていきます！

 

# VRoid Studioのインストール
まずはVRoid Studioをダウンロード&インストールします。VRoid Studioは無料で提供されているので、[公式サイト](https://vroid.com/studio)からダウンロードします。

Windows版とMac版が公開されています。僕はWindowsのため、Windows版をダウンロードしました。


# VRoid Studioをはじめる
早速起動すると、このような画面が立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/942160be-114b-4c1d-83db-893bcfd3a273.png)


VRoid Studioには7つのサンプルモデルが同梱されており、「自分で1から作るのはちょっと……」という人でもモデル制作の楽しさに触れることができます。pixivさん、流石です！

今回は一番左のViviちゃんのモデルを使用してみたいと思います。かわいらしい犬系妹キャラといった印象で、非常に好みです。

Viviちゃんを選択するとこの画面になりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/998d5c6d-ec19-ac5a-32af-79e30135f2e3.png)

一気に3Dモデル制作ソフトっぽくなりましたね。


# 衣装の着せ替え
では早速着せ替えに進みたいところですが、肝心の衣装は何処？

ということで、着させる衣装を入手しましょう。
VRoidの衣装は服の型紙のような画像ファイルです。この画像の場合、真っ白なワンピースに柄を巻き付けて貼っているイメージです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/b16ed88d-919a-b282-e7df-1c6bb580f1ee.png)


同じくpixivが運営しているboothでは、このような形の服の画像ファイルがたくさん売られています。
https://booth.pm/ja/search/vroid

販売されているものの中には無料配布されているものもあります。
今回はその中からdeltastar様のボタンワンピース（茶）を使用させていただくことにしました。
https://booth.pm/ja/items/1605562

気に入った衣装をダウンロードしてVRoid Studioに戻ります。

「衣装編集」を選択し、自分が用意した服の型（制服、ワンピース、パーカー）が現在の衣装の型と合っているか確認します。違っていた場合、画面右の「上半身」「下半身」から型を選択します。

選択ができたら「テクスチャ」を選択し衣装の編集を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/7691d72b-a4c9-c7a8-f54c-9394115d6251.png)

 衣装編集画面のテクスチャ > レイヤーを右クリック > インポートで先ほどダウンロードした衣装をインポートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/07d262b0-d007-6135-2f17-7a3980b1bba2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/526d7971-e461-f2a9-743a-bf3d074ea502.png)
着せ替え終了。

簡単すぎる……！

# ポーズを取って写真撮影
「着せ替えをしたらポーズをとらせたいし撮影会がしたい！したいったらしたい！」と僕の中の幼女先輩が言うので撮影会をします。

「撮影・エクスポート」から撮影会を始めます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/7503234f-a34a-ee19-4914-64a9245bd33b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/fa86602a-8ec2-8cce-4f5a-3e03dbe1e9e5.png)

この画面の操作は、

マウスホイール：ズーム
ホイール押下でドラッグ：視点の縦横移動
右クリックでドラッグ：視点の回転

です。
Unityと同じなのでUnity触ったことのある人はすぐにわかると思います。

ここで「表情」「背景」「ポーズ」などを設定していきます。
それぞれ画面右のスライダーでパラメータを調整できるので、自分好みのキャラクターを作りましょう！

 

完成品がこちら

**「私の部屋に入れる男の人なんて、お兄ちゃんだけなんだからね」**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436187/ec4e91e3-13c6-140d-3f7d-05d25adca244.png)


うぅ……かわいい……。

# まとめ
VRoid Studioは3Dモデル制作の最初の一歩を踏み出すのにはとても良いソフトだと感じました。

これからの時代、1人1アバター時代が来ると思います。そうした世界では、衣装の型が決まっていることで、自身のアバターの着替えなんかも無理なくできるようになったり、服が描けるイラストレーター、デザイナーは注目されるのかなぁと、素人ながら未来に思いを馳せてしまいました。
Web Share API を使ったページ共有を試してみた

はじめまして! 2019年10月フロントエンドエンジニアとして入社した上垣です。
入社してから今まで、 [Toreta now](https://www.toretanow.app/)のブラウザ版開発に携わっています。

toC サービスを開発していく中でよくある要件として、SNSへのページ共有が挙げられると思います。ただ、実装したことがある方ならおわかりと思いますが、シェアさせたいサービスごとに script を埋め込むのは結構大変です。

##### 代表的なサービスの共有方法
- Twitter
  - [Twitter Publish](https://publish.twitter.com/#)
- Facebook 
  - [シェアボタン - ソーシャルプラグイン - ドキュメンテーション - Facebook for Developers](https://developers.facebook.com/docs/plugins/share-button?locale=ja_JP)
- LINE
  - [LINE Social Plugins](https://social-plugins.line.me/ja/) 

Toreta now で共有機能の実装を検討していく中で、[Web Share API](https://developer.mozilla.org/ja/docs/Web/API/Navigator/share) の存在を知ったので、サービスに導入できるか検証してみました。


### Web Share APIとは
Web Share API は、ユーザーが選択した任意の宛先にコンテンツを共有するためのAPIです。
W3Cで仕様が公開されており、現在のステータスは W3C Editors Draft(編集者草案) となっています。

##### 仕様
[Web Share API](https://w3c.github.io/web-share/)

##### GitHub
[GitHub - w3c/web-share: Web API proposal for sharing data from a web page](https://github.com/w3c/web-share)


### 対応ブラウザ
Web Share API はまだ編集者草案のステータスですが、2019年12月時点では、Safari, iOS Safari と Chrome for Android の最新版で実装されています。

[Can I use... Support tables for HTML5, CSS3, etc](https://caniuse.com/#feat=web-share)


### 使用方法

window.navigator の share メソッドをシェアしたい内容を引数に渡して呼び出すことで、共有用ダイアログが表示されます。

JavaScript で実装してみたコードは下記のようになりました。

```javascript
 async share() {
    if (!window.navigator.share) ｛
        alert("ご利用のブラウザでは共有できません。");
        return;
    }

    try {
      await window.navigator.share({
        title: 'Share API で共有！',
        text: 'ご覧の通り、お手軽にSNSにリンクを供することができます。',
        url: 'https://example.com/hogehoge',
      });
      alert('共有が完了しました。');
    } catch (e) {
      console.log(e.message);
    }
}
```

##### 引数
- data : シェアする URL を表す文字列
- text : シェアするテキストを表す文字列
- title : シェアするタイトルを表す文字列

##### 戻り値
ユーザーがシェア操作を完了させたときに解決される Promise。


### 実践
実際に、上記コードを Android Chrome, iOS Safari で実行してみました。
（以下の例は私の端末で試したものです。端末にインストールされているアプリによって、シェア対象のアプリは変わります。)

##### Android 9 Chrome 78
<img width="687" alt="IMG_0769.jpg 2019-12-14 23-08-15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46222/509f8f93-de9c-80fb-a160-783b2a7c7849.png">


##### iOS 13.2.3 Safari
<img width="508" alt="Monosnap 2019-12-14 23-12-08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46222/58d9cf2b-f58d-91f8-7338-90017269ca77.png">


Android iOS 双方とも、SNSアプリに限らず、メモ帳やGmailなど、思ったよりも多くのアプリに共有が可能でした。Slack にも共有できたので、自分宛にメッセージを POST してみました。

##### Slack
<img width="511" alt="Monosnap 2019-12-14 22-50-29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46222/ca36e968-13d3-fadd-7676-a53e39f0ab5e.png">

title は表示できていませんが、指定したメッセージを共有することができました! :smile: 


### まとめ
Web Share API は、まだドラフトのステータスながら、最新の iOS safari, Android Chrome で十分使えるレベルで実装されていることがわかりました。

仕様変更の可能性を残しているとはいえ、モバイルメインのサービスであれば、十分に利用検討の価値があるのではないでしょうか。
【画像処理100本ノックに挑戦】Q.12. モーションフィルタ

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

# Q.12. モーションフィルタ
> モーションフィルタ(3x3)を実装せよ。
モーションフィルタとは対角方向の平均値を取るフィルタであり、次式で定義される。
  1/3  0   0
  0  1/3  0 
   0   0  1/3

これもカーネルを変えるだけです。単純なブレのモデルに相当します。

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

	auto kernel = [&](int i, int j)
	{
		double ret = 0;
		if (i == 0 && j == 0) ret = 1;
		else if (i * j == 1) ret = 1;
		return ret;
	};

	auto conv = [&](const std::vector<std::vector<double>>& f)
	{
		std::vector < std::vector < double >> ret(width, std::vector<double>(height));
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				ret[i][j] = 0;
			}
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				int sum = 0;
				for (int di = -1; di <= 1; di++)
					for (int dj = -1; dj <= 1; dj++)
					{
						if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
						{
							ret[i][j] += kernel(di, dj) * f[i - di][j - dj];
							sum += kernel(di, dj);
						}
					}
				ret[i][j] /= (double)sum;
			}
		return ret;
	};

	std::vector < std::vector < double >> arrr(width, std::vector<double>(height));
	std::vector < std::vector < double >> arrg(width, std::vector<double>(height));
	std::vector < std::vector < double >> arrb(width, std::vector<double>(height));
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			arrr[i][j] = ppm(i, j, 'r');
			arrg[i][j] = ppm(i, j, 'g');
			arrb[i][j] = ppm(i, j, 'b');
		}
	arrr = conv(arrr);
	arrg = conv(arrg);
	arrb = conv(arrb);

	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			ppm2(i, j, 'r') = arrr[i][j];
			ppm2(i, j, 'g') = arrg[i][j];
			ppm2(i, j, 'b') = arrb[i][j];
		}

	ppm2.Flush("out.ppm");
	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/7a0ea8b8-80e0-8b84-ce2e-f59fc586871b.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/30356f3b-7036-0987-ecc7-b5b18bcb4104.png)
オブジェクト指向について

今回は考え方に立ち返って
書いて見ようと思います。

# オブジェクト指向とは
オブジェクト指向とは、複数のオブジェクトを組み合わせてプログラムを構築する考え方です。

メソッド、関数を作成して分業で行っていく方式だと思ってください。

近似で手続き型もありますが、オブジェクト指向で作って行けば
どこのオブジェクトで問題がなど発見しやすくなるメリットがあります。

## オブジェクト
オブジェクトとはデータと処理の集まりです。
漠然とした集まりではなく、ひとつのテーマを持った集まりです。

例：個人データの場合

加藤さん(名前、性別、年齢、教えて(処理))
佐藤さん(名前、性別、年齢、教えて(処理))

オブジェクトが加藤さん、佐藤さんにあたります。

集まっているデータの内
　状態を表すのが名前、性別、年齢になります。
　処理となるのが[教えて]、[データを加えて]などになります。

この場合は格オブジェクトに
データと教えてもらう処理も入っていると言うことです。

# オブジェクトの例
katouと言うオブジェクトを作成して
answer_nameメソッドで名前を出力しています。

```ruby:オブジェクトの例
class Person
  def initialize(name, birthday, age, address)
    @name = name
    @birthday = birthday
    @age = age
    @address = address
  end

  def answer_name
    puts @name
  end
end


# 実行結果
katou = Person.new("katou", "2000/5/5", "19", "名古屋市")
=> #<Person:0x007fc55c1604f8 @name="katou", @birthday="1993/5/5", @age="23", @address="東京都渋谷区道玄坂">
irb(main):016:0> katou.answer_name
katou
```

# オブジェクト指向の例
次はrailsで使用した場合で
コントローラーに処理をまとめて書き込むことで
viewのコードを最小限にしました。

またviewの場合それぞれ独立していて
仕様の変更があった場合コードの更新が必要ですが
これならコントローラーの更新だけですむので大変楽になります。


```ruby:コントローラー
class Person < ActiveRecord::Base
  belongs_to :company

  def display_info
    if company
      "#{name} (#{company.name} 所属)"
    else
      "#{name} (フリーランス)"
    end
  end
end
```

```erb:view
<%= @person.display_info %>
```

# 役に立つ原則

オブジェクト指向には様々な原則がありますが
少しピックアップして説明します。

## DRY
DRYとは、Don't Repeat Your Selfの略で繰り返しを避けるという原則です。

重複があると、アプリケーションのコードは不必要に大きくなりエラーが起きやすくなるので
メソッドを作成と使い回しして、コードをすっきりさせようと言うことです。

## YAGNI
YAGNIとは、You Aren't Gonna Need It の略で実際に必要になった機能だけを追加すべきという原則です。

かもしれないで追加したり、放置したりせず
コードの掃除をこころがける原則です。

## 単一責任の原則
単一責任の原則とは、クラスが果たす役割を一つだけにするという原則です。

例えば、名前を入力するメソッドと
名前を出力するメソッドがあります。

仕様の都合でまとめることがありますがエラー発見の遅延に繋がるので
役割は絞る原則です。

## インターフェイス分離の原則
インターフェイスは専用化する原則で

格クライアントで共通インターフェイスを使った場合
異なる不要メソッドが存在し下手に更新すると影響が出てしまいます。

よって格クライアントごとに専用化して不要メソッドはできるだけ
影響しないようにします。
SystemSpecでログインできない時のお話


新たにSystem Specを導入しようとした時のお話です。

### 事象
ログイン処理を実装した時にログインができませんでした。

### 条件
・ローカルの画面上ではログインできる
・Factoryのデータ作成もできている
・他のSpecにて、Factoryを使用したデータではログインできる = Factoryで作成するデータ構造は正しい
・Feature Specでは成功した = System Specの記述もおかしくなさそう

### 結論
Database Cleanerを導入していてFactoryで作成したデータが消えたためログインできなかったようです。

### 解決方法
Database Cleanerの記述自体を消した時に他のSpecの挙動がおかしくなったから次の書き方で対応しました。
・ `use_truncation: false ` を適用させてDatabase Cleanerを無効
**参照**
https://qiita.com/takeyuweb/items/e7261e9274b3b31d933c


```ruby:XXXX_spec.rb
RSpec.describe 'XXXX', type: :system do
  # ここにはDatabase Cleanerを適用させない
  context "Login", use_truncation: false do
    it 'is login test' do
      expect(page).to have_content 'ログインしました'
    end    
  end
end
```


```ruby:rails_helper.rb
RSpec.configure do |config|
.
.
  config.use_transactional_fixtures = true
.
.
end
```

### Database Cleanerについて
テスト毎にデータベースを空(truncate)にする機能。

Database Cleanerの設定記述を消してSpec実行してみると
テストテーブルにデータが残っていることを確認できます。


[伊藤さんのブログ](https://blog.jnito.com/entry/2018/03/12/053153)(Database Cleaner)より抜粋します。
>Rails 5.1ではDatabase Cleanerはもう必要ありません。

基本的にはDatabase Cleaner自体導入しなくても良さそうです。
途中からSystem Specを導入しようとしたら同じような事象が発生するかもしれませんね。


今まで特にDatabase Cleanerを意識したことがないので良い経験になりました。

他の皆さんはこのような事象に遭遇したことありますか？
もし、経験された方がいましたらどのような対応されたか教えていただけると嬉しいです。

### 追記
System Specでは **データベースが自動的にロールバックされる** みたいです。
(データベースの自動ロールバック)
https://techracho.bpsinc.jp/hachi8833/2018_01_25/51101

だからFeatureSpecでは同じ記述でもログインできました。
ASP.NET Core 3.1でAzure Active Directory B2Cを最速で使えるようにする

# 結論

Azure Active Directory B2Cを作成し、 `appsettings.json`に次のように書く。

```json
{
  "AzureAdB2C": {
    "Instance": "https://login.microsoftonline.com/tfp",
    "ClientId": "12ab1845-7adb-4d66-a094-eca217a58f31",
    "CallbackPath": "/signin-oidc",
    "Domain": "aspdotnetcoretest0000.onmicrosoft.com",
    "SignUpSignInPolicyId": "B2C_1_SUSI",
    "ResetPasswordPolicyId": "B2C_1_RESET",
    "EditProfilePolicyId": ""
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}
```

設定内容と、`appsettings.json` との関係はこんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7886/2f8c3f7f-62d3-9f0e-8505-e784ecbc5e89.png)


# 注意点

ASP.NET Core 3.1のテンプレートを使用して、認証情報を設定してしまうと、当然Gitにもコミットされた状態でプロジェクトが作成されます。ここでは適当な値を入れておいて、`.gitignore`してから設定値を入れるのが無難だと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7886/5ed2a0d6-114d-f4fc-b3f1-2dec538039de.png)

# 終わりに
これだけの設定で認証できちゃうとか簡単！
本当にありがたい！

ちなみに、説明で使用したディレクトリは完全に抹消しましたけど、セキュリティとか問題があればコメントください。

ディレクトリの削除方法は、こちらが分かりやすいです。
- [Azure AD で B2C のディレクトリを削除しようとすると、「削除することはできません」エラー](https://support.microsoft.com/ja-jp/help/3112170/cannot-delete-error-when-you-try-to-delete-a-b2c-directory-in-azure-ad)

ここまでご覧いただきありがとうございます。
postgreSqlのindexはいくつも作用するということで、mysqlのindexについて調べてみた

##mysql index
クエリにindexを使用するのは、一つしか使えない

mysqlでは、一つのテーブルにつきいくつインデックスがはってあっても一つしか使えない
Indexマージという機能が、Mysql5.6から備わったがあまり使えない
これは、indexのタイプが違うと使えない不具合があがってる。
（複合インデックスなら使えるみたい？）

##インデックスと複合インデックスの違い
https://qiita.com/towtow/items/4089dad004b7c25985e3

###インデックス
インデックスは、並び順序のこと
イメージとしては、インデックスをつけるとデータベース内のデータ列がインデックスをもとに並べられているイメージ
それで例えば、idにIndexを貼ったときだと、idを検索対象にするとDBMSがインデックスを利用して高速の検索を行ってくれる。

###複合インデックス
複数の並び替え条件でインデックスを作る
複数のインデックスを考慮して、並び替えてくれる

###主キーのインデックスと普通のインデックス
インデックスという点では違いがないが、主キーはDBが自動でインデックスをつけるため削除不可である

###すべてにインデックスをはるデメリット
- DBMSがまちがったIndexを使ってしまう可能性がある
- 登録時にインデックスの再生成が行われる際に、おおいと多いだけ時間を使ってしまう
###デメリット操作時の対策
インデックスを指定する（ヒント句を使用する）でやれば、indexを指定できるが、めんどくさいのと、上記より登録に時間を要してしまう

インデックスは、DBMSのクエリ評価エンジンの中のオプティマイザが判断して、使っているが、オプティマイザは、その判断基準として、テーブルの統計情報を利用している

###テーブルの統計情報とは
・テーブル統計（行数・ブロック数）
・列統計（カージナリティ・NULL数・最小・最大）
・索引統計（リーフブロック数・ツリーの高さ）
・システム統計（CPU性能　I/O性能）

###統計情報
統計情報は、すぐに更新されるわけではない。たいていは、一定期間ごとに更新が設定されていたりするが、データ追加直後は統計情報は切り替わらない
そういった場合で、大量データだった場合しっかりメンテナンスしてあげる必要がある。
##RDBMS（Oracle、Sql Server、MySql、PostgleSql)のおおまか
###SQLの実行流れ
####パーサー
パースを行い、RDBMSが処理しやすい形式に変換する
１、命令文のチェック（整合性）
２、定型文に変えることで、このあと機能で処理する部分が楽になる

####オプティマイザ
１、カタログマネージャーから受け取った統計情報を元に、最適なデータアクセス方法を決める

####カタログマネージャ
オプティマイザに情報提供する（統計情報）
https://qiita.com/NagaokaKenichi/items/5b6eb9887f88046a594d

##Explain type

####type速さ順
- 1.const
pk or uniqueインデックスを使ったアクセス（検索）
- 2.eq_ref
joinにおいてのconstと同じ
- 3.ref
constでないインデックスを使って等価検索(where k = v)を行った時に使用されるアクセス
- 4.range
indexを用いた範囲検索
- 5.index
フルインデックススキャン、インデックス全体をスキャンしているので遅い
- 6.ALL
フルテーブルスキャン、インデックスが全く使用されていないことを示す

※All以外はIndexが使用されている

##複合Indexのよい利用
https://qiita.com/keii1111/items/02861c74bcd57ab1e290

複合Indexをうまく効かせるには、Indexの順番を意識して使う

例えば、where文とorder by句が入っている命令文があったら、基本的にwhereしてから、order byがはたらく、つまり、whereのほうにindexの順番が前のもののほうが、有効に働く
（データ的にそう並んでいるため）これがwhereにindexの後ろのものを利用したりすると、有効に働かない

https://qiita.com/keii1111/items/02861c74bcd57ab1e290

##posgre index種類　チューニング
https://www.slideshare.net/InsightTechnology/dbts-osaka-2014-b23-postgresql-tomonari-katsumata

##mysql と　postgresql比較記事
https://employment.en-japan.com/engineerhub/entry/2017/09/05/110000

####mysql 
単純なWebシステムの際に使用する

####postgresql
カスタム性が高い

どっちも高機能にUpdateされるため、つかいたいほうでいいという平和的結論
「自動化するテストを選ぶ」というときに気をつけたいこと

この記事は[ソフトウェアテスト Advent Calendar 2019](https://qiita.com/advent-calendar/2019/softwaretesting)の14日目です。昨日はgratkさんによる[レガシーテストからの脱却 - てくてくてすと](http://gratk.hatenablog.jp/entry/2019/12/13/000233)でした。

## はじめに

よく「全てのテストを自動化するのは困難」「自動化する/しないを考えるのが大事」と言われます。最初はこの投稿も「どのテストを自動化してどのテストを自動化しないかの選択」について書こうと思っていたのですが、書いているうちにその前段の話を言いたくなってきたのでこっちの話題にしました。

今回言いたいのが

> どのテストを自動化してどのテストを自動化しないか、を考えることは、どのテストケースを自動化してどのテストケースを自動化しないか考えることとは別ですよね

ということです。

そりゃそうだ、という方は別にいいのですが、そこ混同している方もたまにいるので、改めて考えてみてほしいなと思っています。

### 前提

本記事では、システムテストのテスト実行自動化を主なターゲットにしています。他のテストレベルでも当てはまる点があるかもしれませんが、メインはここです。

## いまある手動テストを自動にただコンバートするのはよくない

「テスト自動化」という単語を「今現在手動で行っているテストケースを自動実行できるものにコンバートすること」という意味で使っているのを目にします。こういう考え方をしていると、「自動化率」のような危険な指標が出てきます。

手動でやっているものを自動実行できるようにそのままコンバートすると何が問題なのでしょうか。いくつか例を挙げます。

### 問題１：テストケースが曖昧で自動化に手間がかかる

- 期待結果に「結果が正しいこと」とか書いてある
- 「任意のデータを選択」と書いてある

など、そもそもテストの実行に人間の判断の余地が残っている場合が多いです。

判断の余地が残っていること自体は必ずしも悪ではなく、そのチームが色々考えた結果のテストがそうであったのならば、私は良いと思います。

しかし、多くの場合はそういった意図が無い状態で単にあいまいな書き方になっています。（個人の感想です

そういった曖昧なテストケースやテスト手順をそのまま自動化しようと思うと、都度都度「ここでは具体的にどんな結果になればいいのか」「データはどれを使うのか」など詳細を詰めていかないといけません。

私としては、この手の「既存のテストケースの詳細化」は全く無意味ではなくて、これまでにテスト実行者依存でやってきた部分が明らかになる等のメリットはあると思っています。

が、「テスト自動化＝テスト実行コスト削減」だと考えているチームでこの問題が起きると、「自動化しても手間が増えて実行コスト減らないじゃん」と言って自動化を止めてしまう可能性があります。

### 問題２：手動実行に最適化されていて、自動だと効率が悪い

自動化の経験はないけれどテスト設計にはこなれてます、という方がテスト設計をすると、無意識のうちに「手動で実行したときの効率の良さ」を考えたテスト設計になっています。

細かい点でいうと、テスト手順書上でのテストケースの並びを工夫して前のケースで使ったデータが次のケースで使えるようにしたり、ログインログアウトやデータ読み込みなどの処理をなるべく少なく済ませるような工夫をしたり、などです。

こういった「手動実行向けの工夫」が、例えばデータ駆動テストをしよう等と考えたときにやりづらかったりします。その結果、実行時間が延びたり、自動テストが安定しなかったり・・・という状況につながっていきます。

### 問題３：自動化率を気にし始める

5年くらい前は「自動化のROIがー」みたいな話がすごくされていた気がしますが、特に「自動化率」を気にする方が多くいました。

この「自動化率」は私はあまり有効な指標ではないなぁと思っていまして、率というからには全体があるわけですが、その全体が「既存のテスト」でいいの？というのが主な疑問です。

今あるテストがイマイチだったら、それを100%自動化しても、自動でイマイチなテストが実行されるだけです。

また、お金と時間が無限にあるのであれば「100%自動化だ！」とチャレンジしてもいいかもしれませんが、実際にはそんなことはありません。

- 自動化が容易でかつ効果的なテスト
- 自動化が容易だが効果は少なめなテスト
- 自動化が困難だが効果的なテスト
- 自動化が困難で効果が少なめなテスト

のざっくり４パターンのうち、仮に上から３つはやったとしても、一番下までやる必要があるのかは考えたほうがいいでしょう。

## 結局どうすればいいのか

今あるテストケースのうち、どのケースが自動化できてどのケースが自動化できないのか、を考えるのではなくて、テスト設計もしくはさらに前の段階からどんなテストを自動化するのかしないのかを考えていきましょうね、という話です。

そのへんの具体的な話は[yasuaki_hiruta](https://qiita.com/yasuaki_hiruta)さんの[自動テストを考慮したテスト設計　〜概念〜 - Qiita](https://qiita.com/yasuaki_hiruta/items/90ad31f0e8731961cdc2)および今後の投稿を読むとわかると思います！（丸投げ）

私もいつも「テストケースで今あるものを自動化するんじゃなくて、自動化ツールやら自動化の知見を含めてテスト開発を行うべきなんですよ」と他人には言っているものの、正直な話体系化までは出来てなくて、「たとえばこう考える」とかポイントでの要素しか持ってない状態です。考えを小出しに公開していくつもりです。

自動化考慮したテスト設計はかくあるべし、的な確固たるものがすでにある方はぜひ公開いただけると嬉しいです。
Azure上でWordPressのサイトを10分で無料で作成する方法

#Azure上でWordPressのサイトを10分で無料で作成する方法
1.以下のサイトにアクセスして、Azureのアカウントを作成します。
    https://azure.microsoft.com/ja-jp/free/ 

2.Azureにサインインし、「リソースの作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/ab3b3317-2f9b-c7dd-38de-d7fd66209a95.png)

3.「WordPress」と検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/0239c536-16b4-87ed-d8a3-c348d951e3e0.png)

4.「作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/4f4cf5e9-e180-c8b9-8f65-c5b97cf1923a.png)

5.「アプリ名」を入力し、「データベース プロバイダー」で「MySQL In App」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/19b03f91-f4ae-5ec1-9866-90eafab77dea.png)

6.「App Service プラン/場所」をクリックし、「新規作成」をクリックします。その後、「App Service プラン」を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/306f44ca-1dd8-813f-c1b7-1922490aa09c.png)

7.「価格レベル」をクリックします。

8.「開発/テスト」タブをクリックし「F1」を選択した後、「適用」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/f1202689-abd6-6dd7-6391-f3ce4e0a755d.png)

9.「OK」をクリックし、新しいApp Serviceプランを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/1bb4e797-7248-80da-e08b-de1db98bf1da.png)

10.「Application Insights」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/10374f53-f717-3c14-11bd-b9e8597cf990.png)

11.「無効」をクリックし、「適用」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/2b13ee67-4402-6506-d3a7-35ce2acb0a3b.png)

12.「作成」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/4c7c45b9-6788-3980-e2b0-34ce022f7562.png)

13. デプロイが完了したら、URLにアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/17048a39-02d4-933e-8fee-7acd0eb02ca0.png)

14. あとはWordPressで設定を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/276299/757cb663-b56e-5c2c-9559-7545670f7b5b.png)
[React] 「create-react-app」環境構築を忘れないようにメモ

# Reactの環境構築
```
npm install -g create-react-app

create-react-app react-app

cd react-app

npm start
```

```
├── .gitignore
├── README.md
├── package.json
├── node_modules
├── public
│   ├── favicon.ico
│   └── index.html
└── src
    ├── App.css
    ├── App.js
    ├── App.test.js
    ├── index.css
    ├── index.js
    └── logo.svg
```
【画像処理100本ノックに挑戦】Q.11. 平滑化フィルタ

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

# Q.11. 平滑化フィルタ
> 平滑化フィルタ(3x3)を実装せよ。

これもよく使います。構造があまりなく滑らかな画像に向いています。Q.9のガウシアンフィルタのカーネルだけ入れ替えればすぐ出来ます。

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

	auto kernel = [&](int i, int j)
	{
		return 1.;
	};

	auto conv = [&](const std::vector<std::vector<double>>& f)
	{
		std::vector < std::vector < double >> ret(width, std::vector<double>(height));
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				ret[i][j] = 0;
			}
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				int sum = 0;
				for (int di = -1; di <= 1; di++)
					for (int dj = -1; dj <= 1; dj++)
					{
						if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
						{
							ret[i][j] += kernel(di, dj) * f[i - di][j - dj];
							sum += kernel(di, dj);
						}
					}
				ret[i][j] /= (double)sum;
			}
		return ret;
	};

	std::vector < std::vector < double >> arrr(width, std::vector<double>(height));
	std::vector < std::vector < double >> arrg(width, std::vector<double>(height));
	std::vector < std::vector < double >> arrb(width, std::vector<double>(height));
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			arrr[i][j] = ppm(i, j, 'r');
			arrg[i][j] = ppm(i, j, 'g');
			arrb[i][j] = ppm(i, j, 'b');
		}
	arrr = conv(arrr);
	arrg = conv(arrg);
	arrb = conv(arrb);

	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			ppm2(i, j, 'r') = arrr[i][j];
			ppm2(i, j, 'g') = arrg[i][j];
			ppm2(i, j, 'b') = arrb[i][j];
		}

	ppm2.Flush("out.ppm");
	return 0;
}
```

![imori.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/0c5d2d0d-9bad-6778-9b6f-e80021e77b16.png) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/fe9ebac5-df91-6e8e-6534-19139bb27511.png)
まだCSS使ってるの？SCSS(Sass)を使ってみよう！【入門編】

# はじめに
HTMLやCSSを少しでもかじった方ならわかると思いますが、CSSを書いているとき

- ネストで書けないかな？
- 変更するときに複数の箇所を変更するのが面倒...
- 使いまわしたいところがある
- コメントを/**/で囲むのが面倒...

こんなことを思ったことがありませんか？

実はこれらがSass(SCSS)で簡単に解決するのです！！

# SassとSCSSとは？
SassとはSyntactically Awesome Stylesheetsの略です
自分でAwesome（すばらしい）と言うなんてすごい自信ですね（笑）
SassとSCSSの違いを簡単に言うとSassはインデント、SCSSはネストを使ってCSSを楽に書けるようにするものです
今回は私の使っているSCSSの方を紹介します

# ネストで書いてみよう
実際に↓のようなものを作ると
![ex1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448051/8ee2e764-be80-4114-a711-9af0e3b4d59f.gif)
CSSはこのようになります。

```css:css
ul {
  width: 100px;
  background-color: #4d747e;
  padding: 20px;
  list-style: none;
}

ul li {
  font-size: 24px;
  color: #fff;
}

ul li.second {
  color: #e24350;
}

ul li:hover {
  background: #55c500;
}
```
`ul` `ul li` `ul li.second`　`ul li:hover`のように同じものを何回も繰り返すの面倒に思いませんか？
それではSCSSを見てみましょう♪

```sass:scss
ul {
  width: 100px;
  background-color: #4d747e;
  padding: 20px;
  list-style: none;
  li {
    font-size: 24px;
    color: #fff;
    &.second {
      color: #e24350;
    }
    &:hover {
      background: #55c500;
    }
  }
}
```
このように繰り返しを減らすだけでなく、親子関係がわかるので非常に重宝します
**ただし、SCSSでは`&.second` `&:hover`のなどは`&`を付けないと機能しないので注意が必要です！**

# 変数を使ってみよう
![FireShot Capture 506 - Sass(SCSS) - .png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448051/64309a05-8060-2b72-91b9-b914a85a95c6.png)
このCSSは普通に書いても簡単なのですが、

```css:css
h1 {
  color: #e66317;
}
p {
  color: #e66317;
}
```
SCSSで書くとこんな感じになります。

```scss:scss
$text_color: #e66317;
h1 {
  color: $text_color;
}
p {
  color: $text_color;
}
```
これはかんたんな例なのであまり恩恵はありませんが、`$text_color`の色を変えるだけで他の色を変えることができるということは後々10個とか変えないといけなくなったときに重宝します。

# コメントを書いてみよう
`/**/`ではなくて`//`でコメントになるよ！（やったね！！）
っていうだけです（**でも地味にありがたいんです**）

# 最後に
SCSS（Sass）にはまだまだ便利な機能がたくさんあるのですが、今回はここらへんで終わりにします。
これを見てSCSS（Sass）使ってくれたら嬉しいです！
【画像処理100本ノックに挑戦】Q.10 メディアンフィルタ

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

# Q.10 メディアンフィルタ
> メディアンフィルタ(3x3)を実装し、imori_noise.jpgのノイズを除去せよ。

Q.9のガウシアンフィルタを少し改造すれば簡単です。普段はガウシアンフィルタを使うよりもメディアンフィルタを使うことが多いです。

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

	auto median = [&](const std::vector<std::vector<double>> &f)
	{
		std::vector < std::vector < double >> ret(width, std::vector<double>(height));
		for(int j=0; j<height; j++)
			for (int i = 0; i < width; i++)
			{
				ret[i][j] = 0;
			}
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				std::vector<int> list;
				for(int di=-1; di<=1; di++)
					for (int dj = -1; dj <= 1; dj++)
					{
						if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
						{
							list.push_back(f[i - di][j - dj]);
						}
						else
						{
							list.push_back(0);
						}
					}
				std::sort(list.begin(), list.end());
				ret[i][j] = list[4];
			}
		return ret;
	};

	std::vector < std::vector < double >> arrr(width, std::vector<double>(height));
	std::vector < std::vector < double >> arrg(width, std::vector<double>(height));
	std::vector < std::vector < double >> arrb(width, std::vector<double>(height));
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			arrr[i][j] = ppm(i, j, 'r');
			arrg[i][j] = ppm(i, j, 'g');
			arrb[i][j] = ppm(i, j, 'b');
		}
	arrr = median(arrr);
	arrg = median(arrg);
	arrb = median(arrb);

	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			ppm2(i, j, 'r') = arrr[i][j];
			ppm2(i, j, 'g') = arrg[i][j];
			ppm2(i, j, 'b') = arrb[i][j];
		}

	ppm2.Flush("out.ppm");
	return 0;
}
```
![imori_noise.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/20634bd3-38e1-91e2-8faf-4463347b7a7b.jpeg) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/6278bce1-8c1c-246e-e07f-30da897255ef.png)
さすがメディアンフィルタ、こういうスパイク的なノイズには非常に有効です。エッジもよく保存されています。
【画像処理100本ノックに挑戦】Q.9. ガウシアンフィルタ

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

# Q.9. ガウシアンフィルタ
> ガウシアンフィルタ(3x3、標準偏差1.3)を実装し、imori_noise.jpgのノイズを除去せよ。

畳み込みですね。普段は適当な閾値で切って、もっと大きなカーネルサイズで使ってます。速度が必要な時はFFTを使います。

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

	auto kernel = [&](int i, int j)
	{
		double ret = 2;
		if (i == 0 && j == 0) ret = 4;
		else if (abs(i) == 1 && abs(j)==1) ret = 1;
		return ret;// / 16.;
	};

	auto conv = [&](const std::vector<std::vector<double>> &f)
	{
		std::vector < std::vector < double >> ret(width, std::vector<double>(height));
		for(int j=0; j<height; j++)
			for (int i = 0; i < width; i++)
			{
				ret[i][j] = 0;
			}
		for (int j = 0; j < height; j++)
			for (int i = 0; i < width; i++)
			{
				int sum = 0;
				for(int di=-1; di<=1; di++)
					for (int dj = -1; dj <= 1; dj++)
					{
						if (i - di >= 0 && i - di < width && j - dj >= 0 && j - di < height)
						{
							ret[i][j] += kernel(di, dj) * f[i - di][j - dj];
							sum += kernel(di, dj);
						}
					}
				ret[i][j] /= (double)sum;
			}
		return ret;
	};

	std::vector < std::vector < double >> arrr(width, std::vector<double>(height));
	std::vector < std::vector < double >> arrg(width, std::vector<double>(height));
	std::vector < std::vector < double >> arrb(width, std::vector<double>(height));
	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			arrr[i][j] = ppm(i, j, 'r');
			arrg[i][j] = ppm(i, j, 'g');
			arrb[i][j] = ppm(i, j, 'b');
		}
	arrr = conv(arrr);
	arrg = conv(arrg);
	arrb = conv(arrb);

	for (int j = 0; j < height; j++)
		for (int i = 0; i < width; i++)
		{
			ppm2(i, j, 'r') = arrr[i][j];
			ppm2(i, j, 'g') = arrg[i][j];
			ppm2(i, j, 'b') = arrb[i][j];
		}

	ppm2.Flush("out.ppm");
	return 0;
}
```
![imori_noise.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/d3d1bf29-e2f4-d0bb-514f-6e9fabfdb18a.jpeg) ![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/f2f8ef51-b537-9b38-ddc9-c7682913bde5.png)
heroku 練習 領域名の登録 タイムゾーン設定　mysql設定　メモ  Application error

#herokuを使っていてエラーが良く出たのでメモを取りました

##login後アプリケーションを登録からです
###自分のアプリケーション用の領域を名前を付けて確保する
```heroku
heroku create アプリケーションの領域名
```

###タイムゾ－ン設定
```heroku
heroku config:add TZ=Asia/Tokyo --app アプリケーション領域名
```

###タイムゾーンの確認
```heroku
heroku run date --app アプリケーション領域名
```
JSTで日本のタイムゾーンになっている

###herokuでmysqlを設定
```heroku
heroku addons:create cleardb:ignite --app アプリケーション領域名
```

##heroku Application error
set HEROKU_DEBUG=1
heroku war:deploy アプリケーション.war --app アプリケーション領域名 --webapp-runner 8.0.50.0

アプリケーションのパスに日本語が含まれるとページにアクセスしても表示されないかったので
パスに日本語が含まれない位置に移動させデップロイすることで解決できました
Azure認定資格 AZ-300を取得しました

Azureの認定資格体系が2019年から変わりました。
以下は [ロードマップ](https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RE2PjDI) からの引用です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/27a7f3b2-27c7-fe61-969e-e6bed0c937e7.png)

AZ-103と [AZ-203](https://qiita.com/shingo_kawahara/items/551ac6b880a4a59e4291) は前に取得したので、次にExpertレベルの [AZ-300 Microsoft Azure Architect Technologies](https://www.microsoft.com/ja-jp/learning/exam-az-300.aspx) を受験してきました。
今回かなーり苦戦したので、注意点などを纏めます。参考になればと思います。

# 試験の傾向は？

* 問題：56問
問題数は毎回変わるかもしれません。私が受けた時は56問でした。
これまでのAssociate試験やMCP試験と同じように「2択問題」「1問1答」「ケーススタディ」は出題されました。各セクションを先に進めると前のセクションに戻ることができません。
そして、今回最も特徴的だったのが、上記に加えて「実技」が含まれています。
これがほんとに苦労したので後ほど詳しく書きます。

* 時間：180分
申込みでは210分になっていますが、そのうち30分は事前の同意書などの時間なので、実際は180分です。

# 試験範囲

* インフラのデプロイと設定(25~30%)
* ワークロードとセキュリティの実装(20~25%)
* アプリの作成とデプロイ(5~10%)
* 認証とセキュアなデータを実装(5~10%)
* CloudおよびAzureストレージ用の開発(20~25%)

今回も幅広いですね。
Expert試験だからなのか、出題内容が少しマニアックだなと思いました。
あるサービスの細かい仕様やオプションなども出てきます。

# 学習方法

普段からAzureをよく触っているので資格のための勉強はほとんどやっていませんが、触ったことがないサービスやオプションは [Microsoft Learn](https://docs.microsoft.com/ja-jp/learn/) を使ったり、実際にAzureに構築してみたりしました。
実技があるので、ドキュメントだけじゃなくて実際に触ったほうが絶対にいいです。

# 実技
さて、本題の実技です。
実際にAzurePortalにログインして、課題を解いていく（Azureを操作していく）ことになります。
実技ありと知らなかったのでちょっと焦りました。（公式ページに書いてないような？）
そしてこの実技が中々の曲者でした。。

## 注意点1: キーボード英語配列

まず注意点としてキーボードが英語配列です。
なので、@とか"とかがいつもと違います。どこで困るかというと、AzurePortalにログインするときのパスワードです。パスワードなので入力した文字は見えません。(●●● みたいな表記になる)
なのでちゃんと@になっているかといった確認ができません。
私はIDを入力する画面で、パスワード文字列がちゃんと合ってるかの確認をしてからログインしました。
ちなみにAzurePortalにログインするときのID/Passwordは試験画面に表示されます。

## 注意点2: キーボード入力誤認識
まぁとはいえ、英語配列はそこまで問題じゃないです。
一番の問題はキーボード入力した際に画面に反映される文字列が誤認識される！
これは本当に困りました。以下のようなイメージです。
「User」という文字をぱぱっと打ったときに、「ssrr」みたいな感じになって最初の「U」や途中の文字を認識してくれなかったりします。
キーボードを早く打つとなぜか反映されない！
反映されるのが遅いだけならまだしも全然違う文字列になってしまう！

仕方ないので試験中に以下のような方法を編み出しました。
「U (1秒置く) s (1秒置く) e (以下略」

これは試験会場やそのときのPCがたまたまダメだった可能性が高いかもしれませんが、もし同じようなことになったら注意してください。

英語配列＋誤認識で、AzurePortalにログインするところでいきなり躓くという試練でした。。

## 注意点3: デプロイに時間が掛かる
実際にサービスをデプロイするので、ものによっては時間が掛かります。待ち時間が発生します。
それほど長くはないのですが、ここでの注意点としては「デプロイに時間が掛かるような選択はしないこと」です。
ほとんどの設問はやり方が1つしかないものになってますが、ものによっては何通りかやり方が思いつくことがあります。
そのときは最もデプロイに時間が掛からない方法を選んだほうがよいです。

## 注意点4: プレビュー中のサービスやオプションはどう捉えればいいのか
例えば、「XXXという要件を満たしたいときに、最もコストパフォーマンスに優れた選択をしてください」みたいな設問があったときに、GAされてる中ならAという答えだが、プレビューも含めるとBという答えになるな。という悩みに当たりました。
実際のAzureを使っているのでプレビュー中のものも表示されてくるんですね。
これは何が正解かはいまだに分かりません。私はプレビューは選ばずにGAされているものの中でやるという自分ルールにしました。

## 注意点5: Azure Portal画面が固まる
これも焦りました。画面が固まったり、リージョンを選ぶときに永遠と読み込み中になったり。。
ブラウザで新規タブは開けますが、ポータル以外は開こうとするとエラーになります。
なので画面が固まったら、新規タブを開いて、portal.azure.com を手打ちして凌ぎました。

# まとめ
実技で色んな困難に当たった結果、3問くらい時間が足りず間に合いませんでした。
とはいえ、合格点700点ですが、821点で無事合格することができました！

実技はキーボードの問題があったものの、実際にAzureを触って構築することができるかを問われるので、実務寄りでいいなと思いました。

AZ-300は実技と時間との勝負です。
次はAZ-301を目指したいと思います。

以上
時系列データをサクッと表示するinfotype


#やりたいこと
IoTデータって時系列データであることが多いと思いますが、標準のline chart infotypeだと物足りないです。色々と調べると、[c3.js](https://c3js.org/)というグラフ・ライブラリが良さそうです。D3.jsの親戚のようですね。

- マウスオーバーで値を見られる様にする
- 縦軸の最大値、最小値を指定できるようにする
- 横軸に適切に時刻を表示する

#完成したInfotype
c3.jsを使ったinfotypeを作ってもらいました。
enebular.comの[Discover](https://enebular.com/discover/infotype/45f38817-f396-423c-b0d2-16ae75ae5309)にありますので、自分のプロジェクトにインポートできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266424/adcbfe48-0fa3-d24e-a11f-24717d73b91b.png)

パラメータを色々いじって、previewボタンを押してみましょう。ちゃんと動きそうです。

以下にある現状の標準Line chartよりも、ExcelやBIツールで見るグラフに近くなっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266424/d29bfc11-4482-9425-d351-1aab668a521d.png)


#動作確認
##フローを作ってデプロイする
###リモートモード
Grovebasehatを載せたラズパイにenebular editorでリモートモードでアクセスします。

###フロー編集
こんなフローを書きました。（[Discover](https://enebular.com/discover/flow/37de6dc2-4d48-49b3-b686-5cede1ec9e00)よりインポート可能です。）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266424/696552d4-64e3-69a5-a10b-d19c10ef4897.png)

###デプロイ
debugノードで値が出ているか確認します。
リモートモードでsaveしたらラズパイにデプロイされています。

##クラウド上のデータを確認
firebaseまでデータが来ているかfirebaseの画面で確認しましょう。

##データを表示する
###データソースの設定
enebularの可視化ツールinfomotionでfirebase上のデータを表示するためには、データソースを登録しましょう。

###infomotionを使ってみる
温度と湿度の時系列データが期待した通り、表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266424/d91eba7e-bf80-4b00-cd39-caaeed2e6304.png)

#まとめ
c3.js使うと、d3で一から作らなくて便利そうです。
いろんなサンプルがあるので、もっといいグラフを簡単に実現できないか調べたいと思います。

https://c3js.org/examples.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/266424/e34744b3-a228-cc80-c8f9-1b45329330c0.png)
Loggingについて


初めまして。
えーじです。
今までプログラムを学んで終わりだったので、今後はメモ兼解説？としてQiitaを書いていこうと思います。

私は今までエラーがあるかないかを"print"で確認していましたが、loggingの方が綺麗にかけそうだったので勉強してみました。
初めてQiitaを書くので、間違いや書き方があればご指摘お願い致します。
[Logging HOWTO](https://docs.python.org/ja/3/howto/logging.html#logging-basic-tutorial)を参考に書いています。

##Loggingとは？
>logging は、あるソフトウェアが実行されているときに起こったイベントを追跡するための手段です。ソフトウェアの開発者は、特定のイベントが発生したことを示す logging の呼び出しをコードに加えます。イベントは、メッセージで記述され、これに変数データ (すなわち、イベントが起こる度に異なるかもしれないデータ) を加えることもできます。イベントには、開発者がそのイベントに定めた重要性も含まれます。重要性は、レベル (level) や 重大度 (severity) とも呼ばれます。
Markdown: [Logging HOWTO](https://docs.python.org/ja/3/howto/logging.html#logging-basic-tutorial)

イメージとしてはprintよりもログを取ることに特化したもののようですね。
levelやseverityを使いこなせれば、便利そうですね。

#サンプルコード
``` python:practice_logging.py

import logging

# 1. logger を作成
logger = logging.getLogger(__name__)

# 2. handlersを設定
std_handler = logging.StreamHandler()
file_handler = logging.FileHandler('practice_debug.log')

# 3. levelの設定
std_handler.setLevel(logging.WARNING)
file_handler.setLevel(logging.ERROR)

# 4. formatters の設定
std_format = logging.Formatter("%(name)s - %(levelname)s - %(message)s")
file_format = logging.Formatter("%(asctime)s\t%(levelname)s -- %(processName)s -- %(filename)s:%(lineno)s -- %(message)s")

# 5. Formatterをそれぞれに接続
std_handler.setFormatter(std_format)
file_handler.setFormatter(file_format)

# 6. logger に handler を追加
logger.addHandler(std_handler)
logger.addHandler(file_handler)

# 7. loggerの発生
logger.warning('This is a warning')
logger.error('This is an error')
```

#Loggingの使う手順(上のコードを一つずつ読む。)
1. loggerという名のLoggingのインスタンスを作成
2. ハンドラーを準備
    1. StreamHandler() -> **コンソール**にログを表示
    2. FileHandler(fileName) -> **'fileName'**の中にログを表示
    3. etc ...

3. レベルの設定
    1. **DEBUG** (おもに問題を診断するときにのみ関心があるような、詳細な情報。)
    2. **INFO** (想定された通りのことが起こったことの確認。)
    3. **WARNING** (想定外のことが起こった、または問題が近く起こりそうである)
    4. **ERROR** (より重大な問題により、ソフトウェアがある機能を実行できないこと。)
    5. **CRITICAL** (プログラム自体が実行を続けられないことを表す、重大なエラー。)
    
    もしDEBUGを選ぶとそれより上のレベルは全て表示される。（**defaultはWARNING**)

4. 表示の仕方を設定する（Formatter)
    1. %(name)s : ロギングに使われたロガーの名前
    2. %(levelname)s : DEBUG, INFO, WARNING, ERROR, CRITICAL
    3. %(message)s : パラメータからのメッセージ
    4. %(asctime)s : LogRecord が生成された時刻を人間が読める書式で表したもの。

5. それぞれのハンドラーに**Formatterをセット**
6. 最初のインスタンス（logger)にaddする。
7. テストとしてログを発生。


初めてのQiitaでした。
あまり綺麗にまとめられませんでした:frowning2:
他の人の記事を見ながらもっと勉強しようと思います！
そしてLoggingをもっと使いこなして、開発者として一歩近付きたいですね:relaxed:
サイバーボランティアの重要性

#サイバーボランティアアドベントカレンダー14日目です。
##サイバーボランティアの重要性について書いていきます。
最近サイバーボランティアと名乗りながら行動規範などを読んでいない人なども見えるようです。
行動規範とは自分が重要と思ったことを書けばいいということではないです。
これをまとめるべき人もいるわけでありマッピング化する人もいるわけです。
その人達のことを考えて行動することが行動規範です。
##悲しいことですが行動規範を守らない人多いです。
正直言って言えることは<strong>政治家の皆さんはっきり言って行動規範に反して自分たちの行動を棚に上げる真似やめてくださいませんか。</strong>
自分たちは被災地の人たちの命を守るための行動をしているわけであなた達の行動を見ると腹が立ちます。
あと言えることですが<strong>個人の行動記録記としてFacebook災害支援グループを使うことはおやめください。</strong>
私どもは被災地のいち早い復旧図るお手伝いと防災支援をもっとうに動いています。
正直妨害行為に近い状態になっています。
<strong>行動記としてお使いになるのならご自分でFacebookページを立ち上げてやってください。
はっきり言って活動の邪魔です。</strong>
それだけミッションクリティカルで被災地に対する支援活動をしています。
あと言えることはネット上の情報は<strong>確証を得てから情報発信してください。
毎回情報確証を得るための情報の洗い出しをしなければなりません。</strong>
ちゃんとした情報を流してください。
<strong>確か名前は思い出せませんが自分のいる団体の宣伝をされている方が見えました。これは非常に困ります。宣伝サイトではありません。災害支援のためのグループです。</strong>
このことを守れない人はこれからは立ち上げメンバーの権限で排除していただいて構いません。
自分も今後は警告し排除するつもりです。
円滑にすすめるためにはこれが一番重要です。
あと言えることはできればすぐにでもいる情報は避難所・給水所・充電施設などの住所場所電話番号の情報をまとめたcsv情報を集めてくれる人がほしいです。
それによってクライシスマネジメントやマッピングのスピードが上がります。
<strong>あとクライシスマッピング活動を開始するときとには終了するときには必ず通知してください。</strong>
これは参加していただいている人に対しての礼儀です。
必ず行いましょう。

##Facebook災害支援グループの存在意味
これを書こうと思ったのはCode For Japan立ち上げて間もないときに伊豆大島の台風災害が起きました。
このときに動いたメンバーは私も存在していましたが必死になって活動しておりました。
そのときに行ったのが今起きている状況をクライシスマッピングをしていました。
本格的に参加した平成24年大雪のときでもみんな必死になって情報をレポーターとしてクライシスマッピングしていました。
それだけクライシスマッピングの情報が重要なのです。
それをマネージメントするために存在するのがFacebook災害支援グループだと自分は思っています。
正直立ち上げメンバーに言いたいことは即座にクライシスマネージメントをするためのマップサイトをすぐ準備してください。
それができなければ私みたいなITエンジニアに連絡いただければ仕事途中にでも準備ができるように上司に話をつけ行動します。
災害の被害や減災をするためのグループであることを忘れずに行動を取ることが必要です。
上から目線なように見えますが実は8年前から携わっていますのでご了承ください。
8年前はそれだけ迅速だったということになります。
あと言えることはまとめるためのスプレットシートを準備してください。
それでCSVを履くことができ次の行動に移ることができます。
やることがいっぱいということもあるとは思いますが今は災害支援グループ立ち上げてからあとの対応がほぼ放置状態です。
立ち上げてからの作業の迅速さが一番重要です。
今の状況を8年前に活躍したメンバーが見たら<strong>この行動の遅さは何なんだ。とっとと行動しやがれ。クライシスマネージメントにいるものをとっとと作れ。</strong>とどやされますよ。
私は引かれるのが怖いので言わなかっただけです。
時間がなければ助けをメッセンジャーで投げてください。
人に助けを求めることは恥ではないです。
運営がわからなければ私達code for japanや古橋くんや後藤先生・自分がいるので聞いてください。
<strong>支援がいるのであれば私達code for japan並びにcode for ブリゲード組織・civictech japanにご連絡いただいて構いません。
CivicハッカーはIT-DARTを支援するためにいるんです。</strong>
忘れないでください。
Code for Japan関代表（@hal_sk）が書いたCode for ブリゲード組織の資料があるのでを合わせて載せておきます。
[各地の Code for コミュニティ](https://medium.com/code-for-japan/cfx-is-not-cfj-subgroup-d6901407f25e)

今後は言うだけではなく裏方としても動ける人間が必要だと思います。
裏方にいる人が優秀であれば救われると思います。
自分もなるだけ協力できるように会社や職場にも協力してもらえるようにお願いしてみるつもりです。

<strong>仕事ができてこそボランティアということもありますが。ミッションクリティカルな状態であれば会社に協力を依頼してください。</strong>

今日も長々と書いてしまいすいません。
AI Quest（2019年度）前半戦で得たもの


## 追記

[前半前どころか全部終えて恨みつらみを残していたり](https://blog.miyawa-tarou.com/?p=482)はしますが、
今年も行われるというのもあってか、ストックとかの通知も来るので一応追記。

これは第1回目（2019年度）の話なので、さすがに色々改善されているとは思います。
また良いチームに恵まれ、うまく成長された方もいると思います。
その上で第1回で自分が思ったことは

- 「AI」実装ってなんぞや感あるけど、うちのチームは機械学習の回帰と分類のことだけやったよ
- ディープラーニングのことは何もやってないよ
- 初期レベルで参加するものが違ったみたいだから、高レベルの人たちのことは知らないよ
- チームビルドから各チーム任せなこともあってチームごとにモチベーションが違って、離脱者が全体的に見られたよ
- というか顔合わせの前にチームが決められて課題を課されて、発表時に初めて会ったよ
- ビジネス課題と実装課題は微妙につながってるけど、バラバラの課題って感じで実装課題はただのSIGNATEのコンペだよ
- ビジネス課題も中途半端なロジカル・コミュニケーションと中途半端なプレゼン研修だよ
- BCGの人は大したフィードバックをくれないけど、参加者同士のフィードバックも弱いよ

特に最後のフィードバックの形なんかは改善されているとは思っています。
ただ紹介ページなどは「きれいな部分」だけを見せるので、参加する方々には「終わってみて糞だった」と書くのではなく、やりながら改善を促していける気持ちも持って望んでほしいと思います（その結果そんなの不要であったらそれは良い）。
改善する気はあっても、参加企業（主催側）の多くは他の仕事の片手間にやっていて、全力で意見を集めて改善していくみたいなことはしないけど、さすがに参加者が動けばなにかしてくれるはずです。

## 以下は以前の

[個人ブログ](https://blog.miyawa-tarou.com/?p=440)ではひたすら文句を書き連ねたが、得たものはあるので色々整理したいと思う
いや思ったのだが特に学んだことが薄くてQiitaに書くのも申し訳ない感じに整理できなかった

## まとめ
前半を終えて3ヶ月程度（残り2ヶ月程度）

・初期状態
なんとなくは機械学習（scikit-learn：分類・回帰）を実行できる
　↓
・今の状態
データを可視化し、傾向を探り、前処理・特徴量をあれこれするのが多少できる
機械学習のツールをツールとして、一部の手法を深く理解していないが扱えるレベル

期待していたビジネスで機械学習をどう活かすかということ：正直学びがなかった
ここががっかり感を作っていると思います。

## 振り返り

### 研修のゴール
これは集め方がペライチのポスターのみだった時点であまり定かではなかった
何をやるかもわからなかったので、自分でも定められなった

### 開始前の自分の実力

2年前にPythonではじめる機械学習（オライリー）を2章までやってscikit-learnの動かし方がわかっている程度
（あと業務中にお遊びでちょっとだけ触った）

応募資格は下記2つの要件を満たす方
・Pythonを使ったコーディング経験のある方
・AI、データ処理（Data Handling, Data Science）についてサンプルコードを書いた程度の経験がある方
とのことなので問題ないはず

### 統計学について

平均・中央値・四分位数とかだった気がする
これ↓のStep0のほうが詳しい
https://bellcurve.jp/statistics/course/

ちゃんと統計学も勉強しよ！ってなったことが一番の収穫です

### 機械学習のついて
#### 分類

- ハイパーパラメータ探索
- データを可視化して傾向を見る（matplotlib）

ハイパーパラメータ探索も知らない人でした。基礎オブ基礎って感じ

#### 回帰

- One-Hot Encoding
- いろいろなモデルの作成（RandomForestRegression、XGBoost、LightGBMなど）
- 色々特徴量を作ってみる
- 正規分布に近づけるために目的変数を対数変換

### ビジネス面について

学んだ気がしない

### その他

- pandasの扱い方

## PBLについて

今回推しているPBL＝[問題解決学習](https://ja.wikipedia.org/wiki/%E5%95%8F%E9%A1%8C%E8%A7%A3%E6%B1%BA%E5%AD%A6%E7%BF%92)
これで得たものがあったか
PBLというけど単に1週間で解ける課題を与えられただけだった気がするのだが気のせいか…？
私の知ってるアクティブラーニングと違う。

集合研修やチームで質問し合うという部分だけ切り取ると、

- 機械学習雑魚としては、対数変換するんですよってところに気づけた
  - 何故するのかはネットで調べた
- どうしてこのモデルを選ぶのか：決定木なのかなのか線形回帰なのか別のものなのか
    - ブラックボックス的なのか、解釈・説明しやすいのか、速度面
- チームメンバーがやっている手法
    - K-Means法でのクラスタ分類、主成分分析
    - 主成分分析は似たようなKaggleのコンペの説明にあったからやったみたいですけど

あたりは得たものでしょうか

今日別のチームの人と話したのは「精度上げるのに行き詰まったときどうすればいいんでしょうね？」ということ
こういうのは話題に出つつ解決できるわけではなかった。

## 内容の網羅性

チーム課題は最大2個しか課題がないので、網羅性はないです。
うちのチーム回帰しかないじゃん…
画像認識をやるところもあります
自然言語処理とかはなさそう

会社からデータを貰っているという理由で、他チームにURLは教えないでください、とのこと
だからやっている課題以外からは学びは得られない
これは相当もったいないと思いました

## いまのままのを他の人にオススメするか

Kaggleのコンペやれ

## 後半に向けて

ゴールは定められない。
学ぶモチベーションとしての研修くらいの気持ちで取り組む