OmniAICreator/Qiita-1.07M huggingface dataset:
SpringBootとは 

Javaを習得するべく、Spring Bootを触ってみたので理解したことをまとめてみます。

<h1>目次</h1>

1. Spring Bootとは
2. Spring Bootのメリット
3. Spring Bootのデメリット


<h1>Spring Bootとは</h1>
Spring Bootとは、Microsoftが提供しているオープンソースのJavaフレームワークです。Springと外部ライブラリを利用して複雑な設定の手間を省いてくれるのが魅力です。

SpringというのはSpring Frameworkの略称で、こちらは2003年にリリースされています。2014年にリリースされたSprint Bootでは複雑なMXL設定ファイルの用意が不要になったり、機能がより充実したことから使いやすいと評判です。さらに、MVCモデルを採用しており、効率よく開発を進めることに特化したフレームワークです。

※MVCモデル
Model View Controllerモデルの略。プログラムをModel、View、Controllerの3つの役割に分けて作ることで作業の効率性や保守性をあげようというソフトウェア設計モデル。

<h1>Spring Bootのメリット</h1>
Spring Bootのメリットに、拡張機能や自動設定が多い点が挙げられます。

Spring Bootには、

https://start.spring.io/

というプロジェクト作成用のクイックスタートジェネレーターがあり、ここに必要な設定を入れることで、プロジェクト作成に必要な言語設定や依存関係を作成することができます。

依存関係にはウェブ開発のためのSpring Webや、JavaのアノテーションライブラリであるLombokなど様々な種類があります。
使いたいものを指定し、Spring Initializr上で「EXPLORE」を選択するとその依存関係を使用するために必要なコードを生成してくれるので、必要な個所をコピーして自分のコードに貼り付けることで簡単に依存関係の指定ができます。

他の例としては、HTMLを使用する際にはHTML生成用のテンプレートエンジンであるThymeleafが便利です。サーバーから受け取ったデータをテンプレートに当てはめて動的に文字を作成してくれます。また、これによりUIとロジックを分けて作業でき、returnにHTMLを直接書く必要もありません。ThymeleafもSpring InitializrのDependenciesから選択できます。

<h1>Spring Bootのデメリット</h1>
Spring Initializrは依存関係を設定するのに便利ですが、Spring系統のフレームワークに利用されている依存関係の注入（DI: Dependency Injection）という概念がそもそも複雑で難しいため、これを理解するのにコストは必要です。

<h1>おわりに</h1>
プログラミングについては初心者で、環境構築や設定ファイルの準備が大変そうというイメージがありましたが、効率良くコーディングするための様々なツールがあるのだと学びました。

これからも色んなツールを試しながら、プログラミングを学んでいきたいと思います。
Deno DeployでBlueskyにツイートするAPI【ポスト】

```bash
curl https://b-sky.deno.dev?identifier=laravel11.bsky.social&password=PASSWORD&text=やあ
```

`laravel11.bsky.social`と`PASSWORD`は適宜書き換えてね！
https://bsky.app/profile/laravel11.bsky.social

<p class="codepen" data-height="720" data-default-tab="result" data-slug-hash="oNONBoy" data-user="04" style="height: 720px; 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/04/pen/oNONBoy">
  Bluesky Post</a> by John Doe (<a href="https://codepen.io/04">@04</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

# ソースコード

```javascript
import AtprotoAPI from 'npm:@atproto/api'

Deno.serve(async (req: Request) => {
    const headers = { 'Access-Control-Allow-Origin': '*' }
    const { identifier, password, text = 'こんにちは！', service = 'https://bsky.social' } = Object.fromEntries(new URL(req.url).searchParams)
    try {
        const agent = new AtprotoAPI.BskyAgent({ service })
        await agent.login({ identifier, password })
        const richText = new AtprotoAPI.RichText({ text })
        await richText.detectFacets(agent)
        const response = await agent.post({
            $type: 'app.bsky.feed.post',
            text: richText.text,
            facets: richText.facets,
        })
        return Response.json(response, { headers })
    } catch (e) {
        return new Response(e.message, { status: 400, headers })
    }
});
```
自分の「声」で書く技術～自己検閲をはずし、響く言葉を仲間と見つける～

[自分の「声」で書く技術――自己検閲をはずし、響く言葉を仲間と見つける](https://www.amazon.co.jp/dp/B0CT7QPZXM)

:::note info
英知出版の読者モニタープログラムにより無料で書籍を受け取りました。
このサイトにレビューを書くようにもとめられてはおらず、下記はあくまで個人としての見解です。
:::

近頃はBlogとかしか読まない感じになってしまい、強制的に読む機会があるなら積極的に参加している。

いまだにＸと言い辛いＴｗｉｔｔｅｒだったと思うけど、募集していたので応募したら抽選してもらえた。

blogについても、なんかネタがないな～という理由で書いていなかったのだけど、この本を読んで、とりあえず書いてみようとおもって、Qiitaっぽくはないけどポエムとしてならいいや。ということで、ここに書いている。

# 感想

書評っぽくこの本だと、やっぱりいいものを書かなきゃとか思う気持ちが、そんなのはダメだよ（ダウティング(doubtingかな？)と書かれている)とことで書けなくしていると言っている。

だから、否定されない環境と仲間の中で書いていこう。その前に、リハビリとして思い立ったことをつらつらと書いていくことを繰り返そう。と言っている。

１９７３年（５０年前！）の本なので言葉がちょっとわかりずらいと感じることもあって「やけくそライティング」なんかは、今だとマインドマップのように連想とかのほうが受け取りやすかったりするのかなとも思った。

あとは「[心理的安全性](https://diamond.jp/articles/-/330163)」と言い変えたほうがわかりやすいのかな。その場で自分の言葉を書いてもいいという感覚は。

ここら辺の感覚は、自分もそうだなと思うことが多い。仕事の中だとどうしても沢山の人に物事を伝えなければいけないことが多くて、でもなんて書けばいいのかわからないとか若い時は思っていた気がする。

でも、締め切りが近すぎ、いいやと言葉をあんまりこだわらず出したものがそのまま通ったのを繰り返していくうちに、あんまり気にならなく書けるようになったと思う。ちょうどそのころ[ ラフコンセンサス(Rough Consensus)、 ランニングコード(Running Code)](https://www.nic.ad.jp/ja/basics/terms/ietf.html)の考え方を知って、とりあえずは不十分でも形にする。見たいなことをやるようになった。今こうやって書くと、かなり誤解していたとは思うけど。

きちんとしたものを書かなければいけない。というのはどうしても自分を知っている場に対して書く場合だと仕方がないのかな。と思う。恥ずかしいし。

仲間を見つけるということは、今だとDiscordとかあるので、何かを志す人とかが集まっていろいろやりやすいとも思う。Ｘでも繋がれるだろうし。
ただ、この本でかかれている２か月以上、それなりの人数で最初は参加者の言葉を傾聴していくというティーチャーレスライティングクラスをしっかりやるのはとても難しそう。

今だったらＬＴで、無理やり発表あたりがいいのかな。自分も思えば、[ログ解析ソフトでハートマークを書く](https://qiita.com/toshikawa/items/a74ef9f6c22d16127507)とか、やったし。

やっぱり、何等かのきっかけが必要だと思う。自分もこのブログの前に、サイバーの題材で発表してみないと先輩に誘われて、発表してなんか楽しかったから、なんか書こうかなと思うようになったし。

この本は、その書こうという気持ちになるためのきっかけを与えてくれるにはいい本だと思う。自分もこんな感じで見直すきっかけとなったし。

今、なんか書いていないのは興味の範囲がＬＬＭとかのＡＩに移っていて、そこで自分のやっていることがまだまだ小僧レベルなんだよな～ということ。

でも、こうやって書いていくことでとりあえずは自分の考えとか気持ちを残していくことはそんなに悪いことでもないと思う。

# これから

これから、この本関連で英治出版は、なにかやっていくのかな？

https://eijionline.com/n/n77cf510ec326

本があって、それについてXでもnoteでも、Discordでも、なんらかの形で感想がまとまっていけるといいかもしれない。

多分、この本は何か書いてみようという気持ちにさせてくれるので、じゃ、どっかで拾ってもらえるとすごくいいことだと思う。
そういうことだと、今だとdiscordなんだろうな。
自分みたいなポエムばっかりになってしまったら、モデレーターの人も大変だろうけど。

# その他
どうしても`eichishuppan`と打ってしまう。
検索して、いや、うれしいけどそうじゃない。
S3のイベント通知で他アカウント上のLambdaを呼び出す際の権限設定方法メモ



## はじめに
S3バケットにアップロードされたオブジェクトを他アカウント上にあるLambdaを用いて別のS3バケットへコピーする環境を構築しようとした際にIAM周りでつまずいたので、設定方法の備忘録としてのメモになります。Lambda関数はコピー元S3バケットにオブジェクトがアップロードされた時をトリガーとして実行されます（S3のイベント通知機能）。
~~S3のレプリケーション機能とかを使えば簡単なのに~~

今回の構成は以下の図の通りです。

![s3Lambda.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682975/9f8912b5-44bd-7eb4-65e5-5565d12ee7cf.png)


|              | コピー元アカウント | コピー先アカウント      |
| ------------ | ------------------ | ----------------------- |
| アカウントID | 000000000000       | 111111111111            |
| S3バケット名 | source-bucket-name | destination-bucket-name |
| Lambda関数名 | -                  | object-copy-function    |

## Lambdaの設定
まずは、LambdaからS3にアクセスするための実行ロール、S3からLambdaを呼び出すためのリソースポリシーを設定します。

### 実行ロール
S3へのアクセス権限を付与します。
今回はオブジェクトのコピーのみ行えれば良いので、権限設定のベストプラクティスに基づいて最小権限の`S3:Putobject`と`S3:GetObject`をそれぞれ付与します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": [
                "arn:aws:s3:::source-bucket-name",
                "arn:aws:s3:::source-bucket-name/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": "s3:PutObject",
            "Resource": [
                "arn:aws:s3:::destination-bucket-name",
                "arn:aws:s3:::destination-bucket-name/*"
            ]
        },
    ]
}
```


### リソースポリシー
S3のイベント通知からLambdaを呼び出すために、S3からLambdaの実行を許可するリソースベースのポリシーを追加します。
Conditionの部分にはコピー元S3バケットがあるAWSアカウントのIDとARNを入れます。

```json
{
    "Version": "2012-10-17",
    "Statement": [
    {
        "Effect": "Allow",
        "Principal": {
            "Service": "s3.amazonaws.com"
        },
        "Action": "lambda:InvokeFunction",
        "Resource": "arn:aws:lambda:ap-northeast-1:111111111111:function:object-copy-function",
        "Condition": {
            "StringEquals": {
                "AWS:SourceAccount": "000000000000"
            },
            "ArnLike": {
                "AWS:SourceArn": "arn:aws:s3:::source-bucket-name"
            }
        }
    },
  ]
}
```


## コピー元S3バケットの設定
### バケットポリシー
他アカウント上のLambdaからのアクセスを許可するよう、バケットポリシーを設定します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
    {
        "Effect": "Allow",
        "Principal": {
            "Service": "lambda.amazonaws.com"
        },
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::source-bucket-name",
        "Condition": {
            "StringEquals": {
                "AWS:SourceAccount": "111111111111"
            },
        }
    },
  ]
}
```

### イベント通知
オブジェクト作成時にLambdaを実行するよう、S3バケットのプロパティからイベント通知を作成します。

設定保存時に指定したLambda関数に対して接続確認が行われるため、適切な権限が設定されていないと`Unable to validate the following destination configurations`エラーが発生します。

## おわりに
今回はS3のイベント通知で他アカウントのLambdaを呼び出し、オブジェクトのコピーをクロスアカウントで行う際の権限や設定についてまとめてみました。IAMは複雑で理解が難しいですが、実際に手を動かしながら設定すると理解が捗りますね。
DatePickerのUI自動テストで気をつけたいこと

こんばんは。今日はテスターにとって特別な日、閏日ですね。
閏日で不具合見つけましたか？
ちなみに、私は一度も閏日の不具合に遭遇したことはありません。

さて、そんな2月29日、閏日でなくても起きるE2Eテストの不具合を引き当てたので、小ネタとして記事にしてみます。


> 「昨日まで問題なく安定して動いていたE2Eテストが今日突如として失敗してる！」

まさか閏日か!?と思ったのですが、結論としては閏日は関係なく月跨ぎのDatePickerの処理の不備でした。

### 処理の概要
DatePickerを表示し、`Today`という値が含まれる属性をクリックする処理です。
レビューの時は、問題なく動いているし、ヨシっとしてしまいました。

### DatePickerの動作と起きた問題
DatePickerを開いた直後、翌日の日付がCurrentになるDatePickerです。

もうお分かりですね。
このDatePickerは月の最終日に開くと、翌月のカレンダーが表示されます。
従って、`Today`という値が含まれた属性は存在しないためテストが失敗します。

`もし翌日の日付が1日なら、前月を選択する`という処理を追加することで事なきを得ました。

ということで小ネタでした。
JavaのJDK内部APIへのリフレクティブなアクセスについての変遷

# はじめに
Javaのリフレクションは強力な機能の1つだと思います。
しかし、強力であるが故に使い方を誤ると想定しない問題を発生させてしまう可能性もあると想像します。
特にJDK内部APIというコア機能に対する操作はより影響が大きいと言えるでしょう。
その様な背景も有るのか、バージョンアップに伴ってその利用について調整が発生しています。
今回はそれらを時系列的に見てみました。

# JDK8以前
特に制限等は見付けられませんでした。

# JDK11
```
WARNING: An illegal reflective access operation has occurred
```
このバージョンから危険性が認識される様に、警告が出力される様になっている様です。
しかし、未だ警告の段階で有り、--illegal-access パラメータで警告や許可、不許可を設定可能です。

<dl>
    <dt>illegal-access 設定例</dt>
        <dd>warn   : 警告の出力</dd>
        <dd>permit : リフレクティブなアクセスの許可</dd>
        <dd>deny   : リフレクティブなアクセスの拒否</dd>
</dl>

# JDK16
デフォルトのillegal-accessがdenyになっています。
しかし、未だillegal-accessをpermitへと設定する事で、利用する事が可能な状態は残されています。


# JDK17以降
前バージョン迄選択出来ていたillegal-accessのpermitが設定不可となりました。
従って、このバージョンからJDK内部APIへのリフレクティブなアクセスを行う手段は無くなった、
と捉えました。

# おわりに
個人的には、バージョン間の差異に着目する事は多くても、1つの機能や利用方法について複数バージョンを追いかけてみる事は無かったので、改めて見ると新鮮でした。

私個人が想定していたより、完全に選択肢を閉じる迄に、警告、オプションによる選択、と
ユーザに対して移行の期間を設けてくれているのだな、と感じました。
Pythonで「引数にデフォルト値を設定する」の動作を確認してみた

# 概要

Pythonで「引数にデフォルト値を設定する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/python/userfunc/index5.html

# 実装

以下のファイルを作成しました。
```sample.py
def myfunc(num1 = 10, str1 = "未入力", str2 = "不明"):
    print("年齢は" + str(num1) + "です。", end='')
    print("名前は" + str1 + "です。", end='')
    print("住所は" + str2 + "です。")

myfunc(28, "Suzuki", "Tokyo")
myfunc(25, "Yamada")
myfunc(30)
myfunc()

def myfunc(str1, list1 = None):
    if list1 is None:
        list1 = ["a"]
    list1.append(str1)
    return list1

print(myfunc("b"))
print(myfunc("c"))
print(myfunc("d"))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
年齢は28です。名前はSuzukiです。住所はTokyoです。
年齢は25です。名前はYamadaです。住所は不明です。
年齢は30です。名前は未入力です。住所は不明です。
年齢は10です。名前は未入力です。住所は不明です。
['a', 'b']
['a', 'c']
['a', 'd']
```

# まとめ

何かの役に立てばと。
wrap-reverseを活用してサイト作成をしてみたら便利すぎた！

## はじめに
サイト作成でのPC・SPで表示切り替えするのにできるだけコードを減らしたいなと思ってたこの頃。
`wrap-reverse`という便利なものに出会いました。もっと早く知っていれば、、！！

## 実際に使用した内容
以下のようにPC・SPで画像、文字の位置が異なる時に使用しました。
![スクリーンショット 2024-02-27 20.05.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524155/697aaf67-0d58-9ad8-ea72-e3b885a7a667.png)

## 以前のやり方
PCとSPで画像とテキストの位置が変わる時に初め以下のようにしていちいち`display: none;`　`display: block;`を使って表示切り替えをしていました。

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

## `wrap-reverse`を使用したやり方
コードも少ないし、メディアクエリを利用しなくても自動で画像・文字の位置を入れ替えてくれます。
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="QWPLyvQ" data-user="lgexfaug-the-sasster" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/lgexfaug-the-sasster/pen/QWPLyvQ">
  wrap-reverse_test</a> by 藤野美優 (<a href="https://codepen.io/lgexfaug-the-sasster">@lgexfaug-the-sasster</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## `wrap-reverse`とは
親要素から子要素であるflexアイテムがはみ出てしまった時、自動的に改行をして表示させることが出来ます。
### `wrap-reverse`で使用できる値
| 属性 | 内容 　　　　　　　| 
|:----|--------:|
| nowrap|flexアイテムを折り返さない（デフォルト）| 
| wrap|flexアイテムを折り返す（左から右）| 
| wrap-reverse|flexアイテムを折り返す（右から左）|
Rails7 でbootstrapを使ってModalを動かす 

## 環境
* Rails 7.1.3
* ruby 3.2.1
* bootstrap 5.3.2

## 目的
**railsでbootstrapを動かす**

Rails tutorialを終えて、その他にもハンズオン形式のサイトに取り組んでいたらbootstrapを使ったモーダルなどが動作しない･･･
ということでとりあえず動くようになるまで調べた結果を書いていきます。

※間違えていたらマジで色々教えてください

>参考サイト
https://nobrainerprogramming.com/rails-7-modal-forms-with-hotwire-and-bootstrap/

## 新しいプロジェクトを作る
まずはコマンド
```
rails new modal
```
Gemfileに必要なgemを書く

```ruby:Gemfile
gem 'bootstrap' 
gem 'mini_racer'
gem 'sassc-rails'
```

:::note warn
sassc-railsは古いらしい
darts-scssというのがrails7では推奨みたいなので、調べて理解したら記事作るかも
:::

gemをインストールする
```
bundle install
```
ファイルの名前を変更する

app/assets/stylesheets/application.css
↓　変更後
app/assets/stylesheets/application.scss

※.cssが.scssになってます

## ★bootstrapのデザインを使えるようにする(css)
そのファイルの中に書く
``` application.scss
@import "bootstrap";  
```
これでbootstrapのデザインが使えます
試しにどこかアクセスして表示が確かめれるViewファイルに書いてみます

```
<h1 class="text-info">bootstrap</h1>
```
無事色が変わればOK！

## ★ bootstrapのモーダルなど動くようにする(js)
あまり詳しくないのですが、モダールとか他のなんやかんやはbootstrap.js的ななんかjavascript使うやつもあるみたいなんでそれ動くようにします

rails7標準のimportmapを使います
```
bin/importmap pin bootstrap
```
これを入力するとこれらが追加されます
```
pin "bootstrap"
pin "@popperjs/core", to: "@popperjs--core.js"
```
そして追記
```application.js
import "@popperjs/core"
import "bootstrap"
```

:::note 
5.3らへんは、なんかクロームのデベロッパーツールみたらめっちゃエラー出るからpopperが原因みたいなので、こうしないといけないという記事を発見
:::

>参考URL：
https://bootstrap-guide.com/getting-started/javascript

参考記事から抜粋
``` text:公式からの抜粋
"imports": {
        "@popperjs/core": "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/esm/popper.min.js",
        "bootstrap": "https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.esm.min.js"
}
```

結論:要はこうすればいいのか...
``` importmap.rb
pin "@popperjs/core", to: "https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.8/dist/esm/popper.min.js"
```
これでモーダルなどが動くのでWeb上に転がってるハンズオンサイトも進めれました！

popperってなんやねん････


****
初めての記事を書いてみました。
自分で見直す為と、自分が躓いた部分で誰か参考になればという想いで書いてみました。
mysql2::error::connectionError: Access denied for user 'root@localhost'(using password no)

# エラー
```
ActiveRecord::DatabaseConnectionError
There are an issue connecting to database with your username/password,username: root
Please check your database configuration to ensure the username/password are valid.
```

ユーザー名/パスワードでのデータベース接続に問題があります、
ユーザー名: root
ユーザー名/パスワードが有効かどうか、データベース設定を確認してください。

### 出典
deepL

### 気づき
username,passwordが関係してdatabaseに接続できていないらしい。
username,passwordに関係していることと言えばログインかな。
とりあえずログインしてみよう。

ログインしたがエラーが治らない。

# スクロール先にエラーがあった。
```
mysql2::error::connectionError: Access denied for user 'root@localhost'(using password no)
```
新規インストールの後、パスワードを使用せずに root としてサーバーにログオンしようとすると、次のエラーメッセージが表示されることがあります。
```
shell> mysql -u root
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
```
これは、インストール時に root パスワードがすでに割り当てられており、指定する必要があることを意味します。 パスワードが割り当てられている様々な方法、およびパスワードの検索方法については、セクション2.10.4「初期 MySQL アカウントの保護」 を参照してください。 root パスワードをリセットする必要がある場合は、セクションB.3.3.2「root のパスワードをリセットする方法」 の手順を参照してください。 パスワードを検出またはリセットした後、--password (または -p) オプションを使用して root として再度ログオンします:

### 出典
https://dev.mysql.com/doc/refman/8.0/ja/problems-connecting.html#:~:text=%E6%96%B0%E8%A6%8F%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%AE,%E3%82%AA%E3%83%B3%E3%81%97%E3%81%BE%E3%81%99%3A

### 気づき
既にパスワードを割り当てられてあるからエラーが出ている。
どうすればいいのか？
接続するためのファイルを見てみるか。

# config/database.ymlを見てみる。
```
...
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:　入力してなかった。　　<---パスワードを入れる
  socket: /var/lib/mysql/mysql.sock

```
これだから接続できなかったのではないか？

# 結果
エラーが変わった。
このファイルがログインしてくれるのか。
多分成功したのだろう。
WPF初心者によるMVVM備忘録

# MVVMとは

ユーザインターフェースを持つソフトウェアの開発において
M(モデル)
V(ビュー)
VM(ビューモデル)
といったように異なる役割の三つの層に分けて設計する手法のことです。

まずそれぞれの層の役割を上げます。

- M (Model)
概念やデータをプログラムに落とし込んだもののことです。食べ物のことについてのプログラムを書くときは食べ物クラスがこれにあたります。

- V (View)
表示される画面のことです。

- VM (ViewModel)
モデルとビューを紐づけるものです。モデルから得たデータを画面表示したときに意味を成すものとするために適宜そのデータを加工します。イベント処理もVMに任せます。

MVVMの場合モデルとビュー直接やり取りをしません。



簡単なコード例を以下に示します。(面白味はありませんがモデルで定義したデータをビューに表示するものです。)

Model.cs

```
namespace MVVM
{
    public class Food
    {
        public string Name { get; set; }
        public int Price { get; set; }
    }
}
```

MainView.xaml
```
<Window x:Class="MVVM.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MVVM"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Window.DataContext>
        <local:ViewModel />
    </Window.DataContext>

    <Grid>
        <ListBox ItemsSource="{Binding Foods}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <TextBlock Text="{Binding Name}" />
                        <TextBlock Text="{Binding Price}" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>
```


ViewModel.cs

```
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace MVVM
{
    public class ViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<Food> foods;

        public ObservableCollection<Food> Foods
        {
            get { return foods; }
            set
            {
                if (foods != value)
                {
                    foods = value;
                    OnPropertyChanged(nameof(Foods));
                }
            }
        }

        public ViewModel()
        {
            Foods = new ObservableCollection<Food>
            {
                new Food { Name = "たこやき", Price = 500 },
                new Food { Name = "お好み焼き", Price = 700 },
            };
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
```
ViewModelではINotifyPropertyChangedインターフェースを実装することなどデータバインディングのための仕組みが必要になります。そうすることでそれぞれの変更を通知することが可能になります。


#### メリット
役割をしっかり分けて実装するためプログラムの拡張がしやすい

#### デメリット
適切にバインドする必要があるため、データバインディングについての知識が必要



## おわりに
WPFを学び始めはいろんなものをコードビハインドに記述してメンテナンスが大変でしたが、MVVMというものを知り、それぞれに役割を分けて実装することでメンテナンスが非常にしやすくなりました(コードビハインドには初期コードしかない状態に、すっきり...!)。ただ実現できるのではなくパターンに基づいた実装をすることは保守性の面でも、人に伝わりやすさでも非常に重要になってきますね。より理解を深めて適切な実装を行えるよう精進していきたいと思います！
Swiftにおけるジェネリクスの理解: コード例付きの包括的なガイド

**ジェネリクスの導入**

Swiftでは、ジェネリクスが柔軟で再利用可能な関数、構造体、およびクラスの作成に重要な役割を果たします。ジェネリクスを使用することで、どの型でも動作する柔軟で再利用可能なコードを記述でき、関数やデータ構造をタイプに依存しないようにすることができます。

**ジェネリクスを使う理由**

ジェネリクスにはいくつかの利点があります：

1. **再利用性:** ジェネリクスを使用すると、どの型でも動作する柔軟で再利用可能なコードを記述できます。
2. **型安全性:** ジェネリクスは、コンパイル時に型エラーをキャッチし、型の安全性を確保し、ランタイムエラーを防ぎます。
3. **コードの明瞭化:** ジェネリクスは、実装の詳細を抽象化し、機能に焦点を当てることで、コードの明瞭さを向上させます。

**Swiftにおけるジェネリクスの構文**

Swiftでは、ジェネリクスは型パラメーターとして知られるプレースホルダーを使用して表されます。これらのプレースホルダーは任意の型を表し、角かっこ (`<>`) 内で指定されます。次の単純な例を見てみましょう：

```swift
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
    let temporaryA = a
    a = b
    b = temporaryA
}

var x = 10
var y = 20
swapTwoValues(&x, &y)
print("x =", x, "y =", y) // 出力: x = 20 y = 10
```
この例では、`<T>` が型パラメーターを示しています。 swapTwoValues 関数は、任意の型 `T`の2つの値を交換できます。

**関数とジェネリクスの使用**

ジェネリクスは、異なる型で動作する再利用可能なコードを作成するために関数と共に使用できます。配列内の最大要素を見つけるためのジェネリック関数を作成してみましょう：

```swift
func findMax<T: Comparable>(_ array: [T]) -> T? {
    guard var maxElement = array.first else { return nil }
    for element in array {
        if element > maxElement {
            maxElement = element
        }
    }
    return maxElement
}

let numbers = [4, 2, 9, 6, 5]
if let maxNumber = findMax(numbers) {
    print("最大の数字:", maxNumber) // 出力: 最大の数字: 9
}
```
この例では、`<T: Comparable>` が型パラメーター `T` を `Comparable` プロトコルに準拠する型に制限し、要素の比較を可能にしています。

**データ構造とジェネリクスの使用**

ジェネリクスは、クラスや構造体などのデータ構造でも使用できます。ジェネリックなスタックデータ構造を作成してみましょう：
```swift
struct Stack<Element> {
    private var elements = [Element]()
    
    mutating func push(_ element: Element) {
        elements.append(element)
    }
    
    mutating func pop() -> Element? {
        return elements.popLast()
    }
    
    func peek() -> Element? {
        return elements.last
    }
    
    func isEmpty() -> Bool {
        return elements.isEmpty
    }
}

var stack = Stack<Int>()
stack.push(1)
stack.push(2)
stack.push(3)
print("トップの要素:", stack.peek() ?? "スタックは空です") // 出力: トップの要素: 3
```
ここでは、`Element` はスタックに格納される要素の型を表す型パラメーターです。これにより、任意の型のスタックを作成できます。

**結論**

Swiftにおけるジェネリクスは、どの型でも動作する柔軟で再利用可能なコードを記述するための強力な手段を提供します。ジェネリクスを活用することで、コードの再利用性、型安全性、明瞭さを向上させることができます。関数、データ構造、クラスなど、ジェネリクスを使用することで、さまざまな型に対応する堅牢で効率的なコードを簡単に記述できます。Swiftプロジェクトでジェネリクスを活用して、より表現豊かで保守性の高いコードを書いてみましょう。
XcodeにおけるCrashlyticsのトラブルシューティング: 読みやすいクラッシュレポートの確保

## はじめに

クラッシュレポートの理解は開発者にとって重要であり、Firebase Crashlyticsはこのプロセスを簡素化する強力なツールです。デフォルトでは、Crashlyticsはデバッグシンボル（dSYM）ファイルを自動的に処理し、非表示になっているクラッシュレポートを提供します。しかし、自動的にアップロードされるdSYMファイルが原因で、クラッシュレポートが不完全になったり、失われたりすることがあります。このガイドでは、Crashlyticsダッシュボードで読み取り可能なクラッシュレポートを確保するためのトラブルシューティング手順を探ります。

## 自動的なdSYM処理の概要

アプリ内でCrashlyticsを設定すると、dSYMを自動的に処理し、ファイルをアップロードするための実行スクリプトが構成されます。このセクションでは、Xcode 15からの新しい要件を特に考慮しながら、設定が最新であることを確認する方法について説明します。

1. Build Phasesタブをクリックし、Run Scriptセクションを展開します。
2. 「Input Files」セクションで、以下のファイルのパスが指定されていることを確認します:
- `${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}`
- `${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${PRODUCT_NAME}`
 - `${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist`
 - `$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)`
 - `$(TARGET_BUILD_DIR)/$(UNLOCALIZED_RESOURCES_FOLDER_PATH)/GoogleService-Info.plist`.

このステップにより、Xcodeが必要な入力ファイルを指定された場所から参照するようになり、CrashlyticsがdSYMを正しく処理できるようになります。

## XcodeによるdSYMの生成の確認

dSYMファイルが欠落する一般的な原因は、Xcodeによるファイルの生成が行われていないことです。ここでは、Xcodeが正しいdSYMをすべてのビルドに対して生成していることを確認します。

1. Xcodeでプロジェクトを開き、Xcodeナビゲーターでプロジェクトファイルを選択します。
2. メインビルドターゲットを選択します。
3. ターゲットの __Build Settings__ タブを開き、 __All__ をクリックします。
4. `debug information format` を検索します。
5. すべてのビルドタイプに対して __Debug Information Format__ を __DWARF with dSYM File__ に設定します。
6. アプリを再ビルドします。

これらの手順に従うことで、Xcodeが必要なdSYMファイルを生成することが確認され、Crashlyticsでのクラッシュレポートが欠落する可能性のある問題が解決されます。

## 結論

Crashlyticsでのトラブルシューティングとクラッシュレポートを正しく読み取るためには、設定の確認とXcodeによる必要なdSYMファイルの生成を確かめることが重要です。これらの手順に従うことで、Firebase Crashlyticsダッシュボードで欠落または不完全なクラッシュレポートに関連する問題を解決する準備が整います。ハッピーコーディング！
OpenVPNのca証明書更新

## はじめに
OpenVPNでVPNサーバを構築されている環境の方は、easy-rsaで作成した自己証明のca証明書の期限が切れるころ(3650日：約10年)ではないでしょうか。
で、いろいろと記事を検索しても、この「ca証明書の期限の更新」の記事があまり見当たらなかったので(あっても、「結局再構築しました」みたいな記事が多い)、自身への覚書も含め記述しておきます。
### 前提条件
1．OpenVPNでVPNサーバを構築している環境(かつ当方の環境はWindowsサーバ)
2．自己証明のca証明書+サーバ証明書+クライアント証明書でのVPN構築をされている環境(いわゆるeasy-rsaのスクリプトやバッチファイルで生成されたca証明書を用いている場合)

証明書名は以下としてコマンドを記述しています。

ca証明書　ca.crt
ca鍵　　　ca.key
サーバ証明書　server.crt
サーバ鍵　server.key

※クライアント証明書の更新についても特に触れません。

### 実施事項

#### ca証明書
~~~
openssl x509 -in ca.crt -days 3650 -out \_temp\ca.crt -signkey ca.key
~~~

これだけです。
Opensslコマンドでca.crtを読み込んで、任意の日数(上記は10年にしていますが任意の値で大丈夫です)の期間を設定し、出力先フォルダは別の一時フォルダにして、同名のca証明書を生成します。

上記のca.crtを、元のca.crtと差し替えて、問題なく認証が成功することを確認してください。
(むろんopenssl verifyコマンド使って認証チェックも必要ですが、最終的にはクライアントがつながるかどうかなので)

#### サーバ証明書
easy-rsaのデフォルトのスクリプト(当方環境ではバッチファイル)を流用して作成します。

OpenVPNとeasy-rsaで構築された場合、たいていの場合はca証明書とサーバ証明書の期間が同じになっているかと思いますので、ca証明書だけでなくサーバ証明書についても更新する必要があります。

通常easy-rsaで構築している場合、
build-key-server.bat
というバッチファイルがeasy-rsaフォルダ内にあるはずなので、これを利用する。

ただしそのまま実行してしまうとkeyからの作り直しになってしまうので、期限だけ延長するため、バッチファイルを以下のように編集します。
~~~
@echo off
cd %HOME%
rem build a request for a cert that will be valid for ten years
openssl req -days 3650 -nodes -new -keyout %KEY_DIR%\%1.key -out %KEY_DIR%\%1.csr -config %KEY_CONFIG%
rem sign the cert request with our ca, creating a cert/key pair
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -extensions server -config %KEY_CONFIG%
rem delete any .old files created in this process, to avoid future file creation errors
del /q %KEY_DIR%\*.old
~~~
を
~~~
@echo off
cd %HOME%
openssl ca -days 3650 -out %KEY_DIR%\%1.crt -in %KEY_DIR%\%1.csr -extensions server -config %KEY_CONFIG%
rem delete any .old files created in this process, to avoid future file creation errors
del /q %KEY_DIR%\*.old
~~~
に変更して、ファイル名も「build-crt-server.bat」に変更して保存します。
何のことはない、前半のKeyとcsrファイル作成部分を削除して、既存のkeyとcsrを用いて証明書を発行しているだけです。
vars.batで環境変数等設定しているはずなので、実行してから上記「build-crt-server.bat」を実行すれば、サーバ証明書の期限も更新できます。

### おわりに
今回は完全に覚書なので、そのうち環境設定、構築、サーバ証明書、クライアント証明書の発行からca証明書、サーバ証明書の期限更新、平時のクライアントの期限更新など運用も絡めた環境構築について書ければいいなと思ったり思わなかったり。

以上、
[Python] Django+Gunicorn+NginxのDockerCompose環境

# はじめに
Djangoのローカル開発環境の簡易テンプレートを作成しました。
目的は、Pythonフレームワークに触ってみたいのと、Djangoの開発環境を知りたかったためです。

あくまで開発環境なので、Djangoのビルトインサーバーであるrunserverで事足りるかもしれませんが、実環境に寄せる目的でnginxとgunicornも用意することにしました。

https://docs.djangoproject.com/ja/5.0/ref/django-admin/#django-admin-runserver

以下は、Djangoのrunserver機能に関する記述です。
>このサーバーを実稼働環境で使用しないでください。セキュリティ監査やパフォーマンス テストは受けていません。(そして、それが今後も続くでしょう。私たちは Web サーバーではなく Web フレームワークを作成する仕事をしているので、運用環境を処理できるようにこのサーバーを改善することは Django の範囲外です。)

# 前提環境

https://qiita.com/perilla/items/ef73cf57ade24bc94f19


https://qiita.com/perilla/items/c9190163ea8a7051737a

# Docker Compose 構成

Docker Composeの構成を記述します。

## サービス一覧

- app
- web
- db_pgsql

### app

Djangoとgunicornを使用したアプリケーションサーバー。
gunicornが8000ポートを使用し、nginxからの中継に応答します。

### web

[nginx](https://hub.docker.com/_/nginx)サーバー。
HTTPリクエストをappコンテナへとフォワード（中継）します。

### db_pgsql

[PostgreSQL](https://hub.docker.com/_/postgres)サーバー。

# Github

https://github.com/perilla0/django_template
vite+react+testing-libraryでのコンポーネントテストの環境構築方法

## はじめに

vite+react+testing-libraryで、コンポーネントテストの環境構築の方法をご紹介します。

## 環境

nodeのバージョンです。

```shell
node -v
v20.11.0
```

モジュールは以下のバージョンで確認しています。

```shell
"@testing-library/react": "^14.2.1",
"vitest": "^1.3.1"
```

## 環境構築

viteの最新版でプロジェクトを生成します。

```shell
npm init vite@latest
```

設定は以下の通りです。

```shell
✔ Project name: … vite-project
✔ Select a framework: › React
✔ Select a variant: › TypeScript
```

作業ディレクトリを移動して、モジュールをインストールします。

```shell
cd vite-project
npm install
```

テストで必要なモジュールをインストールします。

```shell
npm install --save-dev vitest jsdom @testing-library/react
```

`package.json`ファイルの`scripts`に以下を追加します。

```json:package.json
"test": "vitest"
```

`vite.config.ts`ファイルを以下に変更します。

```typescript
+/// <reference types="vitest" />
 import { defineConfig } from 'vite'
 import react from '@vitejs/plugin-react'

 // https://vitejs.dev/config/
 export default defineConfig({
   plugins: [react()],
+  test: {
+    environment: 'jsdom'
+  }
 })
```

`src/App.test.tsx`ファイルを作成して、以下コードを追加します。

`screen.debug();`で描画するHTMLを出力します。

```typescript:src/App.test.tsx
import { describe, it }from 'vitest'
import { render, screen } from '@testing-library/react'
import App from './App'

describe('App', () => {
  it('sample test', () => {
    render(<App />)

    screen.debug();
  })
})
```

テストを実行します。

```shell
npm run test
```

以下のように出力されれば成功です。🎉

```shell
 ✓ src/App.test.tsx (1)
   ✓ App (1)
     ✓ sample test

 Test Files  1 passed (1)
      Tests  1 passed (1)
   Start at  22:00:57
   Duration  341ms (transform 22ms, setup 0ms, collect 79ms, tests 17ms, environment 143ms, prepare 31ms)
```

## まとめ

vite+react+testing-libraryで、コンポーネントテストの環境構築の方法をご紹介しました。今回はやりませんでしたが、ユーザーイベント（クリックなど）を発火するには[こちら](https://testing-library.com/docs/user-event/install)のインストールが必要です。気になる方は試してみてください。


## 最後に

### GoQSystemでは一緒に働いてくれる仲間を募集中です！

ご興味がある方は以下リンクよりご確認ください。

https://goqsystem.recruit.site?qiita=a415d56ad64805f59039
MacでもPower Shellのススメ

## 起こったこと
担当プロダクトの本番データをマスクするツールの開発が必要になりました。
なお、私はモバイルエンジニアでiOSのビルドを行うため、使用するPCはMacです。
本番環境は特定のPCからのみ接続可能で、取得したデータはマスクした状態で転送しなければいけません。

本番環境に接続できるPCはWindowsです。

つまり、**Macで開発できて、Windowsで起動できる** 必要がありました。

また、本番データはXMLやJSON形式で保持しているため、
そういったデータフォーマットを処理できる必要がありました。

まずは、採用技術の検討...

- batファイル...Macで開発できるのか？そもそも使いたくない。
- shell...WSLなら実行できる？でも、XMLやJSONの処理は大変そう
- Electron...XML、JSONを扱える。環境も問わなそう
- PowerShell...Macでも使えるし、Shell Scriptの知識を活かせる

このあたりを検討して、今回は軽量で使いたいこと、ShellScriptの知識を応用できることで
**PowerShell**を採用することにしました！

## やったこと、分かったこと

ツールとしては、PowerShellでXML or JSONを読み込み、特定の項目を「*」で潰す（マスクする）ものです。

以下は、PowerShellを使ってみて、分かったことを備忘録的にまとめています。

### XMLをオブジェクトとして読み込める

```powershell
$xmldoc = [xml]::new()
$xmldoc.Load($targetFilePath)
````
色々やり方を調べましたが、この方法が一番よさそうでした。

参照: https://qiita.com/mueru/items/c84408f82550d4e8cb2f

読み込んだ後は、こんな感じで参照、編集できます。

```powershell
# 名前のmask
$xmldoc.Body.PersonalInfo.Name = "** **"
```

繰り返しや条件分岐もできます。

```powershell
# 住所のマスク（都道府県、詳細、マンションに分かれていて、詳細とマンションはマスクする）
$ref = $xmldoc.Body.PersonalInfo.Address
foreach ($address in $ref) {
    if ($address.detail  -ne $null) {
        $address.detail = "*"
    }
    if ($address.mansion  -ne $null) {
        $address.mansion = "*"
    }
}
```

### JSONもオブジェクトとして読み込める

```powershell
$obj = Get-Content $targetFilePath -Raw | ConvertFrom-Json -AsHashtable
```
こちらは、読み込んだ後に、JSONに変換→さらにHashTableへの変換を行い、
コード上でオブジェクトのように扱えるようにしています。

こちらもXML読み込みと同じようにオブジェクトの参照、繰り返し処理、条件分岐を使用できました。

### デバッグできる

[デバッガーについて](https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_debuggers?view=powershell-7.4)

今回、一番驚いたのは、こちらです。
公式ページにある通り、IDEと比較しても見劣らないほどにデバッガーは充実していました。
少なくとも、Shell開発していた時のprintログをほとんど挟まなくて良かったのが助かりました。

また、シェルスクリプトではなく、コマンドラインからでもXMLの読み込みなどを行い、
値の確認ができることはかなり良かったです（気軽に動作確認やデータの確認ができる）

```shell
my@mac ~ % pwsh
PowerShell 7.4.1
PS /Users/my> $xmldoc = [xml]::new()
PS /Users/my> $xmldoc.Load("./my.xml")
PS /Users/my> $xmldoc.Body.PersonalInfo.Name
テスト太郎
```

上記では伝わりにくいですが、「.」を入力すると、使用できるプロパティやメソッドをサジェストしてくれます。

### ファイルの出力（作成）

マスクしたデータを最後、マスク後の状態でファイル出力しました。

xml
```powershell
$maskedFilePath=$targetFilePath.replace(".xml", "_masked.xml")
$xmldoc.Save($maskedFilePath)
```

json
```powershell
ConvertTo-Json $obj -Depth 100 | Out-File "./my_masked.json" -Encoding utf8
```

json の方はDepthを指定しないと、途中の階層がない状態で出力されるのは罠でした..

### 不満、気になった点

- HashTableを使えるが、参照渡しはやりにくかった

HashTableに直接マスクした状態を保持したかったのですが、
Power Shellの参照渡しの制約が参照渡しするオブジェクトそのものを参照渡しする必要があり、
HashTableで使うのは難しかったです。
（説明が難しい）

- 関数も作れるが、個人的には使いにくかった

関数を作って、処理の構造化・DRYの実現もできるのですが、
スクリプト言語らしく、関数を上に宣言しないといけないことや参照渡しを使いにくいことで、
関数の使用や長い処理を書くには向いていないな...という気持ちになりました。

## まとめ

無事、PowerShellをMacで作って、Windowsで実行できました。
今回、初めてPowerShellを使いましたが、非常に機能が豊富で今後ちょっと複雑だけど、
シェルでできるんじゃないか？という処理をするにはPowerShellを使おうと思います！
ClassicASP開発クライアント証明書の情報を取得

ClassicASP初心者です。
ClassicASPの環境でクライアント証明書の情報を取得する方法を調べて実装したことについて、備忘として書きたいと思います。

# 目次
　[参考](#参考)
　[背景](#背景)
　[サンプル](#サンプル)
　[まとめ](#まとめ)

### 参考
#### HttpRequest.ClientCertificate プロパティ

https://learn.microsoft.com/ja-jp/dotnet/api/system.web.httprequest.clientcertificate?view=netframework-4.8.1

### 背景
IDとパスワードを入力する認証から、クライアント証明書を使った認証へ改修する環境でどうやって、クライアント証明書の情報を取得するかが知りませんでした。
調べてみると、参考のリンクにあるHttpRequest.ClientCertificateから情報を取得できるとのことでした。
クライアント証明書にある特定の文字列を抜き出しユーザーを判別する機能をClassicASPで開発しました。

### サンプル
クライアント証明書の特定の文字列を抜き出すサンプルコード
例えば、開始文字列「START」から終了文字列「END」までの証明書にある情報を抜き出すとして開発しています。

```VB:sample.asp
<%
Dim strTarget
Dim strStartSearch
Dim strEndSearch
Dim intStartIndex
Dim intEndIndex
Dim strClientCert
Dim clientCert
strStartSearch = "START"
strEndSearch = "END"
clientCert = Request.ClientCertificate
'クライアント証明書を取得できているか
If Len(clientCert) > 0 Then
    ' 証明書を文字列として認識するように修正
    strClientCert = clientCert + ""
    ' 開始位置を検索する
    intStartIndex = InStr(strClientCert, strStartSearch) + Len(strStartSearch)
    ' 終了位置を検索する
    intEndIndex = InStr(strClientCert, strEndSearch)
    ' 特定の文字列を抜き出す
    strTarget = Mid(strClientCert, intStartIndex, intEndIndex - intStartIndex)
End If
' 出力
Response.Write strTarget
%>
```

### まとめ
新しく開発する言語は、変数宣言や、関数の使い方を調べながら進めていくことになり、時間がかかりますが、
後で見返したときに何がしたかったのかを思い返せるようにコメントしながら引き続き開発を進めたいと思いました。
JSTQB Foundation Level合格体験記

# はじめに

みなさんこんにちは！
はつかぜ株式会社サポート室のSと申します。
本日はJSTQB試験の最も基礎的なFoundation Levelに合格したので、その体験記を書きたいと思います。

# JSTQBとは

JSTQB（Japan Software Testing Qualifications Board）はソフトウェアテストの技術力をはかるペーパーテストです。試験の形式は選択式で、60分で40問の問題を解かなくてはいけません。合格基準は65%です。受験料が22,000円（税込）と高額なので、なるべく1回で受かりたいですね。（私は1回落ちました泣）

# 使った参考書と勉強法
【使った参考書】

①Foundation Levelシラバス
→試験範囲はここから出題されるものが全てなので極論これを全部暗記したら受かると思います。

②JSTQB Foundation 第4版: ソフトウェアテスト教科書 シラバス2018対応 
→マイナー寄りの資格なので参考書はこれしか知りませんでした。内容は普通に良いと思います。

③テス友【JSTQB, JCSQE, IVEC】完全攻略
→JSTQBの問題を解けるアプリ。答えを覚えるくらい何周もすると効果的だと思います。

【勉強法】
上記①~③をひたすら何周もしました。試験範囲が狭いので、ヤマを張るより全部の項目を完璧にすることを目指しました。抽象的な概念や専門用語が多いので、わかりにくい箇所は単語レベルで細かく調べて理解するようにしました。

# 受験した時のこと
1回目の試験は単純に勉強不足で落とされたと思います。受験した後の感覚もいまいちでした。2回目の試験時は気合い入れて50~100時間くらい勉強してから臨みました。緊張しましたが解いてる時はそんなに難しく感じなかったので、単純な勉強量が結果に直結する試験だと思います。試験時間も足りなくなることはほぼないと思います。


# 実務面
ソフトウェアテストの必要性や実施方法を体系的に学習したことにより、実際にテストをする時に「自分が何を何のためにやっているか」が明瞭になったことがよかったと思います。
主観になりますが、テストエンジニアでなくても、学習する価値の高い資格だと感じました。


# 最後に
はつかぜ株式会社では、JSTQB以外にも基本情報技術者試験やAWS認定資格などの取得サポートを社員に対して積極的に行っています。

はつかぜ株式会社では、IT学習や業務に役立つ情報を定期的にお届けしていきたいと思っています。
システム開発のお問い合わせ・ご相談はこちら https://www.hatsukaze.co.jp/inquire/
Webで利用可能な英語の発音記号データのまとめ

英語アプリmikanや、学校・塾向けのサービスであるmikan for Schoolを運営する株式会社mikanの鈴木です。

業務のなかで発音記号データを取り扱う必要があり、調べてみるとなかなかまとまった情報がなさそうだったのでまとめてみました。

# 発音記号とは

まずは前提となる発音記号そのものの情報を簡単にまとめます。
最も一般的な発音記号は **IPA**（**International Phonetic Alphabet**, 国際音声記号）と呼ばれるもので、様々な辞書で使われています。

**しかし、実際に辞書を見てみると、それぞれで異なる発音記号が使われています。**

### subjectの発音記号の比較

**研究社 新英和中辞典（Weblio）**
```
sˈʌbdʒɪkt
```

**小学館 プログレッシブ英和中辞典（goo辞書）**
```
sʌ́bdʒikt
```

**英辞郎**
```
sʌ́bdʒikt
```

**Cambridge Dictionary**
```
ˈsʌb.dʒekt
```

**Oxford Advanced Learner's Dictionary**
```
ˈsʌbdʒɪkt
```

これは、IPAは発音の音素を忠実に表しているため正確ではあるものの、一般の学習者にとっては難しいからだと思われます。
そのため、各辞書はオリジナルでIPAをベースにした発音記号の記法を使っているようです。
発音記号を扱う際は、この点に注意が必要です。

**様々な辞書サイトから発音記号をかき集めてきたりしてしまうと、微妙に記法が異なる発音記号がまざってしまうと考え、発音記号データがまとまった1つのデータソースを探すに至りました。**

# Webで利用可能な英語の発音記号データ

さて、本題のWebで利用可能な英語の発音記号データをご紹介していきます。

## 1. CMU Pronouncing Dictionary
これがWeb上で無料で手に入る最も信頼の置けるデータだと思います。
カーネギーメロン大学がパブリックドメインで提供している発音辞書です。

データも、プレーンテキスト形式で配布されており、扱いやすいです。
各行には一つの単語とその発音が記載されており、単語と発音は通常スペースや特定の区切り文字で分離されています

ただし、この発音記号はIPAでなく、ARPAbetという形式で書かれているので、IPAにするには変換が必要です。
ARPAbet to IPA はライブラリがありそうでした。

↓実際のデータ（apple, orange, pineapple）
```
APPLE  AE1 P AH0 L
ORANGE  AO1 R AH0 N JH
PINEAPPLE  P AY1 N AE2 P AH0 L
```

公式リンク
http://www.speech.cs.cmu.edu/cgi-bin/cmudict

## 2. Wiktionary

Wiktionaryは、ウィキメディア財団が運営するプロジェクトの一つで、誰でも自由に編集できる多言語オンライン辞書です。Wikipediaの辞書版ですね。
誰でも編集ができるので信頼性は他よりも劣りますが、発音記号以外にも情報量が多いです。
Creative Commons（CC BY-SA 4.0 DEED）で提供されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563719/2f40605a-6e00-ef39-e94e-dc95a9a7ad23.png)

また、データも、XMLデータが提供されています。ウィキメディア財団は、Wiktionaryを含むすべてのプロジェクトのデータベースダンプを定期的に公開しており、これを通じてプロジェクトのコンテンツ全体をダウンロードできます。

ただし、このXMLデータは発音記号以外の辞書データもたくさん入っているので、発音記号だけを取り出すのは一苦労がありそうです。

ダウンロードリンク
https://dumps.wikimedia.org/jawiktionary/latest/

## 3. WordsAPI

WordsAPIは単語に関する様々な情報を提供するRESTful APIです。発音記号の他にも、その単語の定義や同義語、反意語、品詞、例文などをAPI経由で得ることができます。

Playgroundもあるので、どのようなデータが返ってくるのかもわかりやすいです。
発音記号は、`pronunciation` の部分に入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563719/d785b758-81af-577d-555e-ef724e3d6d05.png)


また、$629にて、全てのデータが入ったJSONデータを購入することもできます。

公式リンク
https://www.wordsapi.com/

以上です。
参考になれば幸いです。

# 株式会社mikanは積極採用中！

株式会社mikanは多方面の職種で積極的に採用活動を行っております！
興味をもっていただいた方はぜひ以下のページをのぞいてみてください！

https://mikan.link/careers
PlatformIOのSTM32 (Arduino Framework) でパルスサーボを制御する

めっちゃ簡単なことなのに0.5秒くらいハマったので書く

## 標準ライブラリは使用できない

いつもだったらPlatformIO→LibrariesからServoライブラリをAddして使用すると思うが、こちらはSTM32に標準で対応していない。

Platformsを参照。Atmel AVRとAtmel SAMしか対応していない。

![スクリーンショット 2024-02-29 17.57.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/5c1d3cfd-6f94-9564-dc4c-16ed46f25004.png)

## 解決策

:::note info
GitHubからstm32duino標準ライブラリを引っ張ってくる
:::

https://github.com/stm32duino/Arduino_Core_STM32/tree/main/libraries/Servo/src

拙い図だが、こんな感じでプロジェクトフォルダの中に配置してあとは普通にincludeして使うだけ。

![スクリーンショット 2024-02-29 18.00.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/628782/5a1e99d4-4b67-f720-32e4-979d27b40805.png)

```cpp
#include "./servo/Servo.h"
Servo servo;
```

## 参考文献

https://github.com/stm32duino/Arduino_Core_STM32/wiki/Servo-library
Vimでの入力補完の基本

Vimでは複数の入力補完コマンドが提供されており、これらを活用することで、効率的にコーディング作業を進めることができます。

### 基本の補完コマンド

1. Ctrl-P と Ctrl-N:
Vimで最も基本的な補完コマンドです。編集中の文書内で前方向（Ctrl-P）または後方向（Ctrl-N）にある単語を検索し、現在入力中の文字列にマッチする単語を補完リストとして提案します。

1. Ctrl-X Ctrl-L:
行の補完を行います。現在の行の一部を入力した後、このコマンドを使うと、以前に入力した類似の行を補完として提案します。

1. Ctrl-X Ctrl-F:
ファイル名の補完を行います。ファイルのパスの一部を入力した後、このコマンドを使うと、マッチするファイル名が補完リストに表示されます。

1. Ctrl-X Ctrl-O:
オムニ補完と呼ばれる、プログラミング言語固有のシンボルの補完を行います（例：関数名、変数名）。この機能を使用するためには、使用している言語に対応したVimプラグインが必要になる場合があります。

### 補完リストの操作
補完候補が表示された際には、次のキー操作で候補をナビゲートできます。

- Ctrl-N: 次の補完候補へ移動します。
- Ctrl-P: 前の補完候補へ移動します。
- Enter: 選択した補完候補を確定します。

### 補完の設定
Vimでは、completeoptオプションを設定することで補完の挙動をカスタマイズできます。例えば、補完リストがポップアップ形式で表示されるようにするには、以下のように設定します。

```vim
set completeopt=menu,menuone,noselect
```

この設定では、補完リストがメニュー形式で1つ以上の候補がある場合に限り表示され、最初の候補は自動的には選択されません。

### まとめ
Vimで提供されている入力補完機能は、効率的なコーディングを支援する強力なツールです。基本的な補完コマンドのマスターから始め、自分のニーズに合わせて補完の設定をカスタマイズすることで、Vimでの編集作業をより快適に、そして効率的に行うことができるようになります。
「現代数理統計学の基礎」演習問題解法メモ　第6章問9～10

問10の解法が長いので、問1までの公開です。
![第6章問9 P1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/ee9a177b-fc69-1092-2f0e-5017ac413cb8.jpeg)
![第6章問9 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/decba2cb-77b4-a831-fc2b-3db6d2a63197.jpeg)
![第6章問10 P1 .jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/98f7ec30-dcbe-5207-f1c1-5f092fc5e160.jpeg)
![第6章問10 P2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/03d06b0e-1c86-7260-f6cb-c9fd34090be0.jpeg)
![第6章問10 P3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/3b17148a-fe02-43f4-c99e-81ad8937e9fc.jpeg)
![第6章問10 P4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/882f012e-5c63-d6b4-5ebb-478db854ebd5.jpeg)
![第6章問10 P5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/70141bba-0031-238e-ead1-b689e47060ce.jpeg)
![第6章問10 P6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3576811/abd8acfe-d2da-5a4f-734e-f1095bc2ebb9.jpeg)
Postgres Operatorでクエリーログを出力する方法

本稿では、Postgres Operatorを使用してPostgreSQLのクエリーログを出力する方法について説明します。Postgres Operatorは、Kubernetes環境でPostgreSQLデータベースクラスターの管理を自動化するツールです。ログ出力の設定を適切に行うことで、データベースの操作やパフォーマンス分析に役立つ情報を取得できます。

### 前提条件

- Kubernetesクラスターが設定されていること
- Postgres Operatorがインストールされ、設定が完了していること

### ログ出力の設定方法
Postgres Operatorを使用してPostgreSQLのインスタンスを設定する際に、`postgresql`リソースの`spec`セクション内でログに関するパラメータを設定します。以下はその一例です。

```yaml
apiVersion: acid.zalan.do/v1
kind: postgresql
metadata:
  # メタデータ設定はここで行います（この例では割愛します）。
spec:
  # スペック設定はここで行います（この例では割愛します）。
  postgresql:
    version: "15"
    parameters:
      log_destination: 'stderr'  # ログの出力先を指定します。
      log_statement: 'all'       # 実行されるすべてのSQLステートメントをログに記録します。
      log_connections: 'on'      # 新しいデータベース接続のログ記録を有効にします。
      log_disconnections: 'on'   # データベースからの切断をログに記録します。
      logging_collector: 'false' # ログ収集機能を無効にします（stderrへの直接出力を意味します）。
```

### 設定パラメータの説明
- `log_destination`: ログの出力先を指定します。この例では`stderr`に設定していますが、`csvlog`や`syslog`など他のオプションも利用可能です。
- `log_statement`: 実行されるSQLステートメントのログ記録レベルを設定します。`all`を指定すると、すべてのクエリがログに記録されます。
- `log_connections`: このオプションを`on`に設定すると、新しい接続がログに記録されます。
- `log_disconnections`: このオプションを`on`に設定すると、接続の切断がログに記録されます。
- `logging_collector`: PostgreSQLのログ収集機能を有効または無効にします。`stderr`への出力を選択した場合は、`false`に設定します。

### 注意点
- 上記の設定はPostgreSQLバージョン15の例です。使用するPostgreSQLのバージョンに応じて、利用可能なパラメータが異なる場合がありますので、公式ドキュメントを参照してください。
- ログの出力設定を変更した後は、Postgres Operatorを通じてデータベースクラスターの再デプロイが必要になる場合があります。

この設定を適用することで、PostgreSQLの運用監視やトラブルシューティングに役立つ詳細なログ情報を取得することが可能になります。
[Google Sheets API] セル内のテキストを列に分割させる

Google Sheets API v4（Java）を使用して、
スプレットシートにセル内のテキストを列に分割させる方法
についてご紹介します。

メニュー：「データ」 ⇨ 「テキストを列に分割」
で実行できる内容と同じです。

:::note info
APIを利用する環境の準備から始める場合や、コードを実行する際は、
[⧉[Google Sheets API] Google Sheets API v4をJavaで操作する](https://qiita.com/doran/items/3d43f776188b2281044c)
を参照ください。
```
例：requests.add(moveDimension(sheetId)); //実行したいリクエストのMethodを指定
```
:::

:::note info
その他のGoogle Sheets APIは、下記の記事を参照ください。
[⧉[Google Sheets API] JavaでスプレットシートのメニューとAPIを関連づけてみた](https://qiita.com/doran/items/2f6f8932b994fbd1a170)
:::

## テキストを列に分割させる
セルを指定してテキストを列に分割させます。

区切り文字はTextToColumnsRequestクラスのsetDelimiterTypeメソッドで指定します。
CUSTOMの場合は、setDelimiterメソッドで区切り文字を指定します。
|type|区切り文字|
|---|---|
|COMMA|カンマ　「,」|
|SEMICOLON|セミコロン　「;」|
|PERIOD|ピリオド　「.」|
|SPACE|スペース　「 」|
|CUSTOM|カスタム|
|AUTODETECT|自動判定|

範囲の設定では1列のみを指定してください。
複数列を指定するとエラーになります。

**サンプル コード**
カンマ区切りのデータを列に分割させます。
```
public Request textToColumns(Integer sheetId) {
    Request request = new Request();

    //範囲の設定
    GridRange range = new GridRange();
    range.setSheetId(sheetId);    //シートID
    range.setStartRowIndex(0);    //開始行(0スタート)
    range.setEndRowIndex(3);      //終了行(1スタート)
    range.setStartColumnIndex(0); //開始列(0スタート))
    range.setEndColumnIndex(1);   //終了列(1スタート)
    
    TextToColumnsRequest r = new TextToColumnsRequest();
    r.setDelimiterType("COMMA");  //区切り文字のタイプ
    //r.setDelimiter("¥");        //カスタムの区切り文字(typeがCUSTOMの場合のみ)
    r.setSource(range);
    
    request.setTextToColumns(r);
    return request;
}
```
**実行結果**
カンマ区切りのデータが
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/2bcd0e50-a63b-dc1b-fcf4-df231c2a94d6.png">
列に分割されました。
<img width="320" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114621/f9935a8d-f4f3-3c23-b5a5-5d6c9d7274c1.png">


<br>
おしまい。。
Teradata上のデータサイズ計測について

# はじめに
過去に参画したプロジェクトで、Teradataのデータをファイルに出力し、出力したファイルを他のDB製品に取り込む作業がありました。
その際、Teradataから出力されたファイルサイズと事前に計測していた処理効率の値を使い、スケジュールの見積もりをしました。しかし、Teradata上での圧縮率を考慮せずに出力されたファイルサイズを算出し、スケジュールを見積もったことで追加タスクが発生し余裕のないスケジュール設定でプロジェクトを進めることとなりました。
その失敗談から学んだことを共有させていただきます。
 
 
# teradataのデータ容量はcurrentpermから分かる
Teradataのシステムテーブルで使われている currentperm の値からTeradata内のデータ容量（ディスク容量）を知ることができます。
プロジェクトでは下記のSQLを使用し、DB毎のTeradata上のデータ容量を取得していました。

    select 
        databasename
	    ,CurrentPerm                          
	    ,MaxPerm
	    ,CurrentPerm/MaxPerm AS usage_percent
	    ,MaxPerm - CurrentPerm AS FreePerm_GB
    from Dbc.DiskSpaceV 
	group by 1 order by 1;



# currentpermの値はTeradata上で圧縮された後のサイズ
Teradata上のデータは圧縮された状態で保存されています。
**currentperm の値はTeradata上で圧縮された後のデータサイズ**になります。
currentpermの値 = Teradataのデータをファイルに出力した際のファイルサイズ とは限りません。

# ファイルサイズを知るためにはどうすればよいか
Teradataにはデータを圧縮する方法が3つあります。
・複数値圧縮(MVC)
・アルゴリズム圧縮(ALC)
・ブロック レベルの圧縮

正確に圧縮率を求めるには、実際に対象テーブルを全てファイルに出力し確認するしかありません。

今回のプロジェクトでは作業対象テーブルが多く、調査時間も限られていたため、テーブルをサンプリングしおおよその圧縮率を出すこととしました。
サンプリング方法として下記の2つを考え、私たちは2つ目の方法で実施しました。
1. 作業対象の全テーブルのうち数％の行をファイルに出力する
2. 作業対象テーブルをデータ特性で分類し、データ特性毎にテーブルを選択しファイルに出力する


# 最後に
Teradataのデータサイズを使用する際に私と同じ失敗が起こらないようにと思い、本記事を作成しました。
今後もTeradataをはじめとするDB製品についての知見を発信していく予定です。


# 
株式会社ジールでは、「ITリテラシーがない」「初期費用がかけられない」「親切・丁寧な支援がほしい」「ノーコード・ローコードがよい」「運用・保守の手間をかけられない」などのお客様の声を受けて、オールインワン型データ活用プラットフォーム「ZEUSCloud」を月額利用料にてご提供しております。
ご興味がある方は是非下記のリンクをご覧ください：
https://www.zdh.co.jp/products-services/cloud-data/zeuscloud/?utm_source=qiita&utm_medium=referral&utm_campaign=qiita_zeuscloud_content-area
Windowsでzipコマンドを使う方法

Windowsではデフォルトで`zip`コマンドがインストールされていませんが、`Scoop`などのパッケージマネージャーを使用して簡単にインストールできます。

### Scoopのインストール

Scoopがまだインストールされていない場合は、PowerShellを開いて以下のコマンドを実行してScoopをインストールします。

```powershell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex
```

### zipコマンドのインストール

Scoopをインストールしたら、次にzipコマンドをインストールします。PowerShellで以下のコマンドを実行してください。

```powershell
scoop install zip
```

このコマンドにより、zipユーティリティがインストールされます。

### zipコマンドの基本的な使い方

zipコマンドを使用してファイルやフォルダーを圧縮する基本的な方法は非常にシンプルです。

```powershell
zip --help
```

```Copyright (c) 1990-2008 Info-ZIP - Type 'zip "-L"' for software license.
Zip 3.0 (July 5th 2008). Usage:
zip [-options] [-b path] [-t mmddyyyy] [-n suffixes] [zipfile list] [-xi list]
  The default action is to add or replace zipfile entries from list, which
  can include the special name - to compress standard input.
  If zipfile and list are omitted, zip compresses stdin to stdout.
  -f   freshen: only changed files  -u   update: only changed or new files
  -d   delete entries in zipfile    -m   move into zipfile (delete OS files)
  -r   recurse into directories     -j   junk (don't record) directory names
  -0   store only                   -l   convert LF to CR LF (-ll CR LF to LF)
  -1   compress faster              -9   compress better
  -q   quiet operation              -v   verbose operation/print version info
  -c   add one-line comments        -z   add zipfile comment
  -@   read names from stdin        -o   make zipfile as old as latest entry
  -x   exclude the following names  -i   include only the following names
  -F   fix zipfile (-FF try harder) -D   do not add directory entries
  -A   adjust self-extracting exe   -J   junk zipfile prefix (unzipsfx)
  -T   test zipfile integrity       -X   eXclude eXtra file attributes
  -!   use privileges (if granted) to obtain all aspects of WinNT security
  -$   include volume label         -S   include system and hidden files
  -e   encrypt                      -n   don't compress these suffixes
  -h2  show more help
  ```

### ファイルの圧縮とパスワード保護

コマンドラインやPowerShellで以下のコマンドを実行して、複数のファイルをパスワード付きで圧縮します。

```powershell
zip -p yourpassword -e xxx.zip file1 file2
```

このコマンドでは、-pオプションに続けてパスワードを指定し、-eオプションを使って暗号化（パスワード保護）を有効にしています。xxx.zipは作成されるZIPファイルの名前で、file1とfile2は圧縮したいファイルの名前です。

### まとめ

この記事では、Windowsでzipコマンドを使用するための準備と基本的な使用方法について説明しました。Scoopを使ったインストール方法から、ファイルの圧縮とパスワード保護の追加まで、手順を追って説明しました。これで、Windows環境でもzipコマンドを効果的に活用することができます。


https://www.geeksforgeeks.org/zip-command-in-linux-with-examples/


https://scoop.sh/