OmniAICreator/Qiita-1.07M huggingface dataset:
YellowfinからAWSセッションマネージャーでEC2の踏み台サーバを経由してRDSのデータソースに接続する

オンプレ環境にあるYellowfinから、AWSセッションマネージャーによる接続のみが許可されたAWS環境にあるRDSへ接続したい場合があるというお話をお聞きしたので、簡単に検証してみました。

![image-ssm.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/3655ea65-e0ee-1d3f-5cef-7bbf4b48bf22.png)

### SSM用ロールの作成

踏み台サーバに割り当てるためのIAMロールを作成します。

エンティティタイプは**AWSのサービス**、ユースケースは**EC2**を選択します。
![ssm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/cdaa77ec-b7dd-5b6f-3cca-972a2031c567.png)

ポリシーから**AmazonEC2RoleforSSM**を選択します。
![ssm2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/70ad3dcf-76b8-f5a4-e140-0cde6ab929f7.png)

ロール名やタグをつけてロールを作成します。
![ssm3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/83f04e9a-9106-a82d-86dc-a070c1f4266f.png)

### アクセスキーの作成

セッションマネージャーを使用するユーザー用のアクセスキーを作成します。
![ssm4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/761ea217-8ec1-5956-4404-a350e99d16c4.png)

作成されたアクセスキーとシークレットアクセスキーをメモっておきます。
![ssm5-mos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/efea7baf-2f67-9c24-2d8f-41f5385460df.png)

### AWS CLIとSession Managerプラグインのインストール

以下を参考にして、それぞれインストールします。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html
https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html

### AWS CLIの初期設定

ターミナルで`aws configure`を実行し、先ほどメモしたアクセスキーなどを設定します。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-quickstart.html

### RDSの準備

今回は既存のRDS（PostgreSQL）を使用しました。
本記事中でエンドポイントは**xxx.ap-northeast-1.rds.amazonaws.com**、ポートは**5432**として記述します。

### 踏み台サーバの準備

踏み台サーバがすでに存在する場合は不要ですが、今回は新たに踏み台サーバ用のEC2インスタンスを起動しました。

上記で作成したIAMロールを指定します。
![ssm6-mos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/c7464467-27f3-70f5-12a0-677d075a6885.png)

本記事中ではインスタンスID：**i-999**として記述します。

### セッションマネージャーの接続

ターミナルで以下を実行してセッションマネージャーに接続します。

```sh
aws ssm start-session \
    --target i-９９９（踏み台サーバのインスタンスID） \
    --document-name AWS-StartPortForwardingSessionToRemoteHost \
    --parameters '{"host":["xxx.ap-northeast-1.rds.amazonaws.com（RDSのエンドポイント）"],"portNumber":["5432（RDSのポート）"], "localPortNumber":["15432（ローカル側のポート）"]}'
```

### Yellowfinのデータソース設定

ローカルのYellowfinを起動し、データソースの設定を行います。
![ssm8-mos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/ecba2a9d-4ee9-683c-ed80-9976e14b7bcf.png)

データベースホストは**localhost**、データベースポートは**SSM接続で設定したローカル側のポート**（上記の例では15432）を設定します。

SSM接続している状態で「テスト接続」をクリックすると、以下のようにローカルのYellowfinからRDSへ接続することができます。
![ssm9-mos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/9e39ed38-8662-d66c-2b6f-0e4ac213342a.png)

### 参考にした情報

以下の記事を参考にさせていただきました。
https://qiita.com/comefigo/items/b705325d082018ab2348
https://dev.classmethod.jp/articles/aws-ssm-support-remote-host-port-forward/
input の使い方

pythonの基本入力の方法

・一行の文字の入力方法
s =  input()
#sはstr型となる

・一行の数字の入力方法
n = int(input())
#nはint型となる


split()やmap()を利用することで複数の文字や数字を受け取ることができる
・一行で複数の文字の入力方法
入力例：aaa bbb ccc
s1,s2,s3 = input().split()
入力された文字をリストに直接入れたいとき
s_list = list(input().split())

・一行で複数の数字の入力方法
入力例：111 222 333
n1,n2,n3 = map( int, input().split())
入力された数字をリストに直接入れたいとき
n_list = list( map( int, input().split() ) )


複数行の文字の入力方法
（最初に入力回数を与えられてから入力がある場合）
入力例：
3
abc
de
fgh

n = int(input())
s_list = [input() for _ in range(n)]
print(s_list)

出力
['abc', 'de', 'fgh']
【Laravel】サービスコンテナが何者かを簡単にしらべてみました。

# はじめに
現在インターン先でLaravelを使った開発を1年ほどしています。Laravelの核と言われているサービスコンテナを理解するために調ことをメモとして残しておきたいと思います。

# サービスコンテナとは
サービスコンテナとは、クラスのインスタンス化を管理してくれる仕組みのことです。

例）Exampleクラスのインスタンスを生成
```php:Example.php
$example = app()->make(Example::class);
```

また、上記コードと以下の結果は同じです。
```php:Example.php
$example = new Example();
```

これだけだと、サービスコンテナを使う必要ないのでは？と思います。
しかしサービスコンテンナには、依存関係を自動解決をしてくれる働きを持っています。

# 依存関係の自動解決とは？
以下のように、ExampleクラスがMailクラスに依存しているとします。
```php:Example.php
class Example
{
    public $mail;

    public function __construct(Mail $mail)
    {
        $this->mail = $mail;
    }

    public function run()
    {
        $this->mail->send();
    }
}
```

```php:Mail.php
class Mail
{
    public function send()
    {
        \Log::info('sendメソッド実行');
    }
}
```

通常であれば、以下のようにExampleクラスをインスタンス化する前に、Exampleクラスの依存先であるMailクラスのインスタンス化を実行する必要があります。

```php
$mail = new Mail();
$example = new Exmaple($mail);
```

これをサービスコンテナを使った書き方で書くと以下のようになります。

①bindメソッドでサービスコンテナへ登録
```php
$example = app()->bind('example', Example::class);
```
②makeメソッドを使ってExampleクラスのインスタンス化
```php
$myClass = app()->make('example');
```

サービスコンテナが自動的に依存関係を解決するため、上記は正常に実行されます。

# まとめ
サービスコンテナの役割について簡単にまとめてみました。
サービスコンテナを使うことで依存関係を自動解決してクラスをインスタンス化してくれることがわかりました。

# 参考
https://reffect.co.jp/laravel/laravel-service-container-understand
YellowfinからSSHポートフォワーディングでEC2の踏み台サーバを経由してRDSのデータソースに接続する

オンプレ環境にあるYellowfinから、SSH接続のみが許可されたAWS環境にあるRDSへ接続したい場合があるというお話をお聞きしたので、簡単に検証してみました。

![image-ssh.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/9b779b1c-b8d3-409e-f927-7e00bc934db4.png)

### RDSの準備

今回は既存のRDS（PostgreSQL）を使用しました。
本記事中でエンドポイントは**xxx.ap-northeast-1.rds.amazonaws.com**、ポートは**5432**として記述します。

### 踏み台サーバの準備

踏み台サーバがすでに存在する場合は不要ですが、今回は新たに踏み台サーバ用のEC2インスタンスを起動しました。
![ssm7-mos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/953403b6-e804-1868-7541-3b682e32930b.png)
セキュリティグループは既存のものを使用して、インバウンド接続はsshのみを許可しました。

### SSHポートフォワーディングの接続

ターミナルで以下のsshコマンドを実行して接続します。

```
$ ssh -L 15432（ローカル側のポート）:xxx.ap-northeast-1.rds.amazonaws.com（RDSのエンドポイント）:5432（RDSのポート） ec2-user@xxx.xxx.xxx.xxx（踏み台サーバのグローバルIPアドレス） -i xxxxxx.pem（EC2のキーペア）
```

なお、Windowsの場合はTera TermなどのSSHポートフォワーディングが可能なクライアントを使用してください。

### Yellowfinのデータソース設定

ローカルのYellowfinを起動し、データソースの設定を行います。
![ssm8-mos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/1153bbb6-20f4-d313-ae90-825c61968448.png)
データベースホストは**localhost**、データベースポートは**SSHポートフォワーディングで設定したローカル側のポート**（上記の例では15432）を設定します。

SSH接続している状態で「テスト接続」をクリックすると、以下のようにローカルのYellowfinからRDSへ接続することができます。
![ssm9-mos.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116818/e153741c-b903-1e3d-4c8a-f248103f324c.png)

### 参考にした情報

以下の記事を参考にさせていただきました。
https://dev.classmethod.jp/articles/rds-portforward/
AWSアカウントの解約でやることメモ

::: note warn
本記事は、AWSのドキュメント（[AWSアカウントを解約する](https://aws.amazon.com/jp/premiumsupport/knowledge-center/close-aws-account/)）を読んで、**個人的に大事だと感じた点**をピックアップしている。
プロジェクトによっては、内容が網羅できていない可能性があるので注意！
:::

# やること
* 保持したいリソース・データをバックアップ
* リソースの削除
* アカウント解約

ひとつずつ確認していく

## 1. バックアップ
S3やDB等のデータやリソースをバックアップしておく

## 2. リソース削除

aws-nukeを使うと一括でリソース削除できる

https://qiita.com/rapirapi/items/664b61958aabef51df17

## 3. アカウント解約

マイアカウントページで一番下までスクロールして、アカウントの解約を行う

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1719666/e87bd3be-f2a8-7721-396f-74b03a2f1b6c.png)

# 参考

https://aws.amazon.com/jp/premiumsupport/knowledge-center/close-aws-account/

https://aws.amazon.com/jp/premiumsupport/knowledge-center/check-for-active-resources/


https://dev.classmethod.jp/articles/aws_nuke_intro/
【React/TypeScript】useState()で入力項目を管理する。

## はじめに
昨今、react-hook-formなど入力値を取得〜バリデーションまでしてくれるライブラリが充実していますが、今回、useState()で入力フォームのStateを管理する方法を書きたいと思います。(自分へのメモも兼ねて)
また、この記事は、useState()の知識があることを前提に記事が書かれています。
useStateに関する詳細は、[公式](https://ja.reactjs.org/docs/hooks-state.html)を一読ください。
## サンプルコード
以下のようなログインフォームがあるとします。
uiはMaterialUIを使用しています。(*公式ドキュメントは[こちら](https://mui.com/))
```Typescript
type Props = {
    name: string;
    password: string;
};

const nullLoginParam: Props = {
  name: '',
  password: '',
};

const Login = () => {
  const [params, setParams] = useState<Props>(nullLoginParam);
  const onClickLogin = () => { 
    // ログイン処理
  }
  return(
    <Box>
        <TextField
          id="name"
          label="ユーザー名"
          name="name"
        />
        <TextField
          id="password"
          label="パスワード"
          name="password"
        />
        <LoadingButton onClick={onClickLogin}>
          ログイン
        </LoadingButton>
    </Box>
  );
};
```
## 実装
それでは、TextFieldの`onChange`イベントハンドラに`onChangeState()`関数を指定して、管理していきます。
```diff_Typescript
/* 省略 */

const Login = () => {
  const [params, setParams] = useState<Props>(nullLoginParam);
+ const onChangeState = (
+   e: React.ChangeEvent<HTMLTextAreaElement | HTMLInputElement>
+ ) => {
+   const { value, name: key } = e.target;
+   setParams({ ...params, [key]: value });
+ } 
  const onClickLogin = () => {
    // ログイン処理
  }
  return(
    <Box>
        <TextField
          id="name"
          label="ユーザー名"
          name="name"
+         onChange={onChangeState}
        />
        <TextField
          id="password"
          label="パスワード"
          name="password"
+         onChange={onChangeState}
        />
        <LoadingButton onClick={onClickLogin}>
          ログイン
        </LoadingButton>
    </Box>
  );
};
```
`onChangeState`は、`onChange`イベントハンドラからのイベント(e)を受け取ります。
この`e`の中にある`target`には、入力フォームに入力された値(value)や`<TextField>`の`name=`の値が入っているので、
```diff_typescript
+ const { value, name: key } = e.target;
```
と、分割代入で取り出します。(`name: key`は、keyという変数にnameを代入しています。)
<br/>
次に、`setParams`の中に`params`をスプレット構文で展開し、値を入れていきます。
```diff_typescript
+   setParams({ ...params, [key]: value }); // ...params, password: '1234' のように値がセットされます。
```
以上が、useStateで入力フォームのStateを管理する方法でした。
## 参考にした記事
https://www.wakuwakubank.com/posts/461-javascript-destructuring-assignment/

https://zenn.dev/axpensive/articles/6f35d3da03044f
AccessのVBAで数字を3桁コンマ区切りでフォーマット

# やり方

```vb:
Format(数字, "#,##0")
```

## イミディエイトウィンドウにコピペして動作確認する用

### 数値

```vb:結果は『123』
?Format(123, "#,##0")
```

```vb:結果は『1,234』
?Format(1234, "#,##0")
```

```vb:結果は『1,234,567,890』
?Format(1234567890, "#,##0")
```

```vb:結果は『0』
?Format(0, "#,##0")
```

```vb:結果は『-1,000』
?Format(-1000, "#,##0")
```

### 文字列

```vb:結果は『123』
?Format("123", "#,##0")
```

```vb:結果は『1,234』
?Format("1234", "#,##0")
```

```vb:結果は『1,234,567,890』
?Format("1234567890", "#,##0")
```

```vb:結果は『0』
?Format("0", "#,##0")
```

```vb:結果は『-1,000』
?Format("-1000", "#,##0")
```

### NULL

```vb:結果は『』（例外にならない）
?Format(NULL, "#,##0")
```

### 空文字

```vb:結果は『』（例外にならない）
?Format("", "#,##0")
```

# 『#,###』でフォーマットすると…

下記の結果は『』。

```vb
Format(0, "#,###")
```

0の場合は『#,###』か『#,##0』で挙動が変わる。

**0の時は空文字にしたい** のか **あえて0を表示させたい** のか で使い分け。


# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2546
Microsoft Access for Microsoft 365 MSO (バージョン 2212 ビルド 16.0.16026.20002) 32 ビット
Sassを基本からまとめてみた【便利な使い方】

公式サイト：[Sass](https://sass-lang.com/)

## Sassを利用するメリット
1. ネスト（入れ子構造）で記述できる
2. &(アンパサンド)の使い方
3. 変数が利用できる
4. .scssファイルを分割管理できる
5. コードを複数箇所で使用できる
6. メディアクエリ(ミックスイン（@mixin))機能が利用できる
7. カラーコードを便利に管理できる

## 1. ネスト（入れ子構造）で記述できる
sassでは、親の中括弧の中に下層のスタイルを書く事ができる
```sample.sass
.area_article {
//セレクタ
 
padding: 30px;
//プロパティ　値

//ここに下層のスタイル
.text {
   margin: 20px 0 0;  
   .date{
     font-size: 12px;
     color: #999;          
    }
  }
}
```

## 2. &(アンパサンド)の使い方

親のセレクタを参照する事ができる書き方

```sample.sass
.btn {
  color: #fff;
  background: #000;
  padding: 10px;
  &:hover {
//アンパサンド

color: red;
  }
}
```





## 参考サイト
[SASSの超便利な使い方【HTML/CSSコーディング】](https://www.youtube.com/watch?v=Dxpl3IKLWaQ&t=186s)
open ai で テキスト追記、編集、画像を別バージョンに

# はじめに
https://qiita.com/ma7ma7pipipi/items/c08bf5adbec86fc2c761

を読んでね

# テキストを追記

```
$prompt = "私はあなたのことがずっと好きでした。私をお嫁さんにして下さい";
$apiUrl = 'https://api.openai.com/v1/completions';

// APIに送信するパラメーター
$apiParams = [
    'model' => 'text-davinci-003',
    'prompt' => $prompt,
    'temperature' => 0,//デフォルト1 0.9にするとリスクオン 0 にするとリスクなし
    'max_tokens' => 256,
];

// Guzzleを使ってAPIにリクエストを送信する
$client = new Client();
$response = $client->post($apiUrl, [
    'headers' => [
        'Content-Type' => 'application/json',
        'Authorization' => 'Bearer ' . config('app.open_ai_secret'),
    ],
    'json' => $apiParams,
]);

// APIからのレスポンスを取得する
$result = json_decode($response->getBody()->getContents(), true);
```

#結果

```

//temperature 0.9
私はとても幸せですが、なかなか決断を下せない状況となってしまいました。私たちの双方にとって最良の結果を出すために、しっかりと考えて決断を下したいと思っています。

//temperture 0
ごめんなさい、私はすでに結婚しています。

```

# テキストを編集

```
$prompt = "私はあなたのことがずっと好きでした。私をお嫁さんにして下さい";

$apiUrl = 'https://api.openai.com/v1/edits';

// APIに送信するパラメーター
$apiParams = [
    'model' => 'text-davinci-edit-001',
    'input' => $prompt,
    'temperature' => 0.9//デフォルト1 0.9にするとリスクオン 0 にするとリスクなし,
    "instruction" => "30歳男性が言う言葉に絵文字も利用して書き換えて下さい",
];

// Guzzleを使ってAPIにリクエストを送信する
$client = new Client();
$response = $client->post($apiUrl, [
    'headers' => [
        'Content-Type' => 'application/json',
        'Authorization' => 'Bearer ' . config('app.open_ai_secret'),
    ],
    'json' => $apiParams,
]);

// APIからのレスポンスを取得する
$result = json_decode($response->getBody()->getContents(), true);
```


結果
```
//temperature 0.9
私はあなたのことがずぅ～～～っと好き(❤︎)でした。私をお嫁さん🤵にして下さい

//temperature を 設定しないと
私はあなたのことがずっと好きでした。私をお嫁さんにして下さい:heart:
```


# 画像を別バージョンに

laravelにて。
guzzleを使ってアップロードするの面倒だったので、Httpで書き直した。
画像をアップロードする方法がわからずめちゃくちゃ苦労した。

```
$headers = [
    'Authorization' => 'Bearer ' . config('app.open_ai_secret'),
];


$photo = fopen(public_path("img/test.png"),"r");

$response = Http::withHeaders($headers)
    ->attach('image', $photo, 'test.png')
    ->post('https://api.openai.com/v1/images/variations', [
        'size' => '256x256'
    ]);

$json_result = json_decode($response->getBody(), true);
```


# すげーオリジナルイラストになっちゃうね

before
![test.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/c6babd5a-4ff0-4d04-64ad-b37d2c5a200c.png)

after
![img-AgAU0vO2Sw8VS9fdhLtlvWJz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31338/385836cb-6dea-2d2f-626f-9dc2a3dcbe2e.png)

実物の写真だと、顔がボケてしまう。
イラスト感が出るので使い物にならない。
【SwiftUI】複数行のLinkを左寄せにしたい

# はじめに
先日SwiftUIの[Link](https://developer.apple.com/documentation/swiftui/link)を使用した際に、複数行の要素を**左寄せ**(=alignmentをleft)にしたかったのですが、少し実装に苦戦したので備忘録です。

以下のキャプチャの、1枚目の状態から2枚目の状態にする為の実装方法について書きます。URLが左寄せになっています。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793562/f3193c03-58c1-e772-aae5-f5129d731248.png"> <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1793562/74bf5641-2825-3400-9ac0-898c10ca34d1.png">

# 上手くいかなかった方法
まず思い浮かぶのは下記の様に`HStack`を使う方法ですが、こちらでは上手く動作しません。
```
HStack {
   Link(url.absoluteString, destination: url)
   Spacer()
}
```

こちらも似た方法ですが上手くいきません。
```
Link(destination: url, label: {
    HStack {
        Text(url.absoluteString)
        Spacer()
    }
})
```
`VStack`に`alignment`として`.leading`を指定する方法も思いつきましたが、こちらも上手くいきません。
単純な`Text`ならこれでも上手く動作しますが、`Link`は上手く動作しませんでした。SwiftUIは難しい...。
```
VStack(alignment: .leading) {
    Link(url.absoluteString, destination: url)
}
```


# 上手くいった方法
`multilineTextAlignment`を使うと上手く期待通りの表示になりました！！！
iOS13から使えるのもうれしいポイントです。

```
Link(destination: url, label: {
    Text(url.absoluteString)
        .multilineTextAlignment(.leading)
})
```

# さいごに
私はSwiftUIを勉強し始めたばかりなので、より良い書き方があればお気軽にコメントで教えてください。
さいごに、私がリリースしたSwiftUIのアプリの宣伝をさせてください。

https://apps.apple.com/jp/app/astrum/id6444909778

# 参考
- [https://developer.apple.com/documentation/swiftui/link](https://developer.apple.com/documentation/swiftui/link)
- [https://developer.apple.com/documentation/swiftui/text/multilinetextalignment(_:)](https://developer.apple.com/documentation/swiftui/text/multilinetextalignment(_:))
GitLabのCIからDockerInDocker経由でTestcontainersを使う

## この記事の目的
業務でGitLabのCI/CDを使うケースが多いので、JUnitテストでDatabaseを使うユースケースを試してみました。

## 技術スタック
- GitLab
- GitLabRunner(Docker Executor)
- SpringBoot(あまりSpringは関係ない)
- MySQL
- Testcontainers for Java

Testcontainers for Javaは、JUnitからDockerでDatabaseを建てられるので、便利です。
GitLabのCIとの統合については、以下のページを参考にしました。
https://www.testcontainers.org/supported_docker_environment/continuous_integration/gitlab_ci/

## コード全体
今回のコード全体は以下の場所においてあります。
https://github.com/akiraabe/my-first-gitlab/tree/testcontainers

- Testcontainersとは関係ない話しですが、ローカル環境での、アプリケーション起動の際には、事前に（手動で）docker composeでMySQLを立ち上げます。
- JUnit実行時には、特にDockerを意識する必要はなく、Testcontainersが自動的にMySQLを立ち上げてくれます
使い方は、[README.md](https://github.com/akiraabe/my-first-gitlab/blob/main/README.md)を参照ください。

## 要所の説明
全体を説明すると長くなるので要点だけ説明を加えておきます。
まずは、gitlabのCIの定義です。
ここは、Testcontainersのドキュメントに従い、servicesとvariablesを定義しています。

```yaml:gitlab-ci.yml
# DinD service is required for Testcontainers
services:
  - name: docker:dind
    # explicitly disable tls to avoid docker startup interruption
    command: ["--tls=false"]

variables:
  # Instruct Testcontainers to use the daemon of DinD, use port 2735 for non-tls connections.
  DOCKER_HOST: "tcp://docker:2375"
  # Instruct Docker not to start over TLS.
  DOCKER_TLS_CERTDIR: ""
  # Improve performance with overlayfs.
  DOCKER_DRIVER: overlay2

image: amazoncorretto:11

stages:
  - test

unit-test:
  stage: test
  tags: [docker]
  script:
    # Maven Wrapper を使用する 
    - ./mvnw clean test
  artifacts:
    reports:
      junit:
        - target/surefire-reports/TEST-*.xml
        - target/failsafe-reports/TEST-*.xml

job-checkstyle:
  stage: test
  script:
    - ./mvnw checkstyle:checkstyle
  artifacts:
    when: always
    paths:
      - target/site/*
  tags: [docker]
  allow_failure: true
  except:
    - tags
```

JUnitが使う `application.properties` です。
https://www.testcontainers.org/modules/databases/mysql/
辺りを参考にしました。


```properties:application.propeties
# src/test/resources/application.properties
spring.datasource.url=jdbc:tc:mysql:5.7.38://hostname:port/test?TC_MY_CNF=mysql_conf
spring.datasource.driver-class-name=org.testcontainers.jdbc.ContainerDatabaseDriver
spring.datasource.username=test
spring.datasource.password=
spring.sql.init.encoding=utf-8

spring.jpa.hibernate.ddl-auto=none
spring.jpa.show-sql=true
```

GitLabのPipeline

GitLabにpushするとPipelineが動きます。（今回は、CheckStyleとJUnitの2Job）
![Screenshot 2023-02-04 at 13.39.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130262/2fdc2d47-c2ff-274a-03fe-e9e41b4a6fc1.png)

テスト結果はTestsのタブから見れます。
![Screenshot 2023-02-04 at 13.42.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130262/2a4703b8-c4cf-49af-e2c0-9d2d1075983e.png)


## 雑感

一昔前は、CIでDatabaseテストを実行するのはかなり大変で、JUnitの@CategoryでCIの対象外するというケースも多かったと思います。（Database周りはモックにするなど…）
現在は、コンテナを使って手軽にCIでDatabaseテストが出来るので非常に便利ですね。
Databaseを実際に使わないと発見しづらい不具合もあると思いますので、品質向上に役立てていきたいです。
はじめてのQiita投稿

# 自己紹介 テスト投稿
皆さんこんにちは。mai-maiといいます。2022年4月から社会人になって、完全未経験ITエンジニアになりました。学生では修士まで6年間数学を専攻していました。なので本当に情報関係の知識は一切ありません。

とりあえずテスト投稿としてこれを投稿します。色々書きたいので、数式やコードをテストとして書いてみることにします。意味はほとんどありません。

まずは数式から
```math
\displaystyle f(z) = \sum_{n=0}^{\infty}\dfrac{f^{(n)}(\alpha)}{n!}(z-\alpha)^n
```
点 $z = \alpha$ における複素関数のTaylor展開ですね。

続いて簡単なコードを
```test.py
import numpy as np # numpyをインポートする
a = np.array([[1,2,3],[4,5,6]]) # 2行3列サイズの配列を用意
print(a) # 上記で作成した配列を表示
```
numpy配列の作成ですね。

次はテーブルの挿入を
| 1 | 2 | 3 |
|:-:|:-:|:-:|
| a  | b  | c  |
| d  | e  | f  |

なるほど、「2x3」でテーブルを挿入できるんですね。

**ボールド**

`code`

:::note info
これはテストです。
:::

:::note warn
これもテストです。
:::

:::note alert
もちろんこれもテストです。
:::

他にも色々できることがありそうですが、今後記事を書きつつ覚えていきます。
投稿も不定期で知識もないですが何かアウトプットしていきます。

よろしくお願いいたします。
neosでlogix その110

# 概要
neosでlogixやってみる。
logixを、俺コードで表現してみる。
練習問題、やってみた。

# 練習問題

tabキーを押してる間up、離せばdownを実装せよ。

# 方針
- timer使う
- keyheld使う
- if使う



# 俺コード

```
a = Timer 1
b = KeyHeld Tab
{c, d} = If a b
e = + Int 0.1
f = - Clamp01(Int) 0.1
Int = Write c e
Int = Write d f


```

# 写真

![2023-02-04 03.03.35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/3e9bdeea-20d0-debd-38f6-6cb746a6cc93.jpeg)


以上。
Azure Private DNS Zone リソースが削除できない (できた) 

# はじめに

Private Endpoint を使ったり使わなかったりといった検証を行っていました。
Private Endpoint リソースを削除し、その後いっしょに作られた Private DNS Zone リソースを削除しようとするが、なぜかできず... :scream:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/75ef16a3-7e33-8843-92d1-0542c428aa6a.png)

以下のように「ネストされたリソースが削除される前に、リソースを削除できません。」というエラーで失敗します。

> privatelink.agentsvc.azure-automation.net: Can not delete resource before nested resources are deleted. (コード: CannotDeleteResource)

Private Endpoint リソースは削除済みなので、関連するリソースはもうないと思うのだが、どうしても Private DNS Zone リソースが削除できません。コマッタ。 :cold_sweat:


# 補助的なリソース

Azure ポータルの既定では、一部のリソースが表示されないものがありました。その「一部のリソース」とは、「Azure インフラで作成、管理された**補助的なリソース**」です。

## 表示させるには

Azure ポータルで「**補助的なリソース**」を表示させるには、[非表示の型の表示 (Show hidden types)] チェックボックスにチェックを付けると表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/2d12d097-3d82-3213-bd30-360b4e16e568.png)

上図のように、非表示だった Private DNS Zone リソースに関連する補助的なリソースが表示されました。


# 解決方法

ということで、以下のような手順で削除できました。:grin:

1. はじめに、[非表示の型の表示 (Show hidden types)] チェックボックスにチェックを付ける :white_check_mark:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/d08cf910-a857-2dbb-60b2-9ae3da6c9c8e.png)

2. 次に、Private DNS Zone リソースに関連する補助的なリソースを削除する :negative_squared_cross_mark:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/806618a2-58b4-66ba-563c-6313e5049332.png)

3. 最後に、Private DNS Zone リソースを削除する :negative_squared_cross_mark:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/b98e891f-520e-dbe1-b0a0-b3998f647ffc.png)

4. 無事に削除できました :clap:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230264/a4f97bcf-544f-595a-e337-51124651d6b8.png)


# まとめ

ここでは Private DNS Zone リソースの削除の話でしたが、これに限らず、同じような場面に遭遇したら [非表示の型の表示 (Show hidden types)] チェックボックスにチェックを付けて、非表示だった関連するリソースが存在するか確認すれば良いですね。:thumbsup:
SAM CLI 環境変数読み込み方法 メモ



* SAM CLI利用時に定義した環境変数を読み込む方法をメモする

## 準備

* `env.json`

  * 環境変数ファイル
  * `template.yaml`に合わせて`Globals`と`Resources`はセクションを分けて記述する

  ```json
  {
      "Parameters": {
          "MYSQL_HOST":"db",
          "MYSQL_DATABASE":"test_db",
          "MYSQL_PORT":3308,
          "MYSQL_USER":"mysqluser",
          "MYSQL_PASSWORD":"mysqlpass"
      },
      "HelloWorldFunction":{
          "MYSQL_TABLE":"test_table"
      }
      
  }
  ```

* `template.yaml`

  * `Environment`セクションに`env.json`に対応する変数名を定義する

  ```yaml
  Globals:
    Function:
      Timeout: 3
      Environment:
        Variables:
          MYSQL_HOST: MYSQL_HOST
          MYSQL_DATABASE: MYSQL_DATABASE
          MYSQL_PORT: MYSQL_PORT
          MYSQL_USER: MYSQL_USER
          MYSQL_PASSWORD: MYSQL_PASSWORD
  ...
  Resources:
    HelloWorldFunction:
      Type: AWS::Serverless::Function
      Properties:
        CodeUri: hello_world/
        Handler: app.lambda_handler
        Runtime: python3.9
        Architectures:
          - x86_64
        Events:
          HelloWorld:
            Type: Api
            Properties:
              Path: /hello
              Method: get
        Environment:
        	variables:
        	　MYSQL_TABLE: MYSQL_TABLE
  ```



## 環境変数読み込み(実行)

* 下記のコマンドを実行する

  ```shell
  sam local start-api --env-vars env.json
  ```

  ※`--env-vars {環境変数ファイル}`で指定する



## 参考情報

* [sam local invoke](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-local-invoke.html)
git操作_間違えてaddしてしまった時

## 始めに
ローカルにて間違えて __git add__ してしまった時の対処法を備忘録として残します。

## 環境
| 開発環境    |バージョン |
|-----------|------------|
| __git__ | 2.36.1 |
| __Windows__| 11 |

## コマンド内容
```git:
// 間違ってadd してしまった
git add .
↓　↓　↓
// resetコマンドを使用します。add前の状態に戻したいファイルを選択します。
git reset ファイル名
```
これだけ

## 終わりに
閲覧ありがとうございました。
git操作もっと詳しくなりたいと思う今日この頃です。
ご指摘、ご意見ありましたら、コメントよろしくお願いします。
Docker環境でPlaywright (Python)を並列実行する方法メモ

* Docker環境でPlaywright +pytest-xdistを用いた並列アクセス方法についてメモする。

## プロジェクト構成

```
├── Dockerfile
├── docker-compose.yml
└── scenario
    └── test.py
```



## コード

* `docker-compose.yml`※entrypointでpytestコマンドを実行させる

  ```yaml
  version: '3.8'
  services:
    playwright:
      build: 
        context: ./
      volumes:
          - ./scenario:/var/scenario
      entrypoint: >
        sh -c "
          cd /var/scenario &&
          pytest -n 3 --dist each test.py
        "
  ```

  

* `Dockerfile`※`pytest-xdist`インストール

  ```dockerfile
  FROM mcr.microsoft.com/playwright/python:v1.29.0-focal
  RUN pip install playwright
  RUN pip install pytest-xdist
  ```

  

* `test.py`

  * Playwright公式サイトにアクセスし、`title`要素の確認を行う。
  * pytest-xdistワーカー別にログ出力を行う。

  ```python
  from playwright.sync_api import sync_playwright
  import logging
  
  # ワーカー別ロガーを定義する
  def _get_logger(worker_id):
      logger = logging.getLogger("logger_{}".format(worker_id))    
      handler = logging.FileHandler(filename="test_{}.log".format(worker_id))  
      handler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s"))
      logger.setLevel(logging.INFO)  
      logger.addHandler(handler)
      return logger
  
  # `worker_id`にワーカープロセスIDが格納される
  def test_parallel(worker_id):
      with sync_playwright() as p:
          browser = p.chromium.launch(headless=True)
          page = browser.new_page()
          # ページアクセス＋タイトルチェック
          page.goto('https://playwright.dev/python/')
          assert page.title() == 'Fast and reliable end-to-end testing for modern web apps | Playwright Python'
  
          # ワーカー別ログファイルにログ出力を行う
          # ワーカープロセスID,URL,タイトル
          logger = _get_logger(worker_id)
          logger.info('worker:{}  url:{}  title:{}'.format(worker_id,page.url, page.title()))
          page.close()
  
  ```

  

## 動作確認

* 以下のコマンドを実行する

  ```shell
  docker-compose up --build
  ...
  playwright_1  | ============================= test session starts ==============================
  playwright_1  | platform linux -- Python 3.8.10, pytest-7.2.0, pluggy-1.0.0
  playwright_1  | rootdir: /var/scenario
  playwright_1  | plugins: xdist-3.1.0
  playwright_1  | gw0 I / gw1 I / gw2 I
  playwright_1  | gw0 [1] / gw1 [1] / gw2 [1]
  playwright_1  | 
  playwright_1  | .                                                                        [100%]. [100%]. [100%]
  playwright_1  | ============================== 3 passed in 9.41s ===============================
  ```

  以下のように、`test_{worker_id}.log`ファイルにログ出力も行われる

## 参考情報

* [Pythonで記述されたPlaywrightの実行環境をDockerで用意する](https://nainaistar.hatenablog.com/entry/2021/07/12/120000)
Ruby if, else問題

# if文を使った条件分岐
以下の条件を満たすようプログラムを作成する。

- 条件1：第一引数のnumが1以上かつ10以下の範囲であればTrueを出力すること
- 条件2：第二引数のoutside_modeがTrueの場合は、第一引数numが条件範囲外でもTrueを出力すること
- 条件3：それ以外はFalseを出力すること

```ruby
def in1to10(num, outside_mode)
  if (num >= 1 && num <= 10) || outside_mode
    puts "True"
  else
    puts "False"
  end
end

# 呼び出し例
in1to10(5,false)
in1to10(11,false)
in1to10(11,true)
```
```ruby
True
False
True
# ターミナル出力
```

複数の条件がある場合は、***論理演算子***を使って記述を行います。
## 論理演算子とは
「真（true）」と「偽（false）」の確認を行う時に使われる演算子（記号）をのこと。
複数の条件式を組み合わせて条件式を記述するときは、論理演算子&&や||を使います。

例
```ruby
# aもbもtrueの場合にtrue
a && b 

# aかbのどちらかがtrueの場合にtrue
a || b 
```

## このプログラムの解説
この解説では、呼び出し例がin1to10(5,false)のときを例に進めていきたいと思います。

```ruby
if (num >= 1 && num <= 10) || outside_mode
```
上記条件式では、Trueを返すときの条件を記述しています。

Trueを返すときの条件
= numが1以上かつ10以下の範囲であること
= outside_modeがTrueの場合は、第一引数numが条件範囲外でもTrueを出力すること

呼び出し例では、1以上かつ10以下であり、falseなので、出力結果はTrueとなります。
T-SQLでサクッとテーブル作ってselectで一覧取得までやる

# はじめに
良く忘れるからメモ残す

# コマンド

```
CREATE TABLE users (
    id INT PRIMARY KEY IDENTITY,
    name NVARCHAR(50) NOT NULL,
    email NVARCHAR(255) NOT NULL,
    created_at DATETIME DEFAULT GETDATE()
);
INSERT INTO users (name, email) VALUES ('John Doe', 'johndoe@example.com');
SELECT * FROM users;
```
(若い)プログラマーのみなさんにぜひ読んでいただきたい私たちの未来を切り開くための本

# 山口周　「世界のエリートはなぜ「美意識」を鍛えるのか？」
日本の企業が陥ってしまっている罠。イノベーションを達成出来ず、コストを抑え(労働者を酷使する)ことで何とか生き残りを図っている。そんな状況を変えていくための大いなるヒント。それは鍛え抜かれた美意識(知性)に基づいた直感である。「才能」は生まれつきのもので手のつけようのないものだが「美意識」は今からでも鍛え上げ、磨くことができる。

# 柄谷行人　「力と交換様式」
著者は、2022年12月、哲学のノーベル賞と言われるバーグルエン哲学・文化賞をアジア人として初めて受賞した。日本の至宝である。やさしい言葉で書かれているが、彼の思考を追いかけるのは並大抵のことではない。だが努力をする価値はある。それは世界をより良くするための思考の積み重ねにほかならない。

# ブレイディみかこ　「他者の靴を履く　アナーキックエンパシーのすすめ」
経済的な苦境にある社会では、人々がまるで椅子取りゲームのように、限られたパイを奪いあい憎みあうことを強いられている。著者が提案するのは、他者の靴を履いてみること。それは、他者のことを想像してみよう、多様性をお互い認め合おう、ということです。他者の靴を履いてみるには、まず自分の靴を脱がなければならない。まずそこから始めてみよう。いまこの国を覆い尽くしている不寛容へ挑戦するために。

# 戸部良一他4名　「失敗の本質」
第二次世界大戦において、旧日本軍がなぜ負けたのか、主要な作戦ごとに分析する。これを読むと、良い部分も悪い部分も日本民族の特性みたいなものが浮かび上がってくる。その良い部分を活かして、戦後の脅威的な経済成長を成し遂げた日本。しかし、ここへ来て、またもや敗北への道を歩んでいる今、この本を再読する価値は大いにあるだろう。
Leetcode 567. Permutation in String

https://leetcode.com/problems/permutation-in-string/description/

## アプローチ
### BruteForece

```java
package com.leetcode.midium;

import java.util.Arrays;

public class PermutationinString567 {
    public static void main(String[] args) {
        boolean result = checkInclusion1("ab", "eidboaab");
        System.out.println(result);
    }

    /*
    Input: s1 = "ab", s2 = "eidbaooo"
    Output: true
    Explanation: s2 contains one permutation of s1 ("ba").
     */
    public static boolean checkInclusion(String s1, String s2) {

        int[] cnt = new int[26];

        for (char c : s1.toCharArray()) {
            cnt[c - 'a']++;
        }

        int s1Len = s1.length();
        int s2Len = s2.length();

        for (int i = 0; i < s2Len - s1Len + 1; i++) {
            int[] cnt2 = new int[26];

            for (int j = i; j < i + s1Len; j++) {

                cnt2[s2.charAt(j) - 'a']++;
            }
            if (Arrays.equals(cnt, cnt2)) return true;
        }

        return false;

    }
/* NA
    public static boolean checkInclusion1(String s1, String s2) {
        int len = s2.length() - s1.length();
        int s1Len = s1.length();


        for (int i = 0; i <= len; i++) {
            String temp = "";
            String reverseTemp = "";
            for (int j = i; j < i + s1Len; j++) {
                temp += "" + s2.charAt(j);
            }
            if (temp.equals(s1)) {
                return true;
            }
            for (int k = s1Len - 1; k >= 0; k--) {
                reverseTemp += "" + s1.charAt(k);
            }

            if (reverseTemp.equals(temp)) {
                return true;
            }

        }

        return false;
    }

 */
}

```

- [こちら](https://leetcode.com/problems/permutation-in-string/solutions/3138510/easy-solution-c-java-python-beginner-friendly-brute-to-best-method/?orderBy=hot)を参考しました
JavaScriptで複素関数をプロットしてみた


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

画面左側がz平面で、画面右側がf(z)平面

# 複素関数計算部分のソースコード抜粋

```js
//  parameter c is [real part, imaginaly part]
//            it means c[0] is real part,
//                     c[1] is imaginaly part.

function mul(c,d){
  return [c[0]*d[0]-c[1]*d[1],c[0]*d[1]+c[1]*d[0]];
}
// 1/c
function inv(c){
  let t = abs2(c);
  return [c[0]/t,-c[1]/t];
}
// add
function add(c,d){
  return [c[0]+d[0],c[1]+d[1]];
}
function exp(c){
  let r = Math.exp(c[0]);
  return [r*Math.cos(c[1]),r*Math.sin(c[1])]
}
// return real number -pi to pi
function arg(c){
  return Math.atan2(c[1],c[0]);
}
// return real number abs(c)^2
function abs2(c){
  return c[0]*c[0]+c[1]*c[1];
}
function log(c){
  return [Math.log(abs2(c))*0.5,arg(c)];
}
function pow(c,d){
  // c^d = exp(d*log(c))
  return exp(mul(d,log(c)));
}
```
[Rust] 所有権 参照などについて基礎的なポイント覚書

# 所有権はむずい

今までノリでコンパイラが指示するように参照`&`をつけたりしていた節があったが、学び直しました。
結局は公式ドキュメントですね。

https://doc.rust-jp.rs/book-ja/ch04-01-what-is-ownership.html

## 学んだポイント
- `&mut T`は変更可能な参照（そのままだけど、、）
- `&mut T`は2つ同時に設定できない。
解釈：変更可能な参照が競合できない。
- immutableな参照とmutableな参照は共存できない。（それもそう）
`&T`と`&mut T`が別の変数に与えられてはいけない。

2つ目の具体例（↑リンク見ていただければよいのですが、、）
```rust
    let mut s = String::from("hello");

    let r1 = &mut s;
    let r2 = &mut s;

    println!("{}, {}", r1, r2);
```
エラー内容
```
$ cargo run
   Compiling ownership v0.1.0 (file:///projects/ownership)
error[E0499]: cannot borrow `s` as mutable more than once at a time
(エラー: 一度に`s`を可変として2回以上借用することはできません)
 --> src/main.rs:5:14
  |
4 |     let r1 = &mut s;
  |              ------ first mutable borrow occurs here
  |                    (最初の可変な参照はここ)
5 |     let r2 = &mut s;
  |              ^^^^^^ second mutable borrow occurs here
  |                    (二つ目の可変な参照はここ)
6 | 
7 |     println!("{}, {}", r1, r2);
  |                        -- first borrow later used here

error: aborting due to previous error

For more information about this error, try `rustc --explain E0499`.
error: could not compile `ownership`
```

3つ目の具体例
```rust
let mut s = String::from("hello");

let r1 = &s; // 問題なし
let r2 = &s; // 問題なし
let r3 = &mut s; // 大問題！
```

エラー内容
```
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as
immutable
(エラー: `s`は不変で借用されているので、可変で借用できません)
 --> borrow_thrice.rs:6:19
  |
4 |     let r1 = &s; // no problem
  |               - immutable borrow occurs here
5 |     let r2 = &s; // no problem
6 |     let r3 = &mut s; // BIG PROBLEM
  |                   ^ mutable borrow occurs here
7 | }
  | - immutable borrow ends here
```

しっかりと向き合って考えてみるとそりゃそうって言う話なのですが、
ちゃんと、仕組みを頭で整理することでちゃんと中身を把握して使えそうな気がしています。

あとはポイントはダングリング参照ができないってところですね。
実際にコードを書いていく中でそんなにダングリング参照を引き起こしそうなケースってないのかなと感覚的には思いましたがコンパイラの気持ちを理解するのに役立ったかなと思っています。
【tailwindcss】Reactではなく、単純なwebサイトにtailwindを導入する方法

# はじめに

ここ最近で流行しているtailwindcss。
基本的にはReactのプロジェクトに導入されているイメージがあります。

業務で、LP開発にtailwindcssを使用する機会ができたので導入方法を書き残したいと思います。

# ディレクトリ構成

```
root
    ├─ docs
    |  └─css
    |  | └─style.css
    |  └─img
    |  └─index.html
    |
    ├─ src
    │  └─ css
    |     └─tailwind.css
    |
    └─ package-lock.json
    └─ package.json
    └─ tailwind.config.js
```

# 導入方法

- rootディレクトリに移動し、`npm init`コマンドで初期化、`-y`をつけて`package.json`も同時に作りましょう。

```console
$ npm init -y
```

- tailwindとその他構築に必要なモジュールをインストールします。
```console
$ npm install tailwindcss@latest postcss@latest autoprefixer@latest
```

- tailwindを初期化し、`tailwind.config.js`ファイルを生成します。
```console
$ npx tailwindcss init
```

- 次に`src`フォルダを作成、その配下に`css`フォルダを作成、そしてその中にtailwind.cssを作成して以下の内容を記述します。
```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```
- 最後に`docs`内の`css/style.css`を指定してビルドすると、tailwindcssを扱うための内容が書き出されます。
```console
$ npx tailwindcss-cli@latest build ./src/css/tailwind.css -o ./docs/css/style.css
```

これで導入は完了です。`index.html`ファイル内で`style.css`ファイルを読み込んで試しにクラスを当ててみましょう。
スタイルが適用されるはずです。


また、この記事では書きませんが、`tailwind.config.js`ファイル内に特定の記述をすることでスタイルをカスタマイズすることが可能です。ぜひ調べてみてください。


サイトをデプロイする際は今のままでは`css`ファイルの容量が大きいので、最終的には圧縮が必要になるでしょう。
今後そのような記事を書くかもしれません。
Styledで定義したstyled-componentsにcssが適用されないとき

# styledを使ってcssを適用したコンポーネントを定義する際、never usedのwarningが出てcssも適用されないときの対処法

## 問題が出るテストコード
```react
import React from 'react'
import { Paper } from '@mui/material';
import {styled} from '@mui/material/styles';


// styledされた変数の名前が重要
const styledpaper = styled(Paper)(({theme}) => ({
    marginTop: theme.spacing(8),
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
}));

const test = () => {
  return (
    <styledpaper>TestText</styledpaper>
  )
}

export default test
```

## 実際のエラー

```console
 Line 7:7:  'styledpaper' is assigned a value but never used  no-unused-vars
```


## 解決策
styledで定義した変数名を大文字にする必要がある
エラーの出るコードでは

```react
const styledpaper = styled(Paper)(({theme}) => ({
```

というふうにstyleを適用しており、この時宣言する変数名styledpaperは先頭を大文字にする必要がある。
今回で言えば"styledpaper" を "Styledpaper" に変更する。

##　変更後
```react
import React from 'react'
import { Paper } from '@mui/material';
import {styled} from '@mui/material/styles';


// styledされた変数の名前をStyledpaperに変更
const Styledpaper = styled(Paper)(({theme}) => ({
    marginTop: theme.spacing(8),
    display: "flex",
    flexDirection: "column",
    alignItems: "center",
}));

const test = () => {
  return (
    <Styledpaper>TestText</Styledpaper>
  )
}

export default test
```


これでwarningが消えてcssも適用された。
UnityでGetComponent<Dropdown>()が動かない

# はじめに
UnityでUIのDropDown(やButton）を扱うときのスクリプトで躓いたのでメモ。

# 環境
M1 Mac
Unity 2021.3.17f1

# 要点
```
GetComponent<Dropdown>()
```
がエラーでnullが返ってきて、その先が実行されない。

# 解決策
```
using TMPro;
```
を追加し、
```
GetComponent<TMP_Dropdown>()
```
に変更する。

　UIを追加する際に、お尻に「TextMeshPro」と書いてある物を使うときは、このように書く必要があるようだ。UI>Legacy>Dropdownがあるが、なんとなく推奨されず、消えゆくのかなと思ったので、使ってない。
　が、他のサンプルサイトの多くは、Legacy機能を使っているようで、コードをコピペしただけでは、うまく動かない。

# コード
```cs:TestDropDown2.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class TestDropdown2 : MonoBehaviour{
    List<string> options = new List<string>() { "Motion1", "Motion2", "Motion3", "Motion4", "Motion5" };

    public void Start(){
        TMP_Dropdown dropdown = GetComponent<TMP_Dropdown>();

        dropdown.ClearOptions();
        dropdown.AddOptions(options);

        dropdown.onValueChanged.AddListener((value) => OnValueChanged(value));
    }

    public void OnValueChanged(int value){
        Debug.Log(value);
    }
}
```
Windowsのbatで一定秒数待つ処理（スリープ的なこと）

# 概要

スタートアップに『特定のアプリケーションを起動させるbat』を設置している。
だが、時々アプリケーションの起動が失敗する時がある。
どうやら **PC起動と同時（間髪入れず）** アプリケーションを起動しているのが良くなさそう。

bat内で一定秒数待つ処理をいれたい。

# やり方

```bat
rem 20分待つ。（60秒×20=1200）
timeout /t 1200 /nobreak >nul
```

まず ```timeout /t 秒数``` で指定秒数待つ処理を実装。

だが、 ```timeout /t 秒数``` だけだと途中でユーザーがキー入力した際、待つ処理が中断されてしまう。
なので ```/nobreak``` を付けてキー入力中断を防止。

また、下記のような『※秒待っています。…』の表示を出さないようにする為、 ```>nul``` を付けている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/c96726f8-789d-4790-ea1f-dd004ab2c370.png)


# sleepというコマンドは存在しない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/e1681949-db98-4754-74e8-b31a6523994a.png)

# 参考サイトさん

https://atmarkit.itmedia.co.jp/ait/articles/1206/08/news137.html

# バージョン

Windows 10 Pro 22H2 OSビルド 19045.2546
Numpyで特定の列/行に条件を指定してマッチする行/列全体を抜きだしたい

##### お悩み

numpyで特定の列に対して条件を指定して行全体を操作したいことがある。
例えば、機械学習のモデルに画像を通すと、オブジェクトクラスの値がnumpyの中に入って返ってくるけれど、特定のクラスだけフィルタかけたい時とか。本筋としてはモデル側で欲しいクラスだけを返すようにしろって話なんだけど、それができない時の話。

下の出力例だと6番目の値がオブジェクトクラスなので、例えば車(2)だけの結果を集めたいとか、人間(0)だけを集めたい時に、6列目の値で検索して該当する行だけ集めたい。

```python:とある出力例
[[5.39797363e+02 2.71583344e+02 5.93862732e+02 3.26177856e+02
  8.78980994e-01 2.00000000e+00]
 [7.61696655e+02 2.84762238e+02 7.84034058e+02 3.39492310e+02
  8.69529247e-01 0.00000000e+00]
 [8.06120178e+02 2.78944641e+02 8.31428406e+02 3.36827484e+02
  8.61427248e-01 0.00000000e+00]
 [4.77429657e+02 2.68967316e+02 5.18531067e+02 3.06501892e+02
  8.59408557e-01 2.00000000e+00]
 [2.50081268e+02 2.73935608e+02 2.67830475e+02 3.19194946e+02
(snip)
```


##### ソリューション

numpyにはこれに相当するコマンドはなさそう。一度調べたい行/列だけを対象としてnp.whereをかけて、該当する行/列のリストを取得して、その列を全体から抜きだす必要がある。

```python:４列目が奇数の行を抜き出す例
# python3
Python 3.9.5 (default, Nov 23 2021, 15:27:38) 
[GCC 9.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> a = np.arange(20).reshape((4, 5))　# 行列を作成
>>> a　　　
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
>>> a[:,3]   # 列3(4列目)を抜き出し
array([ 3,  8, 13, 18])
>>> np.where(a[:,3]%2)　 # 列3が奇数な行の番号を取得。タプルで帰ってくるから…
(array([0, 2]),)
>>> np.where(a[:,3]%2)[0]　# 列3が奇数な行の番号のリストを取得。
array([0, 2])
>>> a[np.where(a[:,3]%2)[0], :]　# 上で入手したリストを元にa全体から行を抜き出し
array([[ 0,  1,  2,  3,  4],
       [10, 11, 12, 13, 14]])
```

##### 洗練されたソリューション
コメントでもっと洗練させれた書き方を教えてもらった。
```python:４列目が奇数の行を抜き出す洗練された例
>>> a[:, 4]%2 == 1
array([False,  True, False,  True])
>>> a[a[:, 4]%2==1]
array([[ 5,  6,  7,  8,  9],
       [15, 16, 17, 18, 19]])
>>> 
```
しかし、なぜ奇数を抜き出すような例にしたのか今となっては思い出せない。

###### 結論
というわけで最初に挙げた機械学習の評価から必要なクラスのデータだけ取り出すには以下のようにすれば良い。

```python:6列目に入ったオブジェクトクラスが0のものだけを抜き出す例
 outputs[np.where(abs(outputs[:,5]) == 0 )[0],:]
```

```python:6列目に入ったオブジェクトクラスが0のものだけを抜き出す洗練された例
 outputs[np.isclose(outputs[:, 5], 0)]
```
これで対象のクラスだけにフィルターできる。実行速度は知らん。もしかしたらループまわしても変わらないかも…

##### なんでabs()/iscloseしているか

absで絶対値を取っているのは、値がfloatなので単純な比較ではマッチしないせいです。
```python:abs()
abs(outputs[:,5])
```

参考
[[Python] 浮動小数点数floatの比較は要注意！！](https://qiita.com/k_yamashita/items/e7180809d5fd95f454b9)
[Pythonで浮動小数点数floatの誤差を考慮して比較](https://note.nkmk.me/python-math-isclose/)
今更だけど、cloud shell　でcodecommit リポジトリを作る

cloud shellを開く
![cloiudshell.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120764/8bfc0cd6-40d0-93da-d767-b2b1dd50e764.png)

リポジトリを作成、リポジトリ名はmyrepositorytestformomokukko

```
aws codecommit create-repository --repository-name myrepositorytestformomokukko --repository-description "My demonstration repository" --output yaml 

[cloudshell-user@ip-10-2-59-249 ~]$ aws codecommit create-repository --repository-name myrepositorytestformomokukko --repository-description "My demonstration repository" --output yaml
repositoryMetadata:
  Arn: arn:aws:codecommit:ap-northeast-1:123456789123:myrepositorytestformomokukko
  accountId: '123456789123'
  cloneUrlHttp: https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/myrepositorytestformomokukko
  cloneUrlSsh: ssh://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/myrepositorytestformomokukko
  creationDate: '2023-02-04T01:58:27.641000+00:00'
  lastModifiedDate: '2023-02-04T01:58:27.641000+00:00'
  repositoryDescription: My demonstration repository
  repositoryId: edbe267d-1x1x-467f-8a91-123456789xxx
  repositoryName: myrepositorytestformomokukko
[cloudshell-user@ip-10-2-59-249 ~]$ 
[cloudshell-user@ip-10-2-59-249 ~]$ 
```

コンソールでリポジトリを確認
![viwerepo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120764/fd3cc07d-8541-5c23-4161-3f0113f6e2ab.png)
![emptyrepository.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120764/32aa9cc1-a7b3-cd22-0539-50cf24a0355c.png)

リポジトリに新しくファイルを作成
ファイル名はtestfile
空のリポジトリにファイル作成すると自動的にmainブランチが作成される。
![creatfilenakami.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120764/67b83179-39cf-f879-7743-215de1877cae.png)
![commitchanges.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120764/db332a77-60e5-e24d-ef14-597171eb93c9.png)

mainブランチとファイルを確認

![committedtomain.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120764/9ae0b784-2591-61f7-e5ef-e1c4c6b07ea8.png)
Scanner class

usedelimiterでcsvなどの区切り文字を指定することができる
以下の例は文字列を直接指定している
通常はFileInputStreamを使用してファイル読み込みとする

```java
public class Outer {
    public static void main(String[] args) {
        Scanner sc = new Scanner("A B C");
        sc.useDelimiter(" ");
        try(sc) {
            while(sc.hasNext()) {
                System.out.println(sc.next());
            }
        }
    }

```
```
A
B
C
```
第12回FA設備技術研究会　オブジェクト指向FBを使って装置のプログラミングを書いてみよう



2023/02/18（土）第12回FA設備技術研究会(https://fa-study.connpass.com/)で発表した時の資料です。

この記事を読む前に、読んでほしい記事
第11回FA設備技術研究会　IEC61131-3 Ed.3 オブジェクト指向FB(https://qiita.com/oofunctionblock/items/228dec02b45a9bcadaa9)
Rasberry Pi 4BにCODESYSをインストール(https://qiita.com/oofunctionblock/items/75ea902b11c9d8d67baf)

連絡先
OOFunctionBlock@gmail.com

----
![スライド1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/0c7f27e4-f204-5641-2075-d83737f8deeb.jpeg)

-----
![スライド2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/b0be99e6-ac36-62bd-db7f-a7bfd675c97d.jpeg)

-----
![スライド3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/0b9bc4ae-0f2c-8bbe-f3f3-15561acc69c2.jpeg)

-----
![スライド4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/db4b151c-60e4-767f-c7fa-b5131be10140.jpeg)

----
![スライド5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/bcc4a8ce-9d25-8ab3-6e45-35bcfc712659.jpeg)

----
![スライド6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/fc7ebc85-e6b6-7713-3732-742ee10ab5e6.jpeg)

----
![スライド7.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/7a3dd42e-27c6-75c6-93b7-005a271f3a24.jpeg)

----
![スライド8.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/0ee46261-4897-4488-87e3-7a1bf3eab5e5.jpeg)

----
![スライド9.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/8b6f90a9-e068-3389-0360-853543e3efec.jpeg)

----
![スライド10.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/4e7b7287-f8cb-7da5-b4f3-9343fe2695f5.jpeg)

----
![スライド11.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3119828/7b71dc9e-17fd-0915-5892-282ad1f9d81a.jpeg)

----
CodeIQ:限られた数字で作れる数の、まんなかの値の解答

@nabetaniさんのCodeIQの問題です。
問題とテストケースは、こちらのお世話になりました。解答もあります。
->https://blog.goo.ne.jp/r-de-r/e/764ab34fadd2faf563945b2b56a4f978

0の有無、要素数が1かどうかで分類します。まず作れる数が奇数の場合を考えます。
要素数が1の場合は簡単です。
要素数が1より大きい場合
　0が入る場合
　　0が上位桁に来る部分（除かれる部分）で小さい桁の数を再現するので、
　　n個k桁の場合n^kの中にすべての数が入り、中央値はn^kの中央（要素の数の中央）
　（またはn+n*(n-1)+n^2*(n-1)+...+n^(k-1)*(n-1)=(n-1)*(n^k-1)/(n-1)+1)
　0が入らない場合
　　k桁の数がn^k個あるので1桁から数えると
　　n+n^2+...+n^k=n(n^k-1)/(n-1),中央値はこの半分。
　　これは、一番大きい桁にあるので、一つ下の桁までの数n(n^(k-1)-1)/(n-1)を引いて、
　　k桁目で何番目かを、k-1桁の数n^(k-1)による商と剰余を用いてrec/6で再帰的に求める。
作れる数が偶数の場合も上記の手法で一つ求め、さらに一つ手前の数も求めます。

　

　

```Prolog
%SWI-Prolog (7.4.2,7.6.4)
%:-initialization(start41).    %ideone
%start41.

solv41(K,[X],[R1,R2]):-　　　%要素数1
     divmod(K,2,D,M),D1 is D+1,cal41(D1,X,[R2,_]),
     (M=:=0->R1 is R2 div 10;R2=R1),!.

solv41(K,L,R):-             %0を含む
     member(0,L),!,length(L,N),S is N^K,divmod(S,2,D,M),D1 is D+1,
     rec(N,K,D1,L,0,R1),(M=:=0->rec(N,K,D,L,0,R2);R2=R1),R=[R2,R1].

solv41(K,L,R):-                            
     length(L,N),S is N*(N^K-1)/(N-1),divmod(S,2,D,M),S1 is D+1-N*(N^(K-1)-1)/(N-1),
     rec(N,K,S1,L,0,R1),(M=:=0->(S2 is S1-1,rec(N,K,S2,L,0,R2));R2=R1),R=[R2,R1].

rec(_,0,_,_,R,R):-!.　　　　　　%再帰
rec(N,K,S,L,R,FR):-S1 is S-1,    %桁上がりの部分の調整　（M1 is M+1で戻している)
     N1 is N^(K-1),divmod(S1,N1,D,M),D1 is D+1,nth1(D1,L,V),
     R1 is R*10+V,M1 is M+1,K1 is K-1,rec(N,K1,M1,L,R1,FR).

start41([]).
start41([[A,B,Q]|T]):-
     solv41(A,B,[R1,R2]),(R1==R2->R=[R1];R=[R1,R2]),
     (R==Q->Str=" pass ";Str=" fail "),write(Str),writeln(R),start41(T).

cal41(1,V,[V,R2]).
cal41(N,V,[R1,R2]):-
     N1 is N-1,cal41(N1,V,[R11,R21]),R1 is R11*10+V.

start41:-dat41(L),start41(L),!.

dat41([[1,[2],[2]],[2,[2],[2,22]],[15,[3],[33333333]],[1,[0],[0]],[2,[0],[0]],
     [15,[0,4],[44444444444444,400000000000000]],[1,[0,2,4,6],[2,4]] ,
     [2,[0,2,4,6],[26, 40]],[15,[0,2,4,6],[266666666666666,400000000000000]],
     [15,[1,2,3,4,5,7,8,9],[444444444444444,444444444444445]],
     [15,[1,2,3,4,5,6,7,8,9],[494949494949495]],
     [15,[0,1,2,3,4,5,6,7,8,9],[499999999999999,500000000000000]]]).

```
Oracleで文字列結合（連結演算子とCONCAT関数のどっちを使うのがよいかについても）

# 概要

Oracleで文字列結合する方法としては…

* ||（連結演算子）を使う。
* CONCAT()を使う。

の2種類がある。

この記事では上記2種類のやり方と、『||（連結演算子）を使う』方がおススメなことについて記載。

# やり方（連結演算子の||を使う）

## 動作確認用SQL

```sql:
SELECT 

-- 2カラム結合。
カラム名1 || カラム名2 AS TWO_DAYO,

-- 3カラム結合。
-- 連結演算子の前後にスペースが無くてもOK。
カラム名1||カラム名2||カラム名3 AS THREE_DAYO,

-- 結合する要素内にNULLがある場合。
-- 下記の結果は『ちさとたきな』。
-- （どれか一つにNULLがあったとしても結合結果がNULLにはならない）
'ちさと' || NULL || 'たきな' AS NULL_ARUYO,

-- 文字列以外の数字や日付型を結合した時。
-- 下記の結果は『999と23-02-04』。
-- （2023年02月04日に実行した場合）
999||'と'||SYSDATE AS ANOTHER_DAYO

FROM テーブル名
```

## 連結演算子（||）のまとめ

* CONCAT()に比べて、3つ以上の文字列を結合する時にSQLが煩雑にならない。
（これが連結演算子をおススメする理由）
* どれか一つにNULLがあったとしても、結合結果がNULLにはならない。
* 数字や日付の型を結合しても例外にならない。

# やり方（CONCAT関数を使う）

## 動作確認用SQL

```sql:
SELECT 

-- 2カラム結合。
CONCAT(カラム名1, カラム名2) AS TWO_DAYO,

-- 3カラム結合。
-- 引数を2つしか渡せないので入れ子にする必要がある。
CONCAT(カラム名1, CONCAT(カラム名2, カラム名3)) AS THREE_DAYO,

-- 結合する要素内にNULLがある場合。
-- 下記の結果は『ちさとたきな』。
-- （どれか一つにNULLがあったとしても結合結果がNULLにはならない）
CONCAT('ちさと', CONCAT(NULL, 'たきな')) AS NULL_ARUYO,

-- 文字列以外の数字や日付型を結合した時。
-- 下記の結果は『999と23-02-04』。
-- （2023年02月04日に実行した場合）
CONCAT(999, CONCAT('と', SYSDATE)) AS ANOTHER_DAYO

FROM テーブル名
```

CONCAT()に3つ以上の引数を渡すと下記文言で例外。

>ORA-00909: 引数の個数が無効です

## CONCAT関数のまとめ

* 3つ以上の文字列を結合する時にSQLが煩雑になる。（入れ子）
* どれか一つにNULLがあったとしても、結合結果がNULLにはならない。
* 数字や日付の型を結合しても例外にならない。

# バージョン

Oracle Database 11g Release 11.2.0.1.0 - 64bit Production