OmniAICreator/Qiita-1.07M huggingface dataset:
KubernetesのPodがTerminatingのままで消えない

KubernetesのPodがTerminatingの状態でハングしていてPodが消えない場合にどうやってトラブルシューティングするかまとめてみました。

# PodがTerminatingのままになっている
状況として、Deploymentなどをアップデートやリスタートしたときに一部のPodが以下のように`Terminating`の状態で止まりPodが削除されないことがあります。

```bash
NAME           READY   STATUS        RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
my-pod-2       1/1     Running       0          15h8m   10.100.2.4    myk8snode2  <none>           <none>
my-pod-3       1/1     Running       0          15h9m   10.100.6.0    myk8snode3  <none>           <none>
my-pod-kep-0   0/1     Terminating   0          1h      10.100.2.8    myk8snode1  <none>           <none>
my-pod-kep-1   1/1     Running       0          6h4m    10.100.5.13   myk8snode2  <none>           <none>
```

# ファイナライザー(Finalizers)の確認
ファイナライザーをリソースで使用している場合は、それが理由で削除ができないのか確認する必要があります。ファイナライザーは理由があって使用されているはずなので、Podを削除するためだけにファイナライザーをなくすのは解決法とは言えないと思われます。

https://kubernetes.io/ja/docs/concepts/overview/working-with-objects/finalizers/

# 強制削除
ベストの方法ではありませんが、とりあえずPodの削除を進めてデプロイなどを継続したり、サービスの継続をするために一時的な解決方法として強制削除もできます。

```bash
kubectl -n <NAMESPACE> delete pod  <PODNAME> --grace-period=0 --force 
```

kubeletからの確認を待たずに強制的に削除するので、Podのプロセスが完全になくならなかったりほかのリソースとの競合などが起こりえます。一時的には有効ですが、これを常に行っている場合は原因を追究する必要があります。

# kubeletログの確認
kubeletのログを見ることによって原因を見つけられるかもしれません。


```yaml
apiVersion: v1
kind: Pod
metadata:
  name: nsenter
  namespace: nsenter
spec:
  hostPID: true
  hostNetwork: true
  hostIPC: true
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/hostname
            operator: In
            values:
            - myk8snode1
  containers:
    - name: nsenter
      image: ubuntu
      command: ['tail', '-f', '/dev/null']
      securityContext:
        privileged: true

```
管理者権限などが付いたPodです。`nodeAffinity`でログを確認する必要があるノードを指定してデプロイします。
トラブルシューティング以外の時は使わないほうがいいと思います。

デプロイしたPodにexecします。

```
kubectl -n nsenter exec -it nsenter -- nsenter --target 1 --mount --uts --ipc --net /bin/bash
```
これで、Pod`nsenter`から`myk8snode1`内のログを見ることができます。

```
journalctl -u kubelet 
```
とするとkubeletのログを確認し、原因を探ることができるかもしれません。
QTTabBarアンインストール済みの環境で「QTTabBarException.log」が生成されてしまう時の対処法

:::note alart
警告
結構行き当たりばったりで対処しているのでこの方法が合っているのかは正直分かりませんので試される方は自己責任でお願いいたします。
:::
## C:\Users\User名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup内にある「QTTabBar」のフォルダとQTTabBar Desktop Extension StartUp.QTTabGroupを削除
AGV(無人搬送車)について

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiixta.com/7_inai_)

# AGVとは
AGV(Automated Guided Vehicle)の略で、無人搬送車を意味します。
AGVの用途としては、製造現場における材料や工具の運搬、物流倉庫における商品の運搬といったことが挙げられます。
最近、テレビでニトリやAmazonの物流倉庫の作業風景をよく見かけますが、そこで使用されている床を自動で移動している車輪付きの台車がAGVです。

# AGV流行の背景
近年多くの企業がAGVの導入に踏み込んでいます。その背景には、労働者の減少と費用対効果の高さがあります。特にネット通販市場の拡大により、物流倉庫では多くの労働者が必要になっています。そこでAGVを導入することで、人件費を削減することができます。また、少子高齢化により労働人口の減少が目に見えて迫っている日本では、AGVのように人がしていた作業を機械に変更することは必須の技術となっています。

# AGVの走行方法
AGVの走行方法は、__ガイド式__ と __非ガイド式__ に大別することができます。
非ガイド式のAGVは、AMR(Autonomous Mobile Robot:自律走行搬送ロボット)と呼ばれることもありますが、本記事では「非ガイド式AGV」で統一します。
### ■ガイド式
- ①磁気誘導・ライントレース式
ラントレース式は、磁気テープを床に張り巡らせ、AGVが走行するルートを決める方式です。
磁気テープの検知には磁気センサーを用います。
- ②ランドマーク方式
ランドマーク式は、地面に貼り付けた二次元マーカーをAGVに取り付けたカメラで読み込みながら走行する方式です。磁気テープとの違いは、二次元マーカーを走行ルート全てではなく、要所に貼り付けるだけで良いことです。

### ■非ガイド式
非ガイド式のAGVは、ガイド式の走行方法で挙げたような __誘導体は必要ありません。__ では、どのように走行ルートを決めているのでしょうか？
ほとんどの非ガイド式AGVは、SLAM(Simultaneous Localization and Mapping:位置特定と地図作成を同時に行う)方式が採用されています。AGVに搭載しているレーザースキャナ等で壁や柱までの距離を計測し、周囲の環境地図を作成しつつ、その環境上での自己位置を特定することで、誘導体なしで走行することができます。
また、非ガイド式は誘導体が必要ないため、誘導体を設置する手間が省けるのはもちろん、走行ルートも自由に設定することができます。

# 終わりに
最近ではガストやワンカルビのような飲食店でも、配膳ロボとして活躍するAGVを見かけるようになりました。今までは工場や物流倉庫のような一般人と関わりがない箇所がメインでしたが、飲食店でも導入されたことで、世間的な認知がより高まりました。これから学校や病院のような、現時点では導入されていない場所でも導入されていくかもしれません。


最後までお付き合いくださりありがとうございました。
Figma超入門

:::note warn
この記事は、2023年2月2日にあった社内勉強会で発表した内容を必要に応じてリライトした内容です
:::

Figmaの入門記事はかなり擦られたコンテンツだと思いますが:joy:
社内勉強会では初めて取り上げるので悪しからず！

# Figmaとは？
https://www.figma.com/ja/

2016年9月に正式リリースされたUIデザインツール
最近日本語版がローンチされたことと、Adobeが買収したことで話題
ローカルでの保存は「.fig」

# Figmaのいいところ
- リアルタイムにコラボレーションできる機能
    - モブデザインできる
- クロスOSでも問題なし（ブラウザで動くため）
- 実機プレビューができる（FigmaMirrorというアプリが別途必要）
- プラグインが豊富 - 後述
- :fire:格段にアツい:fire:
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690270/7108529f-078e-d2b1-0a11-802bf2ecfffb.png)

# チュートリアルやる
https://www.youtube.com/playlist?list=PLXDU_eVOJTx7QHLShNqIXL1Cgbxj7HlN4

基本操作はXDとほぼ変わらない？:thinking:

チュートリアルの動画は英語だけど、実際の画面を操作しながら説明しているのでわかりやすかった（ベクター画像の作り方まで解説してくれた:joy:）
全部で6本の動画、すべて再生しても1時間満たないくらいなのでサクッと入門できる

# プラグインを漁る
Figmaの良いところの一つとして「プラグインの豊富さ」がよく挙げられるので、良さげなのを入れてみる

デザインタブ単位でプラグイン導入できるので気軽に試せる
もちろん気に入ったのはストックすることもできる

## プラグインの使用方法
1. プラグインを使用したいデザインのツールバーの「リソース」をクリックして、「プラグイン」タブで検索かける
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690270/15a20f0e-a9a5-2af4-b9df-3801a7ef8095.png)
1. すぐに使用する場合は「実行」をクリック
![image02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690270/2d3f10df-cd3e-2c99-1be3-e1bf86d1b2c9.png)
1. ストックしたい場合は実行ボタンの横のミートボールメニューから「保存」をクリック
てかこのタイプのメニューってミートボールメニューって名前なの初めて知った
![image03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/690270/83d8f6ae-a62d-af51-3949-1f283f54959b.png)

## 良さげなプラグイン集
### Instance Finder
ファイル内で使用されているコンポーネントを検索できる

https://www.figma.com/community/plugin/741895659787979282/Instance-Finder

### Breakpoints

ライブプレビューできるレスポンシブフレームが作成できる
使い方の詳細は:point_down:　※動画です※

https://youtu.be/OaGSreqHCXE

https://www.figma.com/community/plugin/824289601590456356/Breakpoints

### Unsplash

商用利用可能な写真素材を検索、使用できる
ダミー画像とかにいいかも

https://www.figma.com/community/plugin/738454987945972471

### Better Font Picker, Japanese Font Picker

テキストボックスでプレビューしながらフォントを選択できる

https://www.figma.com/community/plugin/739922281164562258

https://www.figma.com/community/plugin/948851319619581556

### Downsize

ファイル上で画像の圧縮やリサイズができる

https://www.figma.com/community/plugin/869495400795251845/Downsize

### Chart

さまざまなチャートがすぐに使用でき、実際にデータをインポートしたチャートも生成することができる

https://www.figma.com/community/plugin/734590934750866002/Chart

### Mockuuups Studio

モックアップにデザインフレームを指定し配置することができる

https://www.figma.com/community/plugin/786250770157843670/Mockuuups-Studio
2次元配列をリスト内包表記を使って作成する方法

2次元配列を作成する方法はいくつか方法がありますが、
今回はリスト内包表記を使って作成する方法について説明します。

結果だけを知りたい方向けに先に結論を書くと、
初期値が「0」で、「4 × 3」の2次元配列「twoD_list」をリスト内包表記で作成するには、
`twoD_list = [[0 for j in range(4)] for i in range(3)]`とします。

以下の説明では、
まず最も基本的な、for文を入れ子にして2次元配列を作成する方法を説明し、
次にリスト内包表記を使った2次元配列作成について説明します。

1. for文を入れ子にして作成する
1. リスト内包表記を使って作成する

　

**1．for文を入れ子にして作成する**
基本的なfor文の入れ子のみを使って作成します。
コードは以下のように記述します。

```Python
# for文の外側は3回実行
for i in range(3):
    # 2次元listの内側に作るlistを宣言
    sub_list = []

    # for文の内側は4回実行
    for j in range(4):
        # 内側に作ったlistに値を追加
        sub_list.append(i * 10 + j)
        
    # 内側に作ったlistを2次元listに追加
    twoD_list.append(sub_list)

# 結果出力
print(twoD_list)
```
実行すると、以下のように「4 × 3」の2次元配列が表示されます。

```Python
[[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]
```
　

**2．リスト内包表記を使って作成する**
続いてリスト内包表記を使って作成します。
コードは以下のように記述します。

```Python
# リスト内包表記で「4 × 3」の2次元listを作成
twoD_list = [[(i * 10 + j) for j in range(4)] for i in range(3)]

# 結果出力
print(twoD_list)
```
for文を入れ子にして作成するのに比べて、かなり簡単に記述できます。
実行すると、for文を入れ子にした場合と同様に「4 × 3」の2次元配列が表示されます。

```Python
[[0, 1, 2, 3], [10, 11, 12, 13], [20, 21, 22, 23]]
```

なお冒頭にも記載しましたが、
初期値が固定値の「0」で、「4 × 3」の2次元配列「twoD_list」をリスト内包表記で作成するには、
`twoD_list = [[0 for j in range(4)] for i in range(3)]`とより簡単に記載できます。
TypeScriptの型について

## 基本型
基本形(プリミティブ型)とは、JavaScriptの基本的なデータ型のことです。具体的には、`文字列型（string）` `数値型（number）` `真偽値型（boolean）` `シンボル型（symbol）` `void` `nullとundefined` `任意型(any)` が該当します。

#### 文字列型（string）
```typescript
let firstName: string = "Steve";
let lastName: string = "Jobs";
let fullName: string = `${firstName} ${lastName}`;

console.log(fullName); // Steve Jobs
```
フルネームを作成するための文字列連結や、テキスト処理、ユーザーからの入力など非常に多くの用途があります。

#### 数値型（number）
```typescript
let myValue: number = 15;
myValue = 10; // 再代入
console.log(++myValue); // 11
```
時間や距離、温度、重量、金額など...例えば、購入商品の価格を計算したり、時間の計算をしたりする際に数値型が使用されます。

#### 真偽型（boolean）
```typescript
let isRaining: boolean = true;

if (isRaining) {
  console.log("雨なので傘を持っていく"); //true
} else {
  console.log("今日は傘いらないな！"); //false
}
```
`true`と`false`しか状態を持たない最もシンプルなデータ型。チェックボックスやラジオボタンのような、UI要素の状態を管理するためにも使用します。

#### シンボル型（symbol）
```typescript
const mySymbol = Symbol('mySymbol');
const myObject = {
  [mySymbol]: 'これはシンボルキー'
};

console.log(myObject[mySymbol]); // これはシンボルキー
```
`[mySymbol]`というシンボルをキーとして、文字列値`'これはシンボルキー'`が割り当てられています。最後に、`myObject`から`mySymbolキー`に対応する値を取得し、コンソールに出力します。

このように、シンボル型は**一意の識別子を表す**ために使用されます。シンボル型は、文字列とは違い、ユニークな値を表現できるため、オブジェクトのキーとして使用されることが多いようです。

#### void
```typescript
function sayHello(): void {
  console.log("Hello!");
}

sayHello(); // Hello!
```
**いかなる返り値も持たないことを明示する**ために使われることが多いです。`undefined`しか代入できません。

この場合、`sayHello関数`は値を返さないことが定義されています。`void`は値の型を持たないので、関数が何も返さないことを示します。関数が値を返そうとした場合にはエラーが発生します。

なお、主に「コンソールにログを出力する関数」や「イベントリスナー」などに`void`を使用します。

#### nullとundefined
```typescript
let myNull: null = null;
let myUndefined: undefined = undefined;

console.log(myNull);        // null
console.log(myUndefined);   // undefined
```
TypeScriptでは`null`と`undefined`もひとつのデータ型として捉えます。`null`と`undefined`はJavaScript・TypeScriptにおいては区別されるのです。`null`は`null`という値が代入されている状態であり、`undefined`は値がまだ代入されていない状態です。

#### 任意型(any)
```typescript
let myValue: any = 10;
console.log(myValue); // 10

myValue = "hello";
console.log(myValue); // "hello"

myValue = true;
console.log(myValue); // true
```
`any型`が付与された変数は、**どんな型の値でも代入することができます**。外部から渡される値の型が分からない場合。一時的な変数の場合や、型が明確でない動的なデータを扱う場合などの使用が考えられます。


## ユーザー定義型

ユーザ定義型とは、開発者が自分で定義した型のことです。**既存の型を組み合わせて新しい型を作成**できます。`interface`、`touple`、`class`などが用意されています。

#### 例1
```typescript
// Person型を定義
type Person = {
  name: string; // 文字列型
  age: number; // 数値型
  address: string; // 文字列型
};

// Person型を使ってオブジェクトを宣言
const person: Person = {
  name: "John Doe",
  age: 30,
  address: "123 Main St.",
};
```
#### 例2
```typescript
// Book型を定義
type Book = {
  title: string; // titleは文字列型
  author: string; // authorは文字列型
  pages: number; // pagesは数値型
};

// Book型を使って配列を宣言
const books: Book[] = [
  { title: "The Great Gatsby", author: "F. Scott Fitzgerald", pages: 180 },
  { title: "To Kill a Mockingbird", author: "Harper Lee", pages: 281 },
  { title: "1984", author: "George Orwell", pages: 328 },
];
```
このように型判定を自由に記載できますが、自分で書いた型判定が誤っていると意図しない挙動になるので注意です。
【Python】多次元配列の初期化の注意点！！！

## 初めに
競技プログラミングサイトAtcoderの以下の問題を解いていました。
普段はC++で解いていますが、pythonで解いているときに問題が起きました。

><h3>問題文</h3><p>$3\times3$ のサイズのビンゴカードがあります。上から $i$ 行目、左から $j$ 列目の数は $A_{i, j}$ です。</p>
><p>続けて、 $N$ 個の数 $b_1, b_2, \cdots, b_N$ が選ばれます。選ばれた数がビンゴカードの中にあった場合、ビンゴカードのその数に印を付けます。</p>
><p>$N$ 個の数字が選ばれた時点でビンゴが達成されているか、則ち、縦・横・斜めのいずれか $1$ 列に並んだ $3$ つの数の組であって、全てに印の付いているものが存在するかどうかを判定してください。</p>

[問題リンク](https://atcoder.jp/contests/abc157/tasks/abc157_b)

宴会で盛り上がるビンゴの問題です。
ビンゴカードを$3\times3$のサイズのbool型2次元配列で管理すると解けそうです。

## そして問題が起こった

### 初期化でやりたいこと
以下のようにビンゴカードをすべてのマスがFalseになるように準備します。
```python
card = [[False, False, False],
        [False, False, False],
        [False, False, False]] 
```
この初期化であれば問題が起きることはありません。

### 問題が起きる初期化の仕方
しかし、サボって以下のような初期化をすると問題が起きます。
```python
# よろしくない例1
card = [[False, False, False]] * 3

# よろしくない例2
card = [[False] * 3] * 3
```

私は実際に「よろしくない例2」で初期化をしました。

### 起きた問題
値を代入して書き換えてみます。
実際には$b_1, b_2, \cdots, b_N$に含まれている数のマスをTrueにするという操作ですが、説明のために```card[0][0]```を書き換えてみます。

```python
# 初期化
card = [[False] * 3] * 3

# 値の書き換え (例:card[0][0]をTrueにする)
card[0][0] = True

# 確認
print(card)
# [[True, False, False], [True, False, False], [True, False, False]]
```

なんと```card[0][0]```のみをTrueに書き換えたつもりだったのですが、```card[1][0]```と```card[2][0]```も書き換えられてしまっています。

これは由々しき事態です。

### 原因
よろしくない例のように初期化すると要素であるリスト(行に対応するリスト)が全て同じオブジェクトとして生成されてしまう
```python
# よろしくない例1
card = [[False, False, False]] * 3

# よろしくない例2
card = [[False] * 3] * 3
```

実際にアドレスを見てみると

```python
card = [[False] * 3] * 3

for i in range(3):
    print(id(card[i]))

# 0: 2520503833544
# 1: 2520503833544
# 2: 2520503833544
```
確かに同じオブジェクトを指しているようです。
そりゃ、同時に値が書き換わるわけですね。。。

### 解決策
リスト内包表記で初期化すると違うオブジェクトとして生成されるようです。
```python
# リスト内包表記による初期化
card = [[False] * 3 for _ in range(3)]

for i in range(3):
    print(f"{i}: {id(card[i])}")

# 0: 2459664737928
# 1: 2459664740296
# 2: 2459662013832
```
確かに違うオブジェクトとして生成されています。

## まとめ
多次元配列(list)を初期化する場合は記述が増えても内包表記を使う。
まぁそもそもnumpyでよい！という話もあったりしそうではある。

## <おまけ>無事にACしたコード
無事に問題の謎が解けました。
汚いですが一応載せておきます。
```python
# input
A = [list(map(int, input().split())) for i in range(3)]
N = int(input())
b = [int(input()) for i in range(N)]

# bingo card
bi = [[False]*3 for i in range(3)]

# check
for i in range(3):
    for j in range(3):
        if A[i][j] in b:
            bi[i][j] = True

# flag of bingo
flg = False

# check row/col
for i in range(3):
    if(bi[i][0] and bi[i][1] and bi[i][2]): flg = True
    if(bi[0][i] and bi[1][i] and bi[2][i]): flg = True
  
# check diagonal
if(bi[0][0] and bi[1][1] and bi[2][2]): flg = True
if(bi[0][2] and bi[1][1] and bi[2][0]): flg = True

# print answer
if flg: print("Yes")
else: print("No")
    
```
【Swift】Combineで同じ値を流さないようにする

# はじめに
Combineを使用していて、同じ値が流れてくると不便なことがありました。
同じ値を削除する機能を使ったので記録しておきます.

# 実装
以下は同じ値が何度も流れてきます。
```swift
import Foundation
import Combine

let subject = PassthroughSubject<Int, Never>()

var cancellable = Set<AnyCancellable>()

subject
    .sink { int in
        print(int)
    }
    .store(in: &cancellable)

subject.send(100)

subject.send(100)

subject.send(100)

subject.send(200)

subject.send(300)

subject.send(300)

subject.send(300)

subject.send(300)

subject.send(completion: .finished)

// success(100)
// success(100)
// success(100)
// success(200)
// success(300)
// success(300)
// success(300)
// success(300)
```

同じ値は除外します。
```swift
import Foundation
import Combine

let subject = PassthroughSubject<Result<Int, Error>, Never>()

var cancellable = Set<AnyCancellable>()

subject
    .removeDuplicates { beforeResult, afterResult in
        switch (beforeResult, afterResult) {
        case let (.success(beforeInt), .success(afterInt)):
            return beforeInt == afterInt
        default:
            return false
        }
    }
    .sink { int in
        print(int)
    }
    .store(in: &cancellable)

subject.send(.success(100))

subject.send(.success(100))

subject.send(.success(100))

subject.send(.success(200))

subject.send(.success(300))

subject.send(.success(300))

subject.send(.success(300))

subject.send(.success(300))

subject.send(completion: .finished)

// success(100)
// success(200)
// success(300)
```

# おわり
単純な型であれば`.removeDuplicate()`だけです。
在席確認アプリを作成する上で学んだこと

# 初めに

この記事では私がPowerAppsを用いてアプリを作成する上で学んだことを記載しております。

備忘録用として記載しておりますので読みにくいなどございましたらご容赦ください。

# 在席確認アプリの構成について

DBはSharePointリストを用いて作成しております
以下の機能をYoutubeなどを参考&自分なりのカスタマイズで作成しました。

[参考:在席状況確認アプリを作成する方法](https://www.youtube.com/watch?v=FReoNcZ12c0)

画面構成としては勤怠を登録する画面と登録した利用者が一覧で見れる画面の構成となります。

## ステータス

ラベルにステータスが表示されるように下記の関数を記載しました

```
Coalesce(
First(SortByColumns(Filter(出退勤履歴, メールアドレス = User().Email && 日付 = Today()),"Created",Descending)).在席ステータス,
"まだ本日は登録していません")
```

## 勤怠を登録するボタン

このボタンを押下すると勤怠が登録されるように記載しました

※Patch関数内の部門では在席状況確認画面でドロップダウンから○○課という値を取得するため余計な部分を削除しています。

例えば「PowerAppsがんばって覚える部技術企画課」の技術企画課の部分のみ
値を取得したいなど

```
OnSelect=
　Patch(
	出退勤履歴,{
		Title:GUID(),
		日付:Today(),
		在席ステータス:selectステータス,
		メールアドレス:User().Email,
		名前:User().FullName
		部門:Substitute(Office365ユーザー.UserProfileV2(User().Email,{'$select':"department"}).department,
"PowerAppsがんばって覚える部",
" "
)

});
```
その下に更に下記を記載しました
```
OnSelect=Set(Selectステータス,Self.Text)
```


```
DisplayMode=If(Label1.Text<> "退勤", DisplayMode.Edit, Disabled)
```

# 出退勤履歴

## 在席状況を確認する

在席状況を確認するギャラリーに下記のように記載しました

```
Items=
	GroupBy(
		SortByColumns(Filter(出退勤履歴,日付=DatePicker1.SelectedDate),"Created",
Descending),列名,"grp"
	)
First(ThisItem.grp).在席ステータス
First(ThisItem.grp).名前
Back()
Reflesh(出退勤履歴)
Navigate(Screen2)
```
## ユーザーのアイコンを他ユーザーがログインしても表示させたい

ギャラリー内にユーザーのアイコンが表示されるように図を追加し、そこに下記のように関数を記載しました。

```
If(
	!IsBlank(ThisItem.Email),
	If(
		Office365ユーザー.UserPhotoMetadata(ThisItem.Email).HasPhoto,
		Office365ユーザー.UserPhotoV2(ThisItem.Email),
		),
	SampleImage
)

```
## ステータス状態を色分けしたい

出社時は緑色、在宅は黄色、休みは赤色のように区別したいので
ラベルを追加して下記のように記載しました。

```
Switch(First(ThisItem.grp).在席ステータス,"出社",Green,"在宅",Yellow,"退勤",Red)
```
もしくは
```
If(
	First(ThisItem.grp).在席ステータス ="出社",Green,
	First(ThisItem.grp).在席ステータス ="在宅",Yellow,
	First(ThisItem.grp).在席ステータス ="出社",Red
)
```

## ドロップダウン

在席確認画面ではドロップダウンで課＆日付を選択すると
その日に出社or在宅or休みされている方を表示されるようにカスタマイズしております。

### 課ごとに表示される
○○課ごとにステータス状態を確認したいため
テーブル内の部門から値を取得しました
※***勤怠登録でPatch関数内で部門情報を調整したのはこのため***

### 日付
過去の状況を確認したい時に選択できるように追加しました

# 所感

***作成する上で苦労したこと***

1.在席確認画面でドロップダウンに○○課を選択するとそれに紐づいた画面を表示させること

2.他ユーザーが見てもユーザアイコンが表示されること


***対策***

勤怠登録ボタンにPatch関数内で部門情報を取得(余計な情報を取り除いた上で)するという考えに至るまで時間がかかりましたが何とか自分がやりたい事が実現しました。

## まとめ:アプリを作成する上で学んだこと

1.Patch関数内で部門情報を取得するときの方法
2.ユーザーアイコンを取得するときの方法
選択ソートを使ってみた。

# はじめに
選択ソートは、先頭にある値とそれ以降の値を比較し、一番小さい値を先頭に持ってくる（これを繰り返す）ソート手法です。

# 実装
```python:
# 選択ソート：リストの中から１番小さな数値を探す → 見つけた最小の数値と、リストの始めの数値を入れ替える → これを繰り返す
from typing import List

# 関数の定義：
def selection_sort(numbers: List[int]) -> List[int]:
    # インデックス番号の取り出し
    len_numbers = len(numbers)
    for i in range(len_numbers):
        # インデックス番号を一時的に保持しておく
        min_idx = i
        # 次のインデックス以降の要素を順に見ていく
        for j in range(i+1, len_numbers):
            # 現在保持している値より小さければ、その値のインデックス値を保持する
            if numbers[min_idx] > numbers[j]:
                min_idx = j
        # 一番小さかった値を先頭に持ってくる
        numbers[i], numbers[min_idx] = numbers[min_idx], numbers[i]
    return numbers


# テスト
if __name__ == "__main__":
    import random
    nums = [random.randint(0, 100) for i in range(10)]
    print(selection_sort(nums))
```

# 参考
https://www.udemy.com/course/python-algo
最近の進捗について

### 今の自分について

たまには、今の現状でも日記のように書こうと思い立ちました。RubyonRailsを只今勉強中ですが、中々難しい。ディレクトリをあちこちと移動するのでかなり混乱しています。また、HTML/CSS/Rubyが混ざり合い更に分からなく（涙）
自分にはまだ早いのか？いや、根本的に基礎が足りないのか。と考えました。
なのでとりあえずは、全体要素を掴む為にrubyの基礎を固めに専念しようと思います。。

### 今後の課題について
- Rubyの基礎固めをする
- Webの仕組みについてもう少し学習をする
- とりあえず、既に完成しているコードを真似して書く。

こんな感じで、数週間はやっていこうかと思います。
Mintを使ったSwiftLintの導入方法について

## はじめに
個人開発をしていく中で、Mintを使ってSwiftLintを導入することがあったので、学習のアウトプットとして残していこうと思います!!
## Mintとは
今回のメインテーマではないので一言で簡単に説明すると、Swiftのコマンドラインツールを簡単に管理してくれるものです！

ex. Swiftのコマンドラインツール
- SwiftLint
- SwiftFormat
- SwiftGen 
などなど...

上記の3つが、自分が学習したことがあるものなので、今回はSwiftLintに注目してアウトプットして行きたいと思います！
他の二つも後程挙げて行きたいと思います！

※Mintのセットアップは以下の記事を参考に学習させていただきました🙇
https://qiita.com/uhooi/items/6a41a623b13f6ef4ddf0
https://blog.mothule.com/ios/mint/ios-mint-basic-usage


## SwiftLintって何？

### 概要
コードの可読性や保守性、一貫性を高めるために、開発者があらかじめ設定したコーディング規約に従って、自動でチェックしてくれるものです！また、コードを自動で修正してくれたりもします！

### Mintを使ったインストール方法
以下のコマンドを打つことで、インストールしてくれます！
```
$ mint install realm/SwiftLint
```
ただチーム開発の現場では、複数のコマンドラインツールやバージョンを管理したいことから導入することがほとんどだと思うので、`Mintfile`を作成してそこに記述していきます!

``` Mintfile
realm/SwiftLint@0.50.3 // ☜ 今回はこれです！！
nicklockwood/SwiftFormat@0.51.1
SwiftGen/SwiftGen@6.6.2
```

次に以下のコマンドを打つことでまとめてインストールしてくれます！

```
$ mint bootstrap
```
以上でインストールは完了になります

### 基本的なコマンド

以下のコマンドでコーディングルールに従って、チェックしてくれます!

```
$ mint run swiftlint 
```
次のコマンドはコーディングルールに従って自動修正してくれます！

```
$ mint run swiftlint --fix
```

### スクリプトへの記載方法

ただ、いちいちコマンドを入力するのは少しめんどくさい...
そういった時にはXcodeのビルド設定を開き、Run Scriptを追加してあげましょう！

```
export PATH=/opt/homebrew/bin:$PATH 

if which mint >/dev/null; then
	xcrun --sdk macosx mint run swiftlint swiftlint --fix
	xcrun --sdk macosx mint run swiftlint swiftlint
else
	echo "warning: Mint not installed, download from https://github.com/yonaskolb/Mint"
fi
```

上記を記述してあげることにより、ビルド実行前に自動実行してくれます！
※上記の記述内容について
- pathをとおすことが重要！ -> Mintのインストール場所を指します！
-  `xcrun --sdk macosx` -> どうやら必要らしい!笑

### コーディングルールの設定方法について

SwiftLintがデフォルトで設定されているものでコードチェックこのままできますが、コーディングルールを自分で作成することもできます！
そのためには`.swiftlint.yml`ファイルを作成してあげましょう！
そこのファイル内にオリジナルのルールを書いてあげればOKです！

ルールの詳細について下記を参考にしました！
https://realm.github.io/SwiftLint/rule-directory.html

## 最後に
以上でMintを使ってSwiftLintを導入することができました！
間違えてる部分等ありましたら、ご指摘いただければ幸いです🙇
これからもiOSエンジニアを目指して日々の学習をアウトプットしていきます!

## 参考
下記サイトを参考にさせていただきました!
大変勉強になりました✨

- https://qiita.com/uhooi/items/bf888b53b4b8210108aa
- https://qiita.com/naginx/items/92a647a76df6c3688302
- https://zenn.dev/st43/scraps/1e1ba7ced9f05c
AI・機械学習でよく使うアルゴリズムメモ。-- 回帰分析 --

# もくじ
>[帰分析分析ってなあに？](#帰分析分析ってなあに？)
[回帰分析の種類](#回帰分析の種類)
[で、何に使うの？](#で、何に使うの？)
[実際に使ってみる](#実際に使ってみる)
[方程式](#方程式)
[誤差を求める(最小二乗法)](#誤差を求める(最小二乗法))
[偏回帰係数](#偏回帰係数)
[今回のデータで解った事](#今回のデータで解った事)


# 回帰分析ってなあに？
簡単にまとめると、**説明変数(やった事とか)に対する目的変数(結果)がどのような影響を受けているかの因果関係を関数の形であらわす分析方法**です。
例えば、**体重**(目的変数)に対する**身長**(説明変数)の因果関係を調べる場合だと、身長が増えると体重も増えるのか？ということが調べられるわけです。
こういった二つの事柄が本当に関係あるの？っていうのを調べるのが回帰分析みたいです。

### 回帰分析の種類
##### ・単回帰分析
結果に対して行ったことが一つだけの場合は単回帰分析になる。
上記のだと体重に対して身長といったように、一つの事柄に対して一つの要素を用いての結果の予測、といった感じです。

##### ・重回帰分析
結果に対して行ったことが複数ある場合は重回帰分析になる。
上記の例だと、体重に対して身長と腹囲、のように一つの事柄に対して複数の要素を用いて結果を予測するといった感じです。

## で、何に使うの？
先ほどの例ではこんなわかりきったことを分析して何になるんだってな感じでしたが、因果関係の推定ができるということは、**やったことが本当に結果出してるのか**ということが分析できるわけです。
例えば**広告表示回数に対する売上**、とか。**勉強時間に対するテストの点数**とか。~~残業時間に対するお給料(当然因果関係があるはずですよね)とか。~~
ぶっちゃけ結構なんにでも使えそうな気がしますね。

# 実際に使ってみる
タイトルにもありますが今回は単回帰分析を使用します。
(重回帰分析についてはほとんど触れませんので悪しからず・・・)

### 使用するデータ
というわけで実際に用意したデータがこちら。
身長に対する体重というシンプルな題材で試してみようと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3163792/ac5a46a2-0a67-be26-6fd3-974e52862d58.png)


## 方程式
まず基本の式がこちらです。
$$y = β_1x + β_0$$


yを**目的変数**(結果)、xを**説明変数**(要因)と呼びます。
この方程式を使用してβ_1とβ_0を求めていくことになるのですが、この式は真の回帰式と呼ばれ求められるのはあくまで"理論値"であり、実際にはデータを作るときの測定誤差などが発生するため、これを加味した次の方程式を使用する必要があります。
$$y = β_1x + β_0 + u$$

この最後に加算された"u"が誤差、つまりは**真の回帰式で求められた値と実際の計測値の差**になり、単回帰分析ではすべてのデータに対してこの値ができるだけ小さくなるようにβ_1とβ_0を求めます。

## 誤差を求める(最小二乗法)
さて、肝心の誤差の計算ですが、
それぞれのデータの誤差(u_i)の二乗和が最小になるようなβ_1とβ_0を算出する、**最小二乗法**という方法を用いて行います。

$$\sum_{i=1}^{n}u_i^2 = \sum_{i=1}^{n}(y_i - (β_0 + β_1x_i))^2$$

しかし、この公式で求められたβ_1とβ_2はあくまで実際のデータ値から求めたものなので、真の回帰式で求められるβ_1とβ_2とは微妙に異なり、推定された値であるため**偏回帰係数**と呼ばれます。

### 偏回帰係数
ggると、**回帰分析において得られる回帰方程式の各説明変数の係数のこと**。とある。
## 今回のデータで解った事
ここまでの結果をグラフ化するとこうなります。
身長と体重がある程度の相関関係にあることが見て取れますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3163792/10a0542a-6a15-6dd9-7505-5b2a732dd0fb.png)

#### 結論
~~美味しいから大丈夫、ではない~~
身長と体重は相関関係にある。(身長が高くなると体重も増える)
この回帰分析という手法は、実際にAIに機械学習をさせた時に**学習結果が実際に推定される値と乖離していないかどうか**などを調べる際にも使用されます。そのうち機械学習を使って何かしてみたいって人は単語だけでも覚えておくと役立つのではないでしょうか。~~ほんとか？~~

それはそれとしてU149の放送が待ち遠しいですね・・・。

記事作成：K&Q
この列の型定義はなに！？そんなときに役に立つコマンド（SQLServer）

# 列定義を確認したい！！！
「～区分」などと付く列は、数字一文字で表現することもあるだろうが、その際についついシングルクォート(')をつけ忘れてエラーを表示させてしまう。
そんなときに思った。
この列の型定義なにっ！？って

経験が浅い故の戸惑いだが、これがきっかけで以下のコマンドを覚えることができた。
__exec sp_columns @table_name = [テーブル名]__
これで列定義の確認はばっちり！
[UE5] HLODビルド時のメモリを抑制するパラメータ

検証バージョン：UE5.1

# 前提
　HLODビルドにおいてアセットが増えるごとにメモリ使用量が増加することは避けられませんが、HLODビルドの設定をデフォルト値から調整することによってHLODのApproximateのメモリを調整(抑制)することが可能になっています。これらの設定を調整することで、HLODビルド時のピークメモリを200GBから100GB未満まで抑制できるといったこと可能です。

https://docs.unrealengine.com/5.0/ja/world-partition---hierarchical-level-of-detail-in-unreal-engine/

## 調整項目
　HLODのビルドに関する調整パラメータは`MeshApproximationSettings`で調整することができます。HLODLayerの中で設定することが可能です。

![2023-02-17_14h59_25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/364110/e4f35d82-c689-a3c1-6410-ffe0839b7f6a.png)

メモリ使用量に対して効果的なパラメータは以下の3点です。

**FMeshApproximationSettings::ApproximationAccuracy**
この値（近似精度）が非常に低く設定されている場合（つまりより高い解像度となる場合）メモリを大きく消費することになります。デフォルトは1.0ですが、この値を大きくすると消費するメモリ量が抑制できます。

**​FMeshApproximationSettings::bUseRenderLODMeshes**
この設定を有効にするとメモリを最も節約できる傾向にあり、ビルド時間をかなりスピードアップさせます。この設定を有効にすることでHLODの品質が低下する可能性がありますが、ジオメトリの複雑さなどに依存します（「HLODを構築するためにNaniteフォールバックメッシュを使用する」ことを意味します）

**FMeshApproximationSettings::bEnableParallelBaking**
この設定を無効にすると多少ビルドが遅くなりますが、ピークメモリが10-20GB程度減少します。

CitySampleではHLODのクオリティに応じてこれらのパラメータを調整していたりもします。プロジェクトでの都合によってこれらのパラメータを調整しつつ最適な設定を見つけてみてください。

## 補足
　Commandlet から HLOD を作成する場合は、*-DistributedBuild* が役に立ちます。

https://forums.unrealengine.com/t/distributing-hlod-building/1161539
バブルソートを使ってみた。

# はじめに
バブルソートとは、リスト内の要素２つを前から順に見ていき、大きいものが右側になるように並べ替えていくものです。

# 実装
```python:bubble_sort.py
# バブルソート：隣同士を比較する → 最後まで繰り返す → 始めに戻り、隣同士を比較 → 最後から２番目まで繰り返す
from typing import List

# 関数の定義(入力：元のリスト、出力：並べ替えた後のリスト)
def bubble_sort(numbers: List[int]) -> List[int]:
    # リストの長さを求める
    len_numbers = len(numbers)
    # リスト内の要素の個数分、インデックス番号を用意する
    for i in range(len_numbers):
        # 隣同士を比較できるのは最後から２番目まで、最後まで行ったらソートをかける範囲をiの分だけ狭める
        for j in range(len_numbers - 1 - i):
            # 大きさを比較する（手前の数値のほうが大きければ、入れ替える）
            if numbers[j] > numbers[j+1]:
                numbers[j], numbers[j+1] = numbers[j+1], numbers[j]
    return numbers

# for文を２回使用しているので、O(NN^2オーダー)

# テスト
if __name__ == "__main__":
    # テスト用のランダムな数値を作成する
    import random
    nums = [random.randint(0, 100) for _ in range(10)]
    # ソート後のリストをプリントする
    print(bubble_sort(nums))
```

# 参考

https://www.udemy.com/course/python-algo/
Heroku Connectの同期モードではまった話

Herokuといえばそれ自体が便利なPaaSサービスですが、Salesfroceのエコシステム上で構築する際に利用できる様々なソリューションが用意されています。Heroku Connectもそのうちのひとつ。
今回そのHeroku Connectの仕様で色々はまったので、調べたことをまとめます。

## 状況

直近のプロジェクトでは、Salesforceへ格納したデータをHeroku上に構築したWebアプリケーションで呼び出して表示しています。ざっくり以下のような感じ。
 - データ読み取り：
     - SFDC → Heroku Postgres (Heroku Connectで同期）　→ Webアプリ
 - データ更新：
     - Webアプリ → MuleSoft (Salesfroce社系列のAPIプラットフォームサービス)  → SFDC

こうすることで、データ更新の流れが一方通行になって整理される、というアーキテクチャです。

ただ更新データがHeroku Postgresへ反映するのがたまに遅れてしまう事象が発生していました。
仕様を読み解いて問い合わせてとやったところ、結論、データ更新の同期が遅れる事象は、結局製品側では解決する方法がなかった:upside_down:


## そもそもHeroku Connectとは
Heroku Conect: SFDCからHeroku上のPostgresに同期してくれるPaaSサービス
同期のモードはふたつあり、オブジェクトごとに設定が可能
 - Interval Polling: 
     - 一定間隔ごとにSFDC側の変更の同期を行う。インターバルは2分～1時間
 - Accelerated Polling: 
     - ほぼリアルタイムで同期を行う。SFDCでデータ更新が入るとSFDC側からAPIでHeroku Connectへ通知が飛ぶ。それをトリガーにHeroku Connectは同期を実行する。

参考：[Salesforce の加速ポーリング](https://devcenter.heroku.com/ja/articles/mapping-configuration-options#accelerated-polling-of-salesforce)

## Accelerated Pollingが曲者
 - Accelerated Pollingをオンに設定していても、"ベストエフォート"対応のため、時々Interval Pollingへ同期方法が切り替わってしまう。（いつ変わってしまい、いつ戻るのかはよくわからない）
 - Herokuに問い合わせたところ、Acceleratedで同期されるのか、Interval で同期されるのかはSFDCで更新が起きた時点の状況による、という回答だった
     - Heroku Connect側のリソース状況、問合せ先のSFDC側の状況などを鑑みて、Heroku Connectはその都度選択して同期方法を決定している。
     - そのため、この場合はIntervalによる同期になる、という簡単な条件では言えない。
     - あるアプリに割り当たっているリソースは限りがあり、Acceleratedで同期すればするほどそのリソースが減っていき、Intervalで同期される確率が高まるようなイメージ。
     - Accelerated Pollingを利用する場合は、Heroku ConnectのPrivate 4以上のTierを推奨。（お高い…）
     - 問題がありそうなことはわかっているものの、2023/4月時点では調査・改修の優先度は低い。

というわけで、時たまデータ更新がHeroku側へ反映されるのに時間がかかってしまうことがあるというわけです。
Heroku ConnectをSFDCデータの読み取り専用で使う場合、**データ更新をリアルタイムで反映させる必要がある処理は別の方法でデータ取得することを考えた方がよさそう。**

## ワークアラウンド
ワークアラウンドはいたってシンプルで、Interval Pollingに切り替わった際に、Heroku Connectのダッシュボードから再度SFDCの再認証を行う、というもの。

[Why has Accelerated Polling stopped working for Heroku Connect?](https://help.heroku.com/ZM7LFT2C/why-has-accelerated-polling-stopped-working-for-heroku-connect)

※ただ、これもAccelerated Pollingに戻る**可能性が高まる**に過ぎず、なんとも煮え切らない回答なのでした…（完）
SQLServer　ロックについて

# はじめに
現場にてwith(unlock)を初めて使用し、ロックについて学習しようと思ったためまとめます。
本記事はSQLServerの公式リファレンスと同じ内容です。公式リファレンスでわかりにくいところを自分用に残しました。
※間違ってたらご指摘いただけますと幸いです。

# ロックの種類、内容
## 共有[S]
selectステートメントなど、データの変更や更新を伴わない読み取り操作で使用。このロックがかけられている間は、データを変更できない。読み取りが完了するとこのロックは解除される。ただし、トランザクションの分離レベルがREPEATABLE READ以上に設定されている場合やトランザクションの間にロックヒントを使用して共有ロックを保つ場合を除く。

## 更新[U]
更新可能なリソースに使用。デッドロックを防ぐことができる。デッドロックになる例として、REPEATABLE READまたはSERIALIZABLEのトランザクションは、データを読み取るときにリソースに共有ロックをかけ、その後、行を変更する際に排他ロックに変換する必要がある。
仮に２つのトラザクションが一つのリソースに対し、共有ロックをかけてデータを更新する場合に片方のトランザクションは排他ロックとなり、もう一方は排他ロックへの変換待ち（すなわち、共有ロックのままということ）となるため、お互いがお互いの解除を待つデッドロックになってしまう。

このようなデッドロックの問題を解決するには、更新ロックを使用する。更新ロックでは、１つのリソースを一度にロックできるトランザクションは１つだけ。トランザクションはリソースを変更する場合に更新ロックが排他ロックに変換される。

## 排他ロック[X]
同時に実行されている複数のトランザクションが同じリソースにアクセスすることを防ぐ。ただし、NOLOCKヒントまたはREAD UNCOMMITED分離レベルなどのコミット前のデータを読み取る操作は可能。
通常、INSERT、UPDATE、DELETEなどの変更ステートメントでは読み取り操作を行ってから変更操作を行うといった組み合わせで行っている。

## インテントロック
下位のロック階層に位置するリソースに共有ロックまたは排他ロックがかかるのを保護する。
例えば、テーブルにインテントロックをかければ、その下位にある行やページといったものにロックをかけられることを防ぐことができる。
このメリットは、他のトランザクションがテーブルの行に対してロックをかけるときに、通常、テーブルに他のロックがかかっているか確認することになるが、行レベルでのロックは調査に時間を要するが、テーブルにインテントロックがかかっていればロックの存在にすぐ気づくことができるのでパフォーマンスが向上する。

インテント共有、インテント排他、インテント更新、インテント排他付き共有、更新インテント排他がある。

## スキーマロック[Sch-Mロック]
テーブルへの同時ロックを防ぐ。すなわち、外部からの操作をすべてブロックすることができる。

## 一括更新ロック
データをテーブルに一括コピーする際に一括更新(BU)ロックを使用する。存在だけまずは知っておけばよし。

## キー範囲ロック
T-SQLで読みとっているレコードセットに含まれている行の範囲を暗黙的にロックしてくれる。
GithubでPull Request テンプレートを使用するには？

### はじめに
GitHubは、ソフトウェア開発者がコードを管理、共有、コラボレートするための便利なプラットフォームです。Pull Request（PR）は、GitHubで最も重要なコラボレーション機能の一つです。PRテンプレートを使用することで、レビューやバージョン管理が効率化され、チームの生産性が向上します。このブログでは、GitHubでPull Requestテンプレートを使用する方法を説明します。

### Pull Requestテンプレートとは？
Pull Requestテンプレートは、プロジェクトに参加している開発者が、PRを作成する際に指定されたフォーマットや情報を提供するためのテンプレートです。これにより、レビュアーはPRの目的や変更点を迅速に理解し、効率的にフィードバックを提供できます。

### テンプレートの作成方法
Pull Requestテンプレートを作成するには、以下の手順に従ってください。

1. GitHubリポジトリのルートディレクトリに`.github`フォルダを作成します。
2. `.github`フォルダの中に`PULL_REQUEST_TEMPLATE.md`という名前のファイルを作成します。
3. 作成したファイルにテンプレートの内容を記述します。Markdown形式で記述してください。

### テンプレートのカスタマイズ方法
テンプレートをカスタマイズするには、`PULL_REQUEST_TEMPLATE.md`ファイルに必要なセクションや情報を追加します。例えば、以下のようなセクションを含めることができます。

- 目的: PRの目的を説明するためのセクションです。
- 変更点: このPRで加えられた変更点や修正箇所をリストアップします。
- 影響範囲: このPRが影響を及ぼす範囲や他の機能への影響を説明します。
- テスト: このPRに関連するテストケースやテスト方法を記載します。

#### サンプルテンプレート
```markdown
## 概要

このセクションでは、このPRの目的と概要を簡潔に説明してください。

## 変更点

このセクションでは、具体的な変更点や修正箇所を箇条書きでリストアップしてください。

- 変更点1
- 変更点2
- 変更点3

## 影響範囲

このセクションでは、このPRが影響を及ぼす範囲や他の機能への影響を説明してください。

## テスト

このセクションでは、このPRに関連するテストケースやテスト方法を記載してください。

- テストケース1
- テストケース2
- テストケース3

## 関連Issue

このセクションでは、このPRが関連するIssueやタスクをリンクしてください。以下のように記述します。

- 関連Issue: #123
```

### 複数のテンプレートを使用する方法
プロジェクトによっては、複数のPRテンプレートが必要な場合があります。
それぞれのテンプレートは、異なる種類のPRに対応するように設計されています。複数のPRテンプレートを使用するには、以下の手順に従ってください。

1. `.github`フォルダ内に`PULL_REQUEST_TEMPLATE`という名前のサブフォルダを作成します。
2. 作成した`PULL_REQUEST_TEMPLATE`フォルダ内に、異なる種類のPRに対応するテンプレートファイルを作成します。例えば、`feature_template.md`、`bugfix_template.md`などです。
3. それぞれのテンプレートファイルに、対応するPRタイプに応じたセクションや情報を記述します。
これで、複数のPRテンプレートが利用可能になります。PRを作成する際に、URLにtemplateクエリパラメータを追加して、適切なテンプレートを指定できます。例えば、次のようになります。

これで、複数のPRテンプレートが利用可能になります。PRを作成する際に、URLにtemplateクエリパラメータを追加して、適切なテンプレートを指定できます。例えば、次のようになります。

```bash
https://github.com/your_username/your_repository/compare/your_branch?template=feature_template.md
```

### まとめ
GitHubでPull Requestテンプレートを活用することで、開発者が効率的にコラボレートし、コードの品質を向上させることができます。テンプレートをカスタマイズして、プロジェクトの要件に合わせた情報を提供することで、レビューアーが迅速に理解し、適切なフィードバックを提供できるようになります。さらに、複数のテンプレートを利用することで、さまざまな種類のPRに対応し、開発プロセスを円滑に進めることができます。

https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository

https://blog.tara.ai/github-pull-request-template-draft/

https://learn.microsoft.com/en-us/azure/devops/repos/git/pull-request-templates?view=azure-devops
【その２】ポイ活対象の決定、処理確認【Power Automate】

<br>[【その１】RPA初心者と歩むPower Automate活用日記【ポイ活】](https://qiita.com/tantanshio/items/2b741584f65d8ce967f8)


# ◆ポイ活対象について

【[TIPSTAR](https://link.tipstar.com/rmRRhVuBR4UNzEjz6)】というアプリを利用


その１にて基準に設けた以下基準をいずれもクリアできるため。
> 　①利用規約に反しないもの
　②周りがあまり自動化を進めていなそうなもの
　③簡易処理で出来そうなもの
　④Excel利用しないもの


自動化に関する規約も無く、

1時間に2回発生する動画広告をクリック　という単純作業でゲーム内通貨を獲得できる。





## ◆実行前の注意点

上記アプリ（TIPSTAR）はブラウザ版も存在しているが
ブラウザ版では動画広告が発生しないため、自動化が行えない。


そのため、アンドロイドのエミュレータを用意し
アプリを立ち上げ、そこから動画広告をクリックさせることとする。


## ◆処理工程の確認


①「動画CMを観て～」を選択

![WS000001.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/c9021264-9657-9196-0ea8-83095fc152c8.jpeg)

②「視聴する」を選択
![WS000002.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/f9e9f5d7-597d-19c1-3b35-f3ebfb3a55b0.jpeg)

③動画視聴（30～60秒）を行い、右上の×を選択
![WS000003.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/74d33635-743c-51c0-be21-05cf736ce1a1.jpeg)

④「達成」マークのついたプレゼントボックスを選択
![WS000004.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/44c04a18-2262-1491-f60b-e256a175c8f9.jpeg)

⑤「受取る」を選択
![WS000005.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/97db1d01-daaa-483a-40d2-e68546a06693.jpeg)

⑥「閉じる」を選択
![WS000006.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2523511/55d1e2cd-4f24-7033-590f-3c69f19f3d9d.jpeg)


⑦画面①に戻るので、2個目の動画視聴を行う。

※毎時、00分に広告は更新される。


# ◆次回　【その３】実際にPowerAutomateでロボットを作る
Ruby on RailsでJSONパーサーAPIを作ってみる。

# はじめに

naritomoと申します。

本職はインフラエンジニアを行っています。
これまでアプリ領域の技術習得のため、各種言語の開発環境Dockerの構築を行ってきましたが、Railsでのアプリ第一号を作ってみましたので、公開したいと思います。

いろいろアドバイスいただけると嬉しいです。

## 開発概要

以下の仕様とします。

* API稼働フレームワークはRuby on Railsを使用する。
* API入力は、以下のものを入力する。
  - URLにクエリでJSONキーを指定する。(?key=key1)
  - POSTボディーにJSONデータを入れる。
* API出力は以下のものとする。
  - クエリで指定したJSONキーに対応した値をプレーンテキストで出力する。

## 事前準備

以下の記事を参考にRuby on Rails開発環境を構築してること。
Railsサイトを参照できること。
プロジェクトフォルダ(src)に移動する。

https://qiita.com/naritomo08/items/b39d4ee6987fb052ca79

## API構築方法

### APIソース作成

コントローラファイルを作成する。

```bash
vi app/controllers/api/v1/data_controller.rb
```

ファイル内容

```bash
module Api
  module V1
    class DataController < ApplicationController
      skip_before_action :verify_authenticity_token

      def extract
        json_data = JSON.parse(request.body.read)
        query_key = params[:key]

        if json_data.key?(query_key)
          render plain: json_data[query_key]
        else
          render json: { error: "Key '#{query_key}' not found in JSON data" }, status: :bad_request
        end
      end
    end
  end
end
```

ルートファイルを開く。

```bash
vi config/routes.rb
```

編集内容

以下の内容に編集する。

```bash
Rails.application.routes.draw do
  namespace :api do
    namespace :v1 do
      post 'extract', to: 'data#extract'
    end
  end
end
```

### 動作確認

新しいターミナルを立ち上げ、以下のコマンドを入力する。

```bash
curl -X POST -H "Content-Type: application/json" -d "{"name": "John", "age": "30"}" "http://localhost:3000/api/v1/extract?key=age"
```

30という値が返ってくること。

# おわりに

Railsでのアプリ開発第一歩として、JSONパーサーAPIを構築してみました。

この作成にはchatgptも利用して構築しています。

この記事がRailsでのAPIを作ってみたい方の助けになればと思います。
stylelintを基本からまとめてみた【入門】

## styelintとは？
チーム全体で使うCSSのエラーを回避し、コードの一貫性を高めるために役立つ モダンなlinterで、スタイルのエラーを自動的に修正してくれ、使用したいルールだけを有効にし、好みに合わせて設定することができる。

## 環境構築
stylelintをインストール
```
// CSS の場合
npm i --save-dev stylelint-config-standard
// SCSS の場合
npm i --save-dev stylelint-config-standard-scss
```
プロジェクトのルートに設定ファイル.stylelintrc.js を作成
```
touch .stylelintrc.json
```
設定ファイルにルールを追加


```.stylelintrc.js
module.exports = {
     // CSS の場合
    "extends": "stylelint-config-standard",
     // SCSS の場合
    "extends": "stylelint-config-standard-scss",
}
```
## Prettier と stylelintを併用して使う場合

prettier はコードのフォーマットを管理するために使用される。
prettier があるフォーマットを設定すると、stylelint はエラーとして検知して prettier と衝突することがある。
『stylelint-config-prettier』を設定に含めることで、衝突するフォーマットを無効にすることができる。
※ この設定は、ルールが上書きされないように、extends の最後に参照される設定にすること

```
{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-prettier",
  ]
};
```


## 参考サイト
[CSSをメンテナブルにするstylelint入門](https://zenn.dev/ignorant_kenji/articles/b331600a5c48d0)
[【CSS】CSS や SCSS を整えるリントツールである stylelint の紹介](https://cpoint-lab.co.jp/article/202205/22840/#:~:text=stylelint%20%E3%81%AF%20CSS%20%E9%96%A2%E9%80%A3%E3%81%AE,%E3%81%AA%E3%81%A9%E3%82%92%E6%A4%9C%E5%87%BA%E3%81%A7%E3%81%8D%E3%81%BE%E3%81%99%E3%80%82)
[CSSをメンテナブルにするstylelint入門](https://zenn.dev/ignorant_kenji/articles/b331600a5c48d0)
脆弱性だらけのプロダクトの Hardening のはじめかた

ベンチャー企業では事業成長優先で突き進んだ故に、気づけば脆弱性だらけのプロダクトとなっているケースがあります。この記事では、「AWS + Github」を利用した環境の　WEB システムのプロダクトにおける Hardening のはじめかたを紹介します。

# 可視化

AWS 環境で稼働する、OS・ミドルウェア・ソフトウェア・クラウドの脆弱性の把握と現状のサイバー攻撃の状況を把握することが必要です。今回は以下の４つの機能を有効にし可視化することをお勧めします。

### AWS SecurityHub

AWS Security Hub は、　AWS のセキュリティがベストプラクティスのチェックに従っているか自動的にチェックをし情報を集約してくれます。主に「AWS 基礎セキュリティのベストプラクティス v1.0.0」のセキュリティスコアの「重要」と「高」の失敗した件数を評価軸として残すことがおすすめです。

以下のベストプラクティスへの適合をチェックできます。

- AWS 基礎セキュリティのベストプラクティス
- CIS AWS Foundations Benchmark
- NIST Special Publication 800-53
- PCI DSS

以下は SecurityHub の表示の例です。

![securityhub.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44348/d38cd5bf-637f-758a-142e-b6c9d576a6bb.png)

### AWS Inspector
AWS Inspector は、EC2・Lambda・コンテナをスキャンして、CVE に一致する主に　OS やミドルウェアなどの脆弱性を検出します。「緊急」と「高」の件数を評価軸として残すことがおすすめです。

![inspector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44348/3c0b3075-7dc4-eb29-a26e-07f5f3930972.png)

### Github Dependabot alerts
Github Dependabot alerts はリポジトリ内の依存関係（例：Gemfile.lock）から CVE に一致する脆弱性を検出します。Serverity より「Critical」と「High」の件数を評価軸として残すことがおすすめです。

以下の言語に対応しています。
- Ruby
- JavaScript
- Python
- PHP
- Elixir
- Elm
- Go
- Rust
- Java
- .NET

以下は Dependabot alerts の表示の例です。

![dependabot_serverity.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44348/697a89af-291a-f209-4c44-1354330c0b02.png)

### AWS WAF
AWS WAF によって外部からのサイバー攻撃の推移を示すことで、発生頻度より緊急度を示すことができます。以下の例ですと、20,000 回もサイバー攻撃を受けていると危機感を説明することができます。

![waf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44348/92420df1-b24e-b819-dcff-13f4faef7c53.png)
 
# 説得

Hardening Project を進めるには予算が必要で経営層や他部署に理解を得る必要があります。

以下に示す「機会損失」と「発生確率」を算出し示すことがおすすめです。

### 機会損失の算出

⼀般社団法⼈⽇本サイバーセキュリティ・イノベーション委員会（JCIC）によると⽇本国内で情報流出等が発⽣した場合の被害損失は以下のとおりです。

- 株価が平均10%下落
- 純利益は平均21%減少

信用失墜し、再発防⽌対応や事故対応調査のための特別損失を被るより、Hardening Project　を実施することが費用対効果で有効であることが説明できます。また、他にも以下のキーワードで説明することも有効です。

- 社会的信用失墜
- 対応・賠償コスト
- 罰則・法的責任

### 発生確率の算出

可視化によって得られた脆弱性の数から、「重要」や「Critical」がある場合は攻撃の容易性を示し発生確率が高いことを説明できます。

| 定量的指標 | ツール | 説得例 |
|:-----------|------------|:------------|
| AWS クラウドの脆弱性 | AWS SecurityHub| AWS が提唱するベストプラクティスに沿わない X 件の重要とされる脆弱性がある|
| OSやミドルウェアのソフトウェアの脆弱性数 | AWS Inspector | 世界的で標準とされる脆弱性として識別される CVE で定義される X 件の緊急の脆弱性がある|
| 自社ソフトウェアの脆弱性数 | Github Dependabot alerts | 同上 |
| サイバー攻撃の推移 | AWS WAF | 直近で１日あたり X 件のサイバー攻撃が発生しており早急な対応が必要である |

また、上記の OWASP Top 10 と照らし合わせて、該当する脆弱性がある場合は、最も重大な　10　のリスクについてのランキングに合致することから早急な対応が必要であると言えます。

さらに、脆弱性に対してどのような悪影響があるのか STRIDE に分類することで網羅的に説明ができます。STRIDE はマイクロソフトが開発した脅威分析モデルです。

| 頭文字 | 英語 | 日本語 |
|:-----------:|:------------|:------------|
| S | Spoofing of user identity | 偽造 |
| T | Tampering | 改竄 |
| R | Repudiation | 否認 |
| I | Information　disclosure | 情報漏洩 |
| D | Denial of service | サービス拒否 |
| E | Elevation of privilege | 権限昇格要 |

情報漏洩は起こってからでは取り返しがつきません。社会的責任であり費用対効果が高いことが多いため、正しくコミュニケーションをとることで、救世主になることができます。
PHP/LaravelでJSONパーサーAPIを作ってみる。

# はじめに

naritomoと申します。

本職はインフラエンジニアを行っています。
これまでアプリ領域の技術習得のため、各種言語の開発環境Dockerの構築を行ってきましたが、laravelでのアプリ第一号を作ってみましたので、公開したいと思います。

いろいろアドバイスいただけると嬉しいです。

## 開発概要

以下の仕様とします。

* API稼働フレームワークはPHP/Laravelを使用する。
* API入力は、以下のものを入力する。
  - URLにクエリでJSONキーを指定する。(?key=key1)
  - POSTボディーにJSONデータを入れる。
* API出力は以下のものとする。
  - クエリで指定したJSONキーに対応した値をプレーンテキストで出力する。

## 事前準備

以下の記事を参考にPHP/Laravel開発環境を構築してること。
Laravelサイトを参照できること。
プロジェクトフォルダ(backend)に移動する。

https://qiita.com/naritomo08/items/a66f4647c13a6c4a920e

## API構築方法

### APIソース作成

コントローラファイルを作成する。

```bash
vi app/Http/Controllers/ExampleController.php
```

ファイル内容

```bash
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class ExampleController extends Controller
{
    public function example(Request $request)
    {
        // クエリパラメータを取得
        $key = $request->query('key');

        // リクエストボディをJSONから配列に変換
        $data = $request->json()->all();

        // キーが存在する場合は、指定されたキーに対応する値を返す
        if ($key && isset($data[$key])) {
            return response($data[$key], 200)->header('Content-Type', 'application/json');
        }

        // キーが指定されていない場合は、すべてのデータを返す
        return response()->json($data);
    }
}
```

ルートファイルを開く。

```bash
vi routes/api.php
```

編集内容

```bash
以下の行を追記する。
use App\Http\Controllers\ExampleController;

Route::post('/json', [ExampleController::class, 'example']);
```

### 動作確認

新しいターミナルを立ち上げ、以下のコマンドを入力する。

```bash
curl -X POST -H "Content-Type: application/json" -d "{"name": "John", "age": "30"}" "http://localhost:8080/api/json?key=age"
```

30という値が返ってくること。

# おわりに

Laravelでのアプリ開発第一歩として、JSONパーサーAPIを構築してみました。

この作成にはchatgptも利用して構築しています。

この記事がLaravelでのAPIを作ってみたい方の助けになればと思います。
Rails – 今更だけど credentials.yml.enc / secret_key_base の扱いがよく分かってなかった

# つながり

- `credentials.yml.enc` でどんな値でも暗号化/複合できる
- `master.key` の値で `credentials.yml.enc` を複合出来る
- `secret_key_base` は秘密情報なので `credentials.yml.enc` に含めておくのが良い

ということらしい

#  rails new

そもそも rails new した時に 

- `config/credentials.yml.enc`
- `config/master.key`

がセットで生成されるようだ

`master.key` はただ復号用の値を記録しただけのファイルなのだが、この値があれば `credentials.yml.enc` を複合したり編集したり出来る

だが `master.key` は `.gitignore` に含まれているので git操作で消えている場合もあるだろう

# 編集

`bin/rails credentials:edit` でファイル編集が出来るはずなのだが怒られた

-  `master.key` がないので自動生成してくれた
- `config/credentials.yml.enc` を暗号化したのは別の `master.key` だったので複合は出来ない

ということみたいだ

```
EDITOR=vi bin/rails credentials:edit
Adding config/master.key to store the encryption key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Save this in a password manager your team can access.

If you lose the key, no one, including you, can access anything encrypted with it.

      create  config/master.key

Couldn't decrypt config/credentials.yml.enc. Perhaps you passed the wrong key?
```

credentials の編集が初めての場合は  credentials を削除してやり直してしまおう

```
rm config/credentials.yml.enc
EDITOR=vi bin/rails credentials:edit
```

以下のようなテンプレ内容が生成されるので、そのまま保存してみる

```
# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

# 再編集

これで準備が整った
`master.key` ファイルがあればこのまま編集し続けられる。

```
EDITOR=vi bin/rails credentials:edit
```

`master.key` ファイルが無くても環境変数で値指定すれば複合・編集が可能だ

```
RAILS_MASTER_KEY=yyyyyyyyyyyyyyyy EDITOR=vi bin/rails credentials:edit
```

# 編集できない場合

エディタ指定が変だとエラーもなく終了してしまうようだ

```
EDITOR=waaaaaaa bin/rails credentials:edit
File encrypted and saved.
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Nuxt3でMicroCMSの画像をレスポンシブ画像として表示する

# まえがき
[前回の記事](https://qiita.com/ddg171/items/fcdf949d54e50609ce75)でNuxt3に導入したNuxt/Imageを実際に使ってみる。ただそのまま使っても公式ドキュメントの内容を機械翻訳したのとあまり変わらないので、今回はMicroCMSの画像フィールドから取得した画像をレスポンシブ画像として表示してみる。
# 環境
- node.js v18.13.0
- Typescript v4.7.4
- Nuxt v3.0.0-rc.14
- TailwindCSS v3.2.4
- @nuxt/image-edge v1.0.0
※Vueは当然3.0系
開発環境はWSL(Debian)だったりChromeOS(Crostini+Debian)だったり色々。
# 手順
Nuxt/Imageは外部の画像処理サービスやライブラリと連携することができる。MicroCMSの画像APIはimgixを利用しており、設定を行えばローカルの画像を読み込むのと同じ要領でレスポンシブ画像を設定することができる
## nuxt.config.tsに設定を追加
公式ドキュメントに従い、nuxt.config.tsにimgixの設定を行う。ただしMicroCMSから取得できるURLはフルパスなのでbaseUrlは空文字列にする。

```typescript:nuxt.config.ts
import { defineNuxtConfig } from 'nuxt/config'

export default defineNuxtConfig({
  modules: ['@nuxtjs/tailwindcss', '@nuxt/image-edge', 'nuxt-icon'],
  image: {
    imgix: {
      baseURL: ''
    }
  },
})

```

## imgixをproviderに設定する。
NuxtPictureコンポーネントのprovider属性を"imgix"に設定し、src属性には画像のURLをそのまま代入する。
ちなみにproviderの初期値は"ipx"のため、ローカルの画像と混在させる場合はprovider属性を"ipx"と"imgix"とで切り替えてやれば良い。


```html:picture
        <NuxtPicture
          provider="imgix"
          :src="article.thumbnail"
          legacy-format="jpeg"
          fit="crop"
          height="500"
          width="500"
          :img-attrs="imgAttr"
          :modifiers="modifiers"
        />
```

## modifierの設定
画像の形式についてはNuxtPictureコンポーネントのpropsにある"format"と"legacy-format"に値を渡すのが正解。
それ以外のimgixのAPIを利用する場合はmodifiers属性にオブジェクトとして渡す。
※2023/9/25 [ドキュメント](https://image.nuxt.com/usage/nuxt-picture#format)を見ていたら間違いに気づいたので修正

```vuejs:modifiers
        <NuxtPicture
          provider="imgix"
          :src="article.thumbnail"
          format="webp"
          legacy-format="jpeg"
          fit="crop"
          height="800"
          width="800"
          :modifiers="{q: 50}"
        />
```

## img要素に属性を追加する。
alt属性などを追加したい場合はimg-attrにオブジェクトとして値を渡す。

```typescript:img-attr
const imgAttr={ alt:`${article.title}のサムネイル画像`,}
```

# 導入した結果
Devtoolで中身を確認して、webpとjpegの両方が設定されていれば成功。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425022/9eb2c094-9a16-ac13-fe4d-1e7558b82098.png)
試しにそれぞれのURLから画像を保存してみると両方の形式で保存できている。(ファイル名が長いので省略した。)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425022/e93d7c9e-9a7c-8f1f-886b-fffd4a9ede51.png)
こうやって見ると意外と容量に差がない。大きいサイズの画像なら差が出るかもしれない。

# 参考資料
- [Optimized images for Nuxt · Nuxt Image](https://image.nuxt.com/)
- [画像APIとは](https://document.microcms.io/image-api/introduction)
【備忘録】基本設計で仕上げる成果物


## はじめに

個人開発しようと考え、いざ着手しようとしたが何から手を付けたらよいか全く見当がつきませんでした。そんな中で下記の記事を読み、このロードマップに従って取り組んでいこうと考えました。

[Pythonでゼロからでもサービス開発・公開できる学習ロードマップ](https://qiita.com/Saku731/items/52a3bbacd002f26f408e)

### 【記事の概要】
本記事は、以下の点に重きを置いています。

- 基本設計の手順
- 基本設計で作成される成果物
- 成果物に盛り込む内容

下記の方向けではありません。

- 初めて基本設計を行う方
- 基本設計について詳しく知りたい方


今回、記事を書くにあたり下記の講座を参考にさせていただきました。

■入門編：

https://www.udemy.com/course/digisaku_requirements_definition_and_system_design/?couponCode=6749911953C418843C45

基本設計に関する詳細な説明・具体的な成果物の内容を知りたい方は、ぜひこの講座を参考にされてください。


## 基本設計

**目的**
要件定義を実現するシステムの完成イメージが、ビジネス側に伝わること。
つまり、エンジニアが主導。

**成果物**
 - 画面設計 

 - 機能設計 

 - データ設計

**進め方**

①画面設計

②機能設計

③データ設計

④全体見直し・ブラッシュアップ

:::note info
設計は、不備が見つかれば都度修正する。「要件定義書」も随時更新する。
:::


## 【実践】①画面設計
```変わらない画面情報を設計する（HTMLに直接書くところ）```
使用ツール⇒PowerPoint, Figmaなど

①項目の洗い出し
 - 登場するオブジェクト（モノ・情報） => （ユーザーが「ほしいもの」）
 - オブジェクトに対するユーザーのタスク（操作） => （ユーザーが「やりたいこと」）

②画面遷移図を作る
 - オブジェクト指向 or タスク指向かを決める
 - 画面遷移図を作成する

③肉付け
 - ユーザー操作（タスク）を各画面に割り当てる
 - 画面遷移図の項目ごとのオブジェクトに対し、肉付けを行う（小項目を作る）
 - タスクを追加する（あれば）
 - オブジェクトに対し、ユーザーに表示する情報を洗い出す

④レイアウト作成
- オブジェクト・タスクに沿ったレイアウトの作成

:::note warn
**オブジェクトとタスクに抜け漏れがない**ようにする
:::

この時点で、要件定義書に無い機能を追加することがある

- レイアウトをもとにデザイン性を追求

デザイナーに依頼するなど

- 作成したレイアウトを、再び画面遷移図に落とし込む



## 【実践】②機能設計
``` 毎回変わる情報を表示させるための機能を設計する。```
使用ツール⇒PowerPoint, Figma, Excelなど

:::note info
毎回変わる情報
- **マスターデータ**
=>オブジェクトに固有の情報のこと

- **トランザクションデータ**
=>ユーザー操作で増減するデータ
:::



①マスターデータの洗い出し
- 必要なデータベースの洗い出し（何個できたか？）

②ユーザー操作で起こる処理を洗い出し

- バックエンド処理の洗い出し
- 処理に対するDBの洗い出し
- トリガーの洗い出し

③機能一覧書の作成

- 必要なデータベース・処理を一覧化
-  Excelにまとめる
    - 以下の内容を記載
        >- NO.
        >- 対象ページ
        >- 処理内容
        >- トリガー
        >- 必要なデータ（DB）/取得元
        >- データの渡し先（DB、渡し先のページ)
 

- トリガーとバックエンド処理を一覧化（箇条書き）
- トリガー(ユーザー操作）とバックエンド処理を画面遷移図に紐づけ
:::note warn
このとき、**操作**と**処理**はしっかりと区別しておく
:::

## 【実践】③データ設計
```ER図を作成する```
使用ツール⇒PowerPoint, Figmaなど


:::note 
**ER図**
*DB構造を可視化するもの*
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124182/f787bcc0-390d-5822-9c3c-763f1b9aefb3.png)

画像引用元：[若手プログラマー必読！５分で理解できるER図の書き方５ステップ](https://it-koala.com/entity-relationship-diagram-1897)
:::
ER図に利用する記号↓
| 記号 | 意味 | 
|:-----------|------------:|
| 〇       | 0（ゼロ）        | 
| \|     | 1（イチ）      | 
| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3124182/2f12b967-4af6-3f5a-aaa6-bcae7f502b10.png)<br>鳥の足| 多        | 


:::note
**DBの基礎知識**
- **構造**
    - table
    -  colum
    -  record
 - **テーブルの種類**
   - マスタ
   ＝＞オブジェクト固有の情報を保存したテーブル
   - トランザクション
   ＝＞マスタ以外のテーブル
   ユーザーがアクションするたびに更新されるテーブル

 - **外部キー**
 ＝＞IDを使用して別のテーブルに情報を挿入するためのもの
:::


①データ構造を明確にする

- テーブルをマスタ・トランザクションに分ける
- 具体的なテーブル構造を決定する（カラムの設定）

②データ間の関係性を定義

- テーブル間の参照関係を可視化する（外部キーとして参照してるもの）

③ER図に書き起こす
 - 一番上にはメインのIDを記載
 - 外部キーには（FK）を記載・太字にする

④設計書をまとめる
- 画面遷移図に、テーブルを紐づける





## おわりに
オブジェクトに対してタスクを探していると、
どうやって実装していくかが明確になっているように感じました。

「自分にはできない」と思っていたシステム開発が、
少しずつ「できるかもしれない」に変わっていくのが楽しいです。

ちなみに、私はどのフェーズの設計でも不備が何度も見つかり、都度修正しました。
出来上がった設計書はお世辞にも「わかりやすい」とは言えないのですが、
アプリの完成形を具体的にイメージすることができました。
引き続き、アプリ開発を進めていきたいと思います。


閲覧ありがとうございました。