OmniAICreator/Qiita-1.07M huggingface dataset:
フラットphpをテストする

### まえがき

phpunitを用いればphpのテストで困ることはありません。

![今夜までだ](https://ctrlzr.sakura.ne.jp/img/ameblo/konya.gif)
**ただし、今夜までだ！**

テスト対象はフラットphp。classもvendorもなく、DBアクセスもありません。
もちろんcomposerも使用していません。

```ruby:テスト対象のphp
<?php
namespace honya;

[$status, $res] = fncHonya();

header('HTTP/1.1 '.$status);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($res);

function fncHonya(){
  // ちょこっとビジネスロジック
  return [200, ['result'=>'ok']];
}
```

### phpunitはフラットphpをテストできない！

初めて知りました。フラットphpで開発したことがなかったので。
テストコードを作る方が面倒でしたが、知恵を絞ってテストできるようにしてみました。

##### 元のファイル構成：
app
└ honya.php


##### テストできるようにしたファイル構成：
app
└ honya.php
└ compser.json
└ phpunit.xml
└ tests
　└ HonyaTestClass.php
　└ HonyaTest.php
　└ fixtures

### テスト用classを作る

HonyaTestClassを作成し、honya.phpをrequireしたメソッドを作成しました。

ポイントは３点

- namespace 
- @runInSeparateProcess
- ob_start、ob_get_clean

```ruby:テスト用class
<?php
namespace honya;

class HonyaTestClass {

	private $header = [];
	private $http_status = null;
	private $body = null;

	/**
	 * @runInSeparateProcess
	 */
	public function request(){
		ob_start();
		require 'honya.php';
		$this->body = ob_get_clean();
		$this->http_status = http_response_code();
		$this->header = xdebug_get_headers(); //@TODO php7 xdebug
	}

	public function getHttpStatus(){ return $this->http_status; }
	public function getHeader(){ return $this->header; }
	public function getBody(){ return $this->body; }
}
```

namespace はテスト時に必要と分かりましたが、実際は不要です。
性能に影響がないので入れました。
echo で bodyを返すため、ob_start、ob_get_clean で echo 出力を奪い取っています。
@runInSeparateProcess を付けることでphpunitに邪魔されず、テスト対象の echo だけ取得できます。
header は header_list() で取得できないので（原因不明）、xdebug_get_headers() を使用しています。php5では機能しましたが、php7では機能しません（原因不明）

### テストを作る

classさえ作ればテストコードは普通です。

```ruby:HonyaTest.php（テスト本体）
<?php
namespace honya;

require_once 'tests\HonyaTestClass.php';
require_once 'tests\HonyaTestUtil.php';

class HonyaTest extends \PHPUnit\Framework\TestCase {

    use HonyaTestUtil;

	/** @runInSeparateProcess */
	public function test1() {

		$body = 'honya body';
		$this->init_function(200, $body);

		$_POST['honya_param1'] = 'honya1';
		$_SERVER['REQUEST_URI'] = '/honya';

		$clazz = new \honya\HonyaTestClass();
		$clazz->request();

		$this->assertEquals('honya2 body', $clazz->getBody());
		$this->assertEquals('200', $clazz->getHttpStatus());
// 		$this->assertSame([], $clazz->getHeader()); //@TODO php7 xdebug
	}
}
```

### テスト用utilを作る

ポイントは２点

- namespace 
- trait


```ruby:HonyaTestUtil.php（）
<?php
namespace honya;

use phpmock\phpunit\PHPMock;

trait HonyaTestUtil {

	use PHPMock;

	public function init_function($http_status, $body){
		$this->getFunctionMock(__NAMESPACE__, 'getenv')->expects($this->any())->willReturn('');
	}
}
```

getFunctionMock は namespace が空のときエラーになります。
テスト対象(honya.php)に namespace を入れたのは、そういう訳です。

HonyaTestUtil はclassにしていましたが、new でも static でもエラーになるので、trait にしました。

### ./vendor/bin/phpunit

で、実行できます。
phpunit.xml のデフォルトで autoload.php と テスト対象フォルダを指定されてるためです。
カバレッジも表示できるみたいですが、表示するまでもないので、暇があったらやります。
時間を作る事、イコール管理ですね

# 違う事に時間取られてしまった
- @c-yanからせっかくコメントもらったのに別件にかなり時間をとられてしまった
- 明日やればいいと言えばいいが、やはり何事に鉄は熱いうちに打つの鉄則かと
- 明日はコメもらった内容をやろう。お休みなさい:first_quarter_moon_with_face:
「移動またはコピーする数式またはシートには、移動またはコピー先のワークシートに既にある名前「？？？」が含まれています。この名前を使用しますか？」

#はじめに
モダンなITシステム開発の現場で大人気なExcel。
皆さんも方眼紙を作って最新のパラメータを管理したり、
「え、WordじゃなくてExcelで!？」という使い方をしたりますよね。
掲題のエラーに直面するたびにググるのに疲れたので、まとめます。

#エラーが出る理由
名前の定義が残っているから。

#エラーを回避する
画面上部のリボンから [ 数式 ] > [ 名前の管理 ]を選択する。
`ctrl + F3`でもいい。


![名前の管理.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155963/f5fb2583-78b0-8c47-f127-499c48ea9aa9.png)

軒並み残っているゴミを削除してきれいにする。

![名前の管理をクリア.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155963/8e509e51-00cd-f3bb-765e-958f9035f1d9.png)

#まだエラーが出る場合の理由
非表示の名前の定義が残っているから。

#しぶといエラーを回避する
VBAを使う。

##Visual Basic Editorを開く。

`Alt + F11`で開く。
そんなショートカットは使いたくないという場合は、[ 開発 ] > [ Visual Basic ] から開く。

![visual basic editor.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155963/472bb711-6212-e8a2-b926-c4425108c510.png)

[ 開発 ] なんてタブは無い、という場合は以下の手順に則る。

[[開発] タブを表示する - Office サポート](https://support.office.com/ja-jp/article/-%E9%96%8B%E7%99%BA-%E3%82%BF%E3%83%96%E3%82%92%E8%A1%A8%E7%A4%BA%E3%81%99%E3%82%8B-e1192344-5e56-4d45-931b-e5fd9bea2d45)

>1.[ファイル] タブで、[オプション]、[リボンのユーザー設定] の順に移動します。
2.[リボンのユーザー設定] および [メイン タブ] の下の [開発] チェック ボックスをオンにします。

![開発.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155963/dec8cd44-177a-7587-7c81-fd488ebeea8c.png)

##コードを貼って動かす

[ 挿入(`Alt + I`) ] > [ 標準モジュール(`M`) ] でウィンドウを開き、以下をペーストする。

```vb:貼ろう
Sub osouji()
Dim C As Name
For Each C In Names
  C.Delete
Next
End Sub
```

![VBE.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155963/9ee80319-4d70-7d07-0d7b-ed283f2edec9.png)


ペーストした部分のウインドウを閉じ、[ 実行(`F5`) ] > マクロの画面で[ 実行(`Enter`) ]。
この状態ですべての名前の定義が消えているはず。

不要であればVBEの画面で [ ファイル(`Alt + F`) ] > [ Module1 の解放(`R`) ]で今回作成したモジュールの掃除。（エクスポートしておくことも可。）`Alt + F11`でVBEを閉じる。

#おわりに
どんなに時代が進んでもExcelは不滅だと思う。
ガッチガチの設計書がこの世にある限り。
「pug」タグについて (タグシノニム: 「Jade」)

# 対象

https://qiita.com/tags/pug

### 説明

Node.jsのHTMLを書くためのテンプレートエンジン
商標の問題でjadeからpugへ名前が変わった


### タグシノニム

https://qiita.com/tags/Jade
IFTTTとGoogleカレンダーでTwitterBotを作る(誕生日Bot編)

※この記事は https://kunosu.qrunch.io/entries/oIZjp7gCq3ZT5Pr6 に移動しました。

---

グーグルカレンダーにあらかじめ予定を登録しておき、予定の時刻になったらIFTTTでTwitterに投稿するBotを作成します。

漫画キャラの誕生日を登録すれば、誕生日にお知らせするボットを作成できます。
例: 斉Ψ誕生日Bot [@saisai_birthday](https://twitter.com/saisai_birthday)

というわけで誕生日Botの作り方を紹介します

## 作り方

Twitter、グーグルアカウント、IFTTTの登録や連携はすでに行っている前提で進めます。
また、IFTTTの基本的な使い方も省略します。

### 1. IFTTTで投稿用のアプレットを作成

1. "New Applet" で新規作成
1. トリガーとなる this にグーグルカレンダーを選択
1. "Any event starts" を選択
1. "Whith calendar?" で誕生日を登録するカレンダーを選択
1. "Time before event starts" は "0 minutes" を選択 -> "Create trigger"<br>
	・これでカレンダーの予定開始時刻がトリガーとなります
1. 実行内容の that にTwitterを選択
1. "Post a tweet" を選択
1. "Tweet text" にツイート内容を記載<br>
	・{{Title}} には予定のタイトルが入ります<br>
	・例: 🎉今日は {{Title}} ！🎂 #斉Ψ #自動ツイート #HappyBirthday
1. 最後にアプレットのタイトルを入力して完了

これで「グーグルカレンダーで予定の時刻になったら決まった書式のツイートを投稿する」アプレットができました。

### 2. 試しに投稿してみる

アプレットが正しく動作していることを確認します。

1. カレンダーに適当な予定を作成<br>
	・時刻やタイトルは問いません
1. 予定の時刻まで放置<br>
	・15分程度遅れることもあります
1. "Tweet text" に記載した内容のツイートがされていることを確認

#### 2-1. 時間になっても投稿されないようなら

- アプレットのOn/Off切り替え画面下部にある "Check now" をクリックして実行させてみる
- ヘッダにある "Activity" でアプレットの実行履歴を見てみる
	- グーグルカレンダーをトリガーにするとよく "failed" になる
		- 問題なく動作しているアプレットでもよく出るため、あまり参考にならないかも
- Twitter側の規制に引っかかってないか
	- あまりにも連続して投稿しようとすると止められることがあります

### 3. 動作が問題なさそうならグーグルカレンダーにキャラの誕生日を登録

誕生日の投稿したい時間に「○○の誕生日」の予定を作成するだけ。

これで誕生日Botが完成しました
Google Colabratoryが便利に使えるようになるChrome拡張機能の紹介

皆様Githubリポジトリ巡回中に見つけたJupyterNotebooksをサクッと動作確認してみたいと思ったことはありませんか、僕はあります。
ということで今回はこちらのChrome拡張機能を紹介したいと思います。

[Chrome拡張機能 - Open in Colab](https://chrome.google.com/webstore/detail/open-in-colab/iogfkhleblhcpcekbiedikdehleodpjo)

## 具体的になにができるの？
GithubでホストされているJupyterNotebooksを直接GoogleColabratoryで開くことができる。

どういうことなの？と思いますのでちょっと例をあげながら説明します。

- まず[こちら](https://github.com/tomo-makes/dl-in-a-sec/blob/master/notebooks/Basic_Classification_ja.ipynb)のURL先に飛んで頂き

- [Chrome拡張機能 - Open in Colab](https://chrome.google.com/webstore/detail/open-in-colab/iogfkhleblhcpcekbiedikdehleodpjo) をインストール後に表示されるアイコンをクリックしてください

![open_in_colab_1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/1ac38504-2bf3-2792-fcd5-417a90052840.png)

- そうしますと先程のJupyterNotebooksがGoogleColabratoryに読み込まれた状態になります

![open_in_colab_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/40310/466abcee-1d36-b71a-7cad-549d1deb42aa.png)


- 読み取り専用で開かれるため編集も何もできないのでご自分のGoogleDriveにコピーしてもらい、あとはお好きなように遊んでみてください

以上になります

# 参考
- [Chrome拡張機能 - Open in Colab](https://chrome.google.com/webstore/detail/open-in-colab/iogfkhleblhcpcekbiedikdehleodpjo)
- [Github - open_in_colab](https://github.com/googlecolab/open_in_colab)
c++ 浮動小数点数 表示方法

# 目次
* fixed と setprecision で固定小数点表記の表示を自在に操る
* scientific を用いて、指数表記の表示を自在に操る

# fixed と setprecision で固定小数点表記の表示を自在に操る
## メイン処理
**std::fixed** は小数部の桁数をより正確に指定したい場合には書式フラグです。fixedを使用しないと、setprecisionの指定した長さが整数部も含むことになります。
**std::setprecision** は入出力ストリームで浮動小数点型の桁数を指定出来るマニピュレータです。

```c++

#include <iomanip> // setprecisionを使用するのに必要
cout << std::fixed << std::setprecision(15) << y << endl;
````
## サンプル

```c++
#include <iostream>
#include <iomanip>
using namespace std;

int main(){
  double y;
  y = 1.0 / 3.0;

  //普通にcout
  cout << y << endl;

  //小数点以下の長さを指定
  cout << fixed << setprecision(15) << y << endl;

  return 0;
}
```
### 出力結果
0.333333
0.333333333333333



# scientific を用いて指数表記の表示を自在に操る

## メイン処理
**std::scientific**は指数表記による出力を行いたい場合に使用します。cout << のあとに記載するだけで指数表記が表示できます。
 
```c++
cout << std::scientific << y << endl;
cout << std::scientific << std::setprecision(2) << y << endl;
```
サンプル

```c++
#include <iostream>
#include <iomanip>
int main(){
  double y;
  y = 31415.926535

  //単純に指数表記
  cout << scientific << y << endl;

  //指数表記 + 小数点以下長さ指定
  cout << scientific << setprecision(2) << y << endl;

  //指数表記 + 小数点以下長さ指定 + uppercaseでeの部分を大文字表記に
  cout << scientific << setprecision(2) << uppercase << y << endl;
  
  return 0;
}
```

### 出力結果
3.141592653500000e+04
3.14e+04
3.14E+04

## まとめ
fixed で小数点以下だよと教えてあげる。 setprecision で小数点以下の長さを指定してあげる。
scientiicで指数表記を使うよと教えてあげる。

TAの採点の仕事が面倒くさい...
terraform v0.11.14 から v0.12.0 にマイグレーションしてみた

# 概要

最近、業務でインフラ系をやらせていただいており、terraformとお友達になりました。
v0.11.14からv0.12.0にマイグレーションしたので、ハマった点を備忘録として残します。

マイグレーションを行う際に0.11系と0.12.0を結構行き来したので、tfenvの導入をお勧めします。

## その１ aliasをつけたproviderが参照できない

別ファイルに定義したaliasをつけたproviderを、moduleで参照している場合参照ができなくなりました。
以下のような例です。

### 例

```main.tf
provider "aws" {
    region = "ap-northeast-1"
    profile = "ex-profile"
    assume_role {
        role_arn = "arn:aws:iam::00000000000:role/ex-role"
    }
}

provider "aws" {
    region = "us-east-1"
    profile = "ex-profile"
    alias = "us-east-1"
    assume_role {
        role_arn = "arn:aws:iam::00000000000:role/ex-role"
    }
}

module "acm" {
    source = "./ex-module"
    certificate_domain = "example.com"
}
```

```ex-module/main.tf
data "aws_acm_certificate" "acm" {
    provider = aws.us-east-1
    domain = var.certificate_domain
}
```

### 回避策

v0.12からmodule内に直接定義する必要があります。

```main.tf
provider "aws" {
    region = "ap-northeast-1"
    profile = "ex-profile"
    assume_role {
        role_arn = "arn:aws:iam::00000000000:role/ex-role"
    }
}

module "acm" {
    source = "./ex-module"
    certificate_domain = "example.com"
}
```

```ex-module/main.tf
provider "aws" {
    region = "us-east-1"
    profile = "ex-profile"
    alias = "us-east-1"
    assume_role {
        role_arn = "arn:aws:iam::00000000000:role/ex-role"
    }
}

data "aws_acm_certificate" "acm" {
    provider = aws.us-east-1
    domain = var.certificate_domain
}
```

## その2 resource名を数字から始められない

### 例

v0.11まではresource名を数字から始めることができましたが、v0.12からはリソース名を数字で始めることができなくなったので、英文字か記号から始まるように修正しなければなりません。
以下のような例です。

```main.tf
resource "aws_route53_zone" "3150example_jp" {
    name = "3150example.jp"
}
```

### 回避策

これは方法が複数あります。
destroy -> add で大丈夫なリソースであれば、リソース名を修正するだけで大丈夫です。
destroyされると困るリソースの場合は、私は以下の手順で修正を行いました。

- tfstateを書き換える

```
terraform state mv <aws_xxx_xxx.旧リソース名> <aws_xxx_xxx.新リソース名>
```

- 該当箇所を新リソース名に修正して、0.12にマイグレーション
- initやplan時にattributeエラーが出る場合は以下の手順を行う
- tfstateのdepens_onが1の修正前のリソース名になっている場合があるので、tfstateを旧リソース名でgrepしてみる。
- 引っかかる場合は新リソース名にして、tfstateを書き換える

```
terraform state push
```

# まとめ
情報が少なく、この２つでなかなか時間を使ったので、誰かの助けになれば幸いです。

# 参考サイト

https://www.terraform.io/docs/configuration/providers.html
https://github.com/hashicorp/terraform/issues/20835
iOS・Safari・Androidブラウザでplaceholderの位置がずれる件

## 事象

chromeやIEでは、「半角数字3桁」と書かれているplaceholderは
ちゃんと真ん中に位置しているのに、、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88533/c874398c-6b8c-dca7-22dd-741ec908a0a3.png)

safariとiOS・Androidブラウザで見ると・・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88533/c7b707bb-27f4-a216-e0e3-3db2c883f589.png)

ん・・・、　真ん中より上になってる。。。。



##　解決方法

簡単です。一行で解決できます。

```css
input::-webkit-input-placeholder { padding-top: 0.2em; }
```

注意しないといけないのは、
padding-topの値をSafari/iOSとAndroidブラウザをみながら
調整をしなければならないことです。

Safari/iOSが真ん中になっても、
Androidブラウザではずれていることがあるので、
細かく調整してみてください。
5/23

・H2ってだいたいOracleと構文同じっぽいが、 LIKE文を%つけずに書いたら部分一致になる？
　　⇒なりません。
・REPLACEを使って小文字->大文字変換しているSQLを見かけたが、これTRANSLATEじゃないの？

SELECT REPLACE('ABCDE', 'ACE', 'XXX')  FROM DUAL    -> ABCDE (文字列の置換)
SELECT TRANSLATE ('ABCDE', 'ACE', 'XXX') FROM DUAL  -> XBXDX (1文字ずつの置換)


・バリデーション

## 数値チェック
```java:TestForm.java
  // Nullはチェックしない，文字列の場合型変換例外

　// 小数／整数依らず使用可能。Stringはダメ。
  @Min(10) // 9以下でエラー
  private Double number; 
  
  @Max(10) // 11以上でエラー
  private Double number; 
  
  @Range(min=10, max=20) // 9以下または21以上でエラー
  private Double number;
	
  @Digits(integer=2, fraction = 4) // 整数部が3桁以上または小数部が5桁以上でエラー
  private Double number;
  @Digits(integer=2, fraction = 0) // 整数部が3桁以上または小数部が1桁以上でエラー
  private Double number;
```


## 文字列チェック
```java:TestForm.java
  // Nullはチェックしない，文字列の場合型変換例外)

  // 全角文字の場合チェックが発生しない。
  @Size(min=2,max=4) // 1桁以下または5桁以上でエラー
  private String text;

  // 全角文字も1文字1カウントでチェックされる。
  @Length(min=2, max=4) // 1桁以下または5桁以上でエラー


 　書くの疲れた。（´・ω・｀）
  @NotNull : Nullでないこと
@NotEmpty : Null or 空白でない
@NotBlank : null or 空白 or スペースのみでない


"デフォルトの場合，FormのパラメタがStringの場合,
リクエスト時に空白が設定されてしまうため、
「入力時のみ，５文字以上でエラー」とするには
空白⇒Nullの変換処理が必要。
InitBinderを付けるとHandlerメソッド呼び出し前に呼ばれる。
@InitBinder
public void initBinder(WebDataBinder binder) {
　binder.registerCustomEditor (String.class, new 　　StringTrimmerEditor(true));

}


```
■参考サイト
https://docs.oracle.com/javase/jp/7/api/java/util/regex/Pattern.html#ucc

全角や半角の文字一覧
https://junk-blog.com/font_list/

SJIS, UTF8コード一覧表
http://ash.jp/code/unitbl21.htm

UTF-8コード一覧表
http://orange-factory.com/sample/utf8/code3/e3.html#Katakana

カタカナの領域とは
http://pentan.info/doc/unicode_list.html




★全角カナ　@Pattern(regexp = "^[ァ-タダ-ヶー]+$")
　⇒ タとダが非連続なのはUTF-8の文字コード上で連続していないから

★全角文字(半角以外) @Pattern(regexp = ^[^ -~｡-ﾟ]+$)
　⇒ 半角英数字，半角記号，半角カナ以外の連続文字列

  ⇒ そういえば全角ひらがなってないんだね。
WindowsでOpenSCを使う（1.準備編）

# はじめに
OpenSCを使うことで、Felica、MIFARE等のICカードの読み取りの時のコマンドやIDmの確認が簡単に行えます。ICカードの中身を手っ取り早く知りたいときや、コマンドが正しいか確認したいときに便利です。

# 環境
- OS:Windows10

# OpenSCとは？
- サイト：https://github.com/OpenSC/OpenSC/wiki
- スマートカードを扱うライブラリやユーティリティを提供している。
- Windows、macOS、Linuxで使用可能

# OpenSCをダウンロード
下記サイトから自分の環境にあったものをダウンロードします。
今回はOpenSC-win64_0.19.0.msiをダウンロードしました。
https://github.com/OpenSC/OpenSC/wiki

# OpenSCをセットアップ
①ダウンロードしたOpenSC-win64_0.19.0.msiをダブルクリックします。
②「詳細情報」をクリック
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/c44e63d6-2a21-3e82-7a86-74669dae8654.png)
③「実行」をクリック
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/874da773-f63b-cf45-2a91-5ebce8b00c86.png)
④「Next」をクリック
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/21a92ed2-1159-c9c2-083f-b236631cad12.png)
⑤「Typical」をクリック
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/95c79ead-3583-1bf5-5bb2-04bc50df121a.png)
⑥「Install」をクリック
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/ffcee723-6175-abe1-50c9-695b1c994d23.png)
⑦インストールを見守ります
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/df8454c7-b536-84bd-3391-ccc9848b808a.png)
⑧「Finish」をクリックで終了
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409907/716c0b56-95f6-c7ef-e70e-e0b1d2344541.png)

# 内容を確認しよう
- OpenSCのモジュールはC:\Windows\System32にインストールされます。
    - pensc-pkcs11.dll
    - opensc-minidriver.dll
    - etc
- ツール群がC:\Program Files\OpenSC Projectに展開されます。次の記事から使用していくのはC:\Program Files\OpenSC Project\OpenSC\toolsのopensc-tool.exeです。

# 参考
[WindowsでOpenSCを使ってカードのIDmを確認する方法](https://qiita.com/gebo/items/eb76d2b83041cdb47ec3)

# 関連ページ
[WindowsでOpenSCを使う（2.カードのIDm確認編）](https://qiita.com/erik_tnk/items/a8e36323a44bab92640d)
リンク集

今までの資料をまとめたい。


#Spring
- [インストールからプロジェクト作成まで(2019/03/25)](https://qiita.com/yakumo3390/items/2c26b4f27ac08d80e2ee)

- バリデーション
 - [自作アノテーションを作成する。(2019/05/26)]
(https://qiita.com/yakumo3390/items/026765a2a0718a9f0c82)
 - [BindingResultを操作する。]
(https://qiita.com/yakumo3390/items/4e47930ba643b45b7430)


#Thymeleaf
- [構文一覧(2019/05/17)](https://qiita.com/yakumo3390/items/6b3fcc9e00f7a682660c)


#JQuery
- [構文一覧(2019/05/30)](https://qiita.com/yakumo3390/items/8563dc6fdea228e3c5a7)

#DBFlute
- [ログを出力する。(2019/05/26)](https://qiita.com/yakumo3390/items/967c5c259aa94167e140)
- [外だしSQLを作成する(下準備)(2019/05/26)](https://qiita.com/yakumo3390/items/c75290fe02d939e358be)
- [外だしSQLのコメント記法(2019/05/26)]
(https://qiita.com/yakumo3390/items/28854672a783fe599083)

#JUnit
 - [Mockito入門(2019/05/26)](https://qiita.com/yakumo3390/items/c34f1f1625c3beffaf9c)


#Git
 - [SourceTree導入編(2019/05/26)](https://qiita.com/yakumo3390/items/8f384967994877b656ca)

#Java
 - [アノテーションの定義 (2019/02/22)](https://qiita.com/yakumo3390/items/76e3977c40c3eb64fb05)
 - [日付の型変換(2019/05/28)](https://qiita.com/yakumo3390/items/ff720ae4a4bf02b99755)
実装したcssまとめ

###画像の指定

```
background:url(asset_path('present.png')) no-repeat;
```

###画像のサイズ

```
background-size: 60%;
```


###要素の位置を相対的に指定

```
position: relative;
```


###要素の位置を絶対的に指定

```
position: absolute;
```


###行の高さを指定

```
line-height: 16px
```

###高さを自動で

```

height: auto;
```
フロントエンド未経験のSEがポートフォリオ作ってみた

#はじめに
普段はSEとしてJavaでバックエンドの開発を行っているのですが、最近フロントエンドの学習を始めました。
学習の一環として自身のポートフォリオを作成しました！
私と同じ様にフロントエンドの経験が浅い方で、何か作ってみたいと考えている方の参考になれば幸いです。

#作ったもの
https://masayuki777.github.io/
![portfolio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278934/89f8700b-1a07-33a6-dee3-319593339c5c.png)

#作り方
以下の記事を参考にしてテンプレートベースに作成を行いました！
[・エンジニアでポートフォリオ作りました](https://qiita.com/turmericN/items/76559f0b70983469e7c7)
[・うちゅういちかんたんなポートフォリオのつくりかた](https://qiita.com/suikasu123/items/c1cfda179078b923084f)

↓テンプレートはこちら
[・テンプレート](https://webdesigner-go.com/template/portfolio/)
<img width="1440" alt="スクリーンショット 2019-05-23 22.39.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278934/c950b48d-7424-cf29-1217-c157e5bd0026.png">

編集したのはhtml(`index.html`)とcss（`style.css`）で後は画像の差替えなどです。

アイコンは以下のサイトのもを利用しました。
https://fontawesome.com/
<img width="1440" alt="スクリーンショット 2019-05-23 22.37.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278934/40219f42-1407-ba2d-96a7-8d886c5a7b0e.png">
無料で利用できるのと登録などが不要な点が良かったです。

また、ヘッダーのグラデーションに関しては以下のサイトのCSSを利用しました。
https://uigradients.com/#Lunada
右上の`Get css`からCSSをコピーして利用できる点が良かったです。

ホスティングに関してはgithub.ioを利用しました。
公式サイトは以下ですが、他にも分かりやすくまとめられている記事はたくさんあるので簡単に公開できました。
https://pages.github.com/

#まとめ
今回初めてWEBサイトを作成したのですが、学ぶことが多くとてもいい経験になりました。
中身はスカスカですし、実力不足でデザインを諦めた部分もあるので、継続的にアップデートしていきたいと思います。（小さく作って大きく育てるの精神大事）
DBに接続しようとしたらORA-28001: the password has expiredとなった時の対応方法

- 環境
    - Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
    - SQL*Plus: Release 11.2.0.1.0 Production

# 事象 : Weblogicでデプロイする時にOracleDBに接続するところで怒られた
```text:サーバのlog
Caused By: weblogic.common.ResourceException: ORA-28001: the password has expired
	at weblogic.jdbc.common.internal.XAConnectionEnvFactory.makeConnection(XAConnectionEnvFactory.java:500)
// 省略 
```

# 原因 : ユーザのパスワードの有効期限が切れたから
メッセージの通り「パスワードの有効期限が切れている」です。
クライアントツールのA5M2でもアクセスしてみるとやはり「パスワードの有効期限が切れている」とメッセージが出ました。

## 対応方法 : パスワードを更新する
**1.. SQLPlusを使ってSYSDBAでデータベースにログインする**

```bash
$ sqlplus / as sysdba
```

> SYSDBAおよびSYSOPERはデータベースの作成、起動、停止、バックアップまたはリカバリなどの高度な管理操作を実行するために必要な管理権限です。SYSDBAシステム権限は、すべての権限を持つデータベース管理者用、SYSOPERシステム権限は、基本的な運用タスクを実行するがユーザー・データを表示する権限は持たないユーザー用です。
> [SYSDBAおよびSYSOPERシステム権限](https://docs.oracle.com/cd/E57425_01/121/ADMQS/GUID-2033E766-8FE6-4FBA-97E0-2607B083FA2C.htm)


**2.. パスワードを変更する**

```sql
-- ユーザの存在を確認する
SELECT username,account_status,expiry_date FROM dba_users WHERE username = '対象のユーザ名';
USERNAME               ACCOUNT_STATUS       EXPIRY_DA
--------------------- --------------------- ---------
対象のユーザ名           EXPIRED              30-OCT-18

-- パスワードを変更する
ALTER user 対象のユーザ名 IDENTIFIED BY 新しいパスワード;

-- 自動CommitがOFF(デフォルト)の場合はCommitする
COMMIT;
```

**3.. (Weblogicを使っている場合だけ)Weblogicのコンソールでデータベースのパスワードを更新する**
1. コンソールにログイン
2. サイドメニュー > [サービス] > [データ・ソース] > 対象のデータ・ソース名のリンクを押下
3. [接続プール]タブ > [パスワード]欄でパスワードを更新する

### 参考
- [OracleのSQL*Plusと自動コミットについて - 大人になったら肺呼吸](http://d.hatena.ne.jp/replication/20130827/1377552605)
- [アカウントのパスワード有効期限の確認と設定方法 - Oracle - Project Group](https://www.projectgroup.info/tips/Oracle/Oracle_110001.html)
_pathメソッドが使えず、文字列のpathでgetする場合に、link_toにクエリパラメータを追加する

# 目的
- こんなことができるのかと驚いた
- ググってもこれは出てこなかった（当たり前だからなのかも...）

# やりたいこと
- link_toでパスパラメータ以外の情報も送りたい。
- クエリパラメータを送りたいが、_pathメソッドが使えず、以下の方法が使えない

```
<%= link_to "#{@user.nickname}", user_path(@user.id, testid: @test.id) %>
```

# 方法
- 直接文字列でクエリパラメータを載せる

```
<li><%= link_to "#{@user.nickname}", "/users/test/#{user.id}?testid=#{@test.id}" %></li>
```
終わらないfor文

# TL;DR
変数の値域、継続条件に注意しよう！

# はじめに
プログラミングをしていて，`for文から抜け出せない`という初歩的なミスをして時間を浪費してしまいました．
いないとは思いますが，同じ問題に直面した人のために理由をメモとして残します．

# 問題
for文を使用していて，デクリメントでループする必要があった．
簡単のため，以下のソースコードで試す．
`incrementSum()`は正常に動作するが，`decrementSum()`は正常に動作しない(Segmentation fault)．
また，`decrementSum()`内の`size_t`は`auto`に変更しても成功しない．

```cpp:testCode-failed
#include <iostream>
#include <vector>
using namespace std;

int incrementSum(const vector<int>& v){
  int sum = 0;
  for(size_t i=0; i<v.size(); ++i){
    sum += v[i];
  }
  return sum;
}
int decrementSum(const vector<int>& v){
  int sum = 0;
//for(auto i=v.size()-1; i>=0; --i){    もダメ
  for(size_t i=v.size()-1; i>=0; --i){
    sum += v[i];
  }
  return sum;
}

int main(){
  vector<int> v(10, 1);

  int sum1 = incrementSum(v);
  int sum2 = decrementSum(v);

  cout << sum1 << " " << sum2 << endl;
  return 0;
}
```

# 原因
`size_t`は正の値しかとらないため，`decrementSum()`関数内において`i==0`の次は`i==SIZE_MAX`となる．これにより，永遠に条件式を満たし続けてしまい，ループから抜け出せない．

# 対処
普通に最初の方法で解決したのだが，ついでに他の方法も挙げた．

## ベストと思われる解決方法
`int`を使うなど考えたのだが，コメントで教えてもらい，これに落ち着いた．

```cpp:solution_3
int decrementSum(const vector<int>& v){
  int sum = 0;
  for(size_t i=v.size()-1; i<v.size(); --i){
    sum += v[i];
  }
  return sum;
}
```

## シンプルな解決方法
おとなしく`int`を使う．

```cpp:solution_1
int decrementSum(const vector<int>& v){
  int sum = 0;
  for(int i=v.size()-1; i>=0; --i){
    sum += v[i];
  }
  return sum;
}
```

## 煩雑になる解決方法
これはループ内が煩雑になるため，一番微妙である．

```cpp:solution_3
int decrementSum(const vector<int>& v){
  int sum = 0;
  if(!v.size()) return 0;
  for(size_t i=v.size(); i>0; --i){
    sum += v[i-1];
  }
  return sum;
}
```

# おわりに
困った人の助けになることを願います．
もっとよい解決方法があれば教えていただけると幸いです．

# 参考
- https://memol.exblog.jp/7664880/
    - 解決のヒント
- https://cpprefjp.github.io/reference/cstddef/size_t.html
    - `size_t`について
- https://ja.cppreference.com/w/c/types/size_t
    - `size_t`の上限
- - https://ja.cppreference.com/w/c/types/size_t
    - `size_t`の上限
EclipseでSpring Boot使用時にpom.xmlのline 1にUnknown error

# 現象

イマイチ説明が難しいのだが、Eclipseでspring-boot使用時に以下のようなエラーが出る。

![booterror.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31934/f7beb3c0-1fc5-cc0b-089c-f86f8181abd7.jpeg)

だいたいこんな感じのpom.xml。

```xml:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.5.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>kagamihoge</groupId>
	<artifactId>springintegratesample</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>springintegratesample</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>11</java.version>
	</properties>

</project>

```

# 対策
当座動けばいいというだけなら、```2.1.5```を```2.1.4```にする。

またはプロパティに以下を追加する。

```xml
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
```
# 参考URL
* https://stackoverflow.com/questions/56142369/why-am-i-getting-unknown-error-in-line-1-of-pom-xml
* https://bugs.eclipse.org/bugs/show_bug.cgi?id=547409
認証情報をreduxで管理してreact-routerのRedirectを学ぶ

#目標
題名の通り、`redux`で管理した情報に基づき`Redirect`を行います。
具体的に実装するのは、ログインした人じゃないと見れないページを作るというものです。

#実装していく
まずはトップのルーティングの部分

```javascript:App.js
import PrivateRoute from './PrivateRoute';

const App = () => {
  return (
    <Switch>
      <PrivateRoute path="/" exact component={TopPage} />
      <Route path="/login" component={Login} />
      <Route component={NotFoundPage} />
    </Switch>
  );
};
```
ここで`PrivateRoute`というものを自分で作っています。
`PrivateRoute`をみていきましょう。

```javascript:PrivateRoute.js
import React from 'react';
import { connect } from 'react-redux';
import { Route, Redirect } from 'react-router-dom';

const PrivateRoute = ({user, component: Component, ...rest}) => {
  return (
    <Route
      {...rest}
      render={props => 
        user ? (
          <Component {...props} />
        ) : (
          <Redirect to='/login' />
        )
      }
    />
  );
}

const mapStateToProps = state => {
  return {
    user: state.auth.user
  }
}

export default connect(mapStateToProps)(PrivateRoute);
```
ここで`redux`で管理している`user`の真偽により、偽であれば`/login`に`Redirect`します。

```javascript:reducers/authReducer.js
const initialState = {
  user: false
}

export default (state = initialState, action) => {
  switch(action.type) {
    case 'LOG_IN':
      return { ...state, user: true };
    case 'LOG_OUT':
      return { ...state, user: false };
    default:
      return state;
  }
}
```
お試しに実装したので`reducer`では大したことはしていません。
あとで`firebase`でのGoogleログインにしようと思っているのでその時は少し考えなければいけないかも。

最後にログインのコンポーネント

```javascript:components/Login/index.js
import React from 'react';

import { connect } from 'react-redux';
import { login } from '../../actions';

class Login extends React.Component {

  reduxLogin = () => {
    const { login, history } = this.props;

    login();
    history.push('/');
  }

  render() {
    return (
        <div>
          <button onClick={this.reduxLogin}>login redux</button>
        </div>
    );
  }
}

export default connect(null, { login })(Login);
```

ログインのボタンを用意してログインするとトップページに飛ぶようにしています。
ログインしないでトップページに飛ぼうとしても`/login`に`Redirect`されます。

#まとめ
今回は`react-router`の`Redirect`についてみました。
参考になれば幸いです。
crontab についての備忘録（linux）

# crontabについての備忘録

linuxを触っている人には馴染みがあるcrontabについてメモ。

## crontabとは？

contabとは、linuxに定期的な処理を行わせたいときに、実行内容とタイミングを記述しておくファイルのことです。
各linux内のユーザ毎に定義することができます。
定期的なバッチ処理とかを走らせたい時とかにはとても便利。

## crontabの内容確認方法

現時点でどのような定義がされているかを見る方法は二つあります。
linuxコマンドベースで確認する方法と、crontabが記述されているファイルを直接参照する方法です。

## コマンドで確認する場合

以下のコマンドを実行することで、現時点で設定されている内容を表示することができます。

```crontab参照方法（コマンド）
crontab -l
```

ちなみに、設定されているcronの内容を編集する場合は、以下のコマンドを打てば良い。

```crontab参照方法（コマンド）
crontab -e
```
編集／保存方法はviエディタと同様で、「i」ボタンで編集モード、「esc」ボタンでコマンドモードに移行。
:q!や:wqで編集を終了または保存することが可能。

viエディタの使い方については、こちらにメモしています。
[viの操作について　メモ](https://qiita.com/bakepotate/items/0f93419e0e06f7ab4e09 "Qiita viの操作について　メモ")

コマンドを実行して、crontabの内容を参照するときに気をつけておかなければならなのは、オプションをつけずに実行してしまうこと。

もし、以下のようにオプションを何もつけずに実行してしまった場合、最悪crontab内に定義していたものが全て削除されてしまいます。

```crontab　基本的に実行しない方が良い
crontab
```

万が一、上記のようにオプションをつけずに実行してしまった場合は、焦らずに[Ctrl + C]で処理を抜けましょう。
大丈夫、落ち着いて対処すれば問題はありません。。

## 実態のファイルを確認する方法

linuxのコマンド操作に慣れていない人や、誤操作が怖い人は直接実態ファイルを参照する方が安全だと思います。
ただし、ルート権限になれる人に限ります。

大体は以下のフォルダ直下にcrontabの定義がされています。

```
/var/spool/cron/
```
ルートユーザになった後、上記ディレクトリに移動してみてください。
lsコマンド等でディレクトリ内を参照してみると、それぞれのユーザ毎のファイルが生成されていることが確認できると思います。
viやcatで中をのぞいてみてください。
それがcrontabの実態ファイルです。
Windows 10 のバージョン 1903 が一般提供開始されましたね

2019/05/22（日本時間）に、ついにバージョン 1903 が一般提供開始されましたね！
早速自宅 PC 、といっても、今この記事を書いている PC なんですが、サクッと初期化してクリーンインストールを行いました。
ちなみにクリーンインストールするためには、以下のサイトからツールをダウンロードしてインストール用 USB メモリを作成しておく必要があります。
https://www.microsoft.com/ja-jp/software-download/windows10

でもって、クリーンインストールしたんですが・・・早速いくつか問題にぶち当たりました。

まず、前提として自分の PC の構成を記載しておきます。

マザーボード：ASUS MAXIMUS VIII HERO
CPU：Intel Core i7 6700K
メモリ：32 GB
グラフィックボード：MSI GeForce GTX1080 GAMING X8G
電源：コルセアの750Wのやつ
ストレージ：SSD、HDD
その他もろもろ（多分関係ないと思うので省略）

# OneDrive を設定するフォルダが変更できない

クリーンインストール時にしか起こらないのかもしれませんが・・・
自分の環境では C ドライブは SSD で、Dドライブから G ドライブは HDD となっています。
今までは D ドライブに OneDrive のフォルダを用意していましたが、バージョン 1903 では OneDrive のフォルダ変更をしようとすると OneDrive が強制終了してしまい、変更不可能でした。
しょうがないので C ドライブのデフォルトのままとしました。

# AI Suite 3 がインストールできない

これは ASUS のマザボを使っている人限定ですが・・・
PC ケースのファンをコントロールするため、マザボに付属する AI Suite 3 というソフトを使っていました。
これがインストールできなくなりました。
CD を入れても強制終了してしまい、 ASUS の公式から最新版を落としてきてもインストールできず。
バージョン 1903 には対応していないようです。

# 初めから Python が入っている

なぜか 1903 から Python が初めから入っています。
コマンドプロンプトで調べてみると・・・

```
C:\Users\{ユーザー名}>where python
C:\Users\{ユーザー名}\AppData\Local\Microsoft\WindowsApps\python.exe
```
ただし、入っているようで入っていません。
Microsoft Store から Python をダウンロードしてインストールすることになります。

---

とりあえず気づいた点をまとめてみました。
rustのアドレス値と各要素の仕様確認

## Vec<String>

コード

```rust
fn main() {
  let mut v: Vec<String> = vec![];

  for i in 0..5 {
    v.push("h".to_string());
  }
  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);
}
```

結果

```
&v: 0x7ffeebfd20a0
&v[0]: 0x7ff29bc02ce0
&v[1]: 0x7ff29bc02cf8
&v[2]: 0x7ff29bc02d10
```

アドレス値は16進数で表現されている。
vectorは連続したある程度のサイズのメモリを一度に確保する。
この事からStringは24byteをベースに持ち、ヒープにstringの中身のchar配列を持っててそれ分の用量を食ってる様子が伺える。
ちなみに`v[0]`等でStringを参照しているが、これは全て借用で借りているので、`v[0]`とかの所有権だけ欲しいとかはできない。どうしても欲しい場合はクローンする必要がある。

## Vec<i32>
コード

```rust
fn main() {
  let mut v: Vec<i32> = vec![];

  for i in 0..5 {
    v.push(i);
  }
  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);
}
```

i32は名前の通り32ビット型の整数型である。
このコードを実行すると以下の出力を確認できる。

```
&v: 0x7ffeefbda0b8
&v[0]: 0x7fd791c02c60
&v[1]: 0x7fd791c02c64
&v[2]: 0x7fd791c02c68
```

32ビットは4バイト。ちゃんと連続で確保されている。正しい。

## Vecのメモリ引っ越しの確認
[引用](https://doc.rust-jp.rs/book/second-edition/ch08-01-vectors.html)

> 新規要素をベクタの終端に追加すると、ベクタが現在存在する位置に隣り合って要素を入れるだけの領域がなかった場合に、 メモリの新規確保をして古い要素を新しいスペースにコピーする。

この挙動を実際に確認します。
対象コードはこちら

```rust
fn main() {
  let mut v: Vec<i32> = vec![];

  for i in 0..5 {
    v.push(i);
  }
  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);

  v.push(1);

  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);

  for i in 0..5 {
    v.push(i);
  }

  println!("&v: {:p}", &v);
  println!("&v[0]: {:p}", &v[0]);
  println!("&v[1]: {:p}", &v[1]);
  println!("&v[2]: {:p}", &v[2]);
}
```

結果

```
&v: 0x7ffeef230dc8
&v[0]: 0x7fc53dc02c60
&v[1]: 0x7fc53dc02c64
&v[2]: 0x7fc53dc02c68
&v: 0x7ffeef230dc8
&v[0]: 0x7fc53dc02c60
&v[1]: 0x7fc53dc02c64
&v[2]: 0x7fc53dc02c68
&v: 0x7ffeef230dc8
&v[0]: 0x7fc53dc02d70
&v[1]: 0x7fc53dc02d74
&v[2]: 0x7fc53dc02d78
```

1つだけpushしても余分にとっていた様で、再確保されませんでしたが、追加でいくつかpushしたら再確保されましたね。
vectorのこの仕様のおかげでvector内を探索したり要素を参照するのがとても高速ですが、沢山pushしたり長さを調整すると何度も再確保され、そこにコストがかかっている様子が確認できました。
Leetcode #57: Insert Interval

```swift
func insert(_ intervals: [[Int]], _ newInterval: [Int]) -> [[Int]] {
    var answer = [[Int]]()
    var insertIndex = -1
    for (index, interval) in intervals.enumerated() {
        if interval[1] < newInterval[0] {
            answer.append(interval)
        } else {
            insertIndex = index
            break
        }
    }
    if insertIndex == -1 {
        return answer + [newInterval]
    }
    let newStart = min(newInterval[0], intervals[insertIndex][0])
    var newEnd = newInterval[1]
    var remainedIndex = intervals.count
    for i in stride(from: insertIndex, to: intervals.count, by: 1) {
        if intervals[i][0] <= newInterval[1] {
            newEnd = max(intervals[i][1], newEnd)
        } else {
            remainedIndex = i
            break
        }
    }
    answer += [[newStart, newEnd]]
    for i in stride(from: remainedIndex, to: intervals.count, by: 1) {
        answer.append(intervals[i])
    }
    return answer
}
```
【Rails】コピペで使えるdevise備忘録

# はじめに
deviseでユーザーログイン機能を追加するにあたって、普段よく使っているものの備忘録です。

## rootをログイン画面に設定

deviseのcontrollerを作成し、`routes.rb`で以下のように設定。


```
$ rails g devise:controllers users
```


```routes.rb
Rails.application.routes.draw do

   # rootをログイン画面に設定
  devise_scope :user do
    root "users/sessions#new"
  end

  devise_for :users, :controllers => {
    sessions: 'users/sessions'
  }

```


## ログイン後のpathを指定
`application_controller.rb`で以下を記載。

```application_controller.rb
class ApplicationController < ActionController::Base
  def after_sign_in_path_for(resource)
    tasks_path
  end
```

このようにログイン後最初のページを条件分岐させることも可能です↓

```application_controller.rb
class ApplicationController < ActionController::Base
  def after_sign_in_path_for(resource)
    if admin_user?
      users_path
    else
      tasks_path
    end
  end
```

## ストロングパラメーターのpermit
deviseではサインアップ時に`email`と`password`系のみを受け取るようにストロングパラメーターが設けられている。
それ以外の **`:name`** などを許可したい場合、permitを設ける必要がある↓

```application_controller.rb
class ApplicationController < ActionController::Base
  before_action :configure_permitted_parameters, if: :devise_controller?

.
.
.


  private

  def configure_permitted_parameters
    added_attrs = [ :name,
                    :email,
                    :password,
                    :password_confirmation,
                  ]
    devise_parameter_sanitizer.permit :sign_up, keys: added_attrs
    devise_parameter_sanitizer.permit :account_update, keys: added_attrs
    devise_parameter_sanitizer.permit :sign_in, keys: added_attrs
  end

```

## 複数のモデルをdeviseに適用

例えば、`creator` と `client`という2種類のModelでdeviseによるログイン機能を適用させたい場合、

```
rails g devise creator
rails g devise client
```
してあげてmigration

```
rails db:migrate
```
するだけでOK.

### ヘルパーメソッド

そしてdeviseが提供しているヘルパーメソッドに関しては、userという文字列をそれぞれcreatorやclientに変更すれば利用できる。
（↓こんな感じ）

|user|creator|client|
|:-:|:-:|:-:|
|before_action :authenticate_user!|before_action :authenticate_creator!|before_action :authenticate_client!|
|user_signed_in?|creator_signed_in?|client_signed_in?|
|current_user|current_creator|current_client|
|user_session|creator_session|client_session|



詳細はこちらを参照→https://github.com/plataformatec/devise/wiki/How-to-Setup-Multiple-Devise-User-Models
https://qiita.com/tobita0000/items/866de191635e6d74e392


# おわり
他にも備忘録しておきたい事ありそうなので、思い出し次第追加したい。
[Kotlin豆知識] KProperty<T, out R>は関数のようにふるまう


# 発端はEnumから
enumのメンバをそのプロパティから復元するときにこういうコードをよく書く。

```kotlin
enum class Moge(val raw: Int) {
    companion object {
        private val map = values().associateBy(Moge::raw)

        fun fromInt(value: Int) : Moge {
            return map[value] ?: throw IllegalArgumentException("Moge!!!")
        }
}
```

丁寧に挙動を調べてやると、 `Hoge::fuga` はHogeのインスタンスを引数にとる関数のような挙動をすることがわかる。

```kotlin
class Hoge(val fuga: Int = 3) 
val fuga = (Hoge::fuga)(Hoge())
```

# fugaをprivateにすると
きちんとコンパイルエラーになってくれる

```kotlin
class Hoge(private val fuga: Int = 3)

// fugaのprivate性はここで検知される
val fuga = Hoge::fuga
fuga(Hoge())
```

## 何の意味もないが
KProperty1をムリヤリ外に出してやると、プライベートメンバにアクセスができる。

```kotlin
class Hoge(private val fuga: Int = 3) {
    companion object {
        fun fugaProperty(): KProperty1<Hoge, Int> {
            return Hoge::fuga
        }
    }
}
val fugaProperty = Hoge.fugaProperty()
val fuga = fugaProperty(Hoge())
```
dstatで出力と同時にログ保存するエイリアス集

トラブル対応時に便利なdstat。オプションが多くて忘れるので、いざというときにすぐ使えなくて困る。

以下のようなエイリアスを普段から作っておくと便利。

# 出力と同時にログファイルに保存したい

```
alias dstat-full='sudo dstat -Ttcglypmdrn --output /var/log/`date +dstat_%Y%m%d-%H%M%S.csv`'
```

`/var/log/dstat_開始時刻.csv` にログを自動保存してくれる。

# CPUコア単位での出力を保存したい

コア単位のCPU使用率も見たいときはこれ。CPUコア数は `nproc` コマンドで自動取得するので、CPUコアがいくつあっても大丈夫。(コア数が多いと表示が切れてリアルタイム監視には向かないけど)

```
alias dstat-full-cpu="sudo dstat -Ttcglypmdrn -Ctotal,$(seq 0  $(( `nproc` - 1 )) | xargs | tr ' ' ,) --output /var/log/\`date +dstat_%Y%m%d-%H%M%S.csv\`"
```

dstat でコア毎のCPU使用率を出力したいときは、`-Ctotal,0,1,2,..` のようにオプション指定しなくてはならず、面倒。

なので、以下のようなワンライナーを組み込んでCPUコアの分だけ `0,1,2,...` という文字列を生成するようにした。

```
$(seq 0  $(( `nproc` - 1 )) | xargs | tr ' ' ,)
```

# 色つきで保存したい

dstatの色つき出力をそのまま保存したいときはこちら。

```
alias dstat-full-color='sudo unbuffer dstat -Ttcglypmdrn | sudo tee /var/log/`date +dstat_%Y%m%d-%H%M%S.log`'
```

dstatの出力をそのままパイプで `tee` に渡してしまうと、エスケープシーケンスが除去されてしまうので、`unbuffer` コマンドをつかう。

`unbuffer` は `expect` パッケージに入っているので、yum でインストールしておく。
rustのvectorの要素を取り出す際のパフォーマンス測定

### 1番目
vectorの要素を添字記法で取り出す

```rust
use std::time::Instant;

fn main() {
  let mut v = vec![];

  for i in 0..100000000 {
    v.push(i);
  }

  let start = Instant::now();
  for i in 0..100000000 {
    &v[i];
  }

  let end = start.elapsed();
  println!(
    "{}.{:03}秒経過しました。",
    end.as_secs(),
    end.subsec_nanos() / 1_000_000
  );
}
```

結果

```
1回目: 5.891
2回目: 5.877
3回目: 6.057
```

### 2番目
getだけする

```rust
use std::time::Instant;

fn main() {
  let mut v = vec![];

  for i in 0..100000000 {
    v.push(i);
  }

  let start = Instant::now();
  for i in 0..100000000 {
    v.get(i);
  }

  let end = start.elapsed();
  println!(
    "{}.{:03}秒経過しました。",
    end.as_secs(),
    end.subsec_nanos() / 1_000_000
  );
}
```

結果

```
1回目: 6.836
2回目: 6.855
3回目: 6.827
```


### 3番目
getしてからunwrapする

```rust
use std::time::Instant;

fn main() {
  let mut v = vec![];

  for i in 0..100000000 {
    v.push(i);
  }

  let start = Instant::now();
  for i in 0..100000000 {
    v.get(i).unwrap();
  }

  let end = start.elapsed();
  println!(
    "{}.{:03}秒経過しました。",
    end.as_secs(),
    end.subsec_nanos() / 1_000_000
  );
}
```

結果

```
1回目: 7.599
2回目: 7.570
3回目: 7.451
```
SORACOM ヒゲボタン( SORACOM LTE-M Button Plus )を使ってみた

["SORACOM Button のボタンをソレノイドで押してみた"](https://qiita.com/nnnn_pi/items/5be6e88a3c99f3128cea)では、ソレノイドを使ってボタンの押下を行いましたが。先月発売された[ SORACOM LTE-M Button Plus ](https://soracom.jp/products/gadgets/button_plus/) 通称ヒゲボタンは、出ている２本のコードを接続させる事によりボタンを押下する動作を行う事が出来ます。

##回路
回路は、前回のソレノイドに接続していたラインを今回はボタンから出ているラインにかえただけです。

![IMG_1560.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395286/0db6817b-adbd-3c90-e892-374f969e9aa7.jpeg)
![IMG_1561.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395286/a0de5230-5c29-7d75-55d0-15503d11061f.jpeg)

##ボタン押下によるデータの流れ概略

##前回のボタン [SORACOM LTE-M Button powered by AWS](https://soracom.jp/products/gadgets/aws_button/)押下時のデータの流れ
- ボタン押下
  - ⇒　[AWS Lambda] (https://aws.amazon.com/jp/lambda/)
     - ⇒　メール
     - ⇒　[twilio] (https://twilio.kddi-web.com/ ) ⇒　電話 (30℃以上です。エアコンをONにしましょう。)

##今回の[ SORACOM LTE-M Button Plus ](https://soracom.jp/products/gadgets/button_plus/) を使った時のデータの流れ

- ボタン押下（　ライン接続（導通）　）
  - ⇒　[ SORACOM Beam ](https://soracom.jp/services/beam/)
     - ⇒　自分でたてたサーバ
          -  ⇒  メール
          -   ⇒  [twilio] (https://twilio.kddi-web.com/ )　⇒　電話 (30℃以上です。エアコンをONにしましょう。)

##メール送信出来ました
![メール.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395286/f05162d1-46d2-1233-5e9e-702e2aa0eda3.jpeg)

##twilioへの処理のメモ
前回のAWS Lambdaではハンズオンで頂いたpythonプログラムの圧縮ファイルをAWS Lambdaにそのまま設定を行い。twilioの設定もAWS Lambdaに設定して行っていましたが。
今回は圧縮ファイルを解凍して自分のサーバ内でこのpythonプログラムを起動しtwilioから電話をする様にしました。


###今回は大きな部品（ソレノイドとソレノイドの電源）が不要になりました。ソラコムサンタさんこんな良い物を作ってくれてありがとう。twilioさん無料使用のサービスを使い切ったのでアップグレードしました。twilioさんありがとう。

###あと１つ必要なのは送信失敗、成功の判定を行いたい。送信失敗時に赤いLEDは点灯するのだが。
pyenvとpipenv

#pyenv で困った時
## 使うコマンドたち
`pyenv install --list`
`pyenv install 0.0.0`
`pyenv local` 
`pyenv global`

## エラー
Mojaveのせいでエラーが出る場合がある。その時は[これ] (https://qiita.com/zreactor/items/c3fd04417e0d61af0afe)を参照。

#pip env 
何やらpip envという便利ツールがあるそうなので[ここ](https://qiita.com/sl2/items/1e503952b9506a0539ea)を参考にしてダウンロードした。

#Pipfileの罠
Pipfile.lockを作成するには時間がかかる。今はとりあえずlockを作成せずに寝ている間にしよう。。。と思ってPipfileだけを作成して`pip install --system`としてしまいたくなりますよね。
しかしこれだとエラーが出ます。
`--skip-lock`[オプションを加えましょう](https://qiita.com/sabaku20XX/items/8bc6e8f999e8009d76fd)。
Selenium Grid をSynology NASのDockerで動かしてみる


### Synology NASにおけるSelenium Gridの設定方法
ありきたりなSelenium hubとnodeの設定ですが、
SynologyのNASのUIを紹介しながら、
設定した箇所のみピックアップして記載します。

---

### 環境
- PC　：MacBook Pro 2014 macOS Mojave<br>
- NAS ：Synology DiskStation 218+<br>
　　　 RAM：10GB（2GB+8GB）<br>
　　　 HDD：4TB + 3TB<br>
<br>
+ RAM 8GBはインストールはできるけどサポート対象外となり、問い合わせも対応してくれなくなる(当たり前)ので自己責任<br>
---

#### アプリのインストール
1. パッケージセンターからDockerをインストールする
2. DockerのレジストリでSelenium関連(HubとNode)をダウンロードする
3. DockerのパッケージでSelenium関連(HubとNode)をコンテナ化する

---

#### Selenium-Hub設定(全般設定)
1. コンテナ名を指定
2. 高権限実行コンテナを使用（お好みで）ON
3. リソースの制限を有効にする（お好みで）ON<br>
<img width="250" alt="ハブの全般設定画面スクショ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179227/eedf9e3c-8e73-6d71-88df-d556511b2dd2.png">

---

#### Selenium-Hub設定(Hubの詳細設定)
5. 自動再起動を有効にするをON<br>
 (夜はNASを電源OFFする方おすすめ)<br>
<img width="250" alt="ハブの詳細設定画面スクショ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179227/64c5fbbd-5485-4bad-db4e-f84625ef3cdf.png">

---

#### Selenium-Hub設定(ポート設定)
6. ローカルポート：環境に合わせて
7. コンテナポート：4444<br>
<img width="250" alt="ハブのポート設定タブスクショ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179227/3804d1fc-bffe-e05f-2cb7-362edaf5e558.png">

---

#### Selenium-node設定(全般設定)
1. コンテナ名を指定
2. 高権限実行コンテナを使用（お好みで）ON
3. リソースの制限を有効にする（お好みで）ON<br>
<img width="250" alt="ノードの全般設定画面スクショ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179227/771ea9ef-4e12-af4f-3a10-4a51b0e36273.png">

---

#### Selenium-node設定(nodeの詳細設定)
4. 自動再起動を有効にする<br>(夜はNASを電源OFFする方おすすめ)<br>
<img width="250" alt="ハブの詳細設定画面スクショ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179227/76c3d39b-4844-fdfc-8e93-158cac4280ef.png">

---

#### Selenium-node設定(ポート設定)
5. ローカルポート：環境に合わせて
6. コンテナポート：5555<br>
<img width="250" alt="ノードのポート設定タブスクショ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179227/567dff71-dd4f-b933-c509-48a6f3ed5618.png">

---

#### Selenium-node設定(リンク)
7. コンテナ名：selenium-hubを指定
8. エイリアス：お好みで<br>
<img width="250" alt="ノートのリンクタブスクショ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179227/06580e40-02b8-2290-908f-d362fada6572.png">

---

### 確認
ブラウザでNASのIPに対し、Selenium-hubの「ローカルポート」を指定。以下のように
Selenium-nodeが表示されれば成功
あとは、一般に書かれてる「WebDriver.Remote」でSelenium-hubに接続すればOK
<img width="250" alt="グリッドコンソール画面スクショ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179227/46197171-bd53-953e-58aa-b9d107ddb7f4.png">

---

### さいごに
それではすばらしいSynology NAS Lifeをお過ごしください:)
【Java初学者】コレクション 型指定なし printlnメソッド

#疑問
最近コレクションを学習し、疑問に感じた点があったため、記事に起こしながら確認します。

#コレクション
Listを使うときに型引数を指定しない場合、格納された時点で**Object型**として処理される。


#理解できなかった謎処理
Listに**String型**変数入れたけど、Listを型指定してないから**Object型**になって、**そのオブジェクトの文字列**をprintlnで表示...?

#printlnの処理
~~printlnの引数に入れられたオブジェクトの**valueOf**メソッドを呼び出して文字列を表示する。~~
<修正 2019/05/24>
println()の引数をStringクラスのstaticメソッドvalueOf()の引数に与え処理が行われる。


#toStringとvalueOfの違い
toStringメソッドはインスタンスの文字列を返す。
valueOfメソッドは引数で渡されたオブジェクトがnullでなければ、そのオブジェクトのtoStringメソッドを呼びだす。


#結局toString
valueOfも結局はそのオブジェクトの文字列を返している。


```java:User.java
public class User{
    private String name;
    public User(String name){
         this.name = name;
    }
    public String toString(){
         return name;
    }
}
```

```java:Main.java
public class Main{
   public static void main(String[] args){
      ArrayList list = new ArrayList();
      list.add(new User("sample"));
      System.out.println(list.get(0)); //sample
   }
}
```

#結果
型安全、Overrideをより理解できた。

#参考
- https://docs.oracle.com/javase/jp/7/api/java/lang/String.html
  【String - Oracle Docs】
AtCoder ABC076 C - Dubious Document 2 (300点)

#問題概要
[問題のリンク](https://atcoder.jp/contests/abc076/tasks/abc076_c)

文字列$S$の $0$ 個以上 $|S|$ 個以下の文字が $?$ に変わった文字列 $S′$ がある。

以下の条件が与えられる。

- 条件1：文字列 $S$ の中に連続する部分文字列として英小文字から成る文字列 $T$ が含まれている。
- 条件2： $S$ は、条件1を満たす文字列の中で辞書順最小の文字列である。

文字列 $S$ を出力せよ。
ただし文字列 $S$ が存在しない時は $UNRESTORABLE$ と出力せよ。

#制約条件

- $1≤|S′|,|T|≤50$
- $S′$ は英小文字と ? から成る
- $T$
 は英小文字から成る

#考えたこと

条件2より、 $S'$ の $?$ の部分は $a$ が入ることが望ましい。よって $?$でない部分を与えられた部分文字列 $T$ と比較していく。

文字列 $S′$ に部分文字列$T$を代入しても、以下の条件を満たすのであれば `vector` に追加する。 
全て探索した後、`vector` を `sort` し、最初の文字列が答えである。

- 文字列の大きさが変化しない（=インデックスをはみ出さない）
- $?$ ではない英小文字が変化しない

`vector` が空であれば $UNRESTORABLE$ と出力する。
計算量は $O(|S′||T|)$ である。

#解答
```c.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    string s,t; cin >> s >> t;
    vector<string> ans;
    int l = s.size()-t.size()+1;
    for(int i = 0; i < max(0, l); i ++) {
        string tmp = s;
        for(int j = 0; j < t.length(); j ++) {
            if(i+j>s.size()-1) break;
            if(tmp[i+j]=='?' || tmp[i+j]==t[j]) tmp[i+j] = t[j];
            else break;
            if(j==t.length()-1) {
                for(int k = 0; k < tmp.length(); k ++) {
                    if(tmp[k]=='?') tmp[k] = 'a';
                }
                ans.push_back(tmp);
            }
        }
    }
    sort(ans.begin(), ans.end());
    cout << (ans.size() > 0 ? ans[0] : "UNRESTORABLE") << endl;
    return 0;
}
```
LINE Notifyを使ってLINEへメッセージを送信するpythonプログラムを作ってみる

## 目的
LINE上で動くプログラムを作成するにはLINEでの手続きとサーバーが必要だったり、初心者には煩わしい。
LINEへメッセージ送信を行うプログラムを作成したいだけなんでLINE Notifyを使ってみる。

## 参考にしたサイト
[たったの2ステップでLINEにメッセージを通知する方法【python】](https://sinyblog.com/python/line/?utm_source=ReviveOldPost&utm_medium=social&utm_campaign=ReviveOldPost)

## LINE側　設定手順
1.LINE Notifyにログインする。マイページを開く
https://notify-bot.line.me/ja/

2.アクセストークンを発行する
アクセストークンの発行(開発者向け)で｢トークンを発行する｣をクリック

* トークン名：任意の文字列を入力
* トークルーム：「1:1でLINE Notifyからの通知を受ける」にチェック<br>他はグループトークから選択するみたい

3.作成したアクセストークンをコピーしておく→プログラム内で定義する

## 実際にやってみた

### コーディング１回目

```sendmessege.py
line_notify_token = "<ここにアクセストークンを定義する>"
line_notify_api = 'https://notify-api.line.me/api/notify'

def main():
    print("LINEへ送信するメッセージを入力してください。")
    message = input("送信メッセージ：")
    
    print('送信メッセージ：' + message)
    payload = {'message': message}
    headers = {'Authorization': 'Bearer ' + line_notify_token}
    requests.post(line_notify_api, data=payload, headers=headers)

if __name__== '__main__':
    main()
```

### 気付き・感想
- メッセージ送信だけならこんなに簡単だと思わなかった。
- 自分のLINEへメッセージ送信できたが、ここから利用価値をつけくわえたい
- requestsモジュールは事前に"pip install"しておく<br>コマンド：**pip install requests**
- アクセストークンをソースにハードコーディングしないといけない←Java屋さんだから設定情報をDIできないの嫌だな。

### コーディング２回目

変更内容
- DI対応：configparserを使って外出ししたアクセストークンを読み込む

```sendmessege.py
# -*- coding: utf-8 -*-
import requests
import configparser

# 設定ファイル情報
config = ""
line_notify_token = ""
line_notify_api = ""

# iniファイルを読み込み
def iniread():
    global config
    global line_notify_token
    global line_notify_api
    config = configparser.ConfigParser()
    config.read('setting.ini')
    line_notify_token = config['LINENotify']['line_notify_token']
    line_notify_api = config['LINENotify']['line_notify_api']

def main():
    # 設定ファイル読み込み
    iniread()

    print("LINEへ送信するメッセージを入力してください。")
    message = input("送信メッセージ：")
    
    print('送信メッセージ：' + message)
    payload = {'message': message}
    headers = {'Authorization': 'Bearer ' + line_notify_token}
    requests.post(line_notify_api, data=payload, headers=headers)

if __name__== '__main__':
    main()
```

### 気付き・感想
- 今回はiniファイルにしたが、定義内容をディクショナリでアクセスできる。configparserモジュールいい感じ。
- もう少しオブジェクト指向で関心を区別しながらクラスをちゃんと設計せねば。
- configparser用のテストがデバッグ用になっている。ユニットテスト用のライブラリ使わねば。
method.invokeについて

動的にメソッドを呼び出して使うという機会はなかったのですが、ソースコードでたまたま見かけることが気になったので実践。

確認のためクラスを作成して試してみました。
ここではInvokeクラスで、Getmethodクラスのメソッド名を受け取り、動的に呼び出しています。
もっと工夫したら色々できそうですが、まずは手を動かして身体に覚えさせる目的でいます。

```
class Getmethod {
	public void a(){
		System.out.println("Aを呼び出しました");
	}
	public void b(String str){
		System.out.println(str + "を呼び出しました");
	}

	public void c(String str,String str2){
		System.out.println(str + "と" + str2 + "を呼び出しました");
	}
}
public class Invoke {
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {

	try {
		// クラスの取得
		Class<?> g = Class.forName("invoke.Getmethod");
		// インスタンスの取得
		Object myobj = g.newInstance();
		// メソッドの取得
		Method a = g.getMethod("a");
		Method b = g.getMethod("b",String.class);
		Method c = g.getMethod("c",String.class,String.class);
		// メソッドの実行
		a.invoke(myobj);
		b.invoke(myobj,"b");
		c.invoke(myobj,"c","d");
	} catch (ClassNotFoundException e) {
		e.printStackTrace();
	}
	}
}
```

下が実行結果です。

```
Aを呼び出しました
bを呼び出しました
cとdを呼び出しました
```


使い方についてこんな使い方があるよなどあれば編集リクエストでお待ちしております。