OmniAICreator/Qiita-1.07M huggingface dataset:
SQL Server Migration Assistant for Oracle  による Oracle Database から Azure SQL Database への移行検証～Oracle ユーザー定義データ型編～


## 概要

### 本記事の位置付けについて

Oracle Database から Azure SQL Database へ SQL Server Migration Assistant for Oracle （SSMA）によるプログラム移行検証結果の一部である。次の記事にて個別機能別記事へのリンクを整理している。

- [SQL Server Migration Assistant for Oracle による Oracle Database から Azure SQL Database への移行検証記事のまとめ - Qiita](https://qiita.com/manabian/items/0ec96b66033a7bd03a25)



### ユーザー定義データ型について

ユーザー定義データ型を作成することができる。

ユーザー定義データ型を、次のユースケースで利用されることがある。

1. テーブル関数

### 参考リンク

- ホワイトペーパー
  - Guide to Migrating from Oracle to SQL Server 2014 and Azure SQL Database
- その他
  - [Oracle to SQL Server migration with SSMA: table expressions (abcloudz.com)](https://abcloudz.com/blog/oracle-to-sql-server-migration-with-ssma-converting-unsupported-table-expressions/)

## Azure SQL Database への移行

### SSMA による変換

ユーザー定義データ型の変換をサポートしておらず、手動での変換が必要となる。

### 移行方針

特になし。

### 変換例

#### 変換例 1 レコードのサンプル

##### Oracle Database のコード

```sql
CREATE OR REPLACE TYPE nested_type IS TABLE OF NVARCHAR2(10);
/
CREATE OR REPLACE FUNCTION table_funciton_001
RETURN nested_type
IS
  nest nested_type := nested_type();
BEGIN
  FOR i IN 1..5 LOOP
    nest.extend;
    nest(i) := i || 'つ目の処理を実施';
  END LOOP;
RETURN nest;
END;
```

```sql
SELECT * FROM table(table_funciton_001);
```

##### Azure SQL Database への変換

次の SSMA Issues が発生する。

```text
ID	Message	Description
O2SS0456	User defined types conversion is not supported	O2SS0456: Conversion of 'USER_DEF_TYPE_001' failed because user defined type is not supported.
```

```sql
CREATE PROCEDURE SSMA.TABLE_FUNCITON_001$IMPL  
   @return_value_argument ssma_oracle.CollectionIndexString  OUTPUT
AS 
   BEGIN

      DECLARE
         @NEST ssma_oracle.CollectionIndexString 
            /* 
            *   SSMA error messages:
            *   O2SS0339: Cannot convert usage of standalone user-defined type SSMA.NESTED_TYPE.
= SSMA.NESTED_TYPE
            */



      DECLARE
         @I int

      SET @I = 1

      WHILE @I <= 5
      
         BEGIN

            EXECUTE ssma_oracle.ExtendCollection @NEST  OUTPUT

            SET @NEST = ssma_oracle.SetCollection_varchar_varchar(@NEST, @I, ISNULL(CAST(@I AS nvarchar(max)), '') + 'つ目の処理を実施')

            SET @I = @I + 1

         END

      SET @return_value_argument = @NEST

      RETURN 

   END
GO
```

```sql
/* 
*   SSMA error messages:
*   O2SS0200: Select list item * cannot be converted.
*   O2SS0482: Conversion of following TABLE expression is not supported: TABLE(table_funciton_001)

SELECT 
FROM  AS fci
*/
```
MAUI Tips - WinUIのPickerの挙動

# 概要
これまでXamarin.Formsで作っていたアプリを、一念発起してMAUIで作り直す中で
調べたことの備忘録。

# 環境
Visual Studio 2022
MAUI
.NET 7

# 問題となった現象
Visual Studio for MACでiOS / Android向けに開発してきたスマホアプリを
Windows上でも動作させられないかと相談があり、
WindowsのVisual Studio 2022でコンパイルして実行してみたんですが、
Pickerの表示がおかしい・・・。
Windows上だと、なぜかPickerに値が表示されない・・・。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/364c4522-71ca-f0cb-1ef3-de0a40f3e755.png)

ちなみに、XAML上ではPickerをこのように記述。

``` XML
                    <Picker x:Name="PrimaryItem"
                            Margin="30,0,20,10"
                            SelectedIndexChanged="PrimaryItem_SelectedIndexChanged"/>
```

コード内でPickerにデータを突っ込んでいるんですが、
そのコードはこんな感じ。

``` C#
            PrimaryItem.Items.Add("加工");
            PrimaryItem.Items.Add("仕上げ");
```

# 解析結果
以下のMicrosoftのサイトに記載のサンプルコードをXAML上に記述しても表示されませんでした。
[https://learn.microsoft.com/ja-jp/dotnet/maui/user-interface/controls/picker?view=net-maui-7.0#add-data-to-the-items-collection](https://learn.microsoft.com/ja-jp/dotnet/maui/user-interface/controls/picker?view=net-maui-7.0#add-data-to-the-items-collection)

``` xml
<Picker Title="Select a monkey">
  <Picker.Items>
    <x:String>Baboon</x:String>
    <x:String>Capuchin Monkey</x:String>
    <x:String>Blue Monkey</x:String>
    <x:String>Squirrel Monkey</x:String>
    <x:String>Golden Lion Tamarin</x:String>
    <x:String>Howler Monkey</x:String>
    <x:String>Japanese Macaque</x:String>
  </Picker.Items>
</Picker>
```

どうやら、（Windows向けにビルドした場合では）PickerのItemsプロパティにデータを入れても、それらがPicker上に表示されない模様・・・。

ItemsSourceプロパティに設定した場合は表示されるので、
そちらに入れろってことなのかな・・・。
SQL Server Migration Assistant for Oracle  による Oracle Database から Azure SQL Database への移行検証～Oracle データ型編～


## 概要

### 本記事の位置付けについて

Oracle Database から Azure SQL Database へ SQL Server Migration Assistant for Oracle （SSMA）によるプログラム移行検証結果の一部である。次の記事にて個別機能別記事へのリンクを整理している。

- [SQL Server Migration Assistant for Oracle による Oracle Database から Azure SQL Database への移行検証記事のまとめ - Qiita](https://qiita.com/manabian/items/0ec96b66033a7bd03a25)

### Oracle データ型について

Oracle Database ドキュメントにて、次のように記載されている。

> 固定された一連のプロパティ

引用元：[データ型 (oracle.com)](https://docs.oracle.com/cd/F19136_01/sqlrf/Data-Types.html#GUID-A3C0D836-BADB-44E5-A5D4-265BA5968483)

### 参考リンク

- SSMA のドキュメント
    - [既定の型マッピング - SQL Server | Microsoft Learn](https://learn.microsoft.com/ja-jp/sql/ssma/oracle/project-settings-type-mapping-oracletosql?view=sql-server-ver16#default-type-mappings)
- ホワイトペーパー
    - Guide to Migrating from Oracle to SQL Server 2014 and Azure SQL Database
    - Oracle to SQL Server Migration Handbook v 2.0
- その他
    - [Mapping Oracle data types when migrating to SQL Server | ABCloudz Blog](https://abcloudz.com/blog/use-caution-when-mapping-oracle-data-types-for-procedures-and-function-parameters-in-ssma/)

## Azure SQL Database への移行

#### SSMA による変換

SSMA による Oracle Database のデータ型と 変換後のデータ型のマッピングが、次のドキュメントに記載されている。

- [既定の型マッピング - SQL Server | Microsoft Learn](https://learn.microsoft.com/ja-jp/sql/ssma/oracle/project-settings-type-mapping-oracletosql?view=sql-server-ver16#default-type-mappings)

### 移行方針

規定のデータ型マッピングにおける次表の項目の変更を検討を推奨。

| #    | Oracle Database のデータ型 | 変換後のデータ型 |
| ---- | -------------------- | ---------------- |
| 1    | VARCHAR2             | varchar(8000)    |
| 2    | NVARCHAR2            | nvarchar(4000)   |
| 3    | NUMBER               | numeric (28,15)  |

Oracle Database の Spatial 型の移行を行う際には、手動で変換する必要がある。
GASで暗号化・復号化 -cCryptoJSを使って-

# GASで暗号化、復号化を行う
## ライブラリの導入
GAS のエディタの左側にある「ライブラリ」の横の「＋」をクリックし、スクリプトID に 1IEkpeS8hsMSVLRdCMprij996zG6ek9UvGwcCJao_hlDMlgbWWvJpONrs を入力して検索する。cCryptoGS を追加する。

cf. [CryptoJS libraries for Google Apps Script](https://ramblings.mcpher.com/gassnippets2/cryptojs-libraries-for-google-apps-script/)
## プログラムの例
```JavaScript
// GAS で暗号を扱う。
// 1. ライブラリの使い方
//     左の「ライブラリ」で＋を押す。
//     スクリプトIDに、与えられた 1IEkpeS8hsMSVLRdCMprij996zG6ek9UvGwcCJao_hlDMlgbWWvJpONrs を入力して検索し、cCryptoGS を追加する。
// 2. 暗号化・復号化
//     サンプルを https://ramblings.mcpher.com/gassnippets2/cryptojs-libraries-for-google-apps-script/ から取得
//     myFunction(){} に書き込み、実行。

function myFunctionEncoding() {
  var cipher = new cCryptoGS.Cipher('this is my passphrase', 'aes');
  var encryptedMessage = cipher.encrypt ('this is my message to be encrypted');
  Logger.log (encryptedMessage);
}

function myFunctionDecoding(){
  var cipher = new cCryptoGS.Cipher('this is my passphrase', 'aes');
  var decryptedMessage = cipher.decrypt("U2FsdGVkX1/s1ieiU/V4WBux5anBTyis47rEOqDectVJny6ILd+oYbsAIfL4DAoVrkltEPB/MkCR/LSNF5QEgg==");
  Logger.log (decryptedMessage);
}
```
PythonとElasticSearchとMetabaseを使ったデータ探索、分析、可視化

業務上でElasticSearchというテキストやログなどのデータの中から高速かつ正確に検索を行える
オーブンソースの検索エンジンが使われていたので調べてみました。
Kibanaを組み合わせてデータを可視化したり、分析したりできるクライアントアプリを作成できることが可能です。
Kibanaは有料でしたので（無料トライアウトあり）、無料で使えるものを探していたところMetabaseというサービスがあったので、今回はPythonとElasticSearchとMetabaseでデータを探索したり分析、可視化できるツールの設計を考えてみます。

・Metabaseについて
https://www.metabase.com/
![スクリーンショット 2023-04-09 17.18.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603047/fa5348f8-fdfd-8e9f-cec3-30ddc32de996.png)
(https://www.metabase.com/docs/latest/ より引用)


・Kibanaについて
https://www.elastic.co/jp/kibana/

# 概要
ElasticSearchでデータをインデックスし、Pythonを使用してデータをクエリして抽出し、
抽出したデータをPandasのDataFrameに変換し、Metabaseにデータをエクスポートして可視化する

# 設計
## Elasticsearchのセットアップ
Elasticsearchをローカル環境にインストールします

## Elasticsearchへのデータの投入
Pythonを使用して、Elasticsearchにデータを投入します。
CSVファイルからデータを読み込み、Elasticsearchにデータを保存するスクリプトを作成します。Pythonのライブラリであるelasticsearch-pyを使用して、Elasticsearchにデータを投入します。

## Metabaseのセットアップ
Metabaseをローカル環境にインストールします。
Metabaseの設定画面から、Elasticsearchに接続するための設定を行います。

## Metabaseでのデータの可視化
Metabaseにログインし、Elasticsearchから取り込んだデータを使用して、グラフやダッシュボードを作成します。

## PythonとMetabaseの連携
Pythonを使用して、MetabaseのAPIを呼び出し、データの取得やダッシュボードの作成を自動化することができます。
Pythonのライブラリであるmetabase-apiを使用すると、MetabaseのAPIを簡単に呼び出すことができます。

以上です。
データ分析に興味のあるエンジニアやデータサイエンティストやビジネスサイドの方の参考になると幸いです。
今後は実際にコードを書いていきます。

# 補足
インプットとなるデータはKaggleやe-Statなどのオーブンデータサイトからデータをダウンロードしてくると手軽に使えます

・e-Stat
https://www.e-stat.go.jp/
非同期処理(promise)

# 非同期処理とは
- Webアプリケーションの中で、ブラウザからサーバーにデータを送信したり、サーバーからデータを受信したりするための仕組みです。

`JavaScriptにおいて非同期処理を扱うための手段として、Promiseとawait/asyncがあります。`
- Promiseは、
  * 非同期的な処理を行う関数を実行し、その結果を処理するためのオブジェクトです。Promiseを使用することにより、コールバック関数のような深いネストを回避することができます。

以下は、Promiseを使用した非同期処理の例です。
```
// Promiseを使用した非同期処理
function fetchData() {
  return new Promise((resolve, reject) => {
    fetch('https://example.com/data')
      .then(response => response.json())
      .then(data => resolve(data))
      .catch(error => reject(error));
  });
}

// fetchData関数を呼び出してデータを取得する
fetchData()
  .then(data => {
    // データを処理する
    console.log(data);
  })
  .catch(error => {
    // エラーを処理する
    console.error(error);
  });
```

> また、Promiseと同様に、**await/aysnc**を使用することもできます。
await/aysncを使用することにより、**Promiseをよりシンプルに扱うことができます**。
>>**awaitは**、Promiseが解決されるまで処理を待機するためのキーワードである。
**asyncは**、非同期処理を行う関数を定義するためのキーワードです。

以下は、await/aysncを使用した非同期処理の例です。
```
// await/asyncを使用した非同期処理
async function fetchData() {
  try {
    const response = await fetch('https://example.com/data');
    const data = await response.json();
    return data;
  } catch (error) {
    throw new Error(error);
  }
}

// fetchData関数を呼び出してデータを取得する
async function getData() {
  try {
    const data = await fetchData();
    // データを処理する
    console.log(data);
  } catch (error) {
    // エラーを処理する
    console.error(error);
  }
}

getData();
```
ここでは、try/catch文を使用することで、エラー処理を簡単に行うことができます。


> 参考サイト

https://tcd-theme.com/2021/09/javascript-promise-then-catch.html
WindowsでApacheとTomcatを連携させてwarファイルをデプロイする

# はじめに
APIを作成してデプロイした際に躓いたので、投稿します。
連携とは具体的にApache側で受け取ったHTTPリクエストをリバースプロキシでTomcatに投げます。

# 環境
* Windows10
* Java JDK 1.8.0.222
* Apache HTTP Server 2.4.56
* Tomcat 9.0.73
※インストール方法は省略します。私はC:ドライブ直下にファイルを置きました。

# Apacheの設定
以下の設定ファイルを編集します。
`C:¥Apache24¥conf¥httpd.conf`

### リバースプロキシ用のモジュールを有効化

以下の２文がコメントアウトされているので、`#`を外して有効にしましょう。
```httpd.conf
...
LoadModule proxy_module modules/mod_proxy.so
...
LoadModule proxy_ajp_module modules/mod_proxy_ajp.so
...
```
### リバースプロキシの設定

末尾に以下を追加します。
```httpd.conf
...
ProxyPass /{リクエストパス} ajp://localhost:8009/{コンテキスト名}
ProxyPassReverse /{リクエストパス} ajp://localhost:8009/{コンテキスト名}
```

:::note warn
警告
Tomcatでデプロイするとwarファイル名がそのままコンテキスト名になります。
:::
warファイル名が`sample.war`であれば`sample`がコンテキスト名です。
リクエストパスを`/api`としたければ以下のようになります。

```httpd.conf
...
ProxyPass /api ajp://localhost:8009/sample
ProxyPassReverse /api ajp://localhost:8009/sample
```

**私はここの設定を誤って、躓きました；；**

### デフォルトのポート番号を変更（任意）
Apacheでデフォルトのポート番号は80番なのですが、
```httpd.conf
...
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to 
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 80
...
```
私のWindowsでは何かのシステムに占有されていたので8080に変更しました。
```httpd.conf
...
#
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to 
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 8080
...
```

以上で「`http://localhost:8080/api`のリクエストが来たら8009番ポートに投げる」設定ができました！

次に、Tomcatで8009番ポートの接続設定を行います。
# Tomcatの設定
以下の設定ファイルを編集します。
`C:¥apache-tomcat-9.0.73¥conf¥server.xml`

### 8080番ポートの停止
以下の記述をコメントアウトします。
```server.xml
...
<!--
<Connector executor="tomcatThreadPool"
port="8080" protocol="HTTP/1.1" 
connectionTimeout="20000" 
redirectPort="8443" />
-->
...
```

### 8009番ポートでの接続設定
以下の文字列を追加します。コメントアウトした部分の直後に追加しました。
```server.xml
...
<Connector protocol="AJP/1.3" 
address="::1"
port="8009" 
protocol="HTTP/1.1" 
secretRequired="false"
redirectPort="8443" />
...
```
以上で8009番ポートでAJP通信を受け付けることができます！

# Tomcatへのデプロイ
以下にwarファイルを配置してTomcatを起動します。
`C:¥apache-tomcat-9.0.73¥webapps`
デプロイの詳細に関しては省略します。

# まとめ
WindowsでApacheとTomcatを連携する方法でした。
Linuxの記事が多かったり、記事自体が古かったりしたので更新する意味を込めて書きました。

リバースプロキシの設定は、リクエストパスとコンテキスト名に注意してください。
私はこの部分を適当に流していました。コンテキスト名でリクエストを送り続け、長い時間”NotFound”状態でした（応答も解決策も）。いっそのこと同じ名前ににしてしまうのもアリかと思います！
Git操作をちゃんと分かろう

## はじめに
腰を据えて勉強してこなかったGitに、入社後速攻でつまづいてしまったのでブランチ操作について勉強しました。

基本的な操作（checkout、add、commit、push）は出来る状態だったのですが、コンフリクトの解消や誤った操作の取り消し方法が分からなかったのでその辺りを中心にまとめます。

## 前提知識
そもそも私はここを全然理解せずに触っていた（危険）。
- Gitとはバージョン管理をするためのもの
    - どのファイルが最新なのか、誰が編集したのか、どんな変更を行なったかの履歴を残す
    - チーム内で同時編集した場合に先に編集した人の変更内容が消えることを防ぐ

- Github上にファイルをUPする際に、ローカルでcommit/pushをする意味
    - 自分が作業しているディレクトリを「ワークツリー」と呼ぶ
    - commitはローカルリポジトリに直接状態を記録するのではなく、その間に設けられた「インデックス」に状態を記録する
        - これがcommitコマンドで行われていること
        - インデックスを間に挟むことで必要なファイルのみローカルリポジトリにコミットできる
    - つまり「ワークツリー」→→**add**→→「インデックス」→→**commit**→→「ローカルリポジトリ」→→**push**→→「リモートリポジトリ」

## コンフリクトが起きそう/起きた時
作業が遅い分、自分が作業している間にリモートリポジトリの状態が進んでしまうことは多い
- mainブランチに戻ってリモートブランチをpull
- 作業していたブランチに戻ってmainブランチをpull（ここ忘れがち！）
    - コマンド：`git pull プル先のリモートリポジトリ名 プルするブランチ名`
        - プル先は「origin」という名称のことが多い
- この時にエラーになるはずなので、ここでコンフリクトを解消する
    - マージ時のオプション選択で迷ったら以下記事を参照すると良さそう
https://qiita.com/tearoom6/items/0237080aaf2ad46b1963

    - 大抵の場合は`git config pull.rebase false`で良いと思っている

## 直前のコミットを取り消したい時
- 作業したファイルは残したい＆ステージングも取り消したい`git reset --soft HEAD^`（これが一番使う）
- 作業したファイルは残したい`git reset --mixed HEAD^`
- 作業したファイルごと消したい`git reset --hard HEAD^`（これはあまり無さそう）
    - 直前のコミットなのでキャレット`^`は1個だが、数を増やすと取り消す数を指定できる
    - 数の指定方法も色々ある
        - 「`HEAD^^^`と`HEAD~3`と`HEAD~~~`と`HEAD~{3}`と`@^^^`は同じ意味」（以下記事参照）

https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe

https://www.r-staffing.co.jp/engineer/entry/20191129_1

## コミットメッセージを修正したい時
「ルール通りにコミットメッセージを作成していない！」と気付いた時の対処法


- コミットを取り消さなくてもメッセージだけ書き換えられる
    - これを使えば直前のコミット漏れしたファイルを後から追加することも可能
- amendオプションを指定してコミットを行う`git commit --amend`
    - ファイルを修正
    - `git add　修正したファイル名`
    - `git commit --amend`（修正したいファイルがないときはここから実施）
    - エディタが表示されるのでコミットメッセージを変更して終了
- `git log`で履歴を見ると綺麗に修正されているはず＝修正履歴が残らない

#### 〜修正したいメッセージが複数ある/直前のコミットメッセージではない場合〜
- `git rebase -i`を使用する
    - `git log`でコミット履歴を確認、修正したいコミットのうち一番古いもののコミット番号を確認
    - `git rebase -i 該当のコミット番号`
        - 表示されるエディタで修正したいコミットの「pick」を「edit」に書き換え、エディタを閉じる
    - `git commit --amend -m 正しいコミットメッセージ`
        - 複数editにした場合は古いコミットから順に表示されるので、修正したい内容の正しいコミットメッセージをここで入力する
    - `git rebase --continue`
        - 複数editにした場合はこのコマンドで次の修正ポイントに飛ぶ、全て修正完了していればこれで完了

https://www.granfairs.com/blog/staff/git-commit-fix

#### 〜push後だった場合〜
- push後だった場合、上記作業のみではリモートリポジトリは変更前の状態のままなので`git push -f`（強制プッシュ）を行う

## PR出す準備中に修正点に気付いた時
- 基本的には、再度ファイルを修正してリモートリポジトリにpushすれば良い
- コミット履歴をどうしても綺麗にしたい場合は`rebase`を使用する


## その他
他にも色々あったので実際に使う場面が出てきたら追記していきます
- 他ブランチの作業を取り込む`cherry-pick`
- 散乱したコミットをまとめる`rebase -i ~~~`

## 参考
https://backlog.com/ja/git-tutorial
Mac Finderの設定をしてみた

# はじめに
- FinderはMacにデフォルトで入っているため、Dockにある以下のアイコンで起動する
![スクリーンショット 2023-04-09 午後5.01.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/afa0fe45-8749-8788-7008-a5287c1db42d.png)

# 新規Finderウインドウの表示先を変更
- Finder > 設定 > 一般 > 新規Finderウインドウで次を表示 > ダウンロード　※お好み
![スクリーンショット 2023-04-16 午後4.05.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/0a1e8e33-5bb9-def3-eb5c-c804a365e33f.png)


# サイドバーの表示項目設定
- Finder > 設定 > サイドバー > サイドバーに表示する項目 > 各自設定
![スクリーンショット 2023-04-07 9.48.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/bb001a52-5078-026b-04f0-6b0d55b8a985.png)

# ファイルの拡張子を常に表示
- Finder > 設定 > 詳細　> すべてのファイル名拡張子を表示 > チェックする
![スクリーンショット 2023-04-07 9.51.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/877b29fd-4602-41fc-2134-b1dea04d30e8.png)

# フォルダを常に先頭に表示
- Finder > 設定 > 詳細　> フォルダを常に先頭に表示する場所 > チェックする
![スクリーンショット 2023-04-16 午後4.11.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/c7b58077-0caa-bb10-6576-813b57a7a5b9.png)


# 表示項目の設定
- 表示 > パスバーを表示
- 表示 > ステータスバーを表示
 ![スクリーンショット 2023-04-07 9.57.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/c808c4e5-09ae-b20c-042e-245da100e0e6.png)

- 表示 > 表示オプションを表示 > 表示する項目: > 各自設定
![スクリーンショット 2023-04-07 10.02.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/44cee4d7-173b-70ce-ffb2-391fca874629.png)

# 隠しファイルを表示
- ショートカット（command shift .）で切り替え
　※ ファイル名が.(ドット)で始まる隠しファイルは隠しファイルが表示される

# .DS_Store ファイルの生成を抑制
- ネットワークドライブ上への .DS_Store ファイルの生成を抑制

```:ターミナル
defaults write com.apple.desktopservices DSDontWriteNetworkStores true
```

# スクリーンショットの保存先を変更
- `comand`+`shift`+`5`で画面収録を起動
- オプション > 保存先 > `ピクチャ`にチェック ※お好み

# ショートカットキーの変更
既存のショートカットキーは以下で確認できる

https://pc-karuma.net/mac-finder-shortcut-key-list/

その中で自分は「進む」と「戻る」を変更した。
変更方法は以下の通り

- システム環境設定 > キーボード > キーボードショートカット
![スクリーンショット 2023-04-27 8.12.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/886aba96-98bb-9acf-ed85-f1d485962361.png)

- アプリケーション > +マーク > アプリケーションでFinder.appを選択

![スクリーンショット 2023-04-27 8.13.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/970b9b85-7e21-2672-9a4b-355e2bfcc195.png)

- メニュータイトルに「進む」と入力し、キーボードショートカットで`command` `→`を押して、完了

- 以下のように設定されていることを確認

![スクリーンショット 2023-04-27 8.16.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/4755f6fb-543d-f909-2bba-a0052d0730cb.png)

# デフォルトの表示内容を設定
ヘッダーのView→ Show View Options

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/e9b246aa-d872-a1d2-81a5-f5bd191d5a99.png)

設定を行い、Use as Defaultsを押下で、デフォルト設定となる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/954726ee-e082-60fb-5374-4c08175c9847.png)
Google Chromeの設定をしてみた

# はじめに
- Google Chromeのインストール

https://www.google.com/intl/ja/chrome/gsem/download/?brand=YTUH&gclid=Cj0KCQjwxMmhBhDJARIsANFGOSsysMCMsAfdxaferUMH6mLd4BRJ-M5bUF7K1lkALazd0nUt2v_fdcMaAnckEALw_wcB&gclsrc=aw.ds

# 各種設定
## 開いているタブを保存し、再起動時も同じように復元
- メニューバーのChrome > 設定 > 起動時 > 前回開いていたページを開く
![スクリーンショット 2023-04-05 9.44.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/3d69ddec-ba55-003b-004e-ec3ecb652526.png)

## デフォルトの表示倍率の変更
- メニューバーのChrome > Appearance > Page zoom > 個人設定
![Screenshot 2023-05-19 at 12.11.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2674841/14f8340f-83e0-5dfb-bba4-bcdf7ab93a0c.png)


# 拡張機能
## Google翻訳
- テキストを選択するとGoogle翻訳アイコンが表示される

https://chrome.google.com/webstore/detail/google-translate/aapbdbdomjkkjkaonfhkkikfgjllcleb/related?hl=ja

## Google検索キーボードショートカット
- googleで検索後、Enterキーでwebサイトを開ける

https://chrome.google.com/webstore/detail/google-search-results-sho/dchaandmcifgjemlhiekookpgjmkcelg?hl=ja

## WebChatGPT
- ChatGPTで最新の情報を入手できる

https://chrome.google.com/webstore/detail/webchatgpt-chatgpt-with-i/lpfemeioodjbpieminkklglpmhlngfcn/related?hl=ja

## Dark Reader
- Google Chromeのwebページ内をダークモードにする

https://chrome.google.com/webstore/detail/dark-reader/eimadpbcbfnmbkopoojfekhnkhdbieeh?hl=ja

## Enhancer for youtube
- YouTubeの各種設定ができる

https://chrome.google.com/webstore/detail/enhancer-for-youtube/ponfpcnoihfmfllpaingbgckeeldkhle?hl=ja

## JSON Viewer
- JSON形式のデータを見やすくする

https://chrome.google.com/webstore/detail/json-viewer/efknglbfhoddmmfabeihlemgekhhnabb

## keyboard-shortcuts
- Chromeで使うショートカットを自由に設定できる

https://chrome.google.com/webstore/detail/keyboard-shortcuts/lplcmnhgijkkmflbmhabnccgelffpnog/related?hl=ja

設定しているショートカットは以下
|名前|ショートカット|
|-|-|
|Select previous tab|⌘ ↑|
|Select next tab| ⌘ ↓|
|Move current tab left|⌘ ,|
|Move current tab right|⌘ .|
|Pin / Unpin current tab|^ P|


解説記事は以下

https://localhost8888.net/note/602/
pi picoでmicropython その42

# 概要
picoでmicropythonやってみた。
練習問題やってみた。

# 練習問題
serialに、sin,cosを吐き出せ。

# サンプルコード

```
from time import time, sleep
from math import sin, cos
def main():
   for i in range(0, 360):
      x = sin(6.283185 * i / 120)
      y = cos(6.283185 * i / 120)
      print("{0},{1}".format(x, y))
      sleep(1)


main()


```

# 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/e3b6e0c7-81e6-d47c-ab58-8f01f25e46be.png)


以上。
自作のプログラムでオプションを使えるようにする(optparse)

# 前提
自分で何かプログラムを作成し、ターミナルでそれを実行します。その際オプションをつけ、引数を1つ指定できるようにすることを目標とします。
そういった時に使えるoptparseについて学んだので使い方を簡単にまとめておきます。

# optparseとは
- Rubyの標準ライブラリの1つ
- コマンドラインのオプションを取り扱うライブラリ

# 使い方
基本的には以下の流れになります。
1. optparseをrequireする
1. OptionParser オブジェクト opt を生成する
1. オプションを取り扱うブロックを opt に登録する
1. opt.parse(ARGV) でコマンドラインを実際に parse する

それぞれ詳しく見ていきます。

### 1. optparseをrequireする
optparseは組み込みライブラリではないので、まず最初にrequireする必要があります。
```ruby:sample.rb
require 'optparse'
```

### 2. OptionParser オブジェクト opt を生成する
次にOptionParserオブジェクトを生成します。
```ruby:sample.rb
opt = OptionParser.new
```

### 3. オプションを取り扱うブロックを opt に登録する
今回はオプションの引数に指定された値を後の処理で使いたいことを想定しています。そういった場合は`params`などを用意してそこに値を格納します。
`-m`のところでオプションとして`-m`を受け付けるようにして、その後ろの`VAL`で引数を受け付けることの指定をしています。
ここはあくまでも登録をしているだけでこれだけでは実行されません。
```ruby:sample.rb
params = {}
opt.on('-m VAL') { |v| params[:m] = v }
```

### 4. opt.parse(ARGV) でコマンドラインを実際に parse する
これでパースします。
parseが呼ばれた時に、コマンドラインにオプションが指定されていれば3で登録した処理が実行されます。
```ruby:sample.rb
opt.parse!(ARGV)
```
cscの作法 その303

# 概要
cscの作法、調べてみた。
練習問題やってみた。

# 練習問題
serialを読み取って、sin波を描画せよ。

# 方針
- ポートは、COM3
- ボーレートは、115200
- 書式は、0.123,0.123

# サンプルコード

```

using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO.Ports;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;

class form1: Form {
	private SerialPort port1;
	private static List<float> ff0 = new List<float>();
	private static List<float> ff1 = new List<float>();
	form1() {
		Text = "draw";
		ClientSize = new Size(400, 400);
		for (int i = 0; i < 360; i++)
		{
			ff0.Add(0);
			ff1.Add(0);
		}
		port1 = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
		port1.BaudRate = 115200;
		port1.Parity = Parity.None;
		port1.DataBits = 8;
		port1.StopBits = StopBits.One;
		port1.Handshake = Handshake.None;
		port1.PortName = "COM3";
		port1.DtrEnable = true;
		port1.RtsEnable = true;
		port1.DataReceived += new SerialDataReceivedEventHandler(DataReceived_Handler);
		port1.Open();
	}
	protected override void OnPaint(PaintEventArgs e) {
		Graphics g = e.Graphics;
		Pen pen0 = new Pen(Color.Gray, 2);
		Pen pen1 = new Pen(Color.Pink, 2);
		SolidBrush brush = new SolidBrush(Color.Yellow);
		for (int i = 0; i < 359; i++)
		{
			float x0 = (200 + ff0[i] * 140);
			float x1 = (200 + ff0[i + 1] * 140);
			g.DrawLine(pen0, 20 + i, x0, 20 + i, x1);
			float y0 = (200 + ff1[i] * 140);
			float y1 = (200 + ff1[i + 1] * 140);
			g.DrawLine(pen1, 20 + i, y0, 20 + i, y1);
		}
	}
	private delegate void SetTextDelegate(string msg);
	private static void SetText(string msg) {
		string[] lines = msg.Split(new string[] {
			","
		}, StringSplitOptions.None);
		float d = 0;
		float e = 0;
		if (float.TryParse(lines[0], out d) && float.TryParse(lines[1], out e))
		{
			ff0.Add(d);
			ff0.RemoveAt(0);
			ff1.Add(e);
			ff1.RemoveAt(0);
		}
		else
		{
			Console.WriteLine(msg);
		}
	}
	private void DataReceived_Handler(object sender, SerialDataReceivedEventArgs e) {
		SerialPort sp = (SerialPort) sender;
		string msg = sp.ReadExisting();
		//Console.Write(msg);
		this.Invoke(new SetTextDelegate(SetText), new object[] { msg });
		this.Invalidate();
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}





```

以上。
【備忘録】よく使う言語の命名規則

# この記事の目的
むっちゃ個人的に「あれ？この言語だとクラス名は大文字だっけ？」とかごっちゃになったりしてたので，備忘録というかメモ書きとして記録しておく用の記事
（間違いとかがあったら優しく教えてください）


## 各記法の名称と例
| 記法 | 例 | 意味 |
|:-:|:-:|:-:|
| スネークケース |すべての単語は小文字<br>単語と単語はアンダーラインでつなげる| `snake_case` | 
| アッパーキャメルケース（パスカルケース） | すべての単語は大文字<br>単語と単語はそのままつなげる| ` UpperCamelCase` |
| ローワーキャメルケース（キャメルケース） | 最初の単語は小文字で，以降は大文字から始める<br>単語と単語はそのままつなげる | `lowerCamelCase` |
| ケバブケース | すべての単語は小文字<br>単語と単語はハイフンでつなげる | `kebab-case` |

## C言語の命名規則
| 種類 | 記法 | 例 |
|:-:|:-:|:-:|
|ディレクトリ名| アッパーキャメルケース | `UpperCamelCase` |
|ファイル名| ローワーキャメルケース | `lowerCamelCase` |
|グローバル関数| アッパーキャメルケース | `UpperCamelCase` |
|ローカル関数| ローワーキャメルケース | `lowerCamelCase` |
|グローバル変数| アッパーキャメルケース | `UpperCamelCase` |
|ローカル変数| ローワーキャメルケース | `lowerCamelCase` |
|引数名| ローワーキャメルケース| `lowerCamelCase`|
|定数名|スネークケース（大文字）|`SNAKE_CASE`|
|構造体（タグ）|アッパーキャメルケース|`UpperCamelCase`|
|構造体（メンバ）|ローワーキャメルケース|`lowerCamelCase`|

## Javaの命名規則
| 種類 | 記法 | 例 |
|:-:|:-:|:-:|
|クラス名|アッパーキャメルケース|`UpperCamelCase`|
|メソッド名|ローワーキャメルケース|`lowerCamelCase`|
|定数名|スネークケース（大文字）|`SNAKE_CASE`|
|フィールド名|ローワーキャメルケース|`lowerCamelCase`|

## JavaScriptの命名規則
| 種類 | 記法 | 例 |
|:-:|:-:|:-:|
|コンポーネント名|アッパーキャメルケース|`UpperCamelCase`|
|変数名|ローワーキャメルケース|`lowerCamelCase`|
|定数名|スネークケース(大文字)|`SNAKE_CASE`|
|メソッド名|ローワーキャメルケース|`lowerCamelCase`|
|プロパティ名|ローワーキャメルケース|`lowerCamelCase`|
|クラス名|アッパーキャメルケース|`UpperCamelCase`|

## Pythonの命名規則
| 種類 | 記法 | 例 |
|:-:|:-:|:-:|
|パッケージ名|英小文字のみ（アンダースコアなし推奨）|`lowercase`|
|モジュール名|スネークケース|`snake_case`|
|クラス名|アッパーキャメルケース|`UpperCamelCase`|
|変数名|スネークケース|`snake_case`|
|関数名|スネークケース|`snake_case`|
|定数|スネークケース（大文字）|`SNAKE_CASE`|

参考URL: [pep8-ja](https://pep8-ja.readthedocs.io/ja/latest/)
***

使う言語が増えたら随時更新予定
IT技術者が使えるChatGPTの使い方

IT技術者が今、注目されているChatGPTをどのように活用できるか考えて見ました。
ITでChatGPTを活用の例としてプログラムコードの生成は取り上げられています。しかし、ChatGPTはそれ以外に次のように活用することもできます。但し、何時も回答が正しいとは限らないので最終的には自分で内容を見直して判断する必要があります。

これらについて実際にChatGPTを利用した場合の注意点について詳細を記述していきます。ChatGPTは色々なことはできますが、使い方により自分の生産性が悪化することが分かりました。ChatGPTがどのようなことが出来るかのような遊びのツールとしての説明ではなく、実際の現場でChatGPTを利用して自分の生産性を上げる方法について述べていきます。

# プログラム開発支援
1. ソースコードの生成
1. アルゴリズム及びデザインパターンの案
1. エラーコードの説明と対策案の提示
1. テストケースの生成
1. テスト用データの生成
1. 開発スケジュール案の作成
1. ドキュメントの作成

# 勉強支援
1. 技術を勉強するスケジュール案の作成
1. 技術を勉強するための推奨教材案の作成
1. 不明な技術の詳細説明と利用サンプルの作成（例：コード例）

# 開発支援
1. コマンドを探す
1. 異なるネットワーク機器の互換コマンドを探す
1. サンプルコードの作成

# サービス／機能の確認
1. サービス及びモジュールで機能をサポートしているか確認する（最新の情報を確認する場合はWebChatCPTを使う）
1. 英語ドキュメントの翻訳を要約

# 資格試験の演習
1. キャリアパスに有力な資格一覧の作成
1. 資格試験の演習問題の作成
1. 問題集の回答の詳細説明
1. 試験のために勉強するスケジュールの作成

# 就職活動の支援
1. キャリアパスのアドバイス
1. 履歴書作成支援
1. 就職希望企業の情報収集
    1. 会社情報の要約
    1. 会社評価
    1. 会社の風習
1. 面接の練習
    1. 対象企業で面接によく出てくる質問一覧の作成と好評価の回答例
    1. ChatGPTに面接官になってもらい、面接の練習
    1. 面接に来ている服装のアドバイス

# ブログの作成
1. 高評価を得るために取り上げる課題一覧の作成
1. 高評価を得るための文書作成
1. 書いた文書の編集と校正（人気ブロガー風に書き直してもらうなどを含む）

# プロジェクト管理
1. 企画書／設計書などの下書きの作成
1. タスク一覧の作成
1. ガントチャートの作成

以上
【Bash】リダイレクトやパイプの権限

## 経緯

bash で実行ユーザが write 権限を持たないファイルに `sudo cat` コマンドで書き込もうとしてエラーにあたりました。リダイレクトとパイプについて少し知識が深まったのでメモを残します。

```bash
$ whoami
testuser
$ ls -l ./testfile
-rw------- 1 otherusr othergrp 13 Apr  7 20:23 ./testfile
$ sudo cat ./testfile
this is test
$ sudo cat << EOF > ./testfile
> abc
> EOF
-bash: ./testfile: Permission denied
$ sudo cat ./testfile
this is test
```

リダイレクトと Linux における権限への理解が浅く、 Permission denied されました。

ここでは `cat` は標準入力から入力を受け付けて標準出力に出力しているだけなので特権を必要としないですね。必要としているのは他のユーザ `otherusr` が所有者になっているファイル `./testfile` に書き込もうとしているリダイレクト`>`でした。

## 原因

リダイレクト `>` はコマンドではなくシェルの機能[^1]なのでシェルの実行ユーザの権限を持ちます。この権限が出力先ファイルの書き込み権限を満たさないといけません。パイプ `|` も同じです。

## 間違いパターン

### `sudo cat` パターン

上記[経緯](#経緯)のパターン

```bash
$ whoami
testuser
$ ls -l ./testfile
-rw------- 1 otherusr othergrp 13 Apr  7 20:23 ./testfile
$ sudo cat ./testfile
this is test
$ sudo cat << EOF > ./testfile
> abc
> EOF
-bash: ./testfile: Permission denied
$ sudo cat ./testfile
this is test
```

`cat` が必要とする権限は入力となるファイルの read 権限だけなので、 cat に対して sudo は必要ないです。ここで Permission denied されているのはリダイレクトです。つまり原因はリダイレクトがファイルへの write 権限を持っていないことでした。

## 正解パターン

:::note warn
4/16 追記: [@ko1nksm さんのコメント](https://qiita.com/dkmats/items/dda2b50de41388fe2cea#comment-a06a27943ced20ec1ab5) の方が簡潔でした。筆者が考えたパターンは無駄が多かったです。
:::

### sudo sh -c パターン

`sudo sh -c` を使うパターン。 `sh` は `bash` でも大丈夫です[^2]。

```bash
$ sudo sh -c "cat << EOF > ./testfile
> abc
> EOF"
$ sudo cat ./testfile
abc
```

### sudo tee パターン

リダイレクトの代わりに `パイプ -> sudo tee` 経由で目的のファイルに渡すパターン。`tee`が `sudo` 権限を持つので `./testfile` に書き込むことができます。`tee` から標準出力への出力は `/dev/null` に捨てます。

```bash
$ cat << EOF | sudo tee ./testfile > /dev/null
> xyz
> EOF
$ sudo cat ./testfile
xyz
```

## 最後に

`sudo sh -c` パターンが一番わかりやすいと感じました。よりよい解決方法などがありましたらコメントで教えてもらえると嬉しいです。

## 参考

### sudo(8) - Linux manual page

https://man7.org/linux/man-pages/man8/sudo.8.html

### Redirections - Bash reference Manual

https://www.gnu.org/software/bash/manual/html_node/Redirections.html

## LICENSE

[![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by-sa/4.0/88x31.png)](https://creativecommons.org/licenses/by-sa/4.0/)

本記事は [CC-BY-SA-4.0](https://creativecommons.org/licenses/by-sa/4.0/) ライセンスの基に公開しています。
このライセンス文の日本語版は下記ページをご確認ください。

https://creativecommons.org/licenses/by-sa/4.0/deed.ja

[^1]: 特定のファイルディスクリプタからの出力先ファイルを指定する機能。
[^2]: bash にも `-c` オプションがあるので。
push時の「error: failed to push some refs to」についてのメモ


# Pushしようとしたころエラーが発生
Gitで新規リモートリポジトリを作成し、そこへファイルをpushしようとしたところ、下のエラーが発生
```
error: failed to push some refs to 'リポジトリ名'
```
いろいろと調べてみたが、解決せず。。。
# 解決方法
最近PCを新調してGitをインストールしなおしたので、もしやユーザー情報が紐づいていないのでは！？と思い、
以下のコマンドを実行
```
git config --global user.email "gitに登録しているメールアドレス"
git config --global user.name "gitのユーザー名" 
```

その後、push実行
```
git push -u origin main
```
無事Pushできました(;^_^A
【独学メモ】- laravelのモデルとマイグレーション -

# 前書き
この記事は自分のための学習アウトプットメモです。
職場でphpを利用してシステムを運用しているので、ある程度の知識を得ておきたいと思い学習を開始しているだけなので、どうぞ暖かく見守ってくれたら嬉しいです。

# この記事の目的
laravelのモデルの作成とマイグレーションについてまとめる。
※ MVCの概念については、Ruby on Railsの学習である程度把握しているので、あんまり深く触れるつもりないよ。

# M - Model -について
DBとのやりとりを担当する役割を担う。
DBとのやりとりは、Railsと同様でORMでやりとりをする様子。
ORM -> Object Relational Mapping
つまるところ、SQL文を書くんじゃなくて、phpの構文でSQLとやりとりするって意味（だと思っている）

:::note info
ORMについて個人的な疑問。
フレームワーク側で構文を準備してくれていることはありがたいんだけど、 SQL文とか直接書いた方が効率良さそうに感じてしまう。
素人目からすると、わざわざphpの構文で記述 → それをSQL文として読み取ってDBとやりとり。という形をとっているように見えて二度手間に感じてしまう。
この辺りは後日調べてみよう。
もしかしたら、データベースの種類ごとに構文が変わる？だからphp側で構文を用意しておけば、どのDBを利用しているかを意識する必要がない。とか・・・？
:::


## モデルの作り方
ターミナル上（モデルを作りたいプロジェクトのディレクトリ配下）で、以下のコマンドを実行

```
php artisan make:model {作成したいモデル名}
```
そうすると、/app/Models配下に作成される。
作成されたファイルの中身を見ると、class名が{作成したいモデル名}と同じで、そのクラスはModelクラスを継承していることが確認できる。

:::note info
モデル名は単数系かつ、頭は大文字
例）
User -> ◯
user -> ×
Users -> ×
:::
※補足
コントローラーとマイグレーションも同時に行うことができたりもする。
その場合は、作成時のコマンドにオプションを追記すればOK

```
php artisan make:model {作成したいモデル名} -mc
```
m:マイグレーション、c:コントローラーって覚えておけば忘れにくそう。

## マイグレーションファイルを作ってModelに紐づくテーブルを作成する
基本的にModelとテーブルは1対1でペアになる（と思っている）ので、さっき作ったModelで参照するテーブルを作成する。
そのためには、テーブルを作るための設計書的な立ち位置のmigrationファイルを作成する必要がある

### migrationファイルの作り方
ターミナル上（モデルを作りたいプロジェクトのディレクトリ配下）で、以下のコマンドを実行
```
php artisan make:migration create_{作成したモデルの名前の複数形}_table
```
これを実行すると、app/database/migrations配下に、以下命名規則に則ったmigrationファイルが作成される
`yyyy_mm_dd_hhmmss_create_※※※※※※_tables.php`
これがさっき言ってた「テーブルを作るための設計書的な立ち位置のmigrationファイル」になる。

### 必要なカラムなどを追記する
`yyyy_mm_dd_hhmmss_create_※※※※※※_tables.php`ファイルを開いて、追加したいカラムを記載する
```migrationファイル.php
/*
 省略 
*/
    public function up()
    {
        Schema::create('{コマンドで指定した複数形の名前}', function (Blueprint $table) {
            $table->id();
            /*
            この辺りに追加したいカラムを記述する。
            例） 年齢を管理するカラム`age`を追加する場合
            $table->integer('age');
            */
            $table->timestamps();
        });
    }
/*
 省略
*/
```

:::note info
Laravelで利用できるデータ型は以下のドキュメント参照
https://readouble.com/laravel/9.x/ja/migrations.html#column-method-bigIncrements
:::

### DBへの反映
必要なカラムを追記したら、DBに反映させる作業が必要になる。
ターミナル上で以下のコマンドを実行することでDBへ反映可能。
```
php artisan migrate  
```

# 最後に
基本的に自分向けのメモなので、参考にする方などはいらっしゃらないと思いますが、
もしどなたか有識者がこの記事を目にして「あ、いやなんかそこ認識違うぞ」と思う箇所あればご指摘いただければ幸いですm(_ _)m
（そのためにあえてこの駄文を公開設定しているので・・・笑)
Tasker でバッテリーの温度を取得する

## 1. プロファイルの新規作成から「イベント」を選択

![Screenshot_20230408-185822.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/b1fa3cbe-27bb-b636-0762-207cffe1005f.png)

## 2. イベントのカテゴリーから「システム」を選択

![Screenshot_20230408-185902.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/9769af4c-40cf-72ed-a70f-a8ac72fe5f4d.png)

## 3. システムイベントから「インテントを受信した」を選択

![Screenshot_20230408-185919.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/e498e98d-cb2f-0554-38cd-0d463a832ed4.png)

## 4. アクションに以下を指定

```
android.intent.action.BATTERY_CHANGED
```

![Screenshot_20230408-190000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/986ef88f-030c-3d89-2a93-64d9423587d4.png)

## 5. 新しいタスクを追加

![Screenshot_20230408-190150.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/b7e55fb2-1a73-36e5-9ac5-0736842e6dd2.png)

## 6. アクションを追加

変数 ＞ 変数を設定
![Screenshot_20230408-190248.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/1047c21d-d0a9-e35e-001d-e7bdd25f2a74.png)

## 7. 以下の内容を指定

| 項目 | 設定値 |
| :-: | :-- |
| 名前 | %temp |
| これに | %temperature / 10 |
| 計算する | チェック |

![Screenshot_20230408-190317.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/3daf62e4-436e-212f-a41b-738bb30e0b90.png)

## 8. アクションを追加

アラート ＞ 通知を表示
![Screenshot_20230408-190220.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/3eee88b9-b568-5a61-4939-fb598a498957.png)

## 9. 以下の内容を指定

| 項目 | 設定値 |
| :-: | :-- |
| タイトル | 温度 |
| 文字 | %temp ℃ |

![Screenshot_20230408-190342.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/0fc7f2e6-04c9-61a9-58ce-817064b56f0f.png)

## 通知の表示内容

![Screenshot_20230408-191139.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76370/9fe84e99-9c50-eee3-06f6-d5a4b3920f92.png)
ERROR 1044 (42000): Access denied for user 'ユーザー名'@'%' to database 'データベース名'

権限があるのに、データベースが作成できずはまったのでメモします。

まずは、権限の確認。
全ての権限をもっていましたが、データベースが作成できませんでした。
```mysql:mysql
mysql> show grants;
+-------------------------------------------------------------+
| Grants for saaaMPro.local@%                                 |
+-------------------------------------------------------------+
| GRANT USAGE ON *.* TO `ユーザー名`@`%`                  |
| GRANT ALL PRIVILEGES ON `db1`.`＊` TO `ユーザー名`@`%`  |
+-------------------------------------------------------------+
```
一旦、退出します。
```mysql:mysql
mysql> exit;
Bye
```
次は、rootで入り、作成したい名前のデータベースに権限を与えます。
```mysql:mysql
mysql> GRANT ALL PRIVILEGES ON データベース名.* TO 'ユーザー名'@'%';
Query OK, 0 rows affected (0.00 sec)

```
データベースを作成します。
```
mysql> CREATE DATABASE データベース名 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
Query OK, 1 row affected (0.01 sec
```
最後に確認
```
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| performance_schema |
| データベース名        |
+--------------------+
```

今回は、ChatGDPに全て聞きました笑
すごい！！！！！
まずは、試してみる！
[ChatGDP](https://openai.com/blog/chatgpt"ChatGDP")
[laravel 9] npm run devが起動しない

環境
laravel 9.0
laravel/breeze 1.19


laravelで認証機能ライブラリのbreezeをインストールをしようとしたらハマったで備忘録として残します。


[リファレンス](https://readouble.com/laravel/9.x/ja/starter-kits.html)に従ってコマンドを打ちます。

`composer require laravel/breeze --dev`

bladeで使用する場合は、以下のコマンドを使用。　
reactやvueは、他のコマンドを使用。
`php artisan breeze:install`


アプリケーションのCSSファイルを使用できるようにアセットをコンパイルさせるコマンド
`npm install`

`npm run dev`
↑コマンドここでハマった。

### エラー内容
`npm run dev`で起動しても終了してしまい、`php artisan ser`でサーバを立ち上げて、アクセスをすると以下のエラーになる。

```
Vite manifest not found at: ファイルパス

Start the development server
Run `npm run dev` in your terminal and refresh the page.
```
エラー内容通りに`npm run dev`実行するも、起動しない。

### 解決方法　

package.josnの内容を変更

変更前
```package.josn
{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production"
    },
    "devDependencies": {
        "@tailwindcss/forms": "^0.5.2",
        "alpinejs": "^3.4.2",
        "autoprefixer": "^10.4.2",
        "axios": "^0.25",
        "laravel-mix": "^6.0.6",
        "lodash": "^4.17.19",
        "postcss": "^8.4.6",
        "tailwindcss": "^3.1.0"
    }
}
```

変更後
```package.josn
{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "mix",
        "watch": "mix watch",
        "watch-poll": "mix watch -- --watch-options-poll=1000",
        "hot": "mix watch --hot",
        "prod": "npm run production",
        "production": "mix --production",
        "dev": "vite",
        "build": "vite build"
    },
    "devDependencies": {
        "@tailwindcss/forms": "^0.5.2",
        "@vitejs/plugin-vue": "^4.0.0",
        "alpinejs": "^3.4.2",
        "autoprefixer": "^10.4.2",
        "axios": "^0.25",
        "laravel-mix": "^6.0.6",
        "laravel-vite-plugin": "^0.7.4",
        "lodash": "^4.17.19",
        "postcss": "^8.4.6",
        "tailwindcss": "^3.1.0",
        "vite": "^4.1.4"
    }
}

```


### 原因
アプリ新規作成時に9を指定していたが、8になっており、コンパイルが9からviteに変更になったため、Mixのままになっていたから。
UE5.1.1のAndroidビルドエラーとその解決策について

# はじめに
小ネタですがUE5.1.1でAndroidビルドした際にエラーで動かなかったのでその原因と解決策を

# 環境
UnrealEngine 5.1.1
Android Studio 4.0
Android NDK 25.1.8937393
Windows11 Pro


# 状況
UE5.1.1のAndroidビルドがGradleにてエラーで失敗する
![2023-04-09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659544/d2b16327-6a6b-16ac-4d07-330a13a9008b.png)

エラーの最初のほうが見切れてしまってますが内容は下記の通りです([hogehoge]はユーザー名)
>\* What went wrong:
>Could not update C:\Users\hogehoge\\.gradle\caches\6.1.1\file-changes\last-build.bin
> \> C:\Users\hogehoge\\.gradle\caches\6.1.1\file-changes\last-build.bin (???????????)
>\* Try:
>Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
>\* Get more help at https://help.gradle.org
>ERROR: cmd.exe failed with args /c "D:\Unreal Projects\Test51_2\Intermediate\Android\arm64\gradle\rungradle.bat" :app:assembleDebug


# 考察
メッセージから"C:\Users\hogehoge\\.gradle\caches\6.1.1\file-changes\last-build.bin"へのアクセスが失敗してるっぽいことまではわかるけど見てみると存在はするし・・・としばしハマる
・・・何のことはない書き込み禁止になってただけでした（汗
UE関係なかった！

# 対応
・"C:\Users\hogehoge\\.gradle"フォルダとフォルダ内の全ファイルに対して書き込み禁止属性を解除
・Windows再起動（ファイルを掴んだままなのか再起動しないと動かなかった）

# おわりに
UE5.1からSDKやNDKの対応バージョンが変更になり微妙に面倒なところでエラーが出ると原因の可能性が多岐に渡るので慌ててしまうんですよね
判ってしまえば簡単なことなのですが気がつかないこともあるので同じような状況の方がいたときに解決の手助けになれば！

# 参考
[UE4] Androidパッケージ作成失敗時に "Run with --stacktrace option to get the stack trace..." というエラーログが出力された時にすること(https://qiita.com/EGJ-Kaz_Okada/items/e325c5e2f8807f430076)

Unity ARFoundation Gradle build fails - last-build.bin access denied(https://stackoverflow.com/questions/51515138/unity-arfoundation-gradle-build-fails-last-build-bin-access-denied)
Google Fontsの使い方

本日はGoogle Fontsと使い方を学んだので投稿します。

○Google Fontsとは
---
Webフォントの一つでフォントのデザインデータをインターネット上から自動で読み込む仕組みの事。
簡単に文字のデザインが変更できるサービスの事！

○使い方
---
①https://fonts.google.com/
　上記のURLでGoogle Fontsを開きます。

②使用したいフォントデザインを選びます。

③フォントの太さや字体を選び、右上のアイコンをクリックします。

https://i.gyazo.com/1b58edf48b463a583e91d941ca1fc6fb.png

右上のアイコンの画像

④クリックしたらHTMLとCSSのコードが現れるのでコピーして変更したいファイルに
貼り付けたら完了です。

以上がGoogle Fontsと使い方です。便利な機能なので活用していきたいです！
Azure KinectはUSB3.1Gen2では正常動作しない

Azure Kinect ViewerでAzure Kinectの表示をしようとしたら、エラーが出て表示できなかった。

# エラー内容
```
Failed to start device!
If you unpluged the device, you must close and reopen the device.
```
![2023-04-09_15h36_37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506075/1a9fc1be-0ee1-6ad3-a138-0f0b7db3e48d.png)

# 対応方法
USB 3.1 Gen2からUSB 3.1 Gen1に変更したら正常に動作するようになった。

# その他
* USB 3.1 Gen2に接続している状態でも、デバイスマネージャーからはAzure Kinectは見えていて、正常に接続できているように見えいていた。
* Windows付属のCameraアプリでもAzure Kinectからカメラ画像の表示はできていた。ただしじゃっかんちらつきが発生することがあり、違和感はあった。
Ubuntu 20.04で外付けDVDが認識されない

Ubuntu20.04で外付けDVDが認識されずDVDを閲覧することができない。

Windowsでは問題なく使えている外付けDVDがUbuntu20.04では認識されない。USBを接続すると一時的にDVDドライブが点滅しますが、直ぐに消えて内容を見ることができない。
Disksを開くとDVDは認識されていますが、「No Medium」と表示されてマウントすることはできない。

参照リンクに上げたページの回答にあるように/etc/udev/rules.d/60-persistent-storage.rulesを/etc/udev/rules.dに複写して修正して再起動したらVLCで映画を見ることができました。

# 参照リンク
[DVDs not mounting in Ubuntu 20.04 - works fine in Windows](https://askubuntu.com/questions/1328762/dvds-not-mounting-in-ubuntu-20-04-works-fine-in-windows)

以上
Javadocまとめ[自分用]

# Javadocとは
Javaのソースコードに記述されたJavadoc用のコメントから
HTML形式のAPI仕様書を作成してくれる便利機能！

## 記述形式
`/**`で始まり`*/`で終わる。  
Javadocコメントの中には「説明文」と「Javadocタグ」を記述できる。

| タグ         | 記述内容                                                                                                                           | 
| ------------ | ---------------------------------------------------------------------------------------------------------------------------------- | 
|  `@author`     | 開発者名                                                                                                                           | 
| `@param`       | メソッドの引数や総称型のパラメータを記述する。<br>引数の数だけ記述する必要がある。<br>引数名と引数の概要を記述する。               | 
| `@return`      | メソッドの戻り値を記述する。戻り値がvoidの時は記述しなくて良い。                                                                   | 
| `@exception`   | メソッドが投げる例外クラスとその説明を記述する。                                                                                   | 
| `@version`     | クラスまたはメソッドのバージョンを記述する。<br>バージョン管理システムを用いてこのバージョン番号割り当てを自動化することができる。 | 
| `@deprecated`	 | 廃止されたクラス やメソッドに付けられる。<br>コンパイル時にこれがつけられたメソッドを使用すると警告を発する。                      | 

## ドキュメントを生成する
javadoc [options] [packagenames] [sourcefiles] [@files]

## 参考リンク
- [Oracle 公式ドキュメント](https://docs.oracle.com/javase/jp/17/docs/specs/man/javadoc.html#standard-options-for-the-standard-doclet)
- [Javadoc ドキュメンテーションコメントの書き方](https://qiita.com/maku77/items/6410c67ce95e08d8d1bd)
DockerでPostgreSQLをクライアントにて管理する仮想環境の構築をしてみた。

# DockerでPostgreSQLをクライアントにて管理する仮想環境の構築をしてみた。
[前回](https://qiita.com/yukishi24/items/317a3b7157ff51328d36)は、Dockerを使用してhello worldを表示する仮想環境を構築しました。
今回は、webアプリを開発する上で欠かせないDBを仮想環境に構築しました。
## 使用image
- [postgreSQL : 14](https://hub.docker.com/_/postgres)
- [pgadmin](https://registry.hub.docker.com/layers/dpage/pgadmin4/5.2/images/sha256-38617bc122e547dcfe3adaba52143f583343928b3700ada6feb9dcf6d13e0ca6?context=explore)
## 起動方法
- compose作成
```
docker-compose up -d
```
[localhost](http://localhost:5050)に接続
参考にしたサイトは[こちら](https://zukucode.com/2022/11/docker-postgres.html)
Git Hubは[こちら](https://github.com/yukishi24/Docker_PostgreSQL_client_sample)

次回は、Spring BootとPostgreSQLを使用した簡単なwebアプリケーションを開発します。
WPGraphQLのエラーについて

# WPGraphQLのエラーについて
WordPressでGraphQLを使用する際、GraphiQL画面で読み込みが終わらず、デベロッパーツールのコンソールに以下のようなエラーが表示される場合があります。

```
Uncaught (in promise) GraphQLError: Names must only contain [_a-zA-Z0-9] but "Template_空白" does not.
```

解決方法しない場合は以下で対応することができます。

・設定の「サイトの言語」を英語に変更する
・外観の「テーマ」　を変更する
　※タイトルに半角が含まれていないものを選択してくだい

一時的な対処なので、プラグインの開発者がエラーを修正するまで待つことが適切かと思います。
exe化したPythonのChromeDriverManager().install()で発生するAttributeErrorの解決方法

## 背景
pyinstallerでpythonファイル群をexe化したら、動いていたはずのアプリが動かない。
スタックトレースを確認したところ、ChromeDriverManager().install()でAttributeErrorが発生していた。


## 前提
|  ライブラリなど  |  バージョン  |
| ---- | ---- |
|  webdriver-manager  |  3.8.5  |
|  pyinstaller  |  5.9.0  |
|  pyinstaller-hooks-contrib  |  2023.1  |
|  python  |  3.10.7  |

## 再現コード
```error_rep.py
from webdriver_manager.chrome import ChromeDriverManager

if __name__ == '__main__':
    # オプション設定
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-extensions')
    options.add_argument('--proxy-server="direct://"')
    options.add_argument('--proxy-bypass-list=*')

    # ↓でエラー
    new_driver = ChromeDriverManager().install()

    service = Service(executable_path=new_driver)
    return webdriver.Chrome(service=service, options=options)

```
ソースが記述できたのでexe化
```コマンドライン
pyinstaller error_rep.py --onefile --noconsole
```

すると以下のエラーが発生
```
Traceback (most recent call last):
  File "error_rep.py", line 13, in main
  File "webdriver_manager\chrome.py", line 39, in install
  File "webdriver_manager\core\manager.py", line 30, in _get_driver_path
  File "webdriver_manager\core\download_manager.py", line 28, in download_file
  File "webdriver_manager\core\http.py", line 35, in get
  File "webdriver_manager\core\utils.py", line 289, in show_download_progress
  File "tqdm\std.py", line 1095, in __init__
  File "tqdm\std.py", line 1344, in refresh
  File "tqdm\std.py", line 1492, in display
  File "tqdm\std.py", line 347, in print_status
  File "tqdm\std.py", line 340, in fp_write
  File "tqdm\utils.py", line 71, in __getattr__
AttributeError: 'NoneType' object has no attribute 'write'

```
VSコードでは問題なく動くので「何もしてないのに壊れた！」という気持ち。

## 原因
[このページ](https://stackoverflow.com/questions/75354151/chromedriver-manager-download-doesnt-work-after-exe-conversion-via-pyinstaller)によると、ChromeDriverManager().install()を呼び出した際にコンソール上にプログレスバーが表示されるらしい。
しかしexe化する際に--noconsoleオプションを指定しているためコンソールが画面上に表示されず、「プログレスバー出力する場所がありませんよー」的な状況らしい。

## 解決方法
プログレスバーを出力する場所を適当に指定すればokなのでソースを以下の通り修正する
```error_rep.py
from webdriver_manager.chrome import ChromeDriverManager

if __name__ == '__main__':
    # オプション設定
    options = webdriver.ChromeOptions()
    options.add_argument('--headless')
    options.add_argument('--disable-gpu')
    options.add_argument('--disable-extensions')
    options.add_argument('--proxy-server="direct://"')
    options.add_argument('--proxy-bypass-list=*')

    # 追加
    buffer = io.StringIO()
    sys.stdout = buffer
    sys.stderr = buffer

    new_driver = ChromeDriverManager().install()
    service = Service(executable_path=new_driver)
    return webdriver.Chrome(service=service, options=options)

```
再度pyinstallerでexe化したら行けた！
C/C++に関する自分向けメモ


## コンパイルエラー
コメントの末尾に『能』があるとバグるよ～ ; ;
```
WGPUBindGroupLayoutEntry bindingLayout{};
bindingLayout.binding = 0; // バインドインデックス
bindingLayout.visibility = WGPUShaderStage_Vertex | WGPUShaderStage_Fragment; // 読み取り可能
bindingLayout.buffer.type = WGPUBufferBindingType_Uniform; 
bindingLayout.buffer.minBindingSize = m_UniformCount * sizeof(float);
```
https://masa-cbl.hatenadiary.jp/entry/20160111/1452438687
https://qiita.com/takey/items/ca49c8048992e8f6c674
【Docker】コンテナという概念とそのメリットの基本理解

## アジェンダ
* Dockerとはどんなものなのか基礎理解を深める
* Dockerのメリットは何なのか、どう活きるのか考えてみる
## Dockerとは
### ざっくり理解
アプリケーションの実行に必要な様々な環境を仮想上で構築し、その仮想環境の中でアプリケーションを実行できる技術です。そして、その仮想環境はイメージ化といって、他ユーザーへ共有できるので、同一の仮想環境を簡単に他ユーザーが構築させることができます。

また、この構築されることをコンテナ化といい、Linuxのコンテナ技術に由来しています。

:::note
**コンテナ技術とは**
アプリケーションの実行に必要なライブラリやツールなどをまとめて分離させる事で、一つのLinux OS環境下で複数のアプリケーションを実行する環境を構築できるLinuxの機能。

例えば、PHPの実行環境と、Rubyの実行環境はそれぞれに異なるので、コンテナ技術を使わずに対応しようとすると、ライブラリ間の競合や共有が原因で、各アプリケーションが正しく動作しない恐れが生じる。

コンテナ技術を用いると、それぞれが独立した実行環境のため、そういった恐れがなく、各アプリケーションの動作に影響しない。
::: 

Dockerを用いることで、WindowsやmacOSといった異なるOS間でも、同じ実行環境を構築できます。単純なLinuxのコンテナ技術は、当然Linux上でしか動作しませんし、単体のマシンでしか操作できません。

また、公式サイトにある膨大な数のDockerイメージによって、構築したい実行環境も整備しやすく、実際の操作自体もGUIやDockerコマンドといった専用のコマンドもあるので、操作しやすいこともメリットです。独自のイメージを生成する事で、各要件にあった実行環境もオリジナルで構築できることもポイントです。

https://hub.docker.com/


なにより、利用するユーザー全員が共通言語を用いて作業できることは大きい利点かなと理解しています。
### 具体的には
例えば、PHPとRubyを実行させたいとします。

単純に一つのマシンで実行させるとしたら、PHPとRubyで、それぞれにライブラリやツールをインストールする必要がありますね。

しかし、PHPとRuby間でこれらの環境が干渉する恐れがあります。同じライブラリの一部分を共有している可能性もあります。PHPをバージョンアップさせたりする場合に、Rubyにも用いている環境も更新されたとしたら、その環境を用いているRubyは正しく動作しなくなるかもしれません。

上記のように、各プログラムやシステムの共有部分が競合したり干渉すると、正しくプログラムを実行できなくなるかもしれないのです。

:::note
集合住宅の各居室をプログラムと仮定すると、各居室の前にある廊下や階段などの共用部分は、各プログラムを実行する（各居室に入る）際に必要なライブラリやツールとなります。

この共用部分が、とある居室の住人Aによって勝手に荷物置き場（しかも通れない）にされると、別の居室の住人は居室に入居するのに弊害が起こります。

これを戸建てが各プログラムと仮定すると、各戸建て前にあるアプローチは戸建てに入るために必要なライブラリやツールです。

各アプローチはその戸建て専用のものですので、荷物をどれだけ置いたとしても隣の戸建てに影響することはありません。
:::

それならば、今まで集合住宅で入居していたPHPとRubyの実行環境を分離させようということです。

PHPとRubyを各コンテナに切り分けることで、それぞれを戸建てにすれば、環境が互いに干渉せず、スムーズな実行環境を構築できるようになります。

また、これは一つのマシン内での話で終わらないのがDockerの技術です。冒頭に記載したように、構築したPHPとRubyの環境を、他のユーザーのマシンでも実行できるように共有することができます。

同じDockerイメージを共有しそれぞれがDockerコンテナを再現及び構築すると、複数のマシン間で同一の実行環境を揃えることができます。
### 実務的には
実務ではエンジニア1人が単独で開発を行うことはほぼないでしょう。複数のエンジニアが、一つのWebサービスを開発するにあたり同一の環境を構築する必要があります。またエンジニアも、初期メンバー固定ではないかもしれません。途中で離脱したり、新たなメンバーがジョインすることも頻繁にあるでしょう。

Dockerの技術を用いれば、メンバーの入れ替えがあっても、簡単に開発環境を構築することができます。環境構築に時間を大きく割くこと無く、すぐに開発作業に着手できます。

また、開発環境にとどまらず本番環境でもDocker技術の利点を活かすことができます。（※まだ、現時点では実際に実務で操作したことがないので、学習した知見になりますが）

ユーザーのマシン内で複数のプログラムを動作させるために、それぞれの実行環境を共存させると、ライブラリやツールの競合で、実行に弊害が生じる可能性を述べました。
これはサーバー上でも同じことが起こります。ですが、サーバー内で各コンテナを動作させ、実行環境を分離させることで、その影響をなくすことができます。

また、サーバーリソースの効率化という点でもDockerのコンテナ技術はメリットとなります。各プログラム毎にサーバーを運用すると、当然運用した台数だけコストがかかりますが、一つのサーバー内で複数コンテナを実行し、プログラムを動作させることで、それだけでサーバーのコスト削減になります。

Dockerって便利なツールですね。
## おわりに
開発環境構築という観点でしか実務では対応したことがないので、本番環境で得られるメリットを享受したことがありません。今後はそこにもリアルで触れていきたいです。

また、Docker一強であった仮想コンテナ技術ですが、AWSより【Finch】というサービスが公開されているようで、そちらも気になります。

https://aws.amazon.com/jp/blogs/news/introducing-finch-an-open-source-client-for-container-development/

今回は以上です。
お時間頂きありがとうございました。