OmniAICreator/Qiita-1.07M huggingface dataset:
フリーのシステム/ディスククローンツールについてのメモ


SSD換装などで行うシステムクローン。わかんなければ移行ツール同封などのSSDを使えば何とかできるでしょう。
だがそんなツールとかない場合どうすればいい？また、マニアックな話になるかもしれないがOSにツールをインストールせずに行うためには？ディスクがGPTの場合は？MBRの場合は？
ディスククローン機能は、パーティションバックアップツールの機能に思えるが、パーティション編集の側のツールも大概持っている。無料版で現在のシステムのディスクをコピー元(システムクローンって表記されてることも)にできない場合もあるが、その時でも起動ディスク(WinPE)からなら可能かもしれない。
この手のツール、無料で使えるのはシェアウェアの機能限定版なのがほとんどであり、バージョンアップで機能の制限が多くなるケースも多々ある。そこも含めて簡単に調べてみた。最新版も性能は改善しているのかもしれず、選ぶメリットは人によりけりなのでしょう。

#### 先に簡単な結論
・すでにAOMEI PE Builder等で作成済みならそれを利用でOK
・WinPE作る気があるならAOMEI Backupper 6.4 + Partition Assistant 7.1 あたりで作成はいかが
・WinPEなんぞわからんという方は、SSDがCrucialならTrueImage for CrucialでOK
・それ以外なら...

#### どうやって旧バージョンをダウンロードするか
バージョン番号と一緒にググれば出てくるはず。他はinternet archiveやoldversionを探す。正直私がいちいち書くまでもない基本事項だけど一応。

## EaseUS Todo Backup
11.5まではシステムクローンが可能（MBR→MBR,GPT→GPTの制限はある。まぁ普通はそうか。）もちろんWinPE作成可能。なんだが、最新Win10ベースPE上ではエラーが出てバックアップもろともできない。新しいPEと相性悪いのだろうか？
12,13ではシステムクローンは不可能、ディスククローンは可能。WinPE作成可能なので、PEからならコピーOKになる。
13.5以上はダウンロード方式で、最新版強制。ディスククローンが不可能になっている。WinPEの作成は可能だがもちディスククローンは不可なので、クローン目的ではNG。
■ インストールしたうえで使う必要があるなら、Win10のバージョンが古ければ11.5でもいけるのか...？
■ PEからしか使わないなら13.0が最適だろうか
■ 基本機能でOKなら最新版で問題ない。

## AOMEI Backupper Standard
システムクローンは4の時点ですでに不可だった。WinPE作成は最新版6.9含めほぼすべてのバージョンで可能。
MBR→MBRの場合はシステムクローンが可能との情報はネット上にあるが私は正直よくわからず。
ディスククローン機能だが、このソフトの場合はPE上からの使用であろうともシステムを含むと不可能なバージョンもあるので注意。4.06(Builder2同封)や6.4までは可能。6.61でシステムを含むとディスククローンは不可だった(6.5は未検証)。データディスクならバージョン問わず可能。
また、5.3では後ろにスペースを残せたが、6.4では自動のみ。ただしどっちにしろ手動ができないので気にする違いではない。
■ システムクローンを行うならWinPE上で6.4までを使用。
■ 基本機能でOKなら最新版で問題ない。

## Macrium Reflect
現行版の8ですでにできることが多い。もちろんWinPEも作成可能。PE作成については他と異なり、割といろんな設定を行える(ベースのPEを指定することすら可能)。
（ただしPEにコピーするファイル一覧がよくわからないし、一部プログラム本体でしか展開できないファイルがあるため公式のプログラム以外でPEを組むのはかなり困難かと思われる。まぁほんのごく一部の人を除きどうでもいいでしょうが）
■ 使い方がちょいわかりにくいとこがある以外は有用

## EaseUS Partition Master
かなり以前からWinPE作成はできないので、今回は調査から外した。再起動時にクローンが行えるタイプかも？しれない。

## AOMEI Partition Assistant Standard
6.5(Builder2同封)含む7.1まではWinPE作成可能。
ディスクコピー可能だが、パーティション編集ツールという性質上システムのコピーは要再起動。
パーティション復元機能は6.5では見当たらなかったが、7.1にはあった。ただし7.5以降はない。
7.5以上ではPro以降の機能が多い。WinPE作成やパーティション復元など。もちろん最新版9.1でも同様。
■ 機能面なら7.1がお勧め
■ 基本機能だけなら最新版でもOK。

## MiniTool Partition Wizard
詳しいことは忘れたが、9.1がパーティション復元の最終版だった気がする。このバージョンはexFat未対応なのは注意。もちろん基本機能だけなら最新版で構わない。

## TrueImage for Crucial
長々と書いてきたが、CrucialのSSDなら最所からこれでいいと思う。WinPEも作成可能。

## 複数積みってできるの？
公式の手段では基本無理です。無理やりできたとしても今度は起動手段に戸惑います。（なので私は公式の方法に何のメリットがあるのか理解できません。）WinPtchXやWimBuilder2等ならできるはず。なおAOMEI Partition Assistantはシステム登録が不要でバイナリさえあれば究極USBメモリからでも動かせるかも。

#### で、複数積みって意味あるの？
バックアップツールの場合は1枚のディスクで複数のマシンを渡り歩いて復元を行うときは意味あるでしょう、がマニアックだなぁ。上に書いてきた通りクローン系の機能はバックアップ、パーティーションどちらのジャンルもカバーしていることが多いのでどちらかで行えれば十分ですね。
パーティーションツールの場合、詳しく調べてませんがフリー版で有効な機能が異なる可能性があるので、複数積んでしまうのも案外悪い選択ではないと思います。

## UEFI/BIOS, MBR/GPT
GPTはUEFI用(?)ではあるが、MBRとUEFIの組み合わせももちろん可能、なのでMBRでも通常はそんなに困ることはない。ただし可能ならばGPTにしておきたい。UEFI＆Win8以上ならGPTがいいのでは。
逆にOSがwin7以下 or/and レガシーBIOSならMBRの方が賢明。
UEFIはMBR,GPT両方対応。レガシーBIOSは起動はMBRのみ、データならOSが対応していればgptも可能。
USBHDD/SSD→GPTでいいがMBRも可。USBメモリの場合MBR推奨(XPとのやり取り含めて)。
<dt><dd>要素をグリッドに配置したい、IE11で！

&lt;dl>要素の項目を定義リスト風に整列して表示する例が、MDNのガイド &mdash; [CSS グリッドレイアウトでの自動配置](https://developer.mozilla.org/ja/docs/Web/CSS/CSS_Grid_Layout/Auto-placement_in_CSS_Grid_Layout)に載っています。各&lt;dt>要素にぶら下げる&lt;dd>要素の個数がバラバラでも対応できるので便利です。
![dl_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/75784070-bc90-489f-c543-4f4b8e27d60d.png)
このレイアウト、IE11でも表示できるでしょうか？
IE11の場合、CSSのgrid関連プロパティについてはベンダープレフィックス`-ms-`が必要になりますが、MDNのサンプルのCSSを単純にIE11用に書き換え、IE11で表示してみました。残念ながら（案の定？）下図のとおりレイアウトが崩れてしまいます。
![dl_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/0368e57f-77a7-911b-9932-626dec374816.png)
そこで今回は、このサンプルをIE11でも表示できるようにする方法のメモです。

まず、MDNのサンプルで使われているマークアップはこれです。

```html:html
<div class="wrapper">
   <dl>
       <dt>哺乳類</dt>
       <dd>猫</dd>
       <dd>犬</dd>
       <dd>鼠</dd>
       <dt>魚類</dt>
       <dd>グッピー</dd>
       <dt>鳥類</dt>
       <dd>ハクセキレイ</dd>
       <dd>フクロウ</dd>
   </dl>
</div>
```

次にCSS。装飾や書式を除いてグリッドレイアウトに関わるコードのみ示します。コードはとてもシンプルで、セレクターdtとddに`grid-column`を指定するだけで自動配置できるというのがポイントです。

```css:css
dl {
  display: grid;
  grid-template-columns: auto 1fr;
}
dt {
  grid-column: 1;
}
dd {
  grid-column: 2;
}
```

このCSSをIE11にも対応させてみましょう。こちらのブログ記事を参考にさせていただきました。

参考： [CSS GridをIE11、EDGEに対応させるために注意する点](https://www.itti.jp/web-design/css-grid/)

`grid-*`プロパティをベンダープレフィックス`-ms-`付きのものに書き換えます。

```css:css
dl {
  display: grid;
  display: -ms-grid;  /* IE11 */
  grid-template-columns: auto 1fr;
  -ms-grid-columns: auto 1fr; /* IE11 */
}
dt {
  grid-column: 1;
  -ms-grid-column: 1; /* IE11 */
}
dd {
  grid-column: 2;
  -ms-grid-column: 2; /* IE11 */
}
```

このCSSで一旦IE11に適用した状態が冒頭に示した画面キャプチャです。 &lt;dt>要素と&lt;dd>要素の配置先の列は正しいですが、全部１行目に表示が重なってしまいました。IE11の場合、アイテムの配置先となるグリッドセルの行番号もプロパティ`-ms-grid-row`で指定してやらないといけません。おまけに`-ms-grid-row`は`auto`値を認識しないようです。

[CSS Grid auto placement in IE/EDGE](https://stackoverflow.com/questions/45436398/css-grid-auto-placement-in-ie-edge)

ならば、HTMLのソースに対応させて「何番目のddは何行目に配置」という情報をもとにセレクターddを`:nth-of-type()`を使って必要な分だけ書き下すという方法も考えられます。しかし、IE11だけのためにそんなことするのは、元々のシンプルなCSSで書ける利点が台無しになりバカげています。

そこで、`-ms-grid-row`についてはJavaScriptから値を設定してやることにします。コードの最初にブラウザがIEかどうかをチェックし、IE以外の場合はそれ以降のコードを実行しないようにしてあります。ブラウザの判定には[UAParser.js](https://github.com/faisalman/ua-parser-js)を使用しました。


```javascript:javascript
function fixIEGrid() {
  // ブラウザ判定
  const parser = new UAParser();
  const ua = parser.getResult();
  if (ua.browser.name != 'IE') {
    return;
  }

  // for IE11
  const dl = document.querySelector('.wrapper dl');
  let row = 1;
  let el = dl.firstElementChild;
  while (el) {
    if (el.localName == 'dt') {
      el.style.msGridRow = row;
    } else if (el.localName == 'dd') {
      el.style.msGridRow = row++;
    }
    el = el.nextElementSibling;
  }
}

fixIEGrid();
```

結果、IE11でも定義リストのレイアウトを正しく表示できました。

![dl_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469745/4c0412c0-adfe-f1dd-08da-0eb4e638a59c.png)

完成したコードはこちら： https://codepen.io/kaz_hashimoto/pen/rNYqmVd
[備忘録]React Hooksって結局なんなの？！初心者なりにまとめてみた

# React Hooksって結局なんなの？！初心者なりにまとめてみた
## 前書き
どうも！エンジニア就活はもう終わりかけと聞いて一瞬絶望しかけたグッピーです！
いやー、インターン先の先輩に就活の相談をしていたのですが、
「エンジニア就活ってもう終わりかけだよね」っていわれ、
軽く絶望してましたw
だからといって早めに始められたかと聞かれると無理だったのでどうしようもないのであんまり気にしていないですね。(強がり)
と自分語りはここまでにして、今回はreactを使っていくに当たって絶対に使うhooksについて個人的にまとめていきます。

## hooksとは
reactのhooksとは2019年に追加された機能です。現在ではreactを使うに当たって、理解が必須の機能と言っても過言じゃないでしょう。

hooksを使うことでreactの関数型コンポーネントで状態をもつことやコンポーネントのライフサイクルに応じた処理を記述できます。今回は基本的なhooksのユースケースを紹介した後、カスタムフックについても解説していきたいと思います！また、今回は[ISID Teck blog](https://tech.isid.co.jp/entry/2021/12/13/React_Hooks_%E3%82%92%E7%90%86%E8%A7%A3%E3%81%97%E3%82%88%E3%81%86#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB
)様の記事を参考にしているので、詳しくはそちらを見るとわかりやすいと思います！

## 基本的なhooksの種類
まずはreactに標準搭載されていて、よく使われるhooksについて紹介していきます！主にいかが挙げられます。
・useState
・useEffect
・useContext
・useReducer
・useMemo
・useCallback

## 具体的な使用方法
### useState
useStateは関数型コンポーネントで状態を扱うためのフックです。
以下はuseStateを利用する場合の基本的なコードです。
```
const[state,setState]=useState<T>(initStateValue);
```
利用シーンはフォーム送信機能など利用者とインタラクティブにやり取りする値を保持する必要がある場合です！
カウント機能などを作るのにも使いますね

### useEffect
useEffectは関数型コンポーネントで副作用を実行するためのフックです。

・・・副作用ってなんやねん！って思う方もいると思います。外部データの取得やdomの手動での更新などの処理をreactでは副作用と呼ぶらしいです。知らなかった・・・

使い所としては、外部APIからリソースを取得したい場合などです。

### useContext
useContextはコンポーネント間で横断的に利用したい状態を管理するためのフックです。通常、コンポーネントでは状態をpropsを通して親から子に渡します。しかし、これが多重化していくと処理が遅くなったりと弊害が起きます。しかし、useContextを使うとpropsを通さずに一気に親から孫までデータを渡すことができ、処理が軽くなります。

ユースケースは認証情報の管理などが挙げられます。

### useReducer
アプリケーション開発を進めていくと処理が複雑になるにつれて、管理しなければならない状態が増えてきます。その場で発揮するのが、useReducerです。useReducerはuseStateよりも複雑な状態を管理するためのフックです。公式ドキュメントでは「useStateの代替品」として位置付けられています。
useReducerを使うユースケース
stateの状態管理に使う場合が多いです。僕のインターン先でも使ってましたね。

### useMemo
useMemoは関数の返り血をメモ化するフックです。メモ化はプログラムの最適化技法の一つで、計算結果を再利用するために保持して、再計算を防ぐ者です。そのため、useMemoは最適化のためのフックという位置付けです。
useMemoのユースケースは、配列を走査するショルが頻繁に必要な場合などに役立ちます。

### useCallback
useCallbackは関数をメモ化するフックです。最適化のためのフックという感じですね。





## カスタムフック
reactでは標準搭載されているhooks以外にも、自分でhooksを作って使ったりすることもできます！！
まあ、僕みたいな初心者は使わせていただくことだけを考えた方がいいですねw



## 用語紹介
ライフサイクル・・データの保持をいつまで行うか、などデータの受け渡しに関する期間などをライフサイクルと呼んでいる。

API⇨ある機能をバックエンド側で処理してくれるコード群のこと。削除機能や送信機能もAPIと言いますし、それらをまとめて一つのAPIとも言えます。

## 終わりに
なかなか難しいですね・・・
hooksを使いこなせてようやく一人前だと思うので、これからも頑張っていきたいですね。
ではまた！グッピーでした！


### 参考記事
https://tech.isid.co.jp/entry/2021/12/13/React_Hooks_%E3%82%92%E7%90%86%E8%A7%A3%E3%81%97%E3%82%88%E3%81%86#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB
【TypeScript入門 #7】InterfaceとTypeAliasの違い

# 概要

オンラインサロンIT_KINGDOMで、typescriptについて学んだことを備忘録としてメモしていきます。

# 学習内容
- Type Alias, Interfaceとは
- Type AliasとInterfaceの違い

# type alias, Interfaceとは
どちらも型の定義をするもの。

```typescript:Type Alias
type Foo = {
  a: number;
};

const foo: Foo = {
  a: 1,
};
```
```typescript:Interface
interface Foo {
  a: number;
}
const foo: Foo = {
  a: 1,
};

```

# Type AliasとInterfaceの違い

- 宣言できる型にちがいがある
 Interfaceでは宣言できるのはオブジェクトのみ。
Type Aliasではどんな型でも宣言できる。

- open-endedに準拠しているかどうか
interfaceでは同じ名前の型宣言をすることが可能。

```
// interfaceでは、open-endedに準拠するため、Fooを2回宣言してもエラーにならない（Type Aliasではエラーになる）
interface Foo {
  a: number;
}
interface Foo {
  b: number;
}
const foo: Foo = {
  a: 1,
  b: 2,
}
```

- 継承できるかどうか
Interfaceでは、`extends`を使って型の継承をすることができる。
Type Aliasで同じ機能を実現するには、`&`によるIntersection Typesを使う必要がある。

```typescript: interfaceによる継承
interface Foo {
  a: number;
}
interface Bar extends Foo {
  b: number;
}
const foo: Bar = {
  a: 1,
  b: 2,
};
````

```typescript: Type AliasによるIntersection Types
Type Foo = {
  a: number;
}
Type Bar =  Foo & {
  b: number;
}
const foo4: Bar = {
  a: 1,
  b: 2,
};
````

- プロパティのオーバーライドが可能か？
Type AliasのIntersection Typesでは、プロパティのオーバーライドが可能。
Interfaceの継承では、プロパティをオーバーライドするとエラーになる。

```typescript:Type Aliasでのプロパティaのオーバーライド
type Foo = {
  a: number;
}
// ここではエラーにならない
type Bar = Foo & {
  a: string;
}
const foo: Bar = {
  a: 1,
}
```

```typescript: Interfaceによるオーバーライド
interface Foo {
  a: number;
}
// ここでエラーになる
interface Bar extends Foo {
  a: string;
}
const foo: Bar = {
  a: 1,
}
```

- Mapped Typesが使えるかどうか
Type Aliasでは、Mapped Typesを使うことができる。

```typescript:Type AliasによるMapped Typesの使用例
type Animals = "dog" | "cat";

type Foo7 = {
  [key in Animals] : number;
}
const foo7: Foo7 = {
  dog:1,
  cat:2,
}
```

# 結論：Type AliasとInterfaceのどちらを使うと良いか
どちらを使っても良い（公式ドキュメントでもどちらでも良いと紹介されているため）。
どちらかといえばType Aliasがおすすめ。

# 参考サイト
[typescript documentation](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html)
Gyazoで撮った画像をQiitaの記事に貼り付ける（めたんこ簡単）

qiitaに記事を投稿する際、gyazoで撮った画像を使用したくて方法を調べたらめっちゃ簡単だった件。

# では早速
Gyazoで画像を撮って画像リンクへ移動する
[![Image from Gyazo](https://i.gyazo.com/33f67e3244246d0edcff78d013cbb0f4.png)](https://gyazo.com/33f67e3244246d0edcff78d013cbb0f4)

右上のメニューの`「シェア」`をクリックするとプルダウンでメニューが出てきます。
その中の`「マークダウンをコピー」`をクリック。

そのまま投稿したい記事に貼り付けるだけです！

めっちゃ簡単ですね＾＾
40 代おっさんLambdaの概要、料金、主な連携サービスを学ぶ

## 本記事ついて

本記事は プログラミング初学者の私が学習していく中でわからない単語や概要をなるべくわかりやすい様にまとめたものです。
もし誤りなどありましたらコメントにてお知らせいただけるとありがたいです。

## Lambda

### Lambdaとは

サーバーレスコンピューティングサービス
サーバーなしでコードを実行できるサービス

#### サポートしている言語

Java,Go,PowerShell,Node.js,C#,Python,Ruby

#### メリット

・基盤となるインフラに依存せずコードを実行
・イベントに応じてコードを実行する
・自動スケーリング
・エッジで実行可能

### 料金

リクエスト数と実行時間で決定

#### 無料枠

リクエスト数：100万件まで無料
実行時間：40万GB-秒まで無料

#### 課金

リクエスト数：100万件あたり0.20USD
実行時間：GB-秒あたり0.0000166667USD
（メモリ１GB割り当ての場合）

### lambdaに連携できるサービス

・Cognito：ウェブアプリケーションおよびモバイルアプリに素早く簡単にユーザーのサインアップ/サインインおよびアクセスコントロールの機能を追加できる

・API Gateway:デベロッパーは規模にかかわらず簡単に API の作成、公開、保守、モニタリング、保護を行える

・Kinesis：ストリーミングデータをリアルタイムで収集、処理、分析することが簡単になるため、インサイトを適時に取得して新しい情報に迅速に対応できる

・DynamoDB：ハイパフォーマンスなアプリケーションをあらゆる規模で実行するために設計された、フルマネージド、サーバーレスの key-value NoSQL データベース

・SQS：フルマネージド型のメッセージキューイングサービス

・SNS:アプリケーション対アプリケーション（A2A）間と、アプリケーション対個人（A2P）間の両方の通信に使用できる、フルマネージド型メッセージングサービス

・S3：スケーラビリティ、データ可用性、セキュリティ、およびパフォーマンスを提供するオブジェクトストレージサービス

・CloudFront：ユーザーへの静的および動的なウェブコンテン(.html、.css、.js、イメージファイルなど) の配信を高速化するウェブサービス

・EventBridge：アプリケーションをさまざまなソースからのデータに接続するために使用できるサーバーレスのイベントバスサービス

・CloudWatchLogs：使用中のすべてのシステム、アプリケーション、AWS のサービスからのログを、スケーラビリティに優れた 1 つのサービスで一元管理することができる

## 最後に

またこの記事は AWS 初学者を導く体系的な動画学習サービス「AWS CloudTech」の課題カリキュラムで作成しました。
<https://kws-cloud-tech.com/>
EnvaderでLinuxコマンドを学ぶ第1回(cd/ls/cat編)


## この記事の内容
はじめましてa-min3150です。エンジニアへの転職を目標に学習中です。
アウトプットのためEnvaderで学習したこと、ハマったことなどを書いていきたいと思います。



<a id="Linux"></a>
## Linuxコマンドとは
LinuxOSで使うことのできるコマンドで主にサーバーのシステムを操作するのにCUI(いわゆる黒い画面)での操作が必要となるため、サーバー管理やインフラ構築をするエンジニアは知っておかなければならないコマンドとなります。

<a id="output"></a>
## 今回の学習アウトプットは
Linuxコマンド(cd/ls/cat)についてです。

第2回(pwd/rm/mkdir/rmdir編)は[こちら](https://qiita.com/a-min3150/items/deb9f1de7ebb2b2ac361)
第3回(mv/cp編)は[こちら](https://qiita.com/a-min3150/items/9458e8ee450966eb749f)
<a id="before"></a>
## 知っておきたいディレクトリ名称


| 名称　　| 説明 |
|:-:|:-:|
| ディレクトリ | LinuxやMacOSなどのUnix系OSでは、フォルダの事をディレクトリと呼びます。 
| カレントディレクトリ |現在作業しているディレクトリを指します。
| ルートディレクトリ| Unix系OSのファイルシステムにおける一番上の階層のディレクトリを指します。
| ホームディレクトリ |ユーザーがログインした時に最初に開くディレクトリを指します。

引用元:https://envader.plus/course/1/scenario/1001

<a id="cd"></a>
## cdコマンドとは
cd は、ディレクトリ間を移動するのに使用するコマンドです。
現在作業をしているディレクトリ（カレントディレクトリ）から、別のディレクトリに移動するときに使います。

基本的な使い方
```
$ cd [オプション] ディレクトリ名
    *[]は省略可能な引数
```

cdコマンドの利用例
```
$ cd test/  # testディレクトリに移動
$ cd /   # ルートディレクトリに移動
$ cd ..  # カレントディレクトリから一つ上の階層へ移動
$ cd ~   # ホームディレクトリに移動
```
<a id="ls"></a>
## lsコマンドとは
ls は、カレントディレクトリの中にあるファイルやディレクトリなどを確認するために使用するコマンドです。
```
$ ls [オプション] ディレクトリ名
    *[]は省略可能な引数
```
よく利用するオプション例

| オプション| 説明|
|:---:|:---:|
| -a | 隠しファイルを含む全てのファイルを表示する |
| -l | 種類、タイムスタンプなどのファイルの詳細を表示する|


<a id="cat"></a>
## catコマンドとは
cat はファイルの中身を表示させるコマンド

使い方
```
$ cat [オプション] ファイル名 ファイル名 ...
    *[]は省略可能な引数
```
catコマンドの利用例
```
$ cat example.txt # example.txtの中身を表示する
```

```
複数のファイルを指定して連結して表示させる
$ cat example1.txt example2.txt # example1.txtとexample2.txtの中身が連結されて表示される
$ cat example1.txt example2.txt > example3.txt
# example1.txtとexample2.txtの中身を連結させて、新しくexample3.txtを作成する。
```
<a id="try"></a>

## 実際にやってみる(GIF画像)
![ls-cd-cat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1709092/100d9502-c148-cb42-dc55-d54beacd3328.gif)

概要を話すと、
①```ls```でカレントディレクトリでのファイル一覧を表示される。
GIF画像では ```~/```ホームディレクトリ内のDesktop Documentが表示されている
②```ls```のオプションを使ってみる
　　```ls -a```で隠しファイルが表示される。
　　```ls -l```でファイル詳細が表示される。
③```cd```でディレクトリ間を移動する。
④```cat```を使って「ファイル表示」「結合して表示」「結合したものを新たなファイルとして作成」をやっています。

<a id="matome"></a>
## まとめ
今回はLinuxコマンド(cd/ls/cat)の使い方についての説明でした。
GIF画像が見にくいので引用元サイトなどで実際に手を動かしてやってみてください。

次回は[EnvaderでLinuxコマンドを学ぶ②(pwd/rm/mkdir/rmdir編)](https://qiita.com/a-min3150/items/deb9f1de7ebb2b2ac361)についてです。

<a id="link"></a>
## 引用サイト

Envader(エンベーダー):https://envader.plus/
コース一覧:https://envader.plus/course
Linux基礎コース:https://envader.plus/course/1
コントローラの生成と削除 【Ruby on Rails】

## コントローラの生成
コントローラ名「Static Pages」を作る際に、表記をキャメルケースの`StaticPages`とした場合、以下のコマンドによりコントローラが生成できる。このタイミングでアクションを作成したい場合は、続けて半角スペースを空けて記載する。（今回は、homeとhelpアクションを作る）
```
$ rails g controller StaticPages home help
```
## コントローラの削除
このとき、「static_pages_controller.rb」というコントローラファイルが作成されるだけではなく、これに関連するファイルが大量に生成される。また、既存のファイルに対してもコードが変更される。
例えば、`rails generate`を実行するとルーティングの`routes.rb`ファイルも自動的に変更される。

このようなときは、`rails destroy`というコマンドを実行することで、元に戻すことができる。
例えば、`rails g controller StaticPages home help`を実行したあとに、これを取り消して元に戻したい場合は、以下のコマンドを実行する
```
$ rails destroy controller StaticPages home help
```
pushしてからrebaseはダメ！

## あるある

自分で作成したブランチで作業している間に開発ブランチの変更が先に進み、自分のブランチは古いままというとき、何気に`git rebase main`とか実行したくなりますが、ちょっと待ちましょう。

本流のブランチの変更を自分の作業ブランチに取り込むときには、rebaseとmergeの2つの方法があり、使い分けるのが望ましいです。

## rebaseとmerge、そもそもどう違うの？

よく見かけるのと同じ図です。
originはgitサーバー上にあるブランチ、localは手元で作業するブランチとします。

### rebase

rebaseは図のように、ブランチの根っこをすげ替える動かし方をします。
コミットログが図の上の状態の時、localブランチをチェックアウトした状態で`git rebase origin`を実行すると、コミットログは図の下のようになります。

![rebase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230005/8a2a228f-78bb-9e02-5334-b7e68bdcc82e.png)

もともとoriginの左から2番目のコミットから枝分かれを始めたところを、rebaseを行うことによってoriginの最新のコミットから枝分かれしたように書き換えられます。

#### rebaseの注意点

__rebaseはコミットを移動させるのではなく、前のコミットを消して新たに同じ内容のコミットをつくる__

この図では、あたかもlocalブランチのコミットをoriginブランチの右端にそっくりそのまま移動したように見えますが、実際は違います。

これはrebaseの内部操作に由来します。rebaseコマンドを叩くと、__rebaseする前のコミット内容をコピーし、新たにコミットを作成__ しています。同じ内容だけど、別のコミットになってしまうのです。

![unsafe_rebase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230005/c72d0b51-1336-be1e-76ae-989d253cc729.png)

pushしたあとrebaseし、さらにpushするときは`-f`オプションをつけて実行するのはこれが理由で、同じ内容でも前のコミットが別物になっているため、無理矢理上書きしてあげないとpushできません。

上書きするので、それまでに行われていた変更が失われる可能性があったり、他の人がpullしたときにmergeする必要が出てきたりと、push後にrebaseするのはデメリットしかありません。

また、rebaseはrebaseしたことを記録することができないのも注意です。

### merge

それに対してmergeは、rebaseのように根っこをすげ替えることはせず、新たにコミットを作成してmainの変更を取り込みます（コミットマージ）。
図でいうと、localブランチをcheckoutした状態で`git merge origin`を実行します。

![merge.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230005/b7ac6739-9544-cf9f-4b48-3f95b74d763a.png)

mergeではrebaseのように破壊的な変更が行われることはなく、mergeしたことも記録することができるため、安全にmainの変更を取り込むことができます。

ただ、rebaseとは違って変更を取り込んだことが記録されるため、頻繁に行うとマージの履歴がたくさんできてしまうのが気になるかもしれません。

## 結局どう使い分ければいいの？

Pull Requestベースのコードレビューをやっている前提で書きますが、

__pushするまではrebase、pushしたあとはmerge__

です。

### pushする前

push前であれば、rebase、merge両方できます。両方できるとなると、履歴がスッキリするrebaseするほうがいいでしょう。自分の作業ブランチで`git rebase <本流のブランチ名（develop/master/mainなど）>`を叩けば変更を取り込めます。

また、rebaseはコミットをまとめることもできるため、レビュー前にコミットをまとめてスッキリさせておくとレビュワーの負担が減ります。（僕はこれをやるのを忘れてpushしてしまうことが多いのですが。いけませんね。）

### push後

すでに述べた通り、push後はmerge一択です。rebaseしてはいけません。

## 最後に

__pushするまではrebase、pushしたあとはmerge__

です！

## 参考

https://www.atlassian.com/ja/git/tutorials/merging-vs-rebasing

https://www.slideshare.net/kotas/git-15276118
【Excel】自分が知らなかった関数の一覧

## 自分が知らなかった関数をリスト化するだけの記事です

* [「できるネット」](<https://dekiru.net/article/4429/>)さんによると、Excelには468個もの関数が存在するらしい（※2021年4月の記事）
*  自分の知らない & 便利そうな関数をリスト化して、役立てるのが目的。

|関数名|機能の概略|形式|使用例|使用例の戻り値|
|:-|:-|:-|:-|:-|
|QUOTIENT関数|分子を分母で割った際の整数商を得る|=QUOTIENT(分子,分母)|=QUOTIENT(3,2)|1|
|SIGN関数|数値の正負を表す戻り値を得る|=SIGN(数値)|=SIGN(3)|1|
|DATESTRING関数||=DATESTRING(シリアル値)|=DATESTRING("2022/04/01")|令和04年04月01日|
|NUMBERSTRING関数|数値から漢数字を得る|=NUMBERSTRING(数値,形式)|=NUMBERSTRING(3,2)|参|
|PROPER関数|||
|REPT関数|指定した回数だけ繰り返した文字列を得る|=REPT(文字列,繰り返し回数)|=REPT("★",3)|★★★|
|FREQUENCY関数|区間に含まれる値の個数を求める|
|EXACT関数|文字列が等しいか調べる|
|DELTA関数|数値が等しいか調べる|
|MEDIAN関数|数値の中央値を求める|
|BASE関数|10進数からn進数を得る||||
|CONVERT関数|単位を変換した数値を得る|
|SHEET関数/SHEETS関数|ワークシートの番号/数を得る|=SHEET([値]/[参照])|=SHEET()|2|

## 補足
【基本情報技術者試験】LRUとLFUの違い

# LRUとは
Least Recently Usedの略称で、置き換え対象の中で最も長い時間参照されていないものを置き換え対象とするアルゴリズムです。
この置き換えアルゴリズムは、「最近使用されたページは近い将来に再度参照される可能性が高く、逆に長い間参照されていないページは今後も参照される可能性が低い」ということを根拠としていて、キャッシュメモリや仮想記憶におけるデータの置き換えを決定するアルゴリズムとして使われています。


# LFUとは
Least Frequently Usedの略称で、置き換え対象の中で最も参照回数の少ないページを置き換えるアルゴリズムです。
HTTPの基本的な操作

## HTTPメソッドの基本
HTTP（HyperText Transfer Protocol）には4つの基本的な操作があり、それぞれ　`GET`、`POST`、`PATCH`、 `DELETE`という4つの動詞に対応づけられている。クライアント（GoogleChromeなどのブラウザ）とサーバー（ApacheやNginxなどのWebサーバー）は、この4つの基本操舵をお互いに認識できるようになっている。

### GET：Web上のデータを読み取る
GETは最も頻繁に使われるHTTPリクエストで、主に**Web上のデータを読み取る**ときに使われる。
ブラウザは、指定されたURLを開くたびに、GETリクエストをサーバーに送信する。
### POST：フォームに入力した値をサーバーに送る
POSTはGETの次によく使われるリクエスト。**ページ上のフォームに入力した値を、ブラウザからサーバーに送信する**ときに使われる。
例えば、ユーザー登録フォームで新しいユーザーを作成するときは、POSTリクエストを送信する。
### PATCHとDELETE：サーバー上の何かを更新したり削除する
この2つの操作はブラウザがネイティブでは送信しないため、GET、POSTほどは使われない。
しかし、Ruby on Railsなどの多くのWebフレームワークは、ブラウザがこれらの操作のリクエストを送信しているかのように見せかける技術（偽装）を駆使して、PATCHとDELETEという操作を実現している。
【GitHub】GitHub Actionsで独自のActionを定義する

## はじめに
最近、GitHub ActionsのWorkflowを構築するお仕事をしていたので、そこで発見したTipsについて書きます！
『**同一リポジトリ内で同じActionを呼びたい**』時に便利です！

## Node.jsのcomposite action
`composite action` ･･･ ユーザーが独自に定義したAction
```yml:.github/workflow/node/action.yml
name: my-actions

runs:
  using: 'composite'
  steps:
    - name: set up Node.js
      uses: actions/setup-node@v2
      with:
        node-version: '14'
        cache: 'npm' # or 'yarn'
        cache-dependency-path: app/node/package-lock.json
```



#### !!!注意!!!
> The metadata filename must be either action.yml or action.yaml. 

ファイル名は`action.yml`または`action.yaml`でないといけないです！

> runs.using
Required You must set this value to 'composite'.

独自でAcitonsを定義す時には、`usign: composite`を付与しないといけないです！

## 呼び出し元のActions
```yml:.github/workflows/test.yml
name: Test

on:
  push:

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - uses: ./.github/actions/node # 👈
```

ディレクトリを指定すると、呼び出すことができます🙌


## 備考
もうちょっと踏み込んだことがわかったら、追記します🙇‍♂️

## 公式
[composite action](https://docs.github.com/ja/actions/creating-actions/creating-a-composite-action)
[Metadata syntax for GitHub Actions](https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions)
vscodeのplantumlのプラグインでcannot find graphvizで描画できない

## エラー画像

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/561891/5e762336-ceb8-4b59-ea98-9d7168a83d94.png">

## 解消法

brewにgraphvizがあったので、以下コマンドにて解消しました。

```
brew install graphviz
```
DP解説動画　コード全文　EDPC　D問題　#AtCoder

https://www.youtube.com/watch?v=gVJ16ThsJYs

動画『【ゆっくり解説】DP(動的計画法)解説 EDPC D 【競技プログラミング】』で使用しているコード全文です。

https://atcoder.jp/contests/dp/tasks/dp_d

```python:
# 入力の受け取り
N,W=map(int, input().split())

# (1)表を作る
dp=[[0]*(W+1) for i in range(N+1)]

# (3)表の小さい方から答えにたどり着くまで埋める
# i=1~N
for i in range(1,N+1):
    # i番目の品物の重さ,価値
    wi,vi=map(int, input().split())

    # w=0~W
    for w in range(W+1):
        # w-wiがマイナスなら
        if w-wi<0:
            # i番目の品物を入れない
            dp[i][w]=dp[i-1][w]
        # 0≤w-wiなら
        else:
            # i番目の品物を入れない
            # i番目の品物を入れる
            # どちらか大きい方
            dp[i][w]=max(dp[i-1][w],dp[i-1][w-wi]+vi)

# (4)答えを出力する
print(dp[N][W])
```
Junitを使用した簡易テスト方法


ローカル実行確認ができない状況でロジックだけ確認したいとき。

## ①テストクラスを作成

配置場所は、テスト用のビルドパス・ソースフォルダーがあれば
その配下のどこか好きなpackageに。

```
package test;
import org.junit.Test;

public class SampleTest {

    @Test
    public void test() {
　　　　// ここに処理を書く
        System.out.println("Test");
    }
}
```

## ②JUnit実行

あとは処理を書いてJUnit実行すればコンソールに出力される。
モジュールについてまとめてみた

# module - 複数のクラスで使用する部品

## モジュールを作る
モジュールの定義は下記のようにして行う。
```ruby
module ModuleName
end
```
クラスの記述と似ているがインスタンスを作ることはできなず、
主にメソッドを複数クラスで共同利用するための部品として使用する。
モジュール内ではメソッドの他に定数やクラス、モジュールの定義が可能。

## メソッドを定義
例えばUserクラスやAnimalクラスが共通で使える`introduce`メソッドを用意してみる。
```ruby
module Introduce
  def introduce
    puts "私は#{@name}です"
  end
end
```

## include - モジュールをクラスで使用する
まずはUserクラスとAnimalクラスを作ります
```ruby
class User
  def initialize(name)
    @name = name
  end
end

class Animal
  def initialize(name)
    @name = name
  end
end
```
クラス内でモジュールを使用するには`include`を使用して、
引数に使用したいモジュール名を指定します。
`include`は何度でも呼べるため1つのクラス内で複数のモジュールが使用可能。

```ruby
class User
  include Introduce
  def initialize(name)
    @name = name
  end
end

class Animal
  include Introduce
  def initialize(name)
    @name = name
  end
end

user = User.new("tarou")
user.introduce

cat = Animal.new("猫")
cat.introduce
```

```bash
私はyumです
私は猫です
```
`include`で取り込んだモジュールはクラスのインスタンスメソッドとして利用できる。
そのため呼び出しの際のレシーバーはインスタンスとなる。

## extend - モジュールをクラスメソッドとして利用する
`extend`を使用した場合はモジュールメソッドがクラスメソッドとして定義される。

```ruby
module Greeting
  def hello
    puts "こんにちは"
  end
end

class User
  extend Greeting
  def initialize(name)
    @name = name
  end
end

class Animal
  extend Greeting
  def initialize(name)
    @name = name
  end
end

User.hello
Animal.hello
```

```bash
こんにちは
こんにちは
```

## クラスメソッド

モジュールにはクラス同様にクラスメソッドを定義することができる。
呼び出し方法もクラスメソッドと同様。
```ruby
module Greeting
 def introduce
  puts "こんにちは"
 end

 def self.info
  "挨拶を行うモジュールです"
 end
end

Greeting.info
```
```bash
挨拶を行うモジュールです
```

クラスメソッドが複数行になる場合もクラス同様に`class << self` `end`内に記述すればOK。

```ruby
module Greeting
  def hello
    puts "こんにちは"
  end

  class << self
    def info
      puts "挨拶を行うモジュールです"
    end

    def english
      puts "Hello"
    end
  end
end

Greeting.info
Greeting.english
```

```bash
挨拶を行うモジュールです
Hello
```

## 定数
モジュール内には定数を用意しておくことも可能。
定数の場合は呼び出し時が異なり、`モジュール名::定数`で使用する。

```ruby
module Greeting
 #何も思い浮かばず...Greetingの文字数としてCharsにしてみた。
 Chars = 8
end

puts Greeting::Chars
```

```bash
8
```

## 組み込みモジュール
Rubyが既に用意してくれているモジュールもいくつかあります。
よく使うもので`Math`や、Array、Hashクラス内で使用している`Enumerable`モジュールなど。

```ruby:Math
# 円周率を保持した定数PI
puts Math::PI
# cosinを計算する際に使用するcosメソッド
puts Math.cos(Math::PI)
```
```bash
3.141592653589793
-1.0
```

## 名前空間
開発が大規模になってくると同じクラス名を使用したい場面などが出てくる。
そんな時に`module`を名前空間として使用することでクラス名の重複を避けることができる。

```ruby
module StarBucks
 class Coffee
  def self.info
   puts "アメリカ発祥のコーヒーショップです"
  end
 end
end

module Doutor
 class Coffee
  def self.info
   puts "日本発祥のコーヒーショップです"
  end
 end
end

StarBucks::Coffee.info
Doutor::Coffee.info
```
```bash
アメリカ発祥のコーヒーショップです
日本発祥のコーヒーショップです
```
上記のようにモジュール内にクラスを定義して、
呼び出す際には`module名::クラス名`とする。
名前空間を使用することでCoffeeというクラス名を複数使用できるようになる。

ちなみにプログラムで一番外側（トップレベル）に書かれているモジュールやクラスは先頭に`::`をつけて、
`::モジュール名` `::クラス名`のように呼び出すこともできる。

```ruby
::StarBucks::Coffee.info
::Doutor::Coffee.info
```
```bash
アメリカ発祥のコーヒーショップです
日本発祥のコーヒーショップです
```

## 最後に
モジュールはよく使うメソッドを部品として一つの箱に用意しておくイメージ。
継承はしたくないけど他のクラスでも使えそうだな...
そんな時にモジュールとして切り出しておくと余計な記述を減らせたり、読みやすいコードがかけるのではないでしょうか。
OTP認証を有効にした際のgemリリースで、GEM_HOST_OTP_CODE環境変数を見てくれなかった原因

## はじめに

https://qiita.com/ohakutsu/items/14c76b0ab3ec626e842d

↑ の記事で GitHub Actions を使って Gem のリリースをやったが、OTP 認証を有効にした場合の Gem のリリースがうまくいっていなかった。

その原因がわかったので、記事にする。

## 原因

原因は`gem`のバージョンに問題があった。
`gem`のバージョンが`3.2.22`以降でなければ、`GEM_HOST_OTP_CODE`の環境変数を見てくれない。

> https://github.com/rubygems/rubygems/blob/master/CHANGELOG.md#3222--2021-07-06
>
> #### 3.2.22 / 2021-07-06
>
> ##### Enhancements:
>
> - Allow setting `--otp` via `GEM_HOST_OTP_CODE`. Pull request #4697 by
>   CGA1123

https://qiita.com/ohakutsu/items/14c76b0ab3ec626e842d の記事では、[ruby/setup-ruby](https://github.com/ruby/setup-ruby) action を使って Ruby のセットアップをしていたのだが、`ruby-version: 3.0.0`では`gem`のバージョンが`3.2.3`であった。

```
$ gem --version

3.2.3
```

そのため、`gem`のバージョンが`3.2.22`以降になるように`ruby-version: 3.1.1`にしたところ無事デプロイができた。

参考として GitHub Actions の workflow を貼っておく。

Secrets に`RUBYGEMS_API_KEY`として API Key を登録しておき、リリースの際は OTP コードを入力し手動でリリースを行う workflow。

```.github/workflows/release.yml
name: Release gem

on:
  workflow_dispatch:
    inputs:
      rubygems-otp-code:
        description: RubyGems OTP code
        required: true

permissions:
  contents: write

jobs:
  release-gem:
    runs-on: ubuntu-latest
    env:
      GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_API_KEY }}
      GEM_HOST_OTP_CODE: ${{ github.event.inputs.rubygems-otp-code }}
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0 # bundle exec rake release で git tag を見るため、tagをfetchするようにしている
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.1.1
      - name: Bundle install
        run: bundle install
      - name: Setup gitconfig # bundle exec rake release でgit tagが打たれていない場合、タグを打ってpushしてくれるため用意している
        run: |
          git config --global user.email "YOUR_EMAIL"
          git config --global user.name "${{ github.actor }}"
      - name: Release gem
        run: bundle exec rake release
```
String.formatを使って空白以外の文字列埋め

簡単に見つからなかったのでメモ。
これ以外にいい方法があれば教えてください。
# **末尾に「#」を付与し12桁にしたい場合**

```
String.format("%-12s", "Test").replace(" ", "#");
```


いったん空白をセットし、
replaceメソッドで空白⇒"#"に書き換えています。

String.formatで直接"#"埋めすることができなかったです。
エスケープ「%」足しても駄目だったのでこちらの方法を使用しました。
PowerApps　編集フォームで送信したレコードをコレクションに登録する

# やりたいこと
* 編集フォームからSubmitしたレコードをコレクションから確認したい


# 結論
```:powerapps
ClearCollect(collection_name,Form1.LastSubmit)
```
関数clearcollectは引数1のコレクションが存在する場合はそのコレクションを初期化して引数2を書き込み、
同じ名前のコレクションが存在しない場合は引数1をコレクション名として登録します。

引数1("collection_name")は、コレクション名です。お好きなコレクション名をドウゾ。


引数2("Form1.LastSubmit")の、Form1は送信したデータ元のフォーム名を指定します。



# さいごに
今回はコレクションに追加しましたが、他のデータベースに追加したいなんて状況も少なくないと思います。
次回記事はコレクションをデータベース(Dataverse)に書き込む方法を書こうと思います。
:)
pythonでのプロジェクト作成に関するツールの使い方まとめ

pythonでプロジェクトを行うにあたってよく用いられているpyenv, poetry, mypy等のツールを利用する際のコマンドをまとめました。

この記事で述べた各種ツールを用いたテンプレートプロジェクトをgithubで公開しています。

https://github.com/eycjur/python_project_template

# pyenv
python自体のバージョン管理ツール

## インストール
```bash
brew install pyenv
echo '
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv init -)"
' >> ~/.zshrc
source ~/.zshrc
```

## pythonのインストール
```bash
# インストールできるバージョンの一覧
pyenv install --list
pyenv install 3.10.1
pyenv global 3.10.1
# インストールされているバージョンの確認
pyenv versions
python -V
```

# poetry
pythonのパッケージ管理ツール

## インストール
```bash
curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python -
# パスが通っていない場合は`source $HOME/.poetry/bin`を実行してください

# プロジェクト内に仮想環境を作成
poetry config virtualenvs.in-project true
poetry config --list
```

## プロジェクト作成
```bash
# 新規プロジェクト
poetry new my_project
# pyproject.tomlやpoetry.lockがある場合
poetry install
poetry install -E <extra-name>
```

## パッケージの追加
```bash
# 検索すると`pip install <package>`で出てくるものをを以下に置き換える
poetry add <package>
poetry add <package>==<version>
poetry add <package> --dev

# 環境に依存するパッケージを入れる
poetry add --optional <package>
# extrasを記載
#     [tool.poetry.extras]
#     <extra-name> = ["<package>"]
# 実際にインストラクターするには次が必要
poetry update
poetry install -extras <extra-name>

# アップデート
poetry update <package>
poetry self update

# 削除
poetry remove <package>
```

## その他
```bash
# インストールされているパッケージ一覧
poetry show

# 仮想環境に入る
poetry shell

# 仮想環境内で各種コマンドの実行
poetry run <command>
```

# pytest
pythonのテストツール

## 実行
```bash
poetry run pytest
make test
# 特定ファイルのみ
poetry run pytest tests/test_<file_name>.py
```

# リンター

- flake8  
pythonのコード規約チェックツール
- black  
pythonのフォーマッター
- isort  
pythonのimportのソートツール
- mypy  
pythonの型チェックツール

## 実行
```bash
# まとめて実行
make lint
make lint target=<target>
# 個別に実行
poetry run <tool> .
make <tool>
# 特定ファイルのみ
poetry run <tool> src/<file_name>.py
```

# jupyter notebook
対話型のpython実行環境

## notebookを開く
vscodeでipynbファイルを開くと実行される

ブラウザで開く場合
```bash
make jupyter
```

## git管理
notebook形式ではdiffが見づらいので、pyファイルをgit管理する

```bash
# notebookとpyファイルを同期
make sync-notebook
# pyからnotebookを作成
poetry run jupytext --to notebook notebook/<file_name>.py
```

# sphinx
pythonのドキュメント作成ツール  
docstringを自動で読み取ってhtml形式に変換する  
手動で作成するファイルはdocs/内に配置

## 実行
```bash
make sphinx
make sphinx-reflesh
```

## 出力
docs/_build/以下にhtmlが出力される

# typer
pythonのCLI作成ツール  
src/cli.pyで利用

## 実行
```bash
make cli target=<command>
poetry run python -m src <command>
# ヘルプを表示
make cli target=--help
poetry run python -m src --help
poetry run python -m src <command> --help
```

# profile
実行時間を計測してボトルネックを探す

## 実行
```bash
poetry run python -m cProfile -o logs/profile.stats -m src <command>
poetry run snakeviz ./logs/profile.stats
```
ブラウザに戻ってきたことを検知する

# はじめに
ブラウザからスマホアプリに遷移した後、アプリから再度ブラウザ（特定のページ）に戻ってきた時に処理を行うという場面があったのでその際の解決方法について記録します。


# PageVisibilityAPI
調べてみたところ、`PageVisibilityAPI`を使うことで検知できそうなことがわかりました。
Page Visibility APIについては以下通りです。

> タブを使って閲覧している場合、どのウェブページもバックグラウンドにあってユーザーから見えていない場合があります。 Page Visibility API では、現在ページが見えているかどうかを調べる機能とともに、文書が表示されたり非表示になったりした時を監視することができるイベントを提供します。
引用元:[Page Visibility API - MDN Web Docs](https://developer.mozilla.org/ja/docs/Web/API/Page_Visibility_API)

PageVisibilityAPIによりウィンドウが最小化されたり、他のタブに切り替えた時にvisibilitychangeイベントを送信し、ページ変化を検知します。

こちらがPageVisibilityAPIを用いたデモサイトです。
このデモサイトの動画再生中に、別タブを開いたりブラウザを最小化するとそれを検知し動画は一時停止状態になります。また、デモサイトのタブに戻るとそれを検知し動画を再生します。

http://daniemon.com/tech/webapps/page-visibility/



# 実装

```javascript
if (document.hidden !== undefined) {
  document.addEventListener('visibilitychange', onVisibilityChange);
} else if (document.webkitHidden !== undefined) {
  document.addEventListener('webkitvisibilitychange', onWebkitVisibilityChange);
}
function onVisibilityChange() {
   if (!document.hidden) {
    //ブラウザに戻ってきた際に行いたい処理
  }
}

function onWebkitVisibilityChange() {
  if (!document.webkitHidden) {
    //ブラウザに戻ってきた際に行いたい処理
  }
}

```

こちらの記事を参考にしました。

https://qiita.com/kwst/items/cb099e175cf414043332


# 不明点について調べる
## document.hiddenとは？

> Document.hidden は読み取り専用のプロパティで、ページが非表示になっているとみられるかどうかを示す論理値を返します。
引用元：[Document.hidden - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Document/hidden)

ページがユーザーから隠された状態である場合`true`を、そうではない場合は`false`を返します。

## document.webkitHiddenとは？
おそらくdocument.hiddenのprefixがついたものだと思います。
ブラウザーの対応表を見ると一部ブラウザの対象バージョンについては、`Implemented with the vendor prefix: webkit`と記載があるのでこのように実装しています。

https://developer.mozilla.org/ja/docs/Web/API/Document/hidden

# 参考

https://developer.mozilla.org/ja/docs/Web/API/Page_Visibility_API

https://developer.mozilla.org/ja/docs/Web/API/Document/hidden
Rubyの依存関係を管理する

# はじめに
ここではRubyでアプリケーションを開発していくにあたってより柔軟な設計をしたいと言う方向けの記事を書いていきたいと思います。
なお、**オブジェクト指向設計実績ガイド**の第3章に記載されている内容です。

## 概要
開発する上でクラス間の依存が強ければ強いほど要件変更に対して大幅な修正が必要になります。次のコードを見てください。
```Ruby:main.rb
class A
    attr_reader :a_one, :a_second
    def initialize(a_one,a_second)
        @a_one = a_one
        @a_second = a_second
    end

    def method_a
        a_one * B.new(a_one,a_second).method_b
    end
end

class B
    attr_reader :b_one, :b_second
    def initialize(b_one,b_second)
        @b_one = b_one
        @b_second = b_second
    end

    def method_b
        b_one + b_second
    end
end

puts A.new(1,3).method_a
```

依存関係にある状態とは以下状態を指します。
- Aクラスの内部に他クラス(Bクラス)が存在していることを記述している
- Aクラスの内部でBクラスのインスタンスがbクラス内で定義されているメソッドBを呼び出そうとしている


これらの依存関係をできる限り解消していく。

## 疎結合的なコードをかく
クラス間での依存が多ければ多いほど二つのクラスは一つのクラスとして見なされる傾向が高まる。これらの依存関係を少しづつ解消していきより柔軟なアプリケーションづくりの一助にしていく。

まず一つ目の課題としてmethod_aがBクラスのmethod_bを明示的に参照している依存についてだが、もしBクラスの名前をBからCに変更したとする。その場合、Aクラス内のmethod_aの記述も少なからず変更する必要が出てくる。この問題を解消すると以下のコードになる。

```Ruby:main.rb
class A
    attr_reader :a_one, :a_second,:b_class
    def initialize(a_one,a_second,b_class)
        @a_one = a_one
        @a_second = a_second
        @b_class = b_class
    end

    def method_a
        #途方もなく長い処理
        a_one * fromBclassMethod
        #途方もなく長い処理
    end

        #カプセル化することで外部クラスへの依存が一目で管理できる
    def fromBclassMethod
        b_class.method_b
    end

end
```

Bクラスのインスタンス生成をAクラスの外部に配置することでAクラスは引数b_classにmethod_bを持っているオブジェクトであればどのような名前のクラスから生成されたインスタンスであろうが受け入れることができるようになったと言うわけです。

また、b_class.method_bを専用のメソッド内にカプセル化することで今後のmethod_aに対する変更も容易にすることができます。

### 終わり
GmailをメールサーバーとしてLaravelからメールを送信する設定

## 内容
Laravelからメールを送信する際、メールサーバーを利用して送信するが、テスト環境など会社のメールサーバーは制約があったり、個人開発レベルでメールを送信する場合にはGmailをメールサーバーとしてメールを送信することもできる。
本記事ではその方法をまとめる。

## 目次
- [Googleアカウントの設定](#Googleアカウントの設定)
- [Laravelアプリの.envを編集](#Laravelアプリの.envを編集)

## Googleアカウントの設定

[Googleアカウントトップ](google.com/account/about/?hl=ja)
- アカウントの設定画面へ入る。（アカウントが必要であれば作成）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/f4f5a972-86bb-6f75-5088-ce106d38b807.png)

- 左メニューのセキュリティボタン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/b83dab68-d330-411e-2cf8-044c2aa6ce8a.png)

- 「２段階認証プロセス」から手順に沿って進め、有効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/fc5c69db-a4b5-9a92-1e4a-d05f2014a5d1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/cbb396dc-c361-01af-1ecf-e44fbd36b1a6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/20a39861-d5de-e8c7-930d-1090d3391b0e.png)
- 「２段階認証プロセス」がオンになればOK、その下の「アプリパスワードをクリック」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/38b98690-e9ca-d012-8a5a-95d680a871b2.png)
- 「アプリを選択」 ⇒ 「メール」 を選択肢、「デバイスを選択」 ⇒ 「その他（名前を入力）」 を選択。アプリ名などを入力する。最後に「生成」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/fb9e6673-8c9d-851b-64a6-158ab73245b8.png)
- 16桁のパスワードが表示されるので、メモしておく。保存したら右下の「完了」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692472/c06c8f51-dc80-711e-0724-69d97896909b.png)

## Laravelアプリの.envを編集

Laravelの.envファイルを以下のように編集する

```plaintext:.env
MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=<使用するGmailのアドレス>
MAIL_PASSWORD=<先ほど発行したアプリパスワード>
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=<使用するGmailのアドレス>
MAIL_FROM_NAME=Samazon
```

これでLaravelからメールを送信することができるようになる。

以上
SAMで構築したLambdaのエラーをSentryに通知する

# 概要

AWS SAM(AWS Serverless Application ModelにてStepFunctionsを利用したバッチを作成しています。
各Lambdaで発生した例外をSentryへ通知したかったため、調べてやってみました。

共通的にソースコードを変えずに設定する方法が見つからなかったので、
1つ1つのLambda handlerのソースを修正する方法になってしまいました。
※知っている方いたら教えてください。

# 設定方法

まずはSentryにてプロジェクトを作成しdsnを取得してください。

次に[公式](https://docs.sentry.io/platforms/node/guides/aws-lambda/)にも書いている通り@sentry/serverlessを追加します。
（Lambda Layerを使用することもできます。詳しくは後述）
```sh
yarn add @sentry/serverless

or

npm install --save @sentry/serverless
```

実際のソースコードへSentryへの通知設定を追記します。
設定をまとめたかったので以下のようなファイルを作成しました。
```ts:sentrySettings.ts
import * as Sentry from "@sentry/serverless";
Sentry.AWSLambda.init({
  dsn: process.env.SENTRY_DSN,
  environment: process.env.ENVIRONMENT,
  tracesSampleRate: 1.0,
});

export const SentrySettings = Sentry;
```

各Lambdaのhandlerでは上記をimportして使用します。
```ts
import { SentrySettings } from "../settings/sentrySettings";

export const handler = SentrySettings.AWSLambda.wrapHandler(
  async (event: any) => {

   処理

  }
);
```

template.ymlには環境変数を設定します。
全Lambdaに反映されるように`Globals`へ記載しました。
※EnvはParametersで渡しています。
```yaml:template.yml
Globals:
  Function:
    Environment:
      Variables:
        ENVIRONMENT: !Ref Env
        SENTRY_DSN: "Sentryで取得したdsn"
```

あとはデプロイするだけでエラーがSentryへ通知されるようになりました。

# 補足　Lambda Layerを使用する

公式ページには@sentry/serverlessを追加する代わりにLambda Layerを用いる方法も載っています。

https://docs.sentry.io/platforms/node/guides/aws-lambda/layer/

その場合は`Globals`へLayersを追加します。
```yaml:template.yml
Globals:
  Function:
    Environment:
      Variables:
        ENVIRONMENT: !Ref Env
        SENTRY_DSN: "Sentryで取得したdsn"
    Layers:
      - "上記公式ページから取得できるLambdaLayerのARN"
```
【Excel】セル範囲を一括選択する方法

## 前提となる知識

* 行方向のセル範囲を一括で選択する方法が紹介されています  
  [【Excel講座】Alt + F3 の威力を知ってますか？★Excel2016](<https://youtu.be/IbOUc8p72zc>)

## 列方向のセル範囲も一括で選択したい

1. R1C1 参照形式でセル範囲を指定する  
  「Excel のオプション」にある「R1C1 参照形式を使用する」にチェックが入っていなくてもOK!  
  ![範囲選択_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/3fca0b19-2775-d5e9-e048-1b259bfb88d1.png)  
1. 列方向にも自由にセル範囲を選択できる  
  ![範囲選択_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/eadc96cb-2acd-e481-fcff-4d4fc0c87d59.png)

## 「A1 参照形式」と「R1C1 参照形式」を一緒に使うとエラー

* 「A1 参照形式」と「R1C1 参照形式」を組み合わせて指定するとエラー  
  「A1 参照形式」は（C列とR列を除いて）、「R1C1 参照形式」と組み合わせるとエラーになる  
  ![範囲選択_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/9e31b359-b96d-dd15-30c1-4967f78aa15e.png)

---

## 別解：「ジャンプ」の「参照先」を使用する方法

* 「参照先」欄に`=INDIRECT("R2C3:R7C8",FALSE)`を指定しても同じ結果になる   
  ![範囲選択_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2115724/21dfbea6-c4d5-e617-2b6e-0b70ef30ad5f.png)
GitLab Runner Kubernetes executorをarm64で構築したときにコケた話

おうち Kubernetes クラスターをラズパイで構築して、いざ実運用しようとしたが、 arm64 のイメージがないとお話にならない。。。今までは手元でクロスコンパイルしてたりしたけど毎度それをやるのは手間なので GitLab CI でいい感じに実現したい。 gitlab.com の shared runner は amd64 ぽいので、 Kubernetes クラスター上で GitLab runner も動かしてしまおう、という話です。

## 環境

* Raspberry Pi 4B
* Kubernetes 1.23
* GitLab 14.9.0-pre (gitlab.com, 2022-03-15 時点)
* GitLab Runner Helm Chart 0.37.2
  * GitLab runner 14.7.0
* Helm 3.3.4
* Helmfile 0.135.0

## 結論

```yaml:helmdile.yaml
repositories:
- name: gitlab
  url: https://charts.gitlab.io

releases:
- name: runner
  namespace: gitlab-managed-apps
  chart: gitlab/gitlab-runner
  version: 0.37.2
  installed: true
  values:
    - values.yaml.gotmpl
```

```yaml:values.yaml.gotmpl
## REQUIRED VALUES
gitlabUrl: {{ requiredEnv "CI_SERVER_URL" | quote }}
runnerRegistrationToken: {{ requiredEnv "GITLAB_RUNNER_REGISTRATION_TOKEN" | quote }}
rbac:
  create: true
  clusterWideAccess: false
runners:
  image: ubuntu:20.04
  builds: {}
  services: {}
  helpers: {}
  config: |
    [[runners]]
      [runners.kubernetes.node_selector]
        "kubernetes.io/arch" = "arm64"
        "kubernetes.io/os" = "linux"
  tags: kubernetes,cluster,arm64
  privileged: false
resources: {}
```

```sh
docker run --rm --net=host \
  -v "${HOME}/.kube:/root/.kube" -v "${HOME}/.config/helm:/root/.config/helm" -v "${PWD}:/wd" --workdir /wd \
  -e CI_SERVER_URL=https://gitlab.com/ \
  -e GITLAB_RUNNER_REGISTRATION_TOKEN=xxxxxxxxxxxx \
  quay.io/roboll/helmfile:helm3-v0.135.0 helmfile -f helmfile.yaml sync
```

Gitlab runner の helmfile は [GitLab Cluster Management のテンプレ](https://gitlab.com/gitlab-org/project-templates/cluster-management) から入手しました。 helmfile の実行コンテナは [helmfile のリポジトリに記載の手順](https://github.com/roboll/helmfile#running-as-a-container) を基にしています。

## コケたところ

GitLab Cluster Management のテンプレからほとんど何も変えずに適用したところ、 CI job の pod が一瞬で `Init:Error` になって終了するというとてもデバッグのしにくい事象に遭遇しました。

![ERROR: Job failed (system failure): prepare environment: waiting for pod running: pod status is failed. Check https://docs.gitlab.com/runner/shells/index.html#shell-profile-loading for more information](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/451958/88a27dcd-42ef-b183-42b8-948d3e64a6eb.png)

色々調べながら試してみたところ、 helper コンテナが arm64 ではなく amd64 のイメージを使っていることが判明しました。 GitLab runner ドキュメントの node selector の項には以下のようにあります。

> Runner additionally uses the information provided to determine the OS and architecture for the build. This ensures that the correct helper image is used. By default, the OS and architecture is assumed to be linux/amd64.
> 訳) Runner は提供された情報をビルドのための OS とアーキテクチャの決定に加えて使用します。これによって正しい helper image が使われることを確実にします。デフォルトでは、 OS とアーキテクチャは linux/amd64 と推定されます。

https://docs.gitlab.com/runner/executors/kubernetes.html#using-node-selectors

ということで arm64 用のサンプルの通りに設定してみたところ、あっさり解決しました :tada:

同じような事象で困っている方の助けになれば幸いです。

## 参考文献

https://docs.gitlab.com/runner/executors/kubernetes.html

https://docs.gitlab.com/runner/install/kubernetes.html

https://github.com/roboll/helmfile
TerraformのBackendとしてk8sのsecretを使う方法

おはようこんにちはこんばんは

あまりやっている人は居ないとは思いますが、Terraformからk8sのdeploymentなどを管理しているとTerraformのstateも管理対象のk8sクラスタに保存したいことがあると思います。

今回はtfstateをk8sクラスタのsecret内に保存することで、状態がk8sクラスタ内で完結するようにしてみました。

## 制約事項
- 保存されるtfstateは合計で1MB内でなければならない
    - https://www.terraform.io/language/settings/backends/kubernetes にあるように、secretは1MBまでしか保存することが出来ないのでそれ以上保存したい場合には使えません

## 早速設定してみる
```tf
terraform {
  backend "kubernetes" {
    secret_suffix    = "hogeapp-state"
    namespace        = "hogeapp"
    load_config_file = true
  }
}
```

`load_config_file`をONにしているので、kubeconfigは環境変数`KUBE_CONFIG_PATH`で指定されたパスから読み込まれます。
(1つ1つ設定することも出来ますが、面倒なのでおすすめしません)

設定値は以下の公式のドキュメントに記載されているので参考にしてください。

[Backend Type: Kubernetes | Terraform by HashiCorp](https://www.terraform.io/language/settings/backends/kubernetes)

## 保存されたtfstateを確認してみる
```bash
aoi@suzz:~$ kubectl get secrets -A | grep tfstate
hogeapp               tfstate-hogeapp-hogeapp-state                  Opaque                                1      75d
```

保存できるとこのようにsecretsに現れます。

## さいごに
そもそものk8sのdeploymentなどの管理にTerraformを使う方は少数派かもしれませんが、tfstateをk8sクラスタ内に保存できるとS3やGCSなどに保存する必要がなくなり考えることが1つ減らせるのでひとつの手段としておすすめです。
Brother VC-500W「暗号化の資格情報の有効期限が切れました」への対応

# 現象
* Brother のラベルプリンタ VC-500W をインフラストラクチャモードで WiFi に接続し、Mac から印刷する。メーカー提供のマニュアルどおりに設定。
* **設定＞プリンタとスキャナ**　から、ふつうに **Brother VC-500W XXXX** を追加。
* メーカー提供のアプリ **Brother P-touch Editor** から印刷する。
* 印刷が開始されず停止する。**プリントキュー** を見ると「**暗号化の資格情報の有効期限が切れました**」の表示がでている。

# 理由
* おそらく、ラベルプリンタ内の証明書の期限が切れている。

# 対応
* ラベルプリンタ内のウェブに接続する。
    * Mac なら **設定＞プリンタとスキャナ** で **Brother VC-500W XXXX** を選択
        * **オプションとサプライ** をクリック
        * **プリンタのWebページを表示…** をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64391/1d590655-eb20-7303-58a5-ab2035985950.png)

* **AirPrintオプション** をクリック
* 管理者ログインする。初期パスワードは本体底部のシリアル番号のステッカーに記載されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64391/618edac1-1e0d-30f9-d23c-b1745f2be41d.png)

* **TLSオプション** をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64391/27f87350-be88-445b-4e5d-3411cb17a1ba.png)

* 自己署名の証明書で問題なければ、「**自己署名TLS認証とプライベートキーを作成します。**」の **生成する** をクリック。
    * しばらく待っててうまくいくと、「生成は成功しました」的な英語のアラートが出て完了。

* これで印刷できるようになる。
    * 「暗号化の資格情報の有効期限が切れました」のエラーメッセージが消えないようなら、**設定＞プリンタとスキャナ** 　から一度プリンタを削除して登録しなおすなどしてみるといいかも。（私はやりました）
Netlifyの設定で躓いた部分


仕事でNetlifyを使ってホスティングしているサービスがあるのですが、先人の方が作成してくれたものであり、それを保守する形になっています。  

今回、Netlifyの知識をつけるべく、reactで作成したプロジェクト(create-react-app)をGitlabと連携してNetlifyでホスティングを行いました。  
その際に躓いた部分をメモとして残しておきます。  

# 最初

まず最初は、以下のシンプルな構成でした。
```
GitLab-Project
 ┗ react-app/
   ┗ src
   ┗ build
   ┗ pubic
     :
```  

作成し終わったプロジェクトをNetlifyと紐付けて自動的に作成されたURLを押して画面を確認しようとしたところ、 `Page Not Found`が表示されてしまいました。


# Page Not Found エラー
https://code-log.hatenablog.com/entry/2018/12/04/170740 を参考にさせていただきました。  
publicフォルダ内に_redirectファイルを作成し、その中に以下を記載することで解決(?)  
```
/*    /index.html   200
```
ここで「?」となっているのは、上記の対応だけでは確認できなかったからです。  
※実際に最後ホスティング完了後に`_redirect`を削除して再デプロイをしましたが、問題なく表示されていました。今回の根本的な対応は以下でした。

# npm run buildエラー  
おそらく上記で表示されていた「Page Not Found」に関しては、ベースとなるディレクトリの情報を設定していなかったからでした・・・。  
画面上でも設定できましたが、仕事上でも利用していた為、`netlify.toml`に設定情報を記載することにしました。  

当初は以下の設定を行いましたが、Netlify上のビルド時に`Command failed with exit code 254: npm run build`が出力されてしまいました。  
**当初**  
```
[build]
  base = "react-app/"
  publish = "build"
  command = "npm run build"
```
そのため、command部分を以下へ修正  
**変更後**  
```
[build]
  base = "react-app/"
  publish = "build"
  command = "CI= npm run build"
```

<br />

以上で、問題なくホスティングできました。  

Gitlabの最終的なプロジェクト構成は以下となりました。
```
GitLab-Project
 ┗ react-app/
   ┗ src
   ┗ build
   ┗ public
     ┗ _redirect  ##設定しなくても問題ないかも
     :
 ┗ netlify.toml
```
javascriptからtypescriptへ変更を考えている場合

javascriptからtypescriptへ変更を考えている方やtypescriptをやって見たいと思っている方が考慮して欲しい内容やその差について、お話ししたいと思います。

ネットで、よく言われているjavascriptとtypescriptの差は以下のものですね。

JavaScriptとの互換性が高い
型定義
クラスを作成することができる
動作が速い
事前のバグ検出がやりやすい


上記のことで、一つ一つお話しして見ましょう。
JavaScriptとの互換性が高いと言うお話しですが、typescriptはビルドされたら、javascriptになります。
つまり、javascriptベースの言語と言うことで、typscriptにてできることはjavascriptもできると言うことです。
内部の規約により、型定義しているように見えると言う感じですね。
その代わりに、javascriptに新しいバージョンが出てそのバージョンでしか利用できない機能があるとしたら、それをtypescript内部開発者が、開発してくれない限り、typescriptとしては、エラーになり、利用ができないとのことです。
実際プロジェクトをしている時、ECMAScript 2015が出て、利用したい関数がありましたが、typescriptではまだサポートしてなかったため、
その関数利用のモジュールだけjavascriptとして作成して、利用しました。

型定義もクラスもjavascriptにて開発できます。
ECMAScript 2015とES6からできて、実際ブラウザ側で、提供できるようになったことも2015年からです。
https://www.w3schools.com/js/js_classes.asp

動作が速いと言うことは、クラスやモジュール化などのオブジェクト指向開発による、速度改善みたいな感じもあるし、typescriptからjavascriptへの変換をしてくれる時の改善でもあります。言語的に早いと言えないのは、typesciptはjavascriptになるからです。

事前のバグ検出がやりやすいことについて、静的検査をするESLintがあるので、javascriptだとしても、事前検査ができます。
個人的にはまだESLintの経験は導入したばかの時点になるので、何とも言えない部分ではあります。
typescriptの方は楽ではありました。

WEB上に言われている理由がメリットだった時点も確かにありました。
しかし、今はあまり納得できなかったので、
本当のメリットは導入して、開発して見ても、上記の理由だったら、感じにくいと思って、
実際のメリットになりそうなものを考えてみました。

大きいプロジェクトで、もしくは全社的にフロント共通の何かの提供が必要、
又はオブジェクト指向の開発や型利用の開発の初めての一歩として、typescriptをやって見るとか
javascriptの性能改善が今のままでは難しいそうだと思っているとか。。。
現在のコードの整備がきれいにできていないから整備したいとか
一つのファイルで、色んなバージョンのjavascriptの支援をしたいとかの場合など。
などなど。

typescriptを導入する長所は色々あります。
やらない方が良いと言うお話しではなくて、実際の効果又は目的を明確にして、それを達成するためにどうしたら良いかを考えてやるともっとやりがいを感じられると思ってこのような雑談を書いて見ました。
EC2インスタンスでLinuxユーザーを作成し、sudo権限を付与する

## 内容
・EC2インスタンスにログインし、homeディレクトリにLinuxユーザーを追加しsudo権限を付与する方法。
・SSHの際に毎回コマンドが面倒くさいので、作成したLinuxユーザーの情報で`~/.ssh/config`ファイルを設定する

## 目次
- [サーバーにユーザーを作成](#サーバーにユーザーを作成)
- [SSH接続情報を登録](#SSH接続情報を登録)

## サーバーにユーザーを作成

```bash
# EC2上で
sudo su -
useradd -m <ユーザー名> # -mオプション：/homeディレクトリにユーザーのディレクトリの作成も行う
passwd <ユーザー名> # ユーザーのパスワード変更

# SSH秘密鍵の登録
cd /home/<ユーザー名>
mkdir .ssh
vim authorized_keys # 公開鍵の内容を記述、保存
chown <ユーザー名>:<グールプ名> authorized_keys
chmod 600 authorized_keys

# sudo権限の付与
visudo # /etc/sudoers.tmp のファイルを編集（sudo権限の設定）するコマンド
<ユーザー名> ALL=(ALL) ALL

# EC2を抜けて、接続確認
ssh -i ~/.ssh/<ログインするユーザーの秘密鍵> <ユーザー名>@<ip>
# sudoの確認
sudo su -
```

### 補足）sudoersファイルの内容
```plaintext
<ユーザー名> ALL=(ALL) ALL
ユーザー ホスト=(誰々として) コマンドパス
```
例えば
```plaintext
snow tty7=(vagrant) /usr/sbin/useradd
「ホストtty7からアクセスしたユーザーsnowは、vagrantとして/usr/sbin/useraddコマンドをsudoで実行できる」
```

## SSH接続情報を登録

```plaintext:~/.ssh/config
Host <任意の接続先名>
  HostName     <ssh接続先のIP(ドメイン)>
  Port         22
  User         <ユーザー名>
  IdentityFile ~/.ssh/秘密鍵ファイル
```
これでSSHする時のコマンドが以下のように変わる

```bash
ssh -i ~/.ssh/<ログインするユーザーの秘密鍵> <ユーザー名>@<ip>
↓↓↓
ssh <任意の接続先名>
```

以上