OmniAICreator/Qiita-1.07M huggingface dataset:
複数のpromiseをまとめて実行して、処理が終わってからなにかする

どうもjavascriptの同期とか非同期の処理がわからなくて四苦八苦している。
取り急ぎpromiseを使うとよいらしいので、作ってみたサンプル。

uploadの処理が終わってから、createとeditをそれぞれ実行して、全部終わってからアラートを出す、というもの。

３つの処理はpromiseでくくっておいて、リターンをresolveに入れておく。
Promise.allを使うとまとめて実行できる、リターンも配列にまとまって返ってくる。

```
upload().then(function(response) {
    Promise.all( [create(response), edit(response)] ).then(function(res) {
        alert("end");// なにかする
        console.log(res);
        // Array [ "3000000", "2000000" ]
        // resには配列で順番にresolveのリターンが入っている
    });
});

function upload() {
    return new Promise((resolve, reject) => {
        $.ajax({
            url:'api1.php',
            type:'get'
        }).done(function (data) {
            alert(data);
            resolve(data);
        }).fail(function() {
            alert("fault");
            reject;
        });
    });
}

function create(response) {
    return new Promise((resolve, reject) => {
        console.log("create" + response);
        $.ajax({
            url:'api3.php',
            type:'get'
        }).done(function (data) {
            alert(data);
            resolve(data);
        }).fail(function() {
            alert("fault");
            reject;
        });
    });
}

function edit(response) {
    return new Promise((resolve, reject) => {
        console.log("edit" + response);
        $.ajax({
            url:'api2.php',
            type:'get'
        }).done(function (data) {
            alert(data);
            resolve(data);
        }).fail(function() {
            alert("fault");
            reject;
        });
    });
}

```
yarnを実行すると「Name contains illegal characters」が発生する

yarnの実行時に不正な文字列が検出されたというエラーが出ることがあります。

```shell
$ yarn run
yarn run v1.22.5
error package.json: Name contains illegal characters
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
```

これは package.json のnameの値に空白が含まれていると発生するようです。

```shell
- "name": "hoge fuga"
+ "name": "hogefuga"
```

空白を取り除けば発生しなくなります。

---
参考
[Github issue - Name contains illegal characters](https://github.com/yarnpkg/yarn/issues/1120)
もろもろ整備されたサンプルプロジェクト作成の手順のまとめ (github + monorepo + nextjs + commitlint + lint-staged + prettier + eslint + editorconfig)

## 環境構築からプロジェクト作成まで

自分でnextjsのプロジェクトを作るとなった際に、どうやってセットアップしたらいいかわからない、という声が多かったので、一例として[このプロジェクト](https://github.com/taijusanagi/nftcert)のセットアップ手順を各記事ごとにまとめてみました、

### github repository

まずはgithub repositoryを作ります。

https://qiita.com/taijusanagi/items/f71a088983fa08637fe1

### husky

次にhuskyの設定を入れます

https://qiita.com/taijusanagi/items/bd44d32efdba980f3f20

### commitlint

次にcommitlintの設定を入れます

https://qiita.com/taijusanagi/items/4117e9c621186b254a9f

### yarn monorepo

次にmonorepoの設定を入れます

https://qiita.com/taijusanagi/items/cfd6ff7ba72e65439b66

### nextjs

次にnextjsの設定を入れます

https://qiita.com/taijusanagi/items/6358933465f5e7ab6b7c

### prettier & eslint

次にeslintとprettierを入れます

https://qiita.com/taijusanagi/items/1ffc7fe6eac935cba83f

### github actions

次にgithub actionsでCIを入れます

https://qiita.com/taijusanagi/items/8281b2e43143101bd515

### lint-staged

次にlint-stagedを入れます

https://qiita.com/taijusanagi/items/f59b9d6a49061fbfe67f

## 終わった状態

こちらが作業が終わったタイミングのrepositoryです。

https://github.com/taijusanagi/nftcert/tree/887c321e85b958a6b74b3501f64c3732203aafa6


## 振り返り
- 公式の記載を見て設定していくのが一番大事だと思うが、全体像を持つ上でもこんな感じで手順を整理するのは良さそう
- lint-stagedはhuskyと一緒に早めのタイミングで入れて良いと思った、github actionsよりも先の方が良さそう
- prettier + eslintは人によって設定の方針が違うのでもう少し掘り下げても良さそう
【VisualStudio】プログラミング学習2ヶ月目でソースコードを少しでも早く書くために知ったこと

#結論
１，キーボードのショートカットキーを意識する。
２，マウスは使ってもいい。
３，変数名の入力を省略してインテリセンスに任せる。

--------
#前提
IDEはVisualStudio2022を使用しています。
OSはwindowsです。

--------

#キーボードのショートカットキーを意識する。
これはプログラミング関係なくPCを使う仕事をしている方なら該当するかなと思います。
私がVisualStudioを使用している時に意識しているショートカットキーを下記にリストアップします。

| できること | キー |
|:-:|:-:|
|   コピー|   Ctrl+C|
|   ペースト|   Ctrl+V|
|   コピー履歴(クリップボード)|   Windowsマーク+V|
|   インテリセンス表示|  Ctrl+Space |
|   インテリセンス入力確定|   Tab|
|   1つ前の変更を取消|   Ctrl+Z|
|   文字を選択|   Shift+矢印キー|
|   区切り文字単位で文字を選択|   Ctrl+Shift+矢印キー|
|   次のブレイクポイントまで実行|   F5|
|   次の行まで実行|   F10|
|   次のステップまで実行|   F11|
|   関数の内部に移動|   F12|
|   ソースコードの整列|  Ctrl+K → Ctrl+D|

#マウスは使ってもいい。
マウスはできる限り使わずに手はキーボードの上から動かさないとかいうのを記事で見ますが、私はプログラミングを覚えるのに精一杯なのでキーボードのすべてのショートカットキーを覚えるのは難しいです。上記に出した1日に何回もするような動作のみショートカットキーを覚えてそれ以外の操作(例えば、ソリューションエクスプローラーでソースファイルを選択するとか)はマウスでやってもいいんじゃないかなと思います。2,3年勉強してある程度プログラミングができるようになってから細かいショートカットキーを覚えていこうと思っています。

#変数名の入力を省略してインテリセンスに任せる。
始めてVisualStudioを触った時にインテリセンスの存在を知らなかったので変数名や関数名はすべてキーボードで打っていました。これでは、タイピングもままならない私だと`var ret = GetYoutubeCommentList()`みたいなプログラムを書くのに30秒かかります。これが積み重なるとプログラムを書くのが嫌になってきます。そこでインテリセンスに入力を任せます。
上記の例でいうと`var ret = gyc`みたいな感じでプログラムを書いてCtrl+Spaceをするとインテリセンスによって入力が推測されて残りを自動入力してくれます。この入力方法だと15秒くらいで入力できます。

#終わり
分からないことがあるとQiitaを覗かせてもらっています。記事を書いてくださっている皆さんのおかげで初心者でもどうにかプログラミングができています。いつもありがとうございます💻
Kubernetesを試してみたい方へ。ローカルでのK8s環境構築オプション

# 概要
- Kubernetesはいろいろな環境構築方法があってすぐに忘れてしまう
- Kubernetes完全ガイド第2版に記載してあったローカルでの環境構築の選択肢をメモ
- 手元のマシン１台に構築する

# Minikube
Minikubeは、Dockerなどのハイパーバイザ上にコンテナや仮想マシンを作成し、その環境上にKubernetesをインストールし、そこにKubernetesクラスタを起動する。`--driver=docker`という形でハイパーバイザを指定する。シングルノード構成。

# Docker Desktop
Docker DesktopでKubernetesを使用するには、起動後に[Preference]からKubernetesを有効にする。Dockerコンテナを作成し、そこにKubernetesをインストールして、クラスタを起動してくれる。シングルノード構成。

# kind (Kubernetes IN Docker)
特徴は、複数ノード構成のKubernetesクラスタが起動できること。Dockerコンテナを複数個起動し、そのコンテナをKubernetes Nodeとして起動することで、複数台構成のKubernetesクラスタを構築。現在ローカル環境でマルチノードクラスタを構築するには、kindを利用するのが一番良い。
Lint-stagedの設定の備忘録

## lint-staged

今回は[こちらのプロジェクト](https://github.com/taijusanagi/nftcert)にlint-stagedを設定していきます。

lint-stagedを使うことによって、変更があったコードを対象に特定のスクリプトをかけることを自動化することができます。こちらの記事で紹介されているhuskyとも連携していきます。

https://qiita.com/taijusanagi/items/bd44d32efdba980f3f20

それでは早速始めてみましょう！

## 手順

こちらのドキュメントを参考に設定していきます。

https://github.com/okonet/lint-staged

こちらのコードを実行します。

```
npx mrm@2 lint-staged
```

それでは実行結果を見てみましょう！

package.jsonには下記のようなコードが追加されています。

```
  "lint-staged": {
    "*.{ts,tsx}": "eslint --cache --fix",
    "*.--write": "prettier --write"
  }
```

また、huskyのpre-commitにも下記のようなコードが追加されています。

```
npx lint-staged
```

これで、変更があったコードを対象に自動的に、prettierとlintをかけることができるようになります！今回のコミットは[こちら](https://github.com/taijusanagi/nftcert/commit/887c321e85b958a6b74b3501f64c3732203aafa6)で確認することができます。

ありがとうございました！
PowerShellで無変換キーを押すとアットマークが入力される問題を回避する

PowerShellで無変換キーを押したときアットマーク `@` が入力されてしまう問題の回避策です。

見たところ、この問題が発生するのは、IMEがオフの状態で無変換キーを押したときだけのようです。私は無変換キーを「IMEオフ」に割り当てているため、結構この問題に悩まされていたのですが、なんとか暫定的な回避策を見つけることができました。

回避策は、Windows Terminalの「操作」設定で「vk(29)[^1]」に何か無害そうなコマンドを割り当てることです。

![powershell-nonconvert-atsign.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1096584/3d29c721-3432-15aa-2673-9df970e7614b.png)

GUIの設定画面にvk(29)が無ければ、JSONで開いてactions[]内に以下を追加してください。

```json
{
    "command": "resetFontSize",
    "keys": "vk(29)"
}
```

[^1]: 仮想キーコード29、すなわち無変換キーを指しているようです。
MySQL コマンドメモ

# 背景

MySQL の起動や停止に手間取ったので、コマンドをメモしておく。

# コマンド

```bash:bash
$ launchctl list | grep mysql
13659   0       homebrew.mxcl.mysql@5.7
```

macにはlaunchctlという仕組みがあり、plist定義を作っておくと、自動でデーモンを起動してくれる。
これにmysqlが定義されているか、確認する。

参考↓

https://qiita.com/Komei22/items/31a3db6d5b803ef5082b

```bash:bash
$ brew services stop mysql@5.7
Stopping `mysql@5.7`... (might take a while)
==> Successfully stopped `mysql@5.7` (label: homebrew.mxcl.mysql@5.7)
```

launchctl の管理から、mysql を除外する。

```bash:bash
$ mysql.server status
 ERROR! MySQL is not running
```

```bash:bash
$ ps aux | grep mysql
glaciermelt      43395   0.0  0.0  4277624    724 s004  S+    2:14PM   0:00.00 grep --color=auto mysql
```

mysql が起動しているか、確認する。
gihub actionsでCIを設定して自動チェックを行うための備忘録

## CI

CIとは、Continuous Integrationの略で、継続的インテグレーションを呼ばれています。自動のコードチェック、テスト、ビルドなどを実行することで、チームで継続的に開発を行う際に、品質を担保するための仕組みです。githubではgithub actionsでこのCIを設定することができます。

この記事では、[このプロジェクトに](https://github.com/taijusanagi/nftcert)にgithub actionsのCIを設定していきます。

## 手順

.github -> actions -> ci.yml　というファイルを作成し、下記のようなコードを入れます。

```
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Use Node.js
        uses: actions/setup-node@v1
        with:
          node-version: 14.x.x
      - run: yarn
      - run: yarn lint

```

このコードでは、mainにpush、もしくはpull requestがあった際にlintを実行する、というシンプルなスクリプトが組まれています。この状態で、githubまでコードをプッシュします。

この設定を起こっておくと、このように設定しているtriggerの条件を満たすと、自動でスクリプトが
走るようになります。

![Screen Shot 2022-02-05 at 14.01.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/6da1315d-abb6-bc7f-7034-d910def5a060.png)

結果をActionsから確認することもできます。

![Screen Shot 2022-02-05 at 14.03.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/ca591cc8-72d0-a488-d716-878c2b738595.png)

この変更を加えたコミットは[ここ](https://github.com/taijusanagi/nftcert/commit/024743327403e502466dd7e81c5a53cedea2469d)から確認できます。

プルリクエストはこの自動チェックが通らないとマージできない、というようなルールをチーム内で設けることによって開発効率を上げていくことができるので、ぜひ試してみてください！
Flaskチートシート〈初心者向け〉

flaskを触り始めたので、自分向けのチートシートとして書き留めてます。

##Flaskとは？

Pythonで利用できる『Webアプリケーションフレームワーク』のこと。

##Flaskのセットアップ

```
% pip3 install flask
```

以上。

##FlaskのHello World

```hello.py
from flask import Flask		#Flaskのインポート#お約束
app = Flask(__name__)		#Flaskのクラスのインスタンス化#お約束

@app.route('/')				#「デコレーター」という機能を使ってルーティングの設定（‘/’を指定はルートへのアクセスを意味します）
def index():					#デコレーターで指定したパスにアクセスされた際に動作する関数を定義
	return 'Hello World！'		#関数の戻り値がWebリクエストのレスポンスとなる

if __name__ == '__main__':    
	app.run()					#Webアプリの実行
```


```
% python3 hello.py
```

##テンプレート

同階層に『templates』というディレクトリを用意しその中にテンプレートファイルを配置して > return render_template(‘hello.html’, …（各種パラメータ）...) なんて書き方もできる。

```main.py
from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def index():
return render_template('hello.html', title='flask test', name='honda')

if __name__ == '__main__':    
	app.run()
```


```templates/hello.html
<!doctype html>
<html>
<head>
	<title>{{ title }}</title>
</head>
<body>
	<h3>Hello {{ name }}さん！</h3>
</body>
</html>
```

##URLパラメータを使う

```main.py
from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
	return 'Hello World！'

@app.route('/hoge/<name>')	#URLパラメータとして扱うアクセスパターンを指定
def hoge(name=None):		#URLパラメータとして受け取った値を関数の引数として受け取れるようにしている
	return name

if __name__ == '__main__':    
	app.run()
```

http://127.0.0.1:5000/hoge/tamura

##GETパラメータを扱う

```main.py
from flask import Flask, request  	#リクエストパラメータを扱うためのモジュール
app = Flask(__name__)

@app.route('/')
def index():
	return 'Hello World！'

@app.route('/hoge')
def hoge():
	return request.args.get('name')	#『request.args.get()』メソッドでGETパラメータを取得

if __name__ == '__main__': 
	app.run()
```

http://127.0.0.1:5000/hoge?name=honda

##POSTパラメータを扱う

```main.py
rom flask import Flask, request  		#リクエストパラメータを扱うためのモジュール
app = Flask(__name__)

@app.route('/')
def index():
	return render_template(‘hello.html’, title=’post test’)

@app.route('/hoge', methods=['POST'])	#『POSTパラメータを受け取る』ための明示的な指定

def hoge():
	if request.method == 'POST':	
		name = request.form['name']	#『request.form()』メソッドでPOSTパラメータを取得
	else:
		name = 'no param'

	return name

if __name__ == '__main__':    
	app.run()
```

```templates/hello.html
<!doctype html>
<html>
<head>
	<title>{{ title }}</title>
</head>
<body>
	<form method=“POST” action=“./hoge”>
		<input type=“submit” value=“送信”>
	</form>
	<h3>Hello {{ name }}さん！</h3>
</body>
</html>

```

##JSONレスポンスを返却

```main.py
from flask import Flask, jsonify 	//リクエストパラメータを扱うためのモジュール
app = Flask(__name__)

@app.route(‘/json’)
def json_res():
	return jsonify(name=‘sosuke’,
		sex=‘male’,
		age=’20’

if __name__ == '__main__':    
	app.run()
```

http://127.0.0.1:5000/json
monorepoでtypescriptなnextjsにeslint + prettierを設定する備忘録

## eslintとprettier

今回の記事は[こちらのプロジェクト](https://github.com/taijusanagi/nftcert)に実際にeslintとprettierを入れていく過程を備忘録として残します。

eslintやprettierの設定はできるだけrootで共通管理しつつ、各パッケージで個別の設定がある場合は個別のパッケージで行うという形にしたいので、下記パッケージをrootに入れていきます。

```
// -Wはyarn monorepoでrootにインストールするときに必要な設定です。
// このあたりの設定はdevDependencyに入れるので-Dを設定します。

yarn add -D -W eslint prettier eslint-config-prettier @typescript-eslint/parser @typescript-eslint/eslint-plugin
```

そして、プロジェクトrootの.eslintrc.jsonを下記のように設定します。

```
{
  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"]
}
```

この設定も人によって異なることが多いと思います。できるだけ最小限の設定にしています。

そして、nextjsのpackagesの中に入っている.eslintrc.jsonの設定を下記のように変更し、rootの設定を継承しつつ```eslint-config-next```を利用するようにし、またrootDirの設定も行います。

```
{
  "extends": ["../../.eslintrc.json", "next"],
  "settings": {
    "next": {
      "rootDir": "packages/frontend/"
    }
  }
}

```

![Screen Shot 2022-02-05 at 13.43.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/14207078-e1f8-e5fb-511b-909bc884a82f.png)


この状態で、下記のようなscriptをルートのpackage.jsonに追加します。

```
  "scripts": {
    "format": "prettier . --ignore-path .gitignore --write",
    "lint": "eslint --ext .ts,.tsx . --ignore-path .gitignore",
  }
```

このscriptでformatとlintが走ることを確認して終了です！

今回のコードは[こちらのコミット](https://github.com/taijusanagi/nftcert/commit/e3aeed79bf5aaaa0040466f6e5d460437ca51ae7)で確認できます。

ありがとうございました！
Reactを基本からまとめてみた【11】【react-three-fiber】


##環境の準備

① ターミナルでreactアプリケーションを作成する。

```
$ npx create-react-app <プロジェクト名>
% cd <プロジェクト名>
% npm start
```

② logo.svg, App.css, index.css, App.test.js,
を削除する。

③必要なパッケージをインストールする。

```
# Use npm
npm install three react-three-fiber
```

##コンポーネント・ファイル構成

```
src
├── assets
       └── circle.png
├── App.css
├── App.js
├── index.js
```

```App.css
html,
body {
  box-sizing: border-box;
  overflow-x: hidden;
}

.anim {
  width: 100vw;
  height: 100vh;
  background-color: black;
}
```
```App.js
import "./App.css";
import * as THREE from "three";
import { Canvas, useFrame, useLoader } from "react-three-fiber";
import circleImg from "./assets/yellow-circle.png";
import { Suspense, useCallback, useMemo, useRef } from "react";

function Points() {
  const imgTex = useLoader(THREE.TextureLoader, circleImg);
  const bufferRef = useRef();

  let t = 0;
  let f = 0.002;
  let a = 3;
  const graph = useCallback(
    (x, z) => {
      return Math.sin(f * (x ** 2 + z ** 2 + t)) * a;
    },
    [t, f, a]
  );

  const count = 100;
  const sep = 3;
  let positions = useMemo(() => {
    let positions = [];

    for (let xi = 0; xi < count; xi++) {
      for (let zi = 0; zi < count; zi++) {
        let x = sep * (xi - count / 2);
        let z = sep * (zi - count / 2);
        let y = graph(x, z);
        positions.push(x, y, z);
      }
    }
    return new Float32Array(positions);
  }, [count, sep, graph]);

  useFrame(() => {
    t += 15;
    const positions = bufferRef.current.array;
    let i = 0;
    for (let xi = 0; xi < count; xi++) {
      for (let zi = 0; zi < count; zi++) {
        let x = sep * (xi - count / 2);
        let z = sep * (zi - count / 2);

        positions[i + 1] = graph(x, z);
        i += 3;
      }
    }
    bufferRef.current.needsUpdate = true;
  });

  return (
    <points>
      <bufferGeometry attach="geometry">
        <bufferAttribute
          ref={bufferRef}
          attachObject={[`attributes`, `position`]}
          array={positions}
          count={positions.length / 3}
          itemSize={3}
        />
      </bufferGeometry>
      <pointsMaterial
        attach="material"
        map={imgTex}
        color={0x00aaff}
        size={0.5}
        sizeAttenuation
        transparent={false}
        alphaTest={0.5}
        opacity={1.0}
      />
    </points>
  );
}

function AnimationCanvas() {
  return (
    <Canvas
      colorManagement={false}
      camera={{ position: [100, 10, 0], fov: 75 }}
    >
      <Suspense fallback={null}>
        <Points />
      </Suspense>
    </Canvas>
  );
}

function App() {
  return (
    <div className="anim">
      <Suspense fallback={<div>Loading...</div>}>
        <AnimationCanvas />
      </Suspense>
    </div>
  );
}
export default App;
```


##参考サイト
[react-three-fiberを使用してReactとThree.jsで3Dリップルアニメーションを作成する|初心者向けチュートリアル]
(https://www.youtube.com/watch?v=wRmeFtRkF-8)
WebSocketサーバーへ接続できないときの対処


# WebSocketサーバー
今回JINS MEMEを使った開発を行おうと下記サイトを参考にWebSocketサーバーを立てました。
これはスマホのアプリ（Loggerアプリ）がClientとなり、立てたWebSocketサーバーに接続に行くはずなのですが、うんともすんともならなかったので調べたことについて書きます。

https://jins-meme.github.io/sdkdoc2/logger/websocket_integration.html

WebSocketサーバーのプログラムはNode.jsで作っています。
下記はNode.jsのプログラムサンプル（JINS MEMEのWebSocket連携に書かれてあるものそのまま）です。

```js
const server = require("ws").Server;
const ws_server = new server({ port: 5000 });

ws_server.on("connection", ws => {
  console.log("connected from client");
  ws.on('message',function(message){
    if(message.indexOf("heartbeat") === -1){
      //メッセージを出力
      console.log(message);

      //実際の処理する場合はparseして処理していきます
      //const obj = JSON.parse(messeage);
    }
  });
});
```
今回はWebSocketサーバーはポート5000としています。
"connected from client"が出力されていないので接続できていないようでした。

# まずはちゃんとWebSocketサーバーにできるかテストする
サーバーが接続できないのか、クライアント側が接続に行けてないのかどうか（サーバーの問題かクライアント側の問題か）を切り分けするため、まずはツールを使ってWebSocketサーバーに接続できるかどうか試してみます。

「WebSocket テストサイト」とかで検索をするとテスト接続できるサイトが公開されているのでどれかを選択して使えば良いです。

今回は下記のサイトを使わせていただきました。
https://develop.miugle.info/websocket/

![WebSocketテストサイト-失敗](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308578/0c031c16-a3b9-a73e-488e-61be2000302b.png)

URL（「接続」の入力欄）に「ws://localhost:ポート番号」を指定します。
localhostはローカルIPアドレスでも良いです。「あれ？外部サイトからローカルアドレス？」って思ってしまいましたが、こちらはJavaScriptでWebSocketアクセスしているのでこのサイトを開いているブラウザがローカルネットワーク上の端末である場合は大丈夫なんですね。（ページのソースを見ればJavaScriptで実装されていることがわかります）

結果は「エラー」と出ているのでサーバーに接続できない（接続できていない）ことがわかりました。

# 怪しいのはファイアウォール
今回はサーバーをWindowsノートPCで起動しています。
なので怪しむべきはWindowsが親切にネットワークの遮断を判断してくれているファイアウォールです。

ということでとりあえず全部いったん解除してこれが原因かどうかを特定してみましょう。

Windows Defenderの設定で「ファイアウォールの状態」を「無効」にします。
今回はローカルネットワーク内でWebSocket接続しようとしてうまくいかなかったのでプライベートネットワークの「プライベートプロファイル」の設定を無効にしてみました。

![Windows Defender](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308578/7c701510-5e34-2148-79a3-28b1e51fa100.png)

それから再度テスト接続を先ほどのサイトから行うと・・
![WebSocketテストサイト-成功](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308578/f6454660-449f-ea63-feb9-6820cac4a325.png)

サイト上に「接続完了」と表示され、WebSocketサーバー側でも"connected from client"と出力されました。
ということはファイアウォールが原因ということがわかりました。

ちなみにウイルス対策ソフトを入れている場合、そちらのファイアウォール機能が働いていることもあるのでいったんそれも止めてみると良いです。（ソフト自体停止できるなら一時的に停止してみるのもアリと思います）

# ファイアウォールの設定をきれいにやっておく
ファイアウォールはこのままでも良いですが、ローカルネットワークで全くファイアウォールが効かないことになるので、ポート指定でできるようにしておくと良いですね。

![ポート5000の接続設定](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308578/8f797e22-ebea-2f5e-5fbd-da3e28c5e978.png)

上記のようにポート5000に対して「接続を許可」にしてあげます。
これは「新しい規則…」で設定を追加してあげることができます。

# おわりに
設定は以上です。
当初行いたかったJINS MEMEのLoggerアプリからも無事WebSocketサーバーに接続できるようになりました。
3行でバーコード作成

## ライブラリをインストール
```
pip install pybarcodes
```
## コーディング
```
from pybarcodes import JAN
barcode = JAN('')
barcode.show()
```
## 実装動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/ZOdxwHdXUcg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
AWS AppSync 概要メモ


## AppSyncとは

* AWSが提供するマネージドGraphQL gatewayサービス
  * Graph QL：サーバー上にあるデータのフェッチ、変更、サブスクライブをクライアントアプリから実行できるデータ言語

## 主な特徴

* **フルマネージド GraphQL サービス** 
* **リアルタイムデータアクセス/更新**
  * GraphQL サブスクリプションを利用し、クライアント側でどのデータをリアルタイムで更新するか指定できる。
* **オフラインデータ同期**
  * クライアントはアプリデータをオフラインで利用でき、データの登録/更新できる。
* **キャッシング**
  * 頻繁に変更されないデータをキャッシュして、パフォーマンスを向上させることができる。
* **複数データソースへのアクセス**
  * AWS Lambda、Amazon DynamoDB、Amazon Elasticsearch がサポートされている。
* **アクセス制御**
  * IAMロールやCognitoユーザープールと組み合わせたアクセス制御が可能。

## 概念とアーキテクチャー

* **AWS App Sync Client** 

  * 認証、オフラインロジックなどを含んだクライアント 

* **Resolver** 

  * リクエスト / レスポンスの処理を記述する関数 
  * マッピングテンプレートによって、GraphQL リクエストをデータソースの命令に変換する⽅法と、データソースからの応答をGraphQLレスポンスに変換する⽅法を定義
  * Resolver マッピングテンプレートは、VTL (Velocity Template Language)によって記述

* **Data Source** 

  * DynamoDB
  * Lambda
  * Aurora Serverless
  * Elasticsearch
  * HTTP Endpoint

* **Schema**

  * サーバ機能を記述し、クエリが 有効かどうかを判断する為に使⽤

  * GraphQL API は、SDL(Schema Definition Language)によって記述された1つのGraphQL Schema で定義される。

    
![appsync_arch.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/b71a1c6d-4828-faf6-68ca-d19456f4e777.png)



## ユースケース

* リアルタイムでデータ更新を行うダッシュボードアプリケーション
* 複数ユーザーがコンテンツ(ドキュメント、画像、テキストメッセージ等)の共同編集を⾏うアプリケーション
* ソーシャルメディアやチャットなど複数ユーザー間でのメッセージング管理を行うアプリケーション

## 料金

|                           | 無料枠(月)     | 価格                                        |
| ------------------------- | -------------- | ------------------------------------------- |
| クエリとデータ変更操作    | 250,000 件     | 4.00USD/クエリおよびデータ変更操作 100 万回 |
| リアルタイム更新          | 250,000 件     | 2.00USD/リアルタイムアップデート 100 万回   |
| リアルタイム更新 接続時間 | 600,000接続-分 | 0.08USD/100万分                             |



## 参考情報

* [AWS AppSync](https://d1.awsstatic.com/webinars/jp/pdf/services/20190821_AWS-BlackBelt_AppSync.pdf)
* [appsyncを使ったServerlessアーキテクチャ](https://www.slideshare.net/AmazonWebServicesJapan/aws-expert-online-appsyncserverless)
OpenID Connect Client-Initiated Backchannel Authentication(CIBA) Flowメモ


## CIBAとは

* OpenID Foundation によって策定された、認証・認可 に関する仕様の一つ。
* ユーザーの認証・同意取得処理を、ユーザーの認証デバイス（Authentication Device）で実施するのが特徴。

## 用語

* Consumption Device (CD、消費デバイス)

  * ユーザーがサービス利用(消費)に用いるデバイス。
  * このデバイスがOIDC IdPに認証リクエストを行うことでCIBAフローが開始される。

* Authentication Device (AD、認証デバイス)

  * ユーザーが認証・同意を行うデバイス。
  * スマホなど。

  ※2つのデバイス自体とそれらを操作する人物は同一でなくてもよい。

## フロー
![CIBA.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/98508bd0-ab85-9b3b-f483-acb54726eace.png)




1. クライアントアプリ(Consumption Device、消費デバイス)は認可サーバー/バックチャネル認証エンドポイント（Backchannel Authentication Endpoint）に対してバックチャネル認証リクエスト（Backchannel Authentication Request）を行う。

2. 認可サーバー/バックチャネル認証エンドポイントはクライアントに対してレスポンスとして認証を識別するための識別子を返却する。

3. 認可サーバーはユーザーの認証デバイス(スマホなど)などに認証・同意取得処理を要求する。

4. クライアントアプリは次の3つのモードをトークンを取得する。

   * `POLL`モード
     * (3で認証デバイスからユーザー認証・同意結果を得るまで、)クライアントアプリは認可サーバー/トークンエンドポイントに対して、トークンリクエストを繰り返す。

   * `PING`モード
     * (3で認証デバイスでのユーザー認証・同意取得処理完了後、）認可サーバーはクライアントアプリの通知エンドポイントに通知を行う。

     * クライアントアプリは認可サーバー/トークンエンドポイントに対して、トークンリクエストを行う。

   * `PUSH`モード
     * (3で認証デバイスでのユーザー認証・同意取得処理が終わった後、）認可サーバーはトークン情報をクライアントの通知エンドポイントに直接渡す。



## ユースケース

* コールセンターでの発信者の認証
* 銀行(対面応対)での顧客認証

- スマホを用いたPOS 端末支払い

## 参考情報

* [OpenID Connect Client-Initiated Backchannel Authentication Flow - Core 1.0](https://openid.net/specs/openid-client-initiated-backchannel-authentication-core-1_0.html#rfc.section.2)
爆速化するためにpythonからRustを呼び出そう！

## Rustで作成したライブラリをpythonで呼ぶ方法
PyO3を利用するには、ツールチェインのnightly版をインストールする必要があります。

```
rustup install nightly 
rustup default nightly 
rustup toolchain list
```

Cargo.tomlにPyO3の依存関係を追記します。

```
[lib]
name = "eratosthenes"
crate-type = ["cdylib"]

[dependencies.pyo3]
version = "0.13.2"
features = ["extension-module"]
```
ダイナミックライブラリを作成するために、--releaseをつけてビルドします。

```
cargo build --release
```
もし以下の様にエラーが出る場合は、バージョンを新しくすることで解決できる可能性があります。
参考：https://github.com/rust-osdev/x86_64/issues/234

```
#![cfg_attr(feature = "const_fn", feature(const_in_array_repeat_expressions))]
                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ feature has been removed
```
`cargo build --release`を実行すると、`target/release`内にWindowsであれば`.dll`,
Linuxであれば`.so`、Macであれば`.dylib`が作成されます。
作成されたファイルを以下対応拡張子に変更し、利用するpythonスクリプトと同じディレクトリに格納することでpythonで利用することができます 

| OS | --releaseで作成されるファイル | pythonで利用するために | 
| ------------- | ------------- | ------------- |
| Windows | .dll | .pyd |
| Mac | .dylib | .so |
| Linux | .so | .so |

## 実装動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/65_7uUGYq-U" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
vscodeにeditorconfigを設定する備忘録

## editorconfig

エディターの細かいルールを統一するためのツールです。インデントや文字コード、改行コードなどを一括で設定し、チーム内の異なるエディタ間で共有することができます。

今回はこちらを[このプロジェクト](https://github.com/taijusanagi/nftcert)に設定していきます。


## 設定ファイルの作成

下記のような設定ファイルをプロジェクトのルートに設定します。
```
root = true

[*]
charset = utf-8
end_of_line = lf
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = false
max_line_length = 120
indent_size = 2
```

![Screen Shot 2022-02-05 at 13.19.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/168b1dc6-4b84-c8f6-6ae9-17dd551f4f36.png)

細かい設定はこちらの公式ページをご覧ください。

https://editorconfig.org/

## VScodeのプラグインの設定

こちらのプラグインをvscodeに設定します。

https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig

下記のようにプラグインの検索画面で```EditorConfig.EditorConfig```と検索し、出てきたこちらのプラグインを有効化します。

![Screen Shot 2022-02-05 at 13.20.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/1007144b-7804-96ff-568d-1678f020bcf5.png)


これで、ファイルの保存時などに、設定したエディタの設定が適用されるようになります。

今回の設定は[こちらのコミット](https://github.com/taijusanagi/nftcert/commit/a5f1ce221dfa8d48f6a6c4664c379b0ebeca9627)で確認することができます。

ぜひ試してみてください！
Jenkinsfileからshを実行しようとして、"nohup: failed to run command ‘sh’: No such file or directory"と言われた

## 事象

Jenkinsfile内で`sh`コマンドを使おうとしたら

```sh
nohup: failed to run command ‘sh’: No such file or directory
```

のエラーになり、実行ができなかった。

## 解決法

環境変数の設定の追加が必要でした。

Jenkinsの管理 > システムの設定 > 環境変数 に以下を設定。

```
Key: Path
値 : ${PATH}:/bin/
```

既に他の`PATH`の設定がある場合には末尾に`:/bin/`を追加してください。
monorepo環境にnextjsを構築する備忘録

## nextjs

nextjsはreactのフロントエンドの開発フレームワークです。

今回は[こちらのプロジェクト](https://github.com/taijusanagi/nftcert)をセットアップする際に、nextjsの構築をおこなったので、備忘録として残します。

## 注意

こちらの記事でmonorepoを設定した後にnextjsを導入しました。

https://qiita.com/taijusanagi/items/cfd6ff7ba72e65439b66

monorepo環境下で実行すると下記のようなエラーが出ました。

```
warning Missing version in workspace at "/Users/taijusanagi/Documents/workspace/taijusanagi/nftcert/packages/frontend", ignoring.
error An unexpected error occurred: "Cannot read property 'manifest' of undefined".
```

そのため、下記のmonorepoの設定をrootのpackage.jsonから外してから下記を行なっています。

```
  "private": true,
  "workspaces": [
    "packages/**"
  ],
```


## 手順

packages直下で、こちらのコマンドを実行します。

```
//こちらはnextjsのアプリケーションを作成するためのコマンドです。
//typescriptを使いたいので、--tsをつけています。

npx create-next-app --ts

//下記の質問の答えがdirectoryとpackage名になります。
What is your project named? … frontend
```

これでpackages/frontendにnextjsの設定ができました。

![Screen Shot 2022-02-05 at 12.59.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/9bae48f4-1eca-d5c6-c81c-b34bf1664994.png)

ターミナルに設定されている、下記を実行して動作確認をします。

```
cd frontend
yarn dev
```

下記のような画面が```http://localhost:3000```に表示されれば成功です！

![Screen Shot 2022-02-05 at 13.00.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/0aaa49e2-6582-4f84-d80a-2c3f82584883.png)


create-next-appで作成されたpackage.jsonにはversionの情報がないので、記載します。

```
  "version": "0.0.1" //任意のバージョンを指定してください。
```

rootのpackage.jsonに下記を戻して、yarnのmonorepoの設定で動かせるか確認していきます。

```
  "private": true,
  "workspaces": [
    "packages/**"
  ],
```

rootのpackage.jsonに下記を追加します。

```
  "scripts": {
    "dev:frontend": "yarn workspace frontend dev"
  }
```

そして、```yarn dev:frontend```を実行してみると...

![Screen Shot 2022-02-05 at 13.04.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/0ddb614d-da40-60b4-975f-4ff252e0cad3.png)

無事に動作しました。

monorepo環境では、各workspace内に表示されるyarn.lockは必要ないので削除します。

![Screen Shot 2022-02-05 at 13.05.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/8b71802a-948c-71d3-8067-4d1051f814dd.png)

ここまででgitに[コミット](https://github.com/taijusanagi/nftcert/commit/889a724de94c9e3dc26db93ec90432f1cf468bb0)して終了です。

ありがとうございました！
git log の "--ancestry-path" と "--first-parent" を図とコマンドで確認する

# "--ancestry-path"

以下説明がイマイチ理解しづらかったので、コマンドで確認してみたメモ。

> 表示するコミットの範囲（例えば、「commit1..commit2」または「commit2 ^ commit1」）が指定されている場合、「commit1」と「commit2」の間の祖先チェーンに直接存在するコミット、つまり、「commit1」の子孫と「commit2」の祖先の両方であるコミットのみを表示します。
https://tracpath.com/docs/git-log/

# 下準備

- master ブランチから master1 / master2 ブランチを切って、また合流する

### イメージ図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/bca1a660-53f2-fc6b-b3a3-9c3bcb5cdbdb.png)

### コマンド

```bash
# master ブランチで最初のコミット
% git init
% git commit --allow-empty -m "Initial Commit"

# master1ブランチを切ってコミットを作る
% git ch -b master1
% touch master1; git add . ; git commit -m "master1-1"
% touch master1-2; git add . ; git commit -m "master1-2"

# master ブランチに戻って master2 ブランチを切ってコミット
% git ch master
% git ch -b master1
% touch master2; git add . ; git commit -m "master2-1"
% touch master2-2; git add . ; git commit -m "master2-2"

# master ブランチに戻ってコミット
% git ch master
% touch master; git add . ; git commit -m "master"

# マージ
% git merge master1
% git merge master2
```

# 例1: 頭から最後まで指定

分岐したもの全てが条件に当てはまるので全て表示される

```bash
git log --oneline --ancestry-path A..H
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/1cbdc2e5-a554-bf2e-2060-ab30ae16457e.png)

# 例2: 分岐したところから最後まで指定

分岐したところから最後まで。異なる分岐の方のコミットは入らない。

```bash
git log --oneline --ancestry-path C..H
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/20f6247d-e9d8-8c3b-d33e-962d94441a21.png)

# "--first-parent"

下準備は上記の引き続き。
master ブランチでコミットしたやつだけを表示。
master1 や master2 ブランチでコミットされたものは表示されない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/5412c362-4d27-efaf-5aa8-3197e472f210.png)

master1 の場合。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50690/8d4401d1-897a-cd34-de03-05ea569fdff5.png)



# 参考
https://git-scm.com/docs/git-log
https://amzn.to/3IZzWyM
Ubuntu Server 20.04.3 LTS 構築#8 セキュリティ設定5-1

実施日:2022/01/22～

<<今回の内容>>
シェルスクリプトを使用して、ウイルススキャンを自動で定期的に実施する。

clamavでスキャンする方法は2通り
①clamscan
メリット:オプションが多く、daemonが不要
デメリット:時間が掛かる

②clamdscan
メリット:時間が掛からない、マルチスレッド対応
デメリット:オプションが少なく、daemonが必要

サーバー使用率が高い時間帯のスキャンは②clamdscanを使用する。
サーバー使用率が少ない時間帯のスキャンは①clamscanを使用する。
このような使い分けをすればいいのかな。

今回のテーマはシェルスクリプトを使用して、ウイルススキャンが目的
ただスキャンして、終わりならcron.dディレクトリ内にcrontabファイルを作成してスキャンすれば良い。
シェルスクリプトを使用してのウイルススキャンをするため、スキャン+αにしたい。

+αの中身として
①ウイルスを検知した場合の対処法
　削除、隔離
②検知したときにどうやって認識するか
　定期的にログを見る、メールで通知を受ける
③定義更新も行う
などなど

シェルスクリプトを使用して、上記のことも併せて行いたい。

今回はここまで

次回からシェルスクリプトを作成して、実行できるようにしていきます。
yarnのmonorepo構築の備忘録

## monorepo

この記事ではyarnを利用したmonorepo構築の備忘録です。

package.jsonに下記を追加します。

```
  // package.json

  "private": true,
  "workspaces": [
    "packages/**"
  ],
```

そして、packagesというディレクトリを作成して、その下に再度ディレクトリを任意の名前で作成し、package.jsonを作成します。

![Screen Shot 2022-02-05 at 12.45.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/4cc7ffc5-17c7-0bc3-e8ff-2c09ae13b413.png)

このpackage.jsonにはversionを指定することが必須となっており、またnameに指定した部分がmonorepoのワークスペースの名前となります。

今回は、```@nftcert/sample```がワークスペースの名前ですので、下記のようにするとworkspaceにnpm moduleをインストールすることができます。

```
yarn workspace @nftcert/sample add -D typescript
```

また、このworkspaceが設定されている状態で、yarnを行うとワークスペースのnpm moduleもまとめて実行することができます。

今回のコミットは[こちら](https://github.com/taijusanagi/nftcert/commit/f08d01cce9e8d1530cf96c04388ddc5deeceef88)です。

ぜひ試してみてください！
トグルボタンでダークモードとライトモードを切り替え


#はじめに
ダークモードにできたら、もっといい感じになるよね！
非常に簡単なので、すぐやろう！

# Windowにトグルボタンを配置する
トグルボタンのIsCheckプロパティとVieModelのDarkMode.Valueプロパティをバインドする。

```MainWindow.xaml

<!-- ダークモード／ライトモードを切り替えるトグルボタン -->
<ToggleButton IsChecked="{Binding Path=DarkMode.Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

```

# ボタンの入力変更を監視するプロパティを用意する

```MainWindowViewModel.cs

using MaterialDesignThemes.Wpf;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;


public class MainWindowViewModel : ViewModelBase
{
    public MainWindowViewModel() : base()
    {
        // 初期化
        this.DarkMode = new ReactiveProperty<bool>(false).AddTo(this.disposedValue);
        // プロパティの値を監視する。
        this.DarkMode
            .ObserveProperty(x => x.Value)
            .Subscribe(x =>
            {
                PaletteHelper paletteHelper = new PaletteHelper();
                ITheme theme = paletteHelper.GetTheme();
                theme.SetBaseTheme((bool)x ? Theme.Dark : Theme.Light);
                paletteHelper.SetTheme(theme);
            })
            .AddTo(this.disposedValue);
    }

    public ReactiveProperty<bool> DarkMode { get; }
}

```

# デバッグで確認
ライトモード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684408/363b383e-abd2-7256-7015-8c521adfc74e.png)
ダークモード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/684408/b0bed20d-0a89-d332-4b5c-b29d4d8b6fad.png)

以上。
GeneratedValueについて

最近、Spring Boot × Dockerで開発をしています。

本日のお題はGeneratedValueです。

## GeneratedValueとは
プライマリキー値を生成する方法を指定する属性である。

GeneratedValueは4つの種類が存在する。
- AUTO : データベースごとに異なる方法を選択
- IDENTITY : テーブルのidentity列を利用
- SEQUENCE : シーケンスオブジェクトを使用
- TABLE : 主キー値を保持しておくためのテーブルを使用
である。

それぞれはDMBSによって動向が変わってくる。

### IDENTITY
PostgreSQL : SERIAL
MySQL : AUTO_INCREMENT
Oracle : サポートなし

### SEQUENCE

PostgreSQL : sequenceName
MySQL : サポートなし
Oracle : シーケンスオブジェクト

### TABLE
何れも対応している。

### AUTO
PostgreSQL : hibernate_sequence
MySQL : AUTO_INCREMENT
Oracle : hibernate_sequence



## 参考
- [@GeneratedValueを使って主キーを生成する方法](https://qiita.com/KevinFQ/items/a6d92ec7b32911e50ffe)
Commitメッセージをチェックするcommitlintの設定の備忘録

## commitlintとは

[Commitlint](https://commitlint.js.org/#/)は、Commitメッセージを特定のルールで守らせるための設定を行うためのツールです。Commitlintの設定手順についてチーム内で共有することが多かったので備忘録として残します。

詳しくルールをカスタマイズすることはできるのですが、この記事では既存のルールセットをそのまま利用し、動かせるようになることを目標としています。

package.jsonが置いてあるプロジェクトルートで下記を実行します。

```
yarn add -D @commitlint/cli @commitlint/config-conventional 
```

devDependenciesに下記が追加されます。

```
  //package.json

  "devDependencies": {
    "@commitlint/cli": "^16.1.0",
    "@commitlint/config-conventional": "^16.0.0",
  }
```

次にprojectのルートに下記を作成します。

```
// .commitlintrc.json

{
  "extends": ["@commitlint/config-conventional"]
}
```

次にこのコミットを自動的に検証する際にhuskyと連携するのがおすすめです。huskyの設定についてはこちらに記載していますのでご参照ください。

https://qiita.com/taijusanagi/items/bd44d32efdba980f3f20

huskyのインストールが終わった後に、下記を実行します。

```
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
```

下記のようにcommit-msgが作成されています。

![Screen Shot 2022-02-05 at 11.39.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/06903a94-df66-2f67-1e82-c5a8590b7c45.png)

この状態でルールに合っていないコミットを実行しようとするとエラーが出てきます。

![Screen Shot 2022-02-05 at 11.41.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/4969155d-74ed-e51b-8ffc-2e49f91a6852.png)

今回使用しているルールセットの詳細はこちらにあります。

https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional

ルールに合わせて下記のようにcommitすると...

```
git commit -m "chore: add commitlint" 
```

無事にコミットできました！

![Screen Shot 2022-02-05 at 11.43.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/440d24d8-7534-21a5-2a3d-2041b05874bf.png)

今回のコミットはこちらです。ありがとうございました！
GCP Dataflow Classic Templateで複数ファイルを取り扱う[備忘録]

Apache BeamのワークフローをGCP Dataflow上で動かせるようになるには[Templateの登録](https://cloud.google.com/dataflow/docs/concepts/dataflow-templates)が必要です。TemplateにはFlex TemplateかClassic Templateが選べますが、今回はClassic Templateについて、特に複数ファイルを使ったテンプレートについての話です。

[Dataflowのチュートリアル](https://cloud.google.com/dataflow/docs/guides/templates/creating-templates#python_7)では特に複数ファイルについての言及はなく、代わりに[Apache Beam側のドキュメント](https://beam.apache.org/documentation/sdks/python-pipeline-dependencies/#multiple-file-dependencies)に説明があります。

ここで例示されたファイル構成は以下の感じです。

```text
 ​root_dir/
  ​setup.py
  ​main.py
  ​other_files_dir/
```

`setup.py`内に設定を書いてパッケージ化が必要とのことで、`main.py`に`if __name__ == '__main__'`ではじまるメイン関数を書き、other_files_dir/にその他依存する複数ファイルを入れる感じのようです。つまり

```text
 ​root_dir/
  ​setup.py
  ​main.py
  ​other_files_dir/
    __init__.py
    aaa.py
    bbb.py
    ...
```

という感じでファイルを置いていけばいいのかなと理解しました。しかしこれでテンプレートを作成して実行したところ`ModuleNotFoundError`が`other_files_dir`以下で発生。
試行錯誤した結果、main.pyをother_files_dirに移すことでとりあえず上手くいきました。

```text
 ​root_dir/
  ​setup.py
  ​other_files_dir/
    __init__.py
    main.py
    aaa.py
    bbb.py
    ...
```

自分が勘違いしてるだけで、元の構成でも行ける気がしますがとりあえず上手く行ったので備忘録。
顔写真をめっちゃ綺麗にする　GFPGAN

#顔に特化した超解像モデルの使い方です
![ダウンロード (37).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/cf68c289-845d-a46a-1c2e-cf4092d08363.png)

#写真の多くは顔写真

超解像モデルはいろいろありますが、一般的な画像データセットやアニメに特化したものが多いです。
世の中の多くの写真は人の写真。

#GFPGANは顔専用
顔を特に綺麗にしてくれます。

https://github.com/TencentARC/GFPGAN

#使い方

実行はかんたん1行。

```shell
python inference_gfpgan.py --upscale 2 --test_path inputs --save_root results --model_path experiments/pretrained_models/GFPGANCleanv1-NoCE-C2.pth --bg_upsampler realesrgan
```
![ダウンロード (36).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235259/6df09da5-89c0-8554-b94a-4f2fe5169dc5.png)

https://colab.research.google.com/github/yuval-alaluf/restyle-encoder/blob/master/notebooks/inference_playground.ipynb

めちゃくちゃすごくないですか？

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
AtCoder ABC214 F-Substrings の「印をつけた文字が隣り合ってはいけない」という制約を外した問題を解いてみた

[AtCoder ABC214 F - Substrings](https://atcoder.jp/contests/abc214/tasks/abc214_f) の [公式解説](https://atcoder.jp/contests/abc214/editorial/2440) は、まず「印をつけた文字が隣り合ってはいけない」という制約を外した問題から解説されている。その問題は次のとおりである。

> $S$ の空文字列でない部分文字列の個数を求めよ。ただし、部分文字列とは元の文字列から $0$ 文字以上取り除き残った文字を元の順番で並べたものである。

そしてその解説の中で、計算量に関して次の様に書かれている。

> 計算量は一見 $O(|S|^2)$ に見えますが、文字の種類数を $σ$ としたとき、累積和を用いれば $O(|S|)$、用いなくとも $O(σ|S|)$ で十分高速です。

そこで、累積和を用いて計算量が $O(|S|)$ であるコードに挑戦してみた。

累積和を ${\rm{dp}}_i$ で表したいので、公式解説の ${\rm{dp}}_i$ を $a_i$ に変えた次のような数列 {$a_i$} を考えます。

> - $a_i$​ := 文字列 $S$ の $1$ 文字目から $i$ 文字目までの部分から得られる部分文字列のうち $i$ 文字目は必ず使うようなものの個数  
> ただし、空文字列に対応して $a_0=1$ とします。

一般項 $a_i$ は次のようになります。（理由は[公式解説](https://atcoder.jp/contests/abc214/editorial/2440) を見てください。）

> - $k$ を $S_i=S_k​$ かつ $k<i$ を満たす最大の整数として（存在しない場合 $k=0$）

> ```math
a_i=\sum_{j=k}^{i-1}a_j
```

ここまで、引用ばかりですが、次から自分で考えた部分です。

${\rm{dp}}_i$ を数列 {$a_i$} の和とします。

```math
{\rm{dp}}_i=\sum_{j=0}^{i}a_j
```

このとき、遷移式は次の様になります。

```math
\begin{eqnarray}
{\rm{dp}}_{i+1} &=& \sum_{j=0}^{i+1}a_j \\
&=& a_{i+1}+\sum_{j=0}^{i}a_j \\
&=& \sum_{j=k}^{i}a_j+{\rm{dp}}_i \\
&=& \sum_{j=0}^{i}a_j-\sum_{j=0}^{k-1}a_j+{\rm{dp}}_i \\
&=& {\rm{dp}}_i-{\rm{dp}}_{k-1}+{\rm{dp}}_i \\
&=& 2{\rm{dp}}_i-{\rm{dp}}_{k-1}
\end{eqnarray}
```

ただし、$k=0$ に対する ${\rm{dp}}_{-1}$ は

```math
{\rm{dp}}_{-1}=0
```

とする。

これをpythonのコードにした。

```python:substrings.py
S = input()
N = len(S)

# k は k<i で S[k]=S[i] となる最大の index (存在しないときは -1)
k = [-1] * 26

dp = [0] * (N + 2)  # k=-1 のために N+2 とした（dp[-1]=dp[n+1]=0） 
dp[0] = 1  # 初期値のため空文字列 '' を 1 個と数える
for i in range(N):
    dp[i + 1] = 2 * dp[i] - dp[k[ord(S[i]) - ord('a')]]
    k[ord(S[i]) - ord('a')] = i  # S[i] に対する k を最大値に更新

print(dp[N] - 1)  # 空文字列は部分列に数えないので dp[0]=1 を引く

# S='abaaabba' の実行結果 59
```

計算量を $O(|S|)$ に出来たと思うが、どなたかアドバイスをお願いします。
M5Stack Core2 for AWS で遊ぶ_2/5更新 

#投稿途中

#内容
〇動機
・AWS触ってみたい
→M5StackからAWS連携の製品出てる！　
→日本語の記事見つけられんかったから、Qiitaにメモを残すことにした。

M5Stackユーザー増えて、自分のような初心者向けの記事が増えてくれることを期待。


〇記事投稿時の経験値
・AWS：[20分くらいのYoutube解説動画](https://www.youtube.com/watch?v=KuR-lcoqrQY&t=532s)、一回見た
・M5Stack：[UIFLOW](https://m5stack.github.io/UIFlow_doc/ja/)（ビジュアルプログラミング）、使って遊んだ
・プログラミング：ArduinoとPythonの入門書を一冊ずつ読み終えた


##AWS_IOT_EDUKIT実践記

1.s




###参考資料
・[スイッチサイエンスの商品紹介ページ](https://www.switch-science.com/catalog/6784/)
・[AWS_IOT_EDUKIT日本語ページ](https://www.switch-science.com/catalog/6784/)
スクリプトをhook実行させるためのHuskyに関する設定の備忘録

## Huskyとは

スクリプトを特定のタイミングで実行させるためのツールです。

https://github.com/typicode/husky

今回は実際に[こちらのプロジェクト](https://github.com/taijusanagi/nftcert)をセットアップとしてhuskyを導入していきます。

こちらの記事に記載されているセットアップ手順を使用します。

https://typicode.github.io/husky/#/

```
npx husky-init && yarn 
```

上記を実行すると、package.jsonに下記のようにhuskyが追加されます。

```
  "devDependencies": {
    "husky": "^7.0.0"
  },
  "scripts": {
    "prepare": "husky install"
  }
```

こちらのpre-commitというファイルに、npm testというscriptが記載されているのですが、こちらのpre-commitはcommitを行う前に特定のコマンドを実行するための設定を行います。

![Screen Shot 2022-02-05 at 11.28.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/0b82c0c0-a4b1-4fd4-9a5f-3467a7da3274.png)

試しにtestでエラーを起こしてコミットしてみましょう。

```
  "scripts": {
    "prepare": "husky install",
    "test": "echo \"Error: no test specified\" && exit 1"
  }
```

上記ではtestを実行すると必ずエラーが起きるようにしているのですが、下記のようにエラーが出てコミットに失敗します。

```
Error: no test specified
npm ERR! Test failed.  See above for more details.
husky - pre-commit hook exited with code 1 (error)
```

今回のセットアップの内容はこちらの[コミット](https://github.com/taijusanagi/nftcert/commit/bf9d4db7f2b4d16deb8c01f3fc88f430ac0d9439#diff-7e4aaf6c668d963718b95dd40f60ead9949a3fa59698707d2cd1c6eb1549112a)で確認できます。テストに関する記載は削除しています。

このようにhuskyを使用することで、commit前に特定の条件を満たしているかどうかをローカルで検証することができるようになるので、チーム開発にはとても便利です。ぜひ試してみてください！

## 関連記事

こちらのcommitlintはhuskyととても相性がいいです。

https://qiita.com/drafts/4117e9c621186b254a9f/edit
買ったばかりのM1 MacにNodejsの開発環境をセットアップする手順の備忘録

## 開発環境構築

チーム内で新しいメンバーに開発環境の構築から初めてもらうことが多いので、メモにしました。ある程度わかる人はググりつつ公式の記事を読みつつ進めていく方がいいのかなと思いますが、開発を始めたばかりで難しい人向けに備忘録として残しています。

こちらの記事では下記について紹介します。

- vscodeのインストール
- homebrewのインストール
- nvmのインストール
- nodejsのインストール
- yarnのインストール

### vscodeのインストール

コードエディタであるvscodeをインストールしていきます。今回セットアップしようとしているnodejsでコードを書く場合にはvscodeを使用することが多いです。

こちらのvscodeのページにアクセスします。

https://code.visualstudio.com/

こちらのダウンロードをクリックして

![Screen Shot 2022-02-05 at 10.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/a3157f0f-f62e-7202-aef7-334e6da3c912.png)

Mac用のvscodeのダウンロードをします。

![Screen Shot 2022-02-05 at 10.34.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/093956f9-7fdd-2888-58c1-0603cf22e289.png)

ダウンロードしたvscodeを起動できたらOKです。

vscodeを起動すると、開発者になったような気がしてきますね！

ここからの操作はターミナル上で行うのですが、vscodeからターミナルを起動することもできるので、こちらで操作を行なっていきます。

こちらからnew terminalでターミナルを開き

![Screen Shot 2022-02-05 at 10.46.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/d9f8cb6a-07c4-c9b5-8349-5fa3ecb7684c.png)

このようにターミナルにアクセスできたらOKです！

![Screen Shot 2022-02-05 at 10.46.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/214cb3a6-f5b5-6d60-0486-71bca99e3b4a.png)

### homebrewのインストール

パッケージ管理ツールのhomebrewをインストールしていきます、今回セットアップするnodejsは直接インストールすることもできるのですが、homebrewのようなパッケージ管理ツールからインストールする方が管理がしやすくて良いのでは、と思っています。

https://brew.sh/

下記を実行します。

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

**下記の実行が終わったタイミングでメッセージをよく見ると、次にこのコマンドを実行してください、と指示されることがあるのでその通りに実行します。**

これでhomebrewの準備は完了です。

### nvmのインストール

nodejsのバージョン管理ツールである[nvm](https://github.com/nvm-sh/nvm)をインストールしていきます。nodejsにはさまざまなバージョンがあり、nvmを使用すると、バージョンの管理がやりやすいです。

https://formulae.brew.sh/formula/nvm

ターミナルで下記を実行します。

```
brew install nvm
```

**こちらもbrewと同様インストール後のメッセージをよく見ると、次にこのコマンドを実行してください、と指示されることがあるのでその通りに実行します。**

これでnvmの準備は完了です。

### nodejsのインストール

nodejsにはさまざまなバージョンがあります。チームやプロジェクトによって使用するnodejsのバージョンが異なるので、可能であれば先に確認しておくといいと思います。ざっくり奇数は開発版、偶数は安定版なので、初めての場合特に指定がない場合は偶数を選ぶのがいいのではと思います

バージョンの状況については[こちら](https://github.com/nodejs/Release)に詳細があります。

![Screen Shot 2022-02-05 at 10.57.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258956/8e8797f2-7eee-5ca7-1aba-ce046a358167.png)

どのバージョンを選べばよくわからない場合は、偶数のltsを指定してinstallしましょう。

```
nvm install --lts
```

僕の環境では下記のようにnode v16.13.2がインストールされました。

### yarnのインストール

nodeをinstallするとnpmというnodejsのパッケージ管理ツールもセットでついてくるのですが、僕のチームではyarnを使うことが多いのでyarnもセットアップしてきます。

https://classic.yarnpkg.com/en/docs/install#mac-stable

下記でyarnをインストールします。

```
npm i -g yarn
```

これでセットアップは完了です！お疲れ様でした！
UIButtonを画面の最前面に出す!!

##はじめに

UIButtonを配置したものの、画面の背面に設置されてしまい、どうやったら前面に出すのか迷ってしまったので、解決方法を記述しておきます。
- - - 
###結論から

```swift
view.bringSubviewToFront(UIButtonの名前)
```
を実行すれば、UIButtonが前面に出てくれます。

以下に具体例を載せておきます。

###TableViewを配置

コードでUITableViewを記述しています。

```swift
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    let item = ["cell 1","cell 2","cell 3","cell 4","cell 5","cell 6","cell 7","cell 8","cell 9","cell 10",]
    
    override func viewDidLoad() {

    override func viewDidLoad() {
        super.viewDidLoad()
        let tableView = UITableView(frame: self.view.bounds, style: .plain)
        tableView.delegate = self
        tableView.dataSource = self
        
        view.addSubview(tableView)
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return item.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        cell.textLabel?.text = item[indexPath.row]
        return cell
    }
}
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2428088/381c4a7a-1282-08ce-d46f-a890650368ac.png" width=40%>

###UIButoonの配置

```swift
import UIKit


class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    let item = ["cell 1","cell 2","cell 3","cell 4","cell 5","cell 6","cell 7","cell 8","cell 9","cell 10",]
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let button = UIButton(type: UIButton.ButtonType.system)
        button.setTitle("Button", for: UIControl.State.normal)
        button.sizeToFit()
        button.center = self.view.center
        let tableView = UITableView(frame: self.view.bounds, style: .plain)
        tableView.delegate = self
        tableView.dataSource = self
        
        view.addSubview(button)
        view.addSubview(tableView)
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return item.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
        cell.textLabel?.text = item[indexPath.row]
        return cell
    }
}
```

このままでは、UIButtonが背面に設置されたままなので、最初に紹介した

```swift
view.bringSubviewToFront(button)
```

を

```swift
view.addSubview(tableView)
```
の下に記載すればOKです!!


<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2428088/09149d1c-cb95-088d-c255-e3c89fc2b33d.png" width=40%>

###さいごに

view.addSubview(button)
view.addSubview(tableView)
の順番を逆にする事でもUIBUttonを前面に出す事が出来ます。

addSubview()メソッドはデフォルトで最前面に出力する事が出来るからです。

ちょっとした事ですが、知っているのといないのとでは結果が全然変わります。
と、自分に言い聞かせながらコードを書いていこうと思います。
ネットワークの知識の整理

# OSI参照モデル

| 層 | 名称 | 規格（プロトコル） | 概要  | 利用例 |
|:---|:-----------|:------------|:------------|:------------|
|7層 | アプリケーション層  | HTTP,FTP,DNS,SMTP,POPなど|個々のアプリケーション |www,メール|
|6層 | プレゼンテーション層| SMTP,FTP,Telnetなど      |データの表現形式 |HTML |
|5層 | セッション層       | TLS,NetBIOSなど          |通信手段・接続の手順 |HTTPS |
|4層 | トランスポート層   | TCP,UDP,NetWare/IPなど   |エンド間の通信制御 |TCP,UDP |
|3層 | ネットワーク層     | IP,ARP,RARP,ICMPなど    |データを送る相手を決め最適な経路で送信 |IP,ICMP,IPsec,ARP 、L3スイッチ、ルータ|
|2層 | データリンク層     | PPP,Ethernetなど        | 隣接する機器同士の通信を実現|Ethernet,PPP,PPPoE、フレームリレー、ブリッジ、L2スイッチ |
|1層 | 物理層             | RS-232,UTP,無線        |物理的な接続、電気信号 |UTPケーブル,光ファイバーケーブル、無線、電話線 |			


# データリンク層

[データリンク層とは？OSI参照モデルを図解でわかりやすく解説](https://www.seraku.co.jp/tectec-note/industry/data-link-layer/)

+ 特定のMACアドレスにのみ通信するためのルールを決めている。: データーリンク層は目的のノードにのみデータを届ける役割がありますが、特定の宛先にのみ送るためには宛先が必要です。その宛先として使われるのがMACアドレスです。
+ 通信中のデータが壊れていないかのチェックが可能。
+ データリンク層で動作する主な機器 : スイッチ（スイッチングハブ、L2スイッチ）

## データリンク層の主な役割

+ 媒体や送信相手にデータを送り出すときのタイミング

同一のネットワークであるイーサネットLAN内で端末からデータを送信する際、データ同士が衝突しないように、データを送信するタイミングを確認して送信します。

+ 伝送中に発生したエラーの検出と対処方法

データを送信中にエラーが発生した際はエラーの認識をします。そしてどのような対処をするかを決めています。

# ネットワーク層

[ネットワーク層とは？OSI参照モデルを図解でわかりやすく解説](https://www.seraku.co.jp/tectec-note/industry/network-layer/)

+ IPアドレスを認識して通信を行っている。
+ 適切な経路選択ができるように様々なルールが決められている。
+ ネットワーク層で動作する主な機器(ルータやL3スイッチ)

L3スイッチはL2スイッチと違い、IPアドレスを処理することができルーティング（経路選択）が行えます。また、ルータよりもポート数が多いことが挙げられます。ルーティングの処理についても、ルータはソフトウェアで処理しますがL3スイッチはハードウェアで処理を行うことで高速に処理することができます。

## ネットワーク層の主な役割

+異なるネットワーク間の通信

データリンク層で接続されているネットワーク同士を相互に接続して、異なるネットワーク間での通信を行えるようにします。

+複数のネットワーク間での通信

送信元から宛先までの通信経路で複数のネットワークが存在する場合などは、各ネットワーク間にあるルータ（機器）がルート（経路）を選択してバケツリレーのようにデータの転送を行っている。

ネットワーク層のPDU（protocol data unit）は、パケットであり、構造を規格として定めています。