OmniAICreator/Qiita-1.07M huggingface dataset:
【3分で出来る】ngrokでデプロイをしてみよう！

さくっと今作っているWebシステムを他の人に使用感ごと共有できるツール？サービスでngrokというのがあるらしい…
他にも使い方として外部サーバとして立ててWebhookなどのテストに使える。

### ざっくり概要
簡単にローカルで作ったWebシステムを公開できるよ！
つまり、http://loalhost にhttp://{hogehoge}.ngrok.com などで外部からアクセスできちまう…

## ngrokとは…？
簡単に言うとlocalhostで動いているサーバーを、外部のLANからアクセス出来るようにするツール

## とりあえず３分クッキング（ハンズオン）してみよう
セットアップとインストールは[get-started](https://dashboard.ngrok.com/get-started)でログインした際に表示されるけど一応手順を書くよ。


### [1/7] 以下よりアカウント作成

https://ngrok.com/
### [2/7] アカウント作成後、それぞれのOSに対応したngrokをダウンロード（私はMac）

```shell
cd Downloads/
unzip ngrok-stable-darwin-amd64.zip
```
### [3/7] 適当なところに解凍後の実行ファイルをコピー
（私はパスの通っているディレクトリに配置した）

```shell1
cp ngrok /usr/local/bin/
```
### [4/7]  アカウントを接続
（トンネル認証トークンはhttps://dashboard.ngrok.com/auth から）

```shell
ngrok authtoken {トンネル認証トークン}
```
### [5/7]  適当なローカルサーバーを建てる
（Dockerない場合はこれとかで建てる→「[お手軽なWebサーバーの立て方](https://qiita.com/massie_g/items/2913066e596dae197539)」）

```shell
docker run -d -p 8080:80 --name test nginx
```
### [6/7] ローカルサーバの動作確認
以下のURLにつないで「Welcome to nginx!」が出ればローカルサーバはOK
http://localhost:8080/

### [7/7] 次にngrokでそれを公開！
8080は公開したいポートを設定したらOK

```shell
ngrok http 8080
```

以下のURLにアクセスしたら管理画面っぽいのが表示されて、公開アドレスが表示されてる。適当にクリックして公開されていることを確認。
http://127.0.0.1:4040


## 停止方法
control + Cで止めれる。
Dockerの方はdocker ps , docker stop {docker id}とかで


サブドメインは以下のようにしたら指定できるっぽい

```shell
ngrok http -subdomain=hogehoge 8006
```
BASIC認証は以下

```shell
ngrok http -auth='user:password' 8006
```


以上、そんな感じ




## 参考リンク
* https://dashboard.ngrok.com/get-started
* https://qiita.com/mininobu/items/b45dbc70faedf30f484e
Java Servlet

#はじめに
JavaServletについて自分用のメモ


#JavaServletとは
動的なwebページの処理を行うための仕様。言語はJava

webページには動的と静的なwebページがある。

- 静的なwebページ
 - いつ閲覧しても表示される内容が変わらない
- 動的なwebページ
 - 表示した時間帯などによって表示内容が変わる

Servlet自体はWebブラウザからの要求に応えたり、送られてきたデータを処理したりするためのもので、単体ではWebアプリを作るための機能が少ない。
なので、tomcatやJSPと連携をしてアプリを作成することが多い。

javaで書かれているのでプラットフォームに依存しないのが特徴。

#tomcatやJSPとはなにか
では、Servletと連携するtomcatやJSPは一体何者だ・・・。

#####tomcatとは

Servletや後述するJSPの実行環境となるソフトウェア。サーブレットコンテナとも言われる。

個人的にこのサイトの説明が参考になった。
[Apacheとtomcat](https://teratail.com/questions/185273)

#####JSP(JavaServerpage)とは
基本はHTMLで動的な処理を書く場合にJava処理を記述できるファイル
拡張子(.jsp)
Javaで処理を書く場合は<% %>で処理を囲む。

```jsp:qiita.jsp
<%-- コメント --%>
<%@ page contentType="text/html;charset=Shift_JIS" %>
<html>
<head>
 <meta charset="UTF-8">
 <title>sampleJSP</title>
</head>
<body>
 <%
  String str = "Hello World";
  System.out.println(str);
 %>
</body>

```

＊)この場合コンソールに処理結果がでます。記述の参考までに。


#参考文献
[技術評論社](https://gihyo.jp/book/pickup/2018/0030)
[teratail](https://teratail.com/questions/185273)
Confluenceプラグイン作り入門（1）-空っぽプラグイン編

#はじめに
先日NRI asleadチームの有志メンバーにてConfluence勉強会を開催し、プラグインを作ってみました。その内容を2回に分けて共有します。
一回目：空っぽプラグイン編
二回目：ビジネスロジック入りプラグイン編

#Confluenceとは
Confluence（コンフルエンス）はJavaで作成され、主にビジネスで使用されるWebベース企業向けウィキです。Atlassianが開発・販売を行っています。
[Confluence公式サイト](https://www.atlassian.com/ja/software/confluence)

#作業前提
1.Confluenceがインストールされていること（※今回はwindowsの評価版を使用）
ダウンロードは[こちら](https://www.atlassian.com/software/confluence/download?_ga=2.34251241.990784763.1572409950-131669489.1541556169)からどうぞ。
2．インターネットに接続できる環境で作業すること


#空っぽのプラグインから作ってみます

1.オフィシャルサイドからAtlassian Plugin SDKをダウンロードし、インストールします。 
https://marketplace.atlassian.com/download/apps/1210950/version/42490

2.SDKの**bin**フォルダに移動し、batファイルがずらりと並んでいます。今回使うのは
atlas-create-confluence-plugin.batになります。
<img width=70%  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522191/a48da71c-d538-d12a-eea9-23fc4cc8441f.jpeg">

3.コマンドラインで**atlas-create-confluence-plugin.bat**を実行します（※雛形プロジェクトをダウンロードするので、インターネットに接続できる環境が必要）
<img width=70%  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522191/78b43435-e93a-1df1-77df-a34bc5e31d1a.jpeg">

4.groupIdとartifactIdなどの情報が質問されるので、答えていきます。回答内容はプロジェクト直下の**pom.xml**ファイルに反映されるので、後で変更したい場合はpom.xmlファイルを直接編集すればよいです。
※groupIdなどの意味は下記をご参照ください。
https://developer.atlassian.com/server/framework/atlassian-sdk/atlas-create-confluence-plugin/
<img width=50%  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522191/798609d3-f66c-be48-2670-ae1f920d2b99.png">

5.binフォルダの下に雛形プロジェクトが作成されます。ビジネスロジックの実装は主に
**\src\main\java\nritest\impl**の下に行いますが、詳しい内容はビジネスロジック入りプラグイン編でご紹介します。
<img width=70%  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522191/36d1b7bb-c384-da0a-a2e1-2639803db399.png">

6.プラグインプロジェクトのフォルダの直下に移動し、**「atlas-package」**コマンドでjarファイルを作成します。（※ここもインターネット接続が必要、初回の場合はダウンロードするのに時間が掛かります）
<img width=70%  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522191/ce5c2f0e-0cc5-b2a5-6bd2-848a9b94240e.png">
<img width=70%  src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549759/754cffbb-b844-4c29-b260-4bfbdc40aadb.png">



7.プロジェクトフォルダに**target**フォルダが生成され、プラグインのjarファイルが保存
されています。
<img width=70% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522191/af5c8429-b903-6db6-4859-3a1d1e0f84ff.png">

8.プラグインのjarファイルをconfluenceのアプリ管理画面からアップロードすれば
インストール完了です！
<img width=80% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522191/37a71302-6e31-f829-2734-bb460c719b35.png">
<img width=80% src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/522191/1945489d-6456-a93f-f956-311291f75eb5.png">


#まとめ
今回はConfluenceプラグイン作成の流れを把握するため、空っぽのプラグインを作成しました。
次回の入門（2）は簡単なビジネスロジックをいれたプラグインの作成の仕方を紹介します。
ヌルいヌルい男がWindows Terminalを初めて使う

Windows 10でWindows Terminal（プレビュー版）というのが使えて評判がいいらしいので使ってみた。
ストアから無償でダウンロード、インストールできる。

最初、ぼくが一生使い方が覚えられないWPSの例の抜けるような青空のように青い画面が出て来てウゲゲと思ったが、タイトルバーのｖというのを押してメニューを展開するとシェルが選べるようになっている。現状では

- WPS
- cmd
- Ubuntu (WSL。ぼくの場合デフォルトシェルのbash)
- Azureなんとか
 
というのがこの順に使える。

Setupという項目もあるのでこれでいじれるかと思って起動したら、なんかVSCodeが起動した。
そういやなんかの仕事で入れたのだがもう有効期限が切れている。
閉じるしかできないので一旦閉じる。
単なるJSONらしいので秀丸でいじりたい。

そこでまず拡張子.jsonを秀丸に関連付ける。

まず、デスクトップにfoo.jsonというテキストファイルを作る。
これは空っぽでかまわない。

これを右クリックし「プログラムから開く」をクリックするとVSCodeと並んで秀丸が出てくるのでクリックしそうになるが、ここはグッと我慢して「他のプログラムから起動する」を開く。
プログラムの一覧があるので、ここでやっと秀丸を選択し、「いつもこのプログラムを使う」をチェックして開く。
中身は空っぽなので閉じる。
秀丸は「このファイル空っぽですが消しますか」と聞いてくるので「はい」と言う。

再びWindows Terminalに戻ってSetupを起動すると偉いもので秀丸が開いた。

![SnapCrab_NoName_2019-12-12_8-33-30_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107571/ff85b691-9292-6414-7edb-dff2cd721d81.png)

`C:\Users\ユーザー名\AppData\Local\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\profiles.json`というファイルを直接編集してもいいようだ。

`"profiles:"`という要素の中に4つのプロファイルが入っているので好みの順序にする。
[JSONはケツカンマを許さない](http://dqn.sakusakutto.jp/2012/05/javascript-last-comma-matome.html)ので注意。

あと、`"defaultProfile"`という要素にオブジェクトIDが指定されてるけど、これは下のエディタのプロファイルのguidで、初期値はWPSになっている。これを好みのにすれば最初に出てくるシェルが選べる。
ぼくはcmdにした。

ここでようやく検索すると[ほかにも色々設定できる](https://e8l.hatenablog.com/entry/2019/06/28/010454)ようだがそこはおいおい。

Windows Terminalはタブになっているのでぼくの場合cmdとUbuntuにする。
タスクバーにcmdとUbuntuを並べていたが、両方削除してWindowsTerminalに統一した。
いまのところうれしいのはそれだけだが、それだけでもうれしい。

（この項おわり）
bitsadmin～Windowsのコマンドラインで、HTTPを使ってファイルをダウンロードする方法 

bitsadminの使い方がちょっと厄介。
まず「ダウンロードジョブ」と呼ぶものを作り（/create）、
そこにダウンロードファイルと保存先を指定するコマンドを登録し、
そのジョブを実行することで初めてHTTPでのファイルダウンロードを始める。
そして、最後にはそのジョブを後片付け（削除）する必要がある（/complete）。
あと、コマンド実行中の状況（ダウンロード中なのか、接続に失敗したのか、完了したのか）が分からないが、
別のコマンドプロンプトで
`bitsadmin /rawreturn /info {ジョブ名}`
コマンドを実行することでリアルタイムに確認できる。
※大抵の失敗は
「TRANSIENT_ERROR - 回復可能なエラーが発生しました。 最小再試行遅延が切れると転送が再試行されます。」
だけど、たいていはもう一回resumeすればいい模様。

わたしはこんな感じでバッチを作りました。



```ruby:httpDownloader.bat
@echo off
@echo,
@echo ### ダウンロードジョブにダウンロード対象ファイルを指定します。
bitsadmin /rawreturn /create /Download myDLjob
bitsadmin /rawreturn /addfile myDLjob http://?????????????? {ダウンロード先フルパス}
：＜ダウンロードしたいファイル分addfile＞


@echo,
@echo    ### ファイルをダウンロードします。
call :bitsadminDL自動判定 myDLjob

@if errorlevel 1 (
    @REM 戻り値1以上は失敗。
    bitsadmin /rawreturn /reset
) else (
    bitsadmin /rawreturn /complete myDLjob
)

@echo    ※「Job completed」が出ていれば、全ファイルのDLが完了しています。
@echo,
@echo    ### ダウンロードジョブ状態確認
bitsadmin /rawreturn /list
@echo    ※「bitsadmin /rawreturn /list」実行で何か残っていれば、DLに失敗しています。
@echo      なお、「bitsadmin /cancel myDLjob」でジョブをクリアできます。

exit /b 0


@REM ---------------------------------------------------------------------------
:addfiles
bitsadmin /rawreturn /addfile myDLjob http://172.24.170.133:7350/%1/%2 %WORKDIR%\%1\%2

exit /b 0

@REM ---------------------------------------------------------------------------
@REM ### 呼び元でジョブをcreateし、completeしてください。
:bitsadminDL自動判定

@setlocal

@if [%1] == [] (
    @echo   [X] arg1:ジョブ名を指定してください。
    exit /b 1
)

@set myDLjob=%1
@set RESULT=


:LOOP
echo %RESULT% | find "TRANSFERRED" > nul
@if not errorlevel 1 (
    @echo,
    @echo    ### 転送完了
    exit /b 0
)

echo %RESULT% | find "CONNECTING" > nul
@if errorlevel 1 (
    @REM ### それ以外の場合は転送ジョブを再開する。
    bitsadmin /rawreturn /resume %myDLjob%
) else (
    @REM ### 転送中の場合はちょっと待つ
)

choice /C YN /T 2 /D N /M "やめる？[Y]/other"
@if errorlevel 2 (
    @REM ### "N"の場合2 ※入力タイムアウト（2秒）でも"N"
    for /f "usebackq delims=" %%a in (`bitsadmin /rawreturn /info %myDLjob%`) do set RESULT=%%a
    goto :LOOP
) else (
    @REM ### "Y"の場合1（2未満なのでこちらの分岐）
    @REM ### 続けないなら、ジョブをresetして終了。
    bitsadmin /rawreturn /reset
)


@endlocal
exit /b 9999
```
例外切り替えメソッド

##ものによって例外を切り替えたい共通処理

なんかAPIとかの戻り値が不正の場合、APIによって違う例外を使いたいけど

だいたいの処理は似ているみたいな状況でこんなの使えそうだなっていう備忘録

```ThrowExceptionTest.java
package reflection;

public class ThrowExceptionTest {
	
	public static void main(String[] args) {
		try {
			throwException("w");
		} catch (WwwwException e) {
			System.out.println(e.getMessage());
		} catch (ZzzzException e) {
			System.out.println(e.getMessage());
		}
	}
	
	/**
	 * フラグによって投げる例外を切り替える.
	 * 
	 * @param flg
	 * @throws WwwwException
	 * @throws ZzzzException
	 */
	private static void throwException(String flg) throws WwwwException, ZzzzException {
		WwwwException w = new WwwwException("wでだめ");
		ZzzzException z = new ZzzzException("zでだめ");
		if (ApiName.W.getText().equals(flg)) {
			throw w;
		}
		if (ApiName.Z.getText().equals(flg)) {
			throw z;
		}
	}
}
class WwwwException extends Exception {
	private static final long serialVersionUID = 1L;
	WwwwException(String msg) {
		super(msg);
	}
}
class ZzzzException extends Exception {
	private static final long serialVersionUID = 1L;
	ZzzzException(String msg) {
		super(msg);
	}
}
enum ApiName {
	W("w"),
	Z("z");
	private String text;
	private ApiName(final String text) {
		this.text = text;
	}
	public String getText() {
		return text;
	}
}
```
だめな点 : キーとなるEnum持つのめんどくね

本当はExceptionクラスを引数としてうまいことする処理にしたかったんですけど
引数 : `Class<? extends Throwable>`
処理 : `throw 引数.newInstance()`
みたいなね

けどこれリフレクションを使うはめになるので
<ul>
<li>いろいろほかの例外処理が必要
<li>Exceptionクラスがものによってできない
</ul>
とかまぁいろんな理由でだめでした
ちなみに`NumberFormatException`ならできました
だめだって分かったのでどんなものならできるのかとか調べるのもやめました
たぶん`IllegalArgumentException`とかその他の例外に引っかかっちゃう系がダメです
とにかくだめです
<br>
まぁ投げる例外だけ違う、似てるメソッドをいっぱい作るのもそれはそれで悪くなさそうですけど
やっぱ似てるならまとめたいですよねぇ
WP-CLI を使って絵文字が文字化けしないようにデータをエクスポートする

毎回忘れて怒られるので覚書に。

WP-CLI では、以下のコマンドを実行することでデータベースのデータのエクスポートを行うことができます。

```
wp db export
```

しかし、これだと絵文字が消えちゃいます。

この場合、とてもややっこしいのが、絵文字以外は大丈夫なので不具合にとても気づきにくいことなんですよね。。。

というわけで、以下のように `utf8mb4` を指定すると大丈夫です。

```
wp db export --default-character-set=utf8mb4
```

WP-CLI の次のバージョンでは、このように指定しなくても `utf8mb4` がデフォルトになると思います。
もういくつ払うと完済できる？Rubyでローンの計算をしてみよう！

この記事は、[株式会社エイチームフィナジー](https://finergy.a-tm.co.jp/) の [Advent Calendar 2019 15日目](https://qiita.com/advent-calendar/2019/ateam-finergy)です。

## はじめに

皆さまクリスマスシーズンいかがお過ごしですか？:christmas_tree: :santa: :christmas_tree:
[株式会社エイチームフィナジー](https://finergy.a-tm.co.jp/) の [Advent Calendar 2019 15日目](https://qiita.com/advent-calendar/2019/ateam-finergy) は、 @kazenomachi が担当します。

[株式会社エイチームフィナジー](https://finergy.a-tm.co.jp/)では、「世の中からお金の不安を解消し、より人生が豊かになる社会を実現する」ことをミッションに、金融領域を中心とした様々なサービスを運営しています。

今回は、[ナビナビ住宅ローン](https://navinavi-mortgage.com/)の開発に携わっているWebエンジニア（住宅ローンアドバイザー:house:）の私が、Rubyでローンの計算をするライブラリをご紹介します。
※本稿の内容は、弊社で運営しているサービスの内容とは関係ありません。

## 使用するライブラリ

今回は、[exonio](https://github.com/noverde/exonio)というgemを使用してみます。
とてもシンプルに財務関数を扱えるgemです。

## インストール

```
$ gem install exonio
```

## 様々なローンの計算をしてみよう

### 支払い回数を算出する

年利15%のローン商品で25万円を借り入れ、毎月1万円を支払っている場合、総支払い回数は`NPER`関数を使って以下のように算出できます。

```ruby
# 月利(年利15%)
# 月単位の支払いなので、月利で計算します。
interest_rate = (15.0 / 100) / 12
# 毎月の支払額 
amount_of_payment = -10_000
# 借入金額
borrowing_amount = 250_000

Exonio.nper(interest_rate, amount_of_payment, borrowing_amount)
# => 30.16243479462554
```

30回払い、2年半…長い道のりです:santa:

### 借入金額から、毎月の支払額を算出する

年利15%のローン商品で100万円を借り入れ、5年で返済する場合、毎月の支払額は`PMT`関数を使って以下のように算出できます。

```ruby
# 月利(年利15%)
# 月単位の支払いなので、月利で計算します。
interest_rate = (15.0 / 100) / 12
# 支払い回数(5年)
number_of_payments = 5 * 12
# 借入金額
borrowing_amount = 1_000_000

Exonio.pmt(interest_rate, number_of_payments, borrowing_amount)
# => -23789.930086358785
```

年利15%なので、利息も高いですね…:santa:

### ローンの利率を算出する

100万円を借り入れ、毎月2万円を5年間払い続ける場合の利率を`RATE`関数を使って算出します。

```ruby
# 支払い回数
number_of_payments = 5 * 12
# 毎月の支払額
amount_of_payment = -20_000
# 借入金額
borrowing_amount = 1_000_000

# 月利
monthly_rate = Exonio.rate(number_of_payments, amount_of_payment, borrowing_amount)

# 年利
monthly_rate * 100 * 12
# => 7.420095794554806
```

およそ7.42%の年利となりました :santa:

### 毎月の支払額から、借り入れ可能額を算出する

住宅ローンの借り入れ可能額を計算してみましょう。
年利1.5%の35年住宅ローンを毎月6万円支払う場合の借り入れ可能額は、`PV`関数を使って以下のように算出できます。

```ruby
# 月利(年利1.5%)
# 月単位の支払いなので、月利で計算します。
interest_rate = (1.5 / 100) / 12
# 支払い回数(35年)
number_of_payments = 35 * 12
# 毎月の支払額 
amount_of_payment = -60_000

Exonio.pv(interest_rate, number_of_payments, amount_of_payment)
# => 19596031.744103875
```

頭金やボーナス払い等を考慮しない場合、およそ1900万円の住宅を購入できる計算です。
煙突はつけられるかな…:santa::house:

## まとめ

財務関数はローン以外にも積立預金などの計算もできます。
[exonio](https://github.com/noverde/exonio)はシンプルなgemなので、ちょっとした計算をしたい時等にぜひ使ってみてください。
ご利用は計画的に…ふぉっふぉっふぉ…:santa:
Auth0のApplication Login URIはちゃんと設定しようという話

この記事を書いていたらAuth0のAdvent Calendarがあることに気づいたので、せっかくの機会と思い参加してみました。

# はじめに

Auth0を触るようになってから、WEBサイトやWEBサービスのログイン画面を見て
「あ、Auth0だ」と思うことがでてきました。
これ、Auth0に限らずIDaaSを使っている人あるあるネタらしいです。

そんな中、つい最近もAuth0が使われているWebサイトを見つけたんですが、ログイン画面でエラーが発生してしまいました。
エラーが発生した状況から推察するに、Auth0のApplication Login URIが設定されていなさそう…。

実はApplication Login URIを設定せずにAuth0を利用している人が他にも結構いるんでは？
という気がしてきたので、設定しないとどうなるかを紹介しようと思います。


**※この記事の内容は全部Auth0のドキュメントに書いてある内容なので本当はこっち見た方がいいです。**
[Tenant's and Application’s Default Login Route](https://auth0.com/docs/universal-login/default-login-url)

# Application Login URIとは？

Auth0のDashBoadから操作できるアプリケーション設定のひとつです。
DashBoadのApplications->登録済みの任意のアプリを選択->Settings の中にある
「Application Login URI」という項目がそれです。
![スクリーンショット 2019-12-10 19.06.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490013/425c28b6-45b7-71df-ea72-ab6a02dd2d54.png)


「Application Login URI」にはhttpsから始まるURIをひとつだけ設定することができます。
ここには、アプリケーションのログインの起点となるエンドポイントを設定します。
Auth0を利用しているWEBサイトのログインボタンのリンク先のURLのことだと思ってもらえれば大抵の場合OKだと思います。

ここに設定したURLがそのアプリケーションのデフォルトのログインパスになります。

# 設定しないとどうなる？

## Auth0のログイン画面に直接遷移するとエラーが表示される

Auth0のUniversal Login画面を利用している場合、WEBサイトからログイン処理を実行すると、いったんAuth0のログイン画面にリダイレクトされ、認証が完了すると元のWEBサイトに戻ってくるようなフローを描くかと思います。

このリダイレクト先のログイン画面をブックマークに登録し、その後ブックマークから直接ログイン画面にやってきてしまうとエラー画面が表示されてしまうことがあります。
![Web 1920 – 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490013/b63fb92a-34e9-7765-4a40-307300226eae.png)
Auth0を利用している人にはお馴染みのエラー画面。

### エラーになる理由

Auth0のログイン画面を開いてブラウザのアドレスバーを見ると、クエリパラメータとして`state`パラメータが存在していることがわかります。
`https://{ドメイン}/login?state=g6Fo2SBpYV9wQ1...`

![Web 1920 – 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490013/a5dbfd26-08da-8fe5-b622-b3116a2243e0.png)

Auth0のドキュメントによると、この`state`パラメータは一連の認証処理のトランザクションの状態を追跡するための値であり、Auth0内部のデータベースに保存されているとのことです。
また、このstateの値は認証処理が完了するか、一定時間経過後にAuth0内部のデータベースから削除されます。

こういった背景から、ブックマークから直接遷移するなどして、すでにAuth0内部データベースから削除されているstateを使ったログイン画面へのアクセスが発生した場合、Auth0は認証処理を継続することができなくなってしまいます。

このとき、「Application Login URI」を正しく設定しておくと、エラーとならずに設定したログインURLにリダイレクトされるので、改めて認証処理をスタートすることができるので、忘れずにちゃんと設定しましょう。

# Application Login URIを設定するその他のメリット

エラー回避以外にも、Application Login URIを設定するメリットがあります。
New Universal Login画面のほうを利用している場合限定ですが以下の2つのメリットがあります。
どちらもUXを高める良い機能なので、New Universal Login画面を利用している人は設定するべきだと思います。

## パスワードリセット再設定完了後の画面にログイン画面に戻るためのリンクが表示されるようになる

Auth0のログイン画面からパスワードリセットを行うと、登録してあるメールアドレスにパスワード変更画面へのリンクが記載されたメールが飛びます。
このリンク先でパスワードを変更した後に表示される完了画面にアプリに戻るためのリンクが表示されるようになります。
リンク先はApplication Login URIに設定したURLです。

![Web 1920 – 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490013/6920fbf2-f7f4-3069-a7e0-5482020191cb.png)


## メール確認完了後の画面にログイン画面に戻るためのリンクが表示されるようになる

「Force email verification」等のRulesを設定し、サインアップ時にメールアドレスの有効性確認のメールを送信している場合、メールに記載されているリンク先の画面にアプリに戻るためのリンクが表示されるようになります。
こちらも同様にリンク先はApplication Login URIに設定したURLになります。

![Web 1920 – 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490013/34ca353a-eab0-dccc-5ad4-1876a0077891.png)

# おわりに

チュートリアルとかだと飛ばされがちな設定なので、以外と設定を忘れている人がいるかもしれません。こういったところも忘れずに設定するようにしたいですね。
Azure IoTHub経由でRaspberry Piにメッセージを送信する。

今までRaspberry PiなどのディバイスからIoTHub経由でAzure上にメッセージを送信することは多々あったのですが、逆を試みたことはなく、今回Azure上にデプロイしたIoTHubから、Raspberry Piにメッセージを送信してみました。

準備したもの
・Raspberry Pi3 Model B
・AzureIoTHub(Freeプラン)

参考にしたMSのドキュメント
https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-python-python-c2d

●手順
とりあえずさらのラズパイでPythonを使えるように準備するまでの手順は省略

1.Raspberry Piに必要なパッケージをインストールする。
pip install azure-iothub-device-client
pip install azure-iothub-service-client

2.IoTHubをAzure上にデプロイする。

3.IoTHubにディバイスを登録し、接続文字列を生成しておく。

4.メッセージを受けるようのプログラムを用意
※CONNECTION_STRINGの中身は3.で生成した接続文字列に書き換える。

```python
import threading
import time
from azure.iot.device import IoTHubDeviceClient

RECEIVED_MESSAGES = 0
CONNECTION_STRING = "{CONNECTION_STRING}"

def message_listener(client):
    global RECEIVED_MESSAGES
    while True:
        message = client.receive_message()
        RECEIVED_MESSAGES += 1
        print("Message received")
        print( "    Data: <<{}>>".format(message.data) )
        print( "    Properties: {}".format(message.custom_properties))
        print( "    Total calls received: {}".format(RECEIVED_MESSAGES))
        
def iothub_client_sample_run():
    try:
        client = iothub_client_init()

        message_listener_thread = threading.Thread(target=message_listener, args=(client,))
        message_listener_thread.daemon = True
        message_listener_thread.start()

        while True:
            time.sleep(1000)

    except KeyboardInterrupt:
        print ( "IoTHubDeviceClient sample stopped" )
        
def iothub_client_init():
    # Create an IoT Hub client
    client = IoTHubDeviceClient.create_from_connection_string(CONNECTION_STRING)
    return client

if __name__ == '__main__':
    print ( "Starting the IoT Hub Python sample..." )
    print ( "IoTHubDeviceClient waiting for commands, press Ctrl-C to exit" )

    iothub_client_sample_run()
```

5.test.pyという名前でRaspberry Piの適当な場所に保存

6.Raspberry Piでtest.pyを実行
画像のような待ち受け状態になってればOK。
![2019-11-19-091907_1600x900_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529894/a0e71189-378d-64f5-028c-9bd8646450eb.png)

5.Azureポータル上で登録したディバイスへのメッセージを送信
今回はtest-messageと送っています。
![画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529894/50452f37-3c3e-3855-b1d0-8a4fec6bf9b6.png)

6.Raspberry Piで受け取れているかを確認
受け取れていれば画面のように受け取ったメッセージが表示される。
![2019-11-19-092126_1600x900_scrot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/529894/a0c90270-7564-08d1-3755-8a9a140a6a32.png)

上記のようにIoTHubからディバイスへのメッセージ送信を試してみることが出来ました。
特筆すべき点は試す費用が比較的安価なところ！(IoTHubはFreeプランでもディバイスへのメッセージ送信をサポートしています。)
今からIoTをやってみようという方も気軽に試せる感じとなっております。
re:Invent2019で個人的に面白かったセッション その②

これは[Media Doアドベントカレンダー](https://qiita.com/advent-calendar/2019/mediado)の記事です。

先日開催されたAWS re:Invent2019で個人的に面白かったセッションをまとめていきたいと思います。
動画や資料があるセッションについては、リンクもまとめていきます。(サムネをクリックするとYoutubeに飛びます)

前編の記事は[こちら](https://qiita.com/rsuet/items/316310d036b126722f96)

## Performing chaos engineering in a serverless world
[![Performing chaos engineering in a serverless world](http://img.youtube.com/vi/vbyjpMeYitA/0.jpg)](https://www.youtube.com/watch?v=vbyjpMeYitA)
https://www.youtube.com/watch?v=vbyjpMeYitA

## Improving resiliency with chaos engineering
[![Improving resiliency with chaos engineering](http://img.youtube.com/vi/ztiPjey2rfY/0.jpg)](https://www.youtube.com/watch?v=ztiPjey2rfY)
https://www.youtube.com/watch?v=ztiPjey2rfY

## Serverless architectural patterns and best practices
[![Serverless architectural patterns and best practices](http://img.youtube.com/vi/9IYpGTS7Jy0/0.jpg)](https://www.youtube.com/watch?v=9IYpGTS7Jy0)
https://www.youtube.com/watch?v=9IYpGTS7Jy0

## Develop serverless GraphQL architectures using AWS AppSync
[![Develop serverless GraphQL architectures using AWS AppSync](http://img.youtube.com/vi/XVU4pYeNfNo/0.jpg)](https://www.youtube.com/watch?v=XVU4pYeNfNo)
https://www.youtube.com/watch?v=XVU4pYeNfNo

## Building modern APIs with GraphQL
[![Building modern APIs with GraphQL](http://img.youtube.com/vi/7aJItKmoeWo/0.jpg)](https://www.youtube.com/watch?v=7aJItKmoeWo)
https://www.youtube.com/watch?v=7aJItKmoeWo

## Build data-driven mobile and web apps with AWS AppSync
[![Build data-driven mobile and web apps with AWS AppSync](http://img.youtube.com/vi/KcYl6_We0EU/0.jpg)](https://www.youtube.com/watch?v=KcYl6_We0EU)
https://www.youtube.com/watch?v=KcYl6_We0EU

## AWS SAM toolkit: Build, test & debug your serverless applications
[![AWS SAM toolkit: Build, test & debug your serverless applications](http://img.youtube.com/vi/3gCzGLdhQao/0.jpg)](https://www.youtube.com/watch?v=3gCzGLdhQao)
https://www.youtube.com/watch?v=3gCzGLdhQao

## Amazon DynamoDB deep dive: Advanced design patterns
[![Amazon DynamoDB deep dive: Advanced design patterns](http://img.youtube.com/vi/6yqfmXiZTlM/0.jpg)](https://www.youtube.com/watch?v=6yqfmXiZTlM)
https://www.youtube.com/watch?v=6yqfmXiZTlM

## Best practices for CI/CD using AWS Fargate and Amazon ECS
[![Best practices for CI/CD using AWS Fargate and Amazon ECS](http://img.youtube.com/vi/7FVK0i9edyg/0.jpg)](https://www.youtube.com/watch?v=7FVK0i9edyg)
https://www.youtube.com/watch?v=7FVK0i9edyg



## 最後に
Keynoteでは機械学習、量子コンピューティングとかが注目されていましたが、セッションを見てみるとカオスエンジニアリング、サーバーレス、GraphQLあたりのトピックも多かったように思います。

英語力が足りず聞き取れなかったところも多かったので、時間を見つけてもう一回聞き直そうと思います😅
DynamoDBを触ってみる#1

[いえらぶのAdventCalendar](https://qiita.com/advent-calendar/2019/ielove)の11日目です。

Dev開発合宿（いえらぶの開発合宿）で作ったチャットをもっとブラッシュアップすべく、チャット用のDBを構築中です。
たまには業務で使わないものも触ってみようと、AWSのDynamoDBを使っています。

# Amazon DynamoDBの特徴
 - 大規模サービスや急激な利用率向上するサービスに向いている。
 - Nosqlのデータベース(key-value型）
 - マネージド型
 - オートスケールが可能
 - サーバーレス

公式サイト曰く、
「1 日に 10 兆件以上のリクエストを処理することができ、毎秒 2,000 万件を超えるリクエストをサポート」

# 1. DynamoDB Localを使えるようにする
DynamoDBはAWSのサービスだから開発も本番でやるかなと思っていたら、
天下のAWS様はDynamoDBのローカル環境を用意してくれているので、さっそくインストール。
個人の開発環境はDockerなので、Docker Imageを使用しています。

##手順
#### 1. docker-compose.ymlで以下を記述

```docker-compose.yml
  dynamodb:
    image: amazon/dynamodb-local
    container_name: dynamodb
    volumes:
       - ./chat/db:/home/dynamodblocal/data
    ports:
      - 5984:5984
    command: "-jar DynamoDBLocal.jar -port 5984 -dbPath ./data -sharedDb"
```
※ portsのデフォルトは8000

#### 2. docker compose up

#### 3. DynamoDB JavaScript Shellを開く。
URL: http://localhost:5984/shell/
このShell上でテーブル作成ができます。MysqlでいうphpMyAdminみたいなものです。

![screencapture-localhost-5984-shell-2019-12-04-22_56_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157922/5cb1b641-ddc4-02a0-94d0-14615db4c994.png)


# 2.テーブルを作成する
ローカルの開発環境ができたので、次はchat用のテーブルを作ります。
今回は簡単なチャットを作りたいので、とりあえず以下ができるようにします。

```
## chatの仕様
* APIでチャットルームを呼び出せる。
* チャットルームに入ると、過去のやり取りを確認できる。
* メッセージを入力して「送信」を押すと、メッセージを送信することができる。
* メッセージが即時で相手方にも表示される。

## 保持したいデータ
* メッセージ内容　（string型、とりあえずテキストのみ）
* 送信者 (int型、idで管理する）
* 送信日時 (マイクロ秒まで取得)
```

DyanamoDB Localでは、テーブル作成の補助機能があるので、それを使うと早いです。
右上の</>のアイコンをクリック→CreateTableを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157922/03ed43c4-ec42-3dee-1001-71cb8af3f21c.png)

サンプルコードを以下のように修正して、クエリを流すとテーブルが出来上がります。

```
var params = {
    TableName: 'chat',
    KeySchema: [
        {
            AttributeName: 'room_id',
            KeyType: 'HASH',
        },
        {
            AttributeName: 'created', 
            KeyType: 'RANGE', 
        }
    ],
    AttributeDefinitions: [
        {
            AttributeName: 'room_id',
            AttributeType: 'N',
        },
        {
            AttributeName: 'created',
            AttributeType: 'N',
        },
    ],
    ProvisionedThroughput: {
        ReadCapacityUnits: 1, 
        WriteCapacityUnits: 1, 
    },
};
dynamodb.createTable(params, function(err, data) {
    if (err) ppJson(err); // an error occurred
    else ppJson(data); // successful response
});
```

* TableName: テーブル名
* KeySchema: 指定の仕方は、HashのみとHash＆Rengeの２種類ある。データ取得をする際に、今回は作成日時で絞りたいので、Hash＆Rengeタイプを使います。

# まとめ
NoSQL初めて触りましたが、RDBとは全然違うので仕組みの理解に時間がかかります。
チャットからの読み込み＆書き込みについてはまた後日。

# 参考
https://hack-le.com/dynamodb-query/
【Rails】デフォルト設定の日本語化方法簡単まとめ【備忘録】

#概要

Railsアプリで初期設定されている英語文章を日本語化する方法を簡単にまとめ。

公式リファレンス
https://railsguides.jp/i18n.html
RubyのI18nというRailsに同梱されているgemを利用して、英語設定をデフォルトで日本語にするよう変更する。
I18nは英語以外の別の１つの言語に翻訳する機能を持っている。

#環境

ruby '2.6.5'
rails '5.2.4'

#実装手順

`config/initializers/locale.rb`を作成し、
以下のコードを追加する。

```ruby:config/initializers/locale.rb
I18n.config.available_locales = :ja
I18n.default_locale = :ja
```

`config/locales/ja.yml`を作成。

上記ファイルにデフォルトのエラーメッセージや基本的なテーブルで使われるカラム名を元に英語から日本語を記載してくれてある以下URLの文をコピペするのが簡単。
https://github.com/svenfuchs/rails-i18n/blob/master/rails/locale/ja.yml



## 自分で設定したカラムの日本語化を行う
上記URLで記載してくれてある項目以外の単語は日本語化されないので、
他の単語・文言については自分で編集する必要がある。

`config/locales/model.ja.yml`を作成し、
`models`に自分が作成したモデル名を追加する。
`blog` `user`モデルを作成していた場合の例の書き方は以下。
`attributes`に自分が設定したカラム名を入れる。

**注意点１** ：インデントのスペースが一つずれただけでエラーになる上にエラーログが出てこない。
**注意点２** ：英語と日本語の間には:(シンボル)と空白１つを入れないとエラーになる。


【例】

```yml:config/locales/model.ja.yml
ja:
  activerecord:
    models:
      blog: ブログ
      user: ユーザー
    attributes:
      blog:
        title: タイトル
        content: 内容
      user:
        title: タイトル
        name: 名前
        email: メールアドレス
        current_password: 現在のパスワード
        password: パスワード
        password_confirmation: 確認用パスワード
        remember_me: ログインを記憶
```




### I18nで使えるメソッド

**translate（別名メソッドt）** ：# 訳文を参照する
**localize（別名メソッドl）** ：# DateオブジェクトやTimeオブジェクトを現地のフォーマットに変換する


【例】

```yml
ja:
  activerecord:
    models:
      task: タスク
      user: ユーザー
      label: ラベル
    attributes:
      task:
        title: タイトル
```

例えばymlに上記のような記載をしていて `translate` メソッドを使いたい場合、

```ruby
<%= t('activerecord.attributes.task.title') %>
```

でタイトルという文字列がviewに参照される。

他にもI18nには様々な便利機能があるので以下参照。
https://qiita.com/Kta-M/items/bd4ba36a58ad602a9d8b
Pythonでスクレイピングしてみる。



1.Python バージョン

```
Python 2.7.16
```


2.Requestsをインスコ。

```
pip3 install requests
```

3.beautifulsoup4をインスコ。

```
pip3 install beautifulsoup4
```

4.テストソース

```test3.py
import requests
from bs4 import BeautifulSoup

r = requests.get("https://news.yahoo.co.jp/")

soup = BeautifulSoup(r.content, "html.parser")

#テキストのみ抽出
print(soup.find("ul", "newsFeed_list").text)
```
gossテストシナリオ作成 その2

本記事は[gossテストシナリオ作成 その1](https://qiita.com/kyou5963/items/119a887db7e5a53f81d2)の続きです

addコマンドによるテストシナリオ作成
------
autoaddでは対応できないテストをaddコマンドを使って追記していきます。

```
goss add command [実行したいコマンド]
```
上記はcommandの箇所はテストしたい内容を記載します。
テストに応じて、必要なパラメータを指定します。
上記のcommandの例では、実行したいコマンドを指定し、テストシナリオには
goss addを実行した際の結果のexit-code, stdout, stderr などがテストシナリオ化されます。

他にもhttpであればリクエストしたURLへのHTTP response codeなど
dnsであれば名前解決した結果のレコードなどをテストシナリオ化します。

add commandで特に注意が必要なのは実行するコマンド自体がOSに何らか変更を行う場合
それはそのままaddサブコマンドやテスト実行するvalidateサブコマンド実行時に実行されてしまいます。

例えば ```systemctl stop httpd.service``` をcommandとしてテスト化した場合
テストの都度httpd.serviceはstopされてしまいます。

goss自体はOSのその瞬間の状態をテストするため、OSの状態を変更した結果を検証したいのであれば、別の方法を用いた方が簡単だと思います。

さらにテストを手動で編集する
---------
出力されたyamlファイルはテキストファイルであるためviなどテキストエディタで編集可能です。

本来期待された結果と異なるシナリオがautoadd/addで作成された場合の修正や
そもそもそれらのサブコマンドでは作成できないテストを記載したりします。

例えばfileのcontains項目には指定パスのファイルにどんな内容が記載されているかをテストすることが可能ですが、autoaddでもadd fileでもその内容は生成できません。

そのため手動でyamlファイルを編集してテストを加えていきます。containsの詳細は別の記事で書きたいと思います。

手動編集時の留意点
------------
一度編集したyamlファイルを対象にautoaddやaddサブコマンドでテストシナリオを追記する場合は注意が必要です。

**YAMLは仕様上、コメントを記載することができますが、autoadd/addサブコマンドでファイルを追記するとYAMLコメントを消してしまいます。**
gossが一度ファイルを読み込んで追記してファイル出力しなおす弊害です。

他にも同じ内容のテストをautoadd/addサブコマンドで追記したりすると元々書いてあったテストを上書きしてしまうため、テスト作成時はautoadd → add → 手動編集の順にやっていくとスムーズです。


テストシナリオファイル内で別のyamlファイルのテストシナリオを呼び出す
--------
テスト項目にgossfileという内容で特定のgossテストシナリオファイルを指定できます。

これを指定すると既にあるテストシナリオファイルをインクルードできます。

そのため、WebServer.yamlというテストシナリオ内に
```gossfile:
    httpd.yaml: {}
    OSCommon.yaml: {}
    PackageCommon.yaml: {}```

としておき、それぞれ呼び出すテストを部品化も可能です。これも詳細は別記事でやりたいと思います。

また、部品化が複雑化した場合でも
```goss -g WebServer.yaml render```
と実行するとすべてのテストシナリオをインクルードした結果のテスト項目を全て表示してくれます。
シェルスクリプトって便利

## はじめに
ArchLinuxを使い始めて、半年くらい経ちました！
少しずつ使い方になれてきて、もう少し楽に立ち上げられるようにシェルスクリプトを作ってみた時の話をしていきたいと思います:relaxed:

## シェルスクリプトって？
シェルで実行するコマンドなどがまとまったドキュメントのようなもので、用意しておくと上から書かれたコマンドが実行されていくので、定期的に使う作業などはこのファイルの中に入れると良い。

## 設定の仕方・実行方法
1. `.sh`ファイルを作成する
1. 実行したい内容を、`.sh`ファイル内に記述する。
1. そのあと、`chmod 755 ~~~.sh`とコマンドを打って実行権限を与える。
1. `sh test.sh`とコマンドを打って実行
1. ファイル内に記述されている内容が実行される 

※上から実行されるので、順番に注意！

## 便利な使い方
私は、ArchLinuxを使う際に、最初のキーボードレイアウトの設定やX410の設定ファイルの読み込みなどをシェルスクリプトに書いて実行しています。シェルスクリプトに記述したことによって、設定を短い時間で終わらせることができました。


## さいごに
皆さんもぜひ、シェルスクリプト作って、つかってみてください！設定などに使っていたコマンドをシェルスクリプトに書くだけで、OKjなのでとっても簡単でした
DockerでMovable Type for AWSを驚くほど簡単に無料SSL化する

[Movable Type Advent Calendar 2019](https://adventar.org/calendars/4113) 12日目です。

Dockerを使った簡単SSL化のお話です。MT以外でも使えます。

# Movable Type for AWS

Movable TypeにはAWS版が用意されています。EC2でインスタンスを立ち上げるときにプレインストールイメージが選択できます。

手順は[Movable Type for AWS（AMI）スタートガイド\| CMS プラットフォーム Movable Type を Amazon EC2 のクラウドで](https://www.sixapart.jp/movabletype/aws/how-to-use.html)などをご参考ください。

nano、microインスタンスでは、Movable Typeが無料です(EC2の料金しかかからない)。太っ腹！

しかもCGI版ではなく、Plack版で高速。格安レンタルサーバーを借りてMTをインストールするという選択肢は過去のものとなりました。

## SSL非対応

Movable Type for AWSは、デフォルトではSSL非対応です。昨今はAOSSLが主流となり、そもそも管理画面の認証もあるのでそのままでは実用化できません。

何らかの方法でSSL化が必要です。

* nginxまたはApacheをSSL対応する → 証明書を購入するかLet's Encryptを使う
* ELB/ALBを使う → ACMで無料のSSL証明書も使える
* CloudFrontを使う → ACMで無料のSSL証明書も使える

ぱっと思いつくのはこのあたりですが、今回はDockerを使って簡単に無料SSL(Let's Encrypt)化する方法を紹介します。

## steveltn/https-portal

「Dockerとかよく知らないし、Let's Encryptも面倒なんだよなー」と思った方もご安心ください。私もそうです。

Let's EncryptによるSSL化をアホみたいに簡単にしてくれるDockerイメージがあります。

https://hub.docker.com/r/steveltn/https-portal/

# 手順

## EC2インスタンスの起動・DNS設定・ポート開放

まずはMovable Type 7のEC2インスタンスを起動し、ドメイン名でアクセスできるようにDNSを設定してください。

この例では、`ssl-mt.ideamans.com`としました(←説明用のドメイン名なので実際には開けません)。

セキュリティグループでは、ポート`22(SSH)`・`80(http)`・`443(https)`のインバウンドアクセスを許可してください。

`http://ssl-mt.ideamans.com`を開くとMTのセットアップページが表示されるはずです。

## まずはdockerをインストール

EC2インスタンスにSSHでログインして次のコマンドを実行します。

```bash
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl enable docker
```

## nginxの待ち受けポートを8080に変更

EC2インスタンスの起動直後は、

> インターネット → nginx(:80) → MT(:5000)

という経路でMTを利用しますが、次のように変更していきます。

> インターネット → Docker(:80/443) → nginx(:8080) → MT(:5000)

そのため、nginxの待ち受けポートを`8080`に変更します(Apacheの場合は読み替えてください)。

```bash
sudo vi /etc/nginx/nginx.conf
```

41行目付近にあるポート番号を変更します。

```nginx
    server {
        listen              8080; # 80から変更
        include             /etc/nginx/nginx_common.conf;
    }
```

nginxを再起動します。

```bash
sudo systemctl restart nginx
```

## steveltn/https-portalを起動

次のdockerコマンドで`steveltn/https-portal`を起動します。`DOMAINS=ssl-mt.ideamans.com->`の部分はお使いのドメインに置き換えてください。

```bash
sudo docker run \
  -e "DOMAINS=ssl-mt.ideamans.com->http://dockerhost:8080" \
  -e "STAGE=production" \
  -d --restart always \
  -p 80:80 -p 443:443 \
  steveltn/https-portal
```

**そのまま2〜3分待ちましょう**。DHの生成などで少し時間がかかりますが、設定は以上です。

認証用のディレクトリの準備とか自動更新とか面倒な部分は全部このDockerイメージ`steveltn/https-portal`がうまいことやってくれます。**え？ Let's Encryptってもっと面倒じゃなかった？**って感じですね。

## SSLで開く！

ブラウザで`https://ssl-mt.ideamans.com/`にアクセスすると安全な状態でMTを開けます。これでインストールも安全にできる！

と、こんな風にSSL化が簡単にできました。

さらに`docker run`コマンドに`-v ./https-portal:/var/lib/https-portal`みたいな感じでボリュームマウントを追加すると、証明書などを永続化できるので再起動も早くなります。

Web制作ではあまり出番がなく、縁の遠いDockerですが、こんなカジュアルな使い方もありますよーというお話でした。
Django を VSCode で 開発するまでの手順

2020/03/13 VSCode Version 1.43.0 に合わせて若干修正
2022/08/11 情報が古くなってきたので修正して更新

## はじめに
初心者がデバッグという言葉に憧れて、実はVSCodeでできるということを知り、設定してみた。その備忘録。メリットは一度設定すると、Debugボタンを押すだけで、仮想環境に入って、サーバーを動かしてくれることだと思う。ブラウザとTerminalとVSCodeを行ったり来たりして`source myenv/bin/activate`とか`python manage.py runserver`を入力する手間が省ける。ちょっと楽。

## 参考URL
[Django Tutorial in Visual Studio Code](https://code.visualstudio.com/docs/python/tutorial-django)

## 環境

VScode 1.70.0
Ubuntu 22.04 LTS
Python 3.10.4
Django 4.1

## Django を VSCode で開発するまでの手順

### Terminalでの下準備

```
$ mkdir myproject
$ cd myproject
$ python3 -m venv myenv
        # 仮想環境も色々あるみたいだがここは venv 一択で.
$ source myenv/bin/activate
        # これで仮想環境に入れた.仮想環境下でのプロンプトは以下(myenv)$とする.
(myenv)$ pip install django
        # Djangoがinstallされる (バージョンを指定する場合は django==2.2.8 のように入力）
(myenv)$ django-admin startproject config .
        # いよいよproject開始.名前はconfigで. 理由は「現場で使えるDjangoの教科書」本から.
        # 最後の「.」を忘れないように.つけないとさらにディレクトリができて少々面倒くさい.
(myenv)$ deactivate
        # 仮想環境を一旦抜ける
```
現在のディレクトリ構成は以下の通り

```
.
├── config
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
└── myenv
```
### VSCodeで開発環境を整える :

1. VSCode を起動し File から Open Folder... をクリック、先程の myproject ディレクトリを開く
![DF65AC17-C584-4D67-AE00-9CEAB7F5F023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321085/fa4020a1-8396-4592-7891-6a684b9ac680.png)



2. Python の Extention を install する
![3F00BD3D-A295-473F-A46E-F84D63325EE9.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321085/638e3f9f-23a6-4778-2716-6ae075058e43.jpeg)


3. View の Command Palette... を選択、Python : select interpreter をクリック。仮想環境(今回ならばmyvenv）のinterpreterを選択すること
![4A0E1826-2126-4F59-922A-3FE59A2F0205.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321085/4f3a35dc-6124-6f72-54b1-347b2d5b4075.jpeg)


4. 左端、虫つき再生ボタンを押してcreate a launch.json fileをクリックする
![456C2401-1099-45E3-A295-CB0E8C31BB02.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321085/4b358a29-d1f6-c69e-5804-b9fae0df84fa.jpeg)


5. 表示から Django を選択する
![DDBA1462-A399-4411-B9D1-0CFF935834DB.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321085/1cb1c0a8-ed03-2f2a-3af9-7007d33a3206.jpeg)



6. DEBUG右の緑色の三角ボタンを押すと自動でrunserverされる
![7169309F-799A-47F4-8765-CBBC721B6321.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321085/fc21951f-e8d6-e991-22e3-3a64563500c2.jpeg)


7. webブラウザで 127.0.0.1:8000 へ飛ぶといつものロケット発射
![ED7BA078-05A2-4681-A8B8-4027FE7AF738.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/321085/5f8f41e1-e94d-11ad-8dee-f762ddd41196.jpeg)




これでTerminalを複数立ち上げたり、毎回毎回コマンド売ったり、ウィンドウを行ったり来たりする手間が省けて楽になる。便利。VSCodeはただのエディタではなく、開発環境なんだなぁ、すごいなぁと実感。

問題は...**初心者はデバッグとは何をどうすることなのかわからない**ということだ。
macOS Mojaveでpygameが動かない

だいぶ前にwindows環境で作ったゲームを動かそうと思ってちょっと詰まった

## 問題

実行環境
- macOS Mojave 10.14.6
- Python 3.6.5 
- pygame 1.9.6
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289210/12d499a3-8943-5f15-8715-de42decf20a7.png", width=500px>
何も表示されない、しばらく待っても動かず

ちょっと調べるとこんなものが
https://github.com/pygame/pygame/issues/555

やっぱりmacOSとデフォルトのpygameの相性が悪いっぽいので
versionを指定して最新のもの(2019年12/12時点)にする

```shell
# pygame1.9.6をアンインストール
> pip uninstall pygame
Uninstalling pygame-1.9.6:
  Would remove:
    /usr/local/var/pyenv/versions/3.6.5/include/python3.6m/pygame/_camera.h
    /usr/local/var/pyenv/versions/3.6.5/include/python3.6m/pygame/_pygame.h

    ...

    /usr/local/var/pyenv/versions/3.6.5/lib/python3.6/site-packages/pygame/*
Proceed (y/n)? y
  Successfully uninstalled pygame-1.9.6
```
```shell
# versionを指定してpygameをインストール
> pip install pygame==2.0.0.dev6
Collecting pygame==2.0.0.dev6
  Downloading https://files.pythonhosted.org/packages/be/1d/03caf4447ff3f9b4a89e169a35360c95eeaa5f9c4d1312a619ce2b23e5a8/pygame-2.0.0.dev6-cp36-cp36m-macosx_10_11_intel.whl (5.5MB)
     |████████████████████████████████| 5.5MB 3.4MB/s 
Installing collected packages: pygame
Successfully installed pygame-2.0.0.dev6
```
```shell
# 確認
> pip freeze

...

pygame==2.0.0.dev6
```

無事動作した。
## リンク
- pygameモジュールリリースノート  
https://pypi.org/project/pygame/2.0.0.dev6/#history
Maplat Coreで古地図の上に明滅するバスを走らせてみる

Maplat Advent Calendar 12日目ですが、Maplat Coreで古地図の上に明滅するバスを走らせてみます。
もう何が言いたいのか自分でもよくわかりませんが、今日の動くものはここで確認できます。 => [CodeSandBox Maplat Advent Calendar day 12](https://codesandbox.io/s/maplat-advent-calendar-day-12-76dmm)

要するに、`app.updateMarker`で情報アップデートできるのは経緯度だけじゃないよ、アイコン画像情報をアップデートすると画像も切り替わるよ、というサンプルなわけですね。

昨日からの変更は、赤いバスのアイコン画像`parts/red_bus.png`[^1]の追加と、ループのインデックス値が奇数か偶数かで赤と青のアイコン画像を切り替えて、`icon`属性として`app.updateMarker`の更新内容に加えているというだけですね。

```app.js
import "@maplat/core/dist/maplat_core.css";
import { MaplatApp } from "@maplat/core";
import { lineString } from "@turf/helpers";
import length from "@turf/length";
import lineChunk from "@turf/line-chunk";
import explode from "@turf/explode";

var option = {
  appid: "maplat_ac_day12"
};

var app = new MaplatApp(option);
app.waitReady.then(function() {
  var ring = [
    [139.53184, 36.251013],
    [139.534322, 36.249581],
    [139.533853, 36.24814],
    [139.530729, 36.248649],
    [139.53184, 36.251013]
  ];
  app.addLine({
    lnglats: ring,
    stroke: {
      color: "#ffcc33",
      width: 2
    }
  });
  document.getElementById("gsi").addEventListener("click", function(e) {
    app.changeMap("gsi");
  });
  document.getElementById("osm").addEventListener("click", function(e) {
    app.changeMap("osm");
  });
  document.getElementById("ojo").addEventListener("click", function(e) {
    app.changeMap("tatebayashi_ojozu");
  });
  document.getElementById("aki").addEventListener("click", function(e) {
    app.changeMap("tatebayashi_castle_akimoto");
  });

  var ringFeature = lineString(ring);
  var ringLength = length(ringFeature, { units: "meters" });
  var divLength = ringLength / 20;
  var chunk = lineChunk(ringFeature, divLength, { units: "meters" });
  var points = chunk.features.map(function(line) {
    var nodes = explode(line);
    return nodes.features[0].geometry.coordinates;
  });
  app.addMarker({
    id: "moveMarker",
    lat: points[0][1],
    lng: points[0][0],
    icon: "parts/blue_bus.png"
  });
  console.log(points);
  var index = 0;
  var regularRun = function() {
    var point = points[index];
    var icon = index % 2 ? "parts/red_bus.png" : "parts/blue_bus.png";
    app.updateMarker("moveMarker", {
      lat: point[1],
      lng: point[0],
      icon: icon
    });
    index = index + 1;
    if (index > 19) index = 0;
    setTimeout(regularRun, 1000);
  };
  regularRun();
});
```

それで、以下のように赤と青で明滅するバスが古地図の上を走るようになります。

![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/10108/27696c0c-578a-52f6-8979-f8029b8c960f.gif)

ちなみに、`app.updateMarker`の動作ですが、第一引数は更新するPOIピンのID、第二引数は更新するデータですが、第三引数にデータを上書きするかどうかがbooleanで指定できます。
第三引数がデフォルト（`false`）の場合、第二引数で指定されたオブジェクトが持つ属性だけが差し替えられますが（削除したいときは、値に`'____delete____'`を指定します）、`true`を指定した場合は、第二引数で指定されたオブジェクトでPOIピンのデータが上書きされます。

明日は、ピンではなく地図の視点を経路に合わせて動かしてみましょう。
中心点だけではなく、地図の角度も進行方向に合わせて回転させてみます。
いわゆるヘッドアップビューというやつですね。

[^1]: (c) Font Awesome
Redmineを使い始めるための初期設定

## この記事について

私がプロジェクト運営で Redmine を使うに当たって、行う初期設定を記載しておきます。

### 対象読者

* これから Redmine の導入を検討している方。
* Redmine 運用について、他の設定例を見たい方

## 環境

* ESXi 上に構築した Centos7

## インストール手順

Redmine のインストールが完了し、最初にトップ画面が出てからの設定です。
インストール手順については、下記サイトを参考にします。

* [Redmine.jp](http://redmine.jp/install/)
* [Redmineガイド](http://guide.redmine.jp/RedmineInstall/)

## 初期設定

### 基本方針

なるべくカスタムフィールドを作成せずに、チケットテンプレートを駆使しての構築を目指しています。カスタムフィールドを使うとどうしても管理が難しくなったり、レイアウトに要望が出て使いにくい印象を与えてしまうので。
とは言っても、使用が０というわけではありません。


### テーマ

* [Redmine用テーマ「farend fancy」公開](https://www.farend.co.jp/blog/2012/02/23/farend_fancy/)

数々のテーマが（主に海外から）作成されて発信されています。個人的には「farend_fancy」一択でよいと思っています。
理由としては、

* Redmineで何か情報を探した場合は、このテーマの使用率が高い気がする
* 日本語で見やすいようにCSSが調整されている

点です。

[farend_fancy(GitHub)](https://github.com/farend/redmine_theme_farend_fancy.git)

### プラグイン

* [view-customize(GitHub)](https://github.com/onozaty/redmine-view-customize.git) … js, css を記述して、Redmineの見栄えやレイアウトを調整します。Redmine本体に傷を付けずにカスタマイズできる便利なツールです。
* [issue_templates](https://github.com/akiko-pusu/redmine_issue_templates.git) … チケットのテンプレートを作成できます。
* [Easy Gantt（開発元）](https://www.easyredmine.jp/en/redmine-gantt-plugin) … 高機能なガントチャートなどを提供してくれます。機能が豊富で全然使いこなせていないです。

### トラッカー

|名称|説明|
|:--|:--|
|ＱＡ|質問対応|
|課題|課題対応|
|バグ|バグ対応|
|設計|要件定義～コーディングまで設計と見なしています|
|テスト|すべてのテスト工程|
|環境構築|ＨＷ環境、ＮＷ環境、データ環境など|
|見積|見積対応|
|要望|要望対応|
|タスク|雑務対応（上記トラッカー以外でＣＳに影響しそうな内容）|
|その他|その他（使わないのが望ましい）|

* [私がやったRedmineの初期設定](https://yoshinorin.net/2016/12/11/redmine-initial-settings/)　参考にさせて頂きました。ありがとうございます。

#### 「トラッカー」運用

* **迷ったら「ＱＡ」**。大規模な構築で複数の関係者がいるならば、全て「ＱＡ」でよいと思う。トラッカーを判断し、担当者をアサインするのはＰＬのお仕事。小規模であればＰＬがいろいろな役割を持つと思うので都度判断になると思われる。
* **一度登録したトラッカーは変更しない**。例えば「ＱＡ」としたが、バグだと判明した場合は「バグ」として新規に作成する。

### チケットステータス

|名称|説明|例|
|:--|:--|:--|
|新規|受付状態|
|様子見|情報収集中など|
|進行中|着手|
|対応済|完了|リリース済まで含む
|承認済|発信者が納得した状態|
|完了|対応完了|
|却下|取り下げ案件|

#### 「ステータス」運用

新規以降のステータスについては、細かく変更するのは面倒になってしまうので、基本ルールとして **そのステータス状態が１日以上続くのであれば飛ばしてＯＫとする**
例えば、着手から対応済までが2～3時間で終わるならば、新規→対応済への変更でもよいと思う。
いずれにしても、毎朝もしくは毎夕、週１の決まったタイミングで自分のアサインされたチケットステータスは棚卸するというルールが必要と考える。

### 優先度

|名称|利用例|
|:--|:--|
|低|クリティカルパスに影響しない突発的内容や立ち消えになりそうな要望など|
|通常|スケジュールや計画通りの場合|
|高|今の手持ち作業が終われば実施|
|即時|他の全ての作業を中断して取り掛かる|

他の判断基準として

|名称|利用例|
|:--|:--|
|低|クリティカルパスに影響しない|
|通常|クリティカルパス及び計画通り|
|高|クリティカルパス及び社内外に影響|
|即時|遅延や社内外の作業が中断している場合|

**「優先順位」は何か１つを決めること**（昔誰かに言われた）ということを念頭にすると、優先度の項目は数が少なくなる。

#### 「優先度」運用

* １担当者に適用できる「即時」は１つまでなどのルールを決める。
* １担当者に適用できる「高」は２つまでなどのルールを決める。

働き方改革があるので「高」「即時」は、残業に繋がる可能性が高い。また、１担当者に集中すると過負荷必至なので、ルールを設ける。

## 感想

**会社の数　×　プロジェクトの数**　だけ、設定や運用例があると思いますが参考にして頂ければと思います。

## 参考サイト

参考にさせて頂きました。ありがとうございました。

* [私がやったRedmineの初期設定](https://yoshinorin.net/2016/12/11/redmine-initial-settings/)


その他、思いつけば加筆修正します。
kaggle一週間チャレンジのススメ - ダレない、飽きない、ハードルが低い


この記事は、[Kaggle Advent Calendar 2019](https://qiita.om/advent-calendar/2019/kaggle)のアドベントカレンダー11日目の記事です。


Kaggleの[NFL Big Data Bowl](https://www.kaggle.com/c/nfl-big-data-bowl-2020/overview)というコンペを
緩く一週間で取り組んだ際の

- どのように取り組んだか
- どんなことが得られたか
- 一週間だったことの良かった点

について書いていきます。

# TL;DR
- 締切の一週間前にコンペを始めた
- 写すというだけでも意外と勉強になったし、それで順位が伸びるのは快感だった
- 短期集中なのでダレなくて良い
- 上位解法も実際に参加したコンペのものなので読みやすさが段違いで最高




# なんで1週間

友達に「NFLコンペ良いらしいよ」とおすすめされたのが締切の一週間前(11/20の夜)だったので(参加登録だけは以前にしていた)。


# どのように取り組んだか
## コンペの概要を理解する
- とりあえずOverviewとData DescriptionをGoogle翻訳にかけて流し読み
    - 幸い、割と設定は理解しやすく「ボールを持った人がどれくらい進めるかを予測するコンペ」だとわかる 

## Discussionを流し読みする
- どういう特徴量を作っていけば強くなるんだろうなーという思いで
- Most Votes でソートして上の方に来たやつを10個くらい読む
    - 持った人とその他の人の位置関係が重要だという知見を得る
    - 割とデータの前処理が大変そうだということも薄っすらと理解する

## いい感じのKernelを見つける
- 割とデータの前処理が大変そうだということを薄っすら理解した
    - 前処理は良い感じのKernelをフォークしてくるか、という気分
    - かといって、適当な前処理引いて爆死したくはない
    - なのでbest scoreでソートして上の方にあるもので
        - (割とvoteがある) & (scoreがそれなりに高い) & (書いてる人の順位が高い | コンペMaster以上)
        という基準でフィルタかけて、良さげなのを改良していくという方針
        - (Kernels GranMaなのにコンペはメダル0とかの人のKernelってどう解釈すれば良いのだろう…？)

## PDCA(？)を回す
後は特徴量をガンガン追加→kernelをしていきました。手順としては概ね
1. Kernel/Discussionの上位を読む
2. 現在の特徴で足りてなさそうな事項を見つける
3. それを加味した特徴を追加する(まんまコピーしたり、考えたり)
です。締め切り前日までひたすら繰り返してました。

具体的に追加した特徴量としては
- ボールを持った選手と他の選手との距離に関する特徴
- 敵チームのプレイヤーの位置に関する特徴
- 両チームの重心に関する特徴
あたりです。

# どんなことが得られたか
## 銅メダル(予定)
順位の出方が少し特殊で、今後の試合結果で都度評価していく形式なため最終結果は出ていませんが
提出締め切りのときの順位が159/2038、2回目の更新の時点での評価が138/2038と(今のところは)銅メダルくらいは貰えそうな順位に付くことができました。初メダルです、ラッキー。

## コンペに纏わるコーディング力
KernelやDiscussionを基本再現しただけ、と言えどもそれを組み合わせたり、またDiscussionをコードに起こしたりしようとすると
割とバグります。それなりに苦労が伴うわけです。
なので、単に再現するというだけでも存外力が付いた気がします。

## コンペ自体への理解とその後の勉強のしやすさ
これはコンペの後に気づいたことです。
たとえ一週間と言えども実際に参加したことでこれがどんなコンペかある程度は理解できます。
そうすると、人のSolutionを見たときに割とスッと頭に入ってきます。
これによって新しい知見を吸収しやすくなり、今後のコンペのための勉強がずっと捗るようになった、かと思います。



# 良かったこと

## 飽きない、ダレない
Kaggleのコンペって基本始まりから終わりで2,3ヶ月くらいの期間があります。
その期間中ずっと集中してやるなんて無理だ！って人も多いかと思います。
その点、1週間チャレンジだと時間がとにかく無いので尻に火が付いて猛烈な短期集中でやっていけます。


## 既に有益な情報が出揃ってるので参入のハードルが低い 
ラスト1週間ということもあり、強い人たちが出せる情報を惜しみなく出してくれてます。
そのため、複雑な前処理とかEDAとかを自力でしなく済みます。
楽です。

## 初心者でも割とスコアが伸びてくれてモチベになる
そして、強い人の公開した情報をトレースするだけで初心者でも割とスコアが伸びます。
この感覚は結構楽しく、病みつきになること間違いないと思います。
この方式を最初にやって、徐々に長い時間をコンペに費やすと無理が無くドハマれるんじゃないでしょうか。

# まとめ
- コンペに締切の1週間前から参加すると情報が出揃っていて楽
- しかも短期集中なのでダレない
- それでも、リアルタイムで参加したから、強い人の解法を読みやすくなり今後の勉強にもなる

以上です、ご愛読ありがとうございました
AWS CDKを使って、既存のドメインとAWS Lambdaに対してAPI Gatewayを作ってLambdaを実行する許可を出したりするサンプル。

AWS CDKを使って、既存のドメインとAWS Lambdaに対してAPI Gatewayを作ってLambdaを実行する許可を出したりするサンプル。

```example.ts
import cdk = require("@aws-cdk/core");
import apigateway = require("@aws-cdk/aws-apigateway");
import lambda = require("@aws-cdk/aws-lambda");

interface MultistackProps extends cdk.StackProps {
  stage: "staging" | "production";
  functionArn: string;
  domainName: string;
  domainNameAliasHostedZoneId: string;
  domainNameAliasTarget: string;
}

export class MuaFrontendApiGatewayStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props: MultistackProps) {
    super(scope, id, props);

    const domain = apigateway.DomainName.fromDomainNameAttributes(
      this,
      `existing-domain-${props.stage}`,
      {
        domainName: props.domainName,
        domainNameAliasHostedZoneId: props.domainNameAliasHostedZoneId,
        domainNameAliasTarget: props.domainNameAliasTarget
      }
    );

    const api = new apigateway.RestApi(this, `api-gateway-${props.stage}`, {
      restApiName: `api-gateway-${props.stage}`
    });

    new apigateway.BasePathMapping(this, `basePathMapping-${props.stage}`, {
      domainName: domain,
      restApi: api
    });

    const lambdaOne = lambda.Function.fromFunctionArn(
      this,
      `lambdaOne-${props.stage}`,
      props.functionArn
    );
    const lambdaIntegration = new apigateway.LambdaIntegration(lambdaOne, {
      contentHandling: apigateway.ContentHandling.CONVERT_TO_BINARY
    });
    const rootProxy = api.root.addProxy({
      anyMethod: false
    });

    const methodOne = rootProxy.addMethod("ANY", lambdaIntegration);

    new lambda.CfnPermission(this, `permission-for-lambda-${props.stage}`, {
      action: "lambda:invokeFunction",
      principal: "apigateway.amazonaws.com",
      functionName: lambdaOne.functionArn,
      sourceArn: methodOne.methodArn.toString()
    });
  }
}
```
プロデルでCSVファイルから折れ線グラフを描く

プロデルでCSVファイルのデータを読み込み折れ線グラフ化するプログラムを作ってみます。
今回は、日ごとの電力の使用量をnipoさんが作った[折れ線グラフのプログラム](https://qiita.com/nipo/items/74d81b4002a3437d92d5)を活用して描いてみます。

プロデルでは、「データ表」種類を使ってCSVファイルを読み込んでテーブルのように扱うことができます。

電力使用量は、東京電力エナジーパートナーの「くらしTEPCO」という契約者向けのサイトにログインすることで前日までの電力使用量をCSVファイルでダウンロードできます。
このサイト上でもグラフを見ることができるのですが、プロデルの画面で同じようなグラフが表示されるか試してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101225/b0d37e84-d22d-2ae3-eb0f-c0f75de7ff67.png)

グラフの右下にCSVファイルのダウンロードボタンがあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101225/5ab1af3b-9cb8-ed48-8ce6-49369b1f6b4c.png)

ダウンロードしたCSVファイルを開くと1行目が見出し行になっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101225/03a1b589-7b25-dd67-e301-224cc8cb68f6.png)

CSVファイルでグラフ化に必要なデータは、9列目の見出しが「ご使用量」となっている列です。
このCSVファイルは、東京電力の例ですが、別の電力会社サイトでもCSVファイルがダウンロードできるかと思います。CSVファイルに使用量に相当する列が分かれば、同じようにグラフ化できます。

```
「行列.rdr」を参照する。
「色.rdr」を参照する。
「グラフ描画.rdr」を参照する。
「Produire.PGraphics.dll」を利用する。
「Produire.WinControl.dll」を利用する。

あは，グラフ（600，300）を作ったもの。
いは，行列（3，33）を作ったもの。

ファイル一覧は、{「20191103_comparison.csv」,「20191110_comparison.csv」,「20191117_comparison.csv」}
番号は、1
ファイル一覧を項目にそれぞれ繰り返す
	データ表を作ってデータとする
	データの見出し行は、○
	データへ項目から読み込む
	うは、0
	データの行一覧を行にそれぞれ繰り返す
		うを増やす
		いの中身（番号）（う）は，行から「ご使用量」を得たもの
	繰り返し終わり
	番号を増やす
繰り返し終わり

あにいで折れ線グラフを描く。
あを表示。
待機する。
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101225/8331afbf-b6e2-ff85-dcad-5db76d07c9de.png)

横軸の目盛りがあるとわかりやすいですね。気が向いたら改造してみます。

#まとめ
今回は簡単でしたが、CSVファイルを読み込んでグラフ化するプログラムを作ってみました。
プロデルで自分でプログラムを作ればWebサイトでは表示できない曜日ごとといった観点から表示させることもできます。もちろんExcelなどでも簡単に折れ線グラフは作れてしまいますが、プロデルを使うことで自動化するといった事も可能です。ちょっとしたガジェットアプリを作るといった活用方法もあるかと思います。
新しくPCを購入してAndroid Studioを始めたけどAVDが動かない

備忘録として
問題解決後に記事を書いているが画面を撮っておけばよかったなと少し後悔…


アプリ開発の勉強に向けて新しくPCを購入しAndroid Studioをインストールし、いざやるぞ！と思った所でAVDが動かずつまずいてしまった。

アプリを作成し、いざAVDを作成！という所でエミュレータを起動できず。画面右の小窓にunknown errorである旨の記載が…

Android Studioを一旦フォルダから直接削除し再インストール。
するとUnable to run mksdcard.exe SDK toolの文字と記載あり。

Cancelするとそのまま進んでしまうため初回はこのエラーを放置して進んだもよう。
なお、Cancelして進んでもSDK toolのHAXMはチェックが入った状態（インストールされているように見える）になるためAVD作成時にunknown errorと記載されてしまうよう。


最終的にVisual C++のダウンロードを行うことで解決ができた。
SDKを使用する際にVisual C++が必要になるため。(エラー内容のrequired libraryはこれを指してたようだ）


間違いあったらすみません。自分はこの方法で解決できました。
日本語のサイトも少なく、Unable to run mksdcard.exe SDK toolで調べるとUbuntuのことしか出てこない状況だったため一助になれば幸いです。