OmniAICreator/Qiita-1.07M huggingface dataset:
pipの使い方の誤解～超初心者の自分のための備忘録～

windows10のコマンドプロンプトを使ってpipを使用したときに自分が困ったエラー対処を載せときます。同じようなミスで困っている人の参考になれば幸いです。
参考とした書籍は『Pythonクローリング&スクレイピング[増補改訂版] -データ収集・解析のための実践開発ガイド』です。


この書籍のp48でスクレイピングを始める前にpipをインストールしています。
```
pip install requests
```

初めてpipをインストールをすると以下のようなものが出てきます。
```
pip install requests
Collecting requests
  Downloading https://files.pythonhosted.org/packages/2d/61/08076519c80041bc0ffa1a8af0cbd3bf3e2b62af10435d269a9d0f40564d/requests-2.27.1-py2.py3-none-any.whl (63kB)
    100% |████████████████████████████████| 71kB 3.2MB/s
Collecting urllib3<1.27,>=1.21.1 (from requests)
  Downloading https://files.pythonhosted.org/packages/c5/05/c214b32d21c0b465506f95c4f28ccbcba15022e000b043b72b3df7728471/urllib3-1.26.16-py2.py3-none-any.whl (143kB)
    100% |████████████████████████████████| 143kB 4.6MB/s
Collecting certifi>=2017.4.17 (from requests)
  Downloading https://files.pythonhosted.org/packages/9d/19/59961b522e6757f0c9097e4493fa906031b95b3ebe9360b2c3083561a6b4/certifi-2023.5.7-py3-none-any.whl (156kB)
    100% |████████████████████████████████| 163kB 9.2MB/s
Collecting idna<4,>=2.5; python_version >= "3" (from requests)
  Downloading https://files.pythonhosted.org/packages/fc/34/3030de6f1370931b9dbb4dad48f6ab1015ab1d32447850b9fc94e60097be/idna-3.4-py3-none-any.whl (61kB)
    100% |████████████████████████████████| 71kB 8.9MB/s
Collecting charset-normalizer~=2.0.0; python_version >= "3" (from requests)
  Downloading https://files.pythonhosted.org/packages/06/b3/24afc8868eba069a7f03650ac750a778862dc34941a4bebeb58706715726/charset_normalizer-2.0.12-py3-none-any.whl
Installing collected packages: urllib3, certifi, idna, charset-normalizer, requests
Successfully installed certifi-2023.5.7 charset-normalizer-2.0.12 idna-3.4 requests-2.27.1 urllib3-1.26.16
```

一度インストールされた状態でpip install requestsを実行すると以下のようになります。
```
Requirement already satisfied:
```
これはすでにインストールされていることを示しています。

しかしここで問題が起きることがあります。すでにpipをインストールしている状態で先にpythonを起動してからまたpip install requestsを実行するとミスが生じます。
言葉で説明してもわかりづらいのでエラーのコードを示します。
```
python

pip insstall requests
  File "<stdin>", line 1
    pip insstall requests
               ^
SyntaxError: invalid syntax
```

pythonを開いてからpipをインストールしようとするとSyntaxError: invalid syntaxというエラーが出てしまうことになります。
そもそもpipはpythonのライブラリ管理ツールです。
なぜこのようなエラーが出てしまうのか自分にはわかりませんが、このエラーを回避する方法はわかりました。

一度pipをインストールしたのであれば、それ以降pythonでrequests機能を使うにはimport requestsを実行するだけでいいです。つまり毎回pip install requestsを実行する必要がありません。自分はpipをインストールした後で毎回このpip　install requestsを実行する必要があると誤解していました。
```
python
import requests
```

こうすれば先ほどのようなinvalid syntaxは出てこなくなります。
逆にまだpipをインストールをしていないのであれば、pythonを実行する前にpip insstall requestsを行えばいいと思います。

きちんとpythonが認識できていれば環境変数の追加といっためんどくさい操作は必要ないです。

参考にした記事:
Pythonのpipでインストールできない？
https://sprockethole.work/2018/09/09/python%E3%81%AEpip%E3%81%A7%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E5%87%BA%E6%9D%A5%E3%81%AA%E3%81%84%EF%BC%9F/
Javaの繰り返し処理を学習してみた

# 概要
Javaの繰り返し処理を学習してみました。以下のページを参考にしました。

繰り返し処理

https://www.javadrive.jp/start/for/

for文を使った繰り返し処理

https://www.javadrive.jp/start/for/index2.html

while文を使った繰り返し処理

https://www.javadrive.jp/start/for/index6.html

do..while文を使った繰り返し処理

https://www.javadrive.jp/start/for/index7.html

拡張for文(for-each文)を使って要素を順に取得する

https://www.javadrive.jp/start/for/index8.html

break文の使い方

https://www.javadrive.jp/start/for/index9.html

continue文の使い方

https://www.javadrive.jp/start/for/index10.html

# まとめ
何かの役に立てばと。
2つの封筒問題（封筒のパラドックス）

## はじめに

本記事では「2つの封筒問題」の主な3種類について、回答と簡潔な説明をする。
書籍やネット上の解説記事は、説明過多でわかりにくく間違いが多い。このような間違った情報が減少すれば幸いである。

※ **本記事へのコメントはしないでください。コメントがあった場合、すべて削除依頼します。**

## 問題

### 2つの封筒問題（未開封版）

> お金の入った2つの封筒があり、片方はもう片方の2倍の金額になっている。無作為に1つの封筒を選んだとき、交換した方が得か？

### 2つの封筒問題（金額仮定版）

> お金の入った2つの封筒があり、片方はもう片方の2倍の金額になっている。無作為に1つの封筒を選んだとき、交換した方が得か？ただし、**選んだ方の金額を2Yとする**（金額を仮定するだけで開封しない）。

### 2つの封筒問題（分布と金額仮定版）

> お金の入った2つの封筒があり、片方はもう片方の2倍の金額になっている。無作為に1つの封筒を選んだとき、交換した方が得か？ただし、**次のように金額を決め、選んだ方の金額をZとする**（金額を仮定するだけで開封しない）。
> 1または２が出るまでサイコロを振る。振った回数が$N$になったら1つの封筒に$2^N$の金額を、1つの封筒に$2^{N-1}$の金額を入れる。

## 回答

### 2つの封筒問題（未開封版）の回答

交換しても**変わらない**。

#### 説明

片方をX、もう片方を2Xとしたとき、無作為に選んだときの期待値は1.5Xである。別の封筒の期待値も1.5Xで変わらない。

### 2つの封筒問題（金額仮定版）の回答

交換した方が得かどうかは**不明**になる。

#### 説明

金額が2Yの場合、下記のどちらかである。この2つの割合がどうなっているかは、情報がないので不明である。

・Yと2Yが用意されていて、2Yを選んだ
・2Yと4Yが用意されていて、2Yを選んだ

※ この2つから無作為に選んでいるわけではないので、確率は半々ではない。

### 2つの封筒問題（分布と金額仮定版）の回答

交換した方が**得**である。

#### 説明

もう１つの数字が$\frac{Z}{2}$か$2Z$かの比は$3:2$であり、交換した場合の期待値は$\frac{11Z}{10}$である[^1]。

[^1]: 厳密にはZが1かどうかで場合分けが必要だが、得という結論は同じなので場合分けは省略

## 補足

未開封の場合は、直感と合致しているのでわかりやすい。

開封して金額を確認した場合は、金額仮定版と同じ回答になる。正解が存在する学校教育に慣れていると「交換したほうが得」と間違いやすい。

金額の分布を問題のように仮定し、さらに選んだ方の金額を仮定すると、交換した方が期待値は増える。なお、金額の分布を仮定しても選んだ方の金額を仮定しない場合は、交換しても変わらない。

## パラドックスか？に対する説明

2つの封筒問題（未開封版）において、片方をX、もう片方を2Xとする。無作為に選ぶので、下記のようになる。

* 確率1/2でXを選ぶ。交換すると2倍になる
* 確率1/2で2Xを選ぶ。交換すると1/2倍になる

上記から、**比率の期待値は1.25倍になる**。

このことから「`どちらを選んでも交換した方が得になるからパラドックスである`」という主張は間違いである。「`比率の期待値が1.25倍`」は正しい。間違いは「`交換した方が得`」というところである。分母が異なるものの比率の期待値が1を超えていても値として増えるわけではないからである。

| 正しい解釈 | X → 2X （確率1/2）<br>2X → X （確率1/2）|
|:--|:--|
| 間違った解釈 | X → 2X （確率1/2）<br>X → X/2 （確率1/2）|

※ 選んだ封筒の金額に、1.25を掛けるのは間違った解釈

別の例で説明する。
たとえば、西暦が偶数のときに`100`万円、奇数のときに`374`万円の給与になる会社があったとしよう。この会社の給与は2年づつ平均を見れば横ばいだが、比率の期待値は約`2`（`(374/100 + 100/374) / 2`）である。

## 「期待値が無限大だから交換しても変わらない」に対する説明

2つの封筒問題（未開封版）において、期待値が無限大だから交換しても変わらないという主張は誤りである。
まず、期待値が無限大だという前提が間違い。さらに、2つの金額を$(X, 2X)$と仮定するだけで答えはでる（$X$の分布は不要）。

## 「開封して必ず金額を確認するつもりなら、交換した方が得」に対する説明

2つの封筒問題（分布と金額仮定版）において、**まだ選択していない**状況で「選択後開封して**必ず金額を確認するつもり**なら、交換した方が得」は間違いである。
「選択後必ず開封する」だけ仮定しても、交換で変わらない。開封だけを仮定しただけでは、金額が前提でないからである。金額を仮定すると変わる。
2つの封筒問題（分布と金額仮定版）では、**選択していなくても**金額を仮定さえすれば、交換した方が得になる。
同様に、2つの封筒問題（金額仮定版）では、**選択していなくても**金額を仮定さえすれば、交換した方が得かどうかは不明になる。

## 「どちらを選んでも得なのはパラドックスか？」に対する説明

2つの封筒問題（分布と金額仮定版）で、以下は矛盾していない。
* 選んだ方の金額をZと仮定すると、交換した方が得
* 選ばない方の金額をZと仮定すると、交換した方が損
選ばない方の金額をZとしたとき、選んだ方はZ/2または2Zなので1つの数字を仮定していない。すなわち、1つの数字を仮定したときと別の仮定なので、異なる結果になっても矛盾しない。

## 参考

https://qiita.com/SaitoTsutomu/items/60b64b0de2c42ec8c1cb

https://qiita.com/SaitoTsutomu/items/63885dec1cca99acb7bb

https://qiita.com/SaitoTsutomu/items/9784e4451d6d510dbfbb#mag-%E3%81%8A%E9%A1%8C%E3%81%9D%E3%81%AE22%E3%81%A4%E3%81%AE%E5%B0%81%E7%AD%92%E3%81%AE%E5%95%8F%E9%A1%8C
初投稿

# 自己紹介
「業務のスキマお埋めします」と称して発信しています。「スキマ」と呼ばれることが多いです。
某製造業に勤務して、試験課という組織に所属しています。ITが専門ではありません。
# Qiita投稿に至る経緯
* 社内の情報発信に限界を感じた
* Twitterとブログ始めた（Blogger）
* ブログ記事を書くのが下手になってきた
* ブログはもっと気楽に発信できるようにしたい
* では気楽ではない情報発信をQiitaに書こう
 
こうです。
# Qiitaでやりたいこと
私は情シスの人間ではないし、市民開発者もよわよわですが
* 開発者と利用者の間にあるスキマ
* 作業者とリーダとマネジャの間にあるスキマ
* 利用者と情シスの間にあるスキマ

などについて情報発信をしていきたいと思っています。
文句を言うだけでは何も変わらないし、社内では言われる側なので反省を込めている面もあるのです。
##### 業務のスキマお埋めします
[https://twitter.com/1RRhcSB6HSUu9hF](https://twitter.com/1RRhcSB6HSUu9hF)
[ブログ　タリタリ団：別館](https://taritari-dan.blogspot.com/)
Power Apps で以前のリクエスト内容を再利用する


# はじめに

例えば、Power Apps で何らかの申請をするアプリを作成する場合、以前申請した内容をコピーして入力を少しでも楽にしたいという場合があると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/231d1c8a-3afc-1b0c-24bc-7c4f246d900d.png)


上記アプリほどの入力項目であれば一から入力するのはそれほど大変ではないですが、入力項目が沢山ある場合において、類似した申請や問い合わせをする場合は、以前のリクエスト内容を再利用できた方が利用者にとって優しいと思います。

そのため、今回は、Power Apps で以前のリクエスト内容を再利用する方法について紹介します。

# アプローチ

今回は、Power Platform の環境の申請を行うアプリを例に説明します。
データソースは、`Environment Request`という SharePoint リストです。

まず、これが出来たら一番楽なのですが、残念ながら、フォームコントロールが`新規`の場合、`[Ietm]`プロパティにギャラリーコントロールで選択されたデータを指定してもデータは入らないようです。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/9ed21135-15d9-0677-2851-2b4abdeb8931.png)

そのため、少しマニュアルな方法を用います。
まず、以下のように、フォームコントロールと同じデータソースを設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/6a73b21f-0373-251b-698a-6e511581bff1.png)

そして、ギャラリー内にアイコンを追加し、アイコンの`[OnSelect]`プロパティでフォームのモードを指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/b7c4238d-bdeb-1b05-e4c6-9381ff66867b.png)

フォーム側の`[DefaultMode]`プロパティは以下のようになっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a12a0454-8449-d695-2980-2b10a651faa1.png)

:::note

こちらから作成したアプリです。上記のようにフォームのモードを変数を元に設定しているようなのでそちらを利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/ae5f70d0-ea98-647b-0293-d0d90f701314.png)
:::

そして、コピーしたい列の部品にて、`[Default]`プロパティを以下のように設定していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/07b8d339-fe06-cf81-2ea4-23f2969d10ff.png)

```
If(
    copyMode = true,
    RecordsGallery1.Selected.タイトル,
    Parent.Default
)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3074511/a2c7dfd9-696a-f97d-3e12-cac74b5ba849.png)

```
If(
    copyMode = true,
    RecordsGallery1.Selected.Purpose,
    Parent.Default
)
```

これにより、以前のリクエスト内容をベースに新規申請をすることが可能になります。

項目が多い場合は少し面倒ですが、これにより利用者は類似した申請や問い合わせをするのがとても楽になると思います。

# まとめ

今回は、Power Apps で以前のリクエスト内容を再利用する方法について紹介しました。
matplotlibで日本語を表示する方法

## 記事内容
以下の画像のように、日本語を使ってmatplotlibのグラフ表示を行えるようにする。
![japanese_matplotlib.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509941/c0b1e564-9768-8522-1d08-f3480d8e05fa.png)

## 状況
matplotlibを用いて折れ線グラフを生成しようとしていた時のこと。日本語のタイトルや、日本語のラベル値を設定しようとしていた。以下のプログラムは、例として用意したプログラムである。
```python
import sys
import matplotlib.pyplot as plt

def main():
    section = ["りんご", "みかん", "ぶどう", "メロン"]
    # 日本語ラベルを指定
    x = range(len(section))
    plt.xticks(x, section)
    
    # グラフ生成
    plt.xlabel("日本語のラベル")
    plt.ylabel("ylabel")
    plt.ylim(0, 15)
    plt.grid()
    
    y = [12, 6, 4, 10]
    plt.plot(x, y, marker="o")
    plt.title('日本語のタイトル')

    plt.savefig("japanese_matplotlib.png")
    


if __name__ == '__main__':
    sys.exit(main())
```
以下のコマンドで実行する。
```console
python3 japanese_matplotlib.py 
```
そうすると、以下のようなエラーと画像が生成される。
```console
~/japanese_matplotlib.py:20: UserWarning: Glyph 26085 (\N{CJK UNIFIED IDEOGRAPH-65E5}) missing from current font.
  plt.savefig("japanese_matplotlib.png")
...
```
![japanese_matplotlib.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3509941/13046469-2181-fbb3-dc0c-e5445704feed.png)

このように、matplotlibはデフォルトで日本語が使えない。

## 解決方法
解決方法としては、追加で日本語版をインストールする必要がある。どうやらanacondaにはなく、pipにしか対応していないらしいので注意が必要。
以下のコマンドを実行する。
```console
pip3 install japanize_matplotlib
```
なぜjapaneseではなくjapanizeなのかが疑問だが、以下の内容をプログラムに追加する。
```python
import japanize_matplotlib
```
importするだけで、グラフを生成した時に日本語がしっかりと表示される。

## 注意点
上記でも記述した通り、importするだけで日本語対応することができる。逆に言えばimportしかしないため、フォーマッターによっては削除されてしまうことがある。その場合は設定を変える必要がある。
フロントエンドエンジニアの将来性

# 目次
1. [現状](#現状)
1. [将来性](#将来性)
1. [求められるスキル](#求められるスキル)

# 現状
1. [仕事内容](#仕事内容)
1. [年収](#年収)

### 仕事内容
Webサイトやアプリでユーザーが操作する部分の設計・構築を行う

### 年収
平均年収：**385万円**
20代：**313万円**
30代：**457万円**

▼日本全体の平均年収(2021年／[国税庁の調査](https://www.nta.go.jp/publication/statistics/kokuzeicho/minkan2021/pdf/002.pdf#page=17))
正社員：**508万円**
非正規雇用社員：**198万円**

▼バックエンドエンジニアの平均年収
全体：**400万円～800万円**
20代：**380万円**ほど
30代：**530万円**ほど
40代：**640万円**ほど

# 将来性
1. [短期的な目線ではフロントエンジニアの需要は明るい](#短期的な目線ではフロントエンジニアの需要は明るい)
1. [数年〜数十年先のスパンで見ると将来性を測ることは難しい](#数年〜数十年先のスパンで見ると将来性を測ることは難しい)
1. [今後は今以上に専門的なスキルが求められる](#今後は今以上に専門的なスキルが求められる)
1. [Webサービスは常にアップデートされていくので無くなることは考えにくい](#Webサービスは常にアップデートされていくので無くなることは考えにくい)

### 短期的な目線ではフロントエンジニアの需要は明るい
スマホの端末など、新しいハードウェアに対応できるフロントエンドエンジニアに需要がある。
またPCでは見やすいWebサイトでも、スマホだと見にくくなるものもあり、これに対応する需要も高い

### 数年〜数十年先のスパンで見ると将来性を測ることは難しい
**AI技術の発展**・**ノーコード／ローコードの発展**のレベルどれだけ大きくなるのかが予測不能の為、基礎的な技術から専門的な技術まで代替されてしまう可能性がある。

### 今後は今以上に専門的なスキルが求められる
「[数年〜数十年先のスパンで見ると将来性を測ることは難しい](#数年〜数十年先のスパンで見ると将来性を測ることは難しい)」という話がある為、仮にほとんどの技術が代替されたとしても、高い専門性により代替されない領域で活躍するスキルが求められる。

### Webサービスは常にアップデートされていくので無くなることは考えにくい
「**現在のトレンドに合わせる**」「**新しいデバイスに対応する**」瞬間は常にある為、フロントエンドエンジニア自体無くなることはないと考えていい。

# 求められるスキル
1. [基本的なプログラミングスキル](#基本的なプログラミングスキル)
1. [フレームワークに関する知識](#フレームワークに関する知識)
1. [マネジメントスキル](#マネジメントスキル)
1. [サーバーに関する知見](#サーバーに関する知見)

### 基本的なプログラミングスキル
HTML/CSS・JavaScriptの基礎的なスキルは最低限必要

### フレームワークに関する知識
クライアントやチームとの効果的・効率的な連携をとる為の技術が必要

▼**フレームワークとは**
意思決定や分析、解決したい問題を特定の型に落とし込み、手順に沿って整理していくための、共通して利用できる思考の枠組み

### マネジメントスキル
チームで開発をしていく為、滞りなく進められているかをマネジメントする技術が必要

### サーバーに関する知見
サーバー関連の知識がまったくない状態では、バックエンドエンジニアとのコミュニケーションが取れなくなってしまう。開発全般を把握する為にもフロントエンド以外の領域への知識・知見が必要

# 関連サイト

https://qiita.com/Cookie_Iwate/items/61c85e86cd0667207d22
Azure Logic Apps で For each の順番を保証する方法

# 背景

ホームページのRSSを取得して、LINE公式アカウントで配信する処理を、Azure Logic Apps を使って実装していたのですが、RSSで取得した情報を順番に並べて、LINEメッセージとして配信すると、なぜかRSSで取得した情報の日付の並び順がおかしい。もとのRSSを確認しても日付順で並んでいて、Azure Logic Apps の処理のログを確認しても、For each 内の処理も日付順で並んでおり、配信されたメッセージのみが順番がおかしくなっている感じでした。
今回は、その原因と対応方法について説明します。

# 原因
Azure Logic Apps の For each は、配列やコレクションの各要素に対して処理を繰り返すことができます。今回は、RSSで取得した一覧に対して、この繰り返し処理を行っていました。
順番がおかしくなったように見えていた原因は、「For each のデフォルトの動作が並列処理である」からでした。


# 対応方法
For each の設定で、コンカレンシー制御をONにして、順次処理を１にすることで、順次処理することが出来ます。
コンカレンシー制御をONにすると、For each が同時に実行できるインスタンスの数を指定できます。 この数値を１にすると、For each は一度に１つの要素しか処理しなくなります。 つまり、順次処理になります。 順次処理では、各要素の処理が前の要素の処理が終了した後に開始されます。 そのため、出力の順番が入力の順番と一致します。

# 設定方法
設定方法は、以下のとおりです。

1. For each ループの右上にある設定アイコンをクリックします。
2. [詳細オプション] を展開します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/f03b62d6-c831-aa89-c622-a4e60fbaeb4b.png)

3. [コンカレンシー制御] をONにします。
4. [並列処理の次数] の値を１にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21408/4ed55ded-db89-6e59-6da7-805f2e2091a1.png)

これで、For each ループは一度に１つの要素しか処理しなくなります。つまり、順次処理になります。順次処理では、各要素の処理が前の要素の処理が終了した後に開始され、出力の順番が入力の順番と一致するので、今回発生したようなことは起きなくなります。


# デメリット
ただし、コンカレンシー制御をONにして、順次処理を１にすることにはデメリットもあります。 それは、処理時間が長くなることです。 並列処理では、各要素の処理が同時に開始されるため、全体の処理時間は最も時間のかかる要素の処理時間に近くなります。 しかし、順次処理では、各要素の処理時間が全体の処理時間に加算されます。そのため、全体の処理時間は各要素の処理時間の合計に近くなります。 特に、要素数が多い場合や各要素の処理時間が長い場合は、並列処理と比べて大きな差が出る可能性があります。

よって、For each の順番を保証したい場合は、コンカレンシー制御をONにして、順次処理を１にすることで実現できますが、その分、処理時間が長くなることを覚えておきましょう。


# 参考URL
参考にしたURLを掲載しておきます。

https://qiita.com/hatobeam75/items/dae2b222d8aa9ca47f0f

https://stackoverflow.com/questions/68128323/azure-logic-app-append-variable-within-for-each-is-incoherent

https://qiita.com/rnakamuramartiny/items/694a0d667a7203506801
[Power Query] １列に積み重なったデータを表形式にするベストプラクティスは？ (6) まとめ

※この記事は 2023/7/22 に作成しました。
※オプションで、「地域の設定」の「クエリステップ」は、「常に英語」に設定されています。日本語で使用している場合は、各自環境で作成されるコードに読み替えてください。


# Index
- [(1) Table.AddIndexColumn → Table.Pivot](https://qiita.com/spumoni/items/f949f370aea5a831aeea)
- [(2) Table.Split → Table.Transpose → Table.Combine](https://qiita.com/spumoni/items/0de5b66f3d71b69572bd)
- [(3) List.Split → Table.FromRows](https://qiita.com/spumoni/items/0bcf50c7720f93804fcb)
- [(4) Table.AlternateRows → Table.FromColumns](https://qiita.com/spumoni/items/679150a28de7a9a30f1d)
- [(5) List.Alternate → Table.FromColumns](https://qiita.com/spumoni/items/4aac2d40984ba4c244ce)
- [(6) まとめ](https://qiita.com/spumoni/items/3503970baa038e349a79)


# まとめ

## 作成の難易度
　ピボット操作は癖がありますが、GUIだけで出来上がるため、初心者への説明がしやすいかもしれません。うまく操作するには、ピボットの動作を理解する必要があります。今回使用したデータを操作する方法として、ほとんどの記事でこの方法が紹介されてるようです。
　その他のものは、わずかではありますがコードを記述する必要があります。その場合、当然ながら関数の使い方、書き方について、きちんと理解できるスキルレベルが求められます。

## 処理速度

　少量のデータを加工するには、さほど違いは発生しませんが、データ量が増えた場合、処理時間に大きな違いが生まれます。

　以下は、957,900行のデータで計測した結果です。

|処理|時間(秒)|
|:--|--:|
|1. Table.AddIndexColumn → Table.Pivot|24|
|2. Table.Split → Table.Transpose → Table.Combine|24|
|3. List.Split → Table.FromRows|-|
|4. Table.AlternateRows → Table.FromColumns|3|
|5. List.Alternate → Table.FromColumns|3|

　1番、2番は、縦横を変換するためにデータをメモリ上に読み込んで処理を行っているため、データ量が増えると処理速度が遅くなります。

　3番は、Table.FromRowsの処理でソースファイルを何回も読み込む処理が行われているため、法外な処理時間が必要となります。30分以上たっても終了しませんでした。この処理は、1つのリストを処理するたびに、改めてデータの最初から読み込みをし直すという動作をしています。つまり、最初のリストを処理で１～3のデータを読み込み、2番目のリストを処理するために１～６のデータを読み直します。処理が進むにしたがって読み込み量は増えていくことになります。

　4番と5番の処理は、データを上から順番に処理していくストリーミング処理が行われます。データの読み込み回数は項目の数だけ行われ、今回の処理では3項目なので全体が3回読み込まれます。しかし、読み込みながら処理が行われることで、過大な読み込み処理が発生せず、メモリの利用効率も優れた処理となります。

　従ってPower Queryを業務で利用する場合、最も望ましい処理は4番と5番の処理になります。それ以外の方法を選択すべきではありません。ここで取り上げた処理の動作を理解し、直ちに書き直すことを強くお勧めします。

https://qiita.com/PowerBIxyz/items/ce155d960f0f6779ec64#%E5%BF%9C%E7%94%A8
[Power Query] １列に積み重なったデータを表形式にするベストプラクティスは？ (3) List.Split → Table.FromRows

※この記事は 2023/7/22 に作成しました。
※オプションで、「地域の設定」の「クエリステップ」は、「常に英語」に設定されています。日本語で使用している場合は、各自環境で作成されるコードに読み替えてください。

以下のように、複数の項目が1列になっているデータをテーブルにする方法の3番目です。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/e87b3164-4a5b-f0dc-49fe-af959488dddc.png"/>

# Index
- [(1) Table.AddIndexColumn → Table.Pivot](https://qiita.com/spumoni/items/f949f370aea5a831aeea)
- [(2) Table.Split → Table.Transpose → Table.Combine](https://qiita.com/spumoni/items/0de5b66f3d71b69572bd)
- [(3) List.Split → Table.FromRows](https://qiita.com/spumoni/items/0bcf50c7720f93804fcb)
- [(4) Table.AlternateRows → Table.FromColumns](https://qiita.com/spumoni/items/679150a28de7a9a30f1d)
- [(5) List.Alternate → Table.FromColumns](https://qiita.com/spumoni/items/4aac2d40984ba4c244ce)
- [(6) まとめ](https://qiita.com/spumoni/items/3503970baa038e349a79)


# 解法３: 3行ごとにリストを作成してテーブルを作成
　解法２では、3行ごとにテーブルを作成していましたが、今回は List.Split でリストを作成します。

## List.Split
　数式バーの右の「fx」を押し、数式バーにList.Split関数を入力します。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/400f68a9-4c00-2178-1bda-82dba03720d2.png"/>

```text:構文
List.Split(
    list as list, 
    pageSize as number
) as list
```

　第一引数の対象となるデータはリストにする必要がありますので、テーブル名の後に列名を[]で囲ってリスト形式にしています。Table.ToList関数を使って、`List.Split(Table.ToList(Source), 3)`とすることもできます。第二引数は、区切るサイズを指定しますので、項目数となる３を入力しています。返される値は入れ子になったリストになります。

https://learn.microsoft.com/ja-jp/powerquery-m/list-split

## Table.FromRows
　数式バーの右の「fx」を押し、数式バーにTable.FromRows関数を入力します。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/ff0a04b0-8f5a-3826-ae39-69d91aa93390.png"/>

　Table.FromRows関数は、入れ子になったリストをテーブルに変換します。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864075/443ea6de-aeef-cade-fc4e-66dae02646f7.png"/>

```text:構文
Table.FromRows(
    rows as list, 
    optional columns as any
) as table
```

## ソースコード

```
let
    Source = Table.FromColumns(
        {
            Lines.FromBinary(
                File.Contents("**File Name**"), 
                null, 
                null, 
                932
            )
        }
    ),
    Custom1 = List.Split(
        Source[Column1], 
        3
    ),
    Custom2 = Table.FromRows(
        Custom1
    )
in
    Custom2
```
AWS Amazon Linux 2023 に MySQL 導入

AWS EC2 で WordPress を構築するのに必要な、MySQL導入に苦戦した内容。

<h3>構成:
Amazon Linux 2023 + MySQL

EC2 に SSH 接続してMySqlインストールを入れるがインストールできない
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/af528efa-ef73-dd5d-cf53-3bfe834d8896.png)

どうやらリポジトリがないようなので URLを直接指定してインストール
$ sudo yum localinstall [使用するLinuxのバージョンに合わせて]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/c5ede9fc-6821-18f5-51ec-b648838bbfcf.png)

インストールできたっぽいのでバージョン確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/b56d8edb-54d5-a8f8-e434-fa181fa782a9.png)

残念ながらエラー
どうやら mysql-community-server が必要みたいなのでインストールする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/03f1d637-2efc-8c4b-0979-bcf7e2bdcf7d.png)

再度バージョン確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/d598499b-99e9-506b-7f99-d4b6fd4eafc5.png)

インストールできたっぽい

サービス稼働と稼働しているかチェック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/de4e4447-4824-de53-46d8-90a2d943ddc7.png)

<h3>無事稼働</h>

コマンド一つでインストールできなかったため苦戦orz
【全体像】エンジニアとしての将来性

# このページの概要
開発領域やスキルに対する将来性を随時まとめて更新していきます。

# 目次
1. [開発領域ごとの将来性](#開発領域ごとの将来性)
1. [スキルごとの将来性](#スキルごとの将来性)
1. [その他の将来性](#その他の将来性)

# 開発領域ごとの将来性
1.[フロントエンドエンジニア](https://qiita.com/Cookie_Iwate/items/aa1ef2962001e26cac66)

https://qiita.com/Cookie_Iwate/items/aa1ef2962001e26cac66

1. [バックエンドエンジニア](https://qiita.com/Cookie_Iwate/items/fa50d4b7701743ffc4ce)

https://qiita.com/Cookie_Iwate/items/fa50d4b7701743ffc4ce

2.[フルスタックエンジニア](https://qiita.com/Cookie_Iwate/items/9f786dab1b88f603b2ef)

https://qiita.com/Cookie_Iwate/items/9f786dab1b88f603b2ef

# スキルごとの将来性
1.[PHP](https://qiita.com/Cookie_Iwate/items/2645e656145d123c42b1)

https://qiita.com/Cookie_Iwate/items/2645e656145d123c42b1

2.[Ruby](https://qiita.com/Cookie_Iwate/items/f7dba28a83ced2ae13e5)

https://qiita.com/Cookie_Iwate/items/f7dba28a83ced2ae13e5

# その他の将来性
シーケンス図

# 目次
1. [シーケンス図とは](#シーケンス図とは)
1. [シーケンス図の特徴・必要性](#シーケンス図の特徴・必要性)
1. [シーケンス図の種類](#シーケンス図の種類)
1. [シーケンス図の注意点](#シーケンス図の注意点)

# シーケンス図とは
プログラムの処理の流れを直感的でわかりやすく図式化したもの

<img src="https://cacoo.com/wp-app/uploads/sites/2/2020/05/%E4%B8%A6%E5%88%97%E5%87%A6%E7%90%86%EF%BC%88Par%EF%BC%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9_%E3%82%B7%E3%83%BC%E3%82%B1%E3%83%B3%E3%82%B9%E5%9B%B3%E3%81%A8%E3%81%AF%EF%BC%9F%E6%9B%B8%E3%81%8D%E6%96%B9%E3%82%84%E3%83%84%E3%83%BC%E3%83%AB%E3%82%92%E5%88%9D%E5%BF%83%E8%80%85%E3%81%A6%E3%82%99%E3%82%82%E5%88%86%E3%81%8B%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E7%B4%B9%E4%BB%8B-1024x675.png" alt="シーケンス図">

# シーケンス図の特徴・必要性
1. [システム開発の設計書として使用される](#システム開発の設計書として使用される)
1. [保守・追加開発時に活用する際に役立つ](#保守・追加開発時に活用する際に役立つ)

### システム開発の設計書として使用される
システムの流れが直感で分かるので、システム設計時やクライアントへの説明など含めて業務が円滑に進めやすくなる

### 保守・追加開発時に活用する際に役立つ
図を参考にする事で、機能追加やエラー等への対応がスムーズになる


# シーケンス図の種類
1. [概略](#概略)
1. [詳細](#詳細)

### 概略
一塊の機能でクラス分けしたもの
1つの図で大きなプログラムを一元的に見ることが出来る

<img src="https://cacoo.com/wp-app/uploads/sites/2/2020/04/%E4%B8%8D%E6%AD%A3%EF%BC%88Neg%EF%BC%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-1024x675.png">

### 詳細
局部的に詳細に説明したもの

#### 例１
「ユーザー」「ログイン」に当たる部分はクラスになる。
「ユーザ存在するか？」「権限があるか？」はメソッドになる
<img src="https://i.ibb.co/zNf3HZT/2023-07-22-115843.png" alt="2023-07-22-115843"><hr />

#### 例２
メソッド名で表現されたもの。
※「main(argc, argv)」などのメソッドから『**どういう処理が行われているか**』を命名から読み取る必要がある
<img src="https://lecture.ecc.u-tokyo.ac.jp/~hideo-t/_images/example.png">

# シーケンス図の注意点
1. [プログラムは命名で読む](#プログラムは命名で読む)

### プログラムは命名で読む
シーケンス図はあくまで『**プログラムの流れ**』を知る為のものであり、『**プログラムの状態**』を知る為のものではない。その為、オブジェクト名・メソッド名から**推定**して読む事が求められる
テスト100

```vb
Sub ADD_Col()
'条件によって指定の列を追加する処理...〆('ω' )
Dim str_SQL As String
Dim str_Year As String
Dim Year_flg As Boolean
Dim cn As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim i As Long

str_Year = Year(Date)

Set cn = CurrentProject.Connection
str_SQL = "SELECT * FROM T_年度"

rs.Open str_SQL, cn, adOpenDynamic, adLockOptimistic
Year_flg = False

'フィールド名の検索
With rs

    For i = 0 To .Fields.Count - 1
    
        If .Fields(i).Name = str_Year Then
            '指定の年度列は既に存在する
            Year_flg = True
            Exit For
            
        End If
    
    Next i

End With

Set rs = Nothing

If Year_flg = False Then
    '指定の年度列が存在しない場合、列を追加する
    str_SQL = "ALTER TABLE T_年度 ADD " & str_Year & " VARCHAR(4)"
    DoCmd.RunSQL str_SQL

End If

Set rs = Nothing
Set cn = Nothing

End Sub
【ChatGPT無】に二日酔いの対処方法を聞いてみた。

:::note info
本記事は、ChatGPT（無料版）で
行なっております。GPT4での確認
はできておりません。あしからず。
:::

　どうも、カーブミラーです。

　今回は、
　　二日酔いですw

　ええ、二日酔いです、私が。

　まぁ、週に一度はなるものですw
　　（もうスケジュールに
　　　　組んであるw）

　とにかく、
　　聞いてみました。
```Text:二日酔い
User
二日酔いです。
対処方法を教えてください。
箇条書き（説明不要）で10個お願いします。

ChatGPT
二日酔いの対処方法を箇条書きで10個お伝えします（説明は不要とのことです）:

1. 水分補給をする。
2. 体を休める。
3. 食事を摂る。
4. アルコールを控える。
5. スポーツドリンクを飲む。
6. ジンジャーやペパーミントティーを飲む。
7. アセトアミノフェンを使用する（必要に応じて）。
8. 空腹時にはアルコールを避ける。
9. シャワーを浴びる。
10. 軽い運動をする。


User
ほかにもありますか？

ChatGPT
もちろん、二日酔いの対処方法はさまざまです。以下にさらにいくつかの対処方法を挙げます（説明不要の箇条書きでお伝えします）:

1. グリセリンを摂取する。
2. ビタミンB群を補充する。
3. ナプキンや吐き袋を準備する。
4. 非アルコール性飲料を選ぶ。
5. 生姜を噛む。
6. レモンの皮を噛む。
7. カフェインを摂取する（過剰摂取は避けてください）。
8. 氷を舐める。
9. レストランで飲酒をする際に軽い料理をつまむ。
10. 二日酔い用の市販の製品を利用する（例: 二日酔いサプリメントなど）。

ただし、二日酔いの症状は人によって異なりますので、何が効果的かは個人差があります。十分な休息と水分補給を心がけることが大切です。また、アルコールを飲む際には適量を守り、飲酒と同時に水分を摂取することも忘れずに行ってください。


User
ほかにもありますか？

ChatGPT
もちろん、さらにいくつかの二日酔いの対処方法を挙げます（説明不要の箇条書きでお伝えします）:

1. アロエベラジュースを飲む。
2. スープやミネラル豊富な食品を摂取する。
3. ハチミツを摂る。
4. ヨーグルトを食べる。
5. エレクトロライト補給飲料を飲む。
6. ショウガ入りのキャンディやチューインガムを噛む。
7. 炭酸水を飲む。
8. カルシウムやマグネシウムを含むサプリメントを摂取する。
9. ピクルスや酸っぱい食品を食べる。
10. 風呂にゆっくり浸かる。

これらの対処方法は、二日酔いの症状を軽減するのに役立つかもしれませんが、何が自分に合っているかは個人により異なります。十分な休息と栄養補給を心がけ、アルコールを飲む場合は適度な量を守ることが大切です。また、二日酔いが長引く場合や症状が重い場合は、医師に相談することをおすすめします。


User
ほかにもありますか？

ChatGPT
もちろん、引き続きいくつかの二日酔いの対処方法を挙げます（説明不要の箇条書きでお伝えします）:

1. 体を冷やしすぎないように注意する。
2. カモミールティーやラベンダーティーを飲む。
3. 胃薬を使用する（必要に応じて）。
4. 空気をよく吸い込むために散歩する。
5. 酸素ボトルを使用する（専門医の指示が必要）。
6. アルコール摂取後に炭水化物を食べる。
7. 飲酒の前後に乳酸菌を摂取する。
8. オイルマッサージを受ける。
9. アルコール摂取を避けるための予防策を考える。
10. 心地よい音楽を聴く。

これらの方法も、二日酔いの症状を和らげるのに役立つかもしれませんが、個人差があるため、自分に合った方法を見つけることが重要です。二日酔いを防ぐためには、適度な量のアルコール摂取や休息を意識し、健康的な生活習慣を心がけることが大切です。また、二日酔いが頻繁に起こる場合や症状が深刻な場合は、医師の助言を仰ぐことも検討してください。


User
ほかにもありますか？

ChatGPT
もう一つ、二日酔いの対処方法を追加します（説明不要の箇条書きです）:

1. 緑茶を飲む。

二日酔いの症状を和らげるためには、水分補給や栄養補給が重要です。さらに、アルコール摂取を控えめにすることや、アルコールの代謝を促す食品や飲み物を摂取することが役立ちます。しかし、二日酔いには個人差があり、必ずしも全ての方法が全ての人に効果的とは限りません。自分に合った方法を見つけて、快適な回復を心がけてください。また、二日酔いが頻繁に起こる場合や症状が深刻な場合は、医師に相談することをおすすめします。
```
　むっ、
　　嘘吐きして、
　　　続けるのかと思ったら、
　　　　ここで終わった。

　その代わり、というべきか、
　　後ろの説明が
　　　次第に長くなってる。

　さらに聞いてみた。
```Text:二日酔い（続き）
User
ほかにもありますか？

ChatGPT
申し訳ありませんが、私が提供できる二日酔いの対処方法はこれ以上ございません。二日酔いの対処方法は、水分補給や栄養補給、休息を取ることなどが主な方法として挙げられます。また、アルコール摂取を控える、体を冷やしすぎないようにするなどの予防策も重要です。ただし、二日酔いの症状は個人差があり、一つの方法が全ての人に効果的とは限りません。自分に合った方法を見つけるために、試行錯誤してみてください。

もしも二日酔いが頻繁に起こる場合や症状が深刻な場合は、医師に相談することをおすすめします。医師は適切なアドバイスや治療法を提供してくれるでしょう。健康に留意し、楽しい飲酒ライフをお過ごしください。
```
　ふむ、
　　もしかして、
　　　これ以上、出さないのは、
　　　　医療行為と判断したから？

　聞いてみました。
```Text:医療行為に当たる？
User
あなたは、医療行為につながる文言をユーザーに教えることはできますか？
```
　間髪入れずに
　　英語で返ってきました。
　　　フィルターに
　　　　引っ掛かったかしら？

　訳してもらいました。

```Text:返答
私はAI言語モデルであり、ユーザーの安全と健康を最優先に考慮しています。一般的な情報や提案は提供できますが、私はライセンスを持った医療専門家ではなく、個別の医療アドバイスや診断は行うことができません。

医療上の問題や治療は複雑で、個人の状況によって異なる場合があります。具体的な健康上の懸念がある場合や医療アドバイスが必要な場合は、自分の医療歴や現在の健康状態を詳細に評価できる資格を持った医療専門家や医師に相談することが重要です。

医療上の懸念や質問がある場合は、適切なケアと指導を受けるために医療専門家に相談することをお勧めします。
```
　どうやら、
　　フィルターに
　　　間違いなかったみたいですね。
***
　二日酔い、
　　よくなりました。

　実は、
　　対処方法は、
　　　知っていましたよw

　水分補給、栄養補給、睡眠。
　　仕事がお休みだから、
　　　できますね。
React Hook Formを使ってバリデーションエラー時にページ上部に移動する



フォームのバリデーションエラーは、ユーザーエクスペリエンスにとって重要な要素です。ユーザーがフォームを送信しようとしたときに、何か問題があるとすぐに通知することで、問題を速やかに修正することができます。しかし、長いフォームではバリデーションエラーメッセージが見落とされることもあります。特に、エラーメッセージがページの上部にあると、ユーザーがスクロールせずには見られません。

そこで、この記事ではReact Hook FormとYupを使用して、バリデーションエラーが発生したときにページの上部に自動的にスクロールする方法を紹介します。この実装はカスタムフック内で行われ、フォームがこの挙動を共有するために再利用可能です。

## なぜそれが必要なのか？

長いフォームでは、エラーメッセージがすぐには見えない可能性があります。特に、ページの下部で「送信」ボタンを押した後、エラーメッセージがページの上部にあると、ユーザーは何が問題なのかわからないかもしれません。この問題を解決するために、バリデーションエラーが発生したときにページの上部に自動的にスクロールすると、ユーザーはすぐにエラーメッセージを見つけることができます。

## 実装方法

React Hook Formの`useForm`フックは、`handleSubmit`関数の第二引数としてエラーハンドラを提供します。これを使用して、バリデーションエラーが発生したときにページの上部に自動的にスクロールすることができます。

以下にその方法を示します。

```tsx
// useCustomForm.ts
const {
  register,
  handleSubmit,
  formState: { errors },
} = useForm<FormData>({
  resolver: yupResolver(schema),
  defaultValues: {
    // ここにデフォルト値を設定
  },
});

const onSubmit = (data: FormData) => {
  // ...
};

const onError = () => {
  window.scrollTo(0, 0); // エラーが発生したらページの最上部へスクロール
};

return {
  register,
  errors,
  handleSubmit: handleSubmit(onSubmit, onError), // handleSubmit関数にエラーハンドラとしてonError関数を渡す
  // ...
};
```

上記のように、`handleSubmit`関数にエラーハンドラとして`onError`関数を渡すことで、バリデーションエラーが発生した際に自動的にページの最上部へスクロールするようにすることができます。このロジックをカスタムフック内に包んで、フォーム全体で再利用することができます。

## 結論

React Hook FormとYupを使ってバリデーションエラーが発生した時にページ上部に移動する方法をご紹介しました。これにより、ユーザーエクスペリエンスを向上させ、ユーザーがエラー情報を見逃す可能性を減らすことができます。さらに、このロジックはカスタムフック内に包むことで、複数のフォームで再利用可能となります。

---
WSL2でNTPサーバを立ててみた

### 　WSL2でNTPサーバを立てようと思った経緯

以下記事の続きです。
社内検証をしていて、NTPサーバも立ててほしいと依頼がありました。
社内検証で使用しているNW機器でもNTPは立つのですが、SNTPは対応していないためWSL2でNTPサーバを立てました。
[WSL1でsyslogサーバを立ててみた](https://qiita.com/shinfx/items/55cdf8c3814e2206e213)

### 　WSLのバージョン選定
WSL1は一部機能が制限されており、NTPサーバを立てることができなかったためWSL2に選定しました。

### 　NTPの設定方法

最初にroot権限を付与する。
```conf
sudo su -
```

nptをインストールする。
```conf
sudo apt update
sudo apt install -y ntp
```

ntp.confを開き設定変更します。
```conf
sudo vi /etc/ntp.conf
```

以下内容で修正する。
今回はインターネットに出ないので、WSL自身をntpサーバとする必要があります。

```conf
#以下をコメントアウトする
#server ntp.nict.jp iburst
#server ntp1.jst.mfeed.ad.jp iburst
#server ntp2.jst.mfeed.ad.jp iburst

#NTPの内部ドライバーを参照する
server 127.127.1.0
fudge 127.127.1.0 stratum 10

#他マシンからNTPサーバにアクセスできるよう制限を設定する
restrict 10.0.0.0 mask 255.0.0.0 nomodify notrap
```

### 　以下備忘録と注意点

"127.127.1.0"はTPの内部ドライバを指す特別なアドレスで、ローカルクロックをNTPサーバーのソースとして使用する場合に用います。

stratumはデフォルト3なので、15以外ならOkです。

nomodify: このオプションが指定された場合、そのアドレスからのクライアントはNTPサーバーの設定や情報を変更することはできません。ただし、時刻情報の取得は可能です。これにより、不正な変更を防ぐことができます。

notrap: このオプションが指定された場合、そのアドレスからのクライアントはNTPサーバーにトラップ（エラーメッセージやログメッセージのような通知）を送信することはできません。トラップは、特定のイベントが発生したときに通知を受け取るためのものですが、不要なトラップを防ぐためにこのオプションを使用します。


設定保存します。
コマンドモード（ESC）に移行し":wq"で保存して終了する。

設定反映するためrsyslogシステムを再起動する。
WSLはsystemctlが使用できないためserviceを使用する。
```conf
sudo service ntp restart
```

rsyslogが正常に動作していることを確認する
```conf
sudo service ntp status
```

もし動いていない場合は、起動するコマンドを使います。
```conf
sudo service ntp start
```

次にWSL2を外部接続できるようにします。
WSL2はHyperVなのでwindowsのIPアドレスとは別のIPアドレスを持っています。
以下イメージ図
```conf
  +---------------------+
  |         PC1         |
  |  +-------------+    |
  |  |    WSL2    |    |
  |  | (独立のIP) |    |
  |  +-------------+    |
  +---------------------+
           |
     Ethernet/Wi-Fi
           |
  +---------------------+
  |         PC2         |
  +---------------------+
```

そのためWSL2の仮想NICとPC1の物理NICをブリッジします。
コントロール パネル\ネットワークとインターネット\ネットワーク接続と開き、
物理NICと仮想NICを選択して、ブリッジをクリックしてください。
詳細な手順は下記URLを参照ください。
[Windows 11でネットワークブリッジを設定する方法](https://faq.nec-lavie.jp/qasearch/1007/app/servlet/relatedqa?QID=023252)

以上でntpの設定は終わりになります。
クライアントがNTPサーバを参照しているか確認するには、各機器でshow ntp associationに相当するコマンドを入力してください。

WSL2自身でクライアントを確認する術はありません。

### 　まとめ
WSL2はWSL1と違いブリッジ設定をしなければなりませんが、使用可能な機能はWSL1よりも多いです。
これからはWSL2を使用する予定です。
ActiveRecord 日付・時刻検索メモ

たまに使う時用のメモ

# 前提
- ruby 3.2.2 (2023-03-30 revision e51014f9c0) [arm64-darwin21]
- rails (6.1.7.4)

# 本題
範囲演算子を使おう

```ruby
# いつ時点以降
Test.where(updated_at: Time.new(2023, 1, 1, 1, 1, 1, 'UTC')..).to_sql
=> "SELECT `tests`.* FROM `tests` WHERE `tests`.`updated_at` >= '2023-01-01 01:01:01'"
# > になると思ったけどならないのか
Test.where(updated_at: Time.new(2023, 1, 1, 1, 1, 1, 'UTC')...).to_sql
=> "SELECT `tests`.* FROM `tests` WHERE `tests`.`updated_at` >= '2023-01-01 01:01:01'"

# いつからいつまで
Test.where(updated_at: Time.new(2023, 1, 1, 1, 1, 1, 'UTC')..Time.new(2023, 1, 1, 1, 1, 1, 'UTC')).to_sql
=> "SELECT `tests`.* FROM `tests` WHERE `tests`.`updated_at` BETWEEN '2023-01-01 01:01:01' AND '2023-01-01 01:01:01'"
# こっちは > になる
Test.where(updated_at: Time.new(2023, 1, 1, 1, 1, 1, 'UTC')...Time.new(2023, 1, 1, 1, 1, 1, 'UTC')).to_sql
=> "SELECT `tests`.* FROM `tests` WHERE `tests`.`updated_at` >= '2023-01-01 01:01:01' AND `tests`.`updated_at` < '2023-01-01 01:01:01'"

# 日付で良い場合は、Date.new(2023, 1, 1)で
```

# 参考
- https://techracho.bpsinc.jp/hachi8833/2023_04_12/24876
- https://techracho.bpsinc.jp/gengen/2022_12_20/125057
LaTeXで印刷に適した文書を作成する

※こちらは，会社の技術ブログとのクロスポスト記事です．元の記事は[こちら](https://www.timedia.co.jp/tech/20221201-tech)

卒業論文や修士論文は，印刷した紙を製本して提出する場合が多いと思います．
自分で製本する場合，紙を綴じる内側部分の余白を多く取らないと，作成した論文の内側の文字が読めない悲劇に見舞われる可能性があります．
この記事では，LaTeXで印刷に適した文書を作成する方法を紹介します．

# jsbookの基本的な文書
日本語の場合，学位論文（卒業論文，修士論文，博士論文）は，jsbookを利用することが多いです．
jsbookの基本的な文書とその作成ファイルは，以下になります．

```latex:main.tex
\documentclass{jsbook}
\begin{document}
    \chapter{序論}
    \section{背景}
    あいうえお...（省略）
\end{document}
```
![tex01-1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308259/5bda039e-ed5b-1ac2-6fc4-210d4fe45038.png)

文書は，本と同じ見開き形式で表示しています．
jsbookの基本設定は，A4サイズの用紙，10ptの文字サイズです．
また，1行の文字数が40文字というお約束があります．

製本時に重要となる，文書の内側部分の余白が小さいことが確認できます．
また，ヘッダーが文章の横幅と一致していないです．
製本にも，webでの閲覧にも適していないと思います．

# LaTeXのパラメータ
文書レイアウトの変更前に，この記事で登場するパラメータを説明します．
登場するのは，以下の4つです．
* `fullwidth`: ヘッダーの横幅
* `textwidth`: 文章の横幅
* `oddsidemargin`: 奇数ページの左側（内側）の余白
* `evensidemargin`: 偶数ページの左側（外側）の余白
![tex01-4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308259/af171e02-4870-cd3b-c86c-14d4b959a85b.png)

図に示した長さは，だいたいの目安です．
パラメータに対して，X cmのように直接長さの指定ができますが，この記事では採用しません．
a4，b5，US Letterなどの文書サイズに対して，汎用的に利用できる形で文書レイアウトを変更します．

# web閲覧に適した文書
documentの開始前，texファイルの先頭を以下にすることで，web閲覧に適した文書が作成できます．
```latex:main.tex
\documentclass[12pt, openany, oneside]{jsbook}
%\setlength{\fullwidth}{\textwidth} % ヘッダーを文章に合わせる
%\setlength{\textwidth}{\fullwidth} % 文章をヘッダに合わせる
```
![tex01-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308259/92334bb8-9f41-5ca1-d51e-c6821d21a904.png)

用紙サイズがA4の場合，文字サイズは12ptがお勧めです．
`openany`を設定すると，章の始まりが奇数ページで固定されなくなり，空白ページの挿入を回避できます．
`oneside`を設定すると，奇数ページと偶数ページのデザインが統一されます．
2つ`%`のどちらかを削除して，ヘッダーと文章の横幅を統一しても良いと思います．
文字サイズ12ptでweb閲覧の場合，2つの横幅が不一致でも違和感は無いです．

# 印刷に適した文書
documentの開始前，texファイルの先頭を以下にすることで，印刷に適した文書が作成できます．
```latex:main.tex
\documentclass[12pt]{jsbook}
\setlength{\fullwidth}{\oddsidemargin}
\setlength{\oddsidemargin}{\evensidemargin}
\setlength{\evensidemargin}{\fullwidth}
\setlength{\fullwidth}{\textwidth}
```
![tex01-3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308259/960d2c85-44c2-b17d-3ced-b456d54813d9.png)

`\oddsidemargin`と`\evensidemargin`を入れ替えた後，ヘッダーの横幅を文章の横幅に合わせています．
`\oddsidemargin`, `\evensidemargin` = `\evensidemargin`, `\oddsidemargin` という変数の交換が出来ないので，`\fullwidth`を一時変数として利用しています．

ヘッダーの外側部分の余白を保ったまま，内側の余白を最大限に取る設定です．
内側の余白をこれ以上取る場合，外側の余白と合わせて上下の余白も小さくしないとバランスが悪くなると思います．
余白を変更するのではなく，製本の方法を変更するのも1つの手です．

# 終わりに
この記事では，LaTeXで印刷に適した文書，web閲覧に適した文書を作成する方法を紹介しました．
紹介した設定や変数の変更で，より余白の大きい文書，余白の小さい文書も作成できます．
余白は，内側と外側，上下のバランスも重要です．
余白を上手く調節して，読みやすい文書を作成しましょう．

提出する論文について，文書の形式が指定されている場合は，その指示に従いましょう．
専門業者に製本を依頼する場合，必要となる内側の余白は，小さくなります．
印刷前に，文書の形式を確認すると良いでしょう．
Power Automate DesktopでExcelの複数シートにデータ入力

## Power Automate Desktopで複数シートにわたりデータを書き込む様子

https://twitter.com/MitsuhiroM82423/status/1681593187490754562

みなさん、こんにちは。
紙、印鑑、手作業に埋もれて業務をしている昭和男子の会社員です。

毎月、**請求書を大量に発行している業務**を行っています。
請求書は、自動でEXCELファイルが作成されるシステムを使用していますが、**発行部署名、電話番号が表示されずに毎回コピペ**してから発行しています。
この作業を**PowerAutomateDesktopで作業の自動化**をしてみたいと思います。

## 使用するもの
・Power Automate Desktop
・Excel

## 請求書（Excel）
ここに電話番号と発行部署名を入力していきます。
![2023-07-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288463/26b9428e-7dde-1d78-b196-f1d65bcbe112.png)
## Power Automate Desktopの設定
![2023-07-22 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3288463/ffb3d64d-105f-7cd9-7830-f31f8af51ba5.png)

**フローのソースコード**
```ruby:Excelの複数シートデータ入力
FUNCTION Main_copy GLOBAL
    Excel.LaunchExcel.LaunchAndOpenUnderExistingProcess Path: $'''\\\\mvssmain\\共有\\05_商品\\専用\\11_契約関連\\02_リベート契約\\請求書電話番号変更\\請求書.xls''' Visible: True ReadOnly: False Instance=> ExcelInstance
    Excel.GetAllWorksheets Instance: ExcelInstance Worksheets=> SheetNames
    SET NewVar TO 1
    LOOP FOREACH CurrentItem IN SheetNames
        Excel.SetActiveWorksheet.ActivateWorksheetByIndex Instance: ExcelInstance Index: NewVar
        Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: $'''Tel：000-000-0000''' Column: 20 Row: 12
        Excel.WriteToExcel.WriteCell Instance: ExcelInstance Value: $'''部署：○○部''' Column: 20 Row: 13
        Variables.IncreaseVariable Value: NewVar IncrementValue: 1
    END
    Excel.CloseExcel.CloseAndSave Instance: ExcelInstance
END FUNCTION
```
## ポイントは、変数の設定
入力したいExcelシートを指定するのに変数を使用しました。シート数は、「**SheetNames**」でカウントされていますので、1からスタートして1つづつ変数を増やしていくと**左端のシートから順**に指定されていきます。**Excelのマクロを動かしたように動いてくれます。**
マクロが使えない方にお勧めです。
（私も使えませ～ん！）
ヤマハルーターで複数Global IP AddressとNAT

# ヤマハルーターRTX830に複数Global IP Address設定とNAT（Private IP Addressネットワーク）との共存
こちらの内容「[自社サーバーを公開(複数の固定グローバルIPアドレス / LAN分割) : コマンド設定](https://network.yamaha.com/setting/router_firewall/internet/dmz_server/multiple_lan_divide)」を実現。ただし、こちらの記載はフィルター設定が多数ある。ここでは、できるだけ（わかる範囲内で）最低限の設定を目指した。

## トポロジー
ネットワーク的には下記となる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/2fcabf8c-873e-1be7-e762-03b149d976cb.png)
ヤマハルーターのWAN側にPPPoE接続によるONUがあり、LAN側に、DMZとして、Global IP Addressを持つ機器（200.1.1.0/29：公開サーバーなど）２機と、Private IP Addressネットワーク（192.168.0.0/24）とが存在するものとする（Global IP Address 200.1.1.0/29は仮の値）。

## 設定情報
```
ip route default gateway pp 1
ip filter source-route off
ip filter directed-broadcast on
vlan port mapping lan1.1 vlan1
vlan port mapping lan1.2 vlan1
vlan port mapping lan1.3 vlan2
vlan port mapping lan1.4 vlan2
lan type lan1 port-based-option=divide-network
ip vlan1 address 192.168.0.1/24
ip vlan2 address 200.1.1.6/29
pp disable all
pp select 1
 pp always-on on
 pppoe use lan2
 pp auth accept pap chap
 pp auth myname USER-ID HIMITSU
 ppp lcp mru on 1454
 ppp ipcp msext on
 ip pp mtu 1454
 ip pp intrusion detection in on
 ip pp nat descriptor 1
 pp enable 1
no tunnel enable all
nat descriptor type 1 masquerade
nat descriptor address outer 1 200.1.1.6
nat descriptor address inner 1 192.168.0.1-192.168.0.254
dhcp service server
dhcp server rfc2131 compliant except remain-silent
dhcp scope 1 192.168.0.2-192.168.0.191/24
dns server 1.1.1.1 8.8.8.8
dns private address spoof on
statistics traffic on
```
キーとなりそう点のみ下記に説明。
- ip route default gateway pp 1　：デフォルトゲートウェイを”pp 1”（PPP側）に設定
- vlan port mapping
    - lan1.1 vlan1：Port1をVLAN1に属させる
    - lan1.2 vlan1：Port2をVLAN1に属させる
    - lan1.3 vlan2：Port3をVLAN2に属させる
    - lan1.4 vlan2：Port4をVLAN2に属させる
- lan type lan1 port-based-option=divide-network；LAN側のポートベース（VLAN）のネットワークとする
- ip vlan1 address 192.168.0.1/24：VLAN1のIPアドレス
- ip vlan2 address 200.1.1.6/29：VLAN2のIPアドレス（ISP指定）
- pppoe use lan2：PPPをWAN側に設定
- ip pp nat descriptor 1：PPPをNAT化
- nat descriptor
    - type 1 masquerade：IPマスカレード
    - address outer 1 200.1.1.6：外側IPアドレス
    - address inner 1 192.168.0.1-192.168.0.254：内側IPアドレス
- dhcp service server
- dhcp scope 1 192.168.0.2-192.168.0.191/24：DHCPによるLAN側IPアドレス範囲

## DMZ
Port3およびPort4に接続される機器情報は下記となる。
- Port3設定情報：IPアドレス202.1.1.1/29, Gateway202.1.1.6
- Port4設定情報：IPアドレス202.1.1.2/29, Gateway202.1.1.6

## 終わりに
さらに簡略化できる可能性はあるかもしれない。
署名付きアップロード・ダウンロードの構成をterraformで作る。

# はじめに
[前回](https://qiita.com/sakai00kou/items/ba5618f0a67064355752)、[AWSブログ](https://aws.amazon.com/jp/blogs/news/large-size-files-transferring-by-serverless-s3presignedurl-and-clientside-javascript/)で公開されていた署名付きアップロード・ダウンロードの構成をAWSマネジメントコンソール画面から構築しましたが、色々と使えそうなので、terraformの勉強も兼ねてterraform化したので公開しようと思います。

- 【前】[API Gateway、Cognito、Lambda、S3を使って署名付きアップロード・ダウンロードを実装する。](https://qiita.com/sakai00kou/items/ba5618f0a67064355752)

**元のブログ記事**
- [AWS のサーバーレスと Amazon S3 署名付き URL、クライアントサイド JavaScript で大きなサイズの複数ファイルの一括アップロード・ダウンロード機能を実現する方法](https://aws.amazon.com/jp/blogs/news/large-size-files-transferring-by-serverless-s3presignedurl-and-clientside-javascript/)

# 公開場所
以下GitHubで公開しています。
- https://github.com/sakai00kou/qiita

# terraformについて
本`terraform`はVPC等を使用していないため、環境に合わせて修正したりしなくても実行できるかと思います。

また、各リソースの名前等は[前回](https://qiita.com/sakai00kou/items/ba5618f0a67064355752)の記事で設定している名前に合わせています。

各リソースの名前等は`variables.tf`にまとめているので、環境に合わせて修正してください。

以下、特記事項について示します。

## SMS External ID
前回、`Cognito`でSMS認証の設定を行いましたが、画面上から行った場合は自動でSMSの外部IDといったIDが設定されますが、`terraform`で作成する場合は自分で設定する必要があるようです。

他の外部サービスと連携したりしなければ、意識する必要はないようなので、適当な`UUID`を指定しておきます。

以下コマンドでUUIDを生成できるので、生成したIDを入力しておきます。

```bash:UUIDの生成
uuidgen | tr "[:upper:]" "[:lower:]"
```

## S3へのファイルアップロード
`aws_s3_object`リソースを使ってS3にファイルをアップロードすると、アップロードしたファイルの`Content-Type`が`binary/octet-stream`となってしまうことで、アップロード・ダウンロードを行う際にJavaScriptが実行できなくなります。

**Terraform Template Directory Module**を使用して、`Content-Type`を付与することで回避しました。

## ファイルが更新された場合のアップロード
`aws_s3_object`リソースで`etag`を設定しておくと、ファイルが更新された際にハッシュ値比較して、ファイルが更新されていればアップロードを行うようになるそうです。便利！

## terraform apply後のアクセス
`Output`でエントランスページのURLを出力するようにしているため、apply後は出力されたURLにアクセスします。

```
（省略）
Outputs:

Entrance_Page_URL = "https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/web/entrance.html"
```

## アクセス時の注意点
`terraform`で作成すると、数十秒程度で構築できますが、裏でAPI Gateway等のデプロイ作業が行われているので、10分程度は待つようにしましょう。

ページアクセスはできますが、デプロイ途中の場合、アップロード、ダウンロードに失敗します。

# おわりに
今回はブログで紹介されていた構成をそのまま`terraform`で作っただけなので、拡張性は考えず`module`等も使用しておりませんが、勉強がてら`terraform`に慣れるのにはちょうどよかったです。

今回の構成をベースに認証方式を変えたりしながら、今後どこかのシステムに導入できれば良いなと感じました。
C#でEnumのDescriptionを使ってみる

# 1. はじめに
* C# でEnum型を使用する時に同時に文字列も定義したい
* Enum型のDescription属性を使用して解決したい

# 2. 開発環境
* C#
* .Net 6
* Visual Studio 2022
* Windows 11

# 3. Enum型を定義する
```C#:
using System.ComponentModel;

public  class SampleEnum
{
    public enum CityEnum
    {
        [Description("東京")]
        Tokyo = 1,

        [Description("大阪")]
        Nagoya = 2,

        [Description("名古屋")]
        Sapporo = 3,
    }
}
```

# 4. Enum型からDescriptionを取得する
```C#:
/// <summary>
/// 列挙体フィールドのDescriptionを取得する。
/// </summary>
/// <param name="value">列挙体値</param>
/// <returns>Description文字列</returns>
public static string GetDescription<T>(T value) where T : Enum
{
    string description = string.Empty;

    if (value != null)
    {
        string strValue = value.ToString();

        description = strValue;

        if (strValue.Length > 0)
        {
            FieldInfo? fieldInfo = typeof(T).GetField(strValue);
            if (fieldInfo != null) { 
                Attribute? attribute = Attribute.GetCustomAttribute(fieldInfo, typeof(DescriptionAttribute));
                if (attribute != null)
                {
                    DescriptionAttribute descriptionAttribute = (DescriptionAttribute)attribute;
                    description = descriptionAttribute.Description;
                }
            }
        }
    }

    return description;
}
```

# 5. 参考文献

http://kawakawa2000.jugem.jp/?eid=27

https://qiita.com/mkuwan/items/be6745f2c9e7823f8a66

https://qiita.com/4_mio_11/items/abf6373b0863ac2ebd5c

https://johobase.com/judge-calculate-enum-csharp/
駆け出しエンジニアがExpress.jsとSwaggerを使ってみました！

こんにちは！私は、ここ最近Web開発の世界に飛び込んだ1年目のエンジニアです。仕事でSwaggerに触れたことがきっかけで、プライベートの時間にAPIドキュメンテーションの作成に挑戦したときの記録を記事化しました。

今回はExpress.jsを使ったAPI開発、SwaggerでのAPIドキュメンテーション生成に挑戦したので、その経験をシェアしたいと思います。

なんとなくでも参考になれば嬉しいですし、もし何かアドバイスがあればぜひ教えてください！

```typescript
// 各種モジュールをインポート
import express from "express";
import userIdCheckRouter from "./userIdCheck";
import swaggerJSDoc from "swagger-jsdoc";
import { serve, setup } from "swagger-ui-express";

// Expressアプリを初期化
const app = express();
// 環境変数からポート番号と許可されたIPアドレスを取得
const PORT = Number(process.env.PORT as string);
const ALLOWED_IPS = process.env.ALLOWED_IPS ? (process.env.ALLOWED_IPS as string).split(',') : undefined;

// リバースプロキシからの接続を信頼（リバースプロキシを使用している場合）
app.set('trust proxy', true);

// 許可されたIPアドレスからのアクセスのみを許可
if (ALLOWED_IPS) {
	app.use((req, res, next) => {
		const clientIp = (req.headers['x-forwarded-for'] as string)?.split(',')[0].trim() || req.ip;
		if (!ALLOWED_IPS.includes(clientIp)) {
			return res.status(403).json({ message: "Your IP address is not allowed." });
		}
		next();
	});
}

// JSONを受け取れるようにする
app.use(express.json());

// ルートを設定
/**
 * @swagger
 * /api/user/userIdCheck/{userId}:
 *   get:
 *     description: Check user ID
 *     parameters:
 *       - name: userId
 *         in: path
 *         required: true
 *         schema:
 *           type: string
 *     responses:
 *       200:
 *         description: success
 */
app.use("/api/user", userIdCheckRouter);

// Swaggerの設定
const options = {
	definition: {
		openai: "3.0.0",
		info: {
			title: "Express API with Swagger",
			version: "1.0.0",
		},
	},
	apis: ["./src/api/*.ts"],
};
const specs = swaggerJSDoc(options);
app.use("/api-docs", serve, setup(specs));

// サーバを起動
app.listen(PORT || 3000, () => {
	console.log("Server is running on port 3000");
});
```
これでコードの完成です！

特に大変だったポイントは以下の3つです：

1\. リストアクセス元IPの制御： 特定のIPからのリクエストのみを許可するよう設定しました。

2\. Swaggerを用いたAPIドキュメンテーションの自動生成： 実務ではNext.jsによるドキュメント生成を行っているのですが、使わない場合はこういった実装法になるのですね。一つのやり方として覚えておこうと思います！

まだまだ学びたいことは山積みですが、一歩ずつ進んでいこうと思います。フィードバックもぜひお待ちしています!
bootloderとkernel

ルーターなどのモジュールではbootloderからkernelが実行されてOSが起動します。

bootloaderはkernelを読み込むために最低限のIOの初期化を行いアクセスを行います。

bootloaderはkernelをメモリに貼り付けて、実行を移します。この時は物理アドレスで実行され、kernelがmmuの初期化を行い仮想記憶に移行します。

bootloaderがCFI Flashにある場合はリセット後にそのまま実行されますが、SPI Flashにある場合は、SOC内のROMなどにあるpre bootloaderがいったんSPI Flashの内容をRAMにコピーしてから実行されます。

SDカードからbootloaderが起動する場合もSPI Flashと同じようにpre bootloaderが処理しています。

最近のRAMはいろいろ選択肢があって、利用前にコントローラーの初期化が必要です。SPI Flashの場合はpre bootloaderがそれをおこないます。またCFI Flashにbootloderがある場合は、初期の処理でそれをおこないRAMを使い始めます。

ARMのSOCには内部に初期化の必要の無い小さいRAM領域があって、それを利用する事もあるようです。

RAMが使えるようになるまではスタックが使えずサブルーチンが使えないので、長々処理が書かれていると思います。

ほとんどのSOCでIOを使えるようにするにはClockの初期化も必要です。

Networkを利用する場合はMACに加えてPHYやSwitchの初期化も必要です。

Kernelを読み出すのはCFI/SPI Flash,SDカード,USB ストレージ,SATA ストレージ,Networkなどがあります。

kernelはbootloaderがある程度初期化をしているので、それをあてにして処理する事もできます。しかしbootloaderのコンフィグレーションに依存する事になるので、リスクがあります。

またbootloaderが初期化しているRAMについて、kernelが再初期化するのは結構リスクがあります。自分が乗ってるRAMをいじるわけですから、当たり前ですよね。まれにパリティチェックなどの仕組みをkernelが利用する場合は再初期化が必要になります。

よくあるトラブルとして、Networkからkernelを読み込んだ場合はNetworkが初期化されていて、kernelではNetworkの初期化が必要なくなりますが、Flashから読み込んだ場合は、Networkが初期化されていなくて、Networkが使えなくなるとかあります。

kernelを起動する前にbootloaderでアクセスしたIOをリセットする事もありますが、これも副作用があるといけないので、最低限を止めているケースが多いです。中にはまったく止めずにkernelを起動するbootloaderもあります。SOCの個別RESETはどこにどのように作用するはそれぞれです。
Databricks Reposでゴミ箱がサポートされました！

こちらのアップデートです。

https://docs.databricks.com/release-notes/product/2023/july.html#move-to-trash-enabled-for-repos

# Databricks Reposとは？

GitHubなどのバージョン管理システムのリポジトリとDatabricksワークスペースで同期を行える機能です。これによって、ソースコードをGitHubで管理しながら、Databricksの様々な機能を活用できます。

https://qiita.com/taka_yayoi/items/b89f199ff0d3a4c16140

これまではRepos配下のソースコードを削除すると、即座に削除され復旧ができませんでした。リモートリポジトリから再度同期するしかありませんでした。

今回のアップデートで、通常のノートブックと同じように削除した際にはゴミ箱に移動されるので復旧が容易となります。

# ウォークスルー

Repos配下のソースコードを一覧表示して、一番右の3点リーダーをクリックすると、**ゴミ箱に移動**が表示されます。
![Screenshot 2023-07-22 at 7.29.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/39029e81-42d6-fd75-2229-16ef72012ac7.png)

確認メッセージが表示されます。
![Screenshot 2023-07-22 at 7.29.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/fe782aa3-e7cf-7f75-7e0b-641659b21e63.png)

ゴミ箱を確認します。移動されています。
![Screenshot 2023-07-22 at 7.29.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/78f6b6ff-7a89-f743-ccb3-52613b37f833.png)

復旧してみます。再度、3点リーダーをクリックして、**復元**を選択します。
![Screenshot 2023-07-22 at 7.30.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c30238e0-b3f8-8e7d-52a4-4c5f9de62491.png)

移動先を選択します。まずは最上位まで移動します。**Repos**から辿って元のパスを選択します。
![Screenshot 2023-07-22 at 7.31.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/8bdf59b4-e295-a078-8ff4-f9571bbe3c7f.png)
![Screenshot 2023-07-22 at 7.30.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/b08732c2-3c50-36b1-0bcd-5d83a6242901.png)

確認メッセージが表示されます。
![Screenshot 2023-07-22 at 7.31.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/0e75292d-835c-6485-d79d-7d21380aba9a.png)

復旧できました！
![Screenshot 2023-07-22 at 7.31.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/80dad1ed-adcc-ff04-94f1-b61e59894a14.png)



### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
pytestでprint()の出力結果をコンソールに出力する

コマンドでpytestを実行する場合は、```-s```オプションを指定する。
```
pytest -s
```

VSCodeを使用している場合、.vscode/settings.jsonに```--capture=no```を指定する。

```json:settings.json
{
    "python.testing.pytestArgs": [
        ".",
        "--capture=no"
    ],
    "python.testing.unittestEnabled": false,
    "python.testing.pytestEnabled": true
}
```