OmniAICreator/Qiita-1.07M huggingface dataset:
jpackageコマンドでfat.jarのインストーラを作成する

jpackageコマンドでfat.jarのインストーラを作成する方法を示します。

# ① 事前準備

Windows環境でjpackageを利用する場合、WiX 3.0が必要です。リリースページからwix311-binaries.zipをダウンロードして、PATHを通しておきます。

https://github.com/wixtoolset/wix3/releases

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/597cc2d6-2e5f-e487-8c5c-84101b416dbf.png)

# ② jpackageコマンドの実行

ディレクトリ構成は以下の通りです。HelloWorld-0.0.1-SNAPSHOT.jarが対象のfat.jarです。

```
build
├─ exe
└─ lib
    └ HelloWorld-0.0.1-SNAPSHOT.jar
```

jpackageコマンドを実行します。

- インストール先のフォルダを指定するダイアログ
- ショートカットへの追加するかどうかを選択するダイアログ
- スタートメニューへの追加するかどうかを選択するダイアログ

以上がそれぞれ必要なので、win-dir-chooser・win-shortcut・win-shortcut-promptオプションを指定します。

```
jpackage --type exe ^
         --win-menu ^
         --win-dir-chooser ^
         --win-shortcut ^
         --win-shortcut-prompt ^
         --name SpringBootApp ^
         --input build\lib ^
         --dest build\exe ^
         --main-jar HelloWorld-0.0.1-SNAPSHOT.jar
```

jpackageコマンドの実行に成功すると、destオプションに設定したフォルダにインストーラのexeファイルが作成されているはずです。

```
build
├─ exe
│  └ SpringBootApp-1.0.exe
└─ lib
    └ HelloWorld-0.0.1-SNAPSHOT.jar
```

# ③ exeファイルの実行

exeファイルを実行すると、インストーラが起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/cccc39f9-db46-fe4d-0378-f9f13d207b27.png)

win-dir-chooserオプションを指定したので、インストール先のフォルダを指定することが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/e09464a2-98ed-794a-3043-05f6d49a146c.png)

win-shortcut・win-shortcut-promptオプションを指定したので、スタートメニュー・ショートカットへの追加するかどうかを選択できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/70cbc5f9-4abf-e300-6c90-96cbcb0be187.png)

「インストール」ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/c7d1ab9d-6e5d-1ab3-95cc-2e2ae98db7c3.png)

インストールが完了したことを確認して、「完了」ボタンを押下します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/cfdadaf7-ade6-0f1b-260c-93b3bc85e2d1.png)

# ④インストール後の確認

デスクトップを確認すると、ショートカットが作成されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/63c9a780-9a80-2ddc-9315-34cc8fe55160.png)

スタートメニューにも追加されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/cbd2490c-0cd0-9c46-010a-0bd2e22c9d5b.png)

ショートカットもしくはスタートメニューから実行すると、アプリケーションが起動することが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/e4caff3f-ae00-b2ac-6628-253a01021c79.png)

# 環境情報

```
D:\>javac -version
javac 21-beta

D:\>java -version
openjdk version "21-beta" 2023-09-19
OpenJDK Runtime Environment Temurin-21+35-202309042131 (build 21-beta+35-ea)
OpenJDK 64-Bit Server VM Temurin-21+35-202309042131 (build 21-beta+35-ea, mixed mode, sharing)
```
[React] Vite - コンポーネントや関数を他ファイルから絶対パスでインポートする方法

# はじめに
現在プロジェクトで実装を行っているのですが、よく他メンバーが書いたコードを読むことがあります。
その際に、インポートされているモジュールがどこにあるファイルなのかがパッと分かりずらいことがありました。

というわけで、今回はより可読性を上げるという目的で、他ファイルに定義された関数等を絶対パスでインポートできるようにする方法を調べましたので、備忘録をここで残したいと思います。

# 実践
今回は`Vite` を使って簡単に方法を記載したいと思います。

## プロジェクトの立ち上げ
```
$ yarn create vite
? Project name: > sample-project
? Select a framework: > React
? Select a variant: > TypeScript + SWC
```
```
$ cd sample-project
```

## 設定
以下のファイルを編集します。
 - `tsconfig.json`
 - `vite.config.ts`

 ### tsconfig.json
`sample-project/`配下にある、`tsconfig.json`を以下のように編集
```json
{
    "compilerOptions": {
        ...
        ...
        
        ↓追記
        "baseUrl": ".",
        "paths": {
            "@/*": ["./src/*"]
        },
        
        ...
        ...
    }
}
```

### vite.config.ts
`sample-project/`配下にある、`vite.config.ts`を以下のように編集
```typescript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";

// https://vitejs.dev/config/
export default defineConfig({
    plugins: [react()],
    // ↓追記
    resolve: {
        alias: {
            "@": "/src",
        },
    },
});
```

## 絶対パスでの書き方
ここでは、絶対パスと相対パスの書き方を比べてみて、どちらがより可読性が高いかを確認してみます。
今回は以下のようなディレクトリ構造で試してみたいと思います。
```
src/
├── App.css
├── App.tsx
├── assets/
│   └── react.svg
├── components/   ← 追加
│   └── Header/
│       └── index.tsx
├── feature/      ← 追加
│   └── login/
│       └── constants/
│           └── user.ts
├── index.css
├── main.tsx
└── vite-env.d.ts
```

`Header/index.tsx`に`constants/user.ts`内の定数をそれぞれの方法でインポートしていきたいと思います。
(なぜ`Header`なのかは気にしないでください。)
### 相対パスでインポート
```typescript
// constants/user.ts
export const USER_NAME = "yolokoki"
```
```typescript
//  Header/index.tsx
import { USER_NAME } from "../../feature/login/constants/user";

export const Header = () => {
    return <>{USER_NAME}</>;
};
```
```typescript
// App.tsx
import { Header } from "./components/Header";

function App() {
    return <Header />;
}

export default App;
```
### 絶対パスでインポート
続いて、先ほど設定した絶対パスでインポートを試してみたいと思います。
```typescript
// constants/user.ts
export const USER_NAME = "yolokoki"
```
```typescript
//  Header/index.tsx
import { USER_NAME } from "@/feature/login/constants/user";

export const Header = () => {
    return <>{USER_NAME}</>;
};
```
```typescript
// App.tsx
import { Header } from "@/components/Header";

function App() {
    return <Header />;
}

export default App;
```
## 最後に
いかがでしたでしょうか。
インポートする際の`./`や`../../`という部分が全て`@`に変換され、スッキリしたかと思います。

# 終わり
今回は可読性を上げるという目的で他ファイルで定義したものを絶対パスで指定できる方法を紹介しました。
使いどきはそれぞれのプロジェクトに合わせるべきかと思いますが、一つの引き出しとして持っておきたいと思います。
削除ボタン実装【filter】

React学習の際に参考にした削除ボタン実装方法を
備忘録として記載させていただきます。

**今回のファイル構造**

![スクリーンショット 2023-12-30 003504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3648707/2c363a0d-b485-166a-f6ca-119954e9876a.png)


**手順**
```ruby:sidebar.jsx
<button onClick={() => onDeleteNote(note.id)}>削除</button>
```
※アロー関数で記述するのは、リロードした際に発火させない事と引数を取得する為です。
```ruby:App.jsx
  const onDeleteNote = (id) => {
    const filterNotes = notes.filter((note) => note.id !== id);
    setNotes(filterNotes);
  }
```
フィルター関数を使用して、
取得したidと一致しないidを削除する命令文を記述していきます。
```ruby:App.jsx
  return (
    <div className='App'>
      <Sidebar
       onDeleteNote={onDeleteNote}
      />
    </div>
  );
```
次にプロップスで渡します。
```ruby:sidebar.jsx
const Sidebar = ({onDeleteNote }) => {…}
```
最後に受け取りの記述をして完了です。
Python株価分析でNo timezone foundとなってしまうエラー対処法


# エラー内容

「　xxxx 」の部分は企業のティッカー（証券コード）が入ります
~~~

1 Failed download:
['xxxxx']: Exception('%ticker%: No timezone found, symbol may be delisted')
~~~

## 問題のコード



書いたコードは下記の通り
~~~
#ダウンロードに必要なモジュールをインストール


from yahoo_fin import stock_info
import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime

import pickle

import matplotlib.pyplot as plt

start_date = '2015-01-01'
end_date = '2023-12-28'

# Define the tickers
tickers = ["xxxxx", "xxxxx","xxxxx"]

# Download the data
data = yf.download(tickers, period="max", group_by='ticker')

# Check the columns in the downloaded data--
print(data.columns)

# Plot the adjusted close of the tickers
data["Adj Close"].plot(figsize=(10, 7))


~~~

## 原因

よく確認したら、DLできなかった企業は特定の時期より上場から非上場に以前よりなっていました。（つまり公開株ではなくなったので、株価データがない）
そのため、
~~~
end_date = '2023-12-28'
~~~
のところで引っかかったんですね。
私の場合はEnd Dateでしたが、Startdateのところでエラーが出ていたら開始年に何か問題があるはず。

Yahoo Financeや他の金融データ提供元は、廃止された企業の株価データを提供することは通常ありません。廃止や上場廃止となった企業の株式は、一般的に金融データベースから削除されるらしい。

## 解決方法

いつの間にか非上場になっている企業はしょうがないですが比較対象から外しましょう
【環境構築】Reactインストールから実行まで

# はじめに
WindowsでWSL上にインストールしたので残しておきます。

# 事前準備
```
# cURLのインストール
sudo apt-get install curl

# nvmインストール
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/master/install.sh | bash

# インストールの確認→「nvm」と返却されることを確認
# "コマンドが見つかりません" というメッセージが返される場合または何も応答がない場合は、一度閉じて開きなおす
command -v nvm
```

# Node.jsのインストール
```
# Node.js の現在の安定したLTSリリースをインストール
nvm install --lts

#最新版は「nvm install node」でインストール可能

#バージョン確認
node --version
npm --version
```

# Reactインストール
```
# ディレクトリ作成
mkdir ＜ディレクトリ名＞

# 移動
cd ＜ディレクトリ名＞

# Reactインストール
npx create-react-app ＜プロジェクト名＞
```
create-react-appをインストールしますか？と聞かれるので、「y」(yes)でインストールに進む
```
Need to install the following packages:
create-react-app
Ok to proceed? (y)
```

# 確認
エディタで開いてプロジェクトが存在すること確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962167/9f00fe7a-ec97-100c-7d57-667529f1817b.png)

アプリを開始し、 **http://localhost:3000/** で画面が表示されればOK
```
npm start
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2962167/b377702d-84f9-6d09-ae84-8e2c16f63a4c.png)


# 参考
[Linux 用 Windows サブシステムに React をインストールする
](https://learn.microsoft.com/ja-jp/windows/dev-environment/javascript/react-on-wsl)
Cursor（AI搭載エディター）は記事を書くときにも有用なのでは！？

https://cursor.sh/

Cursorを使っていてふと気づいたのですが、日本語で記事を書くときもCursorで良いんじゃないかなと。

Cursor自体の紹介や使い方は色々なところで紹介されていますが、
**RULES FOR AI** にこんな風に書いたりすることで、GPTsのような使い方をしたり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34731/9c984e4f-9f17-614e-deba-0e5b0e3e0a93.png)

その上でテーマを与えて骨子を作成してもらったり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34731/e7afe2cf-8f2c-f9df-119b-d1cc2f34e84b.png)

DOCS機能で学習させた上で記事の生成やChatをしたり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34731/ad862a48-16f1-becd-6471-39f73465f201.png)

そんな使い道もあるのかもしれないなと思ったので備忘録として残しておきます。
wslコマンド

wslを操作する
PowerShellターミナルで実行する
## wslの環境の一覧を表示
~~~ps
wsl --list --verbose
~~~
実行結果
~~~ps
> wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu          Stopped         2
  IjiijiUbuntu    Stopped         2
  Ubuntu-20.04    Running         2
~~~
## wslの中に入る
~~~
wsl -d <環境名>
~~~
~~~
wsl -d Ubuntu-20.04
~~~
## wslの現在の環境をエクスポート
~~~
wsl --export <環境名> <ファイル名>.tar
~~~
上記実行結果のUbuntu-20.04を書き出すときは以下のようになる。
~~~ps
wsl --export Ubuntu-20.04 example.tar
~~~
## wslの環境をインポート
~~~px
wsl --import <新しい環境名> <インストールディレクトリ> example.tar
~~~
~~~ps
wsl --import newEnvName envDir example.tar
~~~
【flutter】"..."（スプレッド演算子）について

## はじめに
flutterのコードを読んでいるとよく``state = [...state, toDo]``とうふうに、謎の"..."が登場します。これは``スプレッド演算子``というもので、活用できるととても便利な機能です。私自身、何度勉強しても忘れてしまうのでメモしようと思います。

## スプレッド演算子とは
スプレッド演算子とはリストやマップなどの要素を展開して新しいリストやマップを作るための演算子です。

image
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2984024/3ddfed27-eeea-d265-3fd9-62f3397849ac.png)

では、実際に例を交えながら見ていきましょう。

## リストの要素の結合
```dart
List<int> list1 = [1, 2, 3];
List<int> list2 = [4, 5, 6];

List<int> combinedList = [...list1, ...list2];

print(combinedList);
// [1,2,3,4,5,6]

```
このコードでは、...演算子を使用してlist1とlist2を結合し、新しいcombinedListを作成しています

## マップの結合
```dart
Map<String, dynamic> map1 = {'a': 1, 'b': 2};
Map<String, dynamic> map2 = {'c': 3, 'd': 4};

Map<String, dynamic> combinedMap = {...map1, ...map2};

print(combinedMap);
// {'a': 1, 'b': 2, 'c': 3, 'd': 4}
```
このコードでは、...演算子を使用してmap1とmap2を結合し、新しいcombinedMapを作成しています

## リストやマップの更新
スプレッド演算子はリストやマップの更新にも適しています。
```dart
List<int> originalList = [1, 2, 3];
originalList = [0, ...originalList, 4, 5];

print(originalList);  // [0, 1, 2, 3, 4, 5]

```

## 最後に
リストやマップの結合、更新がたった"..."だけでできてしまう。スプレッド演算子は非常にシンプルで強力な機能ですね。だからこそ活用できたらカッコいい。どんどん使っていきましょう。
Shift15Mの論文輪読　1章（定義）

# はじめに
この記事は株式会社ZOZOが論文で公開したものを輪読しているものになります。

https://arxiv.org/abs/2108.12992

この論文でのデータセットであるShift15Mとは
ファッションアプリ「IQON」に投稿されたコーディネートを基に構成された大規模データセットです。本データセットは、IQONのサービス提供期間である2010年から2020年までに投稿されたコーディネート約255万件のほか、これらのコーディネートを構成する約1,500万件のアイテムに関する特徴量、アイテムカテゴリに関するデータやコーディネート投稿への「いいね」数などの関連データも含みます。
（以下参照）

https://corp.zozo.com/news/20210902-zozo_technologies-18444/

# 1.セット間マッチングとは

2つの異なるアイテムのセットを、何らかの基準に基づいてマッチングさせること
例えば、ファッションの文脈では、衣服アイテムのセットをマッチングすることで、服の完成度を測定するために使用することができる。
画像のような高次元アイテムの文脈では、従来の方法ではそのようなアイテムのセットを比較してマッチングすることは困難であるため、セット間マッチングは重要である。
この問題を解決するためにニューラルネットワークが適用されてきたが、ほとんどの機械学習ベースのアプローチは、訓練データとテストデータが同じ分布に従うことを前提としており、これは実世界のシナリオでは必ずしも真実ではない。

そこでSHIFT15Mデータセットの出番と述べている。

SHIFT15Mデータセットは、分布シフトの下でセット間マッチングモデルを評価するために使用できる。

そもそも分布シフトとは
訓練データとテストデータの分布の差異のことをさしている。

# Shift15Mデータセットの有用性

SHIFT15Mデータセットは、分布シフト下でのセット間マッチングモデルを評価するための貴重なリソースを提供することにより、訓練データとテストデータが同じ分布に従うと仮定する機械学習ベースのアプローチの限界に対処する。
このデータセットは、実世界のアプリケーションで一般的に観察される様々なタイプのデータセットシフトをシミュレートしており、2010年から2020年までの10年間に渡り、ユーザー行動の変化、ファッショントレンド、文化的嗜好などの要因から生じるシフトを網羅している。
これにより、研究者はさまざまなタイプやサイズのシフトを実験することができ、訓練/評価/テストの分割プロセスが自動化され、さまざまなシフトシナリオの下でのモデルの性能評価が容易になります。
SHIFT15Mデータセットは、実際の流通シフトを反映したデータセットを提供することで、より現実的で困難な条件下でのセット間マッチングモデルの評価を可能にする。

# 理想な形

トレーニングデータとテストデータの間で入力変数xに対する出力変数yの条件付き確率が同じである場合は望ましい現象である
ptr(x) = pte(x)で
ptr(y|x) = pte(y|x)が成り立つことは、モデルが共変量シフトに対して頑健であり、トレーニングデータで学習した条件付き確率分布がテストデータにおいても有効であることを示唆しています。このような場合、モデルの汎化性能が向上し、実世界のデータに対して信頼性の高い予測を行うことが期待されます。

## 実際の問題点
ファッション分野における共通現象
トレンドの変化
これらの現象は、ファッションの色合いなどの年間のトレンド変化から、夏から冬への季節的なトレンド変化まで、様々なスケールで観察される。
これらがある限り、訓練データとテストデータが同じであるということはほぼ実生活の中ではない。


# ３つの定義

## 共変量シフト（covariate shift）について

共変量シフトとは、トレーニングデータとテストデータの間で入力変数の分布が異なるという仮定を指します。
具体的には、条件ptr(x) ≠ pte(x)が成り立ち、かつp(y|x) = ptr(y|x) = pte(y|x)が成り立つ場合に、共変量シフトが発生しているとみなします。言い換えると、入力変数xの分布が異なる一方で、条件付き確率p(y|x)が変化していない場合に、共変量シフトが発生していると定義されています。

言葉で説明すると、
購入するアイテムが訓練データとテストデータで特徴量が同じなのに、それを購入した条件の下で購入するものが同じである現象が共変量シフトであると言っている。

## ターゲットシフト
ターゲットシフトは、訓練データとテストデータの出力変数の分布が異なる場合に発生します。

Definition 1.2では、ターゲットシフトが発生している場合の条件を示しています。具体的には、訓練データとテストデータの出力変数の分布が異なる場合、つまりptr(y) ≠ pte(y)である場合、かつ、出力変数yが与えられた条件下での入力変数xの条件付き確率分布が訓練データとテストデータで異なる場合、つまりp(x|y) ≠ ptr(x|y) = pte(x|y)である場合、ターゲットシフトが発生していると考えられます。

先ほどの共変量シフトの逆バージョンみたいな感じですかね

## 一般的なデータセットシフトについての定義

この定義では、データセット全体の変数をいくつかの部分集合に分割し、それぞれの部分集合における条件付き確率分布の変化に注目しています。

具体的には、Zを不変の変数（immutable variables）の集合、
Wを変動可能な変数（mutable variables）の集合、
VをZとWの両方に含まれない残りの従属変数（dependent variables）の集合と定義します。
このような変数の分割により、ptrの因数分解が以下のように定義されます。
ptr (v|w, z)ptr (w|z)ptr (z)

ptr (v|w, z)ptr (w|z)ptr (z)は、確率変数V、W、Zに関する同時確率分布を表しています。

そして、定義1.3では、訓練データとテストデータの間で一般的なデータセットシフトが発生していると考えられる条件を示しています。具体的には、訓練データとテストデータの間で、変動可能な変数Wが与えられた条件下での不変の変数Zの条件付き確率分布が異なる場合、つまりptr(w|z) ≠ pte(w|z)である場合、一般的なデータセットシフトが発生していると考えられます。

ZとWという2つの変数を定義し、これらの変数に基づいてデータセットシフトを定義しています。この定義は、他のデータセットシフトを一般化するものであり、
例えば、Z = ∅ および W = X とすると、
これは共変量シフトに対応します。


# 次の展望
次は2章から説明していきたいと思います。
誤植があればコメントいただけると幸いです。。

年末年始の休日にすべて読めるかわかりませんが、
楽しみながら読んでいきたいです。
【TailwindCSS】カスタム修飾子を登録する方法

`tailwind.config.js`に以下のように記述することでカスタム修飾子を登録できます。

```tailwind.config.js
let plugin = require('tailwindcss/plugin')

module.exports = {
  // ...
  plugins: [
    plugin(function ({ addVariant }) {
      addVariant('third', '&:nth-child(3)')
    })
  ]
}
```
MacOSを快適にしてみよう#2


前回の記事からの続編です。

https://qiita.com/Code-999waltz/items/f37a5994c6da55ac3a61

操作の効率を向上させるために役立ついくつかのソフトウェアやツールがあります。以下は、効率向上のために役立ついくつかのカテゴリとその代表的なツールです。

### 1. **キーボードショートカットツール:**
   - **Alfred:** https://www.alfredapp.com/
       - Spotlightより高機能なランチャーアプリ。キーボードショートカットを使ってアプリやファイルを素早く起動できます。
   - **Quicksilver:**https://qsapp.com/download.php
       -  アプリやファイルへのアクセスを高速化するランチャーアプリ。

### 2. **ウィンドウ管理ツール:**
   - **Magnet:** https://apps.apple.com/jp/app/magnet-%E3%83%9E%E3%82%B0%E3%83%8D%E3%83%83%E3%83%88/id441258766?mt=12
       - ウィンドウを簡単に整列させ、デスクトップ上でウィンドウを効果的に管理できます。
   - **Spectacle:** キーボードショートカットを使ってウィンドウをタイリング配置することができるユーティリティ。
   - **Shiftit:** https://github.com/fikovnik/ShiftIt/releases
    

### 3. **クリップボード拡張ツール:**
   - **CopyQ:** クリップボードを管理し、過去のコピー履歴にアクセスできます。
   - **Alfred (Powerpack機能):** クリップボード履歴の追跡やスニペットの管理ができます。

### 4. **タスク管理ツール:**
   - **Todoist:** タスクを管理し、プロジェクトの進捗を把握するのに役立つ。
   - **Notion:** タスク管理、ドキュメント作成、プロジェクト管理など多様な機能を統合したツール。

### 5. **自動化ツール:**
   - **Keyboard Maestro:** キーボードとマウスの動作を自動化し、複雑なワークフローを作成できます。
   - **Automator:** macOSに組み込まれている自動化ツール。簡単なスクリプトやワークフローを作成できます。

### 6. **メモリ管理ツール:**
   - **CleanMyMac:** 不要なファイルを探し、メモリを最適化してシステムのパフォーマンスを向上させます。

### 7. **ブラウザ拡張:**
   - **Browser Extensions (例: OneTab):** ブラウザでのタブ管理を改善し、リソースの効率的な使用をサポートします。

これらのツールは、作業効率を向上させる一助となりますが、個人の作業スタイルや好みによって異なる場合があります。必要に応じていくつか試して、自分に合ったものを見つけることをお勧めします。
Unityroomの画面サイズが崩れてしまう時にチェックしたほうが良いこと

今回はUnityroomにゲームを投稿したときに画面レイアウトが崩れる問題に対する対処法の一つを説明しようと思います。

以前私はUnityroomの画面サイズを制作時に設定したときと同じサイズにしたのに上手く反映させることができませんでした。その時の自分が試したことを以下に示すので同じ問題で悩んでいる方の役に立てば幸いです。

# Canvasの設定
Unityを開いてすべてのシーンにあるCanvasの設定を以下の**Scale Width Screen Size**に変更し、Reference Resolutionのサイズをビルドする予定の画面サイズに変更します。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554505/053f70ce-b888-ed0d-66cb-b9ad3024b18e.png" >
またScreen Mathch ModeをExpandに設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554505/2e9d9f4a-aa54-ccc4-065f-a4ac9a358b90.png)

# Build settingsのPlayer setting
 Build settingsからPlayer settingに入り以下の画像のように画面サイズを入力してください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3554505/d4841883-8209-c1af-21e3-e443641d78e0.png)

これでズレが解消されると思います。

# ブラウザのズームで調整
以前ゲームを投稿して画面ずれにあったという話をしましたがブラウザのズーム機能で画面を引いて見てみると画面はずれておらず変に拡大している状態だったことがありました。自分のブラウザ環境のせいでずれて見えることもあることが分かったので以後ズームでの拡張で本当にずれているかを確認しています。
# おまけ
私は大学生で現在Unityroomでゲームをいくつか公開しています。もしよろしければ遊んでみてください！

https://unityroom.com/games/dungeondungeon

https://unityroom.com/games/000001111100000

これからもゲーム制作やっていきます！
MacOSを快適にしてみよう #1

MacBookの設定やインストールすると便利なアプリ

### MacBookの基本的な設定:

1. **システムアップデート:**
   定期的にシステムアップデートを確認し、最新のセキュリティや機能の更新を取得しましょう。[Apple メニュー] > [ソフトウェアアップデート]から確認できます。

2. **バックアップ:**
   Time Machineなどを使用して、定期的にデータをバックアップしてください。万が一のデータ損失に備えます。外部ストレージも可能使用し始めて３ヶ月後あたりから。

3. **セキュリティ設定:**
   セキュリティとプライバシーの設定を確認し、必要に応じてファイアウォールやGatekeeperを有効にします。

4. **トラックパッドやマウス設定:**
   [システム環境設定] > [トラックパッド]や[マウス]から、自分の好みに合わせた操作感を設定できます。

### おすすめのアプリ:

1. **ブラウザ:**
   Safariがデフォルトで利用可能ですが、Google ChromeやMozilla Firefoxなども選択肢です。

2. **メールクライアント:**
   Apple Mail以外のメールクライアントを好む場合は、AirmailやThunderbirdなどがあります。

3. **オフィススイート:**
   Microsoft Officeや、無料で利用できるGoogle Workspace（Google ドキュメント、スプレッドシートなど）を検討してみてください。

4. **メモ管理:**
   Apple Notes、Evernote、Microsoft OneNoteなど、使いやすいメモアプリを導入すると便利です。

5. **クラウドストレージ:**
   Dropbox、Google Drive、Apple iCloudなどを使用してファイルをクラウド上で同期・保存できます。

6. **セキュリティアプリ:**
   信頼性のあるアンチウイルスソフトウェアを検討して、Macをセキュアに保ちましょう。

7. **メディアプレーヤー:**
   VLCやIINAなど、さまざまなメディア形式に対応したプレーヤーをインストールすると便利です。

8. **写真編集:**
   Adobe LightroomやPixelmatorなど、写真の編集に特化したアプリを検討してください。

9. **コミュニケーション:**
   SlackやMicrosoft Teams、Zoomなど、ビジネスやプライベートのコミュニケーションに利用できるアプリも重要です。

10. **開発ツール:**
   開発者の場合はXcodeやVisual Studio Codeなどをインストールしておくと良いでしょう。

次は効率アップに関する情報を載せます。
指定されたディレクトリ以下のすべてのファイルのパスを再帰的に取得（Python）

```python
def get_file_list_recursive(directory_path):
  """
  指定されたディレクトリ以下のすべてのファイルのパスを再帰的に取得する

  Parameters:
  - directory_path (str): ファイルリストを取得するディレクトリのパス

  Returns:
  - list: ディレクトリ以下のすべてのファイルのパスを含むリスト
  """
  file_list = []
  for root, dirs, files in os.walk(directory_path):
      for file in files:
          file_list.append(os.path.join(root, file))
          
  return file_list
```
【環境構築】WSLインストール

1\. 管理者権限でpowershell等を開き、以下のコマンドを実行する。
```
wsl --install
```
2\. PC再起動
　
3\. Windows上にアプリとして「Ubuntu」がインストールされているので、
　起動して初回設定（ユーザ名やパスワード）を実施
 
4\. 更新する
```
sudo apt update
sudo apt upgrade
```
GitHubで表示される英語について

# GitHubで表示される英語について
久しぶりにGitHubを触っていたら、ふとリポジトリのPublicとPrivateを変更したいという衝動に駆られて対応していた時に表示されたメッセージダイアログが気になったので、ネタ更新のため追記します。

■環境
Windows :Windows10

## 表示されたメッセージ
以下の通り。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223945/84587607-a1d8-6c04-2e6e-dec24fe503e0.png)

## １行目
(1) Making this repository private could permanently erase these counts by removing stars and watchers associated to users that will no longer have access to this repository;

このリポジトリをプライベートにすると、アクセスできなくなったユーザーに紐づいた星の数やウォッチャー数が削除されます。
(要するに、「星とウォッチャー数が減りますよ」ということかな)

## 2行目
(2) If you decide to make this repository public in the future, it will not be possible to restore these stars and watchers and this will affect its repository rankings.

もし将来的にリポジトリをパブリックにしたとしても、星の数とウォッチャー数を元に戻すことはできず、リポジトリのランキングに影響します。
(要するに、「一度プライベートにすると、元に戻りませんよ」ということかな)

## 3行目
(3) Dependency graph and Dependabot alerts will remain enabled with permission to perform read-only analysison this repository. Any custom dependabot alert rules ill be disabled unless GitHub Advanced Security is enabled for this repository.

依存グラフや依存ボットアラートは、読み取り専用で利用可能です。
このリポジトリに対して GitHub Advanced Security が有効になっていない限り、カスタム依存ボットアラートルールは無効になります。

## 4行目
(4) Code scanning will become unavailable.
コードスキャニングは利用できなくなります。

## 5行目
(5) Current forks will remain public and will be detached from this repository.
現在のforkはパブリックになり、現在のリポジトリから出タッチされます。


---
うーん、翻訳したけど、何のことなのか良く判らない...。
もう少し理解できたら、また更新したいと思います。
Visual Studio Code のコピー時に余分な設定までコピーされる

Visual Studio Codeにて作成した文字をコピーした際に、余分な設定までコピーされたのでmacの設定解除方法を記載する。

1.以下画像の下部に表示されている①の歯車アイコンを押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657329/f5930e9c-ed90-aad8-11c7-930e60fa7b8e.png)

2.Settingsを押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657329/adc9d6eb-2e0c-a9f2-a5ca-dcb813a6d2ca.png)

3.検索ウィンドウへ「Copy With Syntax Highlighting」を入力してチェックを外す。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3657329/b452c9b3-9515-6532-8b3f-efcceac5a2c7.png)
Hugging Face 画像生成

Hugging Faceのstable-diffusion-xl-base-1.0を使ってみました。

![スクリーンショット 2023-12-29 23.01.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102001/8f0ed37a-4657-05d1-daca-e169f27dfa93.png)

<h2> 1 準備 </h2>
Google Colabで”ファイル/ノートブックを新規作成”し、
"ランタイム/ランタイムのタイプを変更"で、"T4 GPU"を選択します。

![スクリーンショット 2023-12-29 22.50.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102001/294f9485-0a49-fd6d-eb07-33de0740527c.png)

<h2> 2 インストール </h2>
diffusersをインストール。<p/>
加えて、invisible watermark、transformers、accelerate、safetensorsをインストール。

```
!pip install diffusers --upgrade
!pip install invisible_watermark transformers accelerate safetensors
```

<h2> 3 コードを記述 </h2>
DiffusionPipelineに、"stabilityai/stable-diffusion-xl-base-1.0"を指定したコードを実行すると、ベースモデルを使った画像が生成されます。

画像は、Google Driveに保存します。

```
from diffusers import DiffusionPipeline
from accelerate.utils import write_basic_config
import torch

from google.colab import drive

write_basic_config()
drive.mount("/content/drive")

pipe = DiffusionPipeline.from_pretrained("stabilityai/stable-diffusion-xl-base-1.0", torch_dtype=torch.float16, use_safetensors=True, variant="fp16")
pipe.to("cuda")

prompt = "An astronaut riding a green horse"
#prompt = "zebra in Africa"

image = pipe(prompt=prompt).images[0]
image.save("/content/drive/MyDrive/outputimage.png")
```

<h2> 4 実行 </h2>
コードを実行すると、Google Driveにpromptで指定した画像が出力されます。

![スクリーンショット 2023-12-29 23.16.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102001/2061efd2-c47d-ccfe-b9cd-3f0f026dbdc4.png)
GitLabよ、この得体のしれないソースコードから、仕様書をつくりたまえ

# GitLab Duo Chatを使うと、ソースコードから日本語で「仕様書」を書き起こせます

世の中、おかしなことがあるもので、ソースコードだけが目の前にあり、仕様書がない、なんてことがあります。
たとえば、オープンソースのソースコードであったり、ずーっと社内で使われている、だれが書いたかわからないコードであったり・・・。

ソースコードを読めばすべてが分かりますが、いちいち読んでいられないこともあります。
たとえば、このコードは「OOOをやるコード」ということだけでもすぐに確認できれば、全体像を把握するスピードが飛躍的に早くなります。

そう、なんでもかんでも「ゼロから理解」するのは、疲れます。
そんなときに試してみていただきたいのが、「GitLab Duo Chat」。
これを使うと、なんと、ソースコードから仕様書を書き起こすことが、ぱぱっとできてしまいます。しかも日本語で。(正式にはきちんと言っておりませんが、日本語で書かせることができちゃっている、というのが正しい回答です)

## Step 1. GitLab Ultimateの環境を手に入れる

みなさんは、GitLabのAI機能をご存知でしょうか？ 無償版のGitLab CE (Community Edition)では使うことができないのですが、有償版のGitLabでは使うことができます。

少し残念なのですが、https://about.gitlab.com/ja-jp/pricing/ にあります、Premiumではなく、Ultimateであれば、触ることができます。お金に余裕がある方はぜひUltimateを。余裕がない方は、ぜひUltimateのTrialを試してみてください。

Trialの申し込みの方法はこちら。

https://www.youtube.com/watch?v=Xpsk1zbOpf0&list=PL05JrBw4t0KoG71s-GicbnFpchLDgchyH&index=1

## Step 2.GitLab Duo Chatを動かしてみる

GitLab Ultimateの環境が手に入ったら、次のビデオをみて、GitLab Duo Chatを試してみてください。

まだベータ版なので、動作が不安なのですが、いまの段階でここまで来てるというのがわかります。

いずれ安定すると思いますので、ぜひご期待ください。

https://www.youtube.com/watch?v=XThhhvPQh_0&list=PL05JrBw4t0KoG71s-GicbnFpchLDgchyH&index=4

## ご参考

GitLab の AI機能「GitLab Duo」の一覧は、こちらです。

https://docs.gitlab.com/ee/user/ai_features.html

このページは、頻繁に変更が入っていますので、ぜひ定期的にチェックしてみてください。

プログラミングはやっぱり楽しいですね！

では。
Digispark製AtTiny85のセットアップ

そのうちちゃんとした記事にするのであくまで自分用メモです

## つかうもの
Arduino IDEで

## インストール
1. [File] -> [Preferences]
1. [Settings] -> Additional boards manager URLs:
1. `http://digistump.com/package_digistump_index.json` を入力して右の変なボタン押してインストール
1. ボードとして `Digispark - Default 16.5mhz` をセットする

## 注意点
- USB繋ぎながらだと3&4ピンが使えない
- アップロード時はUSBから外しておいて、「Plug in device now...」「Please plug in the device ...」が出たタイミングでUSB繋ぐ。じゃないとなんかうまくいかない

## Lチカ
シンプルに2ピンとGNDに繋いでます

```c
#define LED_PIN 2

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_PIN, HIGH);
  delay(1000);
  digitalWrite(LED_PIN, LOW);
  delay(1000);
}

```
1年目で学んだ思考法

## 生産性の高さ
### 情報の整理
エンジニアとして働いていると、未知の事象に数多く遭遇する。
事象を理解するために必要なログやコード、システムを抑えた後、
頭の中で言語化したり、ノートにまとめたりして情報整理する。

情報整理を実施することにより、下記のメリットを受ける
①周りの方に簡潔に事象を説明できる
②不明箇所を把握できる
③適切にタスクをこなすことができる
④ムダが作業を減らすことができる

### システムや処理を頭の中でイメージする
クラスの構造や機能の関係性を理解しておくと、バグやエラーが発生した際に、どこでなぜ起きたのかを想像することができるようになり、より効率的に解決できるようになる。

### 事実ベースで動く
デバッグやバグの調査結果が誤っていた場合、認めることは難しいと感じる。
そこで、自分の判断の逆のことを考え、"xxxだとしたら、なにが分かる"と自分に投げかけるようにしている。自分が冷静に考えられるようになり、自然と過ちを認め、事実ベースで動けるようになる。

### 管理者意識を持ち、仕事に取り組む
管理者は忙しいので、私たちの依頼に直ぐに返答もらえないことが多く、待ち時間が発生しやすい。そのため、質問を投げかける前に、自分が管理者だったらどうするかと考えてから、質問するようにしている。

### 品質を高くすることが優先
バグが発生した場合、予定通りにタスクをこなせないことがある。また、検証作業のプロセスが多いと同様のことが起きる。しかし、予定通りに進めるために作業を疎かにしてはいけない。それよりも丁寧に実施することの方が価値がある。不良品をリリースしてしまった場合、多くの方に迷惑をかけてしまう。そのため、品質を高くすることが何より大切だ。
闘魂Elixir ── Advent of code 2023 Day 11 Part 2 を Livebook で楽しむ

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>

<b><font color="red">$\huge{闘魂とは己に打ち克つこと。}$</font></b>
<b><font color="red">$\huge{そして闘いを通じて己の魂を磨いていく}$</font></b>
<b><font color="red">$\huge{ことだと思います}$</font></b>

https://qiita.com/advent-calendar/2023/elixir

## はじめに

@torifukukaiou さんの ~~パク~~ リスペクト記事です

https://qiita.com/torifukukaiou/items/5361b81407b15e7c2f00

Elixir Livebook で Advent of Code 2023 の問題を解いてみます

https://adventofcode.com/2023

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2023/2023_day11_part2.livemd

問題はこちら

https://adventofcode.com/2023/day/11

Part 1 はこちら



## セットアップ

Kino AOC をインストールします

```elixir
Mix.install([
  {:kino_aoc, "~> 0.1.5"}
])
```

Kino AOC の使い方はこちらを参照

https://qiita.com/RyoWakabayashi/items/3d3abcf9134cee4dff05

## 入力の取得

Day 11 の入力を取得します

![スクリーンショット 2023-12-29 12.04.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/4ef51acd-1a73-9d29-fcca-a1e8da062f9f.png)

## 私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

<details><summary>details</summary>

回答用のモジュールです

入力を扱いやすい形にするための `parse` と、回答を作るための `resolve` 関数を持っています

```elixir
defmodule Resolver do
  def parse(input) do
    orig_space =
      input
      |> String.split("\n")
      |> Enum.with_index()
      |> Enum.map(fn {line, row} ->
        line
        |> String.codepoints()
        |> Enum.with_index()
        |> Enum.filter(fn {cell, _} -> cell == "#" end)
        |> Enum.map(fn {_, col} -> {row, col} end)
      end)
      |> Enum.concat()

    max_row =
      orig_space
      |> Enum.map(fn {row, _} -> row end)
      |> Enum.max()

    max_col =
      orig_space
      |> Enum.map(fn {col, _} -> col end)
      |> Enum.max()

    empty_rows =
      0..max_row
      |> Enum.filter(fn target_row ->
        orig_space
        |> Enum.map(fn {row, _} -> row end)
        |> Enum.member?(target_row)
        |> Kernel.!()
      end)

    empty_cols =
      0..max_col
      |> Enum.filter(fn target_col ->
        orig_space
        |> Enum.map(fn {_, col} -> col end)
        |> Enum.member?(target_col)
        |> Kernel.!()
      end)

    orig_space
    |> Enum.map(fn {row, col} ->
      ex_rows = Enum.count(empty_rows, fn empty_row -> row > empty_row end) * 999999
      ex_cols = Enum.count(empty_cols, fn empty_col -> col > empty_col end) * 999999

      {row + ex_rows, col + ex_cols}
    end)
  end

  def resolve(space) do
    space
    |> Enum.with_index()
    |> Enum.map(fn {{src_row, src_col}, src_index} ->
      space
      |> Enum.with_index()
      |> Enum.map(fn {{dst_row, dst_col}, dst_index} ->
        if src_index >= dst_index do
          0
        else
          abs(dst_row - src_row) + abs(dst_col - src_col)
        end
      end)
      |> Enum.sum()
    end)
    |> Enum.sum()
  end
end
```

Part 1 と 99.9% 同じ答えです

単純に追加する行を　 `* 999999` しただけです

</details>

## まとめ

最短経路が出てくるので、てっきり巡回セールスマン問題でも解かされるのかと思っていたら肩透かしでした
Best diagnostic centres in Chennai

 diagnostic centres in anna nagar chennai, offer comprehensive medical tests ranging from blood work, imaging (X-rays, MRI, CT scans), to health screenings. They employ advanced technology, skilled professionals, ensuring accurate diagnostics for diverse medical needs. Conveniently located, these centers prioritize efficiency, accuracy, and patient comfort, serving the community's healthcare requirements.

ecg test lab list in anna nagar west equipped with state-of-the-art facilities. Renowned centers like V.K Medical ECG test labs, Cardiac Care, and Health First Labs offer reliable ECG services. Staffed by experienced professionals, these labs prioritize accuracy, quick turnaround, and patient convenience, ensuring top-notch cardiac diagnostic solutions.

Koyambedu hosts multiple healthcare facilities offering Hysterosalpingography (HSG) testing, a diagnostic procedure assessing female fertility. Esteemed clinics like V.K Medical Centre  and  Women's Health Center specialize in HSG testing in koyambedu. Skilled gynecologists and radiologists perform these procedures using modern equipment, ensuring precision and patient comfort. These centers prioritize confidentiality, providing detailed insights into uterine and fallopian tube conditions crucial for fertility assessment. Located conveniently, they offer comprehensive pre-test guidance and post-test counseling, supporting individuals through the process and emphasizing the importance of this diagnostic procedure in understanding and addressing fertility concerns.

Thirumangalam boasts several cutting-edge Medical Diagnostic Laboratories  in in thirumangalam catering to diverse healthcare needs. Renowned facilities like V.K Medical Centre Diagnostics Health Center offer an array of tests including blood work, imaging (MRI, CT scans), and specialized screenings. Staffed by skilled technicians and experienced doctors, these labs ensure precise diagnostics and quick turnaround times. With a commitment to quality, convenience, and patient care, these centers prioritize accuracy in reports, employ advanced technology, and maintain strict adherence to safety protocols. Situated strategically, they serve as pivotal healthcare hubs in Thirumangalam, addressing the diagnostic requirements of the community effectively
コンテンツ全消ししちゃった話

まだLinuxコマンドについてよく知らなかった頃の話。

# 静的ページのキャンペーンページの運用

静的なWebサイトで定期的にキャンペーンページを作っていました。
キャンペーンごとにディレクトリを切って、そこにHTMLやらCSSやら画像やら全リソースを詰め込んでいました。
キャンペーンが終わるとテンプレートのキャンペーン終了ページに置き換えていました。

このキャンペーン終了作業を手動で行っていたのですが

- テンプレートキャンペーン終了ページリソースで上書き更新
- 容量節約のため不要なリソースを`ls`コマンドで確認しながら一つずつ削除。

という作業を手作業で行っていたのですが、月に数回あるので結構面倒でした。


# シェルプログラミングに挑戦！

ということで、覚えたてのシェルプログラミング知識で、この作業を一発でできるようにしました。
キャンペーンページのフォルダ名を渡せば、一発で終了ページにしてくれる寸法です。

## end.sh

```
#!/bin/bash

# 引数でディレクトリ名を渡す
dir="/var/www/html/$1"

# ディレクトリ内を全削除する
rm -rf $dir/*

# /var/www/endのすべての中身をディレクトリにコピーする
cp -r /var/www/end/* $dir/.
```

# 全消し

「よーし、試しに実行してみるか〜」
「**"bash end.sh"** っと・・・。あ、フォルダ名引数に入れるの忘れた」
「・・・」
「・・・」
「・・・えっ？」

**懸命な皆様ならもうわかると思いますが、"/var/www/html"の中身が全て消えました。**
つまりWebページ全消ししちゃいました。

# 引数は渡さなければ空文字

という簡単なことに全く気づいていなく、**引数を渡さないとどうなるかの想定を全くしていませんでした**。
**"/var/www/html/${空文字}"** は **"/var/www/html/"の中身を全消し** という簡単な事実に気づいていませんでした。

幸い、**subversion**のリソースから復元はできました。

# 教訓

- 引数のチェック、サニタイズは大事。特にシェルは。
  - 何渡されても大丈夫なようにしておく
- テストディレクトリで事前に動作確認する
  - 一発本番環境で動かさない
- 今思うと終了ページ用のディレクトリ作っておいて、そこにリンク貼ればいいだけじゃね？

----

この世のインフラ障害、何気にこのパターン多い気がするので、インフラエンジニアの皆さん気をつけましょう。
ネット注文承りを内製で自動化したぞって話

社内の従業員向け販売の承りを自動化してみましょって話
自分の成果物はわかるように残しておきましょうねってことで備忘録
~~自分ようなので他人の役に立つような内容はありませんあしからず。~~

# ゴール像
* 注文⇒注文完了メールまでを自動化したい
* 注文完了メールにはExcelファイルで承り表を添付したい

## 使ったもの
* Share Point
* Forms
* Power Automate
以上全部弊社で利用できるMicrosoftのツールたち。

## 各ツールの中身
<details><summary>Share Point</summary>
あらかじめ以下のものをドキュメント内に置いておく。<br>
・承り表の原紙となるExcelファイル　(以下『原紙』と記載します)<br>
・承り表を各店舗の店長さんにメール送付したいのでメールアドレスを記載したExcelファイル<br>
・ 承り表を溜めておくフォルダー<br>
</details>

<details><summary>Forms</summary>
注文ページとして使用
入力してもらうのは<br>
1. 注文者の情報<br>
2. 各商品ごとの購入点数<br>
3. 受け取り希望店舗と受け取り希望日<br>

これらを入力してもらったらあとはPowar Automateに頑張ってもらう

</details>

<details><summary>Power Automate</summary>

フローはザックリ以下の通り<br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459001/8f4f1b7d-c07c-c0de-6ea6-6e96a4a9545d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459001/9837e5f2-3e6e-84a3-5ad1-e8c2de4cd693.png)
躓いたところのみ自分用に詳しく書いておく。
苦戦したのはShare Point上にある『原紙』をコピー⇒注文者ごとの情報を入力して保存すること。
ただ『原紙』自体を書き換えるだけなら簡単だが、Power Automateのフローではコピーしたものを書き換えるのがすんなりとは行かない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459001/03bfc5e8-ca9b-1c5f-673e-18b8e9256e60.png)
上記の通りまずは『ファイルコンテンツの取得』で『原紙』の情報を取得させて
『ファイルの作成』でファイル名をFormsの回答情報から入力して
ファイルコンテンツに先ほど取得したものの『本文』を指定。これで注文者ごとの承り表のExcelファイルが出来上がる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459001/8709af6d-5bbb-58f5-f795-088fe2b884e6.png)
次に中身を入力していく
Excelオンラインの『行の更新』アクションを配置して
場所、ドキュメントライブラリにファイルのある場所を指定。
ファイルに『ファイルの作成』から取り出せた『ID』を動的コンテンツとして指定。
テーブル、キー列、キー値で書き込むセルを指定して
項目のプロパティを指定にはJSON形式で列を指定し、書き込ませたいFormsの回答を動的コンテンツで指定。
書き込む箇所が複数あるならこれを中身弄って繰り返す。

そっからさきはタイムゾーン修正して送付先メールアドレス拾ってきて
さっき作った承り表をメールに添付して送るだけ。簡単。
</details>

## こんな感じでメールが届く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459001/949a325f-db96-e5cd-453a-6bb1bd37da4d.png)
承り表Excelファイルの中身
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3459001/552f759c-58ef-6c1c-80ee-edd1426e8051.png)
見た目の細かい修正は必要だけど頭の中で考えていた物は出来ました。
[Golang]Lambda+APIGatewayでミドルウェアを作るには？

ここ最近はあまりAPIGateway+LambdaのRestAPIを作ることはありませんでしたが昨年からGolangに仕事の言語が切り替わったこともあり、改めて作ってみることにしました。

そこで今回はミドルウェアを作ります。

ECSなどでやるのであればGinなどのWebフレームワークのミドルウェアを作れば良いのですが今回はそうはいかないので自分で作って見ます。

## なぜミドルウェアを作るのか？

Lamdbaに限らず、Webアプリではほぼ全てのAPIに使う共通的な処理があります。

例えばハンドラーのところの実行前に認証をしたり、入口と出口のロギングなどですね。

他の開発同様に共通処理の部分を作れるように2つのミドルウェアを用意します。

## 固定の共通処理の場合

速度測定のロギングなどやエラーハンドリング、認証で使うことが多いです。

```golang
func middleware(next func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)) func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	return func(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
		// 前処理
		// 例: リクエストログの記録
		log.Printf("前処理1")

		// 次の処理を実行
		resp, err := next(ctx, req)

		// 後処理
		// 例: 応答ログの記録
		log.Printf("後処理1")

		return resp, err
	}
}
```

前処理と後処理の部分を必要に応じて変更してください。

基本的に値を渡したりなどしたい場合はctxに追加することをお勧めします。


## 引数を含めたミドルウェア

引数を入れたい場合はクロージャーを変更します。

もう少し細かくやりたい場合はinterfaceを定義して呼び出す関数を定義するなどのやり方があります。

```golang

type MyStruct struct {
	// ここに必要なフィールドを定義
	Value string
}

func createMiddleware(myData *MyStruct) func(func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)) func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	return func(next func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)) func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
		return func(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
			// 前処理: ここで構造体を使用
			fmt.Printf("ミドルウェアの前処理で使用される構造体の値: %v\n", myData.Value)

			// 次の処理を実行
			resp, err := next(ctx, req)

			// 後処理: ここでも構造体を使用
			fmt.Printf("ミドルウェアの後処理で使用される構造体の値: %v\n", myData.Value)

			return resp, err
		}
	}
}
```


## ミドルウェアを呼びだす

先ほど定義した2つのミドルウェアも同じ関数で呼び出すことができます。

```golang
func SetMiddlewares(handler func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error), middlewares ...func(func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)) func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error)) func(context.Context, events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
	
	for i := len(middlewares) - 1; i >= 0; i-- {
		handler = middlewares[i](handler)
	}
	return handler
}

func main() {
	combinedHandler := SetMiddlewares(handler, middleware, createMiddleware(&MyStruct{Value: "test"}))
	lambda.Start(combinedHandler)
}
```
グレースケールのアルゴリズムの比較

## きっかけ

今までグレースケール処理はRGBの平均値を使っていたが調べてみるといろいろと方法があることを知り、それらの違いを理解したいと思った。

## 比較するアルゴリズム

平均法、加重平均法、輝度法をそれぞれ比較していきたい。

>1. 平均法（Average Method）：R、G、Bの値の平均をグレースケール値とします。 グレースケール値 = (R + G + B) / 3
>2. 加重平均法（Weighted Average Method）：R、G、Bの値に重み付けをして平均を計算します。 グレースケール値 = 0.2989 * R + 0.5870 * G + 0.1140 * B
>3. 輝度法（Luminosity Method）：人間の視覚システムに基づいた方法で、R、G、Bの値を異なる重み付けで合算します。 グレースケール値 = 0.21 * R + 0.72 * G + 0.07 * B

引用元：https://musashi-ai.com/glossary/2023/06/132b15f51be239030f34b40a152b0c724506964c.html

比較するときには以下のサイト（自作）を利用した。

https://mogamoga1024.github.io/StudyOnGrayscale/

## 比較していく

### RGBが極値の色たち

<img widht="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/a1047ade-4f9d-cb4d-1d29-a8b8b697f673.png">

おそらく最も違いが分かりやすい画像

平均法は赤、緑、青は同じ色になっているが、
加重平均法、輝度法は青、赤、緑の順に薄くなっている。
特に輝度法の黄色はほぼ白に近い。

### 虹のイラスト

<img widht="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/e810a9db-61d9-5787-49f2-88a750a1aa03.png">

七色の虹のイラスト
各層がきれいに識別できるのは平均法。
加重平均法、輝度法は中心の色が同じ色のようになってしまい区別がつきにくい。

### 普通の画像1

<img widht="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/866496c8-5617-fb32-91c8-5ac878220912.png">

特に差があるようには見えない。

### 普通の画像2

<img widht="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/8b5bcf32-8ba4-eef1-73cf-af3b20fd0a49.png">

加重平均法、輝度法のほうがクラゲが見やすい。

### しもんきん

<img widht="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/a05efaa0-892b-70ad-e27d-ff3a8663bd81.png">

平均法が濃く、輝度法は薄い。
加重平均法は平均法と輝度法の中間くらいの薄さに感じる。

### Lennaさん

<img widht="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649673/763b7d04-e861-ba8e-d7e8-bba81e08915b.png">

しいてあげるなら輝度法は影と光のメリハリが強いように見える。

## どう使い分ける？

シンプルに変換したいなら平均法
人間の目による光の感じ方を忠実に再現したいなら加重平均法、輝度法を使うといいんじゃないかな。
といった感じ。

終わり。

## チラ裏

「輝度法」は「きどほう」と読む。
爆速でGo言語の変数を説明する

# はじめに
皆さんGo言語書いてますか？　
私も最近Go言語を書き始めました。せっかく学習しているので、私が理解できたところは記事として残そうと思います。
今回はGoの変数についてです。

※作成者はこの記事を爆速(2時間くらい)で作ったため、誤字脱字があると思います。ご了承ください。

※この記事では変数の全てを説明していないので、詳しく知りたい方は[公式ドキュメント](https://go.dev/doc/)をご覧ください。

# そもそもGo言語とは？？
Go言語は、Googleによって開発されたプログラミング言語で、シンプルで効率的な設計が特徴です。Goは、コンパイル速度が速く、メモリ使用量が少ないため、大規模かつ分散したシステム向けの開発に適しています。また、静的型付けとガベージコレクションを組み合わせ、安全で信頼性の高いコードを容易に記述できるようになっています。Goは、シンプルな文法や強力な標準ライブラリなど、開発者が生産性を高めるための機能を提供しています。

ってChatGPTが言ってます。
実際に書いてみて、コードをシンプルに書けると感じます。

# [本題] Go言語の変数

## 変数の宣言
Go言語の型の宣言は２種類あります。
```go:
	//var 変数名 宣言する型
	var i int //int型の初期値は0
	
	//Go言語に型を任せる方法
	i2 := 1 //この場合はint型
	i3 := "aaa" //この場合はstring型
```
変数iのように自分で型を宣言する方法と、
変数i2,i3のように型推論のように宣言することができます。

## int型
```go:
	var i int
	var i2 int8
	var i3 int16
	var i4 int32
	var i5 int64
```
int型は整数を扱う型です。
他の言語と同じくint型は使用できます。
Go言語ではビットの指定ができるため、メモリを効率的に使えるのもメリットだと思います。
ビット指定ができる分、最小値と最大値が変わるため、用途によって使い分ける必要があります。
intで宣言するとプラットフォーム依存になるため、その点も注意が必要です。

| 型 | bit | 最小値 |　最大値　|
|:------------:|:------------:|:------------:|:------------:|
|int8|8|-128|127|
|int16|16|-32768|32767|
|int32|32|-2147483648|217483647|
|int64|64|-9223372036854775808|9223372036854775807|
|int||||

:::note warn
int型の注意
各int型は異なる型と扱われるため、計算をする場合は同じ方にする必要があります。

例
```go:
var i int
var i2 int8
i = 10
i2 = 10

i3 := i + i2 //型が違うためコンパイルエラーになる
```
:::

## float型
```go:
	var fl float64
	var fl2 float32
	fl3 := 1.1 //暗黙的にfloat64になる
```
float型は浮動小数を扱う型です。
int型と同じく64bit,32bitと指定することができます。
型の指定をしなかった場合は必ず64bitになります。

:::note warn
float型の注意
int型と同じく
各float型も異なる型と扱われるため、計算をする場合は同じ方にする必要があります。

例
```go:
var fl float64
var fl2 float32
fl := 1.1
fl2 := 1.1
f3 := fl + fl2 //型が違うためコンパイルエラーになる
```
:::

## bool型
```go:
	var b bool //初期値はfalse
	b2 := true
```
bool型は真偽値を扱う型です。
特に他の言語との違いは特にないです。

## string型
```go:
	var s string
	s = "hello" //文字を代入

	s2 := "hello"
```
string型は文字を扱う型です。
他の言語との違いは特にないです。

## byte型
```go:
	var byteA byte
	byteA = 72
	fmt.Println(byteA)         //72と出力される
	fmt.Println(string(byteA)) //「H」と出力される
```
byte型は文字を数字としてを扱う型です。
byte型をstring()を実行すると、byte型がstring型に変換されます。
今回は72をstring型にして、Hと出力されます。

## 配列型
```go:
	var arr [3]int
	arr[0] = 1
	arr[1] = 2
	arr[2] = 3

	fmt.Println(arr) //[1 2 3]と出力される
```
配列型は配列を格納する型です（いきなり小泉構文）
宣言時に要素数を指定して、宣言することができます。

:::note warn
配列型の注意
配列型は他の言語と異なり、要素数を変更することができません。要素数を変更して使う場合はスライスを使う必要があります。
配列を使うときは要素数が変更にならないように実装しましょう！

例
```go:
var arr [3]int
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr = append(arr,1) //要素数が変更できないため、エラーになる
```

```go:
arr := []int{1, 2, 3} //これはスライス
arr = append(arr, 4)  //配列に値が挿入される

fmt.Println(arr) //[1 2 3 4]と出力される
```
:::

## interface型
```go:
	var it interface{}

	it = 1
	fmt.Println(it) //int型の1が出力される
	it = "aa"
	fmt.Println(it) //string型のaaが出力される
	it = [3]int{1, 2, 3}
	fmt.Println(it) //配列型の[1 2 3]が出力
```
interface型はどの型も代入できる型です。
動的言語みたいな動きができるんですねー
しかし、あくまでinterface型であるため、各型のメソッドや、計算はすることができません。
表示するだけなら問題なく使用することができます。

:::note warn
```go:
	var it interface{}

	it = 1

	i := it + 1 //int型ではないため計算できない
```
:::
【SwiftUI】画像をShapeStyleとして使いたい

# はじめに
図形にforgroundStyleで画像をのせたいことがありました。
できるのかなと調べたところ出来そうだったので記事にしておきます。

# 素材
![gradation.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/2fc3a4a2-22db-094d-d55d-89c8b4e7e71c.png)

# サンプルアプリ
![simulator_screenshot_1F031802-7025-43D1-9749-33507E7EC232.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/82c18b2d-cbf6-f050-0c25-b2b72c6b8597.png)

# 実装
`ImagePaint`を使用してShapeStyle化できるっぽいです。
引数はimageの他にscaleやsourceRectなどがあります。
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        Circle()
            .foregroundStyle(ImagePaint(image: Image(.gradation)))
    }
}
```

# おわり
ImagePaintなんて使ったことなかったです

# 公式ドキュメント
https://developer.apple.com/documentation/swiftui/imagepaint
laravel APIのエンドポイントを作成してリクエスト投げたが原因不明のエラーが出る

## 概要

laravelにてエンドポイントを作成し、Thunder Clientからリクエストを投げた。なんのレスポンスもない500が返された。エラーログにも何も出力されていない。laravel.logにも何も出力されていない。かなり詰まったので自分の場合の原因を載せておく。

## 原因

ControllerとRepositoryで間違えて同じクラス（インターフェース）をDIしていた。

具体的に言うとControllerとRepositoryの`__construct()`で下記のような記載が重複していた。

```php
public function __construct(
    private HogeInterface $payment,
) {
}
```

一時的にRepository側のDIの記述をコメントアウトして当該のエンドポイントにリクエストを送ったところ問題は解決した。

## 作業の背景

本事象はリファクタ中に発生した。今までリポジトリ層でDIして呼び出していたインターフェースをコントローラーで呼び出せるようにリファクタしていた。
簡単なUMLをMarkdown内に直接書き込む方法

## 概要
* VScode内にてMarkdownの文章とUMLを同じプレビュー内に表示させる方法を記述。
* 前投稿[PlantUMLを用いた簡単なシーケンス図の作成方法](https://qiita.com/momomo1998/items/0837d99766297346addc)の続き。
* **UMLとして記述したコードが変換されないエラー**の解消法あり。
* 使用拡張機能：Markdown Preview Enhanced、PlantUML
* 使用環境：Windows11 Pro、VScode

## 記述の方法
* ファイルの拡張子は`.md`にて作成。簡単なシーケンス図を作成する。VScodeにて以下のコードを` ``` plantuml `と` ``` `で挟んで記述する。

```md:uml.md
@startuml

object Object1
object Object2

Object1 -> Object2: メッセージ1
Object2 -> Object1: メッセージ2

@enduml
```

* 実際にMarkdown内に記述した全体コードはこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/b5345850-93fa-cc22-5df5-38ce389bb730.png)

* 右クリックで以下画像のように選択することでプレビュー可能。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/352ef36a-8631-0bb2-bb75-fe4d20db81b5.png)


* プレビュー後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/a310b82e-09fd-784c-be32-54a04ac43a49.png)

## Markdown内のUMLが変換されない事象について

:::note info
Markdown内にUMLとして記述したはずのコードが反応せず、以下のようなエラーが出てしまう場合の対処法について記述。
参考サイト：[VSCodeでMarkDownとPlantUMLを使う - yuDigiLife](https://yu88life.com/vscode-markdown-plantuml/#index_id10)
:::

```
    Error: plantuml.jar file not found: ""

Please download plantuml.jar from https://plantuml.com/download.  


If you are using VSCode or coc.nvim, then please set the setting "markdown-preview-enhanced.plantumlJarPath" to the absolute path of plantuml.jar file.

If you don't want to use plantuml.jar, then you can use the online plantuml server 
by setting the setting "markdown-preview-enhanced.plantumlServer" to the URL of the online plantuml server, for example: https://kroki.io/plantuml/svg/
```
* VScodeにて追加済みの拡張機能を確認。`Markdown Preview Enhanced`の拡張機能の設定を開く。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/adb9ddba-4159-ae8d-70b5-0a1d8fcf77a0.png)

* `Markdown-preview-enhanced:Plantuml Jar Path`にPlantuml Jarのファイルパスを入力。`すべてのプロファイルに適用`に設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/1c3a50b0-ec42-b5dc-590a-8a7f4eb41432.png)
AWS認定CLF-C02を暗記で取る

この記事の対象者は以下になります。
* AWSの勉強をしていない
* AWS認定CLF-C02を短期で取得したい
* 暗記は人並みにできる

# 教材
教材はコレだけ。
スマホで気軽に出来るユーデミーさんの問題集です。

https://www.udemy.com/course/aws-4260/
**【CLF-C02版】この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（6回分390問）**


有料ですが、バーゲンを利用すればかなり安いです。
他の問題集と比べて以下の良さがありました。
* AWSの実際の試験問題に出されやすい問題が多い。
* 説明が分かりやすい。

質の良い問題集はとても大切です。
私は無料の問題集で2週間を無駄にしました。

# 試験準備をする
AWSの認定試験を初めて行う場合は、案外手続きに時間がかかります。
まずは認定試験の登録を行ってください。
試験日は2回まで変更可能ですので、1月先など適当に予約しても問題ありません。


# 問題集の使い方

試験問題は65問が1セットで6セットあります。
各セットごとに以下の対応をします。
1. 最初は解かないで読む
2. 集中してテストする
3. テストで不正解となったら説明を読む
4. 正解率90%以上で次のセットへ


## 1.最初は解かないで読む
まずはテスト開始後にすぐ中止して、解答を見ちゃいます。

問題と答えを読みます。

この時点では説明やリンク先までは見ません。

:::note info
記憶する範囲を少なくします。
:::

65問と数が多いですが、流し読みで良いので1日以内に読み切ってください。
スマホを活用して隙間時間に読み進めます。
また、お酒は吞まないでください。

## 2.集中してテストする
ざっと読んだらテストをなるべく早く、集中して行います。

:::note info
最低でも翌日以内にテストしてください。
:::

udemyはテスト中に放置すると、自動的に中断モードになります。
ですが、1の直後のテストはできるだけ中断せずに行ってください。
　例　だいたい最初は2時間かかるので
　　　　1の翌日に早起きして1時間テスト
　　　　+出勤中も電車内で30分テスト
　　　　+お昼休みに30分テスト
　　　　=2時間でテスト完了

## 3.テストで不正解となったら説明を読む
テストの後、不正解となった問題を確認します。
解答だけではなく、説明も呼んでください。
リンク先は読まなくて良いです。

説明をすべて読み終わったら、再テストをしてください。

:::note info
1～2ほど短期集中で行う必要はありませんが、再テストまで2日以上間が空くと忘れてしまいますのでご注意ください。
:::


#  4.正解率90%以上で次のセットへ
問題集の周回です。覚えるまで繰り返します。
6セット終わったら、最初のセットから繰り返します。
慣れるとテストは30分で終わります。
頑張れ。


# 試験を受ける
安定して各セットの正解率が90%になったら、早めにAWS試験を受けてください。

:::note info
1週間経過すると忘れます。
試験までは問題集の周回を行ってください。
:::

予約していた試験日を変更します。
土日祝日は空きが少ないため難しいのですが、平日なら2日後の予約が簡単に取れます。


# おまけ
確保できる勉強時間は人それぞれですが、1～2は3日以内を目安にしてください。

1は海馬で24時間溜め込む記憶を利用します。
海馬はアルコールに弱いので吞んでは駄目です。
2は大脳皮質で3日間溜め込む中期記憶(近似記憶)を利用するので、時間との勝負になります。

3～4は側頭葉の長期記憶を利用します。
半永久的に残る記憶です。
ちょっと怖いですね。
Draw.ioを追加して作図する

## 概要
* VScodeにて拡張機能Draw.ioを追加してシーケンス図を作図する方法を記述。
* 使用環境：Windows11 Pro、VScode

## Draw.ioとは
>draw.ioとは、無料で利用できる作図ツールです。Microsoft EdgeやGoogle Chrome、MacのSafariなどのブラウザから開くことができて、Web上で描画できます。
>draw.ioは、四角や三角、矢印などの図形を選択して画面上に配置して図表を作成していきます。この作成手順は、ExcelやPowerPointの図形作成ツールとあまり変わりません。
draw.ioがExcelなどと大きく違う点は、図形の素材がとても多いことです。立体的な図形や人型の図形、フローチャートやER、UMLのテンプレートが豊富に用意されています。

[draw.ioとは？無料の図版作成ツールの使い方やレイアウト資料の作成について解説！ - Professional Online（プロフェッショナルオンライン）
](https://aporeru.com/articles/drawio)

* ブラウザ版
[draw.io
](https://app.diagrams.net/)

* VScode版
[Draw.io Integration - VScode](https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio)

## Draw.ioを追加
* `Draw.io Integration`を追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/5a97300e-a143-caf4-d1fe-06c8347fa5d5.png)

* ファイルの拡張子を`.drawio`にすることで、以下のような画面が自動で表示されDraw.ioを使うことができる。

:::note  info
拡張子は`.drawio`以外にも`.dio`、`.drawio.png`、`.drawio.svg`が使用可能。`.drawio.png`、`drawio.svg`を使用することで、SVGやPNGのファイル形式で保存でき、importやexportを必要とせずにそのまま画像としての利用や編集が可能。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/f4415ff4-5475-1a45-8671-f22ef05cd6f6.png)


## プレビューと作図
* プレビューと同じものを作成可能。UML以外の作成にも使える。
### PlantUMLを使用してプレビューさせたシーケンス図
* [PlantUMLについてはこちらから](https://qiita.com/momomo1998/items/0837d99766297346addc)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/22087cc6-2a4b-f1d0-2caf-f68feee9abb5.png)


### Draw.ioを使用して作図したシーケンス図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3624672/cc8db537-bb7c-f81a-7d55-7c926ada7e28.png)