OmniAICreator/Qiita-1.07M huggingface dataset:
ヒープソート Heap Sort【可視化GIFでソートアルゴリズムを解説 その７】

ヒープソート (heap sort) とはリストの並べ替えを二分ヒープ木を用いて行うソートのアルゴリズムである（ヒープ領域とは無関係であることに注意する）。ヒープはほぼ完全な二分木構造であると同時に、累積の性質を満たします。つまり、子ノードのキー値またはインデックスは常にその親ノードよりも小さい（または大きい）です。

## 7.1 アルゴリズムの説明

アルゴリズムは、以下のように2つの段階から構成される。

* 未整列のリストから要素を取り出し、順にヒープに追加する。すべての要素を追加するまで繰り返し。
* ルート（最大値または最小値)を取り出し、整列済みリストに追加する。すべての要素を取り出すまで繰り返し。

ヒープ構造は、ポインタ等の制御用データが不要で、データ自体の並び順（配列）だけで表現できるという利点がある。ヒープソートを実装する際にはこの利点を生かし、元のデータ領域をそのままヒープ構造や整列済みリストに転用するインプレースなソートとして実装することが多い。

最初にN個のデータを含む配列が与えられるものとする。添字は1 〜 Nとする。

まず各データをヒープ構造に登録していく。m個のデータを処理した状態では、添字1 〜 mがヒープ構造で、(m + 1) 〜 Nが未整列リストとなる。m + 1個目のデータを取り出し、ヒープ構造に登録する。このとき構成するヒープは、昇順にソートする場合はルートが最大値になるよう、降順にソートする場合はルートが最小値になるよう構成する。

すべてのデータをヒープ構造に登録し終えたら、ヒープからの取り出しに移る。ヒープのルートを取り出し、配列の後ろから詰めていく。mを Nから1まで減しながら、取り出したルート要素を配列の添字mに置く。すなわち、(N - m)個のデータを取り出した状態では添字1 〜 mがヒープ構造であり、m + 1 〜 Nが整列済みリストとなる。

すべてのデータをヒープ構造から取り出し終えると、配列全体が整列済みになる。

ヒープの操作の具体的な実装については、二分ヒープの記事を参照すること。

また、一般のヒープ操作では、根元側から木を成長させるのが普通だが、配列のようなデータ構造のヒープソートで、あらかじめ木の最終的な大きさがわかっている場合は、木の葉の側から順番にヒープを構築すると、より効率が良い（この記事で示す実装例では使っていない）。

## 7.2 可視化デモ

![HeapSort.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/3c6f5f67-645b-8bd3-ec89-4c1a690a3fde.gif)


## 7.3 実装
注：ここでは、完全な二分木の性質の一部が使用されています

```java
//グローバル変数を宣言して、配列の長さを記録します。
static int len;

    /**
     * ヒープソート
     *
     * @param array
     * @return
     */
    public static int[] HeapSort(int[] array) {
        len = array.length;
        if (len < 1) return array;
        //1.最大ヒープを構築する
        buildMaxHeap(array);
        //2.ヒープの最初の位置（最大値）と最後の位置がループで交換され、次に
        while (len > 0) {
            swap(array, 0, len - 1);
            len--;
            adjustHeap(array, 0);
        }
        return array;
    }
    /**
     * 最大ヒープを構築する
     *
     * @param array
     */
    public static void buildMaxHeap(int[] array) {
        //最後の非リーフノードから始まり、上に向かって最大ヒープを構築する
        for (int i = (len/2 - 1); i >= 0; i--) {
            adjustHeap(array, i);
        }
    }

    /**
     * 最大のヒープになるように調整する
     *
     * @param array
     * @param i
     */
    public static void adjustHeap(int[] array, int i) {
        int maxIndex = i;
        //左側のサブツリーがあり、左側のサブツリーが親ノードよりも大きい場合、最大のポインターは左側のサブツリーを指す
        if (i * 2 < len && array[i * 2] > array[maxIndex])
            maxIndex = i * 2;
        //右側のサブツリーがあり、右側のサブツリーが親ノードよりも大きい場合、最大のポインターは右側のサブツリーを指す
        if (i * 2 + 1 < len && array[i * 2 + 1] > array[maxIndex])
            maxIndex = i * 2 + 1;
        //親ノードが最大値でない場合は、親ノードを最大値と交換し、親ノードとの交換位置を再帰的に調整する
        if (maxIndex != i) {
            swap(array, maxIndex, i);
            adjustHeap(array, maxIndex);
        }
    }

```
 
## 7.4 性能評価

* 最良時間計算量：T(n) = O(nlogn) 
* 最悪時間計算量：T(n) = O(nlogn) 
* 平均時間計算量：T(n) = O(nlogn)

***
クイックソート Quick Sort【可視化GIFでソートアルゴリズムを解説 その６】

クイックソート (quicksort) は、1960年にアントニー・ホーアが開発したソートのアルゴリズム。分割統治法の一種。

n個のデータをソートする際の最良計算量および平均計算量はO(n log n)である。他のソート法と比べて、一般的に最も高速だといわれているが対象のデータの並びやデータの数によっては必ずしも速いわけではなく、最悪の計算量はO(n^2)である。また数々の変種がある。 安定ソートではない。

## 6.1 アルゴリズムの説明

クイックソートは分割統治法を使用して、リストを2つのサブリストに分割します。 具体的なアルゴリズムは次のとおりです。

* シーケンスから要素を選択し、それを「ピボット pivot」と呼びます。
* シーケンスを並べ替えると、ベンチマーク値よりも小さいすべての要素がベンチマークの前に配置され、ベンチマーク値よりも大きいすべての要素がベンチマークの後ろに配置されます（同じ番号をどちらの側にも配置できます）。 パーティションが終了した後、ベンチマークはシーケンスの途中にあります。 これは分割（partition）と呼ばれます。
* 二分割された各々のデータを、それぞれソートする

## 6.2 可視化デモ

![QuickSort.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/9168d2a8-0938-5953-685b-904db240e1d4.gif)

## 6.3 実装

```java
　　/**
     * クイックソート
     * @param array
     * @param start
     * @param end
     * @return
     */
    public static int[] QuickSort(int[] array, int start, int end) {
        if (array.length < 1 || start < 0 || end >= array.length || start > end) return null;
        int smallIndex = partition(array, start, end);
        if (smallIndex > start)
            QuickSort(array, start, smallIndex - 1);
        if (smallIndex < end)
            QuickSort(array, smallIndex + 1, end);
        return array;
    }
    /**
     * クイックソートアルゴリズム-分割partition
     * @param array
     * @param start
     * @param end
     * @return
     */
    public static int partition(int[] array, int start, int end) {
        int pivot = (int) (start + Math.random() * (end - start + 1));
        int smallIndex = start - 1;
        swap(array, pivot, end);
        for (int i = start; i <= end; i++)
            if (array[i] <= array[end]) {
                smallIndex++;
                if (i > smallIndex)
                    swap(array, i, smallIndex);
            }
        return smallIndex;
    }

    /**
     * 配列内の2つの要素を交換する
     * @param array
     * @param i
     * @param j
     */
    public static void swap(int[] array, int i, int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

```

## 6.4 性能評価
* 最良時間計算量：T(n) = O(nlogn)   
* 最悪時間計算量：T(n) = O(n^2)
* 平均時間計算量：T(n) = O(nlogn)
osrf / rockerでROS/ROS2のためのGUIコンテナ環境構築

# はじめに
本格的にROS2を使いたいと思っていた所、[ROS Japan UG #42 LT大会](https://rosjp.connpass.com/event/209136/presentation/?utm_campaign=new_event_links_to_group_member&utm_source=notifications&utm_medium=email&utm_content=detail_btn)の資料にずっとやりたかったGUIが使えるコンテナ環境構築のやり方があったので実際にやってみる。

# 方針
* 資料で説明されていたやり方の1つである「Ubuntuマシン+DockerでX11経由でGUIを利用」を採用する。
    * 他にもWEBブラウザ経由([参考](https://memoteki.net/archives/2955#i-3]))というやり方があるが、気軽に試す分にはこれが一番簡単。
* ROS2 Foxyでrviz2とgazeboが起動することを確認する。
    * 念の為、ROS1 noeticでも可能か確認する。

# 環境
* ホストPC
    * OS: Ubuntu 18.04
    * GPU: Geforce RTX 2060

* nvidiaドライバのバージョン

```txt
user@user-ubuntu:~$ nvidia-smi     
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 460.80       Driver Version: 460.80       CUDA Version: 11.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  GeForce RTX 2060    Off  | 00000000:0A:00.0  On |                  N/A |
| 49%   36C    P5    22W / 160W |   1232MiB /  5931MiB |     26%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+
```

# 手順
* Python製Docker CLIラッパーのosrf/rockerを利用することで手軽に環境を構築できるようなのでこれを使う。
    * 詳細 : https://github.com/osrf/rocker
* まずnvidiaドライバーとnvidia container toolkitをインストールしてなければインストール。
    * 今回ドライバのバージョンは動作確認されているものと違うものを使ったが現状問題なく動作している。
* 後はインストールとテストを行う
    * 基本はREADMEに沿ってやればいいがいくつかハマった場所がある。
    * rockerインストール時の注意
        * pipコマンドを直打は現在推奨されていないので記述が古い。
            * 正式には`python3 -m pip install`のような書き方にする。
        * rockerインストール時`Failed building wheel for empy`というエラーがでる。
            * wheelをpipでインストールすれば解決
    * テスト実行
        * 以下のテスト実行コマンドが動作しない。
            * `nosetests-3.4 --with-coverage --cover-package rocker`
        * 後述のサンプル実行に影響なさそうなので、原因は後で調べるとして今は無視。
* サンプル実行
    * サンプルコマンドを実行するとrivz2やgazeboが実行できる。
    * ただし、droneと飛行機のサンプルはエラーがでて動作しなかった。
        * マウントが失敗したというエラーがでる。
        * 対策が分からなかったため後で調査する。
* foxyで実行
    * サンプルにfoxyがなかったが以下のコマンドを実行してrviz2が起動することを確認。
        * `sudo rocker --nvidia --x11 --user --home osrf/ros:foxy-desktop rviz2`
    * gazebo起動についてはコンテナ内でgazeboをインストールしてから実行。
        * コンテナ内に移動: `sudo rocker --nvidia --x11 --user --home osrf/ros:foxy-desktop`
        * パッケージを最新に更新: `sudo apt update`
        * gazeboインストール: `sudo apt install gazebo11 ros-foxy-gazebo-ros-pkgs`
        * gazeboコマンドを入力して起動したらOK
* noeticで実行
    * サンプルにnoeticはなかったがrvizはroscoreを起動しないといけないため以下の手順で動作を確認。
        * コンテナ内に移動: `sudo rocker --nvidia --x11 --user --home osrf/ros:noetic-desktop-full`
        * roscoreとrvizを実行: `roscore & rviz`
        * rvizが起動したらOK。
    * gazebo起動は以下のコマンドで起動したらOK
        * `sudo rocker --nvidia --x11 --user --home osrf/ros:noetic-desktop-full gazebo`
WordPressのFTP認証ができない

##どんなエラー？
社内でWordPressを使用しているのですが、WordPressのバージョンアップに際して、なぜかFTP認証のエラーが発生しました。
自分用のメモのつもりで記事を作成します。

##原因
おそらくですが、上記に記載したようにWordPressのバージョンアップに伴って現れたエラーではないかと思います。
素直にFTP認証できれば良いのですが、社内でAWS(EC2)にデプロイしているので、FTP認証に必要な`パスワード`が分かりませんでした。

普段EC2のは、ターミナルでSSH認証をして使用しています。
EC2で扱う認証情報は、`ホスト名`、`ユーザー名`、`秘密鍵(~.pem)`
ですが、FTP認証に必要な認証情報は、`ホスト名`、`ユーザー名`、`パスワード`なので、そもそもEC2を使っていたら、FTP認証はできない可能性が高いです。
(知識不足で、EC2でもFTP認証できる可能性があります。)
##解決
###WordPressのファイルを書き換え
WordPressにある下記の二つのファイルを書き換えます。

```wp-config.php
define('FS_METHOD','direct');
```

```functions.php
function set_fs_method($args) {
return 'direct';
}
add_filter('filesystem_method','set_fs_method');
```
どちらもWordPressにおいて重要なファイルなので、十分注意し、自己責任で操作してください。

###WordPressのファイルに権限を付与
上記の操作を行なっても、
`Update Failed: The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.`
というエラーが発生する場合があるようです。
その場合は、EC2のコンソール内で下記のどちらかを実行します

```
$ sudo usermod -aG www-data $USER

$ sudo chown -R www-data:www-data /var/www

$ sudo chmod -R 774 /var/www
```
もしくは

```
$ sudo chmod -R /var/www
```

です。こちらもWordPressにおいて重要なファイルなので、十分注意し、自己責任で操作してください。


##参考記事
https://funfairfanfare.com/ftp-wordpress-%E6%9B%B4%E6%96%B0%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%84/

https://www.digitalocean.com/community/questions/cannot-update-wordpress-plugins-file-permission-issues
iOSの画像ロードライブラリ「Nuke」のセットアップ&使い方(Swift)

## 「Nuke」とは？

iOSやmacOSなど、Appleのプラットフォーム向けの画像ロードライブラリです。

## 画像ロードライブラリの比較

iOS向けの画像ロードライブラリを比較しました。

||SDWebImage|Kingfisher|Nuke|
|:--|:--|:--|:--|
|最新バージョン|5.10.4|6.2.1|9.4.0|
|最終リリース|2021/02/02|2021/03/09|__2021/03/27__|
|スター数|__23.5k__|18.2k|5.8k|
|言語|Objective-C|Swift|Swift|

※2021/03/27現在

この比較のみだとライブラリの選定基準にならないかもしれません。
以下の記事が参考になると思います。

https://qiita.com/hcrane/items/422811dfc18ae919f8a4

私は特に深い理由はなく、Nukeを使ってみたかったため選定しました。

## 環境

- OS：macOS Big Sur 11.1
- Xcode：12.4 (12D4e)
- Swift：5.3.2
- Nuke：9.4.0

## セットアップ

### インストール

私はXcodeGen + SwiftPMを使っているため、 `project.yml` に以下を記述します。

```yaml:project.yml
packages:
  Nuke:
    url: https://github.com/kean/Nuke
    version: 9.4.0
```

他の方法は [公式ページ](https://github.com/kean/Nuke/blob/master/Documentation/Guides/installation-guide.md) をご参照ください。

## 使い方

ライブラリをインポートし、ロードするのみです。

以下のような拡張メソッドを用意すると便利です。

```swift:UIImageView+URL.swift
import UIKit
import Nuke

extension UIImageView {
    func loadImage(with urlString: String) {
        guard let url = URL(string: urlString) else {
            return
        }
        loadImage(with: url)
    }
    
    func loadImage(with url: URL) {
        Nuke.loadImage(with: url, into: self)
    }
}
```

## おわりに

かんたんに画像をURLから取得して表示することができました！
詳細な使い方は公式ドキュメントをご参照ください。

## 参考リンク

- [SDWebImage/SDWebImage: Asynchronous image downloader with cache support as a UIImageView category](https://github.com/SDWebImage/SDWebImage)
- [onevcat/Kingfisher: A lightweight, pure-Swift library for downloading and caching images from the web.](https://github.com/onevcat/Kingfisher)
- [kean/Nuke: Powerful image loading and caching system](https://github.com/kean/Nuke)
フォームオブジェクトに該当するモデルのエラーメッセージを日本語化

フリマアプリの商品購入画面のエラーメッセージを日本語化しようとしたところ、何も変化がない状態でした。
フォームオブジェクトに関わるモデルはactiverecordではなく、activemodelだったので変化がなかったとのことでした。




```ja.yml
ja:
  activerecord:
    attributes:
      user:
        nickname: ニックネーム
        birth_info: 生年月日
        last_name: お名前(姓)
        first_name: お名前(名)
        last_name_kana: お名前カナ(性)
        first_name_kana: お名前カナ(名)
        
      item:
        text: テキスト
        image: 画像
        price: 値段
        name: 商品名
        description: 商品の説明
        category_id : カテゴリー
        condition_id: 商品の状態
        shipping_id: 配送料の負担
        shipment_source_id: 発送元の地域
        shipping_date_id: 発送までの日数
        
  
      order_address:
        post_num: 郵便番号
        city: 市区町村
        address: 番地
        phone_num: 電話番号
        shipment_source_id: 発送元の地域
```


改善後

```ja.yml
ja:
  activerecord:
    attributes:
      user:
        nickname: ニックネーム
        birth_info: 生年月日
        last_name: お名前(姓)
        first_name: お名前(名)
        last_name_kana: お名前カナ(性)
        first_name_kana: お名前カナ(名)
        
      item:
        text: テキスト
        image: 画像
        price: 値段
        name: 商品名
        description: 商品の説明
        category_id : カテゴリー
        condition_id: 商品の状態
        shipping_id: 配送料の負担
        shipment_source_id: 発送元の地域
        shipping_date_id: 発送までの日数
        
  activemodel:    #<=ここを追記。
    attributes:
      order_address:
        post_num: 郵便番号
        city: 市区町村
        address: 番地
        phone_num: 電話番号
        shipment_source_id: 発送元の地域
```

無事に日本語表記できました。
kubernetesにkube-prometheusを構築する

# 目的
kubernetesのclusterのmetric監視のためにkube-prometheusをkubernetes clusterにdeployする

# Ref
https://github.com/prometheus-operator/kube-prometheus#access-the-dashboards

# Summary
上記Refのreadmeの通りやるだけ

# 環境
local-machine ----- internet ----- kubernetes on AWS

# kube-prometheusをdeployする
```bash:bash
$ git clone https://github.com/prometheus-operator/kube-prometheus.git
$ cd kube-prometheus
$ kubectl create -f manifests/setup
$ until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
$ kubectl create -f manifests/
```

# Grafanaにアクセスするport forwardを設定

```bash:bash
$ kubectl --namespace monitoring port-forward svc/grafana 3000
```

# sshのport forwardを設定
```bash:bash
$ ssh -L 3000:localhost:3000 user@remote-machine
```

# local machineからgrafanaにwebアクセス
localマシンからhttp://localhost:3000へアクセス

# Prometheusにアクセスするport forwardを設定

```bash:bash
kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090
```

# sshのport forwardを設定
```bash:bash
$ ssh -L 9090:localhost:9090 user@remote-machine
```
# local machineからprometheusにwebアクセス
localマシンからhttp://localhost:9090へアクセス
kubernetesにkubernetes dashboardを構築する

# 目的
kubernetesにkubernetes dashboardを構築する

# Ref
https://github.com/kubernetes/dashboard

# サマリ
基本、上記Refのgithubのreadmeの通りやる

# 環境
local-machine ----- Internet ----- kubernetes on AWS

# kubernetes-dashboardをdeployする
```bash:bash
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
```

# dashboardにloginする際のServiceAccountを作る
Ref: https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md

```bash:bash
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
EOF
```
# ClusterRoleBindingを作る
Ref: https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md

```bash:bash
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
EOF
```

# proxyを立てる
```bash:bash
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
```

# local machineでsshでlocal forwardを設定

sshのport forwardingについては以下を参照
Ref: https://qiita.com/mechamogera/items/b1bb9130273deb9426f5

```bash:bash
$ ssh -L 8001:127.0.0.1:8001 username@remote-machine
```

# local machineからwebアクセスする
以下のURLにアクセスするとdashboardが見える
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
Tableau概要 備忘録

タイトルにもありますが、tableauの忘備録としてメモしていきます。

#簡単なグラフ
データソースでデータを読み込んだ後から。
![スクリーンショット 2021-05-27 15.12.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/4bffe163-3596-a3f6-8eb8-6814fdd7c220.png)
左に表示されるデータペイン"ディメンション"と"メジャー"からなる。ディメンションはデータの切り口、メジャーはその数値を示している。もしディメンションからメジャーに切り替えたいときやその逆を行いたいときは、カテゴリ名(例えばオーダーid)を右クリックし、”メジャーに変換"を行えば可能である。もしくはカテゴリ名をメジャーにもっていくことで自動的に変換される。


![スクリーンショット 2021-05-27 15.35.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/249c6b83-efde-217f-f9a2-443e0bed0e53.png)

上記では、カテゴリ別の売上を四半期ごとにプロットしている。列に時系列を示す”年”や”四半期”があるが、これはその左にある＋を押すことでより詳細な時間単位で見ることができる。時系列のスケールは(年→四半期→月→日...)となっている。これは行の中にあるカテゴリにも使用することができる。このようにより詳細な事象を調べることをドリルダウンという。この動作を行うには階層の確認をする必要がある。

![スクリーンショット 2021-05-27 16.01.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/be8c39b2-29a7-c417-f2c0-f969dd583f02.png)

次にフィルタを紹介する。フィルタを使うことで指定した属性をピンポイントにプロットすることができる。上記の例で言えば顧客区分と年をフィルターにかけている。各々を右クリックし、フィルターを表示するにすれば右側に該当するフィルターが表示される。右側のフィルターの表示方法はその都度変えることができる。

![スクリーンショット 2021-05-27 16.16.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/95042959-256a-ff7f-9ef9-71369e1c5593.png)
これまでのグラフを使いながら利益を棒グラフの色の濃淡で表す。まず線グラフから棒グラフへの切り替えは”マーク”の下にある自動を線に切り替えれば良い。さてこの棒グラフに利益の増減を同時に示したい。このとき利益のメジャーをマークの色にドラッグすることで表現することが可能になる。色についての編集は色をクリックすることで可能になる。

#クロス集計
![スクリーンショット 2021-05-27 16.26.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/bfa6c5f2-0cec-7c9f-9187-dbd9aebf3249.png)
まずはクロス集計を作るにあたっての目的の決定する。ここでは時系列のカテゴリ(サブカテゴリ)ごとの売上及び利益について表現したい。このとき行には年及び四半期を、列にはカテゴリ及びサブカテゴリを指定する。売上と利益の表現方法は、各々のメジャーを表中にドラッグするだけである(ここではabcとなっているところ)。
![スクリーンショット 2021-05-27 16.44.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/dc06acfd-ea6d-7c03-a0e0-fce5430ef8b0.png)



#ダッシュボード
ダッシュボードはこれまで作ってきたワークシートを統合することができる。ダッシュボードを新規作成するには、図の右から2番目をクリックすることでできる。
![スクリーンショット 2021-05-27 16.41.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/48d8bf8e-ed66-82ec-c7e4-5bd45348fa07.png)
![スクリーンショット 2021-05-27 16.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/19fcdc51-1368-0061-55a4-63a785091249.png)
これにより年度別の売上・利益とクロス集計表を同時に観覧することが可能になった。もし棒グラフのフィルタを中心にしたいときは、下の図のように棒グラフをクリックし、右側の小さな漏斗マークをクリックする。これにより棒グラフをフィルターとするダッシュボードを作成することができる。

![スクリーンショット 2021-05-27 16.57.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1451692/25b6cf5d-7abb-5708-ed51-bc7b4ea61b14.png)

以上が大まかなTableauの使用感である。
より詳細な操作方法は以下の書籍を参照すれば良い。
[「Tableauデータ分析 ~入門から実践まで」](https://www.amazon.co.jp/Tableau%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90-%E5%85%A5%E9%96%80%E3%81%8B%E3%82%89%E5%AE%9F%E8%B7%B5%E3%81%BE%E3%81%A7-%E7%AC%AC2%E7%89%88-%E5%B0%8F%E9%87%8E-%E6%B3%B0%E8%BC%94/dp/4798059838)
マージソート Merge Sort【可視化GIFでソートアルゴリズムを解説 その５】

選択ソートと同様に、マージソートのパフォーマンスは入力データの影響を受けませんが、常にO（n log n）の時間計算量であるため、選択ソートよりもはるかに優れたパフォーマンスを発揮します。 価格は、追加のメモリスペースの必要性です。

マージソートは、マージ操作に基づく効果的なソートアルゴリズムです。 このアルゴリズムは、分割統治法の非常に典型的なアプリケーションです。 マージソートは安定したソート方法です。 既存の順序付けられたサブシーケンスを組み合わせて、完全に順序付けられたシーケンスを取得します。つまり、最初に各サブシーケンスを順番に作成し、次にサブシーケンスを順番に作成します。 2つの順序付きリストが1つの順序付きリストにマージされる場合、それは双方向マージと呼ばれます。

## 5.1 アルゴリズムの説明

* データ列を分割する（通常、二等分する）
* 分割された各データ列で、含まれるデータが1個ならそれを返し、2個以上ならステップ1から3を再帰的に適用してマージソートする
* 二つのソートされたデータ列（1個であればそれ自身）をマージする

## 5.2 可視化デモ

![MergeSort.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/67eeaed7-a92d-09ec-47c0-955807a9ef09.gif)


## 5.3 代码实现

```java

　　/**
     * マージソート
     *
     * @param array
     * @return
     */
    public static int[] MergeSort(int[] array) {
        if (array.length < 2) return array;
        int mid = array.length / 2;
        int[] left = Arrays.copyOfRange(array, 0, mid);
        int[] right = Arrays.copyOfRange(array, mid, array.length);
        return merge(MergeSort(left), MergeSort(right));
    }

    /**
     * マージソート-2つのソートされた配列を1つのソートされた配列に結合
     *
     * @param left
     * @param right
     * @return
     */
    public static int[] merge(int[] left, int[] right) {
        int[] result = new int[left.length + right.length];
        for (int index = 0, i = 0, j = 0; index < result.length; index++) {
            if (i >= left.length)
                result[index] = right[j++];
            else if (j >= right.length)
                result[index] = left[i++];
            else if (left[i] > right[j])
                result[index] = right[j++];
            else
                result[index] = left[i++];
        }
        return result;
    }
```

## 5. 4 性能評価

マージソートは安定したソート方法です。 選択ソートと同様に、マージソートのパフォーマンスは入力データの影響を受けませんが、常にO（nlogn）時間計算量であるため、選択ソートよりもはるかに優れたパフォーマンスを発揮します。 価格は、追加のメモリスペースの必要性です。

* 最良時間計算量：T(n) = O(n)  
* 最悪時間計算量：T(n) = O(nlogn)  
* 平均時間計算量：T(n) = O(nlogn)

***
React Qiita API から記事情報を取得して表示させる

ReactのAPI練習用に。


```index.js
import React from "react";
import ReactDOM from "react-dom";
import axios from "axios";
import Search from "./Search";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      postsList: []
    };

    this.handleClick = this.handleClick.bind(this);
    this.renderImageList = this.renderImageList.bind(this);
  }

  handleClick(target) {
    const search = target;
    const limit = 20;
    const url = `https://qiita.com/api/v2/items?page=1&per_page=${limit}&query=${search}`;
    axios
      .get(url, {
        headers: {
          Authorization: "Bearer 0a499cd45f8b05c01ec95e4b852f6e91d0dfff44"
        }
      })
      .then((res) => {
        this.setState({ postsList: res.data });
      })
      .catch(console.error);
  }

  renderImageList(list) {
    const posts = list.map((item, index) => {
      return (
        <li className="item" key={index}>
          <span>{index}: </span>
          <a href={item.url}>{item.title}</a>
        </li>
      );
    });
    return posts;
  }

  render() {
    return (
      <div>
        <Search search={this.handleClick} />
        <ul>{this.renderImageList(this.state.postsList)}</ul>
      </div>
    );
  }
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

```



```Search.js

import React from "react";

class Search extends React.Component {
  constructor(props) {
    super(props);
    this.state = { title: "" };
  }

  render() {
    return (
      <div>
        <h2>Find Qiita</h2>
        <form onSubmit={this.handleSubmit}>
          <input
            value={this.state.title}
            type="text"
            onChange={this.handleChange}
          />
          <input type="submit" value="Search" />
        </form>
      </div>
    );
  }

  // valueが変更された際に実行
  handleChange = (event) => {
    // 変更したvalueが返ってくる
    const title = event.target.value;
    // stateを変更
    this.setState({ title: title });
  };

  // submitされた際に実行
  handleSubmit = (event) => {
    event.preventDefault(); // ページ遷移防止
    // 受け取ったメソッドを実行し、app の state を変更している
    this.props.search(this.state.title);
    this.setState({ title: "" }); // submit後は、titleを空にする
  };
}
export default Search;


```

![スクリーンショット 2021-05-27 16.52.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448787/75c78769-a246-d344-3747-96ce74fdf0a2.png)
Libxcビルドの備忘録

# Libxcの概要
[Libxc - a library of exchange-correlation functionals for density-functional theory](https://www.tddft.org/programs/libxc/)
密度汎関数理論(DFT)に現れる、交換相関汎関数(eXchange-Correlation functional)は、スピン密度、カレント密度の汎関数で、多くの種類がある。それらを個々のDFTコードにhomemadeで書くことも出来るが、あまり合理的ではない。様々な汎関数について、スピン密度、カレント密度を入力することで、対応する交換相関ポテンシャル、交換相関エネルギー密度を返してくれるライブラリが、このLibxc。
Abinit, Elk, SALMON, Ocotopus, WIEN2k等、多くの第一原理計算からリンクできるようになっている。

# Libxcのビルド
公式の[Installation](https://www.tddft.org/programs/libxc/installation/)にある通り、基本的には

```console
./configure --prefix=PATH/TO/LIBXC
make
make check
make install
```

libxcを読み込むアプリがインテルコンパイラでビルドされている関係で、libxcもインテルコンパイラでビルドしてい置かないと、不具合が出る可能性がある。インテルコンパイラにするためには、configureを

```console
./configure --prefix=PATH/TO/LIBXC FC=ifort CC=icc
```

に変える。


でビルドできる。

# トラブルシューティング
## gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) on CentOS Linux release 7.6.1810 (Core) でのビルド失敗
`./configure`までは通ったが、makeでこけた。
エラーメッセージを見ると、`-std=c99`等をオプションに付けろというようなメッセージが現れていた。試しにconfigureで出来たMakefileの`CFLAGS=`の個所にこのオプションを付けてみたが、うまくmake出来なかった。

結果的に、gccのバージョンを上げたところ問題なくビルドできた。具体的にはgcc-6.3.1では、`./configure`から、make, make check, make installまで問題なく進んだ。

**Note**@chibataka からいただいたコメント(コメント欄を参照)に従って設定しても、解決するかも。

## Libxc 5.1.4の intel compiler-2019.3.199 でのビルド失敗
以下のメッセージがでてmakefileがコケる。
未解決。

```console
xc-threshold.c(808): error: expected an expression
    for (int i = 0; i < (int) (sizeof(xc_values_type) / sizeof(double)); i++)
         ^

xc-threshold.c(808): error: identifier "i" is undefined
    for (int i = 0; i < (int) (sizeof(xc_values_type) / sizeof(double)); i++)
                    ^
```

一応Libxc 4.3.4ではインテルコンパイラでも問題なくビルドできた。
【Python】SeleniumでCisco機器の推奨バージョンを自動取得する

<h2>このプログラムの趣旨</h2>
前回のYamahaルータのリリース情報と同様に、Cisco機器の推奨バージョン調査を自動化してみた。

[Python : 【Python】RTXのリリースノートから情報を自動取得してCSVに書き出す
](https://qiita.com/ymochi_camera/items/0320f0e2a89a6e151eae "Python : 【Python】RTXのリリースノートから情報を自動取得してCSVに書き出す")

<h2>プログラム処理のざっくり概要</h2>
・ある機器のソフトウェアリリースURLをCSV(device_list.csv)から受け取る
・受け取ったURLへアクセス
・サイト内の推奨バージョンに付与されているクラス要素を取得して、テキスト情報を取得
・CSVの行数分実行し、結果をリストに格納
・リストの中身をCSVへ出力

<h2>プログラムの中身</h2>
```Cisco_version_check.py
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from subprocess import CREATE_NO_WINDOW
import csv
import datetime
import time

# ヘッドレスモードにするための準備
options = Options()
options.add_argument('--headless')

# ブラウザ起動
driver = webdriver.Chrome(executable_path='C:\\chromedriver_win32\\chromedriver.exe', options=options)

# 結果を書き出すCSVファイル名の設定
today_date = datetime.date.today()
result_file = "推奨バージョン_" + str(today_date) + ".csv"

with open(result_file,'a', newline='') as result_csv:
    # csv書き込み用のwriter設定
    writer = csv.writer(result_csv)

    with open('.\\device_list.csv') as f:
        #csvファイルを2行目から読み込み(ヘッダースキップ)
        reader = csv.reader(f)
        next(reader)
        
        for row in reader:
            # CSVからURLを取得してページ遷移
            driver.get(row[1])
            time.sleep(2)

            # デバイス名をCSVから取得して、推奨バージョン情報を取得
            version_info = driver.find_element_by_class_name('selectedRelease')
            writer.writerow([row[0] + "の推奨バージョン：", version_info.text])

            # プロンプトにも表示しておく
            print(row[0] + "の推奨バージョン：" + version_info.text)


driver.close()
print("書き出しが完了しました。")
```

Cisco機器の推奨バージョンは、class="selectedRelease"の指定があるためその要素を指定してます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316676/d22e11d8-b926-48e1-6812-e35ec459f07f.png)


device_list.csvは以下のように記載。
※1行目は読み込みスキップされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316676/e826bf88-1694-48fc-964f-7a2ff19f808f.png)


URLについては、サイトからコピーしてくると

```
https://software.cisco.com/download/home/286282373/type/280805680/release/15.9.3M3
```

のように、"release/"の後にバージョンが載ってますが、その部分は削除して記載してください。

```
https://software.cisco.com/download/home/286282373/type/280805680/release/
```


Cisco_version_check.pyを実行して出力されるCSVファイルは以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316676/94cf5d07-133b-7055-5a81-4bbeac32f67d.png)

定期的に推奨バージョンの確認をする作業がある場合、最初にURLだけ設定しておけば次回以降の作業がCSVチェックだけになる。

あとはPyinstallerでEXEファイル化すれば1クリックで実行可能になるので、らくちんですね。
巨大Subverionリポジトリをgit-svnで利用したときのメモ

# 概要

リポジトリサイズがギガ単位のSubverion(SVN)リポジトリが運用されている環境に身を置きながら、git-svnを介して、gitでバージョン管理をしたときのメモ。

# 実験環境構築

https://qiita.com/huging/items/c51439217d179bff19cd

# clone(init&fetch)

いきなり`git svn clone`するよりは`git svn init`した後に`.git/config`を編集して、`git svn fetch`した方がよい。
`git svn clone`や`git svn fetch`が途中で失敗した場合は、`git svn fetch`で再開できる。単に再開するだけで成功することが多い。

```bat:init
git svn init -s --prefix=svn/ --preserve-empty-dirs https://www.example.com/repos/project
```

## 不要なファイル・ディレクトリの除外

`ignorepaths`を指定することで、正規表現にマッチするパスを`git svn fetch`時に無視する。
`git svn fetch`や`git svn clone`コマンドのオプションとして指定するか、configに設定する。

```bat
git svn fetch --ignore-paths="^branches/old"
```

```conf:.git/config
[svn-remote "svn"]
	ignore-paths="\\.sdf$|\\.ipch$|^branches/bakcup|/rawdata/"
```

上の設定では以下のパスを無視している。
正規表現上で`.`を意味する`\.`は`\`をエスケープする必要があるので`\\.`と入力する。

- 拡張子が`.sdf`
- 拡張子が`.ipch`
- backupブランチ
- rawdataディレクトリ

すでに`fetch`してしまったデータを`ignore-paths`指定によって消去することはできない。clone(init&fetch)からやり直すしかない。

### 負の遺産

今は削除されているが過去にコミットされてしまった巨大なファイルも、履歴上には残っている。すなわち、除外しなければgit-svnのローカルリポジトリに取り込まれてしまうので注意。

## 特定リビジョン範囲のみ取得(clone/fetch)

リビジョン数の大きいリポジトリに関しては、全リビジョンを取得すると膨大な時間が掛かる。ローカルリポジトリのサイズも大きくなりがち。
一部のみ取得することで軽量化できる。ただし、取得しなかった範囲の履歴は利用できない。

```bat:最新のみclone
git svn clone -r HEAD https://www.example.com/repos/project
```
```bat:最新のみfetch
git svn fetch -r HEAD
```
```bat:リビジョン100から最新までfetch
git svn fetch -r 100:HEAD
```

# git gc --autoとの戦い

git操作時に一定条件を満たすとGCが走る。
GC実行中は操作不能になる。
GCの実行頻度が低い場合は手動でGCを実行することで、嫌なタイミングで操作不能になることを防ぐことができる。週に一度、作業終了時にGCを走らせておくなど。

```bat:git-gc手動実行
git gc --prune=now
```

`--prune=now`はブランチの削除等で到達不可能になったオブジェクトをすべて削除する。

https://git-scm.com/docs/git-gc

## git gc --autoの無効化

以下の設定で自動GCが無効になる。

```bat
git config gc.auto 0
```

完全に無効化するのではなく、頻度の調整がしたい場合は下記を参照。

## git gcが頻発

gitの操作をする際に、以下のメッセージが表示されて処理が終わらなくなることがある。
このときgit gcが走っている。

```
Auto packing the repository in background for optimum performance.
```

リポジトリの大きさに比例して発生頻度が高くなり、所要時間は長くなる。


## git gc 頻度調整

(可能なら`git gc`の後に)`git count-object -v`を実行する。下のような情報が表示される。

```bat
> git count-objects -v
count: 11
size: 4904
in-pack: 15
packs: 1
size-pack: 8
prune-packable: 0
garbage: 0
size-garbage: 0
```

- auto gc開始条件
    - count > gc.auto
        - gc.autoの既定値: 6700
    - packs > gc.autopacklimit
        - gc.autopacklimitの既定値: 50

一つのpackファイルのサイズ上限が1GB程度なので、巨大なリポジトリにおいては常に`packs > gc.autopacklimit`となっていることがあり得る。
頻繁な変更が発生するリポジトリにおいてはcountの値がすぐにgc.autoの値を超えるかもしれない。

下のコマンドで設定値が確認できる。
未設定の場合には何も表示されない。既定値を参照する。

```bat:config値確認
git config gc.auto
git config gc.autopacklimit
```

必要に応じて値を調整する。

```bat
git config gc.autopacklimit 200
```

### 参考

https://qiita.com/koseki/items/f1af58f1ec1693f0536a

count-objectsの詳細は公式情報参照。

https://git-scm.com/docs/git-count-objects

最新または利用バージョンのconfignの既定値は公式情報参照。

http://git-scm.com/docs/git-config
Fargate は EC2 マルチテナントであることを意識して使うべきと改めて思った

# 背景

あるとき Fargate 1.4 で動くバッチタスクがエラーをはくようになった。
内容は `Error retrieving credentials from the instance profile metadata service.` で、タスクのメタデータエンドポイントから認証情報を取得できないというもの。

# エラーの原因

タスクは PHP SDK を利用しており、 CloudWatchClient を生成するときに発生したもののようだった。
Client 生成時に渡すクレデンシャルとして通常 Access Key/Secret Key を指定するが、必ずしもセキュアな方法とはいえないため、代わりにタスクの IAM ロールを利用する方法を採用していた。
このとき、SDK はタスクのメタデータエンドポイントに問い合わせを行い、レスポンスから一時的な認証情報を取得する。
https://docs.aws.amazon.com/ja_jp/sdk-for-php/v3/developer-guide/guide_credentials_assume_role.html

エラーの原因は、エンドポイントへのアクセスがしきい値を超えることでスロットリングが生じたことによるものだった。
Client を大量に生成している実装などがあればわかるのだが、当該タスクは起動～終了のライフサイクル内で 1 度しか生成を行わない。

## スロットリングのしきい値

ECS on EC2 であれば環境変数 `ECS_TASK_METADATA_RPS_LIMIT` から確認・変更が可能。
https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/ecs-agent-config.html

一方で Fargate タイプの場合は公開されていない、かつ変更が不可能。

# 複数の Fargate タスクがひとつの EC2 上で動くことへの意識

本問題の対策としては「Access Key/Secret Key を使う方法」「[Credential をキャッシュする方法](https://docs.aws.amazon.com/ja_jp/sdk-for-php/v3/developer-guide/guide_configuration.html#credentials)」などをサポートに教えてもらった。だが結局、本問題は数日経ったら解消した。

これは想像にしかすぎないが、タスクメタデータエンドポイントは他テナントのユーザーと共有されていることから、どこぞの誰かのタスクが「やらかし」てエンドポイントへのアクセスが一時的に増大し、巻き添えをくらってしまったのではないか?
また、この件に限らず、Fargate はタスクが起動できないなど不安定になることが稀にある。

Fargate に関する障害の原因調査をするときに「必ずしもタスク自身に問題があるわけではない」という観点が抜けていると、調査が難航してしまいそうな印象を受けた。若干厄介な性質だがそれ以上のメリットも享受しているので、うまく付き合いながら活用していければと思う。

# 参考

https://aws.amazon.com/jp/blogs/news/under-the-hood-fargate-data-plane/
https://dev.classmethod.jp/articles/reinvent2019-aws-fargate-under-the-hood-con423/
シェルソート Shell Sort【可視化GIFでソートアルゴリズムを解説 その４】

シェルソート（改良挿入ソート、英語: Shellsort）は、1959年に（Donald Shell）によって提案されたソーティングアルゴリズムです。 シェルソートも一種の挿入ソートであり、改良後の単純な挿入ソートのより効率的なバージョンであり、縮小インクリメンタルソートとも呼ばれます。同時に、このアルゴリズムはO（n2）を破る最初のアルゴリズムの1つです。挿入ソートとの違いは、最初に離れている要素を比較することです。 

**シェルソートとは、テーブルに従ってレコードを特定の増分でグループ化し、直接挿入ソートアルゴリズムを使用して各グループをソートすることです。増分が減少すると、増分が1に減少すると、各グループに含まれるキーワードが増えます。ファイル全体が1つのグループに分割され、アルゴリズムが終了します。**

## 4.1 アルゴリズムの説明
シェルソートの基本的な手順を見てみましょう。ここでは、増分gap=length/2を選択し、縮小増分はgap=gap/ 2で続行します。この増分選択はシーケンス{n / 2、 （n / 2）/ 2 ... 1}、インクリメンタルシーケンスと呼ばれます。 ヒルソートのインクリメンタルシーケンスの選択と証明は数学的な問題です。選択するインクリメンタルシーケンスがより一般的に使用され、ヒルインクリメンタルと呼ばれるヒルによって提案されたインクリメンタルでもありますが、実際には、このインクリメンタルシーケンスは最も優れています。 ここでは、例としてヒルインクリメントを使用します。

最初に、ソートされるレコードのシーケンス全体をいくつかのサブシーケンスに分割して、直接挿入ソートを行います。具体的なアルゴリズムの説明は次のとおりです。

* インクリメンタルシーケンスt1、t2、...、tkを選択します。ここでti> tj、tk = 1;
* インクリメントシーケンスの数kに従ってシーケンスをk回ソートします；
* 毎回のソートでは、対応する増分tiに従って、ソートされるシーケンスが長さmのいくつかのサブシーケンスに分割され、各サブテーブルが直接挿入されてソートされます。 増分係数が1の場合のみ、シーケンス全体がテーブルとして扱われ、テーブルの長さはシーケンス全体の長さになります。

## 4.2 動作例

初期データ:

![ShellSort_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/2dbab5ed-a9cb-1f47-170a-2859a3877493.png)

間隔gap=length/2=5でみる。 色の同じところは、同じグループのデータ列である。[8,3], [9,5], [1,4], [7,6], [2,0]

![ShellSort_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/93bede0b-8aa2-87fe-5d5c-3e995f6fe810.png)


同じグループ内で挿入ソートし、間隔をgap=5/2=2にする。[3,1,0,9,7], [5,6,8,4,2]

![ShellSort_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/c1acc997-3229-cd37-5289-d09739b4a4e2.png)


同じグループ内で挿入ソートし、間隔をgap=2/2=1にする。[0,2,1,4,3,5,7,6,9,8]

![ShellSort_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/e4ae5280-d2a8-645a-faf4-60c5eebd9a9f.png)


間隔1ということは、全体が同じ1つのグループということである。これを挿入ソートする。

![ShellSort_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/196344/44dad3a2-7978-39f8-6843-15078dbf72df.png)

## 4.3 実装

```java
　　/**
     * Shell Sort
     *
     * @param array
     * @return
     */
    public static int[] ShellSort(int[] array) {
        int len = array.length;
        int temp, gap = len / 2;
        while (gap > 0) {
            for (int i = gap; i < len; i++) {
                temp = array[i];
                int preIndex = i - gap;
                while (preIndex >= 0 && array[preIndex] > temp) {
                    array[preIndex + gap] = array[preIndex];
                    preIndex -= gap;
                }
                array[preIndex + gap] = temp;
            }
            gap /= 2;
        }
        return array;
    }
``` 

## 4.4 性能評価

シェルソートの中核は、インターバルシーケンスの設定です。 インターバルシーケンスは事前に設定することも、インターバルシーケンスを動的に定義することもできます。 間隔シーケンスを動的に定義するためのアルゴリズムは、「アルゴリズム（第4版）」の共著者であるRobert Sedgewickによって提案されました。

* 最良時間計算量：T(n) = O(nlog2 n)  
* 最悪時間計算量：T(n) = O(nlog2 n)  
* 平均時間計算量：T(n) =O(nlog2n)
JetBrains RiderでGitを使う

###JetBrains RiderでGitを使う

JetBrains Riderには標準でGit機能があります。
ファイル - オープン - バージョン管理から取得、又はVCSから取得ボタンを押すと接続先レポジトリURL画面が開きます。
<img width="400" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/b226e1a1-fb4c-e17d-8bdb-7a4d50ca8c70.png">

メニューのGitを選択し、VCSと連携ボタンを押します。GitHubなどのサービスるに接続されているとコミットパネルが表示されGitが有効になります。
<img width="500" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/6be8135c-0f79-046e-af4f-b55bb841cda3.png">

Gitウィンドウを開くとファイルの状態の差分がわかります。
<img width="500" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/b7a918e2-ec23-739f-31ef-e79b5aa2b0b1.png">

Gitを有効にするとファイル状態によってExploerの色が変化します。色が気になる場合は設定画面からファイル状態の色を変更できます。
<img width="450" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/3511c704-698a-11a0-bef8-512dde421d3b.png">
スマフォで最下部までスクロールした時に処理実行する仕組み作ってみた

チャット形式でエンドユーザーとクライアントがマッチングするサービスを提供しており、
「①質問を表示する、②回答を入力する」がワンセットで繰り返し表示される仕組み。
回答入力後フォーカスを外すことで次の質問を表示できるが、
フォーカスを外せないエンドユーザーが続出した為、
最下部でスクロールした時はフォーカスを外す処理を実装した。
　　

```JavaScript:jQuery
$(window).on('touchend', function(){ // ー①

    // 現状のスクロールの位置＋要素が表示されている領域の高さ
    const windowHeight = $(window).scrollTop() + window.innerHeight; // ー②,③

    // 表示されている要素の高さ
    const scrollHeight = $('html').get(0).scrollHeight; // ー④

    // 以下の式が成り立つ時、現在当たっているフォーカス外す
    if (scrollHeight < windowHeight) { // ー⑤
        $(':focus').blur();
    }
});
```
　　
## 主な動作の流れ
①スマフォ画面から手が離れた瞬間にイベント発火。
②現在表示されている要素の高さを取得。（図１-A）
③現状のスクロールの位置取得。（図１-B上）
④スマフォ画面の表示領域の高さ取得。（図１-B下）
　※この表示領域にキーボードは含まれない。
⑤「A ＜ B」が成り立つ時、現在当たっているフォーカスを外す。

<img height="500" width="700" alt="代替テキスト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1556380/b2a2ebc8-63bc-e6fd-b0fa-c2858e6a9325.png">
## 苦労したこと
スマフォでキーボードが出ている時と、出ていない時とで表示領域が変わる。
状況によって変わる値をどうやって取得できるかを調べるのに時間がかかった。
（window.innerHeightで取得できる。）
cakephp3のビューブロックについて

https://book.cakephp.org/3/ja/views.html#view-blocks

これの知らなかった超絶便利機能があったのでメモ
自分の言葉でまとめますが、語弊があるかもですので参照するなら自己責任でお願いします

#ビューブロックとは
継承してるView同士で特定のパーツを呼び出せる仕組み

```view1.ctp
$this->start('block');
echo "hoge";
$this->end();
```

```view2.ctp
<?= $this->fetch('block') ?>
<!--これを入れた位置に「hoge」が出力される-->
```

とcookbookには書いてます。

#誤解してた
てっきり

- 継承元で定義したブロックを
- 継承先で呼び出す

しかできないのかなと思ってましたがよーーーくcookbookを見たところ、逆もできるそうです。
実用的な感じで言えば、

- layoutとかで呼び出してるブロックを
- template/以下のview内で書き換えられる。

#何が嬉しいのか
これはつまりアクションに応じてlayoutの記述を書き換えることができるということ。

例えば

- アクションごとに違う処理をjsで実行したい
- しかしその記述箇所は一律でheadの中

という場合は

```layout.ctp
<head>
<?= $this->fetch('action_script') ?>
<head>
```

```top.ctp
<?php $this->start('action_script'); ?>
<script>
//TOPで実行したい何かの処理
</script>
<?php $this->end(); ?>
```

```article.ctp
<?php $this->start('action_script'); ?>
<script>
//記事ページで実行したい何かの処理
</script>
<?php $this->end(); ?>
```

という書き方ができる。

うまいこと使えばよくある「コンテンツの性質に応じてlayoutファイルを分ける」という必要もなくなるかもしれない。

#デフォルトの記述の意味
cakephp3の場合、layout/default.ctpにデフォルトで下記の記述があります。（多分）

```php5
<head>
    <title>
        <?= $this->fetch('title') ?>
    </title>
    <?= $this->fetch('meta') ?>
    <?= $this->fetch('css') ?>
    <?= $this->fetch('script') ?>
</head>
```

一方でページタイトルを設定する場合、

```php
$this->assign('title', 'TOPです');
```

という書き方をするといいよ！！というcookbookの記述があります。

https://book.cakephp.org/3/ja/views.html#view-layouts

これができるのも上記の理由から、ということ。
metaとかscriptも同様。
上記の例はあくまで説明のためのものなので、スクリプトを書くならもっといいやり方があるかもです。
（`$this->assign('script', xxx);`とか）
Split string with \n in python

* source

```python
import sys

sa = sys.argv[1]
l = sa.split("\\n") # not \n
print(l)
if len(l) >= 2:
    ret = float(l[len(l)-1])
else:
    ret = float(sa)
print(ret)
```

* execution

```sh
# python3 test.py "3.1"
['3.1']
3.1
# python3 test.py "3.1\n3.2"
['3.1', '3.2']
3.2
```
rescue_fromを活用して、不足の事態に備えましょう！

# 例外とは
例外(Exception)とは、変則的な事態のことで、`例外が発生すると通常の流れから外れて特別な処理に移行`します。Ruby言語には、例外を表現するための**Exceptionクラス**が用意されています。
普段目にするエラーのほとんどは、以下のような継承をしています。

```
Exception
↓
StandardError
↓
ActiveRecord::ActiveRecordError
↓
ActiveRecord::RecordNotFoundなど、普段目にするエラー
```

## rescue_fromとは
アクション内で発生した例外の処理方法を指定するクラスメソッドのことです。
`rescue_from エラー, with: :メソッド名`の形で指定する。
※通常、application_controller.rbに記載する。

## 記載例

```app/controllers/application_controller.rb
class ApplicationController<ActionController::Base

  class Forbidden < ActionController::ActionControllerError; end
  class IpAddressRejected < ActionController::ActionControllerError; end


  # StandardError発生時、rescue_500メソッドを実行する
  rescue_from StandardError, with: :rescue_500
  
  # ForbiddenもしくはIpAddressRejected発生時、rescue_403メソッドを実行する
  rescue_from Forbidden, with: :rescue_403
  rescue_from IpAddressRejected, with: :rescue_403

  # ActiveRecord::RecordNotFound発生時、rescue_404メソッドを実行する
  rescue_from ActiveRecord::RecordNotFound, with: :rescue_404

  private

  def rescue_403(e)
    @exception = e
    render 'errors/forbidden', status: 403
  end

  def rescue_404(e)
    render 'errors/not_found', status: 404
  end


  def rescue_500(e)
    render 'errors/internal_server_error', status: 500
  end
end
```

### 注意点
- 引数の`e`にははExceptionオブジェクトが渡される。
- 親子関係（あるいは先祖・子孫の関係）にある例外をrescue_fromに指定する場合、親（先祖）の方を先に指定する。
- application_controller.rb内が複雑になってきたら、モジュールとして抽出する。
    - 詳しくは[ActiveSupport::Concernを簡単に解説！](https://qiita.com/ren0826jam/items/5e69db4da6020d0c4442)を参照。
NNC210で事前学習モデルを使用する。

マニュアルを見てもイメージネットモデルのサンプルダウンロードをどうすれば良いか見つけられなかった。

ライブラリのマニュアルからImageNet Modelsの記載を見つけた。
https://nnabla.readthedocs.io/en/latest/python/api/models/imagenet.html
この中のリンクから各モデルのnnp形式のファイルがダウンロードできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520250/6287203a-dd89-1ce2-6fa9-610aeb9ee4cf.png)

#利用方法
NNCのedit画面で右クリック、import からnnpを選ぶ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520250/b69d5195-675d-0ac3-b6b5-6ad22717ef03.png)
入力部分を自分が使用するデータセットのサイズに合わせる。224pixが基本だが、事前学習のパラメーターは画像サイズに依存しないはずなので異なっても良いと思う。なお、0-255階調のカラー画像に0.01735かけて1.99引く正規化処理が行われている。これは、事前学習モデルの学習条件なので変更しない。また、データセット側の設定で0-1の正規化のチェックは外しておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520250/76b092c5-c104-373b-2e2b-df7ab508e903.png)
最終段のアフィン(dense 全結合)層も自分のデータセットに合わせて1000から変更しておく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520250/447c5970-888e-7ff5-ab2c-abf0f3d503de.png)
この層だけは事前学習の重みが使えないので、W.Fileとb.Fileを空欄にする必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520250/fffe6ff3-948b-b5af-3073-104a2978f741.png)

#学習層の凍結
前半の学習は変更を加えたアフィン層(Dense層）だけにしたいところ。~~学習層の凍結解除を一気に設定できる方法が分からない。設定自体は、上の図のLRateMultiplier２カ所をいじる。次善の策として、全体の学習率を10^-7とかにして、アフィン層のLRateMultiplierを１００とか１０００にすればよさそう。~~

凍結したいレイヤーをまとめて選択して、どれか１カ所のconvolutionの設定でLRateMultiplierを０にすれば選択範囲がまとめて変更される。同様に選択範囲中のBatchNormalizationやaffineにも実施する。

#モデルを育てる
いいモデルが育ってきたら、Trainタブの右側から Open in EDIT Tab with  Weightを選んでパラメータを保持しながら改善していく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1520250/d88136f5-1c57-8f26-b15b-4bbab6ae5c1a.png)
TomcatのClickjacking対策について

# TomcatのClickjacking対策

## 0.背景

近年、Webサイトへのサーバー攻撃が続いて増加傾向にあり。
その一つ-「clickjacking」の対策方法について紹介させていただきます。

## 1.clickjackingとは

ウェブページの利用者に対し悪意をもって使用される技術の一種で、リンクやボタンなどの要素を隠蔽・ 偽装してクリックを誘い、利用者の意図しない動作をさせようとする手法である。たとえば、別の機能を実行するボタンに見せかけるなどして、埋め込まれたコードを利用者に気づかれないように実行する。

## 2.TomcatはX-Frame-Optionsの設定で対応する

### 2.1　X-Frame-Optionsとは

X-Frame-Options は HTTP のレスポンスヘッダーで、ブラウザーがページを `<frame>`, `<iframe>`,` <embed>`, `<object>` の中に表示することを許可するかどうかを示すために使用されます。 サイトはコンテンツが他のサイトに埋め込まれないよう保証することで、クリックジャッキング攻撃を防ぐために使用することができます。 

### 2.2　X-Frame-Optionsのディレクティブ

| ディレクティブ  | 意味
|:---------------|:------------
| DENY           | 表示を拒否する
| SAMEORIGIN     | 同じサイトのみ表示か許可
| ALLOW-FROM uri | 指定したURIのみ表示が許可する<br>**※最新のブラウザにはもう動きません、使用しないでください。**

### 2.3　X-Frame-Optionsの設定

Webサーバの設定ファイルに、X-Frame-Options に関する設定を追加します。
WebContent/WEB-INF/web.xml

~~~xml
...  
<filter>
        <filter-name>httpHeaderSecurity</filter-name>
        <filter-class>org.apache.catalina.filters.HttpHeaderSecurityFilter</filter-class>
        <async-supported>true</async-supported>
        <init-param>
          <param-name>antiClickJackingEnabled</param-name>
          <param-value>true</param-value>
        </init-param>
        <init-param>
          <param-name>antiClickJackingOption</param-name>
          <param-value>SAMEORIGIN</param-value>
        </init-param>
    </filter>
  <filter-mapping> 
    <filter-name>httpHeaderSecurity</filter-name> 
    <url-pattern>/*</url-pattern>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>
...
~~~

## 3.検証

* サーバー側を再起動

* リスポンスのヘッダを確認する

  ※Chromeの場合、「F12」を押して、DevToolsを起動します。「ネットワーク」の「ヘッダ」タブに確認できること。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234182/117489a8-71b7-e7cc-c5ad-e0dc6c5e63f6.png)

***
【Docker】『-it』ってなに？no.2

![パンプキン カフェ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/47b00491-894f-fac4-69b4-75f8d43000b4.png)


こんにちは。まゆみです。

Dockerについての記事をシリーズで書いています

今回は第2回目になります

Dockerを使っていると必ず使うことになる『-it』フラッグについて今回の記事では解説していこうと思います

ではさっそく始めていきますね。

# -it の正体とは？　

```
docker exec <container id> redis-cli
```
と-itなしで実行しても、別にエラーを出るわけではない。

一体　-itってなんのためにつけるの？

-it をきちんと理解することで、色々応用をきかせて、いろんな場面で使えるようになると思います。


-it は二つのオプションが組み合わさってできています(-it と書くことも　-i -t　と書くこともできるという意味です)

>-i

>-t

になります

まず、これらが[Dockerのドキュメント](https://docs.docker.com/engine/reference/commandline/exec/)でどのように定義されているか見てみます。


![2021-05-27_13-43-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/993f0ff3-0c7d-6ae7-af09-b73d0bff0ee6.png)
引用元：docker docs


>-i (--interactiveでも可)は、STDINを開いておく

>-t はpseudo TTYを割り当てる

と書いています。

具体的に一つづつ解説していきますね

# -i について

-i がドキュメントでどのように説明されているかは、上記のセクションでみましたが、では一体STDIN とは何でしょうか？

STDIN とはstandard input のことでして、日本語では『標準入力』と訳されています。

標準入力のデフォルトはキーボードからの入力です。


>注意！
ただ、Docker Container はデフォルトでは、標準入力を受け取ることができません。

そこで、
あなたのターミナルと、現在実行中のContainer をつないであげる必要があるのです。


![STDIN.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/470ec4f9-01cb-e76d-5bbe-d7b7a4749f84.png)

実際、Redisを使って、『-i』がどのような効果を持つのかを -itを付けた時と何もつけなかった時を比べてみます。

(redisはredis-cliというコマンドラインインターフェースを通じて対話しなければならないので exec <container id> redis-cliというコードになります)


![2021-05-27_14-20-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/ab4f6bc9-f314-35e0-9ac1-9147daa6a2b8.png)

『myvalueを５にセットする』という対話をあなたのターミナルを通してできるようになりました。

![2021-05-27_14-36-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/438799c8-436a-c220-bcec-5864b590fe65.png)


ただ、もし『-it』をなしでコードを実行してみると、結果は下記のようになります

![2021-05-27_14-29-26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/236be9f8-6d70-ed0f-8e73-a323a266b9f8.png)

あなたのターミナルを通して、redis-cliとつながることができません。

このように、『-i』を書くことによって、STDINをあなたのターミナルに対してオープンにすることができます

もしくは、あなたのターミナルと実行中のContainerを一方通行ではなく、双方向に可能なコミュニケーションを可能にさせると表現する事もできると思います

#-t は？

-t は綺麗にフォーマットするために書くと言われています


例えば、

```
docker exec -i <container id> redis-cli
```
と、『t』なしで実行してみましょう

![2021-05-27_15-24-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/bdc532de-4a45-7bda-8e1b-9aaf38ae6858.png)

-it で実行した時はオートコンプリート機能があったけど、-iでtがない時はその機能はありません。


#まとめ
今回の記事は少し短いですが、ここで終わりにさせていただきます。

次回も引き続きDocker についての記事を書いていきますね。
[nuxt-typed-vuex] 親ストアからサブモジュールを使う方法

Nuxt + Typescript 環境において、`nuxt-typed-vuex` を使って Vuex を構築している場合。
親ストアからサブモジュールを呼び出すときの書き方にちょっと癖があった。

## 簡単な方法

`user` モジュールの `auth` ミューテーションを呼び出したいとする。

```typescript:store/index.ts
import { actionTree } from 'typed-vuex'
import { Context } from '@nuxt/types'

export const actions = actionTree({ state }, {
  nuxtServerInit ({ commit }, { req }:Context) {
    // @ts-ignore
    commit('user/auth', req)
  }
})
```

上記の通り、`commit('user/auth')` と書けば解決です。

しかし、この方法ではTypescriptの型解決が効かないため、`@ts-ignore` でTypescriptエラーを制限しておく必要があります。

## 型を解決するTypescript的な方法
前述の方法で問題は無いはずですが、もし型解決できないのが「Typescript的に許せない」と考えるのであれば、`useAccessor`を使うことで、型の解決が効いた状態で、modules内のストアを使用できます。

```typescript:store/index.ts
import { actionTree, useAccessor } from 'typed-vuex'
import { Context } from '@nuxt/types'

import * as user from '@/store/user'

export const actions = actionTree({ state }, {
  nuxtServerInit ({ commit }, { req, store }:Context) {
    const userStore = useAccessor(store!, user, 'user')
    userStore.auth(req)
  }
})
```

[参考]
https://typed-vuex.roe.dev/
https://github.com/danielroe/typed-vuex/issues/66
Gtk3アプリ イベントハンドラー自動生成ツールの作成

### イベントハンドラー自動生成ツールの作成

C#でのイベントハンドラーを自動生成ツールがなかったので自分で作ることにした。

https://github.com/iotagtk1/gladeGenerator/releases

##### 追記 GUIバージョンを中心に開発しています。

https://qiita.com/iota_11/items/4e4d77e91ca3e2223cfe

##### TreeViewプログラム自動生成ツール

https://qiita.com/iota_11/items/7074e21bf99cc56b69ce

##### 使い方
1. グレードデザイナーでフォームをデザインする。
1. コントロールにIDと名前を記入する。トップのWindowに名前を記入します。書き出しに必要なコントロールにも記入します。
1. イベントを追加したい場合はコントロールにシグナルを記入する。名前は適当で良いです
1. gladeGeneratorを実行する。
1. イベントハンドラーファイルが同じプロジェクト内に自動生成されます

<img width="600" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/f61bf619-f84e-580b-47d2-3503c83e358f.png">

#### Riderから実行 Riderのマクロを利用
```
引数はReadMeを参照ください
```

<img width="500" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/15fdfa55-adba-3248-33cb-e24fc1ec7963.png">

RiderやVisual Studioは外部ツールを登録でき、いつでもショートカットで呼び出すことができます
「実行の後に同期」のチェックを外すしておくと、実行の後に自動実行されなくなります。

<img width="300" alt="スクリーンショット 2020-03-29 12.53.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/182324/4977fb6a-92dc-215b-f745-c8cbcff4f10c.png">

Riderの外部ツールのショートカット

##### 宣言文の自動生成
Gladeファイルにコントロールを追加していくごとに宣言文が追加される

```cs
using System;
using Gtk;
using UI = Gtk.Builder.ObjectAttribute;
namespace testGtkApplication
{
    partial class MainWindow
    {    
		//[UI] private readonly Gtk.Window MainWindow = null;
		[UI] private readonly Gtk.Box sdfsdfsd111 = null;
		[UI] private readonly Gtk.Button _button1 = null;		
    }
}
```

##### イベントハンドラーの自動生成
コントロールにシグナルを追加するごとにイベントハンドラー文が追加される

```cs
using System;
using Gtk;
using UI = Gtk.Builder.ObjectAttribute;
namespace testGtkApplication
{
    partial class MainWindow
    {
	    private void on__button1_Clicked(object sender , EventArgs e){
			
		}	    
    }
}
```

| ファイル名| 内容 | 
|:-----------|:------------|
| ConfigSetting.xml       | 総合設定ファイル        | 
| NoImportGladeFileSetting.xml     | 読み込みたくないGladeファイルを設定      |
| GladeFileClassMap.xml     | クラス名を指定して書き出す      |

不具合の報告はGitHubのissuesでお願いします。

[Gtk3アプリ Sqliteを使う](https://qiita.com/tana_/items/3b2dac78f1ba554e4b06)に続く

##### 追記　機能を追加しました
[Gtk3アプリ イベントハンドラー自動生成ツール　改良](https://qiita.com/iota_11/items/3318fa527065d4c73a3f)

[Gtk3アプリ イベントハンドラー自動生成ツール GUI版](https://qiita.com/iota_11/items/4e4d77e91ca3e2223cfe)