OmniAICreator/Qiita-1.07M huggingface dataset:
【C#】リスト中から毎回違う要素をランダムに取り出すためのクラス【UniqueItemPicker.cs】

## はじめに

C#でリスト中から重複せずに要素を取り出した場面があったので、いい感じのクラスを書きました。Unityで使ってますが、ログ出力部分以外はC#でも使えます。CC0なのでよかったら活用してください。

Gist: [UniqueItemPicker.cs](https://gist.github.com/nkjzm/af7149634a11b2912ba19257d8f33bed)

## 使い方

```test.cs
using UnityEngine;

public class test : MonoBehaviour
{
    void Start()
    {
        // 配列を用意する
        var nameList = new string[]
        {
            "なかじ",
            "リリカちゃん",
            "ゴリラ",
        };

        // 配列を渡して初期化
        var enemyNameGenerator = new UniqueItemPicker<string>(nameList);

        // 要素を取り出す
        Debug.Log(enemyNameGenerator.GetUniqueItem());
        Debug.Log(enemyNameGenerator.GetUniqueItem());
        Debug.Log(enemyNameGenerator.GetUniqueItem());
        Debug.Log(enemyNameGenerator.GetUniqueItem()); // null

        // 履歴を削除
        enemyNameGenerator.ResetUsageHistory();

        // 再び取り出せるようになる
        Debug.Log(enemyNameGenerator.GetUniqueItem());
        Debug.Log(enemyNameGenerator.GetUniqueItem());
    }
}
```

### 出力

<img width="332" alt="スクリーンショット 2019-11-19 18.27.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55365/4955e534-6cfb-7fc5-f138-a5a501ab9933.png">

初期化した時の要素を使い終わると`Null`が返ってくる点に注意してください。そうなった場合、`enemyNameGenerator.ResetUsageHistory()`を呼び出すことで再度要素を取得することができます。


## ソースコード

Gist: [UniqueItemPicker.cs](https://gist.github.com/nkjzm/af7149634a11b2912ba19257d8f33bed)

```UniqueItemPicker.cs
using System.Collections.Generic;

/// <summary>
/// リスト中から重複せずに要素を取り出すクラス
/// </summary>
public class UniqueItemPicker<T>
{
    T[] AllItems;
    /// <summary>
    /// コンストラクタ
    /// </summary>
    /// <param name="allItems">取り出したい要素の配列</param>
    public UniqueItemPicker(T[] allItems)
    {
        AllItems = allItems;
        InitIndexList();
    }

    void InitIndexList()
    {
        indexList.Clear();
        for (int i = 0; i < AllItems.Length; i++)
        {
            indexList.Add(i);
        }
    }

    /// <summary>
    ///  リスト中から重複せずに要素を取り出す
    /// </summary>
    public T GetUniqueItem()
    {
        if (indexList.Count == 0)
        {
            UnityEngine.Debug.LogError("要素がありません");
            return default(T);
        }
        return AllItems[GetIndex()];
    }

    List<int> indexList = new List<int>();
    int GetIndex()
    {
        int index = UnityEngine.Random.Range(0, indexList.Count);
        int result = indexList[index];
        indexList.RemoveAt(index);
        return result;
    }

    /// <summary>
    /// 使用履歴を初期化する
    /// </summary>
    public void ResetUsageHistory()
    {
        InitIndexList();
    }
}
```

ジェネリック型で作っているので構造体やクラスも扱えて便利です。型を限定していないので、要素がない時は `default(T)`を返しているところがポイントです。

## 最後に

役に立ったらいいねください！！
FlutterでローカルのJSONファイルを読み込む

# やりたいこと
例えば以下のようなjsonファイルがあり、こいつの中身をFlutterアプリ内で取り扱いたい。

```data.json
{
    "id": "123456789",
    "name": "unsoluble_sugar",
    "job": "otaku",
    "skill": [
        {
            "language": "C",
            "level": "middle",
            "year": "3"
        },
        {
            "language": "C++",
            "level": "middle",
            "year": "5"
        },
        {
            "language": "C#",
            "level": "middle",
            "year": "3"
        },
        {
            "language": "Objective-C",
            "level": "low",
            "year": "1"
        },
        {
            "language": "PHP",
            "level": "middle",
            "year": "4"
        }
    ]
}
```


というわけで、やってみた。


## jsonファイルをアセットとして認識させる

まずは対象のjsonファイルをアセットとして認識させる。
[Adding assets and images  - Flutter](https://flutter.dev/docs/development/ui/assets-and-images)

今回は雑にルート直下に`json`フォルダを作成。その配下に`data.json`を配置。
![スクリーンショット 2019-11-19 17.38.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/62205481-7b1f-f0e1-3c43-b974c13df1c5.png)


`pubspec.yaml`に`json`フォルダ配下のファイルを認識させるよう定義を追加する。

```pubspec.yaml
assets:
    - json/
```

アプリ内に配置した画像を読み込ませる場合なども、アセットの定義追加が必要となる。

## rootBundleで読み込み

単純にjsonファイルを読み込んで扱う場合は、rootBundleを使って実現できる。
[rootBundle property - services library - Dart API](https://api.flutter.dev/flutter/services/rootBundle.html)

以下、必要部分のコードのみ抜粋。jsonファイルをStringとして読み込んで変数更新してるだけ。

```main.dart
import 'package:flutter/services.dart' show rootBundle;

class _MyHomePageState extends State<MyHomePage> {
  String _data = "Load JSON Data";

  void _updateJsonData() {
    setState(() {
      loadJsonAsset();
    });
  }

  Future<void> loadJsonAsset() async {
    _data = "";
    String loadData = await rootBundle.loadString('json/data.json');
    _data = loadData;
  }

...

```
ボタンの`onPressed`で`_updateJsonData()`を呼ぶなど、そのまま画面表示させるとjsonファイルの中身が出る。
![flutter_json_load.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/bd68f9ed-de99-51df-ae28-85ff5d3d4d45.gif)


## json.decode()を使う

jsonパースしてデータを個別に扱いたい場合は、`json.decode()`で先ほどのStringをデコードする。

```main.dart
import 'dart:convert';

...

  Future<void> loadJsonAsset() async {
    _data = "";
    String loadData = await rootBundle.loadString('json/data.json');
    final jsonResponse = json.decode(loadData);
    jsonResponse.forEach((key,value) => _data = _data + '$key: $value \x0A');
  }

```
key, valueを改行入れて画面表示した様子がこちら。
![flutter_json_decode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6380/a9da8287-f1cf-24a4-3c32-6b981d52c718.gif)
単純なjsonパース程度ならこれでいけそう。

もっとゴリゴリやる場合は、`json_serializable`等のパッケージを使うのが良いのかな。
[json_serializable | Dart Package](https://pub.dev/packages/json_serializable)
Airflow(Cloud Composer)のBigQueryTableSensor使うと ERROR - The conn_id `bigquery_default_conn` isn't defined

# 背景

Composer(image: `composer-1.7.9-airflow-1.10.2` )でBigQueryTableSensor使おうと思ったら、 ``` ERROR - The conn_id `bigquery_default_conn` isn't defined ``` が出て失敗して困った

# 原因

単純にバグっぽい。こちらのissue↓

[[AIRFLOW-3966] Correct default bigquery_conn_id in BigQueryTableSensor](https://github.com/apache/airflow/pull/4786)

# 対応

BigQueryTableSensorの `bigquery_conn_id` パラメータに `bigquery_default` を指定してあげる

```py
from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import datetime, timedelta
from airflow.contrib.operators.bigquery_operator import BigQueryOperator
from airflow.contrib.sensors.bigquery_sensor import BigQueryTableSensor

default_args = {
    "owner": "airflow",
    "depends_on_past": False,
    "start_date": datetime(2019, 10, 28),
    "email": ["airflow@airflow.com"],
    "email_on_failure": False,
    "email_on_retry": False,
    "retries": 1,
    "retry_delay": timedelta(minutes=5),
}

dag = DAG("hoge_dag", default_args=default_args, schedule_interval=timedelta(1))

# t1, t2 and t3 are examples of tasks created by instantiating operators

t1 = BigQueryTableSensor(
    task_id='check_table_exists',
    project_id = 'project',
    dataset_id = 'unmasked_sopurce',
    table_id = 'users',
    poke_interval=10,
    timeout=60,
    retries=24*7,
    retry_delay=timedelta(minutes=60),
    bigquery_conn_id='bigquery_default', # <ー これ！
    dag = dag
)

t2 = BigQueryOperator(
    task_id='bq_writing',
    use_legacy_sql=False,
    write_disposition='WRITE_TRUNCATE',
    allow_large_results=True,
    bql='''
    SELECT product, count FROM `project.suzuki_test.test_001`
    ''',
    destination_dataset_table='project.suzuki_test_001.test_003_copy',
    retry=3,
    dag=dag)

t1 >> t2
```
Delay関数(コンペアマッチタイマー CMT)

# はじめに
コンペアマッチタイマー CMTで作成するDelay関数の設定諸々についての記述．マイコンボードはGR-CITRUSとする．ハードウェアマニュアルの参考先はHM ＊.＊.＊と表記する（例：HM 3.3.4ならばハードウェアマニュアルの3.3.4節を参考）．

資料（必需品）
・ [RX63Nグループ、RX631グループ ユーザーズマニュアル](https://www.marutsu.co.jp/contents/shop/marutsu/datasheet/R5F563.pdf)
・ [GR-CITRUS回路図](https://www.renesas.com/jp/ja/doc/gr/gr-citrus/citrus-1.0.pdf)

# Delay関数の作成

### 初期化関数
[Timer割り込み](https://qiita.com/shiduku/private/d6b012b7ab4e95382aac)の時と異なり，初期化の時点ではタイマーを動作させない．


```c:"hwsetup.c"
void CMT0_init(void);

void HardwareSetup(void)
{
	 CMT0_init();
}
```

```
/*=================================
 * 関数名 : CMT0_init
 * 機能 : CMT0の初期化
 * 引数 : なし
 * 戻り値 : なし
 * 備考 :設定周期 :1ms 割り込み優先度:4
 * ===============================*/
void CMT0_init(void)
{
	/*=== プロテクト解除 ===*/
	SYSTEM.PRCR.WORD = 0xA502;
	/*=== CMTを有効化 ===*/
	MSTP(CMT0) = 0;
	/*=== プロテクト ===*/
	SYSTEM.PRCR.WORD = 0xA500;
	/*=== CMT動作停止 ===*/
	CMT.CMSTR0.BIT.STR0 = 0;
	/*=== CMT設定 ===
	 * クロック選択 : PCLK/8 = 6MHz
	 * CMT割り込み許可
	 * ===========*/
	CMT0.CMCR.BIT.CKS =0;
	CMT0.CMCR.BIT.CMIE = 1;
	/*=== カウントリセット ===*/
	CMT0.CMCNT = 0;
	/*=== 周期カウント設定 ===
	 * 設定周期 : 1ms
	 * CMCOR = 設定周期[s]*PCLKB[Hz]/分周比-1
	 * ================*/
	CMT0.CMCOR = 5999;
    /*=== CMT動作開始 ===*/
    CMT.CMSTR0.BIT.STR0 = 1;
	/*=== 割り込み優先度設定 ===*/
	IPR(CMT0,CMI0) = 4;
	/*=== 割り込み許可 ===*/
	IEN(CMT0,CMI0) = 1;
}

```

### Delay関数

```c:icu_cmt.h
void Delay(unsigned int time);
```

```c:icu_cmt.c
#include"iodefine.h"
#include"icu_cmt.h"
```

```
/*=================================
 * 関数名 : Delay
 * 機能 : 任意時間待機する
 * 引数 : 待機時間[ms]
 * 戻り値 : なし
 * 備考 :
 * ===============================*/
void Delay(unsigned int time)
{
	int i;
    /*=== カウントリセット ===*/
    CMT0.CMCNT = 0;
    /*=== time[ms]待機 ===*/
    for(i=0;i<time ; i++)
    {
    	while( IR(CMT0,CMI0) == 0 );
    	CMT0.CMCNT = 0;
    	IR(CMT0,CMI0) = 0;
    }
}

```

`IR(CMT0,CMI0)`は割り込み要求が発生した時に1になるマクロ関数．必要に応じて関数内でクロックの動作開始終了を記述する．その場合，初期化関数のカウント開始はコメントアウトする．（他の割り込みの時にカウントできなくなるトラブルがあったので使いどころに注意）

```c
void Delay(unsigned int time)
{
    int i;
    /*=== カウント開始 ===*/
    CMT.CMSTR0.BIT.STR0=1;
    /*=== カウントリセット ===*/
    CMT0.CMCNT = 0;
    /*=== time[ms]待機 ===*/
    for(i=0;i<time ; i++)
    {
        while(!IR(CMT0,CMI0));
        CMT0.CMCNT = 0;
        IR(CMT0,CMI0) = 0;
    }
    /*=== カウント停止 ===*/
    CMT.CMSTR0.BIT.STR0=0;
}
```

他の割り込みがある場合は注意が必要な関数．

```c:"HelloWorld.c"
#include"iodefine.h"
#include"icu_cmt.h"

void main(void)
{
	while(1)
	{
		
		LED = LED_ON;
		Delay(1000);
		LED = LED_OFF;
		Delay(1000);

	}
}
```

# 参考文献

- RX220で1ms周期のタイマを作成してLチカ https://qiita.com/ekd/items/6015c1022411b23f15d1
datadogを使ったk8s監視の考え方やポイントのメモ

## 概要
[Monitoring Kubernetes with Datadog](https://www.datadoghq.com/ja/blog/monitoring-kubernetes-datadog/) を読んでk8s環境における監視の考え方や大事なポイントのメモ
現在進捗はInvestigating recursivelyまで、読み進み次第追記予定。

## Kubernetes環境において必要なモニタリングは2つ

- Kubernetes上で動くコンテナ群のモニタリング
- Kubernetesクラスタ自身のモニタリング

## Monitoring Theory
### Collecting the right data

この理論では以下の3種類のメトリクスを集める
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97541/c590f4f7-2a5b-1b30-88cc-a7c23c63a18a.png)

- システムが正常に働いている度合いを示すメトリクス
  - スループット
  - エラー率
  - レスポンスタイム
  - レイテンシー

Resource metrics

- システムが正常に働いているかどうかを知るメトリクス
  - CPU
  - メモリ
  - ディスク容量
  
Events

- システムで発生したイベント
  - スケール
  - デプロイ
  - クラスタの切替
  - DNS変更

### Alert on actionable work metrics

- アラートはアクションが必要なメトリクスのみに対して出す
- Work metricsは「システムが正常に動いているかどうか」を示す
- Work metricsの値に異常があれば何かしら対応が必要になるのでアラートを出すべきである
- Resource metricsについては基本的にアラートは出さない
- CPUやメモリが80%を超えたからと言って何か対応するわけではない
- アプリケーションに影響が影響が出ているかどうかが重要

### Investigating recursively
問題があったときに調査するする際は以下の順番でメトリクスを確認する

1. Work metrics
2. Reousrce metrics
3. Events

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/97541/22043050-fa0f-71c0-ffbf-24f0d88082b6.png)

メトリクスは再起的に見る必要がある
例えばDBのアラートが発生した場合は以下のようにドリルダウンしてメトリクスを確認する

- アプリケーションのスループット(Work metrics)
  - DBのクエリレイテンシ(Resource metrics)
    - CPUやメモリ(Resource metrics)
      - セールなど高負荷が発生しそうなイベントをやっていないか確認(Events)
和暦から西暦に変換　その他諸々

##やりたい事

H28年10月29日 ⇨ 201610 に変換する。

①和暦を西暦に変更
③文字「年」「月」「日」を削除
③日の値削除



##コード①
``` seireki.php
<?php
function seireki($wareki_year)
{
      $data = substr($wareki_year, 0, strcspn($wareki_year, '月'));
      $replace = [
  'H13年' => '2000',
  'H14年' => '2001',
  'H15年' => '2002',
  'H15年' => '2003',
  'H16年' => '2004',
  'H17年' => '2005',
  'H18年' => '2006',
  'H19年' => '2007',
  'H20年' => '2008',
  'H21年' => '2009',
  'H22年' => '2010',
  'H23年' => '2011',
  'H24年' => '2012',
  'H25年' => '2013',
  'H26年' => '2014',
  'H27年' => '2015',
  'H28年' => '2016',
  'H29年' => '2017',
  'H30年' => '2018',
  'R01年' => '2019',
  'R02年' => '2020',
  'R03年' => '2021',
  'R04年' => '2022',
  'R05年' => '2023',
  'R06年' => '2024',
  'R07年' => '2025',
];
      $seireki = str_replace(array_keys($replace), array_values($replace), $data);
      return $seireki;
}

$a = seireki('H28年10月29日');
echo $a;
```

```
$php seireki.php
201610
```

これはもう世に出してはいけないレベル。
変数$replaceを延々と人力でカスタマイズするんですかとツッコミが来そうです。。

##コード②
他の記事を参考に作ってみました。

```seireki.php
function seireki($wareki_year)
{
        $start = mb_strpos($wareki_year, '年')+1;
        $end = mb_strpos($wareki_year, '月');
        $month = mb_substr($wareki_year, $start, $end-$start);
        $wareki_year = substr($wareki_year, 0, strcspn($wareki_year, '年'));
        $wareki_year = str_replace('元年', '1年', mb_convert_kana($wareki_year, 'n'));
  
        if (preg_match('!^(S|H|R)([0-9]+)$!', $wareki_year, $matches)) {
            $era_name = $matches[1];
            $year = intval($matches[2]);
      
            if ($era_name === 'S') {
                $year += 1925;
                $year = $year . $month;
            } elseif ($era_name === 'H') {
                $year += 1988;
                $year = $year . $month;
            } elseif ($era_name === 'R') {
                $year += 2018;
                $year = $year . $month;
            }
            return $year;
        }
        return null;
}
$a = seireki('H28年10月29日');
echo $a;
```

```
$php seireki.php
201610
```

ある程度それっぽい形になりましたが、
まだまだ穴はありそうでリファクタリングが必要になりそうです。

以上です。

参考にさせて頂いたサイトです。ありがとうございました。

【保存版】令和に対応！和暦↔西暦変換をPHP、JavaScript、Pythonで実行する方法
https://blog.capilano-fw.com/?p=3307

[php]文章内の指定文字から指定文字までの文字列を抽出する方法
https://singoro.net/note/mb_substr-mb_strpos/
mongoDB AtlasにCLIで接続するまで


# 手順
1. CLIのインストール
2. MongoDB Userの追加
3. IPホワイトリストの編集
4. 疎通確認

# mongo CLIのインストール

    brew tap mongodb/brew
    brew install mongodb-community

参考: https://github.com/mongodb/homebrew-brew

# MongoDB Userの追加
プロジェクトのメニュー`Database Access`からユーザーを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/bb21adf6-28a4-ca57-2c0c-78c8bdfbf7d5.png)

# IPホワイトリストの編集
アクセス可能なIPアドレスを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96286/c8caab09-a1b7-ae15-aa7e-53ad8293cecf.png)

# 疎通確認

Clusters > Connectから接続先のホスト名を取得し...

```
mongo "mongodb+srv://${HOST}"  --username ${USERNAME}
```

これで接続可能なはずです。
Generating visual explanations (GVE)を使ってみる

#0. 概要
XAI人気ですよね。特にDARPAも力を入れているAIの判断基準を如何に可視化するか。これは、入力画像の何処に着目したか色を付けて画像で可視化する場合もあれば、文字でどこを見ているのかを言うなんていう表現方法等様々あります。
https://www.darpa.mil/attachments/XAIProgramUpdate.pdf
このDarpaの資料でも触れられていますが、その物体を識別した時の理由を文字で表現できるLRCNが生まれました。
それがGVEです。
https://www.mpi-inf.mpg.de/fileadmin/inf/d2/akata/generating-visual-explanations.pdf
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/b58f85cc-5ffa-6aee-c7dc-3ebeda21b83d.png)
こんな感じで、鳥を識別した理由を話してくれます。VQAと異なるのは質問しなくていいということですね。
このGVEをまずは動かしたいと思います。本家実装はCaffeらしいですが、Pytorch版も本家からReferされているのそちらを使いたいと思います。
だってCaffe2からPytorchに吸収されるんでしょう(?)、ならPytorchが良いじゃないということで。

#1. Installation
Gitを見ながら進めて行く。
https://github.com/salaniz/pytorch-gve-lrcn

まずはファイルを設置

``` bash
$ git clone https://github.com/salaniz/pytorch-gve-lrcn.git
$ cd pytorch-gve-lrcn
```

次に、環境を整える。既にPytorchが入っている人は飛ばしておｋ

``` bash
$ conda env create -f environment.yml
$ conda activate gve-lrcn
```

CUBというデータセットを使うので、データセットがない人はダウンロード

``` bash
$ ./cub-data-setup-linux.sh
```

`data`に保存される。


#2. Training
環境構築が終わったのでトレーニングをして行く。

まず、以下でEmbeded文書を学習

``` bash
$ python main.py --model sc --dataset cub
```

学習が終わると`best-ckpt.pth`という最適化されたWeightが保存される。
これを`data`フォルダにコピーしてから`gve`の学習をする。
まずはコピー。

``` bash
$ cp ./checkpoints/sc-cub-D<date>-T<time>-G<GPUid>/best-ckpt.pth ./data/cub/sentence_classifier_ckpt.pth
```

次に学習。

``` bash
$ python main.py --model gve --dataset cub --sc-ckpt ./data/cub/sentence_classifier_ckpt.pth
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/13b51231-7f7d-2e8a-56b4-a1284b5a96aa.png)

こんな感じで亀の歩みで学習が進んでいく。

# 3. Evaluation
学習が終わると以下で評価を実行できる。

``` bash
$ python main.py --model gve --dataset cub --eval ./checkpoints/gve-cub-D<date>-T<time>-G<GPUid>/best-ckpt.pth
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/c05add75-2680-52cf-9ef3-0ccabf7e78ff.png)

学習回数が少ないのかMETEOR低い・・・

# 4. Prediction
以下で学習機及び予測機を作っている。

``` python
trainer_creator = getattr(TrainerLoader, args.model)
trainer = trainer_creator(args, model, dataset, data_loader, logger, device)
```

学習機及び予測機の切り替えは以下で行っている。

``` python
model.train()
model.eval()
```

このため、以下でデータセットにロードされたデータの識別が行える。

``` python
model.eval()
trainer_creator = getattr(TrainerLoader, 'gve')
trainer = trainer_creator(args, model, dataset, data_loader, logger, device)
res = trainer.train_epoch()
````

識別された画像のIDと文字が返ってくるのはいいが、入力画像は特徴量しかないため画像化はできない笑
画像IDを渡せば、以下のように入力の特徴量を見ることも出来る笑

``` python
img = dataset.get_image("081.Pied_Kingfisher/Pied_Kingfisher_0132_72706.jpg")
print(img)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/4b5f8f18-0f0a-e88a-423b-08bcd3c767d9.png)

こんな感じ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95636/10a0abb6-2c5f-8c59-9d50-722713fbc64a.png)

Label: This magnificent bird has a white belly, throat, and crown with a black superciliary, yellow torso, and dark wings with light secondaries.
Prediction: This is a bird with a white belly black wings and a long tail

まあ、正しい？
OpenVBSをビルドしてみよう


# リポジトリへアクセス
https://github.com/yrm006/openvbs


```
cd c:\gits
c:\gits>git clone https://github.com/yrm006/openvbs.git
```

# 環境構築
http://lyncs.hateblo.jp/entry/2018/03/11/032127#1-%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB

1. http://www.mingw.org/ へアクセス
2. メニューのDownloads
3. `MinGW Installation Manager (mingw-get) `を選択
4. `mingw-get-setup.exe`を選択
5. 起動
6. デフォルト設定のまま![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302078/2db25978-ca70-a072-cc1b-e7f906a1be08.png)
7. インストールしたいものを選択![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/302078/9daee039-d9a4-a0ed-ab60-9f7e457fc75d.png)
    - mingw32-gcc-g++
    - mingw32-base-bin
    - msys-gcc-g++
    - mingw32-developer-toolkit-bin
12. メニューから Installation -> Apply Changes
13. パスを通す `Path`に`C:\MinGW\bin`を追加

# ビルド

##  makefile.winでビルド→失敗

```
c:\gits\openvbs>mingw32-make -f makefile.win
cl /Ox /EHa /D_CRT_STDIO_ISO_WIDE_SPECIFIERS oscript.cpp jujube.cpp npole.cpp /link /DEF:oscript.def
process_begin: CreateProcess(NULL, cl /Ox /EHa /D_CRT_STDIO_ISO_WIDE_SPECIFIERS oscript.cpp jujube.cpp npole.cpp /link /DEF:oscript.def, ...) failed.
make (e=2): wｳｽt@CｪｩﾂｩﾜｹB
makefile.win:6: recipe for target 'oscript.exe' failed
mingw32-make: *** [oscript.exe] Error 2
```

##  makefile.osxでビルド→失敗→これが一番動きそう

```
c:\gits\openvbs>mingw32-make -f makefile.osx
g++ -Wall -std=c++14 -O0 -g oscript.cpp jujube.cpp npole.cpp -ldl -o oscript
In file included from jujube.h:1,
                 from oscript.cpp:1:
npole.h:2:14: fatal error: comdef.h: No such file or directory
     #include <comdef.h>
              ^~~~~~~~~~
compilation terminated.
In file included from jujube.h:1,
                 from jujube.cpp:1:
npole.h:2:14: fatal error: comdef.h: No such file or directory
     #include <comdef.h>
              ^~~~~~~~~~
compilation terminated.
In file included from npole.cpp:1:
npole.h:2:14: fatal error: comdef.h: No such file or directory
     #include <comdef.h>
              ^~~~~~~~~~
compilation terminated.
makefile.osx:11: recipe for target 'oscript' failed
mingw32-make: *** [oscript] Error 1
```

##  makefile.linuxでビルド→失敗

```
c:\gits\openvbs>mingw32-make -f makefile.win
cl /Ox /EHa /D_CRT_STDIO_ISO_WIDE_SPECIFIERS oscript.cpp jujube.cpp npole.cpp /link /DEF:oscript.def
process_begin: CreateProcess(NULL, cl /Ox /EHa /D_CRT_STDIO_ISO_WIDE_SPECIFIERS oscript.cpp jujube.cpp npole.cpp /link /DEF:oscript.def, ...) failed.
make (e=2): wｳｽt@CｪｩﾂｩﾜｹB
makefile.win:6: recipe for target 'oscript.exe' failed
mingw32-make: *** [oscript.exe] Error 2

c:\gits\openvbs>mingw32-make -f makefile.linux
g++ -std=c++14 -O0 -g oscript.cpp jujube.cpp npole.cpp -static-libgcc -static-libstdc++ -rdynamic -ldl -o oscript
g++: error: unrecognized command line option '-rdynamic'
makefile.linux:9: recipe for target 'oscript' failed
mingw32-make: *** [oscript] Error 1
```
Laravel FormRequestでバリデーション

####バリデーション
#####参考サイト
[Laravelのvalidationメソッドでバリデーションを実装する入門編（日本語エラーメッセージ付き）](https://www.ritolab.com/entry/40)
[Laravelのフォームリクエストクラスでバリデーションロジックをコントローラから分離する](https://www.ritolab.com/entry/41)
[Laravelのバリデーションにはフォームリクエストを使おう](https://qiita.com/sakuraya/items/abca057a424fa9b5a187)
[Laravel5.6でバリデーションなどのエラーメッセージを日本語化する方法](https://www.takafumitaba.com/laravel-error-messages)

#####ItemRequestクラス

```php:app/Http/Requests/ItemRequest
---
class ItemRequest extends FormRequest
{          
---
    public function rules()
    {
        //バリデーションルール
        return [
            'name' => 'required|string|max:191',
            'content' => 'required|string|max:191',
        ];
    }
}
```
**・注意点** - バリデーションルールはカンマ抜けのsyntax errorレベルでも **class does not exist**エラーになる。
#####コントローラー

```php:app/Http/Controller/ItemController
<?php                                  
namespace App\Http\Controllers;        
                                       
use Illuminate\Http\Request;           
use App\Http\Requests\ItemRequest; //クラス宣言   
use App\Item;         
                                       
class ItemController extends Controller
{                                      
---中略
    //引数の型をバリデーションクラスにする
    public function create(ItemRequest $request) {
        //追加処理                                                                
        $name = $request->input('name');                                      
        $content = $request->input('content');                                
        $item = Item::create(compact('name', 'content'));
        return redirect('item/');
    }
}
```
$request の型を変更するだけでバリデーションされる。
バリデーション ->
OK -> メソッド処理
NG -> 元のビューにリダイレクト

```html:resource/view/sample.blade.php
---
//バリデーションエラーの表示
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
    //バリデーションエラーなら元データを代入
    <?php
    $id = old('id');
    $name = old('name');
    ?>                                             
@endif
<form method="post" action="{{ route($address) }}">                                   
    {{ csrf_field() }}                                                                
    <div><label>商品名:</label> <input type="text" name="name" value="{{ $name }}"></div>
    <div><label>説明:</label> <textarea name="content">{{ $content }}</textarea></div>
</form>
```
**注意 :** レイアウトでもバリデーションできますが、old()が取得できませんでした。

#####エラーメッセージを日本語にする
/config/app.php -> locale = jp
参考サイトからエラーメッセージファイルをダウンロード
/resources/lang/en -> コピーしてjpを作成
/lang/jpにファイルを上書きコピー
応用カリキュラム 04 ruby正規表現

##sub(≒replace)
文字列の指定部分を別の文字列に置換。
##gsub
文字列の指定部分を全て別の文字列に置換。

```.rb
str = "aaabbb"
str.sub(/bbb/,"BBB")
# aaaBBB

str.gsub(/b/,"B")
# aaaBBB
```
##match
検索したい文字が含まれているかどうか。
見つかれば、検索文字リピート
見つからないなら、nil

```.rb
str = "aaabbb"
str.match("ab")
# ab
```

##検索条件

- [a-z] a,b,c,d・・・x,y,zのいずれかの文字にマッチ。
- \d　数字にマッチ
- {n, m} 直前の文字が最低n回、最高m回出現
- i 大文字・小文字を区別しない
- . あらゆる1文字
- 直前文字の1回以上の繰り返し

複合条件可。
データベース簡単なチューニングの手順

## チューニングとは？
１ パフォーマンスチューニングとは
データベースのパフォーマンス（性能）の向上をはかることであり、主に次のような性能の向上を目安としています。
![スクリーンショット 2019-11-19 17.20.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/45064073-c9e7-b9e4-648b-b75eea5e7b85.png)
・スループットの向上は多くの場合に応答時間の向上につながりますが、ある重要な問い合わせの応答時間を短縮するために全体的なスループットを犠牲にするケースもあります。	
・今回の記事では、データ量増加への対応ではなく、実行速度の向上につながる応答時間とスケーラビリティに主眼を置いてご紹介	

２　サーバチューニングとは
・サーバ全体のパフォーマンスを向上させることにより、主にスループットの向上をはかります。	
・より高性能なハードウェアへのリプレース以外で行えるチューニングは、主にパラメータ（システム変数やステータス変数）の最適化をはかることになります。	
・my.iniやmy.cnfなどの設定ファイルの修正で行うことができますが、詳しいご紹介はまた別の機会に

３　SQLチューニングとは
処理速度の向上をはかること	
・個々のSQLを見直し	
・インデックスの追加やデータ型の見直し
・テーブルやカラムに関する部分についても見直し

## SQLチューニングのポイント
![スクリーンショット 2019-11-19 17.20.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/f5f12f91-c3ec-cfec-11c1-07ff4317876f.png)
１　データ型の見直し
テーブルに設定したデータ型と入力したデータのデータ型を同一する

２　インデックスの追加と削除
頻繁に発行するクエリの実行計画を調査し適したインデックスを追加することで、劇的な速度向上が期待できる。

(１) インデックスとは
・データベース内から特定のデータを検索しやすくするための仕組	
・MySQLでは、B-Tree方式
インデックスを貼られたカラムは検索しやすいようツリー構造に加工され、テーブル本体とは別の場所に保存されます。
検索する際にはその加工したデータの方を見に行くことで、高速化を図っている

(2) インデックスを貼るメリット
適切なカラムにインデックスを貼って、検索の高速化
(対象：SQL文を多用する予定であるかを考え、実行計画を確認)

(3) インデックスを貼るデメリット
①データの保存に必要な領域が増える　（理由：テーブル本体とは別の領域に保存される)
②レコードの追加・更新については少し遅くなる　（理由：インデックスも追加・更新する処理が行われる）

(４) インデックスを貼る対象を探す「EXPLAIN」
![スクリーンショット 2019-11-19 17.21.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/061080c5-e2ea-ed6a-af1c-6d5bdc9a7d96.png)
「possible_key」：そのSQLを実行する際に有効なインデックスを貼る候補に挙がっているカラム名
「key」：現在インデックスが貼られているカラム名	

(５) インデックスの追加
ALTER TABLE [テーブル名] ADD INDEX [インデックス名]([カラム名]);		
例：ALTER TABLE db_01.USER_DATA ADD INDEX index01(user_id);
複合インデックスを追加する場合
例：ALTER TABLE db_01.USER_DATA ADD INDEX index02(user_id, user_name)
(６) インデックスの削除
ALTER TABLE [テーブル名] DROP INDEX [インデックス名];
例：ALTER TABLE db_01.USER_DATA DROP INDEX index01;		
    
３　SQLの見直し
無駄なループをなくすなどの処理を見直したり、実行が遅い命令を早い命令に置き換えるなどで対応
例：
①「UNION」より「UNION ALL」を使用
（理由：重複行削除のための処理が行われるためその分時間が必要）
②SELECT時に[＊]より「項目名」を使用
（理由：[＊]を項目名に置き換える処理が内部で行われるため）
③「サブクエリー」より「join」を使用
（理由：「サブクエリー」はindexが消える可能性ある）

４　ストアドプロシージャの削除
コールするだけで使用できるストアドプロシージャですが、普通にクエリを発行するよりも実行に時間がかかる場合がある
			
５　非正規化で処理速度が向上する？	
データベースを正規化しすぎると、検索時にたくさんの表を結合する必要が出てくることから処理速度が低下すると長年言われてきました。				
しかし正規化による結合は処理速度の低下に必ずしも影響しないということを示す実証実験の結果も公開されています。				
今のところ、正規化は行った方がメリットが大きいようです。

## スロークエリログで問題点を発見する
１　スロークエリログとは
・MySQLから出力されるログの一種
・設定した時間以上に処理時間がかかったクエリが出力
		
２　スロークエリログの使い方
![スクリーンショット 2019-11-19 17.21.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/957ef90c-afba-f896-d1fe-feab5467139b.png)
スロークエリログの詳細な設定方法や出力内容の読み方
(１) スロークエリログとは
実行に時間のかかったクエリがあった際に記録されるログ
(２) スロークエリログの出力設定 (例：コールシェア)
/etc/my.cnf
![スクリーンショット 2019-11-19 17.21.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274686/1dc95a8e-2532-0358-c64a-bd08589a5f37.png)
オセロ作りに時間がかかったので、早く作るための反省録

本文はエンジニア１年目の反省録です。
書きなぐりでもあります。

本文は全く期待しないでください


Laravel6とVue.jsの練習を兼ねて
オセロのプログラムを作成してみました。
ネット対戦ができるものではなく、
１人のプレイヤーが１つのマウスで交互に打つだけです。
この先、拡張するならばwebsocket等を使って２人対戦できるようにしたいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535544/e510a847-c120-6835-c626-21740e19eb0f.png)

ソースのurlはこちら。
https://github.com/rabbitbeef/ocelo

頭の中で必要な処理と練習ができている<b>つもり</b>だったので、
長くて３時間程度でぱぱっと作ってみようというつもりが８時間程度かかってしまいました。
そこで、なぜ長くかかったのか反省録や備忘録を中心に書きます。

#1,必要な処理の設計（整理）を予め整理しておく
単に置ける場所からオセロの石を裏返すだけならば、
実はすぐできました。
が、実際にテストしてみて、忘れていた仕様がありました。

・手が置けない場合のパス
→オセロのルール上、能動的にパスはできない。置ける場所がない場合に自動的にパスをする。
→ということは自動的にパスする必要がある。
→パスの条件、<b>手番の人が置ける場所を判定する</b>必要がある。

この置ける場所を判定する処理を書くために、
既に書いたコードの一部を<b>書き直す</b>必要が生じました。
この書き直しの時間は、最初から必要な処理をきちんと整理していれば、起こらなかったタイムロスです。
もしくは、処理を部分毎に細かく疎結合な関数にしていれば、
書き直しの部分が少なくなったかもしれません。

不幸中の幸い
、ハマりに比べて大きなタイムロスはないのですが、
もしここの失敗が大きくなればなるほど、
修正時に負債は自分に降りかかってくると思います。

#2,ハマりをいかに予防するか/回復するか。
ハマりは原因不明のエラーです。
ハマりはどんな時もタイムロス最大の原因です。
進んでいる気もしないし、風呂に入って考えたいくらいです。
コンピューターが自動的にエラーの原因を判別し、
エラーメッセージを残してくれるエラーなら修正はすぐ済みますが、
エラーメッセージすらなく、画面表示の段階で間違えるエラーは発見するのも大変です。

実際に動かして、予定通りの挙動にならないことは、今回の一番のタイムロスの原因になりました。
しかし、ハマり自体はどうやっても起こると思います。人間ですもの。
起こりうるエラーに対処するにはどうしたらようでしょうか。
考え方は２つあると思います。
サーバーのMTTFとMTBFような、故障（エラー）をどう予防するか/回復するか、です。

→予防
・予めアルゴリズムや設計を手やドキュメントに書いて俯瞰してみる。
　実行することをコメントに書いてから対応する関数を作成する。
　またはObjectの構造を書いておく等。
　（特に今回はObjectの参照の仕方が間違えため発生していたエラーが大きかった）

・言語の仕様を理解する。今回であればJavascriptやVueが中心。
　
→回復
・エラーの発見が速ければ回復しやすい。
　エラー出力で何を出力させれば正解、不正解になるのかを考えてみる。
　もしくは、必要ならば関数の挙動を少し変えてみてもよい。
　関数を変えず、何回も面倒なデバックするよりは楽にテストできるように変えた方がよい。

・細かく関数に分け、少しずつ作成し、テストも少しずつ実行してみる。特定に時間のかかる長い関数を作らない。
（こうして書いてみるとエラーを前提に考える場合、テストは重要）

#先は長し
経験値が溜まれば、ハマりは少なくなるでしょう。
とはいえ、常に勉強が必要なエンジニアの中で、
使い慣れていることだけを使い慣れたように使うことも技術的な負債が溜まりそうです。
ならば新しくできることを次々使いこなせるような、
使いこなし方の経験値を意識して貯めるべき、
新しいことを試しても早く作れる、が理想で、
今回の反省がそのために生かせるポイントかなと考えています。

どの道にしてもまだペーペーですが、
こうやって失敗を整理し振り返ってみることが、
自分や、似た立場の人の一助となればと思ってこれを書きます。

#おまけもとい備考
大雑把な処理の流れ
1. ゲーム開始時：初期化 
2. 桝クリック時
　　- （オセロを置いた結果の配列から）自分の置ける場所ならばオセロ石を置いて裏返す。
　　- 盤面を見てオセロ石の周囲がどの座標か把握する。（配列に入れる）
　　- オセロ石の周囲に白も黒も置ける場所がなかったらゲーム終了。
　　- 手番を更新
　　- オセロ石の周囲（の配列）を元に、手番の人がそこに置けるかどうかをチェックする。
　　　置ける場合、置ける場所と結果を覚えておく（配列に入れる）
　　- 置ける場所がなかったらパスして手番更新。
　　- 次の手番でも置ける場所がなかったらゲーム終了


追記
 
oceloじゃなくてothello
Flutterで色々なディレクトリのファイルから、他のファイルのコードを読み込む方法メモ

# 一番シンプルなパターン

まず、```main.dart``` にメインのコードを書いて、
```sub.dart```にインポートしたいクラスを書いておくという状況を想定。

Flutterのプロジェクトのディレクトリ構成は以下。
今回、```sub.dart```は```main.dart```と同じディレクトリに配置。

```
Project Files
    …
    lib
        main.dart 
        sub.dart
```


以下のようにインポートする。

```#sub.dart

class ABC{
    //...変数など...
    ABC(){
    //...コンストラクタ...
    }
}

```


```#main.dart
import 'sub.dart';

ABC abc = ABC();

```

# ディレクトリが入り組んでいるパターン1

次に、```main.dart``` にメインのコードを書いて、同じディレクトリに```components```という新たなディレクトリを作る場合を考えます。
```components```ディレクトリに配置した```sub.dart```にインポートしたいクラスを書いておくという状況を想定。

Flutterのプロジェクトのディレクトリ構成は以下。

```
Project Files
<project name(//任意で自分で決めたもの)>
    …
    lib
        main.dart 
        components
            sub.dart
```

以下のようにインポートする。

```#sub.dart

class ABC{
    //...変数など...
    ABC(){
    //...コンストラクタ...
    }
}

```


```#main.dart
import 'sub.dart';
import 'package:<project name(//任意で自分で決めたもの)>/components/sub.dart';

ABC abc = ABC();

```

# ディレクトリが入り組んでいるパターン2

次に、```main.dart``` にメインのコードを書いて、同じディレクトリに```components```と```screen```いう新たなディレクトリを作る場合を考えます。これはFlutterプロジェクトではよくあるパターンで、```screen```には画面の表示テンプレートっぽい物を中心にファイルを集めます。```compornents```には便利な関数やクラスを集めて使って引き継ぎやすくする工夫です。

今回は、
```components```ディレクトリに配置した```sub.dart```に書いたクラスを、```screen```ディレクトリに配置した```some_screen.dart```にインポートしたいという状況を想定。

Flutterのプロジェクトのディレクトリ構成は以下。
今回、```sub.dart```は```main.dart```と同じディレクトリに配置。

```
Project Files
<project name(//任意で自分で決めたもの)>
    …
    lib
        main.dart 
        components
            sub.dart
        screen
            some_screen.dart
```

以下のようにインポートする。

```#sub.dart

class ABC{
    //...変数など...
    ABC(){
    //...コンストラクタ...
    }
}

```

```#some_screen.dart
import 'package:<project name(//任意で自分で決めたもの)>/components/sub.dart';

ABC abc = ABC();

```
# 相対パスも指定可能

なお、```sub.dart```に```main.dart```の何かをインポートしたい場合は、相対パスも可能です。

```#sub.dart
import '../main.dart';

//main.dartの何かを使う

class ABC{
    //...変数など...
    ABC(){
    //...コンストラクタ...
    }
}

```
ExcelでA,B,C...AA,AB,AC みたいなのを作る

需要があるか不明ですが、掲題について

一行目の式：`=UNICHAR(64+ COLUMN())`
二行目の式：`=MOD(COLUMN()-1,26)`
三行目の式：`=ROUNDDOWN((COLUMN()-1)/26,0)`
四行目の式：`=UNICHAR(65+MOD((COLUMN()-1)-1,26))`
とんで
六行目の式：`=IF(ROUNDDOWN((COLUMN()-1)/26,0)=0,"",UNICHAR(64+ROUNDDOWN((COLUMN()-1)/26,0))) & UNICHAR(65+MOD(COLUMN()-1,26))`

![2019-11-19_17h23_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51918/bef3a9d6-f3cd-292e-26c0-a3a1aa5e971b.png)
BINDの基本的なアクセス制限

# はじめに
BINDを構築した際のセキュリティ設定としてnamed.confに最低限(?)必要なアクセス制限周りのメモとして。

## allow-queryの設定
- **allow-query { any;};**
すべてのIPからDNSの問い合わせに応答する

- **allow-query { trust;};**
許可リストを作成する

### 許可リスト作成の例

```
allow-query { trust;};
    acl trust {
		192.168.1.0/24;
		localhost;
	};
```
	
## allow-recursionの設定
- **再帰的なクエリのを許可するホストを指定する**  
再帰的なクエリ…リゾルバからの問い合わせ要求を受けたDNSサーバが、他のDNSサーバに問い合わせを行い
その最終的な結果をリゾルバに応答する必要のある問い合わせのこと。

```
	options {
		allow-recursion {
		localhost;
		192.168.1.0/24;
		;
	};
```

## allow-transferの設定
- **ゾーン転送を許可するホストを指定する**   
ゾーン転送…DNSにおいてDNSサーバの管理するゾーン情報を別のコンピュータに一括して転送すること

```
	options {
		allow-transfer {
		localhost;
		192.168.1.0/24;
		};
	}
```
Google検索でジオロケーションを指定する方法など

Google検索にエリア検索機能などを盛り込んだchromのプラグイン作りました
(プラグインは現在削除されております）

とりあえず検索エリアは日本の地域のみを組み込みました

プラグインで利用しているGoogleの検索パラメータについて解説します
https://www.google.com/search　以降に記述するパラーメータ
日本語で検索する事を前提として一般的なパラメータを指定する

|パラメータ|内容|値|
|---|---|---|
|q|キーワード |検索文字列|
|ie |クエリ文字コード|utf-8|
|oe |検索文字コード|utf-8|
|mun|1ページの表示件数|数値|
|hl|表示される言語|ja|
|pws|パーソナライズ|1:有効 0:無効|
|gws_rd|リダイレクト|cr:無効|
|adtest|広告テスト|on:有効|

ジオロケーションを指定するパラメータ
Google Adwords
Geo Target CSV fileをダウンロードする
https://developers.google.com/adwords/api/docs/appendix/geotargeting?hl=fr&csw=1

Canonical Name が検索したいエリアになります
エリアに対応したCriteriaID,CanonicalNameの文字数に対応したKeyを取得する
対応表

|文字数|Key|文字数|Key|文字数|Key|文字数|Key|文字数|Key|文字数|Key|文字数|Key|文字数|Key|文字数|Key|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1||11|L|21|V|31|f|41|p|51|z|61|9|71|H|81|R|
| 2||12|M|22|W|32|g|42|q|52|0|62|-|72|I|82|S|
| 3||13|N|23|X|33|h|43|r|53|1|63||73|J|83|T|
| 4|E|14|O|24|Y|34|i|44|s|54|2|64|A|74|K|
| 5|F|15|P|25|Z|35|j|45|t|55|3|65|B|75|L|
| 6|G|16|Q|26|a|36|k|46|u|56|4|66|C|76|M|
| 7|H|17|R|27|b|37|l|47|v|57|5|67|D|77|N|
| 8|I|18|S|28|c|38|m|48|w|58|6|68|E|78|O|
| 9|J|19|T|29|d|39|n|49|x|59|7|69|F|79|P|
|10|K|20|U|30|e|40|o|50|y|60|8|70|G|80|Q|


検索パラメータ

```
tci=g:CriteriaID
uule=w+CAIQICI + Key + CanonicalNameをBase64に変換した文字列
```
札幌を指定した場合
Sapporo,Hokkaido,Japan ⇛ 22文字:W
Sapporo,Hokkaido,Japan ⇛ Base64:U2FwcG9ybyxIb2trYWlkbyxKYXBhbg
tci=g:1009076
uule=w+CAIQICIWU2FwcG9ybyxIb2trYWlkbyxKYXBhbg
こちらを検索パラメータに付与することでエリアを指定できます
Python3でファイルのＤＬとバイト値と削除

ＵＲＬからのＤＬしてバイト値を調べてファイルが圧迫するのでゴミ箱に※⌒ ヾ(*´-｀) ﾎﾟｲするだけのプログラミング。

（追記）
今回はURL先がDBに保存されているURLのみのため、ローカルに保存する形を取りました。
最終的には保存しなくて良いとのことで、後述してあります。

###ソース

```python

# ライブラリの取り込み
import urllib.request
import os.path
 
# URL,保存するパスを指定
url = "https://xxxxxxx.co.jp/1234567.mp4"
save_name = "sample.mp4"
 
# ダウンロードする
mem = urllib.request.urlopen(url).read()
 
# ファイルへの保存
with open(save_name, mode="wb") as f:
    f.write(mem)

# バイト数獲得
ret = os.path.getsize(save_name)
print(ret)

# ファイルの削除
os.remove(save_name)

```


~~メモリ上でDLしたモノからバイト値とか取りたかったけどローカルに落とさないとダメっぽかったので、他にいい方法無いかな。~~


###2019/11/20追記

メモリ上のデータからファイルサイズは取得できるとのこと。

```python
mem = urllib.request.urlopen(url).read()
print(len(mem))
```

それとは別に、urllib.requestにてHEADメソッドを使用すればヘッダー情報のみを取得してファイルサイズを取得することも可能。（コメントより）




Pythonの入門書すら見ないで初めてるからちゃんと勉強しないといけないなと思いました。反省(´･ω･`)
ansibleでディスク領域を拡張する

ansibleでディスクの操作を行う方法はいくつかあるが、特に使いそうな２つをメモしておく
※ansibleのverによって名前が変わるmoduleがあるため注意

### 動作環境
ansible 2.7.10

##partedでパーティションを切る
パーティションの情報をwith_itemsに持たせる。
複数パーティションを切る場合はwith_itemsに追加してやれば良い

```yml:roles/set_disk/tasks/main.yml
  - name: "disk settings"
  include: disk.yml
  with_items:
    - device: /dev/sdb
      num: 1
      label: gpt
      fstype: xfs
      mount_point: /home/foo/bar
      owner: hoge
  loop_control:
    loop_var: disk

```

```yml:roles/set_disk/tasks/disk.yml
- name: "parted {{ disk.device }}"
  parted:
    device: "{{ disk.device }}"
    number: "{{ disk.num }}"
    state: present
    label: "{{ disk.label }}"
  become: yes
  become_user: root

- name: "format {{ disk.device }}{{ disk.num }}"
  filesystem:
    dev: "{{ disk.device }}{{ disk.num }}"
    fstype: "{{ disk.fstype }}"
  become: yes
  become_user: root

- name: "get blkid for {{ disk.device }}{{ disk.num }}"
  shell: "blkid -s UUID -o value {{ disk.device }}{{ disk.num }}"
  register: uuid
  become: yes
  become_user: root

- name: "Mount up device by UUID for {{ disk.device }}{{ disk.num }}"
  mount:
    path: "{{ disk.mount_point }}"
    src: "UUID={{ uuid.stdout }}"
    fstype: "{{ disk.fstype }}"
    state: mounted
  become: yes
  become_user: root

- name: "chown mount point for {{ disk.device }}{{ disk.num }}"
  file:
    path: "{{ disk.mount_point }}"
    owner: "{{ disk.owner }}"
    group: "{{ disk.owner }}"
    state: directory
  become: yes
  become_user: root
```


##LVMでディスクを拡張する
vgとlgの名前は特になければなんでも良い。
マウントポイントはpathに指定する。

```yml:roles/set_disk/tasks/main.yml
- name: create volume group
  lvg:
    vg: hoge
    pvs: "/dev/sdb"
  become: yes

- name: create logical volume
  lvol:
    vg: hoge
    lv: fuga
    size: +100%FREE
  become: yes

- name: make filesystem
  filesystem:
    fstype: xfs
    dev: /dev/hoge/fuga
    resizefs: yes
  become: yes

- name: mount disk
  mount:
    path: /home/foo/bar
    src: /dev/hoge/fuga
    fstype: xfs
    state: mounted
  become: yes

- name: "change permission for mount point"
  file:
    path: "/home/foo/bar"
    mode: "0755"
    owner: "hoge"
    group: "hoge"
    state: directory
  become: yes

```
wmicコマンドでシステムの情報を取得する

# システム情報の取得
プロセスやメモリ使用率などをコマンドを使って取得する。

## プロセス情報
使用中のプロセス情報を取得するコマンド。

```
wmic process get name,workingsetsize
```

## ディスク情報の取得
ドライブ名、ファイルシステム、サイズなどが取得できる。

```
wmic logicaldisk get Caption,Description,FileSystem,Size
```

# 端末情報の取得
端末の型番やシリアルナンバーをコマンドを使って取得する。

## 端末型番の取得
```
wmic csproduct get name
```

## シリアルナンバーの取得
```
wmic csproduct get identifyingnumber
```
### 備考
一部の端末では、Microsoft Windows Management Instrumentation (WMI)に対応していないなどの理由で情報を取得できない場合もあるみたい？

# セキュリティパッチ等の情報の取得
適用されているWindows Updateやセキュリティパッチの情報が取得できる。

 ```
wmic qfe
```
lsyncdでWindowsとNASのデータを同期する

バックアップ用ストレージにユーザープロファイルを同期することは、データ消失を防止する上で非常に重要ですが、WindowsにおいてはWindows10標準搭載の「ファイル履歴」を含め、SMB経由での同期しか行うことができないため非常に低速となります。
そこで、Unix用のファイル同期ソリューションであるrsyncを用いて同期を高速化することを考えます。

# rsyncをwindowsで使う

ファイル同期においてrsyncの右に出るものはいません。
ひとたびNASにrsyncサーバーを立ててしまえば、

```sh
$ rsync -avh ~/ rsync://192.168.0.123/home/
```
のように書けばすぐにNASのhomeモジュール内にホームディレクトリのファイルが全て同期されます。
しかも、転送する必要のあるファイルしかやり取りしないため、robocopy+SMBなどによる転送とは比べ物にならないくらい高速です。

しかし、当然ながらrsyncはunix向けのソフトウェアでありwindowsでは利用することができません。

## rsync on WSL
しかし、Windows10をお使いならば心配は無用です。
Windows Subsystem for Linuxは実際rsyncを実行するのに十分なシステムコールを備えており、
以下のコマンドによるホームディレクトリの同期はうまく動作します。

```sh
$ sudo apt -y install rsync
$ rsync -avh --exclude '/AppData/' /mnt/c/Users/hoge/ rsync://192.168.0.123/home/
```

# lsyncdでリアルタイム同期

rsyncでは明示的にコマンドを実行しない限り同期が行われませんでしたが、
これをinotifyやfseventsなどを活用してリアルタイムに行うデーモン「[lsyncd](https://github.com/axkibe/lsyncd)」が存在します。

例えば、以下のようなコンフィグを記述します。

```lua:/etc/lsyncd.conf
settings {
    logfile = "/var/log/lsyncd.log",
    statusFile = "/tmp/lsyncd.stat",
    insist = true,
    nodaemon = true,
}
sync {
    default.rsync,
    delay = 0,
    source = "/mnt/c/Users/hoge/",
    target = "rsync://192.168.0.123/home/",
    exclude = { "/AppData/" },
    rsync = {
        archive = true,
        links = true,
        update = true,
        verbose = true,
    },
}
```

WSLにlsyncdをインストールします。

```sh
$ sudo apt -y install lsyncd
```


デーモンを開始するためのコマンドラインは以下のとおりです。

```sh
$ sudo lsyncd -pidfile /run/lsyncd.pid /etc/lsyncd.conf
16:58:59 Normal: --- Startup ---
16:58:59 Normal: recursive startup rsync: /mnt/c/Users/hoge/ -> rsync://192.168.0.123/homes/ excluding
/AppData/
sending incremental file list
sent 1,152 bytes  received 21,533 bytes  817.28 bytes/sec
total size is 15,899,217,862  speedup is 5470.29
16:59:34 Normal: Startup of /mnt/c/Users/hoge/ -> rsync://192.168.0.123/homes/ finished.
```

これはinotifyを用いてファイルの変更を検知します。例えば、

```sh
$ echo 'hello' > /mnt/c/Users/hoge/test.txt
```

と実行すると、以下のようなログが出力されます。

```sh:lsyncd
17:07:43 Normal: Calling rsync with filter-list of new/modified files/dirs
/test.txt
/
sending incremental file list
./
test.txt
sent 155 bytes  received 37 bytes 122.67 bytes/sec
total size is 0  speedup is 0.00
17:07:44 Normal: Finished a list after exitcode: 0
```

このようにリアルタイムにユーザープロファイルを同期することが可能です。
ALBを使用してサーバーを止めずに、ページを更新する

やらないと忘れるので、メモしておく。

### ALB
ALBを使用すれば、サーバーを一時停止せず、
メンテ画面を表示せずに裏側でうまくページの更新や機能の追加をすることができる。


## 手順
1. 本番のEC2元のAMIからEC2を起動する
2. ①で作ったEC2にsshする
3. `cd /usr/share/nginx/html/アプリ` し `git pull origin master` する
4. ③のAMIを作成する
5. 起動設定を作成する
6. AutoScalingグループを作成する
7. ⑥のキャパシティを2にする
8. ⑦のキャパシティを1に戻し、更新されているか画面を確認する



### 1. 本番のEC2元のAMIからEC2を起動する
AWSにログインし、現在起動しているEC2の元のAMIから、新しくインスタンスを起動する。
ただし、現在起動中のEC2の元のAMIが存在せずに、起動中のEC2からAMIを作成する場合は一時的にインスタンスが止まってしまうため注意が必要。

<img width="1402" alt="AMI___EC2_Management_Console.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/2d53ade7-5e1f-6475-029e-cff7ddb2fb1f.png">


### 2. ①で作ったEC2にsshする
`ssh -i ~/.ssh/鍵.pem ユーザー名@IPアドレス` で起動したEC２にSSHする

### 3. `cd /usr/share/nginx/html/アプリ` し `git pull origin master` する

### 4. ③のAMIを作成する
<img width="1240" alt="インスタンス___EC2_Management_Console.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/3e49c579-0821-2fed-a973-82a3fd5e6aca.png">


### 5. 起動設定を作成する
- 前回の起動設定をコピーする
- AMIの選択を④で作成したAMIにする

<img width="1627" alt="EC2_Management_Console.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/e6b357f1-3aef-1b40-3d5b-87caf92b9ac8.png">


<img width="1616" alt="EC2_Management_Console.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/862fa492-cc1c-d9b2-53e2-d4fcb373c9c8.png">


### 6. AutoScalingグループを作成する
- 起動設定を⑤にする
- キャパシティ1を確認

<img width="1628" alt="EC2_Management_Console.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/168550/3dc936ee-2833-42e2-1a32-220de504473b.png">


### 7. ⑥のキャパシティを2にする

### 8. ⑦のキャパシティを1に戻し、更新されているか画面を確認する
コマンドプロンプトからネットワークコンポーネントアンインストールする

# ネットワークコンポーネントとは
ネットアダプターなどに紐づいてるネットワークに接続するために必要なソフトウェアようなもの。
不要なものは削除する必要がある場面があったのでメモ。


## ネットワークコンポーネント確認
インストールされているネットワークコンポーネントを確認する。

```
netcfg -s n
```

## コンポーネントをアンインストール
確認したコンポーネントから不要なものをアンインストールする。

```
netcfg -v -u XXXX(NWコンポーネント名)
```

# 参考URL
https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/netcfg
Nuxtでモーダル実装時に背景がスクロールできてしまう時の対処法

# モーダルコンポーネントを作る
```vue
<template>
  <transition name="modal">
    <div class="modal-mask" @click="closeModal">
      <div class="modal-wrapper">
        <div class="modal-container" @click.stop>
          <div class="modal-contents">
            <slot></slot>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
export default {
  name: "TheModal",
  methods: {
    closeModal() {
      this.$emit("closeModal");
    }
  }
};
</script>

<style scoped>
省略
</style>
```
ソースコードは[こちら](https://github.com/taakuuyaa/Nuxt-sample-modal/blob/master/pages/index.vue)

pageコンポーネントのtemplateで以下のように呼び出し

```vue
<TheModal v-show="showModal" @closeModal="showModal = false">
 モーダル
</TheModal>
```

## 結果

![スクリーンショット 2019-11-19 15.59.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288728/4cae0701-d9cd-a4cd-6731-f8e8b02e4cb8.png)

しかし、このままだとモーダルを表示した状態でも後をスクロールすることができてしまう。

![スクリーンショット 2019-11-19 16.09.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/288728/d1151218-503d-27b5-a72f-ede869483214.png)


# 解決方法

モーダルが表示されているときにbodyタグに以下のクラスを付与する。

```css
modal-body {
  overflow-y: hidden;
  position: fixed;
}
```

bodyにクラスを付与するために**グローバルに読み込まれているCSS**などに上のクラスを定義しておく。

ページコンポーネントの**head()**に以下を設定する

```vue
<script>
import Logo from "~/components/Logo";
import TheModal from "~/components/TheModal";

export default {
  components: {
    Logo,
    TheModal
  },
  data() {
    return {
      showModal: false
    };
  }
  //　↓追加↓
  head () {
    return {
      bodyAttrs: {
        class: this.showModal ? 'modal-body' : ''
      }
    }
  },
};
</script>
```
**this.showModal**がtrueの時(モーダルが表示されている)にbodyタグに
modal-bodyクラスを付与することができ背景をスクロールさせなくできます。
IPv6の無効化/有効化

# IPv6 無効化
アダプターのプロパティとインターフェースの両方からIPv6の無効化する。
## アダプタープロパティの設定
- 対象NICのアダプターのプロパティを開き、「インターネット・プロトコルバージョン6(TCP/IPv6)」を無効化する。
- もしくはPowerShell上で以下のコマンドを実行する。

```
Disable-NetAdapterBinding -Name "イーサネット" -ComponentID ms_tcpip6
Get-NetAdapterBinding -Name "イーサネット" -ComponentID ms_tcpip6
```

## 各インターフェースの無効化
以下のコマンドはコマンドプロンプトで実行する。
### ISATAP インタフェース無効化

```
netsh interface ipv6 isatap set state disabled
```
### 6to4 インタフェース無効化

```
netsh interface ipv6 6to4 set state disabled
```

### Teredo インタフェース無効化
```
netsh interface ipv6 set teredo disabled
```

# IPv6 有効化
アダプターのプロパティとインターフェースの両方からIPv6の有効化する。
## アダプタープロパティの設定
- 対象NICのアダプターのプロパティを開き、「インターネット・プロトコルバージョン6(TCP/IPv6)」を有効化する。
- もしくはPowerShell上で以下のコマンドを実行する。

```
Enable-NetAdapterBinding -Name "イーサネット" -ComponentID ms_tcpip6
Get-NetAdapterBinding -Name "イーサネット" -ComponentID ms_tcpip6
```
## 各インターフェースの有効化
以下のコマンドはコマンドプロンプトで実行する。
### ISATAP インタフェース有効化

```
netsh interface ipv6 isatap set state enable
```
### 6to4 インタフェース有効化

```
netsh interface ipv6 6to4 set state enable
```

### Teredo インタフェース有効化
```
netsh interface teredo set state enterpriseclient
```

# IPv6インターフェースのステータス確認
## ISATAP インタフェース

```
netsh interface ipv6 isatap show state
```
## 6to4 インタフェース

```
netsh interface ipv6 6to4 show state
```

## Teredo インタフェース
```
netsh interface teredo show state
```
秘密鍵と公開鍵とデジタル署名と証明書

##署名鍵が分からんのでメモメモ
<b>（※※理解できてないところ多々のメモ※※）</b>

秘密鍵の持ち主＝太郎くん
公開鍵の持ち主＝花子さん

###公開鍵暗号方式
* 公開鍵と秘密鍵がある
* 公開鍵はみんなにばらまく（その内の１人が花子さん）、秘密鍵は自分だけで持っている
* 鍵＝暗号化したり複合化したりする時に使う鍵
* 公開鍵を受け取った相手は、その公開鍵をどこかに持っている状態
* 花子さんはその公開鍵で暗号化したものを、秘密鍵の持ち主である太郎くんに送る
* 太郎くんは、花子さんが公開鍵で暗号化したデータを自分の秘密鍵で複合化することができる

###デジタル署名
* ~~公開鍵暗号方式を利用した仕組みのこと~~
→公開鍵暗号の一種
 ※「いわゆる公開鍵暗号」は、公開鍵暗号の中の暗号化機能、デジタル署名は公開鍵暗号の署名機能

* ~~太郎くんは秘密鍵でファイルを暗号化する＝これがデジタル署名~~
→秘密鍵で署名する
　※「暗号化と署名は別物
* 秘密鍵の暗号文は電子署名として利用出来る 
* デジタル署名付きのファイルを花子さんに送る
* ~~花子さんは公開鍵でデジタル署名を複合化して、一緒に送られてきたファイルと中身を比べる~~
→公開鍵でファイルの中身と署名を検証する
　※別に復号するわけではない。整合性を確認する「検証」は方式によってさまざま異なる。

* 元のファイルと複合化したデジタル署名が一致する→太郎さんが作ったものであると証明できる
* 正しくはファイルそのものを暗号化するわけではないらしい
* とりあえずここで使う秘密鍵を署名鍵と呼ぶらしい…？

よく分からんのだが原文のファイルも一緒に送るとそれを盗み見られないの？そこも厳密には違うのかな？流し読みじゃまだわからないので続調査

###証明書
* コンピュータの世界における「どこかの誰かが発行した身元証明書」
* 認証局が発行してくれるらしい

認証局って何…？（わからん）



参考：
https://wa3.i-3-i.info/word1828.html
https://qiita.com/kunichiko/items/ef5efdb41611d6cf7775
Windowsイベントログサイズをコマンドで変更する

# はじめに
- そもそもイベントビューアーからGUIで設定変更することができる
- 設定台数が多い時やバッチ処理で設定するときに便利

# 各イベントログサイズ変更
セキュリティ、セットアップなど個別に設定する必要がある。
また、最大ログサイズの変更は、1024KBしか設定できない
## セキュリティログのサイズ変更
```
wevtutil sl Security /ms:1024000KB
```
## セットアップログのサイズ変更
```
wevtutil sl Setup /ms:1024000KB
```
## システムログのサイズ変更
```
wevtutil sl System /ms:1024000KB
```

# おまけ
PowerShellでも変更できる。

```
limit-eventlog -logname Application -MaximumSize 1024000KB
limit-eventlog -logname Security -MaximumSize 1024000KB
limit-eventlog -logname System -MaximumSize 1024000KB
```
AngularでDI対象Serviceにプロパティ初期化済みでmixinする

# 概要

mixinというか多重継承みたいになったが以下でできた。

```ts
export type Constructor<T = {}> = new (...args: any[]) => T;
class EmptyClass {}

export function SomeMixin<TBase extends Constructor>(Base: TBase) {
  return class extends Base {
    private privateValue = 1;
    protected protectedValue = 1;
    publicValue = 1;

    someMethod() {
      console.log(this.privateValue);
    }
  };
}

@Injectable({ providedIn: 'root' })
export class SomeService extends SomeMixin(EmptyClass) {
  // ここに普通に実装できる
  constructor(private router: Router) {}
}
```

# 動機

- typescriptにはmixinが用意されていないが単一継承だと足りない場合もいつかあるのでどうにかしたかった。

# 調査

- 公式のやつはプロパティ初期化が無視される
https://www.typescriptlang.org/docs/handbook/mixins.html

- typescript用と銘打たれてる以下のやつはそのまま使うとexport対象がクラスじゃないのでDIで弾かれる
https://typescript-jp.gitbook.io/deep-dive/type-system/mixins
  - これをextendsに使ったらうまく行った。

# あとがき

- 結果的に継承してるだけになったので既に他の子クラスになってるやつ以外は普通に継承を使ったほうが読みやすいと思う。
- もっと良い書き方あればください。
RHEL ロケール(locale)確認方法

#Linux RedHatロケールを確認するには？
#localctlコマンドを利用する
Linux RedHat7.7のロケールを確認する為には、localectlコマンドを利用します。
実行コマンドと結果は下記の通りです。

```
# localectl status 
  System Locale:LANG=ja_JP.utf8
  VC Keymap: us
  X11 Layout: n/a
```




##ロケールを変更したい場合
①まず、設定できるロケールを参照します。

```
# localectl list-locales
```


②次に設定します。「設定したいロケール」の箇所は先ほどのリストから設定したい言語を選出し入力すればOKです。

```
# localectl set-locale LANG=設定したいロケール
```

③設定が反映されているのかを確認します

```
# localectl status
```



#引用
RHEL7のシステムロケールを設定する
>https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/system_administrators_guide/ch-keyboard_configuration

システムロケール変更の設定をする
>https://www.atmarkit.co.jp/ait/articles/1811/30/news060.html


以上がロケールの確認方法でした。
最後までご覧いただきありがとうございました！
変更・修正箇所等ございましたらご指摘いただけますと幸いです。
宜しくお願い致します。
非同期処理に便利なremote: tureオプションを利用する

####remote: tureの概要

・非同期処理を行ないたいに使う
・link_to もしくは　button_to で利用可能。
・button_toで可能ということは、submitでも可能？

---

Railsには、Ajax機能が組み込まれている
remote: ture オプションで非同期処理が可能。

リクエストが、HTML形式ではなくjs形式なる（ページ遷移をしなくなる）
参考URL：https://qiita.com/__tambo__/items/45211df065e0c037d032


####メリット

Railsが自動的にAjaxでサーバにリクエストを送信してくれるため、AjaxのJavascriptコードを自分で書く必要がない

####使い方

ex.)link_to の場合

	<%= link_to post_favorite_path(@post),method: :delete do, remote: true %>


こんな感じだけど動作しない・・・ぐぬぬぬぬぬぬぬぬぬ