OmniAICreator/Qiita-1.07M huggingface dataset:
Kubernetes と Microk8s の概要

### Kubernetes について知る

大部分は、<u>[David Tippet](https://blog.tippybits.com/installing-kubernetes-in-virtualbox-3d49f666b4d6)</u> のチュートリアルに従いました。
virtualbox に microk8s のポートをインストールして正しく構成するため。<br/>

Ubuntu 22.04 LTS を使用してチュートリアルに従ったところ、すべてが期待どおりに機能しました。<br/>
唯一の変更点は、MicoK8s トークンの取得方法です。<br/>
そのために、このコマンドでそれを行いました<br/>
`microk8s config`

### Hello World デプロイを行う
Docker イメージをデプロイする方法を理解するために、microk8s の公式ドキュメントからの簡単なチュートリアルがあります<br/>
<u>[Kubernetes の最初のサービス](https://ubuntu.com/tutorials/install-a-local-kubernetes-with-microk8s#5-host-your-first-service-in-kubernetes)</u ><br/>
このチュートリアルでは cli を使用してデプロイを行いますが、これらの手順ではダッシュボード自体から行うことができます<br/>

#### ダッシュボードにログイン
kubernetes ダッシュボードにログインしたら、左側のメニューで「<デプロイ>」に進みます。<br/>
ここから、右上の「<新しいリソースを追加>」ボタンをクリックします。<br/>

<img oncontextmenu="return false;" src="https://media.publit.io/file/w_1280/microk8s_1.png" srcset="https://media.publit.io/file/w_320/microk8s_1.png 320w、https://media.publit .io/file/w_640/microk8s_1.png 640w、https://media.publit.io/file/w_1024/microk8s_1.png 1024w、https://media.publit.io/file/w_1280/microk8s_1.png 1280w"サイズ="(最大幅: 710px) 100vw,40vw" alt="microk8s_1" />

フォームに入力し、docker イメージをコンテナー イメージの「イメージ + タグを使用」します。この例にはタグがないため、docker はランダムにタグを生成し、ポートを 80/80 に設定します。<br/>
<img oncontextmenu="return false;" src="https://media.publit.io/file/w_640/microk8s_3.png" srcset="https://media.publit.io/file/w_320/microk8s_3.png 320w、https://media.publit .io/file/w_640/microk8s_3.png 640w" サイズ="(最大幅: 710px) 100vw,40vw" alt="microk8s_3" />

ここから、フォームの残りの部分に入力し、`<Show Advance Configuration>` をクリックして、配置のnamespaceを `default` に変更します。<br/>

<img oncontextmenu="return false;" src="https://media.publit.io/file/w_640/microk8s_4.png" srcset="https://media.publit.io/file/w_320/microk8s_4.png 320w、https://media.publit .io/file/w_640/microk8s_4.png 640w" サイズ="(最大幅: 710px) 100vw,40vw" alt="microk8s_4" />

すべてが正しければ、`<deploy>` ボタンをクリックして ssh cli に移動し、namespace コマンドを実行します。<br/>
`microk8s kubectl get all --all-namespaces`.<br/>
これにより、すべての名前空間が一覧表示され、kubernetes によって指定されたポートを持つ新しい「ポッド」が表示されます。<br/>
<img oncontextmenu="return false;" src="https://media.publit.io/file/w_1024/microk8s_6.png" srcset="https://media.publit.io/file/w_320/microk8s_6.png 320w、https://media.publit .io/file/w_640/microk8s_6.png 640w、https://media.publit.io/file/w_1024/microk8s_6.png 1024w" サイズ="(最大幅: 710px) 100vw,40vw" alt="microk8s_6" />
<br/>
このポートを virtual-box のポート転送のリストに追加すると、kubernetes ノードから実行されている「hello world」docker を確認できるようになります。
<img oncontextmenu="return false;" src="https://media.publit.io/file/w_640/microk8s_7.png" srcset="https://media.publit.io/file/w_320/microk8s_7.png 320w、https://media.publit .io/file/w_640/microk8s_7.png 640w" サイズ="(最大幅: 710px) 100vw,50vw" alt="microk8s_7" />
ブラウザに「hello-world」メッセージが表示されるはずです
<img oncontextmenu="return false;" src="https://media.publit.io/file/microk8s_8.png" alt="microk8s_8" />

メッセージが表示されない場合は、microk8s 仮想ボックスでプロキシを再起動します。
OpenCVとpyzbarを使ったQRコード読み取りアプリをPyinstallerでexe化する

# はじめに
ふと、「カメラの画角の中にQRコードが映ったときに、その時刻と内容をロギングできるアプリ」を、そのへんのWindowsPCで実行させといて現場に放り投げておきたいという衝動にかられたので作りました。

# ライブラリの準備
当方、pipenvで仮想環境を切っているのでとりあえず以下で設定
```shell
pipenv --python 3
pipenv install pyinstaller numpy pyzbar opencv-python~=4.5.3.56
```
※現段階では、opencv-pythonのバージョンを上述に揃えないとうまく行かないそうです、１ハマり

https://stackoverflow.com/questions/69855356/recursion-is-detected-during-loading-of-cv2-binary-extensions/70109102#70109102

# コード
以下を参考にしました

https://laboratory.kazuuu.net/creating-a-webcam-qr-code-scanner-in-python-using-opencv/


# exe化後に実行するとdllが足りない問題

一度、.pyファイルをexe化して、何度か実行を繰り返したところ、「`libiconv.dll`がみつからない」とか「`libzbar-64.dll`がみつからない」とかいうエラーになりました。

```shell
#1回目
（中略）
pyimod03_ctypes.install.<locals>.PyInstallerImportError: Failed to load dynlib/dll 'C:\\Users\\<<<USERNAME>>>_~1\\AppData\\Local\\Temp\\_MEI232402\\pyzbar\\libiconv.dll'. Most likely this dynlib/dll was not found when the application was frozen.
[8952] Failed to execute script 'read_qr_with_camera' due to unhandled exception!
```

```shell
#2回目
（中略）
pyimod03_ctypes.install.<locals>.PyInstallerImportError: Failed to load dynlib/dll 'C:\\Users\\<<<USERNAME>>>_~1\\AppData\\Local\\Temp\\_MEI232322\\pyzbar\\libzbar-64.dll'. Most likely this dynlib/dll was not found when the application was frozen.
[13688] Failed to execute script 'read_qr_with_camera' due to unhandled exception!
```

.specファイルをエディタで開き、以下を追加。dllファイルのパスはエクスプローラとかで検索して調べる。
```python
a = Analysis(
    (～～中略～～）
    binaries=[(r'.\.venv\Lib\site-packages\pyzbar\libiconv.dll', '.'),(r'.\.venv\Lib\site-packages\pyzbar\libzbar-64.dll', '.')],
    (～～中略～～）
)
```

## Pyinstallerで作成したexeファイルのカレントディレクトリ
もし相対パスでファイルの入出力がどうしてもしたい場合は以下を参照

https://qiita.com/pm00/items/044d7fb92e11dafb749c

# おわりに
まさかこんなところでバージョンの相性問題と出くわすとは思わなかった。
また、いまさらpyinstallerでexe化するのも流行らないとは思いますけど、まぁそこはね…。
解像度のせいで微妙に識別率が悪いのが難点。というかいまどきのWEBカメラは全部広角過ぎて遠くのQRコードは読めない、というかそもそもQRコードは遠距離から読み取るものじゃない。ARマーカってしゅごい。
Falco Ruleを紹介するシリーズ - Contact EC2 Instance Metadata Service From Container

本シリーズでは、ランタイム脅威検知のデファクトスタンダードである<a href=https://falco.org/ target=new>Falco</a>の検知Ruleを、１つの記事で１つ簡単に紹介していきます。
ランタイムセキュリティやFalco自体の概要を知りたい方は<a href=https://sysdig.jp/blog/intro-runtime-security-falco/ target=new>こちらのブログ記事</a>をご参照ください。
今回ご紹介する検知Ruleは<b>「Contact EC2 Instance Metadata Service From Container」</b>です。
# Rule記述
```
- rule: Contact EC2 Instance Metadata Service From Container
  desc: Detect attempts to contact the EC2 Instance Metadata Service from a container
  condition: outbound and fd.sip="169.254.169.254" and container and not ec2_metadata_containers
  output: Outbound connection to EC2 instance metadata service (command=%proc.cmdline connection=%fd.name %container.info image=%container.image.repository:%container.image.tag)
  priority: NOTICE
  tags: [network, aws, container, mitre_discovery]
```
# Rule概要
コンテナ上からEC2インスタンスのメタデータサービスに問い合わせがあったことを検知します。
EC2インスタンスでは、 169.254.169.254 はメタデータを取得するための特別なIPとして使用されます。
攻撃者はコンテナに侵入した後、ラテラルムーブメントのための情報収集としてメタデータサービスを利用することがありますが、このRuleを使うことで検知可能です。
クラウドにおけるラテラルムーブメントについての詳細は、こちらの<a href=https://sysdig.jp/blog/lateral-movement-cloud-containers-2/ target=new>ブログ記事</a>をご参照ください。

# Condition（条件）
`outbound and fd.sip="169.254.169.254" and container and`
コンテナ上での169.254.169.254に対するアウトバウンド接続で、

かつ

`not ec2_metadata_containers`
あらかじめ定義した、EC2メタデータへのアクセスを許可したコンテナではない場合

---

containerマクロの内容は以下となります。
```
- macro: container
  condition: (container.id != host)
```
`container.id != host`
コンテナidがhostではない場合
※イベントがコンテナ内部で発生したのでなければ、idはhostと設定されます

# Output（出力）
EC2インスタンス・メタデータ・サービスに対するアウトバウンド接続

`%proc.cmdline`
コマンドライン

`%fd.name`
接続名

`%container.info`
コンテナ情報

`%container.image.repository`
コンテナイメージリポジトリ

`%container.image.tag`
コンテナイメージタグ
MariaDBで文字列が整数かどうかをかなり厳密に判定

# やり方（0以上の整数かどうか判定）

```sql:正規表現を使った判定
SELECT '判定対象文字列' REGEXP '^(0|[1-9][0-9]*)$';
```

| 判定対象文字列 | 判定結果 | 備考 |
|--|--|--|
| あいうえお | FALSE |  |
| 12あいうえお | FALSE |  |
| e12 | FALSE |  |
| 12.1 | FALSE |  |
| 12.0 | FALSE | 見た目上は整数として扱えても、末尾に『.0』があるのでFALSE。 |
| 01 | FALSE | 見た目上は整数として扱えても、先頭に『0』があればFALSE。 |
| 012 | FALSE | 見た目上は整数として扱えても、先頭に『0』があればFALSE。 |
| -12 | FALSE |  |
| 00 | FALSE | 見た目上は整数として扱えても、『0』が複数繰り返されるだけの構成はFALSE。 |
| 0 | TRUE | 『0』が1文字だけならTRUE |
| 1 | TRUE |  |
| 9 | TRUE |  |
| 10 | TRUE |  |
| 10000000 | TRUE |  |

# なぜCAST()ではなく正規表現を使うのか

```CAST()``` を使うと想定通りの判定にならない為。

**```CAST('判定対象文字列' AS SIGNED) = 0``` なら 整数ではない**
というやり方だと想定通りの判定にならない場合がある。

例えば下記の結果は『0』ではなく『12』となってしまう。
先頭の『12』という文字列でキャストが成功してしまう。

```sql
SELECT CAST('12です' AS SIGNED);
```

演算コストはかかってしまうが、厳密に判定したいなら正規表現。

# やり方（1以上の整数かどうか判定）

0をFALSEとしてよいなら正規表現パターンを少しシンプルにできる。

```sql
SELECT '判定対象文字列' REGEXP '^[1-9][0-9]*$';
```

# やり方（-1や-10などの負もTRUEにしたい場合）

『-0』をFALSEにする為、マイナス記号を ```[1-9][0-9]``` 側に置くのがポイント。

```sql
SELECT '判定対象文字列' REGEXP '^(0|\-*[1-9][0-9]*)$';
```

# 参考サイトさん

https://hamalabo.net/mysql-isnumeric

https://www.object-lab.co.jp/it/1957/

# バージョン

Windows 10 Pro 21H2 OSビルド 19044.1889
10.5.4-MariaDB

TODO:この記事の正規表現のロジックについて解説を載せておく
iOSバージョンアップ後にXcodeをアップデートせずにデバッグをする方法

# 目次
1. はじめに
1. 対応バージョン
1. 解決方法


# はじめに
新しいiOSのバージョンにアップデートを行った後、
Xcodeでビルドをしようとすると、
>Could not locate device support files

>The run destination [端末名] is not valid for Running the scheme ‘[スキーム名]’.

などのエラーがXcode上に表示され、
バージョン不一致の影響でビルドができなくなることがあります。

# 対応バージョン
Xcodeと端末のバージョンの正確な組み合わせについては、  
Apple公式に対応バージョンが公開されているため、
対応のバージョンにアップデートを行うようにしてください。
▶︎[最小要件とサポートされるSDK](https://developer.apple.com/jp/support/xcode/)

# 解決方法
ただし、毎回アップデートをしなくても簡単にバージョン対応ができる方法があります。
以下のサイトがわかりやすかったので、参考にしてみてください！

https://sussan-po.com/2019/10/12/new-ios-device/

:::note warn
※注意
**2022年4月以降、アプリ審査の提出時にはXcode 13ビルドが必須になります。**
Apple審査を提出する方は、こちらを適宜チェックして必要に応じてバージョンアップをするようにしましょう。

https://developer.apple.com/jp/ios/submit/
>2022年4月以降、App Storeに提出するiOS Appはすべて、Xcode 13およびiOS 15向けのSDKを使用してビルドする必要があります。
:::


# まとめ
iOSのバージョンアップは頻繁に発生するので、
是非今回の方法を役立ててくださいね:relaxed:！
Javaで同時実行スレッド数を制御するコンポーネントを作ってみた

訳あって同時実行数を制御する処理が必要そうなので・・・Javaで実現するとしたら「こんな感じかな〜」というのを作ってみました。完全に個人メモです。

もっと良いやり方や、OSSのこれ使えば同じことできるよ〜みたいなのあれば是非コメントを！！

# やりたいこと

* 同時に処理を行うスレッド数(=最大同時実行スレッド数)を指定できること
* 「最大同時実行スレッド数」に達している際は空きがでるまでキューインングできること（＋キュー数も指定できること）
* キューイング状態で待つ最大時間（=無限に待たないようにタイムアウト）を指定できること
* 「最大同時実行スレッド数」＋「キュー数」を超える状態を検知したら拒否時の処理を実装できること

# 作ってみたコンポーネント

```java
package com.example;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;

public class ConcurrencyControlTemplate {

  private final Semaphore semaphore;
  private final BlockingQueue<Thread> permittedThreads;

  private long queueingTimeout = 30000;
  private TimeUnit timeoutUnit = TimeUnit.MILLISECONDS;

  public ConcurrencyControlTemplate(int concurrency, int queueSize, boolean fair) {
    this.semaphore = new Semaphore(concurrency, fair);
    this.permittedThreads = new LinkedBlockingQueue<>(concurrency + queueSize);
  }

  public void setQueueingTimeout(long queueingTimeout) {
    this.queueingTimeout = queueingTimeout;
  }

  public void setTimeoutUnit(TimeUnit timeoutUnit) {
    this.timeoutUnit = timeoutUnit;
  }

  public void execute(Runnable task, Runnable dinedHandler) {
    executeWithResult(() -> {
      task.run();
      return null;
    }, () -> {
      dinedHandler.run();
      return null;
    });
  }

  public <T> T executeWithResult(Supplier<T> task, Supplier<T> dinedHandler) {
    boolean shouldRelease = false;
    Thread current = Thread.currentThread();
    T returnValue;
    if (!permittedThreads.offer(current)) {
      return dinedHandler.get();
    }
    try {
      if (semaphore.tryAcquire(queueingTimeout, timeoutUnit)) {
        shouldRelease = true;
        returnValue = task.get();
      } else {
        returnValue = dinedHandler.get();
      }
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      returnValue = dinedHandler.get();
    } finally {
      permittedThreads.remove(current);
      if (shouldRelease) {
        semaphore.release();
      }
    }
    return returnValue;
  }

}
```

# 作ったコンポーネントの使い方

```java
ConcurrencyControlTemplate concurrencyControlTemplate = new ConcurrencyControlTemplate(
    8, // 同時実行を許可するスレッド数
    8, // 同時実行を許可するスレッド数を超えている際にキューイングするスレッド数
    true // 実行権を与える順番を厳密に制御するか否かを指定(true: 厳密に制御する、false: 厳密に制御しない)
);
concurrencyControlTemplate.setQueueingTimeout(10); // キューイング状態で待機を続ける最大時間(例：10秒) ※デフォルトは30秒
concurrencyControlTemplate.setTimeoutUnit(TimeUnit.SECONDS);

concurrencyControlTemplate.execute(() -> {
  System.out.println("同実行制御下で行う処理を実装する");

  // ...

}, () -> {
  System.out.println("キューを含む同時実行上限を超えた時の処理（＝リクエスト拒否時に処理）を実装する");

  // ...

});
```

# 参考にしたもの

* Tomcatの「[SemaphoreValve](https://apache.googlesource.com/tomcat/+/refs/heads/9.0.x/java/org/apache/catalina/valves/SemaphoreValve.java)」

# 補足

APサーバや各種サーバ機能の設定で最大スレッド数やキュー数を指定できるものの、リジェクト時の動作が期待通りでなかったり・（思ったように）カスタマイズできないものが多かったので・・・自分で作ってみました。
２年間振り返り

## はじめに
自分は2年半前まで無職で海外放浪していました。そんな自分が会社に就職してからエンジニアとして働く現在に至るまでを振り返ってみました。

## 前職
某大学の数学科を5年で卒業(全然大学行ってない...)
→ガス会社の営業職に新卒で就職
→無職
→塾講師などフリーター
→期間工として工場労働
→東南アジアのあたりを無職で放浪

という、基本エンジニアとは全く関係ないことを色々としていました。ちなみに正社員期間は9ヶ月です。そんな自分をアルバイトとして雇って頂けたのが現在の会社でした。

## エンジニアになる為にやっていたこと
コロナの流行により日本に戻ってきてから、3ヶ月ほどプログラミングの勉強を独学で行っていました。ただ身につけたことといえば、本当に基本的なfor文やif文などの理解くらいで、初心者によくあるpyhonで簡単なプログラムを書いてみる程度のことしかできませんでした。自力でサービスをリリースするなどというレベルとは程遠い感じでした。エンジニアとしてプロダクトを開発するモチベーションだけはあったのですが、今振り返るとあんなレベルでIT関係に就職できたのはラッキー中のラッキーでした。

## 2ヶ月目
一応エンジニアになれる前提で入社したものの、経験があまりになさ過ぎたので入社してからの２ヶ月間は開発とは関係ないサービス運営業務を行っていました。仕事後にドットインストールやUdemyを用いて毎日iOS開発の勉強をしていました。ちなみに入社して初めてmacを触りました。

## 8ヶ月目
開発業務のはじめは、半年ほどiOSの修正業務を行っていました。このとき会社の主力アプリは基本的にObjective-Cで構成されており、初心者の自分はこの言語仕様やレガシーなプログラムに結構苦しめられました。

半年やるとUiKit周りのことや、ビジネスロジックの修正方法についてなんとなく理解してきました。ただこのときはまだREST APIの構造をあまり理解できておらず、自分は取得したデータを整形して修正するくらいのことしかしていませんでした。

この頃会社のiOSアプリは肥大化したMVCでしたが、自分はアーキテクチャや巷でよく言われること(DRY,SOLID原則など)について殆ど理解がありませんでした。
従ってアプリを動かすことはできていましたが、可読性や作業スピードはあまり良くなく、バグを含んだアプリのリリース率は現在よりかなり高かったように思います。
またiOSを修正していたノリで、Androidの修正や新機能の実装も行うようになりました。

## 1年目
この頃になると、徐々にAPIサーバーの修正に関わるようになっていました。REST APIの構造も理解して、新しいAPIの作成をなんとなく一人でやり始めたのもこのあたり(のはず)でした。

このころ正直APIサーバーの構造はいまいちわかってなかったのですが、なんとなくのノリでも修正させてもらえたことで、理解が進んだと思います。勿論リスクはあったとは思いますが。

この頃は自宅でも友達とアプリ開発しており、SwiftとJavaを触っている時間が長かったです。

## 1年目半
この頃にはインフラ周りを少しずつ触り始めました。AWSの管理画面からステージング用のインスタンスを作成したり、簡単なWebアプリケーションの作成をEC-2から行ったりしました。

またWeb周りの修正もなんとなく行っていました。Angular-JSやCake-phpのフレームワークで作成された管理画面やクライアントアプリの修正、DB操作を行わない簡単なWebアプリケーションをEc-2からSpring Bootを使って作成するなどのことをやってました。

サービスを吹っ飛ばすリスクを考えると、本当によく触らせてくれたなという感じです。

また、この頃くらいにようやくアプリのアーキテクチャや巷でよく言われていることを何となく理解するようになりました。ちなみにMVC以外のアーキテクチャを触ったのも初めてでした。このくらいの時期で、なんやかんやの都合により開発リーダーになりました。

## 2年目
この頃会社で爆速で新規アプリを開発しなければいけないフェーズになってしまい、一時期はiOSを割と新規実装してました。以前よりは早く、多少はマシなコードを書くようになりました。アーキテクチャとかは後からのリファクタリングで入ったようです(自分はMVCでViewとModelの切り分けだけは意識しながら書いてました)。

それが落ち着いた後は、DBまわりの処理の高速化や長く発生しているバグやエラーの修正を行うようになりました。その後はバックエンド側の仕事が多めです。
特にバックエンドの仕事では負荷や速さ、料金、セキュリティなどを多少意識し始めるようになりました。

## 現在(約2年半)
主にAPIサーバー周りの修正やインフラ周りの仕事を行うようになりました。サイズが大きい処理の修正や、インフラまわりを修正する際にはまだまだリスク想定が足りていないと感じている今日このごろです。

## 今後
個人としては、きちんと問題を構造化して切り分ける思考をできるようになることが今後の目標です。具体的には、全く知らないことでも自力でググってテストを考えて抜け漏れなくリスク想定しながら修正できるようになることです。険しい感じはしますが。

あとは問題解決にする際に、もっとチーム全体にとってのリソース・リスクなどを考慮できるようにならなきゃなと感じています。これも習慣化していかなきゃですね。

## 最後に
最近会社に新しい人が増えているので、自分が経験してきたことをざっくり書いてみました。今後の自分を想像してもらう参考になると良いかもしれません(かなりニッチ)。他の会社のキャリアデザインはよくわかりません。

なにはともあれ、今後も少しずつ精進していこうと思います。以上。
AWS Lambdaとは

# AWS Lambdaとは
AWS Lambdaは、**データやリクエストのリアルタイム処理やバックエンドの処理を、自動的に実行する仕組み**。このような処理のために専用のサーバーを準備や管理する必要がない。必要なイベントに応じて自動実行される。常駐サーバーとは異なり、プログラムの実行時のみに課金される。
**Lambda関数**と呼ばれる形式の関数を用いますが、これは新しい言語ではない。
よく知られるプログラミング言語で書いたコードをもとに「Lambdaコンソール」などを用いてグラフィカルに作成できる。使える言語は、java,C#,Python,Ruby,Node.js,Goなどで、よくある目的のためのテンプレートも揃っている。
Lambda関数は、Lambdaサービスに保存される。
何かのトリガーで、特定のAWSリソースにおいて実行される。有名な例は、S3バケットに画像が置かれると、サムネイル実行関数が呼び起こされ、サムネイル作成関数が呼び起こされ、サムネイルを自動的に作成する例。
# Lambdaの用語
Lambdaは、プログラムのコードをLambdaサービスにアップロードしておくと、特定のAWSサービスで実行できる仕組み。**アップロードするプログラムコードをLambda関数という。**
|項目|内容|
|-|-|
|イベント駆動|S3にファイルが置かれた、DynamoDBにデータが書き込まれた、SES(System Engineering Service)にメールが届いたなど、AWSサービスに何かが生じた時に、Lambdaのプログラムを実行できる。|
|CGI代わりのLambda|API Gatewayと組み合わせると、WebのCGI（Common Gateway Interface）のように使える。|
# イベントソース一覧
Lambdaを呼び出す方法は３つある。
有名なのは、S3やSES、API Gatewayと組み合わせるパターン。
SES（Amazon Simple Email Service）は、メールを受信した時にアクションを起こすといった形で使う。
API Gatewayは、WebブラウザなどからAPIが呼び起こされたりした時に何らかの処理を実行するといった形で使用する。
## Lambdaを呼び出せるサービス
### Lambdaがイベントを読み取るサービス
* Kinesis
* DynamoDB
* SQS
### Lambda関数を同期的に呼び出すサービス
* ELB
* ALB
* Cognito
* Lex
* Alexa
* API Gateway
* CloudFront
* Kinesis Data Firehose
### Lambda関数と非同期的に呼び出すサービス
* S3
* SNS
* SES
* CloudFormation
* CloudWatch Logs
* CloudWatch Events
* CodeCommit
* Config

# Lambdaの料金
Lambdaの料金は「単価 × 実行時間(秒単位)」。
単価はLambdaで確保するメモリによって異なる。
【エラー解決方法】devise_token_authエラー(Rails7)の対応について

### エラー内容
```
gem 'devise'
gem 'devise_token_auth'
```
Gemfileに上記の2つを追加して
```
$ bundle
```
を実行すると
```
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies....
Bundler could not find compatible versions for gem "rails":
  In snapshot (Gemfile.lock):
    rails (= 7.0.3.1)

  In Gemfile:
    rails (~> 7.0.3, >= 7.0.3.1)

    devise_token_auth was resolved to 0.1.21.alpha2, which depends on
      rails (~> 4.1.4)

Running `bundle update` will rebuild your snapshot from scratch, using only
the gems in your Gemfile, which may resolve the conflict.
```

### 解決方法
方法は以下の2通り
1.device_token_authを使えるようにrailsのバージョンを下げる

2.device_token_authの代わりになるgemを使用する

今回はrailsのバージョンを下げたくないので、2を採用

Gemfileに以下のように`devise_token_auth`を追加する

```
gem 'devise_token_auth', '>= 1.2.0', git: "https://github.com/lynndylanhurley/devise_token_auth"
```

### 補足
- rubygemsに上がっているdevise_token_authがRails7をサポートしていないためインストールができない
- githubに上がっているdevise_token_authはRails7をサポートしているので、インストール出来る
- 1を採用する場合は以下の記事を参考にしてみてください
https://qiita.com/sssssatou/items/054006c3fed544a7aebc
Power BI サービスでワークスペース内のレポートの使用状況を一覧する

Power BI サービスのレポートには、「使用状況メトリック」という、「誰に、どのページが、どのくらい見られているか」が分かるレポートを作る機能があります。詳しい説明は省きますが、下図のようなレポートです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668909/8f0f3ff5-df98-2964-38a3-12315b2a3e55.png)
最初に開くページより、「Report list」ページの方が、管理者の方は興味があるかもしれません。ワークスペース内のレポート全体についての利用状況が分かります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668909/703d6b07-adfd-2ec5-70ec-fde9542c897a.png)
ワークスペースを開いて、レポートの[･･･]メニューから「利用状況のメトリック レポートを表示」をクリックするだけです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668909/4d54a1f0-5e80-edf8-d292-d63e342d5e76.png)
もうタイトルの内容はカバーできてしまいました。これだけじゃつまらないので、ちょっとカスタマイズします。

この「使用状況メトリック」ですが、このままだと「Report Usage」と「Report performance」ページが、作成元のレポートの情報だけになってしまいます。
[フィルター] ペインを開いて **[ReportGuid] にかかっているフィルターをクリアすることで、ワークスペース内のすべてのレポートを対象にすることができます。**

さらにレポートを編集して、「Report list」ページのレポート一覧から、「Report usage」と「Report performance」ページに**ドリルスルー**出来るようにします。

:::note
「**ドリルスルー**」とは、選択したセルやグラフのデータを引き継いで、別の画面に遷移することです。
Power BI では同じレポート内の別のページや、異なるレポートのページにドリルスルー出来ます。
詳細は Docs をご覧ください。
[レポート ページのドリルスルーの使用](https://docs.microsoft.com/ja-jp/power-bi/guidance/report-drillthrough)
[Power BI でレポート間のドリルスルーを使用する](https://docs.microsoft.com/ja-jp/power-bi/create-reports/desktop-cross-report-drill-through?tabs=powerbi-desktop)
:::

1. [ファイル]→[コピーの保存]をクリックし、任意のワークスペースに名前を付けて保存します。
2. 画面右上に下図のようなダイアログが表示されるので、[レポートに移動]します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668909/63f9db93-bc75-03cf-79cc-79b0e2d048af.png)

3. [編集]ボタンをクリックします。
4. [フィルター]ペインを開き、[すべてのページでのフィルター]の「ReportGuid」をクリアします。
4. 「Report list」ページの左下のレポート一覧表では「Workspace reports」の「ReportName」が使われているので、この列の値を条件にドリルスルー出来るようにします。
「Report usage」ページで[視覚化]ペインの一番下にある[ドリルスルー フィールド]に、フィールド一覧から「Workspace reports」の「ReportName」をドラッグ＆ドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668909/7716bdc0-04bf-c751-d7be-724a7c2dac13.png)
4. 「Report performance」ページも同様に、ドリルスルー フィールドの設定をします。
4. 「Report list」ページに戻ると、レポート一覧表で**右クリック**すると、ドリルスルーができるようになっていることが確認できるので、保存します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668909/f876045b-1706-979e-b6b0-21d7043619be.png)

ドリルスルーは、全体概要からより詳細を見せたい場合によく使う機能なので、ぜひ活用してください！

以下は注意事項です。

:::note info
- 使用状況メトリックを出力するには Power BI Pro または Premium Per User (PPU) のライセンスが必要です。 ただし、割り当てられているライセンスに関係なく、すべてのユーザーの利用状況情報が取得されます。
- レポートの使用状況メトリックにアクセスするには、そのレポートに対する編集アクセス権が必要です。
- Power BI 管理者が、コンテンツ作成者に向けて利用状況の指標を有効にしている必要があります。
:::
詳細は Docs をご覧ください。
[ワークスペースで使用状況メトリックを監視する (プレビュー)](https://docs.microsoft.com/ja-jp/power-bi/collaborate-share/service-modern-usage-metrics "ワークスペースで使用状況メトリックを監視する (プレビュー)")
よく見たら、Docs 内の画像と実物に差がありますね…。「プレビュー」と書かれているとおり、改善が加えられて、一部ドキュメントの内容と異なる部分もあるかと思います。
128.Promiseチェーンと並列処理

# Promise.all
## 並列処理
つまり、非同期処理に当たり同時に処理を行うこと
具体的には
1.関数の呼び出しを配列で一気に渡す
2.同時に処理を行う
これを応用して、以下のように-秒おきに関数を実行することができるようになります。
## setTimeout()をー秒おきに実行するには？
setTimeout()で-秒ごとに実行するには？
setTimeout(実行関数,インクリメント＊-秒おき)になる
## 反復について
Promise.all() メソッドは入力としてプロミスの集合の反復可能オブジェクトを取り、入力したプロミスの集合の結果の配列に解決される単一の Promise を返します。

1.resolveのvalに500を掛けていく
2.promise.all([呼び出すPromise入りの関数],[呼び出すPromise入りの関数])
3.thenの中のreturnに　Promise.all([sleep(2),sleep(3),sleep(4)])を返すと上記の処理が一度繰り返される
元データ
```js
function sleep(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log(val++);
      resolve(val);
    }, 1000 * val);
  });
}
// 追加
Promise.all([sleep(2),sleep(3),sleep(4)]).then(function(data) {
    console.log(data) //渡したデータが配列として一気に返ってきます [3,4,5]みたいに
    Promise.all([sleep(2),sleep(3),sleep(4)])
})
引数の流れ
```
![スクリーンショット 2022-09-08 18.22.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/714631/8cfaed8c-766c-d0dd-fe9d-ba5a0407b086.png)


# Promise.race
1.配列の1個目を呼んだ時点で値を返していく
function sleep(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log(val++); //2+1で3
      resolve(val); //2+1で3
    }, 1000 * val);
  });
}
// 追加
Promise.race([sleep(2),sleep(3),sleep(4)]).then(function(data) {
    console.log(data) //2+1で3
    return Promise.all([sleep(2),sleep(3),sleep(4)])
})
#### 使い分け
＊　まとめて配列で返す→Promise.all
＊　一個ずつ単体で返す→Promise.race
＊　一個ずつ単体で返す→Promise.race
# Promise.allsettle
1.Promise.allとおなじだが、rejectでも、catchに飛ばない仕様
→Promise.allSettled([sleep(2), sleep(3), sleep(4)])


```javascript
function sleep(val) {
  return new Promise(function (resolve, reject) {
    setTimeout(function () {
      console.log(val++);
      reject(val);
      // resolve(val)
    }, val * 500);
  });
}
//　all→allSettleに書き換える
Promise.allSettled([sleep(2), sleep(3), sleep(4)])
.then(function (data) {
  console.log(data);
}).catch(function(e) {
  console.error(e);
});
```
AWS Elemental MediaConvert とは

## 勉強前イメージ

Amazon Elastic Transcoder の後継だったはずだけど
何が違うのか・・・・

## 調査

### AWS Elemental MediaConvert とは

ブロードキャストグレードの機能を備えたファイルベースの動画変換サービスです。
ブロードキャストグレードとは、放送局レベルの品質で高い画質を保った動画に変換できます。
また、著作権の保護や多言語音声対応、字幕などの機能を備えてるものになります。

### AWS Elemental MediaConvert の特徴

- 高い動画変換のための機能が揃ってる

大規模なユーザー向けの配信などで使用されているAWS Elementalの技術をベースに作られている為
信頼性の高いサービスです。
また、上記でも記載の通り
グラフィックオーバーレイや著作権の保護、多言語音声や字幕などの機能が提供されています。

- 動画配信に適合する入出力形式に対応

ブロードキャスト用、インターネット配信用など様々な入出力形式のサポートを行っています。
4Kや8K解像度、HDRといった最新のビデオ規格にも対応します。
様々なサポートがあるため幅広い動画形式をサポートしています。

- 作業の自動化

プロビジョニングや管理などの作業を自動化できます。

- 信頼性

ジョブは複数のAZで分散されて実行され、モニタリングがされます。
またコンポーネントの機能が低下するとコンポーネントは交換されジョブは受け継がれます。
コンテンツの需要に合わせてリソースが自動的にプロビジョニングされてスケーリングが可能です。

## 勉強後イメージ

Amazon Elastic Transcoder の+α様々な機能がついたみたいな感じ？
4Kとかも扱えるのすごいね・・・・

## 参考

- [AWS Elemental MediaConvertとは？](https://www.acrovision.jp/service/aws/?p=2321)
- [AWS Elemental MediaConvertとは？動画処理サービス](https://www.skyarch.net/column/aws-elemental-mediaconvert/)
GitHub ActionsにLaraStanを追加する

## TL;DR
以下のソースをリポジトリの`.github/workflows/larastan.yml`に配置すれば導入できます。
このとき、ブランチ名の先頭が`TEST-`から始まるものだけ解析対象になります。

```yml:.github/workflows/larastan.yml
name: LaraStan
on:
  # GitHubにPushしたときに実行
  push:
    branches:
      # ブランチ名が"TEST-"で始まるもののみを対象とする
      - TEST-*

jobs:
  phpstan:
    # Ubuntuの最新版を利用する
    runs-on: ubuntu-latest
    steps:
      # リポジトリの最新ファイル1世代分だけをチェックアウト
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0

      # PHP環境のセットアップ
      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          # PHPのバージョンを7.4に指定
          php-version: '7.4'
          tools: composer, cs2pr
          coverage: none

      - name: Composer install
        run: composer install

      # setup-phpにphpstanはあるがLarastanがなさそうなので、個別にインストール
      - name: Larastan install
        run: composer require nunomaduro/larastan --dev

      # リポジトリの中で今回のPushで変更があったファイルだけを取得し、スペースでつなげた文字列を取得する
      - name: Get changed files
        id: changed-files
        uses: tj-actions/changed-files@v29.0.3

      # PHPStanを実行。解析レベルは10段階中最低の0とし、解析対象は上で取得したファイル名リストの変数を使う
      - name: Run PHPStan
        run: vendor/bin/phpstan analyze --memory-limit=-1 -l 0 -c vendor/nunomaduro/larastan/extension.neon  ${{ steps.changed-files.outputs.all_changed_files }}
```

## 解説
ほぼほぼコメントに書いてありますが、本GitHub Actionsの特徴を説明してきます。

- ブランチ名が`TEST-`で始まるときのみ`LaraStan`[^1]でコードを静的解析します。ブランチ名にだけ気をつければ、既存のブランチのプルリクを妨げない配慮です。すべてのブランチを対象にするのなら対象ブランチ名を`*`にすると良いでしょう。
  例）`TEST-hidao-top-page-layout-fix`
- PHPのバージョンは`7.4`を指定しています。これは`setup-php`プラグイン[^2]の[README](https://github.com/shivammathur/setup-php#readme)にある通り指定できます。
  PHPのバージョンによってはOSのバージョンを変更する必要があります。
- setup-phpプラグインには`phpstan`を入れるオプションはありますが、`LaraStan`を入れるオプションが無いようだったので、`composer`コマンドを叩いて直接インストールしています。
- pushしたときに変更のあったファイルだけを解析したいので、`changed-files`プラグイン[^3]で変更のあったファイルだけを抜き出しています。
- とりあえず導入したてなので、解析レベルを10段階中最低の`0`にしてます。リポジトリの成熟具合に合わせてレベルを上げていけばよいかと思います。

## 改善するなら
- `vender`ディレクトリ以下のキャッシュを持つようにしておけば処理時間が短くなると思われます。

[^1]: https://github.com/nunomaduro/larastan
[^2]: https://github.com/shivammathur/setup-php
[^3]: https://github.com/tj-actions/changed-files
【CSS】ついにChromeでもサポート！ :has() ってなに？

みなさん知ってますか？ `:has()`という擬似クラス。
私は存在は知ってたけど、サポートされてなすぎて泣き寝入りした記憶があります。

そんな`:has()`が、なんと先日のChromeのアプデ105でサポートされるようになりました！（firefoxではまだ使えないんだけどね）

# `:has()` ってなに？

`:hover`や`:not()`の仲間、**擬似クラス**です。

# 何ができるの？
`has = もっている` という意味の通り、 **子要素がある場合の指定ができます。**
下記の場合、
`.parent` の子要素に `.child` があると **`.parent`に`background-color: yellow;`を適用** します。なければ`background-color: pink;`になります。

```html:HTML
<div class="parent">
  <div class="child">.childあり</div>
</div>

<div class="parent">childなし</div>
```
```scss:SCSS
.parent{
  background-color: pink;
  &:has(.child){
    background-color: yellow; 
  }
 }   
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304162/67402669-d1ac-f18a-d793-0f2ace5cad0c.png)


# 実際にいつ使うの？
例えば下記のような`CSS Grid`で構成されたカードに指定すれば、さらに汎用的なカードとして使い回すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304162/a5204859-d3c7-4481-5fdc-9a6bd4cc3b3c.png)

ここでは、**画像がない時メインエリアの横並びをやめたい時に`:has()`を使用** しています。
```html:HTML
  <div class="card">
    <div class="card__header">
      <h2>画像がある時</h2>
    </div>
    <div class="card__main">
      <p>メインエリア</p>
    </div>
    <div class="card__image">
      <img src="~.png" alt="">
    </div>
    <div class="card__footer">
      <p>フッター</p>
    </div>
  </div>
```

```scss:SCSS
.card{
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: 20px auto 20px;

  &:has(&__image){ // 子要素に.card__imageがある時
    grid-template-columns: 1fr 100px;
  }
}
```

今まではこの構造の場合は、クラスを増やすか、構造を変える必要がありました。
でも`:has()`を使えば子要素のクラスの有無を判定して、`.card__image`クラスがあるとき用の指定する事が可能になるのです。


<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="eYrJgvy" data-user="himeka223" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/himeka223/pen/eYrJgvy">
  Untitled</a> by himeka223 (<a href="https://codepen.io/himeka223">@himeka223</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# サポート状況（2022/09/09）
残念なことにfirefoxではまだサポートされていません。
firefoxはシェア率もあり無視できないので、実際に使うことまだはできなそうですね...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/304162/0404e429-2e98-312a-9c22-a9c3f30baefe.png)

https://caniuse.com/?search=%3Ahas()

# 参考サイト

https://coliss.com/articles/build-websites/operation/css/howtouse-css-has-pseudo-selector.html

https://www.qbook.jp/column/20220808_1402.html
ActiveAdminでhas_manyな要素の追加するボタンの表示制御

```active_admin.scss
/* ActiveAdminでhas_manyな要素の追加するボタンの表示制御 */
  li.has_many_container {
    .inputs.has_many_fields + a {
      display: display;
    }
    .inputs.has_many_fields:nth-of-type(5) + a.has_many_add {
      display: none;
    }
    .inputs.has_many_fields:nth-of-type(5) + input + a.has_many_add {
      display: none;
    }
  }
```
nth-childではまったので注意
Amazon Route 53とは

# Amazon Route 53とは
Amazon Route 53とは、DNS（ドメインネームサービス）。
**DNSとは、Webブラウザに入力したURLをIPアドレスに変換する仕組み**。
Amazon Route 53では、**アクセスしてもらいたいアドレスを、実際に使用しているEC2やS3などのAWSサービスのエンドポイントに結びつける。**
これを**名前解決**という。Amazon Route 53ではドメインの取得もできる。
ドメインの取得とは、**〇〇.jpや△△.comなどのドメインの使用権を買って、レジストラ（ドメインの登録を担当する組織）に申請すること。**
Amazon Route 53には、トラフィックが１つのエンドポイントに集中しないようにしたり、1箇所のサービスに障害が生じた時に速やかにほかの場所に切り替える機能があり、ルーティングを柔軟に管理する。
## レジストラとレジストリの違い
レジストリとは、ドメイン情報のデータベースを管理している機関。
レジストラは、レジストリにドメイン情報の登録を担当する組織。
ユーザーはレジストラにドメイン情報を申請し、レジストラはドメイン情報を登録する。
# Amazon Route 53の用語
|項目|内容|
|-|-|
|リゾルバー|ドメイン名とIPアドレスを相互に変換する機構を指す。Amazon Route 53の中心的な機能であり、DNSサーバーが持つ機能。|
|ラウンドロビン|１つのホスト名に複数のIPアドレスを割り当てて返すと、先頭から接続を試みることを利用し、アクセスするたびにIPアドレスを返す順序を変更することで、優先する接続先のIPアドレスを恣意的に調整する仕組み。接続先のIPアドレスが複数あることで、複数のサーバーに負荷分散が可能になる。|
|トラフィックフロー|サーバーの負荷や、最も効率の良いサーバーのIPアドレスを返すように調整する機構を指す。遅延が最小になるサーバーに転送するレイテンシべーすルーティング、地理的に近いサーバーに転送するGeo DNS、サーバーの稼働をヘルスチェックして、稼働していないサーバーに割り振らないようにするDNSフェイルオーバーを組み合わせて構成する。|
|ホストゾーン|DNSの設定単位。ドメイン全体、または、サブドメインのこと。|
|レコード|ドメインやサブドメイン内に設定した、ドメインとIPアドレスを変換する１つの設定項目のこと。|
|クエリ|DNSに対する問い合わせのこと|
# Amazon Route 53の料金
料金 = ホストゾーンごとの基本料金 + 問い合わせ件数に応じた料金 + ヘルスチェックの料金
## ホストゾーンごとの基本料金
ドメインやサブドメイン１つあたりで計算する
## 問い合わせ件数に応じた料金
該当ドメインについての問い合わせのあった件数。
## ヘルスチェックの料金
ヘルスチェックとは、サーバーなどのリソースについて、状態やパフォーマンスを監視する機能。ヘルスチェックは50個まで無料で、それ以上は有料。
システム保守作業で失敗した点と改善

### はじめに
今までシステム保守していて、気を付けることをまとめてみました。
私の経験で記載しているため、参考程度にしてください。m(__)m

### 1.ミドルウェアを導入する際は、サーバーが対応しているか確認する
ミドルウェアーをインストールして構築後、CPUが対応していないことに気づき、
最初からやり直すことになったことがあります。

ミドルウェアを導入する際は、マニュアルを読んで、要件を確認し今のサーバーが対応しているかどうか確認が必要です。

### 2.検証する際は、可能であれば同じOSのサーバーで検証する
ミドルウェアーの導入は、同じOSで検証したほうが良いです。
OSやCPUなどのスペックによって、ミドルウェアーが対応していない可能性があります。


### 3.参考にする記事の投稿日時を確認する。
参考にするネット上の記事は投稿日時を確認する
投稿が古い場合は、現在は使われていない手順書の可能性があり、手順にそって実施したところで想定通りに動作しない可能性があります。
特に手順書から呼び出されているパッケージ情報が古い場合があります。

### 4.パッケージをインストールする際は事前にバックアップを取得する
設定ファイルの変更のみであれば、作業時にターミナルで実行したコマンドをログとして出力し
問題があればログを参考にもとに戻すことは可能です。
パッケージ関連の作業は、アプリ側に影響が出る可能性があるため、
仮に以前のバージョンにパッケージを戻そうとすると、大変手間がかかります。
そのため、パッケージのバージョンアップやインストールの作業前に、サーバーのバックアップを取得した方が安全です。

### 5.作業記録は残すようにする
サーバーの作業ログを出力するようにしたり、事前の画面スクリーンショットを取得したりして、事前と事後で記録を残した方が良いです。

### 6.ツールを外から導入する際は、可能であれば情報が多く、今後メンテナンスされるものを選ぶ
ツールを外から導入する際は、情報量が少なかったり、個人でメンテナンスしているものであれば、ツールに何か問題が起きた際に、少ない情報の中、自分でメンテナンスする必要になる可能性もあります。

### 7.検証環境で確認後、本番環境で作業する
初めての作業は、検証環境で動作確認後、本番環境で作業したほうが安全です。
これぐらいは大丈夫と思って修正したら、動作がおかしくなる場合があります。

### 8.何かを導入する際は今後どうなるかまでイメージする
例えばログファイルをすべてチェックする機能を導入する予定であれば、
ログ削除する機能がない場合は増え続けて影響がでるところまでイメージする。

目の前の導入作業のみに目が行きやすいですが、もっと先までどうなるかリスクを考える習慣があれば、気づけるかもしれません。

### 9.過去に保守した部分は、ドキュメント残す
過去に保守した部分はドキュメントに残し、後任者にも情報共有が出来る状態にする。
属人化を防ぐためにも大事です。
RP2040で液晶ディスプレイドライバボードを作る

RP2040でTFT液晶ディスプレイ用のドライバーボードを作りました。
TFT液晶ディスプレイは __メトロ02系のモニタ装置を液晶ディスプレイで再現しよう__ で使用した3.5インチ液晶ディスプレイになります。

https://qiita.com/usashirou/items/b04e8e164561f05c890e

### 3.5inch SPI Module ILI9488 SKU:MSP3520
http://www.lcdwiki.com/3.5inch_SPI_Module_ILI9488_SKU:MSP3520

# 基板全景
SPI接続でもちろんTouchも使用可能です。
接続用にUSBとUARTなどのGPIOの外部入出力端子を用意しています。
![点灯した様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/d3a2332c-e87a-f0e4-fcbd-f193e4391b4c.jpeg)
# 組立様子
ちょっとネジの位置がずれてますね。
![DSC_0490 (2).JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/dcb33da7-06c6-ef81-12c1-a5edee3d64f5.jpeg)
# MSP3520・MSP3521とそれ以外
ネジの位置がずれていたのはMSP3520・MSP3521以外のものだからです。(以下MSP3520に統合）
 __MSP3520で合わせた様子__
![MSP3520で合わせた様子](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/bdde2b4f-54a8-b173-15b5-93d5098c9f17.jpeg)
MSP3520とそれ以外では基板の仕様が異なりました。
特にお店によっては記載している仕様と異なる製品が届く場合があるので注意する必要があります。
![TFT比較](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/12b9464d-e875-862d-4ade-2804d6e9d449.jpeg)
# 回路図
![回路図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/8eb8dd7e-1cc9-9144-7040-21477dde7dac.png)
# なぜRP2040か？
ArduinoのTFT_eSPIで簡単に動かすことができるようになりました。
ここ最近、ESP32にTFTが搭載されたモジュールが販売されるなど本製品を作った意義を失いかけてしまったのが少し残念ですが
ESP32と違い低電流で動かす事が可能なのとフラッシュメモリを容易に交換可能です。
この為、WiFiを使用しない場合はRP2040を使用した方が良いと私は考えています。
![天安門事件](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285344/59eec7fc-8df0-2bec-e6a9-8aa265c7e3ab.jpeg)
Python,Ruby,PHP,Java,JavaScript,Perlの例外処理の比較 | プログラミング言語比較


<a href="https://qiita.com/yuki_kimoto/items/f9c2454e7f9130ddb003">Qiita > プログラミング言語の比較</a>

プログラミング言語Python,Ruby,PHP,Java,JavaScript,Perlの例外処理の比較

# Python

https://qiita.com/imuimu/items/7f27d156dd0f6507803b

# Ruby

https://qiita.com/k-penguin-sato/items/1a6c8096effccb19565a

# PHP

https://qiita.com/wakahara3/items/bcadef53367097765c82

# Java

https://qiita.com/ts7i/items/d7f6c1cd5a14e55943d4

# JavaScript

https://qiita.com/andota05/items/fc1e340642be42ca47c0

# Perl

https://perlzemi.com/blog/20100411127089.html
人事のおじさんプログラミングを学ぶ Day13「フォームの入力内容の取得とイベント」

書籍『確かな力が身につくJavaScript「超」入門 第2版』に沿って、
フォーム内容の取得とイベントを使ってプログラムが動作するタイミングを制御してみた。

変数を含む文字列が正しく表示されないので調べたら、テンプレートリテラルを利用した記述ではバックコーテーションで囲む必要があると気づく。自分で調べたことは何よりも忘れなそうです。
![2022-09-09 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783084/a0488fb7-88c9-91fe-ce4a-31b8e17182bb.png)
![2022-09-09 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2783084/4187561d-db0a-d3d2-996e-bb2c6d791f87.png)
リレーショナル型とキーバリューストア型以外のデータベース

# そのほかのデータベース
システムの構造が巨大化・複雑化とともに従来のリレーショナル型やキーバリューストア型以外のデータのタイプが出現した。
* DocumentDB(ドキュメント指向型)
* Neptune（グラフデータベース）
* Timestream（時系列データベース）
* Quantum Ledger Database(台帳データベース)
# Amazon DocumentDB（MongoDB 互換）とは
Amazon DocumentDBは、Mongo互換のデータベースサービス。
MongoDBとは、オープンソースのドキュメント指向型のデータベース。
JSON形式をバイナリ化したBSON形式でデータを保存する。
ビックデータ処理、分散処理に向けたNoSQL型のデータベースで高い評価を得ている。
DocumentDBは、MongoDBデータの入出力を大規模かつ安定して行えるように最初から設計されている。既存のMongoDBドライバーおよびツールで利用できる。
AWS Database Migration Serviceを用いて、Amazon EC2上で実稼働中のMongoDBデータベースをAmazon DocumentDBに実質ダウンタイムなしで移行できる。
# Amazon Neptuneとは
Amazon Neptuneは、「グラフデータベース」。
グラフデータとは、色々な要素間の関係や、処理の流れを示すために、ノード同士の連結を方向を含めて記述した内容。Amazon Neptuneは代表的なグラフモデルであるProperty GraphをW3CのRDF、それぞれのクエリ言語であるApache TinkerPop GremlinとSPARQLに対応している。管理は自動化されていて、ネットワーク越しのデータの読み込みはHTTPSで暗号化されている。
レコメンデーションやソーシャルネットワーク、ナレッジグラフなどで必要とされる、データ間の複雑な関係を扱える。
# Amazon Timestreamとは
Amazon Timestreamは「時系列データベース」のサービス。
時系列データとは時間お経過に伴う事柄の変化を記録したデータで、IoTの典型的なデータ取得形式。時間感覚で取得したデータをリレーショナルデータベースに保存することはできるが、集約や集計が用意でなくなる。
Amazon Timestreamでは、クエリ処理エンジンが時間間隔別に最適化されているので、平滑化・近似・補完などの分析関数が最初から組み込まれている。リソースが競合しないように新たなエータの挿入と既存のデータからクエリを異なる処理階層で実行する。必要に応じてスケーリングするので、初めに容量や負荷を考える必要がない。IoTデータを扱うパフォーマンスを維持し、データ管理コストを抑えることができる。
# Amazon Quantum Ledger Database(QLDB)とは
Amazon Quantum Ledger Database（QLDB）は台帳データベース。
台帳では、企業などの商取引や財務の記録に加えて監査も必要。リレーショナルデータベースでは監査に必要とされる「データ変更の追跡や検証」に本来対応していないので、カスタムな監査用アプリケーションの開発に時間と手間がかかる。
Amazon QLDBでは、データの各変更を追跡し履歴として維持する「ジャーナル形式」を採用している。ジャーナル内のデータは変更・削除不可で、暗号学的ハッシュ関数で変更履歴の改竄を防止している。一方で、SQL類似のAPIや柔軟なドキュメント指向データモデルなどが備わっているので、操作が簡単。
1サーバー内でポート番号別にドメインを表示させる（VirtualHost,リバースプロキシ）

## ケース
すでに https://hoge.com というサイトを公開しているサーバーがある（IPは仮に111.22.333.444とする）
（今回はさくらVPSを使っています）
またこのサーバー内には，5443番ポートで動作しているnode.js（Express）アプリがある
このアプリをhttps://fuga.com というドアドレスで新たに公開したい

環境はApache2.4
centos7
です

## DNSの設定とSSL証明書の取得
### DNS設定
fuga.comのドメインおよびSSL証書を取得します
お名前.comでドメイン取得後，DNSレコードの設定から，AレコードにIPである111.22.333.444を設定
これでhttp://fuga.com にアクセスしても　http://hoge.com と同様の内容が表示されることになります

### SSL証明書の取得
openSSLを使ってSSL証明書を取得します
ざっくりとした流れは，
1. サーバーの秘密鍵を作成
2. 秘密鍵を使ってサーバー証明書を発行
3. サーバー証明書を使ってSSL証明書の申請
となります

作成前にopenSSLをインストールしておきましょう
参考：https://qiita.com/Esfahan/items/4e2002f4a24589b2d0bf
インストールできたらサーバーへSSH接続しコマンドを打っていきます

##### 秘密鍵作成とサーバー証明書の発行
まず各種ファイルを保存するディレクトリに移動しましょう
```
例）　$ cd /etc/pki/tls/certs/hoge.com
```

実は下記のようなコマンドを打つことで,1と2は同時に実行可能です

```
$ openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr
```

このコマンドの意味は，
***2048bitの秘密鍵をserver.keyとして作成し，それを使ってserver.csrというサーバー証明書を発行する**
というものです
このコマンドを打つと，サーバー証明書発行に伴う情報を色々聞かれます

```
Country Name (2 letter code) [GB]:JP
State or Province Name (full name) [Berkshire]:Tokyo
Locality Name (eg, city) [Newbury]:Chiyoda
Organization Name (eg, company) [My Company Ltd]:fuga.inc
Organizational Unit Name (eg, section) []:dev
Common Name (eg, your name or your server's hostname) []:fuga.com
Email Address []:（入力しなくてOK、エンターのみ入力）

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:（入力しなくてOK、エンターのみ入力）
An optional company name []:（入力しなくてOK、エンターのみ入力）
```

注意点は，Common Nameはだんのドメイン名にするということです
これで2つのファイルが作成されました

補足：秘密鍵にパスフレーズを設定することもできますが，取り扱いが煩雑になるため，今回はパスフレーズ未設定とします

##### SSL証明書
SSL証明書の取得方法はいくつかありますが，今回はさくらのSSL，JPRSドメイン認証型にします
https://ssl.sakura.ad.jp/
説明に従っていけば取得はすぐだと思います
先ほど発行したサーバー証明書を使用してください

問題なく発行できれば
server.crtというSSL証明書がダウンロードできると思います
![スクリーンショット 2022-09-09 7.59.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869250/c722a216-2881-bde9-96c3-473697c55786.png)

加えて，中間CA証明書もダウンロードします
![スクリーンショット 2022-09-09 8.03.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869250/0f10ee15-a4cd-92c2-4ffc-93da11d88893.png)

JPRS_DVCA_G4_PEM.cerというファイルがダウンロードできました

この2つをサーバー内の管理しやすいディレクトリに設置しましょう
今回は先ほど同様/etc/pki/tls/certs/hoge.comへ入れました

## VirtualHostの設定

```
NameVirtualHost *:443

<VirtualHost *:443>
ServerName fuga.com
Alias / /var/www/fuga.com
DocumentRoot /var/www/fuga.com

SSLEngine on
SSLProtocol All -SSLv2 -SSLv3 -TLSv1
LoadModule ssl_module modules/mod_ssl.so

SSLCertificateFile /etc/pki/tls/certs/fuga.com/server.crt # SSL証明書
SSLCertificateChainFile /etc/pki/tls/certs/fuga.com/JPRS_DVCA_G4_PEM.cer #中間CA証明書
SSLCertificateKeyFile /etc/pki/tls/certs/fuga.com/server.key # 秘密鍵

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

ProxyRequests Off
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerExpire off

ProxyPass / https://fuga.com:5443
ProxyPassReverse / https://fuga.com:5443/
</VirtualHost>
```

この設定により，/(https:fuga.com)にアクセスした時に，https:fuga.com:5443の内容が表示されることとなります
MkDocs PDFとして出力する

[mkdocs-with-pdf](https://github.com/orzih/mkdocs-with-pdf)を使用して、ドキュメントをPDFとして出力してみる。

サイトのほうは[Material for MkDocs](https://squidfunk.github.io/mkdocs-material/)を使用。

https://try0.github.io/mkdocs-example/example-site/site/mkdocs-with-pdf.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92451/4bada3f6-6781-aed1-0fb9-1ad971ed3563.png)


このドキュメントをベースに、こんなpdfが出力可能

https://try0.github.io/mkdocs-example/example-site/site/mkdocs-with-pdf-output.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92451/d281c6ff-28ba-30aa-530e-b44dea7f171e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92451/54ac4d6b-97e2-dca3-305c-f833661f5bce.png)


---

ソース
https://github.com/try0/mkdocs-example
LPC812MAXのPWMを使う(2)



x mbed2リビジョン144
x リビジョンの変更ができる人むけ


目的
使ってみたかった
LED等を繋げる
sg90でためしていないけど


![o_con733.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/1943a29a-d4fc-409b-c985-002783290a39.jpeg)


![o_con734.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/09868631-3e86-c247-4e24-086a938b7f6a.jpeg)




```c++


//PWM_SG90_v2_812_1

#include "mbed.h"

//data SG90
// 2400us 2.4ms
#define s_max  2400
// 500us 0.5ms
#define s_min  500
#define s_r    (2400-500)
#define s_c    ((2400-500)/256)
#define SN(n6) (500+(((2400-500)/256)*n6))

//PWMのピンの設定
PwmOut servo(P0_16); //812

//メイン関数
int main()
{

    //周期の設定
    servo.period_ms (20); // servo requires a 20ms period

    //無限ループ
    while(1) {

        for(int offset = 0; offset<256; offset++) {

            //サーボーモータに値をセット
            servo.pulsewidth_us( SN(offset) );

            //40ミリ秒まつ
            wait_ms(40);

        }//for

    }//while

}//main



```


![o_con833.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/b568fb37-0e3e-cdc3-4a3b-e8826be31aa1.jpeg)


-17-
文字列を桁数で区切る



## PG
```java
public static final int array[][] =
    {
        {0,4},
        {4,9},
        {9,12},
        {12,15}
    };
public void test3() {


    	String mojiretsu = "12あ41 345 23111";
    	String conv = "";
        for(int i = 0; i<array.length; i++){
        	int mae = 0;
        	int ushiro = 0;
            for(int j = 0; j<array[i].length; j++){
            	if(j == 0) {
            		mae = array[i][j];
            	}else {
            		ushiro = array[i][j];
            	}
            }
            System.out.println(mojiretsu.substring(mae, ushiro));
        }
}
```
## 結果
```
12あ4
1 345
 23
111
```
Tinkerboard ２S Android11導入

# 1.Tinkerboard 2Sおさらい

* Tinkerboard 2S でOpenCV(TinkerOS)に関する設定について投稿しました。
    * 一応拙作の記事を記載します。
    
https://qiita.com/Manyan3/items/4010428705a6e26a8a3b

* インストールOS対比表

| 項目/OS | TinkerOS | Android |
|:-:|:-:|:-:|
| OS書き込み  | balena Etcher  | balena Etcher  |
|  主なプログラム言語 | Pythonなど   | Java  |
|  作成環境 | 任意のエディタ  | Android studio  |
|  カスタマイズ | OSレベルで可能  | 開発者モードなど  |
| MIPIカメラ※  | Opencv+Gstreamer  |  カメラ(標準) |
| USBカメラ  | OK  | OK  |

:::note warn
注意
MIPIカメラはカメラメーカで動作確認・保証しているところは今のところない模様です(自己責任）

:::

* OSはこちらより、Download－＞ 2s（今回は2Sの記事なので）　－＞一覧よりAndroidを選択。

https://tinker-board.asus.com/download.html#os

* ダウンロードしたISOイメージはbalena Etcher でMicroSDカードに書き込みます。
    * こちらのサイト御覧の方はご存知かもですが、念の為リンクを載せます

https://www.balena.io/etcher/

* Windowsで簡単にチンと焼けます（時間かかりますが・・・）
* イメージファイルと書き込み先を選んでFlashボタンを押すだけ！


# 2.何はなくともAndroid studio

* 様々な環境（Windows Mac Linux）が用意されています。
    * ダウンロードサイトでは使用時のOSでダウンロードしてくれるので楽ちんです。
   
https://developer.android.com/studio/install?hl=ja

    

# 3. 開発者モードに入る

* PCとTinkerboard 2SをUSB接続しておきます（あとでもいいのかもしれないですが）
* Tinkerboard側でSettings>About tablet>Android version>>Build number
* Build numberを7回クリックするとSystemメニューに「Developer options」が増えます

公式サイトでは以下の様な説明になっていますので、参考まで

https://developer.android.com/studio/debug/dev-options?hl=ja#general


:::note info
インフォメーション
* 開発者の方は特に細かい説明は不要かと思い今回は略。
* 単に私が初心者というのもありますが…（Debianの方が触ってますけど）
:::

# 4. Tinkerboard 2Sのアンドロイド お役立ち
* ボードコンピュータですので、開発環境のAndroid studioでスマホの設定をしても役に立たない事があります。
    * そうなると気になるのは画面の回転ですよね。
    * スマホだと勝手に回転しますが・・・


1. Settingsへ移動
2. Displayを選択
3. Advanced  > System Direction

:::note info
インフォメーション
* 横向き限定なら0または180
* 縦向き限定なら90または270
:::

* 縦長ディスプレイの例

![縦向きのディスプレイ.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2155177/c726070a-b3cf-442f-33eb-9858744b9814.jpeg)


**これで使い道が広がりますね！**
Firebase Storage の CORS エラー回避のメモ

# 結論

下記の「CORSの構成」を読めばOK

- [ウェブで Cloud Storage を使用してファイルをダウンロードする](https://firebase.google.com/docs/storage/web/download-files?hl=ja#cors_configuration)

# 公式からほぼ抜粋

まず gsutil をインストールします。すでに入っているなら、最新版にアップデートします。

- [gsutil ツール](https://cloud.google.com/storage/docs/gsutil?hl=ja)

必要に応じて、認証処理をします。init 済みなのに、認証が失敗するときは、re-initialize します。

```
$ gcloud ini
```

`cors.json` を作成します。

```cors.json
[
  {
    "origin": ["*"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
``` 

さらっと、公式では全部の origin に対して通るようにしてもいいんじゃ的なことが書いてあるんですけど、さすがに全部OKとか嫌な場合は下記のようにします。

```cors.json
[
  {
    "origin": [
            "https://your-project-name.web.app",
            "https://your-other-domain..com"],
    "method": ["GET"],
    "maxAgeSeconds": 3600
  }
]
```

origin なので、サイト名だけでなく `https://` とか `http://` とか、ポート番号とかも（あるなら）記述が必要です。

- [MSDN: Origin (オリジン)](https://developer.mozilla.org/ja/docs/Glossary/Origin)

作成したら、下記を実施します。

```
$  gsutil cors set cors.json gs://your-project-name.appspot.com
```

`gs://` 以下のバケットの名前が分からないときは、Firebase のコンソールにいって Storage のところを見ると書いてあります。
wiringpiを使ってデイジーチェーン用のデータ送信する際にハマったこと

デイジーチェーンで繋いでいたモータードライバー（L6470）にデータを送るときに、
wiringpiを用いたときの書き方がわからずにハマってました。

RPi.GPIOでCSのpinをLOW → データ送信 → CSのpinをHIGH の方法もありますが、
WiringPiを使うパターンだと記述量が少なくて済む。

## 結論:シフトする数に合わせてstruct.pack()の引数を整える

```
import wiringpi as wp
import struct

SPI_CH = 0
SPI_HZ = 100000

# SPI データ送信
def send(SPI_CH, byte_ary_1, byte_ary_2):
    # バイト配列には[0x10, 0xc0, 0x15], [0x10, 0x00, 0x21]などが来るものと仮定します
    # バイト配列の中の個数が違うときは事前に0x00で埋めて配列数を最大数に合わせています
    byte_len = len(byte_ary_1)

    for i in range(byte_len):

        # デイジーチェーンの時は各モーターへの値を１バイトずつのパックにするのがミソ
        #（ドライバによるかも）
        # なお、データは押し出される形でシフトするので、データの順番に注意

        mosi = struct.pack("BB", byte_ary_2[i], byte_ary_1[i])  # ←ここで各バイトをパックする

        # 1台なら mosi=struct.pack("B", ary) 
        # 2台なら mosi=struct.pack("BB", ary1, ary2)

        wp.wiringPiSPIDataRW(SPI_CH, mosi)

if __name__ == "__main__":
    wp.wiringPiSPISetup(SPI_CH,SPI_HZ)
    send(SPI_CH, [<任意のバイト配列>], [<任意のバイト配列>] )
```


[structのpythonドキュメントページ](https://docs.python.org/ja/3/library/struct.html)

やり方が分かればこれだけのことだったんですけどね。
あとはバイト配列の中身の数が異なるときや、データ取得するときなどは送信するバイト配列数にも気をつけましょう。
アジャイル開発とは何か？



## はじめに
こんにちは！新人エンジニアのふかこうです！
今回は私が仕事でアジャイル開発をしていることもあり、それについての記事になります。
アジャイル開発ってどんな開発？っと思う方は是非読んでみてください！
## この記事の対象者
・アジャイル開発について知りたい方
・初級エンジニア
・エンジニアとして働きたい方
・IT企業に就職する学生
## 筆者のレベル
・新人エンジニア
・Android開発初級
## アジャイル開発とは
アジャイル開発では、短い期間でリリースし、フィードバックを受け、改善するサイクルを基本としています。（図表1）
![スクリーンショット 2022-09-09 0.46.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2613554/71eb10b7-7029-02e8-cdeb-51a4235fa6df.png)図表1

一度リリースして終わりではなく、リリースしたソフトウェアに対するユーザーの
フィードバック自体が開発サイクルに含まれる点がアジャイル開発の原則であり、特徴です。

## ウォーターフォール開発との違い
アジャイル開発とよく比較されるのがウォーターフォール開発です。
ウォーターフォール開発では、工程を「企画」「設計」「実装」「テスト」に分割した上で開発を進めていきます。
開発期間ですが、数ヶ月から数年かかるものもあるようです。
全ての工程が無事に完了したあと、はじめてソフトウェアを利用することができるため、開発の計画や予算の見積りが容易になります。
ですが、製品の完成後に初期段階のトラブルに気が付いた場合、戻るための工数が大きくなってしまいます。
それに比べアジャイル開発では、ユーザーのリアルな声を製品に反映しながら開発できるので、より速いスピードでユーザーにプロダクトや新機能を提供することができるのです。
開発期間は開発チームにもよりますが、一般的に１〜３週間程度で、機能をリリースします。
自分の所は機能にもよりますが、２〜３週間、３〜４週間のものが多めです。

## アジャイル開発手法「スクラム」について
先に挙げたアジャイルの亜種とも呼べる開発手法です。
チームを組んで役割やタスクを分散しつつ、コミュニケーションを取りながら行う特徴があります。
スポーツとして馴染み深いラグビーのスクラムにちなんで、「スクラム開発」と名付けられました。
スクラム開発はチーム全員で開発を進める手法のため、アジャイル開発の中でも、チーム間のコミュニケーションがより大切になる開発手法です。

## スクラム開発に適した案件は？
ズバリ！後々に更新が必要なシステムです。
例を挙げると、常に更新が必要な運用型のWEBサイトやアプリケーション開発、最終的な納期よりも品質を優先したい案件に向いています。
チーム間で連携をしつつ、速度と確実性の高い開発を行いたい場合は、スクラム開発を選択することをおすすめします。

## アジャイル開発まとめ
アジャイル開発はスピーディーにお客様の声を聞きながら進めていきます。
完成したから終わり、、、ではなく、リリースした後もどんどん進化していきます。
今誰もが手にしているスマートフォンアプリもその一つです。
私の現在携わっている仕事もアジャイル開発でAndroidアプリの新機能追加などを行なっています。
お客様の声を聞きながら、より良いサービスを提供できることがアジャイル開発の良いところだと思いました。
今回この記事を書く上で「[**いちばんやさしいアジャイル開発の教本　人気講師が教えるDXを支える開発手法**](https://www.amazon.co.jp/%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E9%96%8B%E7%99%BA%E3%81%AE%E6%95%99%E6%9C%AC-%E4%BA%BA%E6%B0%97%E8%AC%9B%E5%B8%AB%E3%81%8C%E6%95%99%E3%81%88%E3%82%8BDX%E3%82%92%E6%94%AF%E3%81%88%E3%82%8B%E9%96%8B%E7%99%BA%E6%89%8B%E6%B3%95-%E3%80%8C%E3%81%84%E3%81%A1%E3%81%B0%E3%82%93%E3%82%84%E3%81%95%E3%81%97%E3%81%84%E6%95%99%E6%9C%AC%E3%80%8D%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E5%B8%82%E8%B0%B7%E8%81%A1%E5%95%93-ebook/dp/B088YGLSRJ)」という本を参考にしました。
講師の方がわかりやすくアジャイル開発について教えてくれるのでオススメです。
是非読んで見てください！
以上
commitしたファイルや変更箇所は"git show"で確認できる

はじめに
--
変更を加えるたびにcommitするように意識をしているのですが、commitしたファイル内の変更箇所を確認したくなる時がありました。
そういえば確認の仕方を知らないなと思ったので、調べたことを備忘録として残そうと思います。

git showで確認できる
--
通常のgit logを叩いても、commitメッセージは表示されますが、commit内のファイルや変更箇所は表示されません。
どのファイルがcommitに含まれているか、ファイル内の変更箇所は何かを確認する際には"git show"コマンドを使用します。

そのままターミナルで"git show"コマンドを叩けば、下記のように最新のcommit内のファイル/変更箇所を表示してくれます。

~~~diff
~ % git show
commit a16cbf9dd299d41dfff4cab3ab9452550b091df6
Author: ~
Date:   Thu Sep 8 23:06:14 2022 +0900

    [update]jsonの記述を修正 #7
    
    updateが失敗した時のjsonデータの記述が間違っていたため修正。

diff --git a/backend/app/controllers/api/v1/quizzes_controller.rb b/backend/app/controllers/api/v1/quizzes_controller.rb
index 4c8ca22..e6584a9 100644
--- a/backend/app/controllers/api/v1/quizzes_controller.rb
+++ b/backend/app/controllers/api/v1/quizzes_controller.rb
@@ -1,6 +1,6 @@
 class Api::V1::QuizzesController < ApplicationController
   before_action :authenticate_api_v1_user!, only: [:create, :update, :destroy]
-  before_action :set_quiz, only: [:update, :destroy]
+  before_action :set_quiz, only: [:show, :update, :destroy]
 
   def index
     quizzes = Quiz.all
@@ -20,7 +20,7 @@ class Api::V1::QuizzesController < ApplicationController
     if @quiz.update(quiz_params)
       render json: { status: 'SUCCESS', data: @quiz }
     else
-      render json: { status: 'SUCCESS', message: 'Not updated', data: quiz.errors }
+      render json: { status: 'SUCCESS', message: 'Not updated', data: @quiz.errors }
     end
   end
 
~~~

HEADでcommitを指定
---

下記のようにHEADを使用することでcommitを指定することもできます。

~~~
#最新のコミットを表示(git showと変わりません)
git show HEAD

#一つ前のcommitを表示
git show HEAD~1

#n個前のcommitを指定
git show HEAD~n
~~~

commit idでcommitを指定
---

最新から数えるのが大変な場合は、"commit id"で指定することも可能です。
~~~
git show <commit id>

#例
git show a16cbf9dd299d41dfff4cab3ab9452550b091df6
~~~

ちなみにcommit idは、git logなどで確認できます。

~~~
~ % git log
commit 16299cf986cfa40cf475ec5dc1d1d0c52a73a110 (HEAD -> ブランチ名)
#commit 以降がcommit　idです！
~~~

内容が気になった時にサクッと確認できますね。
gitコマンドは使って覚えるのが一番早いと思うので、どんどん手を動かして覚えていきたいです！