OmniAICreator/Qiita-1.07M huggingface dataset:
【C#】Math.NET Numericsで単純線形回帰分析（SLR:Simple Linear Regression）

# はじめに
単純線形回帰をサクッと実装したいときが稀にありますよね。最近はPLS回帰の話をよく耳にしますが、帰属を明確にして分析したいなどの意から単純線形回帰を利用したいとの要望は根強いようです。今回、C#で数値計算用ライブラリ[Math.NET Numerics](https://numerics.mathdotnet.com/)[^1]を利用し単純線形回帰を試してみます。
# 単純線形回帰とは
引用先として適切かどうか別として、[Wikipedia](https://ja.wikipedia.org/wiki/%E7%B7%9A%E5%BD%A2%E5%9B%9E%E5%B8%B0)では以下のように説明されています。
>線形回帰（せんけいかいき、英: linear regression）とは、説明変数（独立変数ともいう）に対して目的変数（従属変数、あるいは反応変数ともいう）が線形またはそれから近い値で表される状態。
>線形回帰は統計学における回帰分析の一種であり、非線形回帰と対比される。 また線形回帰のうち、説明変数が1つの場合を単純線形回帰、2つ以上の場合を重回帰と呼ばれる。
# コード実装
## 説明変数及び目的変数準備
近代統計学の父フランシス・ゴルトンが発表した、親と成人した子供の身長についてのデータを利用します。以下の書籍を参考文献として挙げておきます。

https://www.amazon.co.jp/dp/4062575574

親の身長を説明変数 **x**、子供の身長の平均値を目的変数 **y** と定義します。
身長の単位はインチです。
```C#:
double[] x = new double[]
{
    63.5, 64.5, 65.5, 66.5, 67.5,
    68.5, 69.5, 70.5, 71.5, 72.5,
};

double[] y = new double[]
{ 
    65.3, 65.4, 66.7, 67.1, 67.6,
    68.0, 68.7, 69.6, 70.1, 72.1,
};
```
## 回帰係数取得
`MathNet.Numerics.LinearRegression`の`SimpleRegression.Fit`メソッドを使います。
```C#
(double intercept, double slope) = SimpleRegression.Fit(x, y);
Console.WriteLine("intercept: " + intercept);
Console.WriteLine("slope: " + slope);
```
```:output
intercept: 21.1606060606061
slope: 0.689696969696969
```
書籍記載の結果は、intercept=21.16, slope=0.690でした。
得られた結果は概ね一致していることが確認できました。
## 推定値算出
係数が得られたため、以下の回帰直線の式にあてはめます。

:::note info
**y = intercept + slope * x**
:::



試しに、親の身長が70インチのときの場合について、xに70を代入して推定値を出してみます。
```C#
double value = 70;
double result = intercept + slope * value;
Console.WriteLine("result: " + result);
```
```:output
result: 69.4393939393939
```

もし、書籍記載の結果と一致させたい場合は、`Math.Round`メソッドで小数点以下を適切な桁数で丸めてください。

[^1]:Math.NET Numericsのバージョンは **5.0.0** を利用。
AWS Hands-on for Beginners Amazon EC2 Auto Scaling スケーリング基礎編：学習メモ

## はじめに

AWSハンズオンfor Beginnersシリーズとして提供されている「[Amazon EC2 Auto Scaling スケーリング基礎編](https://pages.awscloud.com/JAPAN-event-OE-Hands-on-for-Beginners-Auto_Scaling-2022-reg-event.html?trk=aws_introduction_page)」を実施した際のメモです。
ビジネスの拡大に伴いリソースのスケーリングが必要です。例えば、オンプレでスケーリングする場合、マシンの物理的な入れ替えなどが発生し、即時対応が難しく、手作業であるため、誤りも発生する可能性があります。また、急な需要増加に対応できず機会損失にもつながります。
Auto Scalingを使用することでこれらを解決するとともに、可用性の維持とコスト最適化につなぐことができます。
本ハンズオンでは、2種類のスケーリング方法の実践およびインスタンスに異常があった際の自動置き換えを体験します。

## アジェンダ

1. 本ハンズオンの概要
2. スケーリングにまつわる課題とAmazon EC2 Auto Scalingについて
3. ハンズオンの事前準備
4. スケジュールスケーリング（１）~起動テンプレートの作成~
5. スケジュールスケーリング（２）~Auto Scalingグループの作成、スケジュールの設定~
6. ターゲット追跡スケーリング（１）~ターゲット追跡スケーリングの設定~
7. ターゲット追跡スケーリング（２）~負荷をかけてスケールアウトを確認~
8. ターゲット追跡スケーリング（３）~負荷をとめてスケールインを確認~
9. 異常なインスタンスの置き換え
10. 本シリーズのまとめ、リソースの削除

## メモ

### スケーリングの種類

Auto Scalingにはスケジュールに基づいたスケーリング（スケジュールスケーリング）と需要に基づいた動的スケーリングの2種類があります。

#### スケジュールスケーリング

スケジュールスケーリングは文字通り、スケジュールに基づいてスケーリングを行います。
例えば、指定した日時にインスタンスを4つ起動する、などです。
スケーリングする時間とインスタンスの数を設定するため、このスケーリングを使用する前提として「いつ」「どのぐらい」リソースが使用されているかを把握しておく必要があります。

#### 動的スケーリング

動的スケーリングはインスタンスのCPU使用量などを基準にスケーリングを行う方法です。
例えば、インスタンスのCPU使用量が80%を超えたら1つインスタンスを追加する、などです。
動的スケーリングの場合、予測できない需要に対応できますが、スケーリングには時間を要します。
そのため、スパイクアクセスに注意する必要があります。また、前提として需要増加により「なに」に負荷がかかるか（何をスケーリングの基準とするか）を把握しておく必要があります。

### Auto Scalingのコンポーネント

Auto Scalingには2つのコンポーネントがあります。
1つ目は起動テンプレートです。起動テンプレートとは、Auto Scalingによって起動するEC2インスタンスの情報をまとめたファイルです。AMI、インスタンスタイプ、ネットワーク設定などの情報をファイルに記載します。
2つ目はAuto Scalingグループです。Auto Scalingグループとは、スケーリングの設定をまとめたコンポーネントです。どの起動テンプレートを使用するかとか、維持するインスタンス数、スケールアウト時の最大インスタンス数、スケールイン時の最小インスタンス数、スケーリングのトリガーなどを設定します。

### 動的スケーリング設定

動的スケーリングを設定するには、まず、スケーリングポリシーを作成する必要があります。
スケーリングポリシーには、ターゲット追跡スケーリング、ステップスケーリング、シンプルなスケーリングの3種類があります。
ターゲット追跡スケーリングとは、設定したターゲット値を維持するようにスケールアウト、スケールインを行う機能です。
例えば、CPU使用量が60%を維持するようインスタンス数の増減を自動化してくれます。ターゲット追跡スケーリングを設定すると、CloudWatchアラームが作成されます。ターゲット値によりスケールインするアラームとスケールアウトするアラームの2つが作成されます。

### インスタンスへの負荷テスト

EC2インスタンスにSSHログインし、stressコマンドを実行して、CPU、メモリ、ディスクなどに負荷をかけることができます。

### 設計時の注意点

スケーリングにより、インスタンスが増減するため、インスタンスに依存したステートフルなアプリだとスケーリング時にインスタンスが持つ情報が失われる可能性があります（もしくは、スケールアウトしたことで情報がないインスタンスにアクセスしてしまう）。
このようなことを防ぐため、ステートレスな設計を目指しましょう。
例えばセッション情報はサーバで持つのではなく、DynamoDBやElastiCacheなど外に持たせるなど。

### 異常インスタンスの置き換え

Auto Scalingには、EC2のステータスチェックやELBのヘルスチェックの結果によって異常とみなされたインスタンスを置き換える機能があります。
本ハンズオンでは、Auto Scalingグループ内のインスタンスを停止させてみて、その後新しいインスタンスが立ち上がるかを確認しました。

## ハンズオンの感想

コスト最適化、可用性向上のためほぼ全てのサービスで必要な機能であると感じます。
動的スケーリングの場合、何をどのぐらいの基準でスケールするかは、過去に同じような構成でサービスを作っていればそれを参考にできます。
そうでない場合、一旦決めにし、メトリクスを監視、傾向を掴んだ上で再設定する必要があると感じます。
なお、インスタンスの数を増やしたくないなど（インスタンスにインストールするライセンスの問題）の顧客の要望が過去ありました。その場合はAutoScalingの水平スケーリングではなく、垂直スケーリングを考慮しなければなりません。
フィッシャーの正確検定の代わりに二項検定を使う方法

![fisher_chi2_binomial.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/914f5a55-bf3b-6493-1448-c816ca8dbbc9.png)

# はじめに

フィッシャーの正確検定 (Fisher's exact test) は、2つの集合 $A_1,A_2\subseteq U$ があったとき、それらの重複 $A_1\cap A_2$ が有意に大きい (または小さい) ことを示したいときに使われます。$U$ は $A_1$, $A_2$ が動ける範囲を表す全体集合です。以下では上側検定のみ考えます。

例えば、「袋の中に100個の玉が入っていて、まず10個の玉を取り出し、それらに印をつけてから袋に戻してよく混ぜ、次に20個の玉を取り出したとき、印が付いていた玉が4個あります。これは偶然に起こり得るといえるでしょうか？」のような問題設定です。100個というのが全体集合 $U$、最初に取り出した10個が集合 $A_1$、次に取り出した20個が集合 $A_2$、そのうち印が付いていた4個が $A_1\cap A_2$ です。

$|U|=N$, $|A_1|=n_1$, $A_2=n_2$, $|A\cap B|=x$ とおくと、$A_1$ と $A_2$ が独立の場合に $x$ は超幾何分布 (hypergeometric distribution) に従うので、p値はPythonの場合以下で計算されます。
```
from scipy import stats
stats.hypergeom.sf(x-1,N,n1,n2)
```
ここで sf は生存関数 (survival function) を表します。等号を含まないため、$x$ から1を引いています。

しかし、集合が3つ以上の場合や、$A_1$ と $A_2$ の動ける範囲が異なる場合 ($A_1\subseteq U_1$, $A_2\subseteq U_2$, $U_1\neq U_2$) への拡張は容易ではありません。そこで、フィッシャーの正確検定の代わりに二項検定を使う方法を考え、数値計算で比較してみました。

# 二項検定を使う方法

$A_1$, $A_2$ の大きさを固定する代わりに、集合 $U$ の各要素が $A_1$ に含まれる確率 $p_1=n_1/N$ と $A_2$ に含まれる確率 $p_2=n_2/N$ を固定します。期待値について、$E[|A_1|]=n_1$, $E[|A_2|]=n_2$ が成り立ちます。

$A_1$ と $A_2$ が独立の場合、集合 $U$ の各要素が $A_1\cap A_2$ に含まれる確率は $p_1p_2=n_1n_2/N^2$ となります。従って、重複数 $x$ は二項分布 $\mathrm{Bin}(N,n_1n_2/N^2)$ に従い、p値はPythonの場合以下で計算されます。

```
stats.binom.sf(x-1,N,n1*n2/N**2)
```
フィッシャーの正確検定の近似と考えるよりも、異なる考え方に基づく別の検定であると解釈した方が良いと思います。

# 数値計算の設定

以下の条件でフィッシャーの正確検定と二項検定を比べました。
| 項目 | 設定 |
|------|-----|
|$N$|1000|
|$n_1$|100から1000まで100間隔|
|$n_2$|100から1000まで100間隔|
|出力|p<0.05となるために必要な重複数 $x$|

なお、可能な最大重複 $x=\min(n_1,n_2)$ でもp<0.05にならない場合は0と表記しました。

# 結果

![fisher_binom.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/a4ef3da6-84ba-8c3a-e574-68b0cae39b34.png)

全体的にかなり似た結果となりました。**どちらを使っても実用上は問題なさそうです**。二項検定の方が少しだけ値が大きい、つまり、有意になりにくい傾向がありました。

# 応用

二項検定の利点は拡張がしやすいことです。例えば、3つの集合 $A_1$, $A_2$, $A_3$ があるとき、3つ全ての共通部分が有意に大きいことを示すことが出来ます。$|U|=N$, $|A_i|=n_i (i=1,2,3)$, $|A_1\cap A_2\cap A_3|=x$ とすると、p値は以下で計算出来ます。
```
stats.binom.sf(x-1,N,(n1/N)*(n2/N)*(n3/N))
```
同様に、$A_1$ のみに含まれる部分なら、その数を改めて $x$ とおいて、
```
stats.binom.sf(x-1,N,(n1/N)*(1-n2/N)*(1-n3/N))
```
などと出来ます。

別の例として、全体集合が異なる場合に適用します。$A_1\subseteq U_1$, $A_2\subseteq U_2$, $U_1\neq U_2$ として、$|U_1|=N_1$, $|U_2|=N_2$, $|U_1\cap U_2|=M$, $|A_1|=n_1$, $|A_2|=n_2$, $|A_1\cap A_2|=x$ とおくと、p値は (多分) 以下で計算できます。
```
stats.binom.sf(x-1,M,(n1/N1)*(n2/N2))
```

# 追記: カイ2乗検定との比較

分割表に対するカイ2乗検定との比較も追加します。コメントを下さった某先生に感謝いたします。p値はPythonの場合以下で計算できます。
```
p = stats.chi2_contingency([[x,n1-x],[n2-x,N-n1-n2+x]])[1]
```

上と同じ条件で計算した結果を以下に示します。

![fisher_binom2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2787764/e9316731-032d-3963-a922-9e22fb0ef62d.png)

フィッシャーの正確検定とほぼ同じでした。もちろん、カイ2乗検定は近似的な手法のため、分割表のいずれかのマスの値が小さいときは不正確になる可能性があります。

カイ2乗検定は行数や列数が2より大きい分割表にも使えます。二項検定でも可能です。行数を $r$、列数を $c$ としたとき、 行和を $n_1,\ldots,n_r$, 列和を $m_1,\ldots,m_c$、総数を $N=\sum n_i=\sum m_j$ とすると、$i$ 行 $j$ 列の観測数 $x$ に対する二項検定のp値は (多分) 以下で計算出来ます。
```
stats.binom.sf(x-1,N,ni*mj/N**2)
```

$N$ 個の各要素が、$r$ 通りの値を取るカテゴリカル変数 $X$ と $c$ 通りの値を取るカテゴリカル変数 $Y$ の2つを持つと考えると分かりやすいと思います。$X$ と $Y$ が独立なら $p(X=i,Y=j)=p(X=i)p(Y=j)=(n_i/N)\times(m_j/N)$ が成り立ちます。
【Python】辞書の重複を排除する


備忘録です。
Pythonの辞書型のリストから、重複する値を排除する方法に困ったので残しておきます。

## 前提

以下のようなリストから重複したものを排除したいです。
```python:
user_list = [
    {"id": 1, "name": "Alice", "age": 25},
    {"id": 2, "name": "Bob", "age": 30},
    {"id": 3, "name": "Charlie", "age": 35},
    {"id": 1, "name": "Alice", "age": 27},
    {"id": 4, "name": "David", "age": 40},
    {"id": 2, "name": "Bob", "age": 32},
]
```

## エラーが出る例

set型に変換して、重複排除することはできません。

```python
unique_user_list = list(set(user_list))
```

```text:エラー内容
TypeError: unhashable type: 'dict'
```

## 解決策
ジェネレータ式を使用して、一意のキーの辞書を作成します。
```python:
unique_user_list = list({user["id"]: user for user in user_list}.values())
pprint(unique_user_list)
```

```text:出力結果
[{'age': 27, 'id': 1, 'name': 'Alice'},
 {'age': 32, 'id': 2, 'name': 'Bob'},
 {'age': 35, 'id': 3, 'name': 'Charlie'},
 {'age': 40, 'id': 4, 'name': 'David'}]
```

### 関数に切り出す
`id`だけでなく任意のキーで重複を排除できるようにします。
```python
def distinct_by_key(data: list[dict], key: str) -> list[dict]:
    return list({element[key]: element for element in data}.values())

unique_user_list = distinct_by_key(user_list, "id")
pprint(unique_user_list)
```
```text:出力結果
[{'age': 27, 'id': 1, 'name': 'Alice'},
 {'age': 32, 'id': 2, 'name': 'Bob'},
 {'age': 35, 'id': 3, 'name': 'Charlie'},
 {'age': 40, 'id': 4, 'name': 'David'}]
```
これで辞書型のリストから重複した値を排除することができました。
私のAWS クラウドプラクティショナーの勉強法

# AWSクラウドプラクティショナーを取得できました！
周りの皆さんの参考になるよう、記録を残します。

## 記事を書いている人
- 社会人1数年のSE
- システム保守・運用・開発をやっている会社に勤務

## AWS歴
- AWSで構築されたシステムの運用を2年ほど
- 運用上、マネジメントコンソールは日常的にアクセスしますので、多少知識は持っているつもりです
- 運用ツールをLambdaで作成したり
- ただし業務に耐えうる本格的なプロダクト開発は未経験

## 利用した教材
私が利用した教材をまとめます。以下の２つで十分だと思います。
- AWS認定資格 クラウドプラクティショナーの教科書: 合格へ導く虎の巻 CloudTech制作委員会シリーズ
    - 無料だなんて信じられないクオリティの教材です
- Udemy この問題だけで合格可能！AWS 認定クラウドプラクティショナー 模擬試験問題集（8回分520問）
    - 内容・解説ともに非常に充実していました。

# やって良かったこと
ご自身に合ったやり方があると思いますので、あくまで私がやって良かったかな、と思ったことです。私の場合、小学校低学年の息子がおり、土日は公園に行ったり習い事の送迎をしたりがあり、祝休日だからと言ってまとめて数時間の学習時間の確保、というのは現実的ではありません。なので、使える時間の現実線を捉えるところから始めました。
## 1. スケジュールを立てた！
- これは資格取得プロジェクトです！ガントを引くイメージでスケジュールを起こしました。
- 頭の中から外に出すのが大事。加えて、ちょいちょい目にいれるようにするのが良いと思います

## 2. 1日の過ごし方を振り返って、いつ勉強が出来るのか冷静に見直した！
- 自分の1日の流れをExcelで見える化してみました。1日のうち、どこを勉強に当てられるかを洗い出しました。
    - 私の場合は、朝起きがけの6:30〜7:00、23:00〜24:00ってな具合でした。無理なく続けられそうな落とし所を見つけた方が良いと思います。
    - 寝る前の暗記は定着しやすいような研究結果もあったりするようなので、そういう意味でも良かったのかもしれません。
        - 参考：[「勉強後30時間以内」にしっかり寝ると記憶が強く定着する](https://diamond.jp/articles/-/251690)

## 3. AWS認定資格 クラウドプラクティショナーの教科書 を短期間で繰り返し、眼を通す
- 本書の冒頭にもありました。3日程度で1周位のスピード感で、3回程度は眼を通すのが良いと思います。
    - 短い間隔で同じ内容をインプットするのが、実感としても良いと思います。
    - 始めは色々わからない単語も多いですが、調べるのも程々にどんどん進んだのは正解だったかなと思います。進んでいる実感があった方が精神衛生上もよろしいかと思います。

## 4. Udemyを繰り返し解く！
以下の通り、各単元を3回以上繰り返して解きました。
- 単元の初回は、解説に一通り目を通しました。
- 2回目は、間違えたところの解説を改めて眼を通しました。
- 3回目は、解きながら確信持てないところにマークをつけながら、問題集を解きました。

# 受験した感想
試験としては、スコア838での一発合格でした。正直、Udemyの模擬試験の方が難しかったです。そのため、Udemyでコンスタントに80%を超える正解率が取れれば、本番も合格できると考えて良いでしょう。
気になったところと言えば、Udemyの方は違和感のない日本語であることに対し、本番の方は英語直訳の影響なのか、ん？と思う日本語だなと感じた問題がそれなりにありました。個人的には日本語の部分で難しく感じる部分がありました。
加えて、AWSを全く触らずに勉強するのは、ピンと来にくいと思いますので、ec2を使ったwebサービス構築のハンズオンあたりは一度やってみると良いんじゃないかなと思います。

私の勉強法は以上です。誰かの参考になれば、幸いです。
設計について

# はじめに
プロジェクトにて設計書の作成を任されたときに、ほかの方が作成した資料を見よう見まねで作成していました。
しかしながら、実際に何を意識してどのように作成しなければいけないのかをうまく言語化ができていないままのため、
改めて資料作成について学習し、その内容を備忘録としてまとめていきます。
# 「設計」について
まず設計書の作成は要件定義の次、製造に入る前に行われます。
要件定義では何を作るのかを考えるフェーズとなりますが、設計では「どうやって作るのか」を考えるフェーズになります。

下の図のように設計でも「基本設計」と「詳細設計」に分かれることもあります。
それについては後述していきます。
<img width="600" alt="自作資料 図.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3185129/e66af081-1542-616a-86f7-b51e8de8fd91.jpeg">

# 「設計書」に書かれているもの

* システムの概要
* IF設計
* 機能一覧定義
* テーブル項目定義
* 画面イメージ
* 画面項目定義
* 処理概要

プロジェクトによって違いはありますが、たくさんの資料を作成する必要があります。

# 「基本設計」と「詳細設計」の違い
（※プロジェクトにより内容も異なってきます）

* 基本設計は外部設計ともいわれ、画面のイメージやざっくりとした機能の設計などが行われます。
システムの仕様について確定していくフェーズとなり、顧客に対して認識のすり合わせをしていくときに使われる資料でもあります。

* 詳細設計は内部設計といわれ、1つ1つの処理の詳細など記載していきます。
どうやって実装するのかということをプログラマーに伝えるための資料となります。

# まとめ

設計では「どうやって作るのか」を考えるフェーズとなり、そのあとの製造にも大きく影響するところになります。
設計書を作成する上での意識として「あとは手を動かせば完成する」状態を目指して作成していくとよいかもしれません。
うちのデスクノート君（i7-7700HQ）の調子が悪いからベンチマークしてみた

## あらまし
かなり前に買ってだましだまし使ってた
うちのデスクノート「7700HQ」君、
最近挙動がかなり怪しいので買い替える前に
「原因わからないかな？」と思って
ちょっとベンチマークしてみました。

## 7700HQ君のプロフィール
・マウスコンピューター m-Book
・CPU：Core i7-7700HQ
・メモリ：16GB
・SSD：500GB
・GPU：GeForce GTX 1050 4GB (mobile)
・OS：Windows 10 Pro
・[詳細スペックとか紹介はこちらの記事](https://qiita.com/kit/items/090239c6a0b2a990eab6)

# ベンチマーク結果

## 総合ベンチマーク
### CrystalMark 2004R7
![20230225_CrystalMark2004R7.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/91715637-c95c-bf6c-24fd-1b609ee57563.jpeg)
（https://forest.watch.impress.co.jp/library/software/crystalmark/）

## CPUベンチマーク

### Cinebench
##### マルチスレッド（スコア：3725）
![20230225_CINEBENCH_multi.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/c7132564-1146-acf4-fd88-da44646f8970.jpeg)

##### シングルスレッド（スコア：809）
![20230225_CINEBENCH_single.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/58b3b4de-6750-c5bf-a083-f47a5eb6f648.jpeg)

（https://www.maxon.net/ja/cinebench）

### SuperPI（8M：1m58s）
![20230225_SuperPI.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/e7633b6a-dcf9-85ae-23dd-de3b89f4426d.jpeg)


## メモリベンチマーク
### RAM Benchmark
![20230225_RAMBenchmark.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/649a57c0-646e-4f9e-2b56-5720b70f1441.jpeg)
（https://softaro.net/ram-benchmark/）

## SSDベンチマーク
### CrystalDiskMark
![20230225_SSDベンチ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/41239249-21d7-7040-8134-1f129413bca5.jpeg)
（https://crystalmark.info/ja/）

## グラフィックベンチマーク
### ファイナルファンタジーXVベンチマーク（スコア：1944）
![20230225_FF_Bench.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154954/1df8215b-fdfa-1cb4-aabd-90a3130804c1.jpeg)
（http://benchmark.finalfantasyxv.com/jp/）


## 感想と原因推測
調子悪い原因として、
とりあえずSSDが怪しいなぁと思いました。
空き容量が少なくなってるとはいえ、
SSD購入時にベンチ回したときは
Writeももっと早かった気がしたのだけど、
速度がかなり怪しい。

あとは、もういい加減寿命かなぁと。
全体的に最近のPCと比べると
スコアが見劣りしますね。

というわけで、
後日は新ノートでベンチマークしたいと思います。

7700HQ君は
後日SSD換装＋ESXiでも入れて、
お遊び環境になってもらおうと思います。
gem導入手順

# はじめに
Gemの導入方法を書いていきたいと思います:baby_tone1:！
ユーザーの承認機能作成方法で説明していきたいと思マス:star:

ユーザー承認機能を付けるには「devise」というgemをインストールします。(gem 'devise')


# 導入手順①②(③deviseの時のみ)まであります
①「Gemfile」というファイルに、記述します。(一番下に記述すると◎)
```php:Gemfile
gem 'devise'
```
　　　　　　　　　　　　　　　↓
②ターミナルに「bundle install」というコマンドを打ってインストールします
(railsアプリ内で使用できるようにする)
```php
$ bundle install
```
　　　　　　　　　　　　　　↓

(※deviseの場合のみ、下記の作業が必要になります)
③ターミナルにdeviseのインストール記述


```php:
$ rails g devise:install
```



# 大事なこと

- ①Gemfileとは、railsアプリで使うGemを記述しておく設計書にあたるファイル
- ②gemに追加したら必ず『bundle install』でインストールすること！！
（railsアプリ内で使用できるようにする為です。）

※注意※
- ③deviseの時のみですが、deviseの設定ファイルをrailsアプリにインストールする為に
gemをインストール(bundle install)した後に、
改めてインストール(rails g devise:install)が必要になります！
Github PagesでWebサイトを公開する方法

# Github PagesでWebサイトを公開する
Github Pagesを使ってサイトを公開する流れを備忘録としてまとめておきます。

## Github Pagesとは
Github PagesとはGithubが提供しているホスティングサービス。静的なWebサイトを無料で簡単にインターネット上に公開できる。

ホスティングサービスとは通信事業者が提供しているサーバーをインターネット経由で利用できるサービスのこと。

GithubはGitのホスティングサービス。Gitはファイルのバージョン管理を行うツールで、自分のPC内にある。

Github Pagesを利用したサイトの公開の流れをざっくりまとめると、自分のPC内にあるGitに公開したいサイトのファイルを保存し、それをインターネット上にあるGithubにアップロードして、そのGithubを利用してインターネット上に公開するという流れ。


## Github Pagesを使ってサイトを公開する流れ
1. 公開したいwebサイトを用意する
2. Githubのアカウントを作る
3. ローカルリポジトリを作り、webサイトをGitで管理する
4. リモートリポジトリを作り、ローカルリポジトリの内容をアップロードする
5. webサイトを公開する

### 公開したいwebサイトを用意する
公開したい任意のwebサイトを用意する。

注意点として、Github Pagesではユーザーや時間などの条件によって表示されるコンテンツが変化する動的なサイトは公開できない。Github Pagesで公開できるのはHTML、CSS、JavaScriptで作られた静的なサイトが対象である。

### Githubのアカウントを作る
Github Pagesを利用するにはGithubのアカウントが必要。

アカウントがない場合は以下のURLからアカウントを作成する。
https://github.com/


### ローカルリポジトリを作り、webサイトをGitで管理する
Githubを利用するためにまず自分のPC（ローカル）でGitを使ってファイルのバージョン管理を行う必要がある。

Gitの管理を行う流れは以下
1. Git管理を行いたいディレクトリで`git init`を実行し、ローカルリポジトリを作成する
2. ステージに変更を追加し、コミットする


コミットすることでローカルリポジトリにWebサイトのデータが保存される。


### リモートリポジトリを作り、ローカルリポジトリの内容をアップロードする
ローカルリポジトリを作成しファイルの内容を保存できたので、次はGithubでリモートリポジトリを作成しローカルの内容を保存する。

リモートリポジトリを作るには、自分のGithubのアカウントのページから`Repositories`をクリックして、次に`New`をクリックする。するとリポジトリ作成ページに遷移するのでそこからリポジトリを作成する。

リモートリポジトリを作成したら、コミットが完了している状態で`git push`を実行することでローカルの内容をリモートに保存する。

### webサイトを公開する
プッシュまで完了してGithubにWebサイトのデータを保存できたので、実際にWebサイトを公開する。

公開したいリポジトリのページの上部のタブにある`Setting`をクリックする。次に`Setting`ページの左のメニューにある`Pages`をクリックする。するとGithub Pagesのページが開かれる。

webサイトを公開するには、Github PagesページのBuild and deploymentのBranchの`None`となっているメニューをクリックし、公開したいブランチを選択する。

基本は`main`ブランチを選択する。こうすることで`main`ブランチのファイルの状態がインターネット上に公開される。

ブランチは複数人で並行して開発を行うために分岐させる仕組みのことで、`main`ブランチは実際にインターネット上に公開できる状態にしておく。プロジェクトによるが、何らかのバグが発生したり、機能を追加したりするときはこの`main`ブランチから新しくブランチを作成して作業する。

公開が完了すると、ページの上部に`Your site is live at [サイトのURL]`と表示される。


## まとめ
公開したいWebサイトをGithubにアップロードしたら、リポジトリのページ→`Setting`→`Pages`→公開したいブランチを選択し`Save`をクリックするだけ。

レンタルサーバーやクラウドなど公開する方法は他にもあるが、静的なWebサイトを公開するならGithub Pagesが簡単。
自分のメモ1(IT系)

# ITメモ1

## 初めに
自分がわからなくなった時のメモです。

### 用語

・Amazon S3 ストレージライフサイクルポリシー
Amazon S3 Standard から Amazon Glacier にデータを自動的に移行するライフサイクルポリシーを設定できます。アクセス頻度の低いデータを他のストレージクラスに移動すると、オンプレミス環境に比べてストレージコストを大幅に削減できる。



※メモがわりで更新
電気工学

電験3種の勉強中です
長方形をひとつ思い浮かべ、
縦の長さを電圧V
横の長さを電流I
縦横比を抵抗R(=V/I）
面積をP(=V*I)
として考えると、いろいろ都合が良いのかなと
思いながら過去問題を解いています
MonacoinのSnappyパッケージの提供を開始しました

こんにちは。びりあるです。

Monacoinの非公式なSnappyパッケージを作成しました。

https://snapcraft.io/monacoin

Snappyは複数のLinuxディストリビューションで動作するパッケージングシステムであり、多くのLinuxディストリビューションで動作することが期待できます。



# インストール

まずは各ディストリビューションの提供するSnappyのパッケージをインストールしてください。

Debian/Ubuntuでは

```
$ sudo apt install snapd
```

でインストールすることができます。

次にMonacoinのSnappyパッケージ (Snap) を以下のコマンドを実行してインストールします。

```
$ snap install monacoin
```



# 更新

新しいバージョンのSnapが提供された場合には

```
$ snap refresh monacoin
```

で最新バージョンに更新することができます。


# 使い方

デスクトップ版のLinuxではランチャーなどから「monacoin」と検索することでGUIクライアントが起動します。

また、コマンドとして

- monacoin.cli
- monacoin.daemon
- monacoin.qt
- monacoin.tx
- monacoin.wallet

が利用可能になります。

デフォルトのデータディレクトリは

```
$HOME/snap/monacoin/common/.monacoin
```

になります。



# Ubuntu PPA の今後の方針

筆者はMonacoinのUbuntu向けPPA (Personal Package Archive) を2015年より提供してまいりました。

https://launchpad.net/~visvirial/+archive/ubuntu/monacoin/+packages

本Snappyパッケージのリリースにより、Ubuntu/Debian系以外のディストリビューションでも動作するパッケージングシステムに移行したことにより、上記のPPAの提供は終了する予定です。



# snapcraft.yaml

パッケージングに利用した `snapcraft.yaml` などのデータは GitHub 上にてオープンソースで公開しています。

https://github.com/visvirial/monacoin-snap

こちらは Bitcoin Core の提供しているファイルを元に Monacoin 向けに改変を行うことで作成しています。

具体的には、GitHub 上の Monacoin リポジトリのビルド済みリリースファイルをダウンロードし、パッケージに突っ込んでいます。

パッケージングに対するバグを発見された方は、上記のリポジトリにissueまたはPRの作成をお願いします。

Monacoin本体のバグに関しては、こちらに報告いただいても対応できませんので、Monacoinのリポジトリに対して報告を行ってください。



# 最後に

本パッケージの提供は完全にボランティア（趣味）で行っているため、自己責任の元で利用してください。

また最新のリリースへの対応やバグ対応などは可能な限り行いますが、本業などの都合で対応できないこともあります。

あくまで非公式のコミュニティ版という立ち位置であることをご理解ください。
bashでマッチした部分だけを抽出する正規表現 Lv1

簡単なコマンドのみ

# コマンド
```bash
$ egrep -o '(.*extracted-character/)'
```
egrep は拡張grep
-o はマッチした部分だけ抽出する



# 実行例
```bash
$ pwd
/path/to/my-project-name/src/dir/

$ pwd | egrep -o '(.*my-project-name/)'
/path/to/my-project-name/
```


# 動機
ShellScript内で、プロジェクトルートのpathを取得する際に利用しました。


# 環境
- macOS
- zsh

# 参考
- どのUNIXコマンドでも使える正規表現 - Qiita https://qiita.com/richmikan@github/items/b6fb641e5b2b9af3522e
コントローラー作成の仕方(devise用)

# はじめに
devise用のコントローラーの作成の仕方をアウトプットしたいと思います:fist:

diveseのコントローラーを作成すると、before_actionを使用することができたり、
使用する機能のみルーティングを行うことが出来ます！

※before_actionとは・・・アクションの前に処理を実行するもの

---

### コマンドを打ちます

～顧客用～

```php
$ rails g devise:controllers public
```

～管理者用～
```php
$ rails g devise:controllers admin
```


こんな感じ:ok_hand_tone2:
PythonからDatabricks REST APIを呼び出してみる

こちらを参考に一通り動かしてみます。というかPythonのAPIがあることを知らなかったと言う。

https://docs.databricks.com/dev-tools/python-api.html

DatabricksはREST APIを公開しているので、(適切な認証を経た上で)外部からDatabricksを操作できます。REST APIですと`curl`などを使うのが一般的かと思いますが、より複雑な処理の中にAPI呼び出しを組み込みたい場合には、Pythonから呼び出せた方が何かと便利かと思います。と言うことで、Python APIも公開していました。

# 準備

- [Databricks CLI](https://docs.databricks.com/dev-tools/cli/index.html)をインストールします。
- [こちらの手順](https://qiita.com/taka_yayoi/items/fa7f10bc80475c513383)に沿って、Databricksパーソナルアクセストークンを取得しておく必要があります。



今回はVS Codeから操作するので以下の手順で、パーソナルアクセストークンを環境変数に設定しておきます。

```bash:Bash
export DATABRICKS_HOST="<DatabricksワークスペースのURL>"
export DATABRICKS_TOKEN="<パーソナルアクセストークン>"
```

VS Codeを起動します。

```bash Bash
code .
```

# コードの記述

シンプルな例としてクラスター一覧を取得します。

```py:Python
import os
from databricks_cli.sdk.api_client import ApiClient
from databricks_cli.clusters.api import ClusterApi

api_client = ApiClient(
  host  = os.getenv('DATABRICKS_HOST'),
  token = os.getenv('DATABRICKS_TOKEN')
)

clusters_api   = ClusterApi(api_client)
clusters_list  = clusters_api.list_clusters()

print("Cluster name, cluster ID")

for cluster in clusters_list['clusters']:
  print(f"{cluster['cluster_name']}, {cluster['cluster_id']}")
```

これを実行することでクラスター一覧を取得することができます。
![Screenshot 2023-02-25 at 21.01.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d29da72b-b0b7-2e4d-40cb-e8c00ca01728.png)

次はもう少し複雑な例にトライしてみたいと思います。

なお、最近 **API Explorer(ベータ版)** が公開されました。

https://docs.databricks.com/api-explorer/workspace/clusters

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
エクセルマクロ(VBA)超入門 その１

# はじめに
Excelマクロ(VBA）を使いこなせば、様々な業務が効率化されます。
そこで、これからエクセルマクロを始めたいと思っている方向けに、エクセルマクロ超入門編１と題して、エクセルマクロの初期設定方法や使い方をご紹介します。
尚、初めての方は、文章だけでは分かりにくいと思いますので、主な操作はYoutubeの動画をご覧頂き、完成したプログラムを、以下にご紹介します。

# 環境
Windows10
Microsoft365バージョンのExcel

# 解説の流れ:
・エクセルの開発タブの表示方法
・エクセルマクロの自動記録機能紹介
・自動記録されたマクロの見方
・ファイルの保存方法
・自動作成されたマクロを編集してシンプル化

# YouTubeでの解説：
上記の作業の流れをYoutubeで詳しく解説していますので、ぜひ、ご覧ください。
<iframe width="560" height="315" src="https://www.youtube.com/embed/EncnS-7pT6E" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" loading="lazy" allowfullscreen></iframe>

# サンプルソース
YouTubeで紹介している処理のプログラムソースです。
```vb:練習1
Sub 練習1()
'
' 練習1 Macro
'
    Range("A1").Value = "No"
    Range("B1").Value = "商品"
    Range("C1").Value = "価格"
    Range("A2").Value = "1"
    Range("B2").Value = "ペン"
    Range("C2").Value = "100"
    Range("A3").Value = "2"
    Range("B3").Value = "消しゴム"
    Range("C3").Value = "50"

End Sub
```


# 最後に：
今回は、エクセルマクロの超入門編１ということで、これだけでは、業務に役立つものではありませんが、今後、徐々にレベルアップして、最終的には業務に役立つプログラムもご紹介していきたいと思います。
GoにてGithubActionsを使用してpush時に自動テストを設定した際に発生したエラー

# 概要

本日はGoアプリケーションの開発でGithubActionsを利用してpush時に自動テストが通るような構成を作成してみました。

その際にちょっとしたミスのせいで依存関係のインストールが上手くいかず、少し手間取ったので共有します。

# GithubActions構成(修正前)

まず、修正前の構成は下記です。

```yml
name: Golang Test
run-name: ${{ github.actor }} run Github Actions
on: push
jobs:
  Test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.20

      - name: Install dependencies
        run: go mod download

      - name: Build
        run: go build -v ./...

      - name: test
        run: go test -v ./...
        env:
          TOKEN_LIFETIME: "3600"
          SECRET_KEY: "testsecretkey"

```

# 起こったエラー

起こったエラーは下記で、`mod`というコマンドは知りませんというメッセージが出ています。

```txt
go: unknown subcommand "mod"
Run 'go help' for usage.
Error: Process completed with exit code 2.
```

はい？そんなわけないよなと思い一応`mod`について調べました。

すると下記の意見を見つけました。

>Preliminary module support was added in Go 1.11, so Go 1.10 knows no mod subcommand.

引用元：　[stackoverflow](https://stackoverflow.com/questions/60410729/unknown-subcommand-mod-error-while-running-go-mod-init#:~:text=Preliminary%20module%20support%20was%20added%20in%20Go%201.11%2C%20so%20Go%201.10%20knows%20no%20mod%20subcommand.)

簡単に言うと、`mod`というサブコマンドはGoのバージョン`1.11`からサポートされるようになったみたいです。

しかし、今回の構成ではバージョンは`1.20`にしていたはずと思ったので確認しました。

```yml
- name: Set up Go
    uses: actions/setup-go@v3
    with:
      go-version: 1.20
```

確認してみるとバージョン指定している部分が文字列になっていないではないか。

```yml
- name: Set up Go
    uses: actions/setup-go@v3
    with:
      go-version: 1.20　 ← 文字列になってない
```

もしやこれではないかと思い、下記のように修正しました。

```yml
- name: Set up Go
    uses: actions/setup-go@v3
    with:
      go-version: "1.20"
```

そして再度実行させてみると、**無事に成功**させることができました！

# GithubActions構成(修正後)

修正後の構成ファイルも一応貼っておきます。

```yml
name: Golang Test
run-name: ${{ github.actor }} run Github Actions
on: push
jobs:
  Test:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: "1.20"

      - name: Install dependencies
        run: go mod download

      - name: Build
        run: go build -v ./...

      - name: test
        run: go test -v ./...
        env:
          TOKEN_LIFETIME: "3600"
          SECRET_KEY: "testsecretkey"

```

# まとめ

いかがだったでしょうか。

ほんの些細なミスに気づけなかったために、少し時間を無駄にしてしまいました。

こういったところにもしっかり気を配れるようになりたいです。

最後まで読んでいただいてありがとうございました！
Swift UI & YouTube Data API v3

## はじめに
YouTube Data API v3を使用して検索アプリを作成しました。
APIの使い方を忘れないために手順を記載します。

## 1. APIの作成
検索アプリを作成するために、Google Cloud PlatformにログインしYouTube Data API v3を有効にして、APIキーを作成する必要があります。YouTube Data API v3は、**キーワードでヒットする動画情報やチャンネル情報**を取得することができます。
ここでは、APIの作成などのやり方は割愛します。以下の記事がすごくわかりやすいので参照してください。
https://zenn.dev/eito_blog/articles/f2d870ffddb636

## 2. APIをリクエストURLに適用
まずYoutubeから動画などを取得するには、APIキーを使用しGETリクエストする必要があります。
YouTube Data API v3の基本的なURLは以下になります。

```
https://www.googleapis.com/youtube/v3/search?key=<作成したAPIキー>&好きなパラメータ
```
好きなパラメータには、**part**、**q**、**type**、**maxResults**など色々なものを指定できます。

**part：idとsnippetのみ指定可能（string）**
**q：検索文字を指定する（string）**
**type：どのようなタイプで返すか決める（string）**
**maxResults：アイテムの最大数（int）**

他にも様々なパラメータが指定可能なので、[ドキュメント](https://developers.google.com/youtube/v3/docs/search/list?hl=ja)から参照してください。
また、以下はリクエストの例になります。
```Swift:リクエスト用の文字列を作成
// 最大検索数
let maxResults = "10"
// APIKeyを設定
let APIKey = "作成したAPIキーを入れる"

let url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=\(keyword)&type=video&maxResults=\(maxResults)&key=\(APIKey)"
```
以下は実際に作成したアプリとコードです。
https://github.com/yuuta-hoshi/SearchYoutube
![Simulator Screen Recording - iPhone 14 Plus - 2023-02-25 at 16.02.28.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072069/b8ea0699-3956-b090-b91c-99dd1f73c6b8.gif)

## おわりに
既存のサービスのAPIを使用するとアプリ開発の幅が広がるため引き続き学習していきたいです！:blush:
IntelliJ IDEAで環境変数を使用するときの注意点

# はじめに
IntelliJでkotlinのコードを書いてる時に環境変数の扱いでハマったので備忘録代わりに書きます。
ちなみに環境はMacです。

# ハマった経緯
kotlinで環境変数を使いたかったので
ターミナルから環境変数の追加を以下のように行いました。

```zsh:環境変数のファイルを開く
nano ~/.zshrc  
```
```zsh:最終行に環境変数を追加する
export test=koike
```
testが環境変数名でkoikeが値です。
環境変数設定後
```zsh:設定を反映させる
source ~/.zshrc
```
上記のコマンドで設定を反映させました。


設定反映できたと思ったので
kotlinコード内で
```kotlin:環境変数の取得
println(System.getenv("test"))
```
上記のように環境変数の取得を行おうとしたのですが
出力されたのは  「null」 ...

あれ？と思い
ターミナルで以下コマンドで環境変数の一覧を取得
```zsh:環境変数の一覧を取得
printenv
```
すると、しっかり　test=koikeが反映されています。
なぜだ！！！！なぜkotlinから環境変数が取得できない！！！


# 原因
IntelliJの環境変数の読み込みタイミングが原因でした。
どうやらIntelliJは環境変数の読み込みを起動時に行なっているっぽいです。

環境変数をターミナルから設定した後は　IntelliJを完全に終了させたのち再度起動するようにしましょう！
※IntelliJ内のターミナル経由で環境変数を設定しても同様です。
他にも対応策あれば教えてください。

# まとめ
この単純な問題に気づくのに時間が掛かってしまいましたが
こんなことで時間を無駄にしたとは思わず、いい気付きを得られたとポジティブに考えたいと思います。
System.identityHashcode

System.identityHashcode・・・オブジェクトとしてのhashCode
hashcode・・・オーバーライド可能なhashcode
Stringのhashcodeはメモリ上は別のものを指していても、値が同じ場合同じ値を返す
identityHashcodeは別の値を返す

mutable/immutableのstudyに使用できる

下記の例ではaaaを途中でnew Stringしているのでidentityhashcodeは変更、
値は同じためhashcodeは同じ。

```java
class A{
    int i;
    A(int i) {
        this.i = i;
    }
}
public class SampleProject {
    public static void main(String[] args) {
        String s = "aaa";
        String s1 = "aaa";
        String s2 = "aa2";
        method("s",s);
        method("s1",s1);
        method("s2",s2);
        s = new String("aaa");
        method("s",s);
        A a = new A(1);
        A a2 = new A(1);
        method("a",a);
        method("a2",a2);
    }
    static void method(String varName, Object o) {
        System.out.println(varName + " identityHashCode:" + System.identityHashCode(o) + " " + o.toString());
        System.out.println(varName + " HashCode:" + o.hashCode() + " " + o.toString());
    }
}
```
```
s identityHashCode:249515771 aaa
s HashCode:96321 aaa
s1 identityHashCode:249515771 aaa
s1 HashCode:96321 aaa
s2 identityHashCode:748658608 aa2
s2 HashCode:96274 aa2
s identityHashCode:546718765 aaa
s HashCode:96321 aaa
a identityHashCode:592179046 sampleproject.A@234bef66
a HashCode:592179046 sampleproject.A@234bef66
a2 identityHashCode:1937348256 sampleproject.A@737996a0
a2 HashCode:1937348256 sampleproject.A@737996a0
```
数値積分 2/(x+exp(x))「2023東京工業大学理系第１問」をwolframalphaとsympyとscipyでやってみた。


グラフがでます。
オリジナル

https://youtu.be/AOy49NpsanQ

上と同じです。大学入試数学問題集成＞テキスト

https://mathexamtest.web.fc2.com/2023/202310267/2023102670100mj.html

# wolframで

https://www.wolframalpha.com/input?i=integrate%282%2F%28x%2Bexp%28x%29%29%2C%28x%2C0%2C2023%29%29&lang=ja

定積分
integral_0^2023 2/(e^x + x) dx≈1.61279...

# sympyで(手計算で)
勉強中

# sympyで(計算できませんでした。)
```python
rom sympy import *
x=Symbol('x',real=True,positive=True)
y=2/(x+exp(x))
print("#",integrate(y,(x,0,2023)))
plot(y)
plot(y,(x,0,2023))
# 2*Integral(1/(x + exp(x)), (x, 0, 2023))
```
plotコマンドは、縦横比？異なります。
sympyのグラフは、調子悪いです。

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/86314647-500a-4d1f-1fd2-d2ca7e6ff7d4.png)

![Figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109698/0f701019-b99d-a460-e9d6-d83b3443b2df.png)

# scipyで
数値積分で
```python
from sympy import *
import numpy as np
from scipy import integrate
y = lambda x: 2/(x+exp(x)) 
integ = integrate.quad(y,0,2023)
print("#",integ)
# (1.6127912324146527, 6.673383536190473e-10)
```

# scipyで(不思議という事で)
```python
from sympy import *
import numpy as np
from scipy import integrate
y = lambda x: 2/(x+exp(x)) 
print("# ",integrate.quad(y,0,  0.9))
print("# ",integrate.quad(y,0,  1.0))
print("##",integrate.quad(y,0, 2023))
print("# ",integrate.quad(y,0,21692))
print("# ",integrate.quad(y,0,21693))
#  (0.9760045319574304, 1.0835827035176387e-14)
#  (1.0326015267380333, 1.1464179902476538e-14)
## (1.6127912324146527, 6.673383536190473e-10)
#  (1.6127912324146525, 1.3533953322442555e-12)
#  (7.492842135501631e-09, 1.4898058188138345e-08)
```

# 参考

https://scipy.org/

https://www.google.com/search?q=python+scipy+%E6%95%B0%E5%80%A4%E7%A9%8D%E5%88%86&rlz=1CAUHAM_enJP1038JP1038&sxsrf=AJOqlzV2zrAepVq21SzQoh4-dsXZyXJfbw%3A1677320505334&ei=OeH5Y9TqE7Hg2roP5OKesAc&oq=python+scipy%E3%80%80%E6%95%B0%E5%80%A4&gs_lcp=Cgxnd3Mtd2l6LXNlcnAQAxgASgQIQRgAUABYAGAAaABwAHgAgAEAiAEAkgEAmAEA&sclient=gws-wiz-serp
React + Rails + GraphQL で画像投稿機能をつくる！

# 最初に
最近Reactもさわることが増えたので、学習用に
- React + Rails + GraphQL

でSPAの個人アプリを作成しています！
そこで、今回は画像投稿機能をつくってみようとおもいます！


### 使うものについてさらっと説明

- Ruby on Rails （バックエンド）
- React（フロントエンド）
- TypeScript
- GraphQL
- Apollo

## 実装

### バックエンド
#### 画像アップロードのため以下のGemを入れる
```
# Gemfile
gem 'carrierwave'
gem 'carrierwave-base64' 
```
- モデルファイルにアップローダーを指定する記述を追加
    - 以下の記述だけでbase64で渡ってきたデータを画像として保存してくれる...!
```
# Item.rb
class Item < ApplicationRecord
  mount_base64_uploader :image, ItemImageUploader <- これを追加
end
```

（もしcarrierwaveがわからない方は、調べていただけますと:pray_tone1:）

#### Resolverにて引数で値を受け取って保存
```
# app/graphql/mutations/create_item.rb
module Mutations
  class CreateItem < Mutations::BaseMutation
    argument :params, InputTypes::Item, required: true <- 引数用のTypeファイル

    field :item, ObjectTypes::Item, null: false

    def resolve(params:)
      item = Item.create!(params.to_h)

      {item: item}

    rescue => e
      GraphQL::ExecutionError.new(e.message)
    end
  end
end

```

```
# app/graphql/input_types/item.rb（引数用Typeファイル）
module InputTypes
  class Item < Types::BaseInputObject
    graphql_name 'ItemAttributes'

    argument :image, String, required: false <- 追加
  end
end

```


### フロントエンド

#### 画像選択用のフォームを作る

- inputタグ追加（type="file"でファイル選択フォームに）

```
<input
  name="file"
  type="file"
  accept="image/png"
/>
```

- 画像選択フォームができる
![スクリーンショット 2023-02-25 19.45.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730386/577e350f-251b-cf74-27b2-f578de6d1225.png)

#### useStateを使って、選択画像を管理するstateを追加

```
  import { useState } from "react";
  const [image, setImage] = useState<string | undefined>(undefined)
```

#### 画像選択時に、↑のimage stateに画像データをセットする関数を追加
readAsDataURLで、画像をbase64（画像を文字列に変換）にしています！
※ GraphQLはJSONでデータを受け渡すためバイナリデータを扱うことができないので、文字列に！
```
  const onChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files
    if (files && files[0]) {
      const reader = new FileReader()
      reader.readAsDataURL(files[0])
      reader.onload = function() {
        var image: any
        image = reader.result;
        setImage(image); <- image stateに画像をセット
      }
    }
  }
```
- inputタグで、画像セット時に↑の関数を呼び出して、選択画像をimage stateにセットする
```
<input
  name="file"
  type="file"
  accept="image/png"
  onChange={onChangeFile} <- 追加
/>
```
- 以下のように、image stateを、imgタグのsrcにセットすると選択中の画像が確認できるかとおもいます！
```
<img src={image} />
```
![スクリーンショット 2023-02-25 19.59.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1730386/c742abb9-017c-ceac-b93b-a4947d774917.png)

#### あとはimageのデータを、Mutationの引数に渡すだけ
```
const [createItem] = useCreateItemMutation();
createItem({ variables: { params: { image: image } } });
```

以上が実装の一例となります！
記事を見てくださりありがとございました！！
C#での整数の除算時にFloor・Ceilした値を返す (正値の範囲版)

# まとめ

正値の範囲において、整数の除算を行った結果をFloor・Ceilしたい時、

* Floorは、`c = a / b`
* Ceilは、`c = (a - 1) / b + 1`

で、計算可能。

# 整数の除算時にFloor (正値の範囲版)

C#で、「整数 / 整数」の除算の計算では、どのような値が算出されるかを、下記のコードで確認すると、

(int: 10→1までをint: 3で割った時。`c = a / b;`の部分の計算)
```C#
using System;

namespace ConsoleApp1 {
    class Program {
        static void Main(string[] args) {
            /* 結果: 
▼整数除算の「/」の確認用 Floorの値と同じ 正値の範囲のみ
int: 10 / 3 =  3
int:  9 / 3 =  3
int:  8 / 3 =  2
int:  7 / 3 =  2
int:  6 / 3 =  2
int:  5 / 3 =  1
int:  4 / 3 =  1
int:  3 / 3 =  1
int:  2 / 3 =  0
int:  1 / 3 =  0
            */

            Action<string> WL = Console.WriteLine; // 短縮

            WL("▼整数除算の「/」の確認用 Floorの値と同じ 正値の範囲のみ");
            var a = 10;
            var b = 3;
            for (; a >= 1; a--) {
                var c = a / b;
                WL($"int: {a,2} / {b} = {c,2}");
            }
        }
    }
}
```

Floorした値と同じものになっており、「整数 / 整数」の除算の計算は、そのままFloorした値として、使用できるものと分かります。

# 整数の除算時にCeil (正値の範囲版)

整数の除算を行った結果をCeilしたい時は、Floorの結果を下に2つだけシフトさせればCeilになるので、`c = a / b`を少しシフトさせて、`c = (a - 1) / b + 1`とすると、

(int: 10→1までをint: 3で割った時。`c = (a - 1) / b + 1;`の部分の計算)
```C#
using System;

namespace ConsoleApp1 {
    class Program {
        static void Main(string[] args) {
            /* 結果: 
▼整数除算でCeilの値を作る 正値の範囲のみ
int: 10 / 3 =  4
int:  9 / 3 =  3
int:  8 / 3 =  3
int:  7 / 3 =  3
int:  6 / 3 =  2
int:  5 / 3 =  2
int:  4 / 3 =  2
int:  3 / 3 =  1
int:  2 / 3 =  1
int:  1 / 3 =  1
            */

            Action<string> WL = Console.WriteLine; // 短縮

            WL("▼整数除算でCeilの値を作る 正値の範囲のみ");
            var a = 10;
            var b = 3;
            for (; a >= 1; a--) {
                var c = (a - 1) / b + 1;
                WL($"int: {a,2} / {b} = {c,2}");
            }
        }
    }
}
```

Ceilした値と同じものになります。

# 正値の範囲に限定した内容

:::note info
「整数 / 整数」の除算は、負値の場合が特殊なので、本稿は、正値の範囲に限定した内容になっています。

詳細: 
---
整数の除算「整数 / 整数」は、ゼロ側の整数へ寄せる動作になる (正負の間で特性が変わり特殊)
https://qiita.com/dl_from_scratch/items/b55ec179729a0e215a7a

C#での整数の除算時にFloor・Ceilした値を返す (正値・負値全ての範囲版)
https://qiita.com/dl_from_scratch/items/d3a20eaec07c3eb2c596
:::
現場Railsを読んで参考になった部分（Chapter3）

Railsを1から復習するため、
「現場で使えるRuby on Rails」通称「現場Rails」という本を読んでいます。
勉強になった部分をアウトプットしたいと思います。

参考書籍：

https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Ruby-Rails-5%E9%80%9F%E7%BF%92%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-%E5%A4%A7%E5%A0%B4%E5%AF%A7%E5%AD%90/dp/4839962227


https://github.com/pandineer/genbadetsukaeru_Ruby_on_Rails_5_sokushuzissenguide

## データベースの環境ごとの使い分け
Railsではデフォルトで3種類の環境が用意されていて、
1つの環境に対して1つのデータベースを対応させる。
```
config/database.yml

開発環境：
　development（開発時の動作確認を行う環境）
テスト環境：
　test（自動テストの時に使う環境）
本番環境：
　production（ユーザが利用する時に使う環境）
```

基本的に開発時は、開発環境とテスト環境の2種類の環境を使用する。
サーバ起動前にdb:createコマンドを実行する必要があるが、
それによって、2つのデータベースが作成済みとなっている。
```
Created database 'アプリ名_development'
Created database 'アプリ名_test'
```

## テンプレートエンジン
HTMLのテンプレート（雛形）とそこに記述された動的な処理から、
最終的なHTMLを生成するための仕組み。
Railsはデフォルトで、erbというテンプレートエンジンを使用する。
erbはHTMLとほぼ同じ見た目で、Rubyスクリプトを埋め込むことが可能。

## Railsのエラーメッセージを日本語で出す方法
初期状態だとエラーメッセージが英語で出力されるため、
エラーメッセージを日本語に設定したい場合は日本語翻訳ファイルが必要とのこと。
やることは下記2点。
・localeの言語設定を行う
・辞書ファイルのダウンロードを行う


## BootStarp
CSSのフレームワーク。
Railsで使う場合は、bootstrapというgemをGemfileに追加して、bundleでインストール。
rails newをした直後は、アプリケーション全体で1つのCSSファイル(application.css）を読み込むようになっている。
他のcssファイルはapplication.cssからさらに読み込む形で記述することになる。
したがって、Bootstrapはapplication.cssから読み込むようにしていく方がよいという。


## モデル（Model）

>モデルとは:
>ビジネスロジックを担当する部分です。
>DBとデータをやり取りしたり、データの登録・更新・削除などの処理を行います。
>DBから取得したデータや処理の結果はControllerに送ります。
>>参考文献：
>>https://system-kaihatu.com/archives/3204#:~:text=MVC%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8%E3%81%AF%E3%80%81%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0,%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8%E5%91%BC%E3%81%B0%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82

https://ja.wikipedia.org/wiki/%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF#:~:text=%E3%83%93%E3%82%B8%E3%83%8D%E3%82%B9%E3%83%AD%E3%82%B8%E3%83%83%E3%82%AF%EF%BC%88%E8%8B%B1%3A%20business%20logic,%E8%AA%AC%E6%98%8E%E3%81%AE%E4%BB%95%E6%96%B9%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82


Railsの「モデル」は主に2つの要素から構成される。
・モデルに対応するRubyのクラス
・モデルに対応するデータベースのテーブル

## マイグレーション
Railsのモデルクラスは、DBのテーブルの定義を読み込んで動作する。
そのため、モデルを作成する場合は、まずDBへのテーブル追加から行うとスムーズとのこと。

データベースにテーブルを追加する場合、Railsの用意しているマイグレーションという仕組みを使う。
DBスキーマ（テーブル構造等）への変更をRubyのプログラムとして実現する。
メリット：
・1か月前のコードの状態でアプリケーションを動かしたいといった場合、
　必要なところまでスキーマの状態を戻すことが可能。
・複数の開発者が同時に別々のスキーマ変更を行っているケースでも、混乱なく、
　必要な変更だけをデータベースに反映することができるメリットがあるとのこと。

## リクエストパラメータ
Webアプリでは、リクエストにデータを添えることができる。
このデータを「リクエストパラメータ」と呼ぶという。
リクエストの仕方は2通りに分かれる。
・POSTで送る。form要素をsubmitする。
・GETで送る。URLの?以降に情報を含めることで送る。
Railsでは、コントローラにおいてparamsというメソッドを利用することで、
送られてきたリクエストパラメータをHashのような感覚で取得できる。
Amazon RDS Proxy メモ


## 概要

* Amazon RDS 向けの高可用性フルマネージド型DBプロキシサービス。

* アプリがDBと確立した接続をプールおよび共有することができる。

  

## 利点

* **パフォーマンス向上**
  * コネクションをプーリングすることで、DBは多数のアプリ接続の頻度を効率的に行うことができ、パフォーマンス低下を防ぐことができる。
* **可用性向上**
  * フェイルオーバー時にアプリ接続を維持しながら新しいDBインスタンスに自動的に接続することでき、アプリの停止時間を抑えることができる。
* **セキュリティ向上**
  * DBアクセスに IAM 認証を適用できる。また、AWS Secrets Manager を介してDBの認証情報を一元管理できる。



## ユースケース

* **サーバーレスアプリの開発**

  * サーバーレスアーキテクチャで構築されるアプリの多くは、DBサーバーへの接続を多数使用することになる。

  * 高頻度のDB接続により、メモリなどリソースを消耗する可能性がある。

    ![rds_no_proxy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/f6501ad3-4e8f-3e55-d4f4-b9daab1cbbcd.png)




* **RDS Proxy**を導入することで、アプリがDBと確立した接続をプーリングおよび共有でき、DB接続効率とアプリのスケーラビリティを向上させることができる。

  ![rds_proxy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/e0d147a7-adb5-94d4-ae7a-373d9f69a424.png)






## 参考情報

* [Amazon RDS Proxy](https://aws.amazon.com/jp/rds/proxy/)
【SwiftUI】Combineで初回だけ値を流さない

# はじめに
Combineを使用して値の監視を行うコードを書いていたのですが、躓いたポイントがあったので記録しておきます。
改善前のコードでは`ViewModel`が初期化されたタイミングでも値が流れてきてしまいます。
初期化の段階では値は変化していないので値は流したくありません。
初回のみ値を流さないようにすることでこの問題を解決しました。

# 改善前の実装
```swift:ViewModel
import Combine

final class ViewModel: ObservableObject {
    @Published var text: String = ""

    private var cancellable = Set<AnyCancellable>()

    init() {
        $text
            .sink { _ in
                print("値が変化しました")
            }
            .store(in: &cancellable)
    }
}
```

# 改善後の実装
```diff_swift:ViewModel
import Combine

final class ViewModel: ObservableObject {
    @Published var text: String = ""

    private var cancellable = Set<AnyCancellable>()

    init() {
        $text
+           .dropFirst()
            .sink { _ in
                print("値が変化しました")
            }
            .store(in: &cancellable)
    }
}
```

# おわり
Combineは開発が終わったってTwitterで話題なのでちょっと悲しいです
【Laravel8】ログイン画面の表示がおかしいとき



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/f4940a02-2c2c-78dd-eb03-bf6b2c9c5781.png)


↑ログイン画面がこのような表示になってしまう

# 原因

package.jsonはlaravel-mix指定なのに、
layouts/guest.blade.phpとlayouts/app.blade.phpで、@Viteが使用されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/ce5407bc-f0ef-85c8-192c-13e2c7d4b65d.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/4d29a304-ce5a-7f7a-2537-52fba99bb0f6.png)


# 修正

下記コードを削除
```php:resources/views/layouts/gust.blade.php
@vite(['resources/css/app.css', 'resources/js/app.js'])
```
書き換え
```php:resources/views/layouts/gust.blade.php
<!-- Styles -->
<link rel="stylesheet" href="{{ asset('css/app.css') }}">

<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
```
※resources/views/layouts/app.blade.phpも同様

# 確認

簡易サーバーを立ち上げて確認

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784589/6b016ee2-9a31-d8ec-b4f6-a606be67bdf0.png)

成功
【Java/SpringBoot】入門記事リンク集

# 0. はじめに
大阪の受託開発エンジニアの、kazumakishimoto([@kazuma_dev](https://twitter.com/kazuma_dev))です！

## 0-1. 全体の流れ
> [1.ロードマップ](#1-ロードマップ)
> [2.教材](#2-教材)
> [3.環境構築](#3-環境構築)
> [4.IDE](#4-ide)
> [5.入門記事](#5-入門記事)
> [6.チートシート](#6-チートシート)

## 0-1. TL;DR
- Java/SpringBootの教材や参考リンク集まとめ

# 1. ロードマップ
https://qiita.com/yoichiwo7/items/17190cb440ab7d253cea

https://qiita.com/haruto167/items/5a784df032518277f4a0

https://qiita.com/abeno/items/1aecfad3dc8c340c442e

https://qiita.com/rikako_hira/items/ae208590d02a3bb91789

https://qiita.com/totsu0119/items/528f0f6329c1c40a69e7

https://qiita.com/mikoski01/items/3f5f8793415248eacca6

https://midorigame-jo.com/java-roadmap/

https://runteq.jp/blog/programming-school/language/11897/

# 2. 教材
https://gihyo.jp/book/2022/978-4-297-12685-8

https://gihyo.jp/book/2017/978-4-7741-8909-3

https://gihyo.jp/book/2017/978-4-7741-9087-7

https://www.shoeisha.co.jp/book/detail/9784798150727

https://sukkiri.jp/books/sukkiri_java3

https://sukkiri.jp/books/sukkiri_sql3

https://www.udemy.com/course/intellij-spring-boot/

https://www.udemy.com/course/poco-tech-spring-security/

https://www.udemy.com/course/java_spring_beginner/

https://zenn.dev/sugaryo/books/spring-boot-run-up

https://zenn.dev/angelica/books/52be1e365c61ea

https://zenn.dev/misaka/books/9734700544990d

https://zenn.dev/otkshol/articles/52d2649c6fa4dc

https://zenn.dev/numacci/articles/202101_java_restapi-postgres

https://zenn.dev/numacci/articles/restapi-mongodb-crud-tutorial

https://qiita.com/mistletoe/items/5b2a9eda8d053dda3ea1

# 3. 環境構築
https://start.spring.io/

https://zenn.dev/osuzuki/articles/b41dc7be15e2b5

https://qiita.com/akitika/items/4c701a6ec7a95d6cb78d

https://qiita.com/rubytomato@github/items/b2c0686517e1c86ceb48

https://zenn.dev/kotaro0235/articles/083e30a8755da7

https://qiita.com/shavada/items/2db64a912fd2c20b1fa9

# 4. IDE
## 4-1.IntelliJ IDEA
https://zenn.dev/mongolyy/articles/d6c8983954725b

https://qiita.com/crossroad0201/items/bf5528cc57cadab67638

https://qiita.com/KtheS/items/7179fc2dabe8f1e4fd62

https://qiita.com/kohii/items/a0f7b8bad641e957147b

https://qiita.com/saitoshi/items/bc459a8b3ea312f5287e

https://qiita.com/opengl-8080/items/108102d692b49f804dbd

https://qiita.com/cypher256/items/8ce0527a46bd7cfe43eb

https://qiita.com/oohira/items/825ef5f252d0fd2e752f

https://qiita.com/oohira/items/31767e0958ea322184fb

https://zenn.dev/naoyukik/articles/5c291119b67ba76ef690

https://zenn.dev/naoyukik/articles/5f019beed1006ebd034d

## 4-2.VScode
https://zenn.dev/s_t_pool/articles/f6812fe9c7edf4c07516

https://zenn.dev/ykdev/articles/cde000b2b8f405

https://qiita.com/takuma-jpn/items/b49785a314fb4db85775

https://qiita.com/koukibuu3/items/77734596483ffd788931

# 5. 入門記事
https://qiita.com/Toshihiro_Watanabe_/items/bfda988a70d3d04e3087

https://qiita.com/yk0807/items/c90f02711880fb0fa4f1

https://qiita.com/yk0807/items/70b2dca1e9832280de33

https://www.gorou.style/articles/2022/03/spring-boot-study1/

# 6. チートシート
https://qiita.com/disc99/items/727b51dbe737602a5c91

https://qiita.com/azul915/items/5f7003bb78917dff6bb1

https://qiita.com/uzresk/items/31a4585f7828c4a9334f
【CSS】iPhone画面右にできた微妙な余白

web制作の中で、iPhoneの画面を見ていて詰まったところがあったのでメモ。

# iPhone画面の右に余白ができた
chromeのディベロッパーツールにて、iPhone用画面の確認を行なっているが、右に微妙な余白ができていた。
右に引っ張ると若干余白があり、CSSを確認すると、HTMLタグ、bodyタグも余白部分を覆えていなかった。
また、これのせいで、固定ヘッダーが上手く追従してくれなかった。

# 対応
```html:hoge.html
<body>
 <div class="wrapper"> <!-- wrapperを定義 -->
  <div class="hoge">
  </div>
  ...
 </div>
</body>
```
```css:hoge.css
.wrapper {
 max-width: 100%
}
```
上記のように、bodyタグの下にwrapperのタグを作り、無理やり横幅の最大値を100%にすると余白がなくなった。
※尚、html,bodyタグを100%に設定する必要あり。
【WSL2】WSL2のdocker 環境構築(何故か必要だった)

# はじめに

自分のPCでWSL2を使っていますが、docker が使えずに設定をしたのでメモしておきます。これまでずっとWSL2で開発してきて、苦労した記憶がないですが、忘れてしまっただけなのかな。（ぼけ老人）以前こんなことをしたのか分からないのですが。まぁ、メモです。

# 内容

### docker service がない?

自分のWSL2でdocker が使えなかったので、入れました。/usr/bin/docker があるのに service docker start では登録がなく起動できませんでした。良く分からないので、インストールしました。docker 公式サイトにあるubuntu へのインストール手順に従いました。
メモ。

```bash
$ sudo apt-get update
$ sudo apt-get install     ca-certificates     curl     gnupg     lsb-release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo   "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
$ sudo service docker start
$ docker run hello-world
```
これで使えるようになりました。

### docker build の apt-get で名前解決ができない

いざ、Dockerfile を書いてbuild しますが、apt-get ではまります。涙

```
 => ERROR [2/8] RUN apt-get update && apt-get install -y curl                                                                  19.7s
------
 > [2/8] RUN apt-get update && apt-get install -y curl:
#0 7.025 Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
#0 7.025   Temporary failure resolving 'archive.ubuntu.com'
#0 7.025 Err:2 http://security.ubuntu.com/ubuntu focal-security InRelease
#0 7.025   Temporary failure resolving 'security.ubuntu.com'
#0 13.28 Err:3 http://archive.ubuntu.com/ubuntu focal-updates InRelease
#0 13.28   Temporary failure resolving 'archive.ubuntu.com'
#0 19.51 Err:4 http://archive.ubuntu.com/ubuntu focal-backports InRelease
#0 19.51   Temporary failure resolving 'archive.ubuntu.com'
#0 19.52 Reading package lists...
```

そこで、docker さんがDNSだめなのかも、ということで、下記を実行するとNGだった。

```
$ docker run busybox nslookup google.com
;; connection timed out; no servers could be reached
```

下記を参考にしています。

https://medium.com/@faithfulanere/solved-docker-build-could-not-resolve-archive-ubuntu-com-apt-get-fails-to-install-anything-9ea4dfdcdcf2

で、docker が動いている WSL2内で名前解決ができていない、といういつもの /etc/resolv.conf の問題のようなので、nameserver 8.8.8.8 を追加したら、動くようになりました。

```
$ docker run busybox nslookup google.com
Server:         8.8.8.8
Address:        8.8.8.8:53

Non-authoritative answer:
Name:   google.com
Address: 142.250.196.142

Non-authoritative answer:
Name:   google.com
Address: 2404:6800:4004:821::200e
```

### WSLの時刻がおかしい

それでもapt-get が通らず。WSLの時刻がおかしかったようです。
下記のコマンドののち、apt-get は動くようになりました。

```
# sudo hwclock --hctosys
```

# まとめ

docker が入っていない、DNSがおかしい、時計がおかしい、ということだったのですが、いきなりこの三重苦があり、消耗しました。解決したのでよいですが、メモに残しておきます。
(2023/02/25)
【Angular】外部ライブラリ内のscssファイルを参照するアプローチ

# SassError: Can't find stylesheet to import.
理不尽にnode_modules内の所定の位置にあるはずのscssファイルが読み取れない時、
ビルド時に下記のようなエラーが出る。

```zsh
./src/app/app.component.scss?ngResource - Error: Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
SassError: Can't find stylesheet to import.
  ╷
1 │ @use "~@hoge/style";
  │ ^^^^^^^^^^^^^^^^^^^^^^^
  ╵
  src/app/app.component.scss 1:1  root stylesheet
```

## 前提
Angular v13
Node 14.19.3
sass-loader 12.4.0

## 回避策

 1\. `~`をつけるのを止める。
sass-loaderの仕様として、`~`を付ける事で明示的にnode_modules配下のパスである事を指定出来る。が、動き的に最初は相対パスで解決しようとした後に、node_modules配下での解決を試みるようにはなってるらしい。
https://webpack.js.org/loaders/sass-loader/#resolving-import-at-rules 
```scss
@use "@hoge/style";
```
でも、多分これで解決出来るケースはそんなない。

2\. `angular.json`で`stylePreprocessorOptions`を記述する。
設定したincludePathsに対して、相対パスを必要とせず、プロジェクトのどこからでもインポート出来る様になるので、これを利用する。

```angular.json
"stylePreprocessorOptions": {
    "includePaths": [
        "node_modules/@hoge"
    ]
}
```

インポートする側の記述もこれだけで良くなる。
```scss
@use "style";
```

もしもの時はお試しあれ。