OmniAICreator/Qiita-1.07M huggingface dataset:
CDIの勉強（その３）

### CDIの勉強（その３）

[前回](https://qiita.com/yasu-suge/items/8d09b40f4431604bb216)の記事の続きです。

#### インターセプターの利用
インターセプターは、アノテーションを準備し、インターセプトしたい実装を作成し、アノテーションを追加し、bean.xmlを設定するだけでOKです。

![pic001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292074/2c11aebb-d1a1-77e5-906b-36c553221419.png)

#### デコレーターの利用
デコレーターは、業務ロジックに横断的な実装をしたい場合に使用するようです。
デコレーターとして、追加したい処理を行うクラスを抽象クラスとして定義して、@Decoratorアノテーションを付与します。
フィールド等に、@Delegate アノテーションを付与し、実体のクラス実装に対し、追加する処理をオバーライドします。

デコレーターを有効にするには、beans.xml にクラス情報を登録する必要があります。

![2020-05-24 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292074/31101218-efe2-b9d7-42e3-371776d039e7.png)
お絵かきできるSNSを作りたい！8

レイヤーの実装していきます。

↓この部分
![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104527/f76ea736-1de9-2d85-7336-31ca460d220e.jpeg)

まず、ラジオボタンのname属性を同じにします。

```html:
<p><label><input type="radio" name="rdoLayer" checked>上レイヤー</label></p>
<p><label><input type="radio" name="rdoLayer">下レイヤー</label></p>
```

これで両方のラジオボタンにチェックが付く状態から、片方1つにチェックが付く状態になります。
次にレイヤーを作るに辺りcanvasが2枚必要なので増やしました。

↓変更前

```html:
<canvas id="canvas" width="800" height="600"></canvas>
```

↓変更後

```html:
<div id="canvasarea">
<canvas id="canvas" width="800" height="600"></canvas>
<canvas id="canvas2" width="800" height="600"></canvas>
<!--/#canvasarea--></div>
```

↓スタイルシートはこんな感じ。

```css:
#canvasarea{
	width: 800px;
	height: 600px;
	background-color:#FFF;
}
#canvasarea:after, #canvasarea:before {
	content: "";
	clear: both;
	display: block;
}
#canvas{
	z-index:2;
}
#canvas2{
	z-index:1;
}
#canvas2,#canvas {
	width: 800px;
	height: 600px;
	position: absolute;
}
```

canvas自体を　position:absolute　にして、canvasを入れている#canvasareaは疑似要素で　clear:both　を付けました。
そして、#canvasの方が上に来るようにz-indeを2にしています。(#canvas2は1)

最後にJSです。
今までの処理に下レイヤー用の#canvas2をコピペし、各動作の前にレイヤーの上レイヤーと下レイヤーどちらを選ばれているかを確かめる処理を追加しました。

↓黒で上レイヤー・紫で下レイヤーを使いました。
![WS000000.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104527/5dfa4a08-5d9e-f708-4ed4-1f34ca722843.jpeg)

ちゃんとレイヤーになってますね。
これで右側のカラーパレット・線の太さ・レイヤーが完成です。
![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104527/b0f2dff3-a985-eb73-c740-54bdc27aad62.jpeg)

次回は下の実装を行います。
![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104527/be8ccca7-84f5-c1fe-2ae5-3fcfd22b99c7.jpeg)

次：[お絵かきできるSNSを作りたい！9](https://qiita.com/cardcapt/items/929699a12c2d0f8e269f)
最初：[お絵かきできるSNSを作りたい！](https://qiita.com/cardcapt/items/d15fedf80d336f6b4bb9)
【初心者向け】Verticaとは何か

# 概要
Verticaとは、アメリカ合衆国マサチューセッツ州に本拠を置く、
ヴァーティカシステムズが提供している、「DWH/ビッグデータ活用」に特化した列指向型DBMSのこと。

# 特徴
###1.列指向型
Verticaは検索機能に特化したデータベースを列指向型DBMSとして設計されている。
列のデータをひとまとまりにして取り出すときに場面において有用であり、
大量の類似のデータ項目に対し集計が行われるもの対して効率的に取得できる。

####【利点】
・大量の行に対する少数の列の集約処理が効率的である。
列数が少ないほど、読み込むデータ量を減らすことができる。
・全行に対する少数の列の一括更新が効率的である。
新規に列データを作成し、以前のデータと置換することで、他の列へのアクセスを回避できる。

####【苦手】
・少数の行に対する多くの列の読込・更新が苦手。
行指向DBMSと比較すると、効率面では劣る。

####【その他】
・ストレージの効率とランダムアクセスの観点においても
「利点/苦手」が存在するが、Verticaの概要から逸れるため省略。

###2.UDF（ユーザー定義関数）
他DBMSと同様、モジュールを作成後、手順に沿って、ライブラリに追加すれば、
ファンクション関数として、UDF（ユーザー定義関数）が使用可能となる。
モジュールの言語は、Python/R/C++/Javaが利用可能。

# SQLの仕様

###1.標準的なSQLインターフェースに対応
1.ANSI SQL99に準拠し、JDBC/ODBC/ADO.netの各ドライバに対応しているため、
WebFOCUSやDMExpressといったアシスト取扱製品、
TableauやBusiness Objects、Talend、Infomaticaなどの他社BI/ETL製品との連携もスムーズに実装可能。

###2.独自拡張のSQL[vsql]
vsqlとは、Verticaを操作するために使用するSQL言語である。
Verticaのインストールにデフォルトで組み込まれているため、別途インストールは不要。
vsqlについては、別の記事で詳細情報を記載予定。

# 備考
Verticaは少数の複雑なクエリを実行するDWH等に適性が高いDBMSである。

## 関連記事
・[Verticaとは]
(http://vertica-tech.ashisuto.co.jp/about-vertica/)
・[Wikipedia - 列指向データベース管理システム](https://ja.wikipedia.org/wiki/%E5%88%97%E6%8C%87%E5%90%91%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)
・[Verticaでファンクション機能を利用する方法]
(http://vertica-tech.ashisuto.co.jp/create_function/)
二進数について

# 二進数について

## 目的  
二進数とはこういうもの！と大雑把に理解する

### 対象  
二進数って何？って人向け

#### 本題  
0と1で表現される数字のことです。  

以上。というのは冗談ですが少し掘り下げて見ます。
私たちが普段の生活で使っているのは十進数です。
十進数は、それぞれの桁の値を0～9のどれかで表現します。 
9の次が桁上がりし10となります。  

これが八進数になるとどうでしょうか？ 
八進数のそれぞれの桁の値は0～7のどれかで表現します。 
7の次が桁上がりし10となります。  

本題である二進数も大体分かってきたのではないでしょうか？ 
二進数は、それぞれの桁の値を0～1のどれかで表現します。 
1の次が桁上がりし10となります。  

では、十進数で書いた12を二進数にしてみましょう。 
ちなみにですが、十進数から二進数の表記に変換することを基数変換と言います。 

さて、十進数で書いた12を二進数にするには12を2で繰り返し割り、余りが1になるか0になるかを調べます。 
余りが0になるということは割り切れるということです。 
12÷2=6 余り0 
6÷2=3 余り0 
3÷2=1 余り1 
1÷2=0 余り1 
余りが1になるか0になるかを調べました。 
得られた余りの数字を逆順にすると2進数の表記になります。 
さきほど、計算した数値の余りを逆順にすると1100という数値になります。 
この1100が2進数でいう12ということになります。

余談ですが 
1÷2=0　余り1 
これは、1の中に2は1個も取れないので、商はゼロになります。すると残りの値としての余りは1となります。 
除算の性質ですね。


##### まとめ                                                                                                                                                                                                                         
各桁が2になると桁上がりする数字
SkyWayで後からstreamを送信しようとして詰まった際の対処

複雑な家庭の事情により、どうしてもSkyWayをつかったWebRTC画面共有ツールをつくる必要があったため、詰まったことをメモ。

完全にSkyWay力技ネタなので、[SkyWayのAPIリファレンス](https://webrtc.ecl.ntt.com/api-reference/javascript.html)と見比べながら見てもらえると。

## やろうとしたこと

- SkyWayで
- カメラを使用しない
- けれども画面だけ共有できるツール

をつくろうとしました。

自分の顔、相手の顔は見えなくていいのでただただ画面を共有したいというノリです。

これを実現するには

```
1.peer生成
↓
2.joinRoom（この時はstreamなし）
↓
3.後からgetDisplayMediaして画面をlocalStreamに追加
↓
4.replaceStreamでlocalStreamをルームのmediaStreamへ送信
↓
5.streamイベントを検知してmediaStreamを受信
```

という流れにすればいいんじゃないかと思い、↓のような雰囲気のコードを書きました。

結論として、これだとダメでした。

```
    // Peer生成
    const peer = new Peer({
        key: this.skyway_apiKey,
        debug: 3,
    });

    peer.on('open', (id) => {
      this.localPeerId = id;
    });

    // sfuルームに参加
    const room = peer.joinRoom(this.roomId, {
      mode: 'sfu',
      stream: this.localStream,
    });


    // 画面を取得してlocalStreamにセット
    const myStream = navigator
            .mediaDevices
            .getDisplayMedia(
              { video: true }
            )
    this.localStream = await myStream

    // mediaStreamを更新
    room.replaceStream(this.localStream)

    // streamイベントを検知した際の処理
    room.on('stream', async stream => {
      if ( typeof(stream) === 'object') {
        const remoteVideo = document.createElement('video');
        remoteVideo.srcObject = stream;
        remoteVideo.playsInline = true;
        remoteVideo.setAttribute('data-peer-id', stream.peerId);
        videosContainer.append(remoteVideo);

        await remoteVideo.play().catch(console.error);
      } else {
        console.log("streamなし");
      }
    });
```
※トリガーとか省略してるので本当に雰囲気だけのコードになってます

## うまくいかなかったこと
### 【事象】streamを送信しても、mediaStreamを更新できない

上記のように実装して動かしてみたところ、4〜5を達成できず、画面共有ができませんでした。

で、4のreplaceStreamか、5のstreamイベント検知側に問題があるのかと思い試行錯誤したのですが、最終的に2のpeerJoinの段階で詰んでいたことが発覚。


### 【原因】ルームへの接続時にstreamが空だと"受信のみモード"で接続されてしまう説

[リファレンスのPeer.callのparameters:stream](https://webrtc.ecl.ntt.com/api-reference/javascript.html#methods)の記載によると、

`接続先のPeerへ送るメディアストリームです。 設定されていない場合は、受信のみモードで発信します。`

とのこと。

sfuRoomの欄に記載があるわけではないのであくまで仮説でしかないんですが、

`stream = ""`

の状態でjoinRoomしてしまっていることがそもそもの失敗で、受信のみモードで参加しているからreplaceStreamがうまくいかなかった模様です。

## 解決するためにやったこと

事前にlocalStreamを準備してからjoinRoomをするようにすればいいのですが、カメラは使用したくないし、接続前にかならず画面を取得しないといけないのは使い勝手が悪い。

ならば<b>"mediaStream形式の空データを作成して、それをstreamにセットしてしまえばいいんじゃないか"</b>と思ったので、mediaStreamのモックデータを用意することにしました。

```
    getMock() {
      const mock = document.createElement('canvas');
      this.localStream = mock.captureStream(10);
    }
```

canvas要素を生成して、そのリアルタイムキャプチャをストリーミングとして取得する感じです。


で、localStreamが空だったり死んでたりする場合は、このモックデータを生成してからjoinRoomするように変更したところ、無事に成功。

```
    if ((!this.localStream.active) || (this.localStream === "")){
        this.getMock()
      }
      const room = peer.joinRoom(this.roomId, {
        mode: 'sfu',
        stream: this.localStream,
      });
```

接続時は黒いブランク画面が共有されて、後で画面を取得したらちゃんと画面を共有できるようになりました。

カメラなしで画面だけ共有するアプリをつくっている人の記事が見当たらず困ったので、同じようなことをやろうとしている特異な人がいたら参考にしてもらえればと。
PHP コンストラクタの検証

<h1>1.constractの挙動</h1>
コンストラクタメソッドはよく使います。
個人的には『一番最初に呼ばれるメソッド』というざっくりした印象でした。
調べたところ、インスタンス化した段階で呼ばれます。

ではまず、シンプルなコードで試してみましょう。

```test_sample.php
<?php

require_once(__DIR__ . '/classTest.php');

$app = new classTest();

?>
```

```classTest.php
<?php

class classTest
{
    public function __construct(){
        echo 'constructメッセージ';
    }

}

?>
```

```
・実行結果
constructメッセージ
```


<h1>2.コンストラクタを親・子クラスで書いたら</h1>
では、親クラスのコンストラクタが呼ばれるか、
子クラスのコンストラクタが呼ばれるか
見ていきましょう。

```test_sample.php
<?php

require_once(__DIR__ . '/classTest.php');

$app = new childClass();

?>
```

```classTest.php
<?php

class classTest
{
    public function __construct(){
        echo '親メッセージ';
    }

}


class childClass extends classTest
{
    public function __construct(){
        echo '子メッセージ';
    }

}

?>
```

```
・実行結果
子メッセージ
```

この結果からわかるように、子クラスのコンストラクトが呼ばれます。
(多分、オーバーライドされてます)
親クラスのコンストラクタは呼ばれません。

実は公式ドキュメントに書いてありましたが、実際に実行しないと納得できないので実行しました。
https://www.php.net/manual/ja/language.oop5.decon.php
```
注意: 子クラスがコンストラクタを有している場合、親クラスのコンストラクタが 暗黙の内にコールされることはありません。 親クラスのコンストラクタを実行するには、子クラスのコンストラクタの 中で parent::__construct() をコールすることが 必要です。 子クラスでコンストラクタを定義していない場合は、親クラスのコンストラクタを継承します (ただし、private 宣言されている場合は除く)。 これは、通常のクラスメソッドと同様です。
```

<h1>3.親クラスコンストラクタを呼びたい</h1>
では、公式ドキュメントの通りにコンストラクタの中で
親クラスのコンストラクタを呼んでみましょう。

```test_sample.php
<?php

require_once(__DIR__ . '/classTest.php');

$app = new childClass();

?>
```

```classTest.php
<?php

class classTest
{
    public function __construct(){
        echo '親メッセージ';
    }

}


class childClass extends classTest
{
    public function __construct(){
        parent::__construct();
    }

}

?>
```

```
・実行結果
親メッセージ
```

これで親クラスのコンストラクタが呼ばれるようになりました。

ちなみに、この場合でも親クラスのコンストラクタが呼ばれます。

```classTest.php
class childClass extends classTest
{
    
}
```

<h1>4.コンストラクタの変数を保存</h1>
うまいタイトルが思いつきませんでしたが、コンストラクタで呼ばれた変数は
その後に別のメソッドで使用可能です。

```classTest.php
<?php

require_once(__DIR__ . '/classTest.php');

$app = new classTest();

$app->message();

?>
```

```classTest.php
class classTest
{
    private $message;

    public function __construct(){
        $this->$message = 'メッセージ';
    }

    public function message(){
        echo $this->$message;
    }

}

?>
```

```
・実行結果
メッセージ
```

では、子クラスでも使えるのか見ていきましょう。

```classTest.php
<?php

require_once(__DIR__ . '/classTest.php');

$app = new childClass();

$app->message();

?>
```

```classTest.php
class classTest
{
    private $message;

    public function __construct(){
        $this->$message = 'メッセージ';
    }

}

class childClass extends classTest
{
    public function message(){
        echo $this->$message;
    }
}

?>
```

```
・実行結果
メッセージ
```

いけました。
VBA テキストファイルを作成し、開いてフォーカスする

貼り付け実行で行ける。

参考URL：
https://excel-ubara.com/excelvba1/EXCELVBA422.html

```vb:
 Function fncMakeAndOpenFile()
 
    Dim fso As Object
    Dim ts As TextStream
    Dim strPathCur As String
    
    strPathCur = ThisWorkbook.path
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set ts = fso.OpenTextFile(strPathCur & "\Temp.txt", ForWriting, True) 
' 追記は「ForAppending」新規は「ForWriting」読み取りは「ForReading」

    ts.Write ("文字列")       ' 文字列の書き込み（複数行は書き込めない）
    ts.WriteLine ("改行付き") ' 最後に改行を付けて書き込み
    ts.WriteBlankLines (3)    ' 空行を指定の数だけ書き込み
    
    ts.Close ' ファイルを閉じる

    Shell "C:\Windows\System32\notepad.exe """ & strPathCur & "\Temp.txt""", vbNormalFocus
        
 End Function
```
Google Chromeのセキュリティバグを報告した話

## はじめに
Google Chromeのセキュリティバグを報告したんですが、日本語で手順を紹介してるやつがないっぽい + issueが一般公開されたので一応備忘録も兼ねて書いておこうと思いました。

Vulnerability Reward Programでお金貰えたの！？って気にする方もいらっしゃる方もいるので先に書いておくのですが、結果的にお金は貰えませんでした。
理由に関しては後述。

今回はたまたま発見した物を報告したので特にバグを発見する手順などは記載していません。

## Vulnerability Reward Programとは
簡単に言うとChromeのバグを報告してお金を貰おう！ってやつです。
ついでに[ここ](https://chromereleases.googleblog.com/2020/02/stable-channel-update-for-desktop.html?m=1)に名前が載ります。
詳しくは[こちら](https://www.google.com/about/appsecurity/reward-program/index.html)

## どんなバグを報告したか
【特定文字を検索するとブラウザがクラッシュするバグ】を報告しました。
詳しくは[こちら](https://bugs.chromium.org/p/chromium/issues/detail?id=1024256)
※ちなみに、issueの中で出てくる[blink](https://en.wikipedia.org/wiki/Blink_(browser_engine))というのはChromeのレンダリングエンジンの事です。

### 報告するにあたって
下記リンクを読みました。
２番目のリンクにSigns A Crash Is Not A Security Bugとの記載があったのですが、DoSによるcrashを対象としているっぽかったのでとりあえず報告しました。

- https://chromium.googlesource.com/chromium/src/+/master/docs/security/faq.md
- https://www.chromium.org/Home/chromium-security/reporting-security-bugs

## バグの報告手順
1. まずは[Reporting a Crash Bug
](https://www.chromium.org/for-testers/bug-reporting-guidelines/reporting-crash-bug)を参考にクラッシュレポートを送信しました。
1. その後は[こちら](https://code.google.com/p/chromium/issues/entry?template=Security%20Bug)から必須項目を入力・再現用のテキストファイルを添付して送信しました。その際、上記で報告したクラッシュレポートのIDを書いておくといい感じっぽいです。また、自分は投稿した後にどのように表示されるかがわからなかったのでREPRODUCTION CASEなどの説明文を消さないで送信したのですが、これは消してから投稿した方がいいかもしれないですね。残ってると見にくいかも。
1. あとは提出した情報でバグが再現できた場合はあれよあれよと修正が進むっぽいです。（自分の場合は一度リリース時期の関係で修正したbranchのMergeがRejectされたりしてるのですが、自分の方では何もアクションを起こしていないが最終的にMergeされた）

## 報告してどうなったか
### CVEについて
[CVE-2020-6404](https://nvd.nist.gov/vuln/detail/CVE-2020-6404)として登録されました

### リリースについて
無事にM80に取り込まれ、リリースされました。

### なぜお金は貰えなかったのか
issueに書いてあるのですが、以前に内部で報告されていたのでrewardの対象にはなりませんでした。。。

## 最後に
今回はSecurityについて報告する専用のリンクからバグ報告フォームに行ったので特にTemplateやSummaryを選択・記載する必要はなかったのですが、一般のバグを報告するときには適切なのを選ばないといけないと思うと結構だるいかもしれないですね。。。
どこかにこういうときにはこれ選んどけ！ってやつはあるんでしょうか？
一般バグを報告する際には類似バグを探す + TemplateやSummaryを何にするかで悩んでなかなか報告が捗らなさそうだなーとか思いました。

結構な量の英語を読むのがダルかった（ほとんど自動翻訳に頼りましたが） + 資料を探す手間が結構かかりましたが、資料を見つけることさえ出来れば報告に関する基本的な内容は記載されているので難易度はそんなに高くないのかなーと思いました。

自分の認識が間違っている箇所があれば教えていただきたいです。

また、拙い文章ですが今後どなたかの役にたてばいいなーと思います。
JavaScriptにもrangeが来るかもって話です

**注: Stage 1なので、この記事のとおり、実装される保証も、そもそも実装される保証もありません。提案されているってだけの話です。**

https://github.com/tc39/proposal-Number.range

というProposalでJavaScriptにNumber.rangeとBigInt.rangeを追加しようという提案がされています。
JavaScriptで連番の配列を作成する関数そのものは存在せず、間接的に生成するしかありません。
関数本来の使い方でないうえ、0からの連番でない場合は少し面倒です。

```javascript
[...Array(5).keys()];//[0, 1, 2, 3, 4]
Array.from({ length: 4 }, (_, i) => i + 1);//[1, 2, 3, 4]
```

いろいろなライブラリにて、そのような関数は用意されています。
ですが、これを標準で用意しようというProposalです。
上記Proposalから引用します。
現状だと、Number、BigIntそれぞれに個別の関数が追加されいます。

```javascript
for (const i of BigInt.range(0n, 43n)) console.log(i) // 0n to 42n

// With iterator helper proposal
Number.range(0, Infinity)
    .take(1000)
    .filter((x) => !(x % 3))
    .toArray()

function* even() {
    for (const i of Number.range(0, Infinity)) if (i % 2 === 0) yield i
}
;[...Number.range(1, 100, 2)] // odd number from 1 to 99
```

**上記の通り、配列でなくイテレーターを返します。**
ですので、配列を生成する関数ではないようです。まぁ、 スプレッド構文を利用することで簡単に配列に変換できます。
また、Iterator HelpersのProposalを利用することで、filterやmapなでの関数も利用できます。

https://github.com/tc39/proposal-iterator-helpers

**範囲ですが、fromを含み、toは含まないという範囲のようです。**

```javascript
[...Number.range(0,10)]//[0, 2, 3, 4, 5, 6, 7, 8, 9, 9]
[...Number.range(0,10,2)]//[0, 2, 4, 6, 8]
[...Number.range(0,11,2)]//[0, 4, 6, 8, 10]
```

## 無限イテレーター

この提案がイテレーターを返す利点として、無限イテレーターがあります。

```javascript
for(const n of Number.range(0, Infinity)) {
    if (n * n > 26) break;
    console.log(n);
}
//0
//1
//2
//3
//4
//5
```

上記のコードのように、事前に列挙の終端が分からない場合に便利です。

## 詳細

```typescript
interface NumberConstructor {
    range(from: number, to: number, step?: number): Iterator<number>
    // If accept Number.range(to)
    range(to: number): Iterator<number>
}
interface BigIntConstructor {
    range(from: BigInt, to: BigInt, step?: BigInt): Iterator<BigInt>
    // If accept BigInt.range(to)
    range(to: BigInt): Iterator<BigInt>
}
```

### 1番目の引数 from
列挙の開始の数字です。**この数字は含まれます。**
また、無限の値はエラーになります。
### 2番目に引数 to
列挙の数字の表示です。**この数字は含まれません。**
**こちらは無限も許可されます。**
1番目の引数>2番目の引数の場合でもstepが-1になることはなく、直後に終了するイテレーターになるようです。
また議論中のようですが、2番目以降の引数を省略した場合、1番目の引数が終端の数字となり、始点が0になるようです。
### 3番目の引数 step
**1回ごとに加算される値です。省略した場合は1になります。**
また、stepというプロパティをもつオブジェクトを渡した場合、そのstepプロパティの値が使われるようです。
また、無限の値もしくは0のときはエラーになります。
## 追加構文

関数だけでなく、構文でも連番が作れるようになるかもしれません。

https://github.com/oauo/Range-Proposal

```javascript
[1..5];// [1,2,3,4,5]
[6..3];// [6,5,4,3]
[..4];// [0,1,2,3,4]
[2..];//[2,1,0]
[1..2..5];// [1,3,5]
[1..2..6];// [1,3,5]
[5..2..1];// [5,3,1]
[6..2..1];// [6,4,2]
[..2..5];// [0,2,4]
[..2..6];// [0,2,4,6]
[5..2..];// [5,3,1]
[6..2..];// [6,4,2,0]
```

多言語でよくある「..」で範囲をつくるやつですね。
こちらは始点、終点ともに含まれるようです。また、無限イテレーターは対応されていないようです。
また、始点、終点ともに省略した場合は0にあるようです。
始点>終点の場合は負の報告に列挙されるようです。
途中に数字を挟むことで、その数字が2番目の値になるような列挙がされるようです。
こちらは別のリポジトリで提案されており、上記のリポジトリのissueにても提案されています。
そのため、上記の提案と仕様に違いがあるようです。
JOI 2006 予選 F 通学経路

##問題
https://atcoder.jp/contests/joi2007yo/tasks/joi2007yo_f
##見た感じ
格子点上で進んでいくという問題で遠回りしないので、以下の漸化式を計算すればよさそう。

```math
dp[i][j]=(1,1)から格子点(i,j)までの工事現場を通らない経路数\\
工事現場を(x,y)とするとdp[x][y]=0でfix\\
dp[i][j]=dp[i-1][j]+dp[i][j-1]\\
dp[1][1]=1
```
##解法
上の漸化式を計算するときに、マンハッタン距離順で計算していけば2重ループで書ける。
##ソースコード
```c++
const int N_MAX=23;
ll dp[N_MAX][N_MAX];
int n,a,b;

ll solve(){
    dp[1][1]=1;
    rep1(i,a)dp[i][0]=0;//rep1(i,a)=for(int i=1;i<=a;i++)
    rep1(i,b)dp[0][i]=0;
    for(int i=3;i<=a+b;i++){
        for(int j=1;j<i&&j<=a;j++){
            if(dp[j][i-j]<0){
                dp[j][i-j]=dp[j-1][i-j]+dp[j][i-j-1];
            }
        }
    }
    return dp[a][b];
}

int main(){
    int i,x,y;
    //入力
    memset(dp,-1,sizeof(dp));
    cin>>a>>b;
    cin>>n;
    rep(i,n){
        cin>>x>>y;
        dp[x][y]=0;
    }
    //処理
    ll ans=solve();
    //出力
    puts(ans);
}
```
asp.net coreでサービス作ったから宣伝兼ねて技術公開する -4.追加開発１（概要）-

##追加でやりたかったこと

どうしてもやりたいことがあり、追加で開発を行いました。
それは、よくシステム開発を行っていると様々なエラーメッセージ等が出てきます。

それを、Googleで検索する際に、画像を見ながらテキストを打つのが結構イヤだったんですよね。

それで、画像ファイルから文字を手軽にOCR出来たらなと。

##追加で作ったもの



まずは見てもらったほうがいいですね。


###1.メニュー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/841ef3a4-4ea1-dabe-94e7-e102280120fc.png)


1.クリップボードに保存してある画像を貼り付ける
2.画像ファイルをアップロードする
3.前回アップロードした画像を開く



クリップボードに保存してある画像ファイルをどうやってアップロードするかがけっこう大変でした。
通常ならまだしも、asp.net coreを使うとまぁまぁめんどくさくて。

それは別途技術説明します。

###2.画像の範囲文字指定
アップロードすると、画面遷移します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/8d518386-610d-64a2-178b-172d25db1c21.png)

ここで、マウスで範囲指定し、Enterすることで指定範囲を OCR をかけられます。

※ 2020/05/23 時点で、横長の画像でしか処理できません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/e5ee63a9-5f57-2402-798a-326fcfdd98ae.png)


###3.OCR結果

切り取られた画像、読み込めたテキストが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/382adca4-3bec-ec40-4926-372b9c03bd74.png)


さらに、Google Vision APIからの戻り値（JSON）も全部出してます。
Google Visionを試してみたい人にはうってつけの機能ですね。
これは自画自賛。


##作った感想

いや、思ったより出来がいいですね。
実の業務でも使えるサービス作ったのは初めてかも？

winアプリはたくさんあるのですが。


それでも作ってよかったと思えるものが出来ました。

まだ横画像しか出来ないのが残念ではありますが、個人的には困ってないので、気が向いたら直します。



----


【是非お試しください】※完全無料です
TanaToru -本棚管理サービス-
　https://app.zero-one-system.co.jp/TanaToru/
Raspberry PIでAmazonのPrime Videoをみる

#きっかけ
RaspberryPI４を多目的に使うため、各OSをインストールしていましたが、
あるUbuntuのOSにインストールされているChromium Media EditionからAmazonのPrime Videoが見れましたので、RaspberryPIの基本OSにインストールはできないかのがきっかけになりました。

いつもデスクトップPCでAmazonプライムビデオを見ていましたので、
電気代がもったいないな～と。W

以下の英語サイトからインストールが可能でした。
他のサイトのVideoも見れますと記載がありますが、私はPrime Videoだけ試してみました。

参照サイト：
[Raspberry Pi Netflix One Line Easy Install – along with Hulu, Amazon Prime, Disney Plus, HBO, Spotify, Pandora, and many others](https://blog.vpetkov.net/2020/03/30/raspberry-pi-netflix-one-line-easy-install-along-with-hulu-amazon-prime-disney-plus-hbo-spotify-pandora-and-many-others/)

#1.Chromium Media Editionのインストールコマンド
```bash
curl -fsSL https://pi.vpetkov.net -o ventz-media-pi
sh ventz-media-pi
```
#①コマンド実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/45b92402-c36a-1930-dfea-8a93e24cb61b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/5f6de4c4-87c8-d382-1d19-0b126c3b1621.png)

#②シェルの中身を確認
※変なスクリプトが含まれてないか確認ためです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/718d14cb-7650-46fd-8324-c9bdcccc137c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/099bf5a3-1009-3846-ac25-68e95260cef7.png)

#2.RaspberryPiを再起動及び確認
①再起動のコマンドを実行。

```bash
sudo reboot
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/05c3b2cf-1e94-65d4-0a30-8599bf82b069.png)

②再起動後、インターネットメニューを確認。

※Chromium (Media Edition)が追加されています。実行し、Amazonサイトにログインしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/b7901d5b-f4c7-14c2-af2d-a639a627d974.png)

#3.AmazonPrime Videoの確認
※『僕らのごはんは明日で待ってる』という映画の再生画面です。W
★VNCからは遅いので直接モニターを繋げてみてください。★
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/162336/aa502005-3ead-21c7-2c2d-b62816630720.png)

#終わりに
これからはRaspberryPiで映画を楽しむことだけです。
普段はFlat環境でWEBサーバとして動いて夜にはAmazonのPrime Videoを見る感じで使い道が増えてきました。
Amazon Linux2 にMySQLを入れる際のエラー

AWS EC2インスタンスにLAMP環境構築する際に、MySQLインストールでエラーに詰まったのでメモメモ。

エラーの原因を結論から言えば、AmazonLinux2にはデフォルトでMySQLは用意されておらず、MariaDBがちょこんと居座ってること。そのため対処として公式ページからMySQLをインストールして、MariDB消せばOKである。

##前提

- Amazon Linux 2 AMI (HVM) SSD Volume Type
- MySQL  Ver 14.14 Distrib 5.7.30, for Linux (x86_64) ←これを入れたい

##過程と対処

EC2インスタンスにssh接続後、ApacheとPHPをyumインストール。問題なく進み、そのノリでMySQLもインストール。

```
yum install -y mysql-community-server
```
ここで`No package mysql-community-server available.`とエラーを返される。どうやらパッケージがないらしい。以下で調べてみると確かに無かった。

```
yum list mysql*
```
そこで、**公式から追加する**ことに(→[MySQL Yum Repository](https://dev.mysql.com/downloads/repo/yum/))。ただしAmazonLinux2はcentOS7ベースということなので、追加するのはel7を選択。

```
 yum install http://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm   
```
ちゃんとリポジトリに追加されてるかを次で確認

```
yum repolist
```
`mysql80-community-release-el7-3.noarch`を確認。使用したいバージョンは5.7なので、5.7を有効化させる必要がある（最新バージョンの8.0のインストールによって旧バージョン5.7のリポジトリもセットでインストールされる)。

```
vi /etc/yum.repos.d/mysql-community.repo
```
mysql-communityのレポジトリ設定をいじる。上のコマンドで設定ファイルを開いたらMysql8.0のenabledの欄を0にして、Mysql5.7のenabledの欄を1に変更する。これによってインストールの方向が5.7に向く。

さて、これで` yum install mysql-community-server `で解決かと思えば、次は依存関係のエラーが発生。エラー文を確認すると`Available: 1:mariadb-libs`の文字列を数件発見。MariaDB...?

どうやらAmazonLinux2（CentOS７も同様）ではMariaDBがデフォルトで入っており、MySQLインストールの際に邪魔になってしまうらしい。今回はMySQL使いたいので、**MariaDBを削除すること**に。

```
yum remove mariadb-libs 
```
これの後にyumインストールしたら無事に解決しました。


##参考
[CentOS 7にMySQL 5.7をyumでインストール]
(https://hepokon365.hatenablog.com/entry/2020/03/20/235538)
[AWS Amazon Linux2にMySQL5.7を構築する](https://qiita.com/himatani/items/e1e650992dbc12b8a9b3)
[Amazon Linux2でmysqlを入れようとしたらエラーが出た](https://qiita.com/shinon_uk/items/488c67836219eb300109)
[パッケージ依存関係を解消する(rpm)](https://qiita.com/happykikaku/items/2395c13b00a334e909ce)
Ｃ言語で全角カタカナを判定する

#いきさつ
コンソールで全角カタカナのみを入力させたいということで作りました。
Shift-JISの文字に対応しています。

**要件**
- ひらがなは全角カタカナに変換される
- スペースは削除する
- ひらがな、全角カタカナ以外の入力はお断りする


※コンパイラにより上手く動作しない可能性があります。
（２バイト文字の格納方法やエンディアンの関係上）

2020/5/24 18:45 修正しました

#コード

```c:main.c
#include <stdio.h>
#include <string.h>
/***********************************************************************************/
/*@fn    : isKatakana                                                              */
/*@brief : 文字列の全角カタカナ評価                                                   */
/*@param : str[] 対象文字列                                                         */
/*@return: str[]が、ひらがな、全角カタカナ、長音記号(ー)のみの文字列の時: 1   それ以外: 0 */
/*@detail: 文字列の中にひらがながあれば、全角カタカナに変換。スペースは消滅する            */
/***********************************************************************************/
int isKatakana(char str[])
{
    int i, j;
    unsigned short* ptr;

    //半角、全角スペースを消す
    for (i = 0; i < strlen(str); i++) {
        //半角スペース削除
        if (str[i] == 0x20) {
            for (j = i; j < strlen(str); j++) {
                str[j] = str[j + 1];
            }
            i--;
        }
        //全角スペース削除
        if (((unsigned char)str[i] == 0x81) && ((unsigned char)str[i + 1] == 0x40)) {
            for (j = i; j < strlen(str) - 1; j++) {
                str[j] = str[j + 2];
            }
            i--;
        }
    }
    //ひらがなをカタカナに変換する
    for (ptr = (unsigned short*)str; ptr < (unsigned short*)(str)+strlen(str); ptr++) {
        unsigned short value;   //２バイト文字の比較用
        char* ch = (char*)ptr;
        if (*ch == 0) break;
        //リトルエンディアンをビッグエンディアンに直す(環境によって変更してください)
        value  = (unsigned short)*ch << 8;
        value += (unsigned short)*(ch + 1) & 0xff;
        //全角ひらがなだったら全角カタカナに変換する
        if (value >= (unsigned short)0x829f && value <= (unsigned short)0x82f1) {
            value += 0xA1;
            if (value >= (unsigned short)0x837f && value <= (unsigned short)0x8395) {
                value += (unsigned short)0x1;
            }
        }
        //全角カタカナ以外の文字が含まれていないかチェック
        if ((value != (unsigned short)0x815b) && (value < 0x8340 || value > 0x8396)) {
             return 0;
        }
        //文字列に再格納(環境によって変更してください)
        *ch = value >> 8;
        *(ch + 1) = (char)value;
    }
    return 1;
}

int main(void){
    char str1[50] = "あどび　イラスト れーたー";
    char str2[50] = "ツイtter";
    if(isKatakana(str1) == 0) printf("カタカナ以外が含まれています。\n");
    else printf("%s\n", str1);
    if(isKatakana(str2) == 0) printf("カタカナ以外が含まれています。\n");
    else printf("%s\n", str2);

    return 0;
}
```

```:出力結果
アドビイラストレーター
カタカナ以外が含まれています。
```
Jenkinsを導入する

#プロローグ

各プロダクトだいたい動物アイコンですが、その中、おじさんのアイコンで有名なJenkisを導入します。
<img width="271" alt="1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/27ce5622-f4bb-46da-6d7b-cf1c5e1aee60.png">

#環境
Windows10 Home 64bit

#手順
[公式](https://www.jenkins.io/download/)へアクセスします。
右上の「Download」ボタンを押下し、ダウンロード画面へ遷移します。
<img width="1128" alt="2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/2ae56cc4-2dc0-c142-c38b-9daf5553fdb1.png">

対象のOSを選択します。
左の2.222.3を使いました。
<img width="1128" alt="3.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/a67a19f0-d518-16d6-1bca-26bb91f5288f.png">

ダウンロードしたmsiファイルを実行します。
「Install」を押下します。
<img width="237" alt="4.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/77422dfc-d5b7-7913-6456-7d57501c5ad3.png">

インストール先を指定します。
<img width="237" alt="5.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/aa77f710-2a9d-4283-07bc-2cdba1a754f3.png">

「Install」を押下します。
<img width="237" alt="6.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/fcc809ce-88e4-3739-2281-b3d4364282dc.png">

「Finish」を押下します。
<img width="237" alt="7.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/2e3248ea-718f-2045-755a-520899677bfa.png">

なんかパスワードを聞かれました。
画面に記載されているファイルを開くと暗号化された文字列があるので、コピーして貼り付け「Continue」を押下します。
<img width="754" alt="8.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/307dfefd-29d9-bce9-34de-d87f05d13331.png">

「Install suggested plugin」のおすすめを選びました。
<img width="755" alt="9.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/6e95fcd0-3817-b127-0b98-99340397b305.png">

しばらく待機します。
<img width="755" alt="10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/4e949927-81a6-0318-5c75-5ded13b65c84.png">

いろいろインストールされています。
<img width="755" alt="11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/5a75c46b-c43e-d2b6-a92e-b1b6ad3ffac8.png">

ユーザを入力し、「Save and Continue」を押下します。
<img width="756" alt="12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/ecb0973d-c19f-83a5-69e5-5dc058c69e4b.png">

IPを指定します。
自身はポート8080は他のサービスで使っているので、8070にしておきました。
<img width="755" alt="13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/4960065e-6a41-7c97-cd73-1060dc8ba11f.png">

「Start Using Continue」を押下します。
<img width="755" alt="14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/0dbab661-6a72-3566-04ad-03c7cbbe092b.png">

画面が表示されたら完了です。
<img width="755" alt="15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/0d003b0a-125f-6096-5463-052eb803874d.png">

#使わなかったら止めておく
自動でサービスが起動したので、使わなかったら止めておきます。

```
C:\Program Files (x86)\Jenkins>jenkins.exe stop
2020-05-24 00:04:36,955 INFO  - Stopping the service with id 'Jenkins'
```
韻を扱いたいpart3

##__内容__
前回の流れで、MeCabをもう少し活用したい。分かち書きでは細分化され過ぎていた。MeCabを用いて分節分けのようなことを行っていく。CabochaやKNPがあるよーっていうのは知らないこととする（何度でも言うぞ、~~黄色いB-boy~~折角のMeCabを使いたいのだ）。形態素解析は使っていないので、形態素解析して付属語（助詞、助動詞）は前の言葉にくっつけるという方針でやってみる。
##__付属語の連結__
結果から言うとMeCabは使わなかった。表層形と品詞だけが必要なので、janomeの方が簡潔と判断した。~~ただ、MeCabでも色々試し、DataFrameに入れる記事とかも読み、for分で変に回してしまいメモリーエラーにもなったので、そこそこ楽しめた~~
下記のコードで付属語を連結することによって、分割された言葉の長さが平均2.96となった（分かち書きでは2.16）。

```python
from janome.tokenizer import Tokenizer

with open("./gennama.txt","r") as f:
    data = f.read()
    
tokenizer = Tokenizer()
tokens = tokenizer.tokenize(data)

surface_list = []
part_of_speech_list = []
for token in tokens:
    surface_list.append(token.surface)
    part_of_speech_list.append(token.part_of_speech.split(",")[0])
    
text_data = []
for i in range(len(surface_list)):
    if part_of_speech_list[i] == "記号":
        continue
    elif part_of_speech_list[i] == "助詞" or part_of_speech_list[i] == "助動詞":
        row = text_data.pop(-1) + surface_list[i]
    else:
        row = surface_list[i]
    text_data.append(row)
```

これで前回のように、入力データにどの母音の並びが多いかの順位付けし、それが含まれている言葉を出力させた。出力結果は分かち書きの時より多くなったが、実用性は見いだせていない。やはりN-gramが現状最適である、語順も残り、本来区切らないところで区切るため、繋げれば韻というのも検出できる。
ここであることに気付く。N-gram前に漢字をひらがな…もとい、漢字を読みへ変換しておけばN-gramのバリエーションが増えそうだ。（~~漢字をひらがなはkakasiで出来てしまう~~）そういえば、先程MeCabで形態素解析したときに、「読み」の項目があったぞ。MeCabを使おう。
##__読み方のデータへ変換__
```python
import MeCab

with open("./gennama.txt","r") as f:
    data = f.read()

yomi_data = ""
mecab = MeCab.Tagger("-Ochasen")
lines = mecab.parse(data).split("\n")
for line in lines:
    if line.split("\t")[0] == "EOS":
        break
    else:
        yomi_data += line.split("\t")[1]        
```

「下町」→「したまち」→「iaai」となり、４母音を４文字で表せている。では、「瞬間」→「しゅんかん」→「ua」のような場合はどうだろう？２母音を５文字で表すこととなっている。読み方でN文字分割すれば「下/町」しか出来なかったところが「したま/ち」なども可能になる。しかし、「しゅんかん」は無駄に長くなってしまう。では、母音データにした後にN-gramを使用するか？そのデータにインデックスを割り当てたところで表層形が取り出せない。「下町」の「aa」の並びが検出されないことを良しとは出来ない。改良案はすぐ思いつかないが、ここはよく考えたい。
##__今後の方針__
一つはスコアの付け方を色々加算するのも良いかもしれない。例えば、子音を残しても合致していたら加算するなど、複数のスコアを合算するようなやり方もアリだ。それであれば、「冷蔵庫」を（レイゾウコ、レーゾーコ）のような扱いも可能と思われる。
もう一つは、ノードに分割したwordを、エッジにscoreを用いてグラフを描写してみようと思う。実は、分割方法がスペース区切りしか出来ない時にやってみたのだが、（媒介中心性にテーマが来るのでは？予想で）思った結果にならなかった。`networkx`を一から勉強し直してみようと思う。(~~次に投稿する日がいつになるか不安だ。ただ、検索エンジンの勉強をしていてPageRankや単語の距離のスコアの合算を見て、そのやり使えるかも？と思えたので、勉強します~~)
Spring Security loginページにcss適用できない(MIME type ('text/html') is not a supported...)

## Spring Securityを使用してloginページでcssを適用とした際に以下エラーが発生

```:console
Refused to apply style from 'http://localhost:8080/login' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
```

```html:login.html
<!DOCTYPE html>
<html lang="ja" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <link th:href="@{/css/public/login.css}" rel="stylesheet" />
```

`type="text/css"`は不要だが念のため指定したりしても変化なし。
パスのエラーでもない。(ファイル名が間違っていてもこのエラーは出ます）
と少し悩んでいたところ・・・・

## 結論

Spring Securityでアクセス制限の対象になっていた。
セキュリティ対象外に追加してあげるとうまくいく。

```kotlin:SecurityConfig.kt
@Configuration
@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {

    override fun configure(web: WebSecurity) {

        // セキュリティ設定無視の設定
        web.ignoring().antMatchers(
                "/images/**",
                "/css/**"  // ←これを追加して解決
        )
    }
```
バネマス系を中央差分で陰解法で解きたい。

計算したい微分方程式

```math
m\ddot x+c\dot x+kx=F\left(t \right)
```
##中央差分の公式

```math
\ddot x=\frac{x^{n+1}-2x^{n}+x^{n-1}}{dt^2} \\
\dot x=\frac{x^{n+1}-x^{n}}{dt}
```

##代入したら

```math
m\frac{x^{n+1}-2x^{n}+x^{n-1}}{dt^2}+c\frac{x^{n+1}-x^{n}}{dt}+kx^{n+1} =F^{n+1}
```

右辺には$x^{n+1}$が未知数 
外力Fが$ A\sin\left( 2\pi \omega t \right)$みたいな$t$さえわかれば出てくるものとかなら$x^{n+1}=$の形にすれば求まる。

外力Fが、$F\left(t,x,\dot x,\ddot x\right)$で中身が特に変な関数が入ってくると単純には解けなくなる。

教科書には、「両辺に未知数があるので解けば答えが求まる」みたいにサラっと書いてることが多いが、「そこのやり方を教えてよ」って感じになってる。

##newton raphson法

ニュートン ラフソン法の一般的な式は以下 詳しくはwiki見て

```math
x_{i+1}=x_i-\frac{f\left(x_i\right)}{f'\left(x_i\right)}
```

求めたいものは以下　右辺の$F^{n+1}$を左辺に持ってきて$=0$にしただけ。

```math
f\left(x^{n+1} \right) = m\frac{x^{n+1}-2x^{n}+x^{n-1}}{dt^2}+c\frac{x^{n+1}-x^{n}}{dt}+kx^{n+1} -F^{n+1} =0
```

$f\left(x^{n+1} \right)$が0になる$x^{n+1}$を求めたい。

Newton Raphson法の公式をみると、${f'\left(x^{n+1}\right)}$が必要になる。関数$f$の$x^{n+1}$の微分ってこと。
$x^{n},x^{n-1}$はただの定数だから消える。

```math
{f'\left(x^{n+1}\right)} =\frac{m}{dt^2} + \frac{c}{dt}+k -\dot F^{n+1} \left(x^{n+1} \right)
```

外力 $F'^{n+1}\left(t+dt,x^{n+1},\dot x^{n+1},\ddot x^{n+1} \right)$とかどうしよう・・・・

今回は確認のためだから一定力として、微分したら0になるものを使う。
外力 $F'_{i+1}\left(t,x_i,\dot x_i,\ddot x_i \right)$がマジで非線形すぎて微分出来ない時に無理やり求める方法はそのうち。

これを繰り返していって、$x_i$と$x_{i+1}$が変化しなくなるまで繰り返す。


##初期値計算
あるステップでの$x^{n+1}$を求めるために$x_{i=0}^{n+1}$を仮置しなければならない。


```math
m\frac{x^{n+1}-2x^{n}+x^{n-1}}{dt^2}+c\frac{x^{n+1}-x^{n}}{dt}+kx^{n+1} =F^{n}
```

右辺の$F^{n+1}$を$F^{n}$にして、陽解法的に$x^{n+1}$を求めて初期値にする。

```math
x^{n+1}_{i=0}=\frac{F^n-m\left(\frac{-2x^n+x^{n-1}}{dt^2}  \right) -c \left(- \frac{x^n}{dt} \right)     }{ \left(\frac{m}{dt^2}+c+k   \right)}

```

##初期値の次の計算
ニュートン・ラフソン法の次の計算は、公式を再度みてみると以下なので

```math
x_{i+1}=x_i-\frac{f\left(x_i\right)}{f'\left(x_i\right)}
```

以下のような形になって、繰り返し計算をする。

```math
x_{2}=x_1-\frac{f\left(x_1\right)}{f'\left(x_1\right)}
```
$x_{i}$と$x_{i+1}$の値が変化しなくなったら$x^{n+1}$して、また連立方程式を解く。

一般的には、0.000001くらいまでやるかな。
JSライブラリでAbemaTVとかニコ生をダウンロードしてみた

こんにちは。ひさしぶりです。 

以前にはてなでAbemaTVが落とせなくなった〜！とかやり方見つけた！とか言うことを書いてたんですけど暇なんでqiitaにも書きます。

## Windowsでの操作方法は以下リンクを参照。
https://0115765.com/archives/64

ざっと大まかに言うとminyamiっていうnodeライブラリを使います！以上！


※**今はこの方法以外ではDLできない**。(当方調べ)


## minyamiをぶち込む

とりあえずjsのパッケージ管理ツール「npm」でインストール。
（グローバルのほうがおすすめ。）

```Ruby:terminal
npm install -g minyami
```

## Chrome拡張機能を入れる

今回は拡張機能でhlsのリンクをゲットする。（便利！）

https://chrome.google.com/webstore/detail/minyami/cgejkofhdaffiifhcohjdbbheldkiaed

## あとはDLするだけ。

Abemaのページを開いて、minyamiのマークをクリック。
![20200104013519.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/7b536554-f6f9-8720-b27b-7ac95cbeabba.png)
適当な解像度を選びコピー。
![20200104013516.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/855c93ed-6f15-5531-7b73-ac8e93d783bd.png)

あとはターミナルにそのまま貼り付ける。
![20200104013559.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/4746bce6-c065-295c-8d4e-a123af35f718.png)

結構早く終わるよ。
![20200104013546.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513165/cf680dc0-1045-89f6-3068-81ba3fd6c90a.png)


##スマホでできんのかコラァ！？
→**できます**

◆必要なもの◆
・**VPS**
・JuiceSSH（Android用SSHターミナル。iOSはしらん。ggrks）
・KiwiBrowser（スマホ上で拡張機能が使える神ブラウザ。）
これさえあればできます。

結構便利ですからぜひお試しください！！

**【注意】**
ダウンロードしたファイルは必ず個人利用にとどめてください。またダウンロードしたファイルには著作権[保有](http://d.hatena.ne.jp/keyword/%CA%DD%CD%AD)<span style="color:#000000">者様</span>のコンテンツが含まれる場合があるため他人への譲渡賃貸などは[著作権法](http://d.hatena.ne.jp/keyword/%C3%F8%BA%EE%B8%A2%CB%A1)に抵触する恐れがあります。また一切の責任を負いかねます。また、この方法は技術的保護手段の回避には当たりません。
oracle procedure いろいろ

ただのメモとリンク集です。

1. [SQL*Plusで結果の前後に出力される空行を削除する方法](http://site.m-bsys.com/db/sqlplus-hidden)
2. [SPOOLで不要な空行を出力させない](https://kozirefer.com/sql-0032/)
3. [sqlplus WHENEVER SQLERROR を検証](http://niwanos.hatenablog.com/entry/20100825/1282724361)
4. [表作成、変更など](https://oracle-chokotto.com/ora_table.html)
5. [【シェルスクリプト】IFSで区切り文字（デリミタ）を変更する方法](https://www.server-memo.net/shellscript/ifs.html)
6. [Bashでコマンドライン実行結果を空白区切りで配列に入れる](https://qiita.com/katoken-0215/items/eee2755b4036ba5ebbd2)
7. [PL/SQL EXCEPTION (例外)](http://itref.fc2web.com/oracle/plsql/exception.html)
8. [PL/SQL EXCEPTION (例外)本家](http://otndnld.oracle.co.jp/document/products/oracle10g/102/doc_cd/appdev.102/B19257-01/errors.html)

WHENEVER SQLERROR EXIT SQL.SQLCODE 時のsqlplusの戻り値は、sqlcode mod 255 で設定せれることですね。

```sql
WHENEVER SQLERROR EXIT SQL.SQLCODE
select mod(6550,256) from dual;
```

そして、考えた良さそうなコード（無名ブロック）

```sql
SET SERVEROUTPUT ON

SET LINES 100
SET PAGES 0
SET HEADING OFF
SET TRIMSPOOL OFF
SET FEEDBACK OFF
SET ECHO OFF
SET RECSEP OFF

WHENEVER SQLERROR EXIT SQL.SQLCODE
WHENEVER OSERROR  EXIT failure

variable retcode number
variable upd_count number

declare
	dd date;
	cnt number;
begin
	:retcode := 0;
	select sysdate into dd from dual;
	select to_number(EMP_ID) into cnt from EMP where 1=1 and rownum=1;
	:upd_count := 0;
	FOR i IN 1..30 LOOP
		:upd_count := :upd_count + 1;
	end loop;
	
	/*dbms_output.put_line(cnt);*/
	if cnt = 9 then
		/*dbms_output.put_line(cnt);*/
		cnt := cnt / 0;
	end if;
exception
	when others then
		:retcode := 255;
end;
/

SET TERMOUT ON
print :upd_count

exit :retcode
```

一応動くし、shell から結果を取れる。

以上。
ゼロから始めるLeetCode Day34「118. Pascal's Triangle」

#概要
海外ではエンジニアの面接においてコーディングテストというものが行われるらしく、多くの場合、特定の関数やクラスをお題に沿って実装するという物がメインである。

その対策としてLeetCodeなるサイトで対策を行うようだ。

早い話が本場でも行われているようなコーディングテストに耐えうるようなアルゴリズム力を鍛えるサイト。

せっかくだし人並みのアルゴリズム力くらいは持っておいた方がいいだろうということで不定期に問題を解いてその時に考えたやり方をメモ的に書いていこうかと思います。

[Leetcode](https://leetcode.com/)

[ゼロから始めるLeetCode 目次](https://qiita.com/KueharX/items/6ee2502c3b620c795b70)

前回
[ゼロから始めるLeetCode Day33「1. Two Sum」](https://qiita.com/KueharX/items/fed16d68247ffbc2796c)

基本的にeasyのacceptanceが高い順から解いていこうかと思います。

[Twitter](https://twitter.com/kueharx)やってます。

# 問題
[118. Pascal's Triangle](https://leetcode.com/problems/pascals-triangle/)

偶然YouTubeでこの問題をJavaで解いてるのを見たので私も解いてみようと思いました。

難易度はEasyです！

問題としては、自然数である`numRows`が与えられるので、例のようなパスカルの三角形を作ってください、という問題です。

```
Input: 5
Output:
[
     [1],
    [1,1],
   [1,2,1],
  [1,3,3,1],
 [1,4,6,4,1]
]
```


# 解説

最初と最後に1を入れることは確定しているので、予め1を挿入した状態を用意してあげて、処理の最後に再び1をappendしてあげれば良さそうです。
問題はどういう風に上位の数字の和を計算し、挿入するかについてですが、forループを二重に回せば二つ分の要素を取得し、足すことが出来そうですね。
なお、今回は`numRows`が0と1の場合は例外として除外するような書き方をしました。
こうすることで、3段目からの処理のみを書けば良いのでより読みやすいと思います。


```PYthon
class Solution:
    def generate(self, numRows: int) -> List[List[int]]:
        if numRows == 0:
            return []
        elif numRows == 1:
            return [[1]]
        
        triangle = [[1]]
        
        for i in range(1,numRows):
            row = [1]
              
            for j in range(1,i):
                row.append(triangle[i-1][j-1] + triangle[i-1][j])
            
            row.append(1)
            triangle.append(row)
            
        return triangle
# Runtime: 28 ms, faster than 73.84% of Python3 online submissions for Pascal's Triangle.
# Memory Usage: 13.8 MB, less than 7.14% of Python3 online submissions for Pascal's Triangle.
```

はい、こんな感じになりました。

こっちの書き方の方が良いよ！とかこの言語で書いてみたよ！とかがあれば是非コメントしてみてください。
rails で特定のカラムの確認の仕方



最近オリジナルアプリを作る中で、モデル内のカラムを効率よく検索する方法を探していました。

```ruby

#コンソールを開く
$ rails c

```

```ruby
#調べたいモデル
User.columns
```

こっちの方が、わかりやすい。

```ruby
User.column_names
```

これから沢山お世話になりそう。
Django2.0系のインストールに詰まった話【初学者が参考書片手にpython学習】

## はじめに
[大高隆・著「動かして学ぶ！Python Django開発入門」](https://www.amazon.co.jp/dp/B07YY5RDPC/ref=cm_sw_r_tw_dp_U_x_TCsYEbRH6SF0V)を使用して
python・Djangoの学習を始めた初学者です。

ruby・railsを使用して4ヶ月ほどプログラミングの勉強をしていましたが、
エンジニア転職にあたり、pythonを使用することになったのでこの本を片手に勉強を始めました。

ド級の素人なので、補足・ご指摘等コメントいただけると大変助かります。

## 概要
**【参考書該当箇所】**
Chapter4 04 Djangoをインストールする(Kindleの位置No.1950-1951)

**【詰まった点】**
python仮想環境作成後、Djangoを参考書の指定コードにてインストールしようとしたところ、エラー発生。

**【指定コード】**

```terminal
$ pip install django==2.2.2
```

**【エラー内容】**

```
DEPRECATION: Python 2.7 reached the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 is no longer maintained. A future version of pip will drop support for Python 2.7. More details about Python 2 support in pip, can be found at https://pip.pypa.io/en/latest/development/release-process/#python-2-support
Defaulting to user installation because normal site-packages is not writeable
ERROR: Could not find a version that satisfies the requirement django==2.2.2 (from versions: 1.1.3, 1.1.4, 1.2, 1.2.1......)
ERROR: No matching distribution found for django==2.2.2
```

## 考察
ほう、どうやらpython2系は終わりを迎えたようだ。（それすら知らなかった...）
文献内にも以下のような記述を発見。
>Pythonのバージョンは大きく2系（2.X）と3系（3.X）に分かれます。この２つは大きく仕様が異なり、2系ではDjangoのバージョン2.0以降が動きませんので必ず3系のバージョンをインストールしてください。

ちなみにバージョン指定をしないでDjangoをインストールすると、、、

```terminal
$ python -m django --version
1.11.29
```
そりゃそうだ。python2系じゃDjango2.0以降は動かないって書いてあるし。

あれ、でもpython3ってインストールしたことない？２系なの？？

```terminal
$ python --version
Python 2.7.16
```

...(^ω^)？

```terminal
$ python3
Python 3.7.7 (default, Mar 10 2020, 15:43:33) 
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```
...(^ω^)？？？？？？？
何が起きていることやら。

## 解決策
pip3にてコマンドを実行したところ、

```terminal
$ pip3 install django==2.2.2
```

同じように、**python**ではなく、**python3**でバージョンを確認したところ、

```terminal
$ python3 -m django --version
2.2.2
```

上手くできたみたいです。よかったよかった。

## 仮説
ちなみに上記、**python**でバージョン確認をすると、

```terminal
$ python -m django --version
1.11.29
```

となりました。

ポイントとしては、
・python両バージョンとも環境としてはあるよ
・[python2.7 → Django1.11.29],[python3.7.7 → Django2.2.2]がそれぞれ対応しているよ
・python2系下ではDjango2系は動かないからpython3系下でインストールしてね
ということだったのだろうか。

どうやら調べてみると、macだとpython２.７がデフォルトらしい。
>macOSには最初からバージョン2系（2.X）のPythonがインストールされていますがDjango2.0以降には使えないので別途バージョン3系（3.X）をインストールする必要があります。
(Kindle の位置No.1879-1880)

よく読むとちゃんと文献にも書いてありました。


ということで、下記を参考にバージョン変更をするのが良いのかな？
・[MacにPython3をインストールしようとしたら2.7だったのでバージョン変更したよ](https://qiita.com/takeruw/items/3540c1c618d5459195ad)

・[【Mac】Python のデフォルトをPython 2.7.xからPython 3.x.xにきちんと切り替えるんだ！戻してたまるか](https://dev.classmethod.jp/articles/python-path-settings/)



もし、間違ってるぞ！！という場合は、教えていただけると大変ありがたいです。


## 参考文献
- [大高隆・著「動かして学ぶ！Python Django開発入門」](https://www.amazon.co.jp/dp/B07YY5RDPC/ref=cm_sw_r_tw_dp_U_x_TCsYEbRH6SF0V)
RX65N版GR-CITRUSからFRAMをアクセスする

RX65N版GR-CITRUSとFRAMブレイクアウトボード
---
![2020-05-23 23-05-41.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624954/d232cb9d-c3ce-1f66-efc2-0e6141c73fdc.jpeg)

RX65N-2MBに貼り替えたGR-CITRUSのArduino環境を作成しているのですが、SPI経由のSDカードの通信がうまくいかないためSPI通信の確認がしやすそうなFRAMの組み合わせで通信を試みました。

https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=EEHD-4WYX

Adafruit社がリリースされているArduino向けのサンプルコードがArduiuno UNO R3で動くことをまず確認しました。

https://learn.adafruit.com/adafruit-spi-fram-breakout/wiring-and-test

続いてGR-CITRUS(RX65N-2MB)のWebコンパイラ環境で同ライブラリをコンパイルしたのですが、二点ハマるところがありました。

SPI.hの修正点
---
Adafruit_FRAM_SPI.cpp/hはAdafruit社が独自に作成したAdafruit_SPIDevice.cpp/hとlib下のSPI.cpp/hを両方とも参照するのですが、GR-ROSEのArduinoライブラリのSPI.hで存在自体が消されている関数transfer(引数が2つ版)を参照しておりエラーの原因となっていました。今回はSPIのアクセスで使用しないため空の関数としましたが、他のデバイスを使用した時に具体的に関数の内容の定義が必要となりそうです。

```SPI.h
#ifndef __RX600__
  inline static void transfer(void *buf, size_t count) {
　　//（略）
  }
  
//Add for GR-CITRUS_D (Adafruit lib need this  200523)
#else
  inline static void transfer(void *buf, size_t count) {
    /*
    */
  }
#endif //__RX600__
```

Adafruit_SPIDevice.hの修正点
---

こちらは難しくないのですが、マイコンのdefineでMSB/LSBFIRSTの記述が切り替えられている箇所でルネサスのMCUの定義がないためエラーとなります。下記の定義を追加すればいいのですが、後発のSONYのSPRESENSEの定義が普通にあるのでこの辺は企業努力の差が出ています。

```Adafruit_SPIDevice.h(記述追加)
typedef enum _BitOrder {
  SPI_BITORDER_MSBFIRST = MSBFIRST,
  SPI_BITORDER_LSBFIRST = LSBFIRST,
} BitOrder;
```

感想
---
SPIの通信が確認できたためSCI,I2C,DIO,AIO含め各端子の機能確認は残すはIntのみとなりました。
FRAMでいえば大容量(4Mb程度)のFRAMのディスクリート版が近々出るということで、RX65Dと組み合わせた活用を考えていきたいところです。
初心者の単語Ｎｏ5（デバッグとブレークポイント）

##デバッグ
バグ・欠陥を発見・修正し、動作を仕様通りにするための作業

####デバッグの基本的な手順
**1.バグの存在を認識**
**2.バグの発生源を分離**
**3.バグの原因を特定**
**4.バグの修正方法を決定**
**5.修正し、テスト**
１は特定可能な容易なバグと不特定の条件が発生し始めてわかるバグがある。
（例外処理や実行時エラー、コンパイルエラーなど様々な形で認識することが出来るからだ。）

２は分かりにくいものと分かりやすいものがあると思っている。
（コンパイルエラーなどで発生場所が特定できるものと、発生場所が把握できているが実際の原因が別にある場合がある）
３は2で発生源を分離した原因を特定しやすいものはすぐに解決できるが、特定しづらいものだと時間が掛かると思う。

４は開発によっては周囲に相談したり規約に順守することで解決しやすい。
（自宅で自己啓発の場合はＷｅｂを参考にしたり、質問板などで解決などができる）
５は動作確認し、その上でバグがあるようなら1から4を繰り返し行う。
※テストケースやテストは多種多様なものがある為、いつか纏めて記載する予定。

###ブレークポイント
プログラム開発のデバッグで必須となるデバッグ機能。
この機能を使用することで、素早いバグ調査や処理のトレースを可能にする。

このブレークポイントの特性として、設定した場所で処理を一時停止させる事。
※この際に宣言している変数の値のチェックや、1命令ずつ実行してトレースをするなどメリットは色々ある。
(但しブレークポイントは必ず処理が来ないと止まらない為、注意が必要。設定しても止まらない事は多々ある)
【備忘録】HTMLのテンプレート

単独のHTMLのテンプレートです。
時々バージョンアップしたり追加したりします。

# ソースコード
## 汎用版
```html:index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<title>...</title>
<link rel="stylesheet" href="./style/basic.css">
</head>
<body>

<script src="./script/basic.js"></script>
</body>
</html>
```

```css:basic.css
html, body {
  width: 100%;
  height: 100%;
  margin: 0px;
  overflow: hidden;
}
```

```javascript:basic.js
"use strict";
```

## JavaScriptの名前空間
```javascript
((global)=>{
    // 名前空間環境
    const jp      = global.jp || {};
    const module  = jp.hoge   || {};

    /** 公開関数 */
    const publicMethod = function() {
    };
    module.publicMethod = publicMethod;

    /** 非公開関数 */
    const privateMethod = function() {
    };
})(this);
```
```javascript
jp.publicMethod(); // 呼出可
jp.privateMethod(); // 呼出不可
```


## 過去のバックアップ
<details><summary>...</summary>

### Vue.js（CDN）版

```html:index.html
<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<title>...</title>
<link rel="stylesheet" href="./style/basic.css">
</head>
<body>
<div id='app' style="display:none">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script src="./script/basic.js"></script>
<script>
const vm = new Vue({
  el: '#app',
  data: () => ({
  }),
  methods: {
  },
  mounted() {
    document.getElementById('app').style.display = "block";
  },
});
</script>
</body>
</html>
```

### Vue.js ＋ ElementUI（CDN）版

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8" />
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
<meta name='viewport' content='width=device-width, initial-scale=1' />
<title>...</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<link rel="stylesheet" href="./style/basic.css">
</head>
<body>
<div id='app' style="display:none">
  <el-container>
    <el-header>
    </el-header>
    <el-main>
    </el-main>
    <el-footer>
    </el-footer>
  </el-container>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script src="https://unpkg.com/element-ui@2.13.2/lib/index.js"></script>
<script src="https://unpkg.com/element-ui@2.13.2/lib/umd/locale/ja.js"></script>
<script src="./script/basic.js"></script>
<script>
ELEMENT.locale(ELEMENT.lang.ja);

const vm = new Vue({
  el: '#app',
  data: () => ({
  }),
  methods: {
  },
  mounted() {
    document.getElementById('app').style.display = "block";
  },
});
</script>
</body>
</html>
```
</details>
【Laravel】マイグレーションコマンド

# コマンド集

#### migrationファイル作成
```
php artisan make:migration create_xxxxx_table
```

#### migrate
```
php artisan migrate
```

#### migrate ＆ seed
```
php artisan migrate --seed
```

#### migrate やり直し
```
php artisan migrate:refresh
```

#### migrate やり直し ＆ seed
```
php artisan migrate:refresh --seed
```
#### DBリセット
```
php artisan migrate:reset
```
【学習メモ】AWS（基礎知識　初期設定）

##1.導入

【インフラ構築の設計の考え方】
①サーバーの構成
- サーバーのOSをインストールし設定
- 必要なソフトウェアをインストールし、設定

②ネットワークの構成
- 構築したサーバーをネットワークに接続する
- ネットワークで使用するIPアドレスの範囲を決める
- サーバーにIPアドレスを割り当てる
- ドメイン名とIPアドレスの対応を割り当てる

【インフラとは？】
インフラ：サーバーやネットワーク（＝システムやサービスの基盤となる設備）

サーバー：CLTに対してサービスを提供するコンピューター

コンピューター：データベースサーバー、Webサーバーなど役割ごとに機能を提供するコンピューターのこと

ネットワーク：複数のコンピューターをつないで、データを送受信できるようにするもの

クラウド（＝クラウドコンピューター）：ネットワークを利用してコンピューターリソースを利用する形態

Cf.オンプレミス⇆クラウド


#2.AWSの初期設定

【AWSの特徴】
①サービスが豊富
- EC2、RDSなど100以上のサービスが存在している
- 高負荷に耐えられる信頼性の高いシステムを少ない手間で運用できる
②リソースが柔軟
-　リソースを必要な時に必要な分だけ使える
③従量課金

###初期設定

【料金アラートの設定】
・請求ダッシュボードで請求アラートを受信するよう設定

・CloudWatchで料金アラートを設定する

【IAMで作業用ユーザーを作成】
・ルートユーザーでは、アドレス変更などでのみ使用すること

**CloudTrail**
＜目的＞
いつ誰が何をしたのか記録することで、不正アクセスや不正操作が会った時にチェックするため

＜設定方法＞
CloudeTrailで証跡を作成し、S3にログ保存

＜サービスの概要＞
AWSユーザーの操作を記録するサービス
いくらか料金かかるため導入は後ほど
CDIの勉強（その２）


[前回](https://qiita.com/yasu-suge/items/173dc8273c1575f1e1a0) の記事の続きです。

### CDIの勉強（その２）

#### @Qualifierによる実装の指定

自分の場合、デプロイ時にエラーは生じず、そのままサーバー起動ができました。
よく調べてみると、Servletの @Inject アノテーションの部分で、以下のようなワーニングが出ていることに気づいた。
「Multiple beans are eligible for injection to the injection point [JSR-365 §5.2.2]」

ググってみると、どうやら インストールしている JBoss ToolsのCDIバリデーションツールが警告を出していることが分かった。

日本語に訳すと、「複数のBeanが注入ポイントへの注入の対象となる注入点に存在します。」とでも訳されるのでしょうか。

https://docs.jboss.org/cdi/spec/1.0/html/injectionelresolution.html

ここの部分について、わかりやすい解説がQiitaのこのページにありました。

https://qiita.com/nifram/items/77eda1b01d7d4a6cf1db

組み込みの限定子については、省略。

#### @Producesの使い方

動的に Hello の適切な実装クラスを返してくれるようにする機能のために使用します。
こっちの方が分かりやすかったです。

#### @Alternative の使い方

代替のBeanとして、Mock用のBeanを使うやり方。
@Alternative をBeanの宣言をすることにより、代替のBeanであることを指し示し、
bean.xml にて、その使用を宣言する。@Producers が動的なBeanの入れ替えだったが、
この例の場合は、外部設定によるBeanの入れ替えが可能となる。

![2020-05-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/292074/baf0d1be-e015-cd4d-85f9-46435437d08b.png)

この機能を使うことで、呼出元の単体テストを簡単に実装することが可能なことに気づいた。
また自身の機能を作成する場合においても、機能を構成するための様々なサービスを提供するBeanで構成し、その実装についても、小さな機能を積み重ね、また階層化することにより、自身の単体テストも簡単に実装することができそうだ。

[次の記事](https://qiita.com/yasu-suge/items/c26f8d8772c349ac8472)