OmniAICreator/Qiita-1.07M huggingface dataset:
Googleスライドのグラフをコピーするときにソースデータもコピーする方法（PowerPointと違ってソースデータはコピーされないので注意！）

# はじめに
グラフを作成する際、グラフ形式や各種プロパティを設定してデザインし、そのデザインしたグラフを使い回したい時があります。
PowerPointを使い慣れている私が、使い慣れていないGoogleスライドでそれをやろうとした時に、
Googleスライドではグラフのソースデータがコピーされず少しつまづいたので、解決方法をメモしておきたいと思います。

# つまづいた点
PowerPointでは、グラフをコピーするとソースデータもコピーされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126110/a6d21eba-6aaf-c3a2-0e9d-5cbc0488bf0f.png)

ところがGoogleスライドでは、グラフをコピーすると、コピー元グラフのソースデータを共有する形になります。つまり、同じソースデータのリンクを参照することになり、コピー先のグラフのソースデータを編集すると、コピー元のグラフにも反映されてしまいます。この点がPowerPointと異なるので注意が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126110/097a14c4-dbb5-0331-8fdc-b46456173bbf.png)

# ソースデータをコピーする方法
PowerPointと同じように、Googleスライドでグラフとソースデータコピーし、コピー元のグラフに影響を与えないようにする方法を記載します。

## ソースデータファイルの保存場所を把握する
まず、Googleスライドで新規にグラフを作成した場合に、グラフのソースデータがどこに保存されるのかを知っておく必要がありますが、グラフの作成方法によって最初の保存場所は異なります。

### グラフ形式を選択して作成した場合
グラフを作成する際、「挿入」-「グラフ」メニューから任意のグラフ形式を選択してスライドにグラフを挿入した場合は、挿入したグラフのソースデータがGoogleスプレッドシートで自動作成され、デフォルトでGoogleドライブの「マイドライブ」に保存されます。
ファイル名はデフォルトで「スライド名 - 横棒グラフ 1」のように命名されています。
※チームで共有するGoogleスライドを作成する場合は、ソースデータファイル名を明示的な名称に変更し、保存場所を共有フォルダに移動することをおすすめします。

### 任意のスプレッドシートから作成した場合
グラフを作成する際に、「挿入」-「グラフ」メニューの「スプレッドシートから」を選択してグラフを挿入する場合は、任意のGoogleドライブの場所を指定してソースデータを挿入するので、当然ソースデータの保存場所は任意の場所になります。

### グラフを指定してソースデータファイルの場所を確認する方法
グラフの右上にある「リンクされたグラフのオプションメニュー」からソースデータを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126110/e6086506-f697-e36e-a1cc-7a7ca9f54804.png)

Googleスプレッドーシートでソースデータが表示されるので、「ファイル」メニューの「詳細」を選択すると、保管場所が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126110/e897a263-3c21-2ca8-6806-53e258cd7e33.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126110/29e44b9b-d42e-4f39-3ded-943cb3ec58a3.png)

## コピー元グラフのソースデータファイルをコピーする
ここまでに記載した内容から、コピー元グラフのソースデータファイルの保存場所を把握することができたと思いますので、そのソースデータファイルをコピー先グラフ用にコピーします。

## コピー先グラフを作成する
「挿入」-「グラフ」メニューの「スプレッドシートから」を選択し、コピー先グラフ用に作成したソースデータファイルを選択して挿入します。ソースデータファイルには、グラフの形式や設定などの**グラフのデザインも保存されている**ので、これでソースデータごとグラフをコピーすることできました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3126110/b06fb67b-b500-dbdd-7872-778767e09d53.png)

# おわりに
PowerPointに慣れていることもあり、中々Googleスライドに変えることに踏み切れずにいましたが、PowerPointのままGoogleドライブにアップロードして共有していると、体裁が崩れたり共同編集できないということもあったので、ようやくGoogleスライドに踏み切りました。PowerPointとgoogleドライブの機能差などネット上にたくさん記事が共有されていますが、グラフのソースデータのコピー方法がパッと出てこなかったので今回記事にしました。同じようにつまづいた方のコスト削減になれば幸いです。
element-plus 2.3.7 のインストール

メモ時点2023/06/28

とあるvue 3.0の学習本のchap11でのプログラム例で使用されているUIコンポーネントが動かなかったのでメモ

通常通りvue add vuex, router, element-plusをインストールすると何故かよくわからないエラーが起きた。

scss関係で読み込めないがどうたらこうたら。

参考書にはこう記されている

```
import '../element-variable.scss
```
とあるけど、それじゃeslintにないって言われてエラー

でもその後にもう一度element-plus, router, vuexの順にインストールし直すと今度は
```
import 'element-plus/dist/index.css'
```
と
自動でディレクトリを指定してくれてelement-plusのボタンが使えてたので無事反映されたみたい。

なんどもmnode_modulesフォルダを完全に削除を繰り返したりpackage.jsonをいじっていたのでそれのおかげもあるかも。
コンパイル済み wasm ファイルに後からデータを注入して使用する

## TL;DR

- コンパイル済みの wasm ファイルに後からデータを注入し、注入したデータをその wasm から読むことができた
- あらかじめローカルでビルドしておいた wasm に対し、ブラウザ上で動的にリソースを追加することが可能になる
- サンプルコードのリポジトリは[こちら](https://github.com/53-a/wasm-data-injection-sample)

## はじめに
[Rust から WebAssembly の memory.init 命令を使いたかった話](https://qiita.com/_53a/items/2ed7be658bd5b820b139) という記事を書きましたが、その後日談です。

上記記事中で、 `memory_init` 命令を使用したい箇所をダミー関数として括りだしておき、後から本物の `memory.init` を内容を注入するというアイディアを書きましたが、それがうまく行ったのでその報告です。


## サンプルコードの実行

サンプルコードとして、注入された文字列とその長さを読み取って出力するだけの wasm ファイルと、その wasm ファイルに文字列を注入するプログラムを用意しました。ここではそれを実行してみます。

Rustの開発環境一式（ネイティブおよび `wasm` ターゲット）は揃っているものとします。筆者の手元ではWindows上の `rustc 1.72.0-nightly (5ea666864 2023-06-27)` で検証を行いました。

1. `cargo` [cargo-wasi](https://github.com/bytecodealliance/cargo-wasi)および[wasmtime](https://github.com/bytecodealliance/wasmtime)[^wasmtime]をインストールします。
2. [サンプルコード](https://github.com/53-a/wasm-data-injection-sample)を適当な場所に `clone` します
3. データ注入の対象となるwasmをビルドします
   a. `crates/tartget-wasm/` 以下に移動します
   b. `cargo wasi build -r` を実行します
4. データ注入を行います
   a. リポジトリのルートに移動し、 `cargo run -- （注入元wasm） （生成先） （表示文字列）` を実行します
      例: `cargo run -- .\target\wasm32-wasi\release\target-wasm.wasi.wasm .\hello.wasi.wasm "hello world!"`
   b. 上記コマンドで生成された wasm ファイルを wasmtime などで実行します
   c. a. で与えた表示文字列が出力されれば成功です 

[^wasmtime]: wasmer など、WASIに準拠する他のランタイムでも構いません

## 技術的な解説

先の記事でも書いたとおり、Rust単体では WebAssembly の `memory.init` 命令を直に使用することができません。
そのため、データ注入側で `memory.init` を使ってデータをメモリ上にロードする処理を追加してあげる必要があります。

### 被注入側

被注入側のコード（`target-wasm`）には、 `memory_init` という関数を設けています。注入側のプログラムはこの関数をプレースホルダとして利用し、この関数を書き換えることで上記の処理を追加します。

`memory_init` には `__core_memory_init` というエクスポート名が指定してあります。これはビルド時に関数名がwasmファイル内から消されてしまう場合が多いため、注入側がこの関数をエクスポート名から識別できるようにするためです。

また、`memory_init` は内部で `__core_memory_init_dummy` というインポート関数を呼び出しています。これは `memory_init` やその引数を最適化等から防ぐ意図があります。

### 注入側

注入側のコード（`wasm-data-injection-sample`）では、まずエクスポートされている関数に、そのエクスポート名をつけ直しています。これは上記の、関数名が消去されている状況に対応するためです。
次に `__core_memory_init` に対して、実際に WebAssembly の `memory.init` 命令を叩くコードを追加します。
最後に後片付けとして、最適化防止用のダミーである `__core_memory_init_dummy` を消去したり、`memory_init` の不要なエクスポート指定を外したりしています。

## 最後に

注入側のコードも当然wasmにコンパイルできるため、あらかじめビルドしておいたwasmファイルに対し、ブラウザ上で動的にリソースを追加したりすることができます。
これはブラウザで完結するゲーム制作ツールやコンパイラ、自己解凍書庫などに応用できるのではと考えています。
Arduino Uno R4 MinimaでLチカする

# 経緯
Arduino Uno R4 Minimaが発売された。導入と動作確認をする。

https://www.switch-science.com/products/9000

https://akizukidenshi.com/catalog/g/gM-18114/

# ボードのインストール
ツール→ボード→ボードマネージャ...と辿って、検索欄に「R4」と入力するとArduino Uno R4 Boardsが表示される。
![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563735/f4310e6f-d1c8-f8f5-ee2d-38350687d2cd.png)
「インストール」を押してインストールする。

# ボードを接続する
![IMG_2936.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563735/e926c0d3-917d-b8cf-043c-a88b1b6315bf.jpeg)
USB typeCケーブルでパソコンと接続する。

# シリアルポートを設定する
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563735/3f7404e2-a1d9-4c66-cff1-e306765a5383.png)
ツール→シリアルポート の中の(Arduino Uno R4 Minima)と表示されているポートを選択する。
# サンプルプログラムを読み込む
ファイル→スケッチ例→01.Basics→Blink を選択
![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563735/cdfd15df-5d04-ab36-4861-01081fce08f6.png)

# コンパイルして書き込む
マイコンボードに書き込むボタンを押して書き込む。
![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563735/1223eb90-008f-39a9-8bfc-7ec11655a362.png)

Downloadが100%となり書き込めた。
![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563735/dd49141c-ea62-c5cf-8851-b0d24cda631a.png)

めでたしめでたし😇
DartのDateTimeをうまく扱うコツ

Flutterで「〇〇をした時間を保存しておきたい」という場面があると思います。
処理としてはDateTimeで現在時刻を取得し、Stringに変換して保存、
取り出すときはStringからDateTimeに変換して利用します。

公式ドキュメントを読みつつ、実際にどういう動きをするのか確認していきます。
https://api.dart.dev/stable/3.0.3/dart-core/DateTime-class.html

## DateTimeからStringへの変換方法
`Create a DateTime object by using one of the constructors or by parsing a correctly formatted string, which complies with a subset of ISO 8601.`

単純に訳すと
DateTimeコンストラクターを使用またはISO8601のサブセットに準拠する正しくフォーマットされた文字列を解析することによって、オブジェクトを作成します。
とあります。

ドキュメント記載のように`toIso8601String()`というメソッドを利用するとISO8601に変換をすることができるため、こちらを用いてStringに変換します。

#### ISO8601変換時にタイムゾーンを考慮するには
toIso8601String()をそのまま利用するだけではタイムゾーン考慮はされません。
②のように、String変換前に`toUtc()`のメソッドを利用しUTC変換することで、タイムゾーン考慮がされます。
コードで見てみると下記のようになります。

```
  final now = DateTime.now(); //　この時点でローカルタイムのJSTが適用される

  print(now.toIso8601String()); // ①2023-06-08T09:31:35.001
  print(now.toUtc().toIso8601String()); // ②2023-06-08T00:31:35.001Z
```
①ではJSTで変換されています。
②では末尾に「Z」が入っていますので、UTCの時間帯だと言う情報が入っていることがわかります。


## StringからDateTimeへの変換方法
戻す時は`toLocal()`を利用してローカルタイムに戻すことを忘れないようにしましょう。

```
  print(DateTime.parse(now.toUtc().toIso8601String()).toLocal()); // 2023-06-08 09:49:31.199
```

toLocal()を忘れるとUTCが考慮されているISO8601はUTCの時間でDateTimeに変換されます。

```
  final now = DateTime.now(); 
  print(DateTime.parse(now.toUtc().toIso8601String())); // 2023-06-08 00:49:31.199Z

```

ではここでDateTime->String時にUTCへ変換しなかった場合はどうなるのでしょうか？

```
  final now = DateTime.now();
  final nowString = now.toIso8601String();
  print(DateTime.parse(nowString)); // 2023-06-08 09:49:31.199
  print(DateTime.parse(nowString).toLocal()); // 2023-06-08 09:49:31.199
```
utcでString形式にしなかった場合は
`toLocal()`をつけても、つけなくても同様にローカルタイムになります。
String変換時にローカルタイムで保存される影響です。

一見これでいいのでは？と思いますが、端末の時刻に左右されるため注意が必要です。
DateTime→Stringの変換の時に端末の時刻がGMT+8(時刻は09:49:31)
String→DateTimeの変換の時に端末の時刻がGMT+9(時刻は10:49:31)だった場合は下記のようになり時間が正しく表示することができません

```
  // GMT+8（シンガポールなど）の設定に変更する
  final now = DateTime.now();
  final nowString = now.toIso8601String();　// 2023-06-08 09:49:31.199
  // GMT+9(日本など)の設定に変更する
  print(DateTime.parse(nowString)); // ③2023-06-08 09:49:31.199
  print(DateTime.parse(nowString).toLocal()); // 2023-06-08 09:49:31.199
```

③の時点で、GMT+9を考慮し2023-06-08 10:49:31.199にならないといけないですが09:49:31.199のままになってしまいます。String変換時にUTCを考慮していないためtoLocal()をしても同様の結果になります。



# 結論
DateTimeからiso8601形式にするときは`toUtc()`でutcの時間にしてから保存しましょう。
iso8601形式からDateTimeに戻すときは`toLocal()`をつけて端末の時刻を保存しましょう。
Java SE 11 Silver取得に向けて

# Java SE 11 silver取得

ひょんなことからJava SE 11 silver取得することにしました。
絶賛、子育て中なのでGoldは諦めて隙間時間で学んだことを記載してい行きたいと思います。
（なのでたまに更新します。）

## 配列の宣言

```java
データ型[] 配列名 = new データ型[要素数];
```
または
```java
データ型 配列名[] = new データ型[要素数];
```

<font color="red">[]はデータ型の後ろでも、配列名の後ろでもよし。</font>

```java
データ型[] 配列名 = {値1, 値2,・・・};
```

これでもいけるねや。

## 配列の生成時の初期値

```java
int[] array = new int[3];
System.out.println(array[0]);
```

これは「０」が出力されます。

<font color="red">
配列は生成された時点で初期値が入ります。
整数は0、実数は0.0、論理値はfalse、文字なら’\u0000’が初期値として入ります。
また、Stringのようなオブジェクト参照型はnullが入ります。
</font>

## 配列の{}指定

```java
String array[] = new String[3];
array = {"おはよう", "こんにちは", "こんばんは"};
System.out.println(array[2]);
```

これはどうなるでしょうか。

<font color="red">
コンパイルエラーです。
{}は配列の宣言時のみ使用可能です。
</font>

## インポート不要なクラス

- java.lang
- 同じパッケージに属するクラス

<font color="red">
java.langパッケージはJavaの基本的な機能がまとめられた パッケージです。
頻繁に利用するので「コンパイラが勝手にimportをしてくれる仕組み」になっています。
System.out.printlnとかもそうだと思う。
</font>

## javaのエントリーポイントの５つの条件

1. アクセス修飾子はpublic
1. staticメソッド
1. メソッド名は小文字でmain
1. メソッドの引数はString配列、Stringの可変長引数のみ

Stringの可変長引数

```java
String ... args
```

## javaコマンドの使い方

```
java クラス名またはファイル名.java 引数
```

引数は、スペース区切りで複数指定可能。

## アクセス修飾子

javaでは、public, protected, デフォルト(指定なし), privateの４つ

protected は「他ファイル・他クラスからのアクセスを<font color="red">プロテクトする</font>」  
private は「自クラスからのアクセスしか許さない」

## ラムダ式

```java:例
    list.replaceAll(str -> {
      if(str.startsWith("あ")) {
        return "＊" + str;
      } else {
        return str;
      }
    });
```

```java:書き方
(type args, …) -> { statements }
```

処理内容がreturn文のみの場合、{}とreturnキーワードを同時に省略できる

```java
SampleInterface hoge = str -> str + str;
```

## thisの呼び出しタイミング

クラスをインスタンス化する際は、コンストラクタは1つしか呼び出されません。
呼び出されたコンストラクタから別のコンストラクタを呼び出すときに<font color="red">this</font>
を使います。

```java

Public class Test {

    Public Test() {
        System.out.println("コンストラクタ１");
        this(123);
    }

    Public Test(int idx) {
        System.out.println("コンストラクタ２");
    }

    Public static void main(String[] args) {
        Test test = test();
    }
}
```

これは`this(123)`で<font color="red">コンパイルエラー</font>が発生します。


## Math.sqrt , Math.pow(平方根と累乗)

```java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        double test = Math.pow(8.0,3.0);
        System.out.println(test);
        
        double test2 = Math.sqrt(81);
        double test3 = Math.sqrt(50);
        System.out.println(test2);
        System.out.println(test3);
        
    }
}
```

結果は、

```
512.0
9.0
7.0710678118654755
```

## Comparatorint
MotionBoardでコード値の代わりに画像ファイルを表示させる方法

# MotionBoardでコード値の代わりに画像ファイルを表示させる方法

## はじめに

[MotionBoard](https://www.wingarc.com/product/motionboard/demo/index.html)とはウイングアーク社のBIツールで、同社のDr.SumをはじめとしたDBのデータをグラフや集計表などグラフィカルに表示することができるBIツールです。この記事では、MotionBoardを使用して集計表でコード値の代わりに画像ファイルを表示する方法について説明します。

## 事前準備

集計表で画像ファイルを表示させるためには、以下の事前準備が必要です。

- 項目の値の代わりに表示させる画像ファイルを用意し、MotionBoardの共有フォルダーに格納します。
  - 画像のファイル名は項目の値にしておく必要があります。
  - 画像ファイルが多い場合は、共有フォルダー内にサブフォルダーを作成して保存します。
  - 共有フォルダーの使い方の詳細は、[こちらのURL](https://cs.wingarc.com/manual/mb/6.4/ja/UUID-2e8c4950-8e96-1d64-d6a2-e01ac66e4eaa.html)を参照してください。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780637/8c3fcef3-25c5-9e94-911d-c7b2dff990c1.png)
- MotionBoardに表示する集計表を事前に作成しておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780637/6880648e-b58b-d2ac-35af-546f6dbb7ae7.png)

## 設定手順

以下の手順で、MotionBoardでコード値の代わりに画像ファイルを表示させる設定を行います。

1. MotionBoardの編集画面で、対象の集計表のデータソースエディタを開きます。
2. 画像を表示させたい項目の編集ボタン（鉛筆マーク）をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780637/a58323de-7cbe-0712-1099-08182f2a39ea.png)
3. 「基本項目設定」ウィンドウで、「共通設定」の「リンク/イメージ」右側の[設定]ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780637/da07bccb-66f8-2100-e72f-354265dc345c.png)
4. 「イメージURL」に表示する画像を指定します。
   - 共有フォルダー内の画像を指定する場合は、プルダウンから「内部パス」を選択します。
   - 画像ファイル名は、関数`${value(項目名)}.拡張子`を使って指定することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780637/70fdfdd0-c1ad-841b-ac2f-653a52f9100e.png)

設定が完了したら、保存して設定を反映させてください。
チャートエディタでフォントサイズや行の高さを変更すると見やすくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780637/046ce12e-1c4f-1662-caf1-4e2bbca881bb.png)

## まとめ

以上がMotionBoardでコード値の代わりに画像ファイルを表示させる方法です。MotionBoardの集計表でより視覚的な表示が可能となりますので、ぜひ参考にしてください。
vee-validateのuseFormが突然readonlyを返していた話

# 発覚した経緯
```console
[Vue warn] Set operation on key "email" failed: target is readonly. 
```
コンソールにこいつが出てformが動かなくなっていた。
# 使用箇所
```vuejs
<script>
import { useForm } from 'vee-validate';

export default {
  setup() {
    const { values } = useForm({ initialValues })
    return {
      values,
    };
  }
}
</script>
<component v-model="values[key]" />
```

こいつを子コンポーネントでmodelValueとしていろいろ使用していた。
あるときをさかいにwarnが出た。
# 原因
vee-validateのversionアップデートでuseFormの返すvalueがreadonlyにされているせいだった。
# 解決策
①vee-validateのversionを下げる。
②v-modelを使用せずにv-bindとv-onに分ける

# 分ける場合
```vuejs
<script>
import { useForm } from 'vee-validate';

export default {
  setup() {
    const { values, setFieldValue } = useForm({ initialValues })
    return {
      values,
      setFieldValue
    };
  }
}
</script>
<template>
    <component :bindValue="values[key]" @input="setFieldValue(key, $event.target.value)" />
</template>
```
こんな感じで分けるのがvue3の思想っぽい。でもこの変更をサラッと入れてくるのやばすぎん？

参考urlというか原因のコミット
https://github.com/logaretm/vee-validate/issues/4282
キュー、ワーカー、ジョブとは

# イメージ

イメージはこんなかんじ

キューという名の筒がある
```
       queue
      -------------------------

      -------------------------
```

キューにジョブを入れる
```
       queue
      -------------------------
-> job
      -------------------------
```

```
       queue
      -------------------------
                 job
      -------------------------
```

ワーカーがキューからジョブを取り出す
```
       queue                      worker
      -------------------------
                             job ->
      -------------------------
```

なんのためにキューを使うかというと、非同期に処理を行うため。

```
       queue
      -------------------------
-> job1
      -------------------------
```

```
       queue
      -------------------------
->  job3    job2   job1
      -------------------------
```

キューに入れておけば、後はワーカーが取り出したジョブを適宜処理する
```
       queue                      worker
      -------------------------
         job3   job2       job1 ->
      -------------------------
```

## まとめ

- キュー：非同期処理を行うための待ち行列
- ジョブ：実行したい処理
- ワーカー：ジョブを取り出す役割
【Python】str型オブジェクト

# オブジェクトとは
`オブジェクト`とは、「データ」と「そのデータに関する処理を行う関数」をひとかたまりにしたものです。

# str型オブジェクトが備える代表的なメソッド
オブジェクトが従えるメソッドは、「型」によって決まります。
str型のオブジェクトが従えるメソッドには以下のようなものがあります。

|メソッド名|機能|
|-|-|
|capitalize()|先頭文字だけ大文字に、残りを小文字にする|
|lower()|すべてを小文字にする|
|upper()|すべてを大文字にする|
|title()|単語の先頭だけを大文字に、残りを小文字にする|
|strip()|文字列の前後の空白を取り除く|
|split(⚫︎）|文字列⚫︎で区切り、各要素をリストで返す|
|replace(⚫︎, ▪️)|文字列中の⚫︎を▪️に置き換えた結果を返す|
|count(⚫︎)|文字列⚫︎が登場する回数を返す|

# 参考
https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8BPython%E5%85%A5%E9%96%80-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E5%9B%BD%E6%9C%AC%E5%A4%A7%E6%82%9F/dp/4295006327/ref=sr_1_2_sspa?keywords=python&qid=1687943880&sprefix=py%2Caps%2C222&sr=8-2-spons&sp_csd=d2lkZ2V0TmFtZT1zcF9hdGY&psc=1
PHPのヒアドキュメントでVSCodeのシンタックスハイライト(色付け)

ヒアドキュメントに言語を指定する事によりシンタックスハイライト(色付け)してくれる
# html
```php
$html = <<<HTML
<div>
    <p>hello world</p>
</div>
HTML;

echo $html;
```
# JavaScript 
```php
function shortcode_aaa(){
$contents = <<<JS
    <script>
        $(() =>{
            console.log('hello world');
        });
    </script>
JS;
return $contents;
}
```

# SQL
```php
$sql = <<<SQL
    SELECT id,name
    FROM M_table_data
    WHERE id = ?
SQL;
```
雑魚エンジニアが2週間でAZ-900に合格した方法

つい昨日に無事一発でAZ-900に合格したので、その体験記を記録します。私と同じような雑魚エンジニアの皆さんもよろしければ参考にしていただければ幸いです:relieved:

### 私のスペック
* 法学部卒
* 社会人5年目
* パッケージ開発やフルスクラッチ開発の経験はあれどクラウドの経験は一切ナシ

うーむ、雑魚ですね…。

### AZ-900とは？
* Microsoftが運営しているAzure関連の一番初級の資格
* 試験時間は45分、1000点満点で700点とれば合格。出題数は35問程度
* CBT方式でテストセンターか自宅で受験

### 勉強の流れ
インプット:アウトプット=3:7でやるといいと思います。

タイトルは2週間と銘打っていますが、私は会社の就業時間で試験対策させていただだきました。
ありがたや。でも土日や就業時間後も勉強していたので、1日にとれる学習時間は5~7時間程度とかなり多めでした。

#### インプット
https://az-start.com/

この方のサイトでほとんどインプットはOKだと思います。図が多くわかりやすいです。
[Microsoft公式のラーニングパス](https://learn.microsoft.com/ja-jp/training/paths/microsoft-azure-fundamentals-describe-cloud-concepts/)は書き方が難しいので使いませんでした。雑魚の方は余計混乱するかもしれません。

あとはこちらの[試験対策動画](https://info.microsoft.com/JA-HCSAzureHybridInfra-WBNR-FY21-02Feb-11-AZ900PrepSession-SRDEM61308_LP02OnDemandRegistration-ForminBody.html)も有用です。
SLAなど上記のブログであまりカバーされていないニッチな分野の学習に役立ちます。

インプットはこれで十分です。
私は当初ブログを丁寧に読み込んでいましたが、振り返れば記事のまとめの部分だけさらってすぐに問題演習に入った方が効率的ではないかと感じています。


#### アウトプット
[最短で合格！Azure Fundamentals AZ-900 試験対策問題集](https://www.udemy.com/course/microsoft-azure-az900-exam/learn/quiz/5615406#content)
こちらの試験問題は、本番の試験とほぼ同レベルです(本番の方が若干難しいかもしれません)。
こちらの問題を安定して9割とれるよう学習してください。そうすればほぼ確実に合格するはずです。
私は4~5周しました。要領のいい方は2周程度で9割取れるかもしれませんが、雑魚エンジニアの方は4周はすることになると思います。

[【6万人が受講】AZ-900 Microsoft Azure Fundamentals模擬試験問題集（7回分490問）](https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/learn/quiz/5670644/test#content)
こちらも学習しましたが、3回目からやたら難しいです。1,2回目だけやるのはありだと思います。
満点取るつもりならこちらも完璧に学習するのがよいでしょう。合格すれば満足の方は前者の方の問題集で十分です。

### 効率のいい知識定着の方法
科学的な根拠もないですが、私が覚えやすい！と思った知識定着法をここに記載します。

1. 概要だけでもインプットする
2. 問題を解く
2. 不正解した問題を確認する
2. 不正解した問題の解説文を正確に理解する(ChatGPT等を使うと有用)
2. 理解が足りなければ紙とペンで図解する
2. 2と全く同じ問題を解く

2~6の繰り返しです。
ポイントは2つです。

* 1度解いた問題をすぐにもう一度解く
    不正解した問題の再実施で知識が定着するのと、勘で答えて正解だった回答も再実施で思い出して着実に定着します。
* 紙とペンで図解する
    私は学生時代に塾でアルバイトをしていましたが、成績の悪い生徒は問題を解くときにほぼ確実に手を動かしません。頭の中だけで考えようとします。図を描けば一発でわかるような大したことない問題でも、それすらしないのです。「問題を解くときは大きく図を描こう」と100回は言ったのですが、それをしないからいつまで経っても成績が悪く塾代をどぶに捨てるのでしょう。
    人間のメモリを増設するために、目に見える図を使うのは非常に有用です。冷静に俯瞰できます。そして、文字の羅列はすぐに忘れますが図は意外と覚えています。本番の試験中に詰まってもフッと自分の描いた図が頭に浮かんできて回答できました。(お客様との進捗会議で空気悪くなったときも大きな紙に図解するのは使えますよ:wink:)



### まとめ
* インプットは軽め
* 問題演習は繰り返し実施する
* 図解しよう

まとめるとありふれた答えになってしまいました。でも事実なのでしょうがない。
図解したりChatGPT等を使って正確に理解するのと、問題集9割取れるようになれば受かります。それだけで大丈夫です。雑魚エンジニアでもできます。
Dockerfile書き方　勉強記録　初歩

すごく初歩的な内容です。

Dockerfileを作成する

```dockerfile:Dockerfile
FROM ubuntu:latest　　#　元となるDocker imageをセットする
RUN mkdir sample # Dockerコンテナ作成時に実行するコマンド
```
・FROMコマンドで元となるDocker imageをセットする。  
  ーDockerfileはFROMから書き始める

・RUNコマンドでコンテナ作成時に、名前がsampleというフォルダを作成する
  ーubuntuを元にしているため、RUNコマンドでmkdirを行うことができる




----------------------------------------------------------------------
Dockerfileをビルドするときの作業工程

①カレントディレクトリを確認する
```Terminal:Terminal
$ pwd
```

②Dockerfileが置いてあるディレクトリに移動する
```Terminal:Terminal
$ cd <directory>
```
③docker buildコマンドでDockerイメージを作る
```Terminal:Docker
$ docker build .

```

補足
```Terminal:Docker
$ docker build -t <name> .
```
Docker buildで作成するDocker imageに名前をつけることができる
AWS Cloud Practitioner Essentialsを受講した結果と感想（AWS Training and Certification）

# 受講に至った背景
先日、Qiita運営チームから、『AWSスキルを磨こう！』といった案内がありました。そこで、"AWS Training and Certification"の存在を初めて知り、初めて利用するに至りました。

もともとAWSに興味はあり、図書館でAWS関連の本を借りて読んでみたりはしたものの、しっくりした参考書はなく、AWSの全体像がわかりませんでした。かといって、実際に利用してみようにも、従量課金制などが採用されているため、素人には手が出しずらいということがありました。（従量課金制だからと言って、手が出しづらいというのは人の金銭感覚や事情によると思います）

また私の場合、手を出したとしても、無料枠分のサービスやコンポーネントを利用するだけで手一杯でした。具体的には、EC2インスタンスにRailsのアプリケーションをデプロイして運用することを前提に、インターネットゲートウェイを設置して、VPC内にあるEC2インスタンスにトラフィックを送るといった程度や"CostExplorer"や"Budgets"を使用して、コスト管理やアラート管理などするだけにとどまっていました。そのため、それ以外のサービス（コンポーネント）がどういう役割を持っているのかが分からず、分かりにくかった印象があります。
![スクリーンショット 2023-06-23 17.30.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/6b03d38a-ab55-c31b-c472-432e3a4beb40.png)

:::note warn
※上記画像では、「7日間の無料トライアル〜」と記載がありますが、今回の記事では、私は7日間の無料トライアルは使用していません。
:::

# 受講した結果（小テストの結果）
小テストの結果は、スコアが63%となり、合格点にまで到達することはできませんでしたが、まずまずといった結果になりました。

すでに知っていることの復習に加え、知らなかったことについての全体像（利用目的、サービスの内容、活用方法など）を知ることができました。そのため、『AWSクラウドプラクティショナー認定試験』の受講・認定も視野に含めて、さらに学んでいきたいという意欲を得られました。

このレッスンの受講によって、AWSに関する理解を深められたので、ぜひ一度、この記事を見ていただいた、AWS初心者向は、受講してみてはいかがでしょうか？
https://explore.skillbuilder.aws/learn/course/1875/aws-cloud-practitioner-essentials-japanese-na-ri-ben-yu-shi-xie-ban
![スクリーンショット 2023-06-28 14.27.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/6de6ef98-004c-27d5-cc03-db6dfe54db83.png)
![スクリーンショット 2023-06-28 18.05.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3079289/35dbbc59-b920-88da-7491-a50c24a6b21d.png)
Google Cloud Professional Data Engineerを受験してみて

# 1. はじめに
こんにちは、yamadayです。
2023年3月に[Google Cloud Professional Data Engineer試験](https://cloud.google.com/certification/data-engineer?hl=ja)を受けて、合格しました。
本記事では、勉強方法や問題に対する考え方をまとめていきたいと思ってます。

# 2. Professional Data Engineer とは
Google Cloud のサービスの中でも、データ処理システムの設計に有効なサービスについての知識が問われる資格です。

## 2.1 出題範囲
Professional Data Engineer 試験では、以下のような問題が出題されます。
- データ処理システムの設計
- 機械学習モデルの運用化
- ソリューションの品質の確保
- データ処理システムの構築と運用化

細かい出題項目は、[Professional Data Engineer 認定試験ガイド](https://cloud.google.com/certification/guides/data-engineer?hl=ja)をご確認ください。

## 2.2 推奨経験
業務経験3年以上（Google Cloud を使用したソリューションの設計と管理の経験 1 年以上を含む）の方の受験が推奨されています。
私はクラウド系の仕事を始めて3年、GCPを触り始めて1年なのでピッタリでした。

## 2.3 受験のメリット
認定試験の該当GCPサービスについての知識の取得があります。
業務でGCPサービスを使う場合の選択肢や、サービスの特徴を理解していれば正しい選定、実装を行うことができます。

## 2.4 合格ボーダーライン
合格ボーダーラインは公式が公開していませんが、7割くらいだと言われています。
問題集や模擬試験を受けるにあたって、7割を目標として勉強しました。

## 2.5 テスト形式
2時間のテストで、50~60問の多肢選択（複数選択）式で記述等はありません。

# 3. 勉強方法
## 3.1 GCP 認定トレーニング
[認定トレーニング](https://www.cloudskillsboost.google/paths/16?hl=ja)は、基本有料で、GoogleCloudの認定パートナーのみ無料となります。
※ログインが必要です。
- ビデオ講座：英語であり、かなりの時間を要します。
- ラボ：実際のサービスを動かし、サービスの構築が可能。
- テスト：サービスの理解度テスト。

ラボがサービスの内容を理解しやすく、勉強になります。
全体的に英語であり、時間がかかるので時間がない場合は、重要度が下がります。

## 3.2 問題集
Amazonで販売されている模擬問題集[クラウド認定試験模擬問題集](https://www.amazon.co.jp/Google-Cloud%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93-Professional-Engineer-%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E8%AA%8D%E5%AE%9A%E8%A9%A6%E9%A8%93%E6%A8%A1%E6%93%AC%E5%95%8F%E9%A1%8C%E9%9B%86%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-ebook/dp/B09RHX4NQ4/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=NFAB773AF3RK&keywords=Google+Cloud+Professional+Data+Engineer&qid=1683859031&sprefix=google+cloud+professional+data+engineer%2Caps%2C788&sr=8-3)を使用して勉強しました。
実際の試験と似た問題を扱っており、模擬試験として最適です。
正解の解説しかないので、不正解の選択肢は公式ドキュメントを読んで理解しました。
問題集1回目は約5割しか正解できませんでしたが、試験当日までに9割以上とれるようにもっていきました。

## 3.3 公式模擬試験
[Data Engineer 模擬試験](https://docs.google.com/forms/d/e/1FAIpQLSd4j4bcgbYenBRFIL6Kb0cvXp13qCQ-z6JzowgDxRaPITn56g/viewform?hl=ja)が用意されています。
模擬試験とは書いてますが、実際の試験問題とかなり違いがあります。
腕試し程度に受けるのも有りだと思います。

# 4. 感想
勉強期間は3か月ほど最初の2か月は、GCP 認定トレーニングをやっていました。
残りの1か月は、過去問とドキュメントです。
残り一か月切ってからは、毎日2時間、試験勉強をやってました。
試験当日は、高田馬場テストセンターで試験を受けました。
試験前に10分ほど手続きが必要だったので少し早めに行くといいと思います。
実際の問題ですが大体50パーセントくらいは、上記問題集と似た問題がでます。
試験後に正解率は出てませんが、手ごたえはかなりありました。
7-8割は取れているかなといった感じでした。
試験を受けた感じだと、問題文の意図をくみ取ることが大事で、選択肢的に全て正解みたいな問題もよくあり、より良い選択肢を見つけることが必要です。
コストや労力といった単語がでると、選択肢がかなり狭まり、ボーナス問題だと思ってます。
また、サービスごとに対応する文言が必ずあるので問題集をやってるうちに、ある程度回答が定まっていくと思います。
資格取得をすることで、ソリューションに対する最適なサービスの選択方法やAI知識など幅広い知識を得られ、受けてよかったと思いました。
Typescriptと遊びます

```ts
// Typescriptと遊びます

type Master = {
  id: number
  name: string
  type: 'AA' | 'BB'
  dataJson: {
    [key: string]: any
  }
};

```

Masterと同じ型ですが、ID項目を外したい

---


```ts
// Masterと同じ型ですが、ID項目を外したい

type MasterNonId = Omit<Master, 'id'>;
const masterNonId: MasterNonId = {
  name: '',
  type: 'AA',
  dataJson: {},
};
```

---

```ts
// Typescriptと遊びます

type Master = {
  id: number
  name: string
  type: 'AA' | 'BB'
  dataJson: {
    [key: string]: any
  }
};

```

Masterと同じ型ですが、descriptionの項目を入れたい


---

```ts

type MasterWithDescription = Master & {
  description: string
};

const masterWithDescription: MasterWithDescription = {
  description: '',
  id: 1,
  name: '',
  type: 'AA',
  dataJson: {},
};

```


---

```ts

type Master = {
  id: number
  name: string
  type: 'AA' | 'BB'
  dataJson: {
    [key: string]: any
  }
};

```

Masterと同じ型ですが、dataJsonは型定義できるようにしたい

---

```ts

type MasterForDataJson<T> = Omit<Master, 'dataJson'> & {
  dataJson: T
};

const masterForDataJson: MasterForDataJson<{test: string}> = {
  id: 1,
  name: '',
  type: 'AA',
  dataJson: {
    test: 'test',
  },
};


```


---

```ts

type Master = {
  id: number
  name: string
  type: 'AA' | 'BB'
  dataJson: {
    [key: string]: any
  }
};

```

Masterと同じ型ですが、typeの項目に'DD'に入れたい

---

```ts
type MasterWithType1 = Omit<Master, 'type'> & {
  type: 'AA' | 'BB' | 'DD'
};

const masterWithType1: MasterWithType1 = {
  id: 1,
  name: '',
  type: 'DD',
  dataJson: {},
};

```

それは良くないえすね。 Masterに`CC`追加したら、どうなる


---

考えましょう


---

```ts
type MasterType = Pick<Master, 'type'>;
type MasterNewType = {
  type: 'DD'
};
type MasterWithType2 = Omit<Master, 'type'> & (MasterType | MasterNewType);

const masterWithType2: MasterWithType1 = {
  id: 1,
  name: '',
  type: 'DD',
  dataJson: {},
};

```

これは正しいですね。

---

ありがとうございました。
条件分岐について(ネストの解消)

# 目的
「良いコード/悪いコードで学ぶ設計入門」のアウトプット
　(６章 6.1 条件分岐のネストによる可読性低下)

# 早期return
入れ子構造が深くなると処理ブロック({}で括られた処理範囲)がどこからどこまでが分かりずらくなる。  
複雑そうな処理の場合は、処理ブロックでifを対応するより早期returnで対応した方がネストを防げる。  


```php:元のif文
  function sample(){
    if ( 0 < $condA) { 
      if ( $condB ) {
        if ( $condC <= $condD ) {
          echo("Hello World");
        }
      }
    }
  }
```
```php:早期return を使うと階層が浅くなる。
  function sample(){
    if ( $condA <= 0 ) return;  // 通常のif文から早期returnへ修正する場合は条件を逆にする。
    if ( $condB) {
      if ( $condC <= $condD ) {
        echo("Hello World");
      }
    }
  } 
```
```php:他の条件にも早期returnを適応
  function sample(){
    if ( $condA <= 0 ) return;
    if ( !$condB ) return;
    if ( $condD < $condC ) return;
    echo("Hello World");
  }
```
早期returnを使って冒頭で条件を弾くようにすると見通しがよくなる。


## メリット
### 条件ロジックと実行ロジックの分離
```php
  // 条件ロジック
  if ( $condA <= 0 ) return;
  if ( !$condB ) return;
  if ( $condD < $condC ) return;

  // 実行ロジック
  echo("Hello World");
```
　
### 追加が容易
```php
  // 条件ロジック
  if ( $condA <= 0 ) return;
  if ( !$condB ) return;
  if ( $condD < $condC ) return;
  if ( !$condE ) return;  // NEW!

  // 実行ロジック
  echo("Hello World");
  echo("GOOD!!");  // NEW!
```

# 早期retun(else句)
```php::元のif文
    function sample(){
      if ($condA) {
        $test = "Hello A";
      }elseif ($condB) {
        $test = "Hello B";
      }elseif ($condC) {
        $test = "Hello C";
      }elseif ($condD) {
        $test = "Hello D";
      }elseif ($condE) {
        $test = "Hello E";
      }else {
        $test = "another";  
      }
      return $test;
    }
```
```php:見ずらいので各if文ブロックをreturnに置き換える。
  function sample(){
    if ($condA) {
      return "Hello A";
    }elseif ($condB) {
      return "Hello B";
    }elseif ($condC) {
      return "Hello C";
    }elseif ($condD) {
      return "Hello D";
    }elseif ($condE) {
      return "Hello E";
    }
  }
```
```php:今回は条件に合致したらそのまま返す形にする
  function sample(){
    if ($condA) return "Hello A";
    if ($condB) return "Hello B";
    if ($condC) return "Hello C";
    if ($condD) return "Hello D";
    if ($condE) return "Hello E";
  }
```

# 参考文献
[良いコード/悪いコードで学ぶ設計入門 ―保守しやすい 成長し続けるコードの書き方](https://www.amazon.co.jp/%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89-%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80-%E2%80%95%E4%BF%9D%E5%AE%88%E3%81%97%E3%82%84%E3%81%99%E3%81%84-%E6%88%90%E9%95%B7%E3%81%97%E7%B6%9A%E3%81%91%E3%82%8B%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E6%9B%B8%E3%81%8D%E6%96%B9-%E4%BB%99%E5%A1%B2/dp/4297127830/ref=sr_1_1?keywords=%E8%89%AF%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%2F%E6%82%AA%E3%81%84%E3%82%B3%E3%83%BC%E3%83%89%E3%81%A7%E5%AD%A6%E3%81%B6%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80&qid=1687251418&sprefix=yoiko%2Caps%2C224&sr=8-1
)

# 感想
リファクタリングしているときにif文がネストして複雑になっているとコードブロックがどこがどこまでの範囲が分からなくなっているので、三項演算子とか組み合わせてなるべく短くしたい。
しかし短くしすぎると今度は可読性が低下する。保守しやすいように直さないといけないのでバランスが難しい。
VS CodeでViteのローカルサーバの自動起動を無効化する

[Vite](https://ja.vitejs.dev/)は超高速で重宝しているのですが、VS CodeでViteプロジェクトを開くと毎回以下のようなスクリプトが走ってローカルサーバが自動起動してしまうのが煩わしかったです。

```sh
$ npx vite --port=4000
													17:25:57
  VITE v4.0.4  ready in 550 ms

  ➜  Local:   http://localhost:4000/				17:25:57
  ➜  Network: http://XX.XX.XXX.XX:4000/				17:25:57
  ➜  press h to show help							17:25:57
```

### 拡張機能の設定から無効化する
調べてみたところ、これはVS Codeの拡張機能[Vite](https://marketplace.visualstudio.com/items?itemName=antfu.vite)のデフォルト設定によるものだったので[^1]、これを無効化すればOKでした。

[^1]: [vitejs/vite#7205](https://github.com/vitejs/vite/discussions/7205#discussioncomment-2322747)

1. VS Codeの設定を開く（ macOS: `⌘`+`,`　Windows: `Ctrl`+`,` ）
1. `vite`で検索する
1. `Vite: Auto Start`のチェックを外す

![Vite: Auto Start](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1129415/8ca7cc3a-6a96-ecc5-cee3-cbf226efc68b.png)
【Salesforce】LWC Builder

## LWC Builderをインストール

https://marketplace.visualstudio.com/items?itemName=ninoish.lwc-builder

## ツールの使い方
SFDXプロジェクトの**lwc**フォルダを右クリックし、`Open LWC Builder`をクリックすると、ツールを開けます

![dNL3W4S.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767576/207fe1ee-227e-2d66-f5dd-d65b9cc9c52a.jpeg)


## 参考
https://marketplace.visualstudio.com/items?itemName=ninoish.lwc-builder

https://github.com/developerforce/lwc-builder
[小ネタ] 古いS3バケットで他AWSアカウントとファイル連携する時はBucket Ownership Controlを確認しよう

## 古いS3バケットでの連携に注意

先日、 **数年前からAWSで稼働している** 自システム(A)が、**別のAWSシステム(B)のデータをS3経由で受け取れるように**、 アカウントA側を設定しました。

```mermaid
sequenceDiagram
    participant AccountA as AWSアカウント A<br>(自分)
    participant S3 as [AWSアカウントA]<br>S3バケット
    participant AccountB as AWSアカウント B<br>(相手側)

    AccountA ->> S3: アカウントBに対して<br>書き込みを許可するポリシー付与
    AccountB ->> S3: 連携ファイル保存
    AccountA ->> S3: 連携ファイル読み取り
```

```json:アカウントAのバケットポリシー.json
{   "Version":   "2012-10-17",
    "Statement": [{
        "Effect":    "Allow",
        "Principal": { "AWS" : "アカウントBのID" },
        "Action":    ["s3:ListBucket", "s3:PutObject", "s3:GetObject"],
        "Resource":  ["arn:aws:s3:::バケット名", "arn:aws:s3:::バケット名/*"]}]}
```

上記の設定後、アカウントB側で連携ファイル書き込みを行う主体のIAMロールに対して、アカウントA側のS3への書き込みを許可するポリシーを設定を行い、無事バケット上に連携ファイルの保存ができるようになりました。（やったね！）

……と、ここまでは良かったのですが、その連携ファイルを **アカウントA側で読み取ろうとすると `Access Denied` となってしましました。**

```mermaid
sequenceDiagram
    participant AccountA as AWSアカウント A<br>(自分)
    participant S3 as [AWSアカウントA]<br>S3バケット
    participant AccountB as AWSアカウント B<br>(相手側)

    AccountA ->> S3: アカウントBに対して<br>書き込みを許可するポリシー付与
    AccountB ->> S3: 連携ファイル保存
    AccountA ->> S3: 連携ファイル読み取り
    S3 ->> AccountA: 403 Access Denied???? どうして？

```

「**え？ 自分のバケット上のファイルなのに何で自分で読み込めないの？** 」


## 自アカウントのバケットなのにファイルを読み込めなかった原因

**原因は保存された連携ファイルの所有者に置いた人（アカウントB）が設定されていたためです。**

下記ドキュメントを見ればわかりますが、S3はオブジェクト単位でACLを持つことが可能です。

https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/about-object-ownership.html

> S3 オブジェクト所有権は、Amazon S3 バケットレベルの設定で、バケットにアップロードされたオブジェクトの所有権を制御し、アクセスコントロールリスト (ACL) を有効または無効にするのに使用できます。デフォルトでは、オブジェクト所有権は[バケット所有者の強制] 設定に設定され、すべての ACL は無効になっています。ACL が無効になっている場合、バケット所有者はバケット内のすべてのオブジェクトを所有し、アクセス管理ポリシーのみを使用してデータへのアクセスを管理します。
> **Amazon S3 の最新のユースケースの大部分では ACL を使用する必要がなくなっています。そのため、オブジェクトごとに個別にアクセスを制御する必要がある異常な状況を除き、ACL を無効にしておくことをお勧めします。** ACL を無効にすると、バケット内のオブジェクトをアップロードしたユーザーに関係なく、ポリシーを使用してバケット内のすべてのオブジェクトへのアクセスをより簡単に制御できます。

**現時点で普通にS3バケットを作成した場合、バケットのオブジェクトはバケットのオーナーの持ち主になるようにデフォルトで設定されますが、古いバケットはそうなっていない可能性があります。** そういった場合、今回の私のケースのように他アカウントから書き込まれたファイルを読み込めなくなります。

バケットはTerraformで管理していたため、下記のようなリソースを追加してバケットのACLの挙動を無効にしました。

```terraform
resource "aws_s3_bucket_ownership_controls" "data_sync" {
  bucket = aws_s3_bucket.data_sync.id

  rule {
    object_ownership = "BucketOwnerEnforced"
  }
}
```

(AWSマネージメントコンソールからは、 該当のS3バケット → Permissions → Object Ownership のセクションを確認）


## まとめ

自バケットのオブジェクトをなぜか読み込めない場合は所有者やバケットのデフォルトオブジェクト所有権の設定をチェックしましょう。


https://aws.amazon.com/jp/about-aws/whats-new/2020/10/amazon-s3-object-ownership-enables-bucket-owners-to-automatically-assume-ownership-of-objects-uploaded-to-their-buckets/
Amazon EventBridgeを使ってAPIのエンドポイントを叩いてバッチを実行する

# 目的
AWSのECSを使ったバックエンドのAPIを作成しました。
このシステムでは1つだけ日次でバッチを実行する必要があります。
通常バッチを作ろうと思うと以下のような作業が必要になります

ECSでバッチを実行する方法
1. コードを書く
1. dockerを書く
1. ECRにプッシュする
1. ECSクラスターを作る
1. ECSタスクを作る
1. ECSスケジューラーを作る

このためだけにECSのタスクを立ち上げて実行するのは面倒です。

そこでAPIにバッチを実行するエンドポイントを追加しました。
このエンドポイントをEventBridgeで呼び出すことでバッチを実行します。
ただしこのエンドポイントは誰でも呼び出されてしまうと困るので、特別なヘッダーを入れてチェックすることにします。

ここでは、定期的にエンドポイントを呼び出すEventBridgeのCDKを書きました。
またRustのaxumで書いたエンドポイントのサンプルも書きました。

# 実装

## cdk

```typescript:cdk-batch-stack.ts
import { Stack, StackProps } from 'aws-cdk-lib';
import * as cdk from 'aws-cdk-lib';
import * as events from 'aws-cdk-lib/aws-events';
import * as targets from 'aws-cdk-lib/aws-events-targets';
import { Construct } from 'constructs';

export class CdkBatchStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props)

    // エンドポイント
    const endpoint = "http://www.example.com/batch"

    // 名前
    const name = 'my-app-batch'

    // エンドポイントアクセスするためのパスワード設定
    const connection = new events.Connection(this, 'Connection', {
      connectionName: name,
      authorization: events.Authorization.apiKey(
        'special-password',
        cdk.SecretValue.unsafePlainText(process.env['SPECIAL_PASSWORD'] || 'xxxxx')
      ),
      description: 'Connection with special password',
    })

    // API送信先作成
    const destination = new events.ApiDestination(this, 'Destination', {
      apiDestinationName: name,
      connection,
      endpoint: endpoint,
      description: 'Execute Batch',
    })

    // 0時に実行
    const rule = new events.Rule(this, 'Rule', {
      ruleName: name,
      schedule: events.Schedule.cron({minute: "0", hour: "0"}),
      targets: [new targets.ApiDestination(destination)]
    });
  }
}
```

## APIのサンプル
RustのAxumのサンプルです。
```rust
pub async fn execute(
    headers: HeaderMap,
) -> impl IntoResponse {
    let Some(special_password) = headers
        .get("special-password")
        .and_then(|it| it.to_str().ok())
        .filter(|it| it == "xxxxxx") else 
    {
        return Response::builder()
            .status(400)
            .unwrap()
            .into_response();
    };

    // TODO バッチ処理

    "success".into_response()
}
```

# 注意点
[APIの送信先](https://docs.aws.amazon.com/ja_jp/eventbridge/latest/userguide/eb-api-destinations.html)
というAWSのドキュメントに重要なことが書いてあります。

> API 送信先エンドポイントへの EventBridge リクエストは、クライアント実行タイムアウト時間を最大 5 秒までにする必要があります。ターゲットエンドポイントが応答に 5 秒以上かかる場合、EventBridge はリクエストをタイムアウトします。EventBridge はタイムアウトしたリクエストを、再試行ポリシーで設定された最大値まで再試行します。デフォルトでは、最大値は 24 時間と 185 回です。再試行の最大回数を超えると、デッドレターキューがあればイベントはそこに送られ、なければイベントはドロップされます。

よってバッチ処理は5秒以下のものか、もし5秒以上かかる場合はなんらかのバッチを調停する仕組みが必要になります。
今回に自分が作ったバッチも5秒以上かかるので、バッチ実行中のフラグを立てて、2回目のリトライ時には成功させるコードにしています。
Rubyについて知る

Ruby始めて１日の、ruby初心者です。いろんな言語を触ってみるのはいいことだと勝手に思ってます。
とりあえず特徴を簡単にまとめました。rubyやったことない方大歓迎です。
ご自由にどうぞ。

# rubyの特徴
### 1.いろいろ作れる
https://www.fenet.jp/dotnet/column/language/3345/

いろいろできるそうです。
一番特徴的なのはwebアプリケーションを制作できる点です。
便利だと思います。

<b>ただし開発するにはRuby On Railsの勉強も必要っぽいです</b>

自分はちょっと触ってみるだけなので、今はrubyだけ触ってみます。
後でちゃんとやります。

### 2.()が省略できる
例えば「Hello world!」を出力するときに
```
puts "Hello world!"
```
でも、
```
puts ("Hello world!")
```
でもいけます。
putsの代わりに、<b>print</b>とかでも同じことができます。
私はこの二つ（putsとprint）の違いが判りませんでしたが、どっちでも同じように動きました。

### 3.開発環境が少ない
気になった点です。
例えばC#ならUnity,javascriptやkotlinならAndroidStudioで簡単に開発ができます。
しかし、rubyはゲームを作るためにDXRubyなどがあるだけだと思います。（調べた限りなさそうです）
メモ帳かVisualStudioCodeを使ってコードを書いたら、コマンドプロンプトを使って実行するだけな感じがしました。
なんか使い勝手のいいものがあればいいなと思いました。

### 4.文字列のstringとか、小数点を伴う数字を扱うときのfloatとか書くのを省略できる。
自分はC#を使っていたから、見覚えがあります。型とか言うやつです。
が、詳しいことをよく思い出せなかったので、復習もかねて下に載せておきます。
####  型とは
型は、数字とか文字とかを扱いたいときに必要なものです。上に書いたstring型とかfloat型とかのほかに、trueかfalseかを判定するfloat型や整数値を入れるint型も存在します。

C#では、型を最初に宣言することが必要でした。
例えば、int型を使って「A」に100を代入するときは
```
int A =100;
```
とか書かないといけません。
最初のintを外して、
```
A=100;
```
なんて書くと、エラーが出ます。
Unityを使って試してみましょう。
```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class a1 : MonoBehaviour
{
    int A = 100;
    // Start is called before the first frame update
    void Start()
    {
        Debug.Log(A);
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

```
オブジェクトにくっつけて実行すると、
![スクリーンショット (127).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2961125/880714aa-6efb-5523-d730-a09dc547f6ba.png)

こんな感じにAの値である100が出てきます。
では、７行目の int A = 100;をRubyのようにintを外して
```
A=100
```
に変えてみます。
すると、

:::note alert
Assets\Scenes\a1.cs(7,7): error CS1519: Invalid token '=' in class, record, struct, or interface member declaration
:::
とかエラーが出てしまいます。
C#と比べると、エラーが出ずちゃんと動くrubyは多少使い勝手がよさそうです。
ちなみにpythonもrubyと同じく省略できます。



# まとめ
#### 良い点
:::note info
・いろいろ作れる
・intとか型を省略できる
・（）も省略できる
:::
#### 改善してほしい点など
:::note alert
開発環境が少ない点
:::
初心者でも扱いやすい言語です。

# 参考にしたサイト

https://www.fenet.jp/dotnet/column/language/3345/

https://www.javadrive.jp/ruby/#section_class

https://www.sejuku.net/blog/curriculums-ruby-2
初めてのEC-CUBE。4.2.2を見てみた

こんにちは。
6月28日（水）にEC-CUBE 4.2.2がリリースがされました！😍
今回はEC-CUBE 4.2.2の内容をご案内いたします。


## はじめに
EC-CUBEに出会ってまだ２ヶ月の初心者です！
EC-CUBEについて、新しい気づきばかりですが、そんな中、4.2.2がリリースされたそうです！
プロの方から見ると、”知ってるよ！”という内容になるかも知れないですが、
読んでいただければと思います！
では、4.2.2の内容を説明していきます。

## 4.2.2のリリース内容
では、4.2.1から4.2.2へと何が変わったのでしょうか？

GitHubで取り上げられている**主な変更点**は以下でした。

　・会員による重要操作時のメール通知機能
　・会員情報編集・お届け先編集時にスロットリングを追加
　・EC-CUBEの基本設定内にあるメールの設定を修正したい
　・購入エラー画面ではWarningレベルのメッセージを削除する
　・管理画面URLを「cart」にした場合、カート画面への遷移時に管理画面が表示される

目玉機能としては、ECサイトの会員が重要操作した時に、メール通知が送られるようになったみたいです。

※ただ、重要操作時のメール通知機能は最初は「オフ」になっていたため、
　管理者側で「オン」に設定する必要がありました。
<img width="640" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3469200/4cb82f38-ea8c-47ba-fbc0-b63ac2aac45c.jpeg" alt="EC-CUBE PageImg">

## 旧バージョンから4.2.2へと差し替える場合の注意事項
4.2.2へとバージョンアップする時の手順に関して、少し変更があるようです。
(そんな大したことないではないのですが、、、)

以下のページに記事が掲載されていたので、ご覧ください。

■4.2 本体バージョンアップ
https://doc4.ec-cube.net/update42x

## 最後に
今回、4.2.1から4.2.2のアップデートは約４ヶ月ぶりでした！🎉

4.2.1でも、IPアクセス制限・スロットリング・2段階認証など、
セキュリティ強化を意識しているように見えたのですが、
4.2.2でも同じくセキュリティの向上を目指していた感じですね。🧐

また、今回はGUIの変更はなかったのですが、
個人的にはEC-CUBEのデザインはいつでも綺麗だなーと思いました。笑

次は、どんな機能が追加されるのか楽しみです。笑

皆さんも是非、4.2.2の機能を試してみてください！

■EC-CUBE 4.2.2（GitHub）
https://github.com/EC-CUBE/ec-cube/releases/tag/4.2.2
Step FuntionsでCloudFront を削除する

稼働中のCloudFrontを削除する場合、まずCloudFrontの閉鎖が必要である。
これをlamdbaとかで行う場合は、この閉鎖のための待機が必要なため、代わりにStep Functionsを使い閉鎖を待ってから削除するような方法で実装した。

## Step Functionsの中身

![step_funtion](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/224230/c98db0a1-dfb1-808d-c4b9-88d5344bd396.jpeg)


以下各ステップの説明である。


### CloudfrontDeleteGetConfig

閉鎖するにはIF-MatchようにETagが必要なためGetConfigを行う。
`arn:aws:states:::aws-sdk:cloudfront:getDistributionConfig`
を実行すればlambdaもいらずStep Functionsから直接取得できる。

### CloudfrontDeleteModifyConfig

閉鎖のためには`DistributionConfig`の`Enabled`をfalseにしないといけない。
そのためには前のstepで取得した`DistributionConfig`の値とEnabledをfalseにしたものをマージすることが必要である。
ここでStep Fucntionには組み込み関数というものがあり、パラメータの操作ができる。
ここで`States.JsonMerge`という関数があるのでこれを使う…__ことができない！__

[awsのリファレンス](https://docs.aws.amazon.com/ja_jp/step-functions/latest/dg/amazon-states-language-intrinsic-functions.html#asl-intrsc-func-json-manipulate)にある通り、現在この`JsonMerge`は __deep mergeに対応していないのである！__ 
(「3 番目の引数はのブール値です。falseこのブーリアン値は、ディープマージモードが有効かどうかを決定します。」とあるのでいつかは対応しそうだが…。）
もちろんすべての`DistributionConfig`の値を羅列してもいいのだが保守性が最悪なのでここだけはlambdaにした。このlambdaの中身は`DistributionConfig`のjsonを受け取って`Enabled`をfalseにするだけである。

### CloudfrontDeleteStop

先ほど変更した`DistributionConfig`の値を用いて`arn:aws:states:::aws-sdk:cloudfront:updateDistribution`を実行する。
ここでしばらく時間がかかることになる…。


### CloudfrontDeleteWaiter

待つ。とりあえず5分=300秒待機した。


### CloudfrontDeleteDelete

実際に削除する部分。Stopで取得した`Etag`とかを使い、`arn:aws:states:::aws-sdk:cloudfront:deleteDistribution`で削除する。
ただ閉鎖が完了してないときのために、最大10回分の再挑戦を仕込んである。
この再挑戦は`"ErrorEquals":["CloudFront.DistributionNotDisabledException"],`で判定する。
Backoffrateとか利用して時間がかかってもしっかり削除されるようにしている。


# 感想

lambdaを使わずともStep Functionsでawsのリソースを直接触れるのは良かったが、
パラメータの取り回しの不自由さが気になった。
`JsonMerge`はさっさとdeep copy対応してほしい…。
lambdaを使っているなら`GetConfig`と`UpdateConfig`もlambdaに混ぜてしまってもよかったかも…。
Ubuntuインストールできない

デスクトップPCに Ubuntu 22.04.2 TLS をインストールしようとしたところトラブルがあったのでメモします。

# 現象
インストール過程で
```
Sorry There was a problem ....
```
のようなメッセージが表示されインストールが停止しました。

20.04でも試しましたが同様でした。

# 調査

```ubuntu sorry there was a proglem``` でググってみると同じような現象に遭遇している人がいるようです。が、ズバリな解決策はなさそう。。。

# 対処

上記検索結果の中にnicを無効にしろみたいなのがあったので試したところ、まさにその通りでした。
今回はnic無効化ではなくlanケーブルを引っこ抜いただけです。lanケーブル抜いただけで何事もなかったようにするっとインストールできてしまいました。

# さいごに

これどういうトラブルなんでしょ。PCの構成の問題なのかな。ふしぎー。
Docker環境でAPI通信にハマった話：Failed to load resource: net::ERR_NAME_NOT_RESOLVED - 解決方法まとめ

## はじめに
今回はDocker環境でAPI通信にうまくいかなくプチハマりした事と、
その解決方法について共有したいと思います。

## 開発環境
Ruby on Rails（API側）
Next.js（クライアント側）
Postgres(データベース)
Docker/Docker-compose

## 本文
APIサーバー（Rails）からクライアントに表示させるときは、
今回の場合API通信がrailsとPostgresからのNextなのでDockerのネットワーキング内に収まります、
なのでこのようにサービス名で大丈夫なのでこのコードでいいのですが

```jsx
await axios.get("http://サービス名:ポート番号/エンドポイント"
```
クライアントサーバー(ブラウザでフォーム通信よってコンテナ外)からrailsにAPIを叩くと。。。
**"Failed to load resource: net::ERR_NAME_NOT_RESOLVED"**
というエラーメッセージに遭遇しました。
このエラーの原因は、サーバー名が見つからないためでした。
Dockerコンテナ外部からdockerにアクセスするためには、
dockerのホストIPアドレスを教えてあげる必要がありました!


つまり、**クライアントサーバー(ブラウザでフォーム通信など)からrailsに叩くときは**、
DockerホストのIPアドレスと公開されている（exposeされた）ポート番号を使用する必要があります。
たとえAPIサーバー（rails）とクライアント（Next.js）の両方が
Docker上で動作している場合でも、この方法が必要になります。
```jsx
await axios.post("http://dockerホストのIPアドレス:ポート番号/エンドポイント"
```

## まとめ
Dockerコンテナ内から他のDockerコンテナに通信する場合（この場合、RailsからPostgresへの通信など）、Docker内部のネットワーキングが利用できます。

しかし、Dockerコンテナ外部から（つまり、ブラウザなどのクライアントから）Dockerコンテナ内部のサービスに通信する場合、DockerホストのIPアドレスと公開されている（exposeされた）ポート番号を使用する必要があります。

因みにターミナルにこのコマンドを打つとdockerのホストIPが確認できます。
```bash:zshかbash
ifconfig
```

### 余談
:::note
開発環境をすべてローカルで構築している場合、(Dockerでない場合)
APIを叩くためにはlocalhost:3000/エンドポイントのように指定するだけでいいみたいです。
:::

## 最後に

APIを作成したらPostmanのようなAPIテストツールを使いちゃんとレスポンスが返ってくるのかを
確認する癖をつけたいと思いました！
そして返ってきたらAPI(Rails)が悪いのではなく指定の仕方が悪いと原因が特定しやすいです。

これまでの学習では、Railsだけで開発を進めてきましたが、
クライアントとサーバーを分けて学習するのは今回が初なので苦戦してしまいました
もっといい方法があるかもしれませんが今回はこのような形で無事解決しました。
API操作は使用頻度はかなり多いと思いますし、
同じミスで時間を潰したくないので積極的にアウトプットしていきます！

お疲れ様でした！
pipe

標準入力の代わりに、コマンドの標準出力を標準入力として引数に指定するのがパイプ？

```sample.sh
#!/bin/sh -v
   cat file.txt
   cat file.txt | grep apple    catの結果を標準入力として
   grep apple -                 ハイフンは標準入力として
```
```
#!/bin/sh -v
   cat file.txt
apple
orange
   cat file.txt | grep apple 
apple
   grep apple - 
apple
apple
^C
コマンドを中断しました
```
Docker を基本からまとめてみた【Dockerfileでカスタムイメージを作成する】

## Dockerfileとは？
Dockerfileとは、新規にDockerイメージを作成するための手順を記したテキストファイルのこと。要約すると、Dockerイメージの設計図。
Dockerfileというテキストファイルを作成することで、Docker Imageを作ることが出来る。

## Dockerfileからイメージを作成する

```
//Dockerfileからイメージを作成する
docker image build [ディレクトリパス]

//イメージに名前をつける
docker image build -t [ディレクトリパス]

```


## 参考サイト
[初心者OK！Docker入門＋応用：ゼロからでも実務で使えるスキルが身に付ける](https://itplusjp.udemy.com/course/ok-docker/learn/lecture/36659198#overview)
[【初心者向け】Dockerfileとは](https://aiacademy.jp/media/?p=1386)
5月のフロントエンド開発

# 5月はどんな月だったか
フロントエンド開発に関わって４ヶ月目。こう聞くと意外と時間経ってるなと感じるが、できることはまだまだ少ない。プログラミング自体触りはじめてまだ8ヶ月くらいなんで仕方ない。そこから考えると、8ヶ月でよくアルバイトでプログラム書いて、まあまあそれっぽいことをやらせてもらえてることが驚きである。今月からはまあまあそれっぽいことをやって、苦労しながらなんとかこなしたという感じだった。ある意味で、エンジニア職の洗礼を浴びたと言えるのかもしれない。


## ボタン連打防止
これは個人的にはやばいバグランキング上位入賞作品だと思っている。決済実行ボタンを連打すると、押した分だけ決済が発生してしまうという、こんなことが起きてしまうのか、、、というバグだった。

```JavaScript:JS
export const Pay = () => {
    const [completeModal, setCompleteModal] = useState(false)

    const [formDisabled,setFormDisabled] = useState(false)
    
    const onSubmit = () => {
        setFormDisabled(true);
        changeOrderPayInformation({
          variables: {
            input: {
              arguments: {
             //略
              },
            },
          },
        })
          .then(() => {
            setCompleteModal(true)
          })
          .catch(() => {
            setFormDisabled(false)
          })
      }
    
    　　　　return (
        <>
            <Button type="submit" size="lg" 
            bgColor={color} textColor="white" 
            disabled={formDisabled}>
                 <span>提出</span>
            </Button>
        </>
    )
}
```

ポイントはuseState()とエラーハンドリング。
promiseを使った非同期処理をしています。まだちゃんと自分も理解していないので、今後非同期処理についてもまとめたい。

#### 流れ
1. submitが起きたら、`setFormDisabled(true);`でとりあえずボタンを無効化。
2. onSubmitの処理が成功したら`setCompleteModal(true)`で完了モーダル表示。失敗したら`setFormDisabled(false)`でボタンを有効化。




## 空のオーダーで注文できてしまう
お金が絡むものは早急に対処すべき。商品数が0なのに注文できてしまうバグだった。結果的に何が起きるかというと、商品何も買っていないのに送料だけかかってしまい、お賽銭してしまうことになる。

でも確かに、何も考えなければこの現象は大いに起こりうる。違和感のないWEBサービスというのは、細かいところに数多くの気配りがされているのだなと感じた。
　
　
#### やったこと
```JavaScript:JS
  const cartItemsCount = cart.reduce((sum, { quantity }) => sum + quantity, 0)
  useEffect(() => {
        if (cartItemsCount === 0) {
          navigate('決済ページじゃない、安全なページ')
        }
 },[])
```

方針としては、カート内の商品数が０の場合に決済ページに入った場合は、安全なページへ遷移するように実装した。
一つ問題があって、if文をそのまま置いても実行されなくて、試しにuseEffectの中にif文を入れると期待する動作が確認できた。お恥ずかしい話、なんでuseEffectでちゃんと動くようになったのかが全くわからない。stateは周りで使われていなそうなので、再レンダリングはそこまで問題にならなさそうなのだが、なぜかuseEffectで解決されてしまった。

そこがわからないのも良く無いので、可能性の話でもいいので、こうだからじゃない？っていう思い当たる点があれば教えていただきたいです。　(全体のコード載せて無いのでアドバイスするのも難しいと思いますが、すみません、、、)


## まとめ
5月、本当はもうちょっとやったのですが、実は書いてるのがもう6月後半でして、記憶が薄れてしまっているのでこの辺までにします。鮮度が高いうちにアウトプットすることを心がけます。
約束として、promiseを使った非同期処理の理解がまだ浅いので、近いうちにまとめます！
自分のためだけにまとめる、よく使うgitコマンドたち（ブランチ作成・commit取り消し）

## はじめに
ここ1年くらい時々Gitを使っていますが、使うコマンドは限られているのに全然覚えられないことに気づきました。
自分の業務の流れに合わせてgitコマンドを並べておきます。

## 初めのGitコマンド

-ブランチの一覧を見る
```git branch```

-ブランチの一覧を見る（リモート含む）
```git branch -a```

-ブランチの切り替え（存在するブランチ）
```git checkout <ブランチ名>```

-ブランチを作成する（ローカルブランチから作成する場合は上、リモートブランチから作成する部分は下）
```git checkout -b <ブランチ名>```
```git checkout -b <ローカルでのブランチ名> origin/<リモートブランチ名>```
※ローカルからブランチを作成する場合は、git branchで今いるブランチを確認してcheckoutすること。

-ブランチをリモートに登録する
```git push -u origin <作成したブランチ>```

## 修正するブランチを間違った場合の修正コマンド
-修正を退避する。
```git stash```

▼参考にさせていただきました（個別でstashする）▼

https://qiita.com/yukitaka13-1110/items/935bfa233c6e024f82dc

## Commit先を間違った場合の修正コマンド
-コミットID等を確認する。
```git log```

-Commitを取り消す
```git revert <コミットid>```
※Commitを取り消して、再度正しい先にcommitしたい場合は更にrevertする必要がある。
※マージしてしまっている場合は、オプション-mを使用する。
※revertし終わったら、一度pushを行ってリモートブランチに反映せる必要がある。

-pushする
```git push origin <ブランチ名>```

参考: https://chooringo.hatenablog.com/entry/2017/03/26/225718
【Salesforce】LWC参考サイト

## 目的
すごい人達が作ったLWC、何か色々参考できるところがあるので、共有したいと思います。
サイトのイメージは下記となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1767576/1f3de210-0357-da89-ffb1-810f994156bb.png)


## 参考

https://www.awesomelwc.com/
ls

ファイル名が＼ａａａ
エスケープシーケンス＼を使う、または、シングルクォートで囲むことで＼を表現できる
```sample.sh
#!/bin/sh -v
   ls *aaa* -l
   ls ~/\\aaa
   ls ~/'\aaa'
   ls ~/\aaa
```
```
#!/bin/sh -v
   ls *aaa* -l
-rw-rw-r--. 1 linuxstudy linuxstudy 0  6月 28 03:29 \aaa
   ls ~/\\aaa
/home/linuxstudy/\aaa
   ls ~/'\aaa'
/home/linuxstudy/\aaa
   ls ~/\aaa
ls: /home/linuxstudy/aaa にアクセスできません: そのようなファイルやディレクトリはありません

シェルが値を返しました 2

```
1. ファイルタイプ

ls -lで表示される10桁の記号のうち1桁目はファイルタイプを表します。

ファイルタイプを表す記号の種類は以下の7つです。
記号 	ファイルタイプ
b 	ブロックデバイス(Block special file)
c 	キャラクタデバイス(Character special file)
d 	ディレクトリ(Directory)
l 	シンボリックリンク(Symbolic link)
s 	ソケット(Socket link)
p 	名前付きパイプ(FIFO)
\- 	通常ファイル(Regular file)