OmniAICreator/Qiita-1.07M huggingface dataset:
Ajaxを活用した非同期通信について

##ajaxを使った非同期通信
10月19日現在、ajaxによる非同期通信を学習しているところですが、なかなか理解が追いつかないので自分なりにJavaScriptの復習をかねて中身を確認していきたいと思います。かなり自分向けに書いていますので、語弊がある部分もあるかもしれません。

今回は、ブログに対して投稿されるコメントが非同期通信にて行われるようにしていきます。

####イベントの発火
まずは動作のきっかけ部分を記述します。きっかけはコメントを入力し、投稿ボタンをクリックした時です。

```JavaScript:comment.js
$(function(){
  $('#newcomment').on('submit', function(e){
    e.preventDefault();
    var formdata = new FormData(this);
  })
})
```

- `$(function(){` 
jQuery(JavaScript)のコードが読み込まれる際に、まだHTMLが読み込まれていないとエラーが発生します。1行目、`$(function(){`から書き始めることで、HTMLのページ情報が読み込み完了してからコードが実行されます。
ちなみにこのfunctionメソッド（書き方あっているのかな・・・）では引数は不要ですが、引数がない場合でも（）括弧を書く必要があります。

- `$('#newcomment')` 
jQueryでどのボタンがトリガーになるかは、HTMLタブ内の`class`もしくは`id`から探します。
2行目の`$('#newcomment').`はHTML内の`id`（newcomment）を探します。#は`id`を探す書き方です。
$('.〜')といったように、`.`を使うと`class`要素から探されます。

- `.on('submit', function(e){` 
イベント`submit`が起こった際に以下の関数を実施する、という部分。
ちなみにfunction(e)のeはイベントの頭文字。
次の行の`e.preventDefault`は実行されるべきイベントをキャンセルさせます。

- `var 〜〜 = 〇〇` 
変数`〜〜`に`〇〇`を代入します。
Rubyだと頭の`var`なんて要りませんでしたが、他のプログラム言語では必要な場合も多いようです。

- `new FormData(this)` 
フォームの情報を取得します。引数が`this`の場合、イベントが発生した部分、今回はコメント投稿の部分からの取得になります。

####コメントの保存
非同期通信の中で、入力したコメントがcreateメソッドで保存されるようにします。

```JavaScript:comment.js
$(function(){
  $('#newcomment').on('submit', function(e){
    e.preventDefault();
    var formdata = new FormData(this);
    $.ajax({
      url: $(this).attr('action'),
      type: "POST",
      data: formData,
      dataType: 'json',
      processData: false,
      contentType: false
    })
  })
})
```
- `$.ajax({` 
ajaxで非同期通信をする際のオプションを記述します。
1.type HTTP通信の種類を記述。GETもしくはPOST。
2.url  リクエスト送信先のURLを記述。
3.data 送信する値を記述。
4.dataType データの種類を記述。今は基本的にjson
5.processData dataに指定したオブジェクトをクエリ文字列に変換するかどうか。他の形式でデータを送るために自動変換を行いたくない場合はfalseを指定
6.contentType データのファイル形式を指定。基本false


- `attr` 
要素が持つ属性から、指定した属性の値を返します。
今回では投稿ボタンを含むformタグの中からaction要素を探し、その値となるURLを取得するようにします。

以上の記述で、ajaxで扱われるデータは
「json形式でテキストボックス内の文字をPOSTでコメント投稿のアドレスへ送信」
となります。すなわちコメントが投稿される形となります。

####返ってくる結果を受け取る
.doneメソッドで非同期通信の結果を受け取ります。

```JavaScript:comment.js
    .done(function(data){
      $('.comments').append(〜〜)
      $('.textbox').val('')
    })
    .fail(function(){
      alert('error')
    })
```

`.done`メソッドで、受け取った結果を元に処理を行います。
`comments`クラスの後ろに（）内の記述を追加します。詳細は省略。
`textbox`クラスの値を空にします。今回はフォームボックスの中をクリアします。
`.fail`メソッドは、エラーが発生した時に表示させる処理です。
`alert`メソッドはポップアップを表示させます。

こんな感じなんでしょうか。
まだなんとなく程度の理解ですので、もっと精進していきます。
Reactで直接URLをたたくと404になる時の対応

# Reactで直接URLをたたくと404になる時の対応

## 前提：react-router-domでルーティングしてる

```html:index.html
<html>
  <body>
    <div id="root"></div>
  </body>
</html>
```

```js:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
```

```js:App.js
import React, { Component } from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <div className="App">
          <Switch>
            <Route exact path='/' component={HogeComponent} />
            <Route exact path='/Fuga' component={FugaComponent} />
          </Switch>
        </div>
      </BrowserRouter>
    );
  }
}
```

## 状況：直接URL叩くと404になる
- うまくいくケース
    - `https://hogeapp.com/`にアクセス　→　HomeComponentが表示される
    - /Fugaのリンクを踏む
    - `https://hogeapp.com/Fuga`に遷移　→　FugaComponentが表示される
- うまくいかないケース
    - `https://hogeapp.com/Fuga`が表示された後リロードする　→　404ページが表示される
    - ブラウザで`https://hogeapp.com/Fuga`を直接叩く　→　404ページが表示される

## 原因：SPA構成だと直リンクはリソースがないから死ぬ
- リソースが存在しないと直接URLにアクセスしても404になるから
- うまくいった時の流れ
    - `https://hogeapp.com/`にアクセス
    - `index.html`を読み込む
    - react-router-domのルーティングによりHomeComponentが表示される
    - /Fugaのリンクを踏む
    - react-router-domのルーティングによりFugaComponentが表示される
- うまくいかないときの流れ
    - `https://hogeapp.com/Fuga`のURLに直接アクセス
    - /Fugaリソースを探そうとするが、見つからない
    - 404ページ表示

## 対策：サーバー側の設定でリライト設定をする
- Webサーバーの設定で`index.html`へのリライト指定をする
- 例えばFirebase Hostingなら`firebase.json`ファイルの hosting 内で rewrites セクションを定義できる
    - 参考：https://firebase.google.com/docs/hosting/full-config?hl=ja#rewrites

```json:firebase.json
{
  "hosting": {
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}
```

- 上記のように全要素index.htmlに飛ばすならreact-router-domのルーティングで404コンポーネントを返却するようにする
    - もともとWebサーバー側で設定していた404.htmlは機能しなくなるので

```js:App.js
import React, { Component } from 'react'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
class App extends Component {
  render() {
    return (
      <BrowserRouter>
        <div className="App">
          <Switch>
            <Route exact path='/' component={HogeComponent} />
            <Route exact path='/Fuga' component={FugaComponent} />
            <Route component={NotFound} />
          </Switch>
        </div>
      </BrowserRouter>
    );
  }
}
```

## 参考
- ここの回答
    - https://teratail.com/questions/26245
【Unity】音を鳴らそう

# やりたいこと
　・BGMをループ再生。
　・SEを高頻度で再生。(一度止めてからもう一度再生？)

# AudioClip と AudioSource
AudioClip
  Unityで扱われる「音声データ」(ex. 音楽CD)
AudioSource
  Unityで扱われる「AudioClipの再生状況等を管理するやつ」(ex.音楽プレイヤー)


# リファレンス調査
　・ループ再生はloop = trueにするだけで設定できる。楽だねぇ。

```csharp
AudioSource audioSource;
audioSource = gameObject.AddComponent<AudioSource>();
audioSource.clip = Resources.Load("Sounds/1_3line") as AudioClip;
audioSource.loop = true;
audioSource.Play();
```
　・SEの高頻度再生(シューティングのショットのような)は上記からloopを設定せずPlay()だけで可能。
　　一度目の再生が完了するまで二度目の再生が待たされることはない。
　　ただし、毎フレームだと音が再生されないため、
　　最短でも2フレームに一度として再生する必要があるっぽい。

# 参考サイト
(AudioSource)[https://docs.unity3d.com/ja/2017.4/ScriptReference/AudioSource.html]
goでエラーなのか正常系なのかを判断して出力するログ

# 目的
goで製品開発していて単純なlog.Printfよりはもう少し賢い簡単なログライブラリが必要になりました。そこで要求事項を整理した結果、まずはログの内容がinformationなのかerrorなのかをprefixで判別できるものを作ろうとなり、 [INFO] [ERROR] とログの頭につく形でログを出力することを考えました。
例えばこういうライブラリ関数になります 

- `log.info("this is information")` 
- `log.error("this is error")`

## 出力
- [INFO] this is information
- [ERROR] this is error

## 困ったこと
結果としては上の出力が得られれば問題はなかったのですが以下のような問題が出ました

・すでに結構な数のログが製品中に埋め込まれている。これらを全てどれがinfoかどれがerrorかを一つずつ見ながら対応する関数呼び出しに置き換えるのは大変
・今後ログ関数を呼び出す場合にプログラマ全員がきちんと該当するレベルのエラーを呼び出してくれるのか不安。またコードレビューの際にもログレベルが妥当かをいちいち見て指摘しなければいけない

## 解決策
ログの呼び出し内容にerrorが含まれていればprefixをERRORに、それ以外ならINFOにすれば自動で振り分けられるのではないか。ということで以下が実装になります。

```golang
func logger(format string, args ...interface{}) {
	prefix := "[INFO] "

	if args == nil {
		format = prefix + format
		log.Printf(format)
	} else {
		for _, arg := range args {
			switch arg.(type) {
			case error:
				prefix = "[ERROR] "
				break
			}
		}
		format = prefix + format
		log.Printf(format, args...)
	}
}
func main(){
	logger("this is information")
	logger("%s","yet another information")
	logger("%v",errors.New("i am error"))
}
```

## 出力
2019/10/20 00:11:20 [INFO] this is information
2019/10/20 00:11:20 [INFO] yet another information
2019/10/20 00:11:20 [ERROR] i am error

## まとめ
何も考えずに、とりあえずこの関数呼び出してログ出力して貰えば適切に動いてくれる、十分製品として実用レベルのログライブラリとして活躍しました。

github: https://github.com/nyasuto/logger
ランダムフォレストを使用した分類・重要度評価

#はじめに
こんな方にオススメ。
・ランダムフォレストを使用した分類のサンプルソースがほしい
・ランダムフォレストを使用した重要度評価のサンプルソースがほしい

#ソース
##分類
目的変数と説明変数の分類した正解率を算出

``` py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris

# データセット読み込み
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
x = iris.data
y = iris.target

# 学習データとテストデータに分割
x_train, x_test, y_train, y_test = train_test_split(x, y)

# ランダムフォレストのモデル構築
# n_jobs : 全てのコアを使用(-1)
# n_estimators : 使用する決定木数(デフォルト10)
model = RandomForestClassifier(n_estimators=20,n_jobs=-1)
model.fit(x_train, y_train)

#正解率
print ("正解率",model.score(x_test,y_test))

#予測データ作成
y_pre = model.predict(x_train)

fig = plt.figure(figsize=(14,7))
ax = fig.add_subplot(111)
ax.scatter(2,2,color="white")
ax.plot(y_train,lw=1,color="red",label="train")
ax.plot(y_pre,lw=1,color="blue",label="predict")
ax.legend()
fig.show()
```
訓練データ(赤)と予測データ(青)の乖離が少ないことをグラフ化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439049/ac60a395-189d-3c48-05ae-307848f016cd.png)

##重要度評価
目的変数に対する説明変数の重要度を算出。

``` py
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris

# データセット読み込み
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
x = iris.data
y = iris.target

# 学習データとテストデータに分割
x_train, x_test, y_train, y_test = train_test_split(x, y)

# ランダムフォレストのモデル構築
# n_jobs : 全てのコアを使用(-1)
# n_estimators : 使用する決定木数(デフォルト10)
model = RandomForestClassifier(n_estimators=20,n_jobs=-1)
model.fit(x_train, y_train)

#特徴量の重要度
feature = model.feature_importances_
#特徴量の名前
label = df.columns[0:]
#特徴量の重要度順(降順)
indices = np.argsort(feature)[::1]

# プロット
x = range(len(feature))
y = feature[indices]
y_label = label[indices]
plt.barh(x, y, align = 'center')
plt.yticks(x, y_label)
plt.xlabel("importance_num")
plt.ylabel("label")
plt.show()
```
目的変数に対する説明変数の特徴量を降順でグラフ化。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439049/e3d3de64-6df9-83f0-166e-a3b8b1b88b60.png)

#GitHub
上記実装したipynbファイルは以下に格納しております。
https://github.com/bossjerom/python/tree/master/randam_forest
CpawCTF level 3 個人的解説

[CpawCTF](https://ctf.cpaw.site/index.php)でCTFの勉強をしていたのですが、ネット上にLevel3の解説が落ちていなかったのでここにまとめたいと思います。ここでは、自分の解き方を紹介するのでより効率の良い解き方があるかもしれません。

# Q23.[Reversing]またやらかした！
今回の問題ではstringコマンドを使ってもフラグを見つけることはできません。そこでIDAを用いてmain関数で何を行っているか見てみましょう。
![rev1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514015/7789c1bb-622c-dcd1-afd3-ce5cb9bb5e04.png)

![rev2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514015/60628c64-aa84-1b84-cc1a-ee06b17a383f.png)

以上のアセンブリを読み解くと、スタック領域の14個の変数に対して19という値をxorしていることになります。これはバーナム暗号ですね。

```
元の値　19をxorしたあとの値
7A → 63 (c)
69 → 70 (p)
78 → 61 (a)
6E → 77 (w)
62 → 7B ({)
6F → 76 (v)
7C → 65 (e)
6B → 72 (r)
77 → 6E (n)
78 → 61 (a)
74 → 6D (m)
38 → 21 (!)
38 → 21 (!)
64 → 7D (})
```
実際に計算してみるとフラグをゲットすることができます。

# Q24.[Web]Baby's SQLi - Stage 2-

level2のQ22の問題の続きです。Q22でデータベースを参照したときの2行目に問題ページのURLが記載されているのでそこから問題ページに飛びましょう。

問題ページにはユーザー名とパスワードを入力するフォームがあります。バックエンドでユーザー名とパスワードから認証処理をする仕組みになっていると予測できます。
バックエンドで以下のクエリ文を生成していると考えてみましょう。

```php
string query = "SELECT * FROM user_table WHERE user_name='" + request.getParameter("user") + "'"
"AND password='" + request.getParameter("password") + "'"
```

今回の問題ではユーザー名は与えられているため、パスワードの入力のみとなります。もちろん、パスワードはわからないのでSQLiによりパスワードがわからなくても上記のSQL文が通るように考えてみます。以下の入力をパスワードフォームに与えてみました。

```
' OR '1'='1
```

では、この入力から完成されるクエリ文を見てみましょう。

```SQL
SELECT * FROM user_table WHERE user_name='porisuteru' AND password='' OR '1'='1'
```

'1'='1'はTrueとなるので上記のSQL文は通ります。実際こちらの入力でフラグをゲットできました。


# Q26.[PPC]Remainder theorem

1584891で割って32134余り、3438478で割って193127余る整数xを１つ出力すればよい問題となっています。
つまり、xを1584891で割って32134余る数でfor文を回して、その中で3438478で割って193127余る時にxを出力するプログラムを作ってみましょう。

```c++

#include <bits/stdc++.h>
using namespace std;

int main(){
    for (long long i = 0; i < 1000000000; i++)
    {
        long long x = 1584891*i + 32134;
        if(x % 3438478 == 193127){
            cout << x << endl;
            break;
        }
    }
    return 0;
}
```

# Q29.[Crypto] Common World
問題文で与えられている(e,N)はRSA暗号の公開鍵を表しています。
RSA暗号では、平文をm,暗号文をc,公開鍵を(e,N),秘密鍵をdとすると

```math

\begin{align}
N &= pq\,(pとqは異なる素数)\\
c &= m^e\,(mod\,N)\\
d &= e^{-1}\,(mod\,(p-1)(q-1))\\
m &= c^d\,(mod\,N)\,(復号時)
\end{align}

```

上記の式から分かるように復号するにはp,qの値が必要です。しかし、攻撃者はNを与えられてもp,qを素因数分解を行い見つけるのに計算時間がかかります。この素因数分解の困難性が暗号の安全性を担保しています。

今回の問題では、e=11とe=13の場合について同様のNに対して平文を暗号化しています。つまり以下の式が成り立ちます。

```math

\begin{align}
c_1 &= m^{11}\,(mod\,N)\\
c_2 &= m^{13}\,(mod\,N)\\
↓\\
\frac{c_2}{c_1} &= m^2\,(mod\,N)

\end{align}
```
与えられた2つの暗号文の割り算を実行し、その結果に対して平方根を求めればそれが平文となります。
多桁の計算となるので自力でプログラムを実装するか、既存のツールを使用しましょう。
私は、[こちら](http://www1.s-cat.ne.jp/0123/tabaityousuutikeisan/)のツールを利用させていただきました。
以下が解答となります。

```math
\frac{c_2}{c_1} = 180040032052240663195289808096837316\\
m = \sqrt{\frac{c_2}{c_1}}=424311244315114354\\

```
PythonでExcel基本操作

#はじめに
プロジェクト開発ではExcelの操作はよくあると思います。
簡単に操作方法をまとめてみます。

#ライブラリインストール
`pip install xlsxwriter`

※pipバージョン古い場合はupgradeしたほうがよい
`python -m pip install --upgrade pip`

#データをExcelに書き込みサンプル
```excel.py
import xlsxwriter

data = (
    ["田中 一郎", 20],
    ["山田 一郎", 23],
    ["鈴木 一郎", 21]
)

workBook = xlsxwriter.Workbook("user.xlsx")

workSheet = workBook.add_worksheet(name="ユーザー一覧")

row, col = 0, 0

# dataをExcelに書き込み
for userName, age in data:
    workSheet.write(row, col, userName)
    workSheet.write(row, col + 1, age)

    # 次の行へ
    row += 1

# 平均年齢
workSheet.write(row, 0, "平均年齢")
workSheet.write(row, 1, "=AVERAGE(B1, B3)")
workBook.close()
```

結果：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/40310a19-2928-f3c8-307c-7d15326428f1.png)

簡単ですね。

#各フォーマットのメソッド
- 文字列：　wirte_string()
- 数字： write_number()
- 空白：　write_blank()
- 計算式： write_formula()
- 日付：　write_datetime()
- true/false: write_boolean()
- URL: write_url()

詳細はhttps://xlsxwriter.readthedocs.io/working_with_data.html

#簡単なチャート例
```chart.py
import xlsxwriter

workBook = xlsxwriter.Workbook('chart.xlsx')

worksheet = workBook.add_worksheet()
bold = workBook.add_format({'bold': 1})

headings = ['言語', '人気度']
data = [
    ['Rust', 'Go', 'Kotlin', 'Node.js'],
    [40, 20, 10, 30],
]

# excelにデータをインサート（ダミーの数字です）
worksheet.write_row('A1', headings, bold)
worksheet.write_column('A2', data[0])
worksheet.write_column('B2', data[1])

# チャート種類を指定
pieChart = workBook.add_chart({'type': 'pie'})

# 範囲指定
pieChart.add_series({
    'name':       '言語の人気度',
    'categories': ['Sheet1', 1, 0, 4, 0],
    'values':     ['Sheet1', 1, 1, 4, 1],
})

# タイトル
pieChart.set_title({'name': '言語の人気度'})

pieChart.set_style(10)

# チャートをインサート
worksheet.insert_chart('C2', pieChart, {'x_offset': 25, 'y_offset': 10})

workBook.close()

```

結果：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346425/f8e645d0-d0cd-0a3b-4a1a-9195d9769149.png)


いろいろな種類のチャートがあります。
https://xlsxwriter.readthedocs.io/chart_examples.html


xlsxwriter：https://xlsxwriter.readthedocs.io/

以上
Go で int スライスの二分探索

# Go で int スライスの二分探索

Go 言語でスライスの二分探索をするには sort.Search を使う.

int スライスについては、Python の bisect_left 相当の sort.SearchInts があるのでそれを使えば良い. bisect_right 相当はないので sort.Search で書くことになる.

```go
package main

import (
	"fmt"
	"sort"
)

func bisectLeft(a []int, x int) int {
	return sort.SearchInts(a, x)
}

func bisectRight(a []int, x int) int {
	return sort.Search(len(a), func(i int) bool { return a[i] > x })
}

func main() {
	a := []int{1, 2, 2, 3}
	fmt.Println(bisectLeft(a, 0))
	fmt.Println(bisectRight(a, 0))
	fmt.Println(bisectLeft(a, 2))
	fmt.Println(bisectRight(a, 2))
	fmt.Println(bisectLeft(a, 4))
	fmt.Println(bisectRight(a, 4))
}
```

出力結果

```
0
0
1
3
4
4
```

比較の度に関数呼び出しをするためこの実装はすこぶる遅い. 以下の実装は倍くらい速い.

```go
func bisectLeft(a []int, x int) int {
	lo := 0
	hi := len(a)
	for lo < hi {
		mid := (lo + hi) / 2
		if a[mid] < x {
			lo = mid + 1
		} else {
			hi = mid
		}
	}
	return lo
}

func bisectRight(a []int, x int) int {
	lo := 0
	hi := len(a)
	for lo < hi {
		mid := (lo + hi) / 2
		if x < a[mid] {
			hi = mid
		} else {
			lo = mid + 1
		}
	}
	return lo
}
```
Ruby on Railsでログイン機能を作ろう2

前回ログイン機能を作った続き。
https://qiita.com/clipbord/items/0a716b797115f1368df1

細かいところを整えたり、アクセス制限かけたりしています。主にリンクメモです。

###空白入力時のエラーメッセージの日本語化
https://qiita.com/Ushinji/items/242bfba84df7a5a67d5b

###Flashメッセージ
https://pg-happy.jp/rails-flash-message.html

###bootstrap導入
https://qiita.com/tqkqt0/items/d9a3f3416c242ba48ba0

・text_fieldにclassを書く
https://qiita.com/KeyG/items/10691b0558ca0d0353b3

###バリデーションエラー時のレイアウト崩れ修正
https://blazing.hatenablog.com/entry/2018/12/07/093314

###ログイン・ログアウト判定
https://qiita.com/tobita0000/items/866de191635e6d74e392

###アクセス制限
ログインユーザのみ確認可

```application_controller.rb
  before_action :set_current_user

  def set_current_user
    @current_user = User.find_by(id: session[:user_id])
  end

  def authenticate_user
    if @current_user == nil
      flash[:notice] = "ログインが必要です"
      redirect_to(users_login_path)
    end
  end
```

```user_controller.rb
before_action :authenticate_user, only: [:index,:show,:edit,:update,:destroy]
```

###メーラー追加(development環境用)
参考：設定オプション
https://qiita.com/Anorlondo448/items/3af11c8a5837c2a5e0a1

参考：
https://qiita.com/hirotakasasaki/items/ec2ca5c611ed69b5e85e
基本的にこちらを参考にして、config部分のみ変更。

```config/environments/development.rb
  # Don't care if the mailer can't send.
  config.action_mailer.raise_delivery_errors = false
  config.action_mailer.perform_caching = false
  #下記追記
  config.action_mailer.default_url_options = { host: 'localhost:3000' }
  config.action_mailer.delivery_method = :letter_opener

```
まずは、letter_openerでやってみた。

###メーラー追加(production環境用)
参考：https://rails-ambassador.herokuapp.com/tips/HerokuSendmailAddon
上記を参考にSendGridを使ってherokuでメール送信しました。

```config/environments/production.rb
  config.action_mailer.perform_caching = false
  config.action_mailer.delivery_method = :smtp
  config.action_mailer.perform_deliveries = true
  config.action_mailer.smtp_settings = {
    :domain => 'herokuapp.com',
    :address => 'smtp.sendgrid.net',
    :port => 587,
    :user_name => ENV['SENDGRID_USERNAME'],
    :password => ENV['SENDGRID_PASSWORD'],
    :authentication => :plain,
    :enable_starttls_auto => true
  }
```

##欄外
devise使用。
色々調べてたら、deviseを使ったログイン機能の作成というものが出てきたので、
新しくプロジェクト作ってやってみた。次作る時はこちらをベースにしようと思った。

https://qiita.com/matcham/items/3609e72360491543b1b6
Higher-Kind 型と Natural Transformation を組み合わせて使う

最近会社で流行っているやつ。

Scala では **Higher-Kind 型**と **Natural Transformation** を利用して、
処理の実行モデル(同期、非同期)を抽象化することが可能になるので簡単な実装例を紹介する。

# Higher-Kind 型を使う

### インターフェイスを定義

インターフェイスの定義に **Higher-Kind 型**を利用する。

```scala
trait HogeRepository[F[_]] {
  def get: F[String]
}
```

### 実装する

具体的な実行モデルを指定する。

```scala
import scala.util.Try

class HogeRepositoryImpl extends HogeRepository[Try] {
  override def get: Try[String] = Try("Hoge")
}
```

具体的にする必要がなければ汎用なままでも良いが、必要に応じて **Monad** や **Applicative** といった制約をつけてやる。

```scala
import cats.Monad

class HogeRepositoryImpl2[F[_]: Monad] extends HogeRepository[F] {
  override def get: F[String] = Monad[F].pure("Hoge")
}
```

### 利用する

利用側で具体的な型を確定する。

```scala
import scala.util.Try

object Main {

  val repository: HogeRepository[Try] = new HogeRepositoryImpl()

  def main(args: Array[String]): Unit = {
    println(repository.get) // Success(Hoge)
  }
}
```

このあたりは DI でやることが多い。

# Natural Transformation を使う

`HogeRepository[Try]` を `HogeRepository[Future]` とするのにいちいち実装を書き換えたくない。そんなときは **Natural Transformation** を使う。

`F[_]` を `G[_]` に変換する仕組みを提供してくれる。

### インターフェイスに mapK を実装

```scala
import cats.~>

trait HogeRepository[F[_]] {
  self =>
  def get: F[String]
  def mapK[G[_]](nat: F ~> G): HogeRepository[G] = new HogeRepository[G] {
    def get: G[String] = nat(self.get)
  }
}
```

この `F ~ G` のところが **Natural Transformation**。

### Try ~> Future を実装する

`Try ~> Future` を実装してそれを `mapK` にわたすことで `HogeRepository[Try]` から `HogeRepository[Future]` を作ることができる。

```scala
object Main {

  val tryToFuture: Try ~> Future = new (Try ~> Future) {
    override def apply[A](fa: Try[A]): Future[A] = Future.fromTry(fa)
  }

  val repository: HogeRepository[Future] = new HogeRepositoryImpl().mapK(tryToFuture)
 
  def main(args: Array[String]): Unit = {
    println(repository.get) // Future(Success(Hoge))
  }
}
```

# おしまい
AtCoder Grand Contest 039　Graph Partition(ワーシャルフロイド法)

AtCoder Grand Contest 039　Graph Partition(ワーシャルフロイド法)
https://atcoder.jp/contests/agc039/tasks/agc039_b

直径を求めるのwarshall-floyd法を使っている。木のグラフであったらdouble sweepを使えば求まるが、一般のグラフではwarshall-floyd法などを使う必要がある。

```python
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
from copy import deepcopy
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce


sys.setrecursionlimit(2147483647)
INF = 10 ** 20
def LI(): return list(map(int, sys.stdin.buffer.readline().split()))
def I(): return int(sys.stdin.buffer.readline())
def LS(): return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()
def S(): return sys.stdin.buffer.readline().rstrip().decode('utf-8')
def IR(n): return [I() for i in range(n)]
def LIR(n): return [LI() for i in range(n)]
def SR(n): return [S() for i in range(n)]
def LSR(n): return [LS() for i in range(n)]
def SRL(n): return [list(S()) for i in range(n)]
def MSRL(n): return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007



def warshall_floyd(G):
    dist = deepcopy(G)
    n = len(G)
    for k in range(n):
        for i in range(n):
            for j in range(n):
                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j])
    return dist


def bipartite_or_not(G, s=0):
    n = len(G)
    global color
    color = [0] * n
    color[s] = 1
    dq = deque([s])
    while dq:
        u = dq.popleft()
        for v, bit in enumerate(G[u]):
            if u == v or bit == '0':
                continue
            elif color[v] == 0:
                color[v] = -color[u]
                dq += [v]
            else:
                if color[u] == color[v]:
                    return False
    return True



n = I()
G = SRL(n)
if not bipartite_or_not(G):
    print(-1)
    exit()


for u in range(n):
    for v in range(n):
        if u == v:
            G[u][v] = 0
        elif G[u][v] == '1':
            G[u][v] = 1
        else:
            G[u][v] = INF


dist = warshall_floyd(G)
print(max([dist[u][v] for u in range(n) for v in range(u + 1, n)]) + 1)

```
AWSのLambdaLayersでpandasを使おうとしたらトラブった話

## 記事概要


- トラブルの内容
    - AWS Layersでpandasを使えるようにしたかった
    - numpyのインポートでエラー
- 解決策
    - AmazonLinux2ではなくてAmazonLinuxを使う
    - Pythonのバージョンを合わせる

最近コンテナで開発環境を用意していたから、Pythonのバージョンに全然気を使っていなかった。

## AWS Lambda Layersとは

これまでLambdaでnumpyやpandasを使おうとすると

- AmazonLinuxインスタンスを用意
- 利用するモジュールを`pip install`
- Lambda関数の本体スクリプトと共にzipファイルにまとめる
- AWSにアップロードする

デプロイパッケージを作成する必要があった。おまけにコンソールからスクリプトが見えないし、メンテナンスやデバッグもかなりめんどくさい。

それを解決するのがLayers機能。

[AWS Lambda レイヤー - AWS Lambda](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-layers.html)



## 出てきたエラー

エラーメッセージは下記の通り。なんかnumpyがうまく動いてないらしい。


```
START RequestId: 7cf66e49-c9f4-48d3-8212-3b9279a8ee02 Version: $LATEST
Unable to import module 'lambda_function': 

IMPORTANT: PLEASE READ THIS FOR ADVICE ON HOW TO SOLVE THIS ISSUE!

Importing the multiarray numpy extension module failed.  Most
likely you are trying to import a failed build of numpy.
Here is how to proceed:
- If you're working with a numpy git repository, try `git clean -xdf`
  (removes all files not under version control) and rebuild numpy.
- If you are simply trying to use the numpy version that you have installed:
  your installation is broken - please reinstall numpy.
- If you have already reinstalled and that did not fix the problem, then:
  1. Check that you are using the Python you expect (you're using /var/lang/bin/python3.6),
     and that you have no directories in your PATH or PYTHONPATH that can
     interfere with the Python and numpy versions you're trying to use.
  2. If (1) looks fine, you can open a new issue at
     https://github.com/numpy/numpy/issues.  Please include details on:
     - how you installed Python
     - how you installed numpy
     - your operating system
     - whether or not you have multiple versions of Python installed
     - if you built from source, your compiler versions and ideally a build log

     Note: this error has many possible causes, so please don't comment on
     an existing issue about this - open a new one instead.

Original error was: /opt/python/numpy/core/_multiarray_umath.so: undefined symbol: _Py_ZeroStruct


END RequestId: 7cf66e49-c9f4-48d3-8212-3b9279a8ee02
REPORT RequestId: 7cf66e49-c9f4-48d3-8212-3b9279a8ee02	Duration: 0.51 ms	Billed Duration: 100 ms	Memory Size: 128 MB	Max Memory Used: 73 MB	Init Duration: 423.73 ms	
```

## 対処① AmazonLinux2ではなくてAmazonLinuxを使う

ここを見るとLambda関数はAmazonLinuxで動いているらしい。なのでzipファイルはAmazonLinuxのインスタンス上で用意しないといけない。

## 対処②  Pythonのバージョンをlambda関数のランタイムと合わせる

最近はSageMakerで全て済ましてしまうのでうっかりしていたが、Linuxはpython2.7がデフォルトだ。
コンテナで環境構築すると最初からPython3になっていることが多いからね。

pyenvを導入してLambda関数側のpythonのバージョン(3.6)と合わせることで解決


## 参考
[【サーバレス機械学習入門】AWS Lambda レイヤーの使い方 - Qiita](https://qiita.com/si1242/items/db27c9b5a6a957a64186)
node.js のreadFileでline number付き出力 （個人的メモ）

node.jsでファイルを読み込むには、

以下のように３行書けばいい。stringで、ファイルの中身を取得出来る。
toString()を使って、bufferを文字列に変換するのがミソ！

```js
const fileContent = require('fs')
  .readFileSync('README.md')
  .toString()
console.log(fileContent)
```

しかし、line number付きで、ファイルの中身を標準では取得出来ない。

line numberをつけるには、以下のようにプログラミングをしてあげる必要がある。

```js
const fileContent = require('fs')
  .readFileSync('README.md')
  .toString()
  .split('\n')
  .map((text, index) => `${index}` + text)
  .join('\n')

console.log(fileContent)
```

今度は、配列に変換してから、文頭に数字を入れているだけ

完!
WebStorm で ts-node を用いたデバッグ環境の構築

# はじめに

TypeScript の開発では ts-node を用いることでコンパイルせずにそのまま実行できます。
Node.js のアプリケーションでは `--inspect` を付与して起動することでデバッグ実行が可能になります。
ここでは、 WebStorm 上で ts-node を経由したアプリケーションでの設定をまとめます。

ts-node がプロジェクトにインストールされている前提で話を進めます。

# 環境

- WebStorm 2019.2.3

# Node.js

メインメニューの `Run - Edit Configrations` から Node.js の設定を追加します。
`Node parameters` に `--require ts-node/register` を追加します。
現行のバージョンでは `--inspect` を指定しなくても動作するようです。
ts-node の CLI オプションを付与したい場合は、ts-node の環境変数を `Environment variables` に追加することで有効になります。

![Node.js のデバッグ設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129299/7f8771f4-d9c8-0740-5057-7f636efb9fa4.png)

実際にブレークポイントを設定して実行すると停止することが分かります。

![Node.js のブレークポイント](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129299/82ea8e5e-207b-187e-e813-b326dfb43e34.png)


# Jest

Jest を用いたテストでもデバッグできます。
Jest の設定を追加します。
`Node options` に `--require ts-node/register` を追加します。

![Jest のデバッグ設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129299/bc03dd3c-6d6c-b95a-43b2-276b34056f2c.png)


テストファイル上でブレークポイントを設定して実行すると停止することが分かります。プロダクションコードにブレークポイントを設定しても同様に停止します。

![Jest のブレークポイント](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129299/83cdd033-368d-076e-62b5-f88c3747141e.png)

# nodemon

nodemon はソースコードの変更を検知してリロードしてくれるツールです。
WebStorm ではリロードした際にも再接続してデバッグが続行できるようになっています。
nodemon がプロジェクトにインストールされている前提で話を進めます。

nodemon 起動時の設定を以下のように `nodemon.json` に記載します。

```json:nodemon.json
{
  "watch": ["src"],
  "ext": "ts",
  "exec": "node --inspect --require ts-node/register src/app.ts"
}
```

以下のように npm scripts で nodemon が起動するコマンドを追加します。

```json:package.json
"scripts": {
  "dev": "nodemon"
}
```

追加したコマンドで nodemon を起動しておきます。

```bash
$ npm run dev
```

`Attach to a Node.js/Chrome` の設定を追加します。
`Reconnect automatically` にチェックを入れます。

![nodemon のデバッグ設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129299/7f188650-10aa-e7ac-057c-edefb769aa45.png)

この状態で実行するとソースコードを修正しても再接続されデバッグできます。

# 参考

[Running and Debugging Node.js - Help | WebStorm](https://www.jetbrains.com/help/webstorm/running-and-debugging-node-js.html)
[ts-node を WebStorm でデバッグ実行 - Qiita](https://qiita.com/jnst/items/bd0646d466717cddace4)
文字列を含むデータでも数値だけ取り出して手軽に可視化する

実験データなどを可視化したいけどindexやcolumnsが文字列で扱いづらいと思った経験はありますよね。

例えばこんな風にある電場下での信号測定を温度を変えてプロットしたようなデータとかが該当します。

|| 120V/mm | 100V/mm |
|:------|---|---|
| 214K　| 1 |5|
| 216K　| 2 |6|
| 218K　| 3 |7|
| 220K　| 4 |8|


# 解決したいこと
グラフを作成するときにx座標になる配列が生データだと文字列なので数値だけ取り出したい。

# 解決方法
正規表現ライブラリを使って文字の部分を消してしまう。

```python
# 正規表現操作ライブラリ
import re

# re.sub(正規表現パターン, 置換後文字列, 置換したい文字列)
x = [int(re.sub("\\D", "", temperature)) for temperature in data["120V/mm"].index]

y = data["120V/mm"]
```

re.sub("\\D", "", temperature)の部分で十進数でない任意の文字列を空白””で置き換えて数字（文字列）だけ残し、int()によって整数値に変換する事によって温度の数値のみを取り出した配列を作成することができます。

```python
print(x) #=>[214, 216, 218, 220]
```

以上のような簡単な方法で文字列を含むデータも可視化することができます。

```python
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(x,y)
```
![Unknown.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287284/14796e9e-91ed-4dac-5668-7aa6bb903cea.png)
AtCoder Beginner Contest 12 D - バスと避けられない運命(ダイクストラ法)

https://abc012.contest.atcoder.jp/tasks/abc012_4
ダイクストラ法はこのコードを使えばいい。

実は、この問題は、辺の数のオーダーが頂点数nの2乗なので、heapを使ったdijikstraをそれぞれの頂点から使うと計算量は$O(n^2logn)$と遅くなる。ヒープを使わない$O(n^2)$のdijikstraを使う手もあるが、そうすると、計算量は$O(n^3)$となり、warshall_floydを1回するのと計算量は同じ。


```python
def dijkstra(s):
    hq = [(0, s)]
    dist = [INF] * n
    dist[s] = 0
    checked = [0] * n
    while hq:
        min_dist, u = heappop(hq)
        if checked[u]:
            continue
        checked[u] = 1
        for v, c in G[u]:
            if dist[u] + c < dist[v]:
                dist[v] = dist[u] + c
                heappush(hq, (dist[v], v))
    return dist


n, m = LI()
G = [[] * n for _ in range(n)]
for a, b, cost in LIR(m):
    G[a-1] += [(b-1, cost)]
    G[b-1] += [(a-1, cost)]
```

```python
def dijkstra(G, s=0):
    n = len(G)
    que = [(0, s)]
    dist = [INF] * n
    dist[s] = 0
    while que:
        min_dist, u = heappop(que)
        if min_dist > dist[u]:
            continue
        for v, c in enumerate(G[u]):
            if dist[u] + c < dist[v]:
                dist[v] = dist[u] + c
                heappush(que, (dist[u] + c, v))
    return dist
```
隣接行列版。と言ってもenumerateにしただけだが。

```python
G = [i for i in zip(*G)]
```
グラフの向きを逆にするにはこうする。
Rails で SystemStackError stack level too deep の解決

## 環境
ruby 2.5.3
rails 5.1.7

## エラー
作成中のアプリのブラウザで投稿一覧画面に移動した時、ページが読み込まれない
サーバー画面を見てみると、

```
SystemStackError stack level too deep
```
の文字が。
そして、

```
app/controllers/posts_controller.rb:52:in `request'
```
が何行もある。


## 解決法
###　サーバーを停止
ctrl+cやターミナルを消してもサーバーが停止しなかったため、以下の方法を使った。

```
$ lsof -i:3000
COMMAND     PID       USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
com.apple   687 hoge  131u  IPv6 0xa83beccf9a6cd3c1      0t0  TCP localhost:64379->localhost:hbci (ESTABLISHED)
ruby      64604 hoge   11u  IPv4 0xa83beccf991edd81      0t0  TCP localhost:hbci (LISTEN)
ruby      64604 hoge   21u  IPv6 0xa83beccf9964eac1      0t0  TCP localhost:hbci (LISTEN)
ruby      64604 hoge   26u  IPv6 0xa83beccf9a6cfc01      0t0  TCP localhost:hbci->localhost:64378 (CLOSE_WAIT)
```

でlocalhost:3000のプロセスを取得

```
$ kill -9 64604
```
で停止、もう一度

```
$ lsof -i:3000
```
で何も出ないことを確認。

```
$ rails s
```
無事サーバーが立ち上がった。

###根本的な原因
[ここ](https://the.igreque.info/posts/2013-02-24-override-request.html)に書いてある通り、アクション名にrequestを使うと、予約語のrequestを上書きしてしまい、無限ループになってしまうようだ。
→アクション名を変更して無事解決。
fastlaneでcredentialをremoveしたのにログイン出来るのなんで…

タイトル通りの気持ちになったのでメモ

fastlaneの認証情報を消すのは以下のコマンド
`fastlane fastlane-credentials remove --username info@gmail.com`

ただ、これを消してもdeliverなどでAppStore Connectにアクセス出来る。
--verboseでコマンド実行するとすぐわかる。

```
Reading keychain entry, because either user or password were empty
Loading session from '/Users/name/.fastlane/spaceship/info@gmail.com/cookie'
```

cookie経由でログインしてました…。
と言うわけで、これを消せば無事ログインできなくなります。
AtCoder Beginner Contest 143 参戦記

# AtCoder Beginner Contest 143 参戦記

## [ABC143A - Curtain](https://atcoder.jp/contests/abc143/tasks/abc143_a)

2分で突破. マイナスにならないようにするところを忘れないだけ.

```python
A, B = map(int, input().split())

print(max(A - B * 2, 0))
```

## [ABC143B - TAKOYAKI FESTIVAL 2019](https://atcoder.jp/contests/abc143/tasks/abc143_b)

2分半で突破. 書くだけ.

```python
N = int(input())
d = list(map(int, input().split()))

result = 0
for i in range(N - 1):
    for j in range(i + 1, N):
        result += d[i] * d[j]
print(result)
```

## [ABC143C - Slimes](https://atcoder.jp/contests/abc143/tasks/abc143_c)

2分半で突破. 書くだけ. 最近の C 問題が簡単とはいえ、簡単にもほどがある.

```python
N = int(input())
S = input()

p = ''
result = 0
for i in range(N):
    if p != S[i]:
        result += 1
        p = S[i]
print(result)
```

## [ABC143D - Triangles](https://atcoder.jp/contests/abc143/tasks/abc143_d)

82分で突破. TLE3つ. 手元で最大の 2×10<sup>3</sup> のデータを作ってテストして0.6秒だったので安心して出したら TLE を食らうという……. でも結局3重ループで突破.

```Go
package main

import (
	"bufio"
	"fmt"
	"os"
	"sort"
	"strconv"
)

func main() {
	N := readInt()
	L := make([]int, N)
	for i := 0; i < N; i++ {
		L[i] = readInt()
	}

	sort.Sort(sort.IntSlice(L))
	result := 0
	for i := 0; i < N-2; i++ {
		for j := i + 1; j < N-1; j++ {
			x := L[i] + L[j]
			for k := j + 1; k < N; k++ {
				if L[k] >= x {
					break
				}
				result++
			}
		}
	}
	fmt.Println(result)
}

const (
	ioBufferSize = 1 * 1024 * 1024 // 1 MB
)

var stdinScanner = func() *bufio.Scanner {
	result := bufio.NewScanner(os.Stdin)
	result.Buffer(make([]byte, ioBufferSize), ioBufferSize)
	result.Split(bufio.ScanWords)
	return result
}()

func readString() string {
	stdinScanner.Scan()
	return stdinScanner.Text()
}

func readInt() int {
	result, err := strconv.Atoi(readString())
	if err != nil {
		panic(err)
	}
	return result
}
```

いや、3ループ目を二分探索でやればいいことは途中から分かってたんだけど、その検討途中で条件式が減ったので、なら通るんじゃねって出したら通っちゃったんですよ. Go 言語にビルトインで二分探索がなかったのも悪い(責任転嫁)(※追記: sort.SearchInts があります)

というわけで、二分探索版です.

```python
from bisect import bisect_left

N = int(input())
L = list(map(int, input().split()))

L.sort()
result = 0
for i in range(N - 2):
    for j in range(i + 1, N - 1):
        result += bisect_left(L, L[i] + L[j]) - j - 1
print(result)
```
【開発日記】薬価検索アプリno.2 〜設計・機能の洗い出し〜

##出来上がりのサイト
薬価検索アプリmedipraはこちらです
→　[見に行ってみる](https://www.medipra.net)

前回の内容はこちら。
[【開発日記】薬価検索アプリno.1 〜開発概要→企画〜](https://qiita.com/pharma_tech3/items/51c9a670c605098bc3bf)
開発背景などについて触れています。


こちらの記事ではアプリの設計をしてきます。

##現在の進捗状況
1.必要な機能の洗い出し　⬅︎今ココ
2.必要な画面設計
3.データベース設計
4.Railsでアプリケーションの雛形作成
5.大きな機能から順に実装
6.テストコードを書いて動作を担保する
7.リファクタリングして整理する
8.デプロイ




#必要な機能の洗い出し

では早速開発に取り掛かりましょう。

今回作成したいアプリケーションはDBに入っている薬の情報を、ユーザーが検索して閲覧できるというのがメイン機能になります。いたってシンプルですね。
あとは、同じ成分名で先発品と後発品を関連付けで表示できること、
薬と、必要量を入れれば税込価格や３０％での価格もわかるようにしたいですね。
この辺は細かな機能ですので、後から思いついた場合でも実装は難しくないと思います。

今回はユーザー登録が必要ないアプリケーションなので、大きな機能は実装しない予定です。

一方で、検索することがメインのアプリになるので、検索方法は充実させたい。曖昧でも検索できたり、条件によって絞り込みができたり。カメラで文字やQRコードを読ませて、そこから検索できるようにもしたいですね。
また、検索結果の表示も非同期通信で、ページ遷移なし。
次々と薬を検索できるような仕様にしたい。。。。

ちょっと話が散らかってしまいしたが、今の段階で優先度高めの機能をあげてみます。

**1.薬剤名検索機能**
**2.一般名検索機能**
**3.同種同効薬検索機能**

まずは、この３機能の実装を目標に開発していきたいと思います。

#まとめ・所感

ということで、今回は、アプリに必要な機能の洗い出しを行いました。
今回は実装しませんが、よくある機能としては、
ユーザー登録、メッセージ送受信機能、管理者ページ機能、出品機能、決済機能あたりでしょうか。

自分の作り出したいアプリケーションの世界を十分よく想定して、表現するために必要な機能はなるべく早い段階で洗い出しておくと、あとあとスムーズなります。漏れやダブりがないかよくチェックしながら洗い出してみましょう。


では[【開発日記】薬価検索アプリno.3 〜設計・画面設計〜]　(作成中)に続きます。
Redmineインストール

Redmineのインストール手順を残しておく。
OS：GCP上にインストール済みのDebian(Linux instance-1 4.9.0-8-amd64)

# Middleware系のインストール

## Ruby関連
```
sudo apt install ruby-dev ruby bundler
```
## Apache関連
```
sudo apt install apache2 libapache2-mod-passenger
```
## ImageMagic関連
```
sudo apt install imagemagick libmagick++-dev
```
## バージョン関連
```
sudo apt install git subversion
```

## DB関連
```
sudo apt install mysql-server default-libmysqlclient-dev
```

# DBの準備
今回は、MySQLを使用する。

## MySQLの設定変更
Redmineの文字コードは、utf8mb4を使用する。
/etc/mysql/conf.d/redmine.cnf

```
[mysqld]
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix
character-set-server = utf8mb4
skip-character-set-client-handshake
collation-server = utf8mb4_general_ci
init-connect = SET NAMES utf8mb4

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

[mysqldump]
default-character-set = utf8mb4
```

## データベース作成

* DB: Redmine
* User: redmine
* Password: pass

```
CREATE DATABASE redmine CHARACTER SET utf8mb4;
CREATE USER 'redmine'@'localhost' IDENTIFIED BY 'pass';
GRANT ALL PRIVILEGES ON redmine.* TO 'user'@'localhost';
FLUSH PRIVILEGES;
```

※作ったユーザーで、Mysqlが使えることを確認しておくこと。

# Redmineインストール

今回使用するバージョンは、3.4-stableを指定。

## ディレクトリ作成とダウンロード
```
sudo mkdir -p /var/www/redmine
sudo chown www-data:www-data /var/www/redmine
sudo -u www-data svn co http://svn.redmine.org/redmine/branches/3.4-stable /var/www/redmine
```

### DB設定ファイルの作成
* /var/www/redmine/config/database.ymlに以下の内容でファイルを作成する。

```
production:
  adapter: mysql2
  host: localhost
  database: redmine
  username: redmine
  password: pass
  encoding: utf8mb4
  socket: /var/run/mysqld/mysqld.sock
```

### メール設定ファイルの作成
今回は、メール通知を使用しないため、Sampleをコピーする。

```
sudo cp /var/www/redmine/config/configuration.yml.example /var/www/redmine/config/configuration.yml
```

### utf8mb4の有効化
* /var/www/redmine/config/initializers/utf8mb4.rbに以下の内容で作成する

```Ruby
ActiveSupport.on_load :active_record do
  module ActiveRecord::ConnectionAdapters

    class AbstractMysqlAdapter
      def create_table_with_innodb_row_format(table_name, options = {})
        table_options = options.merge(:options => 'ENGINE=InnoDB ROW_FORMAT=DYNAMIC')
        create_table_without_innodb_row_format(table_name, table_options) do |td|
          yield td if block_given?
        end
      end
      alias_method_chain :create_table, :innodb_row_format
    end

  end
end
```

## Redmineインストール開始

```
find | sudo xargs chown www-data:www-data
sudo -u www-data bundle install -j$(nproc) --without development test postgresql sqlite --path vendor/bundle
sudo -u www-data bundle exec rake generate_secret_token
sudo -u www-data RAILS_ENV=production bundle exec rake db:migrate
sudo -u www-data RAILS_ENV=production REDMINE_LANG=ja bundle exec rake redmine:load_default_data
```

何もエラーが出なければ、インストール完了

## Apacheの設定

今回は、サブディレクトリで使用したいため、VirtualHostに追記

```
Alias /redmine /var/www/redmine/public
<Location /redmine>
	PassengerBaseURI /redmine
	PassengerAppRoot /var/www/redmine
</Location>
```
【html】画像内の特定部分のみにリンクを貼りたい（クリッカブルマップ）

##開始タグ
複雑なレイアウトをページに載せたい時は画像にして対応することが多いと思いますが、フロアマップなどの場合だとページ内リンクをつけることもあったので、今回メモ。

##やりたいこと
・画像内の特定箇所にリンクを貼りたい
・レスポンシブしても同じ箇所（領域）にリンクを貼っておきたい。

##方法
「クリッカブルマップ」と呼ばれるものを使います。
HTMLソースだとこんな感じ。

```html
<figure><img src="asset/img/img_sample.jpg" alt="" usemap="#link"></figure>
<map name="link">
	<area shape="rect" coords="46,0,1034,456" href="#place01" alt="" />
</map>
```
仕組みとしては、紐付けした画像の上にareaタグで領域を指定してリンクを設定している、という感じ。

紐付けしているのは、
`img`タグ=`usemap`属性
`area`タグ=`name`属性（#は除く）
この各属性で共通の名前を指定することで、紐付けされます。

`area`タグで指定している`shape="rect"`は大雑把に言えば四角形であることを表しています。
`coords`属性では座標を指定しています。
4つの数字のうち、前半分が左上隅・後半分が右下隅の計２点の座標を指定することで領域が形成されます。
残りの属性は`a`タグや`img`タグと同じです。

座標の指定は、流石にアナログだと手間がかかりすぎるので、
・Dream Weaverをお持ちであれば活用
・ない場合は[HTML Imagemap Generator](https://labs.d-s-b.jp/ImagemapGenerator/)を使うといいでしょう。
使い方も簡単で、画像をドラッグ＆ドロップしてシェイプを作るだけですので、自分もこれを使っています。

ふぅこれで完了と思いきや・・・`area`タグは絶対的に領域位置を指定している状態ですので、レスポンシブ時には画像に合わせて領域も縮むようにはなりません。

ですので、JSプラグインを利用して対応します。

##クリッカブルマップのレスポンシブ対応
以下のソースをhead内に記述します。

```html
<script src="https://cdnjs.cloudflare.com/ajax/libs/jQuery-rwdImageMaps/1.6/jquery.rwdImageMaps.js"></script>
<script src="asset/js/rwdImageMaps.js"></script>
```
```javascript:rwdImageMaps.js
$(function() {
	$('img[usemap]').rwdImageMaps();
});
```

プラグインファイルを読み込み、`rwdImageMaps.js`内の記述をしてあげれば、レスポンシブさせても画像の伸縮に合わせて領域も変わってくれます。

##閉じタグ
結構単純と言うか簡単なことですが、知っているのと知らないのとでは全く違いますよね。
自分も最初はそうでした。
とはいえ「クリッカブルマップ」というワードさえ知っていればいくらでも検索すれば出てくるので、何かその他問題があれば調べてみてください。
GIMPを画像データ処理ツールとして使いこなす(その0) -プラグイン作成の備忘録-

# GIMPを画像データ処理ツールとして使いこなす
言わずとしれたオープンソースの画像レタッチソフトのGIMP。フリーだしマルチプラットフォームだし多機能ということで画像データの処理に強力なツールになりうるポテンシャルは高いはず。というわけで、GIMPを機械学習に使う画像データ処理ツールとして活用する方法をまとめようと思います。

このGIMP。多機能なのはいいんだけどUIがいまいち精錬されていないし、アート系の初期設定になっているのでそのままでは使いにくいのです。機械学習用のデータともなれば何千枚もの画像を処理することになるので、僅かな使い勝手でも効率には大きく響いてくるということで、自作でプラグインを書くために調べたことを備忘録として残しておきます。

## ubuntu18.04 に GIMP2.10 をインストール
機械学習系の環境構築でOSは何を選ぶかと聞かれたら、結構上位にubuntuが入ってくると思うのですが（かなり主観）、ubuntuストアにあるGIMPはバージョン2.8なのです。機能面で叶わない部分があるので2.10をターミナルからインストールします。
手順は以下の通り。それぞれEnterや「y」の入力などは随時行ってください。
（参考: https://www.virment.com/install-gimp-ubuntu/ ）


#### リポジトリの追加とインストール

```terminal
$ sudo add-apt-repository ppa:otto-kesselgulasch/gimp
$ sudo apt update
$ sudo apt install gimp
```

これでGIMP2.10がインストールされました。2.10には不具合？のためにこのままではpythonを使ったプラグインが使えません。使えるようにするためには以下のgimp-pythonのインストールが必要です。

#### gimp-pythonのインストール

```terminal
$ sudo apt-get install gimp-python
```

## Plug-inのインストール先
作ったPlug-inは特定のフォルダにコピーすることで使えるようになります。
フォルダの参照先はGIMPの
　**編集 > 設定 >GIMPの設定 > フォルダー > プラグイン**　
から参照できます。指定先が2つあると思いますが
  **/home/user_name/.config/GIMP/2.10/plug-ins**
の方に作ったプラグインを置きます。もう片方の方はフォルダ全体に権限が掛かっているのでコピーするにはひと手間かかってしまいます。

## 何はともあれ”Hello World"
とりあえずプラグインが動くか確認するために、下記のスクリプトを**samplePython-fu.py** という名前で保存して
  **/home/user_name/.config/GIMP/2.10/plug-ins**
にコピーしましょう。

```python2.7:samplePython-fu.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from gimpfu import *

def plugin_main(image, layer, message):
    gimp.message("Hello World! " + message)

register(
        "python_fu_hello_world",
        "Hello, World! のあとにメッセージを表示します。",
        "エラーダイアログを立ち上げてHello World! のあとにメッセージを表示します。",
        "maCoto QuoVayashi",
        "copyright",
        "2019/10/19",
        "<Image>/Hello World",
        None,
        [ 
           (PF_STRING, "message", "メッセージ", 'Hello GIMP!')
        ],
        [],
        plugin_main)

main()
```

## 実行権限の付与
コピーした**samplePython-fu.py**もそのままではプラグインとして認識されません。**実行権限を付与する必要があります。**プロパティのアクセス権タグからでもコマンドラインでも、好きな方で実行権限を与えてください。

## プラグインが動くことを確かめる
上記の手順が全て終わったらGIMPを立ち上げてみましょう。既に立ち上がっている場合は再起動が必要です。

メニューバーの<ヘルプ>の横に<**Hello World**>というメニューが追加されているはずです。これをクリックしてダイアログが立ち上がれば成功。
imput imageとかimput drawableとかは気にせず**メッセージ**の項目を入力してOKしてください。
Hello Worldのあとにメッセージの欄に入力したものが表示されたエラーダイアログが現れます。
アプリを作成してGitHubと同期する

## 3行で

- 共有
- コミット
- 同期

## はじめに

とりあえずアプリを作っておく。
GitHubでリモートリポジトリを作っておく。作り方は割愛。
それから作ったアプリのディレクトリに移動しておく。

```terminal
アプリ名 $ 
```

この状態。

## Gitを使う準備をする

```terminal
アプリ名 $ git init
```

`init` はinitialize（初期化）の略。

## 共有するファイルを選択する

```terminal
アプリ名 $ git add .
```

`.` はオプションであり、アプリ内のファイルすべてを共有する場合に使う。

## メッセージ付きでcommitする

```terminal
アプリ名 $ git commit -m "first commit"
```

コメント名は任意ですが他人が見てわかりやすいものにする。

## リモートリポジトリと同期する

```terminal
アプリ名 $ git remote add origin リモートリポジトリのURL
```

## リモートリポジトリにファイルをpushする

```terminal
アプリ名 $ git push -u origin master
```

[`git push -u` オプションの意味](https://qiita.com/ironsand/items/6c301fef730d53f35bc3)

GitHubのリモートリポジトリにアクセスして、pushしたものが表示されていれば成功してます。
MacとChromebookで意識高い系のPS1（プロンプト）を設定する。

# プロンプトで意識を高める
勉強会や、技術動画などでターミナルを使っている人のプロンプトを見ると、

```
■■■▶
```
みたいになっている人がよくいますよね。
これをMacとChromebookのbashで出来るようにしてみます。
（シェルがzshの場合は変更するか諦めてください）

## Macの場合

[フォントファイル](https://github.com/powerline/fonts/blob/master/SourceCodePro/Source%20Code%20Pro%20for%20Powerline.otf)ををダウンロードしてください。
「view raw」ををクリックするとダウンロードされます。

フォントがダウンロードされたら、ダブルクリックして「インストール」をクリックするとMacにインストールされます。

## Chromebookの場合
[フォントファイル](https://github.com/adobe-fonts/source-code-pro/archive/release.zip)をダウンロードし、「/usr/share/fonts/truetype」に解凍します。
その後、ターミナルを再起動してください。

## プロンプトの設定
完全に私の備忘録になりますが、bashのプロンプト「PS1」を下記のように設定します。

```bash
PS1='\[\e[47;30m\]\!\[\e[42;37m\] \[\e[42;30m\] \u@\h \t \[\e[32;47m\]\[\e[30;47m\] \w \[\e[37;40m\]\[\e[37m\]\n$(__git_ps1 "\[\e[47;103m\]\[\e[30m\] %s \[\e[0;93m\]")\[\e[49m\]\[\e[39m\] \$ \[\e[40;37m\]'
```
こうすると、
1. ヒストリー番号
2. ユーザー名@ホスト名
3. 時間
4. カレントディレクトリ（フルパス）

になります。
【Vue.js】Vue CLIのバージョンアップ更新をする



Vue CLIの新しいバージョンがリリースされた時、

<img width="307" alt="スクリーンショット 2019-10-19 22.27.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/3afd9416-4050-bef9-afcc-4de4adb77b48.png">

npmインストール

```
npm install -g @vue/cli
```
<img width="479" alt="スクリーンショット 2019-10-19 22.29.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/13cb684f-10f3-9e71-5539-0f24d90e28df.png">

<img width="834" alt="スクリーンショット 2019-10-19 22.30.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/b096367b-702d-daef-21af-1abc153323fa.png">

これでOK


バージョン確認

```
vue --version
```
<img width="397" alt="スクリーンショット 2019-10-19 22.33.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93155/81ccecd3-bad1-d4f2-cd27-728c4d3740bd.png">


バージョンアップ成功！！
npmでSassをコンパイルしてCSS出力



# 前提
nodeJSがWindowsにインストールしてあること
環境変数に設定してあること


# 導入
```vim
npm init -y
```
> 以下、実行結果

```vim:package.json
{
  "name": "sample2023",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/00ae0e84-e8e7-73ce-3ff5-f67f71e891e4.png)

# npmパッケージを追加
> package.json に追加されます

```vim
npm install sass --save-dev
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/74acddb3-7376-4b6e-45d2-c5ccb067ee12.png)


# ファイルの変更を監視する
```vim
npx sass --watch src/sass/:dist/css/

```

> ファイルを変更したとき、毎回コンパイルのコマンドを実行するのは大変です。
そんなときは、ファイルの変更を監視して、自動的にコンパイルされるようにしておくと便利です

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57249/b1f30fdf-f83d-4c42-83c2-f4dd625b5279.png)
iOS シミュレーターでダークモードを切り替える2つの方法（画像付き）

先日、[iOS実機でダークモードを切り替える3つの方法](https://qiita.com/zono_Bianchi/items/103f03cddf75d20a4b2c)を書きましたが、シミュレーターを使って開発している方も多いかと思います。
そこで今回はシミュレーターでのダークモードの切り替え方を紹介します。

さくっと知りたい方は、[やり方2](#やり方2-xcode--environment-overrides)へどうぞ。

## やり方1: シミュレーター > 設定 > Developer
[実機のやり方](https://qiita.com/zono_Bianchi/items/103f03cddf75d20a4b2c#%E3%82%84%E3%82%8A%E6%96%B91-%E8%A8%AD%E5%AE%9A--%E7%94%BB%E9%9D%A2%E8%A1%A8%E7%A4%BA%E3%81%A8%E6%98%8E%E3%82%8B%E3%81%95)とは場所が違うので注意。
ただこのやり方…動作確認とかでライトモード ⇄ ダークモードを切り替えたい場合、すっごいすっごい手間なんですよね。
<img width="382" alt="スクリーンショット 2019-10-19 21.56.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252462/4baf1e41-7fd3-8e32-336f-9ec12205840a.png">
<img width="388" alt="スクリーンショット 2019-10-19 21.56.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252462/e7cec472-a7b7-c9d7-5050-8b2d8ef5851d.png">

##やり方2: Xcode > Environment Overrides
実はXcode上からもダークモードを切り替えることができます。
これ知ってるのと知らないのとでは全然効率違いますよね！！

Xcode下のバーに出てるスイッチっぽいUIのアイコンをタップします。
<img width="1281" alt="スクリーンショット 2019-10-19 22.06.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252462/d8b64592-185f-aa90-6e71-ed6a497a6ca3.png">

正確にはEnvironment Overridesという箇所みたいですね。
ここのInterface StyleというスイッチをON/OFFすると、シミュレーター上も切り替えることができます！なんて簡単！
<img width="592" alt="スクリーンショット 2019-10-19 22.06.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252462/0214734b-5512-ec12-4f2d-06d7aa934469.png">

よきダークモードライフを！😆
【初心者・未経験向け】個人的に業務で使ってるTips・ノウハウ

#はじめに
まず今回この記事を書こうと思った背景について書こうと思います。
自分は現在、エンジニア4年目でスタートアップでPHP(Symfony)を使って自社プロダクト(SaaS)を開発してます。
とは言え新卒からずっとWebの開発をしていた訳ではなくずっと組み込みやAndroidアプリ開発をやってたので、業務で扱うようになったのは今年の7月からです。
7月から3ヶ月、業務でPHPを使ってそこから今の会社に転職してるのでWebの開発経験は3ヶ月半といったところでしょうか。
もともと仕事で扱う前、今年の2月くらいから6月くらいまでは個人でWebの開発をしたり勉強したりしてましたが、業務で扱う開発に役立つのかな？と最近思うようになってこれから未経験からエンジニアになりたいって人や経験が浅いエンジニア向けにこの記事を書こうと思いました。

#個人的に業務でエンジニアが使えるTips・ノウハウ
###まずは、要件(実現したいこと)を把握する
これはノウハウというより前提です！
基本、業務始まっていきなり全部の機能理解しろってことは無いです！
というか無理です！
なのでまずは要件をヒアリングして何をしたいのか開発する前に必ず理解しましょう！
期待動作が分からないのに実装も何もないです。
ここをいい加減にすると全てが崩壊するのでリーダーやマネージャーの時間を確保してちゃんと分かるまで付き合ってもらいましょう。(経験が浅い状態でここが曖昧だと後々思考停止するのできちんとポイントを抑えておきましょう！)

###タスクを細分化する
もし複数機能を同時に依頼された場合、機能単位でタスク分けします。
タスク分けの仕方は人それぞれあると思いますが自分は[Trello](https://trello.com)などのツールを使ってチケットを切って管理してます。
この時、そのタスク開始時間と終わった時の終了時間を書くようにすると今後慣れてくると自分の中で作業見積もりがしやすくなっていくのでオススメです！！

###要件実現に関係するコードを読もう
例えば自分の場合、今だとMVCの概念を取り入れたFW(Symfony)を業務で扱ってるので、画面表示でこういう表示を追加したいとかだったらテンプレートとしてtwigを使うので、まず修正対象の画面を描画してるtwigを特定しましょう。その後、その画面の遷移元(ボタン押下するとその画面に遷移する部分)をデベロッパーツールで見てルーティング情報を確認します。(Symfonyならrouting.ymlなど)
そこからどのコントローラーを使用しているかを特定します。
データの中身を見たい時やどの条件文が動いてるかをログを貼りまくって確認します。
自分はPHPなのでvar_dump()やechoをたくさん駆使します。
PHPの場合はコンパイルがないので修正してすぐ画面上で確認できます。
割とここまで理解できれば画面表示系の修正はおおよそこなせるんじゃないかと思います。
機能を理解する上でもっとも早いのはソースコードを読むことだと個人的には考えてるので。。。

###作業中、進める上で不安なことなどが発生した場合、自己解決が難しい場合チャットツールなどで聞いておく
正直、直接聞くのはハードルが高いです。
なのでチャットとかで聞けるならチャットツールを駆使しましょう！！(多分だいたいどこのプロジェクトにもあるはず・・・)
分からないことは業務に携わったばかりなら当然ありますし相手もそれは分かってるはずです。
とは言え質問の仕方や頻度には気をつけましょう。
ここの調整は人によって異なると思うので、さじ加減で調整しましょう！


###作業を進めていく中でメモを取っておく
これかなり大事だと思ってます！
人間、頭の中だけで覚えていられることには限界があります。
なので思い出すための引き出しとして開発用のメモを残しておくといいと思います。
この機能はどこのソースコードが関係しているとかどの操作でこの画面にたどり着けるなどその機能を実現する為に必要な情報ですね。。。

#まとめ
業務で扱う開発で求められるスキルを実際に業務として仕事してる身から簡単に書かせていただきました！
まずはシステムを理解することがエンジニアとして業務をこなす上で必須になってきます。
そのシステムを理解する方法として前提として変数や配列の扱いなど最低限の知識はもちろんそうですが、ソースコードを読めるようになるのは必須です。
最低限の知識があれば、後はログを貼って根気よく追っていけば中身は少しずつ理解できるようになってくるはずです！！
厳密にはもっと色々ありますがこの5つのポイントが抑えられていたら多分業務をこなしていくことはできると思います！(自分がそうなので。。。)
参考になれば幸いです！

Twitterの方でも情報発信してるのでもしよかったらこちらもよろしくお願いします！
https://twitter.com/cube_3110

※他にもこういうTipsやノウハウあるよ〜という強い方いましたらコメント欄にぜひ書いていただけると幸いです！！！