OmniAICreator/Qiita-1.07M huggingface dataset:
Power BI: オンプレミスゲートウェイ（パーソナル）での躓きポイント

# 概要
On Premises Data Gateway (personal-mode) をインストールした際の備忘録

# 嵌った内容

## .Net 4.8 が必要
- [最小要件](https://docs.microsoft.com/ja-jp/data-integration/gateway/service-gateway-install#minimum-requirements) に記載はあるんですけどね・・<br>![2021-12-08_20h56_18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/531bac9c-c7d5-d58c-8cf4-57400a75b8f3.png)
    - 会社によっては帯域制限されてることもあるのでオフラインインストーラー作って展開しておいた方がよいかも。おいた方が便利かも・・。オンラインは帯域制限できついかもって意味で

## 同時にPrivate版を二つは入れられない。
- [関連する考慮事項](https://docs.microsoft.com/ja-jp/data-integration/gateway/service-gateway-install#related-considerations) にこちらも記載有り<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/a10eb348-b423-7eb0-d884-a4c9cce81992.png)
    - インストールは可能なので注意。動かすと、Cloud上でおかしなことになる。必ずアンインストールして、一つにしておくこと

## Enterprise/Private 共に、Proxy 設定に気を付ける
- [オンプレミス データ ゲートウェイのプロキシ設定の構成](https://docs.microsoft.com/ja-jp/data-integration/gateway/service-gateway-proxy) に記載有り。
    - ファイル名を間違えやすいのと、XML を壊さないように注意。VS-Code とかXML 対応 Editor で編集すれば無問題。

## 信頼済みサイトに以下入れる必要有

```html
https://login.microsoftonline.com
https://aadcdn.msauth.net
```

## パーソナル版で使えない機能があると、ゲートウェイの接続でエラー表示
- Direct Query を使ってると発生します。
- エラー表示される場所<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/16a257cc-35e9-42f2-b900-4d3a46d1a3a3.png)
- パーソナル版と標準版の比較は [ンプレミス データ ゲートウェイとオンプレミス データ ゲートウェイ (個人用モード)](https://docs.microsoft.com/ja-jp/power-bi/connect-data/service-gateway-personal-mode#on-premises-data-gateway-vs-on-premises-data-gateway-personal-mode)<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/bd7bade6-2aec-e69c-3555-04c7aee90a18.png)

### Direct Query to Import Query
以下とかを参考に対処

https://community.powerbi.com/t5/Desktop/How-to-change-one-table-direct-query-to-import/m-p/874634

# keyword
trouble shootings when installing on premises data gateway (personal mode)
「吉野家の牛丼 メニュー」をサクラエディタの置換を使ってmarkdown表に変換してみた。

https://qiita.com/mrrclb48z/items/8476877386b06e787a01

# 以下、古いです。

オリジナル

https://www.yoshinoya.com/menu/gyudon/gyu-don/

以下、牛丼 のメニューだけです。
どなたか全メニューをスクレーピングしてもらうと助かります。
写真があるから、メニューなのかもしれませんね。

# markdown表(2021-12-08現在)
|my追番|カテゴリー|size  |税込価格(円)|
|----|-----|------|-------|
|001 |牛丼   |小盛    |404    |
|002 |牛丼   |並盛    |426    |
|003 |牛丼   |アタマの大盛|547    |
|004 |牛丼   |大盛    |613    |
|005 |牛丼   |特盛    |778    |
|006 |牛丼   |超特盛   |899    |

# markdown(csv to markdown)の前  
my追番,カテゴリー,size,税込価格(円)
001,牛丼,小盛,404
002,牛丼,並盛,426
003,牛丼,アタマの大盛,547
004,牛丼,大盛,613
005,牛丼,特盛,778
006,牛丼,超特盛,899



# サクラエディタ Ver 2.4.0 (Beta5)のマクロ
テキストファイルから、抽出を使わず置換です。

```
//キーボードマクロのファイル
ReplaceAll('^(?!.*(th class="menu-size|円<span class="menu-tax)).+$', '', 28);	// すべて置換
ReDraw(0);	// 再描画
ReplaceAll('^\\r\\n', '', 28);  // すべて置換
ReDraw(0);  // 再描画
ReplaceAll('</th>\\r\\n', ',', 28);   // すべて置換
ReDraw(0);  // 再描画
ReplaceAll('                                                      <th class="menu-size">', '', 28);  // すべて置換
ReDraw(0);  // 再描画
ReplaceAll('</span>', '', 28);  // すべて置換
ReDraw(0);  // 再描画
ReplaceAll('([^,]*),([^,]*tax">)', '$1,$3', 28);  // すべて置換
ReDraw(0);  // 再描画
```

# 参考

https://qiita.com/mrrclb48z/items/cdaf9a431ff06507556f

https://qiita.com/yamamoto_hiroya/items/481eb05e38aeac87c17b
独学でWeb開発系言語に挑戦したい文系ド素人にはまずPHPがおすすめかもしれない。

外国語にせよプログラミングにせよ、スクールなどに通うと値が張るので、「まずはお試しで」というスタンスなら、なるべく独学で勉強したいと思う人も多いと思います（妄想ですが…）。
Java,Rubyなど様々な言語があって、それぞれに特徴がありどれを選べばいいか分からない場合は、偏見かもしれませんがまずはPHPがおすすめです。PHPなら、かなり無茶苦茶な書き方でもとりあえず動いてくれることが多いので、根気よくやればとりあえず「サービス着想～完成」までどうにかこぎつける見込みが大きい…はずなので、実践レベルで使用できるかは置いておいて、まずは一通りの作業を終えて、自分がプログラミングに向いているかどうか、好みや適性を判断する上での良い材料になると思います。
一度完成までこぎつけば、次回以降のWebアプリ作りに取り掛かる際の自信につながるので、文系やプログラミング素人に限らず、もしバッグエンドに興味があって、まだ触ったことがないのであれば、まずは気軽にPHPから触ってみるとよいかもしれません。
python 3.10からの新機能 match - case を使ったIF文置き換えの紹介

この記事は [Python Advent Calendar 8日目](https://qiita.com/advent-calendar/2021/python) の記事となります。

## はじめに

今年開催されたPyConJP 2021にてキーノートセッションされていたブラント・ブーカー氏の発表にあった、「match - case」構文による条件分岐について、 Pythonistaが馴染み薄いかと思いこの場で紹介しようと思った次第です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186010/dc561691-7660-ba5a-b0a2-243d531e743b.png)
↑は [PyConJP 2021 振り返り会](https://youtu.be/PpLymJQaLqc?t=3865) にて発表した際の資料より。

## match - case 構文とは

端的に言うなら値に応じた処理の分岐に使用する構文。条件分岐が厳密に定められることや、条件が入れ子になってしまった場合にもスッキリとまとまる（言い方を変えるなら波動拳みたいにはなりにくくなる）こと、パターンが柔軟なことがあげられます。

具体的な使い方については、多くのPythonistaが記事にしていただいているのでそちらを見ていただくことにしましょう。

- [Python3.10の新機能(2) - Pythonにmatch文がやってくる](https://qiita.com/ksato9700/items/3ce4c68c0d713874b693)
- [Python3.10 新機能！パターンマッチ構文解説](https://qiita.com/Supu/items/fa8ed3d73eb2748808ae)

## 置き換えの紹介

### fizzbuzz問題

有名な問題です。１から100までの数字の内、3の倍数ならFizz、5の倍数ならBuzz、両方に当てはまるならFizzBuzzを返す問題です。

シンプルにif文を使うと以下のコードになります。

```python
for i in range(1, 101):
    if i % 3 == 0 and i % 5 == 0:
        print("FizzBuzz")
    elif i % 3 == 0:
        print("Fizz")
    elif i % 5 == 0:
        print("Buzz")
    else:
        print(i)
```

これがmatch - case構文だとこうなります。

```python
for i in range(1,101):
    match i:
        case i if i % 3 == 0 and i % 5 == 0:
            print('FizzBuzz')
        case i if i % 5 == 0:
            print('Buzz')    
        case i if i % 3 == 0:
            print('Fizz')
        case _:
            print(i)
```

あれ？これじゃ別にmatch - case構文である必要はないのでは？と思った方がいると思いますので、視点を変えていきましょう。
(ちなみに上記のようにcaseに条件をつけるやり方をifステートメントみたいに呼びます)

### HTTPステータスを分岐させる

HTTPステータスが200なら`OK`、404なら`Not Found`, 334なら ~~`なんでや阪神関係ないやろ`~~ と返すようなコードを書いてみましょう。

#### if文

```python
http_status = 404

if http_status == 200:
    print("OK")
elif http_status == 404:
    print("Not Found")
elif http_status == 334:
    print("なんでや阪神関係ないやろ")
```

#### match - case構文

```python
http_status = 404

match http_status:
    case 200:
        print("OK")
    case 404:
         print("Not Found")
    case 334:
         print("なんでや阪神関係ないやろ")
```

match - case 構文のほうが条件に必要な変数の記載がない分、スッキリと見えませんか？

### 入力された座標によって条件を変化させる
X座標とY座標を持ったリストを受け取ったときに、X座標が0から離れている場合、Y座標が0から離れている場合、両方離れている場合で条件を変化させるようなプログラムを書きます。

#### if文

```python
point = (33, 4)
if point[0] == 0 and point[1] == 0:
    print("原点")
if point[0] == 0 and point[1] != 0:
    print(f"Y={y}")
if point[0] != 0 and point[1] == 0:
    print(f"X={x}")
if point[0] != 0 and point[1] != 0:
    print(f"X={x}, Y={y}")
else:
    print("座標ではありません")
```

#### match - case 文

```python
point = (33, 4)
match point:
    case (0, 0):
        print("原点")
    case (0, y):
        print(f"Y={y}")
    case (x, 0):
        print(f"X={x}")
    case (x, y):
        print(f"X={x}, Y={y}")
    case _:
        print("座標ではありません")
```

match - caseでは受け取る値をそのままcase上で変数に入れて、分岐先で使用することができます。またcase文中の `_` はワイルドカード扱いとなり、条件以外を吸収してくれます。

## まとめ

3つの例題を通してmatch - case文を書いてみましたが、if文との使い分けるポイントは、

- 計算が既にされたもの もしくは カテゴリ名などの文字列 の分岐
- 分岐する条件がリストの中身などといったデータ構造になる場合

にmatch - case構文に置き換えることで、可読性を高めたり、より複雑な分岐をスマートに書くことができるのではないかと思います。無理して使う必要は決してないと思いますが、「if文で書くには冗長だなぁ」と思ったときに検討してみると良いかと思います。
DcockerのContainerに・からファイルをコピーする

dockerのpythonのcontainer作って、とりあえずvscodeで開発できるようにしたので、ローカルにあるpythonファイルをcontainerにコピーして実行してみようと。

# docker cpコマンド

CLIに慣れていれば簡単です。
これだけ。

```
$ docker cp ローカルファイル名　コンテナ名:パス
```


例えば、私はmacなのでterminalを開いて書類フォルダの"test.py"を"python3.10.0"というcontainerの"/roo/src"フォルダにコピーするとすると、次の通りでOK

```
$ docker cp /Users/UserName/Documents/test.py python_container:/root/src
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2351871/aee2f247-561c-5e44-aed2-c1f7249a7b8f.png)

コピーできた

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2351871/af741b0e-62a0-c459-bb5e-86f4a2665b35.png)

containerからローカルにコピーする場合は、逆にすれば良い。

今日は、ここまで。
いちいちコピーするの面倒だからcontainerとデータを共有できるようにしたいと思う。
Javascriptの変数定義に関して(var,let,constの使い分け)

①再代入、再定義可能か
　let,varは可能
　constは不可能（※定数だから）


②スコープの範囲
 var・・・関数スコープ

```javascript
function test() {
  if (true) {
    //条件式の中で宣言
    var x = 1;
  }

  console.log(x) // 条件式の外で呼び出しても、関数内なので1が表示される
}
```

 let,const・・・ブロックスコープ

```javascript
function test() {
  //if文の{}が1つのブロックなので、
  if (true) {
    //条件式の中で宣言すると
    let x = 1;
    const y = 2;
  }

  console.log(x) //ブロックの外側なのでundefined(未定義)となる
  console.log(y) //constを使った場合も同様にundefinedとなる
};
```
Whatを書くな。Whyを書け。

コメントを書くときのお話。

## 「What」のコメントとは

```
    public static void main(final String[] args) {

        final List<String> telList = Arrays.asList("090-1234-5678", "090 1928 3746", "09098765432");
        final List<String> result = formattedTel(telList);
    }

    public static List<String> formattedTel(final List<String> telList) {

        // 結果用のリストインスタンスを初期化
        final List<String> result = new ArrayList<>();

        // 電話番号リストの各要素に対して処理をする
        telList.forEach(tel -> {
            if (tel.contains("-")) {
                // 電話番号にハイフンが含まれている場合
                result.add(tel.replace("-", ""));
            } else if (tel.contains(" ")) {
                // 電話番号にスペースが含まれている場合
                result.add(tel.replace(" ", ""));
            } else {
                // 含まれていない場合
                result.add(tel);
            }
        });

        // 結果を返却
        return result;
    }
```


```
        // 結果用のリストインスタンスを初期化
        final List<String> result = new ArrayList<>();
```

変数名からも結果用とわかるし、`new ArrayList<>()`の意味をわざわざ説明する意味はない。

```
        // 電話番号リストの各要素に対して処理をする
        telList.forEach(tel -> {
```

これも`forEach`を説明しているだけ。

```
            if (tel.contains("-")) {
                // 電話番号にハイフンが含まれている場合
```

これもif文の条件を日本語化しているだけ。

他のコメントもどれもこれも、**プログラムで表現されている内容を日本語に翻訳しているだけで、全く意味の無いコメントになっている。**

プロジェクトによっては、統一性のためにこういったコメントも書く必要があるところもあるとは思うが、こういったコメントは見るのも書くのもしんどい。

また、**コードを修正する際に、コメントも修正する必要があるかどうか**を気にしなくてはならない。
これが大きなプロジェクトになると、コメントの修正漏れが多発し、コードとコメントで言ってることが違う！なんてことが起きる。

## 「Why」のコメントとは

```
    public static void main(final String[] args) {

        final List<String> telList = Arrays.asList("090-1234-5678", "090 1928 3746", "09098765432");
        final List<String> result = formattedTel(telList);
    }

    /**
     * 電話番号のフォーマットを、数字のみの形式に揃える。
     *
     * @param telList 電話番号リスト
     * @return フォーマットを揃えた電話番号リスト
     */
    public static List<String> formattedTel(final List<String> telList) {

        final List<String> result = new ArrayList<>();

        telList.forEach(tel -> {
            if (tel.contains("-")) {
                result.add(tel.replace("-", ""));
            } else if (tel.contains(" ")) {
                result.add(tel.replace(" ", ""));
            } else {
                // 既に数字のみで構成されている電話番号のため、文字列操作は何もしない
                result.add(tel);
            }
        });

        return result;
    }
```

```
    /**
     * 電話番号のフォーマットを、数字のみの形式に揃える。
     *
```

**このJavadocだけで、他はコードを読みさえすれば理解できる。**
さっきまでのあってもなくても意味のないコメントは無くなった。

```
                // 既に数字のみで構成されている電話番号のため、文字列操作は何もしない
                result.add(tel);
```

これは「What」の要素も含んでいるが、個人的にこのコメントは必要だと思っている。
なぜなら、**第３者視点で考えた時に**、「他の分岐と違って文字列操作が無いのはなぜだろう？」となる場合があるから。

なぜなぜ、を考え始めると全部そうじゃんってなるけど、大事なのは、
**自分以外の人が理解出来ない & 出来なさそうな箇所は、自分の意図(Why)を書こう**、ということ。


## まとめ

サンプルコードが簡単なのであまり実感がわかないかもしれないけど、

- 他人がそのコード見て、**意味だけでなく意図まで理解できるかどうか**
- 理解出来ない場合、**理解の手助けになるコメントを書けているかどうか**

が大切。
特に大規模なシステムや、年代物のシステムだと、当時の開発担当が居ないなんて事はザラにあるので、
こういったコメントが無いと、保守する時に痛い目を見る。（実体験済み
ターミナルでファイルを曖昧検索

ルートディレクトリから、hogeに関連する曖昧検索ができる。
プログラミング始めたての時、地味にわからなくてこまる

```
find / -name '*hoge*'
```

曖昧検索の例

```
### カレントディレクトリ配下に2つのファイル
-> % ls
hoge_test test_hoge


### hogeの後ろを曖昧検索
-> % find . -name 'hoge*'
./hoge_test


### hogeの前を曖昧検索
-> % find . -name '*hoge'
./test_hoge


### hogeの前後を曖昧検索
-> % find . -name '*hoge*'
./test_hoge
./hoge_test
```
Simple Docker image to convert Japanese Jupyter Notebook to PDF

## TL;DR

If you want to convert Jupyter Notebook (possibly, with Japanese script included) to pdf, do the following
1. move to new directory
1. inside it, create the subdirectories `./notebooks` and `./pdfs`
1. save your notebook under the name `./notebooks/notebook.ipynb`
1. run the command `docker run nailbiter/jupyter-latex-pdf`
1. pick up the generated pdf from `./pdfs/notebook.pdf`

## Purpose

In my work, I sometimes need to convert the Jupyter Notebook to PDF. While this is easy to do in general via `jupyter nbconvert`, if the Notebook contains Japanese script, experience shows,
that often the additional processing is required. 

In my experience, the approach that works is to convert Notebook to `tex` file first, and then use [XeTeX](https://ja.wikipedia.org/wiki/XeTeX) to create the PDF. However, this requires installing the number of big dependencies, most notably XeTeX and Japanese
fonts. In order to encapsulate these dependencies from contaminating the system, I have put up together simple Docker image, which does exactly that.

## Codes

1. [Dockerfile](https://github.com/nailbiter/for/blob/master/for-docker/jupyter-latex-pdf/Dockerfile)
1. [image](https://hub.docker.com/repository/docker/nailbiter/jupyter-latex-pdf)

## References

While working on this post, I have used the data from the following sources:

1. [https://ysko909.github.io/posts/install-japanese-font-to-docker-cotainer/](https://ysko909.github.io/posts/install-japanese-font-to-docker-cotainer/)
1. [https://unix.stackexchange.com/questions/395694/can-i-automatically-accept-ms-sql-license-terms-while-installing-the-yum-package](https://unix.stackexchange.com/questions/395694/can-i-automatically-accept-ms-sql-license-terms-while-installing-the-yum-package)
フォワードプロキシで守られたNW内でngrokを使用する

最近、久しぶりにWebアプリ開発の試行錯誤をする機会があり、その時に知った便利ツールの紹介とそのツールに関するトラブルシューティングです。

# Problem

開発マシン上で開発中のWebアプリに、WWW経由でHTTPS通信を行いたい。
なお、「開発マシン」は会社の社内NW（あるいは学校のNWなど）に接続しており、あらかじめ決められたフォーワードプロキシを経由する以外にはWWWへのアクセスができない。

# Solution

`ngrok`（えんぐろっく）というツールを使います。

`ngrok` はローカル環境で稼働するWebサーバーを動作検証などのためにWWW（インターネット）に公開するためのツールです。
これにより他のシステムや開発メンバーがWWWを経由して開発中のWebアプリにHTTP/Sでアクセスすることが可能になります。
公開には `*.ngrok.io` のサブドメインが利用され、`*` の部分には都度ランダムな値が設定されます。

またこのようなフォーワーディングの他にも、HTTP/S通信内容を解析したり、HTTP/S要求を再実行したりすることもできるようです。

具体的な手順は次の通り（フォーワードプロキシが介在しない環境であれば、手順3～6は不要です。）：

1. 開発マシンに Node.js をインストールする。直接インストールでも `nvm` 経由でも構わない。
1. シェル／コマンドプロンプトで次のコマンドを実行する： `npm install -g ngrok`
1. [ngrok](https://dashboard.ngrok.com/login) のサイトでサインアップする。
1. ダッシュボードの [Your Authtoken](https://dashboard.ngrok.com/get-started/your-authtoken) で認証トークンを取得する。 
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/30f64466-c6ea-9284-7247-a86c3721434a.png)
1. ngrokのリファレンス [Default configuration file location](https://ngrok.com/docs#config-default-location) を参考にして所定の場所に次のファイルを作成する： `ngrok.yml`
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/895882d5-e86f-c211-fc6c-a42b7042a044.png)
1. テキストエディタで `ngrok.yml` を開き `authtoken`と`http_proxy`のキー／値をYML形式で記述する：
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/309eae17-df2f-7c74-7498-b321d09b1173.png)
1. 開発中のWebアプリを起動し、開発サーバー上でHTTPリクエストを待ち受ける状態にする（例： `http://localhost:8080`）。
1. シェル／コマンドプロンプトで次のコマンドを実行する： `ngrok http ポート番号` （例： `ngrok http 8080`）
1. シェル／コマンドプロンプトに次のように表示されるのを待つ：
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/91f2de15-3e41-9043-18da-d08c961e1c9e.png)
1. `Forwarding` 欄に表示されたURLを使い、Webブラウザでアクセスする。

ところで、、、
この記事を執筆している時点（2021/12/08）で、Chromeブラウザを使って `ngrok` で作成されたURLにアクセスをすると、以下のような警告画面が表示されてしまいます：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50571/7d844b07-9a04-c791-1608-d60a0be66666.png)

FirefoxやEdgeなど他のブラウザでは問題ありません。
この画面そのものについては「詳細」→「安全でないこのサイトにアクセスする」をクリックするとアクセスを続行できますが、この警告内容を見ていると `ngrok` 経由のアクセスがセキュリティ対策ツールなどにより遮断されてしまうケースもありそうに思えます。。

# Background

Webアプリ（WebAPIも含む）を開発するとき、単にWebアプリを作って動かせばよいのであれば比較的シンプルですが、そのWebアプリに別のアプリからHTTPSリクエストで接続する必要がある場合は厄介です。

本番稼動のためのWebサーバーであれば、（LBやWAFなどの介在の有無はともかく）WWWに公開されているでしょうし、SSL証明書もインストール済みでしょう。
しかし、ふつう開発マシンはWWWに公開しませんし、SSL証明書のインストールもしません。

`ngrok` （えんぐろっく）というツールを使えばこのような問題が解決します。都度発行されるランダムなドメインを使って、開発サーバーを一時的にWWWに公開することができるのです。

ところで `ngrok` を使う場合に会社や学校のNWで利用されることの多いフォーワードプロキシが障壁になります。前述の手順のうち3～6を実行しないと、このプロキシにより `ngrok` の動作が妨げられてしまいます。
AtCoderの復習を手助けするWebサイトを作った（AtCoder-Ebbing）

この記事は[競プロ Advent Calendar 2021](https://adventar.org/calendars/6713) 8日目の記事です。

# 概要
AtCoderの復習を手助けする[AtCoder-Ebbing](https://atcoder-ebbing.web.app)というサイトを作成しました。
レートや解いた回数、前に解いたときからの期間等を考慮して解くべき問題を一問ずつ出題してくれます。
名前の由来は忘却曲線のエビングハウス氏です。

- https://atcoder-ebbing.web.app
- https://atcoder-ebbing.firebaseapp.com

（キャッシュのせいか片方見れないことがあります。見れない時はもう片方にアクセスすると良いかもしれません）

## 背景

皆さんAtCoderのレート上がってますか？
僕のレートはずいぶん長いことX軸に平行です😢。

一度解いた問題をちゃんと身につけるために復習が大切だというのは分かっていますが、復習をするため問題を管理するのはやや面倒です。

特に手間をかけず単語カード的な感じで復習すべき問題を1問ずつ出してくれるサービスが欲しいなと思い立ち、丁度アドベントカレンダーの時期だったのをきっかけに作ってみる事にしました。

是非使ってみて下さい。
（なんとか動くようになったのが数時間前なのでバグだらけかもしれません）

使い方は[こちら](https://atcoder-ebbing.web.app/about#usage)です。

## 余談

これだけではポエムで終わってしまうので使った技術を書いていこうと思います。(アドベントカレンダーのお題とは離れてしまいますが……)

### AtCoder Problems API & AtCoderの隠し機能

問題の情報やAtcoderのレート情報を用いるためにAtcoder ProblemsのAPIとAtCoderの[隠し機能](https://twitter.com/chokudai/status/1001332212648701952)を用いました。

**偉大な kenkoooo さんと snuke さんに感謝**

### Flask & gunicorn

今回のwebサイトは殆どをPythonで畫きました。

[Flask Tutorial](https://flask.palletsprojects.com/en/2.0.x/tutorial/index.html)を見つつ作成を行いました。非常に分かりやすかったです。

Cloud Run上で動かすことにしたため、WSGIサーバーは[Cloud Run公式のチュートリアル](https://cloud.google.com/run/docs/quickstarts/build-and-deploy/python)で用いられていたgunicornを使うことにしました。これも非常にわかりやすかったです。

### Cloud Run

サーバーの管理の手間を避けるためCloud Runを使いました。

そのため、サーバサイドに長期間データを保存することができず、後述するLocalStorageを活用しました。


開発中は手元のPCで直接Flaskを動かし、サイトが完成した一番最後にDockerfileを書いてコンテナ化しました。

### LocalStorage & Cookie

FlaskでのデフォルトのCookieは暗号化を用いクライアントサイドにデータを保存するらしく、最初はこれにデータを詰め込もうかと思いました。

しかし、4kB制限がありAPIの使用回数を減らす為もあってLocalStorageも用いることにしました。

後からデータの保存方法を追加したためこのあたりのコードがぐちゃぐちゃになってしまいました。

### Firebase Hosting

Cloud Run直のURLでは見栄えが悪いのでFirebase Hostingを通すことにしました。



### その他諸々
- poetry
    - ライブラリ管理と簡単にパッケージ化するために使いました。
- pyenv
    - バージョンの新しいpythonを使いたかった。
- vscode
    - 競プロだけだと発揮しきれていない機能を見れました。


## まとめ

**これで僕のレーティングも単調増加！！！**
仮想ルータ (SEIL/x86)の回線冗長と自動経路切替

#はじめに
近年、クラウド化が進むにあたり仮想ルータの必要性も高まっている。
よくある構成として、クラウド側にサーバを配置、拠点側のクライアントがサイト間VPNを通して
サーバ側に通信するというもの。
その際にクラウド側は仮想ルータ、拠点側は物理のルータ機器を導入するパターンがある。
クラウド側は高可用性が保たれているが、拠点側は物理ルータ1台や回線1本の場合そのどちらに障害発生してしまった場合
その時点で通信が途絶えてしまうことになる。
今回はそのような状態を回避する、より可用性の高い構成を構築したので備忘録として記載。

#前提
・クラウド側仮想ルータ(SEIL/x86)
・拠点側ルータ(RTX830)×2台
・インターネット回線2本
・常時、2本の拠点間VPN(IPsec)を構成
・マスター側に障害のあった場合。サブ側経路に切り替え

#構成概要
・IPsec VPN×2は問題無く張れている前提で。
・経路切替を以下の方法で実装する
　【SEILx86側】
　　・対向のLANのインターフェース(マスター・サブ)にkeepaliveで死活監視
　　・keepaliveのダウンをトリガーに該当するルーティングを削除
　　・通常時はマスター側が常に優先されるように、distance設定でルーティングの重みづけ
　【RTX側】
　　・2台のルータでVRRPを構成
　　・VRRPのshutdown トリガーをSEILのLAN側へのkeepaliveに設定
　　・上記が動作した場合、VIPが遷移し障害の無い方のルータへクライアントのGWとなるIPが遷移するように設定

【通常時】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2188357/256752ee-6e24-bad7-b465-85f586951bcf.png)


【障害時】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2188357/8328258c-c053-6690-1482-75a4e3d58971.png)


#設定内容
全てを記載すると長くなってしまうので、今回はSEIL側の以下の設定のみ紹介することにします。
●ルーティング設定(keepalive設定) 

```
route add [RTXマスターLANIP/32] ipsec0 ※keepalive用
route add [RTXサブLANIP/32] ipsec1 ※keepalive用
route add 192.168.1.0/24 ipsec0 distance 10 keepalive on target [RTXマスターLANIP] src [SEIL LANIP]
route add 192.168.1.0/24 ipsec1 distance 100 keepalive on target [RTXサブLANIP] src [SEIL LANIP]
```
上記のルート設定が上手く動作している場合、SEIL側の経路確認は以下となる。
●通常時ルート

```
show status route
Destination        Gateway            Interface Flags  Dist.
default            **********     lan0      S*        1
192.168.1.0/24     ipsec0             ipsec0    S*       10
RTXマスターLANIP/32    ipsec0             ipsec0    S*        1
RTXサブLANIP/32    ipsec1             ipsec1    S*        1
```

●障害時ルート※192.168.1.0/24のGWがipsec0→ipsec1

```
show status route
Destination        Gateway            Interface Flags  Dist.
default            **********     lan0      S*        1
192.168.1.0/24     ipsec1             ipsec1    S*       100
RTXマスターLANIP/32    ipsec0             ipsec0    S*        1
RTXサブLANIP/32    ipsec1             ipsec1    S*        1
```

以上仮想ルータ(SEILx86)における、VPN回線冗長構成の一部の紹介でした。
近年今回のパターンのみならず、クラウドーオンプレミス間の回線冗長構成は必須要件となってくる可能性が高く
他のクラウドやソリューションを使用しての回線冗長構成も学ぶ必要があると思うので、次回は他の構成パターンを記載できるように
しようと思います。
Figmaでオリジナルアイコンを作成した際に起こった問題点と解決策

はじめまして！Monoxer, Inc.でデザイナーをしております、moyoです。
普段はWEB、アプリのUIや体験をデザインしたり、エンジニアさんと協力しながらデザインシステムの運用を行なっています。

アドベントカレンダー初参加！初Qiitaです:sunny:

#この記事の要約
* Figmaでアイコンを作成し、いざ実装したらいくつかの問題が発生
* Figma側の処理や設定変更で解決できた
* プラグイン「Fill Rule Editor」が便利！

#Figmaでアイコンを自作！
Sketchを利用していた頃は、Illustratorでアイコンを作成してからSketchに取り込んでいたのですが、Figmaへの移行を機に、アイコンもFigmaで作成するようになりました。

こんな感じ↓　
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/08b693ad-7f55-7176-c77e-55b10ec1bf14.png)


これらのアイコンを、エンジニアさんが以下のライブラリを使って実装してくださったのですが、

https://github.com/jaywcjlove/svgtofont

いくつか問題が発生したので、Figma上での解決方法を紹介できればと思います:wave:

#起こった問題と解決策 
##1.アイコンの線が2重になってしまう
###問題
Figmaではベタ塗りのオブジェクトが、実装すると二重枠になってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/94383fb7-b127-b91a-6e61-adc01d9f8045.png)

###解決方法
1. パーツが全て結合されているかを確認する
![スクリーンショット 2021-12-08 19.33.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/169ee6fc-a42c-de36-e5ec-9a5a1b444f97.png)
2. 結合したオブジェクトに、Command + Shift + O でアウトラインをかける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/92042dbd-c7e0-7815-49d2-d5ebfcf8e699.png)
3. (おまけ)アウトラインしたオブジェクトのConstraintsをScaleに変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/41bfbbf8-6730-1c3d-51f3-a7aaf5f853b4.png)

##2. アイコンがカクカクしてしまう
###問題
なぜか一部のアイコンがカクカクしてしまう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/6a1e48b5-4f9a-f859-f022-e7219ea3114f.png)

###解決方法
~~解像度を上げるため、アイコンのどれか1つを512pxのsvgにする
（エンジニアさん曰く、なぜかそれで他のアイコンもカクカクしなくなったそうです:astonished:）~~

ライブラリ側の設定でfontHeightを指定したら、強制的に解像度をscaleして解決できたのことです！

```
svgicons2svgfonts: {
   normalize:　true,
   fontHeight: 1000,
}
```

##3. アイコンが塗りつぶされてしまう
###問題
アイコン内の線やオブジェクトが塗りつぶされてしまう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/2c8cb1eb-3ee2-8661-c96b-512ec4e6dae7.png)

###解決方法
1. プラグイン「Fill Rule Editor」をインストール
https://www.figma.com/community/plugin/771155994770327940/Fill-Rule-Editor

2. 「Fill Rule Editor」をアクティブにし、アウトライン済みのアイコンを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/5401f9f8-fff1-e7c0-13f3-046b0b2e4fcc.png)
3. オレンジの部分をクリック（Non-zero Ruleに変わります）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/604cb1fc-3d7d-3eb5-6769-c8d97609b282.png)

3. 矢印をクリックし、一番外側を**右周り**、塗りつぶさない所は**左周り**に変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2253846/9240a659-fc39-974e-92d1-805c4e3b380c.png)

##4. 作ったアイコンの数と、実装されたアイコンの数が合わない
###問題
作ったアイコンの数に対して、実装されたアイコンの数が少ない

###解決策
アイコンの命名に重複がないかを確認する。
（特に発展途上のプロダクトは、できるだけ状況依存的な名前を避けるのがベターだと思います。**△Favorite ○Star**）

#まとめ
1. 結合、アウトライン化を忘れずに！
1. Constraintsの設定をScaleにしましょう！
1. プラグイン[「Fill Rule Editor」](https://www.figma.com/community/plugin/771155994770327940/Fill-Rule-Editor")をインストールしましょう！
1. 丁寧な命名を心がけましょう！
[AWS re:Invent 2021] Amazon Inspector の新バージョンが発表されました！

こんにちは、kc-Dreamです。

この記事は株式会社ナレッジコミュニケーションが運営する [クラウドAI by ナレコム Advent Calendar 2021](https://qiita.com/advent-calendar/2021/knowcom-cloudai) の9日目にあたる記事になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229923/cff3b2cf-b7fe-2103-695c-422d15ed81a9.png)

##はじめに
AWS re:Invent 2021にてソフトウェアの脆弱性についてAWSワークロードを継続的にスキャンする脆弱性管理サービスであるAmazon Inspectorの新バージョンが発表されたので、まとめていきたいと思います。

###Amazon Inspectorって何ができるの？
自動的にアプリケーションを評価し、露出、脆弱性、ベストプラクティスからの逸脱がないかどうかを確認することができるサービスです。
今回発表された内容は、Amazon Inspectorが完全に再設計され、脆弱性管理を自動化し、ほぼリアルタイムの調査結果を提供して、新しい脆弱性を発見する時間を最小限に抑えているといったものとなります。

####追加された機能
- ワンクリックで組織全体でサービスを有効化

有効にすると、Amazon Inspectorはすべてのワークロードを自動的に検出し、ソフトウェアの脆弱性と意図しないネットワークの露出を継続的にスキャンします。

- AmazonElastic ContainerRegistry（ECR）をサポート

ECRに存在するAmazonEC2インスタンスとコンテナイメージ全体の脆弱性の統合ビューを取得します。

- Amazon Systems Manager（SSM）エージェント

EC2脆弱性スキャンにAmazon Systems Manager（SSM）エージェントを使用するようになりました。

- その他

脆弱性の調査結果にインテリジェントな優先順位を付けるために、新しいインスペクターは、脆弱性情報を環境要因と相関させることにより、高度にコンテキスト化されたインスペクターのリスクスコアを導入します。インスペクターの結果もAmazonSecurity Hubにルーティングされ、Amazon EventBridgeにプッシュされて、パートナーソリューションで自動化され、平均解決時間（MTTR）が短縮されます。
また、CloudFormationのサポートが予定されています。

###対応リージョン
アジア太平洋（シンガポール）
アジア太平洋（シドニー）
ヨーロッパ（アイルランド）
米国東部（北バージニア）
米国東部（オハイオ）
米国西部（オレゴン）
アジアパシフィック（香港）
アジアパシフィック（東京）
アジアパシフィック（ソウル）
アジアパシフィック（ムンバイ）
カナダ（中央）
ヨーロッパ（フランクフルト）
ヨーロッパ（ストックホルム）
ヨーロッパ（ミラノ）
ヨーロッパ（ロンドン）
ヨーロッパ（パリ）
中東（バーレーン）
南アメリカ（サオパウロ）
米国西部（北カリフォルニア）

###価格
- ネットワークの到達可能性のルールパッケージを使用した Amazon Inspector の評価では、1 回の評価に含まれる各インスタンスについて (インスタンス評価) 月ごとに課金されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229923/32f1e1e6-13e2-f481-851d-14c68c6c840c.png)

- ホスト評価のルールパッケージでは、評価対象のアプリケーションを実行している Amazon EC2 インスタンスにデプロイしたエージェントを使用します。ホスト評価のルールパッケージを使用した評価では、評価に含まれる各エージェントについて (エージェント評価) 月ごとに課金されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229923/a0d5f6a5-815c-e043-8823-de798e85e829.png)


##おわりに
アップデート情報が発表されたばかりですが、特にECRサポートと、SSMエージェントの使用がより使い勝手を向上させていると感じました。
今後、検証を進めていきたいと思います。

###関連URL
- [Amazon Inspector](https://aws.amazon.com/jp/inspector/)
- [Amazon Inspector 発表内容](https://aws.amazon.com/jp/about-aws/whats-new/2021/11/amazon-inspector-continual-vulnerability-management/)
Gitの過去の歴史を新しい歴史として作りたいとき

# Gitでやらかして、過去の歴史を新しい歴史として作りたいとき
- Gitでコミット、プッシュしちゃってからやっちまった、ということに気づくことがままある。
- そんなとき、ググるとやっちまった歴史を**消して**プッシュすればいいという記事はよく見る
  - でもそうするとチームでGit使ってたときに他の人の歴史を**壊す**ことがあるのでしたくない。
- SVNみたいに、やっちまった歴史を残しつつ前の歴史を新しい歴史として作るにはどうしたらいいかわからなかったので無理やりやったのを記録しておく
- すごく無理やりなので他にいい方法が絶対あるはず・・・

# やったこと
- やっちまった前のコミットを新しくcheckout

```
git clone リポジトリ
git checkout <やっちまう前のハッシュか何か>
```
- ディレクトリの.gitディレクトリ消す

```
rm -rf .git
```
- やっちまったリポジトリの.gitディレクトリ持ってくる

```
cp -r /path/to/やっちまった/.git ./
```
- git status

```
git status
```
- 新しい歴史としてコミット、プッシュ

```
git commit -m "やっちまう前の歴史を新しく追加"
git push
```

やっちまう前の.gitディレクトリをやっちまった.gitで上書きする、というだけ。
git上はやっちまった歴史になってるけどファイルたちはやっちまう前のものになってる。
きっと正しいやり方じゃないのであまり当てにしないほうがいいと思いますが
これでできてちょっと嬉しかったので書きました。
選択シート以外のシートを削除する【ExcelVBA】

何十シートもあるExcelファイルをつくるなよ
重いんだよ

しかもマスターブックから項目ごとに抜粋するとか。。。

など不満はありますが、使わざるを得ないのでせめてその単純作業をラクにしたくて即興で作りました。

最近ようやく捨てマクロ的な手軽さで書けるようになってきました。

## 使い方

1. Ctrl＋クリックで残したいシートを選択する
1. マクロ`選択シート以外を削除`を実行する


## コード

``` vb
Option Explicit

Sub 選択シート以外を削除()
  Dim wb As Workbook
  Dim ws As Worksheet
  Set wb = ActiveWorkbook
  Dim ws選択中 As Sheets
  Set ws選択中 = ActiveWindow.SelectedSheets
  
  Dim myList
  Set myList = Get重複無しリスト_ws(ws選択中)
  
  Application.ScreenUpdating = False
  Application.DisplayAlerts = False
  For Each ws In wb.Sheets
    If Not myList.Exists(ws.Name) Then
        ws.Delete
    End If
  Next
  Application.DisplayAlerts = True
  Application.ScreenUpdating = True
End Sub

Private Function Get重複無しリスト_ws(ws対象 As Sheets)
    Dim Dic, i As Long, myKey As String, myColorIndex As Long
    Set Dic = CreateObject("Scripting.Dictionary")
    
    myColorIndex = 0
    Dim ws As Worksheet
    For Each ws In ws対象
        myKey = ws.Name
        If Not Dic.Exists(myKey) Then
            Dic.Add myKey, myKey
        End If
    Next
    Set Get重複無しリスト_ws = Dic
End Function
```

## 振り返り・新しく知ったこと
### 選択中のシートを指すメソッドは`ActiveWindow.SelectedSheets`
``` vb
Dim ws選択中 As Sheets
Set ws選択中 = ActiveWindow.SelectedSheets
```
でSetしておいて

``` vb
Set myList = Get重複無しリスト_ws(ws選択中)
```
といった感じで変数に投げ込めば普通にSheetオブジェクト群としてループを回せる。

重複処理をする必要はないが、他で使ったリストアップ系自作関数の使い回しでいけたのでとりあえず流用している感じ。

重複無しリストアップ関数は入れるものの型別にシリーズ展開して自分ライブラリに登録しておいてもいいかも。
「ラズパイ×Alexa」水やりを忘れるので観葉植物に喋ってもらった

# きっかけ
家で育てている観葉植物のポトスにふと目をやるとすっかり元気がなくなっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506008/6c467426-e975-8931-3ad2-699755ea34b7.png)
水やりを１か月くらい忘れていて土が干からびていたのです。。
ただの言い訳になりますが、水やりのサボり癖がついたのには理由がありました。

* ポトスは鉢土がしっかり乾いていることを確認してから水やりをします。表面だけ乾いていても中が湿っていることがあるので土を触って確かめる必要があります。
* 季節によって水やりの頻度が全く異なります。寒い時期は室温が低いので夏に比べて水やりの頻度が減ります。

土の確認が面倒なのと寒い時期になり水やりの頻度が減ったことが原因で、土が乾いたまま放置するようになっていたのです。

ポトスさんは凄まじい生命力を持っているので1〜2ヶ月水を上げなくても全て枯れることはなかったです。

しかしほんとは水が欲しかったのだろう...と

それならポトスさんに水が欲しいときに喋ってもうらおうじゃないか！

# 作ったもの
というわけでラズパイとAmazon Echoを使って土の水分がなくなったことを教えてくれるIoTシステムを作りました。

こんな感じ...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506008/333c6824-4b8e-14e7-071b-aa5cfec0735d.png)

水やりは朝にするといいらしいので、起床時刻に合わせて毎朝8:00に水分量を計測して3段階で教えてもらうようにしました。

|  水分量(0~950)|  メッセージ |
| ---- | ---- |
|  水中 700~950  |  喋らない|
|  湿ってる 300~700  |  そろそろお水が欲しい！　|
|  乾燥 0~300  |  今すぐお水が欲しい！|

どれくらいのペースで水分量が減っていくのかわからないので、とりあえず上表で設定してみました。
土が乾燥していると「今すぐお水が欲しい！」とAlexaが可愛い声で喋って教えてくれます。これでサボり癖のある私でも忘れずに水やりができそうです！


#### 用意したもの
・Raspberry Pi
・Echo Plus
・[Grove Base Hat for Raspberry Pi](https://wiki.seeedstudio.com/jp/Grove_Base_Hat_for_Raspberry_Pi/)
・[Grove - Moisture Sensor](https://wiki.seeedstudio.com/Grove-Moisture_Sensor/)

これらを揃えれば簡単に作れます。seeed社のGroveシールドとセンサーを使うのがポイントです。通常のセンサーを使うとハンダ付けや電子回路の知識が必要になりますが、なんとGroveはハンダ付けが不要でピンを差し込むだけです。また[seeed社の公式サイト](https://wiki.seeedstudio.com/Grove-Moisture_Sensor/#play-with-raspberry-pi-with-grove-base-hat-for-raspberry-pi)にはサンプルのプログラムまで付けて解説してくれるので電子回路の知識がなくても大丈夫です。


#### プログラム
プログラムはたったこれだけです。
seeed社提供の[Pythonライブラリ](https://wiki.seeedstudio.com/Grove-Moisture_Sensor/#software_1)をインポートすると簡単に水分量センサーの値が取得できるのでかなりすっきりと書くことができます。Alexaとの連携も非常に簡単でGitから[alexa_remote_control.sh](https://github.com/thorsten-gehrig/alexa-remote-control/blob/master/alexa_remote_control.sh)を取得してAmazonアカウント情報を該当行に書き込み、下記のように引数に話してほしい文字を渡します。
あとはcornからプログラムを呼び出して完成です。

```python
import os
import time
from grove.grove_moisture_sensor import GroveMoistureSensor

# connect to alalog pin 2(slot A2)
PIN = 0

sensor = GroveMoistureSensor(PIN)

print('Detecting moisture...')
m = sensor.moisture
if 0 <= m and m < 300:
    result = 'Dry'
    msg = '今すぐお水が欲しい！'
    os.system("/home/pi/potos/alexa_remote_control.sh -d 'Echo Plus' -e 'speak:{0}'".format(msg))
elif 300 <= m and m < 700:
    result = 'Moist'
    msg = 'そろそろお水が欲しい！'
    os.system("/home/pi/potos/alexa_remote_control.sh -d 'Echo Plus' -e 'speak:{0}'".format(msg))
else:
    result = 'Wet'
print('Moisture value: {0}, {1}'.format(m, result))


```

# さいごに
久々にラズパイ触りましたが工作は楽しかったです。Groveは様々な種類のセンサがあるのでラズパイの幅が広がります。次は余っているカメラモジュールがあるのでそれで観察日記でもつけようかと思います。実物を触るのは楽しいのでサーバレスの時代になってもラズパイは手放すことはできないだろうなと思いました。
御老公様によるgemとnpmのアップデートとそのリリース

はじめまして信州の廻船問屋です。
これは[Catallaxy Advent Calendar](https://qiita.com/advent-calendar/2021/catallaxy) 5日目の記事です。「私が本物の御老公様」という技術ブログを書こうと思っていましたが、今は外は真っ暗だし、もう脳みそが疲弊してきたし。

CatallaxyのMitsuriサービスを開発するメンバーに老公と呼ばれるかもしれないエンジニアがいる。（注：実際にそう呼ばれているエンジニアはいません）
GitHub Dependabotを活用して、3年以上にわたり累積してきた、セキュリティアップデートと依存ライブラリのアップデートを実施することにした。gemとnpmのアップデートとそのリリースを一気に実施することにした。

`.github/dependabot.yml` をいじるだけでいい。

```yml:参考までに当社で設定されている最も簡単な.github/dependabot.ymlを貼っておきます
version: 2
updates:
  - package-ecosystem: "bundler"
    directory: "/src"
    schedule:
      interval: "daily"
  - package-ecosystem: "npm"
    directory: "/src"
    schedule:
      interval: "daily"
```

2021年はエンジニアが楽な時代になったと感じるのにふさわしい一年だった。延べMitsuriサービスにおいては100以上のアップデートを重ねてきた。ある程度まとまったPRをまとめてリリースすることも選択できるが、当プロジェクトではあえて全部のアップデートを都度リリースしました。効率は悪いかもしれないがロールバックがしやすい気がします。2021年12月28日の最終出社日までには全てのライブラリが最新になっていることが確信できるレベルのバーンダウンチャートである。残りの時間を100%達成に充てるかはまだ決めていない。

2022年はこの楽な環境でプロダクト開発をより効率的にリリースできる一年にしていきたい。明日のアドベントカレンダーは京極春彦による[リモートワーク生活と部屋とYシャツと私](https://qiita.com/catallaxy/items/dbf5d9ad3abc2b6de352)です。お楽しみに。
いきなりフリーランスをやってヒヤッとしたときの話

@Earthfreedom さんからバトンを受け取りました、G's Academy 東京LAB4卒の大森と申します。

アドベントカレンダーの予約でもしないと記事を書かないので、
ほぼ昨年ぶりにQiitaを書きます。

[面倒な水替えを自動化！RaspberryPiで自動水替えシステム作ってみた。WIP](https://qiita.com/Earthfreedom/items/e039de4ea29903649003)面白いですね。

IoTのツールはまだまだ感度の高い人しか身近に使えていない感じがするので、
IoT界隈の方々の活動を見るとついつい応援したくなります。


さて、僕はG's卒業後いきなりフリーランスになったので、よく
「どうやって勉強してるの？」とか、「失敗したとき怖くない？」とか聞かれます。

正直に言うと、失敗はときどきしてます笑
一緒に働く方々の支えやご厚意があって、なんとかやっていけてる状態です。

今回は今までで一番ヒヤッとした体験をお送りします。

# 簡単に自己紹介
2018年4月に東京LAB4期を卒業後、事業家およびフリーランスエンジニアとして活動しています。

エンジニア歴はもう4年弱といったところですが、
そのうち半分ぐらいはビジネスサイドをやっていたり、プータローしていたりなので、
実質的にコードを書いている経験年数的には2年ぐらいでしょうか。

# いきなりフリーランスエンジニアをやることの問題
僕は最初からいきなりフリーランスエンジニアになるという、
今思えば悪手とも思える選択をしましたが、一番困ったことは誰も教えてくれる人がいないことです。

コードレビューももちろんそうですし、
案件の進め方、納品の仕方、チーム開発の方法、技術選定の方法、
全て完全に素人なので、合っているのかどうか不安でしかありませんでした。

そして何より、いざというときに助けてもらえる人がいません。
（案件の形態にもよりますが）

# 実際に経験したヒヤリハット

独立後間もない頃、某大企業のコーポレートサイト（WordPress）の刷新を任せていただきました。

Web開発というよりは、Web制作の案件です。

せっかくのリニューアルのタイミングなので、僕はクライアントに
「このままだとセキュリティ的によろしくないので、WordPressのアップデートもしておきましょう」
と提案しました。

WordPressのアップデートぐらい簡単に済むだろうと思っていたところ、
WordPressの最新版にするには、PHPを7系にアップデートしないといけないではないですか。
（PHPが5.3から更新がされていなかった!）

そして、その7系へのアップデートは、5.6からは自動でできるが、
現在の5.3からは自動でできず、一旦5.6に（多分）手動でアップデートしないといけない状態でした。

PHPのバージョン更新なんて、自分のローカルPCですらしたことないのに、本当に大丈夫だろうかと内心思いつつも、
手順を調べ、入念な準備とシミュレーションをし、テスト環境でアップデートに成功した上で、
リリースを約束した夜中に本番環境で作業を開始します。

作業内容自体はざっくり、

- 5.3の削除
- 5.6のインストール

です。

作業自体は簡単ですが、必要そうなパッケージを自分で手動で選択して（アン）インストールする上、
一つ一つのパッケージは中身を全く知らない状態です。

万が一何かがうまく行かないときにどうすればいいのか分からないリスクがあり、かなり緊張感があります。

とりあえず削除には成功し、インストールもしました。

さて、HPを見て動作確認...と。

あれ、何も表示されない。

「PHPが動いていない...だと...？」

はじめての経験に頭が真っ白になります。

背中を嫌な汗が伝い落ち、心臓がバクバク言っています。

さっき5.6のインストール時になんか変な表示があったような気がしたので、
もう一度terminalをよく見てみます。

テスト環境ではなかったエラーが出ている。

5.6のインストール時に、パッケージ間の依存関係の解決に失敗したようです。

（昔のことであまり覚えてないのですが、
確か必要なパッケージのバージョンを間違えたかなにかで、
テストしたときとはちょっと違うことをしたような記憶です）

エラーを急いで調べると、どうやらもう一度パッケージの削除からやり直すようです。

「これ、万が一直らなかったらどうなるんだ？」

最悪の事態がふと頭をよぎります。

どうやって先方に謝罪するのか、
発生した損失をどうやって個人の力で補填するのか（いや、できない）、
そんなことが高速で頭の中を駆け巡りました。

しかし、やるべきことは目の前のことです。

一度深呼吸をし、冷静になります。

「大丈夫、別に失敗しても命まではとられない」

そう思い直し、まずは先方にお詫びとともに今サーバーが動作しておらず、HPが閲覧できない旨をお伝えします。

そして、次にもとの5.3が動くようになれば最悪の事態はまず回避できるので、試します。

まずは、インストールに失敗した5.6を削除。

削除されたことを確認する。

ここまでは大丈夫。

そして5.3をインストール...

これが無事成功。

最悪の事態は回避できました。

あとは、バージョンアップの約束を守るべく、5.6(と7系)のインストールに再チャレンジするだけ。

この後は、テスト環境でやった通りの手はずで完了し、何も問題は起きませんでした。

後で振り返ってですが、
我ながらちゃんとやっててよかったなと思うのは、
手順書の作成とテスト環境でのテストです。

↓当時の実際の手順のメモの一部
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224815/828f3dd7-5db4-83b8-0fa2-6c5b62244212.png)

今となっては当たり前ですが、
まだエンジニアの経験が浅いながらにも、
仕事の基本を押さえながら進めていたことが救いとなりました。

先方にも無事更新が完了したと報告もできました。

めでたしめでたし。
Rubyアプリを手軽にCloud Runにする話

こんにちは妖精です。
[Catallaxy Advent Calendar](https://qiita.com/advent-calendar/2021/catallaxy) 4日目として、既存アプリケーションをGCPのCloud Runへ移行したことを簡潔に記録しようと思います。

元々のアプリケーションはVPS（さくらのVPS）1台にデプロイされていました。たまに突然Rubyサーバーが丸ごと落ちてしまうようで、そのたびに業務が止まってしまっていたようです。原因として最も考えられるのは単一のVPSに複数のサービスがただ単純にプロセスとしてデプロイ・稼働していたことでした。開発者は既にこの業務から離れており残されたのは必要最低限のドキュメントとわずかに継承された脳裏の記憶でした。

![cloudrun.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2345141/2279ec5e-4949-1307-40f4-4d1c2483e81a.png)

そんな状況だったので一気にGoogle CloudのCloud Runに移行することに決めました。ビルドの仕組みがなかったので、Google Cloud Buildを手順通り使うのは面倒なので、Cloud Runの[Deploying from source code機能](https://cloud.google.com/run/docs/deploying-source-code)を利用することとしました。この機能は `gcloud run` でいうところの `--source [DIR]` フラグに該当します。
Rubyアプリケーションなので、[Google Cloud Buildpacks](https://github.com/GoogleCloudPlatform/buildpacks)ではサポートされません（Cloud Run移行時も2021年12月現在も同じ）。しょうがないのでDockerfileを手で記述しました。と言ってもほとんどありのままのコピーに毛が生えた程度です。30秒でPRが作成され、瞬時にマージされていきました。
デプロイ(CD)はいつも通りGitHub Actionsを利用したのですが、利用するService Accountの設定の際、Google Cloud Buildの `(Project number)@cloudbuild.gserviceaccount.com` に対して `roles/iam.serviceAccountUser` ロールを追加する必要があるので、ハマりやすいポイントだと思います。

今回用いたActionsのコアの内容は以下です。

```yml:.github/workflows/deploy.yml
    - name: Deploy to Cloud Run
      id: deploy
      uses: google-github-actions/deploy-cloudrun@v0.6.0
      with:
        credentials: ${{ secrets.GCP_SA_KEY }}
        source: .
        service: ${{ env.SERVICE }}
        region: ${{ env.REGION }}
```

## 参考リソース
https://github.com/google-github-actions/deploy-cloudrun

以上、妖精でした。明日は信州の廻船問屋さんによる「私が本物の御老公様(仮)」です。
【Ruby】each_with_objectとinjectの違い

##each_with_object
配列やハッシュの要素を使って、新たに配列やハッシュを作成したりする際に簡潔に書くことができる。

- 引数に渡されたオブジェクトが常にhash変数に入っている。

```ruby
array = [[:hoge, 1], [:fuga, 2], [:piyo, 3]]

array.each_with_object({}) do | (key, value), hash |
  hash[key] = value
end

# => {:hoge=>1, :fuga=>2, :piyo=>3}
```

##inject

- ブロック内で最後に評価された値が入るのでブロック内でもう一度```hash```を書かないといけない。

```ruby
array = [[:hoge, 1], [:fuga, 2], [:piyo, 3]]

hash = array.inject({}) do | hash, (key, value) |
  hash[key] = value
  hash
end

#=> {:hoge=>1, :fuga=>2, :piyo=>3}
```


配列やハッシュの要素から一つのオブジェクトを作る場合に使うほうが向いてる。

```ruby
array = [2, 3, 4, 5]
array.inject do |result, item|
  result + item
end

#=> 14
```


##参考

https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/inject.html

https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/each_with_object.html

https://o-tyazuke.hatenablog.com/entry/2017/08/27/181042
wingetにより一瞬にしてWindowsにR環境を構築する

R Advent Calendar 2021 8日目の記事です。


https://qiita.com/advent-calendar/2021/rlang


2021年も終わろうという今日この頃、皆様のWindows（Windows 10）でもwingetコマンドをいつの間にか使えるようになっているのではないでしょうか？
本日はこれでRとRStudioをインストールしていきたいと思います。

なおWindowsTerminal未インストールの場合、Windows PowerShell（Windows10に最初から入っているPowerShell 5）で起動するコンソールでは表示がアレになるため、cmd.exeを起動して開くコンソールで作業した方が良いようです。
![コンソール](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/675583/a35d2dbc-9adc-f6ad-d53a-66badbfaa705.png)
（スクリーンショットのためにWindowsサンドボックス上で再現したため管理者権限で動いていますけど、cmd.exeを管理者として起動する必要はありません）

## インストール

### Rのインストール

```powershell
winget install -i rproject.r
```

`-i`オプションを付けているためインストーラーの画面が開くので、お好みで選択肢を選んでインストールします。終わり。

### RStudioのインストール

```powershell
winget install -i rstudio.rstudio.opensource
```

`-i`オプションを付けているためインストーラーの画面が開くので、お好みで選択肢を選んでインストールします。終わり。

## Rの設定

### デフォルトリポジトリ（CRAN）の設定

https://cran.r-project.org/mirrors.html

パッケージをインストールするCRANのミラーサイトを設定します。日本にあるミラーサイトを使っても良いのですけど

> Automatic redirection to servers worldwide, currently sponsored by Rstudio

と書かれている`https://cloud.r-project.org/`（0-Cloud）を使っておけば問題ないでしょう。RStudio社に感謝。

最近追加したアプリとして表示されるR（RGui）から`file.edit()`関数を使いマイドキュメント（例：`C:\Users\username\Documents`）に`.Rprofile`（`.rprofile`）というファイルを作成して以下のような内容を記入します。

```R:RGui
file.edit("~/.Rprofile")
```

```txt:.Rprofile
options(repos = c(CRAN = "https://cloud.r-project.org/"))
```

なお、Rに限らずマイドキュメントに設定を保存するようになっているプログラムが大量にあることとOneDriveが自動で「ドキュメント」というカタカナでフォルダを作り変更できない仕様になっているのとの合わせ技で、OneDriveのバックアップ機能でドキュメントフォルダをバックアップするのは完全に罠になっています。マイドキュメントをOneDriveでバックアップするのはオススメできません。

### ライブラリ保存先の変更

とりあえずRGuiから`{dplyr}`パッケージをインストールしてみましょう。

```R:RGui
install.packages("dplyr")
```

規定の設定ではライブラリは`C:\Program Files\R\R-4.1.2\library`のような場所にインストールされます。ここは管理者権限のない場合には書き込めないので、書き込めない場合Rは`C:\Users\username\Documents\R\win-library`のような場所へインストールするか尋ねてきます。
承諾してインストールするとデフォルトのインストール先はそこに設定され、今後は尋ねられなくなります。

## RStudioの設定

特になし。

## その他インストールとは関係のない話

### Proxy設定

~~`install.packages()`等はWindowsのProxy設定を使ってくれるようで、特に設定の必要はありません。~~

（2022/05/22追記）これまで`download.file(method = "wininet")`だったためにWindowsのProxy設定を自動で使ってくれていたところがR 4.2.0で`wininet`は非推奨となり、デフォルトは他OSと同じ`libcurl`になったため、WindowsのProxy設定を使ってくれなくなりました。以下のように`ALL_PROXY`を設定するのがオススメです。

色々なパッケージの内部で使用されている`{curl}`パッケージはWindowsのProxy設定を使ってくれないようなので、Cntlmやpxを設定して`.Renviron`（`.Rprofile`と同じように`file.edit("~/.Renviron")`で編集できます）に`ALL_PROXY=localhost:3128`とか書くと良いです。詳しくは`{curl}`パッケージのドキュメントを見てみてください。

### Rscriptコマンドと.Rファイルの文字コード

`Rscript --encoding=utf-8 foobar.R`みたいな感じでエンコードのオプションを指定できます。
Evil で縦方向 f/F  (リピート不可 😢)

[Emacs Advent Calendar 2021](https://qiita.com/advent-calendar/2021/emacs) 9 日めの記事です。

# デモ

うおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおおお

![vf-4x.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594390/0724dce1-0620-64ed-38aa-dffc14e8cf76.gif)

> Firefox では画像をクリックしないと gif 画像がアニメーションしませんでした……

# コンテキスト

| 語        | 解説 |
|---|---|
| [Evil]    | Vim 再現プラグイン   |
| f/F       | 横方向ジャンプ (Vim バインディング) |
| 縦方向 f/F | 縦方向ジャンプ       |

[Evil]: https://github.com/emacs-evil/evil

# コード

## 実装

1 行ずつ移動して目当ての文字を探します。また `evil-read-key` のおかげで [digraph] も読めます:

[digraph]: https://vim-jp.org/vimdoc-ja/digraph.html

```elisp
(defun toy/vf--impl (target-char delta-move)
    (let* ((start-point (point))
           (start-col (current-column))
           (jump-point nil))
        (while (and (not jump-point)
                    (eq 0 (forward-line delta-move)))
            (when (and (eq (move-to-column start-col) start-col)
                       (eq (char-after) target-char))
                (setq jump-point (point))))
        (goto-char (or jump-point start-point))
        jump-point))

(defun toy/vf (&optional target-char)
    "Searches forward a character in the same column. Returns the point on jump or nil on failure."
    (interactive)
    (toy/vf--impl (or target-char (evil-read-key)) 1))

(defun toy/vF (&optional target-char)
    "Searches backward a character in the same column. Returns the point on jump or nil on failure."
    (interactive)
    (toy/vf--impl (or target-char (evil-read-key)) -1))
```

しかし `;` キーで検索のリピート……はできないなんちゃって実装です。

## Tip

縦方向ジャンプ後にカーソルを画面中央へ持っていくキーバインディング例:

```elisp
(defun toy/force-center()
    (evil-scroll-line-to-center (line-number-at-pos)))

(evil-define-key 'normal 'global
    " v" (lambda () (interactive) (when (toy/vf) (toy/force-center)))
    " V" (lambda () (interactive) (when (toy/vF) (toy/force-center))))
```

# ご閲覧いただきありがとうございました

　ベター版をお持ちの方はお知らせください

　　　　　\_(.\_.)\_

# 真の姿

```
+---------------------------------+
| ベター版をお持ちの方はお知らせください |
+-------+---------+----------------+
        |         |
        \__(._.)__/
            |  |
            \  \
              \  \
                \  \
                  \  \
                     \ \
                        \\
                           \
```
【React】 UseEffect を使用して、コンポーネントが呼ばれた最初だけ実行する処理を実装

今回のテスト
ボタンをクリックすると、コンポーネントが呼ばれる最初だけ、ある処理を実行する。

■以下前提のコード

```react:sample.js
import React,{useState,useEffect} from 'react'
const sample= () => {
}
export default sample
```

■以下ボタンを実装

```react:sample.js
import React,{useState,useEffect} from 'react'

const sample = () => {
    return (
        <div>
            <button onClick={()=> setCnt(prevCnt=>prevCnt+1)}>Click Count {cnt}</button>          
        </div>
    )
}
export default sample
```

■以下stateとstateを更新する関数(setCnt)を実装。※constの最後の,[]が一度だけ呼び出す肝。

```react:sample.js
import React,{useState,useEffect} from 'react'

const sample = () => {
    const [cnt,setCnt] = useState(0)
    useEffect(()=> {
        console.log("useEffect invoked")
    },[])
    return (
        <div>
            <button onClick={()=> setCnt(prevCnt=>prevCnt+1)}>Click Count {cnt}</button>          
        </div>
    )
}
export default sample
```
■結果
ブラウザを開くとブラウザのコンソールに「useEffect invoked」と1度だけ表示される。ボタンをクリックしても、それ以降表示されない。
[Flutter]ThemeDataのprimaryColorが適用されない

概要
===
FlutterでThemeDataを利用してアプリのテーマをカスタマイズしたい

課題
===
ThemeDataの[primaryColor](https://api.flutter.dev/flutter/material/ThemeData/primaryColor.html)がのpropertyだとAppBarの色が変更されなかった適用されなかった

```main.dart
Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        primaryColor: Color(0xFF0A0E21),
        scaffoldBackgroundColor: Color(0xFF0A0E21),
      ),
      home: home(),
    );
  }

```

対策
===
ThemeDataの[colorScheme](https://api.flutter.dev/flutter/material/ColorScheme-class.html)のpropertyを使う

```main.dart
Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(
        colorScheme: ColorScheme.light(
          primary: Color(0xFF0A0E21),
        ),
        scaffoldBackgroundColor: Color(0xFF0A0E21),
      ),
      home: home(),
    );
  }
```

参考文献
===
[Flutter ThemeData Primary color not changing from theme when trying to add a primary color](https://stackoverflow.com/questions/69169306/flutter-themedata-primary-color-not-changing-from-theme-when-trying-to-add-a-pri)

最後に
===
なぜこのような動作になるのかまでは確認できておりません。
そもそもprimaryColorを使うべきではないという話かもしれません。
理由やベストプラクティスをご存じであればコメントいただければ幸いです。
Stripe Connectを利用したレベニューシェアシステム

もう今年も残りわずかとなりました。
[Stripe Advent Calender 2021](https://qiita.com/advent-calendar/2021/stripe)の16日目の記事です。

https://qiita.com/advent-calendar/2021/stripe

# 概要

WordPressをベースとした静的サイトホスティングやヘッドレス CMSを提供している**[Shifter](https://www.getshifter.io/ja/)**というサービスがありますが、Shifterのパートナー向けのレベニューシェアのシステムの開発をお手伝いする機会がありました。

ユーザーがパートナー経由でShifterアカウントを申し込むと、ユーザーが月額利用料を支払う際に一定額をインセンティブとしてパートナーへ、残りをShifterへ送金するような仕組みをStripe Connectを使って実装しました。

https://www.getshifter.io/ja/

https://spn.getshifter.io/

# Stripe Connectとは

だいぶ雑に言うと、Stripeアカウント同士で親子関係をつくれて、決済したお金のフローを細かく柔軟にコントロールできるものです。

公式サイトでは 購入者/サービスプラットフォーム/販売者 間でのお金の流れがShopifyやLyftなどを例に、どの場合にどのようなフローが適しているのかいくつかのユースケースが記載されています。



https://stripe.com/jp/connect

# どのように実現したか

|![スクリーンショット 2021-12-09 16.53.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213486/e2c39fc5-dbb7-cdc5-e148-cfe682af8b0f.png)|
|:--|

収益の分配を行う仕組みとしてパートナー用のポータルサイト構築を行ないました。
ポータルサイトは以下の機能を持っています。

- Shifterアカウントの発行
- パートナーに紐づくShifterアカウントリスト確認
- パートナーのStripeアカウントとShifterのStripeアカウントの連携

ポータルサイトではStripe Connect を利用し、ShifterのStripeアカウントとパートナーのStripeアカウントの連携を行います。

ポータルサイト経由で発行したShifterアカウントにはどのパートナーが発行したかの情報が紐づけられており、ユーザーがShifterの月額利用料を支払うたびに、支払い金額の一定割合がパートナーに送金されるようになっています。

|![スクリーンショット 2021-12-09 16.53.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213486/7f8198a2-877e-441f-fd45-5dffedee1da5.png)|
|:--|

ポータルサイトからStripe Connectを利用したStripeアカウント間の連携には以下のOAuthの仕組みを利用しています。

https://stripe.com/docs/connect/oauth-reference

https://stripe.com/docs/connect/oauth-standard-accounts

また、ユーザーの月額利用料支払い時に連携しているStripeアカウントへの送金を行う仕組みは以下のあたりを参照しました。

https://stripe.com/docs/connect/subscriptions

# おわりに

Stripeは開発者フレンドリーで、ドキュメントもコードとあわせて記載されています。
実装周りで困ることはほぼありませんでした。

Stripe Connectでは、**アカウントタイプ**、**支払い/送金/入金のフロー**などを理解して自分が提供したいサービスにはどんなパターンが適しているのかを決定するまでが少し大変だと思います。

https://stripe.com/docs/connect/accounts

パートナービジネスをする上で、レベニューシェアやキックバックを行うようなビジネスモデルの場合に、Stripe Connectを使うことで送金の仕組みを簡単に実装することができます。

今回のようなSaaS向けの決済システムの設計や開発の支援が必要な場合は、[デジタルキューブ](https://www.digitalcube.jp/)か[ヘプタゴン](https://heptagon.co.jp/)へご連絡ください。
【JS】配列操作のまとめ②（some, every, includes）

# これは何？ 
前回[こちらの記事](https://qiita.com/Yuji_6523/items/b84fcaeea8b932d757ac)の続編として、`some, every, includes`の配列操作についてまとめていきます。

# some()
第１引数の関数で指定された条件に、配列内の要素が１つでも当てはまるかどうかを判定する
＊元々の配列の要素は変更されない。

### 返り値
- 配列の要素が1つでも条件を満たしていれば`true`を返し、そうでなければ`false`を返す


``` js
const array = [1, 2, 3, 4, 5, 6];

// 配列の要素に3が含まれているか判定
const isThree = array.some((item) => item === 3);

// 配列の要素に10が含まれているか判定
const isTen = array.some((item) => item === 10);


console.log(isThree); // true
console.log(isTen); // false
```

### どんな時に使う？
配列内の要素に、想定している条件が存在するかどうか判定したい時


# every()
第１引数の関数で指定された条件に、配列内の全ての要素が当てはまるかどうかを判定する
＊元々の配列の要素は変更されない。

### 返り値
- 配列の要素が1つでも条件を満たしていれば`true`を返し、そうでなければ`false`を返す


``` js
const array = [1, 2, 3, 4, 5, 6];

// 配列の全て要素が6以下の数か判定
const lessSix = array.some((item) => item <= 6);

// 配列の全て要素が10以上の数か判定
const greaterTen = array.some((item) => item >= 10);


console.log(lessSix); // true
console.log(greaterTen); // false
```

### どんな時に使う？
配列内の全ての要素が、想定している条件に当てはまるか判定したい時


# includes()
特定の要素が配列に含まれているかどうかを`true` or `false`で返す

＊元々の配列の要素は変更されない。また、文字列に対してもincludesメソッドを使用できるが今回は配列に絞ったものになりますので割愛いたします。



### 返り値
- 引数で指定した値が、配列内から見つかった場合は`true`を返し、見つからなかった場合は`false`を返す


``` js
const array = [1, 2, 3, 4];

const hasValue = array.includes(3);
const hasNotValue = array.includes(5);

console.log(hasValue); // true
console.log(hasNotValue); //false

```

### どんな時に使う？
配列内の要素に、想定している値が含まれるか判定したい時

### 第２引数
第２引数を指定することで、検索を開始する位置を指定することができます


``` js
const array = [1, 2, 3, 4];

// arrayのインデックス番号`1`から開始する[2, 3, 4]の配列から探している
const hasValue = array.includes(3, 1);
// arrayのインデックス番号`2`から開始する[3, 4]の配列から探している
const hasNotValue = array.includes(1, 2); 

console.log(hasValue); // true
console.log(hasNotValue); //false

```

第２引数が配列の長さと同じか大きい場合は、`false`を返す


``` js
const array = [1, 2, 3, 4];

console.log( array.includes(1, 4)); // false
console.log( array.includes(1, 10)); //false
```


# まとめ
- some()は、配列内の要素が１つでも条件に当てはまれば`true`になる
- every()は、配列内の全ての要素が条件に当てはまれば`true`になる
- includes()は、配列内に、指定した値が含まれれば`true`になる
- `some, every, includes`は配列の要素を変更するのではなく、配列の要素をチェックするメソッド