OmniAICreator/Qiita-1.07M huggingface dataset:
P5.js 日本語リファレンス(noiseDetail)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の noiseDetail関数を説明します。

## noiseDetail() 

### 説明文

Perlin ノイズ関数によって生成される特性と詳細レベルを調整します。物理学の高調波と同様に、ノイズは数オクターブにわたって計算されます。オクターブが低いほど出力信号に寄与し、ノイズの全体的な強度が定義されます。一方、オクターブが高いほどノイズシーケンスの細部が細かくなります。

デフォルトでは、ノイズは4オクターブにわたって計算されます。各オクターブは前のオクターブの50％の強度から始まり、前のオクターブの半分に相当します。この減衰量は、fallout パラメタで変更できます。例えば、減衰量0.75は, 各オクターブが以前の低いオクターブの75％(25％減少)の影響を持つことを意味します。 0.0から1.0までの任意の値が有効ですが、0.5より大きい値は, noise() から1.0より大きい値が返される場合があることに注意してください。

これらのパラメータを変更することにより、noise() によって作成された信号を特定のニーズや特性に合わせて調整できます。

### 構文

noiseDetail(lod, falloff)

### パラメタ

- lod  
Number：ノイズが使用するオクターブの数

- falloff  
Number：各オクターブの減衰係数

### 例

```javascript
function setup() {
  createCanvas(200, 200);
}

function draw() {
  let noiseScale = 0.03;

  background(0);
  for (let x = 0; x < width; x++) {
    for (let y = 0; y < height; y++) {
      noiseDetail(4, 0.4);
      let noiseVal = noise(x * noiseScale, y * noiseScale);
      stroke(noiseVal * 255);
      point(x, y);
    }
  }  
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/Q53FHEpd3


### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
TKGで展開したノードから .local ドメインを名前解決できない

## はじめに

[前回の記事](https://qiita.com/ttani03/items/70b03e978f73de3c20c0)でTKG用にHarborを展開しましたが、Workerノードから`.local`ドメインを名前解決できないことに気づきました。

```
$ ping harbor.tta.local
ping: harbor.tta.local: Temporary failure in name resolution
```

今回は、解決策と調査した内容についてメモとして残したいと思います。

## 解決策

以下の対処法を行うことで`.local`ドメイン名で名前解決できるようになります。

1. 以下のように、`/etc/systemd/network/10-eth0.network`ファイルに`Domains=<ドメイン名>`を追加します。

    ```
    $ cat /etc/systemd/network/10-eth0.network
    [Match]
    Name=eth0
    [Network]
    DHCP=ipv4
    Domains=tta.local
    ```

2. `systemd-networkd`サービスを再起動します。

    ```
    $ sudo systemctl restart systemd-networkd
    ```

3. `.local`ドメインが名前解決できることを確認します。

    ```
    $ ping harbor.tta.local
    PING harbor.tta.local (192.168.7.103) 56(84) bytes of data.
    64 bytes from harbor.tta.local (192.168.7.103): icmp_seq=1 ttl=64 time=0.271 ms
    64 bytes from harbor.tta.local (192.168.7.103): icmp_seq=2 ttl=64 time=0.433 ms
    64 bytes from harbor.tta.local (192.168.7.103): icmp_seq=3 ttl=64 time=0.266 ms
    ```

以上の手順で`.local`ドメインを名前解決できるようになります。しかし、後述する内容から、`.local`ドメイン自体を使用しない方法がオススメです。

## `systemd-resolved`サービスでは、`.local`ドメインの使用は非推奨

TKGのベースとなるPhoton OSでは、DNSの設定に`systemd-resolved`サービスを使用しています。

[Adding a DNS Server](https://vmware.github.io/photon/assets/files/html/3.0/photon_admin/adding-a-dns-server.html)
> Photon OS uses systemd-resolved to resolve domain names, IP addresses, and network names for local applications.

`systemd-resolved`について、マニュアルを確認したところ、以下のように`.local`ドメインを解決するためには明示的に指定する必要があると記載されています。
そのため、上述した方法で`.local`ドメインを明示的に指定することで、名前解決ができるようになります。

[systemd-resolved.service - Freedesktop.org](https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html)
> Other multi-label names are routed to all local interfaces that have a DNS server configured, plus the globally configured DNS server if there is one. Address lookups from the link-local address range are never routed to DNS. Note that by default lookups for domains with the ".local" suffix are not routed to DNS servers, unless the domain is specified explicitly as routing or search domain for the DNS server and interface. This means that on networks where the ".local" domain is defined in a site-specific DNS server, explicit search or routing domains need to be configured to make lookups within this DNS domain work. Note that today it's generally recommended to avoid defining ".local" in a DNS server, as RFC6762 reserves this domain for exclusive MulticastDNS use.

しかし、引用部分の後半に記載されている通り、`.local`ドメインはマルチキャストDNSと競合するため、`.local`ドメインを使用すること自体が非推奨です。

各ノードに毎回解決策を適用する手間も考えると、`.local`ドメインで環境を構築すること自体を避けた方がよいです。
P5.js 日本語リファレンス(noise)

このページでは[「P5.js 日本語リファレンス」] (https://qiita.com/bit0101/items/91818244dc26c767a0fe) の noise関数を説明します。

## noise() 

### 説明文

指定された座標での Perlin ノイズ値を返します。Perlin ノイズは、標準の random() 関数と比較してより自然な順序で調和のとれた一連の数値を生成するランダムシーケンスジェネレータです。 1980年代に Ken Perlin によって発明され, 手続き型のテクスチャ、自然な動き、形状、地形などを生成するためにグラフィカルアプリケーションで使用されました。

random() 関数との主な違いは、Perlin ノイズが無限のn次元空間で定義されることです。この場合、座標の各ペアは、固定されたセミランダム値に対応します(プログラムの存続期間に対してのみ固定されます。noiseSeed() を参照してください) p5.j​​s は、指定された座標の数に応じて、1D、2D、および3Dノイズを計算できます。結果の値は常に0.0 から 1.0 の間になります。上記の例で示したように、ノイズ値はノイズ空間を移動することでアニメーション化できます。 2番目と3番目の次元も時間として解釈できます。

関数による周波数の使用に関しては、実際のノイズはオーディオ信号と同様に構成されています。物理学における高調波の概念と同様に、Perlin ノイズは最終結果のために加算されるいくつかのオクターブにわたって計算されます。

結果のシーケンスの特性を調整する別の方法は入力座標のスケールです。関数は無限空間内で機能するため、座標の値自体は問題ではなく、連続する座標間の距離のみが関係します(たとえばループ内で noise() を使用する場合) 一般的なルールとして、座標間の差が小さいほど結果のノイズシーケンスは滑らかになります。 0.005〜0.03 のステップがほとんどのアプリケーションに最適ですが、これは使用状況によって異なります。

### 構文

noise(x, [y], [z])

### パラメタ

- x  
Number：ノイズ空間のx座標

- y  
Number：ノイズ空間のy座標(オプション)

- z  
Number：ノイズ空間のz座標(オプション)

### 戻り値

Number：指定された座標でのPerlinノイズ値(0と1の間)

### 例1

```javascript
function setup() {
  createCanvas(200, 200);
}

function draw() {
  let noiseScale = 0.03;

  background(0);
  for (let x = 0; x < width; x++) {
    for (let y = 0; y < height; y++) {
      let noiseVal = noise(x * noiseScale, y * noiseScale);
      stroke(noiseVal * 255);
      point(x, y);
    }
  }  
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/Q8ufiqtMG

### 例2

```javascript
var ns = 0.02; // ノイズスケール(係数)
var sz = 5; // 1ドットの縦横サイズ
var t = 0; // 時間軸

function setup() {
  createCanvas(200, 200);
  colorMode(HSB);
  noStroke();
}

function draw() {
  for (var x = 0; x < width; x += sz) {
    for (var y = 0; y < height; y += sz) {
      var n = noise(x * ns, y * ns, t);
      fill(n * 360, 100, 100); // HSBでカラー指定
      rect(x, y, sz, sz);
    }
  }
  t += 0.005; // 時間の更新
}
```

### 実行結果
https://editor.p5js.org/bit0101/sketches/obJ5qGjSQ

### 著作権

p5.js was created by Lauren McCarthy and is developed by a community of collaborators, with support from the Processing Foundation and NYU ITP. Identity and graphic design by Jerel Johnson.

### ライセンス

Creative Commons(CC BY-NC-SA 4.0) に従います。
AWS　EC2へのpingコマンドを使えるようにする

# やりたいこと
パブリックサブネットのEC2にSSH接続をして、プライベートサブネットのEC2にpingで通信ができるかをチェックしたい。

# やり方
プライベートサブネットのEC2のセキュリティグループで、
「ICMP（Internet Control Message Protocol）」を許可する。

※pingのプロトコルがICMP

# 参考
https://a1-style.net/cloud/aws/ping-icmp-setting/
正規表現でバリデーション設定した項目を空欄のままでも通過できるようにしたい

# はじめに
電話番号やメールアドレス等の入力値のフォーマットチェックに正規表現が使える。

指定した文字列、数列以外の値が入力されたらバリデーションチェックに引っ掛かる仕組みだ。

今回は任意入力とした項目を指定された正規表現、または空欄のままでもバリデーションが通過するようにしたい。

# 電話番号にバリデーションをかけてみよう
今回は電話番号を例にして、まずは電話番号にバリデーションをかけてみる
<img width="412" alt="スクリーンショット 2020-05-17 17.37.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595035/3be4cc6e-35b9-950b-4b00-f311e24897ca.png">


```ruby

validates :phone_number, format: { with: /\A\d{10,11}\z/ }
```

これはハイフンなしの10桁または11桁の半角数字で入力してくださいという意味の正規表現だ。

今回は電話番号は任意入力にしたいのでpresence: trueは書いてないし、このままでいいだろうと思ったが…。

# 問題発生
指定された正規表現でのバリデーションは突破し、次に入力欄を空白にして進んだらバリデーションに引っかかってしまった！
<img width="401" alt="スクリーンショット 2020-05-17 17.40.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595035/2c4d7b01-a48d-b351-d4e9-b71d7b694d1f.png">


# 原因
どうやら正規表現でバリデーションをかけるとその正規表現以外の入力をたとえ空欄(nil)でも受け付けなくなってしまうらしい。

# 解決法その1
メンターに聞いてみるとカスタムメソッドというのを用いて

「空か、あるいは10桁または11桁の半角数字」といったカスタムメソッドを作るという方法があると言われたが、カスタムメソッドについて調べると非常に面倒臭いし大変そうである。

↓カスタムメソッドの参考記事
https://qiita.com/h1kita/items/772b81a1cc066e67930e

なので自分で他の方法がないか考えて試行錯誤した結果、非常に簡単な解決法が見つかった。

# 解決法その2
以下のようにallow_blank: trueを追加するだけである。

```ruby
validates :phone_number, format: { with: /\A\d{10,11}\z/ }, allow_blank: true
```

これは文字通り空欄のままでもOKという意味。

これで電話番号が未入力でもバリデーションが通るようになりました！

# まとめ
入力値を正規表現、または空欄でバリデーションを通過したい場合はallow_blank: trueを追加すれば良い。
toio™ にプログラムを転送して動かそうとするまで


toio™ で遊んでみようと思ったので、遊ぶまでの記録です。

# はじめに

toio™ は、本体だけでは遊べません。遊べないどころか充電もできません。
（買う前にきちんと調べろという話ですが。）
本体と言っているのはこれ。正しくは、「コアキューブ」と言います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81274/623297a0-ea81-fbeb-86dd-c49070d41713.png" width=50%>

後ろ側が
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/81274/68bed759-9c37-dab0-504a-a15828a05fb4.png" width=50%>

コアキューブ単体品を買って、うらを見るまで、USB Type Cあたりで充電できるかと勝手に思っていました。そんなことはありません。

充電端子も専用です。さすがにきちんとできてます。というわけで、改めて書い直す（買い足す）こととなりました。

# プログラムする上で最低必要なもの

- toio™ 本体セット
- toio™ 専用タイトル トイオ・コレクション

 toio™ コンソールという、台座の部分は単品販売していますが、 コントローラーである、 toio™ リングなどは単品販売していません。
他にも小物が色々とあるので、素直に、本体セットを買うのが良いです。

そして、自分で作ったプログラムを実行させるのには、 toio™ 側のプログラムとして、トイオ・コレクションが必要です。

在庫があるようであれば、その2つのセットである、toio™バリューパック（トイオ・コレクション同梱版）を素直に買うのがおすすめです。

次回は、[https://toio.io/programming/visual-programming.html](こちら)を見ながら、実際にプログラムで toio™ を動かしてみようと思います。
Ubutnu20.04LTS(UbuntuServer)をRaspberryPi4上で動かす

## 概要
- Ubuntu20.04LTSをRaspberryPi4にインストールする。
- RaspberryPi4にはディスプレイとキーボードを接続せず、ホストPCからのSSH接続で一通り設定する。(ハードまわりの準備が面倒なので)
- wifi接続の設定を行い、電源供給のみでサーバーとして動作可能な状態にする。

## 準備物
##### ホストPCまわり
- Windows10 PC
- microSDカードリーダー
- Wifiルーター
- LANケーブル

##### RaspberryPiまわり
- Raspberry Pi 4 Model B
- microSDカード(32GB)
- 5V3A電源(USB Type-C)

## Ubuntu20.04LTSのインストール

進め方は、下記の公式のチュートリアルに従う。
https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi

##### 1.Raspberry Pi Imager のインストール

下記ページの"Raspberry Pi Imager for Windows"をクリックして、imager.exeをダウンロードする。
https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi#2-prepare-the-sd-card

ダウンロードしたimager.exeを実行してRaspberryPiImagerをインストールする。

##### 2.Ubuntu20.04LTSイメージをmicroSDカードに書き込む

RaspberryPiImagerを実行する。
![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327534/0a7e4152-0bf0-da2a-d608-67f438897d83.png)
"CHOOSE OS"からUbuntu20.04LTS(Pi 3/4)を選ぶ。
![fig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/327534/30c14303-afce-e749-d27f-3b880efba768.png)
"CHOOSE SD CARD"で書き込む対象のmicroSDカードを選んで"WRITE"を実行する。
書き込みが終わるまで待機。1時間半ほど要した。

##### 3.RaspberryPi4上でUbuntu20.04LTSを実行

RaspberryPi4に、Ubuntu20.04LTSイメージを書き込んだmicroSDカードを挿入する。
RaspberryPi4をLANケーブルでルーターに接続し、電源を接続する。

電源接続後1分程度でUbuntuが立ち上がる。

##### 4.ホストPCからUbuntu20.04LTSに接続

立ち上げたUbuntu20.04LTSのIPアドレスを調べるため、
arpコマンドを使って、RaspberryPi4のMACアドレスに対応するIPアドレスを検索する(※1)。
ホストPCのコンソールに下記コマンドを入力する。

```
>arp -a | findstr "b8-27-eb dc-a6-32"
```


調べたIPアドレスにSSHで接続する。

```
>ssh ubuntu@<Ubuntu_IPaddress>
```

初期パスワードは"ubuntu"。初期ログイン時にパスワードの変更が求められるので、実施する。

(※1)RaspberryPiModel3+までのMACアドレスは"b8-27-eb"から始まる、が、
RaspberryPi4からは"dc-a6-32"から始まるMACアドレスが増えたとのこと。
  参考資料：
  https://qiita.com/tomotomo/items/2ff445377c13f9db38e2
  https://udger.com/resources/mac-address-vendor-detail?name=raspberry_pi_foundation


## Wifi設定

公式チュートリアルに記載されているwifiの事前設定が上手く行えなかったので、
一度LANケーブルで接続した後に、改めてwifi設定を行う。

##### 1.wifi設定の記述
Ubuntu上でコンソールに下記コマンドを入力して、
wifi設定用ファイル"99-cloud-init.yaml"を作成する(※2)。

```
>sudo nano /etc/netplan/99-cloud-init.yaml
```

作成した"99-cloud-init.yaml"に下記設定を記述する。

```99-cloud-init.yaml
network:
    version: 2
    wifis:
        wlan0:
            optional: true
            access-points:
                "<Network-name>":
                    password: "<Password>"
            dhcp4: true
```

記述し終えたら、新しいネットワーク設定を適用する。

```
>sudo netplan apply
```

(※2)/etc/netplan/以下にネットワーク関連の設定ファイルがある。
既存の設定ファイルである"50-cloud-init.yaml"を弄るのは好ましくないとのこと。
参考資料
https://qiita.com/yas-nyan/items/9033fb1d1037dcf9dba5
https://ubuntu.com/server/docs/network-configuration

##### 2.wifi接続用IPアドレスの確認

Ubuntu上でコンソールに下記コマンドを入力して、
wifi接続用のIPアドレスを確認する。

```
>ip a
```

wlan0に対応するIPアドレスがwifi接続用のIPアドレスとなる。
IPアドレスが確認出来たら念のためリブートする。

```
>sudo reboot
```

##### 3.ホストPCからUbuntu20.04LTSにwifiを通じて接続

Ubuntuからログアウトし、RaspberryPi4のLANケーブルを引き抜く。
ホストPCのコンソール上から、wifi接続用IPアドレスにSSHで接続できることを確認する。

```
>ssh ubuntu@<Ubuntu_IPaddress>
```
【Docker】GolangからMySqlへ接続してみた

##やりたいこと
GolangコンテナからMySqlコンテナに接続したい！

##環境
docker 19.03.8
docker-compose 1.25.5

##リポジトリ
https://github.com/atsugitakuya/go-mysql-docker.git

##フォルダ階層
root /
　├ app /
　｜　└ main.go
　├ docker /
　｜　└ Dockerfile 
 　└  docker-compose.yaml 

##main.go作成
今回はgormというORMライブラリを使って接続していく。
https://gorm.io/

```ruby:/app/main.go
package main

import (
	"fmt"
	"net/http"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
)

func main() {
	http.HandleFunc("/", index)
	http.ListenAndServe(":80", nil)
}

// mysqlのconnectionが確認できれば「DB接続成功」が表示される
// 接続に失敗時はエラーメッセージを吐く
func index(w http.ResponseWriter, r *http.Request) {
	_, err := sqlConnect()
	if err != nil {
		fmt.Fprintf(w, err.Error())
	} else {
		fmt.Fprintf(w, "DB接続成功")
	}
}

// connetion確認func
func sqlConnect() (database *gorm.DB, err error) {
	DBMS := "mysql"
	USER := "root"
	PASS := "golang"
	PROTOCOL := "tcp(mysql:3306)"
	DBNAME := "mysql"

	CONNECT := USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?charset=utf8&parseTime=true&loc=Asia%2FTokyo"
	return gorm.Open(DBMS, CONNECT)
}

```
##Dockerfile作成
今回使用するgormとmysqlのdriverをインストールしている。
なんかgitがないと動かないっぽい。あとRunコマンドは少なくした方がいいが良い。
多分もっと良い方法があるはず....


```ruby:/docker/Dockerfile
FROM golang:alpine
# フォルダ作成
RUN mkdir /app
# 作成したフォルダ内にmain.goを配置
COPY ./app /app
# 作業場所を/appに設定（main.goがある場所）
WORKDIR /app
# 必要ライブラリをインストール
RUN apk add --no-cache git
RUN go get "github.com/go-sql-driver/mysql"
RUN go get -u github.com/jinzhu/gorm
# main.goをbuild
RUN go build -o main . 
# port開放
EXPOSE 80
# app開始
CMD ["/app/main"]
```
##docker-compose.yaml作成
golangとmysqlを動かすためのdocker-compose。特に説明することない。

```ruby:/docker-compose.yaml
version: '3'

services:
  golang:
    build: 
      context: .
      dockerfile: ./docker/Dockerfile
    ports:
    - "80:80"
    container_name: go-sample
    depends_on:
    - mysql
  mysql:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: golang
      MYSQL_USER: golang
      MYSQL_PASSWORD: golang
      MYSQL_DATABASE: golang
    container_name: mysql
```

##実行し、DBの接続確認を行う
```ruby:zsh
# docker-compose.yamlのある階層で実行
$docker-compose up -d
....
# 立ち上がったよ！メッセージが出たらOK
Creating mysql ... done
Creating go-sample ... done

```

localhostに接続すると、「DB接続成功」が出るはず...

<img width="1368" alt="スクリーンショット 2020-05-17 17.48.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/631619/995e2d15-9896-f5b5-af0a-f9ce2f6b4222.png">

接続成功！！！！
意外と簡単に接続できた...さすがGoだな...
AWS ネットワークACL「送信元は IPv4 または IPv6 CIDR ブロックにする必要があります。」

#やりたいこと
AWSのネットワークACLで特定のIPからのアクセスを拒否する設定をしたい。

#起きた問題
インバウンドールールの送信元にグローバルIPを入力したところ、
「送信元は IPv4 または IPv6 CIDR ブロックにする必要があります。」と表示されて保存できない。

#解決策
CIDR「/32」（ユニキャスト）を追記する。
※1つのIPを指定する場合、/32(=255.255.255.255)を指定する。

#参考
https://www.mrl.co.jp/download/manual-online/gl2000/gl2000_02/manual/docs/netlistc.htm
zsh no matches found error

# zsh で no matches found っていうエラーが出るとき
もうたくさん記事を書いている人がいるかもしれないけど、OSXをCatalinaにして、思い切ってzshを使ってみようと思い、運用二日目とかでワイルドカードを使おうとしたらしょうもないエラーが出たので忘備録として投稿しておきます。

[こちら](https://github.com/ohmyzsh/ohmyzsh/issues/31)で色々議論されてますが、

.zshrcに

```bash
unsetopt nomatch
```

を追加。これで解決できるようです。rsyncとかscp使うときに*が使えないと困るもんね。
PHPのstaticの理解〜初心者用〜

##はじめに
PHPを勉強し始めると、すぐに出てくるstaticというキーワードですが
自分が理解をするのに時間がかかってしまったので
アウトプットも兼ねてまとめていきます。

##staticとは

インスタンスを作らずにクラス変数もしくは、
クラスメソッドを宣言すればアクセスすることができます。

staticは、インスタンス（個別の実体）ではなく
クラス側にプロパティやメソッドを持たせることができます。
クラス側に持たせた変数は「クラス変数」
関数を「クラスメソッド」といいます。

###注意点

1.staticの変数はオブジェクトからのアロー演算子->でアクセス不可
2.sutaticではないメソッドをstaticをつけたものと同じ方法で呼び出すとエラーになる

詳しくは、PHPドキュメントの[こちら](http://qiita.com/)をご確認ください。

###クラス変数やクラスメソッドの呼び出し方

クラス変数やクラスメソッドでは、アロー演算子->が使えないため
->の代わりにスコープ定義演算子（::)を
$thisの代わりにselfを使います。

Nekoクラスにクラス変数とクラスメソッドを使ってみます。

```test.php

<?php

<?php

class Neko {
    public static $type = "飼いネコ";
    public $suffix = "";
    
    public $hp = 20;
    public $power = 10;
    
    function __construct($suffix) {
        $this->suffix = $suffix;
    }
    
    function name() {
        return $this::$type . "の" . $this->suffix;
    }
    
    function attack($owner) {
        print $this->name() . "が" . $owner . "を攻撃し" . $this->power . "ポイントのダメージを与えた!" . PHP_EOL;
    }
    
    //クラスメソッド
    static function description() {
        print self::$type . "は、凶暴だが最愛の家族だ。" . PHP_EOL;
    }
}

Neko::description();

$neko_A = new Neko("モカ");
$neko_B = new Neko("カフェ");

$neko_A->attack("飼い主");
$neko_B->attack("他のネコ");

```


コンソール入力

```
$php tex.php
```

実行結果

```

飼いネコは、凶暴だが最愛の家族だ。
飼いネコのモカが飼い主を攻撃し10ポイントのダメージを与えた!
飼いネコのカフェが他のネコを攻撃し10ポイントのダメージ

```
クラスの説明をする関数
description()という名前のクラスメソッドを用意しました。

Neko::description();と書いて呼び起こしていますが
アロー関数->を使うとどうでしょう。

```一部抜粋

// Neko::description();　だったものを
Neko->description();

```

実行結果

```エラー文

PHP Parse error:  syntax error, unexpected '->' (T_OBJECT_OPERATOR)

```

となり、変なところに->があるねん！という内容になります。
なので、staticをつけた変数や関数はクラス名::○○と書く必要があるということですね。（変数を参照したい場合はスコープ定義演算子の後に$を入れてください）

###まとめ

スコープ定義演算子が出てきた時は、
アロー演算子を覚えたばかりだと戸惑ってしまいますが
staticを使った関数の場合はアロー演算子ではなく
スコープ定義演算子を使うと覚えれば良さそうです。

---


・クラス名::○○　static宣言されたメソッドやプロパティへアクセスする
・self::○○　自クラスのクラス変数、クラスメソッドへアクセスする
・parent::　指定した親クラスを示す
・インスタンス変数::○○ (self::○○)　インスタンスが持つクラス変数やクラスメソッドへアクセスする
Qt for Python アプリのデスクトップアプリ化

備忘録です。自作アプリ完成に近づきつつ、周辺作業もということで。

Guiアプリを起動するのに、ターミナルから python3 hoge.py とかするのは多少残念だけど、パッケージ化をめざす程の事でも無く、簡単にデスクトップなりApplicationフォルダーなりに置いておくことは出来ないものかと調べて見ました。
初めてだけどもAutomatorでいけるのでは？と思いつき、下記のサイトを参考に。（ありがとうございます。）

[[Mac] Automatorでターミナルのコマンドをアプリ化する方法](https://www.searchlight8.com/automator-terminal-app/)

Automaterで作業して、hoge.appというアプリを作り、デスクトップのそれを叩けば、QtforPythonのGuiアプリが起動するようになりましたが、メニューバーにAutomater自身のクルクル歯車アイコンが残ってしまいこれはかなり悲しい。

最初の案

```bash:start.sh
/usr/local/bin/python3 hoge.py &
exit
```
これで歯車アイコンクルクルが消えない理由がわかりませんので、さらに調べてみると、下記のサイトにたどり着き。（ありがとうございます。）

[Automatorのシェルスクリプトは標準エラーの出力先を明示する](http://knyijong.blogspot.com/2014/07/automator.html)

修正案

```bash:start.sh
/usr/local/bin/python3 mainwindow.py >& log &
exit
```
歯車アイコンクルクルが消えて目的通りの状態になりました。
Windows (WSL)で簡単にPowerline対応版のRictyを使用する

## はじめに
WindowsのWSL上でもプログラミングがしやすい視認性の高いフォントを使用できるようにする方法のメモです。

評判の高いRictyフォントをPowerline対応にしたものをインストールしていきます。

[プログラミング用フォント Ricty](https://rictyfonts.github.io/)

## 環境
- Windows 10 (筆者はversion 2004)
- WSL (WSL2) インストール済み
- Homebrew (Linuxbrew)をWSL環境下へインストール済み

直接関係ないですが、筆者はWindows Terminalを使用しておりとても快適です♪

## 手順
### WSL上での操作
Homebrewを使用することで簡単にRictyフォントのダウンロードと、Powerline対応化パッチの適用を行います。

```sh
$ brew tap sanemat/font
$ brew install --with-powerline ricty
$ cd /home/linuxbrew/.linuxbrew/opt/ricty/share/fonts/
$ explorer.exe .
```

ダウンロードされたフォントが入ってるフォルダーがエクスプローラーで開きます。
(開かない場合はWSLのバージョンが古い可能性があります)

### GUIでのインストール操作
1. エクスプローラーで開いたWSL環境下のファイルを直接開こうとするとエラーが発生したため、一度`fonts`フォルダごとデスクトップ等のWSL環境外へコピーします。
2. インストールしたいフォントをダブルクリックし、フォントビュワーを開きます。
3. 左上にある`インストール`ボタンをクリックして完了です。(あるいは、フォントファイルを右クリックし「すべてのユーザーに対してインストール」を選択します。）

ちなみに筆者は、Rictyの中でもASCII文字も含めて可読性を向上させたDiscord版である`Ricty Discord Regular for Powerline`をインストールしました！

## 最後に
WindowsでもWSLを使用したかっこいい開発環境の完成です！
ConfigMap/Secretから環境変数を抽出する

# 概要

- kubernetes上で稼働しているアプリケーションと同じ設定でローカル環境で動かしたい時がある
- そんなとき毎回configmapやsecretから値をコピペして環境変数をexportしていて面倒だと思ったのでwebツールを作ってみた

# 成果物

https://rhirabay.github.io/web-tools/src/html/convert/configmap2env

# 使い方

- 左の入力欄にConfigMapをコピペして変換ボタンを押すだけ！

<img width="1428" alt="Screen Shot 2020-05-17 at 17.41.28.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/cee1adbb-601d-3467-baf5-9e3254142c84.png">

- kindによってConfigMap/Secretを判別して、secretの場合にはbase64デコードも行います
- 「追加」ボタンを押すことでそれまでの変換結果に今回の変換結果を追加できます

<img width="1432" alt="Screen Shot 2020-05-17 at 17.44.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/2b021f99-d4d9-49da-b192-10634bb4f010.png">
【JavaScript】関数の定義4種類

```main.js

function getTryangle1(base, height) {
    return base * height / 2;
}
console.log(`三角形の面積: ${getTryangle1(5, 2)}`);

var getTryangle2 = new Function('base', 'height', 'return base * height / 2;');
console.log(`三角形の面積: ${getTryangle2(5, 2)}`);

var getTryangle3 = function(base, height) {
    return base * height / 2;
};
console.log(`三角形の面積: ${getTryangle3(5, 2)}`);

let getTryangle4 = (base, height) => {
    return base * height / 2;
};
console.log(`三角形の面積: ${getTryangle4(5, 2)}`);

```
Windows10でDjangoからCelery + RabbitMQを使うときに発生したエラーと解消法

# 事象と環境

## 事象

DjangoアプリケーションからCelery(メッセージブローカーとしてRabbitMQを使用)を使用した時に、Celeryを実行しているコマンドプロンプトに以下のエラーメッセージが表示された。

```
[2020-05-17 17:13:11,060: INFO/MainProcess] Received task: elevator.tasks.add[73368f71-a119-4c93-82f9-99949fc2d7bc]
[2020-05-17 17:13:11,072: ERROR/MainProcess] Task handler raised error: ValueError('not enough values to unpack (expected 3, got 0)')
Traceback (most recent call last):
  File "c:\users\hogehoge\appdata\local\programs\python\python37\lib\site-packages\billiard\pool.py", line 362, in workloop
    result = (True, prepare_result(fun(*args, **kwargs)))
  File "c:\users\hogehoge\appdata\local\programs\python\python37\lib\site-packages\celery\app\trace.py", line 546, in _fast_trace_task
    tasks, accept, hostname = _loc
ValueError: not enough values to unpack (expected 3, got 0)
```

上記事象が発生したときに実行した手順は以下になる。

1. Windows10のスタートメニューからRabbitMQを実行
2. `celery -A ApplicationName worker -l info`でCeleryを実行
3. `python manage.py runserver`でDjangoを実行
4. Celeryのタスクが実行されるように操作
5. エラー発生

## 環境

実行環境はCelery4.4.2、Django2.2.12、python3.7、Windows10である。

# 原因

不明。

# 対応

`pip install eventlet`でeventletモジュールをインストールする。

`celery -A elevator worker -l info -P eventlet`でCeleryを起動する。

上記対応後、Celeryのタスクが正常に実行されることを確認した。

# 参考

https://github.com/celery/celery/issues/4178
上記URLのコメント(`vfxpandit commented on 10 Mar 2018`)に記載あり。

https://docs.celeryproject.org/en/latest/userguide/concurrency/eventlet.html?highlight=eventlet
Celeryの公式ドキュメントに記載あり。

https://docs.celeryproject.org/en/latest/faq.html?highlight=windows#does-celery-support-windows
そもそもCelery4系はWindowsをサポートしていないと記載あり。
巨大なファイル(100万行とかでも)を1行1行処理するrubyスクリプトのテンプレートを作った

私が巨大ファイルを作るときにテンプレートをコピーして使います。

# メリット
- いちいちCSVやファイルの読み書きをするときにコマンドを調べなくていい
- プログレスが出る
    - 大抵巨大ファイルを読む場合10分くらいかかるけど、進捗が見えなくて進んでるかわからないため表示

# スクリプトテンプレート
以下のスクリプトはCSVを読む場合のスクリプトです

- テキストファイルをいじる場合は[こちら](https://github.com/setsumaru1992/portableScripts/blob/master/frequent_use_codes/ruby_file_handlers/read_and_write_file.rb)
- 1行1行の逐次処理でなく全行見たあとに集計処理をとかをやりたい場合は[こちら](https://github.com/setsumaru1992/portableScripts/blob/master/frequent_use_codes/ruby_file_handlers/read_csv_lines_and_write_result.rb)

```ruby
require "csv"

$is_debug = true

def main(csv) #, output_file)
  # output_file_writer = CSV.open(output_file, "w")
  # output_cols = ["hoge"]
  # output_file_writer.puts(output_cols)

  FileHandler.csv_foreach(csv) do |row|
    # 処理
    p row

    # output_row_values = []
    # output_file_writer.puts(output_row_values)
  end

  # puts "#{output_file}を作成しました"
  # output_file_writer.close
end

module FileHandler
  class << self
    def csv_foreach(csv)
      log "#{Time.now}: read start #{csv}"
      all_line_count = line_count(csv)

      return_values = CSV.foreach(csv, headers: true).with_index(1).map do |row, row_no|
        log progress(row_no, all_line_count) if progress_timing?(all_line_count, row_no)
        yield(row)
      end

      log "#{Time.now}: read end #{csv}"

      return_values
    end

    def line_count(file)
      open(file){|f|
        while f.gets; end
        f.lineno
      }
    end

    private

    def log(message)
      puts(message) if $is_debug
    end

    def progress_timing?(all_line_count, line_no)
      return false if all_line_count < 100

      # NOTE 処理時間によって変更
      div_number = 100

      percent_unit = all_line_count / div_number
      line_no % percent_unit == 0
    end

    def progress(current_count, all_count)
      "#{Time.now}: #{CommonUtilities.percent(current_count, all_count)}% (#{CommonUtilities.number_with_commma(current_count)} / #{CommonUtilities.number_with_commma(all_count)})"
    end
  end
end

module CommonUtilities
  class << self
    def percent(num, all_count)
      (num.fdiv(all_count) * 100).round(2)
    end

    def number_with_commma(number)
      number.to_s.gsub(/(\d)(?=\d{3}+$)/, '\\1,')
    end
  end
end

main(ARGV[0])
```
PythonでのimportによるオブジェクトIDの違い

# 環境
windows 10 Pro
version : Python 3.8 (docker)

# 一行でいうと
状態管理のファイルを分けるのをサボってハマった話、サボるな。

# 本題
```game.py
from status import Status

class Game():
  def __init__():
    self.status = Status.NOTHING
```

```status.py
from enum import Enum, auto

class Status(Enum):
    NOTHING = auto()
    WAITING = auto()
    PLAYING = auto()

class GameStatus():
  def start():
    if self.game.status == Status.NOTHING:
      ...
    if self.game.status == Status.WAITING:
      ...
    if self.game.status == Status.PLAYING:
      ...

```

Statusによって処理を変えるって感じですね。
Statusを列挙型で作成し、初期状態Status.NOTHINGでゲームの流れによってStatesがWAITINGやPLAYINGに変更するって感じです。
game.pyのGameクラスではStatusをimportしていますが、status.pyでは同一ファイル内にStatusがあるため、importしていません。
ここでオブジェクトIDに齟齬が発生し、init関数で代入した `Status.NOTHING` のみオブジェクトIDが異なり、等値比較が成立しません。
列挙型の等値比較が値ではなくオブジェクトIDを参照しているのではないかと思われます。

サボらずに

```gamestatus.py
from status import Status

class GameStatus():
  def start():
    if self.game.status == Status.NOTHING:
      ...
    if self.game.status == Status.WAITING:
      ...
    if self.game.status == Status.PLAYING:
      ...
```
```status.py
from enum import Enum, auto

class Status(Enum):
    NOTHING = auto()
    WAITING = auto()
    PLAYING = auto()
```

って感じでファイルを分割し、全ファイル使用する際はimportする手順を踏むことでimportの有無によるオブジェクトIDの違いはうまれないです。

サボらずにきちんとファイルを分割しましょう。。。。
AWS Amplifyを使ってて挙動がおかしくなった話～備忘録～

<h1>AWS Amplifyを使ってて挙動がおかしくなった話～備忘録～</h1>
<p>最近、はまっているゲームのキャラクター紹介SPAを作ろうと思って、React.jsとsemantic-ui-reactを使って作成しております。</p>
<p>せっかくなら、デプロイして他の人にも見てもらいたいと思い、が、バックエンドの知識が皆無なのでAWS Amplifyを使用して、ビルドからデプロイまでお任せすることにしました。<p>

<h2>問題点</h2>
<p>SPAのデプロイが出来たまではいいのですが、、、ページをリロードすると301,302ステータスコードがレスポンスされ、意図しない動きをしてしまいました。(locationの値がindex.htmlとなり、うまくリロードができていない)

<h2>原因</h2>
<p>おそらく、ページ遷移した後のURIとリロードした時のURIが一致せず、index.htmlがリダイレクトされたことが原因だったと思います。</p>

<h2>解決策</h2>
<p>Amplify Consoleは、リダイレクト設定なるものがあるので、そこに指定された値を埋め込めばよしというものでした。
以下、Amplifyのリダイレクトに関するページ
https://docs.aws.amazon.com/ja_jp/amplify/latest/userguide/redirects.html

●送信元アドレス：
</^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>
●ターゲットアドレス：
/index.html
●入力
200(Rewrite)

これで解決されました。送信元アドレスが複雑ですが、リロードしても今のURIで更新するよって意味なのでしょうか。

とりあえず、備忘録。
【開発ログ⑭】社員を削除したら有休データも削除したい

# 前提について
はじめまして、 プログラミングスクールに通ういりふねと申します。この記事は、スクールの課題である個人アプリの開発の記録を書くことで、自身のアウトプットに利用しています。もし、読んでいただけた方がいましたら、フィードバックをしていただけたら嬉しいです。

開発するのは「有給休暇管理ツール」です。仕様は[過去記事](https://qiita.com/iczo32/items/97ad7d4baa985b3b99ca)をどうぞ。

アプリはデプロイまで行いますが、サービスとして提供するものではありません。あくまでも自学習の一環ですので、ご理解下さい。では本題へどうぞ。

# 今回の実施内容
前回までで有休登録の機能が実装できたので、今回は社員と支社の削除機能を実装します。具体的には以下の通りです。

- 社員削除の問題点
- 社員削除の制約の設定
- 支社の削除画面の検討
- ビューで確認

# 社員削除の問題点
今回のアプリケーションでは、4つのテーブルを用意しています。社員は、employeeテーブルに保存していますが、外部キーとして支社のbranch_idを持っています。社員にとっては親テーブルは支社になるわけです。さらに社員は、有休登録されたデータを複数持ちます。これは、holidayテーブルに保管され、holidayレコードは、外部キーとして社員のemployee_idを持ちます。

親子関係を表すと以下のとおりです。
親：支社のbranchテーブル
子：社員のemployeeテーブル
孫：有休のholidayテーブル

ここで、親や子（つまり支社や社員）を削除すると、その下のテーブルには外部キーに対応する親レコードがなくなってしまいエラーになってしまいます。
そこで、社員を削除したら、社員の持つ有休データもまとめて消せるように実装していきます。

# 社員削除の制約の設定
実装は非常に簡単で、モデルファイルにdependent制約を記述するだけです。
参考にさせていただいた記事[「[Rails] has_manyおよびbelongs_toへのdependent: :destroyの設定について」](https://qiita.com/after4649/items/1ad419dc705f807735e0)@after4649様


```ruby:employee.rb
class Employee < ApplicationRecord
〜中略〜
  has_many :holidays, dependent: :destroy
〜中略〜
end
```

アソシエーションを記述しているhas_manyの後ろに文章を追記するだけで、コントローラーなどの設定は変更せずにそのまま使用することができました。
ただし、記事にもありますが、belongs_toの方につけると大変なことになるので、注意が必要です。それからこのdependent制約には:destroy以外にも記述方法があるようなので、ご自身にあったものを使用して下さい。

# 支社の削除画面の検討
社員の設定は、これで良いとして支社を削除する際に同じように社員とその有休のデータをまとめて削除してよいか悩みましたが、同じようにdependent制約をかけることにしました。
そのかわり、支店削除は簡単に行えないよいうにステップに分けるようにしました。
まず、削除ボタンがindexに表示されないように「編集／削除」のボタンを設定し、編集画面を表示させます。編集画面内に「支社削除」がありますが、大きめの文字で注意を促します。
<img width="618" alt="スクリーンショット 2020-05-17 17.20.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614723/376a78ff-a67f-598a-ef7e-2570cf8b4086.png">
ここについては、私の技術がさらに向上したときに別の方法を検討しようと思います。今は、これが精一杯汗


# ビューで確認
ちょっと回り道をしましたが、ビューで確認します。座布団運びの山田くんは、5日有休を付与されていますが、このたび解雇となります。<img width="868" alt="スクリーンショット 2020-05-17 17.25.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614723/3c0e3e6b-046d-8358-46b8-f1c80e63bd2e.png">

社員の削除は表の右端（これも簡単に押せないよう配慮しているつもり）にあります。クリックすると見事に削除されました。
<img width="859" alt="スクリーンショット 2020-05-17 17.26.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614723/67cb1932-211e-7416-ac47-c226eadef37e.png">
付与及び消化の履歴にも山田くんの履歴は残っていません。無事に成功しました。
<img width="859" alt="スクリーンショット 2020-05-17 17.27.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/614723/159b9b92-d0ec-95a7-a518-78da5102de42.png">
ちなみに可愛そうだったので、この後山田くんは再登録してあげることにしました。

# 今日の積み上げ
dependent制約は、実はカリキュラムで触れられていました。まだまだ知識が十分定着していないのかも知れません。今後もどんどんアウトプットをして学んだことを定着させたいです。
【WIP】【検討メモ】フリマアプリのDB設計

自分用メモ

# What
フリマアプリのDB設計をまとめるためのメモ

# Why
チームメンバーとDB設計内容を共有し、円滑なアプリ開発の助けとするため


# DB設計
## Usersテーブル

|Colunm|Type|Options|
|---|---|---|
| nickname | string | null: false |
| email | string | null: false |
| family_name | string | null: false |
| first_name | string | null: false |
| birth_year | string | null: false |
| birth_month | string | null: false |
| birth_day | string | null: false |
| phone_number | integer | unique: true |

## Association
has_many :items
has many :comments


## itemsテーブル
|Colunm|Type|Options|
|---|---|---|
| name | string | null: false |
| price | integer | null: false |
| img | references | null: false, foreign_key: true |
| introduction | text | null: false |
| condition | integer | null: false |
| category_id | references | null: false, foreign_key: true |
| shipping_id | references | null: false, foreign_key: true |
| brand_id | references | null: false. FK: true |

## Association
belongs_to :user
belongs_to :category
belongs_to :brand
has_many :comments
has_one :shipping

## Commentsテーブル
|Colunm|Type|Options|
|---|---|---|
| comment | text | null: false |
| user_id | references | null: false, foreign_key: true |
| item_id | references | null: false, foreign_key: true |

## Association
belongs_to :item
belongs_to :user

## Categoriesテーブル
|Colunm|Type|Options|
|---|---|---|
| name | string |  |
| parent_id | integer |  |

## Association

## Shippingsテーブル
|Colunm|Type|Options|
|---|---|---|
| fee_burden | boolean？？ | null: false |
| region | integer | null: false |
| handling_time | integer | null: false |

## Association
belongs_to :item

## Brandsテーブル
|Colunm|Type|Options|
|---|---|---|
| category_id | references | null: false, FK: true |
| brand_id | references | null: false, FK: true |
| name | string | null: false |
PHPのstatic とは、静的とは

##static（静的）概要

PHP Manualより

>クラスプロパティもしくはメソッドを static として宣言することで、 クラスのインスタンス化の必要なしにアクセスすることができます。 static なプロパティは、インスタンス化されたクラスオブジェクトから アクセスすることはできません

つまりクラス外から　staticメソッド(静的メソッド)にアクセスする場合、
Foo::staticではこのメソッドにアクセスできるが、foo->static()の形ではアクセスできない。

##staticメソッド(静的メソッド)についての備忘
- 静的（静的メソッド、静的プロパティ）というのは、インスタンス化しないで使うということ
- なのでインスタンスに影響を受けない（保守しやすい）
- 基本宣言されたクラス内で使用するケースが多い（self::xxxの形）
- 平たく言うと、**インスタンス化が必要な時は、staticはつけない、インスタンス化が不要な時はstaticをつける**
- アクセスする際は、`::`を使用する。
- `::`はスコープ定義演算子と言う
- 無闇にインスタンスを実装して保守範囲を広げないために静的を利用する

##staticメソッド(静的メソッド)にアクセスする例
```sample.php
<?php

class Foo {
    public static function aStaticMethod() {
        echo "Hello Static!!!";
    }
}

Foo::aStaticMethod();
//or
$classname = 'Foo';
$classname::aStaticMethod();
//出力結果
"Hello Static!!!";

//staticなメソッドには->ではアクセスできない
$foo = new Foo();
$foo->aStaticMethod;
//出力結果
PHP Notice:  Undefined property:xxx
?>

```

###参考
[PHP: 静的メソッドは何のためにあるか？](https://qiita.com/suin/items/0897adc7dc653b9c20de)
[self::と$this->の使い分け](https://teratail.com/questions/62224)
[PHP - What is OOP?](https://www.w3schools.com/php/php_oop_what_is.asp)
【1分解説】あれ、最近いつrpmパッケージアップデートしたっけ？と思ったときの対処法【rpmコマンド】

##rpmコマンドのオプションで最近のアップデートやインストール日付を確認しよう
rpmコマンドのlastオプションを利用すると、アップデートやインストール日付を確認することができます。

```
$ rpm -qa --last
kernel-doc-x.x.32-358.18.1.el6.noarch       Wed Sep  9 08:12:50 2019
postgresql-libs-x.x.20-3.el6_6.x86_64       Wed Sep  9 08:12:50 2019
　　：　
　　：
```

例えば、apacheのアップデート最近いつしたっけな？と思った時は

```
$ rpm -qa --last | grep apache
```
で、apacheの最終アップデート日を確認します。
AWS SAA資格取得~ネットワークサービス編~

今回はVPCなどのネットワーク関連について！

##VPCとは
AWS上に独立したプライベートネットワーク空間を作成できるサービス。
世界中のユーザーが利用するAWSにおいて、特定のユーザーだけ利用できるネットワーク環境を
構築することはセキュリティの観点から重要。

####サブネットとは
VPC内に構成するネットワークセグメントのこと。
１つのVPCに対して１つ以上のサブネットで構成される。

####ルートテーブル
サブネット内インスタンスに対する静的ルーティングを定義するもので、
設定はサブネット単位で行う。
ルートテーブル内のデフォルトゲートウェイ（0.0.0.0/0）へのルーティングに、
インターネットゲートウェイを指定したサブネットがパブリックサブネット
インターネットゲートウェイを指定してないサブネットがプライベートサブネット

**パブリックサブネット**
グローバル環境と通信できるサブネット。
通信先：インターネットゲートウェイ
パブリックIP：もつ
プライベートIP：もつ

**プライベートサブネット**
グローバル環境と通信できないサブネット。
通信先：NATゲートウェイ（※option）
パブリックIP：持たない
プライベートIP：もつ

プライベートサブネットはパブリックIPを持たない代わりに
NATゲートウェイに通信を行うことでパブリックIPに変換をしてもらって
グローバルネットワークに通信できるようになる。
NATゲートウェイはプライベート側からの通信は通すが、
外側からプライベート側への通信は行わない。


####インターネットゲートウェイ（IGW）
VPC内のリソースからインターネットへアクセスするためのゲートウェイ。
IGWをVPCにアタッチすることでVPC内のリソースからインターネットへアクセスすることができる。

####NATゲートウェイ
VPC内に構成したプライベートサブネットからインターネットに接続するためのゲートウェイ。
NATゲートウェイを利用しない場合、NATインスタンスと呼ばれるEC2インスタンスを利用して、
インターネットへアクセスする。

####バーチャルプライベートゲートウェイ（VPゲートウェイ）
Direct ConnectやインターネットVPN接続するためのゲートウェイ。
オンプレミス環境と接続するVPCにアタッチして利用する。

####VPCフローログ
VPC内のネットワークインターフェース（ENI）で通信するトラフィック情報をキャプチャするサービス。
キャプチャ情報はCloud Watch Logsへ転送される。

####Elastic IP
固定のグローバルIPアドレスを提供するサービス。
EC2インスタンスにアタッチされてない場合やアタッチしているEC2インスタンスが停止されている
場合に料金が発生してします特徴がある。※グローバルIPの枯渇を防ぐため。

####VPCピアリング接続
異なるVPC間をプライベート接続するサービス。
通常接続はできないが、VPCピアリング接続をすることによってインターネット接続せず、
プライベートネットワーク内で直せる通信することができる。

####VPCエンドポイント
・ネットワークレイヤーのゲートウェイ型
⇨ルートテーブルに指定されたターゲットを追加することでS3やDynamoDBへアクセスする際、
インターネットを経由せずAWS内のプライベート接続を実現することができる。

・アプリケーションレイヤーのインターフェース型
⇨「AWS PrivateLink」とも呼ばれAWSへのAPIコールに対して、
インターネットを経由せずプライベート接続を実現することができる。

####セキュリティグループ
EC2インスタンスなどに適用するファイアウォール機能。
EC２インスタンスから出る通信を制御するアウトバウンド、
EC２インスタンスへの通信を制御するインバウンドを設定しる。

主な特徴↓
>
・許可リストを設定することができますが、拒否リストは設定できません。
・インバウンドルールとアウトバウンドルールを設定することができます
・デフォルトで、インバウンドルールを追加をするまで、全てのトラフィックを拒否する設定になっています。
・デフォルトで、アウトバウンドルールを追加するまで、全てのトラフィックを許可する設定になっています。
・インバウンドのトラフィックに対するレスポンスは、アウトバウンドのルールに関係なく許可されます。
・許可リストを設定しなければ、セキュリティグループ内のインスタンスは互いにやりとりすることはできません。
（ただし、デフォルト状態のセキュリティグループに属する場合を除きます。）
・インスタンスの起動後、どのセキュリティグループに属するか変更することできます。
・セキュリティグループの設定変更・追加は即座に反映される。


####ネットワークACL
サブネット単位で設定するファイアウォール機能。
アウトバウンド通信とインバウンド通信を設定する。

主な特徴↓
>
・VPC内に構成したサブネットごとに１つのネットワークACLを設定可能
・デフォルトは全て許可
・インバウンドとアウトバウンドそれぞれに対して許可または拒否を明示した通信制御が可能。
・ステートレス（セキュリティグループとは異なり、インバウンドとアウトバウンドに対する通信制御が必要）

[セキュリティグループとネットワークACLの違いについて※参照](https://milestone-of-se.nesuke.com/sv-advanced/aws/network-acl-and-security-group/)
【python】SlackのAPIで、複数人にメンションする

##概要
表題の通り。こちらで書いた[記事⑥](https://qiita.com/nonono_kita/items/ade838a9d3ccf0070399)のための記事。
複数人にメンションしたいとき、どうすれば良いかと考えて以下の通りに実行した。

##やりたかったこと
赤枠のように複数人にメンションしたい。
![a.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/630898/21c5f266-0ee6-bc55-a46a-7d78fbb2f4d2.jpeg)


##私が間違えたところ
通知先:記法
@user:<@user>
ここはuserなので`"user": "U012YTNNPB5"`を**使用すること。**(slackのapi`users.list`で取得可能)
`"real_name": "test_1"`ではないで注意。

##コード
```
menber = ['U012JDYRD2T', 'U012X478FNZ']
tmptmp = []
for i in menber:
    tmptmp.append("<@" + i + ">")
r = map(str,tmptmp)
mojiretsu = ' '.join(r)
text = mojiretsu + " 出勤者はステータスに合わせて、スタンプを押下してください！！"
```
①`<@user>`の形にしないといけないので、【member】を一つずつ取り出して【i】に代入。そこに文字列`"<@"`などを加える。
②`【map(str,tmptmp)】`と書いているので、リストtmptmpの全ての要素に対してstr()関数を使用。
③文字列となったリストに`' '.join`（半角アンダースペース）を追加。
④このtextを使用してpostする。

##わかったこと
苦労して`real_name`を取得したが、結局は使わなかった。
エンドポイントのパスパラメータで何をどのように使うかは事前に調べておく必要がある。
UITableViewとUICollectionViewにおいてFallbackする方法


# 環境
Xcode: Version 11.3.1 (11C505)
Swift: 5
iOS: 13.2

# 執筆きっかけ
先輩から「その方法ではUICollectionViewの場合はクラッシュするよ」と指摘されたので検証する

# その当時のフォールバック方法
*一部省略しております

```swift

 final class TableViewController: UIViewController {
     var mockError: String? // エラーを模しています
     
     private lazy var tableView: UITableView = {
             ・・・
 			・・・
             tableView.register(UITableViewCell.self, forCellReuseIdentifier: NSStringFromClass(UITableViewCell.self))
             return tableView
         }()
 ・・・
 ・・・
 }
 
 extension TableViewController: UITableViewDataSource {
 ・・・
 ・・・
     func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
         guard mockError != nil else {
             return UITableViewCell() // これが実行される
         }
 
         return tableView.dequeueReusableCell(withIdentifier: NSStringFromClass(UITableViewCell.self), for: indexPath)
     }
 
 }
 ```

上記の場合，mockErrorがnilであるため，

```swift
 guard mockError != nil else {
     return UITableViewCell()
 }
```

が実行されます．これは，Errorが発生した想定です．
TableViewの場合は，registerされていないCellを返してもクラッシュしません．

# UICollectionViewの場合
*一部省略しております

```swift
 final class CollectionViewController: UIViewController {
 
     private lazy var collectionView: UICollectionView = {
         ・・・
 		・・・
         collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: NSStringFromClass(UICollectionViewCell.self))
         return collectionView
     }()
 
     var mockError: String?
 
 ・・・
 ・・・
 
 }
 
 extension CollectionViewController: UICollectionViewDataSource {
 ・・・
 ・・・
 
     func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
         guard mockError != nil else {
             return UICollectionViewCell() // これが実行される
         }
 
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: NSStringFromClass(UICollectionViewCell.self), for: indexPath)
         cell.backgroundColor = .black
         return cell
     } 
 }
```

先程のコードをUICollectionViewに置き換えてみました．
上記を実行すると．．．

```
 Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'the cell returned from 
- collectionView:cellForItemAtIndexPath: does not have a reuseIdentifier 
- cells must be retrieved by calling 
- dequeueReusableCellWithReuseIdentifier:forIndexPath:'
```

上記の通り，UICollectionViewの場合は，registerしたCell以外を返すとクラッシュします
よって，下記の用に書き換えます

```swift
 guard mockError != nil else {
     return collectionView.dequeueReusableCell(withReuseIdentifier: NSStringFromClass(UICollectionViewCell.self), for: indexPath)
 }
```

# まとめ
今後TableViewの仕様が変わる可能性も考えて，フォールバック時にはregisterしたCellをどちらも返すようにします
ubuntu + webpack + typescript でlibxmljsを使う

# タイトルの設定で動かない

# エラー
こんな実行時エラー

```
internal/validators.js:117
    throw new ERR_INVALID_ARG_TYPE(name, 'string', value);
    ^

TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received undefined
    at validateString (internal/validators.js:117:11)
    at dirname (path.js:1128:5)
    at Function.getRoot (webpack:///./node_modules/bindings/bindings.js?:154:13)
    at bindings (webpack:///./node_modules/bindings/bindings.js?:60:32)
    at eval (webpack:///./node_modules/libxmljs/lib/bindings.js?:1:92)
    at Object../node_modules/libxmljs/lib/bindings.js (/home/user/dist/index.js:118:1)
    at __webpack_require__ (/home/user/dist/index.js:20:30)
    at eval (webpack:///./node_modules/libxmljs/index.js?:4:16)
    at Object../node_modules/libxmljs/index.js (/home/user/dist/index.js:107:1)
    at __webpack_require__ (/home/user/dist/index.js:20:30) {
  code: 'ERR_INVALID_ARG_TYPE'
}

```

# 対応
ここの[記述どおり](https://github.com/libxmljs/libxmljs/issues/253#issuecomment-443446212)に修正する。
node_modules/libxmls/lib/bindings.js

```javascript
// module.exports = require('bindings')('xmljs');
module.exports = require('bindings')({
    "bindings": "xmljs",
    "module_root": process.cwd() + "/node_modules/libxmljs",
});

```
GitHub、作業前・プルリク前にpull-rebaseするメモ

[GitHubのフォークを同期するメモ](https://qiita.com/414_cherry/items/924a034c8baaec971f71)
の改良版。

何をしているか↓
[Github で Fork してから Pull Request をするまでの流れ][link-fork]
これの後半と同じ。図があって分かりやすい。

##上流リポジトリを確認
upstreamが正しいか確認。originは自分のGitHubリポジトリ。

```
$ git remote -v
origin  https://github.com/自分のユーザー名/リポジトリ名.git (fetch)
origin  https://github.com/自分のユーザー名/リポジトリ名.git (push)
upstream    https://github.com/上流リポジトリのユーザー名/上流リポジトリ名.git (fetch)
upstream    https://github.com/上流リポジトリのユーザー名/上流リポジトリ名.git (push)
```

指定方法

```
$ git remote add upstream https://github.com/上流ユーザー名/上流リポジトリ名.git
```


##pull --rebase
上流リポジトリ(upstream)の最新の状態をローカルのファイルに同期させる。

`git pull origin master`＝`git fetch`＋`git merge origin/master`
`git pull --rebase origin master`＝`git fetch`＋`git rebase master`
mergeだとマージ履歴がそのままきれいに残る、そのせいで複雑になる。
rebaseは履歴がすっきりする、そのせいで（滅多に起こらないけど）コンフリクトした時の修正が大変。
[らしい][link-rebase]。

```
$ git pull --rebase upstream master

$ git fetch upstream
$ git merge upstream/master
```

##push
上流リポジトリ→ローカルのファイルの最新状態を自分のGitHubリポジトリ（origin）にプッシュする。

```
$ git push origin master
```
この後、GitHubでプルリク送ったり、作業したり。
##参考
[git pull と git pull –rebase の違いって？図を交えて説明します！][link-rebase]
[Github で Fork してから Pull Request をするまでの流れ][link-fork]

[link-rebase]:https://kray.jp/blog/git-pull-rebase/ "参考"
[link-fork]:http://kik.xii.jp/archives/179 "参考"
cloud monitoring によるGCLB p99 latency json出力と処理

都合によりGoogle Cloud Load Balancing(GCLB)によるp99 latencyをjsonとして出力した上でパーセンテージとして出力する必要があったのでこちらにその方法を記録する。

必要となるAPIリクエストはGCPのページで公開されている[テスト機能](https://cloud.google.com/monitoring/api/ref_v3/rest/v3/projects.timeSeries/list#try-it)を使うのが手っ取り早い。

```
curl \
  'https://monitoring.googleapis.com/v3/projects/PRJECT-NAME/timeSeries?aggregation.alignmentPeriod=60s&aggregation.crossSeriesReducer=REDUCE_PERCENTILE_99&aggregation.groupByFields=metric.labels.REDUCE_PERCENTILE_95&aggregation.perSeriesAligner=ALIGN_PERCENTILE_95&filter=project%3D%22PROJECT-NAME%22%20AND%20resource.labels.url_map_name%3D%22k8s-XXXXXXXXXXXXXXXXXAND%20metric.type%20%3D%20%22loadbalancing.googleapis.com%2Fhttps%2Fbackend_latencies%22&interval.endTime=2020-05-17T03%3A20%3A20.426432489Z&interval.startTime=2020-05-10T03%3A20%3A20.426432489Z&key=[YOUR_API_KEY]' \
  --header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
  --header 'Accept: application/json' \
  --compressed
```

リクエスト結果はこのようなjsonとして出力される。

```
{
  "timeSeries": [
    {
      "metric": {
        "type": "loadbalancing.googleapis.com/https/backend_latencies"
      },
      "resource": {
        "type": "https_lb_rule",
        "labels": {
          "project_id": "PROJECT-NAME"
        }
      },
      "metricKind": "GAUGE",
      "valueType": "DOUBLE",
      "points": [
        {
          "interval": {
            "startTime": "2020-05-17T03:22:20.426432Z",
            "endTime": "2020-05-17T03:22:20.426432Z"
          },
          "value": {
            "doubleValue": 432.28348532753915
          }
        },
        {
          "interval": {
            "startTime": "2020-05-17T03:21:20.426432Z",
            "endTime": "2020-05-17T03:21:20.426432Z"
          },
          "value": {
            "doubleValue": 596.89633564125677
          }
        }
      ]
    }
  ]
}
```

responseをファイルに出力した場合、jqコマンドを使うことによりp99latencyのみ出力することができる。

```
$ cat response.json | jq  '.timeSeries[].points[].value.doubleValue'
432.28348532753915
596.8963356412568
```

この場合、doubleValueのkeyにp99が出力されているのでそちらを取得している。

次に、例として７日間のp99データを取得した上で、そのlatencyがどの程度1000msのしきい値以内に収まっているかを出力する。

```
$ cat response_7day.json | jq '.timeSeries[].points[].value.doubleValue' | wc -l
   10034
$ cat response_7day.json | jq '.timeSeries[].points[].value.doubleValue' | awk '{ if($1>1000)  fp++; else low++ }END{print " violation: " fp " / within norm: " low}'
 vaiolation: 47 / within norm: 9987
```

この例では10034件中47件が1000msのしきい値を超過している。逆に言うと、9987件はしきい値内に収まっており、これは9987/10034、つまり現状で99.53%という状況となっている。
先日いよいよAnimate.cssがv4になったのでwow.jsの使い方にコツがいる

[Animate.css](https://animate.style/)とWOW.js、駆け出しwebエンジニアなら誰しもが一度は通る道ですよね。
とくにWOW.jsのはっちゃけたオフィシャルサイトは印象強いかも。

> WOW.js
> 本家: https://github.com/graingert/wow
> Fork: https://wowjs.uk/
> Forkの方がStar多い...。内容はほぼ同じです。

そんな彼らですが、先日の[Animate.css v4.0.0リリース](https://github.com/animate-css/animate.css/releases/tag/v4.0.0)で、使い方にコツがいるようになりました。

## 変更点
- クラス名にprefixがつくようになった
    - Animate.cssから提供される全てのクラス名に`animate__`というprefixがつきます。
- utilityクラス名の命名が変更になった?(DurationとかDelayとか)

## ① Animate.cssを導入
### `npm`の場合
`npm install animate.css --save`とか`yarn add animate.css`とかする

node_modules下のcssファイルは `~` を使って読み込むのですよ。こんな感じ▼

```scss
@import "~animate.css/animate.min.css";
```

### `CDN`の場合
公式サイトに沿ってCDN経由で読み込む。

## ② WOW.jsを導入
GitHubからローカルに導入するか、`npm install wowjs`でいけます。探すとCDNもあります。（公式からの案内はない）。

> 本家 ... `wowjs`
> Fork ... `wow.js`

## ③スクリプトを配置

Typescriptの例ですがJavascriptでも同じです。
TSの場合はdefinition fileは提供されていないので `require` 関数で読み込みます。
ESLintを導入しているひとは例外を認めるコメントを書く必要があるかもです。下を参考にどうぞ。

```app.ts
// eslint-disable-next-line @typescript-eslint/no-var-requires
const WOW = require('wow.js');

new WOW({
  animateClass: 'animate__animated'
}).init();
```

これだけで従来通り使えます。

ただしアニメーションのクラス名も
`fadeIn` -> `animate__fadeIn`
と変わっているのでお気をつけくださいまし。
Qiskitで組み合わせ最適化問題解いてみた

以前blueqatで組み合わせ最適化問題を実装しました（blueqatの記事は[こちら](https://qiita.com/Tusnori/items/71ea8d01fb4892e0eae9)）が、今回はQiskitで実装していきたいと思います。この記事は実装方法の確認を目的としているため、組み合わせ最適化問題自体は簡単なものを取り扱いたいと思います。


# 解く問題
解く問題は以前と同じです。以下のハミルトニアン$H$が最小となる$q(0)$、$q(1)$の組み合わせを求めます。
$$
 H = 1 - q(0) - q(1) 
$$
なお、$q(0)$、$q(1)$は0もしくは1のどちらかの値となります。この問題設定では、$q(0)=q(1)=1$のときハミルトニアン$H=-1$で最小値となります。

## 補足情報
ちなみに、すべての$q(0), q(1)$の組み合わせについてハミルトニアンは以下の値となります。

- $q(0)=0,q(1)=0 \rightarrow H = 1$ 
- $q(0)=0,q(1)=1 \rightarrow H = 0$
- $q(0)=1,q(1)=0 \rightarrow H = 0$
- **$q(0)=1,q(1)=1 \rightarrow H = -1$**

# 実行環境について
Google Colabratoryで実行します。Qiskitのバージョンは「0.14.1」となります。

# ソースコード
Qiskitをインストール

```
pip install qiskit
```

Qiskitの必要パッケージのインポート

```python
from qiskit import BasicAer
from qiskit.aqua.algorithms import QAOA
from qiskit.optimization.algorithms import MinimumEigenOptimizer
from qiskit.optimization import QuadraticProgram
```

変数、ハミルトニアンの定義

```python
qubo = QuadraticProgram()
#バイナリ変数定義
qubo.binary_var('q0')
qubo.binary_var('q1')
# ハミルトニアン定義
qubo.minimize(linear=[-1,-1],constant=1.0)
print(qubo.export_as_lp_string())
```
変数、ハミルトニアンの定義結果は以下の通りです。

```
\ This file has been generated by DOcplex
\ ENCODING=ISO-8859-1
\Problem name: CPLEX

Minimize
 obj: - q0 - q1 + 1
Subject To

Bounds
 0 <= q0 <= 1
 0 <= q1 <= 1

Binaries
 q0 q1
End
```
QAOAで定義したハミルトニアンを解きます。

```python
# MinimumEigensolverの初期化
qaoa_mes = QAOA(quantum_instance=BasicAer.get_backend('statevector_simulator'))

# Optimizerの作成
qaoa = MinimumEigenOptimizer(qaoa_mes) 

#QAOA計算/結果出力
qaoa_result = qaoa.solve(qubo)
print("QAOA result:")
print(qaoa_result)
```
実行結果は以下の通りです。

```
QAOA result:
x=[1.0,1.0], fval=-1.0
```
うまく解を求めることができました！

# 実装してみた感想
実装してみた感想は「書きにくい・・・」です。特に違和感があるのは、ハミルトニアン定義部分です。バイナリ変数q0、q1をSympyのSymbolみたいに扱えると思っていたんですが、そうじゃなさそうです。

# 最後に
Qiskitでのもっといい実装方法があれば教えてください。個人的にあまりスマートじゃないなーと思っているので。