OmniAICreator/Qiita-1.07M huggingface dataset:
Streamlit で驚くほど簡単に地図を表示できた話

以前から、聞いたことはあるけど使ったことがなかった **Streamlit** なのですが、キャッチアップする時間を確保できたので色々と検証していたところ、（筆者の主観ですが）驚くほど簡単に地図を表示できたので、ここにメモしておきたいと思います。

コードは次の通りです。

```python
import streamlit as st

st.map()
```

たったこれだけで地図が表示できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/20364eb4-1a35-d7e1-9c53-acc064279970.png)

ちなみに、streamlit のバージョンは `1.32.2` を使用しました。

`st.map()` は `st.pydeck_chart()` のラッパーだそうで、3D マップや点群などもサポートしているそうです。

[公式サイト](https://docs.streamlit.io/library/api-reference/charts/st.map)では `st.map()` や `st.pydeck_chart()` の仕様やパラメータについて確認ができます。

## 県庁所在地をプロットしてみる

折角なので、県庁所在地をプロットしてみます。
今回は熊本、宮崎、鹿児島の３県分の緯度経度データを用意してみました。
※緯度経度は[こちらのページ](https://qiita.com/yasuman/items/bfd385424fe58f8bfab6)から拝借しました。

```python
import streamlit as st

# 緯度経度データ（10進数）
pref_list = [
  {"longitude":130.741667, "latitude":32.789828}, # 熊本県
  {"longitude":131.423855, "latitude":31.911090}, # 宮崎県
  {"longitude":130.557981, "latitude":31.560148}, # 鹿児島県
]

st.map(pref_list)
```

プロットも非常に簡単で、データを用意して`map()` に渡すだけです。
pandas.DataFrame や Iterable、dict など、多数の型に対応しているようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/759747/04ef1e5e-c474-8599-9194-9976e3653196.png)

すこし見づらいかも知れませんが、３つの赤い点がプロットされていることを確認できるかと思います。

## さいごに

筆者はまだ試せていませんが、folium を Streamlit で使うためのラッパーである **streamlit-folium** もあるようで、こちらを使えば、よりリッチな表現ができそうです。

また、streamlit インストール後に `streamlit hello` コマンドを実行するとデモページを起動することができ、こちらのデモページは見ているだけでも楽しかったので、興味のある方は是非ご覧ください。地図を使ったデモも用意されています。
proxmoxVE を eMMC に インストールする。

執筆時点で proxmox VE インストーラーは 8.1-2

https://internet.watch.impress.co.jp/docs/column/shimizu/1551702.html

ここを参考に 作業を 進めていった。

▼Proxmox VEのダウンロード

https://www.proxmox.com/en/proxmox-virtual-environment/overview

から isoファイルを ダウンロードした。

次に USBライターとして imageusb を つかったんだけど 私の使い方がわるかったのかブートできないUSBメモリが できてしまったので 記事に ある Raspberry Pi Imager を 使うことにした。

最初 Raspberry Pi Imagerを 使おうとしたんだけど バージョンが 上がってる上に使い方がわからなかったからimageusb に 浮気したんだけど 失敗して 戻ってきたというわけだ。

見つけ出した手順 は 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125882/96c48164-e8a8-079e-0d48-b4bc62e89d56.png)

OS を 選択するときに 一番下の Use Custom を 選択して ISOファイルを 選択したらよかった。

ストレージで 書き込み対象の USBフラッシュメモリー を 選択して つぎへ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125882/630e0fb1-443c-cb7d-7fb1-23d28c320027.png)

選択すると このような画面に なり 次へが 押せるようになる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125882/01a26577-9642-a62d-3c02-aeb64a65c2ec.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125882/1a19f431-f165-0934-d0fb-614e04c70dd1.png)

カスタムセッティングは いいえ を 選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125882/647e5830-b6ae-7371-1eca-66eec1442527.png)

警告は はい を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125882/356aa9c4-3aee-dcf0-6efa-38756892cd37.png)

書き込みが 始まって 確認が おわると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125882/c1a27757-2935-bf44-a0f1-dabebd356184.png)

と表示され 書き込みが 完了しました。

インストール先のミニPC 
今回は 2機種 ある。 
一つは GMKtecの N100 もう一つは ECSの LIVA Z で こちらは N4200だ

GMKtecのは 最近の PCらしく NVMe M.2 SSD なのだが
LIVA Z は 当時一世を風靡した eMMC である。

GMKtecのには さくっと インストールできたんだけど
LIVA Z は すんなりとは いかなかった なので このように記事にしている。

インストールしていると

Unable to get device for partition 1 on device /dev/mmcblk0

と 表示されてしまうのだ。

ググったら 

https://deflis.hatenablog.com/entry/2023/08/21/015821

が 見つかってこの中に やり方が 書いてあった。この記事の元ネタは 

https://ibug.io/blog/2022/03/install-proxmox-ve-emmc/


/usr/share/perl5/Proxmox/Sys/Block.pm に次のブロックを 追加するというものだった。

```perl
 } elsif ($dev =~ m|^/dev/mmcblk\d+$|) {
     return "${dev}p$partnum";
```

実際には 

```perl
 } elsif ($dev =~ m|^/dev/[^/]+/hd[a-z]$|) {
     return "${dev}$partnum";
 } elsif ($dev =~ m|^/dev/nvme\d+n\d+$|) {
     return "${dev}p$partnum";
 } else {
     die "unable to get device for partition $partnum on device $dev\n";
 }
```
を
```perl
 } elsif ($dev =~ m|^/dev/[^/]+/hd[a-z]$|) {
     return "${dev}$partnum";
 } elsif ($dev =~ m|^/dev/nvme\d+n\d+$|) {
     return "${dev}p$partnum";
 } elsif ($dev =~ m|^/dev/mmcblk\d+$|) {
     return "${dev}p$partnum";
 } else {
     die "unable to get device for partition $partnum on device $dev\n";
 }
```
と 変更する

実施手順は 

インストーラーをデバッグモードで起動する。

起動オプションを「もっと見る」するとグラフィカルデバッグモードがあるので、それを起動します。
1回目のデバッグコンソールはまだ最低限のLinux環境しか読み込まれていないので、無視して exit か Ctrl+D して次に進めます。
2回目のデバッグコンソールはインストーラを起動する直前の状態で止まるのでここで作業をします。
vi か nano で /usr/share/perl5/Proxmox/Sys/Block.pm を開きます。
修正して 保存したらdebug用の シェルを終了したら インストーラーが 起動するのでeMMCへのインストールが うまくいくはずです。

さっそく、実行したところ インストールできました。

https://設定したIP:8006 に アクセスして

ユーザ名 root パスワードは インストール時に設定したパスワードで ログインできました。
古いバージョンのglibcを用いる実行モジュールのビルド環境をlxdでサクッと構築する手順

# はじめに

Steam で Linux に対応したゲームを配信しているのですが、ユーザーさんから [「glibc のバージョンを下げてくれないか？」](https://steamcommunity.com/app/2824990/discussions/0/4355617421470222247/) と依頼されました。

Linux 版のゲームを自分の PC (Ubuntu 22.04.4 LTS) でローカルビルドしたものをリリースしていたのですが、その環境の glibc は 2.35、実行モジュールの glibc バージョンは 2.34 となっています。

（glibc のバージョン確認）

```
$ ldd --version
ldd (Ubuntu GLIBC 2.35-0ubuntu3.6) 2.35
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.
```

（ゲームモジュールの依存 glibc バージョンの確認方法）

```
$ readelf -W -a '~/.local/share/Steam/steamapps/common/Battle Marine/bmarine' | grep libc_start_main
0000000000285fb0  0000002100000006 R_X86_64_GLOB_DAT      0000000000000000 __libc_start_main@GLIBC_2.34 + 0
    33: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.34 (4)
  1082: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.34
```

ビルド環境の Linux はもっと低いバージョンの Linux にする必要がありそうです。

# コンテナでビルド環境を構築

もちろん、自分の PC の Linux バージョンは下げたくないので、ビルド用に古い Linux のコンテナを作ります。

コンテナといえば Docker がよく使われるかもしれませんが、今回のケースなら lxd の方が軽くて良い感じでしたので、私が実施した構築手順を共有します。

## lxd を準備

```bash
sudo snap install lxd
sudo lxd init
```

:::note info
lxd init の設定項目は全部デフォルト（enter）
:::


## コンテナ作成

```bash
lxc launch ubuntu:18.04 steam-build
```

:::note warn
当初、なるべく古いバージョンが良いかと思い ubuntu は 16.04 をインストールしてみたのですが、ネットワークが繋がらないなど色々と不便だったので 18.04 を使うようにしました。（多分、古いバージョンを使うには色々と面倒な設定が必要なはず）
:::

## コンテナへのログイン

```bash
lxc exec steam-build bash
```

コンテナにビルド環境を構築

```bash
sudo apt update
sudo apt install build-essential
```

あとは github の環境設定なりをしてビルドするだけです。

なお、コンテナから外部ホストへの通信がタイムアウトする場合は iptables の変更などが必要になるかもしれません。

https://qiita.com/engishoma/items/7226c884247be5b1290e

この環境でビルドしたモジュールの GLIBC バージョンは 2.2.5 になりました。

```bash
$ readelf -W -a bmarine | grep start_main
000000000047cfd0  0000005a00000006 R_X86_64_GLOB_DAT      0000000000000000 __libc_start_main@GLIBC_2.2.5 + 0
    90: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@GLIBC_2.2.5 (3)
  2567: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_2.2.5
```

## コンテナの起動・停止・削除

```bash
# 起動
lxc start steam-build

# 停止
lxc stop steam-build

# インスタンス削除
lxc delete steam-build
```

# もっと美しい対処

今回、GLIBC のバージョンを下げる対応をしましたが、GLIBC のバージョンを下げなくてもコンパイルとリンク時に次のオプションを指定することで GLIBC バージョン依存の問題を解消できるようです。

```
-static-libgcc -static-libstdc++ -ftls-model=global-dynamic
```

> - -static-libgcc will dodge libgcc ABI issues (which are common)
> - -static-libstdc++ will dodge c++ ABI issues (which are legions and happening all the time)
> - -ftls-model=global-dynamic will spare ELF static TLS slots for system libs (because they are somewhat rare)

私はビルド環境の CI 化のためにコンテナを用いる方式も別途検討していて、その方式の方が色々とリスクが少ないかなということでコンテナ方式を採用しましたが、こちらの対処方法の方が良いと思います。

今回はこのオプションを付与しつつ古いバージョンのGLIBCを使う安全策を取っておいたので、今後GLIBCのアップデートが必要になっても同じ問題を回避できるかもしれません。
エンジニアに坊主をオススメしたい

## はじめに
私自身半年前まで短髪でしたが坊主ではありませんでした。あることをきっかけに坊主にして時間が増えた話をしたいと思います。坊主過激派の意見ですので軽くお読みいただければ幸いです

## きっかけ
坊主にしたきっかけは子供が生まれたことでした。
より具体的な理由は下記３つです。

① バリカンに失敗した　
② 髪を切りに行く時間が勿体無い　
③ 節約

## 背景
### 髪
散髪の2回に1回はバリカンとセルフカットしていました。
元々短髪のため2週間もすると切りたくなるためです。
後頭部のカットが特に難しく失敗しがちです。

### 私生活と坊主に至るまで
子供が生まれると可処分時間も可処分所得も減ります。
無情にも伸びる髪をどうしようかと悩むならいっその事坊主にしてしまおうと思い頭を丸めるに至りました。バリカンの失敗がトリガーです。バリカンの失敗をバリカンで取りもどします。

下記記事のように人それぞれですが生活の変化は大きいです。

https://qiita.com/JY8752/items/d9ffda5d36237c44cede

## 坊主のメリット
**時間とお金の確保**
髪に関する事象は短く、少なくなります。
 - バリカンがあれば床屋、美容院代が掛からない
 - シャンプーが少量で済む
 - ドライヤー要らない
 - 髪の毛が落ちないので掃除が減る
 - ヘアセット要らない
 などなど

現代ではますますコスパ・タイパが叫ばれますが坊主は優秀です。

**認知資源を確保できる**
決断する回数を減らして大事な決断に使おうってやつです。髪に関する考えや決断はゼロに近づきます。唯一エンジニアらしい話ができました。私はここまで深く考えて坊主はやっていないですが...

> 効率化といえば、「世界の偉人はいつも同じ服を着ている」ということが一部で知られています。たとえばフェイスブックのマーク・ザッカーバーグはいつもグレーのＴシャツにジーンズをはいています。アップルのスティーブ・ジョブズは黒のタートルネックにジーンズをはいていました。

> それは彼らが日常のささいな決断の数を減らそうとしているからだそうです。日々たくさんの人と会い、様々な意思決定を行う彼らは、普段から大きな決断を迫られています。そのため会社の経営や政治に関わる重大な決断をするときに脳が疲れないよう、無駄な決断をしないようにしているのだそうです。無駄な決断とは、ここでは服選びのことを指します。 　心理学では、決断や意思決定をする際に減少する気力のようなものを「認知資源」という名前で呼んでいます。この言葉を使うと、つまり世界の偉人は、認知資源を経営や政治のために温存しているということになります。服選びなどのつまらない決断で疲れるのを避けようというわけです。
 -『なぜ、あなたの仕事は終わらないのか スピードは最強の武器である』中島聡著

 私ももれなくユニクロ白Tエンジニアでもあります。

**その他**
涼しい
清潔を保ちやすい
ジョリジョリ触るのが楽しい

## デメリット
**ハードルが高い**
性別問わず坊主のハードルは間違いなく高いです。坊主は極論なので初めはショート、ベリーショートから始めてみるのもいいでしょう。ある程度の効果を得られると思っています。

**元に戻す難しさ**
個人差はあれど男性の一般的な髪の長さにするのに半年はかかりそうです。伸ばしている間もバランスが難しいです。

**冬は寒い、頭皮を紫外線から守りづらい**
→ 帽子で解決できます

**怖い人に見られることもある**
→ 笑顔で過ごしましょう


## おすすめのバリカン
なるべく細かい設定ができ、設定できる長さは短ければ短い程よいです。短さを追い求めたくなるためです。防水機能があると水洗いができるので便利です。

憧れのバリカン

https://panasonic.jp/mens/products/hair/er-sc61.html

## まとめ
今回焦点を当てたのは坊主ですが様々なアプローチで時間の節約や質を上げることはできると思います。坊主も一つの選択肢としてエンジニアの皆さんにおすすめしたいです。

大前研一さんの言葉を残しておきます。
>人間が変わる方法は3つしかない。
１番目は時間配分を変える。
２番目は住む場所を変える。
３番目はつきあう人を変える。  


## 最後に
私の働いている会社で経験の有無を問わず採用を行っています。
興味のある方は是非カジュアル面談から応募してみてください！

https://jambo-support.com/recruit_engineer/
Figmaでデザインを作成する時のTips（基礎編）

案件や個人学習をする時にFigmaを使う機会が増えてきました。
個人的に身につけて良かった内容を「準備編」「基礎編」「応用編」に分けて、投稿していきたいなと思います。
少しでもお役に立てたら幸いです。
※約5分で読めます。

:::note info
過去記事はこちら
:::

https://qiita.com/hirokazu_nakao/items/167fbacc34c5cfde535f

https://qiita.com/hirokazu_nakao/items/a93c8f688e6858d95a02

今回は基礎編ということで、今回は**ショートカットキー**をご紹介します。
普段から操作を覚えておくことで作業効率がどんどん上がるので、ぜひ覚えていってください！

# 1. ショートカットキーの確認方法

```
Control + Shift + ?
```
押下後、以下のショートカットキーの一覧を確認することができます。
水色が利用したことのあるものです。

![スクリーンショット 2024-04-05 6.34.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/eefab06e-c1f5-c2ad-344e-aeabc518c2d4.png)

ある程度ショートカットキーが使える様になったらこちらの水色以外のショートカットキーを使ってみるのも良さそうですね！


# 2. 利用頻度 ： ★★★ （基本中の基本）

```
①移動ツール : V
②フレームツール : F 
③テキストツール : T
④長方形ツール : R
⑤線ツール : L
⑥楕円ツール : O
⑦コメント : C
⑧コピー : Command + C
⑨切り取り : Command + V
```

上記のショートカットキーを覚えておくだけでだいぶ作業効率が上がります！

:::note info
GIFで比較しようと思ったんですが「比較しにくいな...」と思いやめました
すみません
:::


# 3. 利用頻度 ： ★★☆ （使いこなせるとだいぶ楽になる）

```
①選択範囲のグループ化 : Command + G
②選択範囲のグループ解除 : Command + Delete
③オートレイアウトの追加 : Shift + A
④ネスト選択 : Command + クリック
⑤すべて選択 : Command + A
```
①：要素同士をくっつけたい時に便利です
②：くっつけた要素に修正を加える時に便利です
③：ナビゲーションやリスト等、要素を等間隔で配列表示できます
④：要素がくっついてる時、下の階層にある要素を一撃で選択できます
⑤：要素を一気に選択できます

# 4. 利用頻度 ： ★☆☆ （たまに使うがめちゃ便利）

```
①:アウトラインの確認 : Command + Y
②:UIの表示・非表示 : Command + .
```
動画の方が分かりやすいと思うので以下ご覧ください！

①：アウトラインの確認することで不要な要素を発見・削除することができます。

![GIF1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/b3f82b69-90cf-c6bc-aae0-d532cda49ff3.gif)

②：左右のサイドバーを指します。すぐ非表示にしたい！そんな時に便利です。

![GIF2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/038598a6-831c-991e-1847-9c3ab94f5bf4.gif)

# 5. さいごに

いかがだったでしょうか？
はじめは慣れないので使いづらいですが、慣れてくると作業効率が目に見えて上がります。
ぜひお試しください。

最後は「応用編」、Figmaを使う際に困ったことと解決策をご紹介する予定です。


**最後までご覧いただきありがとうございました！**
【iframe】YouTube埋め込み用URLの取得方法

## はじめに
iframeタグにYouTube動画を埋め込む際に埋め込み用のURLを取得したい場合があります。
PCを使っての埋め込み用URLの取得は容易ですが、スマホを使っての埋め込み用URLの取得が少し手間だったので、備忘録としてまとめます。

## 前提
スマホでYouTubeの埋め込み用URLを取得する場合は、YouTubeアプリではなくブラウザで動画を開く必要があります。
そのため、ここでは以下のブラウザについて取得方法をまとめています。

- Chrome
- Safari

## Chrome

|1.&nbsp;右下の「・・・」<br>をクリック&nbsp;|2.&nbsp;「PC版サイトを見る」<br>をクリック&nbsp;|3.&nbsp;「共有」をクリック&nbsp;|
|---|---|---|
|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/4517d652-da96-24bc-814b-68d078571f0a.png">|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/c2818909-4e53-f18e-7385-64fdcc920950.png">|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/9de4b8e6-bcb1-6f29-b388-62db7c548c18.png">|

|4. 「埋め込む」をクリック|5. iframeタグ内の<br>srcパラメータの内容＝埋め込み用URL|
|---|---|
|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/2baae753-e4e7-6ad6-bab3-917d36318add.png">|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/7af30267-6d64-397d-dc58-c2a702841586.png">|



## Safari

|1. 左下の「ぁあ」<br>をクリック|2.「デスクトップ用Web<br>サイトを表示」をクリック|3. 「共有」をクリック|
|---|---|---|
|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/52e7e5b9-48e8-cbed-7263-3ae675a63ae4.png">|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/fdb627b5-a80c-b938-4b44-b452690a53d0.png">|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/eef1e9bc-a9a3-1d15-5d2c-285a6f070c02.png">|

|4. 「埋め込む」をクリック|5. iframeタグ内の<br>srcパラメータの内容＝埋め込み用URL|
|---|---|
|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/7bfdac01-d611-9069-25a5-4d225704caab.png">|<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2145496/db3e114d-9df2-3d2c-cc9d-026d9ac67792.png">|
スケジュール管理ExcelVBA

他環境で試していないソースを記述するのはどうかと思いつつ
スケジュール管理が手いっぱいになってきたので管理用の通知を作成してみた。

簡単な仕様としては
スケジュールシートを作成し
A列：日付
B列：時間
C列：メッセージ
D列：チェック（OKが入力される）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3758592/272f5a7d-52f8-7735-85f2-fccf421f3b04.png)



#### 仕様としては
10分後のタイミングで本日日付とD列とE列が合致及びF列にOKが無い状態のレコードを通知バックグラウンドで立ち上げた状態で時間が来たらC列を通知する


#### ■リマインド部分
```ScheduleReminder
Public Sub ScheduleReminder()
    Dim ws As Worksheet
    Dim targetDate As Date
    Dim targetTime As Date
    Dim message As String
    Dim lastRow As Long
    Dim i As Long
    Dim reminderFlag As Boolean

    ' スケジュールが記録されたシートを指定します
    Set ws = ThisWorkbook.Sheets("スケジュール")

    ' 今日の日付と時間を取得します
    targetDate = Date
    targetTime = Time

    ' 最終行を取得します
    lastRow = ws.Cells(ws.Rows.Count, "E").End(xlUp).Row

    ' スケジュールをチェックし、条件に合致する場合に通知を行います
    For i = 2 To lastRow ' 1行目はヘッダーなので無視します
        Dim scheduledDateTime As Date
        Dim scheduledtargetDateTime As Date
        scheduledDateTime = DateValue(Format(ws.Cells(i, "D").Value, "YYYY/MM/DD")) + TimeValue(Format(ws.Cells(i, "E").Value, "hh:mm"))
        scheduledtargetDateTime = targetDate + targetTime
        If scheduledDateTime <= scheduledtargetDateTime And ws.Cells(i, "F").Value <> "OK" Then
            ' スケジュールされた日時が現在の日時を過ぎている場合に通知を行います
            message = ws.Cells(i, "B").Value
            MsgBox "リマインダーメッセージ: " & message, vbInformation
            ' リマインダーが存在することを示すフラグを立てる
            reminderFlag = True
        End If
    Next i

    ' リマインダーフラグがTrueでない場合、リマインダーは存在しない
    If reminderFlag = False Then
        MsgBox "リマインダーメッセージはありません。", vbInformation
    End If
    ' タイマー再設定
    StartTimer
End Sub
```
<br>

#### ■タイマー設定（１０分後に再度実行）
```StartTimer
Sub StartTimer()
    ' 10分ごとにマクロを実行するためのタイマーを開始します
    Application.OnTime Now + TimeValue("00:10:00"), "ScheduleReminder"
End Sub
```
<br>

#### ■タイマー停止
```StopTimer
Sub StopTimer()
    ' タイマーを停止します
    On Error Resume Next
    Application.OnTime EarliestTime:=Now + TimeValue("00:10:00"), Procedure:="ScheduleReminder", _
        Schedule:=False
    On Error GoTo 0
End Sub
```

本来は立ち上げたタイミングで実行したかったが手動実行ボタンなどを付けて一度実行させておけばあとはタイマーが起動してくれるはず。
cscの作法 その475

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

# 練習問題
treeviewを、使え。

# 参考にしたページ

https://bsofsys.com/2022/09/27/csharp-treeview/ 


# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/d5e2d5e9-b6c7-7d20-97e3-bbd89fdfc9b7.png)

# サンプルコード

```
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO;

namespace App
{
	class DirTreeNode: TreeNode {
		public DirTreeNode() {
		}
		public DirTreeNode(string directoryName, string directoryPath) : base(directoryName) {
			DirectoryPath = directoryPath;
		}
		public string DirectoryPath {
			get;
			set;
		}
	}
	public partial class Form1: Form {
		private TreeView treeView1;
		public Form1() {
			ClientSize = new Size(500, 300);
			Text = "TreeView";
			treeView1 = new TreeView();
			SuspendLayout();
			treeView1.Dock = DockStyle.Fill;
			treeView1.HotTracking = true;
			//treeView1.ImageList = imageList1;
			treeView1.Location = new Point(10, 10);
			treeView1.Name = "treeView1";
			treeView1.Size = new Size(480, 280);
			treeView1.TabIndex = 0;
			treeView1.BeforeExpand += new TreeViewCancelEventHandler(treeView1_BeforeExpand);
			Controls.AddRange(new Control[] {
				treeView1
			});
			DirTreeNode driveNode = new DirTreeNode("C:Neos", "C:\\Neos");
			treeView1.Nodes.Add(driveNode);
			driveNode.Nodes.Add(new DirTreeNode());
		}
		private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e) {
			DirTreeNode dirNode = (DirTreeNode) e.Node;
			dirNode.Nodes.Clear();
			foreach (string directoryPath in Directory.GetDirectories(dirNode.DirectoryPath))
			{
				DirectoryInfo directoryInfo = new DirectoryInfo(directoryPath);
				if ((directoryInfo.Attributes & FileAttributes.System) != FileAttributes.System)
				{
					DirTreeNode subDirNode = new DirTreeNode(directoryInfo.Name, directoryPath);
					dirNode.Nodes.Add(subDirNode);
					if (Directory.GetDirectories(directoryPath).Length > 0)
					{
						subDirNode.Nodes.Add(new DirTreeNode());
					}
				}
			}
		}
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
	}
}





```

以上。
Node.js のサポート期間を８年に延ばせるひとつのやり方

先日、「[Javaエンジニアのための Nodejs/Nuxt3入門](https://speakerdeck.com/hidekatsu_izuno/nuxt3ru-men)」という資料を公開したのですが、Node.js がすでに業務システムを作るのに十分な環境が整っています。しかし、どう考えても導入を進めるためのネックになっている項目があります。それは LTS （長期サポート）の短さです。

Node.js のランタイムは偶数バージョンが LTS となっており、リリースの半年後に長期サポートが始まり 30 カ月後にはセキュリティ・パッチの提供が受けられなくなります。実はこの 30 カ月という期間は、PHP（3年） や Ruby（3 年 3カ月） といった他の言語ランタイムに比べて特別短いわけではないですし、JavaScript の言語としての安定性を考えれば、気軽にメジャーバージョンアップをすればいいと思うのですが、これがこと業務システムとなると大問題になります。

業務システムの開発に長く携わっていると、多くの日本企業が EOL（製品のライフタイム終了）を非常に気にしていることに気付かされます。システムの情報セキュリティの重要性が叫ばれる中、セキュリティ・パッチが提供されないというのは事業継続のリスクとなるからです。とはいえ、安易なバージョンアップは予期せぬ不具合を引いてしまうといった潜在的なリスクを呼び込むため、そう簡単にバージョンアップというわけにもいきません。そのため、セキュリティ問題が発生した場合には早急にパッチを当てられるようにするものの、通常時はパッチを当てない、という運用になることが一般的だと思います。そして、バージョンを更新した際には動作を保証するために全機能に対して再テストを実施しなければならなくなります。これは大変コストがかかる話です。[^1]

[^1]: ユニットテストがあればいいのでは、というのはその通りですが、ユニットテストで画面の動作やデザインも含めて網羅できるかは別の話ですし、ユニットテストの開発自体もコストが高く、常時維持し続けるのにもコストがかかるわけですから、どちらの方が安上がりな選択は微妙なところだと思います。))

このような事情のため、新機能はいらないからできる限り長い期間セキュリティパッチを提供してほしいというのが企業からの要請となり、そのためには（総テストよりは安いので）有償契約もいとわないという状況があります。

業務システムと言えば Java ですが、さすがというか、あまりにも使われすぎていてセキュリティ・パッチを打ち切れないというべきか、多くの提供元がとても長いサポート期間を打ち出しています。

- Oracle JDK: [有償だが最大 8 年サポート](https://www.oracle.com/jp/java/technologies/java-se-support-roadmap.html)
- Red Hat OpenJDK: [最大 6 年サポート（有償のELSで延長の場合あり）](https://access.redhat.com/ja/articles/1457743)
- Eclipse Temurin OpenJDK: [4～6年程度](https://adoptium.net/support/)

Node.js も有償による長期サポートを提供してくれる企業が出てきてくれればよいのですが、エンジンとして使っている V8 の維持が難しいためか、そのような企業は出てきていないのが実情です。では、本当に長期サポートを受けられる方法はないのでしょうか。

ありました。**GraalVM** です。

GraalVM は Oracle が開発しているポリグリット（多言語）対応の仮想マシンです。主な用途は Java のネイティブコンパイルですが、なんと Node.js 互換機能も提供されているのです。

- [GraalVM JavaScript and Node.js Runtime](https://www.graalvm.org/latest/reference-manual/js/)

graaljs と呼ばれるこの機能ですが、JavaScript 実装は V8 を使わず独自開発、Node.js 固有のコードはそのまま利用という構成で構築されており、Node.js v18 相当の機能がほとんどそのまま動きます。 [その互換性なんと 94% を超える](https://github.com/oracle/graaljs/blob/master/docs/user/FAQ.md)とのこと。

私も試しに Nuxt3 のサンプルプログラムをビルドし実行環境として動かしてみましたが、何ら変更もせずに動かすことができました。特殊なものでなければ問題なく動くようです。

この GraalVM ですが、[Java SE Universal Subscription](https://www.oracle.com/jp/java/java-se-subscription/) の一部としてサポートを受けられます。そのため JavaVM 同様、最大8年間のサポートが受けられます。

Oracle 社に問い合わせたところ Subscription のサポート範囲に graaljs が含まれるとのことなので、Node.js v18環境の延命が可能です。[^2]

厳密には Node.js じゃないじゃん、パフォーマンスが不安、という意見もあろうかと思いますが、ひとつの選択肢として考えて頂ければと。

[^2]: サポートはされるそうなのですが、具体的な範囲は Oracle 社にお問い合わせください。
『科学的根拠に基づく最高の勉強法』を誰でも実践できるようにまとめてみた

# はじめに
執筆時現在（2024年4月5日）で，Amazonの教育学一般関連書籍の売れ筋ランキングで1位になっている[本書](https://www.amazon.co.jp/%E7%A7%91%E5%AD%A6%E7%9A%84%E6%A0%B9%E6%8B%A0%E3%81%AB%E5%9F%BA%E3%81%A5%E3%81%8F%E6%9C%80%E9%AB%98%E3%81%AE%E5%8B%89%E5%BC%B7%E6%B3%95-%E5%AE%89%E5%B7%9D-%E5%BA%B7%E4%BB%8B/dp/4046067233)を，誰でも実践できるようにまとめてみました．

本書は研究結果を基に勉強法が良いか悪いかを結論づけており，非常に良い本だと感じました．この本はわかりやすく書かれていますが，中学生が読んですぐに実践するのは少々難しいかなと思ったので，出来る限り簡潔に必須事項のみをまとめました．また必要に応じてオリジナルの具体例を載せています．研究結果や私が重要でないと判断したところは省いておりますので，詳細が気になった方はぜひご購入ください．

# それぞれの勉強法を分析する前に
さまざまな良い勉強法，悪い勉強法が登場しますが，それらに共通することをまとめておきます！
**効果の高くない勉強法**...<font color="red">**脳に負荷がかからない勉強法**</font>
**効果の高い勉強法**...<font color="red">**脳に負荷がかかる勉強法**</font>


# 効果の高くない勉強法

- **繰り返し読む**
  何回も教科書を読んでると見慣れてきて，<INS>本当は理解していないのに理解したように感じてしまう</INS>のでダメ😔
<br>

- **ノートに書き写す，ノートにまとめる**
  <INS>勉強した気になるだけで，頭に入っていない</INS>のでダメ😔
  →**問題集にメモするのは良い！** 例えば，難しかった問題に印を付ける，自分が忘れていた知識をメモする，教科書の対応しているページを書いておく，など．**あとで見直した時に役に立つなら何でもメモ**していきましょう！
<br>

- **何となくハイライトや下線を引く**
  <INS>勉強した気になるだけで，頭に入っていない</INS>のでダメ😔
  ただし，**あとで見直すところにハイライトや下線を引くのはOK！**
<br>

- **自分なりの勉強法にこだわる**
  下にある色んな勉強法を試してみましょう！😆


# 効果の高い勉強法

- **アクティブリコール：勉強したことを頑張って思い出す勉強法**
  知識を頭にインプットするだけでは中々覚えられない😔
  →インプットとアウトプットはセット！😆
  
  例えば，
  - 何も見ずに英単語の意味を思い出す！英単語リストを作ると便利！
  - 教科書の一部を隠して，そこに書いてあった内容を要らない紙に書く！
  - 誰かに教えているフリをしながら問題を解く！「この知識を使って...」，「この式を変形するとこうなるから...」などブツブツ喋りながら解きましょう！
  
  そして，**忘れていた知識はすぐに見直して，間違えた問題はすぐに解説を読みましょう！💪** 
<br>

- **分散学習：時間を空けて勉強する**
  同じ内容を2時間かけて覚えるより，今日と別の日で1時間ずつ勉強した方が良い！😆  　逆に一夜漬けで何とか覚えた知識はすぐ忘れてしまう😔

  じゃあ，**どれくらい時間を空ければ良い？🤔**
  - 難しいところ，覚えにくいところは間隔を短く
    例えば，今日と明日．

  - 簡単なところ，覚えられたと思うところは間隔を長くしてもOK
    例えば，今日と3日後．

  色々試して，自分が覚えやすい間隔を見つけよう！
<br>

- **アクティブリコールと分散学習を組み合わせる**
  時間を空けて（分散学習），内容を思い出す（アクティブリコール）！！😆
  
  早めにテスト勉強を始めて，この勉強法を試してみましょう！
<br>


- **インターリービング：問題を混ぜる勉強法**
  問題集にある分野ごとのまとめ問題ページのように，色々な問題を混ぜて勉強しよう！😆
  テストと同じように色んな問題が混ざった状況で，どの知識や公式を使えば良いか考えるのが重要！😆
<br>


- **自己説明：自分に説明しながら勉強する**
  （これはちょっと難しい勉強法になります．）
  自分がどれくらい理解できてるか考えながら勉強する！😆

  例えば，
  - このページの内容で，知ってることはどれ？知らないことはどれ？
  - これまでに勉強した内容とどのように関係しているかな？
  - 自分なりに内容を説明するとしたら？
  - この分野は何%くらい理解できてるかな？
  
  自分の勉強を客観的に見てみるとより効果的に勉強ができる！

# 勉強法以外で大事なこと

- **モチベーションを上げる方法**
  - 勉強してることが今後どのように役に立つか考えてみる！
  - 得意と思い込む！「数学が得意」，「英語が得意」と思って勉強してみよう！
  - 成功体験を積もう！まずは小テストを目標に頑張ってみよう（自分で用意してもOK），もし小テストで良い点が取れたら，「このまま頑張ればテストでも良い点が取れる！」と自信を付けて，良い点が取れなかったら次の小テストに向かって頑張ろう！
  - どれくらい勉強したか記録しよう！自分の頑張りを褒めてあげるのもGOOD
<br>

- **睡眠**
  - 寝る間を惜しんで勉強しない...寝てる時に記憶が定着するから
  - 睡眠の質を上げる...適度に運動をする，寝る前にスマホを見ない，寝る前にご飯を食べない，夕方以降カフェインを摂らない，など．（ネットで検索すれば色々な睡眠の質を上げる方法が見つかります．）
<br>

- **その他**
  - スキマ時間の活用...例えば，電車の中で英単語の意味を思い出してみる
  - 難易度...簡単な問題集→難しい問題集 の順で進める
  - スマホは別の部屋に置いておく...近くにあるだけでも集中力が落ちる😔
Linuxでネットサーフィン

## インストール
```bash
sudo apt install lynx
sudo apt install w3m
```
## 実行
```bash
lynx
```
```bash
w3m google.com
```
↓Vueの公式画面：w3m
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3125890/29e67a49-76d2-d432-3495-cc943c0b66fb.png)

## 感想
- 軽く触ってみた感覚では、w3mのほうがシンプルで扱いやすいと感じた
- lynxはいろいろ試せるようであるが、感覚で使うには少し難しく感じた
- ノリと勢いで試したが、何に使うべきか考えるとどうしてもCLI上でネットに触らなければならないとき、、という超限定的な用途しか思いつかなかった、、、
- メリットとしては広告がないから見やすいことかな、、？
予習シリーズ算数と面積図と連立方程式と線形代数学


面積図のプログラム
```
import matplotlib.pyplot as plt
#1個70円の品物Aと1個120円の品物Bを合わせて20個買ったところ、代金は1850円でした。Bを何個買いましたか
#定数の値
#AとBは固定
A = 1
B = 1
a = 20
C = 70
D = 120
b = 1850

# 式の計算
F = (a * D - b * B) / (A * D - C * B)

# 点の座標
points_red = [(0, 0), (0, C), (F, 0), (F, C)]
points_blue = [(F, 0), (F, D), (a, 0), (a, D)]

# プロット
plt.scatter(*zip(*points_red), color='red', label='Red Points')
plt.scatter(*zip(*points_blue), color='blue', label='Blue Points')

# ポイントの値を表示
for point in points_red:
    plt.text(point[0], point[1], f'({point[0]}, {point[1]})', fontsize=9, ha='right', va='bottom', color='black')

for point in points_blue:
    plt.text(point[0], point[1], f'({point[0]}, {point[1]})', fontsize=9, ha='right', va='bottom', color='black')

# プロットの設定
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Points Plot')
plt.legend()
plt.grid(True)

# プロットを表示
plt.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760770/9334e340-bc5b-06f3-024d-877711d14fec.png)

```
import numpy as np
import matplotlib.pyplot as plt

# 与えられた係数行列 A
A = np.array([[1, 1], [70, 120]])

# 逆行列を求める
A_inv = np.linalg.inv(A)

# 定数ベクトル B
B = np.array([[20], [1850]])

# 変数ベクトル X を求める
X = np.dot(A_inv, B)

# BとXをプロットする
plt.figure()

# Bをプロット
plt.plot(B[0], B[1], 'ro', label='B')

# Xをプロット
plt.plot(X[0], X[1], 'bo', label='X')

plt.xlabel('X1')
plt.ylabel('X2')
plt.title('B and X')
plt.legend()
plt.grid()
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760770/a775945a-a206-d8e7-f3a8-0ec984ac988a.png)


A= {{1, 1, 2}, {-1, 2, 2}, {3, 2, 3}} 
行列Aの転置行列を求める
行列Aの逆行列を求める
行列Aの固有値ベクトルを3次元プロットする
行列Aの対角化する
```
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

A = np.array([[1, 1, 2], [-1, 2, 2], [3, 2, 3]])

# 転置行列の計算
A_transpose = np.transpose(A)

print("Aの転置行列:")
print(A_transpose)

# 逆行列の計算
A_inv = np.linalg.inv(A)

print("Aの逆行列:")
print(A_inv)

# 固有値と固有ベクトルの計算
eigenvalues, eigenvectors = np.linalg.eig(A)

print("Aの固有値:")
print(eigenvalues)
print("Aの固有ベクトル:")
print(eigenvectors)

# 3次元プロット
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# 固有ベクトルのプロット
for i in range(len(eigenvalues)):
    ax.quiver(0, 0, 0, eigenvectors[0, i], eigenvectors[1, i], eigenvectors[2, i], color='r')

ax.set_xlim([-1, 1])
ax.set_ylim([-1, 1])
ax.set_zlim([-1, 1])

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')

plt.show()

# 対角化
D = np.diag(eigenvalues)
P = eigenvectors

# P * D * P^(-1)で元の行列に戻す
A_diagonalized = np.dot(np.dot(P, D), np.linalg.inv(P))

print("Aの対角化:")
print(A_diagonalized)
A= {{1, 1, 2}, {-1, 2, 2}, {3, 2, 3}} 
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3760770/dde236a4-5e2d-8500-a978-7630aea036b3.png)
Pythonで「ファイルを開く/ファイルを閉じる」の動作を確認してみた

# 概要

Pythonで「ファイルを開く/ファイルを閉じる」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/file/index1.html

# 実装

以下のファイルを作成しました。
```sample.py
f = open('myfile.txt', 'r')
data = f.read()
print(data)
f.close()
```
```myfile.txt
明日の天気はどうだろう。
晴れるといいな。
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
明日の天気はどうだろう。
晴れるといいな。

```

# まとめ

何かの役に立てばと。
Dijkstra 法（priority 付き Map 利用, Javascript）

こんにちは。
[Dijkstra 法](https://ja.wikipedia.org/wiki/ダイクストラ法)処理を行いました。オリジナル形のように main 部が率直な形となるよう priority 付きの ```Map``` を作って用いました[^1]。
[^1]: 本当に便利であれば（他の用途は思いつきませんが）、計算量低減化も今回の```pop()```部分に必要と思いました。参考例として、"[Deep Dive into Data structures using Javascript - Priority Queue](https://www.sahinarslan.tech/posts/deep-dive-into-data-structures-using-javascript-priority-queue)" (www.sahinarslan.tech) 。

##### 実行例
```console
$ node dijkstra.js 
vertices of the graph: [Map Iterator] { 0, 1, 2, 3 }
source: 0
result: {path: [0, 2, 3], distance: 1.5}
```

##### ソース
```dijkstra.js
const source = 0, destination = 3;

// array of edges represented by adjacent vertex and length
const diGraph = new Map([
  [0, [{target: 0, length: 0}, {target: 1, length: 1}, {target: 2, length: 0.5}, {target: 2, length: 1}]],
  [1, [{target: 2, length: 1}, {target: 1, length: 0}]],
  [2, [{target: 3, length: 1}, {target: 0, length: 0}]],
  [3, []]
]);

console.log("vertices of the graph:", diGraph.keys());
console.log("source:", source);
console.log("result:", dijkstra(source, destination, diGraph));

function dijkstra(source, destination, graph) {
  if (!graph.has(source)) return {path: [source], distance: 0};

  class MapWithPriority extends Map {
    constructor() {
      super();
      this.visited = new Set();
    }
    pop() {
      let keyMin, valueMin = Infinity;
      this.forEach((v, k) => {
        if (v < valueMin) {keyMin = k; valueMin = v;}
      });
      this.delete(keyMin);
      this.visited.add(keyMin);
      return [keyMin, valueMin];
    }
    set(key, value) {
      if (this.visited.has(key) || value >= this.get(key)) return false;
      super.set(key, value);
      return true;
    }
  }

  // initialization
  const prev = [];
  const pq = new MapWithPriority();
  pq.set(source, 0);
  let vertex, distance;

  // main
  while (pq.size > 0) {
    [vertex, distance] = pq.pop();
    if (vertex == destination) break;
    graph.get(vertex).forEach(edge => {
      if (pq.set(edge.target, distance + edge.length)) prev[edge.target] = vertex;;
    })
  }

  return {path: path(source, vertex), distance: distance}
  
  function path(source, vertex) {
  	const pathReversed = [vertex];
  	while (vertex !== source) {
  		vertex = prev[vertex];
  		pathReversed.push(vertex);
  	}
    return pathReversed.reverse();
  }
}
```
SONYのテレビのHDDが認識しなくなったときの対処法

#  序章
SONYのテレビにHDDを接続をして録画を行っていたら、ある日突然認識せず、新しいHDDとして認識されるようになった。そこで色々悩んだのだが無事復旧できたので下に記す。

# 下準備
CrystalDiscinfoなどを利用してディスクの状態を調べておく。

:::note warn
注意
もし、注意や危険判定の場合は不良セクタの修復となり今回の修復方法とは異なる。
:::

# 実際の方法
1:Ubuntuを起動する。
（仮想環境でも、実況環境でもよし）
>仮想環境の時
>VirtualBoxでHDDを認識させるときドライバをUSB3.0に設定しないとエラーが出ることがある。

2:disks（ディスク）アプリなどを使用してディスクが認識しているか、マウントできるかを確認。
もし、マウントできなかったら次の手順に進む

3:コマンドを実行
```Command
sudo fdisk -l #このコマンドでディスクの名前（/dev/sdb2）などを確認する。
              # なお、一番大きい録画ファイルが入っていそうなところの名前を控えておく。
sudo xfs_repair -Lv /dev/sdb2(ここは場合によって変わる)
（この下に結果が続々と出てくる。）
```
ここまでで回復ができたはず。
確認には、もう一度マウントの手段を踏んでみると良い。
マウントができるようになっている。
#13【勉強メモ】エヴァンス本からざっくり理解するDDD

## 目標
・ふわっとした理解のDDDについて[エヴァンス本](https://www.amazon.co.jp/%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88-Architects%E2%80%99Archive-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E5%AE%9F%E8%B7%B5-%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9/dp/4798121967/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=17W0M5YAY0R9Z&dib=eyJ2IjoiMSJ9.qtIEGNumTF4Fq3OG4r7BcgPPpMccQaiAMFjoQiYsRfAUl2LJ3kucBAwXJG1pE1-9MMyozf_R6XnUk8kwhpkIPyRMzsu94DrC82a2cWHXn2TDjembTcFwG0z4uuYeu7EY_VF_p_KcGaJhu-sFQP2IfF8BXdAN9RWcUsZLGOA8hIhkuAKrptA3cagpPrF5ZoxXjjZ9ctVxNzHN-qanc6enklCzFiHeCY1UpXho238Cgd4eMsXlRTbQ5u_T9ZSbUOj5EOjKzf1jx0xSJbTwFJrRetDuJaorGcsbbNpAuJkvNAs.F3zE4YfUXPLj7DRzsSV4wM07EgTKoLqmpU491uMjIhw&dib_tag=se&keywords=%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88&qid=1710421495&sprefix=%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88%2Caps%2C279&sr=8-1)を通して体系的に学習する
・各章の要約をアウトプットすることで知識を定着させる

## 前回の記事
第12章の内容は以下でまとめています。

https://qiita.com/kotemendo2819/items/80b3417e34f52b47d9f4

## 【第13章】より深い洞察へ向かうリファクタリング
より深い洞察へ向かうリファクタリングは多くの側面をもつプロセスである。
主要なポイントは以下の3つだ。

・ドメインに馴染む
・物事に対して常に違う見方をする。
・ドメインエキスパートとの対話を途切れさせない。

## 開始
リファクタリングに対する従来の見方を変え、コードのぎこちなさや複雑さの根源はドメインモデルにあると考える。
ドメイン知識を身につけ、より深くドメインを理解するようになると、モデルを改善したり役立つように改修するきっかけとなる。

## 研究チーム
次の段階は、意図を明確かつ自然に伝達するようなモデルに改良する方法を探すこと。
このプロセスを生産的にするポイント3つ。

・自主的な意思決定
　少数精鋭でチームを組む。(長期的な組織構造は不必要)

・スコープと休憩
　数日の感覚を空けて短いMTGを2~3回することで、価値のある設計が作れる。

・ユビキタス言語の駆使
　他チームやドメインエキスパートとのMTGではユビキタス言語を駆使することでモデル改良の機会が生まれる。

## 先達の技
ドメインに関する文献や別の情報源から、モデルに対して役立つ概念を見つけることで
知識を噛み砕くプロセスの糧にする。

## 開発者のための設計
しなやかな設計を意識することで、依存関係と副作用が抑制され、変更したコードの実行結果が予想しやすくなる。
結果的に開発者の精神的過負荷を制限することにつながる。

## タイミング
ソフトウェア開発は、変更することで得られる利益や、変更しないことで生じるコストを
正確に割り出せるような予測可能なプロセスではないため
ドメインに関する継続的な研究やドメインエキスパートとの会話を続けなければならない。

具体的には次の場合にリファクタリングを行う。
・設計がドメインに関する理解を表現していない。
・重要な概念が設計で暗黙的になっている。
・設計の重要な部分をよりしなやかにする好機がある。

逆に以下の場合にリファクタリングを避ける。
・リリース前日。
・技術的なアピール目的。
・ドメインエキスパートに理解されてない。

## 好機となる危機
より深い洞察へ向かうリファクタリングは継続的なプロセスであるため
突然ドメインに対するブレイクスルーが起きて古いモデルは貧者に見え、危機的に見えるかもしれないが
この視点があればはるかに優れたモデルを思いつくことができる。

## まとめ
本章ではしなやかな設計を前提としたリファクタリングのプロセスを学ぶことができた。
これで第3部は終了になるが、ソフトウェアは継続して改善し刷新していくことで価値を生むことができる
という考え方が印象的だった。
今後作るプログラムは保守しやすい設計を心がけるとともに、これまでの作ってきたプログラムに対しては
改善できる箇所がないか目を向けることが大事だと感じた。

次は「第４部戦略的設計」から「第14章モデルの整合性を維持する」を学んでいく。

参考になったらいいねやコメントおまちしています！！
滅びろPDF

PDFとかもういらんやろ、原則HTMLにしろ。

# PDFじゃなくてHTMLにすべき理由
## もはや印刷なんてしない
ご存じの通りPDFにはページという概念があって1ページ目2ページ目みたいに文書が分かれている。

この改ページは完全に印刷することを前提とした概念だが、もはや印刷とかほとんどしない。私が生活で触れる全てのPDFファイルの内、95%はディスプレイの中でしか見てないと思う。ディスプレイで見るなら改ページとかむしろ邪魔で見づらくなるだけである。

また文書を作る側としても、改ページの位置が不自然だから直さなきゃとか無駄にやらなきゃいけないことが増える。

## もはやHTMLだってポータブルである
PDFは Portable Document Format の略で、どの環境でもずれなく同じに見えるポータブル性が売りだった。

だが今はHTMLだってポータブルである。昔はブラウザによって同じHTML、CSSでも表示が異なってしまうとかあったが、今はそんなことはほぼ無い。最新機能とか使わなければどの環境で見ても同じに見える。

HTMLは画像とか埋め込むときに別ファイルにしないといけないからメールとかで交換しづらい（ポータブルでない）だろという意見がありそうだが、大丈夫、HTMLには[データURL](https://developer.mozilla.org/ja/docs/Web/HTTP/Basics_of_HTTP/Data_URLs)がある。これを使えば画像等のあらゆるメディアのデータをHTML内に埋め込める。そうすれば1ファイルのみで交換できPDFと同じである。ベクター画像なら`<svg>`要素で直接書くこともできるし。

## 表現力が高い
PDFはあくまで印刷することを前提にしているので静的である。印刷を前提にしないならもっといろんなことができる。

説明をわかりやすくするためにアニメーションを入れたり動画を入れたり、サイドバーから好きな章や節に飛べたり、注釈はいちいちどこにあるか探さなくてもホバーするだけで表示されたり、埋め込まれた表は好きにソートしたりフィルタリングしたり…

文書とは情報や知識を伝えるための物だという目的を考えれば、静的である必要なんてないはず。インタラクティブ性やアニメーションを活用することで伝わりやすくなることは多いので、どうせディスプレイで見るならこの高い表現力を活かさない手はない。

## （エンジニアにとって）編集や変更履歴管理がしやすい
これはエンジニア限定のメリットだが、HTMLはプレーンテキストファイルなので編集したり変更履歴管理がやりやすい。エンジニア以外の人にとってはHTMLでもPDFでも変わらないのでメリットでもデメリットでもない。

# あとがき　～「文書」の未来～
ホームページに掲載されている企業のプレスリリースとか製品の説明書とか、さらにはエンジニア専門の転職サイトでさえ職務経歴書はPDFで、とかだからね。PDF好きすぎないかと思う。

今後文書というものは静的なものであるという概念が壊れていくんじゃないですかね。サイドバーから好きな章や節にぱっと飛べたり、注釈はどこにあるか探さなくてもホバーすれば出てきたり、文書に埋め込まれた表は好きにソートできたり、インタラクティブな文書という概念が生まれるんじゃないかと思ってる。

まあある意味Webサイトという物自体がそれなんだけど、今まできっちりした「文書」と言えばPDF！、HTMLはWebサイトを作るための物！という考え方が固定的すぎて、実はこれHTMLの方が良くない？みたいな事は沢山ありそう。
超初級：Oracle LiveLabs 躓きポイント2点

実際に触ってみて2点、入口で躓いたところを共有します。

## 1. ラボ用アカウントの確認方法

### 回答：左上のview login infoを展開し確認する

其方の情報をもとにLaunch OCIを選択してログインすれば良し。
自身のtenancy名でログインするなどの記載も見受けられましたが
個人的にはLiveLabsのsandbox環境のほうが誤課金に繋がる誤操作も防げ、より安心して勉強が出来て良いかなと。

画面左上のView Login Infoを選択 :
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160387/702f9515-75af-3e97-5bb3-a92219230279.png)

画面右側に表示されたログイン情報をもとに画面右上の
`Launch OCI`を選択しsandbox環境を起動 : 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160387/7304f515-9823-f3c7-4bf9-7c696e5e2d1e.png)

起動（ログイン）完了：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160387/7666f188-2660-9470-d06c-7708c08c629d.png)


## 2：Authorization failed or requested resource not found.エラー対応方法

### 回答：ラボ用の正しいcompartment名を指定する事

例えば、Autonomous Database 15 Minute Quick Start手順中のADB作成時に
`'Authorization failed or requested resource not found.' ` が表示された場合は、`view Login Info`のcompartment名が選択されていないためとなります。（確か手順内にあったはず？）
今回私の場合は、Compartment 名が`LL80229-COMPARTMENT` でしたので、此方を選択する必要があります。


エラーイメージ(末尾)：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160387/36f15175-83e7-782f-6335-fb04181fea14.png)

Compartment名選択状況：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160387/b28a60b5-2cfe-998f-54c8-c55de035662b.png)

ADB作成完了画面：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/160387/edd0cad6-1d26-66af-d8c2-3aa680a793fa.png)

### 感想
少し考えれば思いつくのですが意外に躓くかなと。
まずはこの2か所クリア出来てとにかくOCIに触れてみたい方は、
次は、下記の初級コースがおすすめです。

`Autonomous Database 15 Minute Quick Start`

実際にADBが作成できObject Storageのcsvデータ取得から
グラフ化表示まで完成時は嬉しいです。

## コース概要：
### Autonomous Database 15 Minute Quick Start
* Deploy an Autonomous Database instance that is optimized for data warehousing workloads
* Use Autonomous Database tools to load object storage sources
* Use advanced SQL find at risk customers

それでは皆様、
共い良いクラウドジャーニーを！！！
【TypeScript】判別可能なユニオン型

オブジェクトのユニオン型に共通のプロパティを持たせることでどの型か判別できるようになります。
これを判別可能なユニオン型と呼びます。

具体例は以下のとおりです。

```ts
type Dog = {
  type: 'dog'
  bark: () => void
}

type Cat = {
  type: 'cat'
  meow: () => void
}

type Pet = Dog | Cat

function makeNoise(pet: Pet) {
  if (pet.type === 'dog') {
    pet.bark()
  } else if (pet.type === 'cat') {
    pet.meow()
  }
}

```

上記では`Dog`と`Cat`の両方に判別用の`type`プロパティを設定しています。
オブジェクトの`type`の値を検証することで`Dog`か`Cat`かを判別できます。

`switch`を使用しても同様に判別可能です。

```ts
type Dog = {
  type: 'dog'
  bark: () => void
}

type Cat = {
  type: 'cat'
  meow: () => void
}

function makeNoise(pet: Pet) {
  switch (pet.type) {
    case 'dog':
      pet.bark()
      break
    case 'cat':
      pet.meow()
      break
  }
}

```
StreamlitとMatplotlibを組み合わせたグラフの作成方法

お疲れ様です。

今日は「StreamlitとMatplotlibを組み合わせたグラフの作成方法」について部分いたします。

他のライブラリと連携して、Streamlitでより高度なグラフを作成できます。

Matplotlibは、Pythonで広く利用されているグラフ描画ライブラリです。

そのため、StreasmlitでもMatplotlibとの組み合わせ方を学んでおいた方が良いでしょう。

# Matplotlibでの基本的なグラフ作成

Streamlitでは、`st.pyplot`関数を使用して、Matplotlibで作成したグラフを表示します。

まず、Pythonでのコードと同じようにMatplotlibを使用してグラフを作成し、`plt.title`、`plt.xlabel`、`plt.ylabel`でグラフのタイトルや軸ラベルを設定していきましょう。

そして、st.pyplot()を呼び出すことで、Webアプリ上にグラフを表示します。

```python
import streamlit as st
import matplotlib.pyplot as plt
import numpy as np


x = list(range(50))
y = np.random.randn(50)


plt.plot(x, y)
plt.title('Matplotlib and Streamlit')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')

# Streamlitで表示
st.pyplot(plt)
```

上記のコードを実行すると、以下のようなグラフが出力されます。

![Screenshot 2024-04-04 at 11.09.25 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507088/ed32d90c-eefe-cfbb-4dd0-aafb9d1f9ced.png)

いつものMatplotlibのグラフが出力できました。

ですが、Streamlitよりはデザインに優れているとは言えないため、Streamlitを用いる場合はあまり使わないかもしれません。

とはいえ、多くの方がMatplotlibに慣れているので、複数人で作業する場合は使用機会もあるでしょう。

# StreamlitとMatplotlibの組み合わせ方の例

StreamlitのウィジェットとMatplotlibを組み合わせることで、ユーザーの入力に基づいてグラフを動的に変更できます。

例えば、セレクトボックスでデータのサイズを選択すると、表示されるグラフを変えることが可能です。

以下が、セレクトボックスを追加した形のグラフの出力コードになります。

```python
import streamlit as st
import matplotlib.pyplot as plt
import numpy as np

counting = st.selectbox(
    'サンプルデータの数を選んでください',
    (50, 100, 1000))

x = list(range(counting))
y = np.random.randn(counting)

plt.plot(x, y)
plt.title('Matplotlib and Streamlit')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')

# Streamlitで表示
st.pyplot(plt)
```

上記のコードでは、セレクトボックスで選択したものがcountingに格納され、xとyのサイズの所が入力によって変化するようになっています。

「セレクトボックスの扱い方があまりよく分からない...」という方は、[【完全網羅】Streamlitでセレクトボックスを作成する方法](https://shoblog.iiyan.net/streamlit-selectbox/)の記事をご参照ください。

実際に、セレクトボックスで変更したグラフを横に並べて比較してみましょう。

![Screenshot 2024-04-04 at 11.11.32 PM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3507088/067893c0-7111-8b7a-cfe7-36973ff1a8a6.png)

上のセレクトボックスの数値を変更しただけで、グラフが変更されました。

このように、動的にグラフを変化させられるのが、Streamlitの特徴になります。

今日は以上です。

ありがとうございました。
よろしくお願いいたします。
#12【勉強メモ】エヴァンス本からざっくり理解するDDD

## 目標
・ふわっとした理解のDDDについて[エヴァンス本](https://www.amazon.co.jp/%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9%E3%81%AE%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88-Architects%E2%80%99Archive-%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%96%8B%E7%99%BA%E3%81%AE%E5%AE%9F%E8%B7%B5-%E3%82%A8%E3%83%AA%E3%83%83%E3%82%AF%E3%83%BB%E3%82%A8%E3%83%B4%E3%82%A1%E3%83%B3%E3%82%B9/dp/4798121967/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=17W0M5YAY0R9Z&dib=eyJ2IjoiMSJ9.qtIEGNumTF4Fq3OG4r7BcgPPpMccQaiAMFjoQiYsRfAUl2LJ3kucBAwXJG1pE1-9MMyozf_R6XnUk8kwhpkIPyRMzsu94DrC82a2cWHXn2TDjembTcFwG0z4uuYeu7EY_VF_p_KcGaJhu-sFQP2IfF8BXdAN9RWcUsZLGOA8hIhkuAKrptA3cagpPrF5ZoxXjjZ9ctVxNzHN-qanc6enklCzFiHeCY1UpXho238Cgd4eMsXlRTbQ5u_T9ZSbUOj5EOjKzf1jx0xSJbTwFJrRetDuJaorGcsbbNpAuJkvNAs.F3zE4YfUXPLj7DRzsSV4wM07EgTKoLqmpU491uMjIhw&dib_tag=se&keywords=%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88&qid=1710421495&sprefix=%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E9%A7%86%E5%8B%95%E8%A8%AD%E8%A8%88%2Caps%2C279&sr=8-1)を通して体系的に学習する
・各章の要約をアウトプットすることで知識を定着させる

## 前回の記事
第11章の内容は以下でまとめています。

(※現在工事中)

## 【第12章】デザインパターンをモデルに関係づける
ドメイン駆動設計でデザインパターンを利用するためには以下2点のレベルで考える必要がある。
・コードで用いられる技術的なデザインパターン
・モデルで用いられる概念的なパターン

## ストラテジー
アルゴリズムをカプセル化し、さらにそのファミリーを定義することで、それぞれのアルゴリズムを交換可能にする。

・プロセスの中で変化する部分を、独立したストラテジーオブジェクトとして定義する。
・ルールと振る舞いを切り離す。
・ルールや置き換え可能なプロセスはストラテジーパターンにしたがって定義する。

## コンポジット
オブジェクトを組み立てて、部分と全体の階層を表すツリー構造を作ること。

・コンポジットを構成するすべてのメンバを含む抽象型を定義する。(abstractクラス)
・情報を戻すメソッドはコンテナに実装され(Override)、内容についての集約された情報を戻す。
・リーフノードはそれぞれ独自の値に基づいてメソッドを定義する。
・クライアントは抽象型クラスを扱い、それ以下のコンテナやリーフを区別しない。

## まとめ
ドメイン駆動設計で用いられるデザインパターンについて学ぶことができた。
本書では紹介されなかった他のデザインパターン(GoFなど。。。)も今後学んでいきたい。

次は「より深い洞察へ向かうリファクタリング」を学んでいく。
次の13章で第３部はラストなので気合を入れていこう。

https://qiita.com/kotemendo2819/items/1263e1c9d12ac48fafea

参考になったらいいねやコメントおまちしています！！
RFI / RFP

# RFI
Request For Informationの略で情報提供依頼書のこと
発注者がベンダーを知るための情報を提供するための文書
→webサイト等には記載されていない技術情報や製品情報を得ることができる。

# RFP
Request For Proposalの略で提案依頼書のこと
RFIが一般的な情報を得るのに対して、やって欲しいことが明確になっており、それに対しての提案を依頼する。

::: note info
何らかの変更を行うように管理者や作業者に要求すること
:::

# 参考サイト
https://hibiki.dreamarts.co.jp/smartdb/learning/le-sp211111-3/
ONLYOFFICE DocSpace用プラグインテンプレートの作成方法

プラグイン開発を始める前に、プラグインテンプレートを作成し、DocSpaceプラグイン設定に表示される設定を行います。

１．*onlyoffice/docspace-plugin-sdk*パッケージをグローバルにインストールします：
```
npm i -g @onlyoffice/docspace-plugin-sdk
```
これでプラグイン開発の時に使用する**npx**コマンドは使用できるようになりました。

２．プラグインのテンプレートを作成するには、以下のコマンドを実行します：
```
npx create-docspace-plugin
```
３．ダイアログで以下の設定を行い、ターミナルでプラグインを設定します：

| パラメータ | 説明 |
|:-:|:-:|
| Name  | プラグインをデプロイするために、この名前のフォルダが作成されます。このフィールドは必須です。  |
| Version  | 現在のプラグインのバージョンは、DocSpaceプラグイン設定に表示されます。ページが再読み込みされると、プラグインはこのバージョンに合わせて更新されます。ポータルに現在のバージョンのプラグインがすでにアップロードされている場合は、何も行われません。  |
| Author  |  DocSpaceプラグイン設定で表示されるプラグインの開発者です。 |
| Name of the logo image  | assetsフォルダにアップロードする必要があるプラグインロゴ画像の名前です。このファイルへのパスを指定する必要はありません。このロゴはDocSpaceプラグイン設定で表示されます。必要なアイコンサイズは48x48pxです。それ以外の場合は、このサイズに圧縮されます。  |
| Description  | DocSpaceプラグイン設定で表示されるプラグインの説明です。  |
| License  |  プラグインのライセンスです。 |
| Homepage  |  プラグインのホームページです。例えば、プラグインのGitHubリポジトリなどです。この情報はDocSpaceプラグインの設定で表示されます。 |

４．必要なスコープ上で Space キーを押して、リストからプラグインスコープを選択します：

* **API**：プラグインは、ポータルサーバーへのリクエストを行うためのオリジン、プロキシ、プレフィックスを提供されます
* **Settings**：プラグインは、管理者または所有者の設定を管理することができます
* **Context menu**：ファイル、フォルダ、ルーム、画像、ビデオ（オーディオ）のコンテキストメニューにプラグインを埋め込むことができます
* **Info panel**：プラグインは、ファイル情報パネルの独立したタブとして埋め込むことができます
* **Main button**：プラグインをメインボタンに埋め込むことができます
* **Profile menu**：プラグインをプロフィールメニューに埋め込むことができます
* **Event listener**：プラグインはポータルイベントへのアクセスを与えられます
* **File**：プラグインはファイルリストと相互作用し、ファイルの種類とイメージを変更することができます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2655664/2c519358-77ee-b11c-4fc8-42f60c08da52.png)

指定されたパラメータはすべて、*package.json*ファイルで後で変更できます。

*package.json*ファイルでは、サードパーティのウェブサイトのアドレスを指定してCSPヘッダに追加し、これらのアドレスがブロックされるのを防ぐこともできます。

依存関係として@*onlyoffice/docspace-plugin-sdk* npmパッケージを追加し、*package.json*ファイルに必要なフィールドをすべて指定することで、どのプロジェクトでもプラグインを作成できます。

例：

```
{
    "name": "PDF-converter",
    "version": "1.0.0",
    "author": "ONLYOFFICE",
    "scopes": [
      "API",
      "Settings",
      "ContextMenu"
    ],
    "description": "Sample description",
    "pluginName": "PDFConverter",
    "license": "MIT",
    "logo": "logo.png",
    "homepage": "https://github.com/ONLYOFFICE/docspace-plugins/tree/master/pdf-converter",
    "cspDomains": [
      "https://embed.diagrams.net/",
      "https://*.diagrams.net/"
    ]
}
```
今どこにいるのか分からなくなったら

# はじめに
Linuxで作業をしていて、ふと「わしは今どこにおるんじゃろぉ」と人生の深淵をのぞき込むような思いが込み上げてきたときに役立つコマンドの話です。それは`pwd`コマンドです。

# pwdは何の略？
`pwd`はピーダブリューディーと読みますが
`pwd`とは何を略しているのでしょうか。
Print Working Directory、あるいはPresent Working Directoryの略だと言われています。

# pwdでわかること
Present Working Directoryは、直訳すると「現在の作業ディレクトリ」という意味です。
そう、今いるカレントディレクトリを表示できるコマンドなのです。

# さいごに
今どこにいるのか不明になったとき、あるいは今どこで作業しているのかログに残しておきたいときなど`pwd`コマンドを使いましょう。

LinuCレベル1で出題されるコマンドは結構あって初めてLinuxに触れる初学者には結構大変ですが簡単なコマンドから一つずつ覚えていきましょう。千里の道も一歩から。40歳超えて知識0からでもLinuCレベル3コンプリートできたのです。そう、約半世紀ずっーーーーーと引きこもりで地球から一歩も出ていない石ころでも。

LinuCとは

https://linuc.org/about/01.html
Excel グラフの軸（改行文字含む）を右揃えにする

# 背景
Excelのグラフの軸に改行文字を含む値を出力したいと思い、単純に改行文字（CHAR(10)）を追加したところ、軸の表示が中央揃えになってしまいました。
2024年4月4日現在、ワンクリックで右揃えを叶える方法はなさそうでしたので、備忘録としてここに残します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763181/629146b7-a6ea-5e57-a1a1-d78489122d2e.png)

# 注意事項
* 軸に使うフォントは、等幅フォントとします。（上記画像は、游ゴシックのため不可。今回はメイリオを使用しました。）
* 長い文字列に改行文字を挿入すると、グラフサイズによっては、改行文字以後の文字列が、表示されない可能性があります。


# やり方
`REPT関数`を使用し、スペースでパディングして調整します。

上図の場合、H2セルに、以下のように関数を設定します。
n数（`"(n=" & F3 & ")"`）を別のセルに記載し、参照する方がスマートな気がします。
```
=A3 & CHAR(10) & REPT(" ", LENB(A3) - LENB("(n=" & F3 & ")")) & "(n=" & F3 & ")"
```
参照セル部分を置き換えると以下のとおりです。

```
="いろは小学校" & CHAR(10) & REPT(" ", LENB("いろは小学校") - LENB("(n=180)")) & "(n=180)"`
```

* `LENB関数`
指定した文字列の文字数（バイト数）を返す関数です。全角の文字は2バイト、半角の文字は1バイトとカウントされます（`LENB("いろは小学校")`の返値は12です）。軸に記載する文字列がすべて全角である場合は、LEN関数を使用しても問題ないでしょう。

* `REPT関数`
`REPT(文字列, 繰り返し回数)`の形です。上記の記載では、「改行文字以前に記載の文字列（いろは小学校）の文字数」と「改行文字以後の文字列（(n=180)）の文字数」の差分をとり、半角スペースでパディングしています。

  
  <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763181/b0f4dc5a-5c99-15bc-7982-e3ecd4217001.png" alt="修正後" width="500" height="200">


# 改行文字前後の文字数にバラつきがある場合

先の例は、改行文字以後の文字列の文字数が少ないことを前提としています。文字数の大小にバラつきがある場合は、文字数が少ない方をパディングすることで実現可能です。
if文を使用して分岐した例が以下です。

```
=IF(LENB(A3)<LENB(B3), REPT(" ", LENB(B3)-LENB(A3)) & A3 & CHAR(10), A3 & CHAR(10) & REPT(" ",LENB(A3)-LENB(B3))) & B3
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763181/c76db1a6-a988-2ba2-13b3-149210d96ab6.png)


# おわりに

ここに投稿するには、ふさわしくない記事でしたら申し訳ございません。
他に良い方法をご存じの方いらっしゃいましたら是非ご教示ください。
個人的には、スペースでパディングしたくはないのですが、見栄えを求められるので仕方なくでした。
【Ten Queensなど】再帰関数・バックトラック法の練習

# 再帰関数
## 階乗を返す関数
```c
int	ft_recursive_factorial(int nb)
{
	if (nb < 0)
		return (0);
	else if (nb == 0 || nb == 1)
		return (1);
	else
	{
		return (nb * ft_recursive_factorial(nb - 1));
	}
}
```
## 累乗の答えを返す関数
```c
int	ft_recursive_power(int nb, int power)
{
	if (power < 0)
		return (0);
	if (nb == 0 || power == 0)
		return (1);
	else if (nb == 0)
		return (0);
	else
		return (nb * ft_recursive_power(nb, power - 1));
}
```
## フィボナッチ数列
```c
int	ft_fibonacci(int index)
{
	if (index < 0)
		return (-1);
	else if (index == 0)
		return (0);
	else if (index == 1)
		return (1);
	else
	{
		return (ft_fibonacci(index - 1) + ft_fibonacci(index - 2));
	}
}
```

# バックトラック法
## Ten Queens
```c
void	ft_putnbr(int queen[10])
{
	int		i;
	char	tmp;

	i = 0;
	while (i < 10)
	{
		tmp = queen[i] + '0';
		write(1, &tmp, 1);
		i++;
	}
	write(1, "\n", 1);
}

void	ft_change_board(int board[10][10], int x, int y, int i)
{
	int	j;

	j = 0;
	while (j < 10)
	{
		board[x][j] += i;
		board[j][y] += i;
		if (x + j < 10 && y + j < 10)
			board[x + j][y + j] += i;
		if (x + j < 10 && y - j >= 0)
			board[x + j][y - j] += i;
		if (x - j >= 0 && y + j < 10)
			board[x - j][y + j] += i;
		if (x - j >= 0 && y - j >= 0)
			board[x - j][y - j] += i;
		j++;
	}
}

void	ft_set(int queen[10], int board[10][10], int x, int *count)
{
	int	y;

	if (x == 10)
	{
		ft_putnbr(queen);
		*count += 1;
		return ;
	}
	y = 0;
	while (y < 10)
	{
		if (board[x][y] == 0)
		{
			queen[x] = y;
			ft_change_board(board, x, y, 1);
			ft_set(queen, board, x + 1, count);
			ft_change_board(board, x, y, -1);
		}
		y++;
	}
}

int	ft_ten_queens_puzzle(void)
{
	int	i;
	int	j;
	int	queen[10];
	int	board[10][10];
	int	count;

	i = 0;
	count = 0;
	while (i < 10)
	{
		queen[i] = 0;
		j = 0;
		while (j < 10)
		{
			board[i][j] = 0;
			j++;
		}
		i++;
	}
	ft_set(queen, board, 0, &count);
	return (count);
}
```
[AtCoder備忘録記事]AtCoder Beginner Contest 339 A問題

[AtCoder Beginner Contest 339 A問題](https://atcoder.jp/contests/abc339/tasks/abc339_a "Atcoder")
こちらの問題です。

# 問題
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374978/a992c329-a317-3344-546d-4edba499cff6.png)

# 入出力例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374978/f1628c2f-0668-7a71-006e-c0ad6efd6309.png)

# 解法
std::stringのfind_last_ofメソッドを使うと、特定の文字の最後の出現位置を簡単に見つけることができます。
見つけた後にそれ以降の文字列を出力して終了です。
```
#include <iostream>
#include <vector>
#include <string>
#include <unordered_set>
#include <cmath> 
#include <algorithm>
using namespace std;

int main() {
    string S;
    cin >> S;
    size_t pos = S.find_last_of('.');
    if (pos != string::npos)
        cout << S.substr(pos + 1) << endl;
    else
        cout << "" << endl;
    return 0;
}

```
EC-CUBE 4.2.x 〜（symfony5.4）でSendGridでメールを送信する設定

<dl>
<dt>前提条件</dt><dd>SendGrid側のSender設定とか終わっている</dd>
</dl>

## プラグインとかsymfony/sendgrid-mailerを使わない（smtp transport）

```sh:.env
MAILER_DSN=smtp://apikey:<APYKEY>@smtp.sendgrid.net:587
```
.envファイルの``MAILER_DSN``を変更する。
上記の`<APYKEY>`はsendgridの管理画面で発行するapikeyに置き換えてください。

:::note warn
URLエンコードを忘れずに！
sendgridのapikeyはURLエンコードしたものを.envファイルに記述します。そのまんまじゃダメ
:::

プラグインでやる方法や2系のやり方はこちら

https://qiita.com/nanasess/items/6531581b4e3e8a308502