OmniAICreator/Qiita-1.07M huggingface dataset:
[Python]等差数列×等比数列の解を求めてみた[備忘録]

# はじめに
実装結果を備忘録として残します🐍
Python3環境下にて、是非お使いください🎸

# 本編
## 数式
```math
今回コーディングする当差数列×等比数列の数式： \left(an+b \right) \left(c \right)^{\!n} 
```
## コーディング
```py:python
#sympy内の関数を使用
from sympy import *
n=Symbol("n")
a,b,c = map(int,input("a,b,c=? ? ?").split())
while c==0:
    print("Input a,b,c except c=0")
    a,b,c = map(int,input("a,b,c=? ? ?").split())
Prog = sequence((a*n+b)*c**n, (n, 0, 20))

#以下、出力(例：a,b,c=1 1 2)
print([int(N) for N in Prog])
print(Prog[3])
```
>出力結果
[1, 4, 12, 32, 80, 192, 448, 1024, 2304, 5120, 11264, 24576, 53248, 114688, 245760, 524288, 1114112, 2359296, 4980736, 10485760, 22020096]
32

# 使い方
▶a,b,cは半角スペースで区切り、入力してください。

:::note info
c=0の場合、while文以下のループが発生します。(c≠0でお願いいたします。)
:::

▶外部ライブラリにつき、予めインストールを要します。（以下、プロンプトでの入力例）
```bash:bash/zsh
conda install sympy　#エラーが起これば、下のコマンドを実行してください。
pip install sympy 
```


# References
## More Info
- About Sympy:https://www.sympy.org/en/index.html
- About How to Use Sympy: https://note.nkmk.me/python-sympy-factorization-solve-equation/

## About me

- SNS landing page(lit.link): https://lit.link/myon123
- GitHub: https://github.com/myon-bioinformatics
- Qiita: https://qiita.com/myon-bioinformatics
- Twitter(仕事用): https://twitter.com/myonitbusiness
- Twitter(プライベート用): https://twitter.com/myonmusicpgdev
- tumblr: https://www.tumblr.com/myon-helloworld
- Reddit: https://www.reddit.com/user/myon_reddit
- Pixiv: https://www.pixiv.net/users/87109499
- YouTube(Composer): https://www.youtube.com/channel/UC22_pvlkQynYsrSpAfyzEzA
- SpeakerDeck: https://speakerdeck.com/myon_bioinformatics
- マシュマロ(質問箱): https://marshmallow-qa.com/myonitbusiness

- LINE: https://line.me/R/ti/p/@661cphit
- Microsoft TechNet: https://social.msdn.microsoft.com/Profile/myon.TechNet
- プロフカード: https://profcard.info/u/ziUhwgZihSSTLZdqPZ0gz5aru6A3
- ニコニコ動画(niconico): https://www.nicovideo.jp/user/126513036
- Wish List: https://www.amazon.co.jp/hz/wishlist/ls/290EJPJ3PAS73?ref_=wl_share
- 転職ドラフト: https://job-draft.jp/users/58541
- RESUME.id: https://www.resume.id/myon
- Wantedly: https://www.wantedly.com/id/myon123
- Mastodon: https://mstdn.social/@myon
- mixi: https://mixi.jp/show_profile.pl?id=68...
- Instagram: https://www.instagram.com/myonmusicpgdev
- Pinterest: https://www.pinterest.jp/myonmusicpgdev
- Forkwell: https://portfolio.forkwell.com/@myon

https://twitter.com/myonitbusiness/status/1573533239133671424


https://twitter.com/myonitbusiness/status/1587393241371987968
UnityカスタムシェーダでPOINTSIZEを変更する。


UnityカスタムシェーダでPOINTSIZEを変更する。

DirectからOpenGL系に変更をする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555658/33e19202-cd92-b3f2-7bc4-b79a7d38daba.png)

```cs

Shader "Custom/VertexColor"
{
    Properties{
      _Size("ShaderSize", Float) = 1.000000
      _PointSize("PointSize", Float) = 5.0

    }
    SubShader{
    Pass {
        LOD 200

        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        uniform float _PointSize;


        struct VertexInput {
            float4 v : POSITION;
            float4 color: COLOR;
        };

        struct VertexOutput {
            float4 pos : SV_POSITION;
            float4 col : COLOR;
            float psize : PSIZE;

        };

        VertexOutput vert(VertexInput v) {

            VertexOutput o;
            o.pos = UnityObjectToClipPos(v.v);
            o.col = v.color;
            o.psize = _PointSize;

            return o;
        }

        float4 frag(VertexOutput o) : COLOR {
            return o.col;
        }

        ENDCG
        }
    }
}

```

```cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class PointCloud : MonoBehaviour
{

    private Mesh mesh;
    int numPoints = 600000;

    // Use this for initialization
    void Start()
    {
        mesh = new Mesh();

        GetComponent<MeshFilter>().mesh = mesh;
        CreateMesh();
    }

    void CreateMesh()
    {
        Vector3[] points = new Vector3[numPoints];
        int[] indecies = new int[numPoints];
        Color[] colors = new Color[numPoints];
        for (int i = 0; i < points.Length; ++i)
        {
            points[i] = new Vector3(Random.Range(-10, 10), Random.Range(-10, 10), Random.Range(-10, 10));
            indecies[i] = i;
            colors[i] = new Color(0,0,1,  1.0f);
        }

        mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        mesh.vertices = points;
        mesh.colors = colors;
        mesh.SetIndices(indecies, MeshTopology.Points, 0);

    }
}

```
curl: SORACOM Harvest Files に画像データを送る

トークンの取得

```bash:get_token.sh
#
EMAIL=guest@example.com
PASSWORD=secret007
#
curl  -X POST -H "Content-Type: application/json" \
        -d "{ \"email\": \"${EMAIL}\", \"password\": \"${PASSWORD}\" }" \
        https://api.soracom.io/v1/auth > token.json
#
```

画像のアップロード

```bash:send_jpg.sh
#
API_KEY=`jq .apiKey token.json | sed 's/"//g'`
API_TOKEN=`jq .token token.json | sed 's/"//g'`
#
FILE="sample01.jpg"
#
echo ${API_KEY}
#
curl -X PUT -H "Content-Type: text/x-sh" -H "X-Soracom-API-Key: ${API_KEY}" \
 -H "X-Soracom-Token: ${API_TOKEN}" --data-binary @${FILE} \
	"https://api.soracom.io/v1/files/private/sample/${FILE}"
#
```

Harvest Files でデータの確認
![harvest_files_aug01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/8a0375c0-4dcb-0d37-66f1-b2139339f0e1.png)


参考情報

[API キーと API トークン](https://users.soracom.io/ja-jp/tools/api/key-and-token/)
[ファイルを Harvest Files に送信する](https://users.soracom.io/ja-jp/docs/harvest/send-files/?tab-2-2=selected)
10 約数列挙 Dif:142 ABC180 C：「AtCoder　凡人が『緑』になるための精選50問詳細解説」サンプル

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

前：https://qiita.com/sano192/items/9e611a60ba2a49b94e89
次：https://qiita.com/sano192/items/2193fbb57ab66237ed9e

https://atcoder.jp/contests/abc180/tasks/abc180_c

**【目標】**
・約数列挙のアルゴリズムを理解し、実装できるようになる

**【概要】**
Nが何で割り切れるか＝Nの約数は何か、つまりNの約数を列挙できれば解ける。約数列挙のアルゴリズムはそこまで難しくないので、内容までしっかり理解して実装できるようになろう。

**【方針】**
Nの約数がわかればそれを答えて終わり。
問題はNの約数をどのようにして求めるか。

以下の手順でNの約数を確認できる。
・Nが1で割り切れるか確認する。(絶対に割り切れる)
　→1と、N//1を約数として記録。
・Nが2で割り切れるか確認する。割り切れるなら
　→2と、N//2を約数として記録。
・Nが3で割り切れるか確認する。割り切れるなら
　→3と、N//3を約数として記録。
…
・√N<(割る数)になったら終わり。記録した約数を出力する。

例：N=40の場合
・40が1で割り切れるか確認する。
　→1と、40//1=40を約数として記録。
・40が2で割り切れるか確認する。
　→2と、40//2=20を約数として記録。
・40が3で割り切れるか確認する。
　→割り切れない。
・40が4で割り切れるか確認する。
　→4と、40//4=10を約数として記録。
・40が5で割り切れるか確認する。
　→5と、40//2=8を約数として記録。
・40が6で割り切れるか確認する。
　→割り切れない。
・√40=6.32...<7だから終わり。
記録した約数=1,2,4,5,8,10,20,40

なぜ√N<iになったら終わりか？
√Nより大きい数で割り切れてもそのペアはすでに記録されているはず。そのため√Nより大きい数での試し割りは不要。
(√40=6.32...より大きい8は40を割り切れるが、そのペアである5で割った時、40//5＝8も約数として記録されている)

以上の方法を使い、計算量O(√N)で約数が列挙できる。
制約はN<=10^12だから√N<=10^6。これならTLE(実行時間制限超過)しない。

**【実装】**
まず約数列挙する関数を作ろう。
Nを引数として受け取り、約数を記録したリストを返す関数。
名前はDivisor_Listとする。

```python:
def Divisor_List(N):
```

まず約数を格納するリストを作る。

```python:
    divisor=[]
```

i=1~√Nまで順に割り切れるか確認する。

```python:
    i=1
    while i**2<=N:
        if N%i==0:
            divisor.append(i)
            if i!=N//i:
                divisor.append(N//i)
        i+=1
```

while i<=math.sqrt(N)
と書けばi=1~√Nの範囲とできそうだが、ルートをとるなど少数が出る操作はプログラミングにおいて誤差がでる可能性がある。
そのため
i<=√N
→i^2<=N
と置き換え、少数が出ないようにwhileの範囲を指定している。

Nがiで割り切れるか確認し、割り切れる場合はi、N//iを約数として記録。
if i!=N//i
というのは約数のペアが同じ場合に重複して記録しないため。
例えばN=49に対してi=7を試す場合、
i=7
N//i=7
となり、このif文がないと7を2回divisorに追加してしまう。

最後にdivisorをソートして返す。

```python:
    divisor.sort()
    return divisor
```

この関数の計算量は約数の個数をkとしてO(√N+klogk)となる。klogkの部分はソートを行うため。ただしほとんどの場合klogkは√Nに比べて非常に小さいので気にしなくてよく、実質の計算量はO(√N)と覚えておけば良い。

入力を受け取る。

```python:
N=int(input())
```

ansという変数にNの約数リストを格納する。

```python:
ans=Divisor_List(N)
```

あとはansを順に出力するだけ。

```python:
for x in ans:
    print(x)
```

for x in リスト:
と書くとリストの要素を一つずつxに格納して処理ができる。便利な書き方なのでぜひ他の問題でも使ってほしい。

**【コード全文】**

```python:
def Divisor_List(N):
    divisor=[]

    i=1
    while i**2<=N:
        if N%i==0:
            divisor.append(i)
            if i!=N//i:
                divisor.append(N//i)
        i+=1

    divisor.sort()
    return divisor

N=int(input())

ans=Divisor_List(N)

for x in ans:
    print(x)
```

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

前：https://qiita.com/sano192/items/9e611a60ba2a49b94e89
次：https://qiita.com/sano192/items/2193fbb57ab66237ed9e
Excelで請求書バーコードGS1-128を作成する

バーコードの作り方って記事が少なくて作るのに苦労したので書いておきます

## CODE128フォントをインストール

GS1-128はCODE128(CODE-C)なのでCODE128のフォントをダウンロード、インストールしてExcelでバーコード表示できるようにします

Grandzebu code128.ttf ページ中央部にダウンロードがあります
https://grandzebu.net/informatique/codbar-en/code128.htm

## 関数でCODE-Cバーコード作成

バーコードは適当な値で作っています
![gs1-128sample.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530205/b64e692b-9265-f30d-386e-a57dcbed7259.png)
B1セルはGS1-128バーコード値です（桁数と項目のマッピングは参考のガイドライン参照）
B2セルはチェックディジットで関数は以下です

```vb
=MOD(105+102+2*INT(LEFT(B1,2))+3*INT(MID(B1,3,2))+4*INT(MID(B1,5,2))+5*INT(MID(B1,7,2))+6*INT(MID(B1,9,2))+7*INT(MID(B1,11,2))+8*INT(MID(B1,13,2))+9*INT(MID(B1,15,2))+10*INT(MID(B1,17,2))+11*INT(MID(B1,19,2))+12*INT(MID(B1,21,2))+13*INT(MID(B1,23,2))+14*INT(MID(B1,25,2))+15*INT(MID(B1,27,2))+16*INT(MID(B1,29,2))+17*INT(MID(B1,31,2))+18*INT(MID(B1,33,2))+19*INT(MID(B1,35,2))+20*INT(MID(B1,37,2))+21*INT(MID(B1,39,2))+22*INT(MID(B1,41,2))+23*INT(MID(B1,43,2)),103)
```

A4セルはCODE128フォントを適用しています　バーコードの形式は以下です
`105(startC) + 102(Fnc1) + バーコード値 + チェックディジット + 106(stop)`

```vb
="ÒÏ"&UNICHAR(IF(INT(LEFT(B1,2))<95,LEFT(B1,2)+32,LEFT(B1,2)+105))&UNICHAR(IF(INT(MID(B1,3,2))<95,MID(B1,3,2)+32,MID(B1,3,2)+105))&UNICHAR(IF(INT(MID(B1,5,2))<95,MID(B1,5,2)+32,MID(B1,5,2)+105))&UNICHAR(IF(INT(MID(B1,7,2))<95,MID(B1,7,2)+32,MID(B1,7,2)+105))&UNICHAR(IF(INT(MID(B1,9,2))<95,MID(B1,9,2)+32,MID(B1,9,2)+105))&UNICHAR(IF(INT(MID(B1,11,2))<95,MID(B1,11,2)+32,MID(B1,11,2)+105))&UNICHAR(IF(INT(MID(B1,13,2))<95,MID(B1,13,2)+32,MID(B1,13,2)+105))&UNICHAR(IF(INT(MID(B1,15,2))<95,MID(B1,15,2)+32,MID(B1,15,2)+105))&UNICHAR(IF(INT(MID(B1,17,2))<95,MID(B1,17,2)+32,MID(B1,17,2)+105))&UNICHAR(IF(INT(MID(B1,19,2))<95,MID(B1,19,2)+32,MID(B1,19,2)+105))&UNICHAR(IF(INT(MID(B1,21,2))<95,MID(B1,21,2)+32,MID(B1,21,2)+105))&UNICHAR(IF(INT(MID(B1,23,2))<95,MID(B1,23,2)+32,MID(B1,23,2)+105))&UNICHAR(IF(INT(MID(B1,25,2))<95,MID(B1,25,2)+32,MID(B1,25,2)+105))&UNICHAR(IF(INT(MID(B1,27,2))<95,MID(B1,27,2)+32,MID(B1,27,2)+105))&UNICHAR(IF(INT(MID(B1,29,2))<95,MID(B1,29,2)+32,MID(B1,29,2)+105))&UNICHAR(IF(INT(MID(B1,31,2))<95,MID(B1,31,2)+32,MID(B1,31,2)+105))&UNICHAR(IF(INT(MID(B1,33,2))<95,MID(B1,33,2)+32,MID(B1,33,2)+105))&UNICHAR(IF(INT(MID(B1,35,2))<95,MID(B1,35,2)+32,MID(B1,35,2)+105))&UNICHAR(IF(INT(MID(B1,37,2))<95,MID(B1,37,2)+32,MID(B1,37,2)+105))&UNICHAR(IF(INT(MID(B1,39,2))<95,MID(B1,39,2)+32,MID(B1,39,2)+105))&UNICHAR(IF(INT(MID(B1,41,2))<95,MID(B1,41,2)+32,MID(B1,41,2)+105))&UNICHAR(IF(INT(MID(B1,43,2))<95,MID(B1,43,2)+32,MID(B1,43,2)+105))&UNICHAR(IF(INT(D77<95),D77+32,D77+105))&"Ó"
```
PayPayやLINEPayの請求書バーコードリーダーで読み込めれば完成！！

#### 参考

GS1-128シンボルによる標準料金代理収納ガイドライン（第4版）
https://www.dsri.jp/standard/barcode/gs1-128_payment_service.html

yahoo知恵袋　CODE128(CODE-C)バーコード作成について
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12147492422
CakePHP4_migrationでdatetimeカラムが追加できない



#まえがき
CakePHPのmigrationを利用した際に発生したエラーの対処法となります。

#バージョン
CakePHP4

#手順
・Usersテーブルにmigrationでcreatedカラムを追加する

```php:20210801024646_ChangeUsers.php
    public function change()
    {
        $table = $this->table('users');
        $table->addColumn('created', 'datetime');
        $table->update();
    }
```

※上記のmigrationファイルでmigrate実行するとエラーが発生
 `bin\cake migrations migrate`

```
PDOException: SQLSTATE[22007]: Invalid datetime format: 1292 Incorrect datetime value: '0000-00-00 00:00:00' for column `proto_todo`.`users`.`created` at row 1 in C:\xampp\htdocs\cakephp_apps\todo\vendor\robmorgan\phinx\src\Phinx\Db\Adapter\PdoAdapter.php:194
```

設定情報はシンプルなものなのですが、何度実行しても失敗してしまいます。
原因を調査した結果、以下の内容に変更すると成功しました。

```php:20210801024646_ChangeUsers.php
    public function change()
    {
        $table = $this->table('users');
        $table->addColumn('created', 'datetime', [
            'null' => true // NULLを許容
        ]);
        $table->update();
    }
```

 `bin\cake migrations migrate`

#原因
エラーが発生した原因としては、既にテーブル上に登録されているデータが悪さをしていたようでした。
addColumnsが処理される際、既存レコードのcreatedに対しては'0000-00-00 00:00:00'が登録される動きになるようです。
しかしcreatedカラムはnullを許容していなかった為エラーが発生してしまった様です。
上記を踏まえカラムをnull許容する事で正常にmigrationが行われました。

考えれば分かる事でした。。余計な時間を使ってしまった。。。
Win11にアップデートするとWSL2のマウントでエラーが出る

# 背景
Windows 11 Insider Previewの通知が来たので、ウキウキしながらアップデート

新しくなったUIに感心してたら、WSLからWindows側のファイル(`/mnt/c/`)が参照できなくなった。

# 発生したエラー

WSL起動時に

> ファイル システムの 1 つをマウント中にエラーが発生しました。詳細については、「dmesg」を実行してください。

というメッセージが発生。

指示に従ってdmesgを叩くと、

```
ERROR: MountPlan9WithRetry:285: mount drvfs on /mnt/c
```

みたいなエラーが発生していることが確認できた。マウントに失敗したんだろうなぁ。

# 対処方法

いろいろ調べて試したけど効果なし。

やけくそになったので、管理者権限のPowerShellでwslをアップデートしたら解決

```powershell
PS C:\WINDOWS\system32> wsl --update
更新をチェック中...
更新をダウンロード中...
更新をインストール中...
この変更は、次回の WSL 再起動時に有効になります。強制的に再起動するには、'wsl --shutdown' を実行してください。
カーネル バージョン: 5.10.43
PS C:\WINDOWS\system32> wsl --shutdown
```
AtCoderログ：0047 - ABC 090 B

# 問題

https://atcoder.jp/contests/abc090/tasks/abc090_b

## 問題文
> $A$ 以上 $B$ 以下の整数のうち、回文数となるものの個数を求めてください。 ただし、回文数とは、先頭に $0$ をつけない $10$ 進表記を文字列として見たとき、前から読んでも後ろから読んでも同じ文字列となるような正の整数のことを指します。

## 制約
> ・$10000 \le A \le B \le 99999$
> ・入力はすべて整数である

## 収録されている問題セット
- [AtCoder に登録したら次にやること](https://qiita.com/drken/items/fd4e5e3630d0f5859067) ([第05問類題](https://qiita.com/drken/items/fd4e5e3630d0f5859067#%E7%AC%AC-5-%E5%95%8F--abc-083-b---some-sums-200-%E7%82%B9))

# 回答
## 回答1 (AC)
回文数 (Palindromic Numbers) に関する問題です。整数 i を a 以上 b 以下の範囲で変化させ、i が回文数かどうかをチェックし、回文数である場合にはカウンター answer の値を1ずつ増やしていけば良いでしょう。整数 i が回文数かどうかのチェックは一般には面倒ですが、この問題では整数 i は 5 桁なので、回文数になる条件は、万の位(i/10000)＝一の位(i%10)、かつ、千の位((i/1000)%10＝十の位((i/100)%10)となります。コードは以下のようになりました。

```C++:abc090b-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int a, b;
  cin >> a >> b;
 
  int answer = 0;
  for ( int i=a; i<=b; i++ ) {
    if ( i/10000==i%10 && (i/1000)%10==(i%100)/10 ) {
      answer += 1;
    }
  }
  cout << answer << endl;
}
```

## 回答2 (AC)
回答1のように整数 i の各位を数式で表すのにピンと来ない場合には、文字列で処理することも可能です。整数 i を型変換した文字列 s が回文数になる条件は、s.at(0)==s.at(4) かつ s.at(1)==s.at(3) です。コードは以下のようになりました。

```C++:abc090b-2.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  int a, b;
  cin >> a >> b;
 
  int answer = 0;
  for ( int i=a; i<=b; i++ ) {
    string s = to_string(i);
    if ( s.at(0)==s.at(4) && s.at(1)==s.at(3) ) {
      answer += 1;
    }
  }
  cout << answer << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc090/tasks/abc090_b/editorial) → [コンテスト全体の解説](https://img.atcoder.jp/arc091/editorial.pdf)
回答1と同じ方針でした。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0046 - ARC 124 B](https://qiita.com/RoadLynton/items/757323fe4f27ba8e2df7)
ELECOM UC-SGTをMacで動かす

## ドライバインストール
インストール手順に関しては、すでに良い記事があるのでそちらを参考に。

https://www.opensourcetech.tokyo/entry/2017/04/07/ELECOM_UC-SGT%E3%82%92_Mac_OS_X%E3%81%A7%E4%BD%BF%E7%94%A8%E5%87%BA%E6%9D%A5%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B%EF%BC%81

## ドライバがロードできない問題
インストール時にInfo.plistを編集するので、コードサインエラーが発生する

```
$ kextutil -tn /Library/Extensions/ProlificUsbSerial.kext
Skipping staging and system policy checks because not running as root, expect staging errors.
Untrusted kexts are not allowed
Kext rejected due to invalid signature: <OSKext 0x7fec95f0a330 [0x7fff8e5aecf0]> { URL = "file:///Library/Extensions/ProlificUsbSerial.kext/", ID = "com.prolific.driver.PL2303" }
Code Signing Failure: code signature is invalid
Warnings: 
    Dependency lacks appropriate value for OSBundleRequired and may not be available during early boot: 
        com.apple.iokit.IOSerialFamily - Safe Boot

Diagnostics for /Library/Extensions/ProlificUsbSerial.kext:
Warnings: 
    Dependency lacks appropriate value for OSBundleRequired and may not be available during early boot: 
        com.apple.iokit.IOSerialFamily - Safe Boot
```

Appleのサイトを確認するとドライバ(KEXT's)の場合はInfo.plistも追跡対象と記載があるのでこれが原因で間違いなさそう

```
Approved KEXTs are tracked in a system-wide policy database through the team identifier in the KEXT's code signature and the bundle identifier from the KEXT's Info.plist, so updating a KEXT that has already been approved will not trigger a new approval request.
```
参照元:https://developer.apple.com/library/archive/technotes/tn2459/_index.html

## SIPを無効にする
リカバリモードでcsrutil disableを実行し、System Integrity Protection(SIP)を無効化すれば問題なくロードできるようになる
ロードは以下のコマンド
```
sudo kextload /Library/Extensions/ProlificUsbSerial.kext
```

下のサイトがよくまとまっています。
https://leico.github.io/TechnicalNote/Mac/csrutil

## Macで保護されるディレクトリ
システム整合性保護では、システムの以下の部分が保護されます。

/システム
/usr
/bin
/sbin
/var
OS X にあらかじめインストールされている App
他社製の App とインストーラが引き続き書き込めるパスと App は、以下の通りです。

/アプリケーション
/ライブラリ
/usr/local

https://support.apple.com/ja-jp/HT204899
iex -S mix phx.server でのlisten errorについて 

```
iex -S mix phx.server
```
を実行した時に

```
** (Mix) Could not start application reactor: Reactor.Application.start(:normal, []) returned an error: shutdown: failed to start child: ReactorWeb.Endpoint
    ** (EXIT) shutdown: failed to start child: {:ranch_listener_sup, ReactorWeb.Endpoint.HTTP}
        ** (EXIT) shutdown: failed to start child: :ranch_acceptors_sup
            ** (EXIT) {:listen_error, ReactorWeb.Endpoint.HTTP, :eaddrinuse}
```
というエラーが出た。

内容としては「listenしたポートが既に使用済み」ということなので、すでに該当のポートを占有しているサーバーを止めれば解決。

###参考
https://elixirforum.com/t/a-problem-with-mix-phx-server-please-help/37794
ついにセッションと Cookie の違いを理解する

## なぜセッションと Cookie は分かりにくいのか
参考書などを読むと、途中から分からなくなる。

* HTTP はステートレスなプロトコルです。 ← 分かる
* そのままだと同一ユーザの1つ目のリクエストから2つ目のリクエストへ情報を引き継げません。 ← 分かる
* **セッション**という仕組みを使うことで同一ブラウザからの一連のリクエスト間で「状態」を共有できます ← おおおお！！！
* セッションに似た仕組みとして **Cookie** があります。 ← お？
* セッションの仕組みの一部に Cookie が使われています。 ← お？？
* セッションデータの保管場所に Cookie を選ぶことができます。 ← ふーん（分からない）

要するに、セッションと Cookie がセットで語られており、混同することでふんわり理解に留まってしまう。
今回は、これらを人に説明できるレベルまで理解してみます。

## まずは HTTP というプロトコルを知る

HTTP は、Web サーバと Web クライアントの間で情報をやりとりするためのプロトコルです。
クライアントは情報をサーバに要求し、サーバは要求に応じて情報をクライアントに返す。

このとき、サーバはどのクライアントからどんな要求があったのかを管理することはない。そのため、HTTP を素直に使うだけだと、カート情報を引き継いだり、ログイン状態を保持したりといった気の利いたことはできない。

これでは困る。ということで、セッションのお出まし。

## セッション

はじめに重要な事実をお伝えすると、上述でセッションと呼んでいたものは正確には**「セッション管理」**のことであった。

セッションとセッション管理は区別して整理する必要がある。

### まずセッションとは何か
セッションとは、クライアントとサーバ間の通信の一連の流れを指す。

1. クライアントとサーバ間でコネクションを確立
1. クライアントがリクエストを送る
1. サーバがレスポンスを返す
1. コネクションを切断

これが基本的なセッションの単位である。

繰り返しだが、HTTP を素直に使うだけでは、あるセッションから次のセッションへ情報を引き継ぐことができない。ゆえに、EC サイト等の状態管理が必要なサイトが困ってしまう、というのが課題でした。

### セッション管理とは
上記の課題を解決するために、セッションを管理しようというわけです。

どう管理するのかというと、クライアントに一意のIDを紐付けてやればいい。単純です。
この一意のIDのことを**セッションID** と呼び、次のように利用します。

サーバは、クライアントからリクエストを受け取った際に、「あ、これセッション管理必要なやつだ」と判断し、レスポンスにセッションID を含めて送る。次のリクエストのときに、クライアントがセッションID も一緒にリクエストに入れて送れば、サーバは「あ、さっきサバ缶をカートにいれたヤツや」となる。

![sessionID.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/026c6c0b-083f-2343-1c72-6fa8eaba818e.png)


そして、このセッションID の管理方法の1つが **Cookie** なのだ。

## Cookie
Cookie は、セッションID を管理する方法の1つである。
ということは、方法は他にもあるのだが、Cookie が最もメジャーな方法だ。

Cookie によるセッション管理の流れはこう。

1. サーバ：受け取ったリクエストよりセッション管理が必要か判別する
1. サーバ：必要なら、レスポンスヘッダの中にセッションID を含めてクライアントに渡す
1. クライアント：受け取ったセッションID をドメインなどの情報と紐付けて保存する
1. クライアント：次回通信時に保存していたセッションID をリクエストヘッダに含めて送る
1. サーバ：受け取ったセッションID を元に、クライアントを識別し、カスタマイズした情報を送る（更新した Cookie も一緒に送る）

![cookie.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619762/39d4dc0d-a5cb-fa6c-aa97-2d2ea7c83e50.png)

上述のセッション管理の流れとほぼ同じことを繰り返していることにお気付きだと思う。

要は、セッションを管理するための取り決めを、サーバとクライアントで用意しておく必要があり、その取り決めとして Cookie がありますよ、というだけのこと。

### Cookie 以外の方法
余談だが、Cookie 以外のセッション管理方法として、URL Rewriting と hiddenフィールド というのがある。
詳細は割愛するが、セキュリティや実装のシンプルさの観点から Cookie が主流となっている。

## セッションと Cookie の違いはこれだ！
「セッションと Cookie の違い」という見出しが的を射ていないことがここまで調べて分かった。

セッションとは、HTTP による通信の一連の流れのことだった。
そして、状態によってカスタマイズしたページを送りたいという要望に応えるため、セッションを管理する必要が生じ、この方式の1つとして Cookie が存在している。

つまり、セッションと Cookie はそれぞれ独立した存在ではなく**「セッションの拡張方式として Cookie が用意された」**というのが正しそうだ。

ちなみに、学習本でセッションと呼ばれているものは、正確には「セッション管理をしてくれる機能・メソッド」のことなのだと分かった。

## 参考文献
https://www.wakhok.ac.jp/~tomoharu/web2004/text/index_c9.html

https://e-words.jp/w/HTTP.html

https://ja.wikipedia.org/wiki/HTTP_cookie

https://thinkit.co.jp/free/tech/7/4/1.html
8 関数 Dif:105 ABC192 C：「AtCoder　凡人が『緑』になるための精選50問詳細解説」サンプル

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

前：https://qiita.com/sano192/items/c908830ad0800afe139f
次：https://qiita.com/sano192/items/9e611a60ba2a49b94e89

https://atcoder.jp/contests/abc192/tasks/abc192_c

**【目標】**
・関数の実装ができるようになる

**【概要】**
やること自体は簡単なのだが、いざ実装しようとするとどうすればよいかわからなかったり、バグが大量に出てしまったという人が多かったと思う。問題文で関数が指定されていたり、複雑な操作が必要なものはその部分を関数として作ってしまうのが一番確実で手っ取り早い。この問題で関数の作り方を覚えよう。

**【方針】**
問題文は最初ごちゃごちゃとわけのわからないことが書いているが、「例えば・・・」の部分を見れば何をすればよいかわかる。

必要な関数は3つ。
g1：数字を受け取って大きい順に並び替える
g2：数字を受け取って小さい順に並び替える
f：g2-g1
これを自作の関数として先に作ってしまえば後は問題文の指示通りに計算するだけ。

そもそもプログラミングにおける関数が何かわからない場合は以下のサイトを見てほしい。
https://www.python.jp/train/function/index.html

**【実装】**
まず関数g1を作ろう。
g1はどのような処理を行うか、順番に書くと以下のようになる。

(1)数字を引数として受け取る(314)
(2)受け取った数字を文字列(str)にする("314”)
(3)文字列を一文字ずつリストに格納する([“3”,“1”,“4”])
(4)リストを並び替える([“4”,“3”,“1”])
(5)リストを結合し、文字列にする(“431”)
(6)文字列を数値(int)にして返す(431)

(1)数字を引数として受け取る(314)
関数を作るときは
def 関数名(引数):
と書く。
引数の名前はxにしよう。これで数字xを受け取れた。

```python:
def g1(x):
```

(2)受け取った数字を文字列(str)にする("314”)
数字xがintのままだと一桁ずつ取り出す処理が面倒だ。一旦文字列strに変換しよう。

```python:
    x=str(x)
```

(3)文字列を一文字ずつリストに格納する([“3”,“1”,“4”])
並び替えのための準備。1桁ずつ=1文字ずつリストに格納する。
list(文字列)と書けば1文字ずつリストに格納できる。

```python:
    x=list(x)
```

(4)リストを並び替える([“4”,“3”,“1”])
大きい順に並び替えるため、「reverse=True」にしてソート。

```python:
    x.sort(reverse=True)
```

(5)リストを結合し、文字列にする(“431”)
リストの結合は
"".join(文字列のリスト)
と書く。
「python リスト 結合 文字列」と検索すれば出てくるのでこの書き方を暗記する必要はない。

```python:
    x="".join(x)
```

(6)文字列を数値(int)にして返す(431)
関数で値を返すときは
return 値
と書く。
xをintへ再変換して返す。

```python:
    return int(x)
```

これでg1を関数として定義できた。

```python:
def g1(x):
    x=str(x)
    x=list(x)
    x.sort(reverse=True)
    x="".join(x)
    return int(x)
```

公式解説の「実装例(Python)」ではこの関数を一行で作っているが、ややこしいことをすると余計なバグが増える。行数が増えてもよいのでわかりやすいコードを書くようにしよう。

g1ができればg2はg1をコピペして並び替えを小さい順にするだけ。つまり「reverse=True」をなくしてしまえば良い。

```python:
def g2(x):
    x=str(x)
    x=list(x)
    x.sort()
    x="".join(x)
    return int(x)
```

fはg1-g2を行うだけ。

```python:
def f(x):
    return g1(x)-g2(x)
```

これで3種類の関数ができた。
あとは初期値Nに対してK回fを行うだけで答えを出せる。
具体的には
0回目：N=a0
1回目：f(a0)=a1
2回目：f(a1)=a2
3回目：f(a2)=a3
…
K回目：f(aK-1)=aK
と処理を行う。

入力を受け取る。

```python:
N,K=map(int, input().split())
```

初期値Nを変数aに入れる。

```python:
a=N
```

aに対してK回fを行う。

```python:
for i in range(K):
    a=f(a)
```

答えを出力する。

```python:
print(a)
```

**【コード全文】**

```python:
def g1(x):
    x=str(x)
    x=list(x)
    x.sort(reverse=True)
    x="".join(x)
    return int(x)

def g2(x):
    x=str(x)
    x=list(x)
    x.sort()
    x="".join(x)
    return int(x)

def f(x):
    return g1(x)-g2(x)

N,K=map(int, input().split())

a=N

for i in range(K):
    a=f(a)

print(a)
```

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

前：https://qiita.com/sano192/items/c908830ad0800afe139f
次：https://qiita.com/sano192/items/9e611a60ba2a49b94e89
Atcoder ABC212 Python C問題振り返り

#前書き
C問題でACできなかったので今回も振り返っていきます。
Atcoder Factsという問題ごとの正解率をレート帯ごとに出してくれるサイトを見たところ、200-399のレートにいる人達の正解率が63.85%だったので解けるようにしておきたいですね...



#自分の提出（TLE）
ソートするところまでは良かったのですが、その後でどうすればよいか全く浮かびませんでした。

```python:
N, M = map(int,input().split())
A_2 = list(map(int,input().split()))
B_2 = list(map(int,input().split()))
 
A = sorted(A_2)
B = sorted(B_2)
 
ans = 0
 
if A[-1] <= B[0]:
  ans = B[0] - A[-1]
  print(ans)
  exit()
elif B[-1] <= A[0]:
  ans = A[0] - B[-1]
  print(ans)
  exit()
 
flg = []
Ans = []
 
for i in range(N):
  a = abs(A[i] - B[0])
  b = abs(A[i] - B[-1])
  if a > b:
    for j in range(-1,-M//2,-1):
      flg.append(abs(A[i] - B[j]))
    Ans.append(min(flg))
    flg = []
  elif a <= b:
    for j in range(0,M//2):
      flg.append(abs(A[i] - B[j]))
    Ans.append(min(flg))
    flg = []
 
ans = min(Ans)
print(ans)
```

#修正後の提出（AC確認済み）
Atcoderで解説動画を出してくださっているsnukeさんの解説を聞くことで実装できました。
snukeさんの解説は図を書いて視覚的に説明して下さるのでとても分かりやすいです。
（いつもありがとうございます...）

```python:
import math
N, M = map(int,input().split())
A_2 = list(map(int,input().split()))
B_2 = list(map(int,input().split()))
 
A = sorted(A_2)
B = sorted(B_2)
 
a = 0
b = 0
ans = math.inf
 
while a < N and b < M:
  ans = min(ans, abs(A[a] - B[b]))
  if A[a] < B[b]:
    a += 1
  else:
    b += 1
print(ans)
```

#感想

AとBのリストをソートしてあげて、それぞれにカーソルを用意して（このコードでいうaとb）、一つずつ進めてあげるイメージらしいです。（片方のカーソルの位置を超えたタイミングで超えられた方のカーソルを進めていく）
リストBの要素をソート後のリストAに入れて（ソートされている状態をくずさないで）、両隣との差を出していくのかなと考えていましたが、カーソルをイメージするやり方の方が個人的に分かりやすいなと感じました。
React Native + Expo で一瞬で作るHello Worldアプリ

React Native
https://reactnative.dev/docs/getting-started

Expo
https://docs.expo.dev/get-started/installation/

## 前提
Nodeが入ってること

## 作る
expo CLIをダウンロードする

```
$ yarn global add expo-cli
```

expo CLIでプロジェクトを作る。

```
$ expo init AwesomeProject
```

プロジェクトのディレクトリに移動して 

```
$ cd AwesomeProject
```

App.jsの`<Text>`タグ内を`Hello World !`に編集する

```js
import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';

export default function App() {
  return (
    <View style={styles.container}>
      <Text>Hello World !</Text>
      <StatusBar style="auto" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
```

サーバー起動

```
$ yarn start
```

※ `expo start`でもOK

Android端末 か iOS端末で [Expo Go](https://expo.dev/client)をストアからインストールする

さっき起動したターミナルか起動した時に開いたブラウザページのQRコードをExpo Goで読み取る

終わり。


## 感想
すごい簡単じゃん

Expo は全てのAndroid / iOSのAPIが使えるわけではなかったり、その他にも制限はあるみたいなので、使う前に読んでおいたほうがいいね
https://docs.expo.dev/introduction/why-not-expo/?redirected
2021-08-01 Godot Engine > キッチンタイマー > const, SpinBoxからの値読み取り, 書式指定付き文字列作成, Timerイベント

### 動作環境

```
Windows 10 Pro v21H1
Godot Engine v3.3.2.stable.official
```

Godotの学習歴 (今日開始: 2021-08-01)

### 処理の概要

- キッチンタイマー
    - 現在時刻表示
    - カウントダウン
    - 指定の秒数でカウントダウンもできる

### 学習内容

- const
- SpinBoxからの値読み取り (int型)
- 書式指定付きの文字列作成
- Timerイベント


### 準備

- Scale=4でNode2Dを用意
    - ボタンやラベルを拡大表示したいため
- 以下の項目を追加 (左が名前だが、任意で)
    - CurrentTime: Label
        - 右上の文字列
    - Timer : Timer
    - CountDown : Label
        - 右下の文字列
    - Button : Button
        - "reset"ボタン
    - SpinBox : SpinBox
    - Label : Label
        - "Count"という表示


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/6baebdfb-47be-6e5a-95c9-577b52a654b1.png)

### 実装

```python:main.gd
extends Node2D

## A. const
## B. get integer value from SpinBox
## C. print format
## D. Timer Event

onready var l_time = $CurrentTime  # Label 
onready var t_time = $Timer        # Timer
onready var l_cdwn = $CountDown    # Label
onready var sb_num = $SpinBox      # SpinBox

const DEFAULT_COUNT_DOWN = 3610

var countdown = DEFAULT_COUNT_DOWN

func _ready():
	t_time.start(1)

func _on_Timer_timeout():
	# 1. display current time
	var timedict = OS.get_time()
	var hh = timedict.hour
	var mm = timedict.minute
	var ss = timedict.second
	l_time.text = "%02d:%02d:%02d" % [hh, mm, ss]

	# 2. display count down
	countdown -= 1;
	var leftsec = countdown % 60 
	var leftmin = countdown / 60 % 60
	var lefthour = countdown / 60 / 60 
	l_cdwn.text = "%02d:%02d:%02d" % [lefthour, leftmin, leftsec]

func _on_Button_pressed():
	countdown = int(sb_num.get_value())
```

### 関連

- [OS](https://docs.godotengine.org/ja/stable/classes/class_os.html#class-os-method-get-time)
    - get_time()の例
- [GDScriptの基本](https://docs.godotengine.org/ja/stable/getting_started/scripting/gdscript/gdscript_basics.html)
    - constの例
- [GDScriptフォーマット文字列](https://docs.godotengine.org/ja/stable/getting_started/scripting/gdscript/gdscript_format_string.html)
- [SpinBox](https://docs.godotengine.org/en/stable/classes/class_spinbox.html)
    - get_value()の記載はなし
- [Doing a IntegerField](https://godotengine.org/qa/39647/doing-a-integerfield)
    - こちらにget_value()がある
- [int](https://docs.godotengine.org/ja/stable/classes/class_int.html)
ドメイン検索×LINE Bot=効率的にドメイン検索　　　


#【ドメイン管理の重要性】
昨今、新型コロナウィルスをきっかけに、人々の生活や働き方は、大きく変わりました。
ウェブサイトや電子メールは、ビジネスにおける重要な役割を担ってきており、インターネットがなければ生活できない時代となりました。
企業としても、インターネットの設備環境、サイト管理が非常に重要な資産管理となり、怠ってしまった結果、ブランド毀損、多額の賠償金に繋がっているケースも散見されます。
(例)
・サイト取得日や管理者が分からない⇒不更新となり、サイトが急にダウン
・サイトが存在しているかも分からない⇒いつの間にか、第三者に新規取得され、模倣サイト

#【そんな中、、こんなシステムがあったら便利？】
サイト運営にあたり、ドメイン管理は、重要な役割であるが、各社・各部署どのドメインを取得、保持しているのか、分からないという事例が非常に多いです。
その為、サイト構築するたびに、ドメインを新規取得しています。
SEOの観点やセキュリティ上、あまりよろしくないです。
基本的に、サブドメインやディレクトリを活用する事がお勧めです。
そのような背景の中、各社がドメイン取得状況を一括で確認できるツールがあれば、非常に便利かつ、SEO対策やセキュリティレベルを強化できると感じた為、ドメイン管理検索に特化したLINE Botを作成しようと考えました。

#【作成した仕組み】
ドメイン検索を簡単にできる仕組み
(例)Facebookを含むなど

#【開発環境の準備】
・LINE公式アカウント開設
・LINE Developersアカウント登録
・Herokuの登録
・Node-REDインストール、アカウント登録
・API(https://domainsdb.info/?query=facebook)

#【Node-RED構成】
![全体構成①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/5688d299-490a-f294-793d-f244a1cac42d.png)

#【各ノード詳細】
http inノード:ラインサーバーから送信されたメッセージ取得
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/93372395-5bb8-e059-14ad-6ec2f2a2f728.png)

「function」ノード(左側):受け取ったメッセージ格納
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/9a8701b5-c7aa-bf80-0110-2638c8bd6abc.png)

```
// LINEサーバーからの情報を「msg.line」に移動させる
msg.line = msg.payload;
// msg.payloadにメッセージ本体を入れる
msg.payload.domain = msg.payload.events[0].message.text;
return msg;
```

「http request」ノード:入力メッセージのすべてまたは一部を Web サービスに送信された要求として使用して、Web サービスと対話。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/bde5cbe0-da94-79d0-f2a8-a487a0fb5d43.png)

「function」ノード(右側)：受け取ったメッセージと突合させて条件に合致したものをメッセージとして代入する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/edb6e237-b6fe-631c-b20f-c8deea877fba.png)

```
//http requestの結果を取得する
const result = msg.payload
// 返信したいメッセージの変数を定義しておく
let reply = 'こんにちは、Facebookを含むドメインは、下記ドメインになります';
// http requestの中身を配列ごとに順番に処理
result.domains.forEach(item => {
    // 返信メッセージにドメイン名と改行を追記する
   reply = reply + JSON.stringify(item.domain) + "\n";
});
// LINEサーバーからの内容を復元する
msg.payload = msg.line;
// 返信メッセージをreplyの中身にする
msg.payload.events[0].message.text = reply;
return msg;
```

「ReplyMessage」ノード：メッセージをラインサーバーに返信
![プロトアウトスタジオ②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/b1c4a960-7300-1114-cdcb-bcd738817089.png)
![プロトアウトスタジオ①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793863/a6c182e0-3e7e-e0ab-1708-ba7ffe2a3161.png)

#【動画】
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <br>中々苦戦してますが、日々成長出来て嬉しい！<br>今週も頑張るぞ！ <a href="https://t.co/qJ6RF5mrA5">pic.twitter.com/qJ6RF5mrA5</a></p>&mdash; YE0905 (@EgashiraYosuke) <a href="https://twitter.com/EgashiraYosuke/status/1422126078378737665?ref_src=twsrc%5Etfw">August 2, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>





#【感想】
LINE Botを活用し、ドメイン検索システムを作成してみました。
今後は、ドメイン検索に加え、DNS情報や権利者情報、有効期限なども一括で確認できる仕組みを構築していきたいと思っております。
良い勉強になりました。
【Unity】NatShareでツイート後に報酬を付与する #アセットアドカレ2021

# はじめに

「[Unity アセット真夏のアドベントカレンダー 2021 Summer!](https://assetstore.info/eventandcontest/adventcalendar/summer-advent-calendar-2021/)」 2日目の記事です。1日目は[ラズ](https://twitter.com/raspberly)さんによる「【アセット紹介】Grabbitでオブジェクトを配置する【Unity】」でした。

今回紹介するアセットはこちら。簡単にSNS投稿や画等付きツイートが実装でき、無料で使えます（記事執筆時点）。

https://assetstore.unity.com/packages/tools/integration/natshare-mobile-sharing-api-117705?utm_source=twitter&utm_medium=social&utm_campaign=jp-advent-calendar-summer

このNatShareを使って、ツイートをした時点で報酬を付与する方法を紹介します。

よくある実装ではツイート画面を開いた時点で付与自体が確定するのでキャンセルしても付与されてしまうのですが、NatShareではシェアの成否に応じた処理の切り分けをすることができます。そこまで厳密な方法ではないのですが、簡単に実装できるのでおすすめです。

![RPReplay_Final1627795549_2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55365/40a68000-0bbe-a309-2a25-c69ed5297fdc.gif)


# 環境

- NatShare 1.2.3
    - [Asset Store](https://assetstore.unity.com/packages/tools/integration/natshare-mobile-sharing-api-117705?utm_source=twitter&utm_medium=social&utm_campaign=jp-advent-calendar-summer)
    - [ドキュメント](https://docs.natsuite.io/natshare/)
    - [GitHub](https://github.com/natsuite/NatShare)
- macOS 11.4
- iOS 14.6
- UniTask 2.2.5（サンプルで使用）


# 実装

`payload.Commit()`でSNS共有ができるのですが、非同期で実装されていて成否がbool値で返ってきます。キャンセルの時は`false`が返ってくるので、`true`の時だけ報酬付与処理を実行すればOKです。下記が実装例です。

```.cs
// 実装例
shareButton.onClick.AddListener(async () =>
{
    var shareText = $"共有するテキスト";

#if !UNITY_EDITOR
    var payload = new SharePayload();
    payload.AddText(shareText);
    var result = await payload.Commit();
    // キャンセルされた場合は何もしない
    if (!result) return;
#else
    // Editor上では決め打ちで実行
    await UniTask.Delay(TimeSpan.FromSeconds(3f));
#endif

    // SNS共有後のリワード付与処理など
});
```

共有先の指定ができないので実際にはツイッター以外でも成否判定がなされてしまうのですが、かなりライトに実装ができるので活用できる場面は多いんじゃないかなと思います。

# 最後に

最後に宣伝なのですが、この記事で紹介した方法は「[ワンナイト人狼オンライン](https://online.1nite-jinro.com/)」というアプリの開発で使用しています。よかったらぜひ遊んでみてください！

Twitterもやっているのでよかったらフォローお願いします！
https://twitter.com/nkjzm

「[Unity アセット真夏のアドベントカレンダー 2021 Summer!](https://assetstore.info/eventandcontest/adventcalendar/summer-advent-calendar-2021/)」 明日の担当は[さとや]()さんによる「単独でも活用できる！Corgi Engine/TopDown Engineに同梱されているMMFeedbacksの紹介」です。
【SAP-C01試験対策】ネットワーキングのまとめ

# はじめに

AWSのネットワーキングについて以下の講座および書籍を参考に学習したので内容をまとめます。

https://www.amazon.co.jp/dp/B08F9CQ6LT/

https://www.udemy.com/course/aws-associate/

# 背景
本記事はAWSソリューションアーキテクトプロフェッショナルに合格するために、[Udemyの模擬試験](https://www.udemy.com/course/aws-53225)を解いて分からなかった部分を勉強してまとめるものです。

試験対策用のため、分からない知識を補足したり試験で問われなさそうなところを省略したりしながらまとめています。
なるべくわかりやすい記載を心がけますが、最終目的は自己学習用であるということをご容赦ください。

# VPC (Amazon Virtual Private Cloud)
## 通常の設定方法

1. VPCを作成(CIDRを設定)
1. サブネットを作成
1. Gatewayの設定(インターネットの経路)
1. ネットワークACLの設定(トラフィックの許可)

### Gatewayの設定
* パブリックサブネットからインターネットに接続するにはインターネットゲートウェイが必要。
* プライベートサブネットからインターネットに接続するにはNATゲートウェイがパブリックサブネットに必要。

## ネットワークACLとセキュリティグループ

|ネットワークACL| セキュリティグループ|
|----|----|
|サブネットへのトラフィック制御|インスタンスへのトラフィック制御|
|[ステートレス](#用語集)| [ステートフル](#用語集)|
|許可と拒否を設定|許可のみを設定|
|デフォルトは全て許可<br>最終行に全て拒否の設定をする|デフォルトでは全て拒否|
|上から順に適用|全てのルールを適用|

## VPC Endpoint

* インターネットを経由せずにAWSサービスにアクセスすることが可能。
 * ゲートウェイエンドポイント : S3、DynamoDBのみ対応
 * インターフェースエンドポイント : [Private Link](Private Link)のこと

## Private Link

* VPC内に[ENI](#用語集)が作成され、プライベートIPアドレスが割り当てられる。これによりインターネットを経由せず各サービスにアクセスが可能になる。

## VPC Peering
* 複数のVPCで通信が可能になる。リージョンをまたぐことも可能。

## Direct Connect
* オンプレミスとVPCをVPN接続(仮想的な専用線)ではなく物理的な専用線でつなぐこと。

## AWS Managed VPN
* VPCとオンプレミス間でアンケに暗号化接続を確立する手段。 
* オンプレミス側にネットワーク機器の用意が必要。
* VPC側に[Customer Gateway](#用語集)と[Virtual Private Gateway](#用語集)が必要。



# 用語集
* ステートフル ： インバウンドのみ設定すればアウトバウンドも許可される。
* ステートレス : インバウンド設定だけではアウトバウンドは許可されない。
* [ENI](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_ElasticNetworkInterfaces.html) : 仮想[ネットワークカード](#用語集)を表す VPC 内の論理ネットワーキングコンポーネント。ネットワークインターフェイスの作成、インスタンスへのアタッチ/デタッチが可能。
* [ネットワークカード(NIC)](https://e-words.jp/w/NIC.html) : コンピュータなどの機器を通信ネットワーク（LAN）に接続するためのカード型の拡張装置。
* Customer gateway : オンプレミス側とVPC側の接続を有効にするためのゲートウェイ
* Virtual Private Gateway : AWS側のVPN接続を有効にするためのゲートウェイ
【React】再レンダリングとメモ化

# はじめに
``React``の再レンダリングとメモ化、について学習したことを簡単にまとめてみました。

## 参考
わかりやすく有益な記事で、参考にさせていただきした。
本当にありがとうございました！！

- https://qiita.com/soarflat/items/b9d3d17b8ab1f5dbfed2#usecallback-%E3%82%92%E9%96%A2%E6%95%B0%E3%81%AE%E5%86%8D%E7%94%9F%E6%88%90%E3%82%92%E9%98%B2%E3%81%90%E7%9B%AE%E7%9A%84%E3%81%A7%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%81%AF%E3%81%84%E3%81%91%E3%81%AA%E3%81%84%E3%81%AE%E3%81%8B
- https://zenn.dev/b1essk/articles/react-re-rendering

# コンポーネントの再レンダリングが起きる条件
#### 1. ``state``が更新されたとき
例：フォーム入力の値を監視する``state``を保持しており、その``state``の値に変更があったとき（フォームに値を入力 or 削除するとき）
#### 2. ``props``が更新されたとき
例：親コンポーネントで値を保持しており、その値を``props``で子コンポーネントに渡して表示している際にその値に変更があったとき
#### 3. 親コンポーネントが再レンダリングされるとき

# メモ化による再レンダリングの最適化
## 再レンダリングの最適化とは
Reactのコンポーネントではレンダリングは頻繁に起きることが多いため、そのたびに重い処理などを走らせるとパフォーマンスが落ちる。
その不必要な処理をできるだけ抑え、処理は必要最低限にしたい。

それによりページ描画スピード向上など、パフォーマンスの最適化をはかることが再レンダリングの最適化である。

## メモ化とは
計算処理結果や生成された関数、コンポーネントなどを保持しておき、それを適切に再利用すること。

メモ化しておくことで不必要に処理を走らせることを防ぐことができる。

※メモ化すること事態にもコストが発生するようなので、何でもかんでもメモ化すれば良いということでもないようである。

# メモ化の方法
1. ``memo()`` コンポーネントに対してのメモ化
2. ``useCallback()`` コールバック関数に対してのメモ化
3. ``useMemo()``　値に対してのメモ化

## ``memo()`` コンポーネントに対してのメモ化
親コンポーネントが再レンダリングされても、子コンポーネントに渡す``props``の値が変更されない限り、子コンポーネントは再レンダリングされないようにする仕組み。

逆に言えば``memo()``を利用しても``props``に変更があれば再レンダリングされてしまう。

```jsx
memo(コンポーネント);
```

## ``useCallback()`` コールバック関数に対してのメモ化
不必要に関数が再生成されることを防ぐ。
第２引数で指定する``依存配列``に変更がない限り第１引数のコールバック関数は再生成されず、メモ化された保持している関数をコールバック関数を返す。

``useCallback``を利用しないと、このコンポーネントがレンダリングされるたびにその関数は再生成される。この関数を``props``として渡していたら、再生成のタイミングで``props``が変更されたことを子コンポーネントが検知して子コンポーネントも再レンダリングされる。

```jsx
const 関数名 = useCallback(コールバック関数, [依存配列]);
```
※ 利用方針は様々あると思うが、基本的には``memo(コンポーネント)``とセットで利用することで子コンポーネントの不必要な再レンダリングを防ぐ目的で利用する。

## ``useMemo()``　値に対してのメモ化
不必要に重い処理を走らせることを防ぐ。
第２引数で指定する``依存配列``に変更がない限り第１引数の処理は実行されず、メモ化された保持している値を返す。

```jsx
const 変数名 = useMemo(処理, [依存配列]);
```

※第１引数で渡す処理が重い処理でなければ、``useMemo()``を利用するコストの方が大きくなることもあり、利用するメリットが無いこともあるよう。
初心者による初心者のためのGatsbyJS覚書2 (ページ作成編）


##この記事について
この記事はGatsbyJS初心者の新卒２年目が作成しています。
参考資料として書籍を使用していますが、筆者がビギナークラスのため読んでいて「？」となる部分や間違っている箇所もあるかと思います。
参考までに、そして間違えている箇所がありましたらご連絡いただけると嬉しいです。

##Chapter1：ページの作成の備忘録メモ

知っている方からすると「当たり前だろ」となるかもですが、、、
個人的に「なるほど…」「覚えておこう！」となった部分だけ記載します。


###JSXのルールについて

####HTMLコードはラップする

```jsx
export default () => <div> <h1>挨拶</h1> <p>こんにちは</p> <footer>Copyright 2021</footer> </div>
```

####複数行になるときはHTMLを括弧内に入れる

```jsx
export default () => (
<div>
 <h1>挨拶</h1>
 <p>こんにちは</p>
 <footer>Copyright 2021</footer>
</div>
)
```
####classはclassNameと書く

```jsx 
export default () => (
<div className="contents"> //classNameと記載
 <h1>挨拶</h1>
 <p>こんにちは</p>
 <footer>Copyright 2021</footer>
</div>
)
```

####style属性の値は｛｛｝｝に書く

```jsx
export default () => (
<div className="contents"> 
  <h1 style={{ color: "red", fontWeight: "bold"}}>挨拶</h1>
  <p>こんにちは</p>
  <footer>Copyright 2021</footer>
</div>
)
```

####装飾目的のaltについて
HTMLからJSXへの変換ツールなどを利用すると、altの表示が`<img alt/>`となっている場合があるが、ESLintErrorが発生するので`<img alt="" />`と書き換える

altの変換も良い感じに仕上げてくれる[変換ツール](https://magic.reactjs.net/htmltojsx.htm)はこちら

###トップページ用に画像を追加したときのエラーについて

static配下にimagesフォルダを作成して画像を追加し、`gatsby develop`を実行すると下記のエラーがいっぱい表示された。。。

```sh
watchpack error (watcher): error: emfile: too many open files, watch
````
こんなの書いてないよ・・・と項垂れつつ調べると自分のMacの設定されているファイルの上限の問題らしい。解決方法はこちら。

####ファイルの上限を確認

```sh
$ launchctl limit
```
`maxfiles`の上限が足りてないのが原因らしい。
####設定ファイルを作成する

```sh
$sudo vi /Library/LaunchDaemons/limit.maxfiles.plist
```
初期ではファイルはないはずなので新規作成となるはずなので
設定内容を追加を追加する。

```sh
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">  
  <dict>
    <key>Label</key>
    <string>limit.maxfiles</string>
    <key>ProgramArguments</key>
    <array>
      <string>launchctl</string>
      <string>limit</string>
      <string>maxfiles</string>
      <string>524288</string>
      <string>524288</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
    <key>ServiceIPC</key>
    <false/>
  </dict>
</plist>  
```

####plistファイルを読み込み

```sh
$ sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
```
もう一回設定値を確認して増えていればOK

```sh
$ launchctl limit
```


今回はここまで。
BuildしてNetlifyにデプロイまですると見た目はサイトらしくなりました。(途中経過キャプチャ)
![スクリーンショット 2021-08-01 14.57.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281399/87dc9748-f5b5-fa74-0be2-95e94adf9a88.png)


詳しいgatsbyのことは次回以降から書いて行く予定です。
iPadでプログラミング

#はじめに
業務とは全く関係なしに、私用で使っている端末で何か面白い事が出来ないか、興味があり、調べて見たことをまとめました。たまに仕事とは関係なく、遊びの一環で学んでみた事をここに記載しました。

#iPadでプログラミングできるの？？？
先に結論を言うと、iPadでプログラミングは出来ます！！！
私用でiPadを使っていて、何か出来ないかと考え、調べてみました。
iPadでは、文章編集やスライド作成など、色々出来ます。
そしてプログラミングも出来、且つそのコーディングした内容も実行する事も出来ます。
必要なアプリをインストールする事で、コーディング及び実行が出来ます

#用意した物
本体
iPad (第7世代)

アプリ
a-shell
 ※iPad用ターミナルの様なもの
LiquidLogic
 ※メモ等のテキストエディタでも代用が可能だが、本アプリで作成したファイルの配置先の指定が可能

#実際につかってみた
以下の手順でコーディング/実行をしてみました。
※今回はpythonのファイルを作成/実行

1.Pythonコードを入力したファイル(.py)で保存
2.a-shellを起動し、1.で作成したファイルの格納先へ移動
 ※ターミナルと同様にコマンド:cdでディレクトリの移動が可能
3.実行コマンドを入力
 python ファイル名.py 
 
結果として、実行され、処理結果が出力されました。

#統括
ＰＣと同じ様に使える為、勉強用として使う分では問題はないと思います。
ただアプリを作成、ファイルを構築する等が出来るかは不明です。
簡単なコーディングでは問題はない為、スマートフォンやタブレットに導入し、コーディングの勉強に活用する事が出来ます。
AWS Solutions Architect Professionalに100時間で合格した話

最近、AWSの勉強をしていまして、先日AWS Solutions Architect Professionalに合格しました。
そこで、所感と勉強法のシェアができればと思います。

##AWS認定試験の構成

AWSが分野別に認定試験を設けており、アーキテクト、運用、デベロッパーのそれぞれの分野での
アソシエイトレベル、プロフェッショナルレベルが設定されています。
赤枠内の試験を下から順に受験していきました。AWS界隈では王道の取り方のようです。
https://aws.amazon.com/jp/certification/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/171131/96325076-49a1-1d48-03b9-eb78a0b8085b.png)


##勉強時間・使った教材
私はオンライン教材より紙が好みなので、書籍中心の勉強をしました。
各試験に対し、勉強時間と教材を紹介します。

####CLF(クラウドプラクティショナー)
- 勉強時間：10h程度
- 使用教材：「一夜漬け AWS認定クラウドプラクティショナー 直前対策テキスト」
  - テキストの内容からほぼ出題されますので、丸覚えでも大丈夫です。
  - あまり時間を掛けずにAWSの知識を証明できるので、お忙しい方はこれだけ受けるのもおすすめです。

####SAA(ソリューションアーキテクト　アソシエイト)
- 勉強時間：+40h程度
-  使用教材①：「この1冊で合格! AWS認定ソリューションアーキテクト - アソシエイト テキスト&問題集」
  - 某大手コンサルが出している本のようです。
  - Amazonレビューで酷評されていますが、網羅性が高く、よい本だと思います。
 - SAAとSAPの範囲はあまり変わらないので、SAPの勉強をしているときにこの本に戻って理解しなおすこともありました。
- 使用教材②：「これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（SAA-C02試験対応版）」
 - 問題演習に使用しました。問題集としては他に書籍も出ているので、あえてこの教材を使う必要もないかなと思いました。。

+αとして、馴染みのないサービスはBlackBeltやサミットの動画を検索して基本を身に付けました。
特にコンテナに関しては全くわからなかったので、いい機会なので動画を見て勉強しました。以下の動画はコンテナ知らない人でも理解できるので、おすすめです。
https://www.youtube.com/watch?v=L4bLDNRSYC8

####SAP(ソリューションアーキテクト　プロフェッショナル)
- 勉強時間：+40h程度
- 使用教材：「AWS認定ソリューションアーキテクト-プロフェッショナル ~試験特性から導き出した演習問題と詳細解説」
  - 他に日本語の教材が見つからず、書籍の中では1択でした。
  - 問題を3周程度しました。
  - Udemyの問題集も買いましたが、使いませんでした。SAAがしっかり勉強できていれば、この1冊で大丈夫だと思います。

 

##実際の問題
守秘義務もあるので、そこまで詳細には記すことができませんが、ざっくりと。
CLF、SAA、SAPで必要な基礎知識は変わりませんが、1つずつ聞かれることが深くなっていくイメージです。

- CLF：Auto Scalingとは何ですか？
- SAA：月末に処理量がスパイクするシステムをEC2インスタンス群で構成します。  高負荷に耐えられるAuto Scaling構成はどれですか？
- SAP：※下記

以下はSAPの問題の一例です。模試より抜粋しました。
>あるソリューションアーキテクトは、ビッグデータアプリケーションのコストを削減する必要があります。
アプリケーション環境は、Amazon Kinesis データストリームにイベントを送信する数百のデバイスで構
成されています。各デバイスは、1 秒あたり 50 KB～450 KB のデータを送信します。シャードは、デー
タを処理してその結果を Amazon S3 に保存する AWS Lambda 関数によってポーリングされます。
毎時間、AWS Lambda 関数は結果でデータについて特異点を識別し、これを Amazon SQS キューに配
置する Amazon Athena クエリを実行します。2 つの EC2 インスタンスで構成された Amazon EC2
Auto Scaling グループはキューをモニタリングし特異点を処理する短い (約 30 秒) プロセスを実行しま
す。デバイスは、1 時間に平均 10 個の特異値を送信します。
次の中で、コスト削減に最も適切な方法は何ですか。(2 つ選択)

引用元:https://d1.awsstatic.com/ja_JP/training-and-certification/docs-sa-pro/AWS-Certified-Solutions-Architect-Professional_Sample-Questions.pdf


要件を実現不可能な選択肢が2つ、要件を実現できるが最適でない選択肢が1つ、正解が2つのイメージです。
SAPはこのテンションで75問・3時間出題され続けるので、後半は意識を失いかけながら問題を解ききりました。なかなか体力勝負です。
788点で一発合格できましたが、正直、もう一度受ける気力はありません。。

ただ、問題文は長いですが、原則を抑えていれば解けます。
「EC2よりマネージドサービス」、「できるだけ安く」、「サービス停止は最小限で」のような、選択肢同士を比較する観点を身に付ければ、（なんとか）解けるようになります。

##結論:AWSの勉強はおすすめです！

この試験の勉強の過程で、一通りAWSの体系的な知識がついたかと思います。
アプリ担当なので、直接インフラの作業やアーキテクティングを行うことは無いですが、インフラご担当と会話する前提知識として大変役に立っています。
例えば、AWSの提唱するベストプラクティスに沿っていない実装がされている場合、どうしてそのような構成なのかの見当がつくようになりました。
その方がアプリの修正量が少ない、とか、その方が安い、とか。

AWS試験はベンダ試験の中では比較的教材が揃っていて、勉強しやすいです。
100h程度の勉強でProfessionalレベルの認定が取れると考えると、コスパのいい試験と言えると思います。
比較対象はCCNPやOracle Goldかと思いますが、それよりは断然取りやすいと感じました。

AWSはしばらくはパブリッククラウドのデファクトスタンダードであり続けるかと思います。
アプリ技術者が勉強しても決して無駄にならないと思うので、ぜひトライしてみてはいかがでしょうか！
5 全探索1 Dif:21 ABC190 B：「AtCoder　凡人が『緑』になるための精選50問詳細解説」サンプル

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

前：https://qiita.com/sano192/items/f2bb2fde590bc11e7cfb
次：https://qiita.com/sano192/items/b2b22aa77ad6da118c3e

https://atcoder.jp/contests/abc190/tasks/abc190_b

**【目標】**
・全探索で間に合うかを判断できるようになる。
・全探索で必要な操作を実装できるようになる。

**【概要】**
全ての場合を試してみることを「全探索」という。「全探索」は基本のやり方で、ABCのA~C問題まではほとんどこの方法で解ける。どのような場合に「全探索」を行うのか、どうやって実装するのかこの問題で理解しよう。

**【方針】**
問題文はダメージを与えられない条件が書いているが、1つでもダメージを与えられる呪文があれば「Yes」となるので、逆にダメージを与えられる条件を考えよう。

問題文にあるダメージを与えられない条件は以下。
・詠唱にS秒以上かかる → S<=X
または
・威力がD以下 → Y<=D

これを逆にして、ダメージを与えられる条件を考える。
・詠唱がS秒より小さい → X<S
かつ(しかも)
・威力がDより大きい → D<Y

次に全ての魔法について上記条件を確認して解けるか、つまり「全探索」で解けるかを判断しなければならない。

制約を見よう。　
実行制限時間：2sec(2秒)
呪文の種類：1<=N<=100

よって2秒以内に最大100種類の呪文を試せるか？が判断基準となる。
pythonでは2秒以内にだいたい1000000=10^6回程度の計算ができる。
100回の計算なら余裕で間に合うので、全ての呪文を試してもTLE(実行時間制限超過)しない。
全探索で間に合うか？の目安は計算回数がだいたい10^6回以下と覚えよう。

計算量については解説でよくO(N)という書き方をしている。
厳密に説明すると難しい話なのだが
O(N)=N回くらいの計算が必要
という意味だと覚えよう。
O(N^2)=N^2回くらいの計算が必要
O(logN)=logN回くらいの計算が必要(logの底は2)
と覚えておけば良い。

この問題はN種類の呪文について計算が必要なので、
O(N)で解ける
という言い方をする。

計算量について詳しく知りたい人はWikipediaを参照してほしい。
https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%B3%E3%83%80%E3%82%A6%E3%81%AE%E8%A8%98%E5%8F%B7#%E4%B8%80%E8%88%AC%E7%9A%84%E3%81%AA%E3%82%AA%E3%83%BC%E3%83%80%E3%83%BC

**【実装】**
入力を受け取る。X,Yがいくつもあって戸惑うかもしれないが、for文で一つずつ受け取ればよい。

```python:
N,S,D=map(int, input().split())

for i in range(N):
    X,Y=map(int, input().split())
```

受け取ったX、Yについて以下の条件を満たすか判定する。
・詠唱がS秒より小さい → X<S
かつ(しかも)
・威力がDより大きい → D<Y
もし条件を満たすものが一つでもあれば「Yes」を出力して終わり。
途中で終了する場合は exit()と書く。

```python:
for i in range(N):
    X,Y=map(int, input().split())
    if X<S and D<Y:
        print("Yes")
        exit()
```

ひとつも条件を満たすものがなかった場合、途中で終了することなくループが終わる。
そこで「No」を出力すれば完成だ。

```python:
print("No")
```

【コード全文】

```python:
N,S,D=map(int, input().split())

for i in range(N):
    X,Y=map(int, input().split())
    if X<S and D<Y:
        print("Yes")
        exit()

print("No")
```

**この記事は拙著「AtCoder　凡人が『緑』になるための精選50問詳細解説」のサンプルです**
価格：100円
kindle：https://www.amazon.co.jp/dp/B09C3TPQYV
booth(pdf)：https://sano192.booth.pm/items/3179185

前：https://qiita.com/sano192/items/f2bb2fde590bc11e7cfb
次：https://qiita.com/sano192/items/b2b22aa77ad6da118c3e
Visual Studio Code で PowerShell のバージョンを切り替える

Windows PowerShell (PowerShell 5.1 以前) と PowerShell Core (PowerShell 6 以降) の両方がインストールされている場合、以下の方法で使用するバージョンを切り替えることができる。

1. コマンドパレットを開く（`Ctrl` + `Shift` + `P`）
1. `PowerShell: Show Session Menu` を開く
1. 使用するバージョンを選択する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383318/1cb8906b-a72a-7f36-a65e-5b7b2c10b5d9.png)

設定ファイルに反映される。

```json:settings.json
{
    "powershell.powerShellDefaultVersion": "PowerShell (x64)"
}
```

```json:settings.json
{
    "powershell.powerShellDefaultVersion": "Windows PowerShell (x64)"
}
```

現在使用しているバージョンを確認する。

```
$PSVersionTable.PSVersion
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383318/5b3be6ba-34c7-342f-e7a0-6b28b5699e8e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383318/1b23d0d1-aae2-2fe1-570a-34f74dfa70cf.png)

https://docs.microsoft.com/ja-jp/powershell/scripting/dev-cross-plat/vscode/using-vscode?view=powershell-7.1#choosing-a-version-of-powershell-to-use-with-the-extension
sbt-play-swagger を運用してみた

[こちら](https://qiita.com/__kijuky__/items/8182d5c5ec43c3ed87e8) のつづき。

https://qiita.com/__kijuky__/items/8182d5c5ec43c3ed87e8

生成された swagger.json は、GitLab にレンダリングさせるためにコミットに含めます。ここで問題なのは routes ファイルと swagger.json ファイルの差異をどうするか... 皆さんはこのような自動生成ファイルをどのように管理していますか？

routes ファイルの変更があれば気づくかもしれませんが、自動生成されたモデルの変更があった場合などはどうでしょうか。swagger.json ファイルの生成は忘れそうですね。そんな時は [Danger](https://danger.systems/ruby/) さんにお任せしましょう。

# Danger による解決方法

GitLab CI で sbt swagger を実行し、 git diff を使って差分を検出します。

```.gitlab-ci.yml
swagger:
  only:
    - merge_requests
  stage: build
  script:
    - mkdir logs
    - sbt swagger
    - git diff -U0 > logs/swagger-git-diff-U0.log
  artifacts:
    paths:
      - logs/
    when: always

danger:
  only:
    - merge_requests
  stage: test
  image: ruby
  script:
    - bundle install --jobs=4 --path vendor/bundle
    - bundle exec danger --fail-on-errors=true
```

```ruby:Dangerfile
base_path = "#{Dir.pwd}/"

# swagger
lines = []
File.foreach("logs/swagger-git-diff-U0.log"){ |line| lines << line.chomp }
for index in 0..(lines.count - 1) do
  line = lines[index]
  result = /\+\+\+ b\/(.*)$/.match(line)
  if result then
    filename = result[1].sub(/^#{base_path}/, "")
  end
  if filename.include? "swagger.json" then
      message = "[swagger] routes changed. Run `sbt swagger` and commit swagger.json"
      failure(message)
  end
end
```

# 余談

個人的にはこの git diff を使った差分検出、最初見た時は感動したんですけど、まぁ当たり前体操だったりするんですかね？

こちらのインスパイア

https://github.com/johnno1962/GitDiff/blob/master/FormatImpl/clang_format.sh