OmniAICreator/Qiita-1.07M huggingface dataset:
【ChatGPT＋DALL-E3】【Dream Machine】の動画を倍速にします。


　どうも、カーブミラーです。

　今回は、Dream Machineの動画をChatGPTで倍速にします。たぶん、ほかの動画も可能（未確認）

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　まずは、ニュース。

　音楽生成AIであるsunoに
　　オーディオ入力機能が
　　　付きました。

　これにより
　　ユーザー自身が
　　　音を入力して、
　　　　曲作りに参加できます。

　この機能が
　　全ユーザーに開放された
　　　とのことです。
　　　　[sunoポスト](https://x.com/suno_ai_/status/1806740548595671300?t=ppQrrTQsfdaqwVrnR8D2Sg&s=19)
***
　次のニュース。

　Luma AIの
　　Dream Machineに
　　　新機能が登場。

　“Keyframes in Dream Machine”と
　　いうらしい。

　画像を二枚、
　　アップロードすることで
　　　そのあいだを補完して
　　　　動画を生成します。

　開始点と終了点の画像は
　　同一である必要は
　　　ありません。

　これにより、
　　動画の途中での
　　　破綻が少なくなり
　　　　いいものが生成できます。
　　　　　[ひろちゅ〜さんポスト](https://x.com/hirochuu8/status/1806683768759144946?t=2AlqjjBL-5guXJd53H_eSQ&s=19)

　また、下記のポストには
　　Luma AIが出したFAQ集が
　　　簡単に書かれています。
　　　　使う方は、参照しましょう。
　　　　　[てんねんさんポスト](https://x.com/munou_ac/status/1806581315577462953?t=esZbfalmrBuLSX5kCDRz-Q&s=19)

　[Luma AIが出したFAQ集](https://lumaai.notion.site/FAQ-and-Prompt-Guide-Luma-Dream-Machine-f7bd5f77478c4994aa692aa58b063ef3)

　なお、こちらもどうぞ。
　　[ITmedia NEWSポスト](https://www.itmedia.co.jp/news/spv/2406/28/news207.html)
***
　今回は、
　　この“Keyframes in Dream Machine”
　　　で作った動画を倍速にします。

　まずは
　　ごらんください。

　使った画像がこちら。
![1719630142372.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/40b2e9f2-6820-572a-566e-1cbaca9df468.jpeg)
![1719630165124.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/50c271a2-a471-d8ed-f413-9619abbaa07d.jpeg)

　こちらが
　　DreamMachineで
　　　作成した元動画（5秒音なし）。
　　　　[元動画](https://x.com/kabumira862571/status/1806853289054806153?t=31F6EIWES0zZ2yy7u0oIaQ&s=19)

　こちらが上記を
　　倍速にした動画（5秒音なし）です。
　　　[倍速動画](https://x.com/kabumira862571/status/1806873263446053340?t=rviPegKWQiB6IOFwhF7WQA&s=19)

　どうですか？

　では、やり方をどうぞ。
***
　やり方
　❶GPT-4oであることを確認
　❷元動画をアップロード
　❸Prompt入力
```Text:
MoviePyを使って、この動画を倍速にしてください
```
　❹送信
　❺ダウンロード

　これで
　　倍速動画が
　　　出来上がります。

　もちろん
　　倍速動画を
　　　確認してくださいね😅

　これの
　　使いどころは
　　　みなさん次第です。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
DNSSECってなんだ？？

## 概要

DNSSECについて簡単に調べてみたのでメモ的にまとめておく。

## 内容

### DNSSECとは

DNSの応答が改ざんされていないことを保証する仕組み
セキュリティ拡張機能らしい
ぱっと見た感じ、よくあるキーを使って複合する感じなのかなと思った（間違えていたらすみません、このへんは半信半疑でお願いします。）

### メリット

DNSキャッシュポイズニングを防ぐことができる。
ようはDNSからの応答が保証されているので、ポイズニングされているDNS情報が返っていない事が保証されて安全性の向上につながる。

::: note info
DNSキャッシュポイズニング・・・

偽のサイトにユーザーを誘導して偽サイト側で悪いことをしようとするやつ
キャッシュポイズニングそのものが悪いことというより悪事の入口になっているイメージ。
大体は誘導した先の偽サイトでメインの悪いことをするっぽい

要は本物のサイトのドメインのDNS情報を偽サイトのものにすり替えて、本来アクセスする先のサーバーを偽物の悪意のあるサーバーに切り替えるって感じだと思う
:::

### どうやったら使える？

レジストラ（ドメインの販売元、例えば「お名前.com」とか）がDNSSECを提供しているらしい。
「お名前.com DNSSEC」とかで検索したら方法が出てくる。

またドメインの種類とレジストラによってはDNSSECが利用できない場合もあるらしい。

https://help.onamae.com/answer/15014

ちなみにお名前.comの場合DNSSECの設定はオプションらしく追加料金がかかる。



## 参考文献

https://help.onamae.com/answer/14987

https://help.onamae.com/answer/14996
PCでphpファイルで作成した記事を確認したいのでDockerでサーバー立てる

PCでphpファイルで作成した記事を確認したいのでDockerでサーバー立てる。

仕事でphpファイルを使ったホームページを制作しており、現在レンタルサーバーにftpでファイルをアップしてIPアドレスを直叩きして確認しているのですが、それだと開発効率がちょっと悪いのでローカル環境でサーバーを立てて手元で確認できるようにします。

## 構成

構成はこんな感じ↓になっている。

```
C:.
├─about
├─assets
│  ├─css
│  ├─images
│  │  ├─about
│  │  └─top
│  ├─js
│  └─scss
└─top
    └─index.php
```

phpファイルのほか、assetsファイルも毎回ftpにアップして確認するので面倒。。

## docker

- docker-compose.yml

```yml
version: "3.8"
services:

  # Apache コンテナ
  apache:
    image: php:8.2-apache
    ports:
      - 80:80
    volumes:
      - ./html:/var/www/html
```

これだけでOK。あとは先ほどのソースをhtmlディレクトリにおく。

```
C:.
│  docker-compose.yml
│
└─html
    ├─about
    ├─assets
    │  ├─css
    │  ├─images
    │  │  ├─about
    │  │  ├─top
    │  ├─js
    │  └─scss
    └─top
        │  index.php
```

ひとまずこれでlocalhostでアクセスしたら表示できるようになった。

## 余談

phpのWarningエラーの出力をftpでアップしている先のサーバーでは出力OFFにしていたので、ローカルでも同様にOFFになるようにする。
（ほんとはWarningでないようにしたいが、共通部分ということもあり、、ブツブツ）

htmlディレクトリに.htaccessファイルを作成して難をしのぐ。

```.htaccess
php_flag display_errors off
```

php.iniで設定する方法がベターだと思うけど、Dockerfile作成の手間を考えて今回はこれで済ませました。
クローンアプリを作ってみたーNetflixクローン①

# はじめに
初めまして！
エンジニアになって数年、今まで本を読むだけでしたが、もっとプライベートで楽しみながら成長したい！自分が学んだ足跡を残していきたい！と思い記事を書きました！
最終的には自在に開発できるようになりたいと思っています。:triumph:
いろいろな記事を参考にさせてもらっています。:bow_tone2:
その中でもこれってどういう意味？とかつまづいたところを念入りに書いていこうかと思います。:fist:

# 今回の目的
nextjsはまだですが、実際のアプリ開発からどう作られていくかを学んでいくためにクローンアプリを開発します。
とは言っても自分で考えることは特になくYoutubeを見てやっていきます。
その中で覚えておきたい部分を分類ごとに記載していきます。なので、その時々に知ったことを小出しにしていく形になります。

# 使用したものや事前準備
・Macbook Pro
・Visual Studio Code

# 使用にさせていただいた動画

https://www.youtube.com/watch?v=mqUN4N2q4qY&t=4201s


# 新規プロジェクトのクリーンアップ
pageルーターで対応
下記のファイルを修正・削除します。
### pages
・_document.tsxを削除
・index.tsxの<main>タグ以降を全て削除し空タグに変更、他export default外の記述（importなど）も削除
### styles
・globals.cssの中を全て削除。
### tailwindcss
下記のサイトを見てセットアップ
https://tailwindcss.com/docs/guides/nextjs

さらに補完入力ができるようにIntelliSenceを追加
Tailwind CSS IntelliSense

### public
imageフォルダを作成

# TailWindの知識
### ＠apply
・@applyはtailwindをcssに記述できる書き方です。

### bg-[url('/images/hero.jpg')]
背景画像の設定で使用できる

### lg:max-w-md
レスポンシブ対応のCSS。この場合は1024ピクセル以上で最大幅を768に指定
sm: 640ピクセル以上
md: 768ピクセル以上
lg: 1024ピクセル以上
xl: 1280ピクセル以上
2xl: 1536ピクセル以上

### bg-neutral-700
グレーで明るさが700

### lg:w-2/5
2/5で40%幅

### appearance-none
ブラウザ固有のデフォルトクラスを無効

### focus:outline-none
フォーカスした時の外枠を無効

### peer
inputタグに対するアクションがあった時に、別のタグでpeer-focusなど指定するとCSSが適用される

### peer-focus:-traslate-y-3
peerで設定したタグをフォーカスしたら3単位分上に移動する

### duration-150
150ミリ秒で変化する

### transform
変化元、scale、translateなどと一緒に使う

# TypeScriptの知識
### const input: React.FC<InputProps>
InputProps型のpropsを受け取る

# Next.jsの知識
### import Input from "@/components/input";
@はtsconfig.jsonに記載されているpathsを参照し参照先を読み込む
```json
    "paths": {
      "@/*": ["./*"]
    }
```

# 次
https://qiita.com/mr_noppo/items/4dd10edb45d0febd2d77
Github ✖︎ Source Treeを簡単にセットアップしてみる

# はじめに
Github（無料アカウント）とSourceTreeの組み合わせでGithubを簡単にセットアップする方法についてご紹介します。
昔はprivate keyとか細かいトラブルが多かった気がしますが、今は簡単になりましたね。とはいえいくつかのステップを踏む必要があるため、手順としてまとめてみる。

前提とする環境は以下の通り。
・MAC OS: 14.5 (Sonoma)
・Xcode：15.4 (Xcode Command Line Toolインストール済み)
・Source tree：4.2.8(265)

# Gitのインストール
Xcodeの開発を前提としているので、
Xcode Command Line ToolsとHomebrewも合わせてインストールします。

### 1. Xcodeのインストール
　App Storeからインスコ

### 2. Homebrewのインストール
　"https://brew.sh" 参照

### 3. `brew install git`　を実行
　インストールに成功した後に`git --version`でバージョンが出力されればOK
 ![スクリーンショット 2024-06-29 11.16.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/046d8076-9b1b-e099-ce89-defe2a27c4ed.png)

# Githubアカウントの作成
ここでは個人の無料アカウントを作成してみます。

### 1. Sign up
"https://github.com" にアクセスし、"Sign up for GitHubを選択。
指示通りにEmail address, Password, アカウント名などを入力し、アカウント作成（特に注意事項はないのでここは簡略化してます）
 ![スクリーンショット 2024-06-29 11.19.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/0deed245-9d07-874e-0192-6e4edbd65d1d.png)

### 2.リポジトリの作成
Repositoriesタブを選択し、"New"ボタンを押下
![スクリーンショット 2024-06-29 11.25.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/7972c55b-0498-6551-4408-dc68ec258090.png)

リポジトリ名を適当に入力し、他はざっと見て設定してください。
無料アカウントでもprivateなリポジトリを作成できるようになっているので、念の為privateにしておきます。
![スクリーンショット 2024-06-29 11.27.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/389c2159-3afb-94a4-6fc2-859ce83b4e4d.png)


# Source Treeのセットアップ
### 1.Source Treeのダウンロード
https://www.sourcetreeapp.com からダウンロード。
ダウンロードしたファイルを開き、普通にインストール

### 2.Registration
SourceTreeを初めて開こうとすると、"Registration"という画面が表示され、初期セットアップする必要があります。

ここでスキップ表示が出てない場合、アカウント作成しないと進めません。
そのため、`Create one for free` を押してアカウント作成をしてください！
（ScreenShotを撮るの忘れた。。）

Gitをすでにインストール済みであれば、Source TreeのRegistrationでGitのインストール画面は出ないはず（バージョンによっては出るかも？）

GithubのアカウントやSSHキーの読み込みは、ここでは全てスキップして構いません。
あとで設定できます。

### 3.GitHubアカウント追加
右側の3点リーダーを選択し、"アカウント"を選択
![スクリーンショット 2024-06-29 10.54.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/b1cbd978-6c9a-dc16-6e41-7162e4b4f002.png)

ここでも"アカウント"を選択し、アカウント一覧が表示。
"+"ボタンを押下し、アカウントを追加していきます。
![スクリーンショット 2024-06-29 10.55.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/f1369693-d772-8329-7a24-19a755c11614.png)

GitHubと接続する場合の設定値は以下の通り
①ホスト：GitHub
②認証タイプ：Oauth
③アカウントを接続：クリックし、作成していたGitHubアカウントでログイン
④プロトコル：SSH
⑤SSHキー："キーが見つかりません"となったら適当にキーを生成してください。
　→最後に"保存"ボタンを押下
![スクリーンショット 2024-06-29 10.56.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782130/9aae95da-8500-3e7b-2e76-a43ce48d2a40.png)

※"アカウントを接続"をクリックすると、
　SourcetreeからGitHubへのアクセスを許可する画面が表示されるので、
　"Authorize atlassian"ボタンを押して承認してください。

これでセットアップは完了です。
CloneやCommit, PUSHができるようになっているはずです。

以上
apache2.2のどのVirtualHost設定にもServerNameが該当しないときの挙動

たとえば、xxxxx.comのServerName設定がなく、aaaaa.comのVirtualHost設定の優先順位が先頭の場合、xxxxx.comはaaaaa.comのVirtualHost設定が適用される。

https://httpd.apache.org/docs/2.2/ja/vhosts/examples.html#:~:text=%E3%81%A4%E3%81%BE%E3%82%8A%E3%80%81%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%8C%20%E3%81%A9%E3%81%AE%20ServerName%20%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%86%E3%82%A3%E3%83%96%E3%81%AB%E3%82%82%E3%83%9E%E3%83%83%E3%83%81%E3%81%97%E3%81%AA%E3%81%84%E5%A0%B4%E5%90%88%E3%80%81%20%E4%B8%80%E7%95%AA%E6%9C%80%E5%88%9D%E3%81%AE%20VirtualHost%20%E3%81%AB%E3%82%88%E3%82%8A%E6%89%B1%E3%82%8F%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82

> つまり、リクエストが どの ServerName ディレクティブにもマッチしない場合、 一番最初の VirtualHost により扱われます。

どのVirtualHost設定が最優先されるかは、以下のコマンドで確認できる
```
httpd -S
```
いつの間にかコンビニおにぎりは安全なものに、AIは信用できるものになっていた。

生成AIの回答精度が非常にたかい。

私はその手軽さから Copilot が好みですが、ほかの生成AIもよく使います。宗教戦争がおこりそうなので優劣はつけませんが、どの生成AIも人間よりもくわしい回答を出してくれますし、また、その内容も正しいです。

<br>

───と私は思っていますが、皆さんはどうでしょう。

<br>

■この記事の内容
・先月、MicrosoftとLinkedInが活用状況をまとめたレポートを公開しました。
・それにより、生成AIが世界中の職場に普及したことが分かりました。
・私はAIが"信用"を勝ちとった今、すべての仕事はAIに取られる可能性があると思っています。

<br>

# コンビニのおにぎりには愛情がない？
私が実際に経験した話ではないので、間違っていたらごめんなさいなのですが、こんな時代があったみたいです。

「コンビニのおにぎりは愛情がないからまずい。」

「人が握ったおにぎりはあたたかいよね。」

「機械が作ってるおにぎりは、かたい気がする。」

<br>

今では考えられませんよね。だって、今日日そんなことを本気で思っている人なんていないと思うんですよ。この主張は"クソでか主語"を恐れずに使えます。

むしろみんなこう思ってるんじゃないですか？と。

「むしろ、工場で作られたものだから安全」

「誰が握ったか分からないおにぎりの方が怖い…機械の方がいい」

「コンビニのおにぎり美味しい。のりパリパリ」

<br>

実は、私が生成AIに抱いていた印象もコンビニのおにぎりでした。

「なんか回答精度悪いな、やっぱAIはダメかー」

「結局人間がちゃんと調べた情報が最強や」

「回答出てきたけど、本当かなぁ…どうせ間違ってるんやろ？」

<br>

# いつの間にかおにぎりは美味しくなっていた
「AIが解答してくれるものだから信用できる。」

<br>

凄いですよね、いつの間にかこんな社会になっています。

私はその瞬間を見逃しましたが、いつからこうなっていたのでしょうか。

<br>

–

<br>

先月、MicrosoftとLinkedInは、職場におけるAI（人工知能）の活用状況をまとめたレポート「2024 Work Trend Index Annual Report」を公開しました。

出典：Microsoft. “2024 Work Trend Index Annual Report”(2024/05/09) -
https://news.microsoft.com/ja-jp/features/240509-ai-at-work-is-here-now-comes-the-hard-part/

<br>

内容をかいつまんでご紹介します。

・知識労働者（ナレッジワーカー）全体の75%がAIを活用しています。その 46％ は使用を始めてから半年未満です。

・ユーザーは AI が役立つこととして、時間の節約 (90％)、最も重要な仕事への集中 (85％)、より創造的になれる (84％)、より仕事を楽しむことができる (83％) を挙げています。

・リーダーの 79% は、競争力を維持するために自社への AI 導入が不可欠であることに同意しています

・企業はすでに AI技術者の獲得に乗り出しており、AI 技術者の採用は過去 8 年間で 323％ 増加しています。また、リーダーの 66％ が AI スキルの無い人材は採用しないと回答しています。

>懐疑的なユーザーは、少なくとも AI を使ったことはあるものの、使ったとしても月に 2～3回程度。AI による節約時間は 1 日あたり 10 分以下。～略～パワーユーザーは、AI に習熟しており、少なくとも週に数回使用。1 日あたり 30 分以上の時間を節約。
>
>～略～
>
>AI の効果は明らかです。パワーユーザーは、AI を活用することで、膨大な仕事量を管理しやすくなり (92％)、創造性が高まり (92％)、最も重要な仕事に集中できるようになり (93％)、モチベーションが上がり (91％)、仕事が楽しくなった (91％) と回答しています。

<br>

───このレポートにより、生成AIが世界中の職場に普及したことが分かります。また、これはAIはひとの仕事に大きな影響を与えているほか、ひとからの信用を得ていることを意味するでしょう。

ひとからの信用を得ることでどうなるのか…

私は、ますますのAI活用と、その技術力の向上速度が上がると思います。そのうち、すべての仕事における"技術的な壁"もなくなるでしょう。そうなるといよいよ、あとはそれを「AIにやらせるのか？やらせないのか？」というだけの話になり、その決定は人間の感情次第になるかもしれません。

<br>

今はまだ、介護士、看護婦、保育士など「ひとを相手にする職業は人間が行うべきだ！」と答える人が多いのではないでしょうか。

「人の相手をするのは、人であるべきだよね！」

「AI（機械）にお世話されると大事にされてる感がない。」

「機械は人間の感情を理解できないから、柔軟な対応はできないだろ。」

<br>

じゃあ、コンビニのおにぎりはいつからそうなった…？じゃあ、今は人がやるべきだと信じられている職業はいつからそうなる…？

「介護は能力差のないAI（ロボット）にやってもらったほうが安心できる」

「感情を仕事に持ち込むべきではない、サービスに差がでるから良くない！」

「教師の人間性で子どもの思考が変わるのは心配、AIの方がいい。」

<br>


# 人間は慣れる
いつか、すべての仕事は「やっぱりAIの方が安心！」となってしまうのでしょうか。

<br>

人間は、慣れる生き物です。新しい環境や状況に適応する能力をもっています。

人間は、忘れる生き物です。考え方ですらすぐアップデートすることができます。

であれば、AIの方が「安全」で「安心」で「間違えない」ことが分かれば、きっと迷いなくそちらの道に進むでしょう。

<br>

大学の卒業式の日、「教師は感情労働の重労働のクソ労働だけど、今日があるから頑張れるんだわな」と冗談っぽく笑った恩師の顔が浮かびます。

これすらもAIに取られたとき、そこには何が残るのだろうか。そんな曖昧な、ちょっと未来のことを考えて「まぁでも、まだまだ先の話だよな」と思い、私は日常に戻るのです。

<br>

きっと、またその瞬間を見逃すのでしょう。

<br>

以上です。
PC の縮小率を 100% にして生産性を高めましょう！（windows）

# 初めに
さて突発的な質問ですが、

**タスクバーにアプリがいっぱいいっぱいになったこと、ありませんか？**

私はめちゃんこあります。

そして、それが大の嫌いです。

マルチタスクで作業を取り組んだり、一気にアプリを開いたり、よく使うアプリをタスクバーに全部ピン止めするという方は、経験があるのではないかと思います。

今回は、そんな時のための解決方法を私なりに発見したので、書きます！

# 拡大/縮小率を調整しましょう
・・・以上です！

上段です。

ということで、windowsでは設定から、ディスプレイの拡大/縮小率とやらが調整可能ですハイ。

設定方法としては、[windows key] + [i] で設定を開き、「ホーム」が表示されておりますはずなので、左側の一覧から、「システム」をクリックし、表示される設定一覧から（たぶん）一番上のディスプレイをクリック

そして、「拡大表示とレイアウト」という項目が存在するので、そこから、[拡大/縮小]の部分でパーセンテージを選択してあげると、表示が変更されます。

以下を参考にしていただけると幸いです：

150%（推奨サイズ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674822/6260fa4e-ca75-8485-6f0d-347a8f989c98.png)

100%（現在、私が日常的に使用しているサイズ）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674822/3765a2e5-e6e7-4143-e977-43bec198bafa.png)


どうですか？

**全然使える広さが違いますよね？**

意図的に一緒にスクショさせていただいているのですが、**ウィンドウのスナップレイアウトも様々なものが使える** ようになっています！

# 最後に
windows では設定からディスプレイの縮小率を調整することが可能です。

今回は、縮小率を調整することによって使える広さを増やすといったことをやってみました。

いかがだったでしょうか？

そして、実はこれについてはいいことばかりではなく、使う人にとっては、むしろ生産性低下の大きな原因になってしまいます。

いかに、この記事を作成している際の、ブラウザの表示をスクショさせていただきます：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674822/966f84e2-8a35-52ae-268e-8a039d445e5e.png)

どうですか？

**おっそろしく** 文字が小さいことがわかると思います。

スクロールの手間は小さくなりますが、このサイズの文字では読みにくいといった場合、それは大きなストレスになり、生産性は大幅に下がってしまうでしょう。

以上をまとまますと、

**縮小率 100% を使って生産性が向上するかどうかはあなた次第** ということです。

・・・かなり適当なまとめに思えますが、今回は「私が使ってみて **便利だった** から、**生産性が向上した** から」紹介させていただきました。

今後もこのディスプレイ設定で頑張っていきたいと思います（藁

最後まで読んでくださり、本当にありがとうございました！！
新卒1年目がスクラムマスターを任された！

## はじめに
この記事では、23年に新卒エンジニアとして入社し、新卒1年目からスクラムマスターを任されてからの8ヶ月間を振り返り、試行錯誤してきたことについてお話ししたいと思います。最後まで読んでいただけると幸いです。

## スクラムで使用していたツール
- Backlog: 進捗管理のためにカンバンボードとして使用
- jamboard: 振り返りでFun Done Learnを行う際に使用
- gather: チームでスクラムイベントを行う場として使用(ポイント付もここで行っていました)
- GitHub: いうまでもなく、コード開発で使用

## スクラムマスターになる前のチームの課題
開発者として3ヶ月ほどチームで活動し、以下の改善点があると考えていました。
1. スクラムマスターとプロダクトオーナーが同じ人であり、**負担が偏っている**
2. チーム内で新しいチケットを切る人が**固定化**されている
3. ベロシティがスプリントによって差があり、**消化予定ポイントが見積りづらい**
4. GitHubのPRにBacklogのチケットを貼っているが、リンク切れ等で背景が追えなくなってしまう

皆さんのチームでも似たような課題・悩みがある方も多いのではないでしょうか？
私はスクラムマスターを引き受けるのであるならば、この課題を少しでも解決したいと意気込んでいました。

## スクラムマスターとして改善した点
では早速私がこの数ヶ月で挑戦したこととその結果について記述します。
### チケットの切り方を変えたお話し
チームのリーダーが主体となりチケットを切っていた方法を見直し、**miro**へ移行しました。ユーザーストーリーを作成した上でチームメンバーと話し合いながらチケットを切るようにしました。この際、これまでチケットを切っていた方にお願いして、細分化までは行わないようにしてもらいました。

**メリット**: 
- チームメンバーが背景を知った上でチケットを取ることができるようになったので、その後の個別の相談が少なくなった
- チームの誰でもユーザーストーリ経由でチケットを切って良いという感覚が生まれ、チケットを切る偏りが小さくなった
- チーム内の負担が分散された

**デメリット**
- スプリントプランニングに今まで以上に時間がかかるようになった(始めた当初は約1.5倍ほど時間がかかるようになった)
- ユーザーストーリー上のチケット(以下プロダクトバックログ)とBacklog上のチケット(以下スプリントバックログ)の2重管理となり、スクラムマスターとしての雑務が増えてしまった

### ベロシティの計測方法を変えたお話し
これまでは、スプリントの振り返りの際に`スプリントで消化したポイント×キャパシティ`をベロシティとして次のスプリントで使用していましたが、振り返りで消化したポイントと実際のポイントに乖離がある場合に申告してもらい、その原因を話し合った上でポイントを再調整する作業を入れました。また、ベロシティも3回分のスプリントの平均ベロシティとすることで、より実態に近いベロシティを算出するようにしました。
**メリット**
- スプリント毎の消化予定ポイントのブレが小さくなりチーム内でこの指標に対する意識が強くなった

**デメリット**
計算が少し面倒になるだけで、他のデメリットはなし

### BacklogをやめてGitHub Actionsへ移行したお話
スプリントバックログをGitHub Actionsへ移行しました。

**メリット**
- Backlogのリンク切れがなくなった
- GitHubのワークフローを使用することで、少しボードの管理が楽になった(自動アーカイブやDoneへのチケット移動など)
- スプリントでのグラフの可視化をより自由に作成できるようになった（例えばスプリント毎にどのリポジトリに対するチケットが多かったのかを可視化し、振り返りで使用することができるようになった）

**デメリット**
- 親子課題がGitHub Actionsの基本機能ではないなどの制限はありますが、私のチームではこの機能をほとんど使用していなかったのでほとんでデメリットにはならなかった

### 他チームのスクラムマスターと意見交換をする機会を作った
スクラムマスターをしながら気づいたのですが、同じ会社であってもスクラムチームが異なると、それぞれで独自のスクラムの形を模索し、それに対する情報の共有がありませんでした。そこで、数ヶ月に1回各チームのスクラムマスターが集まり、現状のチームで抱えている課題について話し合う場を設けました。

**メリット**
- チーム内で悩んでいることは大抵どのチームでも共通で、それを共有することでより迅速に問題解決が行える
- スクラムをする上で困ったことを気軽に相談できる場ができる

## 最後に
この数ヶ月、私が試行錯誤しながらスクラムマスターとして悪戦苦闘してきたことを書きましたが、トータルでは当初の課題を解決できたのではないかと思います。
また、スクラムマスターとして常に意識していたのは「自分のチームにとって最善の方法は何か」ということでした。もちろん、教科書通りのスクラムであればアンチパターンな部分もあるかもしれませんが、現状を踏まえた上で改善を行わないと本末転倒な結果を招きかねません。チームは生き物のように常に動いているので、今後もその変化を捉えながらスクラムマスターとして邁進していきたいと思います。
「Uptime Kuma」のステータスページをCloudflaredを使って外部に公開する

# 読み飛ばしてください
おはようございます、しなもんです。

:::note warn
この記事にたどり着いたあなたは、きっと、おそらく、Uptime Kumaの構築が終わっていることでしょう。

終わっていない方はこちらの記事を参考に構築してきてください！

https://qiita.com/CinnamonSea2073/items/3f8af558b9b5a2a7381a
:::

# 本題

Uptime Kumaには、なんとデフォルトでCloudflaredが付属しています。

:::note info
**cloudflaredってなんぞや**

cloudflaredというのは、Cloudflareという会社が提供するサービスの一つです。（名称がややこしい）

簡単に言うと、セキュアな状態で**ポートに穴を開けずとも外部にサイトを公開できる**サービスです。
:::

なので、この記事ではそのcloudflaredを使って外部に簡単にステータスページを公開していきます。

# 前提

* 独自ドメインを所有し、CloudflareでDNSの管理をしている必要があります。
* Cloudflareアカウントが既にあるものとします。

# トークンを取得する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/c6a97b8a-3745-22f6-83f3-d07bc5b9bb96.png)

Cloudflareのダッシュボードにアクセスし、「Zero Trust」にアクセスします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/491378a3-160f-b84e-b840-979a2aec1a80.png)

Networksの中に隠れている「Tunnels」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/dcec65c6-9b35-5a17-7bcf-31a3fb3f07c9.png)

「Create a tunnel」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/26a187ef-d7ae-d7b7-5379-1e502013a1c8.png)

「Cloudflared」を選択した状態で「Next」。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/b02ab2d0-74c8-5d97-af2f-c04d33b84477.png)

名前を入力したら「Save tunnel」。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/1394ab02-2d47-4140-7cdc-8e9efb23dee9.png)

```bash
$ cloudflared.exe service install eyJhIj...
```
の部分をクリックしてコピーします。

# インストール

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/941bad8d-764d-a2d8-6208-d56a93f63e04.png)

Kumaに戻り、設定を開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/d615c805-dec0-be28-9204-d6e3d177cd62.png)

リバースプロキシのタブを開き、`Cloudflare Tunnel Token`に先ほどコピーしたものをそのままペーストします。

そして「始める Cloudflared」をクリックすると、準備はOKです。

# ドメインの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/ca8c3705-4b0c-b904-5343-199845d8c066.png)

Cloudflareに戻り、StatusがConnectになっていることを確認します。
「Next」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/7613f642-18c1-e2b6-0cd4-494a027d3ff3.png)

ドメインの設定をします。

> Subdomain

任意のサブドメインを入力してください。

> Domain

自分の所有するドメインを選択してください。

> Path

無くても構いません。

> Type

HTTPを選択してください。

> URL

localhost:`<設定したポート番号>`
としてください。

最後に、「Save」をクリックして準備は完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927831/ffe2fb76-9268-4a13-28ef-7772458da680.png)

指定したリンクからアクセスできるようになりました。
お疲れ様でした。
Bashのエイリアス設定方法

## 概要
Bashで毎回長いコマンドを短縮する方法を紹介しています。


## 環境
エディタ：nano
シェル：Bash


## 手順
### 1.　エイリアス一覧を確認※省略可能
ターミナルで現在設定されているエイリアス一覧を表示させます。
```bash:Bash
alias
```
---
### 2.　'.bashrc'ファイルをnanoで開く
`.bashrc`ファイルはBashシェルの設定をカスタマイズするために使用します。
※`rc`の意味は`run command`
※`.bashrc`ファイルはLinuxで各ユーザーのホームディレクトリに存在
```bash:Bash
nano ~/.bashrc
```
---
### 3.　エイリアス追加する箇所を確認
エディタを開くと`# some more ls aliases`という記述があるので
その下にカスタマイズしたいエイリアスを記述するための余白を作成する。
※lsコマンドに対するエイリアスが既に定義されている。

![screenshot_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711935/e69d46b9-27cf-d3ac-5488-aaac12a7b4e4.png)


---
### 4.　エイリアス追加
構文
```bash:Bash
alias <短縮コマンド>='<元のコマンド>'
```
例えばDocker関連のコマンドを短縮したい場合、以下のように記述。
```bash:Bash
# some more docker aliases
alias d='docker'
alias dc='docker compose'
alias dcwe='docker compose exec web'
```

![screenshot_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2711935/6d3f0c93-cc65-4d54-bd12-48918b111539.png)

---

### 5.　保存と終了

①Ctrl+O を押して保存
②エンター
③Ctrl+X を押してエディタを閉じます。

---

### 6.　反映
エイリアス設定を反映
```bash:Bah
source ~/.bashrc
```

---

参考記事

https://www.ne.jp/asahi/tao/elis/bitfaq/s001.html#1993.4


https://qiita.com/turmericN/items/dc62c06dce773ec41133
【初心者】Proxmox PVEノードのIPアドレスをDHCPにする

検索したのですが、意外となかったので投稿させて頂きます。

# 経緯
・なるべくクライアントドリブンな静的IPを使いたくない
・[Unifi Expressを導入したので](https://qiita.com/minoden_osaka/items/5ec8a687798b1dd5cc5a)ルーター側で（たぶん）できそう

# ブリッジポート名の確認
・機種によって数字が変わることがあるようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/d3aa40b8-3883-6f6c-37b2-9fa29ac9cb46.png)

# ネットワークコンフィグを開く
```.sh
nano /etc/network/interfaces
```
ここの静的IPの設定を書き換えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/080d868a-6ee2-c4d8-8892-31659cdfec1c.png)

# 設定変更

```.sh
auto vmbr0
iface vmbr0 inet dhcp
    bridge-ports enp2s0
    bridge-stp off
bridge-fd 0
```
保存したらPVEを再起動します。

# Unifi Express側の設定
・Client Devicesから設定できそうでした。
・上にProxmox上の仮想マシンも表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/21df8a49-ed3d-17f7-9df4-ae1d4f7d407e.png)


# 固定IPに設定
・Settingsから簡単にできました。
・これで、しばらくするとhttps://<このIP>:8006にアクセスしてPVEにログインできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/12d1521b-74e8-3ca4-213a-2dac9dd71ab8.png)

# 切り替わりを見る
・永続的なpingを打つことで切り替わったタイミングが分かります。
```
ping -t <このIP>
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/790864/4267ca04-67ce-0014-22a1-2109e1fcfb4d.png)

# まとめ
・Proxmox on NUCということもあり可搬性を担保しているため、これで上位ルーターが変わったりしてIPレンジが変わるとアクセスできなくなる問題が解決できました。
・自分の用途（持ち運べる開発環境）という意味ではDHCPが好適でした。
・クラスターを組む予定でしたらもしかしたら問題が生じるかもしれませんのでご注意下さい。

# コラム
・Unifiから見て仮想マシンもProxmoxも同列に見えてしまうのがちょっとだけ気になったので、難易度が高そうですが、こんどはNATもやってみたいと思います。
・ただその場合、Unifi側での細かいルーティングとかはできなくなる？ので一長一短かなと思いますが、ネットワーク初心者としては勉強にはなりそうです。

# 参考サイト
https://forum.proxmox.com/threads/set-a-dynamic-address-to-pve.119847/
Ubuntu 22.04で全角ピリオドを標準設定する方法

## Ubuntu 22.04で全角ピリオドを標準設定する方法

全角ピリオドを標準設定する方法に関する記事があまりなかったので書きます。
以下のリンク先にも説明がありますが、バージョンが20.04で、少し内容が違ったのでそこだけ修正して記載します。

参考記事：https://qiita.com/hoshianaaa/items/cfd7396d0de7fd04bbf8

---

1. 右上の日本語入力できる部分をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323577/d2c20d67-88d4-3ac9-c7d2-662b3f2fae88.png)
1. プロパティを開くと以下の設定が開かれるので、その設定から「、 。」を「、 .」に変更します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2323577/7cca6ccd-7120-2ec4-697e-cfa29337c853.png)

1. 完了

できました．
大津の２値化のプログラム

今回は前回記載した大津の２値化をPythonでプログラム作成します。


# Pythonでのプログラミング
```python
import cv2
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib

# 画像を読み込む（ここでは適切なパスを指定してください）
image = cv2.imread('hoge.jpg', cv2.IMREAD_GRAYSCALE)

# 大津の二値化を適用する
_, binary_image = cv2.threshold(image, 0, 255, cv2.THRESH_OTSU)

# ヒストグラムを計算
hist_original = cv2.calcHist([image], [0], None, [256], [0, 256])
hist_binary = cv2.calcHist([binary_image], [0], None, [256], [0, 256])

# ヒストグラムを表示
plt.figure(figsize=(12, 7))
plt.subplot(121)
plt.plot(hist_original, color='blue')
plt.title('元画像のヒストグラム')
plt.xlabel('ピクセル値')
plt.ylabel('頻度')
plt.grid()

plt.subplot(122)
plt.plot(hist_binary, color='blue')
plt.axvline(x=_, color='red', linestyle='--', label=f'大津の2値化での閾値 ({_:.2f})')
plt.title('大津の2値化後の画像のヒストグラム')
plt.xlabel('ピクセル値')
plt.ylabel('頻度')
plt.legend()
plt.grid()
plt.tight_layout()
plt.show()
```

上記のようなプログラムを実行すると、元の画像のヒストグラムが左図で、大津の2値化で2値化した結果のヒストグラムは右図です。
AWS Data Engineer Associate受験レポート

# 概要
先日、Data Engineer Associateを受験して暫定全冠に復帰する事ができました。
今後受験される方の助けになれば幸いです。

## 自分の経験値
AWS歴は約3年ですが、データ分析周りはほとんど触った事がありませんでした。
そのため、試験前は会社の環境で公式ハンズオンなどをある程度触った上で受験しました。

## 感想
廃止されたData Analytics Speciality(以下、DAS)とDatabase Speciality(以下、DBS)の範囲をカバーする試験と聞いていたのですが、どちらかといえば前者のDASの毛色が強かったように感じました。DBS関連も数問あったと思うのですが、記憶にあまり残ってません。

問題の難易度としては、Associateレベルにしてはかなり細かい部分まで聞かれた印象がありました。正直なところ、これのProfessionalレベルが出ると自分にとってはかなり厄介な試験になるなと感じさせられました。

試験対策としては参考にしたブログ以外と合わせて、各種BlackBeltも読んでいましたが、それだけでは厳しい問題もあったので、公式ドキュメントをちゃんと読んでいて良かったと思いました。

ただ、実務経験がなかったために全くわからない問題が数問あったので、いつか来るProfessionalの試験に向けて空いてる時間にサービスに触っておこうと思いました。

## 参考にしたもの

・[AWS Certified Data Engineer - Associate(DEA)の学習方法](https://tech.nri-net.com/entry/aws_certified_data_engineer_associate)

NRIネットコムの小西さんが書かれたブログなのですが、ほぼこれに書いてある内容を覚えられれば合格ラインは達成できると思います。自分はそれくらい参考になりました。
Db2 activate と deactivate

## activateとdeactivate

起動処理や停止処理の前に入れるのが普通なんだろうか？



### まずは、activateから

```
[db2inst1@DB2 ~]$ db2 activate db zzz
DB20000I  ACTIVATE DATABASE コマンドが正常に完了しました。
[db2inst1@DB2 ~]$
```

activate状態で、再度実行すると以下のようなエラーになる
戻り値は2でした

```
[db2inst1@DB2 ~]$ db2 activate db zzz
SQL1490W  データベースは正常にアクティブになりましたが、
このデータベースは 1
つ以上のノードですでにアクティブになっています。
[db2inst1@DB2 ~]$ echo $?
2
```

### 次に「deactivate」

こっちは何度実行してもエラーは出ませんでした。
そういうものなんだろうか？

```
[db2inst1@DB2 ~]$ db2 deactivate db zzz
DB20000I  DEACTIVATE DATABASE コマンドが正常に完了しました。
[db2inst1@DB2 ~]$ echo $?
0
[db2inst1@DB2 ~]$ db2 deactivate db zzz
DB20000I  DEACTIVATE DATABASE コマンドが正常に完了しました。
[db2inst1@DB2 ~]$ db2 deactivate db zzz
DB20000I  DEACTIVATE DATABASE コマンドが正常に完了しました。
[db2inst1@DB2 ~]$ db2 deactivate db zzz
DB20000I  DEACTIVATE DATABASE コマンドが正常に完了しました。
[db2inst1@DB2 ~]$ db2 deactivate db zzz
DB20000I  DEACTIVATE DATABASE コマンドが正常に完了しました。
[db2inst1@DB2 ~]$ db2 deactivate db zzz
DB20000I  DEACTIVATE DATABASE コマンドが正常に完了しました。
[db2inst1@DB2 ~]$ echo $?
0
```


参考URL

https://qiita.com/kayokok/items/ffd37a6f40cb714412f6
apache2.2で特定のIPからのアクセスを制限する

apache2.2で特定のIPからのアクセスを制限するには、以下のように書く

## 許可するIPが先、拒否するIPが後の場合
```
Order allow,deny
Allow from xxx.xxx.xxx.xxx
Deny from xxx.xxx.xxx.xxx
```

## 拒否するIPが先、許可するIPが後の場合
```
Order deny,allow
Allow from xxx.xxx.xxx.xxx
Deny from xxx.xxx.xxx.xxx
```

## 気をつける点

特定のIPだけ許可して、それ以外は全拒否したい場合
以下の場合、許可した後に全拒否されるので、意図した動作にならない
```
Order allow,deny
Allow from xxx.xxx.xxx.xxx
Deny from all
```

正しくは以下

全拒否した後に特定のIPだけ許可できる
**つまり、Orderの順がキモということ**
```
Order deny,allow
Allow from xxx.xxx.xxx.xxx
Deny from all
```
なぜか画面から変更できない設定



+ [Chatterプロファイルからレコードタイプを削除](https://qiita.com/Keiji_otsubo/items/178a5c6933618ffb2b30)

# MutingPermissionSet

+ [Where I can see the list of Muting Permission Set in Group that I created?](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007epr4d)

+ [Unable to create labels for mute permission sets in groups](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007cmQo8)
Docker を基本からまとめてみた【Docker入門】

## システム構成要素

|アプリケーション |ミドルウェア  |OS  |ハードウェア|
|---|---|---|---|
|クライアントサイド<br>サーバーサイド  |DB,Webサーバー<br>など  |Linux,Mac,Windows<br>など  |CP,ネットワーク<br>など |
|JS,React,PHP etc |MySQL,nginx etc || |


## Docker とは？

- 仮想環境を作ることができるサービス 

※ 仮想環境：本来ある環境とは別の環境を作ること

- DockerFileやdocker-composeを使ってインフラ情報をコード化する

※ 注意事項：Dockerを使用する上でかなりのメモリを消費する。PCのメモリは16GB以上がおすすめ

- バージョンを細かくしてContainerに入れる

## Docker Image とは？

- Docker ImageからDocker Containerを生成する

## Docker Container とは？

- PCの中で動く仮想環境の空間

## Docker Repository とは？

- Docker Repository ⇨ Docker Image　⇨　Docker Container
- Docker Repositoryの例　⇨ Docker Hub,GCR,ECR

## Docker Compose とは？

- Containerを複数を生成することができ、それぞれ独立をしているが連携し合ってデータをやり取りすることができる

## Docker Volumes とは？

- データを入れて保存しておける領域


## 参考サイト
[世界一わかりやすいDocker入門！爆速で開発環境を作る方法](https://www.youtube.com/watch?v=YfaB3PJv1f0)
指定ファイル以外を再帰的に削除する

```Main.java

package main;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class Main {
	String absolutePath = "C:\\Users\\ \\Desktop\\～♪";
	ArrayList<String> deleteFileList = new ArrayList<String>(Arrays.asList(
			".gitignore",
			"Tests.java",
			"LogAspct.java"
			));

    public static void main(String[] args) throws IOException {
    	new Main();
    }
    
    public Main() throws IOException {
    	
        findAllFile(absolutePath);
        deleteEmptyDirectory(absolutePath);
    }

    public List<File> findAllFile(String absolutePath) throws IOException {

        List<File> fileList = new ArrayList<>();

        Stack<File> stack = new Stack<>();
        stack.add(new File(absolutePath));
        while (!stack.isEmpty()) {
            File item = stack.pop();
            if (item.isFile()) {
            	fileList.add(item);
            	deleteFile(deleteFileList, item);
            }

            if (item.isDirectory()) {
        		for (File child : item.listFiles()) {
        			stack.push(child);
        		}
            }
        }

        return fileList;
    }

    public static void deleteEmptyDirectory(String target) {
		 
    	System.out.println(target);
        Stack<File> stack = new Stack<>();
		try {
			File directory = new File(target);
			File[] files = directory.listFiles();
 
			for(File file: files) {
				if (file.isDirectory()) {
					stack.add(file);
					deleteEmptyDirectory(file.getPath());
				}
			}
			
	        while (!stack.isEmpty()) {
	            File file = stack.pop();
		    	System.out.println("dir削除：" + directory.getAbsolutePath());
                ファイル消える～♪ file.delete() 
	        }
		} catch (Exception e) {
			System.out.println(e);
		}
	}
    
    private void deleteFile(List<String> dList, File file) throws IOException  {
    	
    	for(String fileName : dList) {
    		if(file.getAbsolutePath().contains(fileName)) {
    			return;
    		} else {
    		}
    	}
    	System.out.println("ファイル削除：" + file.getAbsolutePath());
        ファイル消える!! file.delete() 
    }
}
```
WSL上のDockerコンテナからホストマシンにアプリログを出力する。

ローカルのDockerコンテナ上で動いているSpring bootのアプリログを、コンソールではなくファイルに出力したかったのですが、なかなか設定が上手くいかなかったので備忘として残しておきます。

# 環境
||バージョン|
|-|-|
|OS|Windows 10|
|WSL|2.2.4.0|
|Docker|26.1.3|
|docker-compose|1.25.0|
|Spring Boot|3.3.1|

# 設定
logbackの設定とdocker-compose.yamlの設定をしていきます。
## logback-spring.xml
locaback-spring.xmlにはログファイルの出力先を設定していきます。
```xml:src/main/resouces/locback-spring.xml
<configuration>
    <!-- 出力先とファイル名 -->
    <property name="directory" value="log" />
    <property name="fileName" value="app.log" />

    <appender name="FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${directory}/${fileName}</file>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${directory}/${fileName}-%d{yyyy-MM-dd}.log</fileNamePattern>

            <maxHistory>10</maxHistory>
        </rollingPolicy>

        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>

    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
        <!-- ファイルにも書き出すようにする -->
        <appender-ref ref="FILE" />
    </root>
</configuration>
```

:::note warn
今回は説明を簡略化するため、プロファイルによる出力先やログレベルの切り替えはしていません。
:::

## docker-compose.yaml
docker-compose.yamlにはログファイルの出力先と、ホストマシンのディレクトリをリンクさせるためにvolumesを指定します。
```yaml:docker-compose.yaml
version: '3'
services:
  app:
    image: eclipse-temurin:21
    build:
      context: .
      dockerfile: Dockerfile
      args:
        - JAR_FILE=build/libs/*.jar
    ports:
      - "8080:8080"
    entrypoint: ["java","-jar","/app.jar"]
    volumes:
      - ./build/libs:/build/libs
      - /mnt/c/log:/log     # これを追加する
```

## DockerFile
念のため、今回使用したDockerFileも記載しておきます。
```Dockerfile
FROM eclipse-temurin:21
ARG JAR_FILE=build/libs/\*.jar -t springio/gs-spring-boot-docker .
COPY build/libs/OutputSpringLogOnDocker-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","/app.jar"]
```

# まとめ
ローカルで動かす時は普段はコンソールで確認していたので気にしていませんでしたが、ファイルとして出力するとなると意外に苦労しました。
volumeの指定がWindowsのパスではなく、WSLのパスにする必要があることに気づけばすぐだったのですが・・・。
プラグイン紹介その1｜小さな改善、大きな効果、Vim Yank Highlightのススメ

## はじめに

### この記事を読むとできること

ObsidianのVimモードでヤンクしたテキストをハイライトするプラグイン「Vim Yank Highlight」の効果や使いかた、インストール方法を理解できます。

![SS 2024-06-29 10.26.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/584d825d-4ad5-1ffc-a050-8e2d43b4f97a.png)

▲ たとえば `2yy` した場合

### 記事を書くに至った背景

ObsidianでのVimモードでのテキスト編集は非常にここちよいものですが、ヤンクしたテキストを視覚的に確認できないという問題がありました。

このプラグインはその問題を解決し、編集体験を大幅に向上させます。ごく小さな機能ですが、想像以上に大きな効果をもたらします。

## つかいかたと効果

Vim Yank Highlight Pluginは、ヤンクしたテキストをさりげなくアニメーションでハイライトします。これにより、ヤンクした部分が一目で分かり、編集作業がスムーズになります。これだけと言えばこれだけですが、その効果は絶大です。

## インストールと設定方法

### コミュニティプラグイン

1. Obsidianを開きます。
2. 設定 > コミュニティプラグイン > 閲覧 へ移動します。
3. 「Vim Yank Highlight」を検索します。
4. 「インストール」をクリックしてプラグインを有効にします。

### 設定

ハイライトがタイムアウトする時間を設定できます。

![SS 2024-06-29 10.35.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184128/2de3505d-5e4b-a825-bfa5-99c362e10860.png)

▲ デフォルト値は失念しましたが、わたしは1000msに設定しています


## おわりに

このプラグインは小さな機能ですが、編集体験を大きく向上させます。Vimモード専用で、そもそもすこしハードルは高いのですけれども。

わたしにとっては、身体とエディタが直結している感覚をもたらし、わたしをそのままObsidianに映しながら編集作業を進める助けになっています。


### 参考リンク

- [Obsidian Vim Yank Highlight Plugin GitHub](https://github.com/your-username/obsidian-vim-yank-highlight)
- [Obsidian｜使いかたとコツ（目次）](https://qiita.com/hann-solo/items/ac8fa75394813e8adcf4)

### 環境

以下のバージョンで実施しました。

- Obsidian v1.6.5
- macOS Sonoma 14.5
- MacBook Pro (14-inch, 2021)
Excel VBAで秒未満

　Excelで1秒未満の時間を扱いたい。具体的にはスポーツのタイムの記録で，1/100秒単位である。
　セルの表示形式を`m:ss.00`にし，3分45.67秒を`3:45.67`と入力するとちゃんと表示される。
　さて，VBAである。以下，必要な精度は1/100秒だが，誤差が出ていないかを見るため，表示形式を`m:ss.000`にしている。時間を発生する`TimeSerial`関数がある。しかし，これの秒（第3引数）は整数である。
```
    Cells(1, 1) = TimeSerial(0, 3, 45.67)
```
と，`45.67`と実数にしても文句は出ないが，結果は45.67秒ではなく46秒になる。あれえ。
　では，`TimeSerial`で作った45秒に0.67秒を足すか。まず，0.01秒は作れるか。
```
    Dim ts, tcs
    ts = TimeSerial(0, 0, 1)
    tcs = 0.01 * ts
    Cells(1, 1) = tcs
```
これはOK。0.67秒は作れるか。
```
    tss = 67 * tcs
```
これもOK。では足す。
```
    ti = TimeSerial(0, 3, 45)
    t = ti + tss
```
あれえ，これは46秒である。`TimeSerial`の結果は`Variant (Date)`というものらしいが，これは可能であれば1秒単位で丸めてしまおうとするもののようだ。
　`Variant`がダメなら`Single`にすればいいのか？以下にしたらできた。
```
    Dim rts As Single, rtcs As Single, rtss As Single, rti As Single
    rts = TimeSerial(0, 0, 1)
    rtcs = 0.01 * rts
    rtss = 67 * rtcs
    rti = TimeSerial(0, 3, 45)
    Cells(1, 1) = rti + rtss
```
Db2 バックアップスクリプト

## Db2バックアップスクリプト

以下のようなスクリプト
動作することは確認しました。

```
[db2inst1@DB2 ~]$ cat backupdb2.sh
db2 "connect to zzz"
db2 "quiesce database immediate force connections"
db2 "terminate"
db2 "backup database zzz to /tmp"
db2 "connect to zzz"
db2 "unquiesce database"
[db2inst1@DB2 ~]$

```

## バックアップ履歴の確認

```
list history backup ALL for soukyu
```
リレーショナルデータベース (RDBMS) の選択基準と利点

こんにちは。齋藤です。
今回はシステム構築の際に多くの場合で採用されるリレーショナルデータベース (RDBMS)の選択基準や利点に関してまとめてみようと思います。

### はじめに
リレーショナルデータベース (RDBMS) は、データをテーブル形式で管理し、SQLを使用してデータ操作を行うデータベース管理システムです。多くの企業や組織で広く使用されており、その選択にはいくつかの重要な基準があります。本記事では、RDBMSの選択基準とその利点について詳しく解説します。

### 目次
1. リレーショナルデータベースの基本
2. リレーショナルデータベースの利点
3. RDBMSの選択基準
4. 主なリレーショナルデータベース製品の紹介
5. まとめ

# 1. リレーショナルデータベースの基本
リレーショナルデータベースは、データを行と列で構成されたテーブルに格納します。各テーブルは一意のキー（主キー）で識別され、異なるテーブル間のデータは外部キーを使用して関連付けられます。

#### 主要な特徴
- **テーブル構造**: データは行と列で構成されたテーブルに格納されます。
- **SQL**: データの操作や管理にSQL（Structured Query Language）を使用します。
- **ACID特性**: トランザクションの一貫性と信頼性を保証します。

# 2. リレーショナルデータベースの利点
リレーショナルデータベースは、以下のような多くの利点を提供します。

#### データの一貫性と整合性
リレーショナルデータベースは、ACID特性（Atomicity, Consistency, Isolation, Durability）をサポートし、トランザクションの一貫性とデータの整合性を保証します。

#### 強力なクエリ機能
SQLを使用して複雑なクエリを簡単に実行できるため、大量のデータを効率的に検索、集計、分析することができます。

#### データの正規化
正規化により、データの重複を最小限に抑え、データの一貫性を保つことができます。

#### 拡張性とスケーラビリティ
多くのRDBMSは、スケーラブルな設計を持ち、大量のデータや高トラフィックに対応可能です。

# 3. RDBMSの選択基準
適切なRDBMSを選択するためには、以下の基準を考慮することが重要です。

#### パフォーマンス
システムの要求に応じて、パフォーマンス要件を満たすRDBMSを選択します。
特に、高速なクエリ応答時間が必要な場合は、インデックスやキャッシング機能が強力なRDBMSが適しています。

#### スケーラビリティ
システムの将来的な拡張を考慮し、スケーラビリティの高いRDBMSを選択します。
クラスタリングやシャーディング機能を持つRDBMSが有効です。

#### セキュリティ
データの機密性を確保するために、強力なセキュリティ機能を持つRDBMSを選択します。
暗号化、ユーザー認証、アクセス制御などが重要なポイントです。

#### コスト
ライセンス費用や運用コストを考慮し、予算に合ったRDBMSを選択します。
オープンソースのRDBMSは、コストパフォーマンスが高い場合があります。

#### サポートとコミュニティ
サポート体制が充実しているRDBMSを選択します。公式サポートの有無や、活発なコミュニティが存在することは、問題解決の迅速化につながります。

# 4. 主なリレーショナルデータベース製品の紹介
以下に、代表的なリレーショナルデータベースを紹介します。

#### MySQL
- **特徴**: オープンソース、広範なコミュニティサポート、高速な読み取り性能
- **利点**: 無料で使用可能、豊富なドキュメントとチュートリアル

#### PostgreSQL
- **特徴**: オープンソース、ACID準拠、強力な拡張機能とカスタマイズ性
- **利点**: トランザクションの一貫性と信頼性が高い、複雑なクエリに対応可能

#### Oracle Database
- **特徴**: 商用製品、強力なエンタープライズ機能、高度なセキュリティ
- **利点**: 大規模システム向けの高度な機能、優れたサポート体制

#### Microsoft SQL Server
- **特徴**: 商用製品、Windowsとの統合性が高い、BI機能の強化
- **利点**: 直感的な管理ツール、優れたパフォーマンスとスケーラビリティ

# 5. まとめ
リレーショナルデータベースは、多くのシステムで利用されるデータベース管理システムです。
選択基準と利点を理解することで、最適なRDBMSを選び、システムのパフォーマンスと信頼性を最大化することができます。
適切なRDBMSを選定し、効率的なデータ管理を実現しましょう。

以上、齋藤でした。

### 参考文献
- [MySQL公式ドキュメント](https://dev.mysql.com/doc/)
- [PostgreSQL公式サイト](https://www.postgresql.org/)
- [Oracle Database公式サイト](https://www.oracle.com/database/)
- [Microsoft SQL Server公式サイト](https://www.microsoft.com/en-us/sql-server)
PDF操作ライブラリのissueを調べてみた

## とあるPDF操作ライブラリのissue

とあるPDF操作ライブラリのissueに
> ページの高さを取得する関数に問題がある。
> 595x842のはずが
> 幅は595になるが、高さが-842となる。
と指摘があった。

さて、これはどんなことが起きているのか？

最近PDF関連興味があっていろいろ触っているので、この問題について調べてみた。

## PDFの座標

PDFの仕様を見てみた。

### PDFの想定する空間

まず、PDFの空間は無限の平面と考えるとしていて、
「正のX軸が水平方向の右、正のy軸が垂直方向の上」としています。
これはよく見るx,y座標の図をイメージしてもらえばいいと思います。

その中で使う場所を矩形領域として指定します。
使用する矩形領域をPDFの中ではMediaBoxで指定しています。
さらに追加で領域指定することもできたりしますが、それは置いておいて
ここではMediaBoxが所謂ページのサイズ(紙のサイズ)と考えてください。


### MediaBoxの指定値

MediaBoxは4つの数値で指定します。
この4つの数値は二つの(x,y)座標を示します。
仕様書では「通常、配列は以下の形式をとる」としており
[ llx lly urx ury ]
左下x,左下y,右上x,右上yの順となっています。

Microsoft OfficeでA4サイズのデータをPDFにエクスポートしたら
MediaBoxは[0 0 595.32 841.92]となっていました。[^1]
[^1]:ちなみに、単位は基本1/72インチ

これは
左下が(0,0)で右上が(595.32,841.92)となる矩形領域で
分かりやすくすると

左上から
(0,841)-(595.32,841.92)
(0,0)-(595.32,841.92)
となる矩形になります。
図にすると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667610/03928bee-9ebb-a420-2166-5b966443ae14.png)




そのライブラリの実装では
width = urx - llx;
height = ury - lly;
となっており
この場合

width = 595.32 - 0  = 595.32
height = 841.92 - 0 = 841.92

正しい幅と高さです。

## 問題を探る

で、問題のPDFのMediaBoxは
[0 842 595 0]
でした。

この場合
単純に読んでしまうと
左下が(0,842)で右上が(595.32,0)となる矩形領域で

   ?    -(595.32,0)
(0,842)- ?
はい、変な配置です。


幅と高さも
width = 595 - 0  = 595
height = 0 - 841 = -841
と計算さて、指摘されている通りになります。

では、正しい動作なのか？


さきほど
> 左下x,左下y,右上x,右上y の順となっています。

としましたが、実は仕様では正確に言うと
「対角線上に対向する一対の角の座標を与える4つの数値の配列として記述」
であり「左下x,左下y,右上x,右上y」であるとはしていません。
矩形は慣例的に左下隅と右上隅で指定されます。
(その場合は)通常、「左下x,左下y,右上x,右上y」になる
と記載されている、というだけです。

なので、
[0 842 595 0]は
(0,842)と(595,0)を結ぶ線分を対角線として持つ矩形領域、です。
２点を配置した図にしてしまうとすぐわかるのですが、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1667610/90110bef-a2ca-73d1-7b58-425eda4f2984.png)

これは以下のような領域です。
(0,842)-(595,842)
(0,0)-(595,0)


## 結論
これはバグでしょう。
ただ幅と高さの値を修正するだけなら簡単でしょうけど、
これを基準に描画アイテムの配置処理とかありそうなので、その辺の影響とか
もしかしたらマイナイスが出てしまうことと前提にしているアプリケーションとかありそうで、単純ではないかも？
ただ、このライブラリ最近メンテナンスされていなくてPRしたところで修正はされないと思われます。
それなりに動いているフォークがあるので、修正するとしたらそっちでやるかな。
train-images-idx3-ubyte.gz が403エラーでダウンロードできない件

## 問題点
OCRのトレーニングファイルを探していたら、以下のサイトへの誘導が多いのだが、ダウンロードリンクをクリックすると、403エラーになってしまい、ダウンロードが出来ない。

http://yann.lecun.com/exdb/mnist/


イメージ：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/a11d5584-b7b5-e848-8604-3c69724972c7.png)

↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/97f8dc20-8332-61c6-b3cf-8ab9620e8800.png)


## 解決策
Gitからダウンロードできました！
※要ログイン

https://github.com/golbin/TensorFlow-MNIST/tree/master/mnist/data

ファイル：
t10k-images-idx3-ubyte.gz
t10k-labels-idx1-ubyte.gz
train-images-idx3-ubyte.gz
train-labels-idx1-ubyte.gz

未検証だけど、ファイルサイズも一致しているので、間違いないはず。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249830/e7a890bb-c9b1-24ea-e8ae-0b65691a1eda.png)


これ探すのに、30分かかったので、記事にしておきます。


以上
wslでelixir その150

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題やってみた。

# 練習問題
Livebookで、GPIOを操作したフリをせよ。

# 方針
- Agentを使う。
- Kino使わん。


# サンプルコード

```
defmodule Pin do
	use Agent
	def start_link() do
		Agent.start_link(fn ->
			%{"GPIO15": 0, "GPIO16": 0, "GPIO17": 0, "GPIO18": 0}
		end, name: __MODULE__)
	end
	def on15() do
		Agent.update(__MODULE__, fn v ->
      IO.puts("GPIO15 1")
			Map.put(v, "GPIO15", 1)
		end)
	end
	def off15() do
		Agent.update(__MODULE__, fn v ->
      IO.puts("GPIO15 0")
			Map.put(v, "GPIO15", 0)
		end)
	end
	def on16() do
		Agent.update(__MODULE__, fn v ->
      IO.puts("GPIO16 1")
			Map.put(v, "GPIO16", 1)
		end)
	end
	def off16() do
		Agent.update(__MODULE__, fn v ->
      IO.puts("GPIO16 0")
			Map.put(v, "GPIO16", 0)
		end)
	end
	def on17() do
		Agent.update(__MODULE__, fn v ->
      IO.puts("GPIO17 1")
			Map.put(v, "GPIO17", 1)
		end)
	end
	def off17() do
		Agent.update(__MODULE__, fn v ->
      IO.puts("GPIO17 0")
			Map.put(v, "GPIO17", 0)
		end)
	end
	def on18() do
		Agent.update(__MODULE__, fn v ->
      IO.puts("GPIO18 1")
			Map.put(v, "GPIO18", 1)
		end)
	end
	def off18() do
		Agent.update(__MODULE__, fn v ->
      IO.puts("GPIO18 0")
			Map.put(v, "GPIO18", 0)
		end)
	end
end
Pin.start_link()

Pin.on15()
Process.sleep(3000)
Pin.off15()
Process.sleep(3000)
Pin.on16()
Process.sleep(3000)
Pin.off16()
```

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/40f67643-e2cc-367b-3558-a6e0a4776c2b.png)

# ブリンクさせる
```
for i <- 0..10 do
  Pin.on15()
  Process.sleep(100)
  Pin.off15()
  Process.sleep(100)
end
```


以上。
【Next.js】Drupalで準備したAPIにFetchしよ

## はじめに
Qiita/RSSシリーズです。前回までの記事を振り返ります。

### 記事①では…。
「Qiita/RSS」を題材にPHPでXMLの解析を行いました。

https://qiita.com/umekikazuya/items/c20ac26b59670a72ca7b

### 記事②では…。
「Qiita/RSS」を題材にDrupalでAPI化をしてみました。

https://qiita.com/umekikazuya/items/6379e3785b385bceabb3

## 今回は…。
タイトルでも紹介している通り、Next.js で Drupal で準備した API に Fetch してみます！！（お前フロント行けるんかい 😥）

行けないです。ストリート実装です。
夏休みの自由研究程度で見てください。

一応…。完成イメージ。
[umekikazuya.vercel.app](https://umekikazuya.vercel.app/)

## さっそくですが、実装の紹介をします。
Next.js ですが、AppRouter で実装しました。話題の TurboPack とやらも試してみました。

### Fetch実装
```tsx:/app/page.tsx
async function fetchData() {
  const response = await fetch(ENDPOINT);
  if (!response.ok) {
    throw new Error("Failed to fetch data");
  }
  const data = await response.json();
  return data;
}
// 本記事では例外処理割愛.
```

### Component実装
```tsx:/components/feed.tsx
export function feed() {
  const data: FeedType = await fetchData();
  return (
    <>
      <ul>
        {feed.data.map((item, index) => (
          <ListItem
            key={index}
            title={item.title}
            link={item.link}
            published={item.published}
          />
        ))}
      </ul>
    </>
  );
}

function ListItem({ title, link, published }: FeedElement) {
  return (
    <li className={style.li}>
      <a className={style.li_inner} href={link} target="_blank" rel="noreferrer">
        <span className={style.li_inner__title}>{title}</span>
        <time dateTime={published} className={style.li_inner__time}>
          {new Date(published).toLocaleDateString("ja-JP")}
        </time>
      </a>
    </li>
  );
}

// `new Date()`や、fetch時の例外処理は本記事では割愛.
```

## 詰まったポイントを共有します。
### 環境変数の扱い方
「サーバーサイドコンポーネント」と「クライアントサイドコンポーネント」で、環境変数の扱い方が異なるようです。
ちょっとハマりました。

> 変数をブラウザに公開するには、変数の前に `NEXT_PUBLIC_` を付ける必要があります。

クライアントサイドで使用したい時は prefix が必要なんですね。

https://nextjs-ja-translation-docs.vercel.app/docs/basic-features/environment-variables

### データのキャッシュが永続的？？
Fetch側は設定なしの場合都度通信してくれるのかと思ったらそうでもないよう。

明示的に設定する必要があるようです。
- Time-based revalidation：時間駆動
- On-demand revalidation：イベント駆動

```tsx
fetch('https://...', { next: { revalidate: 3600 } })
```

今回は、時間駆動で設定しましたが記事投稿時に何かしらのイベントを拾うように組み込むのもおもしろいかも。

## まとめ
Backend の API（Drupal）側でキャッシュ機構はしっかり組み込んだので、Frontend側の細かいキャッシュのチューニングについては本記事内では省きました。

Next.jsのDataFetchには標準でCache機構が搭載されているようですので、調査/検討してみようと思います。

Drupalだったら簡単に **Headless** できるんでぜひ試してみてくださいね。（本記事の内容は、データ自体の出力をしてないからHeadlessではないけど）

もちろん、Drupal内のData(Entity)に外部からアクセスすることも可能です。

実は、まだこのシリーズ終わりません。（え〜！！？）
せっかく準備したAPIです。活かさないともったいないですよね。
Slack通知編いきましょう。（え〜！！？）
LeetCode挑戦日記：Day22

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Medium] 1657. Determine if Two Strings Are Close

次の操作を使用して一方の文字列から他方の文字列を得ることができる場合、二つの文字列は「近い」と見なされます

操作1: 既存の任意の2文字を入れ替える。
例: `abcde` -> `aecdb`

操作2: 既存の1文字を別の既存の文字に変換し、同時に他の文字も入れ替える。
例: `aacabb` -> `bbcbaa` (すべての`a`を`b`に変え、すべての`b`を`a`に変える)

これらの操作を任意の回数だけ使用することができます。

二つの文字列`word1`と`word2`が与えられたとき、`word1`と`word2`が近い場合は`true`を、そうでない場合は`false`を返してください。

## 素直に解いてみる

### 考え方

1. `word1`と`word2`に含まれる文字の登場回数をカウントする
1. 含まれる文字が全て同じか確認し、異なる場合は`false`を返す
1. 登場回数を比較し、異なる要素がある場合は`false`を返す

### コーディング

```typescript
function closeStrings(word1: string, word2: string): boolean {
    const map1 = new Map<string, number>();
    const map2 = new Map<string, number>();

    word1.split('').forEach((c) => {
        let count = map1.get(c) ?? 0;
        count++;
        map1.set(c, count);
    });
    word2.split('').forEach((c) => {
        let count = map2.get(c) ?? 0;
        count++;
        map2.set(c, count);
    });

    if (map1.size !== map2.size) { return false; }

    const keys1 = Array.from(map1.keys());
    const keys2 = Array.from(map2.keys());
    if (keys1.some((key) => keys2.indexOf(key) === -1)) {
        return false;
    }

    const values1 = Array.from(map1.values()).sort((a, b) => a - b);
    const values2 = Array.from(map2.values()).sort((a, b) => a - b);
    for (let i = 0; i < values1.length; i++) {
        if (values1[i] !== values2[i]) { return false; }
    }

    return true;
};
```

### 結果

## 改善：`Map`を使わない

### 考え方

1. 英小文字しか入らないので、`Map`を使う必要がないので、配列に置き換える

### コーディング

```typescript
function closeStrings(word1: string, word2: string): boolean {
    if (word1.length !== word2.length) { return false; }

    const letterCounter1 = new Array(26).fill(0);
    const letterCounter2 = new Array(26).fill(0);

    for (let i = 0; i < word1.length; i++) {
        letterCounter1[word1.charCodeAt(i) - 0x61]++;
        letterCounter2[word2.charCodeAt(i) - 0x61]++;
    }

    for (let i = 0; i < 26; i++) {
        if (
            (letterCounter1[i] && !letterCounter2[i]) ||
            (!letterCounter1[i] && letterCounter2[i])
        ) {
            return false;
        }
    }

    return letterCounter1.sort((a, b) => a - b).join('') === letterCounter2.sort((a, b) => a - b).join('');
};
```

### 結果

Runtime：74ms
Beats 99.18%

Memory：58.30MB
Beats 81.74%
LeetCode挑戦日記：Day21

# はじめに

最近、業務で実装する時間よりも資料作成やレビューをする時間が多くなってきました。
このままでは自身のコーディング能力が落ちそうで怖いので、LeetCodeを始めてみました。

自身の学習の記録 & LeetCodeに興味のある人が挑戦しやすいように、記事に残していきます。
このような競技プログラミングをした経験がないので、ひよってEasyからやっていきます...

# [Easy] 1207. Unique Number of Occurrences

整数の配列`arr`が与えられたとき、配列内の各値の出現回数がすべてユニークである場合は`true`を、そうでない場合は`false`を返してください。

## 素直に解いてみる

### 考え方

1. 各値の出現回数をカウントする
1. 出現回数が被っていなければ、`true`を返す

### コーディング

```typescript
function uniqueOccurrences(arr: number[]): boolean {
    const map = new Map<number, number>();

    arr.forEach((num) => {
        let count = map.get(num) ?? 0;
        count++;
        map.set(num, count);
    });

    const values = Array.from(map.values());
    return [...new Set(values)].length === values.length;
};
```

### 結果

Runtime：54ms
Beats 83.36%

Memory：51.32MB
Beats 94.76%
【論文毎日読んでみる#2】BERTが発表された論文 "BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding" (Devlin et al., 2018)

# 読んだ論文
本記事は以下の論文を読んだ際に記録した要約とメモです。

[Devlin, Jacob, et al. "Bert: Pre-training of deep bidirectional transformers for language understanding." arXiv preprint arXiv:1810.04805 (2018).](https://arxiv.org/pdf/1810.04805)


この論文は、BERTは自然言語処理に革命をもたらしたモデルで、テキストデータの高度な解析に役立ちます。経済データのテキストマイニングや感情分析などにも応用できます。

# 要約とメモ
## abstract
- BERTという新しい言語表現モデルを紹介するね！
    - BERTは```Bidirectional　Encoder　Representations　from　Transformers(トランスフォーマーからの双方向エンコーダー表現)```の頭文字をとったものです
- 一方向性という問題を緩和することで、精度改善したんだ！

## 1. Introduction
- 言語モデルの事前学習は、多くの自然言語処理タスクの改善に有効であることが示されている
    - Dai and Le, 2015
    - Peters et al., 2018a
    - Radford et al., 2018
    - Howard and Ruder, 2018
- 事前に訓練された言語表現を下流のタスクに適用するための既存の戦略は、特徴ベース```feature-based```と微調整```fine-tuning```の2つ
    - ELMo (Peters et al., 2018a)のような特徴ベースのアプローチは、追加特徴として事前に訓練された表現を含むタスク固有のアーキテクチャを使用する
    - Generative Pre-trained Transformer (OpenAI GPT) (Radford et al., 2018)のような微調整アプローチは、最小限のタスク固有のパラメータを導入し、全ての事前学習済みパラメータを微調整するだけで、下流のタスクで学習される
- 特に微調整```fine-tuning```においては、一方向性（unidirectional）が精度改善のボトルネックになっている
    - 一方向性とは、モデルが文の一方向（例えば左から右）にしか情報を処理しないこと
    - 例えばGPTのモデルでは、文を左から右に読むようにトークン（単語や文字）を処理していて、各トークンは前のトークンしか参照できないという特徴を持ちます
- BERTは双方向エンコーダー表現という意味で、この一方向性の問題を緩和しようとしているよ！
    - コードと事前学習済みモデル公開しているよ
    - https://github.com/google-research/bert


## 2. 関連研究
特徴ベース```feature-based```と微調整```fine-tuning```の2つにわけて紹介してくれている。原著論文参照してください

## 3. BERT
BERTの説明

## 4. experiments
一般言語理解評価(GLUE)で評価したときに、GPT３に比べても良い結果だった
awkコマンドで99.0タイルを取得

## はじめに

過去対向システムが既存機能を使いたい希望があり、
ピーク時間帯の応答時間(TAT)の99.0パーセントタイル値を取得する依頼がありました。

「なんだ？99.0パーセントタイルって」という状態だったので、ググって参考にしたのは以下のページでした。


@atsutama さんの投稿
[99.0パーセントタイルってどういう意味？](https://qiita.com/atsutama/items/6be56c0d8d65874eb2c7)


## awkコマンドで取得

もちろん色んな方法があると思いますが、よっぽど叩かれている機能だったし、
ピークごと機能ごと定期的に取得しているわけではなかったので、
ログから取得せざるを得ませんでした。

色々調べたところ、既存ツールがあったので
そこからコマンドを少しずつ抜粋したり応用してできました。

まず、機能と期間に絞るログ整形はした上で、以下のような形でファイルで出力しました。
※時間帯は全部同じ（ピーク時間帯の1時間）
```
#分、秒、応答時間ms
00 00 1000
00 00 2000
00 00 1500
00 01 800
```


その上、以下コマンドを実行すると
ちょうど応答時間msが99.0パーセントタイル値で出力されました。

```
cat ファイル名 | sort -n | awk 'BEGIN{c=0} length($0){a[c]=$0;c++]END{pt=(c/100*(100-99)); pt=pt%1?int(pt-0.5)+1:pt; print a[c-pt-1]}'
```



## 検証方法

一番簡単なのは、100行くらいデータを作成して、
excelとかに貼り付けて取得した99.0パーセントタイル値が同じであるかを
コマンド結果と比較することで簡単にいけました。