OmniAICreator/Qiita-1.07M huggingface dataset:
MFC から SVG クラスの基本図形呼び出しコードサンプル(1/2)

## MFC から SVG クラスの基本図形呼び出し
MFC の GDI+ で出力するサンプルコードと SvgImage クラスに出力するサンプルコードを比較しながら基本図形をどのように出力していくかを確認していきます。

## MFC(GDI+) と SvgImage のライン出力

MFC(GDI+) でラインを描いている箇所が以下のようにあるとします。
```cpp
	Gdiplus::Pen pen(Color(255, 0, 0, 0));
    graphics.DrawLine(&pen, 0, 0, 100, 100);
```

これを SvgImage に対して描くと次のようになります。

```cpp
    pImage->AddLine(0, 0, 100, 100)
    pImage->AddAttrStroke(RGB(0, 0, 0), 1, PS_SOLID);
```
Gdiplus::Pen クラスの設定項目を SVG タグの属性値として設定する必要があるため描画関数の呼び出し順序が逆になっています。
Gdiplus::Pen のように描画前にペンやブラシなどの設定項目を反映させたい場合は SvgImage クラスにたいして使える属性値をセットにしたクラスオブジェクトを作成する必要があります。

CPoint クラスでポイントを指定したい場合は関数をオーバーロードして宣言してください。

## MFC(GDI+) と SvgImage の接続された複数のライン
１辺が解放されている八角形を描く例です。

MFC(GDI+) の場合以下のようになります。
```cpp
    Gdiplus::Point poly[8];
    int nPoints = 8;
    poly[0] = Gdiplus::PointF(10,20);
    poly[1] = Gdiplus::PointF(20,10);
    poly[2] = Gdiplus::PointF(30,10);
    poly[3] = Gdiplus::PointF(40,20);
    poly[4] = Gdiplus::PointF(40,30);
    poly[5] = Gdiplus::PointF(30,40);
    poly[6] = Gdiplus::PointF(20,40);
    poly[7] = Gdiplus::PointF(10,30);
    Gdiplus::Pen pen(Color(255, 0, 0, 0));
    pGraphics->DrawLines(&pen, poly, nPoints);
```

SvgImage に書き出すと以下のようになります。
```cpp
    CPoint poly[8];
    int nPoints = 8;
    poly[0] = CPoint(10,20);
    poly[1] = CPoint(20,10);
    poly[2] = CPoint(30,10);
    poly[3] = CPoint(40,20);
    poly[4] = CPoint(40,30);
    poly[5] = CPoint(30,40);
    poly[6] = CPoint(20,40);
    poly[7] = CPoint(10,30);
    pImage->AddLines(poly, nPoints)
    pImage->AddAttrStroke(RGB(0, 0, 0), 1, PS_SOLID);
```

普通のラインの項目と同様に大きな差分はありません。

## MFC(GDI+) と SvgImage の多角形出力
八角形を描く例です。

MFC(GDI+) の場合以下のようになります。
```cpp
    Gdiplus::Point poly[8];
    int nPoints = 8;
    poly[0] = Gdiplus::PointF(10,20);
    poly[1] = Gdiplus::PointF(20,10);
    poly[2] = Gdiplus::PointF(30,10);
    poly[3] = Gdiplus::PointF(40,20);
    poly[4] = Gdiplus::PointF(40,30);
    poly[5] = Gdiplus::PointF(30,40);
    poly[6] = Gdiplus::PointF(20,40);
    poly[7] = Gdiplus::PointF(10,30);
    Gdiplus::Pen pen(Color(255, 0, 0, 0));
    pGraphics->DrawPolygon(&pen, poly, nPoints);
```

SvgImage に書き出すと以下のようになります。
```cpp
    CPoint poly[8];
    int nPoints = 8;
    poly[0] = CPoint(10,20);
    poly[1] = CPoint(20,10);
    poly[2] = CPoint(30,10);
    poly[3] = CPoint(40,20);
    poly[4] = CPoint(40,30);
    poly[5] = CPoint(30,40);
    poly[6] = CPoint(20,40);
    poly[7] = CPoint(10,30);
    pImage->AddPolygon(poly, nPoints)
    pImage->AddAttrStroke(RGB(0, 0, 0), 1, PS_SOLID);
```
こちらも大きな差分はありません。
SvgImage クラスの描画が MFC の描画に近づけてあることもありますが、描画を行う上で最低限必要な情報だけ抽出を行うと描画ライブラリと似通ってくるのではないかと思います。
用途に合わせて関数をオーバーロードや追加などしてカスタマイズしてください。
マネージメント必見tips：相手を思った通り動かす方法

**Any code doesn't run as you thought, run as it wrote.
プログラムは思った通りには動かない。書いた通りに動くのだ**

プログラムの格言としての言葉です。
深い言葉です。色々と考えさせられます。
それにかっこいい。

# プログラマーは誰でも思ったはず
>えっなんでだろう？
そんなはずはない？
プログラム言語のバグだ。
ライブラリーのバグだ。
Apaceのバグだ。

ほとんどの場合は、自分のソースコードのバグです。人は、自分を信じて他人の性にしがちな生き物です。
思い込み状態でソースコードを見るので、真剣に読んでる様で全くバグに気づきません。
他人に見てもらうとあっという間にバグが発見されたりする事もよくあります。
紳士に**プログラムは思った通りには動かない。書いた通りに動くのだ**を受け入れる必要があります。

# 他人との関係でもよくある話です
自分がとった行動から、特定の相手の行動を期待してたが、思った通りの行動が受けられないので相手が間違ってると思ってしまいます。
例えば、
・朝、おはようと挨拶したけど相手に無視された。→　小さい声で聞こえてなかっただけ。
・新しい仕事を喜んでくれると思っていたが　→　その人にとっては新しい仕事でなかった。
・納期を指示していたのに　→　成果物の定義が正しく伝わって無く成果物が違った。
自分の行動が全ての結果に結びついていて、相手がイレギュラーの行動をしている訳ではない。

# 相手は思った通りには動かない、自分が行動した通りに動くのだ
人の場合は、ソースコードと違って必ず同じ行動を取るわけではないので勘違いしやすいですが、やっぱり、**相手は思った通りには動かない、自分が行動した通りに動くのだ**
他責にせずに自責で考えてみる。マネージメントの基礎です。

# ポイントはゲーム感覚
相手が人なので期待してしまいます。期待するとその行動が裏切られた時にショックを受けます。腹が立ちます。
ゲームと思って期待値をなくしてみます。自分の行動次第で未来が変わるゲームと思い込みます。事前準備で相手の心が動いてるのが感じられます。対戦相手毎に攻略法を自分で考えます。上手く行った時の喜びは格別です。失敗しても期待値が無いので、腹も立ちません。自分のゲーム操作ミスです。
ゲーム感覚でチャレンジしてみてください
備忘録：grepコマンドの正規表現で$を使った行の終端一致が効かない謎

# 起こったこと
プログラミング・エンジニアリング初学者です。
正規表現の勉強中、grepコマンドでテキストファイルの行の終端にある文字列を「文字列$」のような表記で検索しようと試みたところ、明らかに存在するはずなのにヒットしませんでした。
（書籍「独学プログラマー」の学習中に詰まったポイントです。同じところで詰んでいる方の助けになれば幸いです…）

# 原因
改行方式の違い。
自分のPCがWindowsで、改行が「CRLF」という方式になっていた。
これを「LF」方式で保存しなおしたファイルで試したところ、検索がヒットするようになった。

LFはLinuxで使われる改行方式らしいです。
Windows環境で作成したテキストファイルをUbuntuのEC2にアップロードしてSSHで利用していたのでこんな感じになってしまっていました。

# 改行方式の変更方法
0. VS codeでテキストファイルを開く
0. 画面下部の「CRLF」とあるところをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2825787/aed9b80a-0a7e-38c2-7dd2-d96245f38654.png)
0. 「改行コードの選択」で「LF」を選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2825787/69dde019-ab5b-f16e-4782-0fc50773550c.png)
0. ファイルを保存する

以上です。




P.S.
お読みいただきありがとうございます:bow:
学び始めて間もないため、内容が不正確だったりもっと良い方法があったりすることもあるかと思います。
もしお気づきの点がある際は、お知らせいただけたら大いに助けになります。ぜひお願いいたします。
BigQuery Data Transfer Serviceで高頻度でデータ連携を行う方法

BigQuery Data Transfer Serviceを使うとS3などの外部データソースからBigQueryにデータ転送を簡単に行うことができます。
しかし、転送間隔は最短でも24時間ですので、これ以上の高頻度でデータ転送を行う場合には工夫が必要です。

https://cloud.google.com/bigquery/docs/s3-transfer#limitations

この記事では1日に複数回の転送をBigQuery Data Transfer Serviceで行う設定方法を紹介します。

1つの転送設定だけでは1日に1回しか転送できないのであれば、転送設定を複数個作れば高頻度での転送を行えます。
例えば1日に2回の転送を行いたい場合には、以下のようにします。
scheduleとdisplay_name以外は完全に共通の転送設定を2つ作成します。

```terraform
resource "google_bigquery_data_transfer_config" "s3-transfer-1" {
  display_name           = "表示名"
  data_source_id         = "amazon_s3"
  schedule               = "every day 00:00"
  destination_dataset_id = "転送先データセット"
  params = {
    ...
  }
}

resource "google_bigquery_data_transfer_config" "s3-transfer-2" {
  display_name           = "表示名"
  data_source_id         = "amazon_s3"
  schedule               = "every day 12:00"
  destination_dataset_id = "転送先データセット"
  params = {
    ...
  }
}
```
Godot Engine "... after yield, but script is gone. ..." エラー対策

# はじめに

[Peanuts Codeさん](https://www.peanuts-code.com/ja/) の Tutorial で Godotを学習中。こんなに充実したコンテンツを提供してもらい感謝しきれません:pray:
ブロック崩し制作を終えて、現在はプラットフォーマー制作を学習中。

今回のエラー現象、ブロック崩しの時は Part14 で対処されていたが、プラットフォーマー制作では（未着手ページを斜め読みしたところ）見当たらなかったので、自分なりに対処したことを記録しておくことにしました。


# 環境
- Windows版 Godot Engine Ver.3.5(stable)
- GDScript

# 現象
Godot で作るプラットフォーマー [Part 5](https://www.peanuts-code.com/ja/tutorials/gd0005_platformer/platformer_5/)、[Part 7](https://www.peanuts-code.com/ja/tutorials/gd0005_platformer/platformer_7/) において、最弱敵キャラである Mushroom が Playerに踏まれて死ぬ、もしくはステージの切り替わり時にレベルシーンごと抹消される際、
```text: error
resume: Resumed function '_on_Timer_timeout()' after yield, but class instance is gone. At script: res://*****
```
というエラーが発生する。（エラーにならない時もある。Mushroomインスタンスが削除されるタイミング次第）

エラーの対象箇所はMushroom のスクリプト、歩行・停止の待ち時間制御部
`yield(get_tree().create_timer(2), "timeout")` 

この方法は、[公式リファレンス](https://docs.godotengine.org/ja/stable/getting_started/first_2d_game/06.heads_up_display.html#scorelabel)に 『 短い時間の一時停止であれば Timerノードの代わりに SceneTreeのcreate_timer()がある 』と紹介されている。
デバッグ実行時、エラーは出力されるが動作はします。放っておくか迷いましたが、ちゃんと対処することにしました。

# ボツ案
Playerにやられたら Mushroom自身の表示とコリジョンを消して3秒待機してから `queue_free()` する方法を実施。Playerアタックによるエラーは解消されたが、ステージ切り替え制御を追加した時にエラーが発生。

# 解決策
この方法が一番スッキリしていそうなので採用しました（リンク先の一番下）
https://godotengine.org/qa/76800/resumed-function-after-yield-but-class-instance-is-gone

1. MashroomのルートノードにTimerノードを追加。名前をYieldTimerに変更
1. コード（Mashroom.gd）の変更
    - 旧：`yield(get_tree().create_timer(2), "timeout")`
    - 新：`$YieldTimer.start(2); yield($YieldTimer, "timeout")`

Playerからのアタック、ステージ切り替え、共にエラーを解消できた。

yield実行中にルートノードのインスタンスが消える可能性がある場合は、yield実行用のTimerノードを用意することにしました。

# 最後に

まだ学習し始めなので、良し悪しの判断が付かない。もっと良い方法があるかもしれません。また、正式リリースが近づいている Godot4 では yield が廃止、await に置き換わるようです。それによって、本件気にしなくてもよくなる可能性はあります。
dockerfileのコマンドまとめmemo

## 概要:point_up:
dokcerfileのコマンドについて調べたことをまとめる

## コマンド各種:eyes:

### FROM
ベースイメージとなるdockerImageを指定する
DockerHubのイメージを指定するのが一般的
```
FROM php:8.0-fpm-alpine
```

### ENV
docker内に環境変数を設置する
```
ENV LANG ja_JP.UTF-8
```

### COPY
ホスト側のファイル・ディレクトリを
コンテナ側へコピーする
```
COPY . /app
```

### WORKDIR
Dockerfileでコマンドを実行する際に基準となるディレクトリを設定
存在しないディレクトリを指定するとディレクトリが作成される
デフォルトは /
```
WORKDIR /app
```

### RUN
Docker内でコマンドを実行する
この時複数ある場合は連続して実行すると
中間イメージというものが作成されず、イメージサイズを小さくすることができる。
```
RUN apk update && \
    apk add --no-cache --virtual .php-builds oniguruma-dev postgresql-dev nodejs npm git curl zip unzip && \
    npm install npm@latest -g
```

### USER
コンテナにログインするユーザーを指定する
デフォルトはroot
```
USER app
```

### CMD
コンテナ起動時にデフォルトで実行されるコマンドを設定する
コンテナはここで設定したコマンドがフォアグラウントで実行されている間が生存期間となる。
バックグラウンドで実行するとコンテナプロセスが終了する。
そのためフォアグラウンドで実行するように設定する。
```
CMD ["npm", "run", "start"]
```

### EXPOSE
コンテナ起動時に公開するポート番号を指定する。
```
EXPOSE 80
```
ホスト側とコンテナのポートを紐付けは
```
$ docker run -p 80:80
```

### VOLUME
Data Volumeを作成する
build時にボリュームが作成される。
```
VOLUME ["/app"]
```

#### AWS ECSの場合の挙動
タスク実行時にDockerfileのファイルをデータボリュームに公開するために、
AmazonECSデータプレーンがVOLUMEディレクトリを探します。VOLUMEディレクティブで指定された絶対バスが、タスク定義で指定されたcontainerPathを同じである場合、VOLUMEディレクティブパス内のデータがデータボリュームにコピーされる。次のDockerfileの例では、/var/log/exportディレクトリにあるexamplefileという名前のファイルがホストに書き込まれ、その後コンテナ内にマウントされる。
```
FROM public.ecr.aws/amazonlinux/amazonlinux:latest
RUN mkdir -p /var/log/exported
RUN touch /var/log/exported/examplefile
VOLUME ["/var/log/exported"]
```


### ENTRYPOINT
指定されたコマンドを実行する
CMDと違うのはdocker run 時に指定した引数を渡すことができる
```
ENTRYPOINT ["echo"]
```
```
$ docker run <IMAGE NAME> "hogehoge"
hogehoge
```

## dockerImage
コンテナイメージはdockerfileの1行ごとがレイアーとなっている。
イメージとしてはスナップショットという感じでしょうか?
```
$ docker history イメージ名
IMAGE          CREATED       CREATED BY                                      SIZE      COMMENT
6af75be42b5f   6 hours ago   WORKDIR /app                                    0B        buildkit.dockerfile.v0
<missing>      6 hours ago   COPY /usr/bin/composer /usr/bin/composer # b…   2.81MB    buildkit.dockerfile.v0
<missing>      6 hours ago   COPY ./sample /app # buildkit                   48.1MB    buildkit.dockerfile.v0
<missing>      9 days ago    RUN /bin/sh -c docker-php-ext-install mbstri…   2.18MB    buildkit.dockerfile.v0
<missing>      9 days ago    RUN /bin/sh -c apk update &&     apk add --n…   386MB     buildkit.dockerfile.v0
<missing>      9 days ago    ENV COMPOSER_NO_INTERACTION=1                   0B        buildkit.dockerfile.v0
```
こんな感じでレイアーを確認することができる。

## 参考
https://y-ohgi.com/introduction-docker/
pythonのmatplotlibでsinとcosグラフを作成

sinとcosのグラフを描く（凡例表示）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165847/375428a8-b767-afe0-6108-060650411f75.png)
```py
import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-2*np.pi, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, color='b', ls='-', label='y=sin(x)')
plt.plot(x, y2, color='r', ls='-', label='y=cos(x)')

plt.xlim(-2*np.pi, 2*np.pi)
plt.ylim(-1.5, 1.5)

plt.xticks([-2*np.pi, -(3/2)*np.pi, -np.pi, -(1/2)*np.pi,
           0, (1/2)*np.pi, np.pi, (3/2)*np.pi, 2*np.pi])

plt.legend()
plt.grid()
plt.xlabel('x')
plt.ylabel('y')
plt.title('sin & cos')

plt.show()
```

sinとcosのグラフ交点をプロットする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165847/1e57293b-fdc0-15f4-a10e-387acddcdb44.png)
```py
import numpy as np
import matplotlib.pyplot as plt

# np.arange 等差数列
# numpy.arange([start, ]stop, [step, ]dtype = None)
x = np.arange(0, 10, 0.01)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, '-')
plt.plot(x, y2, '-')

# argwhere 配列をnumpy.argwhere()に渡すと、値が0以外の要素のインダイスをインダイスごとに返す。
# numpy.sign() 符号を取得する。
idx = np.argwhere(np.diff(np.sign(y1 - y2))).flatten()
plt.plot(x[idx], y1[idx], 'ro')
plt.show()
```
備忘録:WindowsからUbuntuのEC2へファイルをアップする方法(scpコマンド)

# やりたいことと実現した方法
やりたい：EC2上のサーバにファイルを転送したい
実現した方法：SCPコマンドで転送

プログラミング・エンジニアリング初学者です。
書籍「独学プログラマー」にてBashを使って正規表現を学ぶセクションがあり、自身のPCがWindowsのため、Bashを利用するためにEC2インスタンスにSSH接続して利用していました。
参考書の途中でローカルのテキストファイルに対してgrepコマンドを実行する箇所がありEC2にファイルをアップする必要が出てきました。

# 環境
PC: Windows
SSHクライアント: Powershell
転送先: Amazon Web Service EC2 OSはUbuntu

# 手順
0. EC2インスタンスのSSH用pemキーをダウンロードしておく
1. Powershellを立ち上げる
2. cdコマンドでpemキーを置いているディレクトリに移動
3. 以下のコマンドを実行
`scp -i "[pemキーの名前].pem" ファイルのディレクトリ(\Users\~~) 接続先のホスト名(ubuntu@~~~~.compute.amazonaws.com):Ubuntu側のファイルを置きたいディレクトリ(/home/ubuntu/~~)`

以上です。
オプションの「-i」は秘密鍵を利用するときに必要らしいです。

# 余談：「独学プログラマー」で他に詰まった個所の話
冒頭に書いた通り、書籍「独学プログラマー」の学習中にこの箇所でややつまづきました。
（Windowsで無理やり勉強しているせいで起こったことで、書籍の内容自体はとても分かりやすくオススメです。）
同じくWindowsでこの本を勉強している方向けに、もう一か所つまづいた箇所があったので共有です。
[**grepコマンドで正規表現「$」を使った行の終端一致がうまくいかない**](https://qiita.com/misaki-kaneko/items/a1035aed88f26b708f98)というもので、対応方法を別途[記事](https://qiita.com/misaki-kaneko/items/a1035aed88f26b708f98)にまとめましたので良ければご参照ください。




P.S.
お読みいただきありがとうございます:bow:
学び始めて間もないため、内容が不正確だったりもっと良い方法があったりすることもあるかと思います。
もしお気づきの点がある際は、お知らせいただけたら大いに助けになります。ぜひお願いいたします。
Install AnyDesk to Ubuntu20.04

#  インストール手順

1.[AnyDesk公式HP](https://anydesk.com/en/downloads/linux?utm_campaign=Japan+-+Search+-+Mid+Funnel+-+DSA+-+APAC&utm_source=adwords)よりLinux用をダウンロードする。

2.ターミナルを立ち上げ、以下の手順に沿ってインストールする(user@PC:~$省略)。

まず、リポジトリキーをソフトウェア・プロバイダー・リストに登録。
```
wget -qO - https://keys.anydesk.com/repos/DEB-GPG-KEY | sudo apt-key add -
```
リポジトリを追加。
```
sudo sh -c 'echo "deb http://deb.anydesk.com/ all main" > /etc/apt/sources.list.d/anydesk-stable.list'

```
リポジトリを更新。
```
sudo apt update
```
インストールする。
```
sudo apt install anydesk
```

[参考元](https://www.nemotos.net/?p=5054)

---
<font color="yellowgreen">**QiitaLink**</font>
<font color="black">**Designed by RENOX**</font>
raspberry pi 4b で rgb led matrix を使用した場合の問題

# 配線
RGB LED matrixを使用するのは初めてで、配線については何も知りません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2982600/e9ff3386-11f9-f8eb-6eee-5dac9fa37867.png)
| 左　　| 右 |
|--|--|
| R1  |  G1  |
| B1  | GND  |
| R2  | G2  |
| B2  | E  |
| A  | B  |
| C  | D  |
| CLK | LAT/STB  |
| OE   | GND  |
## 対処方法
配線の際は、ラズベリーパイの40ピンに対応する位置にLEDの16本のケーブルを接続する必要があります。
rgb led matrix をラズベリーパイ 40　ピン に接続する方法
| rgb-led-matrix  | raspberry pi | raspberry pi  | rgb-led-matrix |
| ------------- | ------------- | ------------- | ------------- |
| R1  | 23  | 13  | G1  |
| B1  | 26  | 6  | GND  |
| R2  | 24  | 21  | G2  |
| B2  | 19  | 10  | E  |
| A  | 15  | 16  | B  |
| C  | 18  | 22  | D  |
| CLK  | 11  | 7  | LAT/STB  |
| OE  | 12  | 9  | GND  |
# 再生速度
Raspberry Pi をはじめとする Raspberry Pi からのデータ出力速度は、LED パネルとはいえ速すぎます。
画面の再生速度に影響します。

## 対処方法
hzeller のドライバーを使用して(https://github.com/hzeller/rpi-rgb-led-matrix)。
 `--led-slowdown-gpio=（1-···）`これを使用して再生速度を制御します。
速度が約200〜300に低下。

# 音との衝突
raspberry pi で rgb led matrix を使用する場合は、音をオフにする必要があります。そうしないと、rgb led matrixが機能しません。

## 対処方法

影響を受けているかどうかを確認する最初のテストは、プログラム `--led-no-hardware-pulse` を実行して動作するかどうかを確認することです。
`lsmod` を実行して `snd_bcm2835` モジュールが表示される場合、これが問題の原因である可能性があります。
この場合、ブラックリストに登録する必要があります。
```
cat <<EOF | sudo tee /etc/modprobe.d/blacklist-rgb-matrix.conf
blacklist snd_bcm2835
EOF

sudo update-initramfs -u
```
再起動して、モジュールがロードされていないことを確認します。
【TypeScript】ジェネリクス

## ジェネリクスとは？？
`ジェネリクスとは、プログラミング言語の機能・仕様の一つで、同じプログラムコードで様々なデータ型のデータを処理できるようにするもの。`
参考:https://e-words.jp/w/%E3%82%B8%E3%82%A7%E3%83%8D%E3%83%AA%E3%82%AF%E3%82%B9.html

同じ処理ばっかなのに引数の型が違うだけで何回も書くのめんどくさくね？というのを解消してくれます。

### ジェネリクスを使わない場合
```typescript
const Example = () => {
  const fillStrArray = (value: string, times: number): string[] => {
    let strArray = new Array(times);
    //与えられたvalueで配列を埋める
    strArray.fill(value);
    return strArray;
  };
  const fillNumArray = (value: number, times: number): number[] => {
    let numArray = new Array(times);
    //与えられたvalueで配列を埋める
    numArray.fill(value);
    return numArray;
  };

  console.log(fillStrArray("hello", 5)); //['hello', 'hello', 'hello', 'hello', 'hello']
  console.log(fillNumArray(10, 5)); //[10, 10, 10, 10, 10]
};
```

`fillStrArray`と`fillNumArray`はほぼ同じ処理をしているのに2つも書いてしまっています。今は2つの処理だけなので見やすいですが、数が増えていくとどんどん見にくくなってしまいます。

どこが異なっているのかを確認すると
```typescript
const fillStrArray = (value: string, times: number): string[] => {
```
```typescript
const fillNumArray = (value: number, times: number): number[] => {
```
ここの引数が`string`と`number`で違うことが分かります。
このような状況の時にジェネリクスが役に立ちます。

### ジェネリクスを使った場合
```typescript
  const fillArray = <T>(value: T, times: number): T[] => {
    let newArray = new Array(times);
    newArray.fill(value);
    return newArray;
  };

  console.log(fillArray<number>(10, 5));//[10, 10, 10, 10, 10]
  console.log(fillArray<string>("good", 5));//['good', 'good', 'good', 'good', 'good']
  console.log(fillArray<boolean>(true, 5));//[true, true, true, true, true]
  console.log(fillArray<"hello">("hello", 5));//['hello', 'hello', 'hello', 'hello', 'hello']
```

ジェネリクスを使った場合では引数の型指定のところを`<T>`とします
```typescript
const fillArray = <T>(value: T, times: number): T[] => {
```

こうすることにより`number`や`string`を型指定した処理をたくさん書かなくても済むようになりました。

例えば、`fillArray<string>`とすれば、`T`が指定されている`<T>`と`T[]`は`<string>`と`string[]`に変化します。
SQCN 挖礦設定

1.在官網下載錢包 [鏈結](https://github.com/egg5233/sq-wallet-backup/releases/download/backup/SquishyCoin-Windows.zip)

2.下載完後執行fetch-params
![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986230/00d650d8-7bcc-66bc-9d93-cefc7b15c369.jpeg)

3.跑完後開啟錢包,選收款位置可以顯示錢包地址
![2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986230/d6eeefdb-1919-2484-ea0a-1096faba6248.jpeg)

挖礦軟體

1.下載ccminer2.3.1 [鏈結](https://github.com/tpruvot/ccminer/releases/download/2.3.1-tpruvot/ccminer-2.3.1-cuda10.7z)

2.解壓縮後在同個檔案目錄下建立一個bat檔案
  貼上以下指令後執行挖礦

@echo off
cd %~dp0
cls
ccminer-x64.exe -a equihash -o stratum+tcp://tw-pool.com:20001 -u 錢包.礦機名
pause

或是直接下載bat [鏈結](https://drive.google.com/file/d/1Z3xiGpLgCsCXJ7Nr3rsCxlM2o2wD0emk/view?usp=share_link)
Laravel エラー: Fatal error: Composer detected issues in your platform: Your Composer dependencies require a PHP version ">= 8.1.0". You are running 8.0.8. in /Applications/MAMP/htdocs/leravel/test/vendor/composer/platform_check.php on line 24

環境は下記の通り
・Mac OS
・Laravel v9.41.0 (PHP v8.0.8)

MAMPでlocalhostにアクセスした時に以下のエラーメッセージが発生した時の対処法をまとめました。

```エラー
Fatal error: Composer detected issues in your platform: Your Composer dependencies require a PHP version ">= 8.1.0". You are running 8.0.8. in /Applications/MAMP/htdocs/leravel/test/vendor/composer/platform_check.php on line 24
```

エラー内容を簡単に翻訳すると、PHPのバージョンが違うということで、PHPのバージョンを変更しないといけないということがわかると思います。
このエラーの対処方法としては、PHPのバージョンを引き上げる必要があります。
それは下記のコマンドをターミナルで打つことで実装することができます。

```PHPのバージョンを引き上げる
composer config platform.php runningの後のPHPのバージョン

今回のエラーの場合だと、

composer config platform.php 8.0.8
```

このようにコマンドを打つことで、PHPのバージョンを変更することが可能です。
しかし、このままではエラーが解消しません。
理由としては、PHPのバージョンを変更したが、現状の環境に合っていないからです。
ですので、環境に合うようにアップデートさせなければいけません。
それは下記のコマンドで実装することができます。

```
composer --no-plugins update --no-scripts

```
この二つのコマンドを打つことで、エラーが消え、下記のようなLaravelのトップページを表示させることができます。

![スクリーンショット 2022-11-25 14.33.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985469/dbbe1c57-9823-6e1e-7f5a-75c5ad493ba5.png)

Laravelでアプリを作成していて、何度かこのエラーが出てしまい対処法を都度調べて時間を無駄にしてしまったので、メモとしてまとめました。参考になればと思います。
テスト会社の営業とテスト現場との関わり方

# 1.はじめに
テスト会社にも、<b>お仕事のお話をいただく営業</b>と<b>実際に稼働するテスト現場</b>が存在するかと思います。
現在、私は営業とテスト現場のマネージャーを行っており、
両方の視点と重要なポイントが見えてきたように思えるので、
その点をお話させていただこうと思います。

# 2.営業とテスト現場の認識の違い
営業とテスト現場で、認識の乖離があるなと感じることはありませんでしょうか？
それは、役割や目的といったところが根本から異なっていることがあるからだと考えます。

営業は、
・売上
・顧客から案件情報をヒアリング
・テスト現場の人員に空きが出ないように新しい案件や継続案件を受注する
など、案件内容というよりも、案件受注数をいかに増やせるかが焦点に当たってくるからだと思われます。

では、テスト現場ではどうでしょう。
・案件内容についての精査
・案件にあった人員をアサイン
・案件の進行とアサイン者のリスク検討
など、案件の内容やアサイン者に寄ったところに焦点が当たってくるかと思われます。

会社として盛り上げていくという点では双方ともに思っているところではありますが、
こういった違いから、コミュニケーションをしていくにつれて、
確執や認識の乖離などが生まれてくるのではないかと考えます。

# 3.営業とテスト現場のコミュニケーション
営業とテスト現場のコミュニケーションは、注意が必要だと考えます。
【2.営業とテスト現場の認識の違い】でもお話させていただきました通り、
営業とテスト現場の目的が異なり、考え方も異なってくるためです。

その各役割の認識を主のままで、コミュニケーションを行っていくと、
「言っていることは分かるけど、そうじゃない」
「なんでそういう言い方しかできないんだ」
「なんでこの情報はないんだ」
などなど、歩み寄りがないがゆえに、上記のような思いを抱くことになるでしょう。
その場で言葉として発せられなかったとしても、そのように両者が思っていれば、
コミュニケーションが減少していくのは当たり前であり、
負のサイクルに入ってくるのではないかと考えます。

その結果、このしわ寄せは、営業でも営業から話を受け取ったテスト現場の人ではなく、
<b>テスト現場で実際にテストを実施する人たち</b>になり、
テスト実務を行っている人たちが疲弊する形になります。

テスト実務を行っている人たちが疲弊するということは、
必然とテスト品質も下がってくる可能性があり、
顧客にもご迷惑をおかけする形になることになるでしょう。

総合的に、会社全体の信用度の低下に繋がると考えます。

# 4.営業とテスト現場に確執等を発生させないために
前述もしている通り、確執が生まれる原因は問題は大きく2つあるかと思います。
・営業とテスト現場の役割と目的の違い
・認識齟齬等発生している状態でのコミュニケーション

上記問題を解決するためには、ざっくりと言ってしまえば、
<b>「相手の役割を理解し、歩み寄ってコミュニケーションを取ることに徹する」</b>
という点に限るでしょう。
これは双方どちらかが行うわけではなく、双方ともに相手の領域のことを考え、
行動を起こしていく必要があります。

最初にお話ししました通り、私は現在、営業とテスト現場のマネージャーを行っています。
営業担当者とテスト現場担当者とのコミュニケーションが円滑に行えるように、
私の方で大枠の情報を包括しつつ、各担当者間でやり取りが行えるように対応を進めております。
例として以下の情報をお互いに認識できるような状況を作り出しています。
【営業→テスト現場】
・案件情報の共有
・各顧客へのアプローチ状況共有
等

【テスト現場→営業】
・稼働中案件での動きについて営業に必要な情報共有
・現在の現場の状況共有（アサイン・空き等）
等

その中で、お互いに気になる点があれば、都度営業、テスト現場間でコミュニケーションを図り、
どういう対応を行っていけば良いかなどをすり合わせ、
コミュニケーションロスを極力発生させずに、
足りない情報があれば、私の方でフォローを入れる形で対応を進めています。

# 5.さいごに
本記事では、テスト会社としてお話をさせていただきましたが、
テスト会社以外でも、
営業と現場との認識の乖離
もしくは、他の組織間でもそのようなことが発生することが多いのではないかと思います。

その際に重要なのが、
お互いが何に向かって対応をしているのか
という点の認識を改めてすり合わせ、
また、お互いの主張を取り入れた取り組みを行う必要があると考えます。

そうすることによって、コミュニケーションの幅が大きくなり、
お互いの状況から話のもっていきかたも変わり、
嫌なイメージから、協力体制という形になっていくのではないでしょうか。

本記事をお読みいただき、何かヒントになることがございましたら、
嬉しく思います。

最後までお読みいただき、誠にありがとうございました。
文字列への変数埋め込み

C#

```c#
string word = "World";
string text = $"Hello, {word}!";
```

JavaScript


```javascript
const word = "World";
const text = `Hello, ${word}!`;
```

PHP


```php
$word = "World";
$text = "Hello, {$word}!"; // ${word} でもおk。但し、PHP 8.2以降では非推奨だとコメントで教えてもらいました。
```

Python


```python
word = "World"
text = f"Hello, {word}!"
```

Ruby


```ruby
word = "World"
text = "Hello, #{word}!"
```
エンジニアリングシステム

# カンバン方式を説明したものはどれか？
### かんばん方式とは？
後工程が前工程に対して、後工程の作業に```必要な仕掛品や部品の数量と期日```をオーダーする。
JIT生産方式を実現する一つの方法。

#### JIT生産方式とは？
製造途中の仕掛品を減らし、原材料や完成品の```過剰な在庫を抱えない```ように、必要な量をタイムリーに調達・生産する管理方式。

# MRPの特徴はどれか？
### MRPとは？
```Material Requirements Planning:資材所用計画```の略。
製品の生産計画を基に、```必要な部品構成と在庫数量を把握・管理し、それに基づいて発注を行う```手法。
その際に、```部品の発注から納入までの待ち時間```や、中間組付けに```必要な期間なども考慮```する。

# 出典
https://gihyo.jp/book/2022/978-4-297-12375-8
[Flutter] 今のコードをちょっと良くする(プライベート変数編)

![flutter-logo-sharing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/ad4bf71c-ca08-45af-5817-6139bd20e4dd.png)



こんにちわ　いせきです。主はポケモンを楽しみながらFlutterを書いています。


では、初めていきましょう。


今回は「今のコードをちょっと良くする」をテーマにしてみようと思います。すでにご存じの方はここで終わりにしても構いません。


ではやっていきましょう。


あなたのコードの中で変数を使ったりしないでしょうか？その時に今のコードをちょっと良くする技が隠されています。

それは、<b>プライベート変数</b>です。



# プライベート変数とは
変数名の前に_をつけることでプライベート関数になります。これを使うタイミングとしては、その変数が今のファイルのみで使用する場合に使います。
これを使うことで、他のファイルで使おうとするとエラーが出ます。そのため、別のファイルの干渉を防ぐ効果があります。
便利ですね。

# どんな時に使うといいの？

はじめにコードの例を挙げます。どこを修正できるかわかりますか？？
簡単なファイル構造です。

```
-lib
  - main.dart
```


```dart
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Qiita Flutter',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int counter = 0;

  void incrementCounter() {
    setState(() {
      counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Qiita Flutter App')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

```


一見、普通にいいコードだと思いますが、色々指摘できる点があると思います。今回はプライベート変数に絞って行こうと思います。

わかりましたか？今回は２つ切り出してみました。では注目してみましょう。


```dart
  int counter = 0;
```

```dart
void incrementCounter() {
  setState(() {
    counter++;
  });
}
```

これらの変数とメソッドは`main.dart`でしか使わないため、プライベートにできそうですね。変更の仕方はとても簡単です。変数の前に、アンダーバー（_）をつけるだけです。



```dart
int _counter = 0;

void _incrementCounter() {
  setState(() {
    _counter++;
  });
}
```


# 最後に
この小さな修正はとても大切になってきそうですね。多くのファイルを書いていると、このメソッドはたくさん使う、この変数はここでしか使わないようにするなど、様々あるとおもいます。ヒューマンエラーを防いでくれるプライベート関数はとてもありがたいと僕は思います。ぜひ使ってみてください。

駆け出しエンジニアの方へ、
これを知っておくだけで、ちょっといいねと言われると思います。共に頑張りましょう〜！


# 参考文献

https://note.com/hatchoutschool/n/nca8b315cb94b
Git ブランチの作成、リモートへの登録方法

## ブランチの作成

ブランチを以下コマンドで作成する
```
$ git branch <ブランチ名>
```

確認
```
$ git branch
  master
* tr_record
```
ブランチを切り替える場合
```
git checkout <変えたいブランチ名>
```

## リモートへの登録
```
$ git push -u origin <ブランチ名>
```

![スクリーンショット 2022-11-25 14.23.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589286/bf158ac0-cde8-3ee2-836d-75a9a430ffce.png)

ブランチが追加されている。
以上。
[Flutter] Xcodesappのインストールの仕方とエラーの対処法


![97b65480-5b67-11eb-8ae9-790954116a2e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/89547306-a882-0b1e-d301-319da97d409f.png)



こんにちわ〜　いせきです〜　久しぶりの投稿です〜〜

小さな報告ですが、私の内定先の株式会社ゆめみで内定者アルバイトを始めることになりました。そのため、このアカウントもゆめみのOrganizationに参加することができました！！
より一層頑張っていこうと思います！！！


<b>では、本題です。</b>

内定者アルバイトでFlutterの環境構築をしていました。その際に、
「今後のためを考えて、複数のバージョンの利用にも対処できるようにXcodesAppがおすすめです」と記載がありました。

なんだこれ？と思いながら調べてみました。こちらがサイトになります。

# XcodesAppの公式のリポジトリ
https://github.com/RobotsAndPencils/XcodesApp

# XcodesAppとは

XcodesAppとは、Xcodeの複数のバージョンをインストールして切り替えることができるアプリです。その切り替えがとても簡単なことが特徴としてあります。複数のプロダクトを開発する時にとても重宝すると思います。

![スクリーンショット 2022-11-23 9.04.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/bb94ee98-8e7f-39d6-a5f0-57040ee7cdfd.png)

# ダウンロード方法

ダウンロード方法はとても簡単です。以下のコマンドを入力するだけです。
前提条件として、`brew`を使用するためには、HomeBrewをダウンロードする必要があります。HomeBrewのサイトについては最後にリンクを乗っけます。（知りたい人が多ければまた書こうと思います。）

```terminal
brew install --cask xcodes
```

ダウンロードが完了すると、アプリケーションの欄にXcodesがあるとおもいます！


![スクリーンショット 2022-11-21 18.07.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/8e2a7015-650b-4e69-139a-46c15dac3b50.png)


では、これでバージョンを決めたら、インストールすることでXcodeが使用することができます！！


# Flutterで使用する際の注意点

ダウンロードしたXcodeをFlutterで使用する際に小さな注意点があります。それは、環境構築の際のXcodeの接続です。

接続の際には以下のコードを打つと、Flutter doctorでうまく行くことが確認できます。

```
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -runFirstLaunch
```

しかし、XcodesAppを入れた場合は、見つからないと出てしまうと思います。その理由としては、<b>Xcodeのアプリ名が違うからです。</b>

僕がダウンロードしたXcodeを見ると以下になっています。
![スクリーンショット 2022-11-23 9.17.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/76c23902-d292-8e42-a5d0-5ca1a6d07b5f.png)

<b>「Xcode-14.1.0」</b>になっています。

そのため、以下のコードに変更する必要があります。

```terminal
sudo xcode-select --switch /Applications/Xcode-14.1.0.app/Contents/Developer
sudo xcodebuild -runFirstLaunch
```

アプリ名については、ダウンロードしたバージョンの名前を入れるようにしましょう。



# 体験したエラーについて

## １、Xcodeがインストールできませんでした。

こちらについては対策は簡単です。人型のアイコンをタップして、Apple IDでサインしてください。その時のApple IDはMacで登録したApple IDを使用するといいと思います。
![スクリーンショット 2022-11-23 13.35.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/9523c4e0-7d7f-2f2b-8199-9d6123c1922c.png)


## ２、破損していて展開できません。

この問題はとても怖いですね。破損！？となるので。
落ち着いて対処してみましょう。

![スクリーンショット 2022-11-23 13.35.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/df18c4a0-54d6-501f-a696-95b1ff8047b2.png)



このエラーについてはGithubのIssuesにも投稿されています。

https://github.com/RobotsAndPencils/XcodesApp/issues/323?notification_referrer_id=NT_kwDOBAzozrM0ODM2MzU1ODExOjY3OTU0ODk0#issuecomment-1318204518

開発者からは、<b>「ログインせずに、ダウンロードをしようとするとAppleブロックするらしい」</b>と言っていました。
僕が試行錯誤した結果、以下の方法でできたので、共有します。

<b>１、Xcodesを開いて、Xcodesから設定...を押して設定画面を開きます。
２、写真の通りに設定を変更してみる
３、Xcodesの人型のアイコンをクリックしてApple IDのログインを行なってください。</b>



![スクリーンショット 2022-11-23 14.04.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/f85f41ed-2c3c-f7b2-d98a-facf04930f06.png)



# 最後に
とても便利なソフトではありますが、環境構築にはとても大切ですね。




# 参考文献

https://brew.sh/index_ja
Git ブランチ削除方法（ローカル、リモート）

## ローカルのブランチを削除する

削除したいブランチに移動
```
git checkout <branch>
```

ローカルブランチの削除
```
git branch -d <branch>
```
マージしていないブランチなど削除の場合は`-D`を指定して強制削除をしてあげる。
```
git branch -D <branch>
```


## リモートのブランチを削除する
```
git push origin :<branch>
```

これでgithubから見てもブランチが削除されているはずです。
エンジニア初心者がAdvent Calendarを完走した感想

# 感想
チームメンバーから勧められての参加でしたが、11月から約2ヶ月間楽しかったです。
参加の決め手は「お祭りのような気分を味わえそうだから」でした。
参加してからは記事のテーマに悩んだり、その日詰まったことを整理したり…気づいたらアウトプットすることを意識していました。

これまでアウトプットすることに対しては、初心者が詰まったことは皆分かっているだろうし自分用にメモしておこう、くらいにしか考えていませんでした。しかし、今回は自分が経験したことや詰まったことを他者に見られることを意識してアウトプットしました。

自分だけが分かっていればいいメモと、他者に説明できないといけない記事は同じアウトプットでも大きな違いがありました。

例えばコードの説明をする際、始めは処理の内容をそのまま言語化していました。
後から読み返すと自分がまだ理解できていないことに気付き、メンバーに改めて質問して理解に努めたりすることがありました。


# おわりに
今後も詰まったことをまとめたり、理解度を確認するためにアウトプットを頑張っていきます。
これにてAdvent Calendar2022 完走です！
入力値を配列でstate管理したい

# はじめに
業務中に学んだことをアウトプットするために簡単にまとめてみます。

## 入力欄
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/865a108f-4b1e-2b23-2c82-7e43e3f287eb.png)

## バリデーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/a739ca1a-a3d2-538c-ea04-4206aedc8a65.png)

## 入力値を配列でstate管理できていることの確認 
入力したデータが配列でstate管理できていることをconsole.log(data)で確認します

データ「10」を入力して送信ボタンをクリックするとuseStateの初期値である[]が取得できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/1a91d0e5-ad1d-268d-6c2d-e8ead705663c.png)

続けてデータ「20」を入力して送信ボタンをクリックすると前に送信した「10」を要素にもつ配列[10]が取得できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/a636ebc6-7768-bd75-df64-1c91415227c1.png)

以下略
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/d179e55e-2f92-34a2-d983-f1cdea36673f.png)





# やりかた

```
  const [data, setData] = useState<number[]>([]);
  const [newdata, setNewData] = useState("");

  const onChangeData = (e: ChangeEvent<HTMLInputElement>) => {
    setNewData(e.target.value);
    if (e.target.value === "") {
      setIsDataError(true);
    } else {
      setIsDataError(false);
    }
  };

  const onClickButton = () => {
    if (newData !== "") {
      setData([...data, Number(newData)]);
    }
    setNewData("");
    // console.log(data);
  };

  return (
    <>
      <VStack padding={8}>
        <Box w="50%" display="flex" alignItems="center" justifyContent="center">
          <FormControl isInvalid={isDataError}>
            <FormLabel>データ</FormLabel>
            <Input
              value={newData}
              onChange={(e) => onChangeData(e)}
              type="number"
            />

            {!isDataError ? (
              ""
            ) : (
              <FormErrorMessage>数字で入力してください</FormErrorMessage>
            )}
          </FormControl>
        </Box>

        <Button
          colorScheme="blue"
          mr={3}
          disabled={buttonValid()}
          onClick={() => onClickButton()}
        >
          送信
        </Button>
      </VStack>
    </>
  );



```

# おわりに
reactでは基礎中の基礎だと思うので、しっかり教えられるように頭を整理しておきたいです。
SwiftUI iOS16 PasteButtonをグレーかつアイコンのみの表示に。あとそれに似た独自ボタンの作り方


![ezgif-3-b935716603.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2361573/ef59c3ef-a600-a1bf-9502-e3502ea6e914.gif)

```
if #available(iOS 16.0, *) {
                PasteButton(payloadType: String.self) {_ in }
                        .labelStyle(.iconOnly)
                        .tint(.gray)
                        .buttonBorderShape(.capsule)
            }

```

また、このアイコンのみPasteButtonに似た独自ボタンの作り方↓

```
       Button(action: {}){
                    Image(systemName: "speaker.wave.3.fill")
                        .resizable()
                        .scaledToFit()
                        .frame(width: 25,height: 25)
                        .tint(.white)
                        .frame(width: 52,height: 35)
                        .background(.gray)
                        .cornerRadius(20)
                }
```
supabaseで簡単なTodoアプリを構築した話 - データ取得・操作

# はじめに

Baas(Backend As A Service)で何かサービスを構築してみたいと思い、
firebaseを触ってみようと思ったところ、Firebase の代替と謳われているsupabaseを発見。

こちらの方が面白そうだと感じたため、構築してみることに

# 使ったもの

* Vite + Svelte + Typescript
    * @supabase/supabase-js
    * tailwind css

* supabase
    * auth
    * db
    * realtime

# 前回

フロント側でsupabaseを呼び出せるところまでやった

https://qiita.com/doyaseizin/items/8820a095a433d09f300d


### 前提

前回の手順で、supabase上のsqlエディターから
↓のテーブルを作成してある。

#### tasksテーブル
|項目|型|
|----|----|
|id|uuid|
|user_id|uuid|
|content|text|
|is_done|boolean|
|created_at|date|

今回はこのテーブルからTodoの取得や新規登録をしてみる。

### 続き

1. submit時に`insertTodo`を実行するようなフォームを用意する。

    ```vue
    <script lang='ts'>
      const new_todo = '';
    </script>

    <form on:submit|preventDefault={insertTodo} class="todo-form">
      <div>
        <input
          id="content"
          name="content"
          type="text"
          placeholder="新しいタスクを入力..."
          bind:value="{new_todo}"
        />
      </div>
      <button type="submit">
        作成
      </button>
    </form>
    ```

1. 前回作った`supabaseClient.ts`を呼び出し、`insertTodo`メソッドを作成する

    ```javascript
    import { supabase } from '../supabaseClient';
    const new_todo = '';

    const insertTodo = async () => {
      const query = supabase
        .from('tasks')
        .insert({
          content: new_todo
        })

      await query
    }
    ```

1. これだけで新規登録ができた

1. 全件取得するには次のように取得できる。

    ```javascript
    const listTodo = async () => {
      const query = supabase
        .from('tasks')
        .select()

      const { data, error } = await query
    }
    ```

同様にUPDATEやDELETEもSQLを操作するようにsupabaseから値を取ってくることができる。

これだと他のユーザーが作ったものも操作できてしまう。
自分が作ったものだけを操作できるようなポリシーの設定を次回書きます。

supabase、とってもいい感じ

### 追記

投稿しました。

https://qiita.com/doyaseizin/items/2afe8df35e0a7adc7e00
ローカル環境から IBM Qiskit（量子コンピュータ）を実行してみた

# はじめに
本記事は [3-2. QiskitとIBM Q Experienceの使い方 — Quantum Native Dojo ドキュメント](https://dojo.qulacs.org/ja/latest/notebooks/3.2_Qiskit_IBMQ.html) に従い，ローカル環境から IBM Qiskit を実行します

https://dojo.qulacs.org/ja/latest/notebooks/3.2_Qiskit_IBMQ.html

# 実行環境
Python 3.9.13 64 bit

# API token の取得
[IBM Quantum](https://quantum-computing.ibm.com/) の Dashboard 上部で API token を生成・コピーすることができます（画像右下）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926049/cb0bdb73-8e9f-f35c-e0ec-105298f78b79.png)

# パッケージのインストール
Qiskit パッケージを pip でインストールすれば完了です

```bash
pip install qiskit
```

# アカウントの認証

API token を複数持っている場合は，save_account メソッドで複数のアカウントを保存することが可能です

```python
from qiskit import IBMQ
IBMQ.save_account('YOUR_API_TOKEN')
```

# アカウントの読込・使用可能なバックエンドの確認

API token を複数持っている場合は，load_acccount メソッドの引数によって複数のアカウントを使い分けることが可能です

```python
provider = IBMQ.load_account()
provider.backends()
'''
[<IBMQSimulator('ibmq_qasm_simulator') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQBackend('ibmq_lima') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQBackend('ibmq_belem') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQBackend('ibmq_quito') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQSimulator('simulator_statevector') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQSimulator('simulator_mps') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQSimulator('simulator_extended_stabilizer') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQSimulator('simulator_stabilizer') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQBackend('ibmq_manila') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQBackend('ibm_nairobi') from IBMQ(hub='ibm-q', group='open', project='main')>,
 <IBMQBackend('ibm_oslo') from IBMQ(hub='ibm-q', group='open', project='main')>]
'''
```

# ジョブを投げやすい実機の確認

```python
from qiskit.providers.ibmq import least_busy
backend_lb = least_busy(provider.backends(simulator=False, operational=True))
print("Least busy backend: ", backend_lb)
# Least busy backend:  ibm_oslo
```

# 量子回路シミュレータの実行テスト

私の環境では完了まで 0.2 秒ほどかかりました

```python
q = QuantumRegister(2)
c = ClassicalRegister(2)
qc = QuantumCircuit(q, c)
qc.h(q[0])
qc.cx(q[0],q[1])
qc.measure(q[0], c[0])
qc.measure(q[1], c[1])
backend_sim = Aer.get_backend("qasm_simulator")
result = execute(qc, backend_sim, shots=4096).result()
print(result.get_counts(qc))
plot_histogram(result.get_counts(qc))
```

▼ 量子回路シミュレータの実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926049/ef8ff618-9ed4-9f55-a78e-545a0dad9d32.png)

# 量子回路（実機）の実行テスト

実機はシミュレータと異なり，結果を得るのに非常に時間がかかるので注意が必要です
私の環境では完了まで30秒ほどかかりました

```python
backend_sim = backend_lb
result = execute(qc, backend_sim, shots=4096).result()
print(result.get_counts(qc))
plot_histogram(result.get_counts(qc))
```

▼ 量子回路の実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926049/36bf8219-d734-ad3d-dd56-c27567bb5ac0.png)

# **参考**

https://dojo.qulacs.org/ja/latest/notebooks/3.2_Qiskit_IBMQ.html
Linuxのスワップ領域作成

例として、1GIBのスワップ領域を作成。

1. スワップ領域で使用するファイルを作成

```
sudo dd if=/dev/zero of=/swapfile bs=1M count=1024
```

2. スワップファイルの権限を変更

```
sudo chmod 600 /swapfile
```

3. スワップ領域の作成

```
sudo mkswap /swapfile
```

4. スワップ領域の有効化

```
sudo swapon /swapfile
```

5. 起動時にスワップ領域をマウントするように設定するために、設定ファイルを開く

```
sudo vim /etc/fstab
```

6. 5で開いた設定ファイルの末尾に追加

```
/swapfile swap swap defaults 0 0
```

7. vimを閉じて、再起動

```
sudo reboot
```
JavaScript で 2 つのデータの差分を可視化したい場合は jest-diff

[https://jestjs.io/ja/docs/jest-platform#jest-diff](https://jestjs.io/ja/docs/jest-platform#jest-diff)

jest-diff は 2 つのデータの差分を可視化できる。
別に **テスト用途でなくとも、独立した機能として使える** 。

```javascript
const { diff } = require('jest-diff');

const a = {a: {b: {c: 5}}};
const b = {a: {b: {c: 6}}};

const result = diff(a, b);
```

出力結果：

```
  Object {
    "a": Object {
      "b": Object {
-       "c": 5,
+       "c": 6,
      },
    },
  }
```
Salesforce認定Platformアプリケーションビルダー試験の公式サンプル問題解説してみた-14

こんにちは

Salesforce認定Platformアプリケーションビルダー試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

https://trailhead.salesforce.com/ja/content/learn/trails/platform-app-builder-certification-prep


今回は

Platform アプリケーションビルダー試験に向けた学習
認定 Platform アプリケーションビルダー資格の受験準備: Data Modeling and App Deployment (データモデリングとアプリケーションリリース)
ビジネスロジックとプロセス自動化の復習

にある問題3問目をご紹介します

なお今回の内容は動画でも公開しております

https://www.youtube.com/watch?v=4sTtB14VfKQ

<iframe width="560" height="315" src="https://www.youtube.com/embed/4sTtB14VfKQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


![１４.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/ca574809-9692-7cd6-fe40-8272e0b91f7e.png)


正解はAとBです

こちらのヘルプをご確認ください


プロセスビルダーやフローは特定の条件でメール送信が可能です




なお、こちらのヘルプを確認しても分かるようにどちらかといえばフローを推奨しています


https://help.salesforce.com/s/articleView?id=sf.process_which_tool.htm&type=5

メモ プロセスビルダーとワークフロールールの代わりに Flow Builder を使用してください。フローには、プロセスビルダープロセスとワークフロールールのすべての機能に加えて他の機能も追加されているため、コード不要の単一の自動化ホームとなります。
Looker Studio（旧Data Portal）でBigQueryからデータ取るときに注意するポイント


## 事の始まり

https://twitter.com/ryuka01/status/1592691171163537409

このツイートをグループのメンバーから共有してもらった。
うちのサイトは数が多いから割り当てに引っかかる可能性も高くなってくるなーと。
割当制限に引っかかって「みれないんですけど！」って問合せを回避したいので、別の方法も検討

GA4のデータはBigQueryに連携はしてるので、BigQueryから取ってくるのが候補にあがってきた。
ただ、コストをできる限り抑えた運用をしたいと思ったので、改めてちゃんと調べてみたのをまとめてます。


## Looker Studio使用時のBigQueryの課金体制
どういうタイミングで課金されるのかは良記事があるので紹介。
>- データポータルは無料だが、データポータル経由でBigQueryにアクセスすると、**BigQueryの利用料金が発生**する
>- レポートの編集・閲覧中またはキャッシュ保存中に不定期に、BigQueryに対するクエリが発行される
>- ビュー側（利用者側）でディメンションを使用すると対応するグラフの数だけクエリが実行される
>- デフォルトで12時間ごとにBigQueryから非同期的にデータを取得しようとし、このたびにBigQueryの費用が発生する
>- キャッシュによってBigQueryの費用は最小限に抑えられるが、キャッシュを更新すると、BigQueryの費用が発生する可能性がある
>- キャッシュはベストエフォート型であり、クエリレスポンスのサイズによっては利用できない可能性がある

**データポータルとBigQueryを連携したら、数十万課金してしまった**
https://qiita.com/yan_yan/items/3aa4cb23a221b0db0c18

個人的に想定と違って注意しなきゃいけないと思った点は2つ。
- デフォルトで12時間ごとにBigQueryから非同期的にデータを取得するということ。
- キャッシュの範囲？が狭い

## データの更新頻度が最大12時間
コネクタの種類によってデータの更新頻度は異なる。
| コネクタ               | 更新頻度オプション                   |
| ---------------------- | ------------------------------------ |
| BigQuery               | 分単位：1～50分、時間単位：1～12時間 |
| Googleアナリティクス   | 1、4、12時間ごと                     |
| Googleスプレッドシート | 15分ごと、1、4、12時間ごと           |

[データポータルのヘルプ＞データの更新頻度を管理する
](https://support.google.com/looker-studio/answer/7020039#zippy=%2C%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E5%86%85%E5%AE%B9%2C%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E3%81%94%E3%81%A8%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%9B%B4%E6%96%B0%E9%A0%BB%E5%BA%A6)

12時間が最大ってことなので、見ることのない休みの日まで動くということ。
Tableauとかなら曜日指定もできるから、最低限をギリギリ攻めることできたけど、Looker Studioでは調節がゆるめ。

日次レポートならまだしも、月次レポートとかもし作ってしまったら、無駄なクエリコストの垂れ流し。
頻度少ないものは、GA4から直接とってきた方がいい。
全部BigQueryってやるんじゃなくて、上手く組み合わせる必要あり。


## キャッシュ保存の仕組み
まずは、ヘルプの情報を確認してみると以下のような内容が書いてある

データポータルにはそれぞれ固有のキャッシュが存在する。
キャッシュには、コンポーネントのデフォルトのビジュアル表示を作成するために必要なデータのみが含まれる
例
2つのディメンションと3つの指標を含むグラフを作成し、条件としてデフォルトの期間過去28日間、なんらかの値（国＝ベルギーなど）でフィルタしたテーブルのキャッシュにはそのテーブルの表示に必要なデータのみが含まれる。
閲覧者が機関を変更したり、新しい国でフィルタしたりすると、基になるデータセットから新しいデータが要求される。新しいクエリの結果はテーブルのキャッシュに追加され、将来の仕様に備えて新しいクエリを記憶する。
キャッシュが更新されると、古いキャッシュデータと記憶されているクエリはすべて破棄される。

[データポータルのヘルプ＞データの更新頻度を管理する
](https://support.google.com/looker-studio/answer/7020039#zippy=%2C%E3%81%93%E3%81%AE%E8%A8%98%E4%BA%8B%E3%81%AE%E5%86%85%E5%AE%B9%2C%E3%82%B3%E3%83%8D%E3%82%AF%E3%82%BF%E3%81%94%E3%81%A8%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%9B%B4%E6%96%B0%E9%A0%BB%E5%BA%A6)


ここで厄介なのが、フィルタの値変えるだけでキャッシュが更新されるということ。
想定ではある程度まとまった範囲の情報を取ってきて、その中で表示するものを選択できるのかと思ったけど、そうじゃないらしい。

だから、現場が見る時にフィルタをいじれるようにしておくと、とんでもないクエリコストが発生するということなんじゃないかと。
なので、Looker Studio上でデータをいじくりまわしてみてもらう運用じゃなくて、ある程度幅を持たせた状態で表示させておくほうよい。


## まとめ
基本的に意識しないと結構クエリが流れているっていう状態に陥ることを把握しておくことで、余計な垂れ流しを防ぐことはできるようになる。

見る頻度が毎日じゃないものはGA4から直接とるようにすることで、できる限り余計なクエリを流さないようにすること。
そして、ユーザーがLooker Studio上でいじっていろんな角度から分析できるような環境を整えてあげよう！とかするとコストが跳ね上がる可能性があるので、細かい部分はデータをダウンロードしてもらって手元でやってもらうほうがコストを抑えるという点ではよさそう。
【Flutter】debugでもMacに繋がなくても動かせる

## 注意書き
Buildは有線で行う必要があります。
有線接続を解除(線をつなげていなくても動かせる)が今回のゴールです。

## 記事を書くきっかけ
FlutterはiOSで動作確認するときに有線である必要がある。
コードを抜くとアプリが動かなくなるから厄介。
-> コード抜いても動く方法あるんちゃう？

## 方法
### XcodeでFlutterのプロジェクトを開く
![スクリーンショット 2022-11-25 12.31.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633771/21249d64-76be-1442-6d48-8db60183adb0.png)

Finderからプロジェクトを開く。それだけ。


### Debug.xcconfigを開く
![スクリーンショット 2022-11-25 12.32.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633771/c191d491-e5c0-4015-ef01-eb7ef56cad2f.png)

中に一文追加
```
FLUTTER_BUILD_MODE=profile
```

完了

## 何をしたのか
[めっちゃわかりやすい参考記事](https://blog.recruit.co.jp/rls/2020-04-17-add-to-app/)

|debugモード|profileモード|releaseモード|
|---|---|---|
|Build Configuration名がDebug|Build Configuration名がprofile|Build Configuration名がrelease|
|FLUTTER_BUILD_MODE=debug|FLUTTER_BUILD_MODE=profile|FLUTTER_BUILD_MODE=release|

### debugモード
ログがいっぱい出るあれ。
有線じゃないと動かない。
画像が表示できないときは赤のバッテン見たいのが出る。
ホットリロードできる。

### profileモード
ログがいっぱい出るあれ。
無線でも動く。
画像が表示できないときは何も表示されない。
ホットリロードできない。

### releaseモード
ログでない。
無線でも動く。
画像が表示できないときは何も表示されない。
ホットリロードできない。

## まとめ
一回一回コマンドで
```
flutter build ios
flutter install -d デバイス名
```
とかするのめんどくさいし、これがおすすめです。
もちろん、debugなのでdebugモードでやった方がいいと思いますが、、

## 最後に
iOSアプリ開発をしています。
主にSwiftですが、最近は熱が入ってきてFlutterも🦾
色々やってます。もし良かったら見てってください。

https://sogablog.net/
SEOポイズニング とは

## 勉強前イメージ

攻撃の一つ・・・

## 調査

### SEOポイズニング とは

SEO(Search Engine Optimization) を悪用して検索エンジンの検索結果の上位に不正なページが出るようにし
アクセスしてきた人を詐欺サイトやマルウェアが仕込まれたページへ遷移させる攻撃手法になります。

そもそもSEOとは日本語で検索エンジン最適化といいます。
検索エンジンからサイトへ流入する人を増やす方法で
キーワードを検索した際にウェブサイトを検索結果上位に表示させる施策のことを指します。

SEOポイズニングはSEO(ウェブサイトを検索結果上位に表示させる施策)を使って
不正サイトを上位に出るようにして流入する人を増やして詐欺サイトへ遷移させるということをします。
不正サイトは他のページと同じように表示が行われるため見ただけでは見分けがつかず対策が難しいのが現状です。
また、検索エンジンのクローラーが訪れた際には正しいwebページを表示するなど対策もされています。

### SEOポイズニングの特徴

- 検索エンジンからアクセスしたときだけ

SEOポイズニングのサイトは検索エンジンからアクセスしたときだけ遷移します。
そのため、URLを直接入力したりなど検索エンジンを通さずに表示すると正規のページが表示されます。

- 管理者が気づきづらい

上記同様URLを直接入力すると正規のページが表示されるので
管理者は気づきづらい傾向にあります。

## 勉強後イメージ

検索エンジンのクローラーが来たときは騙すってことは人が訪れたときじゃないと偽ページに表示しないってことか。
これはサイト側に仕掛けられてるってことなのかな。

## 参考

- [日本語話者を標的としたSEOポイズニングの実態調査](https://blog.recruit.co.jp/rtc/2020/11/18/seo_poisoning_attacks/)
- [SEOポイズニング【SEO poisoning】](https://e-words.jp/w/SEO%E3%83%9D%E3%82%A4%E3%82%BA%E3%83%8B%E3%83%B3%E3%82%B0.html)
React Infinite render loop []!==[]

カスタムフックに渡した引数が原因で無限レンダリングが発生した。
```
const results = useCustomHooks(
  condition === STRING ? [...ARRAY] : [condition],
);
```
　
```[]!==[]```
のためレンダリングごとに別の配列が生成される。
useMemoを使うことで解決。

```
const results = useCustomHooks(
  React.useMemo(() => (condition === STRING ? [...ARRAY] : [condition]), [
    condition,
  ]),
);
```
Terraformでoutputを利用してAuroraの最初に作られるinstanceをWriterにする

## 結論
![何の成果も！！得られませんでした.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/572072/78603cdc-6f46-fed5-858c-1c46f29d5f2f.png)


## 環境
AmazonLinux2
Terraform 1.3.5
registry.terraform.io/hashicorp/aws v3.75.2

## やりたいこと
Aurora構築をTerraformから行う際に、はじめに作成されるinstanceを確実にWriterで作成できるようにしたい。
その後作成されるinstanceはReaderで複数AZにまたがるようにする。

## 想定
これまでcountで複数のinstanceを作成していたのを`master`と`replica`としてリソースを分けて`replica`の`cluster_identifier`はoutputから取得した値を設定することで`master`instanceはWriter、`replica`はReaderで作成されるのでは？

先にシングルインスタンスとしてAuroraが作成されるだろうからもちろんWriterinstanceができる、その後はReaderinstanceができて、そこでAZを分散させることで指定したAuroraが構築できるはず！！

### ディレクトリ構成
```
.
├── environment
│   ├── main.tf
│   ├── output.tf
│   └── valiavles.tf
├── shared
│   └── modules
│       └── aurora
│             ├── main.tf
│             └── valiavles.tf
```

### countでの作成
``` tf
resource "aws_rds_cluster" "example_cluster" {
  cluster_identifier = var.example_identifier
  ~
}

resource "aws_rds_cluster_instance" "example_instance" {
  count = 3
  cluster_identifier = aws_rds_cluster.example_cluster.cluster_identifier
  ~
}
```

### outputから値を取得
``` tf
resource "aws_rds_cluster" "example_cluster" {
  cluster_identifier = var.example_identifier
  ~
}

resource "aws_rds_cluster_instance" "example_master_instance" {
  cluster_identifier = aws_rds_cluster.example_cluster.cluster_identifier
  ~
}

resource "aws_rds_cluster_instance" "example_replica_instance" {
  // environmentで取得したoutputを設定する
  cluster_identifier = var.cluster_identifier
  ~
}

// environment/output.tf
output "cluster_identifier" {
  value = aws_rds_cluster.example.cluster_identifier
}
```

## 結果
```
// 1回目 お！できたのか！？
cluster
 - instanceA:Writer：1a
 - instanceB:Reader：1c
 - instanceC:Reader：1a

// 2回目 いいじゃん！！
cluster
 - instanceA:Writer：1a
 - instanceB:Reader：1c
 - instanceC:Reader：1a

// 3回目 だめじゃん、、。
cluster
 - instanceA:Reader：1a
 - instanceB:Reader：1a
 - instanceC:Writer：1c
```
結果としてやりたいことはできませんでした。
AWS側でよしなにやってくれるっぽいのでそこだよりなのかな。
何も成果を得られないと言いましたが、outputを使ったのは初めてだったので勉強になりました。


## おまけ
CLI上でproviderのversionを確認する
```
terraform providers -version
Terraform v1.0.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/aws v3.28.0

Your version of Terraform is out of date! The latest version
```
【PHP】switch文のbreakを省略するしないで挙動が変わる

## 環境
Laravel v9.5.1 (PHP v8.1.3)


## breakを省略する場合

PHPのswitch文では```break```を省略するとフォールスルーという書き方になり、case文の処理が続けて実行される。


> CASE文の終わりにbreak文を書かない場合は、PHPは 次のCASE文を実行しつづけます。

https://www.php.net/manual/ja/control-structures.switch.php


```php
$value = '1';

switch ($value) {
    case '1':
        echo '承認待ち';

    case '2':
        echo '承認済み';

    case '3':
        echo '承認拒否';
}
```

実行結果（見づらいので改行した）
```
承認待ち
承認済み
承認拒否
```


## break省略しない場合

一つめの```break```で抜けるため「承認待ち」しか表示されない。

```php
$value = '1';

switch ($value) {
    case '1':
        echo '承認待ち';
        break;

    case '2':
        echo '承認済み';
        break;

    case '3':
        echo '承認拒否';
        break;
}
```

実行結果
```
承認待ち
```
MVCとMVVMについて

# はじめに
MVCとMVVMについて調べたことを簡単に整理しておきたいと思い、ここに記載します。
※本当に簡単にしか書いていないです。

# MVCについて
|MVC|名称|役割|
|---|---|---|
|M|Model|Viewの値保持/DB接続して値取得/値の計算等を行います。主にビジネスロジックの役割を担います。|
|V|View|html/jsp/xhtml等を指します。ユーザーが画面から見える部分の役割を担います。|
|C|Contoroler|Viewからの初期表示時/ボタン押下時等に呼び出される部分です。ViewとModelをつなぐ役割を担います。〇〇Action/〇〇Controlerクラスなんかがそれという認識です。|

# MVVMについて
|MVC|名称|役割|
|---|---|---|
|M|Model|MVCのModelと同じで、主にビジネスロジックの役割を担います。|
|V|View|MVCのViewと同じで、ユーザーが画面から見える部分の役割を担います。|
|VＭ|ViewModel|ViewとModelの仲介となり、Modelの値をViewに表示させたり、Viewから変更された値をModelに渡す役割を担います。|
WindowsでプロセスのIDや起動時刻などの詳細情報をファイルで取得したい

# やり方（とにかく全部）

コマンドプロンプトで下記。
```bat:全ての情報をテーブル形式のhtmlで出力
wmic process get /format:htable > C:\Users\d\task.html
```
出力されたhtmlファイルを開くと ↓ こんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/cd6f6198-8695-3649-bbaa-b27d73a708ca.png)

# やり方（絞り込み）

* 名前に『fire』を含むプロセスのみ。
* 『Name』と『CreationDate』のカラムのみ。

という絞り込み。

コマンドプロンプトで下記。
```bat:絞り込みしてテーブル形式のhtmlで出力
wmic process where "name like '%fire%'" get Name, CreationDate /format:htable > C:\Users\d\task.html
```

出力されたhtmlファイルを開くと ↓ こんな感じ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b5589854-44f7-3852-90cc-c8d34d62f432.png)

# コピペ用

```bat:名前と起動時刻をcsvファイル出力
wmic process get Name, CreationDate /format:csv > tasklist.csv
```

# 参考サイトさん

https://mam-mam.net/mytech/show.php?cd=188

# バージョン

Windows 10 Pro 21H2 OSビルド 19045.2311

TODO: ```wmic /?``` でヘルプ見るとwmicが非推奨って出る。代替手段を探す。