OmniAICreator/Qiita-1.07M huggingface dataset:
Seabornを使って分類を可視化してみた




## はじめに
初めての投稿。下記の内容を参考にJupyter Notebookで可視化をしてみた。訓練データで分類したものがテストデータにどのくらい合致しているか目で見れるようにした。

https://scikit-learn.org/stable/auto_examples/neighbors/plot_classification.html

##環境
Windows10
Python 3.8.5

## 準備

```python
#ライブラリインポート
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.colors import ListedColormap
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
from sklearn.svm import LinearSVC

##データセットの用意
data = load_breast_cancer()
df = pd.DataFrame(data.data, columns = data.feature_names)
df.head()
```


Dataframeの表示。今回グラフ描写には1番目と2番目の要素を使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/1c122712-f009-6ca2-41f4-a2bddd6897e7.png)

## 分類の可視化

```python
#データの設定
X = data.data[:,:2]
y = data.target

# ランダムにトレーニングデータとテストデータとに分割
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.25,random_state=5)

# マップの色(青と赤で指定)
cmap_light = ListedColormap(['b', 'r'])
cmap_bold = ['b', 'r',]

#モデル化
svc = LinearSVC()
clf = svc
clf.fit(x_train, y_train) #訓練データを使って区分化
 
# メッシュサイズ
h = .02 

# プロットの境界を決める
# point in the mesh [x_min, x_max]x[y_min, y_max].
x_min, x_max = x_train[:, 0].min() - 1, x_train[:, 0].max() + 1
y_min, y_max = x_train[:, 1].min() - 1, x_train[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])

# 実際にプロットし、どのように分類されるか定義
Z = Z.reshape(xx.shape)
plt.figure(figsize=(7, 5))
plt.contourf(xx, yy, Z, cmap=cmap_light,alpha=0.5)

# 描画
sns.scatterplot(data=data, x=x_train[:, 0], y=x_train[:, 1],hue=y_train,
                    palette=cmap_bold, alpha=0.8, edgecolor="black",marker='o',s=50) #訓練データ
sns.scatterplot(x=x_test[:, 0], y=x_test[:, 1],
                    palette=cmap_bold, alpha=0.8, edgecolor='yellow',linewidth=1,marker='*',s=250,legend=False) #テストデータ
plt.legend(bbox_to_anchor=(1.2,1),loc='upper right',borderaxespad=0) #凡例をグラフの欄外に出す
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.xlabel('mean radius')
plt.ylabel('mean texture')

plt.show()
```

黒の枠線で囲われたのが訓練データ、黄色の枠線で囲われたのがテストデータ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259951/de948290-0e3d-5214-0e94-66211248b1b5.png)
regl+VueでWebGLのシェーダを簡単に扱う


## 概要
[regl](https://github.com/regl-project/regl)はWebGL APIのwrapperのようなライブラリ。生のWebGLに近い自由度を保ちつつ、格段にシンプルな記述を可能にする。
ここでは、Vue (+TypeScript) 環境でreglを用いた描画を行うシンプルな方法を記載する。

（↓のVue版に相当。reglの説明などはそちらを参照。）

https://qiita.com/sw1227/items/2745d36f20ba47d7e53a

※ VueもTypeScriptも初心者なので、より良い方法があったら教えてください。

## Vueでreglを扱う
もともとNuxt.jsを利用して`/pages`以下に置くことを想定したコードだが、Nuxt.jsを使わなくても（ほぼ？）同じだと思う（詳しくない）。


```vue:regl.vue
<template>
  <div id="regl" style="width: 100%; height: 100%"></div>
</template>

<script lang="ts">
import Vue from 'vue'
import createRegl from "regl";

const frag = `
precision mediump float;
uniform vec4 color;
void main() {
  gl_FragColor = color;
}`
const vert = `
precision mediump float;
attribute vec2 position;
void main() {
  gl_Position = vec4(position, 0, 1);
}`

export default Vue.extend({
  data () {
    return {
      regl: {} as createRegl.Regl
    }
  },
  mounted () {
    this.regl = createRegl("#regl")
    const drawTriangle = this.regl({
      frag: frag,
      vert: vert,
      attributes: {
        position: [[0, -1], [-1, 0.5], [1, 1]] // No need to flatten
      },
      uniforms: {
        color: this.regl.prop('color')
      },
      count: 3 // Number of vertices to draw in this command
    })
    this.regl.frame(({ time }) => {
      this.regl.clear({
        color: [0, 0, 0, 0],
        depth: 1
      });
      drawTriangle({
        color: [
          Math.cos(time * 1.0),
          Math.sin(time * 0.8),
          Math.cos(time * 3.0),
          1
        ]
      });
    })
  },
  destroyed () {
    this.regl.destroy()
  }
})
</script>
```

マウントされたタイミングで`div#regl`要素に関してreglのインスタンスを作成し、三角形の描画を行っている。シェーダは文字列として直接記述しているが、外部ファイルに分離したものを[raw-loader](https://github.com/webpack-contrib/raw-loader)で読み込んでも良い。
Cognito入門 〜SAML連携〜

# 概要
Cognitoの基本的な用語や設定については割愛します。
今回は、Cognitoと外部Idp経由(SAML)での認証の仕組みを構築したときのポイントについて説明します。イメージは以下のようになります。ユーザープールのフェデレーションの仕組みを活用、外部Idpと連携することで、認証処理そのものはIdp側におまかせすることになります。

![cognito01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117386/305edee7-2241-c6ae-f2b8-87f07ae76bf9.png)

# 設定方法
### 外部Idpの設定
ここでは省略します。設定後、外部Idp側からSAML設定用のメタデータドキュメント(XML)を入手しておきます。

### Cognitoの設定(主な設定項目のみ)
| カテゴリ | 設定項目１ | 設定項目２ |　値 |
|:-----------|:------------|:------------|:------------|
| 全般設定     | アプリクライアント|トークンの有効期限を更新|デフォルト(30日)|
|             |             |アクセストークンの有効期限| 720分|
|             |             |IDトークンの有効期限| 720分|
|アプリの統合    |アプリクライアントの設定|コールバックURL|https://xxxx/oauth2/idresponse|
|             |                  |サインアウトURL|システムに独自の値。|
|             |                  |許可されているOAuthフロー|Authorization code grant, Implicit grantにチェック。|
|             |                  |許可されているOAuthスコープ|phone,email,openid,aws.cognito.signin.user.admin,profileにチェック。|
|            |ドメイン名|         |プレフィックスを指定。実際にはアクセスするURLとしてDNS登録する。DNS登録されたURLをSAML構成時のエンティティIDとしてIpdと連携する。|
|フェデレーション|IDプロバイダ||Idpから入手したメタデータドキュメントをアップロードしてプロバイダを作成。|
|           |属性マッピング||Idp側の属性をCognitoのユーザープールの属性にマッピング。| 

### ALBの設定
今回は、ALBとCognito認証を組み合わせています。ALBにリクエストが来た場合にCognitoで認証をかけます。ALBからリスナーを追加。追加したリスナーのルールを設定します。
ルールの条件を指定して、
![リスナールール1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117386/98db526f-ba08-e456-76e1-e5b60e30d57a.png)
ヒットさせる条件としては、パスでもHTTPヘッダの中身でもなんでも構いません。

アクションで認証を選択して、
![リスナールール2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117386/455d2487-2969-cdea-36ff-8b8c5a85a984.png)

認証で Amazon Cognito(ユーザープールIDとクライアントID)を選択します。スコープに openidとaws.cognito.siginin.user.adminを指定します。アプリクライアントのスコープの設定と合わせる必要があります。
![リスナールール3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117386/00c3dfca-dd9f-b28f-c4fc-37144db77a3e.png)
それからCognito認証がパスしたあとの転送先(ターゲットグループ)を指定します。
これでALBにリクエストが来ると、条件にヒットしたときに Cognito 認証を通ることになります。

# ポイント
- ユーザ情報<br>
外部Idpでの認証が成功すると、Cognitoのユーザープール内にユーザ情報が保存されます。保存された情報は、Cognito→ユーザプール→全般設定→ユーザとグループの設定から参照できます。万が一ユーザ情報がおかしくなってしまった場合は、ユーザ情報を無効化してから削除すると解決するケースがあります。

- タイムアウト制御について<br>
外部Idp側でユーザ名とパスワードを入力するのですが、そこでしばらく放置(10分程度)しているとCognitoの呼び出しがタイムアウトします。Cognito側でのタイムアウト制御ができないため、ここは泣く泣く運用で回避しました。

- サービスクォータ<br>
秒間で数千くらいのリクエストを想定していたため、サービスクォータの上限緩和を申請したところあえなく却下。AWSのサポート担当の方曰く、トークン自体もある一定期間は保持されること、また数千万のユーザを抱えるアカウントでも1秒あたり1000リクエスト以下で運用可能であるから、という理由でした。


Cognitoと外部Idpとの連携については、以上です。
これ以外にも、認証をパスしたあとで、認証付きURLを用いてS3へのアクセス制御をしたのですが、それについてはまた別途。
Pwnable.kr-[fd] writeup

>Mommy! what is a file descriptor in Linux?
>
>* try to play the wargame your self but if you are ABSOLUTE beginner, >follow this tutorial link:
>https://youtu.be/971eZhMHQQw
>
>ssh fd@pwnable.kr -p2222 (pw:guest)

```
fd@pwnable:~$ ls -l
total 16
-r-sr-x--- 1 fd_pwn fd   7322 Jun 11  2014 fd
-rw-r--r-- 1 root   root  418 Jun 11  2014 fd.c
-r--r----- 1 fd_pwn root   50 Jun 11  2014 flag
fd@pwnable:~$ cat fd.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[32];
int main(int argc, char* argv[], char* envp[]){
	if(argc<2){
		printf("pass argv[1] a number\n");
		return 0;
	}
	int fd = atoi( argv[1] ) - 0x1234;
	int len = 0;
	len = read(fd, buf, 32);
	if(!strcmp("LETMEWIN\n", buf)){
		printf("good job :)\n");
		system("/bin/cat flag");
		exit(0);
	}
	printf("learn about Linux file IO\n");
	return 0;

}


```

ファイルディスクリプタ(fd)に関する問題です。
fdは接続したファイルや入出力に関する情報が入った変数で、0が標準入力、1が標準出力を指します。
なので、今回はargv[1]に 1+0x1234 を入力してその後LETMEWIN\nを入力すれば良いです。

```
fd@pwnable:~$ python3 -c "print(1+0x1234)" | xargs ./fd
LETMEWIN
good job :)
mommy! I think I know what a file descriptor is!!
```
Rubyで素数を判定するコードを書く

##はじめに
この記事は「たのしいRuby 第6版」の練習問題の一つを解いたものです。解答はすでにweb上に存在しますが、自分が何を考えてコードを書いたかを含めて解説していきます。

##問題
整数numが素数であるかどうかを調べるメソッドprime?(num)を定義してください。なお、素数とは「それ自身と１以外で割ることのできない数」です。

##コード

```ruby
def prime?(num)
  return false if num == 1

  ary = (2..Integer.sqrt(num)).to_a
  ary.each.none? {|i| num % i == 0}
end

num = gets.to_i

if prime?(num)
  puts "#{num}は素数です"
else
  puts "#{num}は素数ではありません"
end

```

##考え方
例えばnumと言う数があるとします。このnumと言う数が1とnum以外の約数を持たなければ素数といえます。ならば、2からnumの平方根までの数でnumを割ってやり、余りが0になる（割り切れる）ことがあればnumは素数ではないといえます。

numの平方根はRubyでは

```ruby
Integer.sqrt(num)
```

と記述します。これを踏まえて
"2からnumの平方根までの数でnumを割ってやり、余りが0になる（割り切れる）ことがあればnumは素数ではない"を表現することを考えます。素数の場合はtrueをかえし、そうでない場合は全てfalseを返すこととすると、

コメントより
> 割り切るものが一つもなければ `true`，そうでなければ `false`

と言う処理を行わせれば良さそうです。このような時、 `none?`メソッドが活用できそうです。このメソッドは、対象とするオブジェクトのすべての要素が偽であれば真を返し、そうでなければ偽を返すものです。`none?`を用いて以上のことを表現すると

```ruby
  ary = (2..Integer.sqrt(num)).to_a #2からnumの平方根までの配列を用意
  ary.each.none? {|i| num % i == 0} #用意した配列の数全てがnumを割り切れなければtrue
```
となります。

他に素数でない数字としては"1"が挙げられます。"1"でもなく、上記の処理にも引っかからないnumが、素数だといえます。

また、素数でないことが分かった段階で処理は終えるべきです。なので、returnを用いてメソッドを終了させます。


```ruby
def prime?(num)
  return false if num == 1

  ary = (2..Integer.sqrt(num)).to_a
  ary.each.none? {|i| num % i == 0}
end
```

##参考にしたもの
[
Integer.sqrt (Ruby 3.0.0 リファレンスマニュアル)](https://docs.ruby-lang.org/ja/latest/method/Integer/s/sqrt.html)

[Enumerable#none? (Ruby 3.0.0 リファレンスマニュアル)]
(https://docs.ruby-lang.org/ja/3.0.0/method/Enumerable/i/none=3f.html)


[「たのしいRuby 第6版」練習問題の解答例](https://tanoshiiruby.github.io/6/answer.html)

いただいたコメントをもとに大幅に変更しました。(2021/4/2)
【2021年版】RubyでGoogle Search Console APIを利用する

RubyでGoogle Search Console APIを利用したいが、ライブラリのアップデートが激しく、過去の情報しか残っていないため使い物にならなかったのでだいぶハマった。とりあえず2021年3月31日時点で動いたので、メモ。

過去のものをみる感じ、google-api-clientのバージョンアップでライブラリそのものが使えなくなっていたりするので、公式のGithubレポジトリをみながら頑張った。

https://github.com/googleapis/google-api-ruby-client/blob/master/generated/google-apis-searchconsole_v1/OVERVIEW.md

## Gemfileのインストール

Gemfile

```Gemfile
gem 'google-apis-searchconsole_v1', '~> 0.1'
```

models/search_console.rb

```
## models/search_console.rb
require "google/apis/searchconsole_v1"

class SearchConsole
  def initialize
    authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
      json_key_io: File.open(ENV["SERVICE_ACCOUNT_CREDENTIAL_FILE_PATH"]),
      scope: %w(
        https://www.googleapis.com/auth/webmasters
      )
    )
    @client = Google::Apis::SearchconsoleV1::SearchConsoleService.new
    @client.authorization = authorizer
  end
end
```

GCPでSearch Consoleのプロジェクトの有効化、サービスアカウントでのJSON KEYのダウンロードなど必要なので、参考資料をみてください！

## 参考

https://qiita.com/ikamirin/items/9ae2bf2e914252d29450

https://github.com/googleapis/google-api-ruby-client

https://developers.google.com/webmaster-tools/search-console-api-original/v3/searchanalytics/query?hl=ja

http://bekkou68.hatenablog.com/entry/2014/08/20/222032

https://www.rubydoc.info/gems/google-apis-searchconsole_v1/0.2.0

https://github.com/googleapis/google-api-ruby-client/blob/master/generated/google-apis-searchconsole_v1/OVERVIEW.md

https://github.com/googleapis/google-api-ruby-client/blob/master/docs/auth-guide.md

https://teratail.com/questions/26046

https://qiita.com/ts-3156/items/1f84d06e50795a9df4c8
Pythonで関数の実行時間を測定する

デコレータを使って関数の実行時間を測定する方法です。このデコレータをコピペすれば、好きな関数の実行時間を手軽に測ることができるようになります。

まず以下のデコレータをコピペします。

```python
import time

def exec_time(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        res = func(*args, **kwargs)
        end = time.time()
        print(
            "execution time of {func_name} (sec): {second}"
            .format(second=end-start, func_name=func.__name__))
        return res
    return wrapper
```

関数にデコレータをつけて実行します。手軽につけたり外したりできるのがデコレータの魅力ですね。

```python

@exec_time
def functionA():
    for i in range(100 * 100):
        a = 1 + 1

@exec_time
def functionB():
    for i in range(100 * 100 * 100):
        a = 1 + 1

functionA()
functionB()
```

実行結果は以下のようになります。

```
execution time of functionA (sec): 0.003993988037109375
execution time of functionB (sec): 0.23200011253356934
```

お役に立てば幸いです。
Ubuntu 20.10 に Nginx をインストール方法

Ubuntu に apt で Nginx をインストールするには、2つの方法があります。
>1) Ubuntu が配布しているものを使う方法
>2) Nginx が配布しているものを使う方法
>両者の違いは、設定ファイル /etc/nginx に顕著に現れます。

1) Ubuntu が配布しているものを使う方法

```bash
sudo apt install nginx
```

インストールした時の状況

バージョン

```text
$ nginx -V
nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
```

設定ファイル

```text
$ ls /etc/nginx
conf.d          koi-win            nginx.conf       sites-enabled
fastcgi.conf    mime.types         proxy_params     snippets
fastcgi_params  modules-available  scgi_params      uwsgi_params
koi-utf         modules-enabled    sites-available  win-utf
```

Nginx の削除

```bash
sudo apt remove nginx --purge
sudo apt autoremove
dpkg -l | grep ^rc | awk '{print $2}' | for list in `xargs`;do sudo apt-get purge -y "$list";done
```

/etc/nginx が空であることを確認します。

2) Nginx が配布しているものを使う方法
こちらの通りです。
[Ubuntu](https://nginx.org/en/linux_packages.html#Ubuntu)

依存パッケージのインストール

```bash
sudo apt install curl gnupg2 ca-certificates lsb-release
```

インストールの準備

```bash
echo "deb http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \
    | sudo tee /etc/apt/sources.list.d/nginx.list
#
echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \
    | sudo tee /etc/apt/preferences.d/99nginx
#
curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key
#
sudo mv /tmp/nginx_signing.key /etc/apt/trusted.gpg.d/nginx_signing.asc
```

インストール

```bash
sudo apt update
sudo apt install nginx
```

インストールした時の状況

バージョン

```text
$ nginx -V
nginx version: nginx/1.18.0
built by gcc 10.2.0 (Ubuntu 10.2.0-13ubuntu1)
built with OpenSSL 1.1.1f  31 Mar 2020
TLS SNI support enabled
```

設定ファイル

```text
$ ls /etc/nginx
conf.d          koi-utf  mime.types  nginx.conf   uwsgi_params
fastcgi_params  koi-win  modules     scgi_params  win-utf
```
【エラー備忘録】コントローラーを呼び出すと、Target class [TaskController] does not exist.

##状況

routes/api.php 内で TaskController を呼び出すと、
Target class [TaskController] does not exist.
と表示されてしまった。

##原因
TaskControllerが読み込めていないようなので、関連するファイルを探る。

TaskControllerを呼び出しているコードはこちら。

```php:api.php
Route::get('/tasks', 'TaskController@index');
```

##解決策
コントローラー名の前に、完全な名前空間を追加してみる。

```php:api.php
Route::get('/tasks', 'App\Http\Controllers\TaskController@index');
```

これで画面表示ができた。
連想配列(dictionary)でインスタンス登録型動的配列

#やりたかったこと
長さが不定の配列でインスタンス登録をしたかった。

##今までやってたこと
型1,型2,型3.............型999と最大越えないように先に決め打ちで用意して
必要なところまで登録してた。
リフレクションで変数名を添え字で自動生成しようとしたことまである。

##解決策
Dictionary"<"int,custom class">"();　//"は文字表示用

dictionaryに放り込んで
あとは好きにArrayに放り込むなり配列に放り込むなり。
なぜこんな簡単な事に気付かなかったのか…
正規表現を使った文字チェック

# 文字チェック
アプリ開発をする上で文字チェックによるセキュリティ管理はとても重要です。
アカウント作成・ログイン機能がついてる場合、メアドやパスワードを入力してもらうと思いますが、その際、パスワードに同じ文字が並んでいたり、メアドの形式が違うのに処理が完了してしまうと、セキュリティ的に良くないです。

## メソッド
文字に対する処理なので、Stringをextensionして以下のメソッドを記述すると便利ですよ〜

・同じ文字が3字以上並んでるか判定。
　パスワードに対してのチェックですね。3字以上並んでたらアウト。

```swift
    // 同じ字が３つ以上並んでいるか判定
    func isContainContinuousSameChar(count: Int = 3) -> Bool {
        guard count > 1 else { return true }
        let pattern = "(.)\\1{\(count-1)}"
        guard let regex = try? NSRegularExpression(pattern: pattern) else { return false }
        let matches = regex.matches(in: self, range: NSRange(location: 0, length: self.count))
        return matches.count > 0
    }
```
・使い方

```swift
     if password.isContainContinuousSameChar(count: 3) {
         // アラートなりHUD
         return
     }
```

・半角英数字判定
　全角とか含めてほしくないとこで使える。

```swift
    // 半角英数字判定
    func isAlphanumeric() -> Bool {
        let pattern =  "[^A-Za-z0-9]+"
        let regex = try! NSRegularExpression(pattern: pattern, options: [])
        let result = regex.matches(in: self, options: [], range: _NSRange(0..<self.count))
        return result.count > 0
    }
```
・使い方

```swift
    if password.isAlphanumeric() {
        // アラートなりHUD
        return
    }
```

・メールの形式判定

```swift
    // メールの形式判定
    func checkEmail() -> Bool {
        let pattern =  "[A-Z0-9a-z._+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"
        let regex = try! NSRegularExpression(pattern: pattern, options: [])
        let result = regex.matches(in: self, options: [], range: _NSRange(0.. <self.count))
        return result.count > 0
    }
```
・使い方

```swift
    if !address.checkEmail() {
        // アラートなりHUD
        return
    }
```

・特殊文字判定
アカウント作成において特殊文字は使ってほしくないです。特殊文字は文字化けの原因になったりするので防ぎたいところです。

```swift
    // 特殊文字判定
    func checkSpecialWord() -> Bool {
        let pattern =  "[!@#%$&*！＠＃％＄＆＊]+"
        let regex = try! NSRegularExpression(pattern: pattern, options: [])
        let result = regex.numberOfMatches(in: self, options: [], range: _NSRange(0..<self.count))
        return result > 0
    }
```

・使い方

```swift
    if displayName.checkSpecialWord() {
       // アラートなりHUD
       return
    }
```

## ハマりどころ
最初はNSPredicateの方が簡単に記述できそうだったのでそっちでやろうとしましたが、半角全角の区別がつかなくなっちゃうみたいなので、少し大変ですがNSRegularExpressionを使ってやりました。
Amazon Neptune とは

## 勉強前イメージ

Neptune の意味調べてたら海王星とかギリシャ神話の海の神とか出てきたけど、結局よくわからない

## 調査

### Amazon Neptune とは

グラフ型のデータベースサービスになります。
RDBなどでは図がわからりずらくなってしまう際に使用されます。
`Gremlin` と `SPARQL` というオープンソースのグラフAPIに対応していて、
複数のグラフ記法に対応しているため、新たに記法を学び直すことなくグラフ型のデータベースを使用することが出来ます。

### グラフ型データベースとは？

グラフ構造を備えたデータベースのことで
データ構造がネットワーク状になっている際に格納や検索面で有用になります。

基本要素としては以下になります。

- ノード : 頂点のこと。
    - 下記の図でいうと人にあたる
- エッジ : 辺で、ノード間の関係性を表す。
- プロパティ : 属性のことで、ノードとエッジにおける属性情報。
    - 下記の図でいうと `name:Aさん` の箇所。
    - key／value形式で保持される。


![2021-03-31 グラフ型DBUntitled Diagram.drawio - diagrams.net - Google Chrome 2021-03-31 13.32.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/39f9d27d-e610-8c5e-6e25-317b992c739d.png)


### 特徴

- フルマネージドサービス

インフラやサーバの管理などすべてAWS側に任せて、DBを使用することが出来ます。
運用管理を行わなくて良いので、今のタスクに集中することが出来ます。

- パフォーマンスとスケーラビリティ

3つのAZで最大15のリードレプリカをサポートしています。
変更の必要に応じてインスタンスタイプを変更し、簡単にスケールアップ・スケールダウンを行うことが出来ます。

- 高可用性と耐久性

3つのAZにデータのコピーが6つ作成されます。
またデータをs3にバックアップしておりストレージ障害からデータを守ります。
またインスタンスのフェイルオーバーは30秒以内で完了します

### 設定画面の確認

`Neptune > データベース > データベースの作成` から作成することが出来ます。
RDSの設定画面と似たような感じがします。

![2021-03-31 設定 Neptune · AWS Console - Google Chrome 2021-03-31 13.22.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/04a03d57-387d-109b-a4c8-2460ba8f8bbc.png)


## 勉強後イメージ

そもそもグラフ型のデータベースがあるって知らなかった
グラフにするとちょっと重そうだね。
簡単にスケールアップできるのはいいかも？

## 参考

- [グラフデータベースとは何か　～ネットワーク状のデータ構造から瞬時に情報を検索するDBを解説](https://www.imagazine.co.jp/12805-2/)
- [Amazon Neptune](https://aws.amazon.com/jp/neptune/)
- [Amazon Neptune とは](https://www.acrovision.jp/service/aws/?p=1200)
Chrome に 青い線 (ストライプ) がかかって読めない問題の一時的な解消方法

## 何が問題か
これQiitaのTopなんですが、Chrome が下記のようになって内容が読めない！
SafariやFireboxは問題ないのでChrome固有の問題のよう。

![Screen Shot 2021-03-31 at 13.02.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51328/9d682f7d-4845-901e-5a83-9cd2139e639d.png)

## 解決策

**1. Chromeの設定から、ハードウェアアクセラレータの使用をOFFにする**

![Screen_Shot_2021-03-31_at_13_03_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51328/ca8aac00-fe91-2446-04dc-ad5a72a3a8e6.png)

**2. Chromeを再起動する**

![Screen_Shot_2021-03-31_at_13_03_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51328/aaef37c5-5f23-bad0-f315-a719bf60faf0.png)

これだけで私の環境は解消しました!

## 原因と考察
事象は解消しましたが、ハードウェアアクセラレータを使わないため描画速度が遅くなることが考えられます。私は特に困ってないので当面はこの設定で利用する予定です。

気になる原因ですが、[Chromeのヘルプページでいろいろと議論がされています](https://support.google.com/chrome/thread/39447594?hl=en)が、サブディスプレイを使用していると発生する気がします。

当方の環境は、Macbook Pro 16に、下記の社外品ケーブル（Displayport ⇔ Type C）をつないで4Kディスプレイで拡張して使っています。

https://www.amazon.co.jp/gp/product/B08183F8PH/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&psc=1

ケーブルとの互換性が良くないのかもしれません。

## 参考
https://support.google.com/chrome/thread/39447594?hl=en
テーブル結合について復習(inner joinとouter join)



# テーブル結合(inner joinとouter join)

あらためて自分用にDBの結合について解説。
よく使うのは LEFT JOIN ですかね。
等価結合とINNER JOIN（内部結合）、
LEFT JOIN, RIGHT JOIN(外部結合)について見ていきましょう。


### テーブルの内容

dogsテーブル

|  id  |  name  | owner_id  |
| ---- | ---- | ---- |
|  1  |  ハチ  |  1  |
|  2  |  ポチ  |  2  |
|  3  |  タマ  |  1  |
|  4  |  ノラ  |  4  |

ownersテーブル

|  id  |  name  |
| ---- | ---- |
|  1  |  太郎  |
|  2  |  次郎  |
|  3  |  三郎  |
|  4  |  四郎  |

太郎は２匹の犬（ハチとタマ）を飼っていて、三郎は犬を飼っていません。

### 内部結合と外部結合

２つのテーブルを結合する方法として、大きく内部結合と外部結合というものが存在します。

#### 内部結合と等価結合

内部結合は、それぞれのテーブルの指定したカラムの値が一致するものだけを結合します。

**内部結合**

```sql
// sql文
SELECT * FROM dogs
INNER JOIN owners
ON dogs.owner_id = owners.id;
```

結果
内部結合結果
![innerjoin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264884/1be924a9-9efa-182f-f01e-0a5645a1a961.png)


三郎がいませんね。両方のテーブルに合致するデータのみ出力されます。

**等価結合**

```sql
// sql文
SELECT * FROM
dogs,owners 
WHERE dogs.owner_id = owners.id;
```

結果
等価結合結果
![quivalentjoin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264884/0fcd6562-073b-ee01-556f-2ee82e1d9411.png)


**内部結合の場合、ベースとなるテーブルから条件にマッチするレコードがないものは削除** されます。
等価結合は、内部結合と同じです（厳密には違いますが）。


---

#### 外部結合

外部結合は、内部結合のようにそれぞれのテーブルの指定したカラムの値が一致するものを結合するのに加え、どちらかのテーブルにしか存在しないものに関しても取得します。

**外部結合 LEFT JOIN**

```sql
// sql文
SELECT * FROM
dogs LEFT JOIN owners 
ON dogs.owner_id = owners.id;
```

結果
等価結合結果
![leftjoin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264884/b8877f27-74a6-501a-19ab-28f4a4051946.png)


構文の左側にある「dogsテーブル」を基準にしています。
dogsテーブルには「空き」がないのでわかりにくいですが、次のRIGHT JOINを見てください。

**外部結合 RIGHT JOIN**

```sql
// sql文
SELECT * FROM
dogs RIGHT JOIN owners 
ON dogs.owner_id = owners.id;
```

結果
等価結合結果
![rightjoin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264884/449e9cd5-2b21-d5a7-df7d-4f930dacc69e.png)


ownersテーブルを基準に出力されているのがわかりますでしょうか？
実際はだいたい基準になるテーブルを左側にしてLEFT JOINするものと思いますが、どちらを使っても同じで、「どちらのテーブルを基準にデータを取得したいか？」で使い分けます。

---

### まとめ

今まで雰囲気でやっていたことは否めない。
ORMさまさまです・・・
git command


git init
---
git init

git initはカレントディレクトリに空のリポジトリを作成します。

git add
---
git add ファイル名

git add ディレクトリ名

git add .

git addは変更をステージにadd（追加）します。

ワークツリー　　→　　ステージ

git commit
---
git commit

git commit -m "メッセージ"　　　　　　　　　

git commit -v　　　　　　　　　　　　　　　　　　　　（変更点がエディタに表示される）

git commitは変更をcommit（記録）します。

ステージ　　→　　ローカルリポジトリ

git status
---
git status

git statusは変更の状態を確認します。

（ワークツリー　　ステージ　　ローカルリポジトリ）のどこにいるか

git diff
---
ワークツリー　〜　ステージの差分
git diff

git diff ファイル名

ステージ　〜　ローカルリポジトリの差分
git diff --staged

git diffは変更のdiff（差分）を確認します。

※diff　=　difference

git log
---
git log

git log --oneline　　　　　　　　　　　　　　　　　　　　 （最新の一行表示）

git log -n コミット数　　　　　　　　　　　　　　　　　　（最新のコミット数行表示）

git logはcommitの履歴を確認します。

git push
---
git push リモート名 ブランチ名

例：git push origin main

git pushはローカルリポジトリの内容をリモートリポジトリに反映させます。

ローカルリポジトリ　→　リモートリポジトリ

git fetch
---
git fetch リモート名/ブランチ名

例：git fetch origin/main

git fetchは、指定したリモートのブランチをローカルのブランチに取り込みます。

git fetch…リモートのmainブランチ　→　ローカルのorigin/mainブランチ

git merge
---
git merge ブランチ名

git mergeは、カレントブランチに指定したローカルのブランチを取り込みます。

例：git checkout main　→　git merge origin/main

git merge…ローカルのorigin/mainブランチ　→　ローカルのmainブランチ

git pull
---
git pull リモート名 ブランチ名

例：git pull origin main

git pullはローカルのカレントリポジトリに、リモートリポジトリの変更を取り込みます。

リモートのmainブランチ　→　ローカルのorigin/mainブランチ　→　ローカルのmainブランチ

git pull = git fetch + git merge

git branch
---
ブランチの表示
git branch　　　　（ローカル）

git branch -a　　　（ローカル + リモート）

ブランチの作成
git branch ブランチ名

git branchはブランチの確認・作成をします。

git checkout
---
git checkout 既存ブランチ　　　　（指定したブランチに移動）

git checkout -b 新ブランチ名　　　（指定したブランチを作成し、そのブランチに移動）

git checkoutはブランチを切り替えます。

git reset HEAD
---
git reset HEAD .

git reset HEAD　ファイル名

git reset HEAD　ディレクトリ名

git reset HEADはステージした変更を取り消します。
css OMG

footer固定したい
positionをabsoluteや、width:100%で試した
https://techacademy.jp/magazine/19410

cssのボーダー折りたい
https://stackoverflow.com/questions/7059597/slanted-corner-on-css-box
https://stackoverflow.com/questions/7324722/cut-corners-using-css
https://www.w3schools.com/cssref/css3_pr_border-top-right-radius.asp
https://www.w3schools.com/cssref/tryit.asp?filename=trycss3_border-top-right-radius
https://stackoverflow.com/questions/31785198/css3-diagonal-border-line
Google Earth Engineでスエズ運河座礁

#概要

Google Earth Engineで、タンカーを探してみた。

#写真

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/74fb4b76-e0ff-e539-9a77-82d30fa948b4.jpeg)


#サンプルコード

```
var mtSM = ee.Geometry.Point(32.5803558145989, 30.01814881097645);
var image = ee.ImageCollection('COPERNICUS/S2').filterBounds(mtSM.buffer(10000)).filterDate('2021-03-21', '2021-03-29').first();
Map.addLayer(image, {
  bands: ['B12', 'B8', 'B5'], 
  max: 4400
}, 'mtsm');
Map.centerObject(mtSM, 14);

```


以上。
【Swift】TableViewまとめ

#はじめに
基本的なTableViewの扱い方を練習していく中で学んだことをまとめました。
自分のQiitaの記事も貼っていきます。

#GitHub
https://github.com/0429oonishi/TableViews

#学んだこと
###CustomCells
https://qiita.com/REON/items/6388b6a522b9d7fc949c

###CollectionViewInTableView
https://qiita.com/REON/items/beb1e94fc0a5c9e25cce

###SearchableTableView
https://qiita.com/REON/items/cbbacec4f318c0435d3f

###MyTableViewController
https://qiita.com/REON/items/de7fd985c5e0f6a0bb73







#おわりに
随時更新予定
Rails 5.0 から 5.1 に｜やり方

最近日本からオーストラリアに帰国しました！新しい会社でまたRails5.1に更新しました。
今回成功しましたが、何で日本の会社でやった時にできなかったとか色々分かってきました！
#rspec使っている？
正直に言うと、日本で働いてたの会社で「rspec」のテストが足りませんでした、手動でテストだけでRails更新するのはとても難しいです。自動テストがシステムの少なくとも80％をカバーしていない場合は、問題が起こりやすいと思います、ご注意ください！（システムがrspecを使ってない場合はほぼ無理です、rspec使ってください。）
##更新の前に
今のプロジェクトはバーション5.0を使っているの確認。そして、rpsec が80％以上システムテストしている状態。

今の使っている`gem`が更新の後でまだ使えるかどうかのチェック、
`next_rails` の `gem` を使って、5.1.7 までにチェックができます。
ターミナルで `gem install next_rails` を使いましょう。
バーション5.1.7 に更新したいから、`bundle_report compatibility --rails-version=5.1.7` で使っている`gem`はまだ使えるかどうか`next_rails`が教えてくられます。
エラーとか合ったら、エラー起こっているの`gem`を使えないって言うことになってしまったので、使えなくなった`gem`は使わないように、プロジェクトを変更しなきゃあかん。
問題ない場合は、進みましょう。

#Gemfile
`Gemfile`の中に2つのライン更新しましょう。
`gem "rails", "5.0.x.x"` -> `gem "rails", "5.1.7"`
`gem "activejob", "5.0.x.x"` -> `gem "activejob", "5.1.7"`
そしてターミナルに `bundle exec rails app:update` でいけます！
これはちょっと時間がかかりますが、変わったのファイル全部ご確認してください。
自動で消されてしまうファイルとコードたまにあるので注意ください。
特に
`config/environments/` の中
`bundle` と `secrets.yml` が消されてしまうかも、これは自分のプロジェクト元々に戻そう！
など、、、
簡単？
おめでとう、もう5.1.7に更新できました！！！
けど、、エラーが、、
#たくさんエラーが出ました！？！
5.1からたくさん使えなくなること、変わったこともあるので、`rspec` 使ったら多分たくさんエラーと注意も出たはずです。
`before_action` と `after_save` などのフローが変わったし、`_changed?` なども使えなくなるやし、これから大変そうですが、ちょっとずっつでコードの更新も行きましょう。

####`after_create`+`after_update`+`after_なんちゃら` の中に

|修正前|修正後|
|---|---|
|attribute_changed?|saved_change_to_attribute?|
|attribute_change|saved_change_to_attribute|
|attribute_was|attribute_before_last_save|
|changes|saved_changes|
|changed?|saved_changes?|
|changed|saved_changes.keys|
|changed_attributes|saved_changes.transform_values(&:first)|

####`before_create`+`before_save`+`before_なんちゃら` の中に

|修正前|修正後|
|---|---|
|attribute_changed?|will_save_change_to_attribute?|
|attribute_change|attribute_change_to_be_saved|
|attribute_was|attribute_in_database|
|changes|changes_to_save|
|changed?|has_changes_to_save?|
|changed|changed_attribute_names_to_save|
|changed_attributes|attributes_in_database|

`Hash`を使っている時に`.uniq`が使えなくなったので`.uniq` -> `.distinct` に変更も必要です、`Array`の時にしないでね！

`Hash`に`.compact`も使えなくなった、変わりに`.delete_if { |_k, v| v.blank? }`使いましょう。


`previous_changes` は使えなくなったので、合ったら違うロジックでコードやり直ししかないです。

#テスト、テスト、テスト、
全部の先に言った更新だけで、エラーはもう消えたはずですが、`rspec` で自動テスト数回使って、エラーないを確かめて見てください。
`docker-compose run web bundle exec rspec`
エラー合ったら、`spec` の1個ずっつテストして直しましょう！
頑張ってね！
なんか質問合ったら、是非聞いてください。
備忘録 - IF構文 【VBA】

##基本構文

条件に合致する際の処理のみ書く場合

```vb
If 条件 Then
　条件に合致する場合の処理
End If
```
条件に合致する場合としない場合を書く場合

```vb
If 条件 Then
　条件に合致する場合の処理
Else
　条件に合致しない場合の処理
End 
```
複数の条件を書く場合

```vb
If 条件1 Then
　条件1に合致する場合の処理
Elseif 条件2 Then
　条件2に合致する場合の処理
Else
　どの条件にも合致しない場合の処理
End 
```

##End Ifの省略
```vb
'条件分けがない場合、End Ifを省略し、1行で書くこともできる
If 条件 Then 条件が合致する場合の処理
```
## GoToステートメント
条件に合致した場合、ラベルまで飛んで処理を行う。条件に合致しなかった場合は、ラベルまで飛んで処理を行う。主にエラー時の動作などを指定。

```vb
Sub プロシージャ名
If 条件 Then GoTo ラベル
　条件に合致した場合の処理
Exit Sub ' 条件に合致した場合はここで処理が終わる
　
ラベル:
 条件に合致しなかった場合の処理
End Sub
```

具体例

```vb
Sub myVBA()

 Dim myRange As Range
 Set myRange = Range("B3")
    
 If VBA.IsError(myRange.Value) Then GoTo Getout
  Range("C3").Value = myRange.Value
 Exit Sub

 Getout:
  Debug.Print "myRangeにエラーがあります"
End Sub
画像処理入門（OpenCV）

#はじめに
画像処理について学んだ際に、フィルタ処理等はまとめられていますが、変換等についてはまとめられている記事が少ないと感じたため、こちらの記事にまとめさせていただきました。
筆者も勉強中ですので間違い等ありましたら優しくご指摘いただけるとありがたいです。

#環境
OS：Ubuntu 20.04
プログラミング言語：C++
画像処理ライブラリ：OpenCV 4.2
カメラ : [ELECOM UCAM-C0220FBNWH](https://www.elecom.co.jp/products/UCAM-C0220FBNWH.html)

#目次
１．[OpenCVインストール]()
２．[ピンホールカメラモデル]()
３．[内部パラメータ]()
４．[外部パラメータ]()
５．[歪みパラメータ]()
６．[透視投影変換]()
７．[ホモグラフィ変換]()
８．[画像の合成]()
Visual Studio 2019でGitFlowを始める方法


何度やってもすぐ忘れるのでここに書き残そうと思う。
始める方法とは書いたが、何ということはない。
Visual Studio 2019には<b>最初から拡張機能でGitFlowが始められるようになっている</b>のだ。
そんなにやることも多くないのでさらっと書いていきたいと思う。

***

>GitFlowのインストール

では実際に拡張機能からインストールしていこう。

まず、メニューバーから『拡張機能(X)』のタブを選択。
開いたタブ内から『拡張機能の管理(M)』を選択。
![20210331.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259240/a056e15d-90d0-39d4-b9d8-8559d5d1f944.png)



押したらウィンドウが開くので『GitFlow』で検索。
<b>※間に空白を入れると表示されないので注意。</b>
検索したら出てくる『GitFlow for Visual Studio 2019』をインストールする。![202103312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259240/020ce472-fc7d-1370-01b6-a8d7e5159064.png)

言ってしまえばこれだけである。こんなこと忘れるな、と過去の自分に言いたい。

***

>チームエクスプローラーの表示

ちなみに始め方とはちょっと違うのだが、メニューバーの『表示(V)』から『チームエクスプローラー(M)』を一回押して表示しておくと便利になる。
![202103313.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259240/3b884ca8-3e63-a248-0b0e-1f303001a61a.png)

こんな感じで表示される。
![202103314.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1259240/1a554723-53e4-80a8-f110-3cb49f3323b8.png)

今回は新規のソリューションでスクリーンショットを撮ったので何も表示されていないが、本来はここでFeature、Release、Hotfixなどの高頻度で使用するブランチがすぐに作れるようになる。
作れるだけでなく、ブランチのマージ・削除もパパっとできる。

変更のコミットやリモートブランチとのプル・プッシュも行える。万能か？

***

再三言うが、どうしてこんなにわかりやすいうえに少ない手順を何度も忘れてしまうのか。
自分の脳のキャパの少なさに悲しくなる今日この頃なのであった。
行列の対角化とジョルダン標準形について

以下では簡単のため $3 \times 3$行列のみに限って記述する. $2 \times 2$やそれ以上の行列に関しても基本的に同じである. 

# 対角化
行列 $A$ を対角化することを考える. $A$ の重複のない固有値を $\lambda_1, \lambda_2, \lambda_3$とする.　それぞれの固有ベクトルを $x_1, x_2, x_3$ とすると, 相違なる固有値の持つ固有ベクトルは互いに線型独立であるため, $P = ( x_1\ x_2\ x_3 )$ は正則で逆行列をもつ. ここで

```math
\begin{align*}
    AP &= A( x_1\ x_2\ x_3 ) \\
       &= ( Ax_1\ Ax_2\ Ax_3 ) \\
       &= ( \lambda_1 x_1\ \lambda_2 x_2\ \lambda_3 x_3 ) \\
       &= ( x_1\ x_2\ x_3 )\left(
    \begin{array}{ccc}
      \lambda_1 & 0 & 0 \\
      0 & \lambda_2 & 0 \\
      0 & 0 & \lambda_3
    \end{array}
  \right) \\
       &= P\left(
    \begin{array}{ccc}
      \lambda_1 & 0 & 0 \\
      0 & \lambda_2 & 0 \\
      0 & 0 & \lambda_3
    \end{array}
  \right)
\end{align*}
```

となることがわかる. ここに左から $P^{-1}$ を掛ける. すると

```math
\begin{align*}
    P^{-1}AP &= P^{-1}P\left(
    \begin{array}{ccc}
      \lambda_1 & 0 & 0 \\
      0 & \lambda_2 & 0 \\
      0 & 0 & \lambda_3
    \end{array}
  \right) \\
    &= \left(
    \begin{array}{ccc}
      \lambda_1 & 0 & 0 \\
      0 & \lambda_2 & 0 \\
      0 & 0 & \lambda_3
    \end{array}
  \right)
\end{align*}
```

となりこれで対角行列が得られた. 最初に固有値は重複がないこととしたが, たとえ重複があったとしても互いに線型独立な固有ベクトルが $n$ 本とれれば対角化は可能である.

# ジョルダン標準形
では互いに線形独立な固有ベクトルが $n$ 本取れない場合はどうしたらよいのだろうか？
固有値を $\lambda_1, \lambda_2$ とし( $\lambda_2$ は重複度2),　それぞれの固有ベクトルを $x_1, x_2$ とする. ここで $(A - \lambda_2 E)x_3 = x_2$ を満たし, $x_1, x_2$ と線型独立となるような $x_3$ をとる. すると $Ax_3 = x_2 + \lambda_2 x_3$ となる. $P = ( x_1\ x_2\ x_3 )$ とすると, 

```math
\begin{align*}
    AP &= A( x_1\ x_2\ x_3 ) \\
       &= ( Ax_1\ Ax_2\ Ax_3 ) \\
       &= ( \lambda_1 x_1\ \lambda_2 x_2\ x_2 + \lambda_2 x_3 ) \\
       &= ( x_1\ x_2\ x_3 )\left(
    \begin{array}{ccc}
      \lambda_1 & 0 & 0 \\
      0 & \lambda_2 & 1 \\
      0 & 0 & \lambda_2
    \end{array}
  \right) \\
       &= P\left(
    \begin{array}{ccc}
      \lambda_1 & 0 & 0 \\
      0 & \lambda_2 & 1 \\
      0 & 0 & \lambda_2
    \end{array}
  \right)
\end{align*}
```

となることがわかる. 対角化のときと同様にして,

```math
\begin{align*}
    P^{-1}AP &= \left(
    \begin{array}{ccc}
      \lambda_1 & 0 & 0 \\
      0 & \lambda_2 & 1 \\
      0 & 0 & \lambda_2
    \end{array}
  \right)
\end{align*}
```

となりジョルダン標準形が得られた. 得られる固有値が1つのときも同様にしてジョルダン標準形を得ることができる.
システム運用の監視についての知識

#本記事について
プログラミング初心者がシステム運用の監視に関する知識を学んだので、その備忘録として載せております。

どうかお手柔らかにお願いいたしますm (- -)(_ _)ペコリ

##監視システム
安定を保つことはサービスを運用する上で最も大切なことであり、人力ではミスも増え労力も増す。そこで自動的に運用しているサービスの監視を行い異常が検知された場合は運用担当者に通知するシステムのことを監視システムという。

##サービスが正常に動くことの確認をする監視
「ユーザーへサービスを提供し続ける」とは、正常にサービスへアクセスが可能であり、かつ正常にサービスが利用できることである。

→定期的にチェックし問題があれば報告できるようにする。
→そのためにサービスが正常に利用できるかをチェックするWebシナリオ監視を行う

##Webシナリオ監視
実際に運用しているサービス（Webサイト）にアクセスし、問題なく想定どおりの結果が得られるかを監視する手法。定期的に自動監視。

結合テストを本番環境において適用するイメージ

##インフラ監視
アプリケーションを動かすサーバーなどのシステムを監視すること
システム間の繋がりをうまく行っているかを監視（システムは小さな連携で成立）
運用システムの裏側を監視し続けること

いつサービスが停止ししてもおかしくない状態を迅速に未然に予防するための監視。

##発生した障害の「原因特定」のための監視
障害が発生したポイントだけではなくインフラのつながりも監視することで障害が発生した時も速やかに原因を特定し復旧までの道筋を立てれる。

→トラブル発生は広い視野で、多角的に原因分析を行い解決する。またその際にも新たなトラブルになるかもしれない箇所を見つけることがあるので、監視システムを確立することは重要
ローカルで動くNode.jsとPostgresqlを使ったアプリがHerokuだと動かないときに解決できた方法 


###１．問題

背景：Postgresql + Express + React + Node.jsでCRUD アプリを作成。

症状：ローカルでは動くが、Herokuにデプロイはできるものの、最初に行われるはずの「Postgresqlに入っているデータを読み込んで表示」ができず、固まったまま。

見つかったエラー：code H12, "fetch failed loading", no pg


### ２．原因

Herokuではフロントとポスグレの間はssl接続をしないといけないのに、その設定をしていなかった。

### ３．具体的な解決方法

サーバー側、DATABASE＿URLを設定するところでSSL接続を以下のように設定しました。[イイダリョウさんの投稿](https://www.i-ryo.com/entry/2020/10/27/183001#SSL%E6%8E%A5%E7%B6%9A%E3%82%A8%E3%83%A9%E3%83%BC%E7%99%BA%E7%94%9F)を参考にしました。感謝です。

```javascript:quita.js

const pool = new Pool({
   connectionString : process.env.NODE_ENV === "production" ? proConfig : devConfig,
   
//この下のSSL設定を追加した。

ssl: process.env.NODE_ENV === "production" ? {
       sslmode: 'require',
       rejectUnauthorized: false} : false 
})
// ローカルでも動かそうとするとsslが使えず、サーバーが止まったので
// process.env.NODE_ENV === "production"と条件を付けています。

```


### ４．解決に至るまでの経緯

最初、terminalで　heroku logs　と打ってログを出す。

するとまず目に留まったのがエラーコード。

```
at=error code=H12 desc="Request timeout" method=GET path="/xxx" host=xxxxxx.com request_id=xxxxxxx fwd="xxx.xx.xx.x" dyno=web.1 connect=1ms service=30002ms status=503 bytes=0 protocol=https
```

で、なにしろerrorと書いてあるのでこちらの線で調べましたが、Herokuのポスグレのリージョンがアメリカになってるのは関係ある？！（→なかった）とか、いろいろ想像力を働かせましたが、fetchに時間がかかるというのも、ローカルでサクッとできている限りおかしいと思い、ブラウザーの開発者コンソールを見ると、

```fetch failed loading```とある。

そうか。そもそもfetchできてない？

では、コード自体でデプロイの準備を間違ったかなぁと調べて、まぁpackage.jsonの中、enginesをengineと書いてあったとかミスは見つかりましたがそれを直したところで、やはりロードしれくれない。

基本に戻ろうと、もう一度ログを落ち着いて読むと、 ​

```
no pg_hba.conf entry for host "xxx.xx.xxx.xx", user "xxxxxxx", database "xxxxxxx", SSL off

```
とある。え？no pg??? ポスグレがない？
これだわ、原因は！ということで（これ、見てなかった💦）

```no pg_hba.conf entry for host heroku```

でググりましたところ、stackoverflowで、SSL接続が必要ということが分かり、その設定方法も、コードの中で設定する方法、ターミナル上でconfigを編集する方法、など、複数紹介されていました。


ターミナルで直接できるなら楽だわ、と思ったものの、いやいや安易に決めてはいけないともう一度調べると、上に掲げたイイダリョウさんの詳細な検討を記した投稿が見つかり、具体的な解決方法のところに示したSSL接続設定をコード内で行ってgit push heroku main すると、、、見事解決しました！ありがたや～。

ちなみに、あとで、調べてみると、Herokuの公式サイトにあるHeroku Postgresql ＆SSLというセクションでも、

>Most clients will connect over SSL by default, but on occasion it is necessary to set the sslmode=require parameter on a Postgres connection. Please add this parameter in code rather than editing the config var directly. Please check you are enforcing use of SSL especially if you are using Java or Node.js clients.　（たいていのクライアントではデフォルトでSSL接続をするけれど、ポスグレの接続についてsslmode=requireというパラメータを設定しないといけないこともあります。そのときは、直接 config varを編集するんじゃなくて、コードにこのパラメータを足してください。JavaやNode.jsのクライアントを使っているときはSSLを使うようにしているか確認してください。）

とありました。そのものずばり、しかも、コードで足してよ！とまで書いてました。安易に飛びつかず、もうひとググりしようかというまで成長したのはこれまで痛い目にあったから。まぁ、すなおに自分をほめてやりたいです。

ログを読み、無い知恵を絞り、また、あちこちググりまくって、多くの方々の投稿に助けられたので、今後どなたかの参考になるかもと思いまとめました。
Windows10にSSHしてからPowershellでNASに接続

# つながらないだと？

Windows10にSSHで接続した時、PowershellでNASにアクセスしようとしました。
ところが、簡単にNASに接続できませんでした。

# 接続したい場所

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134703/bd0d09d5-9a9f-0c7b-c9c8-52f1298cafd1.png)

# 試してみた方法

```posh
New-PSDrive -Name Z -PSProvider FileSystem -Root \\192.168.0.100\myNAS
```

```bat
net use \\192.168.0.100\myNAS /user:username password
```

※少し前までpushdで行けたのに、なぜか出来なくなっている！

```posh
pushd \\192.168.0.100\myNAS
```

pushdでいけるのは、すでにcmdkeyで接続しているときらしいです。
しかし、`cmdkey`は通常のssh接続のセッションからは資格情報を保存する権限が無いです。

# 接続できた方法

```posh:main.ps1
    # Make PsDrive

    $Nas = "\\192.168.0.100\myNAS"
    $NasDir = "project001"

    $NasUser = "username"
    $NasPass = "password"
    $SecureString = ConvertTo-SecureString $NasPass -AsPlainText -Force
    $TempCredential = New-Object System.Management.Automation.PsCredential($NasUser, $SecureString)

    $psDriveName = "TestDrive"
    if(Get-PSDrive | Where-Object {$_.Name -eq $psDriveName}){
        # If already exists then temporary delete

        Remove-PSDrive -Name $psDriveName
    }
    $TempDrive = New-PSDrive -Name $psDriveName -PSProvider FileSystem -Root $Nas -Credential $TempCredential

    # Check Behavior

    ls $TempDrive":"$NasDir
    cd $TempDrive":"
    ls

    # Cleanning

    Remove-PSDrive -Name $psDriveName
```

# スクリプトの解説

記事内では`main.ps1`とのファイル名を付けていますが、コマンドラインでそのままコピペしても動くと思います。

## Make PsDrive

`$TempDrive`というドライブ名で一時的にドライブを追加しています。

`$Nas`にはFQDNを指定しています。具体的には`\\192.168.0.100`の部分でIPアドレスを`\myNAS`の部分でホスト名を指定しています。
そして、`$NasDir`が共有フォルダ名です。後は、`$NasUser`が共有フォルダへ接続用ユーザー名、`$NasPass`がそのパスワードです。

## Check Behavior

`ls`コマンドを使って、フォルダ内の一覧が見れるか確認しています。

## Cleanning

`$TempDrive`を割り当て解除します。

# 環境

- Windows 10 20H2 or Later
- Powershell 7 or Later
- NAS Buffalo TS5410D

**Excelsior!**
社会人2年間の集大成！占いサイトを作成した話⑤

[社会人2年間の集大成！占いサイトを作成した話④](https://qiita.com/nacho0707/items/c2db9e5e376fab61f769)のつづきとなります！

# 占い師一覧画面の紹介
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/401d4856-028a-190b-1ad1-4d4e74a6d328.png)

## 機能の紹介
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/9e51e906-65ce-0fe7-c2dc-f72b1e61bceb.png)
画面に遷移すると占い師の一覧が表示されます。
「申し込む」ボタンをクリックすると・・

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/a9218ee2-14a9-057d-d71d-a802b6962fb2.png)
申し込みフォームに遷移します。
「申し込む」ボタンをクリックすると・・
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/d3a2dc57-0d9c-7440-265b-86fc63162c87.png)
「申し込みが完了しました！」というメッセージのモーダルが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700107/7412ed25-a9b9-d2f3-f9e2-8d528b312e1e.png)
何も入力せずに「申し込む」ボタンを押下した場合はエラーにします。

## 実装方法の紹介
このページではJavaScriptやHTMLでは特別な処理はしていないため使用したCSSを紹介します！
### 占い師達のレイアウト
```css
// 占い師の画像の周りを囲む線を設定
.fortune-teller-img {
    border: solid;
    border-color: black;
    margin: 10px 30px 0px 30px;
}
// １行目の占い師を横並びにし中央寄せに設定
.first {
    display: flex;
    justify-content: center;
}
// ２行目の占い師を横並びにし中央寄せに設定
.second {
    display: flex;
    justify-content: center;
}
```
justify-contentプロパティは、フレックスアイテムの主軸方向の揃え位置を指定します。

### 申し込みフォームのレイアウト
```css
// 項目の幅と文字の太さの設定
label {
    width: 25.5%;
    font-weight: 500;
}
// 必須項目のラベルの後ろに*を赤字で表示
.required:after {
    content: " *";
    color: red;
}
// 入力欄毎に周りの余白と区切り線の設定
.form-group {
    padding: 26px 0;
    border-top: 1px solid #e5e5e5;
}
// 入力欄の幅と周りの余白と入力欄の内側の影を設定
input,select {
    width: 74.5%;
    padding: 9px 10px;
    border: 1px solid #d9d9d9;
    box-shadow: inset 0.5px 0.866px 3px 0px rgba(5, 1, 2, 0.25);
}
```
widthを%で指定することで、画面幅が変化しても一定のレイアウトが保てます。
box-shadowを設定することで入力欄が立体的になります。

# まとめ
今回は申し込みフォームをよく見かけるwebページと同じような見た目にすることに苦労しました。見た目は簡単そうでもいざ実現しようとすると知識が足りない点がありました。
また、占い師の先生の名前を決めるのに苦労しました:joy:インターネットで調べると色んな先生の名前があり、占い業界について少し触れることができました！
今回はここまでとなります。次回は最後！！特集ページの紹介を行っていきます:point_up_tone1:

続きはこちら！
[社会人2年間の集大成！占いサイトを作成した話⑥](https://qiita.com/nacho0707/items/cf55c6bcdd72177adade)
2 つのロック概念とそれぞれの関係

# 概要
- 友人とロックについて話すことがあったが、自分自身きちんと理解していなかったため勉強し直した
- MySQL を前提とする
    - 他 RDBMS では実現方法が変わってくるかもしれない
    - 分離レベルはデフォルトの REPEATABLE READ


# TL;DR
- ロックの概念は 2 つあるよ
    1. 共有・占有ロック
        - 排他制御の実現「方法」
        - DB から実現方法は提供される（ SELECT FOR UPDATE、 LOCK IN SHARE MODE ）
    2. 楽観・悲観ロック
        - 排他制御の実現「方式」
        - アプリケーション側の実装が必要

- 楽観ロックを実装するために共有・占有ロックは用いない
- 悲観ロックを実装するために占有ロックは使用する
    - 共有ロックは用いない
- 共有ロックを使用する場面は、「俺がこのレコードを読んでいる間、誰も更新してくれるな」って時
    - 更新を目的とはしていない


# 用語説明
- 共有ロック
    - ロック対象（行や表）に対して、他トランザクションからの READ は許すが WRITE は許さない
        - ここでの READ は共有ロックを指す（ SELECT 文の意ではない）
        - ここでの WRITE は UPDATE/DELETE 文の発行もしくは占有ロックを指す
        - つまり、「ロック対象（行や表）に対して、他トランザクションからの共有ロックは許すが UPDATE 文の発行もしくは占有ロックは許さない」という意味
    - そもそも、他トランザクションからの SELECT 文発行を制御するロックは存在しない

- 占有ロック
    - ロック対象（行や表）に対して、他トランザクションからの READ も WRITE も許さない
        - READ、WRITE の意味は上記と同様
        - つまり、「ロック対象（行や表）に対して、他トランザクションからの共有ロックも UPDATE 文の発行もしくは占有ロックも許さない」という意味

- 楽観ロック
    - 「自分以外誰も更新しないだろ。一応更新前に確認するけど」というロック方式
        - 具体的には、
            1. 更新画面を表示
                - この時に更新対象のバージョン番号や最終更新日付を保持する
            2. 更新内容を入力
            3. 更新
                - この時、[1.] で取得したバージョン番号や最終更新日付が更新直前の DB の値と相違ないことを確認する
                    - 相違がある場合はエラーにする
    - 共有・占有ロックは実行しない

- 悲観ロック
    - 「自分以外が更新されたら困る。誰も変更できないように制御する」というロック方式
        - 具体的には、
            1. 更新画面を表示
                - この時に占有ロックを実行する
            2. 更新内容を入力
            3. 更新
                - 更新後、占有ロックを解放する
        - 上記 [2.] の間に他トランザクションが更新しようとすると、占有ロックの解放待ちになる（即時エラーとはならない）


# 嵌ったところ
- 多くの媒体で「占有ロック中は他トランザクションからロック対象が見えなくなる」と書かれているが、実際にやってみると「SELECT 文発行できるじゃん！」となった
    - 単純な SELECT 文を発行しても待ち状態 or エラーとなると期待してた
        - 単純な SELECT 文発行自体は制御されないんだと理解
    - ただし、占有ロック前の値しか読み取れない
        - 占有ロックしたトランザクションがコミットして初めて、更新された値を参照できる
        - ↑この制御内容を「見えなくなる」と表現した？と理解した

- 元々、楽観・悲観ロックを実現する際にそれぞれ「共有ロックを使うか？占有ロックを使うか？」と選択できると理解していた
    - これが誤りで、共有ロックは楽観・悲観ロックで使うことは無いと理解するのに時間がかかった
    - 共有ロックはファントムリードを防ぐ際に用いられることが多いとのこと


# 参考にさせていただきました
https://qiita.com/daiching/items/835fa37de22b397eece0

https://saekis.hatenablog.com/entry/2019/02/06/191454

https://ja.wikipedia.org/wiki/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%88%86%E9%9B%A2%E3%83%AC%E3%83%99%E3%83%AB

https://qiita.com/momotaro98/items/ad859ec2934ee98540fb

https://dev.mysql.com/doc/refman/5.6/ja/innodb-lock-modes.html
【Java】Selenium＋ChromeDriverで突然「あなたは人間ですか？」と聞かれた時は

# 突然の死
Seleniumで作ったツールで保存したキャプチャ画像みんなCAPTCHA認証(Cloudflare)になってるやろがい！
先週までちゃんと動いてたのに何で急に認証を要求してくんの！？聞いてないわ！
そんな感じで突然それまで動いてたツールが死んでしまったので、その対処法のメモです。

なお、突然の死が発覚したキャプチャ対象はMavenのリポジトリでした。
手動では閲覧のために認証を必要としない普通のサイトです…

動作確認を行ったChrome本体とChromeDriverのバージョンは以下の通りです。

- Google Chrome： 89.0.4389.90(Official Build) (64 bit)
- ChromeDriver - WebDriver for Chrome：89.0.4389.23

JSoupでCAPTCHA認証による突然の死を迎えた場合は、こちらの解決法が使えるかも？
→[【Java】JSoupでCAPTCHA認証を回避する](https://qiita.com/11295/items/adb1101856b012317815)

# ソース
```java
ChromeDriverService service = new ChromeDriverService.Builder()
				.usingDriverExecutable(new File("chromedriver.exeのパス")))
				.usingAnyFreePort()
				.build();
service.start();

ChromeOptions options = new ChromeOptions();
options.addArguments("user-agent=Type user agent here");	// headlessでのCAPTCHA回避に必須
options.addArguments("--disable-blink-features=AutomationControlled");	// headlessじゃなければこれだけでもいけた
options.setHeadless(true);

WebDriver driver = new RemoteWebDriver(service.getUrl(), options);
```

急に自転車やらボートの画像を選択するよう強制されて大変びっくりしました…長女だから我慢できた。
社内ツールだからいいけど、客先に納品してたらまじで困ったことになってたね…

2022/10/11　追記
どうやら知らないうちに表示したページから遷移すると、再びCAPTCHA認証が発生するようになってました…
これはもうどうしていいかわからん。chromedriver.exeのバイナリ書き換えとか考えないといけないかも。
Pythonだとなんかいろいろライブラリも出ているんだけど、Javaは見つからないねえ…
Pythonって結局はPANDAS

最近はPANDASオンリーで使っています。
主な用途は

* CSV読み書き
* EXCEL読み書き
* SQL読み書き
* 簡単な表構成

上記のためPANDASは、いまやEXCELと同等に使いこなしています
ただしPYTHON一択という状況は否めず、他の言語への移植の妨げになります

・java
・C#
・NODE.JS
・GO
・PHP

できれば、PANDAS自体をほかの言語に移植できないものでしょうか？
（仕様そのままだとさらにありがたいです）
wordpress OMG

#### タグが自動作成される

自動整形機能を無効化
https://fukuro-press.com/wp-disable-auto-formatting-in-edit/

上やっても変わらないてかそれ自体できんときわ
カスタムHTML内にHTMLを入れてみよう。つかこっちのほうが推奨？
[>なんかのフォラーム](https://ja.wordpress.org/support/topic/remove_filter%E8%A8%98%E8%BF%B0%E5%BE%8C%E3%82%82a%E3%82%BF%E3%82%B0%E3%81%8C%E8%87%AA%E5%8B%95%E6%8C%BF%E5%85%A5%E3%81%95%E3%82%8C%E3%82%8B%E5%A2%97%E3%81%88%E7%B6%9A%E3%81%91%E3%82%8B/)
[>使い方](https://www.adminweb.jp/wordpress/gutenberg/index22.html)

#### 親のスタイルに移植したスタイルが固定される（固定ページとか）

ローカルと差異がでる場合がある。スタイルで優先度調整とかする
http://creator.aainc.co.jp/archives/4947

#### WP手動更新

https://www.youtube.com/watch?v=hLo_p6kk44k
https://www.webdesignleaves.com/pr/wp/wp_folder_structure.html
https://okuden-labo.com/wp-manual-update
https://wp-staging.com/docs/update-wordpress-manually/
ElementUIでformのsubmitボタンをdisabledにする

# 背景

ElementUIを使ってformを作成しています。

公式のサンプルにある通り、submitボタンを押下した際に、バリデーションを発火させるのは簡単にできます。
https://element.eleme.io/#/en-US/component/form#validation

ただ、今回はformを初期表示した際にsubmitボタンをdisabled状態(押下できない状態)にしたいというものです。

# 結論 validateStateをチェックする

# 解説

#### 1: el-formにrefを設定する
![スクリーンショット 2021-03-18 20.46.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151354/af3d84aa-c4b9-d485-fadb-93c161fd3d92.png)

#### 2: そのrefをからvalidateStateを見て、バリデーションステータスを確認する
サンプルコード

```vue
<template>
  <div id="app">
    <el-form
      :model="ruleForm"
      :rules="rules"
      ref="ruleForm"
      label-width="120px"
      class="demo-ruleForm"
    >
    　<!-- 省略 -->
      <el-form-item>
        <el-button
          :disabled="isInValid"
          type="primary"
          @click="submitForm('ruleForm')"
          >Create</el-button
        >
        <el-button @click="resetForm('ruleForm')">Reset</el-button>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
    data() {
      return {
        // その他省略
        isInValid: false, //これでdisabledかを保持する
    };
  },
  mounted() {
    let isSomeEmpty = false;
    let hasSomeError = false;
    // $refsからruleFormを取得し、fieldsに対してループを回す
    this.$refs.ruleForm.fields.forEach((field) => {
      /* fieldのvalidateを確認する
       * validateState === "error"  : バリデーションエラー
       * validateState === ""       : 未入力
       * validateState === "success": バリデーションクリア
       */
      if (field.validateState === "error") {
        isSomeEmpty = true;
      }
      if (field.validateState === "") {
        hasSomeError = true;
      }
      this.isInValid = isSomeEmpty || hasSomeError;
    });
  },
};
</script>
```

fieldsはel-form-itemの配列になっています。
el-form-itemはpropというプロパティがあって、そのpropの値でどの入力欄か判別できます。
そしてvalidateStateというプロパティがあって、これでバリデーションの状態を判別できます
validateStateは以下の通り3パターンに分かれます

```
validateState:"error"  -> バリデーションエラー
validateState:""       -> 未入力
validateState:"success"-> バリデーションクリア
```

なので、未入力状態のものか、エラー状態のものがあればボタンをdisabledにすればいいというわけですね

※ 注意
サンプルコードでは初期表示のみの対応ですが、入力項目に変更加わった時などにisInValidの調整が入ります

## 感想

これが最適解かどうかわからないので、良い案あればご教示いただきたいです
読んでいただきありがとうございました
【JavaScript】関数の引数が{}なのはオブジェクト

###関数の引数で引数に{}というものがありなんじゃろ？と思った
ので備忘録メモ

[js-primeのオブジェクト](https://jsprimer.net/basic/object/)の[ES2020] Optional chaining演算子（?.） のところ。

```javascript
printWidgetTitle({
    // タイトルが定義されてない空のオブジェクト
});

```
こんな記述があって、引数に{}ってなんだろ？と思ったら見た目通りオブジェクトだったというお話。
###試した感じ
関数 testの処理で、引数をオブジェクトと想定し、そのプロパティ「hoge」をconsole.logしてみて見比べた。
引数の{}を消したら、ちょっとエラーが変わります。

```javascript
function test(argument) {
  console.log(argument.hoge)
}

test({}); // -> undefined になる。
test(); // -> Error: argument is undefined になる。
```

#####前者はオブジェクトはあるけど中身がundefinedだよ！
#####後者はそもそも引数であるオブジェクトがないよ！という感じでしょうか。



###js-primeにもあるOptional chaining演算子（?.） を使った場合

```javascript
function test(argument) {
 console.log(argument?.hoge)
}

test({}); // -> undefined になる。
test(); // -> undefined になる。

```

と、どちらもundefinedとなります。
ドット記法（.）だと例外を発生してしまいますが、この書き方（?.）ならそのプロパティ自体が見つからない場合も、undefinedにしてくれます。
if文を使わずにかけます。


###ついでにNullish coalescing演算子(??) を使った場合
最終的に何も見つからない場合の処理をかけます。

```javascript
function test(argument) {
  console.log(argument?.a ?? "ないです")
}

test({}); // ないです になる
test(); // ないです になる

//ちなみにちゃんとオブジェクト渡すパターン
test(
  {
    a:"ややや",
   	b:"よよよ"
  }
)//やややになる
```