OmniAICreator/Qiita-1.07M huggingface dataset:
モルフォロジー演算(Morphological Transformations)を用いた垂直線検出

ただの備忘録


主要処理はclass内に記述
入力はコマンド上に　ファイル名,使用画像の順で入力
当たり前だが別ディレクトリにいると動かない
コマンドプロンプトに文字化けがでたら大体いる場所が違うので確認すること。

``` Python
import cv2
import sys
import numpy as np
import matplotlib.pyplot as plt
```
**変換前元画像**
![moto.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321297/08ee151d-476f-2dc0-4811-4366a63d8110.png)


### 一度の膨張+収縮でノイズを消す
``` Python
def cleanIsolatedPoints(img,kernel):
    img = 255-img #色反転
    erosion = cv2.erode(img,kernel,iterations = 1)
    delation = cv2.dilate(img,kernel,iterations = 1)
    img = 255-img
    print(img.shape)
    plt.imshow(img,cmap="gray")
    plt.show()
```
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321297/ad9bb4c3-7473-d006-dbc9-03a786254d98.png)


### 輪郭抽出
``` Python
def findLinesCanny(gray_image):
    gray_image = 255 - gray_image
    t_lower = 110 
    t_upper = 150

    edge = cv2.Canny(gray_image,t_lower,t_upper)
    plt.imshow(edge, cmap="gray"))
    plt.show()
```
参考：[Carry関数の解説(英語)](Carry関数の解説(英語)https://www.geeksforgeeks.org/python-opencv-canny-function/)
Lower,Upperを変えるとしきい値が変わる

※dilateとerodeの差を出すことでも似たようなことができる
　行っている計算が同じかは不明、要確認
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321297/d92deb57-fa12-1991-f690-a49cf74d0f65.png)



文字の縁取りが出来ている。
### 問題の垂直線抽出部分
```Python
def detectVerticalLines(gray):
    vertical = np.copy(gray)

    vertical = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, 75, -3)
    rows = vertical.shape[1]
    #数字を大きくすると分割が細かくなる　とりあえずここからいじる
    vertical_size = rows // 50
    #ここの第2引数を(vertical_size, 1)にすると水平線検出になる
    verticalStructure = cv2.getStructuringElement(cv2.MORPH_RECT, (1,vertical_size))
    vertical = cv2.erode(vertical, verticalStructure)
    vertical = cv2.dilate(vertical, verticalStructure)
    # return resulting image
    plt.imshow(vertical , cmap="gray")
    plt.show()
```
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321297/ae98fc4f-2beb-cf8d-2393-4c0b1b0f5a9d.png)


cv2.adaptiveThreshold関数の引数は以下の通り
参考：[Opencvの関数説明サイト](https://docs.opencv.org/3.4/d7/d1b/group__imgproc__misc.html#ga72b913f352e4a1b1b397736707afcde3)

| 引数 | 内容|
|:-:|:-:|
|   1| 画像  |
|   2| 閾値を超えたときに出力する値  |
|   3|  計算方法の指定  |
|   4| Threshold Typeの指定  |
|   5| 平均値を出すための計算領域のサイズ  |
|   6|  平均値から引く定数　しきい値の微調整に使用 |

***T(x,y)* = (第5引数で指定した領域内の平均値)－(第6引数)**
がしきい値となり、その値を超えると第2引数の値に変換するようになっている。
そのため、第5引数を大きくすると、より大雑把な区分けになる。

:::note warn
第5引数には奇数のみ指定可能
第6引数は小数も可能(double)
:::

各引数について
**第3引数**：第5引数で指定した領域内の平均をとるか、ガウス分布によって重み付けを行うかの指定ができる。
        ガウス分布を使う場合は、cv2.ADAPTIVE_THRESH_GAUSSIAN_C
        とすればOK。平均でうまくいかないときに試す。

**第4引数**：二値への変換

**THRESH_BINARY**
```math
dst(x,y) = \begin{cases}
    Maxvalue(第2引数) &  　　　IF(src(x,y)>T(x,y)) \\
    0 & 　　　それ以外
  \end{cases}
```
もしその位置の値(色)が、しきい値よりも大きければ第2引数で指定した色(今回は白)に、そうでなければ黒にする。
THRESH_BINARY_INVはこの場合分けが逆になるだけなので省略。
cv2.THRESH_BINARYかcv2.THRESH_BINARY_INVの二択。OTSUなどは指定できない。


コードは[GitHub](https://github.com/kurage-pchan/opencv/commit/a1a1c7570bc403b0c88c4c474f81aef2345d572e)にあります。
【Flutter】アプリストアの言語がENのままになってしまう場合の対処法【AppStore】


# アプリストアの言語がENのままになってしまう


![スクリーンショット 2023-06-19 10.57.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653721/310816df-117b-95ec-fcdf-6b25e30c16a5.png)

ストアの設定画面ではデフォルト言語を日本語設定していたつもりでしたが、なぜか言語の部分が英語（「EN」）となってしまっています。これが原因でアプリストアの検索順位に影響が出てしまう可能性もあるので改善したいところ。

ゴールは、英語（「EN」）ではなく日本語（「JA」）となることです。

![スクリーンショット 2023-06-19 11.00.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653721/75de1b51-74e0-0580-e4b2-3ebf2cf2d5ce.png)

ということで今回は私が調べたなかで、最も簡単な対処法をご紹介します。

対応自体はシンプルなのですが、アプリアップデートしないと改善できたかの確認が出来ないのがめんどくさかったです。わざわざ審査にださなければならないし、マイナーチェンジのアップデートを重ねるとユーザーに不要なアプデを強いてしまうことになってしまいます。。


##### ちょっとだけ宣伝

https://lit.link/taminaryousuke

## 手順
### 1. XcodeでiOS用のプロジェクトを開く
Xcodeでプロジェクトを開き、PROJECT > Runner > Info > LocalizationsにJapaneseを追加します。

![スクリーンショット 2023-06-20 19.11.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653721/067fd8ba-b82d-490a-b8dd-15d43d81db9e.png)

### 2. Japaneseをデフォルト設定する
先ほど追加したJapaneseを選択し、SetDefaultボタンを押下します。
これでDefaultの部分にチェクマークがついたら、たったのこれだけで対応完了です。

このままストアへリリースし、審査に通れば無事問題が解消されていることを確認できると思います。


## まとめ
開発したアプリの一覧はこちらから！

https://lit.link/taminaryousuke

今回作ったアプリ

https://apps.apple.com/jp/app/%E6%89%8B%E6%9B%B8%E3%81%8D%E3%83%81%E3%83%A3%E3%83%83%E3%83%88-%E3%83%94%E3%82%AF%E3%83%88%E3%83%BC%E3%82%AF-%E6%83%B3%E3%81%84%E3%82%92%E5%B1%8A%E3%81%91%E3%82%8B-%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8B%E3%82%A2%E3%83%97%E3%83%AA/id6449237575

https://play.google.com/store/apps/details?id=com.tamina.hand_writing_chat

一番バズったアプリは「ガチャメーカー」です！

https://apps.apple.com/jp/app/%E3%82%AC%E3%83%81%E3%83%A3%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC-%E3%81%82%E3%81%AA%E3%81%9F%E3%81%A0%E3%81%91%E3%81%AE%E3%82%AA%E3%83%AA%E3%82%B8%E3%83%8A%E3%83%AB%E3%82%AC%E3%83%81%E3%83%A3%E3%82%92%E4%BD%9C%E3%82%8B%E3%82%A2%E3%83%97%E3%83%AA/id1617490189

Twitterもやってます。
https://twitter.com/minnasinario


### 参考URL

https://impreatesoft.jp/program/app-store-english/

https://zenn.dev/moimoi_prog/articles/b3491746e67ef2

https://starhoshi.hatenablog.com/entry/2023/01/16/115721
【AWS MGN】テストインスタンスの"インスタンスの接続性チェックに失敗しました"の解決策

案件で得た小ネタです。どなたかの役に立てば幸いです。
※カットオーバーインスタンス→テストインスタンスの間違いでした。失礼しました。
# 発生した事象
移行元のサーバ(RHEL7.3)からAWSに最初のデータレプリケーションが完了し、テストインスタンスを起動後にインスタンスのステータスチェックに失敗。下記画像のように赤字で`インスタンスの接続性チェックに失敗しました`と表示されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986198/abd32d53-e103-2c9f-c4b2-a6409410c23f.png)
インスタンスのログを確認するも、所々`failed`なっているが根本原因を特定できなかった。また、構築したインスタンスにssh接続を試みるも接続はできない状態だった。

# 原因
今回移行元のOSはRHEL7.3を使用していたが、Nitro System上に構築されたインスタンス(今回はm5.xlarge)を使うにはRHEL7.4以降でなければ対応していなかったため、ステータスチェックで失敗していた。
以下、AWS公式ページからの引用。

:::note
* Nitro System 上に構築されたインスタンスには、次の要件があります。
    * NVMe ドライバーがインストールされている必要があります。
    * Elastic Network Adapter (ENA) ドライバーがインストールされている必要があります。
    以下の Linux AMI はこれらの要件を満たしています。
    * Amazon Linux 2
    * Amazon Linux AMI 2018.03
    * linux-aws カーネルを搭載した Ubuntu 14.04 以降
    * **Red Hat Enterprise Linux 7.4 以降**
    * SUSE Linux Enterprise Server 12 SP2 以降
    * CentOS 7.4.1708 以降
    * FreeBSD 11.1 以降
    * Debian GNU/Linux 9 以降
:::

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/general-purpose-instances.html#general-purpose-instances-release-notes

ちなみに、Nitro System上に構築されるインスタンスかどうかは、以下のURLから確認可能。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-types.html#ec2-nitro-instances

# 解決策
Nitro Systemを利用しないインスタンスタイプを起動インスタンスに指定し、リトライで解決。
具体的にはテストインスタンスのインスタンスタイプをm4.xlargeに変更することでインスタンスのステータスチェックに成功した。
pandasでTBL差分チェック関数を作成してみた


# データの作成

```python
df = pd.read_csv(file_name,encoding="utf-8")
df1 = df[0:11].copy()
df2 = df[0:11].copy()
​
# 違いを生む
df2.loc[10,"name"] ="John Deo"
```
​
df1
|id|name|class|mark|gender|
|---|---|---|---|---|
|0|1|John Deo	|Four|75|female|
|1|2|Max Ruin	|Three|85|male|
|2|3|Arnold	|Three|55|male|
|3|4|Krish Star	|Four|60|female|
|4|5|John Mike	|Four|60|female|
|5|6|Alex John	|Four|55|male|
|6|7|My John Rob	|Fifth|78|male
|8|9|Tes Qry	|Six|78|male|
|9|10|Big John	|Four|55|female|
|10|11|Ronald	|Six|89|female|



df2
|id|name|class|mark|gender|
|---|---|---|---|---|
|0|1|John Deo	|Four|75|female|
|1|2|Max Ruin	|Three|85|male|
|2|3|Arnold	|Three|55|male|
|3|4|Krish Star	|Four|60|female|
|4|5|John Mike	|Four|60|female|
|5|6|Alex John	|Four|55|male|
|6|7|My John Rob	|Fifth|78|male
|8|9|Tes Qry	|Six|78|male|
|9|10|Big John	|Four|55|female|
|10|11|John Deo	|Six|89|female|​

df2のnameをJhon Deoにして、差分を生む
​
この2つのTBLを比較し、差分チェックを行う
​
​
# データの差分チェック関数
​
```python
​
from typing import Union
​
# python 3.10 added
def diff_check(df1:pd.DataFrame,df2:pd.DataFrame)-> bool | pd.DataFrame:
​
# python 3.9
def diff_check(df1:pd.DataFrame,df2:pd.DataFrame)-> Union[bool, pd.DataFrame]:
  df_diff = df1[df1["id"].isin(df2["id"])]
  if df_diff.equals(df2) is True:
    return True
  else:
    df_dup = df1.compare(df2)
    return df_dup
​
    
diff_check(df1,df2)
```
​
一致すれば、Trueが返り
不一致なら不一致のdataframeが返ってくる
​
python3.10以上ならtype hintに上のやり方を試してみてはどうでしょうか
​
​
# 差分結果
​
|   |name|   |
|---|---|---|
|   |self|other|
|10|Ronald|John Deo|​


これを見ると、nameカラムでRonaldとJhon Deoがindex番号10で重複していることがわかる
​
​
#### ちなみに
​
```python
#nameで重複しているものを取得できたり
df_diff = df1[df1["id"].isin(df2["id"])]
```
​
​
参考：
​
https://stackoverflow.com/questions/33945261/how-to-specify-multiple-return-types-using-type-hints
​
https://motamemo.com/python/pandas-tips/pandas-dataframe-change-value/
ローカルリポジトリの作成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/a5182c91-d06a-f4fe-566e-21c4490a65ff.png)
１：ローカルリポジトリを作成する。
①TOP画面の左下にある「Add Existing Repository...」をクリック
②追加したいディレクトリを選択する。例：「first_app」ディレクトリを選択し、追加
※もしも Add repository をクリックできない場合は、表示されている注意書きの add an exception for this directory をクリックすると下記のように画面が表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/c5b8d845-76c0-df5c-83b6-2b22908c58a4.png)
これで、ローカルリポジトリが作成できました。
Kusto の render timechart でデータが無い期間のグラフをきれいにする

# TL;DR

`make-series` を使う

https://learn.microsoft.com/ja-JP/azure/data-explorer/kusto/query/make-seriesoperator

## お題

以下のような日付毎の集計結果をいい感じにグラフ表示させたい。

```kql
let ST = datetime(2007-11-01);
let ET = datetime(2007-12-01);
StormEvents 
| where StartTime between (ST .. ET)
| where State == "HAWAII"
| summarize count() by bin(StartTime, 1d)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/b2d66f9a-52dc-cf60-a537-a8d7c8f4ec9a.png)



## ありがちな書き方

そのまま `render timechart`

```kql
let ST = datetime(2007-11-01);
let ET = datetime(2007-12-01);
StormEvents 
| where StartTime between (ST .. ET)
| summarize count() by bin(StartTime, 1d), State
| render timechart 
```

### 結果
11/3や11/6、11/8~11/18 などレコードがない期間のポイントが無いグラフが描画される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/21d94ba1-3585-39a4-8d12-6d04c24ecba2.png)

## make-series をつかう書き方

```kql
let ST = datetime(2007-11-01);
let ET = datetime(2007-12-01);
StormEvents 
| where StartTime between (ST .. ET)
| where State == "HAWAII"
| make-series count() on StartTime from ST to ET step 1d
| render timechart 
```

### 結果

データがない日は0になってますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4914/56e77f1b-5206-60ac-3a47-707d08218ccd.png)
Laravelのroute/api.phpでauth web認証でAPIが叩けなくて困った（401）

# Laravelのroute/api.phpでauth web 認証を入れたら使えなくて困った

### 前提：auth:web 認証を適当に実装

```routes/api.php
Route::middleware(['auth:web', 'verified'])->group(function () {
    Route::prefix('test')->name('test.')->group(function () {
        Route::get('testApi', [TestApiController::class, 'testApi'])->name('testApi');
    });
})
```
```config/auth.php
    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
    ],
```
### 結果：routes/web.phpではsessionで認証が保持されてアクセスできるのに、routes/api.phpでは使えなかった。
config/auth.phpは間違ってないし、apiにアクセス時のヘッダーにはsessionが保持されている。

どうやら、app/Http/Kernel.phpのauthが呼び出すapiのmiddlewareGroupsにsessionで認証管理するmiddlewareが足りないかららしい。

### 対処：下記の4つ追加すること（= auth:webとmiddlewareGroupsを同じにする）で動いた。

```app/Http/Kernel.php
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\HandleInertiaRequests::class,
            \Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
        ],

        'api' => [
            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];
```
　　　↓
```app/Http/Kernel.php
    protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
            \App\Http\Middleware\HandleInertiaRequests::class,
            \Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets::class,
        ],

        'api' => [
            //  session関連のmiddlewareを上のwebからまとめて追加
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,

            // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
            \Illuminate\Routing\Middleware\ThrottleRequests::class . ':api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],
    ];
```
VMware NSX 4.0 : NSX-T 3.x との管理UIの違いについて

<font color="red">**NSX-T 3.x → VMware NSX 4.x**</font>  へのアップグレードにおける、<font color="red">**管理UIにおける主な変更点**</font> に関して記載します。

具体的には、NSX 4.x 以降は、<font color="blue">**[システム]＞[ファブリック]**</font>における、<font color="blue">**ホスト及びEdgeトランスポートノードの設定**</font> に関するUIの設定メニューが変更となっている形です。


# NSX-T 3.x： [システム]＞[ファブリック]メニュー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251519/95c00db5-a005-6c5b-9f36-c489cb6135ed.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251519/71bc2c70-e476-42f1-5835-ada6b4cec6e8.png)

[システム]＞[ファブリック]＞
- **[ノード]**：　ホストトランスポートノード、Edgeトランスポートノード、Edgeクラスタ等を設定していた
- **[プロファイル]**：　アップリンクプロファイル、トランスポートノードプロファイル等を設定していた


#  NSX-T 4.x： [システム]＞[ファブリック]メニュー

<font color="red">**[システム] ＞[ファブリック]に、[ホスト]**</font>  のメニューが追加されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251519/2f0e2e16-380c-3497-1e2f-3506bb0dcc8a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251519/3c871b13-81b4-34f8-e703-e98684c4fd48.png)

[システム]＞[ファブリック]＞
- **[ホスト]**：　<font color="blue">**ホストトランスポートノード、トランスポートノードプロファイル**</font> 等を設定する
- **[ノード]**：　<font color="blue">**Edgeトランスポートノード、Edgeクラスタ**</font>等を設定する
- **[プロファイル]**：　アップリンクプロファイル等を設定する



# 結論
- <font color="blue">**NSX-T 3.xの [ノード]**</font>：　NSX 4.x以降は、[ホスト]と[ノード]メニューにて対応
- <font color="blue">**NSX-T 3.xの [プロファイル]**</font>：トランスポートノードプロファイルのみ、[ホスト]メニューにて対応、他のプロファイルに関しては、[プロファイル]メニュー対応となる
VS Code Server for WSL closed unexpectedlyの対処

## VS Code Server for WSL closed unexpectedlyの対処方法
- powershellを起動

- 以下のコマンドを入力
```
wsl --shutdown
```
１度WSLをシャットダウンする

- 以下のコマンド入力
```
code
```
以上で解決


## 事前に確認したこと
- powershellで以下のコマンドを打つ

```
wsl -l -v
```
デフォルトがUbuntuになっていることを確認


- デフォルトがUbuntu出なかった場合は以下のコマンドを実行
```
wsl -s Ubuntu-22.04 (←例：20.04など自分のものをいれる)
```
OCI IAM --「ユーザー機能の編集」を活用

本ブログは、[オラクル・クラウドの個人ブログ](https://qiita.com/letian/items/10152a4fec813c1b7d98)の1つです。

## 初めに
OCIの管理者が、通常なら数多くのエンドユーザーを管理しています。エンドユーザーが作成された直後、<strong>デフォルト</strong>は、そのユーザーが自ら<strong>APIキー、認証トークンなどの作成ができます</strong>。場合により、あるユーザーに対し、それらの機能を制御したいケースがあります。例えば、<strong>ユーザーAにAPIキーの作成権限を付与したくない</strong>というご要件があります。<strong>OCIのユーザー機能の編集</strong>を活用すれば、簡単に実現できますので、それを紹介したいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/148210f8-3c6d-4eb6-522d-3e2a51fcb554.png)

## ユーザー機能の編集
OCIの管理者ユーザーでログインして、エンドユーザーの詳細画面に、「<strong>ユーザー機能の編集</strong> (Edit user capabilities)」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/ea9cdcb4-a88f-c9c2-fd6e-c33b15348034.png)

デフォルトは、全ての認証関連の機能がチェックされています（利用可能）が、ご要望により、チェックを外し保存してください（この例は、APIキーの作成を無効にする）。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/5f7380a9-3b8e-3c77-023f-c95aa1fc926b.png", width="300">

エンドユーザーがOCIコンソールにログインしたら、APIキーの作成ができなくなりました。
OCIコンソールの右上の<strong>プロフィール・アイコン</strong> → 自分のプロフィール
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1121622/0bf9cead-58c6-b757-4bf9-7fd918ba6101.png", width="400">

<strong>IAMポリシー</strong>の追加作成は<strong>不要</strong>で、管理者よりOCIコンソールで簡単に編集できますので、必要な時この機能を活用していただけばと思います。

以上です。

----
__関連記事__
[オラクル・クラウドの個人ブログ一覧](https://qiita.com/liu-wei/items/10152a4fec813c1b7d98)

__オフィシャル・ドキュメント__
[ユーザー機能の編集](https://docs.oracle.com/ja-jp/iaas/Content/Identity/userfed/edit-user-capabilities.htm)
Shifter CLI の使い方

こちらのページを参考にしました。
 [Shifter CLI を詳しく見ていこう](https://ja.getshifter.io/exploring-the-shifter-cli/)
[@shifter/cli](https://www.npmjs.com/package/@shifter/cli)

## インストール

```bash
sudo npm install -g @shifter/cli
```

バージョンの確認

```text
$ shifter -v
@shifter/cli/0.4.0 linux-x64 node-v20.3.0
```

## 使用例

sites

```bash:go_sites_list.sh
ARGS="--username ekzemplaro --password ****"
#
shifter sites:list $ARGS
```

```bash:go_sites_describe.sh
ARGS="--username ekzemplaro --password ****"
#
shifter sites:describe $ARGS \
	--site-id "d003fd5f-45c7-45bf-868b-192072d81453"
```

artifacts


```bash:go_artifact_list.sh
ARGS="--username ekzemplaro --password ****"
#
shifter artifacts:list $ARGS \
	 --site-id "d003fd5f-45c7-45bf-868b-192072d81453"
```

```bash:go_artifact_status.sh
ARGS="--username ekzemplaro --password ****"
#
shifter artifacts:status $ARGS \
	 --site-id "d003fd5f-45c7-45bf-868b-192072d81453"
```

## 確認したバージョン

```text
$ node --version
v20.3.0

$ npm --version
8.19.2
```
ブラウザで XPATH 式を確認するためのTIPS


# 目的

Seleniumなどで使えるXPATH式を作成したい

# 方法

F12 (開発者ツール) のJavascript Consoleにて以下の関数を流し込みます。
```
function printXpathAll(xpath) {
    var xpath_result = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null); 
    var next = xpath_result.iterateNext(); 
    while (next) {
        console.log(next);
        next = xpath_result.iterateNext();
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63179/e00700a3-d511-0a6a-ab7e-4350aaae90d5.png)

# 使用例

"//a" だと、候補が多数表示されます：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63179/890e72b1-0ca0-7449-59eb-4782b8a8d04e.png)

"//a[text() = '開発者']" にて候補を絞り込めました：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63179/93036be1-deff-6590-b2f9-e9f98b4aad04.png)
Ansibleのsystemdモジュールを使ってサービスを操作してみた

検証環境
---
コントロールノード・・・RHバージョン8.6にインストールしたansible 2.9.25を使っています
ターゲットノード　・・・RHバージョン8.6

検証内容
---
複数のサービスに対して起動/停止、及び、自動起動設定のON/OFF行う
基本的にサーバー構築時は役割に応じて必要なサービスを起動したり、リソース節約の観点から不要なサービスを停止する必要があるため、サービス開始・停止の処理をそれぞれ準備しました


変数
---
複数のサービスを処理できるように、リストとして定義しました
```
---
# vars file for os_base
enable_services:
  - crond.service
  - kdump.service
  - chronyd.service

disable_services:
  - iptables.service
  - postfix.service
```

playbook
---
|オプション|説明|
|---|---|
|name|操作するサービス名|
|state|started・・・サービス起動<br>stopped・・・サービス停止|
|enabled|OS起動時に自動起動するか|

```
---
- name: enable_services
  systemd:
    name: "{{ item }}"
    state: started
    enabled: yes
  loop: "{{ enable_services }}"

- name: disable_services
  systemd:
    name: "{{ item }}"
    state: stopped
    enabled: no
  loop: "{{ disable_services }}"
```

実行結果
---
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3482362/55976350-9d75-fc17-2c48-4d1380f76e8a.png)

参考サイト
---
https://docs.ansible.com/ansible/latest/collections/ansible/builtin/systemd_module.html

所感
---
今回は処理対象サーバーがRHEL7以上の為、systemdモジュールを使っていますが、RHEL7未満の場合はSysVinitなのでserviceモジュールを使う必要があるのでそこは注意が必要だと思いました
【Flet】アニメーション無しのページ遷移

::: note warn
2024/07/12 追記
いつの間にか公式で[PageTransitionsThemeクラス](https://flet.dev/docs/cookbook/theming/#pagetransitionstheme-class)が実装されていました。
こちらを使用することを推奨します。
:::

-----

Fletでページ遷移をするとき、公式リファレンスを参考にするとページが入れ替わるアニメーションが入ります。
そのアニメーションを再生させずにページを遷移する方法について書きます。
ただし、この記事で紹介する方法は邪道というか力技な感じになります。

動作イメージ↓
![Videotogif (3).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2960906/70595e1c-2d37-28cd-d7ae-c33483b1d91b.gif)

Fletのページ遷移の方法はこちらの記事がわかりやすいのでぜひ参考にしてください。

https://qiita.com/donraq/items/b0cc1ad273996477b25a


# 考え方
標準的なページ遷移では、複数の`view`と呼ばれる画面を作り その`view`を重ねて表示することで画面遷移をしています。（より具体的には上で紹介したリンク先の記事を読んでください。）

`view`を切り替えるときに遷移アニメーションが入るのですが、このアニメーションをカスタムする機能はないみたいです。（2023/06/20時点）→[公式リファレンス](https://flet.dev/docs/guides/python/navigation-and-routing "Navigation and routing|Flet")
なので、`view`の切り替えをせず、ページのコントロールを入れ替えることでページ遷移を再現します。


## 処理の流れ
1.ページaからページbに遷移する
2.ページaのコントロールをクリアする
3.ページbのコントロールをページに追加する

ページaのコントロールは削除されるので、表示内容を持ち越すことはできません。
例えば、
1.ページaでテキストボックスに入力
2.ページbに遷移
3.再度ページaに遷移
この時、ページaのテキストボックスは空になっています。

もし、ページを遷移しても表示内容を持ち越したい場合は`page.views.append`と`ft.AppBar`を使用してください。
`ft.AppBar`を持つページが`view`のリストに追加されたとき、自動的に`ft.AppBar`に`Back`ボタンが追加されます。この`Back`ボタンから戻った時のみ前のページが変更状態が保存された状態で表示されます。
`Back`ボタンで前のページに戻るには`page.on_views_pop`の設定が必要です。具体的なコードは冒頭に示した記事を読んでください。



## コード
<details><summary>アニメーション無しのページ遷移、ページの変更内容は保存されない</summary>

```py
import flet as ft

def main(page: ft.Page):
    def go_view1(e):
        page.go("/view1") #view1へ遷移
    
    def go_view2(e):
        page.go("/view2") #view2へ遷移
    
    def route_change(handler): #routeが変更されたときの処理群
        troute = ft.TemplateRoute(handler.route)
        page.controls.clear() #page内容をクリア
        if troute.match("/view1"): #routeが"/view1"の時の処理
            page.add(ft.Row(
                [ft.Text("view1"),ft.TextButton("go to view2", on_click=go_view2)]
            ))
        elif troute.match("/view2"): #routeが"/view1"の時の処理
            page.add(ft.Row(
                [ft.Text("view2"),ft.TextButton("go to view1", on_click=go_view1)]
            ))

    page.on_route_change = route_change #ページのrouteが変更されたときの処理を指定

    page.go("/view1") #最初に表示したい画面へ遷移

ft.app(target=main)
```
</details>

動作は記事の冒頭で示したgifのようになります。

`page.add(ft.Row([ft.Text("view1"),ft.TextButton("go to view2", on_click=go_view2)]))`の部分にいろんなコントロールを追加したりコンポーネントを指定することでいろんなページが作れます。

コンポーネントについてはこちらの記事がわかりやすいです。

https://qiita.com/donraq/items/043bde2e480d5359261b
Aerospike Go ClientでQueryがNode: Index not foundというエラーが出る

# はじめに

仕事で利用しているツールを回収する際に、Aerospikeからデータを取得するのに苦戦したのでまとめます

# 問題

```go
	stm := aerospike.NewStatement("test", "log", "user", "timestamp")
	stm.SetFilter(aerospike.NewRangeFilter("timestamp", from, to))
	recordset, err := client.Query(nil, stm)
	if err != nil {
		fmt.Println("Query error:", err)
	}
	defer recordset.Close()

	for res := range recordset.Results() {
		if res.Err != nil {
            // ここでエラーが発生する
			fmt.Println("Result error:", res.Err)
		} else {
			fmt.Println(res.Record.Bins)
		}
	}
```

上のコードを実行すると以下のエラーが出ます

```
Node BB9020011AC4202 127.0.0.1:3000: Index not found
```

おそらくAerospikeからデータがうまくとれていないからだとこの時点で予測しました

# 解決方法

インデックスが正しく作成されていないのが原因でした
Aerospikeのコンテナに入り、インデックスを作成するとうまく動きました

```
$ docker exec -it as-log sh
$ aql
$ SHOW INDEXES
$ CREATE INDEX idx_timestamp ON test.log (timestamp) NUMERIC
$ SHOW INDEXES

+--------+-------------+-----------+--------------+-------+-------------------+-------------+-----------+
| ns     | bin         | indextype | set          | state | indexname         | path        | type      |
+--------+-------------+-----------+--------------+-------+-------------------+-------------+-----------+
| "test" | "timestamp" | "NONE"    | "log" | "RW"  | "timestamp_index" | "timestamp" | "NUMERIC" |
+--------+-------------+-----------+--------------+-------+-------------------+-------------+-----------+
```

# おまけ

Queryのドキュメントを見ると以下の文章があります

>This method is only supported by Aerospike 3+ servers. If the policy is nil, the default relevant policy will be used.

これをみてaerospike-server 3系でないと動かない！？と勘違いしました
それ以上ならだいじょうぶです

# おわりに

色々デバックをしてここまで行き着くのが大変でした
Aerospikeのコンテナでもつまづいているので別記事で作りました

# 参考

https://pkg.go.dev/github.com/aerospike/aerospike-client-go
cloudformationを半分用いて、codecommit、codebuildを用いたfargateのCICDシステムの構築

# やること
タイトルの通り

# 対象者
codecommit、codebuild、cloudformationを実際にハンズオンで試したい人
作業中のエラーログとその解決策を知りたい人

# できるであろうもの
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206781/f3b5f377-640f-b49f-b45e-40993bcf4ef0.png)

# 構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206781/465e3d86-aa61-8ca2-9641-b461a4a457cc.png)



ALB経由でレスポンスを返却するfargateのターゲットグループ

# 注意
どっちかというと、この通り作業すればできるタイプの記事ではなく、
作業前に目を通しておけば、つまりが少なくなるタイプの記事

# 使用したリソース
(記事中のリソースの全てがこのrepository)
https://github.com/tamae1111/ecs-poc

# 作業の流れ

## 作業1
git直下のREADMEを読み、ディレクトリ構造をざっくり理解する
```
.
├── Dockerfile
├── README
├── README_other
│   ├── README_DEBUG_DOCKERFILE_TIPS.md
│   ├── README_ERROR_LOG.md
│   ├── README_FOR_Qiita.md
│   └── README_SETTING_NAMES.md
├── buildspec.yml 
├── cloudformation
│   ├── archived
│   │   ├── ecr01.yml
│   │   ├── ecs-fargate-01.yml
│   │   ├── except-ecs-01.yml
│   │   ├── resources-except-ecs-service01.yml
│   │   └── sample-ecs_resources_inference.yml
│   └── vpc-01.yml
└── scripts # 使用するのはsimple_serverは以下のみ
    ├── inference
    │   ├── inference.py
    │   └── requirements.txt
    ├── sample
    │   ├── requirements.txt
    │   └── sample.py
    └── simple_server
        ├── index.html
        ├── requirements.txt
        └── simple_server.py
```

## 作業2
README_otherディレクトリのドキュメントを読み、作業の勘所、詰まりそうなところをあらかじめつかむ

https://github.com/tamae1111/ecs-poc/tree/main/README_other



## 作業3
以下yamlでcloudformationのスタックを作成する

https://github.com/tamae1111/ecs-poc/blob/main/cloudformation/vpc-01.yml


## 作業4
https://github.com/tamae1111/ecs-poc/blob/main/README_other/README_FOR_Qiita.md

に従って作業する

以上
🐋Dockerとは・コマンドまとめ

***:cherries:学んだことを随時まとめてく:cherries:***
<font color="MistyRose">~間違っている点があれば是非教えてください~<font>


# イメージ
**（例：同時に複数のゲームができるすごいゲーム機本体:video_game:）**
アプリケーションやその動作に必要なファイル、設定などが含まれている
dockerコンテナの実行に必要なファイルシステムやソフトウェアのスナップショット

# コンテナ
**(例：ゲームカセット:minidisc:)**
イメージの実体化であり、アプリケーションが実際に動作する状態
イメージからコンテナをビルドする

# ボリューム
**（例：セーブデータ:notebook_with_decorative_cover:）**
 ボリュームはデータを格納、永続的な保存をするために使用される
MySQLみたいなポジション?
***

# コマンドまとめ
```docker:
#イメージのビルド
docker-compose build

#コンテナのビルドと起動
docker-compose up

#イメージとコンテナの起動
docker-compose up -d

#起動中のコンテナを確認
docker ps

#コンテナの停止
docker-compose stop

#既存のコンテナの起動
docker-compose start

#コンテナの終了
docker-compose down

#キャッシュを反映させたくない時
 #イメージのビルド
 docker-compose build --no-cache
 #コンテナの起動
 docker-compose up

#cssを保存するたび反映させる(npmのインストール必要)
docker exec -it コンテナID npm run watch
```
EC-CUBE4.1系→4.2系にプラグインを換装した

# 基本環境
EC-CUBE4.1.2-p2　→　4.2.0, 4.2.1, 4.2.2 へ換装
プラグイン種類：送料カスタムプラグイン

# プラグイン名の変更
<font color="blue">OriginalPlugin</font>　→ OriginalPlugin42

### サーバー書き換え

サーバーディレクトリ：
root/app/Plugin/<font color="blue">OriginalPlugin</font>　→ OriginalPlugin42

### composer.json書き換え

`:root/app/Plugin/OriginalPlugin42/conposer.json`
{
  <font color="blue">"name": "ec-cube/originalplugin",</font>　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　↓
  "name": "ec-cube/originalplugin42",

  "version": "1.0.0",

  <font color="blue">"description": "オリジナルプラグインforEC-CUBE4",</font>　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　↓
  "description": "オリジナルプラグインforEC-CUBE4.2",

  "type": "eccube-plugin",

  "require": {
    "ec-cube/plugin-installer": "~0.0.7 || ^2.0"
  },

  <font color="blue">"extra": {
    "code": "OriginalPlugin42"
  }</font>　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　↓
  "extra": {
    "code": "OriginalPlugin"
  }
```


### 各ファイルの書き換え

namespace：
namespace Plugin\OriginalPlugin　→ OriginalPlugin42\各ファイル

useパス：
use Plugin\OriginalPlugin　→ OriginalPlugin42\各ファイル

ファイル内パス：

```:root/app/Plugin/OriginalPlugin42/Entity/OriginalPlugin.php
@ORM\Entity(repositoryClass="Plugin\OriginalPlugin　→ OriginalPlugin42\Repository\OriginalPluginRepository")
```

```:root/app/Plugin/OriginalPlugin42/Form/Type/OriginalPluginType.php
'data_class' => 'Plugin\OriginalPlugin42\Entity\OriginalPlugin',
```

```:root/app/Plugin/OriginalPlugin42/Repository/OriginalPluginRepository.php
->from('Plugin\RegionalShippingFeePro\Entity\RegionalShippingFee', 's');
```

```:root/app/Plugin/OriginalPlugin42/Resouce/Admin/OriginalPlugin.twig
{% block stylesheet %}
    <link rel="stylesheet" href="{{ asset('RegionalShippingFeePro/assets/css/plugin.css', 'plugin') }}">
{% endblock %}
```

# RegistryInterface書き換え

```:root/app/Plugin/OriginalPlugin42/Repository/OriginalPluginRepository.php
use Symfony\Bridge\Doctrine\RegistryInterface;
    ↓書き換え
use Doctrine\Common\Persistence\ManagerRegistry;
```

```:root/app/Plugin/OriginalPlugin42/Repository/OriginalPluginRepository.php
class RegionalShippingFeeRepository extends AbstractRepository
{
    /**
     * RegionalShippingFeeRepository constructor.
     *
     * @param RegistryInterface $registry
     */
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, RegionalShippingFee::class);
    }


    ↓書き換え


class RegionalShippingFeeRepository extends AbstractRepository
{
    /**
     * RegionalShippingFeeRepository constructor.
     *
     * @param ManagerRegistry $registry
     */
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, RegionalShippingFee::class);
    }
```

`RegistryInterface`
    ↓書き換え
`ManagerRegistry`

# カートページ→レジページでエラー

```:root/src/Eccube/Entity/Order.php (line 123)
$roundingTypes[$rate]->getId()
```
の部分で、
Call to a member function getId() on null
と怒られた

### 対策

```:root/app/Plugin/OriginalPlugin42/Service/OriginalPluginPreprocessor.php
$TaxRule = $this->taxRuleRepository->getByRule();

->setTaxDisplayType($TaxInclude)
->setTaxType($Taxation)
```
以上を削除することでエラー解消
プラグインの内容によるでしょう

# 参考記事
https://note.com/kacchan570/n/n608ed77c8f18
タスク管理ツールの超便利でちょっとニッチな使い方を5つ紹介します

# はじめに

:writing_hand:[**この記事誰得？ 私しか得しないニッチな技術で記事投稿！**](https://qiita.com/official-events/5d4f04cf2ba0cdbc8821)の参加記事になります！

皆様はタスク管理ツールを利用していますでしょうか？
私は数年前からタスク管理にハマっていまして、バリバリ使っています！
使用しているのは[**Jooto**](https://www.jooto.com/)というツールで、過去に以下で紹介させて頂きました。

- [**~日々成長し続けるために~マジでやってよかった4つのプラクティス**](https://qiita.com/i-tanaka730/items/005fc27c0c44bfd7a0b0#1-%E3%82%84%E3%82%8A%E3%81%9F%E3%81%84%E3%81%93%E3%81%A8%E3%81%AF%E5%85%A8%E9%83%A8%E3%82%BF%E3%82%B9%E3%82%AF%E7%AE%A1%E7%90%86)

そんなタスク管理ツールですが、業務はもちろん、**プライベートにおいてもバリバリ使える**んです！
ちょっとニッチな使い方かもしれませんが、私のタスク管理ツール使用法についてご紹介させていただきます。
# タスク管理ツールの使い方

### 1. 業務の作業をタスクを管理

まあこれはよく使われているタスク管理方法ですね:eyes:
ステータス（ワークフロー）の分け方はプロジェクトによって様々かと思います:eyes:

![1x.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247638/137558fa-944d-1df9-1efc-4aa2a03c291d.png)


### 2. 勉強の作業をタスクを管理

1つ目と似ていますが、この方法はめちゃくちゃおススメします。
私は数年前までは勉強のモチベーションが全然上がらないタイプだったのですが、タスク管理することにより勉強量が**爆上がり**しました:muscle:
具体的には、自分に以下のような変化が出ました。

- 「やりたいこと」が「やらなくては / 早くやってしまいたい」という感情に変わった
- タスクを片付ける毎に充実感・成長を感じることができるようになった
- やりたいことがどんどん出てくるようになった。負のループならぬ、正のループ！

![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247638/58ecf2e3-83c6-4899-afb0-f3319eed5716.png)


### 3. ラーメン屋さんをタスク管理

「県内のラーメン屋さんをコンプリートしたい」と思ったことがある方は少なくないと思います。
別にラーメン屋さんでなくてもいいのですが、●●をコンプリートしたい！という方は多いですよね:eyes:
その目的を果たすのに、タスク管理ツールが打って付けです！
どうでもいいですが、ラーメンを食べているときが「進行中」のステータスにしています。

![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247638/547db99f-6ab9-4ea1-ac7d-5d5b2f44ca10.png)

### 4. 欲しいものをタスク管理

私は最近キャンプにハマっています！（まだ2回しか行ってませんが）
キャンプめちゃいいですよね！
家族、友達、BBQ、お酒、自然、星空が1度に味わえて、しかも帰らなくていい！最高！

キャンプにハマり始めると、欲しいアイテム（ギア）がたくさん出てきます:sweat_smile:
そんな欲しいものもタスク管理で解決です:v:
集めるのにお金は掛かってしまうんですけどね。。。あれも欲しいこれも欲しいと考えるのも楽しいんですよね！

![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247638/41435ad3-7df1-3420-ff74-90015b82207f.png)

### 5. 家族でタスク管理

:::note warn
これを実施するかどうかは検討中ですｗ
:::

「料理」「皿洗い」「洗濯」「買い物」「掃除」などなど、家族内でやらないといけないことは盛りだくさんです！
はい！これもタスク管理すればすっきりです:blush:
家族は助け合いが不可欠！

![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247638/a5fc11f3-da9f-baf2-9fd0-8ac006729e7a.png)

# おわりに
- タスク管理ツールは、少し工夫してもしなくてもめちゃくちゃ便利に使えるツールですね:innocent:
- タスク管理ツールをこんな風に便利に（or ニッチに）使ってるよ！という方がいましたらコメント等で教えて頂けると嬉しいです:innocent:
- [Jooto](https://www.jooto.com/)はとても使いやすいのでおススメです！ぜひ利用してみてください:innocent:
blackとisortがコンフリクトする問題

# 目次
[問題になった経緯](#問題になった経緯)
[原因](#原因)
[解決策](#解決策)
[こうやって修正したよ](#こうやって修正したよ)

# 問題になった経緯
GithubActionsでCIを実行したところblackがエラーになったので、コマンドでblackを実行してコミットした。
これで大丈夫！と思ったら次はisortのエラーになったので、コマンドでisortを実行してコミットした。
そしたらまたblackのエラーが！！
もう一度、コマンドでblackを実行してコミット。
そしたらまたisortのエラー。。

blackを実行すればisortのエラーになるし、isortを実行すればblackのエラーになるし。。
どうしたらいいの？🥺

# 原因
blackとisortではフォーマットのルールが異なるためコンフリクトしてしまう。

# 解決策
isortにはprofileというオプションがあり、black互換用のprofileも提供されているのでそれを利用する
https://pycqa.github.io/isort/docs/configuration/profiles.html
```
--profile black
```

# こうやって修正したよ
isortの処理を記述しているymlファイルにオプションを追記してあげるだけ。
### 修正前
```.yml
      #blackの設定
      - name: black
        run: |
          black {対象ファイル} --check
      #isortの設定
      - name: isort
        run: |
          isort $file --check-only
```

### 修正後
```.yml
      #blackの設定
      - name: black
        run: |
          black {対象ファイル} --check
      #isortの設定
      - name: isort
        run: |
          isort $file --check-only --profile black
```
C#でPDFを固定レイアウトのWord文書に変換する

PDFをWordに変換することは、ユーザーがPDF文書を編集、修正、再利用するための実用的な作業です。PDFは比較的安定した固定フォーマットであり、直接編集や修正が困難な一方、Word文書はより柔軟で編集や組版が可能です。PDFをWordに変換することで、文書のテキスト、画像、書式を簡単に変更、調整することができます。本チュートリアルでは、C#プログラムで**Free Spire.PDF for .NET** を使用して、PDFを固定レイアウトのWord文書に変換する方法を紹介します。

## プログラム環境
* [Free Spire.PDF for .NET](https://www.e-iceblue.com/Introduce/free-pdf-component.html#.ZH_ihWdByUk)
* Visual Studio 2022

## DLLファイルのインポート
* Visual Studioを開いて新しいプロジェクトを作成します。
* 「Solution Explorer」で「References」を右クリックします。
* 「NuGet Manage Packages」を選択します。
* Free Spire.PDF for .NETを検索してインストールします。

または、この[リンク](https://www.e-iceblue.com/Download/download-pdf-for-net-free.html)から直接ダウンロードすることもできます。
* Visual Studioを開いて新しいプロジェクトを作成します。
* 「Solution Explorer」で「References」を右クリックします。
* 「Add Reference」を選択します。
* 「Browse」をクリックします。
* DLLを検索してインストールしてプロジェクトにインポートします。

## コード
```c#
using Spire.Pdf;

namespace ConvertPdfToDoc
{
    class Program
    {
        static void Main(string[] args)
        {
            //PdfDocumentオブジェクトを作成する
            PdfDocument doc = new PdfDocument();

            //サンプルPDFファイルを読み込む
            doc.LoadFromFile(@"sample.pdf");

            //PDFをDocに変換して保存する
            doc.SaveToFile("ToDoc.doc", FileFormat.DOC);

            // PDFをDocxに変換して保存する
            //doc.SaveToFile("ToDocx.docx", FileFormat.DOCX);
        }
    }
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2811193/70d7ca01-9705-e6fa-2fd8-9d5fa5174a69.png)
このコードは、PDFファイルをDOCおよびDOCXファイルに変換することができます。最初に、PdfDocumentオブジェクトを作成し、LoadFromFileメソッドを使用してPDFファイルを読み込みます。次に、SaveToFileメソッドを使用して、PdfDocumentオブジェクトをDOC形式のWord文書に変換し、「ToDoc.doc」という名前のファイルに保存するか、またはPdfDocumentをDOCX形式のWord文書に変換し、「ToDocx.docx」という名前のファイルに保存します。最後に、プログラムは終了します。
上記の方法を参考にして、[PDFをExcelに変換](https://www.e-iceblue.com/Tutorials/Spire.PDF/Program-Guide/Conversion/Convert-PDF-to-Excel-in-C-VB.NET.html)したり、[PDFを画像に変換](https://www.e-iceblue.com/Tutorials/Spire.PDF/Spire.PDF-Program-Guide/Convert-PDF-Page-to-Image-with-C-code.html)したりすることもできます。
【React】Chakra-UIのGridで要素の位置を揃える

# はじめに
ヘッダーに配置した文字列と、コンテンツに配置した要素の位置を揃えたいです。

これを

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/66ca7070-64fd-b7e7-ced9-6b861dc2acde.png)

こうしたい

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/cce258b6-d3e6-d64e-ccac-ccb74e703ad8.png)

# flexではなくgridを使う

## 修正前のコード

```tsx
  return (
    <Box bg="#95BFEA" height="50px" display="flex" alignItems="center">
        <Flex align="center" justify="space-between" width="100%" marginX="auto">
        <Text textAlign="center" flex="1">{title}</Text>
        {showSettingIcon && <Icon mr="4px" as={SettingsIcon} boxSize={6} />}
        </Flex>
    </Box>
  )
```

文字列とアイコンをflexで横並びにしているだけです。
この状態で文字列を中央寄せにしても、
画面の横幅からアイコンを除いたスペースに対して中央寄せになるので、コンテンツの文字列やアイコンと位置がずれてしまいます。

そのため、flexではなくgridを用いて文字列やアイコンの配置を細かく決めてあげます。

https://chakra-ui.com/docs/components/grid

- Gridタグで全体のサイズを指定
- gridに割り当てる要素はGridItemタグで囲み、割り当てる縦横のスペースをrowSpan/colSpanで指定

今回は全体のサイズを12にし、
左配置用のアイコン：文字列：右配置用のアイコンを4:4:4で割り当てます。

## 修正後のコード
(戻るアイコンやメールアイコンなども追加していますが、気にしないでください)

```tsx
  return (
    <Box bg="#95BFEA" height="50px" display="flex" alignItems="center">
      <Grid
        w='100%'
        templateColumns='repeat(12, 1fr)'
        gap={4}
      >
        <GridItem rowSpan={1} colSpan={4} >
          {showBackIcon && <Icon as={ArrowBackIcon} boxSize={6} onClick={handleBackIconClick} />}
        </GridItem>
        <GridItem colSpan={4} >
          <Text textAlign="center" >{title}</Text>
        </GridItem>
        <GridItem colSpan={4} >
        <Box w="100%" display="flex" justifyContent="end">
          {showSettingIcon && <Icon mr="4px" as={SettingsIcon} boxSize={6} />}
          {showEmailIcon && <Icon mr="4px" as={EmailIcon} boxSize={6} onClick={handleEmailIconClick}/>}
          </Box>
        </GridItem>
      </Grid>
    </Box>
  )

```

よしなにできました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/cce258b6-d3e6-d64e-ccac-ccb74e703ad8.png)


# おわりに
かゆいところに手が届くと気持ちがいいです。
EC2 Instance Connect Endpoint ( EICE )を使ってローカルからインスタンスにアクセス

## 背景

RDSでAuroraDBを作ったが、そのDB操作をローカルから実行したい。でもDBは基本的にプライベートサブネットにあるからローカルと接続するにはそれ用の踏み台サーバー作らなきゃいけないか…
と、思っていたらつい最近EC2 Instance Connect Endpointっていうサービスが出たらしい。

:::note warn
現在EICEは22番ポートと3389ポートのみでしか利用できなくなりました。
AWSが想定した動作ではなかったようです。
:::

## EC2 Instance Connect Endpoint（EICE）とは

公式ではこう説明されている。
「EC2 Instance Connect Endpointを使用すると、インスタンスにパブリック IPv4 アドレスを持たせることなくインスタンスに接続できます。TCP をサポートする任意のインスタンスに接続できます。」
つまりEC2上のインスタンスへのアクセス用エンドポイントを簡単に設置できるようになった。
例えばプライベートなRDSをローカルから操作することもできる。しかも無料らしい。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/connect-using-eice.html

## やること

既存のRDS（Aurora）にEICEを設置してローカルからMySQL接続する。

## EICE作成

### セキュリティグループの設定

1. EICEのセキュリティグループを作成
    - __RDS（接続したいインスタンス）があるVPCと同じVPCを選ぶ__
    - インバウンドルール
        - タイプ：「すべてのトラフィック」
        - 自分のPCからのみアクセスできるようにソースを「マイIP」に設定    
        ![スクリーンショット 2023-06-20 15.23.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2388259/2e088ee6-06ba-5b34-565e-f4898765abca.png)

    - アウトバウンド
        - タイプ：「すべてのトラフィック」
        - ソース：RDS（接続したいインスタンス）のセキュリティグループ
            - 虫眼鏡押したら選べる

2. RDSのセキュリティグループを編集
    - インバウンドルール
        - タイプ：「すべてのトラフィック」
        - ソース：上記で作成したEICEのセキュリティグループ

### マネコン（VPC > エンドポイント）からエンドポイントを作成。

- 以下の部分でEC2 Instance Connect Endpointを選択
![スクリーンショット 2023-06-20 15.16.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2388259/776d88b2-fda2-aecc-9fd6-84ce863ac8d0.png)

- また、__VPCはRDSなどの接続したいインスタンスがあるVPCと同じものにする。__
- Subnetはどれでもいい（プライベートでも大丈夫）

「作成」を押す

## RDSに接続してMySQLに入る

以下のシェルスクリプトを作成

~~~bash:connect-db
#!/bin/bash

##-----------------
## 接続情報
##-----------------
TARGET_EICE_ID="eice-xxxxxxxx" # EICEのID
AURORA_ENDPOINT="xxxx.cluster-xxxx.ap-northeast-1.rds.amazonaws.com" # RDSのエンドポイント
LOCAL_PORT="15432" # テキトーなローカルのポート
TARGET_PORT="3306" # RDSのポート
PROFILE="default" # プロファイル（特に変更がなければdefault）

##-----------------
## RDS接続
##-----------------
AURORA_IP=$(dig $AURORA_ENDPOINT +short | grep '^[0-9]' | head -n 1)

echo "RDSに接続します。"
str1="EICE ID : "
echo $str1$TARGET_EICE_ID
str2="AuroraDB endpoint : "
echo $str2$AURORA_IP
str3="Local port : "
echo $str3$LOCAL_PORT
str4="AuroraDB port : "
echo $str4$TARGET_PORT
str5="Profile : "
echo $str5$PROFILE
aws ec2-instance-connect open-tunnel \
    --instance-connect-endpoint-id $TARGET_EICE_ID \
    --private-ip-address $AURORA_IP \
    --local-port  $LOCAL_PORT \
    --remote-port $TARGET_PORT \
    --profile $PROFILE

~~~

~~~
./connect-db
~~~
を実行して
~~~
RDSに接続します。
EICE ID : eice-xxxxxxxx
AuroraDB endpoint : xx.x.xxx.xxx
Local port : 15432
AuroraDB port : 3306
Profile : default
Listening for connections on port 15432.

~~~
となれば接続成功。

あとは別ターミナルで
~~~
mysql -h 127.0.0.1 -P 15432 -u RDSユーザー名 -p
~~~
を実行してパスワードを入力したらMySQLに入れる。

## まとめ

EC2 Instance Connect Endpoint ( EICE )を使えばローカルからインスタンスに接続できた。
踏み台サーバーやVPNのようなものを設置しなくてもいいのでかなり楽。
しかも無料。

## 参考資料

https://qiita.com/hedgehog051/items/47c879a013888decb48d
パスワードを登録するときに必要なこと

## DBに入力された生のままのパスワードを保存しない
 - DBのデータが何らかの方法で盗またり、流出してしまうことがある。
     - 標的型攻撃
     - 内部犯
 - 他のサービスでも同じパスワードを使用していた場合に流用できてしまう。

## パスワードを保存する際は暗号化、またはハッシュ化する
 ### 暗号化
 - 暗号化した内容をもとに戻すことができる(複合できる)
 - 複合化の方法が漏れてしまった場合に内容がわかってしまう

 ### ハッシュ化
 - 一度ハッシュ化したものはもとに戻すことができない(不可逆)
 - 同じ方法でハッシュ化した場合に同じ値になるため、それでパスワードがあっているか確認する。
 - 同じハッシュ関数から辞書を作られていた場合、パスワードがバレてしまうこともある

## 現在はハッシュ化+別の方法の組み合わせでセキュリティを高めるのが主流
 ### ソルト
 - パスワードをハッシュ化する前に、ランダムな文字列を付与する(20桁程度の長さ)
 - 固定値ではなく、ユーザーごとに異なる値を付与するのが望ましいとされる

 ### ペッパー
 - パスワードをハッシュ化する前に、ランダムではない文字列を付与する
 - ペッパーの値はDB以外に保存する
 
 ### ストレッチング
 - 何度もハッシュ化する(数千から数万回)
 - 解読に多くの時間がかかる
DateTimeフィールドの計算


+ [問合せから初回対応のリードタイムを出したい](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V000074pHZuSAM)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3cdbd664-9b1c-831c-a708-04c5eb4b7186.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/d15b77c3-4759-769f-0c71-a89138c255a0.png)

```
IF(OR(isblank(formulacheck__c.Start_DateTime__c),isblank(formulacheck__c.End_dateTime__c)),NULL,

TEXT(FLOOR( formulacheck__c.End_dateTime__c-formulacheck__c.Start_DateTime__c)) + "日" +

TEXT ( FLOOR( (formulacheck__c.End_dateTime__c-formulacheck__c.Start_DateTime__c  - FLOOR( formulacheck__c.End_dateTime__c-formulacheck__c.Start_DateTime__c))*24)  ) + "時間" +

TEXT(  FLOOR(  (  (formulacheck__c.End_dateTime__c-formulacheck__c.Start_DateTime__c  - FLOOR( formulacheck__c.End_dateTime__c-formulacheck__c.Start_DateTime__c))*24 - FLOOR( (formulacheck__c.End_dateTime__c-formulacheck__c.Start_DateTime__c  - FLOOR( formulacheck__c.End_dateTime__c-formulacheck__c.Start_DateTime__c))*24) )*60 )  ) + "分"

)
```


+ [Error element Schedule_Cadence_Restart_Time (FlowActionCall). Specify a resume time value at least 1 hour in the future in the ISO 8601 format [2021-06-25T05:38:15.521917Z]. ](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007bLRofSAG
)
AWS Cloud Practionerへの道 まとめページ＆感想

AWS Cloud Practionerに合格しました。受験に向けてAWS Skill Builderを中心に勉強をしたのでその時のメモを残しておきます。全９セクションに分けています。どこかに偏りがあったという印象はなく、まんべんなくAWSの各サービスやコストについての問題が出題されていました。

### リンクまとめ

https://qiita.com/TakahiRoyte/items/1999ec2247787d4b3f1a

https://qiita.com/TakahiRoyte/items/54559ae828a094cfc18d

https://qiita.com/TakahiRoyte/items/1adf955355b875ab9685

https://qiita.com/TakahiRoyte/items/ff5293449e9508da0d36

https://qiita.com/TakahiRoyte/items/248516e0dce195983740

https://qiita.com/TakahiRoyte/items/8251351a0ce341b56e6f

https://qiita.com/TakahiRoyte/items/757702aacb038c361e4b

https://qiita.com/TakahiRoyte/items/db24c891d073c2596458

https://qiita.com/TakahiRoyte/items/41d9c14515dab07cab6a

### 感想

今日無事合格できました。スコアはまだ届いていないので、気づいた＆気が向いたらアップデートしておきます（最下部に追記しました！）。私がした勉強法としては、上記まとめリンクまとめたのとAWS Summitの参加、AWSome Day Online Conferenceの視聴＆ノートの作成ぐらいです。

自分は過去にAWSのEC2を少し触ったことがあるのと、AWS Amplifyを使ってWebサービスを組んだことがあるぐらいで、AWSについては正直大した知識やスキルはない状態でした。今回の受験がはじめて体系だった学習の機会となったので、とても良かったです。

一部、AWS Skill Builderでは「一切触れとらんかったでしょ！」みたいなサービスが出てきたりもしました。たまたま知っていたのでなんとかなったみたいなところもあります。ただ、そういった問題も例外で65問出題された中でよくいわれる70%を超えれば合格（大体46問正解が合格ライン）なので、捨て問題としておいてもいいかもいしれません。

私はテストセンターで受験しましたが、自信のない問題を見直しフラグつけて、それが18問ぐらいでした。1周目が35分ぐらい、見直しに10分程度で、予定されている100分はかなり余ると思います。

AWSのサービスの概要を理解するには良い資格だと思いますが、これを持っているからソリューションのアーキテクチャを考えられるかと言うと別問題ですね。そういったスキルを身につけるにはソリューションアーキテクトアソシエイトなどを取る必要があるのだと思っているので、次はそれの取得を検討したいと思います。あとは、コースの中で紹介されていたようにAWSは無料枠があるので、その中で実際に自分でサービスを組んでみるのも面白そうです。

### スコア

![Screenshot 2023-10-12 at 10.32.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89911/d57fc8a5-7791-3a3b-08d9-71b8fda762bc.png)

満点1000の合格ラインは700だったので、上位資格はもう少し気合い入れて勉強しないと難しそうです……！
Aurora のスナップショット（デフォルトKMSキーで暗号化されてる）を別アカウントに共有する 1

弊社では会社全体で１つのアカウントを共有していましたが「管理が面倒！どの部署がどれを使っているのかさっぱり分からん！」という苦情が増えてきたため、部署ごとにアカウントを分ける事になり Aurora 移行の作業を振られたため手順をまとめました。

<br>

# AWS マニュアルを確認

https://repost.aws/ja/knowledge-center/rds-snapshots-share-account

マニュアル見てると手動スナップショットを共有するだけっぽいので簡単だな！と思っていましたが当然そんなに上手く行かず…デフォルトKMSキーで暗号化されていたため、別アカウントへの共有が不可になっていました。あと KMS キーも別途発行して別アカウントに共有しておく必要があるっぽい。

> デフォルトの Amazon RDS 暗号化キーを使用しない、暗号化された手動スナップショットは共有できます。ただし、まず AWS Key Management Service (AWS KMS) キーを、スナップショットを共有するアカウントと共有する必要があります。

<br><br>

**デフォルトKMSキーで暗号化されているため、スナップショットのアクセス許可設定を保存できない**
現在サポートされていない、という文言から将来はサポートしてくれるんでしょうか

![snapshot-share.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/052b17e7-42e9-ac4f-d631-a54153123967.png)



<br><br>

# 移行元アカウントでの作業

ここから作業手順

## KMS キーの作成と共有

デフォルトでない KMS キーが必要なので作成していく

![kms.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/fdca76b4-3539-81de-eabd-835679e428f8.png)




### キーを設定

#### キーのタイプ

対象

#### キーの使用

暗号化及び復号化

#### 詳細オプション

- キーマテリアルエンジン : KMS 推奨
- リージョンごと : 単一リージョンキー

次へ

### ラベルを追加

#### エイリアス

わかりやすい名前を追加（aurora-snapshot-share-key、みたいな）

#### 説明

必要であれば追加

#### タグ

必要であれば追加

次へ

### キーの管理アクセス許可を定義

#### キー管理者

必要であれば追加

#### キーの削除

「キーの管理者がこのキーを削除できるようにします。」にチェック

次へ

### キーの使用アクセス許可を定義

#### キーユーザー

必要であれば追加

#### 別の AWS アカウント

arn:aws:iam::【移行先のAWSアカウント番号】:root

次へ

## 確認

問題なければ「完了」



## Aurora スナップショットを取得

- RDSメニューから、移行元のDBクラスターを選択
- 「アクション」の「スナップショットの取得」

現行だとデフォルトKMSキーで暗号化されているため共有できない。
そのため、先程作成したKMSキーを使って暗号化されたスナップショットをコピーする

## スナップショットをコピー

- スナップショットメニューから、取得したスナップショットを選択し「アクション」の「スナップショットのコピー」を選択

### スナップショットをコピー

#### 送信先リージョン

必要であれば変更

#### 新しいスナップショットID

コピー元スナップショットIDを適当にちょっと変える

#### タグをコピー

「タグをコピー」にチェック

### 暗号化

#### AWS KMS キー

デフォルト KMS キーではなく、先程新しく作成した KMS キーを選択する


**※コピーめっちゃ時間掛かるので適当に時間潰す。29GiB で3時間かかりました。**


## スナップショットのアクセス許可

- スナップショットメニューから、コピーしたスナップショットを選択し「アクション」の「スナップショットの共有」を選択

### 設定

#### AWS アカウントID

移行先の AWS アカウント ID を入力

次へ



# 移行先アカウントでの作業

スナップショットメニューから、「自分と共有」タブをクリックし、共有したスナップショットが表示されていればOK

![snapshot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76272/a93c7777-8fd1-6cf3-5428-6ed0d2c6c492.png)

この共有スナップショットから、新しい DB クラスターを作成するなりなんなりして完了。






## 参考サイト

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_ShareSnapshot.html
【Volta】VPN接続したままVoltaはエラーになる？

node.js, npm, yarn 等の JavaScript のツールマネージャーの一つに`Volta`というものがあります。
詳細は以下
[公式](https://volta.sh/)

### 起きたこと
※投稿時点でのエラーになります。
先日以下のようにVoltaを用いて、yarnをインストールしようとするとエラーが起きました。
```bash:
volta install yarn
```
としたところ
```bash:エラー
error: Could not download yarn@1.22.19
from https://registry.npmjs.org/yarn/-/yarn-1.22.19.tgz

Please verify your internet connection and ensure the correct version is specified.
Error details written to C:\Users〜**********
```

なぜ。。。？

以下も試した

```bash:
volta setup
```
でもだめ。。。

なぜ。。。？

## 解決方法

調べていたら`Isuues`に以下の記載が
[Volta error: Could not download node@XX.YY.Z #1506](https://github.com/volta-cli/volta/issues/1506#issuecomment-1537477222)

どうやらVPN接続時にはVoltaが全く動作しない人がいるみたい

試しにVPNを切ったら、正常にインストールできました。