OmniAICreator/Qiita-1.07M huggingface dataset:
WP管理画面デイトピッカーのリアルタイムバリデーション

WPの投稿画面でデイトピッカーを使用するとき、リアルタイムで条件にあっているかを判別して、あっていない場合はアラートを出すって感じの機能を作ってみました。
使う場面があるのか本当に微妙。。。

デイトピッカーはjQueryUIのものを使用しています。

```javascript
jQuery(function ($) {
	var $_myDatepicker = $('.datepicker');

	// 公開日の取得
	var get_releaseday = function () {
		var $_timestamp = $('#timestampdiv .timestamp-wrap'),
			year = $_timestamp.find('#aa').val(),
			month = ('00' + $_timestamp.find('#mm').val()).slice(-2),
			date = ('00' + $_timestamp.find('#jj').val()).slice(-2),
			rls_day = year + "/" + month + "/" + date;
		return (rls_day) ? rls_day : false;
	};

	// デイトピッカーの実行
	var init_datepicker = function () {
		var rls_day = get_releaseday();
		$.datepicker.setDefaults($.datepicker.regional['ja']);
		$_myDatepicker.datepicker({
			dateFormat: 'yy/mm/dd',
			closeText: '閉じる',
			prevText: '<前',
			nextText: '次>',
			currentText: '今日',
			monthNames: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
			dayNames: ['日', '月', '火', '水', '木', '金', '土'],
			monthNamesShort: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
			autoSize: true
		});
		// 値が空のとき初期値を代入
		if (!$_myDatepicker.val()) {
			$_myDatepicker.datepicker('setDate', rls_day);
		}
	}();

	// デイトピッカーのバリデーション
	var valid_datepicker = function () {
		var $_publish_btn = $('#publishing-action input');

		// 最終更新日を変更したときに
		$_myDatepicker.on('change', function () {
			valid_vals();
		});

		// 公開・更新ボタンを押したときに
		$_publish_btn.on('click', function (e) {
			e.preventDefault();
			var valid_err_msg = valid_vals();
			if (valid_err_msg) {
				return false;
			} else {
				$('#post').submit();
			}
		});

		// バリデーションの実行
		function valid_vals() {
			var mdf_day = $_myDatepicker.val(),
				str_arr = mdf_day.split('/'),
				rls_day = get_releaseday(),
				err_msg = '';

			valid_format(str_arr, 3);
			valid_Ymd(str_arr);
			malid_newer(rls_day, mdf_day);

			if (err_msg) {
				alert(err_msg);
				$_publish_btn.prop('disabled', true);
			} else {
				$_publish_btn.prop('disabled', false);
			}

			// 日付形式のバリデーション
			function valid_format(array, length) {
				if (array.length !== length) {
					err_msg += '更新日のフォーマットが不正です。\nyyyy/mm/ddの形式で入力してください。\n\n';
				}
			}
			// Ymd形式のバリデーション
			function valid_Ymd(array) {
				var msg = '';
				for (var i = 0; i < array.length; i++) {
					var _self = array[i];
					switch (i) {
						case 0:
							if (!_self.match(/\d{4}/) || _self.match(/\d{4}/).input.length !== 4) {
								msg += '更新「年」の値が不正です。\n半角数字4桁で入力してください。\n\n';
							};
							break;
						case 1:
							if (!_self.match(/\d{2}/) || _self.match(/\d{2}/).input.length !== 2) {
								msg += '更新「月」の値が不正です。\n半角数字2桁で入力してください。\n\n';
							};
							break;
						case 2:
							if (!_self.match(/\d{2}/) || _self.match(/\d{2}/).input.length !== 2) {
								msg += '更新「日」の値が不正です。\n半角数字2桁で入力してください。\n\n';
							};
							break;
					}
				}
				err_msg += msg;
			}
			// 最終更新日と公開日の前後関係(公開日が先、更新日が後)
			function malid_newer(rls_day, mdf_day) {
				if (rls_day > mdf_day) {
					err_msg += '最終更新日が公開日より古いです。\n公開日は' + rls_day + 'です。\n\n';
				}
			}

			return err_msg;
		}
	}();
});
```
Docker/Rancherを使ってRedmineをバックアップ自動化まで

# Docker/Rancherを使ってRedmineをバックアップ自動化まで
まだ勉強中だから参考にしないでね

## 前提
OS : CentOS7.6
docker : なんだかよくわからないけど最新を入れる
docker-compose : なんだかよくわからないけど最新を入れる
rancher : なんだかよくわからないけど最新を入れる

## docker
何はともあれdocker

```bash
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum list docker-ce --showduplicates | sort -r
#docker-ce.x86_64            17.09.ce-1.el7.centos             docker-ce-stable
sudo yum -y install docker-ce
sudo systemctl enable docker
sudo systemctl start docker
```

## docker-compose
まだ使いこなせていない docker-compose を入れる

```bash
sudo curl -L https://github.com/docker/compose/releases/download/1.24.0-rc1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
```

## Rancher 
2.0はよくわからないので1.6

```bash
mdkir -p /root/rancher/
cd /root/rancher/
```

### 以下のファイルを作成。
CATTLE, k8s とはなんぞ。という状態。そんな私でも起動はできます。

```bash:docker-compose.yml 
version: '3'
services:
  rancher-server:
    image: rancher/server:latest
    container_name: rancher-server
    ports:
      - "8000:8080"
    environment:
      - CATTLE_DB_CATTLE_USERNAME=rancher
      - CATTLE_DB_CATTLE_PASSWORD=rancher
    volumes:
      - /root/rancher/rancher-server/mysql:/var/lib/mysql
      - /root/rancher/rancher-server/mysql-log:/var/log/mysql
      - /root/rancher/rancher-server/cattle:/var/log/cattle
    env_file: .env
    restart: unless-stopped
```

```bash:.env
以下を追加。必要なのかよくわからない。
NO_PROXY="{IP-Address}"
```


## 実行
立ち上がりを待つ

```bash
docker-compose up -d
```

## port解放
local上にRancher構築のみかわからないが、8000を開けとかないと
各スタック側のInitilizingが終わらない

```bash
firewall-cmd --add-port=8000/tcp --zone=public --permanent
firewall-cmd --reload
firewall-cmd --list-ports --zone=public
```

## Rancher設定
{IP-Address}:8000 にブラウザでアクセス

「管理者」→「設定」→「ホスト登録URL」→「サイトのアドレス」で
http://{IP-Address}:8000
を指定して保存する。127.0.0.1やlocalhostはダメ。

## Redmine
`sameersbn/docker-redmine`
とかいうのがいいっぽい。

```bash
https://raw.githubusercontent.com/sameersbn/docker-redmine/master/docker-compose.yml
```
の中身を
スタック => スタックを追加の `docker-compose.yml` に貼り付ける。
`rancher-compose.yml`のほうは勝手にやってくれるみたい。
http://{IP-Address}:10083
でRedmineを見れれば成功？

## バックアップ
(まだ)わからん。
・convoy
・dockerイメージのまるごとバックアップ
・redmineの個別データバックアップ
が選択肢としてあるのかなぁ

```bash
```
[Udemy講座]はじめてのLinuxサーバー構築運用入門　受講備忘録

# CentOS7インストール後、yum update時にエラーが表示される
<img width="874" alt="スクリーンショット 2019-02-11 22.56.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/282484/b8831d93-14fc-1e5b-f07d-829c76e0e170.png">
yum updateを実行すると、「**Cannot find a valid baseurl for repo: base**」というエラーが表示された。

ネットで調べて、ファイルの記述を変更すると解決したので、情報を共有する。

## 手順1
<img width="1012" alt="スクリーンショット 2019-02-14 23.57.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/282484/35730127-056f-8b00-dbcb-110bf0eefcde.png">

```
vi /etc/yum.repos.d/CentOS-Base.repo
```

```
[base]
#mirrorlist=http://mirrorlist.centos.org/release=$releasever&arch=~~~
baseurl=http://mirror.centos.org/centos/$releasever/os/$basearch/
``` 

上記ファイルの[base]の欄のmirrorlistをコメントアウトして, baseurlのコメントアウトをはずす。
## 手順2
<img width="1012" alt="スクリーンショット 2019-02-15 0.04.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/282484/759c526d-2293-7934-9b78-5d779b47b7c5.png">

```
[extras]
baseurl=http://ftp.riken.jp/Linux/centos/$releasever/extras/$basearch/
```
同一ファイル内の[extras]の欄に、「ftp.riken.jp」のパスを通したbaseurlの行を追加する。
上記の手順を実行すると、正常にyum updateが完了した。

以下の２つのサイトを参考にした。
<<解決方法が記載されたURL>>
[yum Error: Cannot find a valid baseurl for repo: baseの対処法](https://weblike-curtaincall.ssl-lolipop.jp/blog/?p=561)
[さくらVPSのyum update実行時に出るエラーの対処法](https://qiita.com/asukiaaa/items/f92bfa7ba6fba2aeb7ed)

【Udemy受講講座】
[はじめてのLinuxサーバー構築運用入門](https://www.udemy.com/learn-basics-of-linux/)
WSLでKuromoji.jsに単語追加

# 参考資料
WSLのインストール
https://qiita.com/Aruneko/items/c79810b0b015bebf30bb

WSLのリセット
https://www.atmarkit.co.jp/ait/articles/1807/06/news028.html

Mecabのインストール
http://tech-blog.rakus.co.jp/entry/2018/03/27/124418#MeCab%E3%81%AE%E5%B0%8E%E5%85%A5%E3%81%AE%E5%89%8D%E3%81%AB%5C

UTF-8変換／辞書作成
https://blog.apar.jp/linux/2796/

Kuromoji.jsへの登録
https://qiita.com/muraken720/items/dc67c8dc32138be7b3f8



# 手順
### Mecabのインストール
```
sudo apt update
sudo apt upgrade
sudo apt install make automake autoconf autotools-dev m4 mecab libmecab-dev mecab-ipadic-utf8 npm
```

### 動作確認
```
echo "人事を尽くして天命を待つ" | mecab
```

### 作業ディレクトリ作成
```
mkdir ~/mecab_work
cd ~/mecab_work
```

### 辞書とモデルのダウンロード
web上の情報だとURLが間違っているケースが多い。
コマンドは記載するものの、正規のURLは以下からたどること。
https://taku910.github.io/mecab/#download
![image.png](https://qiita-image-store.s3.amazonaws.com/0/255566/8fc46fe2-0013-9e51-879d-b56d6ca91be2.png)

https://taku910.github.io/mecab/dic.html
![image.png](https://qiita-image-store.s3.amazonaws.com/0/255566/b817d758-8a4f-281f-efd6-ad503c9b5351.png)

```
wget -O  mecab-ipadic-2.7.0-20070801.tar.gz "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7MWVlSDBCSXZMTXM"

wget -O mecab-ipadic-2.7.0-20070801.model.bz2 "https://drive.google.com/uc?export=download&id=0B4y35FiV1wh7bnc5aFZSTE9qNnM"
```

```
tar xvzf mecab-ipadic-2.7.0-20070801.tar.gz
nkf --overwrite -Ew mecab-ipadic-2.7.0-20070801/*
cd mecab-ipadic-2.7.0-20070801/
/usr/lib/mecab/mecab-dict-index -f utf-8 -t utf-8
```

```
bzip2 -d mecab-ipadic-2.7.0-20070801.model.bz2
nkf --overwrite -Ew mecab-ipadic-2.7.0-20070801.model
# charsetを修正する
vi mecab-ipadic-2.7.0-20070801.model
# charset: euc-jp ⇒ UTF-8
```

### ファイル作成
```person_name_tmp.csv
坂部卯太郎,,,,名詞,固有名詞,*,*,*,*,坂部卯太郎,サカベウタロウ,サカベウタロウ,（追加単語）
```

### コスト計算
```
/usr/lib/mecab/mecab-dict-index \
-m mecab-ipadic-2.7.0-20070801.model \
-d mecab-ipadic-2.7.0-20070801 \
-u person_name.csv \
-f utf8 -t utf8 \
-a person_name_tmp.csv
```

### 辞書作成
1.kuromojiのダウンロード

```
git clone https://github.com/takuyaa/kuromoji.js.git
/usr/bin/npm install
```

作成した辞書ファイルを
kuromoji.js/node_modules/mecab-ipadic-seed/lib/dictにコピー

npm run build-dict
でdictディレクトリに生成される。
* build-dictを見ると、mecab-ipadic-seedから辞書データを作っていた
c++初心者が躓く「値型、ポインタ型、参照型」

# 対象者
c/c++でif文等の制御文を理解していて
**ポインタって難しいらしいぞ。。。**
**「*,&」みたいなマークめっちゃ見るけどよくわかってないまま使ってる。。。**
って感じの人たち

# 値型
画像１(メモリ上の値は実際には２進数ですが、16進数で省略表記)
![memory_int_float.PNG](https://qiita-image-store.s3.amazonaws.com/0/358527/3d88ff40-80d2-947a-f2e4-d8a004532529.png)
ポインタの理解に困ってる人あるあるなのですが、そもそも値型が曖昧になっていることが多いので簡単に説明します。（アドレスとポインタの違いがわかる方は飛ばしていただいて問題無いと思います。）  
プログラム上で使用される全ての値は、画像１のようにメモリという物理装置に格納されます。
見てわかるとおり 変数 i,f は 同じ値(0001) ですが、プログラム側で使用する際は型という情報が与えられプログラム上での値は int と float とで異なっています。


####  値型のまとめ
> - 値はメモリというものに保存される。
> - どの型として読み取るかで全く別の物になるというもの。　

# ポインタ型
画像２
![pointer.PNG](https://qiita-image-store.s3.amazonaws.com/0/358527/d405f0f2-ee76-5219-46c5-c23e8623989c.png)
値型のところでは省略しましたが、メモリには **アドレス** という1byteずつに振られた目印が存在します。
現実で言うところの 家（値） と その住所（アドレス） のような関係だと考えてもらえればわかりやすいかもしれません。

そして、その **アドレス（0x????）を値として保持する型を〇〇ポインタといいます。**
（〇〇はそのアドレスに格納されている変数の型です。）
画像２を見ると、変数 ip は変数 i のアドレスを値として保持しているのがわかると思います。

## ポインタの宣言
「型*」(* : アスタリスク)

```サンプルコード
// intを参照するポインタの宣言
int* ip; // intポインタ
```  
**ポインタ型もただの型** なのでポインタのポインタを宣言することも可能。
ポインタのポインタを **ダブルポインタ** といったりします。

```
int** ipp; // intのダブルポインタ

// ↑と同じ意味
using IntP = int*; // intポインタ型を定義
IntP* = ipp2; // intポインタ型のポインタ
```

## インスタンスからのアドレスの取得
「&変数」（& : アンパサンド）

```
int i;
int* ip = &i;
```

## ポインタの値が指す アドレス に存在する値の取得
「*ポインタ変数」

```
// i をポインタを通して i2 に代入。
int i;
int* ip = &i;
int i2 = *ip
```
# 参照型
参照型は本質的にはポインタと同じくアドレスを保持する型です。
違いはポインタが参照先を変更出来るのに対して、参照型は初期化時以外で参照先を変えることができません。つまりconstポインタ型のようなものです。
また、コーディングも大きく異なり下のようになります。

## 参照型の宣言と代入
「型& 変数名 = 参照先変数」
参照型は初期化時のみ代入が可能な為、宣言時やメンバ初期化時に代入する必要があります。

```
int i;
int& ref = i; // &iとする必要はない。
```

## 参照型からの値の取得
「参照型変数」（通常の変数と同様の記述のみ）

```
int i;
int& ref = i;

// 値取得時も *ref 等の特別な記述をする必要がない。
int i2 = ref; 
```

# 逆引き「*, &」記号の使い方

## 「 * 」（アスタリスク）
- [ポインタ型宣言](#ポインタの宣言)
- [ポインタから参照先の値を取得](#ポインタの値が指す アドレス に存在する値の取得)

## 「 & 」（アンパサンド）
- [インスタンスからのアドレスの取得](#インスタンスからのアドレスの取得)
- [参照型の型の宣言](#参照型の宣言と代入)

※ 特にアンパサンドは紛らわしいので気をつける!!!

# 次のc++erへの道
* const Type&は特殊な型なので少し調べると面白いかも
* new delete によるインスタンスの生成、破棄。
Rangeオブジェクト

#Rangeオブジェクト
###Rangeオブジェクトとは...
ある値の範囲を扱うオブジェクトのこと。

```
range = 1..3

puts range.class
>Range
```
to_aメソッドで中身を見ると...

```
#to_aメソッドを使用して配列を生成する
puts (1..3).to_a
>[1, 2, 3]

#Rangeオブジェクトの「.」を3つにすることで最後の値は含まないものにすることができる
puts (1...3).to_a
>[1, 2]
```
数字だけでなくアルファベットのRangeオブジェクトも生成できる

```
puts ('a'..'z').to_a
>a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z

```

###eachメソッドを使ってみる

```
num = 1..31

num.each do |day|
  puts "#{day}日"
end
>1日
2日
3日
4日
5日
6日
7日
8日
9日
10日
11日
12日
13日
14日
15日
16日
17日
18日
19日
20日
21日
22日
23日
24日
25日
26日
27日
28日
29日
30日
31日

```
#「do end」は「｛｝」と同義

```
num = 1..31
num.each {|day| puts "#{day}日"}
>1日
2日
3日
4日
5日
6日
7日
8日
9日
10日
11日
12日
13日
14日
15日
16日
17日
18日
19日
20日
21日
22日
23日
24日
25日
26日
27日
28日
29日
30日
31日

```
LinqAliasってライブラリを作って公開した！

`LinqAlias`というライブラリを作って、公開しました。

`LinqAlias`は、C#において`LINQ to Objects`の一部メソッドのエイリアスを提供するライブラリです。

「他のプログラミング言語の開発経験があるけれど、C#はこれから使う初心者だよ！」という方の役に立つかもな、と思い開発しました。

GitHub : https://github.com/RyotaMurohoshi/LinqAlias
NuGet : https://www.nuget.org/packages/LinqAlias/

# どんなライブラリ？

C#は`LINQ to Objects`という素晴らしいコレクション関連の言語機能を持っています。

さて、この`LINQ to Objects`のメソッド名は、他のプログラミング言語の経験がある人は奇妙に感じるかもしれません。

例えば、

* `Where`メソッドの公式ドキュメントの説明は「述語に基づいて値のシーケンスをフィルター処理します。」となっています。他の多くのプログラミング言語では、このようなメソッドは`Filter`という名前です。（選択）
* `Select`メソッドの公式ドキュメントの説明は「シーケンスの各要素を新しいフォームに射影します。」となっています。他の多くのプログラミング言語では、このようなメソッドは`Map`という名前です。（射影）

`LinqAlias`は、`Where`や`Select`などの`LINQ to Objects`の一部のメソッドに、エイリアスを提供するライブラリです。

具体的には、

* `Map`メソッド : `Select`メソッドのエイリアス。（内部的に`Select`を呼び出す）
* `Filter`メソッド : `Where`メソッドのエイリアス。（内部的に`Where`を呼び出す）

などです。これにより次のような`Select`・`Where`を用いたC#のコードが、

```csharp
var resultArray = sourceArray
  .Select(it => it * it)
  .Where(it => it % 2 == 0)
  .ToArray();
```

一部のプログラミング言語経験者に馴染みのある`Map`・`Filter`というメソッド名で同様の処理を記述できます。

```csharp
var resultArray = sourceArray
  .Map(it => it * it)
  .Filter(it => it % 2 == 0)
  .ToArray();
```

# 提供メソッド一覧

* Filter : [Where](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.where?view=netstandard-1.0)のエイリアス
* Map : [Select](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select?view=netstandard-1.0)のエイリアス
* FlatMap : [SelectMany](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.selectmany?view=netstandard-1.0)のエイリアス
* ForAll : [All](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.all?view=netstandard-1.0)のエイリアス
* Exists : [Any](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.any?view=netstandard-1.0)のエイリアス
* Reduce : [Aggregate](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.aggregate?view=netstandard-1.0)のエイリアス
* Fold : [Aggregate](https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.aggregate?view=netstandard-1.0)のエイリアス

# 本当は・・・

「郷に入っては郷に従え」という言葉があります。

C#では`Map`・`Filter`ではなく、`Select`・`Where`なので、「他のプログラミング言語の開発経験があるけれど、C#はこれから使う初心者だよ！」という方にも、そちらを覚えて欲しいと実は思っています。

今後`LinqAlias`の亜種として、`Filter`を使うと「C#では`Filter`じゃなくて`Where`だよ」という警告を表示するやつも作ろうかと計画中です。

（Obsoleteで、メソッド利用箇所に警告を出せるけれど、該当メソッドがObsoleteな訳じゃないから、これを使うのはな・・・）

# 補足: WhereとSelectという名前の補足

C#においてLINQは`クエリ構文`というSQL風な記述ができます。その点を考えると、選択が`Where`で、射影が`Select`という名前は納得できますね。
railsアプリをherokuにデプロイするとき割とつまづいたのでメモ

自分用のメモです。

* macOS
* brewインストール済み
* rbenvインストール済み
* Heroku CLIインストール済み

の前提ですのでご注意ください。

----------

### 新しいrubyをインストールしてrailsアプリを作成

```console
$ brew update && brew upgrade ruby-build
$ rbenv install 2.6.1
$ gem install bundler
$ gem install rails
（2019/2/16現在、bundler 2.0.1 と rails 5.2.2 がインストールされました）
```

```console
$ rails new hoge
$ cd hoge
（この後、いろいろ作り込む）
```


### ある程度出来上がったので、デプロイしようとする

```console
$ heroku login
$ heroku git:remote -a heroku側のアプリ名
$ git push heroku master
```

### bundler関係のエラーが出て、デプロイに失敗する

```console
remote: -----> Ruby app detected
remote: 
remote:  !
remote:  !     You must use Bundler 2 or greater with this lockfile.
remote:  !
```

ローカルのbundlerは2.0.1だが、herokuは対応していないらしい。
↓の記事が非常に参考になった。
https://qiita.com/yoshijbbsk1121/items/87250501b32c6433943e

公式の情報が欲しくて探してみたが、 ~~この記事執筆時点(2019/2/16)ではハッキリした情報は得られなかった。~~

<details><summary>[追記] 2019/2/19 に bundler2.0.1 に対応したようです。公式にも情報が追加されてました。</summary>
<div>
この記事書いたのが 2019/2/16 だから、タッチの差でしたね・・・
https://devcenter.heroku.com/changelog-items/1563
https://devcenter.heroku.com/articles/ruby-support#libraries
https://devcenter.heroku.com/articles/bundler-version
</div></details>


### 仕方がないのでbundlerをダウングレードすることにした。

```console
$ gem install bundler -v 1.17.2
$ gem uninstall bundler -v 2.0.1
$ rm Gemfile.lock
$ bundle install
```

注）今回は作りたてのアプリだったので、Gemfile.lockを丸ごと消すという荒技を行ったが、本当は `BUNDLED WITH` の行だけを消すのが良いと思う。


### 再度デプロイにトライ。しかし、別のエラーがでる。

```console
$ git push heroku master
```

```console
remote:        Running: rake assets:precompile
remote:        Yarn executable was not detected in the system.
remote:        Download Yarn at https://yarnpkg.com/en/docs/install
remote:        rake aborted!
remote:        Uglifier::Error: Unexpected character '`'
...中略...
remote: 
remote:  !
remote:  !     Precompiling assets failed.
remote:  !
remote:  !     Push rejected, failed to compile Ruby app.
```

ES6の機能を使うとプリコンパイルが通らないらしい。
↓の記事が非常に参考になった。
https://qiita.com/Thort/items/18c44604aba65303c221


### 再度デプロイにトライ。今度は成功！

* Active Storageの設定がlocalになってるよ、と警告されたけど、とりあえずファイルアップロードする予定ないので無視
* なんかProcfile作っとけって警告されたけど、今日は疲れたので無視

↓ また今度、元気なときに読みます
https://devcenter.heroku.com/articles/active-storage-on-heroku
https://devcenter.heroku.com/articles/ruby-default-web-server


### migrateしてseed投入して終わり！

```console
$ heroku run rake db:migrate
$ heroku run rake db:seed
```

疲れました。
grepの奇跡 

# お題

- 以下のサンプルファイルから7行目が `T` の行のみを抽出する
- 以下のサンプルファイルから7行目が `F` を行のみを抽出する

```text:サンプルファイル
2018-11-14T02:37:34.399Z,35125321,,,,,T,4211421,463412,4214343534,424321,
2018-11-14T02:37:35.399Z,35125321,,,,,T,4211421,412412,42576434,424321,
2018-11-14T02:37:36.399Z,34135321,,,,,F,421221,41762,4246534,4241,
2018-11-14T02:37:37.399Z,354535321,,,,,T,4211421,412,421434,424321,
2018-11-14T02:37:38.399Z,34135321,,,,,F,421221,41762,4246534,41,
...
...
...
3万行
...
```

特徴
 - `,` 区切りのCSVファイル
 - 1行目に列名はない
 - TとFが出現する場所は7列目に固定されている
 - 1列目は T Z を含むタイムスタンプ

# 最悪の選択肢を選ぶ

上記のタスクを上司から振られたらどうしますか？
普通だったら、grepでいけそうですよね。以上ですよね。



ここで馬鹿な私は普通にatom開いて、shellscriptを書き始めました。あんまりshell書いた経験ないのに。
1時間以上かけた。
grepなら2分だろうな(考える時間も込みで)

作ってしまったのは仕方ないので、二度と同じ失敗をしないようにしたい。
間違えてしまったのはなぜだ。明らかに ` 2分で終わるタスクを1時間もかけたこと ` はエンジニアとしてよくないことだ。
おそらくfile形式がcsvであるので、エクセルで処理した方がもっと早かっただろう。
なぜ、シェルスクリプトを書く方法しか思いつかなかったのだろう。
` 筋の悪い解法を選ばないために、何ができるのだろう ` っていう問題に帰着できるだろう。
これはもう少し考えて、別の記事にしたい。というか今は ` できる先輩に相談する ` くらいしか思いつかない。

 `ググる ` のはどうだろう? 検索キーワードを打ち込むまで解法が思いついていないと意味がない気がする。
` csvファイル　該当文字列 行　抽出 ` とかで調べてしまうだろう。 良い解法にたどり着けるかはちょっと自信ないな。
 
シェルスクリプト書くの難しかったな。
変数を使うのが ` $((変数名)) ` , ` ${変数名} ` だったりする。違いなに？ 基本的なことを勉強できていない証拠だ。 (今度勉強して記事にしよう)

# 出来上がったシェルスクリプト
動作確認した環境はMacOS High Sierra

```bash:shellscript
#! /bin/bash

# set -x
echo $1
sorcefilepath=$1

echo $2
targetfile=$2

cat $1 | while read row;
do
  flag=$(echo ${row} | cut -d',' -f7)
  # echo $flag

  # echo $((row)) | cut -d',' -f7 | read flag;
  # echo $((flag))
  if [ ${flag} = "T" ]
  then
    # echo $row
    echo $row >> ${targetfile}
  fi
  # echo normal
done

``` 


# 実行時間

```text:実行結果
$ time sh ./csv_allocate.sh sample.csv newfile.csv
sample.csv
newfile.csv

real	4m15.998s
user	1m20.583s
sys	2m50.077s
```

おっっそ。なんでやねん。


# grepの奇跡

やっと
grepでできるやん
ってひらめいた。
普段よくgrepは使うのに、なんで第一候補に出て来なかったんだorz

```text:実行結果2
$ time grep -v F sample.csv > newfile2.csv

real	0m0.065s
user	0m0.030s
sys	0m0.015s
```

はっや。コマンド叩いた瞬間に結果返ってきた。

# これから調べたいこと
 - なぜgrepが速いのか 
 - shellの変数の使いかた
MacにRedmineを入れて社内で共有するまでやってみたが壮大な冒険になった

## 目標
1. MacにRedmine入れて、社内ネットワークを介して自分に割り振られているIPに接続すると、他の社員でもRedmineに入れるようにする
2. デフォルトだと見た目がアレなので、プラグインを入れて動かす

ちなみに、Ruby知識もRails知識も0。後述のdockerも初めてだし、Redmineを立てるのも今回が初めてだった。表現の齟齬は許してほしいのです・・

## 下準備
Dockerのインストール
https://www.docker.com/

もしくは`brew cask`でインストール

```
$ brew cask install docker
```


それから、easy ganttのインストール
https://www.easyredmine.jp/en/redmine-gantt-plugin

## やったこと
### ボツ案1 BitnamiでRedmine
https://yuki222.com/redmine/
↑を参考にスタート。なるほど、あっという間に出来上がった。
共有するのもGUIでサクッとできた。

しかし、プラグインをいれるのに実体がわからない。
様々なサイトを参考にするも、そもそもパスが合わなかったり初心者向きではなかった気がする。
そして、壊してしまった😅

**もっとシンプルなやつにしよう、そうだシンプルイズベスト！！**

### ボツ案2 MacにそのままRedmineを置く
https://qiita.com/janus_wel/items/06dae0dec1ff1a886d54
↑を参考にインストール。

しかし、Apatchの設定がうまく行かず断念。。
不躾ながらコメントを残しているのですが、`rails server`で起動されるところまでは確認できました。

`passenger-install-apache2-module`まわりがうまくいかない上にサーバー知識がほぼ0なので、原因を突き止めることができずに断念。MAMPも心なしか不調になってしまったので、そのままMacにインストール案は断念。

**サーバーの勉強しなきゃな。という意思が1.5倍強くなる**



### 採用案 DockerでRedmineを置く

```
$ docker pull redmine
$ docker run -p 3000:3000 --name redmine redmine
```

引用) https://qiita.com/mojihige/items/de95d8aeb0587e149128

こんな感じで、コンテナの生成に成功。すでに自分に割り振られたIPにアクセスすると社内ネットワーク上の他のデバイスでもブラウザにRedmineが表示されることが確認できた。走り出しは思いの外ラクチン。

しかし、ここでもプラグインでつまづく。**その様子と採用案の詳細は下記にまとめた**。

[[docker/redmine4.0.1]プラグイン"easy gantt"を入れようとすると怒られる](https://qiita.com/missyyy/items/9706ee3705cc8cb73b76)

`bundle exec rake redmine:plugins:migrate RAILS_ENV=production`をしたとき、エラーを残したままDockerのシェルの中から退出したら、起動できなくなり、シェルの中に入ることもできなくなり、どうしようもなくなったので消したエピソードもある。今後はエラーを残してシェルの中から出ないように気をつけようと思った。

結局作ったイメージとコンテナは捨てて

```
$ docker pull redmine:3.4.8
$ docker run -p 3000:3000 --name redmine redmine3.4.8
```

ブラウザでRedmineがうまく表示されることを確認。ホスト側のプラグインの入ったディレクトリをDocker側へ転送し、下記を実行。

```
$ docker exec -i -t {{コンテナ名}} bash
// コンテナの中に入る 
$ ls ←Redmine直下かつGemfileがある階層にいることを確認
// 自分はplugin/の中に入って"git clone"で入れられるタイプのプラグインをいくつか入れ、また元の階層へ戻った
$ bundle install
$ bundle exec rake redmine:plugins:migrate RAILS_ENV=production
```

コンテナを再起動。Redmineにプラグインが入ったことが確認できた。

"easy gantt"以外のプラグインは下記の記事を参考に選んだ。
https://qiita.com/y_hokkey/items/7c02a3af319b353136d5

## まとめ
- **MacでRedmineを動かしたいときは、Dockerを利用するのが良さそう。一番不具合なく、ソースも多いので対応しやすいと思った**
- この一連の流れでRedmineに強くなった気がするし、Dockerに対しての謎の抵抗がなくなり、むしろ便利かもと思えるようになった
- Apatchに対する謎は拭えなかった
- Railsのエラーを通してRubyに興味を持った
- 今後のRedmineの運用方法、主にバックアップのとり方を考えることが次のタスクになった

その他ここでは補えなかった詳しい解決法は[[docker/redmine4.0.1]プラグイン"easy gantt"を入れようとすると怒られる](https://qiita.com/missyyy/items/9706ee3705cc8cb73b76)にまとめた。

(たぶん今ボツ案1やったらうまくいくかもしれない。。)
ExpressのProgreSQL　node-postgres　Ver.6系⇒7系　記述方法比較

#はじめに
node-postgresを使おうとして、
pg.connect is not a function がでたらVer違いによる記述方法の違いが原因なので
下記を参考に変更すると対応できると思います。
Ver.6系⇒Ver.7系で記述方法が大きく変わりました。

#pg@6までの記述方法
```index.js
var express = require('express');
var router = express.Router();
var pg = require("pg");

router.get('/', function(req, res) {
  var conf = "tcp://user:password@localhost:5432/user_db";
  pg.connect(conf,function(err,client){
    if(err){
      console.log(err);
    } else{
      client.query("SELECT * from mydata",function(err,result){
        res.render("index",{
          datas : result.rows
        });
      });
    }
  });
});

module.exports = router;
```

#pg@7での記述方法
```index.js
var express = require('express');
var router = express.Router();
var pg = require("pg");

router.get('/', function(req, res) {
  var pool = pg.Pool({
    database: 'user_db',
    user: 'user',
    password: 'password',
    host:"localhost",
    port: 5432
  });
  pool.connect(function(err,client){
    if(err){
      console.log(err);
    } else{
      client.query("SELECT * FROM mydata",function(err,result){
        res.render("index",{
          datas : result.rows
        });
      });
    }
  });
});
module.exports = router;
```
よかったら参考にしてください。
学習メモ「Python機械学習プログラミング」

[第2版]Python機械学習プログラミング
# 1-2章：機械学習
教師あり・・・教師信号あり→人がクラスタリングする（答えのパターンを用意する）
教師なし・・・教師信号なし→クラスタリングしてアウトプットする（答えのパターンが決まっていない）
強化学習・・・自分でどんどん学習していくやつ

## 機械学習のステップ
前処理(クレンジング、次元削減)→学習・訓練(ハイパーパラメータ最適化)→評価→予測
## 前処理
次元削減・・・特徴を表す次元を統計的に分析し、割合の高いものを学習対象とする。
## 学習・訓練(トレーニング)
ハイパーパラメータ最適化・・・y=ax+bx^2+cx^3などのa,b,cがハイパーパラメータ
最適化はパラメータ数と値、数が多すぎても少なすぎても極端な値になりがち
 ニューラルネットワークのパーセプトロン・・・答えがあるやつなら強い
学習アルゴリズム・・・SVM,ランダムフォレスト、パーセプトロン etc.


### ニューラルネットワーク
 ・アルゴリズム：パーセプトロン＿＿＿離散出力(0or1)を学習に使い、離散出力(0or1)を結果として返す。
 ・アルゴリズム：ADALINE＿＿＿連続出力(0~1)を学習に使い、離散出力(0or1)を結果として返す。

 連続出力を組み込む価値は微分可能→コスト関数(誤差平方和)を二次関数にすると、最適値を微分して求められる。

#3章： scikit-learn:機械学習のライブラリ
## 機械学習の手順
基本的な機械学習ロジックはライブラリが提供されているため、チューニングの勘所を見極めるのが大事
①特徴量・・・画像はピクセル、色などで構成されるが、ベクトルとしてどの要素を捉えるか。
②性能指標・・・性能の良し悪しを何でみるか
③分類器とアルゴリズム性向・・・医療機器の品質チェックだと、失敗は許されないテストなので◯を×と行ってはいいが×を◯と言わない方が良いなど。
　　分類器・・・ADALINE、パーセプトロン
④モデルの評価・・・目的の達成度、正解率などを定義して評価する
⑤ハイパーパラメータのチューニング・・・パーセプトロンに固定値の値を流し込む。
＜わかっているふりをするためのポイント＞
①、②は外部のライブラリをそのまま使い、③の方針を自分で決めていて、
④を良くなるような⑤を探す繰り返す。
このような運用していますとプレゼンできたらいいらしい。

## ロジスティック回帰：確率分布を出すために存在している
尤度・・・分析結果の尤もらしさの程度を表すもの。
  ロジスティック回帰分析したら、0,1,2に振り分けるケースがあったとして、
  ギリギリ1なのか完全に1なのか、尤もらしさの程度を表すもの。
  尤もらしさがわかるのが、ロジスティック回帰分析の嬉しみ。
  (0:0%,1:100%,2:0%と0:33%,1:34%,2:33%では同じ1でも違う)

機械学習の手順③に尤度の考えを組み込むと評価に幅を持たせられる
尤度の最大化≒コスト関数(誤差平方和)の最小化


## アルゴリズム：サポートベクターマシン（support vector machine, SVM）
教師あり学習（◯、×がある）を用いるパターン認識モデルの一つである。分類や回帰へ適用できる
特徴量が2次元なら1次の平面、特徴量が3次元なら2次元の平面を見つけ出すためのモデル。
SVMであるxのとき(最小マージン)を最大化するような直線の傾きが求められる。
  マージン=それぞれの点(◯、×)と平面の距離
  最小マージン=◯から平面の距離の一番小さいもの + ×からの平面の距離の一番小さいもの

※ラグランジュの未定乗数法で計算を簡略化できるらしいが偉い人が頑張るらしい。
### ハードマージンとソフトマージン
　カーネル：機械学習の大量の結果データから統計的に導き出したアルゴリズム
　　カーネルによって計算量が減るから皆、公理化された暗黙の了解ロジックとして使われる

## アルゴリズム：ランダムフォレスト（random forest）
　決定木・・・質問を分割したら答えが求まる
　https://mathwords.net/randomforest
　不純度・・・正規(50:50)に近いほど低い。偏りがあるほど答えが導きやすく高い。
　　　　　　A,Bで100%がAorBで構成されるなら純度100%で不純度が低いとみなせる。

## k近傍法：怠惰学習アルゴリズム
　アメリカの大統領選挙方式

# 4章：前処理
訓練データ(トレーニングデータ、教師データ)をどうそろえるか？
汎化性能をあげるためには？
欠損値対策・いろんなトレーニングデータを揃える
過学習対策・パラメータが少ないモデルにする
偽相関対策・データの次元数を減らす→次元を減らす
過学習対策・正則化を使って、ペナルティ・重みの影響を減らそう

##次元削減
a,b,c,d,eの5次元パラメータをあったとき、4次元にして検証しやすくする。
　特徴選択・・・cを消去する。a,b,d,eの4次元へ
　特徴抽出(特徴圧縮)・・・a,bからαをつくる。α,c,d,eの4次元へ
   ・ PCA（主成分分析）・・・教師なし次元削減（5次元のベクトルをクラスタリングして3次元のベクトルにする）
   　　　線形分離できないときに使えない。
   ・ LDA（線形判別分析）・・・教師あり次元削減
   ・ KPCA（カーネル主成分分析）・・・線形分離できないときにカーネルの仕組みを使って主成分分析をする。
JavaScriptのあらゆるものがObjectのように振る舞うとは

# あらゆるものがObjectのように振る舞う
JavaScriptを学び始め

『あらゆるものがObjectのように振る舞う』

ということは本などで目にしていたがあまりピンと来なかった。

これを初心者の僕が納得できる本を見つけた。

# 認識を深めることができた本
『開眼！JavaScript』の15ページのNOTEに書かれていた。

#『あらゆる...』とはどういうことか

<img width="189" alt="スクリーンショット 2019-02-17 1.25.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/255152/60c4b1b8-06fd-cb61-cd61-ca580d24a109.png">

このような文字列をリテラルで記述するとオブジェクトではなく、プリミティブ型としての性質を持ちます。

つまり、```foo```はオブジェクトではなくプリミティブなのでオブジェクトのメソッドやプロパティにはアクセスすることができないはずです。

しかし、
<img width="226" alt="スクリーンショット 2019-02-17 1.27.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/255152/636e347e-02c9-a160-b725-7605427ef6fd.png">

プリミティブである```foo```がStringオブジェクトのメソッドを利用できています。

これは、JavaScriptがプロパティにアクセスしようとするとプリミティブ値を補完するラッパーオブジェクトを一時的に生成するのです。(```foo.length```)

これによりラッパーオブジェクトによりStringオブジェクトのメソッドやプロパティを利用できます。目的のメソッドが実行されるとプリミティブ値に戻ります。

つまり、

『JavaScriptはObjectばっかりだ』

というよりも

『JavaScriptはすべてがObjectのようにふるまう』

が正しい。

# 結論

裏でプリミティブ⇄オブジェクトのような変換を行うことで、全てがObjectのように振る舞えるようにやっているんだ、と認識を改めることができた。
c++の基本を備忘録的にまとめていく Part3 (libcurl)

最近無性にc++をやりたい

### やったこと
libcurlをインストール & mnistをダウンロードした。

とりあえず機械学習のド定番mnistによる文字認識をやろうと思い、mnistをダウンロードしようと思った。

以下コマンドs

```
brew install curl
```
これで

```
#include <curl/curl.h>
```

でインクルードできるはずだと思ったが、問題が

```:error
Undefined symbols for architecture x86_64:
  "_curl_easy_cleanup", referenced from:
      _main in libcurl-e55a4c.o
  "_curl_easy_init", referenced from:
      _main in libcurl-e55a4c.o
  "_curl_easy_perform", referenced from:
      _main in libcurl-e55a4c.o
  "_curl_easy_setopt", referenced from:
      _main in libcurl-e55a4c.o
ld: symbol(s) not found for architecture x86_64
```
みたいなエラーメッセージが、
pathとか確認したり、色々やった果てに
[同じエラーをstack overflow](https://stackoverflow.com/questions/3840957/lib-curl-symbol-not-found)にて発見,
コンパイルする時`-lcurl`オプションをつければ良いらしい

```
g++ test.cpp -lcurl
```
コマンドだとこんな感じでコンパイル出来た。

そして以下がダウンロード用のプログラム

```cpp:download_mnist.cpp
#include <stdlib.h>
#include <curl/curl.h>
#include <iostream>
#include <string>

void download_mnist() {
  FILE *fp;
  std::string read_filenames[4] = {
    "train-images-idx3-ubyte.gz",
    "train-labels-idx1-ubyte.gz",
    "t10k-images-idx3-ubyte.gz",
    "t10k-labels-idx1-ubyte.gz"
  };

  std::string out_dir = "./datasets/mnist";
  std::string out_filenames[4] = {
    "train_images",
    "train_labels",
    "test_images",
    "test_labels"
  };

  CURLcode res;
  std::string url, out;
  for (unsigned i = 0; i < 4; i++) {
    curl = curl_easy_init();
    url = "http://yann.lecun.com/exdb/mnist/" + read_filenames[i];
    out = out_dir + "/" + out_filenames[i] + ".gz";

    if ( (fp=fopen(out.c_str(), "wb")) == NULL ) {
      std::cout << "can't open file" << std::endl;
      std::exit(EXIT_FAILURE);
    } else {
      std::cout << "downloading "<< out_filenames[i] << "..." << std::endl;
      curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
      res = curl_easy_perform(curl);
      if (res != CURLE_OK) {
        std::cout << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
        std::exit(EXIT_FAILURE);
      }
      curl_easy_cleanup(curl);
     }
    fclose(fp);
    std::cout << "downloaded " << out_filenames[i] << "." std::endl;
  }
}

```

簡単にまとめると
curl_easy_init(): curlポインタの初期化, このcurlに色々な情報が格納されている？
curl_easy_setopt: ダウンロードするurlとか、関数とか、出力先を設定する
curl_easy_perform: curlのレスポンスを取得
curl_easy_cleanup: curlポインタの解放
みたいな感じだと思われる。

###感想
curlはコマンドで打つべし
また、libcurlはc++の基本ではないのでは？という疑問が拭えない

次回こそはclassについてまとめるはず

こんなコードあるよとか、こここうした方がいいのでは？＞＜というコメントとても大切で嬉しいです
### 参考
https://curl.haxx.se/libcurl/c/
競技プログラミングのための標準値入力~python編~

## はじめに
最近pythonで競技プログラミングに取り組む人が増えているらしいので初心者は詰まるのではないかと思ったので書きます。
私が競プロを始めた頃は今ほど教材が揃っておらず、標準値入力が分からなくてかなり困りました。
![2019-02-17.png](https://qiita-image-store.s3.amazonaws.com/0/169545/bdaa1c0a-f002-e59f-f18a-edb4b07747f4.png)


## 内容
### 1行に数字一つ

```python:qiita.py
n = int(input())
```

### 1行にスペースを挟んで数字を複数

```python:qiita.py
#二つの場合
a, b = map(int, input().split())
```

### 1行に文字列一つ

```python:qiita.py
s = input()
```

### 1行にスペースを挟んで文字列を複数

```python:qiita.py
a, b = input().split()
```

### m列の数字
具体的には[こちら](https://atcoder.jp/contests/abc117/tasks/abc117_c)

```python:qiita.py
n, m = map(int, input().split())
a = list(map(int, input().split()))
print(a)

>>[10, 12, 1, 2, 14]
```

### n行の数字
具体例は[こちら](https://atcoder.jp/contests/abc046/tasks/arc062_a)

```python:qiita.py
n = int(input())
a = [list(map(int, input().split()))for i in range(n)]
print(a)

>>[[2, 3], [1, 1], [3, 2]]

##別解
n = int(input())
T = [0]*n
A = [0]*n
for i in range(n):
    T[i], A[i] = list(map(int, input().split()))
print(T, A)

>>[2, 1, 3] [3, 1, 2]
```
### h行w列の文字列
具体例は[こちら](https://atcoder.jp/contests/atc001/tasks/dfs_a)

```python:qiita.py
h, w = map(int, input().split())
graph = [list(input())for i in range(h)]
print(graph)

>>[['s', '#', '#', '#', '#'], ['.', '.', '.', '.', '#'], ['#', '#', '#', '#', '#'], ['#', '.', '.', '.', 'g']]
```

## おわりに
個人的な感想としてProgateの後に実装力を身に付けるという意味では競プロはオススメです。
間違いや質問がありましたら、コメント、編集リクエストをお願いします。
[docker/redmine4.0.1]プラグイン"easy gantt"を入れようとすると怒られる

## 背景

はじめてのDockerではじめてのRedmine(4.0.0)をインストール。
ここまでは無事だった。社内のひとからもアクセスしてもらって一安心。ちゃんと動く。

しかし、新たなハードルとして、デフォルトであの使いづらそうなUIをどうにかして少しでも美しく整えたい。そうだ、Redmineのプラグインだ！！

しかし、人気プラグイン**"easy gantt"**がすんなり入れられなかったときの話。

## 環境
Before

```
- docker
- Redmine 4.0.1 (latest)
- Rails 5.2.2
- easy gantt
```


## 道のり
プラグインをplugins/の中に入れて`bundle install`したあとに下記を実行し、エラーが発生した。

```
$ bundle exec rake redmine:plugins:migrate RAILS_ENV=production
rake aborted!
NoMethodError: undefined method `to_prepare' for ActionDispatch::Callbacks:Class
Did you mean?  to_param
```

さっそくググってみると

> to_prepareコールバックは、`ActiveSupport::Reloader`に移ったみたいですね。たぶんほとんどのプラグインで修正が必要かと。
(該当のコードの修正でいうと `ActiveSupport::Callbacks.to_prepare` に書き換える、ではダメかもしれません。本体のコード読む限りでは4系でdelegateしてたのがしなくなっているように見えた。`ActiveSupport::Reloader.to_prepare`かな？ちょっとやってみないとわからないですが。)
あと、4系以前と5系の両対応する必要がありますね。

引用) https://github.com/agileware-jp/redmine_work_days/issues/16


とある。要するにRedmine4.0.0で使われているRails5.2.2では"easy gantt"で使われている関数のバージョンが合わずにエラーが起きてしまうということだろう。では、`Rails4.2.11`はどうだろうかと思い、Gemfileを書き換えてRailsをダウングレードしたが今度は他の部分で**『勝手にダウングレードしないでね』と言わんばかりにエラーが発生**。そうですよね・・


本当はGemfileを読み解いたり、Rubyで修正するのが正統派なんだろうけれども、時間もないし、知識も足りない。

ってことで、**結局Redmineのバージョンを下げることで解決した**。

## 解決法

```
$ docker rm {{コンテナID}}
$ docker rmi {{イメージ ID}}
```
混同しないように前もって既存のコンテナ・イメージを消しちゃう。

https://hub.docker.com/_/redmine?tab=tags にアクセスして、良さそうなバージョン(正しくは"タグ")を選ぶ。今回は`3.4.8`を選びました。


```
$ docker pull redmine:3.4.8
docker run -p 3000:3000 --name redmine redmine:3.4.8
```
あとはホスト上にある"easy gantt"のプラグインディレクトリをDocker側に転送。

https://qiita.com/gologo13/items/7e4e404af80377b48fd5
上記を参考に転送しました。


```
$ docker exec -i -t {{コンテナ名}} bash
$ bundle install
$ bundle exec rake redmine:plugins:migrate RAILS_ENV=production
```

して、`Exit`し、`docker restart`でDockerを再起動したら"easy gantt"が入っていることを確認できると思います。

### まとめ

Redmine4系だと"easy gantt"がうまく入らないので、"easy gantt"使いたい方はRedmine3系以下にダウングレードして使おう。

もちろん、ひとつひとつ紐解いて4系を使ってもいいのかもしれない。そんなの尊い。
超お手軽にブラウザ上で形態素解析（MeCab@colob)

↓のリンクをブラウザで開くだけで超お手軽に試せます。

[colab] (https://colab.research.google.com/gist/zaq9/298f05363c5e3fa15a44c4bf30d1165f/test_mecab.ipynb)

##Google colab 上でのインストール:

```python
!sudo apt-get install mecab mecab-ipadic-utf8 libmecab-dev swig
!pip install mecab-python3

```

##テスト１：すももももももものうち

```python
import MeCab
mecab = MeCab.Tagger ("-Ochasen")
print(mecab.parse("すもももももももものうち"))

```
###テスト１の出力結果:
```text
すもも	スモモ	すもも	名詞-一般		
も	モ	も	助詞-係助詞		
もも	モモ	もも	名詞-一般		
も	モ	も	助詞-係助詞		
もも	モモ	もも	名詞-一般		
の	ノ	の	助詞-連体化		
うち	ウチ	うち	名詞-非自立-副詞可能	
```


##テスト２：森のくまさんの歌詞

```python

kuma = """
ある日　森のなか
クマさんに　出会った
花咲く　森の道
クマさんに　出会った

クマさんの　いうことにゃ
お嬢さん　おにげなさい
スタコラ　サッササノサ
"""
print(mecab.parse(kuma))

```

### テスト2　出力結果：
```text

ある	アル	ある	連体詞		
日	ヒ	日	名詞-非自立-副詞可能		
　	　	　	記号-空白		
森	モリ	森	名詞-固有名詞-人名-姓		
の	ノ	の	助詞-連体化		
なか	ナカ	なか	名詞-非自立-副詞可能		
クマ	クマ	クマ	名詞-固有名詞-人名-名		
さん	サン	さん	名詞-接尾-人名		
に	ニ	に	助詞-格助詞-一般		
　	　	　	記号-空白		
出会っ	デアッ	出会う	動詞-自立	五段・ワ行促音便	連用タ接続
た	タ	た	助動詞	特殊・タ	基本形
花	ハナ	花	名詞-一般		
咲く	サク	咲く	動詞-自立	五段・カ行イ音便	基本形
　	　	　	記号-空白		
森	モリ	森	名詞-固有名詞-人名-姓		
の	ノ	の	助詞-連体化		
道	ミチ	道	名詞-一般		
クマ	クマ	クマ	名詞-固有名詞-人名-名		
さん	サン	さん	名詞-接尾-人名		
に	ニ	に	助詞-格助詞-一般		
　	　	　	記号-空白		
出会っ	デアッ	出会う	動詞-自立	五段・ワ行促音便	連用タ接続
た	タ	た	助動詞	特殊・タ	基本形
クマ	クマ	クマ	名詞-固有名詞-人名-名		
さん	サン	さん	名詞-接尾-人名		
の	ノ	の	助詞-連体化		
　	　	　	記号-空白		
いう	イウ	いう	動詞-自立	五段・ワ行促音便	基本形
こと	コト	こと	名詞-非自立-一般		
にゃ	ニャ	にゃ	助詞-特殊		
お嬢さん	オジョウサン	お嬢さん	名詞-一般		
　	　	　	記号-空白		
お	オ	お	接頭詞-名詞接続		
にげ	ニゲ	にげる	動詞-自立	一段	連用形
なさい	ナサイ	なさる	動詞-非自立	五段・ラ行特殊	命令ｉ
スタコラ	スタコラ	スタコラ	名詞-一般		
　	　	　	記号-空白		
サッササノサ	サッササノサ	サッササノサ	名詞-固有名詞-組織	

```


「サッササノサ」は固有名詞らしい…


##失敗したこと:

[Windows で pip で mecab-python をいれる](https://qiita.com/yukinoi/items/990b6933d9f21ba0fb43)

 の記事を試してみたけど、うまく動きませんでした（Versionは出たけど解析時RunTimeError)
現状だとWindows上で頑張るよりWSLやDocker等挟んでLinux環境で構築した方が楽そうな模様。
railsのroutes.rbの書き方はちゃんと覚えようって話

## 環境
- cloud9
- Rails 5.2.2

## routes.rbを書き換えたかった

よくある「/」に対するルーティングを書きたかった。
以下の例では「home/top」を「/」にしたかった。

```
Rails.application.routes.draw do
  get 'sing/in'
  get 'sing/out'
  get 'sing/up'
  get '/' => 'home/top'
  get 'home/about'
  get 'card/show'
  get 'list/show'
  get 'list/add'
end
```

ほいほい、それじゃあ実行してこー。

```
$ rails server
=> Booting Puma
=> Rails 5.2.2 application starting in development 
=> Run `rails server -h` for more startup options
Exiting
/usr/local/rvm/gems/ruby-2.4.1/gems/actionpack-5.2.2/lib/action_dispatch/routing/mapper.rb:329:in `check_part': Missing :action key on routes definition, please check your routes. (ArgumentError)
        from /usr/local/rvm/gems/ruby-2.4.1/gems/actionpack-5.2.2/lib/action_dispatch/routing/mapper.rb:318:in `check_controller_and_action'
　　(以下略)
```

どーーぉしてーえーえぇー！(サカナクションのアイデンティティっぽく)
「=>」を「->」に変えて「それシンタックスエラーやで」と怒られてみたり、矢印の向きを逆にしてみたりといろいろやって5分経過。

## 解：「/」を「#」に変更

正しい書き方はこちら。

```
Rails.application.routes.draw do
  get 'sing/in'
  get 'sing/out'
  get 'sing/up'
  get '/' => 'home#top'
  get 'home/about'
  get 'card/show'
  get 'list/show'
  get 'list/add'
end
```

なんでこんなことでハマってんだと自己嫌悪になりながら、自戒を込めてメモメモ。
Django2.1でのカスタムmiddlewareの実装方法

# 概要

Django2.1で開発中のシステムでミドルウェアを実装した時にディレクトリ構造やファイル名、MiIDDLEWAREへの指定方法で迷ったので記録しておきます。参考になれば幸いです。

- Django 2.1.4
- Python 3.6.7
- django-allauth 0.38.0
- Ubuntu 18.04.2 LTS

# 参考にした記事

- [Django2.1 公式ドキュメント(ミドルウェア)](https://docs.djangoproject.com/ja/2.1/topics/http/middleware/)
- [how to setup custom middleware in django(stackoverflow)](https://stackoverflow.com/questions/18322262/how-to-setup-custom-middleware-in-django)・・・2017年の回答。middleware本体の実装はエラーになるがディレクトリ構造について参考になった

# 手順

ミドルウェアを配置するアプリケーションを作成します。既存のアプリケーションに入れても問題ありません。
`app_name`は実際のアプリケーション名に置き換えます。

```
$ python3 manage.py startapp app_name
```

アプリケーションの下に`middleware`ディレクトリを作成して、その直下に空の `__init__.py` ファイルを配置します。

```
$ cd app_name
$ mkdir middleware
$ cd middleware
$ touch __init__.py
```

`middleware`ディレクトリ下でクラスを実装します。requestオブジェクトからクライアントのリモートIPをログ出力するコードです。

```{app_name/middleware/custom_middleware.py}

from django.core.exceptions import MiddlewareNotUsed
import logging

class LoggingRemoteIPAddressMiddleware(object):
    logger = logging.getLogger('LogginRemoteIPAddressMiddleware')

    def __init__(self, get_response):
        #raise MiddlewareNotUsed 
        self.get_response = get_response

    def __call__(self, request):
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        self.logger.info('REMOTE_ADDR={}'.format(ip))
        return self.get_response(request)
```

ここまでで以下のよう構成になってればOKです。

```
<プロジェクトルート>
 └── app_name
     └── middleware
         ├── __init__.py
         └── custom_middleware.py
```

作成したクラスをsettings.pyの`MIDDLEWARE`定義に追加します。

```{settings.py}

MIDDLEWARE = [
    ・・・
    'app_name.middleware.custom_middleware.LoggingRemoteIPAddressMiddleware',
]
```

logging設定（出力レベルや書式）によりますが実行すると以下のようなログが得られます。

```
2019-02-17 00:25:21,076 [INFO] 省略/project/app_name/middleware/custom_middleware.py:71 REMOTE_ADDR=127.0.0.1
```

以上です。
競プロ参戦記 #33 Match Matching | ABC 118

AtCoder のプログラミングコンテスト ABC 118 に参加しました。今週は ABC-only 回で、なんとか全完できました。この記事では、問題の考察を自分なりに書いていきます。

本連載は前回 (https://note.mu/vain0x/n/n07b1b0686624) までは note に書いていましたが、今後は Qiita に掲載します。

- 回答は Rust (1.15.1) で書いていて、入力のパースに自作マクロを使っています。

## AtCoder Beginner Contest 118

問題一覧: https://atcoder.jp/contests/abc118/tasks

- 問題の正確な説明や制約などは問題ページを参照してください。

## A - B +/- A

問題概要: A が B の約数なら A+B を出力し、そうでなければ B-A を出力せよ。

考察: A が B の約数であるとは、B を A で割った余りがゼロであることをいいます。これを実際に判定して場合分けすればOK。

筆者の回答 (AC): https://atcoder.jp/contests/abc118/submissions/4283197

## B - Foods Loved by Everyone

問題概要: N 人それぞれに、 M 個の食べ物の種類について好きか嫌いかを質問した。人 i が好きな食べ物の種類のリストを A[i] とおく。すべての人が好きと答えた食べ物の種類の個数を求めよ。

考察: すべての人の「好きな食べ物の種類の集合」の共通部分の要素数が答えになります。というわけでそのように実装しましたが、冷静に考えると全探索するだけでよかった……

筆者の回答 (AC): https://atcoder.jp/contests/abc118/submissions/4283061

## C - Monsters Battle Royale

問題概要: N 体のモンスターがいる。モンスター i の体力は A[i] である。いずれかのモンスター x が他のモンスター y の体力を A[x] 減らす、という操作を好きなだけ繰り返す。これによって体力が正のモンスターが1体になった。その体力としてありうる値の最小値を求めよ。

考察: もとの問題文には「ランダム」と書かれていますが、実際には確率の話は出てこないので、どのモンスターがどこに攻撃するかは好きに選べると考えていいです。

体力 A[i] の最大公約数を g とします。どのように操作をしても、体力は g の倍数になるので、最小値は g 以上です。

また、ユークリッドの互除法と同様手順を踏むことによって、最終的な体力が g になるようにできます。だから g が答えです。

筆者の回答 (AC): https://atcoder.jp/contests/abc118/submissions/4282226

## D - Match Matching

問題概要: マッチ棒を W[d] 本使うことで、数字 d (1〜9) を作れる。ただし作れる数字は集合 A に含まれるものに限られる。合計 N 本のマッチ棒をちょうど使って作れる整数のうち、最大のものを求めよ。ただし W = [_, 2, 5, 5, 4, 5, 6, 3, 7, 6] である。

考察: マッチ棒の本数 N が 10^4 と多めなので、整数は 64 ビットに収まらない点に注意。

桁数が大きいほど大きい整数になるので、なるべく少ない本数のマッチ棒を使って多くの数字を作るのがよさそうです。

そこで、集合 A に含まれる数字のうち、使うマッチ棒の本数が最小である数字を d とします。複数あるときは、値が最大のものを選びます。余っているマッチ棒の本数 N が W[d] の倍数なら、すべての桁を d とするのが最善です。

問題は W[d] の倍数にならない端数の処理です。

例えば A = {2, 8, 9} のとき d=2 (W[d]=5本) です。数字の 9 (6本) や 8 (7本) を組み合わせて、マッチの余りが 5 の倍数になるようにします。N=624 では 9999 (24本) の後に 2 を120個 (600本) 並べるのがベストです。

ここで注意点として、d の個数を最大化すればいいというわけではないです。24本のマッチで 8822 を作れば d=2 の個数が最大化されますが、結果の整数は最大になりません。(はじめ、これに気づかなくてWAしました。)

では何桁ぐらいまで端数処理に費やせばいいのか。d の他に数字 e があるとき、端数処理に使うマッチの本数の上限は W[d] と W[e] の最小公倍数です。これを超えると d を並べたほうがよくなります。W の値をみると、最大で42本です。このことには後から気づいたので、本番ではおおざっぱに「整数10桁分」ということにしました。このへんを正確につめられない……

まとめると、こういうアルゴリズムにしました。全探索で10桁の整数を作る方法を列挙します。マッチ棒の残りの本数が W[d] の倍数にならないものは除外します。これで得られた最大の整数と、余ったマッチで作った数字 d を組み合わせます。これが答えです。

筆者の回答 (AC): https://atcoder.jp/contests/abc118/submissions/4290474

想定解は DP らしいです。

### D: 想定解

(追記 2019-02-18)

公式の解説 PDF を読んで想定解を実装しました。

提出: https://atcoder.jp/contests/abc118/submissions/4306236

これは、はじめに DP によって「dp[n]: マッチ棒 n 本で作れる整数の桁数の最大値」を調べます。これによって答えとなる最大の整数の桁数が判明します。

あとは「マッチ棒の残りを使って、整数の残りの桁をぴったり埋められるか？」に注意しながら、整数の各桁の値を上位桁から順に決めていける、という流れのようです。
【備忘録:python】dictのkeyを日本語にするとKeyErrorになる

# はじめに


`python`のdictでkeyを日本語に設定すると、keyerrorに直面しました。
見た目は同じなのに、`KeyError`ですと言われたときの解決方法です。

半ば強引ですがとりあえずこれでなんとかなります。

# 解決策

```
import unicodedata
KeyMatched_str = unicodedata.normalize('NKFC', KeyError_str)
```



# 原因

`dict`で`KeyError`になる原因は、日本語の濁点や半濁点にありました。
どういうことかというと、`utf-8`では「ど」などの濁点・半濁点のつく文字には以下の二通りの表現方法があるためです。

* 単純に「ど」
* 「と」＋「濁点」

パソコンで表示される上では、上の２つは全く同じ文字ですが`utf-8`などで表示すると違うことがわかります。
試しに以下のコードを実行してみます。

```
print(b'\xe3\x81\xa9'.decode('utf-8'))
print(b'\xe3\x81\xa8\xe3\x82\x99'.decode('utf-8'))
print(b'\xe3\x81\xa8'.decode('utf-8'))

--result--
ど
ど
と
```

このように、違うことがわかります。
`Python`の`dict`はこの違いも判別しているらしく、`KeyError`が発生してしまうことがあるようです。

# 参考
<sup><sub>ほぼ参考サイトのコピペです。。。</sub></sup>
* [文字と濁点・半濁点が分かれていて，それらを結合したい時](https://qiita.com/tma15/items/61c38fba5ca6c5f7bd77)
Oracle上にあるテーブルをISO 8601形式の日付で範囲指定して絞込検索を行う方法


日付を利用した絞込において、ISO 8601型式の日付を検索に利用すると、タイムゾーンにかかわらず等しい検索結果を得ることができます。

### 条件

- テーブル上の日付はtimestamp型でセットされている(＝DBのタイムゾーンに応じた日付がセットされている）こと
- 検索時に指定する日付はtimestamp_tz型でセットされること

### コード

```
select * from <テーブル名>
where 
    sys_extract_utc(<日付列>) >= 
    to_timestamp(
        sys_extract_utc(
            to_timezone_tz(
                '<開始日時(timestamp_tz型で指定)>',
                'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
            )
        )
    )
    and
    sys_extract_utc(<日付列>) >= 
    to_timestamp(
        sys_extract_utc(
            to_timezone_tz(
                '<終了日時(timestamp_tz型で指定)>',
                'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
            )
        )
    )
order by <日付列> asc;
```

### 例

```
select
    id, /* pk */
    date /* timestamp型 */
from hogetbl
where
    sys_extract_utc(date) >= 
    to_timestamp(
        sys_extract_utc(
            to_timestamp_tz(
                '2019-02-01T00:00:00.000+0000',  
                'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
            )
        )
    )
    and
    sys_extract_utc(date) >= 
    to_timestamp(
        sys_extract_utc(
            to_timestamp_tz(
                '2019-02-01T23:59:59.000+0000',  
                'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM'
            )
        )
    )
order by date asc;
```
OracleでISO 8601形式の日付を出力する

timestamp型の日時をUTCへ変換したうえでISO 8601形式で出力します。

## 前提条件

- ISO 8601形式で表示させる日付列の型はtimestamp型であること
- 日付列の各行の値は、DBMS(Oracle)のタイムゾーンに準じたものであること（例えば、DBMSのタイムゾーンがJSTである場合はJSTで日付がセットされていること）

## コード

```
to_char(
    SYS_EXTRACT_UTC(<timestamp型の日付>),
    'YYYY-MM-DD"T"HH24:MI:SS.FF3"+0000"'
)
```

### 例

```
select
    sessiontimezone,
    to_timestamp('2019-01-21 09:12:27.804000') as jst,
    to_timestamp(sys_extract_utc(to_timestamp('2019-01-21 09:12:27.804000'))) as utc,
    to_char(
        sys_extract_utc(to_timestamp('2019-01-21 09:12:27.804000')),
        'YYYY-MM-DD"T"HH24:MI:SS.FF3"+0000"'
    ) as utc_iso8601
from dual;
```

### 結果
![image.png](https://qiita-image-store.s3.amazonaws.com/0/64876/caf612e6-12fb-e082-1118-1e641daa7f72.png)
【BigQuery】TIME型の加算をINT64に変換して秒単位でする

# 背景
Bリーグのスタッツの分析をしようと以下のようなデータを用意しました。
<img width="386" alt="BigQuery_-_itatibs_-_Google_Cloud_Platform.png" src="https://qiita-image-store.s3.amazonaws.com/0/231123/c1003e3c-6e7c-870a-2d46-d712062622d3.png">

|カラム名|型|備考|
|---|:---:|---:|
|game_date|DATETIME|試合日|
|team|STRING|チーム名|
|player|STRING|選手名|
|F|INT64|ファール数|
|MIN|TIME|出場時間(時:分:秒)|
|div|STRING|ディビジョン(B1/B2)|

B1については投稿時点で最新の2018-19シーズンの24節までのスタッツを保持しています。
第24節の三河vs秋田後、秋田のディフェンスに若干おこな[桜木JRさんのツイッター] (https://twitter.com/JRSakuragi32/status/1095253685314117632)を見て各選手の出場時間10分あたりのファール数を出してみようとしました。
そのため、出場時間として使っているTIME型を選手毎にSUMして平均を出したいと思った時にそもそもTIME型同士の加算ってどうしたらいいのかと悩んだのがきっかけです。

#　TIME型を秒のINT64型に変換して使用
結論として以下のようなクエリを発行して出しました。

```
SELECT
  team,
  player,
  ROUND(SUM(F) / SUM(CAST(FORMAT_TIME('%M',MIN) AS INT64) * 60 +CAST( FORMAT_TIME('%S',MIN) AS INT64))  * 600, 2) F_per10min
FROM
  `Dwh.boxscore_P*`
WHERE
  div = 'B1'
GROUP BY
  team,
  player
ORDER BY
  F_per10min DESC
```

単純にTIME + TIMEができればベストなのですが、SQLは基本的にTIME_ADDとかしかないので、結局秒に変換して使用することにしました。
TIME型の変換先はSTRING型とTIME型なので、一旦STRINGに変換してからCASTでINT64に変換しています。
これだと1行が長くなってしまうのでなんとか改善したいです。

# 余談
ちなみにこの分析で秋田の選手がやっぱり上位に出てくるのかと思いましたが、ガベージタイムやインサイドの外人を休ませる間の繋ぎ選手が上位で出てきました。(確かにそりゃそうですよね。。。)

<img width="438" alt="report001_20190216.png" src="https://qiita-image-store.s3.amazonaws.com/0/231123/f79fa348-aa5c-3ae4-09c4-ed4072b80941.png">
Laravelカンファレンス2019に行って、知れた事を列挙

Laravelカンファレンス2019に行って、学べたものを列挙してみる。
ただし、私参加したのは15時くらいから

## コントリビュートするには
- 公式ドキュメント読む
- 元コードを読む

## Laravel Telescope
>Laravel TelescopeはLaravelフレームワークのエレガントなデバッグアシスタントです。Telescopeはアプリケーションへ送信されたリクエスト、例外、ログエンティティ、データクエリ、キュージョブ、メール、通知、キャッシュ操作、スケジュールされたタスク、様々なダンプなどを提示します。TelescopeはLaravelローカル開発環境における、素晴らしいコンパニオンです。
引用：https://readouble.com/laravel/5.7/ja/telescope.html

## Laravel zero & Laravel dusk
この二つで、コンソールでブラウザ操作可能。

### Laravel zero
>コマンドラインアプリケーションを構築するために最適化されたLaravelの非公式かつカスタマイズされたバージョンです。
https://github.com/laravel-zero/laravel-zero

### Laravel dusk
>Laravel Dusk（ダースク：夕暮れ）は、利用が簡単なブラウザの自動操作／テストAPIを提供します。デフォルトのDuskは皆さんのマシンへ、JDKやSeleniumのインストールを求めません。代わりにDuskはスタンドアローンのChromeDriverを使用します。しかし、好みのSeleniumコンパチドライバも自由に使用することもできます。
https://readouble.com/laravel/5.7/ja/dusk.html

## Lighthouse
>Lighthouseは、LaravelアプリケーションからGraphQLエンドポイントを提供することを可能にするPHPパッケージです。スキーマを作成するために必要な定型句を大幅に削減し、あらゆるLaravelプロジェクトとうまく統合できます。また、高度にカスタマイズ可能であるため、データを完全に制御できます。
https://github.com/nuwave/lighthouse

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">lighthouseとは<br><br> <a href="https://twitter.com/hashtag/laraveljpcon?src=hash&amp;ref_src=twsrc%5Etfw">#laraveljpcon</a> <a href="https://t.co/1Z0dPMEioL">pic.twitter.com/1Z0dPMEioL</a></p>&mdash; ZUMI＠アラサー新米エンジニア (@hanlio) <a href="https://twitter.com/hanlio/status/1096679608588484608?ref_src=twsrc%5Etfw">2019年2月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## Laravel spark
https://spark.laravel.com/
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">laravel sparkとは<br> <a href="https://twitter.com/hashtag/laraveljpcon?src=hash&amp;ref_src=twsrc%5Etfw">#laraveljpcon</a> <a href="https://t.co/4bBwudQCXd">pic.twitter.com/4bBwudQCXd</a></p>&mdash; ZUMI＠アラサー新米エンジニア (@hanlio) <a href="https://twitter.com/hanlio/status/1096683733975937024?ref_src=twsrc%5Etfw">2019年2月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

公式より登壇者のQiita記事が上にくる　→[Laravel Sparkをインストールする](https://qiita.com/k-kurikuri/items/42abb5f3818ac30a4b51)

## Laravel Shift
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">laravel shiftすげー <a href="https://t.co/49k3Gvxaii">pic.twitter.com/49k3Gvxaii</a></p>&mdash; ZUMI＠アラサー新米エンジニア (@hanlio) <a href="https://twitter.com/hanlio/status/1096715271476109312?ref_src=twsrc%5Etfw">2019年2月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

https://laravelshift.com/
LXQtでデスクトップにショートカットを作る

# 環境
- Arch linux
- liblxqt 0.14.0-1

# 手順
- すでにデスクトップエントリーが存在する場合、ドラッグアンドドロップでデスクトップにコピーする
- 自作のシェルスクリプトなどデスクトップエントリーが存在しない場合、以下のコマンドでエントリーを作成
 - 参考： [Lubuntuでデスクトップにショートカットを作る](https://qiita.com/kota9/items/3a29a1d625f78c5ad2ec, "Lubuntuでデスクトップにショートカットを作る")

```
# lxshortcutパッケージが必要
lxshortcut -o ~/Desktop/hoge.desktop
```

以上の操作でデスクトップにショートカットは作成できるが、最近のバージョンのLXQtではアイコンに「!」マークが表示され、クリックすると「This file 'hoge' seems to be a desktop entry. What do you want to do with it?」というダイアログが表示される（らしい）。

~~これを回避するには、アイコンを右クリックし「Trust this executable」にチェックを入れれば良い。~~

Trust this executableオプションが永続的でないため、ログアウトするとまたもとに戻ってしまう。
そこで、以下のworkaroundを紹介する。

1. PCManFM-Qtファイルマネージャを開き、設定を開く
2. 「挙動」タブ内の"Launch executable files without prompt"にチェックする
3. 「！」マークは消えないが、ダイアログは表示されずショートカットからアプリケーションを実行できる

「！」マークが消せるいい方法をお待ちしております。
初心者がshellをfishに変更！rbenv使えるようにするところまで。〜もうターミナルの打ち間違えには悩まない〜

##この記事書いた理由

こんにちは！

maxです。

初心者エンジニアあるある。

terminalで入力するとき、typoに気づかず時間を溶かす。（typoって使いたがる初心者）

これまじであるあるだと思うんですよね〜。

自動補完が使えたらいいなあと思うんですけど面倒な設定はしたくない、、、

そんな中で職場の先輩があるshellを教えてくださりました。

それが**fish**です。

fishのgithub↓
https://github.com/fish-shell/fish-shell

こいつね、インストールするだけでターミナルで自動補完とか勝手にできるようにしてくれるんですよ。

めちゃくちゃ便利すぎて惚れましたね（チョロイ）

同じ悩みをもつ初心者の方の参考になれば嬉しいです！！

##fishのインストール方法
```
$ brew install fish
```

これだけですww

```
$ fish -v
```
上記のコマンドできちんとfishが入っているか確認！

はい導入終了！！楽チン！！

##rbenvの導入

自動補完は既に使えるようになったんですが、僕は（一応）railsエンジニアなのでrbenvを使わなければならない。

しかしターミナルをmacデフォルトのbashからfishに変更すると、rbenvの環境変数などがリセットされてる。

環境変数の設定面倒だな〜。

しかしですね、fishではたった数行で終わるのですよ。

```
curl -L http://get.oh-my.fish | fish 
omf install rbenv
```
はい、おわりですwww

oh-my-fishというfish用のプラグインをダウンロードし、oh-my-fishを通じてrbenvようの機能をダウンロードすると、勝手に環境変数の設定やってくれます。

便利〜。


##最後に
fishは神。

なんか間違っていることとかあったら書いてもらえると泣いて喜びます！！