OmniAICreator/Qiita-1.07M huggingface dataset:
MySQLでデータベースを削除する

自分の忘備録としてMySQLで使わなくなったデータベースの削除方法を残します


#消去の流れ



##1.MySQLにログイン
MySQLを使用するには、ターミナルからログインします。
ホームディレクトリから接続します。

**『-u root』**はオプションで、**「ユーザーは『ルート』でログインする」**という意味です。 
ここでいうルートとは、MySQLであらかじめ用意されているユーザーのことです。







```

% cd

# MySQLに接続
% mysql -u root

```




 MySQLに接続すると以下のような表示になリます。

```sql

% mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 428
Server version: 5.6.47 Homebrew

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

```
SQLはmysql>の続きから入力して実行ができます。








##2.SHOW文で消したいデータベースを確認

```sql

mysql> SHOW DATABASES ;
```


##3.DROP文でデータベースを削除

```sql

mysql> DROP DATABASE 《データベース名》;
```
tmux on Ubuntu


aptを使った方法でも良いが，最新版が入らない可能性がある．

```bash:aptでインストール
apt install tmux
```

ソースコードからビルドしてインストールする方法

```bash:ソースコードからインストール
sudo apt update
sudo apt install git automake bison build-essential pkg-config libevent-dev libncurses5-dev
cd /usr/local/src/
git clone https://github.com/tmux/tmux
cd ./tmux/
./autogen.sh
./configure --prefix=/usr/local
make
sudo make install
bash
```
SQLのグループとは何？【GROUP BY】

# SQLのグループ化がわからなかったので学びなおしました。
例えば大会社の社員情報データを保管しているデータベースがあるとして読んでいただけたらと思います。

## 使用RDBMS
PostgreSQL
## グループって何ぞや
例えば大規模の社員マスタ情報を集めたDBから**部署ごとの人数**を知るためにはどう抽出するのか。

### 一つ一つの部署ごとに検索する方法

```sql
SELECT COUNT(*) FROM menbers WHERE busho = '営業部';
SELECT COUNT(*) FROM menbers WHERE busho = '人事部';
SELECT COUNT(*) FROM menbers WHERE busho = '労務部';
```

もし他にも部署があるとキリがありませんし面倒です。

エンジニアはめんどくさがりなのでそこで登場するのがグループ化です。

```sql
SELECT count(*),busyo FROM member GROUP BY busyo;
```

## GROUP BY
GROUP BY は「〜ごと」という処理を行います。

上記の例では、全ての注文の「部署ごと」の人数を出しています。


以上です。
Refinementsで遊んでみた

## はじめに

Refinementsで遊んでみた記事です。具体的な内容としてはトップレベルでRefinementsが使えないかなと試してみたとき備忘録です。

[ブログ](https://gamelinks007.hatenablog.com/entry/2021/01/16/170807)からの転載です

## Refinementsとは

Rubyでは、後から自由にクラスにメソッドを追加することができる。

```ruby
class Integer
  def hoge
    puts :hoge
  end
end

42.hoge
# => :hoge
```

これはこれで便利なんだけど、グローバルに変更されるし、継承とかでも意図しない動きをする可能性があるのであまりいいとは言えない。

そこでRefinementsの出番。

```ruby
module Refine
   refine Integer do
      def hoge
         p :hoge
      end
   end
end

# 42.hoge
# => Error!

using Refine

42.hoge
# => :hoge
```


Refinementsでは`using`した以降で再定義したものを使える。
また`using`した箇所のファイルスコープに限定されるので影響範囲が小さくて済む。

## やりたかったこと

以下のようにトップレベルで`refine`を使って特定のクラスにメソッドを生やしたかった(毎回、`using`とか書くのが面倒だったので……)

```ruby
refine Integer do 
   def hoge
      puts :hoge 
   end
end

42.hoge

```

ただ、このコードは`refine`というメソッドが定義されていないのでエラーになる。

## やってみた

で、出来そうか試してみたところ以下のコードで動作した。

```ruby
module Kernel
    module_function
    def refine klass, &block
        Module.new do
           refine klass do
              yield
           end
        end
    end
end

refine Integer do 
   public
   def hoge
      p :hoge 
   end
end

42.hoge
# => :hoge
```

## やっていること

Refinementsをよく使われる人は以下のようなコードで無名モジュールを使っているんじゃないかと思う。


```ruby
using Module.new {
    refine Integer do
        def hoge
            p :hoge
        end
    end
}

42.hoge
# => :hoge
```

このコードを元に`Kernel`モジュールに`refine`メソッドを作成。

```ruby
module Kernel
    module_function
    def refine klass, &block
        Module.new do
           refine klass do
              yield
           end
        end
    end
end
```

`refine`メソッドは第一引数に再定義したいクラスなどを受け取り、メソッドの再定義などはブロック引数で渡します。

これにより以下のように`hoge`メソッドを追加できます。

```ruby
refine Integer do 
   public
   def hoge
      puts :hoge 
   end
end

42.hoge
# => :hoge
```

## ただし……

ただ、このコードは`using`していないのに再定義した内容が使用できているんですよね……。

```ruby
module Kernel
    module_function
    def refine klass, &block
        Module.new do
           refine klass do
              yield
           end
        end
    end
end

# ここで usingを使っていないが作成したhogeメソッドが使えている……
refine Integer do 
   public
   def hoge
      p :hoge 
   end
end

42.hoge
# => :hoge
```

これはRefinementsの仕様通りの動きなのかがはっきりとしていないのでなぜ動いているのやら……。

それと今回のコードでは`public`を追加しないとメソッドが呼び出されなかった。

```ruby
module Kernel
    module_function
    def refine klass, &block
        Module.new do
           refine klass do
              yield
           end
        end
    end
end

refine Integer do 
   def hoge
      p :hoge 
   end
end

42.hoge
# => private method `hoge' called for 42:Integer (NoMethodError)
```

エラーから`private`メソッドとして定義されているらしいことがわかったので`public`を付けてみたら動いたという……。
この辺も仕様通りの動きなんだろうか……？

## おわりに

とりあえず、やりたいことはできた。
これが仕様通りの動きなのかは判断がつかないので、Refinementsの実装とか読んでみようかと思う。

## 参考


[Ruby の refinements の使い途](https://qiita.com/scivola/items/dc49d56c90fd0cb6d4d3)

[【Ruby Advent Calendar 2018】あなたのしらない Refinements の世界【3日目】](https://secret-garden.hatenablog.com/entry/2018/12/03/231925)

[Ruby で動的に refine を定義する](https://secret-garden.hatenablog.com/entry/2016/09/09/000000)
バイトコードと仮想マシーン

# バイトコードと仮想マシーン

### WindowsやmacOSなどのPC向けプログラムはスパコンでは動かない
パソコンとスパコンでは、CPUが理解できる命令(マシン語)が異なるから
しかし、Javaで開発したプログラムはPCでもスパコンでも同様に動く

これは、Javaコンパイラから出力されるバイトコードが特定のCPUに依存しない凡用的なマシン語であるため

Windows用のマシン語にスパコンで実行する場合にはスパコン用のマシン語に変換される

```
PCやスパコン中にある
「凡用マシン語を理解するコンピューター」がバイトコードを実行しているように見える
```
これが「Java仮想マシン(JVM)」という名前の由来

### スパコン
一般的なコンピュータでは解くことが困難な大規模で高度な科学技術計算を高速に行うことができ、主に研究機関や企業などで使われている

```
パソコンの数十万倍の速度での計算処理を可能とする高性能なコンピューターのこと
```

### バイトコード
Javaの仮想マシンのために用いられる実行可能なプログラムとしてのバイナリデータ
機械語ではなく、中間コードに分類

### 開発の流れで理解
```
コンパイル
- ソースコードはそのままでは実行できない
- コンパイルという処理を行い、ソースファイルをクラスファイルに変換する「.class」
- ソースコードの各命令をコンピューターが実行しやすいように変換したバイトコードというものが中に詰まっている
- コンパイルはコンパイラというソフトウェアを用いて誤りがあればコンパイルが失敗し誤りの箇所が指摘される

実行
- バイトコードはソースコードに比べ実行に適しているが、実行はできない
- インタリプタと呼ばれるソフトウェアに対してバイトコードの変換実行を依頼する
- インタリプタは内部にJVMという仕組みを持っていて結果としてコンピューターはソースコードで支持した通りに動作する
```
Flask(sessionで引っ張るログイン)

#初めに
- この前書いた時にログインデータ引き摺り回すの忘れてたので書く

#書く
```python:python
    if "name" not in session:
        if belong == 0:
            session["name"] = request.form["name"]
            session["sc_number"] = request.form["sc_number"]
            name = session["name"]
            sc_number = session["sc_number"]
        else:
            session["name"] = "訪問者"
            session["sc_number"] = 0
            name = session["name"]
            sc_number = session["sc_number"]
    else:
        sc_name = session["name"]
        sc_number = session["sc_number"]
```
- Cookieにあるの参照して回してく

#終わり
- 終わり！
SQL基礎

# SQL基礎の基礎 SELECT文から
### (1)SELECT文
```
select カラム from テーブル;
```
大体これでOK

複数のカラムからデータを取得する場合は下のようにカンマで区切って追加する

```
select カラム,カラム２ from kakeibo;
```

### (2)SELECT文WHEREを使う

```
select * from kakeibo where categoly = '食費';　
```

データ型はクオーテーションマーク必要
カラム名categoryから食費の入ったレコードを取得する

`where price = 1000;`
数値の場合は、''クォーテーションマークをつけない
`where purchased_at = '2010-10-09'`
日付の場合もクォーテーションマークは必要

### (3)比較演算子
大なり小なりの後にイコール＝を入れる
`>=　大なりイコール`
`<=　小なりイコール`

```
where price >= 1000; `  例:1000以上　1000より大きい
```
上記は完全一致しか拾えません

### (4)LIKE演算子
あいまい検索（ワイルドカード）
含むレコードを抽出できます

```
select * from purchases where name like '%プリン%';

前方一致
select * from purchases where name like 'プリン%'

後方一致
select * from purchases where name like '%プリン';
```

### (5)not使い方　条件を満たさないデータ取得
```
where not name >= 1000;
where not name like '%プリン';

IS NULL
IS not NULL
```

### (6)and演算子/or演算子
```
and演算子
where name = 'プリン' and price = 1000;

or演算子
where name is null or price is null;

where character_name = 'ねこ' or character_name = 'いぬ';
```


### (7)データの並び替え
order by カラム名 並べ方;
`asc　昇順に並び替える`
`desc　降順に並び替える`

```
select *
from perchsed
where price = 1000
order by price desc;
```


### (8)件数を限定する
何件を指定して取得する
My SQLやPostgreSQLでは使えますが、Oracleでは使えないんですね

```
limit データ件数;
limit 5;
```


### (9)最大値・最小値を取得する
最大・最小値を調べたいとき
NULLがあっても、最大値を調べることができ、全部の列がNULLだった場合、NULLを返す

```
select MAX(カラム名) from テーブル名	
select MIN(カラム名) from テーブル名
```
Contentfulの日本語設定（デフォルトロケール変更）

Contentful導入時にやっておきたいことのメモ。

## Contentfulにブラウザログイン

GithubあたりでSSOして、ログインしてください。

![スクリーンショット 2021-01-16 15.18.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73176/6cd0a64d-993d-15b6-65d1-ffbc53f97d74.png)

## Settings - Locales

![スクリーンショット 2021-02-06 16.40.53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73176/eb2609e6-9a93-df20-1b16-ee9eec3f0c5a.jpeg)

## 日本語（ja-JP）に変更

デフォルトは英語です
![スクリーンショット 2021-01-16 16.50.15.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73176/c311ffe1-996c-6aa8-7f40-069cb0864614.jpeg)

日本語を選択して、Saveします。
![スクリーンショット 2021-01-16 16.51.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73176/138a3f28-e3ec-0d58-7bd1-48a4c64ef690.png)

変更前のロケールの入力を求められるので、「en-US」と入力して、保存します。
![スクリーンショット 2021-01-16 16.52.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73176/27cfd7c1-cda2-e381-f2ad-77ac583fcb00.png)

一覧に戻ると、日本語がデフォルトに変更されています。
![スクリーンショット 2021-01-16 16.52.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/73176/a2886615-49b3-e8b1-c9ef-fb15a45d9edb.png)

# その他

ロケールが複数設定されていると、API（GraphQL）で取得時にロケールの絞り込みが必要になります。

[Gatsby+Contentful+GraphQLでデータが重複（2重）に取得されてハマった件](https://qiita.com/takeshi_hirosue/items/afa5dabb96a9ab2b1901)

# 参考リンク

- [Localization with Contentful](https://www.contentful.com/developers/docs/tutorials/general/setting-locales/)
- [Gatsby+Contentful+GraphQLでデータが重複（2重）に取得されてハマった件](https://qiita.com/takeshi_hirosue/items/afa5dabb96a9ab2b1901)
UITextFiledで一発でplaceHolderの色を選択できるExtensionを考えてみた

# はじめに
どうもこんにちは、TOSHです。
UITextFieldを使用したときに、textColorはそのままセットできるのに、なぜか、placeHolderの色はそのままセットできないって感じた人ことある人は多いと思います。
ということで、placeHolderについてもTextColorと同じようにセットできるようなExtensionを考えてみました。

#通常の方法
通常、placeHolderの色を変更する場合は、

```swift
let color: UIColor = ~ここで任意の色を指定する~
textField.attributedPlaceholder = NSAttributedString(
                string: "placeHolderの中の文字",
                attributes: [NSAttributedString.Key.foregroundColor : color])
```

まあ、別にそんなに大変ではないが、NSAttibutedStringを使うのかといった感じですよね。

#Extensionを用いた実装方法
```swift
extension UITextField {
    var placeHolderColor: UIColor {
        set {
            self.attributedPlaceholder = NSAttributedString(
                string: self.placeholder ?? "",
                attributes: [NSAttributedString.Key.foregroundColor : newValue])
        }
        get {
            let defaultPlaceHolderGray = UIColor(red: 0, green: 0, blue: 0.0980392, alpha: 0.22)
            guard self.attributedPlaceholder?.length != 0,
                  let placeHolderColor =  self.attributedPlaceholder?.attribute(.foregroundColor, at: 0, effectiveRange: nil) as? UIColor else {
                return defaultPlaceHolderGray
            }
            return placeHolderColor
        }
    }
}
```

extensionのなかで、Stored Propertyはできないので、Computed Propertyを使用します。
setterは簡単なのですが、意外と苦戦したのは、getter。
Place Holderのなかに文字が入っていない可能性もあるので、self.attributedPlaceholder?.length != 0でガードをする必要があります。あと、あくまで、attributedPlaceholderの１文字目を取っているだけなので、１文字目以降で文字が変わるようなAttributedString出会った場合は、うまく動いていないと思っていいでしょう。
ただ、セットすることはあってもなかなか取ってくることはないと思われるのでこれについてはあまり深く考えなくてもいい気がします。。。

# まとめ
実装していて気づいたことは、そもそも、Place Holderの色をセットしたが、中身をセットしないということはないので、textのセットと同時に行うことのできるNSAttributedStringを使用しているののだなと思いました。(Textの場合は、ユーザーが文字を入力するので、初期状態で、色を指定しておいて、Textを指定しないということがメインの使い方)
なので、せっかく作ったはいいんですけど、あまり使用されないようなExtensionだなーという感覚です。
【図解付き】開発用オレオレ認証局SSL通信(+dockerコンテナ対応) : 2021

## はじめに

オレオレ証明書使ってますか？無料でssl通信ができて便利ですよね。

![ssl-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/026f95c1-870d-ea11-b885-a449c3a465ad.png)

便利にオレオレしてたのですが、開発用 vm 内に docker コンテナを2つ起動してコンテナ間で https 通信させようとしたら **「怪しい証明局が署名した証明書やろ」** って怒られたので対処方法を記載しておきます。

``` error.log
# 怪しい証明局が署名したやろエラー
x509: certificate signed by unknown authority
```

## 怪しくないオレオレ証明書発行

手順は以下となります。
- オレオレ証明局を作成
- 作成した「オレオレ証明局」を開発用 vm に「信頼できる証明局」として登録
- 「オレオレ証明局」が署名した「オレオレ証明書」を発行

若干めんどくさそうに見えますが、mkcert を利用すると非常に簡単です。
[mkcert](https://github.com/FiloSottile/mkcert)

![ssl-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/84380faa-ba9d-868c-5537-fe1b6e188fba.png)


### mkcert インストール
``` install.sh
# https://github.com/FiloSottile/mkcert/releases より最新版をダウンロードして実行権限追加
# ubntu の場合
wget https://github.com/FiloSottile/mkcert/releases/mkcert-v1.4.3-darwin-amd64
mv mkcert-v1.4.3-darwin-amd64 mkcert
chmod +x mkcert
```

### /etc/hosts にドメイン登録

```
127.0.0.1 {domain}
```
※2021/01/23追記：/etc/hosts にドメイン登録した状態で、`mkcert -install` しないとダメなようでした。

### オレオレ証明局を作成 + 「信頼できる証明局」として登録

```
mkcert -install
```

### 「オレオレ証明局」が署名した「オレオレ証明書」を発行

```
mkcert -key-file key.pem -cert-file cert.pem {domain}
```

## コンテナ起動時に自己証明局をマウント

この状態で dockerコンテナ間で https 通信を行うと、オレオレ証明局が「信頼できる証明局」として認識されていない状態になり、**「怪しい証明局が署名した証明書やろ」** エラーとなります。

これを回避するために、VM の「信頼できる認証局」をコンテナにマウントします。

![ssl-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/16ed5059-5ffc-3134-04a9-e07d787dec17.png)

本番環境ではSSL証明書発行業者によって署名されたSSL証明書を利用するため、この処理は不要となります。
通常のdocker-compose.yaml ではなく、docker-compose.override.yaml に記載しておき、本番環境には docker-compose.override.yaml をコピーしない様にします。

```
{docker-compose folder}/
 │ docker-compose.yaml
 └ docker-compose.override.yaml # 追加
```

``` docker-compose.override.yaml
  # mount 設定を追加
  volumes:
    - /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt
```

``` docker-run.sh
docker run .... -v /etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt
```

## おわりに

昔は大変面倒だったことが、簡単にできるようになってきました。
プロジェクトのスリム化が進むと共にフロントエンジニアやインフラエンジニアの境界が曖昧になってきていますので、なるべく簡単に色々な作業をこなせるようにしてより多くの要件を満たせるようにしたいものです。
JavaScriptのオブジェクト比較をできるだけ短いコードで行う

# はじめに
Reactを書いていて、initialState（初期ステート）とstate(現在のステート)の比較を行いたいことがあった。
しかし、意外とJavaScriptではオブジェクトの比較が難しかったので、できるだけ短いヘルパー関数を作ったので共有したい。

# 結論
```js:helper.js
/* オブジェクトをソート済み配列に変換する */
const objToSortedArray = obj => Object.entries(obj).sort()

/* ソート済み配列を文字列に変換して比較する */
const isEqualOneDimentionalArray = (obj1, obj2) =>
  JSON.stringify(objToSortedArray(obj1)) === JSON.stringify(objToSortedArray(obj2))

/* 再帰処理を行い、ネストされたオブジェクトまで比較する */
export const isEqual = (obj1, obj2) => isEqualOneDimentionalArray(obj1, obj2)
  && objToSortedArray(obj1).map(([key, val]) => typeof val === "object" ? isEqual(val, obj2[key]) : true)
```

```js:howToUse.js
import {isEqual} from "./helper.js"

const initialState = {
  tmpConditions: {
    target: "makeup",
    personalColor: false,
    faceType: false,
    items: []
  }
}

const state = {
  tmpConditions: {
    target: "makeup",
    personalColor: true,
    faceType: false,
    items: [1, 23]
  }
}

console.log(isEqual(initialState, state)) // false

```
Talend API Testerで簡単にbasic認証のAuthorizationヘッダを生成

# 概要

Talend API Testerを使ってbasic認証の効いているAPIにアクセスする時、いちいちユーザー名・パスワードをbase64エンコーディング計算をしてAuthorizationヘッダを入力するのは面倒です。
そんな手間を省くTalend API Testerの機能を紹介します。

# 方法

「Add authorization」を押下すれば容易に設定できます。

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441085/f44dda6f-d1b5-3838-579d-d459a99ae810.png)

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441085/47dc3776-0cf0-db33-d7c5-ab5eed6ea226.png)

![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/441085/3a907695-d799-9551-2b0f-f73cfadaaf64.png)

算出結果も合ってそうです。

```
nannany@MyComputer:/mnt/c/WINDOWS/system32$ echo john:12345 | base64
am9objoxMjM0NQo=
```
P2Pの実装

# P2Pの課題
現在P2Pはストリーミングやリアルタイムの放送型のコンテンツ配信などに使われていたり、ダウンロードの蓄積型コンテンツ配信、情報共有（コミュニティ、ファイル共有）がある.そのダウンロードの中でファイル交換による通信帯域の圧迫が起こる、その通信帯域が圧迫され回線速度が遅くなってしまうのを解決するために分散システムの仕組みを必要としている.そこで送信先のノードが通信が出来ない状況時に送信元の通信が圧迫された状態になってしまうため、圧迫された状況を改善する必要がある.

## 本研究の提案
P2Pのファイルを共有をする際に送信先と送信元が存在する。本研究の提案は送信先のpeerが何らかの通信障害または不具合で接続できなくなってしまった時の送信元のpeerがファイルを送れなくなってしまい、通信が圧迫されるのを別のpeerに送信先を移行させてできるだけ送信元のデータ送信を早く終わらせて通信帯域の圧迫を分散させる手法である。

###　提案の処理方法

まず、送信元のpeerが送信先のpeerに1024バイトの分割データを送信する.この時は送信先のpeerの接続が継続しているとする.
次に送信先のpeerからの反応がなかった場合、送信先のpeerに1024バイトの分割データを送信できないため転送のpeerに送信先を切り替える.最後に送信元のpeerの通信が改善された場合、送信元のpeerが転送のpeerに送った1024バイトの分割データを転送のpeerから送信先のpeerに送信する.

###　実装

Pythonのソケット通信を使ってP2Pの環境を構築する。

クライアント側

```
import time
import socket

def main():
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    soc.connect(("192.168.100.196", 2000))
    data = b'a' * 1024 * 1024 * 40 
    t = time.time()
    soc.send(data) 
    print(t)

if __name__ == '__main__':
    main()
```

サーバー側

```
import time
import socket

def main():
    soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    soc.bind(("0.0.0.0", 2000))
    soc.listen(1)
    soc, addr = soc.accept()
    data_sum = ''
    while True:
        data = soc.recv(1024) 
        data_sum = data_sum + str(data) 
        if not data:
            break
    t = time.time()
    print(t)

if __name__ == '__main__':
    main()
```

今回ソケット通信でP2P環境を作るためサーバー側とクライアント側で分けて作成した。

#### やってみて
完璧なP2Pの実装ができなかったので今後修正して完成させたい。
Kubernetes the hard way を初学者目線で解説する ~ #11 Podネットワークの構築

#はじめに
30代未経験からエンジニアを目指して勉強中のYNと申します。
インフラ初学者の私ですが、`Kubernetes the hard way`を進めるにあたって、インフラに関する基本的な知識を体系的に学ぶことができました。
そこで、初学者目線での学びなどを本記事にまとめておきたいと思います。

#目次
[こちらをご覧ください](https://qiita.com/theFirstPenguin/items/1f702af92f4eee83f398#%E7%9B%AE%E6%AC%A1)

#CNIとDNSアドオンによりノードを跨ぐPodネットワークを実現する
kubernetesクラスタの中のPodのネットワークは下記のように`kube-proxy`と`CNI`と`DNS`が連携することで実現しています。

* CNIはノードを跨ぐネットワークを築き、Pod間通信を可能にする
* CNIによってPodに付けられたIPアドレスを、core-DNSで名前解決する
* kube-proxyが展開するserviceに対して送られたリクエストを、どのPod宛に振り分けるかをkube-proxyが決定する

※ Podのネットワークについて、こちらの記事が分かりやすく解説しているので、ぜひ一読ください。
>[Kubernetesネットワーク 徹底解説](https://zenn.dev/taisho6339/books/fc6facfb640d242dc7ec)

ここからは、下図のように、それぞれのworkerノードの中にstatic-Podとして`core-DNS`と`Weave`をデプロイし、ノードを跨ぐPodのネットワークを実現します。
![スクリーンショット 2021-01-16 16.15.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/f315e2b1-50f0-4adf-3770-44c98dd2eb77.png)

##Provisioning Pod Network
###CNIプラグインのインストール
```worker-1.node/worker-2.node
wget https://github.com/containernetworking/plugins/releases/download/v0.7.5/cni-plugins-amd64-v0.7.5.tgz
```
```worker-1.node/worker-2.node
sudo tar -xzvf cni-plugins-amd64-v0.7.5.tgz --directory /opt/cni/bin/
```
###Weave-Podのデプロイ
```master-1.node
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"
```
##Deploying the DNS Cluster Add-on
```master-1.node
kubectl apply -f https://raw.githubusercontent.com/mmumshad/kubernetes-the-hard-way/master/deployments/coredns.yaml
```
Splunkでイベントをグループ化する

[Master Joining Datasets
Without Using Join])https://conf.splunk.com/files/2019/slides/FNC2751.pdf)
や
[About event grouping and correlation](https://docs.splunk.com/Documentation/Splunk/8.1.1/Search/Abouteventcorrelation)
に書いてあることを改めてまとめてみたいと思います。

:koala: でも書いてなかったか〜

#解説
![Search_event_grouping_flowchart](https://docs.splunk.com/images/8/8e/Search_event_grouping_flowchart.png)
英語なので日本語に直してみる。
`yes`は段落を変えます。


- データの1つのサブセットは静的なままか、ほとんど変化しないですか？
    - `lookup`を使ってください
- 検索条件を単純な分離として書けますか？ 
- 条件付き eval 式でグループ化を定義できますか？
    - 一定時間以上の大きなグループを分割しますか？
        - `transaction`を使ってください
    - IDなどのフィールド値でグループ化を定義できますか？
        - このフィールドは再利用されますか？(そうでなければ、それらは一意です)
        - グループ化されたイベントの全文を見る必要がありますか？
            - `transaction`を使ってください
    - 開始や終了などのパターンでグループ化を定義できますか？
        - `transaction`を使ってください
    - `stats`を使ってください
    - コマンド一つでは無理です。
- `join`か`append`を使ってください。

`transaction`人気:sweat:

_条件付き eval 式でグループ化を定義できますか？_　がここの肝だと思う。

[Splunkで先月比のグラフをつくる](https://qiita.com/toshikawa/items/f0d60a242b5b03645653)とか、検索期間とかindexとかsourcetypeが別な検索結果をくっつけようとした時、単純に考えると`join`を使いたくなります。

でも**`join`が使える≒`stats`でまとめられる。**のはず。

#例
```java:あんまりよくない例だけど
index=_audit  earliest=-2w@d 
| eval period=if(_time < relative_time(now(),"-1w@d"),"last_week","current_week")
| timechart cont=f count by period
| eval weekday=strftime(_time,"%A")
| stats max(_time) as _time sum(*) as * by weekday
| fields - weekday
| sort _time
```
２行目の`eval`でやっているように、条件に応じてラベルをつけてあげれば、あとは集計（`stats`,`chart`,`timechart`）でなんとかなる。

`timechart`後に`stats`はイベントがない期間を`0`にすることもできていろいろと応用が聞きますね :smile:

[evalで条件](https://community.splunk.com/t5/Splunk-Search/How-to-create-a-list-of-literal-values-of-strings-with-Splunk/m-p/536059#M151556)はこんな感じでもかけますので、いろいろと頑張りがいがあります。

```java:timechartは引数が一つ
(index=_audit  earliest=-60m) OR (index=_internal user=* earliest=-10m)
| eval header=index.":".user
| timechart cont=f span=1m count by header
| rename VALUE_* as "*"
```
`timechart`は引数が一つなので、最初にくっつけてしまえば大丈夫です。

#まとめ

個人的な感想では
**join** << **stats** < **dedup** なので、`sort`して一番上の値になるのであれば、`dedup`が一番速いです。

`coalesce`を使えば、どっちか片方にしかないフィールドもまとめられます。

`join`は検索時間が倍になるので、検索範囲が多い場合は

1. 一括検索
2. `eval`等で条件分離
3. `stats`等で集計

を頑張りましょう。

リクエストがありましたら、twitter、Qiita、Splunk>Answersでどうぞ。
imagenetに関する僅かな情報

#目的
ここに記載するのは、imagenetに関するわずかな情報です。
（まずひとつ。）

* imagenet-21kとimagenet-22k

##imagenet-21kとimagenet-22k
まず、結論を先に書きますと、**同じもの**です。
どちらかというと、imagenet-21kが一般的でしょうか。

##imagenet-21kという言い方をしている例。

###imagenet-21k　例１
http://proceedings.mlr.press/v97/hendrycks19a/hendrycks19a-supp.pdf

文中に、以下の説明あり。(この説明の意図がよくわからないのですが。。）
>Note that the ImageNet-21K dataset is the ImageNet-22K dataset with the ImageNet-1K classes held out.

###imagenet-21k　例2
https://github.com/dmlc/mxnet-model-gallery/blob/master/imagenet-21k-inception.md
ちなみに、21kとは、21,841 classes　の意味です。

###imagenet-21k　例3
https://blog.tensorflow.org/2020/05/bigtransfer-bit-state-of-art-transfer-learning-computer-vision.html
imagenet-21kのリンク先が、imagenetそのもの。
http://www.image-net.org/about-stats
（Total number of non-empty synsets: 21841）



#imagenet-22kという言い方をしている例

###imagenet-22k　例１
https://github.com/lukasruff/Classification-AD

###imagenet-22k　例２
https://research.fb.com/wp-content/uploads/2019/08/Scaling-and-Benchmarking-Self-Supervised-Visual-Representation-Learning.pdf

#まとめ
特にありません。
コメントなどあれば、お願いします。
記事を投稿する


備忘録的に使用しています。
間違い等々あればご指摘ください！

1.コントローラーで定義
　newとcreateの定義
　newは新規作成するだけ、定義なし　
　createは「どんな内容」を投稿するか
　　テーブル名.create(引数)　


2.投稿フォームのviewの作成
　new.html.erb ：　投稿するときに出る画面
　　・フォームタグで作成
　　form_tag ('/テーブル名' method: :post) do


　create.html.erb　：投稿後に切り替わった画面
Kubernetes the hard way を初学者目線で解説する ~ #10 RBAC for Kubelet Authorization

#はじめに
30代未経験からエンジニアを目指して勉強中のYNと申します。
インフラ初学者の私ですが、`Kubernetes the hard way`を進めるにあたって、インフラに関する基本的な知識を体系的に学ぶことができました。
そこで、初学者目線での学びなどを本記事にまとめておきたいと思います。

#目次
[こちらをご覧ください](https://qiita.com/theFirstPenguin/items/1f702af92f4eee83f398#%E7%9B%AE%E6%AC%A1)

#API-serverからkubeletへのアクセス制御の設定
下図のように、API-serverからkubeletへのアクセス制御を行います。
[参考](https://kubernetes.io/ja/docs/reference/access-authn-authz/rbac/)
![スクリーンショット 2021-01-16 15.49.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572098/951e9de2-5771-b757-de50-c41493e047c0.png)

次の流れとなります。

* (1) `ClusterRole`を定義する
* (2) `ClusterRoleBinding`で上記`ClusterRole`をkube-apiserverにバインドする


##`ClusterRole`を定義する
API-serverからkubeletへ送られる一般的なリクエストの種類を定義しています。

```master-1.node
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: system:kube-apiserver-to-kubelet
rules:
  - apiGroups:
      - ""
    resources:
      - nodes/proxy
      - nodes/stats
      - nodes/log
      - nodes/spec
      - nodes/metrics
    verbs:
      - "*"
EOF
```
##`ClusterRoleBinding`で上記`ClusterRole`をkube-apiserverにバインドする
上記で定義した`ClusterRole`を`kube-apiserver`というuserに許可します。

```master-1.node
cat <<EOF | kubectl apply --kubeconfig admin.kubeconfig -f -
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: system:kube-apiserver
  namespace: ""
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kube-apiserver-to-kubelet
subjects:
  - apiGroup: rbac.authorization.k8s.io
    kind: User
    name: kube-apiserver
EOF
```
オレオレgoimportsを作ってみた

# やりたいこと、作ったもの

## `goimports`最高

`goimports`はGoのCLIツールで、`*.go`ファイルに対して↓を実行してくれます。

- `import`していない外部パッケージを`import`してくれる
- 使っていない`import`は削除してくれる
- 最後に`gofmt`もかけてくれる

## でも`goimports`は変な空行を入れてくる

[github.com/golang/go/issues/20818](https://github.com/golang/go/issues/20818) のIssueにある通り、`goimports`は変な空行を入れてきます。
こうなっている理由は単に「仕様が決まっていないから」で、Issueでも4年間くらい議論され続けています。

## 空行を最低限にする`goimports`を作った

こういう状況ならオレオレ`goimports`を自作するしかないだろうと思って作ってみました。

https://github.com/rinchsan/gosimports

どれだけ空行を入れていようが順番をバラバラにしていようが、問答無用で空行の数を最低限にしちゃいます。
つまり標準パッケージとそれ以外の間に空行を1つだけ入れます（本家と同じく`-local`オプションを使えばプロジェクト内のパッケージの前にも空行を入れることができます）。
`import`ブロック内にコメントを書いていた場合も問答無用で削除しちゃいます（これはいい感じの仕様があれば改善したいなと思っています）。

# 作り方

今回作った`gosimports`は本家の`goimports`のコードを改変する形で実装しました。

## goimportsの処理は大きく分けると3つ

### 1. importするパッケージを整理する

`*.go`ファイルの中身を見て使用しているパッケージを静的解析しています。
本家のソースコードでいうと [このあたり](https://github.com/golang/tools/blob/b894a3290fff7ed8373c3156460600f8216a6c2d/internal/imports/fix.go#L521-L528) ですね。
今回の自作ツールではここはまったく改変していません。

### 2. グループごとに空行を入れる（gosimportsはここを変えた）

`gofmt`は`import`ブロック内の空行で区切られたパッケージ群をそれぞれAlphabetical orderにソートします。
なので本家`goimports`は出来るだけキレイにするために(?)、標準パッケージとそれ以外の間に空行を入れる処理を`gofmt`の前段に行っています。
ソースコードでいうと [このあたり](https://github.com/golang/tools/blob/b894a3290fff7ed8373c3156460600f8216a6c2d/internal/imports/imports.go#L311-L346) ですね。

### 3. gofmtを実行する

最後に`gofmt`をかけて終了です。

## 2番の処理を改変した

今回自作したほうの`gosimports`では、↑の2番の処理を改変しています。
ソースコードでいうと [このあたり](https://github.com/rinchsan/gosimports/blob/3e853eb6aaf9d3fe1101b3477604217bc60d7519/internal/imports/imports.go#L301-L344) です。
本家の方にあった`addImportSpaces`関数を`separateImportsIntoGroups`関数に変更しています。
`import`のグループ分け（標準パッケージとそれ以外とか）はすでに本家のほうに [分類機能](https://github.com/golang/tools/blob/b894a3290fff7ed8373c3156460600f8216a6c2d/internal/imports/fix.go#L62-L69) が実装されていたのでそれを使いまわしました。

# 余談

## 派生OSSはオリジナルのライセンスを保持する

Goのツール群は多分だいたいBSDライセンスというライセンスのもとでOSSとして公開されていて、`goimports`もそうです。
BSDライセンスで公開されているプロジェクトは、ライセンスをそのまま保持しつつオリジナル著者の名前をプロモーションとかで使ったりすることをしなければ、自由にソースを改変・再配布してもオーケーです。
今回作った`gosimports`でもオリジナルのライセンスをそのまま保持しています。 OSS最高。

## コード生成などにgofmtは特に便利

今回作った`gosimports`はコード生成をしている部分がかなり適当に作っています。
タブ文字がなかったり無駄な空行とかが入りまくったりしています。
でもその後段で実行している`gofmt`がすべてをキレイにしてくれるので、実装するのがとても楽でした。
普段から`gofmt`にはお世話になっていますが、コード生成とかを実装するときには特に便利だなと思いました。

## Renovateとrelease-drafterがとても便利

`gosimports`が依存しているパッケージは`golang.org/x/mod`と`golang.org/x/tools`だけですが、`golang.org/x/tools`はgitのタグが切られておらずリリースは最新のコミットハッシュが更新されるだけです。
[Renovate](https://github.com/renovatebot/renovate) はタグのリリースだけではなくコミットハッシュの更新にも対応しているので、ちゃんと最新に追従することができます。
あと、masterブランチにPRがマージされるたびにリリースノートに追記してくれる [release-drafter](https://github.com/release-drafter/release-drafter) もとても便利でした。

## gosimportsという命名は割と気に入っている

`gosimports = simpler + goimports`です。
結構気に入っています。
javascriptでif関数やswitch関数を作る（別記事のものを参考にしました）

最初に前提として書いておくと、javascriptでifやswitchは文となっています。この記事では、そんな二つの文法を返り値を返せるようにiff関数やswitchf関数として実装するというものです。
https://qiita.com/Yametaro/items/17f5a0434afa9b88c3b1
の感想で書いていたものになります。このページに掲載するプログラムは元記事の物を参考にしています。
#if関数改めiff関数
　これに関しては、元記事の中でも元記事の感想欄でも指摘されてましたが、通常は三項演算子を使ってください。
　元記事の感想欄で失敗したので、省略はできないとします。
　感想欄でも書いたものになりますが、thenとelseの順番が逆でもいいバージョンを作ってみました。

```javascript
const iff = cond=>{
  const met = cond2=>func=>{
    const revmet = revfunc => {
      return cond2? func():revfunc();
    }
    return (cond==cond2)?{else:revmet}:{then:revmet}
  };
  return {then:met(cond),else:met(!cond)};
}
//以下サンプル
a=true;
document.write(iff(a).then(()=>"that is right<br>").else(()=>"that is wrong<br>"));
document.write(iff(a).else(()=>"that is wrong<br>").then(()=>"that is right<br>"));
```
いい実装かはわかりませんが、仕組みを説明します。最後の```return {then:met(cond),else:met(!cond)};```というところを見てください。thenを先にした時とelseを先にした時で、引き渡している条件が逆転しています。これが肝となっています。cond（指定した条件式）とcond2を整理したいと思います。

| thenが先かelseが先か | cond | cond2 |
| :------------------ |:-----|:------|
|                then |  true |  true |
|                else |  true | false |
|                then | false | false |
|                else | false |  true |
まず、最後のcond2に注目してください。cond2がtrueになるときはthenが先で条件式がtrueの時と、elseが先で条件式がfalseの時です。つまり先に指定された方の関数の返り値を返すときです。次にcond2がfalseになるときはelseが先で条件式がtrueの時と、thenが先で条件式がtrueの時です。つまり後に指定した方の関数返り値を返すときです。つまり、条件式だったり、thenとelseどっちが先かによらず先に指定した関数か、後に指定した関数かどっちの関数の返り値を返せばいいのか一緒になっています。なので、revmet関数は単にcond2によって分岐しているだけになっています。また、thenが後に来てもelseが後に来ても同じrevmetでいいというわけです。
次に、condとcond2を比較すると、両方trueの時と、両方falseの時にthenを先に指定しています。なので```cond==cond2```という式で、thenを含むオブジェクトを返すかelseを含むオブジェクトを返すかを分岐しています。
よって上記の簡単な実装で適切な返り値となっています。なかなか説明が難しかったのでうまく説明できた自信ないですけどわかりましたか？
　ちなみにelseifいりますか？といってもelse-thenの順番で書く人はelseifはどこに書くんでしょうか？
#switch関数改めswitchF関数
　ttstsfさんのプログラムを参考にしました。case関数の第二引数（カリー化されてる時ってこの言い方でいいんでしょうか？）を空にすると、次のcase関数の第二引数のが実行されます。もちろん、次のcase関数の第二引数もからならさらにその次の。最後のcase関数だけ引数は空にできません。対応させることもできましたが、意味がないので。

```javascript
const switchF = num =>{
  const caseF = num1 => num2 => casefunc =>{
    const defaultF = num1 => defunc =>{
      return (num1==undefined)? defunc():num1();
    }
    if(num1[0]==undefined){
      return (num==num2)||(num1[1]==1)?
        (casefunc==undefined)?
          {case:caseF([casefunc,1]),default:defaultF(casefunc)}
          :{case:caseF([casefunc,0]),default:defaultF(casefunc)}
        :{case:caseF([undefined,0]),default:defaultF(undefined)}
    }else{
      return {case:caseF(num1),default:defaultF(num1[0])}
    }
  }
  return{case:caseF([undefined,0])}
}
```
ちょっと説明がわかりにくかったかもしれないのであんまりいい例ではありませんが、サンプルを書いておきます

```javascript
const re = switchF(1)
  .case(0)()
  .case(6)(()=>"土日です")
  .case(1)()
  .case(2)()
  .case(3)()
  .case(4)()
  .case(5)(() => "平日です")
  .default(() => "正しい曜日番号ではありません");
document.write(re);
```
読めばわかりますが、曜日番号をもとに平日か土日か返します。
なんかこれ以外にわかりやすい使用例があれば教えてください。少なくともこの例だったら簡単なif文で調べられるのでいい例ではありません。
多分元記事の物には該当機能はなかったように記憶してます。
#他には
　他にはなんか式にしたら便利そうな文ってありましたっけ？あったら関数の実装に挑戦するので教えてください。元記事のコメントではfor関数を作った例がありました。
DATA-DOG/go-txdbでDB接続を含むテストを楽に書こう

# DB接続を含むテストはツライ

- テスト用のデータをテストケースごとに用意しないといけない。
- DBの変更結果が他のテストケースに影響を与えないようにリセットしないといけない。
- DBへの変更が他のテストケースに影響を与えるので並列実行できない。

# DATA-DOG/go-txdbを使うと改善できる

- [DATA-DOG/go-txdb](https://github.com/DATA-DOG/go-txdb) で生成することのできるDBコネクションには↓のような特徴があります。
  - `sql.DB`と互換性がある。
  - すべてのクエリが独立したトランザクション内で実行される。
  - `.Close()`を呼ぶとそのトランザクション内で実行されたクエリがすべてRollbackされる。
- これをうまく使うと、テストケースごとに独立したトランザクション内でクエリを実行することができ、テスト終了後にDB変更がRollbackされるので、テストケースごとのデータ処理が必要なくなり、他のテストケースへの影響もなくなるのでテストを並列実行することができます。
- 実際のサンプルコードは [こちら](https://github.com/rinchsan/txdb-todo) に置いています。

# 軽い解説

## [`pkg/dao/dao_test.go`](https://github.com/rinchsan/txdb-todo/blob/master/pkg/dao/dao_test.go)

- 今回はDB接続を含むコードを`dao`パッケージに置きます。
- `TestMain`を定義して、テストに必要なデータを [go-testfixtures/testfixtures](https://github.com/go-testfixtures/testfixtures) を使って挿入します。
  - `testfixtures`は平行テストに対応していないことがREADMEにも書いてありますが、今回は`TestMain`でしか呼ばれないので問題ありません。
- 後のテストで`txdb`を使うために`txdb.Register`を呼んでおきます。

```go
func TestMain(m *testing.M) {
	prepare()

	txdb.Register("txdb", "mysql", config.DB.DSN)

	code := m.Run()
	os.Exit(code)
}

func prepare() {
	db, err := sql.Open(config.DB.Driver, config.DB.DSN)
	if err != nil {
		panic(err)
	}
	defer db.Close()

	fixtures, err := testfixtures.New(
		testfixtures.Database(db),
		testfixtures.Dialect("mysql"),
		testfixtures.Directory("/go/src/github.com/rinchsan/txdb-todo/testdata/fixtures"),
	)
	if err != nil {
		panic(err)
	}

	if err := fixtures.Load(); err != nil {
		panic(err)
	}
}
```

## [`pkg/dao/user_test.go`](https://github.com/rinchsan/txdb-todo/blob/master/pkg/dao/user_test.go)

- ユーザ追加のテストを例に取ります。
  - テスト対象のコードやDBのスキーマなどの詳細はGitHubのほうを見てください。
- `sql.Open`に渡すDriverに`"txdb"`を指定して取得したコネクションを使ってテストをしていきます。
  - `sql.Open`の第2引数に渡す文字列ごとに独立したトランザクションを作成してくれます。
- `defer`で呼んでいる`db.Close()`によってテストケースごとにDBの変更がRollbackされています。
- `t.Parallel()`を利用してテストを平行に走らせることも可能です。
- ちなみに今回の例では環境変数を利用することで、ローカル開発用に使っているデータベースとは別のものを使ってテストを行うようにしていますので、詳しくは [`Makefile`](https://github.com/rinchsan/txdb-todo/blob/master/Makefile) の`test`を見てみてください。

```go
func TestUserImpl_Add(t *testing.T) {
	t.Parallel()

	cases := map[string]struct {
		user  *entity.User
		noErr bool
	}{
		"new user": {
			user:  &entity.User{Username: "rinchsan"},
			noErr: true,
		},
		"duplicate username": {
			user:  &entity.User{Username: "John"},
			noErr: true,
		},
		"empty username": {
			user:  &entity.User{Username: ""},
			noErr: true,
		},
	}

	for name, c := range cases {
		c := c
		t.Run(name, func(t *testing.T) {
			t.Parallel()

			db, err := sql.Open("txdb", uuid.New().String())
			assert.NoError(t, err)
			defer db.Close()
			impl := dao.NewUser(db)

			err = impl.Add(context.Background(), c.user)
			if c.noErr {
				assert.NoError(t, err)
			} else {
				assert.Error(t, err)
			}
		})
	}
}
```

# 感想

ビジネスロジックのテストをgomockとかを使って書くと、今回のtxdbと合わせて結構いい感じにプロジェクト全体のテストが書けそうです。
Azure IoT Hub に az-cli で pub/sub

sas トークンで接続する場合です。

```bash:publish.sh
HubName=iot-aa
deviceId=pansy
#
ddx=`date`
az iot device c2d-message send  -d ${deviceId} \
        --data "Hello World $ddx" \
        --props "key0=value0;key1=value1" -n ${HubName}
#

```

こちらのプログラムで　subscribe した結果
[Azure IoT Hub に paho で pub/sub](https://qiita.com/ekzemplaro/items/5bb6c666d9ddb0127a0f)

```text
***on_message ***
devices/pansy/messages/devicebound/%24.mid=31e11faf-385d-4ff2-a10d-ff4ed0d90205&%24.to=%2Fdevices%2Fiwata%2Fmessages%2Fdevicebound&%24.ce=utf-8&key0=value0&key1=value1&iothub-ack=none Hello World 2021年  1月 16日 土曜日 15:50:02 JST
```

次のようなメッセージが出たら、az login を行って下さい。

```text
AADSTS50132: The session is not valid due the following reasons: password expiration or recent password change, SSO Artifact is invalid or expired, session is not fresh enough for application, or a silent sign-in request was sent but the user's session with Azure AD is invalid or has expired.
```

```text
$ az login
You have logged in. Now let us find all the subscriptions to which you have access...
```

```bash:subscribe.sh
#
HubName=iot-aa
deviceId=pansy
#
az iot device simulate -d ${deviceId} -n ${HubName}
#
az iot hub monitor-events --output table --hub-name ${HubName}
#
```
お前らはまだShopifyの凄さを知らない

#はじめに
今回は少し煽りタイトルを付けました。すみません。

Shopifyは日本でも徐々に知名度は上がっていますが、まだ知らない人のほうが多いと思います。

ましてやShopifyがどれぐらい凄いのかを知っている人はそれほど多くないと思います。

今回の記事では、Shoppifyとはそもそも何なのかということについて解説して、その後にShopifyの凄さについて解説して、最後にShopifyの勉強方法についてまとめていきたいと思います。

#Shopifyとは
Shopifyとは、ECサイトを簡単に構築できるプラットフォームです。

競合としてはBASEなどがあります。BASEは皆さんも聞いたことがあるのではないでしょうか。

昨今のD2Cの大ブームもあり、アマゾンを離れて自社ECサイトを解説する企業も増えています。


#Shopifyの凄さについて
一言でいうと、Shopifyはマジで凄いです。

どれぐらい凄いのかというと、全Webサイトの3.1%がShopifyで作られているぐらい凄いです。

しかも、ここ一年ほどで1.3%程もシェアを伸ばしたそうです。

ちなみに下記が2020年11月のWebサイト向けCMSシェアのランキングです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/878708/ed1ba1b7-936c-11f9-b202-3531be01ee26.png)

[マイナビニュース](https://news.mynavi.jp/article/20201104-1448652/)

世界のWebサイトのシェア1位はお馴染みのWordPressです。38.8%は流石ですね。

というかCMSで作られてないWebサイトは39.0%しか無いんですよ。そもそもこれが驚きですよね。

WordPressが凄すぎるのは置いておいて、Shopifyのシェア率を見て下さい。

なんと3.1%もあります。ECサイト構築プラットフォームはShopifyの一人勝ちと言えるでしょう。

ちなみに、株価もここ数年で何倍にも膨れ上がっています。

##なぜShopifyが凄いのか
Shopifyの凄さは、一言で言うならコミュニティにあります。

Shopifyは拡張機能の開発やテーマ開発、アフィリエイト、Shopifyストア構築を行う方々(Shopifyパートナーと呼ばれます)を非常に優遇しており、Shopifyパートナーに数多くのメリットを提供しています。

例えばShopifyのアプリを開発すると、アプリ開発者は売上の80%を貰えますし、ストアを構築すると運営費用の20%を貰うことができます。

このようにShopifyはコミュニティを非常に優遇しているため、足りていない機能があればパートナーが開発してくれます。

ここまででShopifyの凄さについて分かって頂けたと思います。

それではこれから、Shopifyの勉強方法について簡単にまとめていきたいと思います。

#Shopifyの勉強方法
勉強方法については以前Qiitaで書いた記事が非常に好評でした。

もしよろしければ御覧ください。

[[完全攻略]Shopify学習ロードマップ](https://qiita.com/dougarokugayou/items/f9c5c15c2d5d323a63f9)

ここでも簡単に勉強方法についてまとめていきます。

##Shopify前提知識編
前提知識としては、以下のYoutuberをご覧になれば問題ないでしょう。


**[おすすめ資料]**

・[Shopifyマスターニシカワ](https://www.youtube.com/channel/UCgSBs6u71Ftxj8gGv_blOfg/videos)

##Shopify基礎知識編
Shopifyの基礎知識を入れて置きましょう。

以下の非常に長文のShopify構築ロードマップの記事を読めば、Shopifyで簡単な構築ができるようになるはずです。

**[おすすめ資料]**

[【Shopifyマスターへの道】](https://unreact.jp/blog/roadmap-before-begin)

##Shopifyコード編集　
以下のQiitaのアカウントで、ひたすらShopify独自言語であるLiquidについて解説されていました。

一読しておくことをオススメします。

[eiji saito](https://qiita.com/eijiSaito)

##やっぱり公式ドキュメントでしょ
最後は公式ドキュメントを読みましょう。

[Liquid公式ドキュメント](https://shopify.dev/docs/themes/liquid/reference/basics)

## Shopify アプリのご紹介

Shopify アプリである、「商品ページ発売予告アプリ | リテリア Coming Soon」は、商品ページを買えない状態のまま、発売日時の予告をすることができるアプリです。Shopify で Coming Soon 機能を実現することができます。

https://coming-soon.reterior.jp/

https://apps.shopify.com/shopify-application-314?locale=ja&surface_detail=%E3%83%AA%E3%83%86%E3%83%AA%E3%82%A2&surface_inter_position=1&surface_intra_position=1&surface_type=search

#最後に
今回はShopifyの凄さについてまとめていきました。

ここまで読んで頂きありがとうございました。
laravel welcome.blade.phpから他のページに遷移する方法


#投稿者の環境
1. MacBook Pro (13-inch, 2019, Two Thunderbolt 3 ports)
2. macOS Big Sur バージョン11.0.1
3. PHP 7.3.23
4. Laravel Framework 6.20.7

#はじめに
1. laravelをインストール済みであることが前提となります。
2. MVCの流れをアウトプットしやすいように`ルーティング` `コントローラー` `ビュー`の順に説明します。
3. 今回は遷移すると文字が表示されるまでとなります。



#ステップ1 welcome.blade.phpを編集しよう
laravelをインストール&ローカルサーバーを立ち上げたら大文字でlaravelという大きな文字が出てくると思います。
こちらのページからルーティングを設定しましょう。

```welcome.blade.php

<div class="クラス名">
  <a href="{{ url('/about_me/index') }}">about</a>
</div>

//{{ url('/表示させたいフォルダ名/ファイル名') }}
```

![“スクリーンショット” 2021-01-16 15.05.58.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/8ad5bd43-5099-8dd5-41d9-4cd7d72c3a18.jpeg)
divクラスの入子に`<a href="{{ url('') }}">`を作成します。
これを設定することによりルーティング化したページに飛べるようになります。
`スクショとcssは分かりやすくするために調整しています。`


#ステップ2 web.phpでルーティングを設定しよう

```web.php
Route::get('/about_me/index', 'AboutMeController@index')->name('about_me.index');

//　'/about_me/index' 検索窓をクリックしたらURLに表示される部分
/* 'AboutMeController@index' 
@ は、名前空間に属したクラスのメソッド指定の区切り。
名前空間@メソッド名　単刀直入に説明すると 
コントローラー名@viewフォルダにあるファイル名
*/
//  ->name('about_me.index'); 
nameを付けることによりルーティングに名前をつけて尚且つ分かりやすくするため。
```
![“スクリーンショット” 2021-01-16 16.06.01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/9199a83b-6680-3260-c56b-56b5463cde1e.jpeg)

###補足
vscode上にて`⌘＋p`を実行すると指定のファイル名を検索できます!!
ファイル名を探すのが難しかったら是非覚えてください!!
![“スクリーンショット” 2021-01-16 15.18.39.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/9b746453-5503-3f64-619f-f9a5bbe0724d.jpeg)

#ステップ3 コントローラーを作成しよう

```
//ターミナルにて
php artisan make:controller AboutMeController 

//命名規則 php artisan make:controller 付けたい名前+controller
/* 補足　
php artisan make:controller Testcontroller --resource
これを実行すると index create store等々の全てのコントローラーが作成される
*/
```

#ステップ4 作成したコントローラーを編集しよう
```AboutMeController.blade.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AboutMeController extends Controller
{
    public function index()
    {
        //表示させたいviewを指定させる
        return view('about_me.index');
    }
}
```
#ステップ5 viewファイルを作成しよう
viewファルを作成するには手動にて作成します。
`これからviewファイルを沢山作成する可能性がある場合はフォルダ毎に分けるのが一番分かりやすいです!!`
フォルダ名/ファイル名

#ステップ6 viewファイルに文字を入れよう

```about_meフォルダ/index.blade.php
<!DOCTYPE HTML>
<html>
<head>
    <title>About</title>
</head>
<body>
    <h1>About Me</h1>
</body>
</html>
<h1>about_meフォルダのindexファイル</h1>
```
#ステップ7 ページが遷移されるか確認しよう
ページが遷移されるかを確認するためローカルサーバーを立ち上げてください。
もし画面が遷移されない場合は下記を実行して下さい。

1. 名前に間違いがないか?ちゃんと橋渡しができているかどうか。
2. 分かりにくい場合は`php artisan route:list > route1.txt`を実行。ルーティングの一覧が出てきます。

```
ターミナルにて
php artisan route:list > route1.txt
```
以上となります。
pkg version で標準外の perl|python を使う時にバージョンチェック時 ? が出る問題の対処法

#背景
[FreeBSD 8.1-RELEASE](https://www.freebsd.org/releases/8.1R/announce.html) 以降で使われる [pkg(8)](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=pkg&dir=jpman-12.2.2%2Fman&sect=0) で管理される ports tree 更新後の差異確認コマンドとして [_pkg version_](http://koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=pkg-version&dir=jpman-12.2.2%2Fman&sect=0) コマンドを利用する事になる。

_lang_ カテゴリで複数の版が管理されていて、標準とされている版では無い物を利用中に _pkg version_ を使うと比較対象が見当たらなくなるようで正しく差異表示がされるので、その対処法。

#具体例
```text:例えばpython
> pkg version -I | grep py
py39-Babel-2.8.0                   ?
py39-Jinja2-2.11.2_1               ?
py39-alabaster-0.7.6               ?
py39-certifi-2020.12.5             ?
py39-cffi-1.14.4                   ?
py39-chardet-3.0.4_3               ?
py39-cryptography-2.9.2            ?
py39-cython-0.29.21                =
...
```
執筆現在では python のデフォルトは 3.7

```text:デフォルトの版の調べ方
> grep PYTHON_DEFAULT /usr/ports/Mk/bsd.default-versions.mk
PYTHON_DEFAULT?=        3.7
```
#スイッチ「-P」で解決
man を読めと言われれば其れ迄 :rolling_eyes: 

```text:スイッチ「-P」附加の結果
> pkg version -P | grep py
py39-Babel-2.8.0                   =
py39-Jinja2-2.11.2_1               =
py39-alabaster-0.7.6               =
py39-certifi-2020.12.5             =
py39-cffi-1.14.4                   =
py39-chardet-3.0.4_3               =
py39-cryptography-2.9.2            =
py39-cython-0.29.21                =
...
```
大体こんな感じ。
じゃが、表示の際 /usr/ports/INDEX-* からの比較では無くなり、skeleton の総なめしよるけインスコされちょる数が多いと其れなりの時間がかかりよる。

#応用編
このコマンドとスイッチの応用として、導入している版より ports tree が新しい場合にその版を表示させるエイリアスを書いておく。

```text
alias pkgold '/usr/sbin/pkg version -vPl"<" | /usr/bin/tr -d "<"'
```
メモ イヤホン抜き差し

iOSで[AudioKit](https://github.com/AudioKit/AudioKit)を利用して音を入力する機能を実装する際、本体とイヤホンのマイクを考慮する必要がある。
本体とマイクとでは、サンプルレートが異なることがあり、本体は44.1kHz、iPhone同梱のLightningイヤホンは48kHzとなる。
抜き差しは、`AVAudioSessionRouteChangeNotification`を利用するのではなく、`AVAudioEngineConfigurationChangeNotification`をトリガーにして、`AKMicrophone`を再インスタンス化しつなげ直し、`AVAudioEngine`を再開させる（`AKManager.engine.start()`)。
また、`AudioKit`が`AVAudioEngineConfigurationChangeNotification`をハンドリングしているので、事前に無効にしておく (`AKSettings.enableCategoryChangeHandling = false`)。
heroku と vercel にお手軽デプロイ

## heroku の cli を入れる

ゴニョゴニョ調べてください😃

## rails api のデプロイ heroku
できてる rails app に行く

```
cd hogehoge-api
```
heroku app を作る

```
heroku create -a hogehoge-api
```

heroku の `Deploy` タブ押して github との接続とかして、 `Deploy Branch` ボタンを押す。
終わり🙌🏽

## next.js のデプロイ vercel

vercel のマイページ行く
`New Project` を押す
github とつなぐ
`Deploy` を押す
終わり🙌🏽

# かんたんすぎる！！！！！！！！！！！！！！！

あとはそれぞれのダッシュボードでドメインの設定とかをポチポチするだけです
Markdown記法とは何か？

# Markdownとは:writing_hand:
調べてみると2014年にアメリカのジョン・グルーバーさんが作った軽量マークアップ言語の一つ。
ダウンと言っているのに、アップ？という私は無知の知です。

##(1)見出し作成 [#]
・見出し作成は # を使う
・htmlのヘッダーと同様1〜6まで大きさを選べる（#の数で調整）
　例として　'#マークダウン' こう書くと
#こうなる　←これは#1個のサイズ
次に'####マークダウン' こう書くと
####こうなる　←これは#4個のサイズ

'##'２個まではアンダーラインが引かれるようです。そして大きめ改行が入りますね。


## (2)テキストに背景黒い画面にするのは「`」
「`」　shift+@ 何ていう記号でしょうか ←調べたらバッククォートだそうです。
これをテキストの上下段に３つ連続で入れるとこうなります

```
こうなる
```

皆さん頑張って画像を張り付けて大変だなーと思いましたが違うんですね（爆）:stuck_out_tongue_closed_eyes:
これは黒板だそうです

## (3)文字背景をグレーにする [`]
インラインコードというそうです
先ほど使ったバッククォートで文字を囲むだけ
`こうなる`
説明になってないですね（笑）

## (4)太字にする [**]
アスタリスクを２こ使って囲む
**こうなる**

## (5)箇条書き [-]
「-」をテキストの前につける、テキストの上下段に改行が必要

- こうなる1  
- こうなる2
- こうなる3 

## (6)改行を挿入する [br]
<> の間にbrを入れると

```
こうなって
<br>
こうなる
```

## (7)リンクの挿入方法
[リンク名]の後に(url)を入れる
[Markdown記法とは何か？](https://qiita.com/kikana/items/8f978642420782d56f37) ←このページのリンクです
PWA+SPAのwebアプリ作成にnuxt.js + firebase(hosting, authentication, storage)がめちゃ便利だった

# 背景
　PWA＋SPAのwebアプリを作る際にnuxt.js＋firebaseを合わせて利用すると便利だったので、そこで得た知見をメモとして残しておこうと思います。まだ勉強を進めている途中のため勘違いや不明点も多々があり、もし正しいやり方などをご存知の方がいらっしゃればコメントをいただけると泣いて喜びます！

# nuxt.jsの設定値
```bash
$ npx create-nuxt-app {{ アプリ名 }}
  create-nuxt-app v3.4.0
  ✨  Generating Nuxt.js project in frame-catch
  ? Project name: {{ アプリ名 }}
  ? Programming language: JavaScript
  ? Package manager: Npm
  ? UI framework: Vuetify.js
  ? Nuxt.js modules: Axios, Progressive Web App (PWA)
  ? Linting tools: ESLint, Prettier, Lint staged files
  ? Testing framework: None
  ? Rendering mode: Single Page App
  ? Deployment target: Static (Static/JAMStack hosting)
  ? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
  ? Continuous integration: None
  ? Version control system: None
```

設定の選び方
- 基本的には他サイトを検索して出てきたおすすめ設定を利用
- PWA・SPAでなるべくスマホ上で高速に動くようにする
- firebase hostingにデプロイするため静的サイト(SSG)を使う
- インフラ（terraform）と同じリポジトリで管理をするため、ciやGitはここでは導入しない


# 使ってみて感じたメリット・デメリット

## nuxt.js

### メリット

- プロジェクトを作ってlocalでページを立ち上げるまでがめちゃ早い（railsと同じで理解してなくても動く）
- 言語やパッケージ、Lintツール、UI フレームワークなどが自由に選べる
- 静的ファイルとして出力できるためfirebase hostingにもデプロイ可能（firebase functionsを使えばSSRもすぐできるみたいです）
- (Vue.jsだから)「画面・ロジック・デザイン」をまるっとコンポーネントとして管理できる

### デメリット（≒理解していない点）

- コンポーネントの理想的な単位が難しい...
- storeの値を使う際にpage側・component側それぞれどこで呼び出した方が良いかがわからない
- (nuxt.jsだからではないが)promise系の処理が入ると画面が更新されなかったりが多発する（特にstore内でpromise系を使うと難しい。。。）

## firebase(hosting, authentication, firestore)

### メリット

- どれもjavascriptから使いやすい
- firestoreはterraformでデータを記述できるため、開発環境におけるテストデータを用意しやすい
- firestoreの権限管理(rule)の柔軟性が高く、 「userドキュメント内でroleの値がADMINのユーザーだけ、noteドキュメントの値を変更できる」といった複雑な権限管理が行える
- cloud buildからciを組む際に、[firebase コミュニティ ビルダー](https://cloud.google.com/cloud-build/docs/deploying-builds/deploy-firebase#using_the_firebase_community_builder)を利用すると簡単に実装できる

### デメリット

- (firebase側の問題ではないが)terraformからfirestore以外（authenticationなど）の設定ができない
- firestoreがNoSQLのため？N対Nが作りにくい（referenceを多用する形になる）

## ＋α：Vuetify

### メリット

- 今まで使っていたuikitと比べてデザインやコンポーネントが豊富
- Vuejsに特化しているのでデータの渡し方が簡単

### デメリット...？

- [公式ドキュメント](https://vuetifyjs.com/ja/)につながらないことがよくある（自分だけ。。。？）
- [Time pickers](https://vuetifyjs.com/en/components/time-pickers/)が時代の先取りをしすぎていて理解が追いつかなかった

# 感想
　元々自社サイトでは「S3ホスティング＋cdnで入れたvuejsでフロント作成＋uikitでデザイン」をしていたのですが、今回nuxt.js+firebaseを使ってみたら簡単＋デザインが綺麗(Vuetifyが)すぎて勢いで[自社サイト](https://www.sink-capital.com/)リニューアルをしてしまいました笑。細かい構成やコードは[こちらのブログ](https://www.sink-capital.com/blogs/nuxtjs_firebase)にまとめているので気になる方はいてみてください。（Nuxt、cloud build、terraformなどのコードや構成図などを詳しめに記載しています。）
　唯一Nuxtを使っていて気になった点は「pagespeed insights」のスコアが結構悪くなったことです。体感としてもSPAだからか最初の読み込みは少し時間がかかる印象だったので、仕方ないのかなと思いつつ今後早める方法を模索していこうと思います。
また触り初めて数週間時点で書いているので間違いやご指摘等あればコメントいただけると助かります。
最後まで読んでいただきありがとうございました。

# 参考リンク
- [公式ページ ディレクトリ構成](https://ja.nuxtjs.org/docs/2.x/get-started/directory-structure/)
- [【Nuxt.js 入門】ゼロからプロジェクトを作成するまでの手順まとめ](https://upd.world/nuxtjs-start/)
- [Nuxt.js プロジェクトを Firebase Hosting にデプロイして公開する方法](https://upd.world/nuxtjs-deploy-firebase-hosting/)
サーバー移管に伴う、Let's Encryptにて発行したSSL証明書の使い回しをしてみた

## 前提
今回サーバーA（以降、旧サーバー）からサーバーB（以降、新サーバー）へお引っ越しをする機会があり、
旧サーバーで使用していたSSL証明書を、新サーバーへ持っていきそのまま使用したかったため、以下を参考にやってみた。
以下手順であれば一瞬でもSSL化が解除されることはなくなり、安心・安全にサーバー移管可能かと思う。

> https://blog.fileshelfplus.com/vps/280

## 環境

* conoha VPS → conoha VPS
* お名前.comにて発行したドメイン（そのまま・IPアドレスの紐付けだけ変更）
* centos7 → centos7

## 手順

まずは旧サーバーへsshログイン
（基本的に **Let's Encrypt** にて発行した証明書は、```/etc/letsencrypt/```にある。）
```letsencrypt```ディレクトリ丸ごと圧縮する。

```bash:旧サーバー
$ zip -ry letsencrypt.zip /etc/letsencrypt
# または
$ tar zcvf letsencrypt.tar.gz /etc/letsencrypt
```

圧縮したファイルを新サーバーへリストア後、sshログイン。

Let’s Encrypt ユーザーガイドに従ってCertbotクライアントをインストールする。

```bash:新サーバー
$ sudo yum -y install epel-release
$ sudo yum -y install certbot
$ sudo curl https://dl.eff.org/certbot-auto -o /usr/bin/certbot-auto
$ sudo chmod 700 /usr/bin/certbot-auto
```

次にリストアした圧縮ファイルを解凍する。
解凍場所は```/etc```。

```bash:新サーバー
$ zip -ry letsencrypt.zip /etc/letsencrypt
# または
$ tar zcvf letsencrypt.tar.gz /etc/letsencrypt
```


## ドメインのIP紐付け変更
ここまで出来たらドメインの付け替えを実施。
各種サーバー会社の手順に従い、AレコードやTXTレコード、ネームサーバーの変更を行う。
今回は以下を参考にした。



> https://qiita.com/sugra511/items/3b05423d4adeeec5cdd4



最後に証明書の更新を実施しwebサーバーを更新。

```bash:新サーバー
$ certbot-auto renew
$ systemctl restart httpd
```

※必要に応じて```cron```にて証明書の自動更新設定をしておく。

```
# 以下は、毎月1日の午前4時に自動更新をするcron
# certbot-auto で証明書を更新し、apacheを再起動
# [webroot]の設定を忘れないこと

$ crontab -e
00 04 01 * * certbot-auto renew --force-renew --webroot-path /var/www/html/[webroot] --post-hook "systemctl reload httpd"
```
manimの作法 その17

#概要

manimの作法、調べてみた。
練習問題、「九九」やってみた。

#参考にしたページ。

https://qiita.com/maskot1977/items/c01180cc63aa67ac004e

#サンプルコード

```
from manimlib.imports import *

class test(Scene):
	def construct(self):
		for x in range(9):
			for y in range(9):
				A = TextMobject("{} x {} = {}".format(x + 1, y + 1, (x + 1) * (y + 1))).scale(3)
				A.shift(UP * 3)
				self.play(ShowCreation(A))
				points = []
				for i in range(x + 1):
					for j in range(y + 1):
						X = j * 0.5 - 3
						Y = 2 - i * 0.5
						points.append(Dot(point = np.array([X, Y, 0.0])))
				group = VGroup(*points)
				self.play(ShowIncreasingSubsets(group, run_time = 2.0))
				self.wait()
				self.remove(group)
				self.remove(A)



```

#生成した動画

https://www.youtube.com/watch?v=WhoECILZ5RY

以上。
ActiveRecordのdefault_timezoneについて

## 想定バージョン

Ruby 2.5系
Ruby on Rails 5.2系

## 説明
ActiveRecordが発行するタイムスタンプのtimezoneはRailsの場合、config/application.rbで定義します。

```ruby
# config/application.rb 

Rails.application.configure do
  config.active_record.default_timezone = :local
  # (ActiveRecord::Base.default_timezone = :localと同義)
  中略
end
```

この:localは何を指しているのかというとrubyプロセスタイムゾーンを指していて
rubyプロセスタイムゾーンはOSに定義されている環境変数の`TZ`を見ています。
つまりこの環境変数を設定しないとActiveRecordはdefaultのUTCでタイムスタンプを発行してしまうことになります。

例えば以下のように定義すると、 created_atやupdated_atが東京の時間になります。

```
TZ=Asia/Tokyo
```

## config.time_zoneとの違い

Railsで設定するタイムゾーンといえば、以下の方もあると思います。

```ruby
Rails.application.configure do
  config.time_zone = 'Tokyo'
end
```
こちらは`Time.zone`で取得するタイムゾーンを東京にできる設定となっています。

アプリケーション上で`Time.zone.now`を叩くと東京の現在の時間が取得できるようになります。

## 参考
[Railsタイムゾーンまとめ](https://qiita.com/aosho235/items/a31b895ce46ee5d3b444)
manimの作法 その16

#概要

manimの作法、調べてみた。
ShowIncreasingSubsets、使ってみた。

#サンプルコード


```
from manimlib.imports import *

class test(Scene):
	def construct(self):
		points = []
		for x in range(-5, 6):
			points.append(Dot(point = np.array([x, 0.0, 0.0])))
		group = VGroup(*points)
		self.play(ShowIncreasingSubsets(group, run_time = 3.0))
		self.remove(group)
		self.wait()

```

#生成した動画

https://www.youtube.com/watch?v=x5fCYTdwWys

以上。