OmniAICreator/Qiita-1.07M huggingface dataset:
SpringBootで複数DataSourceについてまとめ（まだうまくいってません）

# はじめに
Framework選定などしたことがなかった自分ですが、ひとりですべてこなすプロジェクトだったため、どれにしよう～と最近のはやりFremeworkと、案件の内容からSpringBootを選択した。
DBは１つと聞いていたのに、あとになってログインだけは別のDBを見る必要があると判明。
複数DB（以降複数DataSourceと書きます）つなげるのに四苦八苦しております。
いま現時点でもまだうまくいかず。。。
途中経過も含め、残しておくことにします。
（※うまくいくところまで載せたいと思っています）

# 開発環境
Eclipse Version: 2021-12 (4.22.0)
Java 17
Maven
SpringBoot
（新規スタータープロジェクト(Spring Initializr)で選択したもの）
SpringWeb／Lombok／Spring Boot Dev Tools／Thymeleaf／Spring Data JPA

:::note info
pom.xmlでみると、
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.1</version>
:::

# 見たところその１．Spring Boot Reference Documentation
SpringBoot公式のリファレンス。
ここがなぜググって最初に出てこないのか不思議。
関係ありそうなのは以下の２項目。
### 18.8.2. Configure Two DataSource
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.data-access.configure-two-datasources


### 18.8.10. Using Multiple EntityManagerFactories
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.data-access.use-multiple-entity-managers

この上記２か所を参考にしようとすると、どう書くべきなのかわからない。
要所のみ記載なのは仕方ないが、全体ソースがないので、この項目は何だ？となる。
実際どう書くべきかは想像するしかない。


# 見たところその２．Baeldung　Configure and Use Multiple DataSources in Spring Boot
https://www.baeldung.com/spring-boot-configure-multiple-datasources

公式なのかな？で、なんと最終更新日が2023/03/24。最近更新されている！
全部見ていくが、4.SpringデータJDBCは飛ばして、5.Spring Data JPAを参照。
ここででてくる、「basePackageClasses = Todo.class」が分からない。
TodoはEntityだが、まさか１エンティティだけ見るシステムなんてありえない。
じゃあここにどう列挙するのか？
GitHubのリンクが最後にあるのでそこを見るも、この辺りは不明のまま。

そしてこの通り（bacePackageの部分は下のを参考にして定義）に実装してみたが、
やはりエラーでうまくいかない。

2023/04/03 最終更新日が2023/03/30。ただどこが更新されたかわからない。


# 見たところその３．Baeldung　Spring JPA – Multiple Databases
https://www.baeldung.com/spring-data-jpa-multiple-databases

公式なのかな？で、なんと最終更新日が2023/02/09。最近更新されている！
ただここはSpringJPAなので、ちょっと違う・・・？と思いきや、下のほうの、
6. Multiple Databases in Spring Boot
からがSpringBootの複数DataSourceの記事が載ってる。
ここでは、「basePackages = "com.baeldung.multipledb.dao.user"」となっている。
その他にもよく見てみるとこっちの記事のほうが詳細だ。

この通り実装してみたが、エラーは変わらない。

いったんここまで。


# おわりに
「できる」と「わかる」を区別する

この記事は、[新人プログラマ応援_記事投稿キャンペーン](https://qiita.com/tags/%e6%96%b0%e4%ba%ba%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9e%e5%bf%9c%e6%8f%b4_%e8%a8%98%e4%ba%8b%e6%8a%95%e7%a8%bf%e3%82%ad%e3%83%a3%e3%83%b3%e3%83%9a%e3%83%bc%e3%83%b3)向けに書かれたものです。

もともとは自身の頭の整理として書き始めたものですが、ちょうどいい内容かと思い、こちらのカテゴリで紹介させていただきました。

## 「できる」から「わかる」？

たとえば`docker`コマンドや`docker-compose`コマンドを普段使いこなしている開発者でも、

- イメージとコンテナの違いとは？ 
- ボリュームの種類とは？

というようなDockerに関する知識は知らなかったり[^1]、そもそも

- ポートって何?
- コンテナ化されることで何が嬉しいのか?

みたいな基礎的・本質的な知識をおさえていないことはよくあるかと思います。

しかしそれでもコマンドは使えているし業務は行えている。

つまり、**「できる」と「わかる」は完全に一致するわけではない**、ということです。

## 「できる」ことから「わかる」ことを増やす

上記は決して良くないことや恥ずべきことではありません。

むしろエンジニアであれば、こういったタイプのスキルは無限に存在し、日々増えつづけています。

ただし「できる」で満足せず、その仕組みや背景を「わかる」ように調べたり考えたりすることは重要です。

完璧に理解することは難しいでしょうが、ちょっと調べたりする。その蓄積が、後々の自身のスキルマップの広がりになるはずです。

## 「わからない」から「できない」？

同様に、あるタスクを誰かから依頼されたときに「わからないのでできない」と感じることも多くあると思います。

わからないから、まずは「わかる」ためにキャッチアップに時間をかけたり、先輩にみっちり教えてもらうことを最初のステップに据える方もいるでしょう。

しかしググって見つけたページに書いてあるコマンドを実行したら、すんなり終わってしまったような経験は誰にでもあるはずです。とはいえ何故上手くいったのかは説明できない。

このように「わからない」と「できない」が一致しないことも確認できました。

## 「わからない」と上手に付き合う

だいたいの仕事は「わからない」ことが多いです。

だからでしょうか。「わからない」を上手に対処できるエンジニアは、総じて仕事も上手いです。とくにいろいろな仕事を任せられそうなオーラが出てきます(笑)

対処方法はさまざまで、上述のようにまずは手を動かしてみたり手本を探してみることもあれば、求められる質によっては誰かに頼ってみたり、それこそ公式ドキュメントを最初から読み込まなければいけないこともあります。

この記事の文脈で言えば、**「わかる」必要があるのか、それとも「できる」ことが求められているのか**、という点を考えて仕事に臨むのがよさそうですね。

## まとめ

「できる」と「わかる」、そして「できない」と「わからない」を区別できるようになると、自身のスキル感も精度高く把握できるようになりますし、周りとのコミュニケーションもよりスムーズになり、仕事がやりやすくなるはずです。

ちなみに誰かに教える立場のエンジニアであれば、教える対象のエンジニアが「できる」だけなのか、それとも「わかる」状態でもあるのかを意識したり、「できる」ようになってほしいのか「わかる」ところまで期待しているのかを区別すると、説明のレベルも上手に調整できるはずです。

すこしずつ「できる」と「わかる」を増やしていければ良いですね。自分もひきつづき頑張ります。

[^1]: ボリュームに関しては、["なんとなく”Dockerのファイル共有について語れるようになる](https://qiita.com/kobori_akira/items/73488918d6fb2a1ae020)という記事も書いたりしています。
【WordPress】文章（コンテンツ）中のURLを自動的にリンク（aタグ）にしよう！

# TL;DR
``` php
//$strの中のhtmlタグに設定されていないURLをリンク化する関数
function convert_string_url_to_link($str){
  $ptn = '/([^"])(https?:\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])([^"])/imu';
  $rep = '$1<a href="$2" target="_blank" rel="nofollow">$2</a>$3';
  $result = preg_replace($ptn, $rep, $str, -1);
  if($result == null) return $str;
  return $result;
}
//上記関数をthe_contenのfilterに設定
add_filter('the_content', 'convert_string_url_to_link');
```
特にエラー処理とかはしてないので、必要に応じて編集してください。

# この記事を書いた理由
クライアントさんから「URLが勝手にリンクになったらいいなー」のお声。
エディタ側でリンクにしてください。で一蹴しないのが弊社のホスピタリティ。

# コードの説明
まずは文章中のURLをaタグで囲む関数を作りましょう。
URLは正規表現で取得し、置換取得したURLを置換してaタグ内に入れるようにします。
今回、大体は外部リンクになるかなーって思ったので、とりあえず外部リンクにになるようにtarget属性も設定しました。

後は、the_contentのフィルターとして設定すれば完了です。

# 蛇足
関数化することで、単体でも利用可能なので、カスタムフィールドに入力された文章中のURLも変換できます。
``` php
$str = get_field('hoge');
echo convert_string_url_to_link($str);
```
VimとNeovimでTerminal-Normalモードに切り替えるキーマップが違った


Neovim でターミナルを使おうと思ったら、`<C-w>N`で Terminal-Normal モードにならなくて少し困った。

ドキュメントなどを見たところ

- Vim の場合: `<C-W>N`
- Neovim の場合: `<C-\><C-N>`

と異なる様。

どちらにせよ、不便だったので`Esc`で Terminal-Normal モードに切り替えるようにした。

```lua:init.lua
vim.keymap.set("t", "<Esc>", "<C-\\><C-n>")
```

## Refs

- [terminal - Vim 日本語ドキュメント](https://vim-jp.org/vimdoc-ja/terminal.html)
- [Nvim_terminal_emulator - Neovim docs](https://neovim.io/doc/user/nvim_terminal_emulator.html)
自然言語処理は人工知能なのか ...

... と故長尾真先生が研究室で発言されたことがありました。

自分自身は人工知能の一分野だと思っていたので、ちょっとびっくりしました。その頃助手だった故中村順一先生も困惑した表情を見せていました。

確かにその頃 (1980年前後)、人工知能の教科書では、ゲームが題材に使われ、手の選択により枝分かれした空間の探索が基本技術になります。自然言語処理における形態素解析や構文解析も解の探索ではあるのですが、人工知能の基本技術の探索を応用したというものではなかったと思います。

ちょっと脱線しますが、探索における評価値は、強化学習における報酬とつながりますね。

人工知能の定義はいつもあいまいで、現在は機械学習との違いとして、全体で知的なふるまいをする応用という見方が中心になってきていると思いますが、当時はストレートフォワードに解けない複雑な問題を解くことのような見方もされていたと思います。例えば、「数式処理は以前は人工知能の扱いだったが、解法が固まってきて、今では人工知能の分野から外れた」という言い方もされていました。

自然言語処理は解法が固まったという訳ではないのですが、先に触れたように人工知能の基本技術を使っている訳ではなく、人工知能の他の分野の進展とは無関係に研究を進めている雰囲気があった*ので、独立した分野として扱ってもいいんじゃないかという思いも持たれていたのかもしれません。その後言語処理学会は1994年に設立されます。一方、言語処理学会ができた以降も、人工知能学会の中でも自然言語処理は扱われていました。

注* 論理という点では密接につながっていました。一階述語論理、モンタギュー文法、Situation Semantics、Prologなどのキーワードがありました。私が忘れているだけで、他にも接点はあったかもしれません。

今、ChatGPTはもうAGI (汎用人工知能) じゃね? と言われている時代に、ついつい昔のことを思い出してしまいます。確かに汎用人工知能到来!と見えるときがあります。しかし、昔からの自然言語処理をやっていた人間にとって、じゃあそれまで取り組んでいたことは何だったの? という思いもあります。今後少しずつ大規模言語モデル、ChatGPTについて考えていきたいと思います。

考えたいこと：
* 記号処理と単語ベクトル →　[(1) 記号処理と単語ベクトル](https://qiita.com/ryokan/items/17113cbb01545e181799)
* 処理の対象と処理内容 →　[(2) 処理対象と処理内容](https://qiita.com/ryokan/items/7f28cd6673b9ed1d721d)
* 形態素解析はどこへ行った? →　[(3) 処理対象と処理内容](https://qiita.com/ryokan/items/167150759eaca504ad57)
* 論理はどこへ行った? →　[(4) 論理について](https://qiita.com/ryokan/items/8e22edae0ab1a7803cd0)
* 運用論、敬語など →　[(5) 語用論、敬語など](https://qiita.com/ryokan/items/6ed345c7a27a18c4765b)

そして最後に、[(6) どう向き合うか](https://qiita.com/ryokan/items/eaa6efd1644cc0230ff8) をまとめました。
長過ぎるterraform planの結果をGitHubのPRに自動コメントするときのエラーの対処

HashiCorp公式のActionではterraform planの結果をGitHubのPRに自動でコメントするサンプルが載っています。

https://github.com/hashicorp/setup-terraform

しかし、この方法はplan結果が長くなりすぎると以下のようなエラーが発生します。

```
An error occurred trying to start process '/home/runner/runners/2.303.0/externals/node16/bin/node' with working directory '/home/runner/work/<リポジトリ名>/<リポジトリ名>'.
Argument list too long
```

これはGitHub Actionsの環境変数経由で渡すことができる文字列の最大長が65535であることによります。
そのため、plan結果が長くなりすぎる場合は以下のようにplan結果の切り詰めを行うと正常に実行されます。

```yaml
    - name: Terraform Plan
      run: |
        terraform-bin plan -out=tfplan
        terraform-bin show -no-color tfplan > show_result.txt
        plan_result=$(cat show_result.txt)
        tf_plan_summary=$(grep -x -E "Plan: [0-9]+ to add, [0-9]+ to change, [0-9]+ to destroy\.|No changes. .*" show_result.txt) || true
        echo "TF_PLAN_SUMMARY=${tf_plan_summary}" >> $GITHUB_ENV
        EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
        echo "TRUNCATED_TF_PLAN<<$EOF" >> $GITHUB_ENV
        echo "${plan_result:0:65536}" >> $GITHUB_ENV
        echo "$EOF" >> $GITHUB_ENV
    
    - uses: actions/github-script@v6
      id: tf_plan_result
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        result-encoding: string
        script: |
          const tf_plan = process.env.TRUNCATED_TF_PLAN;
          const tf_plan_summary = process.env.TF_PLAN_SUMMARY.length == 0 ? "Unexpected plan output." : process.env.TF_PLAN_SUMMARY
          const run_id = process.env.GITHUB_RUN_ID;
          const repository_name = process.env.GITHUB_REPOSITORY;
          const tf_plan_in_comment = tf_plan.length == 65536 ? "\nTerraform plan too long. Refer to its workflow run in Actions tab for the full-length plan.\n\n" + tf_plan + "...\n" : tf_plan;

          const output = `#### terraform plan: \`${ tf_plan_summary }\`
          [CI Details](https://github.com/${ repository_name }/actions/runs/${ run_id })

          <details><summary>Show Plan</summary>
            \`\`\`
            ${ tf_plan_in_comment }
            \`\`\`
          </details>

          ---

          *Pusher: Action: \`${{ github.event_name }}\`, Workflow: \`${{ github.workflow }}\`*`;

          return output
```

setup-terraformアクションでセットアップされるterraformコマンドはGitHub Actionsが内部的に使うための情報も出力するラッパーになっているので、「裸の」terraformコマンドを使うためにterraform-binコマンドを使っています。

https://github.com/hashicorp/setup-terraform/issues/167

また、EOFを毎回乱数から生成しているのはGitHub Actionsのセキュリティを高めるためです。

https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#multiline-strings
Carbon使用時に注意すること【Laravel】

CarbonオブジェクトはMutable（変更可能）という特性を持っています。
Mutableは便利である反面、注意しなければならない点もあるため、自分用のメモも兼ねて記事を書いてみました。

## Carbonとは？
日付と時刻を簡単に操作できるライブラリです。DateTimeクラスを拡張しており色々と便利なメソッドが利用できます。

## Mutableとは？
Mutableとは、オブジェクトの状態が変更可能であるということです。
例えば以下コードのように`$date1`に対して2023年4月1日という日付のcarbonインスタンスを代入し、
addDaysメソッドを使って、そこから7日後の日付（4月8日）を`$date2`に代入したとします。
```php
$date1 = Carbon::createFromDate(2023, 4, 1); 
$date2 = $date1->addDays(7); 
```
この状態で、diffInDaysメソッドを使って`$date1`と`$date2`の差が何日なのかを確認してみます。
当然7日になるだろうと思いますが、、
```php
dd($date1->diffInDays($date2));

// 出力結果「0」
```
なんと「0」日になってしまいました。

なぜこんなことが起きるのでしょうか？
それは、以下の行で`$date1`自体も4月1日から4月8日に変更になっているからです。
```php
$date2 = $date1->addDays(7); 
```
つまり、`$data1 = ～～` といった形で代入をしなくても
`$date1->addDays(7);` とするだけで状態を変更できるということです。
```php
$date1 = Carbon::createFromDate(2023, 4, 1); 
$date1->addDays(7); 

dd($date1->format('Y-m-d'));
// 出力結果「2023-4-8」
```
これがMutable（変更可能）なオブジェクトの特性です。
便利な側面もありますが、気付かずに意図しない変更が行われてしまう可能性もあります。

## 意図しない変更を避ける方法

##### 方法①：copy()を使う
以下のように、`$date1`に対してcopyメソッドを使って複製を作ったあとにaddDaysメソッドを使用すれば`$date1`は4月1日のままです。
```php
$date1 = Carbon::createFromDate(2023, 4, 1); 
$date2 = $date1->copy()->addDays(7); 

dd($date1->format('Y-m-d'));
// 出力結果「2023-4-1」
```
##### 方法②：CarbonImmutableを使う
以下のように、`Carbon`クラスではなく`CarbonImmutable`クラスを使用するとMutable（変更可能）ではないインスタンスが作成されるので、意図しない変更を避けることができます。
```php
$date1 = CarbonImmutable::createFromDate(2023, 4, 1); 
$date2 = $date1->addDays(7); 

dd($date1->format('Y-m-d'));
// 出力結果「2023-4-1」
```
なお、MutableとImmutableは、以下のようにtoImmutableメソッドやtoMutableメソッドを使用して相互変換が可能です。

```php
$date1 = Carbon::now(); 
$date1->toImmutable();
// Immutableに変換

$date2 = CarbonImmutable::now(); 
$date2->toMutable();
// Mutableに変換
```
gunicornでディスク使用量が増え続ける現象への対処

# はじめに
Linux環境にてFastAPIを[gunicorn](https://gunicorn.org/)で動かしています。
しばらく運用しているうちにローカルストレージの使用量が増えていっていることに気が付きました。
なぜなのか等、調査し対応したメモを残しておきます。

AWSのFargateでの事象および回避方法ですが、
オンプレサーバなどの環境でも設定方法が違うだけで内容は同じはずです。

なお、gunicornのバージョンは20.1.0です。

# 結論
max-threadsを設定するとコアダンプファイルがストレージを圧迫するので、
コアダンプが出力されないように設定しよう。

# 調査
Fargateの場合、Cloudwatch Container Insightを有効化することでコンテナのストレージ使用量(EphemeralStorageUtilized)を見ることができます。
有効化してしばらく運用していたところ、使用量が増えていっていることに気が付きました。

## どんなファイルが増えていっているのか？

Fargateなので、コンテナに直接ログインしてみて中身を見てみます。
CloudShellから[Amazon ECS Exec](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/userguide/ecs-exec.html)を使ってコンテナにログインします。
あらかじめ設定等が必要ですが、[こちら](https://dev.classmethod.jp/articles/ecs-exec/)を参考に設定しておきます。
```
aws ecs execute-command  \
    --region ap-northeast-1 \
    --cluster クラスタ名 \
    --task XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
    --container コンテナ名 \
    --interactive \
    --command "/bin/sh"
```

つながったらlsなどでFastAPIを動かしているディレクトリを見てみると、
core.999 という謎のファイルが多数、、、
```
/HOGE # ls -lh
total 2G     
drwxr-xr-x    2 root     root        4.0K Feb 28 07:30 __pycache__
-rw-------    1 root     root      164.7M Feb 28 19:05 core.1058　←？？？
-rw-------    1 root     root      156.9M Feb 28 23:24 core.1257　←？？？
-rw-------    1 root     root      175.9M Feb 28 09:54 core.21　　←？？？
-rw-------    1 root     root      178.7M Feb 28 13:01 core.337 　←？？？
drwxr-xr-x    1 root     root        4.0K Feb 28 07:30 hogehoge
-rw-r--r--    1 root     root        3.7K Feb 21 00:39 main.py
-rw-r--r--    1 root     root         285 Feb 21 00:39 requirements.txt
/HOGE # 
```

fileコマンドで何者かを確認してみましょう。
```
/HOGE # file core.1058
core.1058: ELF 64-bit LSB core file, x86-64, version 1 (SYSV), SVR4-style, from '/usr/local/bin/python /usr/local/bin/gunicorn main:app --workers 2 --worker-cla', real uid: 0, effective uid: 0, real gid: 0, effective gid: 0, execfn: '/usr/local/bin/gunicorn', platform: 'x86_64'
```

`ELF 64-bit LSB core file`ということでコアダンプのファイルだとわかりました。
また、gunicornの異常終了でできたものであることもわかりました。


## gunicornの異常終了はなぜ起こるのか

gunicornには指定回数分の処理をこなすとワーカープロセスを再起動してくれる設定(max_requests)があります。
これを設定しておくことで、万一メモリリークなどが発生していたとしても回避することが可能です。

https://docs.gunicorn.org/en/stable/settings.html#max-requests

今回、gunicornの起動オプションとして ```--max-requests 500``` を指定していたため、
ワーカープロセスが再起動されるのですが、
その再起動が異常終了とみなされてコアダンプが生成されているようです。

# 対処

再起動してもコアダンプを出さないように設定することで対処します。
ulimitでcore file sizeを0に設定します。

`Webコンソール > ECS > タスク定義 > 設定したいタスクの最新リビジョン`
`新しいリビジョンの作成 > JSONを利用した新しいリビジョンの作成`
を開きます。
（2023/03現在、JSONでないと設定できません）

以下のように __containerDefinitions.ulimits[]__ にcoreの設定を追加して、サービスに適用させれば完了です。
```
{
  ～略～
  "containerDefinitions": [
    {
      ～略～
      "ulimits": [
        {
          "name": "core",
          "softLimit": 0,
          "hardLimit": 0
        }
      ],
      ～略～
    }
  }
}
```

冒頭に記載しましたように、上記はFargateでの設定です。
オンプレ環境だと /etc/init.d/ や /etc/security/limits.conf にulimitの設定をすることになると思います。


# おわりに

max-requestsを設定するときは同時にmax-requests-jitterも設定しましょう。という記載は比較的よく見かけるのですが、
コアダンプファイルへの注意を記載しているのが見つからなかったので、
今後のために記録しておきます。
【入門】Gatsby x Contentfulで爆速でいい感じのブログをデプロイまでする

## ターゲット
QiitaやZennを卒業して、初めて自分用のブログを作ってみたい！！と思っているあなた
私と一緒にやっていきましょう

[Gatsby Starter Contentful Homepage](https://github.com/gatsbyjs/gatsby-starter-contentful-homepage)に沿って進めてみる

## ディレクトリ作成
gatsbyをグローバルインストール
```bash
npm i -g gatsby
```

contentfulを使ったgatsbyのテンプレディレクトリを作成
```bash
npx gatsby new my-homepage https://github.com/gatsbyjs/gatsby-starter-contentful-homepage
```

```bash
cd my-homepage
```

## ContentfulのAPIkeyを取得

1. Contentfulの[公式](https://www.contentful.com/help/contentful-101/#step-2-create-a-space)に遷移
1. アカウント登録
1. SEOの設定などは一旦無視
1. Setting > API keysにあるSpace ID, Content Delivery API - access tokenをメモ
1. Setting > API keys > 上部のContent Management TokenからGenerate Tokenを行い、メモ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/f209aca3-b575-b349-648b-e9c0a394b0c3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/1a67b64f-2d47-038b-8359-d6134eab525e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/1cd210c9-b4b0-8654-ff94-5aea74a38214.png)


## 環境変数ファイルにAPIkeyを記載
自力で作成してもいいんですが、
```npm run setup```でメモした情報を指示された内容に沿ってコピペしていくと、環境変数ファイルが自動で作成される


## ローカル立ち上げ
```npm run dev```でローカル起動されたサンプルサイトがhttp://localhost:8000/ に立ち上がる


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/31f5d0b9-010c-33d9-2e5e-282061a4dd3c.png)

かっこええやん！！！


## 一旦Gitにコードをpushする
1. ```git init```
1. ```git add .```
1. ```git commit -m"first comit"```
1. ```git remote add 新規作成したgitレポジトリのURL```
1. ```git push -u origin master```

## デプロイ
[Gatsby Cloud](https://www.gatsbyjs.com/dashboard/signup)に新規登録を行う

GitProviderとしてGithubなりGitbucketなり自分がpushしたサービスを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/6e97cae4-7f58-f4ee-8a5d-8ff5b72efc30.png)
あとは流れに任せていってPublishedステータスになれば完了

## 確認
画面上部にあるURLをクリックするとデプロイされたサイトを確認できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/d6fabac5-eed9-9d9d-8c02-df5779533a69.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/6b3c0fa4-6d9a-9a7f-094d-03fc62c4fd58.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/487834/641a2380-2fa9-1a76-d15f-a692efa27120.png)
モバイルも良い感じ

## 感想
Netlifyなどの統合もできるようですが、一応これだけでもGitからの自動デプロイまで勝手にやってくれるようです。

理解してしまえば簡単なんですが、意外と情報が少なくて苦戦しました、、、

## 参考
https://www.contentful.com/gatsby-starter-guide/
[どうやって消す？]Dataverse 容量を消費するログの存在

ZHBK(ずいぶん久しぶりにブログ書きます）小林です。

今回は、自社で起こったDataverseの容量消費対策について書きます。

## 気がついたらキャパシティオーバー！

かれこれ4年ほど利用しているDataverseの環境がありました。

データベース容量もかなり使っていますが、なにより増え続ける「ファイル」容量が気になります。

この時点でギリギリでしたが、数日してキャパシティーオーバー、、、💦

このファイルってなに？？

![dataverse01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/8994ff78-7fe8-b5cf-8879-71d2750cd293.jpeg)


## 何が容量を取っているのか？
それを調べるために「容量」から「ファイル使用量」調べると「AsyncOperation」が、かなり多いのがわかりました。そもそも「AsyncOperation」と言われてもDataverseの内部ファイルなので、何を指しているのかわかりません💦

![dataverse02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/cd8c9a3d-8ff9-2b16-11a0-9a12d8b86e1b.jpeg)


調べてみると、

:::note info
System Job (AsyncOperation) テーブル/エンティティの参照
https://learn.microsoft.com/ja-jp/power-apps/developer/data-platform/reference/entities/asyncoperation
:::

システムで利用しているテーブルみたいで、ログデータが記録されている様ですね。


## 容量不足の解消方法
どこから削除すればよいのか調べていると、きちんとLeanに紹介されていました。

:::note info
AsyncOperationBase および WorkflowLogBase テーブルからレコードをクリーンアップする
https://learn.microsoft.com/en-us/power-platform/admin/cleanup-asyncoperationbase-table
:::

>AsyncOperationBase テーブルは、システム ジョブを格納するために使用されます。システム ジョブは、非同期登録ワークフローやプラグインなどの非同期拡張機能、および一括削除、一括インポート、ロールアップ操作などのその他のバックグラウンド操作を表します。イベントが発生し、同期拡張機能が処理された後、プラットフォームは非同期拡張機能のコンテキストをシリアル化し、それを AsyncOperation エンティティとしてデータベースに保存します。

>Dataverse 組織で非同期ワークフローがトリガーされると、AsyncOperationBase テーブルにレコードが作成され、非同期ジョブの処理が追跡されます。ワークフロー実行のログを維持するために、追加のレコードも WorkflowLogBase テーブルに作成されます。業務プロセス フロー(BPF) は、BPF ステージ遷移と BPF のアクション ログも WorkflowLogBase テーブルに格納します。

>組織でワークフローやビジネス プロセス フローを頻繁に使用している場合、***これらのテーブルは時間の経過とともに大きくなり、最終的にはパフォーマンスの問題を引き起こし、組織のデータベース内のストレージを過剰に消費するほど大きくなります。***


書かれているのと全く同じ状況ですね！

ページ内に削除方法の記載がありますので、それに習い「設定」に「一括削除」から設定します。

![dataverse03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/e5698fcd-d495-d622-c795-13e628095702.jpeg)


「新規」アイコンをクリックすると、「一括削除ウィザード」が始まりますので、

検索：システムジョブ
条件を、
システムジョブの種類：次の値と等しい：ワークフロー
ステータス：次の値と等しい：成功しました

![dataverse04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/1af439b2-a342-9f33-5eac-77c2d28fd37a.jpeg)


この内容で実行しますが、なぜか一括削除ジョブが私の環境では***キャンセル***されてしまいます。
まったく理由がわからないので、サービスリクエストをあげたところ、ご丁寧にご返答いただきました。

>レコードの一括削除ジョブがキャンセルされる要因として、環境の管理者モードが有効になっている場合、バックグラウンド処理が無効化されていることが考えられます。

>環境内のバックグラウンド処理が無効化されている場合、環境内のシステム ジョブ (非同期サービス) が実行されない動作となり、ジョブのステータスが "取り消し" となります。

><公開情報>
Title : 管理者モード
URL : https://learn.microsoft.com/ja-jp/power-platform/admin/admin-mode

この環境は、一度データをバックアップから復旧させたことがあり、その際に管理者モードが有効になってしまってたのが原因でした。

上記ページに変更方法がありますので、設定変更したところ

きちんと実行されました。
![dataverse05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/879d7c25-ecb5-b525-9bb0-9b3f2b645158.jpeg)


これで一件落着かとおもいきや、容量が減らないんですよね💦

これには凄い悩みましたが、まったくわからないので諦めて寝たら、翌朝容量が減っていたので、どうやらこの表示はリアルタイムではなく、反映に少し時間がかかるみたいです☺


## まとめ
反映に時間がかかると書いてくれていれば悩まずに済んだのにー！ということで。
無事に容量を減らすことができました。
Leanにも記載がありますが、データを残す必要がなければ、30日ごとに自動削除設定も可能です。
容量問題で困ったときに、何かの手助けになれば幸いです。

![dataverse06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140547/2c1fb527-0f72-398a-f0af-b343787109ac.jpeg)
cscの作法 その299

# 概要
cscの作法、調べてみた。
ProgressBar、使ってみた。

# 参考にしたページ。

https://qiita.com/tabelog2001/items/2fbd08a1d2e014ddfb76


# サンプルコード

```


using System;
using System.Drawing;
using System.Windows.Forms;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ProgressBarTest
{
	partial class Form2 : Form {
		public System.Windows.Forms.ProgressBar progressBar1;
		private System.ComponentModel.IContainer components = null;
		public Form2() {
			Text = "progressBar";
			ClientSize = new Size(200, 100);
			progressBar1 = new ProgressBar();
			progressBar1.Location = new Point(30, 30);
			Controls.AddRange(new Control[] {
				progressBar1
			});
		}
		protected override void Dispose(bool disposing) {
			if (disposing && (components != null))
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}
	}
	class BackGroundClass1 {
		private Form1 f1;
		private Form2 f2;
		public BackGroundClass1(Form1 f1) {
			this.f1 = f1;
			this.f2 = new Form2();
		}
		public void start() {
			Thread t = new Thread(new ThreadStart(LongTask));
			t.IsBackground = true;
			t.Start();
			f2.ShowDialog(f1);
			f2.Dispose();
		}
		private void LongTask() {
			for (int i = 0; i <= 100; i++)
			{
				Thread.Sleep(20);
				f2.BeginInvoke(new UpdateProgressBarDelegate(UpdateProgressBar), new object[] { i });
			}
		}
		private delegate void UpdateProgressBarDelegate(int val);
		private void UpdateProgressBar(int val) {
			f2.progressBar1.Value = val;
			if (val >= 100)
			{
				f2.Close();
			}
		}
	}
	public partial class Form1 : Form {
		private Button button1;
		public Form1() {
			Text = "bar";
			ClientSize = new Size(300, 200);
			button1 = new Button();
			button1.Location = new Point(130, 100);
			button1.TabIndex = 0;
			button1.Text = "start";
			button1.Click += new EventHandler(button1_Click);
			Controls.AddRange(new Control[] {
				button1
			});
		}
		private void button1_Click(object sender, EventArgs e) {
			BackGroundClass1 BGC1 = new BackGroundClass1(this);
			BGC1.start();
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
ChatGPTで始めるJavaScript入門⑨～クラス～

# 概要
　今回は3.JavaScriptの文法と構文について、の
　クラスについて確認していきます。

　他言語では一般的なクラスですが、JavaScriptはプロトタイプベースなので、ES6からクラスという概念が使用できます。

　**※無料版なので、誤っている情報もあると思いますが、アウトプットできれば良しとします。**


# クラス
　JavaScriptにおけるクラスはどういったことができて、何に注意すればいいかを聞いてみます。


　【質問】
　JavaScriptの文法と構文について、クラスの概要、記述方法や注意点を教えてください。

　【回答】
　JavaScriptのクラスは、オブジェクト指向プログラミングの機能の一つで、複数の関数や変数をまとめて、ひとつの「クラス」という単位で扱うことができます。　
　JavaScriptのクラスは、ES6（ECMAScript2015）から導入されました。

**クラスの基本的な構文**

以下は、JavaScriptでクラスを定義する基本的な構文です。

```javascript:class.js
class MyClass {
  constructor(prop1, prop2) {
    this.prop1 = prop1;
    this.prop2 = prop2;
  }

  method1() {
    // メソッドの処理
  }

  method2() {
    // メソッドの処理
  }
}
```

classキーワードでクラスを定義します。
constructorメソッドは、クラスのインスタンスが作られるときに実行されるメソッドで、クラスのプロパティを初期化するために使用されます。
method1やmethod2は、クラスのメソッドです。

**クラスの注意点**

クラス内で定義するメソッドには、アロー関数を使わずに通常の関数を使用する必要があります。
これは、アロー関数では自身を参照するためのthisが定義されず、予期しない動作をすることがあるためです。
クラスのプロパティには、アンダースコア(_)を前置する命名規則がありますが、実際にはプライベートプロパティを定義するためのものではありません。
代わりに、ES2022からはプライベートフィールドが導入されており、#を前置することで定義することができます。

**クラスの継承**

JavaScriptでは、クラスの継承もサポートされています。
以下は、クラスの継承を実現する構文の例です。

```javascript:extends.js
class MySubClass extends MyClass {
  constructor(prop1, prop2, prop3) {
    super(prop1, prop2);
    this.prop3 = prop3;
  }

  method3() {
    // メソッドの処理
  }
}
```

extendsキーワードを使って、親クラスを指定します。
superキーワードを使って、親クラスのコンストラクタを呼び出します。
子クラスで新たに定義するメソッドやプロパティがある場合は、親クラスには影響を与えずに子クラスに追加することができます。

*****

extends・superやプライベート化など、他言語とも変わりなく使用できるようです。
ただ、バージョンによって使用できないことを考えると、現場によっては使われていない場合もあるので、注意が必要です。
cscの作法 その298

# 概要
cscの作法、調べてみた。
delegate、使ってみた。

# 参考にしたページ。

https://qiita.com/night_bird/items/612ec8c1501f41e96f1a

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;

namespace _test
{
	public partial class Form1 : Form {
		private Button button1;
		private TextBox textBox1;
		public int count = 0;
		delegate void DelegatePutsMessage(int cnt);
		DelegatePutsMessage PutsCount = null;
		public Form1() {
			Text = "delegate";
			ClientSize = new Size(300, 200);
			button1 = new Button();
			button1.Location = new Point(130, 100);
			button1.TabIndex = 0;
			button1.Text = "count up";
			button1.Click += new EventHandler(button1_Click);
			textBox1 = new TextBox();
			textBox1.Location = new Point(30, 30);
			textBox1.Multiline = false;
			textBox1.Size = new Size(150, 20);
			textBox1.TabIndex = 2;
			Controls.AddRange(new Control[] {
				button1,
				textBox1
			});
			PutsCount = new DelegatePutsMessage(FuncPutsMessage);
		}
		private void button1_Click(object sender, EventArgs e) {
			this.count++;
			PutsCount(this.count);
		}
		private void FuncPutsMessage(int cnt) {
			textBox1.Text = "カウント + 1 = " + cnt;
		}
		[STAThread]
		public static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
bindingRedirect の再生成をする

# bindingRedirect の再生成をする

\# 以下の記事が書かれた時の版数は .NET Framework 4.8 となります.

`app.config` の `bindingRedirect` がおかしくなったときの再生成方法. というか、Git submodule と `bindingRedirect` の相性悪い.

1. app.config の `bindingRedirect` を全部手で消す
2. Visual Studio のパッケージマネージャのコンソールで `Add-BindingRedirect` を実行する
E1187: Failed to source defaults.vim が出ないようにする

# E1187: Failed to source defaults.vim が出ないようにする

いつの頃からか、Cygwin のパッケージをアップデートしたら以下のようなエラーが出るようになっていたのを対応したメモ.

```sh
$ vi
E1187: Failed to source defaults.vim
Press ENTER or type command to continue
```

ググって出てきた対応法を実施したが直らない. 何度か設定ファイル名が変わっているのだろうか?

どうやら vi --version で設定ファイルの現在の正しいパスが出力されるようだ,

```sh
$ vi --version
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Feb 13 2022 22:07:03)
～～～ 中略 ～～～
   system vimrc file: "/etc/virc"
     user vimrc file: "/home/Marco/.virc"
 2nd user vimrc file: "~/.vim/.virc"
      user exrc file: "$HOME/.exrc"
       defaults file: "$VIMRUNTIME/defaults.vim"
  fall-back for $VIM: "/usr/share/vim"
～～～ 後略 ～～～
```

というわけで以下で解決.

```sh
$ mkdir ~/.vim
$ mv ~/.vimrc ~/.vim/.virc
```
pi picoでmicropython その29

# 概要
picoでmicropythonやってみた。
Lチカ、やってみた。

# 環境
- windows10

# micropythonを焼く。

- bootselを押しながらUSBを刺す。
- エクスプローラーが開くので、ダウンロードした、rp2-pico-20220618-v1.19.1.uf2をペーストする。
- picoがリブートする。
- デバイスマネージャーでcom3が認識される。

# シリアルコンソールを起動。

https://qiita.com/ohisama@github/items/ba7de7062327ecf37c48

# Lチカ

```
led = machine.Pin(25, machine.Pin.OUT)
led.toggle()

```

以上。
React開発Part6～Context～

## はじめに
　こんにちは、Tunです。
今回は、Stateの管理について深堀していきたいと思います。
## stateの管理問題
　Reactにおいて、コンポーネントの構成が5階層の場合、一番上の階層のコンポーネントで定義している`state`を一番下の階層のコンポーネントに渡したい場合は、`props`で渡すことができます。
　しかし、この方法では問題点が多く、バケツリレーのように複数のコンポーネントにまたがって`state`の受け渡しが行われ、コードの複雑化や、再利用不可のコンポーネント、中間コンポーネントにおける無駄な`props`の受け取り、さらには一番下の階層のコンポーネントに`state`を渡そうとすると、全てのコンポーネントが再レンダリングされるというデメリットがあります。
　この、無駄なコードや挙動を減らすために`state`の管理方法を考えなければならないというわけです。

:::note note
**Global stateの管理方法**
:point_right:`useContext`以外にもReduxやRecoil、Apollo Clientなどがありますが、今回は`Context`の解説のみで、別の記事で他の管理方法を書きたいと思います。
:::
## Context
　上記の`state`の管理問題を解決してくれるオーソドックスな方法は、Reactが提供している`Context`を使うことです。

1. `React.createContext`で`Context`の器を作成する
2. 作成した`Context`の`Provider`でGlobal stateを扱いたいコンポーネントを囲む
3. `state`を参照したいコンポーネントで`React.useContext`を使う

　上記の手順で、Globalな`State`管理が可能になります。
詳しく解説:point_down:

１. まずは`Context`を保持するためのプロバイダーコンポーネントを`ExampleProvider.jsx`という名前で、providersというフォルダの配下に作成します。
```react:ExampleProvider.jsx
import { createContext } from "react";

export const ExampleContext = createContext({});
```
　これで`Context`の器の作成が完了しました。`createContext`の引数にはデフォルト値が設定でき、上記の例は空のオブジェクトが初期値になっています。

２. `Context`の器を作成しただけでは使えるようにはなりません。`Provider`でContextの値を参照したいコンポーネント群を囲む必要があります。
```react:ExampleProvider.jsx
import { createContext } from "react";

export const ExampleContext = createContext({});

export const ExampleProvider = props => {
 const {children} = props;

 //動作確認のためのオブジェクト
 const sampleObj = { sampleObj : "test" };

 //ExampleContextの中にProviderがあるのでそれでchildrenを囲む
 //valueにはグローバルに扱う実際の値を設定する
 return ( 
  <ExampleContext.Provider value={sampleObj}>
   {children}
  </ExampleContext.Provider>
 );
};
```
 `Provider`コンポーネントはなんでも囲めるように**Propsとしてchildrenを受け取る**ようにするのがポイントです。この`Provider`というコンポーネントには`value`というPropsを設定することができ、ここにグローバルに管理する実際の値を設定します。
```react:index.js
import ReactDOM from "react-dom";

import { App } from "./App";
import { ExampleProvider } from "./components/providers/ExampleProvider";

ReactDOM.render(
 <ExampleProvider>
  <App />
 </ExampleProvider>,
 documenet.getElementById("root")
);
```
　これで、Provider周りの準備が整いました。

３.実際にContextの値を参照してみましょう。
```ExampleUseContext.jsx
import { useContext } from "react";

import { ExampleContext } from "./components/providers/ExampleProvider";

const contextValue = useContext(ExampleContext);
console.log(contextValue); //{sampleValue : "test"}
```
　まず、Reactから`useContext`を`import`し、作成した`ExampleContext`もimportします。importした`useContext`の引数に参照するContextの値を指定します。
　このようにContextの値を使用するコンポーネント側では、**useContextを使いその引数に対象のContextを指定するだけ**で参照できます。

:::note warn
**再レンダリングに注意**
:point_right:Contextオブジェクトの値が何か更新されたときは、useContextでそのContextを参照しているコンポーネントは全て再レンダリングされます！
　なので、1つのContextに属性の異なるいろんなStateを詰め込むのは避けましょう。
:::

　次回はTypeScriptに軽く触れたいと思います:wave:

## 参照
- [モダンJavaScriptの基本から始める React実践の教科書](https://www.amazon.co.jp/%E3%83%A2%E3%83%80%E3%83%B3JavaScript%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%81%8B%E3%82%89%E5%A7%8B%E3%82%81%E3%82%8B-React%E5%AE%9F%E8%B7%B5%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E6%9C%80%E6%96%B0ReactHooks%E5%AF%BE%E5%BF%9C-Informatics-IDEA/dp/481561072X)
EC2作成時、詰まったところ

個人的に詰まったところ
名前解決を有効にすること
yum updateができない＞VPC作成時、DNSホスト名を有効化する
https://huamutou.hatenablog.com/entry/2019/09/20/101359

EC2立ち上げ後
ターミナルソフトからSSH接続ができない
OpenSSHがデフォルトでRSA/SHA1を無効にしている

対策
以下に対応したターミナルソフトなら接続は可能
rsa-sha2-256/512
https://ja.osdn.net/projects/ttssh2/releases/78350

ED25519で作成した方が手っ取り早かった
https://dev.classmethod.jp/articles/tsnote-ec2-rsa-sha-001/

ゴリ押し
以下へ設定ファイルへ追記すれば、接続は可能
/etc/ssh/sshd_config
＞PubkeyAcceptedAlgorithms=+ssh-rsa
https://dev.classmethod.jp/articles/tsnote-ec2-rsa-sha-001/
qmk_firmware 分離型キーボードで片方が反応しない



下記症状の改善
- ファームウェア書き込み後、片手ずつでは動作する
- 両手をTRRS/TRSケーブルで接続し、片手（primary側）をUSBケーブルにてPCにつなぐと、もう片手（secondary側）がまったく反応しない

QMKファームウェアで keymap.c あるいは config.h 等にて下記のように SPLIT_USB_DETECT を定義してファームウェアを焼き直しする。

```
#define SPLIT_USB_DETECT
```

参考: https://kochikbd.hatenablog.com/entry/2021/03/13/153000
cscの作法 その297

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

# 練習問題
ラズベリーパイpico用のシリアルコンソールを実装せよ。

# 方針
- ボーレイトは、115200
- シリアルポートは、COM3
- delegate使う。

# サンプルコード

```
using System;
using System.Windows.Forms;
using System.Drawing;
using System.IO.Ports;
using System.Threading;

class form1: Form {
	private Button button1;
	private TextBox textBox1;
	private static TextBox textBox2;
	private SerialPort port1;
	form1() {
		Text = "serial console";
		ClientSize = new Size(400, 400);
		button1 = new Button();
		button1.Location = new Point(300, 50);
		button1.TabIndex = 0;
		button1.Text = "send";
		button1.Click += new EventHandler(button1_Click);
		textBox1 = new TextBox();
		textBox1.Location = new Point(30, 20);
		textBox1.Multiline = false;
		textBox1.Size = new Size(300, 20);
		textBox1.TabIndex = 2;
		textBox1.Text = @"dir()";
		textBox2 = new TextBox();
		textBox2.Location = new Point(30, 80);
		textBox2.Multiline = true;
		textBox2.Size = new Size(300, 300);
		textBox2.TabIndex = 2;
		textBox2.Text = @"";
		port1 = new SerialPort("COM3", 115200, Parity.None, 8, StopBits.One);
		port1.BaudRate = 115200;
		port1.Parity = Parity.None;
		port1.DataBits = 8;
		port1.StopBits = StopBits.One;
		port1.Handshake = Handshake.None;
		port1.PortName = "COM3";
		port1.Encoding = System.Text.Encoding.ASCII;
		port1.NewLine = "\r\n";
		port1.DtrEnable = true;
		port1.RtsEnable = true;
		port1.DataReceived += new SerialDataReceivedEventHandler(DataReceived_Handler);
		port1.Open();
		Controls.AddRange(new Control[] {
			button1,
			textBox1,
			textBox2
		});
	}
	private void button1_Click(object sender, EventArgs e) {
		string msg;
		msg = textBox1.Text;
		port1.WriteLine(msg);
		textBox1.Text = "";
		Console.WriteLine(msg);
	}
	private delegate void SetTextDelegate(string msg);
	private static void SetText(string msg) {
		textBox2.Text = msg;
	}
	private void DataReceived_Handler(object sender, SerialDataReceivedEventArgs e) {
		SerialPort sp = (SerialPort) sender;
		string msg = sp.ReadExisting();
		Console.Write(msg);
		this.Invoke(new SetTextDelegate(SetText), new object[] { msg });
	}
	[STAThread]
	public static void Main() {
		Application.Run(new form1());
	}
}




```

# 実行結果

```
>pico4
dir()
dir()
['machine', '__name__', 'rp2']
>>>
```

以上。
オブジェクト指向・UML ステートチャート図とは

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！

今回は具体的なオブジェクト指向・UML ステートチャート図について更に詳しく調べてみましょう！
![インスタスライド_2023031703.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/0cba6c26-5a44-d46c-6ec3-8dcf8647b56c.gif)


# ステートチャート図
オブジェクトの状態の変化に着目し記述する。
画面と機能とデータが明確になる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/5ad855b2-a58e-df5e-e822-f787cedf9eb4.png)

# まとめ
ーUMLのステートチャートを知ろう

ーオブジェクトの状態の変化に着目し記述する。

ー画面と機能とデータが明確になる

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
JavaScript 初心者のメモ帳 ( 日付関係 )

JavaScript の勉強を始めたけど、色々と勝手が分からない為、
一度解決した問題の解決方法を忘れないようにメモする為の投稿です。
※胴体真っ二つにするくらいのマサカリ希望です。

##### 1. datetime-local に現在日時を分まで入力する。
```JavaScript
// input type = "datetime-local" に、現在日時を入力する方法。
// 表示例：2023/04/04 05:00
<input type = "datetime-local" id = "my_datetime_local">
<script>
    var now = new Date();
    //UTC 時刻に 9 時間足して日本時間にする。
    now.setHours(now.getHours() + 9);
    document.getElementById("my_datetime_local").value = now.toISOString().slice(0,16);
</script>
```

##### 2. datetime-local に現在日時を秒まで入力する。
```JavaScript
// input type = "datetime-local" に、現在日時を入力する方法。
// 表示例：2023/04/04 05:00:00
<input type = "datetime-local" id = "my_datetime_local">
<script>
    var now = new Date();
    //UTC 時刻に 9 時間足して日本時間にする。
    now.setHours(now.getHours() + 9);
    document.getElementById("my_datetime_local").value = now.toISOString().slice(0,19);
</script>
```

##### 3. 日時の加減算
```JavaScript
var now = new Date();
// 1 年加算
now.setFullYear(now.getFullYear() + 1);
// 1 年減算
now.setFullYear(now.getFullYear() - 1);
// 1 月加算
now.setMonth(now.getMonth() + 1);
// 1 月減算
now.setMonth(now.getMonth() - 1);
//1 日加算
now.setDate(now.getDate() + 1);
//1 日減算
now.setDate(now.getDate() - 1);
//1 時間加算
now.setHours(now.getHours() + 1);
// 1 時間減算
now.setHours(now.getHours() - 1);
// 1 分加算
now.setMinutes(now.getMinutes() + 1);
// 1 分減算
now.setMinutes(now.getMinutes() - 1);
// 1 秒加算
now.setSeconds(now.getSeconds() + 1);
// 1 秒減算
now.setSeconds(now.getSeconds() - 1);
```

##### 4. 指定年月日の曜日を取得
```JavaScript
// 今日の曜日を取得する例
// new Date() の引数の書式は "yyyy-MM-dd"。
// 引数の例："2023-04-03"
// 下記は 2023-04-03 に実行したので「月」の一文字が表示された。
var date = new Date(now.toISOString().slice(0,10)); //又は var date = new Date("2023-04-03");
date.setHours(date.getHours() + 9);
var daysOfWeek = ['日', '月', '火', '水', '木', '金', '土'];
var dayOfWeek = daysOfWeek[date.getDay()];
alert(dayOfWeek);
```


##### 5. 指定年月の末日を取得
```JavaScript
//第一引数は西暦、第二引数は月、第三引数は 0。
var lastDay = new Date(2016,2, 0);
//29 が表示される。
alert(lastDay.getDate());
```
Vim + npm install --save-dev textlint

# はじめに

これは[Vim駅伝](https://vim-jp.org/ekiden/)4/5の記事です

皆さんはVimで文章を書きますか？
僕は書きます。

Vimと[textlint](https://textlint.github.io/)を連携させ、快適なVimライフを送っている人も多いのではないでしょうか？
そんな方は、

```
npm install -g textlint
```

のように、グローバルインストールしたtextlintを使うことが多いと思います。
しかし、これにはデメリットがあります

- textlintの拡張もグローバルインストール必要がある
- 用途に応じてtextlintのルールを分ける方法がめんどくさい

また、僕はファイルを作らず、なぐり書きをした状態のテキストをtextlintに入力として渡したいと思ったことが多いです。

そこで今回は、

- ファイルを作らずに文字を書く
- バッファに書き込んだ文字を指定したルールのtextlintに入力として渡す
- Vimでtextlintの出力を見る

を目的とし、この目的を達成するための環境づくりを紹介したいと思います。

# いるもの

- Vim
- [textlint](https://textlint.github.io/)
- [vim-quickrun](https://github.com/thinca/vim-quickrun)


# 1. ルールごとにtextlintプロジェクトを作成する

今回は例として、日本語用のtextlintプロジェクトを作成します

- 日本語ディレクトリ

まずはホームディレクトリにtextlintプロジェクト用のディレクトリを作成します。

```
mkdir -p textlint-ja
cd textlint-ja
```

textlintプロジェクトを作成します

```
npm install --save-dev textlint
npm install textlint-rule-preset-ja-technical-writing
npx textlint --init
```

see also:

> https://textlint.github.io/docs/getting-started.html

これでtextlintの準備は完了です。

# 2. Vimの準備

今回の要件は

- ファイルを作らずに文字を書く
- バッファに書き込んだ文字を指定したルールのtextlintに入力として渡す
- Vimでtextlintの出力を見る

です。

これらの要件を満たすために以下のDraft関数を作成しました。

```vim
function! s:Draft()
  enew | setlocal buftype=nofile bufhidden=hide noswapfile
  " 指定するパスは、textlintプロジェクトのパス
  set ft=markdown | lcd $HOME/textlint-ja
  let g:quickrun_config['markdown'] = {}
  let g:quickrun_config['markdown']['exec'] = 'cat %s | npx textlint --stdin-filename draft.md --stdin'
endfunction
command -nargs=0 Draft call s:Draft()
```

やってることとしては

1. 新しく下書き用のバッファを作成する
1. 手順1. で作成されたバッファのファイルタイプをmarkdownに設定する
1. [lcd](https://vim-jp.org/vimdoc-ja/editing.html#:lcd)コマンドを使って、下書き用のバッファのカレントディレクトリをtextlintプロジェクトに移動させる。
1. vim-quickrunを設定する

です。

これでセットアップは完了です。

# デモ

1. :Draftを実行
1. 作成された下書きバッファに文字を書く
1. vim-quickrunを実行

これだけで、目的を達成できました


ここにデモを貼っておきます。
このように、ファイルを作らず、バッファに書き込んだ文字をそのままtextlintに渡せていますね！！！

![textlint.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278618/26769bea-21a4-3f98-def9-6ed6308b7306.gif)

# 改造例

上記の方法で目的を達成できましたが、改善点があります。
いくらか挙げておきます。

- textlintプロジェクトのパスをDraftコマンドで指定できるようにする
- Draftコマンドの定義をftpluginに書く
- visualモードで選択した範囲の文字をtextlintに入力として渡す

もし、この方法が気に入った方は、上記の改善例を試すとより豊かになると思います。

# まとめ

この方法であれば、よりtextlintを便利にVim上で使えると思うので是非試してみてください！！！

追記

> 時間に余裕があれば、改造例で挙げた構成も追記するかもしれません
2023/4/3主にITとかセキュリティの記事

Androidスマホに深刻なゼロデイ脆弱性。今すぐアップデートしよう(4/1)
https://news.yahoo.co.jp/articles/3923e1c1a55e26e5d41b8a1e8fb306fb7891d132?source=rss

漏えいデータから分析、業界別“ガバガバパスワード”集　海外セキュリティ企業が公開(3/30)
https://news.nicovideo.jp/watch/nw12337915

Apple、世界スマートフォンユーザー数でSamsungを上回ったことが判明(3/31)
https://iphone-mania.jp/news-531004/

関西電力を偽るフィッシング確認、注意を(4/1)
https://news.mynavi.jp/techplus/article/20230401-2640592/

顧客情報５２９万件流出か　ぷらら、ひかりＴＶで(3/31)
https://www.tokyo-np.co.jp/article/241316

NTTドコモ業務委託先からの利用者情報流出の可能性についてまとめてみた(4/1)
https://piyolog.hatenadiary.jp/entry/2023/04/01/003719

脳活動から「気分」を解読、究極のうつ病治療法になるか(4/1)
https://www.technologyreview.jp/s/292963/neuroscientists-have-created-a-mood-decoder-that-can-measure-depression/

ChatGPTに潜むAIリスクと今求められるAIガバナンス(3/31)
https://www.risktaisaku.com/articles/-/78058

ChatGPTの業務活用はまだこれから--Jitera、エンジニア向け調査結果を発表(4/1)
https://japan.cnet.com/article/35201963/

エン転職で２５万人超の履歴書漏えいか(3/30)
https://www.oita-press.co.jp/1002000000/2023/03/30/NP2023033001001542

高齢者を狙う特殊詐欺はなぜ減らない？ これがリアルに会わずにダマす手口だ(4/1)
https://news.yahoo.co.jp/articles/e824ba2e49b25ffd50fb865e630fd607713bc477?source=rss

「サイバー安全保障」にオール霞が関が集結…霞が関官僚の総動員態勢で行われた「合同会議」の中身(4/1)
https://gendai.media/articles/-/108443

自動運転「レベル４」解禁　自家用車は対象外―改正道交法施行(4/1)
https://www.jiji.com/jc/article?k=2023033100754&g=soc

皇室もネット発信強化へ　宮内庁に「広報室」 新設　初代室長に女性キャリア官僚(4/1)
https://news.yahoo.co.jp/articles/77c14f6f0118b42b36b664af5369e1313960c11c?source=rss
【Azure】Application Gatewayを停止して課金抑制

Application Gatewayは1ヵ月使いっぱなしにすると万単位の課金が発生します。本番運用ならいいですが、検証目的だとこの課金はつらい。検証のために作ってそのまま置いておくとコストがかかってしまう、しかし毎回消して作り直すのも大変…。と思っていたら、なんと停止して課金抑制できます。Azure Portalには停止するボタンが今現在は存在しないので、Azure PowerShellを使って停止します。

## 停止
~~~
$appgw = Get-AzApplicationGateway -Name <Application Gateway 名> -ResourceGroupName <リソースグループ名>
Stop-AzApplicationGateway -ApplicationGateway $appgw
~~~
停止には数分かかります。

## 起動
~~~
$appgw = Get-AzApplicationGateway -Name <Application Gateway 名> -ResourceGroupName <リソースグループ名>
Start-AzApplicationGateway -ApplicationGateway $appgw
~~~
起動にも数分かかります。
なお、停止状態でApplication Gatewayの設定を何か変更して保存すると、設定保存と同時に自動起動されてしまうのでご注意ください。
設定を参照するだけであれば起動しません。

## 状態確認
以下のコマンドを実行し、「OperationalState」を確認してください。
~~~
Get-AzApplicationGateway -Name <Application Gateway 名> -ResourceGroupName <リソースグループ名>
~~~
Azure PortalでApplication Gatewayの「プロパティ」画面を開くと、「動作状態」という項目があります。そちらからも実行中か停止済みか確認可能です。
stable-diffusion-webui-dockerがどうしてもGPUで実行できなかった件

# はじめに
stable-diffusionでえっちな女の子を生成しようとしたのですが、
どうしてもGPU版が動作せず(コンテナ生成が終わらない、止まる)、格闘したので解決策を残します。

色々試したのですが、クリティカルな方法だけ残します。

前提として以下を参考に実行環境などを作成しています。

https://zenn.dev/isi00141/articles/2fc745b11e8796

# 現象発生手順
stable-diffusion-webui-dockerをクローンする
```
git clone https://github.com/AbdBarho/stable-diffusion-webui-docker
```
ファイルのダウンロード
```
docker compose --profile download up --build
```
GPU版実行
```
docker compose --profile auto up --build
```
現象発生、コンテナ生成が終わらない、止まる。
その後portが占有されたままになるのでプロセスが死んでる感。

GPUを使用するための設定をいろいろ試しましたが解決しませんでした。
- WSLインストール
- Ubuntuインストール
- NVIDIAドライバ再インストール


# Dockerのバージョン4.17.1を使うな！！！！！！！
最新のDockerを使用するとコンテナ作成がうまくいかないそうです。

https://github.com/AbdBarho/stable-diffusion-webui-docker/issues/369

DockerDeskTopをアンインストールして以下の4.17.0をインストールしてください

https://docs.docker.com/desktop/release-notes/#4170

僕はこれで動きました

# 終わり
えっちな女の子のために１週間くらいつぶしました。
小学生のころを思い出します。
PHP ヒアドキュメント

## はじめに
業務でヒアドキュメントを使うことがあったのでその際に調べたことを簡単にまとめます。

## 環境
PHP 8.1.7

## ヒアドキュメント
ヒアドキュメントはPHPで文字列を扱う方法のうちの1つです。
「'」や「"」で囲って文字列を扱うことが多いですが、ヒアドキュメントという形式で文字列を扱うこともできます。

**ヒアドキュメントでは「<<<」のあとに任意のIDを指定し、文字列を置いた後でさらに「<<<」のあとに指定したID(終端ID)を置いて閉じることで文字列を定義します。**
```php
echo <<<EOM
    Hello
    World
EOM;
```
ヒアドキュメントで調べると「EOF」や「EOM」がIDで書かれていることが多いですが、ルールに沿っていれば任意のものを設定できます。ルールについては章末に記載しています。

上記のコードでは下記のように出力されます。
```
    Hello
    World
```

また、終端IDは通常のコードと同様に半角スペース、タブでインデントすることができます。(PHP 7.3.0からの仕様)
```php
echo <<<EOM
    Hello
    World
    EOM;
```
```
Hello
World
```
終端IDをインデントする際の注意点としては、上記の出力例のように**終端IDのインデントした分が文字列本体の全ての行から削除されます。**


## ヒアドキュメントの主なルール
- 最初のIDと終端IDは同じである必要がある
- 英数字およびアンダースコアのみを含み、 数字でない文字またはアンダースコアで始まる必要がある。
- 文字列本体、終端ID間でスペース、タブを混ぜてはいけない。
- 文字列本体にスペース、タブを混ぜてはいけない。
- 終端IDにスペース、タブを混ぜてはいけない。

## 参考文献
[PHP公式リファレンス](https://www.php.net/manual/ja/language.types.string.php#language.types.string.syntax.heredoc)
Power Automate for desktop を勉強する話

# Power Automate for desktopを勉強してみる！
新しい季節なので、積読しかけていた以下の書籍を勉強していこうと思います！

https://twitter.com/inaho3517/status/1632726377375092736?s=20

3月に頑張ると言っておきながらこの調子だったので、Qiitaにてアウトプットしようかと思います！

# 勉強内容
公開されている目次は以下の通りです。

　**＜基本編＞**
　　　第１章　Power Automate for desktopの基本を学ぼう
　　　第２章　[業務の自動化に必要な基本操作を覚えよう](https://qiita.com/inaho3517/items/d5f770c3e278d6b626e1 "Power Automate for desktop の基本操作を覚える")
　**＜活用編＞** 
　　　第３章　[Excelの作業を自動化しよう](https://qiita.com/inaho3517/items/490fe4e36b981ea2b135 "Power Automate for desktopでExcelの作業を自動化してみる")
　　　第４章　[Webフォームへの入力を自動化しよう](https://qiita.com/inaho3517/private/3eb2edd276b9c8222f97 "Power Automate for desktopでWebの操作を自動化してみる")
　　　第５章　業務シーン別のテクニックを覚えよう

上記の通り章立てになっておりますが、レッスンが50個用意されていて少しずつ勉強できる構成になっています。
これはありがたい！😊
# まずは基本編から！
まずは登場人物たちの会話で話が始まっていて、勉強に入りやすい構成！
普段の業務が自動化できるという内容なのでワクワクしながら次のページへ……。

……と、ここからはパソコンでPower Automate for desktopを使用できるよう準備から入る構成。
つど用語の解説もされていて、登録画面の画像も豊富で手順が分かりやすい。
さらにダメ押しでYouTube動画も用意されているなんて……🎥
これはITに詳しくない人や初めて触る人でも分かりやすい内容だと感じました🎶

とりあえず基本はOK！明日からは２章に取り組みます💪
stable-diffusion-webui-docker実行時に「webui-docker-auto-1 exited with code 137」で落ちる件

# はじめに
表題のとおりです。
stable-diffusion-webui-dockerを実行している時、一定時間経過後「webui-docker-auto-1 exited with code 137」でDockerが落ちてしまう現象に遭遇しました。
その解決策についいて記載します。

# 対策
## Dockerに割りあてるメモリを増やす
stable-diffusion-webui-dockerがそもそも起動しないケースでも有効な対策なのですが、
Dockerに割り当てるメモリを12GB以上にします。

Macの場合はDockerDeskTop上で変更できます。
Windowsの場合はユーザーホームディレクトリ以下に「.wslconfig」ファイルを作成してください。
windowsの場合の手順は以下を参考にしてください。

https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config

私は以下の設定にしています。
```
[wsl2]
memory=12GB
```

# 低メモリ向けの設定で実行する
以下の内容に従って低メモリ向けの設定で実行するようにします。

https://stealthinu.hatenadiary.jp/entry/2022/10/07/160746

Docker-composeファイルってオーバーライドできるの知らなかった。。。

フォルダ直下に「docker-compose.override.yml」を作成して以下の内容に変更してください。
```
services:
  auto:
    environment:
      - CLI_ARGS=--lowvram
```

autoの部分は実行する構成によって書き換えてください。
私はautoにしていますが、CPU版を使用する場合はauto-cpuに変更するとよいはずです。
(CPUは動作未確認)

# 終わり
えっちな女の子を生成するために頑張りました。
【Spigot】ItemStack#addEnchantment と ItemMeta#addEnchant の違い

# 何が違うの?
__:arrow_right: エンチャントを付与できるアイテムに違いがある__


# コードを見てみる

> [Spigot ItemStack#addEnchantment](https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/inventory/ItemStack.java#389)

398 行目で 429 行目 - 434 行目の addUnsafeEnchantment(Enchantment,int) を呼び出している。
```java
398: addUnsafeEnchantment(ench, level);
```
```java
429: public void addUnsafeEnchantment(@NotNull Enchantment ench, int level) {
430:         ItemMeta itemMeta = (meta == null ? meta = Bukkit.getItemFactory().getItemMeta(type) : meta);
431:         if (itemMeta != null) {
432:             itemMeta.addEnchant(ench, level, true);
433:         }
434:     }
```
432 行目で `itemMeta#addEnchant` を呼び出しているので `ItemStack#addEnchantment` と `ItemMeta#addEnchant` は同じように振舞う......ように見えるが、 394, 395, 396 行目でツール類以外のアイテムであった場合に `IllegalArgumentException` を出すように書かれているので多少の違いがある。
(.canEnchantItem が true なアイテムはツール類のみ)
```java
394: else if (!ench.canEnchantItem(this)) {
395:             throw new IllegalArgumentException("Specified enchantment cannot be applied to this itemstack");
396:         }
```

# 風のうわさ
追加で調査をしたところ

__「ItemStack#addEnchantment は将来廃止されるかもしれないので ItemMeta#addEnchant を使うことを推奨する (意訳)」__

という文章を見かけたのでここに記す。

> [Spigot Forum 
"Difference between ItemStack.addEnchantment and ItemMeta.addEnchant"](https://www.spigotmc.org/threads/difference-between-itemstack-addenchantment-and-itemmeta-addenchant.424917/)
>
> _"ItemStack#addEnchantment(...) is just an easy-access method, but internally it just calls the ItemMeta#addEnchant(...) method.
You should stick to the latter one though, as the first one might get removed in the future. Other easy-access methods that modify the meta have been removed in the past."_

なお、公式声明ではないため信頼性は０である。本当にただの風の噂でしかない。


# まとめ
`ItemMeta#addEnchant` : どんな状況でもエンチャントを付与できる。ただし、#getItemMeta で呼び出さなければならない。

`ItemStack#addEnchantment` : ItemStack から直接操作できる。ただし、ツール類以外にはエンチャントを付与できない。
LightGBM

# LightGBM
https://lightgbm.readthedocs.io/en/latest/index.html
分類モデル
```.py
from lightgbm import LGBMClassifier
model=LGBMClassifier(
    objective='binary',    #---------2値分類：'binary', 3値以上分類：'multiclass'
    n_estimators=100,      #---------繰り返し数（作成する決定木の数,デフォルト:100）
    max_depth=3            #---------作成する木の深さの最大値(大きいほど過学習傾向)
    learning_rate=0.1      #---------繰り返しごとに前のモデルを修正する係数（デフォルト:0.1）
    colsample_bytree=1,    #---------各決定木においてランダムに抽出される列の割合(大きいほど過学習寄り,デフォルト:1)
    num_leaves=31,         #---------1本の木の最大葉枚数(大きいほど過学習寄り,デフォルト:31)
    min_child_samples=20,  #---------1枚の葉に含まれる最小データ数(小さいほど過学習寄り,デフォルト:20)
    class_weight='balanced'#---------'balanced'に設定すると各クラスのサンプル数に応じて重みを付ける（各クラスのサンプル数に偏りがあるときに指定）
    subsample=1,           #---------各決定木においてランダムに抽出される標本の割合(大きいほど過学習寄り,デフォルト:1)
    subsample_freq=1       #---------サンプルを復元抽出（バギング）する頻度(小さいほど予測精度改善,ただし0では復元抽出しない,デフォルト0)
```

回帰モデル
```.py
from lightgbm import LGBMRegressor
model=LGBMRegressor(
        n_estimators=100,      #---------繰り返し数（作成する決定木の数,デフォルト:100）
        max_depth=3            #---------作成する木の深さの最大値(大きいほど過学習傾向)
        learning_rate=0.1      #---------繰り返しごとに前のモデルを修正する係数（デフォルト:0.1）
        colsample_bytree=1,    #---------各決定木においてランダムに抽出される列の割合(大きいほど過学習寄り,デフォルト:1)
        num_leaves=31,         #---------1本の木の最大葉枚数(大きいほど過学習寄り,デフォルト:31)
        min_child_samples=20,  #---------1枚の葉に含まれる最小データ数(小さいほど過学習寄り,デフォルト:20)
        subsample=1,           #---------各決定木においてランダムに抽出される標本の割合(大きいほど過学習寄り,デフォルト:1)
        subsample_freq=1       #---------サンプルを復元抽出（バギング）する頻度(小さいほど予測精度改善,ただし0では復元抽出しない,デフォルト0)   
    )
```


特徴率の寄与率出力
```.py
model.feature_importances_
```

ツリーを表示
```.py
from lightgbm import plot_tree as l_plot_tree
import matplotlib.pyplot as plt

fig,ax=plt.subplots(figsize=(20,10))
l_plot_tree(model,ax=ax,tree_index=4)
```