OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonのin演算子は遅いのか？ (ABC167Dより)

「リストの中に或る要素が有るかどうか」を繰り返し判断するような場合、毎回`in`を使う（ループの中で`in`を使う）と遅くなるのではないかという話。
結論から言うと、`in`そのものが遅いというよりは「`in`を使ってリスト内を検索するのが遅い。」ということらしい。うすうす気づいてはいたが、これだけの速さの違いを実感したのはたぶん初めて。

以下ABC167Dで提出した似たようなプログラムだが、1つ目はループの中で`in`を使ってリスト内を検索し`TLE`のオンパレードとなった。それに対し、2つ目は別にフラグ用のリストを作って処理し、軽々`AC`(139ms)となっている。また、3つ目は親切な方の「検索対象をlistでなくsetにすればいい」とのアドバイスにより実験したもの。これも楽々`AC`(188ms)となった。

[AtCoder Beginner Contest 167 D - Teleporter](https://atcoder.jp/contests/abc167/tasks/abc167_d)


```python:ABC167D/TLE
n, k = map(int,input().split())
a = list(map(int, input().split()))
dst = [1] #今まで行った町（最初も含む）のリスト
twn = 1 #テレポーター転送先
for _ in range(k):
    if a[twn - 1] not in dst: #テレポーター転送先が今まで行った町リストに入っていなかったら
        dst.append(a[twn - 1]) #入っていなかったら今まで行った町リストに追加
        twn = a[twn - 1] #テレポーター転送先の更新
    else: #テレポーター転送先が今まで行った町リストに入っていたら（そこから先の転送先はループする）
        index = dst.index(a[twn - 1]) #今まで行った町リストでのテレポーター転送先のindex取得
        ld = len(dst[:index]) #ループする前の長さとループ部分の周期を求める
        cyc = len(dst[index:])
        print(dst[(ld - 1) + (k + 1 - ld) % cyc] if (k + 1 - ld) % cyc != 0 else dst[-1])
        exit()
print(dst[-1])
```

```python:ABC167D/AC139ms
n, k = map(int,input().split())
a = list(map(int, input().split()))
flg = [True] * n #各町に行ったかどうかのフラグリスト(行ってなかったらTrue)
dst = [1]
twn = 0 #テレポーター転送先(フラグリストのindex)
for _ in range(k):
    if flg[twn]:
        dst.append(a[twn])
        flg[twn] = False
        twn = a[twn] - 1
    else:
        index = dst.index(a[twn])
        ld = len(dst[:index])
        cyc = len(dst[index:])
        print(dst[(ld - 1) + (k + 1 - ld) % cyc] if (k + 1 - ld) % cyc != 0 else dst[-1])
        exit()
print(dst[-1])
```

```python:ABC167D/AC188ms
n, k = map(int,input().split())
a = list(map(int, input().split()))
dst = [1] #今まで行った町（最初も含む）のリスト
dsts = set(dst) #今まで行った町（最初も含む）のset
twn = 1 #テレポーター転送先
for _ in range(k):
    if a[twn - 1] in dsts: #テレポーター転送先が今まで行った町setに入っていたら（そこから先の転送はループする）
        index = dst.index(a[twn - 1]) #今まで行った町リストでのテレポーター転送先のindex取得
        ld = len(dst[:index]) #ループする前の長さとループ部分の周期を求める
        cyc = len(dst[index:])
        print(dst[(ld - 1) + (k + 1 - ld) % cyc] if (k + 1 - ld) % cyc != 0 else dst[-1])
        exit()
    else: #テレポーター転送先が今まで行った町setに入っていなかったら
        dst.append(a[twn - 1]) #入っていなかったら今まで行った町リストに追加
        dsts.add(a[twn - 1])
        twn = a[twn - 1] #テレポーター転送先の更新
print(dst[-1])

```

結論
ループの中で何回も有無の判断をする場合は、目的のリストを直接`in`を使って調べるのではなく、別に作った検索用setを`in`を使って調べるか、フラグ用のリストを作ってそれで調べたほうが圧倒的に速い。
【Vue.js】vue-cliとNuxt.jsの比較まとめ

Vue.jsのフレームワークとして、いろいろあるが、今回はvue-cliとNuxt.jsについて比較してみたいと思う。
ファイル構成や標準で用意されてるものが異なるので、整理用の記事となります。

フレームワークを移行したい時にみていただけるといいかもしれません。

#ディレクトリやファイル構成

###vue-cli

|ファイルパス|役割
|:--|:--
|./index.html|静的ファイル
|./src/main.js|静的ファイルのJS / Vueインスタンスの作成|
|./src/App.vue|動的テーマ
|./src/components/Hello.vue|動的部品
|./src/router/index.js|ルーティング
|./src/store/index.js|状態管理
|./dist|本番用のファイル群


###Nuxt.js

|ディレクトリ|格納するファイル|ファイル例
|:--|:--|:--
|assets|CSSや画像やフォントなど|headerImage.jpg
|components|コンポーネントファイル|Logo.vue(デフォルト)/ Header.vue / Footer.vue
|layouts|サイトの基盤となる全体共通のデザイン|default.vue
|pages|切り替えたい画面 / **ルーティングは自動で行われる**|index.vue(/) / about.vue(/about)
|middleware|画面を読み込む前に処理したい内容|
|plugins|Vue.jsアプリをインスタンス化する前に実行したいJSファイル|axios.js
|static|変更されない静的ファイル|favicon.ico
|store|状態を格納してくれる機能（Vuexストア）のファイル|index.js



最大の違いともいえるのが、Nuxt.jsは自動でルーティング設定を行ってくれるところ。

||vue-cli|Nuxt.js|
|:--|:--|:--
|ルーティング設定|手動|自動
|ルーティングを司るファイル|router/index.js|.nuxt/router.js|


##プロジェクトを生成した時に必要なもの

必要なものは、挙げればキリがないのだが、とりあえず必要なのは**ルーティングするvue-router**と、**状態管理するVuex**をみていく。


###標準装備されているか。

||vue-cli|Nuxt.js|
|:--|:--|:--|
|vue-router|×|○|
|Vuex|×|○|
【git】fatal: 'origin' does not appear to be a git repository と怒られたときの対処法

# 状況

git commit し、git push しようとしたら突然以下のようなエラーが発生

```
fatal: 'origin' does not appear to be a git repository
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

```
git remote -v
```
を実行し、pushしたいURLも表示されていた。

# 対処方法
以下のコードを実行して解決した。
再度urlを登録という意味なのかな

```
git remote add origin https://github****
```

なんだったのだろうか・・・
[Go]文字列をhashにして数字として取得したい

何かしらの文字列からhashを作成する事はそんなに難しくないと思いますが
hashを数字として取得したい事があると思います。
そんな時には [hash/fnv#Sum32()](https://golang.org/pkg/hash/fnv/)が使用出来ます。

以下は「文字列を入力して特定の色typeを返す」サンプルです。

```Go
package main

import (
	"fmt"
	"hash/fnv"
)

type COLOR uint32

const (
	COLOR_RED    COLOR = 0
	COLOR_BLUE   COLOR = 1
	COLOR_GREEN  COLOR = 2
	COLOR_PURPLE COLOR = 3
	COLOR_BROWN  COLOR = 4
)

func (c COLOR) String() string {
	switch c {
	case COLOR_RED:
		return "RED"
	case COLOR_BLUE:
		return "BLUE"
	case COLOR_GREEN:
		return "GREEN"
	case COLOR_PURPLE:
		return "PURPLE"
	case COLOR_BROWN:
		return "BROWN"
	}
	return ""
}

func color(s string) COLOR {
	h := fnv.New32a()
	h.Write([]byte(s))
	return COLOR(h.Sum32() % 5)
}

func main() {
	fmt.Println(color("hogehoge"))
	fmt.Println(color("fugafuga"))
	fmt.Println(color("piyopiyo"))
}
```

実行すると以下のように毎回同じCOLOR typeが取得できます。

```
BLUE
RED
GREEN
```
Docker環境のLaravelでlaravel-mix-bundle-analyzerを使う

# Docker環境では、デフォルト設定では使えなかったのでメモ

## Laravel用のパッケージをインストール

インストールは手順通り。
[https://www.npmjs.com/package/laravel-mix-bundle-analyzer](https://www.npmjs.com/package/laravel-mix-bundle-analyzer)

```
npm install laravel-mix-bundle-analyzer --save-dev
```

## docker-composeの設定を変更

```yaml:docker-compose.yml
version: '3'
services:
  web:
    ports:
      - 8080:8080
      - 8888:8888 // 追加
```

## webpack.mix.jsに追加
ほとんどUsageに書いてある通り。
`{analyzerHost: "0.0.0.0"}`の部分を追加するだけ。

```js:webpack.mix.js
const mix = require("laravel-mix");
require('laravel-mix-bundle-analyzer');

if (!mix.inProduction() && mix.isWatching()) {
  mix.bundleAnalyzer(
    {analyzerHost: "0.0.0.0"} // これ追加
  );
}
```

以上。
CakePHP4 404エラーを別のログファイルに記録する


- 参考元資料 https://tt-computing.com/cake4_0-log-404
- 前提として https://qiita.com/aokazu/items/24c3865312d6568ee048 の ExtErrorHandlerMiddlewareがセットされている。


## config/app.php
- Log設定に記述追加

```php
<?php
//...
'Log' => [
  //...
  'error404' => [
      'className' => FileLog::class,
      'path' => LOGS,
      'file' => 'error404',
      'url' => env('LOG_ERROR_URL', null),
      'scopes' => ['error404'],
  ],
]

```

## src/Middleware/ExtErrorHandlerMiddleware.php 
- 設定変更

```php
<?php
//...
use App\Error\ExtErrorLogger;
//...

class ExtErrorHandlerMiddleware extends ErrorHandlerMiddleware
{
  //...
  //設定追加 ExtErrorLogger を利用するようにする
   protected $_defaultConfig = [
       'log' => true,
       'trace' => false,
       'skipLog' => [],
       'errorLogger' => ExtErrorLogger::class,
   ];

   ```


## src/Error/ExtErrorLogger.php 
- 独自のエラーロガー・ファイル追加

```php
<?php
/** @noinspection PhpUnused */
declare(strict_types=1);

namespace App\Error;

use Cake\Error\ErrorLogger;
use Cake\Log\Log;
use Psr\Http\Message\ServerRequestInterface;
use Throwable;

/**
 * Log errors and unhandled exceptions to `Cake\Log\Log`
 */
class ExtErrorLogger extends ErrorLogger
{
    /**
     * Generate the error log message.
     *
     * @param Throwable $exception The exception to log a message for.
     * @param ServerRequestInterface|null $request The current request if available.
     * @return bool
     */
    public function log(Throwable $exception, ?ServerRequestInterface $request = null): bool
    {
        // 404 扱いとする Exception
        $targetExceptions = [
            'Cake\Controller\Exception\MissingActionException',
            'Cake\Http\Exception\MissingControllerException',
            'Cake\Http\Exception\NotFoundException',
        ];
        // 404 の場合は別ファイルにログを記述
        if (in_array(get_class($exception), $targetExceptions)) {
            $message = $this->getMessage($exception);
            if ($request !== null) {
                $message .= $this->getRequestContext($request);
            }
            $message .= "\n\n";
            return Log::error($message, 'error404');
        }

        return parent::log($exception, $request);
    }
}

```

## logs/error404.log
- このファイルにエラーが書き込まれるのを確認する。
ゆっくりに青空文庫を読んでもらう

[前回](https://qiita.com/Mechanetai/items/78b04ed553cce01fa081 "Pythonでゆっくりボイスを作ろう - Qiita")，Pythonからゆっくりボイスを作成する方法を書きました
今回は，青空文庫をゆっくりに読んでもらいましょう

# 環境

- Python 3.8.3
- SofTalk 1.93.46
- Windows10

# 青空文庫本文のDLと整形

これを1から書こうと思ったのですが，すでに同じことをされている方がいましたので，ありがたく使わせてもらいましょう

[青空文庫からPythonで本文を取得したい - AI人工知能テクノロジー](https://newtechnologylifestyle.net/711-2/)

こちらのサイトで紹介されているコードのmain()関数から，本文の文字列を返すようにします

```python
def main():
    #中略
    return text
```

#ゆっくりに読んでもらう

では，実際にゆっくりに読んでもらいましょう

本文が改行されているとそれ以降は読んでくれないので，改行ごとにループさせて読んでもらいましょう
順次実行してくれるので，読んでる途中で次の本文に割り込まれることはありません

青空文庫本文を取得する `aozora.py` を同じ階層に置いた上で

```python:yukkuritest2.py
import os
import subprocess
import aozora

aozora_text_splitline = aozora.main().splitlines()

os.chdir(os.path.dirname(os.path.abspath(__file__)))

_start = "start ..\\yukkuri\\softalk\\SofTalk.exe"

_speed = "/S:120"

_word = "/W:"

for i in aozora_text_splitline:
    _command = [_start, _speed, _word + i]
    subprocess.run(' '.join(_command), shell=True)
```

これで読んでくれるはずです
試しに短い文章として，芥川龍之介の商賈聖母[^seibo]でも読んでもらいましょう

……流石に精度が低いですね

[^seibo]: 図書カード：商賈聖母
 https://www.aozora.gr.jp/cards/000879/card3813.html
はじめて学ぶjava 【入門】

##javaを初めて学びました

####HelloWorld 文字出力

```
public class Main {
	public static void main(String[] args) {
		System.out.println("hello, world!");
	}
}
```

出力

```
Hello World!
```
System.out.printlnが出力
文字列は””で囲う
おわりには;をつける


####計算方法

```
public class Main {
	public static void main(String[] args) {
		System.out.println("hello, world!");

		System.out.println("31+31の計算をします");

		System.out.println(31+31);
	}
}

```
出力

```
hello, world!
31+31の計算をします
62
```

数式の場合は”で囲わない

####変数の定義と掛け算
```
public class Main {
	public static void main(String[] args) {
	    int x;
	    x = 6;
		System.out.println(x * x * 3.14);
	}
}
```

出力

```
113.04
```

intは数字を定義するときに使う
JavaScriptで値のデータ型を調べる方法（typeofとObject.prototype.toString.call）

typeofでは配列、null、Date、クラスインスタンスなどが全て`object`になってしまう。

```
> typeof("hoge")
'string'
> typeof([])
'object'
> typeof(null)
'object'
> typeof(undefined)
'undefined'
> typeof(new Date())
'object'
```

その点`Object.prototype.toString.call`なら配列、null、Dateなどを識別できる。

```
> Object.prototype.toString.call("hoge")
'[object String]'
> Object.prototype.toString.call([])
'[object Array]'
> Object.prototype.toString.call(null)
'[object Null]'
> Object.prototype.toString.call(undefined)
'[object Undefined]'
> Object.prototype.toString.call(new Date())
'[object Date]'
```
【Rails】wheneverを本番環境＋Capistranoで使う

# 環境
* Ruby: 2.5.7
* Rails: 5.2.4
* 本番環境：AWS EC2／MySQL2／Nginx／Puma／Linux(CentOS)

# 前提
* Capistrano導入済み

# 本番環境で動かす
## 1. wheneverを本番環境にセッティング
* config/schedule.rb

```
env :PATH, ENV['PATH']
# ログファイルの出力先
set :output, 'log/cron.log'
# ジョブの実行環境の指定
set :environment, :production  ★ ここ変更


# 日本時間の午前8:00にメール送信される（JSTは+9:00なので-9:00の時間を記述）
# 未読通知が3件以上たまっているユーザーにメール通知
every 1.days, at: '11:00 pm' do
  runner "ScheduledProcessingMailer.check_notice_mail.deliver_now"
endb
```
実行環境はprodaction環境がデフォルト設定なので`set :environment, :development`を下記に変更


## ２. config.application.rbに追記
* config.application.rb

```
config.paths.add 'lib', eager_load: true
```

`Rails5からデフォルトで本番環境時においてはautoloadが無効化されておりeager load(rails起動時にまとめて読み込む機能)が有効で、開発環境では逆にautoloadが有効でeager loadが無効になっている`ため。


> こちらの記事を参考にさせていただきました。
[Rails5のproduction環境でlib/配下のクラス読込みがNameErrorになるのはautoloadが無効化されたからだった](https://qiita.com/K_Yagi/items/edc46fd976526279312b)


## 3. EC2current上で下記実行

~~~
# 定時処理の内容更新を反映
RAILS_ENV=production bundle exec whenever --update-crontab

# 無効化
RAILS_ENV=production bundle exec whenever --clear-crontab

# cronのログ確認
RAILS_ENV=production crontab  -l
~~~
ちなみに開発環境ではlog/cron.logでログが確認できたが本番環境では出力されない（当たり前）

# Capistranoでwheneverをセットする

## 1. Capfile

```
require 'whenever/capistrano'
```
## 2. config/deploy.rb

```
set :whenever_roles,        ->{ :app }
```

## 3. 開発環境でcapコマンドを実行

```
bundle exec cap production deploy
```



## 参考にさせていただきました
[capistrano3 + wheneverでハマったメモ](http://ria10.hatenablog.com/entry/20140716/1405493180)

[Railsでwheneverを使ってcronを設定する](https://qiita.com/Esfahan/items/e7a924f7078faf3294f2)
[SQL Server] 重複レコードの抽出

# やりたいこと
テーブルの重複レコードを抽出する
忘れがちなのでメモ

# サンプル

同一のcodeを持つレコードを抽出する
抽出するカラムは全カラム


```sql:test

--テーブル作成
CREATE TABLE test(
	 code int NOT NULL
	,accountname varchar(10) NULL
	,item varchar(10) NULL
)

--データをinsert
INSERT INTO test
VALUES(1, 'a', 'もも')
	,(2, 'b', 'メロン')
	,(1, 'a', 'スイカ')
	,(3, 'c', 'なし')

--重複を抽出
SELECT
	 a.code
	,a.accountname
	,a.item
FROM
	test AS a
WHERE
	EXISTS(
		SELECT
			*
		FROM
			test AS b
		WHERE
			a.code = b.code
		GROUP BY
			b.code
		HAVING COUNT(b.code) > 1
	)
ORDER BY
	a.code
```

## 結果

| code	 | accountname	 | item|
|:----------:|:------------:|:------------:|
| 1| a| もも|
| 1| a| スイカ|

## 補足

複数条件で抽出したい時は、```a.code = b.code```の部分に追加すればOK
BOXでExcelVBA（相対パス）

# はじめに
こんにちは。
以前、お客様から`BOX`で`Excelマクロ`が動くのかという質問を受け、調査したのでメモとして残したいと思います。
結論からいうと動きます。
公式の`BoxDrive`というツールを使うことで解決しました。

BOXは、GoogleDriveのようなオンラインストレージです。
権限など充実したビジネス向けの機能がついています。
参考: [BOX公式ページ](https://www.box.com/ja-jp/home)

# BoxDriveについて
BoxDriveは、BoxSyncと同じようなデスクトップアプリケーションです。
BoxSyncは、公式ツールですが下記のような問題がありました。
「`保存したファイルがすぐに反映されない`」「`いつまで経っても同期が終わらない`」

それらの事象は、BoxDriveでは解消されています。
正しくは違うのかも知れませんが、`リンク`があるだけです。PC上にあたかもフォルダやファイルがあるように見えます。

インターネットにさえ接続されていれば、ファイルの`編集・追加・削除`が可能です。

# インストール・設定
**①BoxDriveのインストール**
BoxDriveのインストール方法は、導入環境によっては専用のインストーラーが準備されていたりすることもあるため、管理者に確認して頂ければと思います。
あえて、これですよという示し方はしません。

**②ログイン**
インストール後、ログイン画面が表示されるのでboxアカウントの情報を入力します。
ログインが完了すると、すぐさま現在自分のアカウントの全ファイルが同期できるBoxDrive環境が構成されます。
　⇒『C:\Users\[OSユーザー名]\Box\』にBox上の全ファイルのリンクが作成されます。
ファイル同期ではないため、時間がかかる事はありません。

**③②で作成されたBoxフォルダを開きます。**
するとフォルダやファイルがあるように見えます。正しくは違うのかも知れませんが、`リンク`があるだけです。

# Excelマクロ
上記まで出来たら、`マクロ付きのExcelファイル`をさわってみます。
基本的にマクロは問題なく動くと思います。
フォルダを跨ぐようなパスを参照する場合は、そのExcelブックがある場所から遡ってフォルダを見る`相対パス`で参照するようにします。
>絶対パスは人それぞれPCによって変わってしまいますので、正しく動きません。

筆者のケースでは元々相対パスを利用していたため、問題なく動きました。


以上ですが、参考になれば幸いです。
Java11 + gradle + xjcでxsdからソースコードを生成

# はじめに
Java11 + gradle + xjcでxsdファイルからソースコードを生成するサンプルです。
※Java11.0.4 + gradle6.0.1で動作確認済み

# ビルドファイル
こんな感じ。
src/xsd/sample.xsdにスキーマを配置して、build/xjc_outputにソースが出力されます。


``` 
plugins {
    id 'java'
}

sourceCompatibility = 11
targetCompatibility = 11

repositories {
    mavenCentral()
}

dependencies {
    compileOnly 'org.glassfish.jaxb:jaxb-xjc:2.3.1'
}

task xjc(type:JavaExec) {
    classpath configurations.compileOnly
    main 'com.sun.tools.xjc.XJCFacade'
    args "src/xsd/sample.xsd", "-p", "hoge.fuga", "-d", "build/xjc_output"
}
```

以下に全てのコードを載せています。
https://github.com/HikosakaRyo/xjc_with_java11_sample

# 参考にしたサイト
https://stackoverflow.com/questions/40366754/using-ant-xjc-in-gradle-to-compile-multiple-xsds-from-jar https://stackoverrun.com/ja/q/2104837 https://javaee.github.io/jaxb-v2/doc/user-guide/ch04.html#tools-xjc-ant-task
venvを利用してPythonの仮想環境を構築する(Django + MySQL①)

## この記事について
この記事は、「[Django + MySQLの環境構築を通じてDockerの使い方を学ぶ](https://qiita.com/toffe_hy/items/f17d78abd92f0b4272f6)」に関連する記事群の **Part.1** にあたります。

1. **venvを利用してPythonの仮想環境を構築する ( 当記事 )**
2. [Dockerfileの記述を考える](https://qiita.com/toffe_hy/items/0429a95bfe1786955c2a)
3. [docker-compose.ymlの記述を考える](https://qiita.com/toffe_hy/items/f2e6ecc516fdf593c777)
4. [設定ファイルを編集し docker-compose up を実行する](https://qiita.com/toffe_hy/items/0571b84faa3e6b834c6e)
5. [依存関係にあるサービス間のコンテナ立ち上げタイミングを調整する](https://qiita.com/toffe_hy/items/4b7d8c47c5a1a2defcac)

## はじめに
この記事ではまず、**`venv`を利用して`Python3`の仮想環境を構築**します。

`Pyenv`でホストPCに準備した任意のバージョンの`Python3`を元に、特定のプロジェクト向けの仮想環境を`venv`で作成します。
目的は、**プロジェクト単位で`Python`のバージョンを管理できるようにすること**と、**`pip`によるパッケージ群のインストールを 効率/軽量 化すること**です。

この記事では **`Python3.7.7`** を利用します。

## Pythonを準備する

```shell
# Python 3.7.7 のインストール
$ pyenv install 3.7.7

# 利用する Python3 のバージョンを 3.7.7 にする
$ pyenv global 3.7.7

# バージョン確認
$ python3 --version
Python 3.7.7
```
## 仮想環境の作成
**プロジェクト用のディレクトリを作ってから、その中に仮想環境を作成**します。

```shell
# プロジェクト用ディレクトリの作成
$ mkdir django_starter

# ディレクトリの移動
$ cd django_starter

# 仮想環境の作成
$ python3 -m venv .venv
```
コマンド末尾の`.venv`はパス名です。ここでは慣例にそって`.venv`としましたが、お好みでディレクトリをはさんで階層を深くしたり、好きな名前をつけたりしてももちろん大丈夫です。

続いて、**仮想環境を有効化し、有効化を確認**します。

```shell
# 有効化
$ source .venv/bin/activate

# 「 どこにある Python を使っている状態か 」 確認してみる
(.venv) $ which python
(略)/django_starter/.venv/bin/python
```
shellのユーザー名の前に先ほどつけた仮想環境名が表示されていれば、有効化されていることが確認できます。プロジェクト内に配置された仮想環境のパスに、**このプロジェクトのための`Python3`が配置されていて、それを使っていく**、というイメージで捉えています。ちなみに、

```shell
$ deactivate
```
と実行するだけで、仮想環境から出ることができます。

## パッケージのインストール
仮想環境内の`pip`を使って、必要なパッケージをインストールします。
この記事群の目的で使うことが確定しているものを、いくつか事前にインストールしておきます。

```shell
# インストール
(.venv) $ pip install django==3.0.8 mysqlclient==2.0.1 pathlib==1.0.1

# インストールされているパッケージの確認
(.venv) $ pip freeze
```
次に、これらを元に`requirements.txt`を作成します。

```shell
(.venv) $ pip freeze >> requirements.txt
```
中身はこんな感じになっているはずです。

```txt:requirements.txt
asgiref==3.2.10
Django==3.0.8
mysqlclient==2.0.1
pathlib==1.0.1
pytz==2020.1
sqlparse==0.3.1
```
今後は、環境を共有する際やコンテナ内に環境をコピーする際、このファイル内の記述を元にインストールを行なっていくことになります。(`$ pip install -r requirements.txt`)

## Djangoプロジェクトを作成する
次回から`Docker`関連ファイルの設定を行なっていきますが、その前に`Django`のプロジェクトを作成しておきます。

```shell
(.venv) $ pwd
(略)/django_starter

(.venv) $ django-admin startproject config .
```
もちろんコマンドで生成するディレクトリの名前はなんでもいいのですが、個人的に親ディレクトリと同名だと混乱してしまうタイプなので`config`にしておきます。
`.`は作成場所のパス指定です。

## 現時点でのディレクトリ構成
```shell
django_starter
    ├── config
    │     ├── __init__.py
    │     ├── asgi.py
    │     ├── settings.py
    │     ├── urls.py
    │     └── wsgi.py
    ├── manage.py
    ├── .venv
    │   └── (略)
    └── requirements.txt
```

## 終わりに

仮想環境を利用することで、**プロジェクトに関係のないパッケージのインストールを回避し、必要なものだけを管理できる**ようになります。同様に、このプロジェクトでしか使わないようなものがあっても、**ローカルのメイン環境(?)を汚さずに済み**、とてもいい感じです。

これを、続いて実践に入るコンテナ内の環境構築に利用します。

次の記事では、**Dockerfileの記述について**考えていきます。
続きはこちら↓
「 2. [Dockerfileの記述を考える](https://qiita.com/toffe_hy/items/0429a95bfe1786955c2a) 」

ご覧いただきありがとうございました。
SEIR モデルの日本語表示

次のページを参考にしました。
[【minimize入門】SEIRモデルでデータ解析する♬](https://qiita.com/MuAuan/items/88d5d0c416abb9e9915e)

1000 人の孤立した島に、1 人の感染者がいたらどうなるかというモデルです。パラメータの設定で結果はかなり変わります。

![seir_aug26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/26a4a239-44db-2375-3f81-19ae6e704db8.png)

```py:seir.py
#! /usr/bin/python
#
#	seir.py
#
#						Aug/26/2020
# ------------------------------------------------------------------
import sys
import numpy as np
from scipy.integrate import odeint
from scipy.optimize import minimize
import matplotlib.pyplot as plt

# ------------------------------------------------------------------
def seir_equation(vv,t,beta,sigma,gamma,N):
	ss = vv[0]
	ee = vv[1]
	ii = vv[2]
#
	yprime = np.zeros(4)
	yprime[0] = -beta * ss * ii / N
	yprime[1] = beta* ss * ii/N - sigma * ee
	yprime[2] = sigma * ee - gamma * ii
	yprime[3] = gamma * ii
#
	return yprime
#
# ------------------------------------------------------------------
sys.stderr.write("*** start ***\n")

S_0 = 999.0
I_0 = 0.0
E_0 = 1.0
R_0 = 0.0

N = S_0 + E_0 + I_0 + R_0

beta = 6.87636378
sigma = 1. / 1.21965986
gamma = 1. / 2.01373496

ini_state=[S_0,E_0,I_0,R_0]
t_max = 14
dt = 0.01
tt=np.arange(0,t_max,dt)
#
plt.rcParams["font.family"] = "IPAGothic"
plt.title("SEIR モデル")
plt.plot(tt,odeint(seir_equation,ini_state,tt,args=(beta,sigma,gamma,N)))
plt.legend(['S: 未感染者','E: 潜伏者','I: 感染者','R: 回復者'])
#
plt.show()

sys.stderr.write("*** end ***\n")
# ------------------------------------------------------------------
```

Arch Linux で確認しました。

```text
$ uname -a
Linux iwata 5.8.3-arch1-1 #1 SMP PREEMPT Fri, 21 Aug 2020 16:54:16 +0000 x86_64 GNU/Linux

$ python --version
Python 3.8.5
```
【VisualStudioCode】拡張機能でsqlite3を扱いやすくする

#プロローグ
VisualStudioCodeをsqlite3の拡張を使って扱いやすくします

#手順
マーケットプレイスからsqliteの拡張をインストールします
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/a13f6f57-f73f-f9b7-f9a8-38fa9c245dab.png)

「Ctrl + Shift + P」のコマンドパレットから「Open Database」を実行します。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/858efc87-d34a-c11c-ad52-19ff52216f84.png)

そのまま対象のDBを選択すると、「SQLITE EXPLORER」でDBやテーブルが表示できます
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/b9fc5b2c-fcb2-b4a4-26d0-8fff208d117f.png)

データを確認してみます。
コマンドパレットから「Use Database」を選択します。
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/2ff97821-057a-f604-02af-69827bf8144d.png)

対象のDBを選択します
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/8ad1766d-6d4c-86ff-775a-22234a9cff97.png)

右下に利用中のDBが表示されます
選択したのは「test.db」です。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/c109ab53-bde7-cd78-08dc-3b7b6fd7f426.png)

sqlファイルを作ります。
同じくコマンドパレットから「New Query」を実行します。
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/e094e329-631e-73b5-d94d-4b7146b52734.png)

適当なselect文を書きました。
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/aab9bbeb-f665-d5de-5ce6-69cff4822588.png)

コマンドパレットから「Run Query」を選択します
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/8dfc4ecb-c861-5311-41d6-459f34c56d7a.png)

実行結果が表示されました。
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538462/e83142fd-6818-5cbf-59a5-b0e81f73a737.png)

#エピローグ
VSCにはいろいろな拡張機能があって便利ですね。
ほかにもどんどん使っていこうと思いました。
nuxt spa, ssg, ssrそれぞれのasyncData, fetchのタイミング

Nuxtのサーバーサイドでデータ取得のために使用する`asyncData`と`fetch`がspa, ssg, ssrそれぞれのモードでどういうタイミングで呼ばれるのか調査した。

Nuxt 2.14.0

[API: asyncData メソッド - NuxtJS](https://ja.nuxtjs.org/api/)
[The fetch Method - NuxtJS](https://ja.nuxtjs.org/guides/components-glossary/pages-fetch/)

## spa

```javascript:nuxt.config.js
{
  mode: 'spa',
  target: 'static',
}
```

```
$ nuxt generate
$ nuxt start
```

spaモードで`asyncData`も`fetch`も呼ばれないということはなく、クライアントサイドでちゃんと呼ばれる。

【PageAにアクセス】
Client PageA asyncData
Client PageA beforeCreate
Client PageA data
Client PageA created
Client PageA beforeMount
Client PageA fetch
Client PageA mounted

【nuxt-linkでPageBにアクセス】
Client PageB asyncData
Client PageA beforeDestroy
Client PageA destroyed
Client PageB beforeCreate
Client PageB data
Client PageB created
Client PageB beforeMount
Client PageB fetch
Client PageB mounted

## ssg

```javascript:nuxt.config.js
{
  mode: 'universal',
  target: 'static',
}
```

```
$ nuxt generate
$ nuxt start
```

`asyncData`と`fetch`はgenerate時に呼ばれ、クライアントサイドでは呼ばれない。

【generate】
Server PageA asyncData
Server PageB asyncData
Server PageA beforeCreate
Server PageA data
Server PageA created
Server PageA fetch
Server PageB beforeCreate
Server PageB data
Server PageB created
Server PageB fetch

【PageAにアクセス】
Client PageA beforeCreate
Client PageA data
Client PageA created
Client PageA beforeMount
Client PageA mounted

【nuxt-linkでPageBにアクセス】
Client PageA beforeDestroy
Client PageA destroyed
Client PageB beforeCreate
Client PageB data
Client PageB created
Client PageB beforeMount
Client PageB mounted

## ssr

```javascript:nuxt.config.js
{
  mode: 'universal',
  target: 'server',
}
```

```
$ nuxt build
$ nuxt start
```

直接アクセスするとサーバーサイドで`asyncData`と`fetch`が呼ばれる。
nuxt-linkでアクセスすると、クライアントサイドで`asyncData`と`fetch`が呼ばれる。

【PageAにアクセス】
Server PageA asyncData
Server PageA beforeCreate
Server PageA data
Server PageA created
Server PageA fetch
Client PageA beforeCreate
Client PageA data
Client PageA created
Client PageA beforeMount
Client PageA mounted

【nuxt-linkでPageBにアクセス】
Client PageB asyncData
Client PageA beforeDestroy
Client PageA destroyed
Client PageB beforeCreate
Client PageB data
Client PageB created
Client PageB beforeMount
Client PageB fetch
Client PageB mounted
【Android】マルチスライダー(操作ポイントが2つ以上)の作成方法


マルチスライダー([参照画像](https://miro.medium.com/max/1200/0*zk1tVyZtIlucLEzk.gif))作成方法の結論:
 [MultiSliderライブラリ](https://github.com/apptik/MultiSlider)を使用すればいい。

### 補足

以下のようなコードを追加すると、いい感じにスライドしてくれます。

```kotlin
    with(binding.priceRangeSlider) {
        max = 99999
        min = 0
        getThumb(0).value = 0
        getThumb(1).value = 99999
    }
```
文字列の配列を数値に変換する

## 文字列の配列を数値に変換したい！

```ruby:test.rb
> "1,2,3".split(",")
=> ["1", "2", "3"]
```

とあるプログラミングテストとかで標準入力で値を受け取って配列に直すのですが、split使うと
文字列になっちゃうから数値に戻したいなーとか思ってたんですよね。

※そもそも標準入力で値受け取る時にもっと効率的な方法あるんじゃ、、、、笑

、、、、、、とりあえず調べてたら便利なのがあるじゃないですか。

__mapメソッド__

```ruby:test.rb
> "1,2,3".split(",").map(&:to_i)
=> [1, 2, 3]
```
https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/map.html
https://teleporter.hateblo.jp/entry/ruby-str-to-num

「mapメソッドは、要素の数だけ繰り返しブロックを実行し、ブロックの戻り値を集めた配列を作成して返します」

ざっくり考えると、指定した条件で配列を作り直す感じですかね。
Gitなにがし忘れがち


# 忘れないでね

Gitなにがし忘れがちあるある言いたい。

## 初期に設定すること（必須）

- 個人の識別情報設定

```bash
git config --global user.name "My Name"
git config --global user.email ID+ユーザー名@users.noreply.github.com
```

## メールアドレスのプライバシー設定（任意）

Git操作でユーザーに変わってメールを送信する場合、メールをGitに設定する必要がある。  
プライベートメールアドレスを表示させないようにGitHub側で設定する。  
[GitHub Settings Emails](https://github.com/settings/emails)の下記項目にチェックする。  

- [x]  __Keep my email addresses private__

## コマンドとか

### バージョン確認

```bash
git version
```

### コンフィグ確認

```bash
git config --list
```
- (END)を抜けるには ```q```

### オプション付与で、レベル毎に確認

```bash
git config --system --list
git config --global --list
git config --local --list
```

- localの確認はリポジトリ内で実行

### コンフィグの優先順位と場所

|Priority| level | range | path |
|:----:|:----:|:----:|:----:|
|1|local |リポジトリ|リポジトリ/.git/config|
|2|global|ユーザー全体|~/.gitconfig|
|3|system|システム全体|/usr/local/etc/gitconfig| 

### GitHubでリポジトリ名を変更したとき

#### リモートリポジトリの確認

```bash
git remote -v
```
#### リモートリポジトリの変更

```bash
git remote set-url origin <new URL>
```

#### コンフィグファイル編集でもOK

```tex
対象ディレクトリ.git　>　config　>　[remote "origin"]　を編集
```

<details><summary>Deleteすると草消えるなんて知らなかったYO🌼</summary>
リポジトリ名が気に入らないだけで気さくにDeleteしてたら気付いた..😨
</details>

### リモートリポジトリにpushしてしまったファイルを消したい

```bash
git rm --cached 指定ファイル
```
- --cachedオプション： ローカルのファイルを残しつつリモートリポジトリから指定ファイルを削除する

## 参考

[Git-最初のGitの構成](https://git-scm.com/book/ja/v2/%E4%BD%BF%E3%81%84%E5%A7%8B%E3%82%81%E3%82%8B-%E6%9C%80%E5%88%9D%E3%81%AEGit%E3%81%AE%E6%A7%8B%E6%88%90)
ビルドの自動化_メモ_20200826

#ビルドの自動化


**１．継続的インテグレーション**

　　そもそも継続的インテグレーションって何？

　　**継続的インテグレーション**とは、ソフトウェア開発において、ビルドやテストを頻繁に繰り返し行なうことにより
　　問題を早期に発見し、開発の効率化や省力化、納期の短縮などを図る手法のことである。

　　ここで自分の気づきを加えるとすると、
　　継続的インテグレーションは繰り返しビルドとかをするから、アジャイル開発などで使われそうですね。
　　筆者はウォーターフォール型開発のほうが好みですが・・

　　もちろんちょこっとずつ動かして動くことを確認しながらちょっとずつ変更していくのが安心できる人も
　　いると思います。

　　ですが私たちは技術者ですので面倒なことは作業時間範囲内で自動化するのがおすすめです。
　　
**２．継続的インテグレーションと自動化**

　　継続的インテグレーションでは、各メンバーは極めて高い頻度でコンパイルやテストを繰り返します。
　　同じテストを何回もやるような現場で筆者も働いたこともあり、そういったものが該当するかと思います。

　　リファクタリングしてより良いものにしようとしている過程で、メトリクスの計測を何度も行うことも
　　あると思います。
　　それらの作業をすべてメンバーの手作業で行っていては、メンバーに大きな負担がかかってしまいます。

　　筆者は全部手作業でやるのが品質を担保できるんだよ！といわれたことがありますが決してそんなことはありません。
　　なぜなら人間の手でやると集中が途切れてミスする可能性があるからです。
　　人の集中できる時間はせいぜい１０分など様々な仮説がありますが、短いことは確かです。

　　そこで多くの開発プロジェクトではコンパイルやテストなど一連の開発作業(ビルド)を一回のコマンド実行で自動的に
　　行えるような仕組みを準備することが一般的です。
　　これを**ビルドの自動化**と呼びます。

　　＜自動化のメリットデメリット＞

　　**メリット**

　　・自動化することによって手作業でやらなければいけなかった作業が減り
　　　業務の効率化が図れる

**３．バッチによるビルドの自動化**

　　まず誰にでも手軽に実践できるのが、OSが備えるコマンドを連続して実行する機能を使う方法です。
　　Windowsではバッチファイル(.bat)、LinuxやMacOSXではシェルスクリプト(.sh)と呼ばれるファイルを
　　作成し、その内容として「コマンドプロンプトで入力する一連のコマンド」をテキストエディタで書けば、
　　一回のコマンド実行でビルドが完成します。

　　基本開発現場では専用のバッチやシェルが用意されていますが、いろいろな事例があり作りたいな
　　作ったらもっと作業効率が上がりそうなのにという状況があるかもしれません。

　　例えばログを収集しないといけないが自分で各ログが格納されるところまで全部取りに行くのはなかなか
　　大変です。
　　そんな時に一回起動するだけでログを収集できるようなものがあれば効率が上がりそうですよね。

　　大体の開発者は作業効率を上げるためが自動化の理由としていますが、
　　"めんどくさいから"自動化してしまおうが根底にあってもよいと思います。

**４．その他自動化の方法**

　　Antによるビルドの自動化

　　バッチファイルやシェルスクリプトは、違うOSではうまく動作しないこともあります。
　　また、本格的な自動化をしようとすると、ビルド失敗時の処理の内容の記述も自分で書かなければいけません。

　　そこでJava開発においては、古くからAntという自動化ツールが使われてきました。
　　

　　mavenによる高水準ビルド自動化

　　Antと並んでよく利用されているビルド自動化ツールがApache Mavenです。
　　MavenでもAntと同じように設定ファイルを作成して利用します。
　　設定ファイルにソースコードやテストコードが格納されているフォルダ構成や依存しているライブラリ
　　やプロジェクトの基本情報を記述して最後に何を生成したいのかを指定します。
unicornが起動しなかった話

先日にお名前ドットコムでドメインを制限解除されてようやくサイトにアクセス出来ると思ったらまさかのエラー
EC２にアクセスして色々と弄って見たところnginxは起動するがunicornを起動させようとすると

``` 
master failed to start, check stderr log for details
```
と返ってきたのでその時の解決方を自分用にまとめて起きました。

# 結論
unicornのverが原因でした。
私が参考にしたデプロイの[記事](https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1#mysql%E3%81%AE%E8%A8%AD%E5%AE%9A)はこちらで、ここではunicornを指定していませんでした。なのでverを指定して```bundle install``` をしてあげれば解決です！！
Amazon Cognitoユーザープールで各種トークンの有効期限がカスタマイズ可能になった件

# はじめに
つい先日、Amazon Cognitoユーザープールのアップデートが公開されました。

[Amazon Cognito ユーザープールがトークンの有効期限のカスタマイズをサポートするように] (https://aws.amazon.com/jp/about-aws/whats-new/2020/08/amazon-cognito-user-pools-supports-customization-of-token-expiration/)

これまでにCognitoユーザープールを利用されていた方には衝撃だったんじゃないかと思います(私もその一人でした)。
発表されてすぐに少し動きを試したので少し備忘録がてら記事にしようと思いました。

## 主な変更
- リフレッシュトークン、アクセストークン、IDトークンにそれぞれ有効期限を持たせることができるようになりました。
- これまで◯日間単位のみだった期限の指定が◯日間と分で指定できるようになりました。

## UI的な変更
![スクリーンショット 2020-08-26 14.39.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/382072/bd2687d3-2d9c-5d73-fd17-e676fc238dfa.png)

### ちょっとしたメモ
- セッションストレージは空になる
- リフレッシュトークンの期限が切れた時のエラー

```
ERROR 
{code: "NotAuthorizedException", name: "NotAuthorizedException", message: "Refresh Token has expired"}
code: "NotAuthorizedException"
message: "Refresh Token has expired"
name: "NotAuthorizedException"
```



## 最後に
これまでアプリの開発中に「◯◯にアップデートがきたぞ！！」ってなっても、自分の利用していないサービス or 利用はしているが、機能としては使わない部分がアップデートされることが多々ありました。しかし今回のアップデートは今後開発を予定していた箇所に関連する内容となり、少し開発が楽になるなーと思いました。

Cognitoヘビーユーザーなのでもっともっとアップデートしてほしい...UIとか...

ではまた。
bit全探索の確認

Python de アルゴリズム（bit全探索）
https://qiita.com/gogotealove/items/11f9e83218926211083a

この記事の例題1を自分なりに整理した

```main.py
money = 300
item = (("みかん", 100), ("りんご", 200), ("ぶどう", 300))
n = len(item)
for i in range(2**n):
    bag = []
    total = 0
    for j in range(n):
        if((i >> j) & 1):
            bag.append(item[j][0])
            total += item[j][1]
    if(total <= money):
        print(total, bag)
```
出力

```
0 []
100 ['みかん']
200 ['りんご']
300 ['みかん', 'りんご']
300 ['ぶどう']
```

i >> j : i を　右にjビットシフト(iを(1/2)^jする) 
i << j : iを左にjビットシフト(iを2^jする)

n=3,i = [0:7], j=[0:2]において
######i = 0, j=0のとき　
i >>j = 0 0と1の論理積は0なので0 i = 0, j=1のとき i>>j = 0 0と1の論理積は0なので0 i = 0,j=1 i=0, j=2 のときも同様に0

######i=1, j=0のとき 
1 >>0 = 1 1と1の論理積は1なので1 よってbag.append(item[0][0]), total += item[0][1], total = 100 <= 300 なので print 100 ['みかん'] i=1, j=1のとき 1 >> 1 = 0.5 = 0 0と1の論理積は0なので0 i=1, j=2のとき 1>>2 = 0

######i=2, j=0のとき 
2>>0 = 2 i=2, j=1のとき 2>>1 = 1 1と1の論理積は1 よってbag.append(item[1][0]) = "りんご", total += item[1][1],total=200<=300　なので print 200['りんご'] i=2, j=2のとき 2>>2 = 0

######i=3, j=0のとき 
3>>0 = 3 i=3, j=1のとき 3>>1 = 1 よって bag.append(item[1][0]) = りんご, total += item[1][1]

######i=4, j=1のとき 
4 >> 1 = 2 
######i=4, j=2のとき 
4 >> 2 = 1 
よって bag.append(item[2][0])= "ぶどう", total += item[2][1], total = 300 <= 300 なので print 300['ぶどう']

######i=5, j=0のとき 
5>>0 =5 5&1 = 1 
######i=5, j=1のとき 
5 >>1 =2 
######i=5, j=2のとき　
5>>2 = 1 1&1 = 1 total= 100 + 300 = 400 > 300　より不適

######i=6, j=0のとき 
6>>0 = 6 6&1 = 0 
######i=6, j=1のとき 
6>>1 = 3 3&1 = 1 
######i=6, j=2のとき 
6>>2 = 1 1&1 = 1 
total = 200 + 300 = 500 > 300 より不適

######i=7, j=0のとき 
7>>0 = 7 7&1=1 
######i=7, j=1のとき 
7>>1 = 3 3&1=1 
######i=7, j=2のとき 
7>>2 = 0 
total = 100 + 200　なので print 300['みかん']['りんご']
Django: url kwargsをtemplate内で取得する

## kwargsの取得
slugなどのkwargsをtemplate内で取得する方法です。

## 環境
- Django: 2.2.9
- Python: 3.8.2

## template

```html:templates/sample.html
<div>
  {{ view.kwargs.pk_name }}
  {{ view.kwargs.slug_name }}
</div>
```


## 参考
- [Can I access url kwargs in django template context processor?](https://stackoverflow.com/questions/35392596/can-i-access-url-kwargs-in-django-template-context-processor)
1分で読めるフロント向けセキュリティ対策

## OS コマンド・インジェクション
OSのコマンドを実行される脆弱性。 ~~ユーザーの入力をバリデーションしてからサーバに送るか、~~ サーバサイドにバリデーションをお願いする ~~（言わなくてもしてくれてることが大半）~~

## XSS
ユーザーからの入力で変化する画面でjsやらhtmlを埋め込まれて情報を抜き取られたりする脆弱性。
~~ユーザーからの入力をチェックし、表示しても問題ない値にしてから表示してあげれば解決~~
こちらもサーバーサイドにバリデーションをお願いする

## ライブラリの最新化
jsのパッケージには脆弱性を含むものも複数存在している。そのため脆弱性の情報を素早くキャッチし、パッケージを最新のものに更新する必要がある

## 他の脆弱性
フロントじゃ対策できない

## 結論
ユーザー入力のデータを生のままサーバ側にサーバに送ったり、画面に表示したりしてはいけない。
ただフロントサイドはバリデーションや修正を回避されるので、基本サーバーサイドに対策をお願いすることになる
ただしフロントで使うパッケージの脆弱性は定期的に行うこと


他にもこんな対策があるよ！ というのがあれば教えてくださるとありがたいです
Azure Synapse Analytics SQLプール作成してみた

Azure Synapse Analytics SQLプールのポータルからの作成方法を掲載します。

####①Azure Portalへログイン
Azureポータルへログインしたら、Azure Synapse Analyticsを検索し、「Azure Syanapse Analytics（以前のSQL DW）」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/40d060a4-bdef-0a0d-6de9-32e1ad4466c0.png)


####②Azure Synapse Analyticsの追加
「Azure Synapse Analytics（以前のSQLDW）」の画面に遷移後、「追加」を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/fd187c1e-6462-3ac8-333d-cbe31e4befc4.png)

####③「基本」の設定
* 「基本」タブにてSynapse SQLプールが稼働するサブスクリプションやリソースグループの設定を行います。
* 「SQLプール名」は実際にSynapse SQLプールとして稼働するユーザデータベースの名前を入力します。
* 「サーバー」はSQL データベースを指定します。Synapse SQLプールの接続ユーザやホストの情報が管理されます。既存の物を選択することもできますが、「新規作成」からこの画面より新規に作成も可能です。
* 「パフォーマンスレベル」はSynapse SQLプールのパフォーマンス設定がおこなえます。もともとGen1とGen2が存在していましたが、現在はGen1は利用できず、Gen2のみ選択可能です。
「cDWU」という単位で指定し100~30000まで指定可能です。（DW6000cを超えて利用する場合はサポートへの制限解除申請が必要です。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/3aceb71c-db47-3f41-a4cd-e337fc1761c7.png)

####④「ネットワーク」の設定
「ネットワーク」タブでは前述の基本タブで新規にSQLデータベースを作成した場合に、接続の方法を指定します。
※既存のSQLデータベースを指定した場合は、プライベートエンドポイントを作成するか聞かれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/14534ca4-3975-6aca-5f45-22da7d266d2f.png)

####⑤「追加設定」の設定
「追加設定」タブでは取得したバックアップからの復元や、事前にサンプルデータを作成するかなどを選択できます。また、「SQLプールの照合順序」にてSynapse SQLプールの照合順序が変更できます。（照合順序は基本的に後から変更はできません。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/9ab90b71-523e-c2f2-dd0e-b347e79d878f.png)

####⑥「タグ」の設定
「タグ」タブで必要なタグ付けを行えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/d7bf12c1-9a98-efe1-ef87-da8facc666a0.png)

####⑦「確認および作成」
最後「確認および作成」タブにて設定の確認を行います。問題なければ「作成」を押下すればSyanapse SQLプールが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/5491ada9-6095-6fa7-0357-f1801432759e.png)

####【Appendix】SSMSでの接続
作成が完了すればSSMSなどで接続することが可能です。

* 「サーバ名」にはSQLデータベースのサーバ名を入力します。
* 「認証」はSynapse SQLプールでは「Azure AD認証」と「SQL Server認証」を選択できますが、画像はSQL Server認証の例で、
SQLデータベースのログインユーザ名とパスワードを入力するとログイン可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/7c8773bc-604b-f9a3-e010-de7fdb480ba7.png)


接続が成功すれば、オブジェクトエクスプローラーにて作成したSynapse SQLプールが確認出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/697647/e2f968d2-bdb3-b869-2668-a05c8aeab0de.png)
デザイン苦手の初学者がVue.jsでポートフォリオサイトを作ってみた

#はじめに

普段は、独学で開発をしている初学者です。
これまで主にRailsを使って開発を行っていましたが、作成したWebページのセンスが壊滅的だったので、自分についてまとめたポートフォリオサイトを作成してみました。

URL：https://masanori-kimura.netlify.app/

使用言語：Vue.js
FW： Vuetify

トップページはこんな感じです
![スクリーンショット 2020-08-23 9.52.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454986/e2e881df-1970-686b-2878-5764f2edddc7.png)

#意識したこと
まずは『ポートフォリオサイト』で検索し、いろいろなサイトをみて勉強しました。

そして自分のポートフォリオサイトに取り入れようと意識した点は、以下の3つです。

+ Google Fonts使って、細めなフォントにする
+ あまり色を使わない（カラフルだとセンスがいる）
+ トップページの背景を印象的な画像にする

結局フォントは、'Recursive'　'M PLUS 1p'を使用しました。

##ヘッダー
　ヘッダーは、アンカーリンクを使って指定したコンポーネントまでスクロールできるように作りました。
スクロールをどう実装するかは悩みましたが、Vuetifyなら簡単に実装できました。

```
# Aboutページの場合
@click="$vuetify.goTo(href='#about')"          
```

##TOPページ
TOPページに使用した画像はCanvaから引っ張ってきたものです。

画像の上に文字を重ねてアニメーションも使用しました。
アニメーションは、Vueの公式サイトに名前が挙がっていたAnimate.cssを使用しました。

https://animate.style/

たった１行のコードでアニメーションが実装できます。

##ABOUTページ
ABOUTページではVuetifyの『Timelines』を使用しました。

https://vuetifyjs.com/en/components/timelines/#timelines
![スクリーンショット 2020-08-26 11.24.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454986/95c4af37-aa1b-9ca2-e2db-24818023191f.png)

薄い経歴ですが、分かりやすいですね。

##SKILLページ

SKILLページでは自分扱える言語・FW・インフラ周りについてまとめました。
ページのレイアウトは一番迷ったのですが、こんな感じになりました。
![スクリーンショット 2020-08-26 11.29.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454986/1ee11640-8d53-c4b3-078b-93f332ede2f8.png)

アイコンはプログラミング系のアイコンが揃っている『DEVICON』を使用しました。
https://devicons.github.io/devicon/

また、スキルのレベルを表した星もVuetifyで実装しました。
https://vuetifyjs.com/en/components/ratings/

##WORKESページ

WORKESページはシンプルで、ポートフォリオの画像を並べて、クリックしたらモーダルウィンドウが開くようになっています。
![スクリーンショット 2020-08-26 11.30.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454986/fe5e7db5-062f-8fe1-151a-9af0dcf2f08e.png)

ありがたいことに、このモーダルウィンドウもVuetifyで実装しました。
https://vuetifyjs.com/en/components/dialogs/

#まとめ
このようにしてポートフォリオサイトを作成しました。
以前作っていたWebサービスのページと比べ、まだまだですが多少見れるようになったと思います。
CentOSでmatplotlibが「いまAggを使ってるからfigureを出せないよ」と怒られた時の対応

# 現象

CentOSでこんなコードを実行する。

```py:test.py
import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.show()
```

するとこんなエラーが出る。

```sh
$ python3 test.py
test.py:3: UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.
  plt.show()
```

# 対策

tkinterをインストールする。

```sh
sudo yum install python3-tkinter
```

すると、以後はちゃんとグラフが表示される。

```sh
$ python3 test.py
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79744/c8eac3da-a730-4907-fe2a-596f5e7dba04.png)

# 原因

CentOSのPython3は、デフォルトでnon-GUIのAggしか入っていない。tkinterを入れてやると、GUI-backendの`TkAgg`が有効になり、それを使ってくれるようになる。

ちなみに、記事によっては

```py
import matplotlib
matplotlib.use('TkAgg')
```

のように、明示的に`TkAgg`を指定する必要があると書いてあったりするが、僕の環境(CentOS Linux release 7.8.2003)では、`python3-tkinter`を入れるだけで(Xが有効なら)自動的に使ってくれるようだ。
【Heroku】にデプロイした【Laravel】の外部ストレージをS3に設定する

###要約

1. controllerに`use Illuminate\Support\Facades\Storage;`を追記してstorageファサードを使えるようにする
2. storeAsの代わりに`Storage::disk('s3')->putFileAs('/', アップロードファイル, ファイル名, 'public'`を使って保存する
3. s3のユーザを追加する
4. 追加したユーザのアクセスキーをHerokuのconfigに追加
5. その他、
AWS_ACCESS_KEY_ID 
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION
AWS_BUCKET
AWS_URL
を追加していく。



###画像を保存するメソッドが変わる

```php:controller.php
use Illuminate\Support\Facades\Storage; // 追記
```

ローカルではstorageディレクトリに画像を保存していたが、Herokuにデプロイする時点で保存できないので、外部ストレージを使う必要がある。

とりあえずAWSのs3ストレージを使うことに。それに伴いいくつか設定しないといけない。

（S3でバケットをすでに作成している前提です。）
https://www.youtube.com/watch?v=nMDIVQsESBY&t=2s
バケット作成の参考にした動画↑


S3ストレージ上でアカウントのプルダウンメニューでマイセキュリティ資格情報というところからユーザの追加ができます。

手順にしたがっていくとアクセスキーなどが表示されるので、それをHerokuのconfigに追加していく。

```:ターミナル
$ heroku config:add AWS_ACCESS_KEY_ID=キー
```
という感じで追加していく。ちょっと面倒。
herokuのサイト上でも入力できます。


###データベースに保存しているのが画像のパスじゃなくてファイル名だとimgのsrcを変更する必要あり

```:view.blade.php
<img src="s3のURL/{{ ファイル名 }}">

```
とすることで表示されるようになりました。


###基本はハッシュ化したファイル名でアップするのかな？

いくつか動画やサイトをみてみたけど、ストレージに保存する際のメソッドがほとんどpuFileだった。

それをデータベースとストレージに保存して表示されるね！みたいな説明だったので、よくわかりませんが、オリジナルのファイル名でやらない方がいいのかも。
xmlstarletコマンドでRDFデータを取得する

　xmlstarlet コマンドでRDF形式のファイルを取得するときの備忘録です。
　以下のようなRDFファイルにおいて、title と link を取得することを想定します。

```rss.rdf
<rdf:RDF xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:sec="http://jvn.jp/rss/mod_sec/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xml:lang="ja">
  <item>
    <title>タイトル</title>
    <link>https://example.com/no123456.html</link>
    <description>説明書き</description>
  </item>
</rdf:RDF>
```
この場合、-N オプションで名前空間を指定する必要があります。また、xmlns="http://purl.org/rss/1.0/" のように、名前空間接頭辞が無い定義については、x などの重複しない名前空間接頭辞を指定する必要があります。

```
# xmlstarlet sel -N rdf=http://www.w3.org/1999/02/22-rdf-syntax-ns# -N x=http://purl.org/rss/1.0/ -t -m "//rdf:RDF/x:item" -v "x:title" -o " / " -v "x:link"
```
Railsでlib以下に作った自作クラスを呼び出す

#config/environment.rbに自作クラスをrequire
----

lib/
　├ assets/
　├ tasks/ 
　└ test.rb <-追加

```ruby:test.rb
class Test
    def aa
        puts "aa"
    end
end
```



##config/environment.rbを編集

```ruby:environment.rb

# Load the Rails application.
require_relative 'application'
require 'test' #これを追記

# Initialize the Rails application.
Rails.application.initialize!
```

##使えるかテスト

```
 % rails c
Running via Spring preloader in process 62643
Loading development environment (Rails 6.0.3.2)
[1] pry(main)> Test
=> Test

```

以上
デバイスとLinuxファイルシステム

<h2>パーティションとファイルシステムの作成</h2>
　ディスクに保存されるデータをファイルとして管理して利用できるようにする仕組みを***ファイルシステム***という.ハードディスクまたはSSDを利用するには、ディスク内にパーティションを作成してその内部にファイルシステムを作成し、それをマウントするという流れになります.
>ハードディスク

　接続するための規格まとめ

- [ ] SATA…Serial Advanced Technology Attachmentの略.コンピュータとハードディスク等の接続に関する規格のひとつ.
- [ ] SAS…SATAと比べて高速、高信頼性.
- [ ] SCSI…周辺機器との接続において一般的な規格.SCSIデバイスを使うにはSCSIホストアダプタ（SCSIカード）が必要.

　デバイス-PC間でやりとりするインターフェースとして***デバイスファイル***があります.Linuxが扱うデバイスは、ブロックデバイス（ハードディスクやSSDなどメディア上の任意の場所にアクセスできるもの）とキャラクタデバイス（キーボードやシリアルポートなど文字単位でデータを読み書きするもの）の2種類あります.

>パーティションの種類

　1つのディスクドライブを論理的に分割して異なるファイルシステムを利用できます.以下はBIOSベースのパーティションの種類です.

- [ ] 基本パーティション…最大4つ（/dev/sda1～sda4）のパーティションを作成できます.
- [ ] 拡張パーティション…本パーティションにはファイルシステムではなく論理パーティションが格納されます.
- [ ] 論理パーティション…拡張パーティション内に作成されたパーティションのことで、基本パーティションの数に依らず/dev/sda5から作成されます.

>パーティション管理コマンド

　構文：***fdisk -l {デバイス名（絶対パス）}***

>ファイルシステムの作成

　Linuxのファイルシステムは「ファイルの中身（データ）」と「ファイルの属性や管理情報」は別々で保存されます.後者を格納しているのがiノード（Indexノード）という管理領域です.これはファイルシステム作成時に確保されて、ファイルやディレクトリが作成されるごとに1つずつ割り当てられます.
　
　ファイルシステムの種類は、ext2(Linux標準)、ext3(ext2にジャーナリング機能付き)、Btrfs(高機能)が挙げられる.Btrfsは***mkfs.btrfs***コマンドで実行できます.

 ***mkfs -t ファイルシステムの種類 {デバイス名}***を使ってパーティション上にファイルシステムを作成できます.

　***mkswap {デバイス名}***でパーティション上にスワップ領域を作成できます.

<h2>ファイルシステムの管理</h2>
>ディスクの利用状況の確認

　ファイルシステムに書き込めなくなる原因は、
・空き容量の不足
・iノードの枯渇
　が挙げられる.空き容量の確認は***df***コマンド、iノードの使用状況は***df -i***で行う.容量が大きいほど割り当てられるiノードの値が大きいです.
　ファイルやディレクトリが占める容量を確認するには****du　-a***コマンドを使います.

>ファイルシステムのチェック

　***fsck -a***コマンドでディスクのチェックを行い、自動的に修復を試みます.ext2、ext3、ext4には***e2fsck***コマンドが利用できます.

>ファイルシステムの管理

　***tune2fs -i(sec) {デバイス名}***を用いてチェックする間隔を指定できます.

<h2>ファイルシステムのマウントとアンマウント</h2>

　ファイルシステムの情報は、/etc/fstabファイルに記述されています.デバイスファイル欄のUUIDはデバイスを識別するためのIDで、***blkid***コマンドで各デバイスとIDの対応を確認できます.
　コマンドとしては***mount [オプション]***と***umount[オプション]***を用いて行います.


<h2>ファイルの配置と検索</h2>

>FHS

　File Hierarchy Standardの略でファイルシステム階層標準のことです.

- [ ] /bin …一般ユーザーでも使用可能なコマンド(cat,dd,mount,shなど)が配置されています.
- [ ] /sbin …rootユーザーのみが実行できるシステム管理に必須のコマンド(fdisc,fsck,rebootなど)が配置されています.
- [ ] /etc …システムやアプリケーションの設定情報、スクリプトファイルなどが配置されています.
- [ ] /dev …ハードディスクやDVD-ROMなどのデバイスファイルが配置されています.
- [ ] /lib …共有ライブラリやカーネルモジュールが配置されています.
- [ ] /media …リムーバブルメディアのマウントポイントが配置されています.
- [ ] /opt …プログラムがインストールされるディレクトリです.
- [ ] /proc …カーネル内部にアクセスするための仮想的なファイルシステムです.
- [ ] /boot …起動に必要な設定やカーネルイメージ（Linuxカーネルを圧縮したファイル）が配置されています.
- [ ] /var …配下に/cache,/log,run(システムの状態を示すファイル)などがあります.
- [ ] /usr …コマンドやユーティリティが配置されています.

>ファイルの検索

　構文：***find {検索ディレクトリ}{検索式}***
　　検索式一覧：-name {ファイル名}…ファイル名で検索します.
　　　　　　　　-atime{日時}…最終アクセス時刻で検索します.
　構文：***which {コマンド名}***
　　　　コマンドが格納されている絶対パスを表示します.
　構文：***whereis {オプション}***
　　　　バイナリファイル、ソースコード、マニュアルファイルが置かれている場所を検索します.
　構文：***type {コマンド名}***
　　指定したコマンドが通常の実行ファイルなのか、シェルの組み込みコマンドなのかエイリアスなのか返します.
　　結果一覧：ハッシュされています⇒外部コマンド
　　　　　　　シェル組み込み関数です⇒組み込みコマンド
　　　　　　　エイリアスです⇒エイリアス
　　　　　　　シェルの予約語です⇒予約語
[Go言語] Sliceを完璧に複製するには? (How to perfectly clone a slice?)


# 結論

```go
b := append(a[:0:0], a...)
```

# 解説

`a[:0:0]` は `a[0:0:0]` の省略で、 **Full slice expressions**（フルスライス式？）と言います。

* その構文

  ```go
  a[low : high : max]
  ```

  > 最初のインデックス(`low`) が `0`の場合、`a[: high : max]`  に省略することができます。

注意：普通のスライス式 `a[0:0]` ですと、 `b` が  `a` と同じメモリを使うことになります。

# おまけ

```go
b := make([]T, len(a))
copy(b, a)
```

OR

```go
b := append([]T(nil), a...)
```

でも複製できますが、

前者は、`nil slice` を `non-nil blank slice` に、

後者は、`non-nil blank slice` を `nil slice` に複製してしまう問題あります。

`nil`判定を入れれば問題解消できますが、コードが長くなります。

```go
if a == nil {
	b = nil
} else {
	b = make([]T, len(a))
	copy(b, a)
}
```

# ベンチマーク

## テストコード

```go
package main

import (
	"testing"
)

const N = 1024 * 1024
type T = int64
var xForMakeCopy = make([]T, N)
var xForAppend = make([]T, N)
var yForMakeCopy []T
var yForAppend []T

func Benchmark_MakeAndCopy(b *testing.B) {
	for i := 0; i < b.N; i++ {
		yForMakeCopy = make([]T, N)
		copy(yForMakeCopy, xForMakeCopy)
	}
}

func Benchmark_Append(b *testing.B) {
	for i := 0; i < b.N; i++ {
		yForAppend = append(xForAppend[:0:0], xForAppend...)
	}
}
```

## テスト結果

```shell
❯ go version
go version go1.14.2 darwin/amd64
❯ go test -bench=.
goos: darwin
goarch: amd64
Benchmark_MakeAndCopy-8             1142            990016 ns/op
Benchmark_Append-8                  2289            526206 ns/op
```

`append` が `copy`  より2倍ぐらい早いようでした。


# 参考

[How to efficiently clone a slice?](https://github.com/go101/go101/wiki/How-to-efficiently-clone-a-slice%3F)

# 元記事
https://aifan.jp/2020/08/17/go言語-sliceを完璧に複製するには/
【SCSS】@eachで、キーを使った配列

#```@each```とは？
配列の数の分だけ、繰り返し処理を行います。

#どんな時に使うか？
```sample.scss
.block {
  .element1 {
    border: solid 1px black;
    color: black;
  }

  .element2 {
    border: solid 1px red;
    color: red;
  }

  .element3 {
    border: solid 1px green;
    color: green;
  }
}
```

今回の場合は、要素ごとに色が異なります。
これをまとめてループ処理にします。

###【書き方】

```
@each $変数名 in $リスト名{
  処理
}
```

```sample.scss
$colors: (1:black, 2:red, 3:green);

@each $key, $color in $colors {
  .block {
    .element#{key} {
      border: solid 1px $color;
      color: $color;
    }
  }
}
```

#参考
・[3-2. ループ処理（each・for・while）で繰り返し記述する手間を省く](https://chot.design/sass/a45e488f818b/)
【Heroku】データベースの初期化とマイグレーションの実行でデーブルを空にする

###要約
ターミナルで以下のコマンドを実行。
ディレクトリは、アプリ上に移動しておく。

1. $ heroku pg:reset DATABASE --confirm アプリ名でデータベースをリセット
2. テーブルごと消えるので$ heroku run php artisan migrateを実行
3. 空のテーブルが出来上がり

###データベースのリセット

```
$ heroku pg:reset DATABASE
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/668402/addac239-f25a-fa0b-376b-4f9862ebd88b.png)

アプリ名を入力するか
`heroku pg :reset DATABASE`
の後に
 `--confirm アプリ名`
でもう一度コマンドを打ち直して実行するかしなさいよって言われる。

どちらでもいいけど、そのままアプリ名だけ入力するのが楽ですね。

とりあえず最初の入力しておけばアプリ名が表示されるので、表示された上で選んでも問題なさそう。



###データベースを初期化したら、migrationの実行

テーブルごと消えるので、またmigrationを実行してテーブルを作成する必要がある。

```:ターミナル
// migrationの実行
$ heroku run php artisan migrate
```

これで空のテーブルができるので、ファイルのアップロードの挙動をテストできる！
PHPでリコメンデーションロジックを作る

Laravelで作成したアプリケーションにリコメンデーション機能を作ったときの備忘録
pythonじゃなくてもk近傍法（もどき）はできることにはできたが、pandas,numpyとか使えるPythonの方が触りやすいと思う。floatの精度問題とかもある。

# 前提
・複数の質問結果からアイテムをお勧めする
・質問はYes・No（ie, 0 or 1）
・初期データ入力可能
・実際の質問の回答結果を学習させより実態に沿ったお勧めにする
・お勧めするアイテム数がそこまで多くない(数百程度)

# 設計
1.お勧めに載せるアイテムごとに、質問結果のパターンを初期値として入力
2.回答パターンをベクトル成分（[1,0,1,1,~,0]）として捉える

```php

$itemA = [1,0,1,1,1,0,~,1,0]
  ~
$itemN = [0,0,1,0,1,0,~,1,0]           
```
3.実回答のベクトル成分とお勧め候補アイテムのユークリッド距離を計算し、近い順に取得しリコメンド

```php:euc_distance.php
foreach($items as $coordinate_points) { // items = ["itemA" => [0,1,0,0....], "itemB" => [0,1,1,..] ... ]
    $total = 0;
    foreach($coordinate_points as $coordinate_point) {
        $t += abs($coordinate_point - $actual_answer_point) ** 2
    }
    $euc_distance = $total ** 1/2
}
// $euc_distances = ["itemA" => 80, "itemB" => 14, ....]
```

4.実際に選択されたアイテムをリコメンド結果として取得、保存
5.お勧め候補アイテムの実選択データが一定数を超えたタイミングで、実回答群の重心を求め新たに該当アイテムの回答パターンとする。

```php:balance.php
// $merged_scores = ["q1" => [1,0,1,1,1], "q2" => [0,0,0,1,0] ...]
foreach ($merged_scores as $question_id => $coordinate_points) {
    $new_coordinate_point = array_sum($coordinate_points) / $merged_scores->count(); //balance
    if (!is_nan($new_coordinate_point)) { //prebend NaN
        //update vector components
}
```

#　まとめ
限りなくシンプルな形で初期実装してみたけれど、外れ値を考慮していない点、全探索しているためリコメンドアイテム数が無数になる場合には向いてない点など多々問題点あり、試験的にこの形で実装してみて実データをとり相関とかを調べながら、より実態に即した形に変更していく必要がありそう。
そもそもの計算に関しても、リレーションを組めるならSQLでユークリッド距離計算をさせてしまった方が実は早い可能性もある。