OmniAICreator/Qiita-1.07M huggingface dataset:
固定ヘッダがあるモーダル内でさらに内部ヘッダを固定する方法【vue.js3】

## 説明

### HTMLテンプレート（\<template>）
- 役割: コンポーネントの構造を定義します。外側のヘッダ、内部のヘッダ、コンテンツ領域を含むモーダルを構築します。
- 要素:
  - `<div class="modal">`: モーダル全体を包む要素。
  - `<div class="modal-header" ref="modalHeader">`: 外側の固定ヘッダ。ref属性でDOM要素を参照します。
  - `<div class="modal-content">`: モーダルのコンテンツ領域。
  - `<div class="inner-header" :style="{ top: innerHeaderTop + 'px' }" ref="innerHeader">`: 内部の固定ヘッダ。動的にtopプロパティを設定します。

### JavaScriptロジック（\<script setup>）
- 役割: 外側のヘッダの高さを計算し、内部のヘッダの位置を動的に調整します。
- 部分:
  - `ref`の使用:
    - `modalHeader`, `innerHeader`, `innerHeaderTop`: `ref`を使用してリアクティブな参照を作成します。
  - `updateInnerHeaderPosition`関数:
    - 外側のヘッダの高さを計算し、内部のヘッダの`top`プロパティを更新する関数です。
  - `onMounted`フック:
    - コンポーネントがマウントされたときに呼び出され、関数を実行し、イベントリスナーとMutationObserverを設定します。
  - onBeforeUnmountフック:
    - コンポーネントが破棄される前に呼び出され、リスナーを解除し、オブザーバーを切断します。

### スタイル（\<style scoped>）
- 役割: コンポーネントの見た目を定義します。モーダル全体、外側のヘッダ、内部のヘッダ、コンテンツ部分のスタイルを設定します。
- 部分:
  - `.modal`: モーダルの位置とスタイルを設定します。
  - `.modal-header`: 外側の固定ヘッダのスタイルを設定します。
  - `.modal-content`: コンテンツ領域のパディングを設定します。
  - `.inner-header`: 内部の固定ヘッダのスタイルを設定し、`top`プロパティは動的に変更されます。
  - `.content`: スクロール可能にするためのコンテンツの高さを設定します。

```vuejs
<template>
  <div class="modal">
    <div class="modal-header" ref="modalHeader">
      モーダルの固定ヘッダ
    </div>
    <div class="modal-content">
      <div class="inner-header" :style="{ top: innerHeaderTop + 'px' }" ref="innerHeader">
        内部の固定ヘッダ
      </div>
      <div class="content">
        スクロールコンテンツがここに入ります。
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';

const innerHeader = ref(null);
const innerHeaderTop = ref(0);

const updateInnerHeaderPosition = () => {
  const modalHeader = document.querySelector('.modal-header');
  if (modalHeader && innerHeader.value) {
    const modalHeaderHeight = modalHeader.offsetHeight;
    innerHeaderTop.value = modalHeaderHeight;
  }
};

onMounted(() => {
  updateInnerHeaderPosition();
  window.addEventListener('resize', updateInnerHeaderPosition);

  const observer = new MutationObserver(updateInnerHeaderPosition);
  const modalHeader = document.querySelector('.modal-header');
  if (modalHeader) {
    observer.observe(modalHeader, { attributes: true, childList: true, subtree: true });
  }

  onBeforeUnmount(() => {
    window.removeEventListener('resize', updateInnerHeaderPosition);
    observer.disconnect();
  });
});
</script>

<style scoped>
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 80%;
  height: 80%;
  background-color: white;
  overflow: auto;
  border: 1px solid #ccc;
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.modal-header {
  position: sticky;
  top: 0;
  background-color: #f1f1f1;
  padding: 10px;
  border-bottom: 1px solid #ccc;
  z-index: 10;
}

.modal-content {
  padding: 20px;
}

.inner-header {
  position: sticky;
  background-color: #e1e1e1;
  padding: 10px;
  border-bottom: 1px solid #ccc;
  z-index: 5;
}

.content {
  height: 1000px;
}
</style>
```
Inertia.jsでクソデカJSONを取り扱う際にレスポンスが遅なってた

大きなデータを取り扱う際に
ControllerとInertia.jsの間でパフォーマンスに問題が発生していた。

データ量を削減することは極めて難しく、最適化を試みても転送サイズが**742.55KB**となってしまいました。
データの分散取得と並列処理を検討したのですが、全てのデータが揃わないと作れない画面でしたので、
まずは、MiddlewareでJSONを圧縮することを考えました。

```php
namespace App\Http\Middleware;

class CompressJsonResponse
{
    public function handle(
        Request $request,
        Closure $next
    ): mixed {
        $response = $next($request);

        $content = $response->getContent();
        if (!is_string($content)) {
            return $response;
        }

        $compressedContent = gzencode($content, 9);
        if (!is_string($compressedContent)) {
            return $response;
        }

        $response->setContent($compressedContent);
        $response->headers->add(['Content-Encoding' => 'gzip']);
        $response->headers->set('Content-Length', (string) strlen($compressedContent));

        return $response;
    }
}
```

Kernel
```php
protected $middlewareGroups = [
    'compressed' => [
        \App\Http\Middleware\CompressJsonResponse::class,
    ],
];
```

クソデカJSONを生み出しているRouteにmiddlewareを適用して...

転送サイズ: 34.17KB

小さくなりました。

多段VPN接続をしているので回線速度が遅いのもあるのですが
8秒くらいかかっていたものが、1.6秒になりました。
<br><br>

CDN, Nginx

いつもありがとな！！！！！！
Sambaサーバの設定方法 (AlmaLinux 9.4)

# はじめに
SambaとはLinuxをWindowsのファイルサーバとして使用するためのOSS。Linuxで動作しながら、Windows Serverと同等の機能を提供し、WindowsをSambaクライアントとして接続する際にWinodws Serverのようにふるまう。
今回、Sambaサーバの設定を行ったので備忘録として記載する。

# 環境
AlmaLinux 9.4

# 手順
- インストール
```
$ sudo dnf install samba
```

- firewall設定
    - Sambaの通信を許可する。
```
$ sudo firewall-cmd --permanent --zone=public --add-service=samba
$ sudo firewall-cmd --reload
$ sudo firewall-cmd --list-all
```

- サービス起動設定
```
$ systemctl start smb
$ systemctl enable smb
```

- サービスの起動状態を確認したい場合
```
$ systemctl status smb
```

- Sambaサーバの共有ディレクトリ設定
    - 今回は```/var/samba/share/public```を共有ディレクトリとする。
```
$ sudo mkdir /var/samba/share/public
$ sudo chmod 0777 /var/samba/share/public
```

- smb.confの設定
    - ```/etc/samba/smb.conf```を編集する。
```
$ sudo vi /etc/samba/smb.conf
```
以下を追記する。
``` smb.conf
[public]
      path = /var/samba/share/public
      public = yes
      writable = no
```
```[public]```は共有する際のディレクトリ名
```path```: Sambaサーバの共有ディレクトリのパス
```public```: ゲストアカウントのアクセスを許可
```writable```: 書き込みを許可

- smb.confを編集後再起動
```
$ systemstl restart smb
```
ひたすら資格取得しまくったけど効果がなかった話

# 経緯
エンジニア歴10年以上ですが、資格について思うところがあったので記事にしました。

IT系の資格にはじめて触れたのが最初の会社です。
そこでは資格を取得するごとに年収が上がる制度がありました。

この制度のおかげもあって、新卒ながら結構良い給料まで上り詰めました。

しかし、資格取得に注力するあまり、次第に資格の勉強が第一優先となり、実際に手を動かしてコードを書くことが少なくなりました。書籍やオンラインコースで知識を詰め込むだけで、実際の開発環境で試行錯誤する機会が減ってしまったのです。

実業務では、資格取得に直接関係のない開発業務に従事していました。
そのため、資格取得で得た知識を業務に活かすことができず、理論と実践が乖離してしまいました。

# 教訓と学び
この経験から、私は以下の教訓を学びました。

### 資格取得は勉強過程を大事にするべき
資格を取得すること自体が目的になってしまうと、試験対策のための表面的な勉強に終始してしまいます。資格取得の過程で学ぶことを重視し、実際に理解し、応用できるようになることが重要です。

### 資格取得後も実際に手を動かして技術を身につける
資格を取得した後も、実際の開発環境で手を動かして技術を磨くことが必要です。実務に即したプロジェクトを経験することで、資格で得た知識が確かなものとなり、実際の業務に活かせるスキルとなります。

### 目的と手段が混在しないように注意
資格を取得することは目標の一つに過ぎません。最終的な目的は、エンジニアとしての技術力を高め、業務に貢献することです。資格取得が目的となり、技術力向上という本来の目的が見失われないように注意する必要があります。

# 結論
資格取得はエンジニアとしてのキャリアにおいて有益ですが、それ自体が最終目標ではありません。資格取得の過程で得られる知識と、実際の開発経験を通じて身につけるスキルの両方が重要です。資格取得後も手を動かして学び続ける姿勢を持ち、目的と手段を混同しないように意識することが、真に価値のあるエンジニアとして成長するための鍵です。
Viteを使った開発の流れ

# はじめに
この記事では、Viteを使ったフロントエンド開発の流れについて説明します。Viteは、次世代のフロントエンドツールで、超高速な開発サーバーと最適化されたビルド機能を提供します。以下に、Viteのセットアップから基本的な使い方、そしてプロジェクトのビルドまでの流れを紹介します。

https://ja.vitejs.dev/

# 前提条件
* Node.jsがインストールされていること

# 1. Viteプロジェクトのセットアップ
## プロジェクトの作成
まず、Viteのプロジェクトテンプレートを使って新しいプロジェクトを作成します。以下のコマンドを実行します。

```
npm create vite@latest my-vite-app
```

または、yarnを使用する場合:

```
yarn create vite my-vite-app
```

コマンドを実行すると、プロジェクトのテンプレートを選択するように求められます。例えば、vanilla（プレーンJavaScript）、vue、react、preact、lit、svelteなどが選択できます。ここでは、vanillaを選択します。

## プロジェクトディレクトリに移動
```
cd my-vite-app
```

## 依存関係のインストール
```
npm install
```

または、yarnを使用する場合:

```
yarn
```

# 2. 開発サーバーの起動
Viteの開発サーバーを起動するには、以下のコマンドを実行します。

```
npm run dev
```

または、yarnを使用する場合:

```
yarn dev
```

ブラウザで http://localhost:3000 にアクセスすると、Viteの開発サーバーが起動していることを確認できます。Viteの開発サーバーはホットリロードをサポートしており、コードを変更すると即座にブラウザに反映されます。

# 3. プロジェクト構成
Viteのプロジェクトはシンプルな構成になっています。以下に主要なファイルとディレクトリを説明します。

```
my-vite-app/
├── index.html
├── package.json
├── vite.config.js
├── node_modules/
├── public/
└── src/
    ├── main.js
    └── style.css
```


### index.html
index.html はプロジェクトのエントリーポイントです。

### main.js
src/main.js はJavaScriptのエントリーポイントです。このファイルで、アプリケーションの初期化を行います。

```js
import './style.css';

document.querySelector('#app').innerHTML = `
  <h1>Hello Vite!</h1>
  <p>Vite is a fast and modern build tool.</p>
`;
```

### style.css
ここにプロジェクトのスタイルを定義します。

```css
body {
  font-family: Arial, sans-serif;
  margin: 0;
  padding: 0;
  text-align: center;
  background-color: #f0f0f0;
}
```

### vite.config.js
基本デフォルトで問題ありません。カスタム設定が必要な場合、このファイルで設定を追加します。

```js
import { defineConfig } from 'vite';

export default defineConfig({
  // カスタム設定を追加する場所
});
```



# 4. ビルド
開発が完了したら、プロジェクトをビルドして本番環境にデプロイできます。以下のコマンドを実行してビルドします。

```
npm run build
```

または、yarnを使用する場合:

```
yarn build
```

ビルドが完了すると、distディレクトリに静的ファイルが生成されます。これらのファイルをWebサーバーにデプロイすることで、アプリケーションを本番環境で動かすことができます。

# まとめ
Viteを使用すると、フロントエンド開発の速度と効率が大幅に向上します。この記事では、Viteのセットアップから開発サーバーの起動、プロジェクト構成、そしてビルドまでの基本的な流れを紹介しました。Viteの公式ドキュメントも参考にして、さらに高度な機能やカスタマイズ方法を学んでみてください。
【Python】入門 開発環境を作成

# はじめに
Pythonは非常に多くのケースで利用されているプログラミング言語となります。
様々な異なるバージョンのライブラリやパッケージが必要とされることが多くなりました。

プロジェクトが異なる場合、利用するライブラリやパッケージのバージョンが異なることが多々あるため、バージョンの競合する問題が発生します。
例えば、あるプロジェクトは`requests`というモジュールを利用する場合、
`pip install requests==2.0`としてインストールした場合、別プロジェクトで1.0を利用したい場合、インストールができません。

`venv`はこのようなパッケージバージョンの競合を回避するために仮想環境を作成するツールとなります。

# venvコマンド

## 仮想環境の作成
venvコマンドで仮想環境を作成します。.venvは作成する仮想環境名になります。仮想環境名は任意で構いません。コマンドを実行するとフォルダ「.venv」が作成されます。
```bash
python3 -m venv .venv
```

## 仮想環境のアクティベート
activateコマンドで仮想環境を開始できます。
```bash
source .venv/bin/activate
```

## 仮想環境内でパッケージをインストールする
仮想環境がアクティベートになった後、パッケージのインストールを行います。
パッケージのインストールコマンドは通常のインストールコマンドと同じです。
```bash
pip install package-name
```

## 仮想環境内でパッケージ一覧を出力
requirements.txtにパッケージ一覧を出力します。
```bash
pip freeze > requirements.txt
```


## 仮想環境のディアクティベート
deactivateコマンドで仮想環境を終了できます。
```bash
source .venv/bin/deactivate
```

## 別PCに環境を複製したい場合
「仮想環境内でパッケージ一覧を出力」で出力したrequirements.txtを用いて別環境でも同一パッケージを別仮想環境で作成できます。
```bash
pip install -r requirements.txt
```

# 最後に
仮想環境の作成方法について解説しました。
同一マシンで複数環境を作成するときに困っている方が多いと思うので参考にしてもらえると助かります。
わかってみれば「なるほど」となるが、わかるまでが大変なこと

# はじめに
chromeのプラグインを作成していると、中々、原因をつかむことができなくて、困るエラーに出会います。エラーメッセージを見ても意味を理解しにくいというか、現象の原因がはっきりとメッセージに表現されていないということです。単に'undefined'と表示されても困ります。もう少し、具体的なメッセージにはならないでしょうか。どこがどう悪いからエラーになっていますとか。今回、遭遇したエラーの現象と解決策をご説明します。

# 現象
chrome.runtime.sendMessage()を使用して、background.jsへメッセージを送信しようとして、sendMessage()がundefinedというエラーになりました。
デバッガーで追うと、chromeのオブジェクトに、runtimeメソッドがありません。
runtimeがないから、sendMessageもないことになります。
ここで、なぜ、runtimeメソッドがないのかを具体的に示して欲しいのですが、その記述はありません。この原因を特定するまでに相当の時間がかかりました。
この現象をもう少し、追いかけてみました。
別のプラグインでは発生していません。そこで、何が違うのか、二つのプラグインをツールの差分を使って比較しましたが、これといってそれらしい原因は見当たりませんでした。

実際に呼び出しているコードは以下になります。
呼び出しているjavascriptは、プラグインではなく、iframeプレーヤーのjavascriptからです。そのため、g_EXTENSION_IDでプラグインを特定するIdを指定しています。


``` index_radio_simple.js(抜粋)　
            function get_tabId() {
                return new Promise((resolve, reject) => {
                    chrome.runtime.sendMessage(g_EXTENSION_ID, {'type': 'get_tabId', 'url': location.ancestorOrigins[0]}, (msg) => {
                        //応答で、tabIdを取得して、要素にセット
                        $("#tabId").html(msg);
                        resolve(msg);

                    });
                });

            }

```

# 原因
上記のコードを見ていて、ハタと気が付きました。もしかしたら、manifest.jsonの問題かなと思いました。
以下はその部分です。

``` manifest.json(抜粋)

"externally_connectable": {
    "matches": ["https://*/*"
    ]
  }


  
```
動作しなかった方のmanifest.jsonには、上記の設定がありませんでした。もともとは、動作していたmanifest.jsonをコピーして使用していましたが、そのプラグインでは不要のため、削除していました。
その後、再び、ある機能を追加するため、先のget_tabId()関数を導入しましたが、manifest.jsonまでは修正していませんでした。
このため、externally_connectableの指定がなかったため、sendMessage()でundefinedエラーがでていました。

しかし、このexternally_connectableの指定がないことと、sendMessage()でundefinedエラーが出ることのつながりがエラーメッセージを見ただけではわかりません。このことが、エラー原因の特定が遅れたことにつながります。

# 結論
今回のエラーは、manifest.jsonの指定漏れが原因でした。しかし、実際に表示されるエラーメッセージでは、その実際の原因が表示されていません。このようなエラーメッセージは他にも多くあります。中々、個々の原因までを細かく表示することはできないのでしょうか。自分に当てはめるとよくわかります。中々、そこまでは手間をかけられないですね。しかし、エラーが発生してみて、初めてわかります。もっと具体的なメッセージを出して置けばこんなに時間をかけなくてもよかったと。

# あとがき
ソースコードを再利用しているとよく、このようなことが起こります。不要なコードをカットしてゆき、新規に追加するコードを書き足してゆきます。その時に設定ファイルはそのままとか、あるいは設定ファイルにもカットする箇所があり、カットしたままで、後から、再び、カットしたコードを戻すことをしているときに起こります。
この整合性をしっかりとチェックしないと、結構、無駄な時間がとられてしまいます。何度、反省してもまた、繰り返してしまいます。
【Ubuntu22.04】VSCodeで日本語が入力できない場合の対処法

# 日本語でコメントを書きたい

私は Visual Studio Code でC++やPythonを書いています。

OSをUbuntu20.04から22.04にアップデートしたところ、日本語入力ができなくなったのでメモ。

ちなみにブラウザの検索窓など、VSCode以外ではちゃんと日本語が入力できる状態でした。(ibus-mozc)

# 結論

__公式から.debファイルをダウンロードして、それをインストールしたら直ります。__

以下のリンクから飛んで、

https://code.visualstudio.com/download


.debファイルをダウンロード、保存。

![Screenshot from 2024-08-05 18-55-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103136/dbd1dc45-5b66-a024-43cb-589de523d6fe.png)

.debファイルがDownloadsディレクトリに保存されると思うので、Software Installから実行。

![Screenshot from 2024-08-05 18-57-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103136/f5c5975c-9e4a-5173-47cb-fb7013bad329.png)


このVSCodeはなぜか日本語が打てた。めでたし。

---

# 原因: Ubuntu Software

Ubuntu Software centerで配布されてるVSCodeにバグが含まれていた模様。


![Screenshot from 2024-08-05 18-52-42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103136/a4e179ca-f808-f1d6-b024-773baf4c3f71.png)

ここの検索窓でvscodeと入力して出てくるヤツは日本語打てませんでした。

![Screenshot from 2024-08-05 18-53-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103136/ccb610b8-8082-97c5-8634-d52a6c030611.png)

許すまじ…。


# 日本語コメントは善か悪か

日本語コメントにもメリットはあります。
それは、読みやすいこと。漢字を含めると英語より情報量が濃縮できます。

また、母国語ってのも重要ですね。
チーム全員が英語得意なスーパーマンというのは日本企業なら寧ろレアケースでしょう。
新入社員やひよこエンジニア達が円滑に成長できる土台を整える事は非常に重要と考えます。

一方で外国人がチームに１人でもいる場合は、必ず英語でコメントを心がけましょう。
ただでさえ母国を離れている彼らに、職場でも疎外感を感じさせるのは冷たいと思います。
[paiza]【殿堂入りキャンペーン】名刺バインダー管理 (paizaランク B 相当)

# 力こそパワー
いい感じの公式だったりアルゴリズムが思いつかない時に大事なのは？

**そうだね、筋肉だね!!**

https://paiza.jp/works/mondai/b_rank_skillcheck_archive/name_card

# 面倒くさいので画面パタメータをListでもらった後のFunctionだけ
ちなみに引数のListを作ってる箇所は[こっちの記事](https://qiita.com/AsilHatake/items/842548e48ae4a0eae119)に書いてあるYO!!

```javascript:nameCard.js
// [問題文（原文）]
// あなたはこれまでに出会った人たちの名刺を集めています。
// 名刺は、複数枚のファイルを閉じることができるバインダーに保存されています。
// 
// 1枚のファイルには、n個のポケットが横に並んでおり、表と裏の両面から名刺を眺めることができます。
// このため、1つのポケットには、2枚の名刺が背中合わせに入っています。
// 
// 各名刺には1から順に通し番号が付いているため、この番号の順に名刺を眺めることができるようにポケットに入っています。
// 1番からn番の名刺は、1枚目のファイルの表面から見たときに左詰めに並んでおり、
// n+1番から2n番の名刺は、1枚目のファイルの裏面から見たときに左詰めに並んでいます。
// 2枚目以降のファイルにも同様に名刺が並んでいます。
// 上の図はn=3のときのバインダーの様子を表しています。
// 各ポケットの数字はそのポケットで眺めることができる名刺の番号で、
// 括弧で表される数字はそのポケットを反対の面から見たときに眺めることができる名刺の番号です。
// 
// 名刺の番号mが与えられるので、その名刺の裏側の名刺の番号を表示するプログラムを作成してください。
// ただし、番号mの名刺の裏面には必ず名刺が存在するものとしてください。
function nameCard(lines) {
  // 入力は以下のフォーマットで与えられます。
  // n m

  // 入力チェック面倒くさいので正常系のみ対応するよ
  const [col, target] = lines[0].split(" ").map(v => Number(v));
  // 対象の数が見つかるまでループする力技
  let page = 1;
  let output = 0;
  rootLoop: while(true){
    // 1ページの表と裏を一気に求める
    const frontEnd = page * col;
    for(let i = 0;i < col; i++){
      const frontBack = [frontEnd - i, frontEnd + i + 1];
      if(frontBack[0] === target){
        output = frontBack[1];
        break rootLoop; 
      } else if(frontBack[1] === target){
        output = frontBack[0];
        break rootLoop; 
      }
    }
    // 1回のループで2ページ分の値を求めるため、2ページ進むようなループにする
    page += 2;
  }

  // m番の名刺の裏側の番号
  console.log(output);
}

module.exports = {
  nameCard
};
```

とりあえず分かる情報としては
- 右側ページの最後は`横の枚数 * ページ`で求められる
- 上で求めた数字の裏側（左側ページ）は`+1`した数字
- 右側ページは最後から`-1`していけば左に行く
- 左側ページは上に比例して増えていく

ってことなので、1,3,5...奇数ページ（右側ページ）を求めれば、
必然的にその裏側となる偶数ページ（左側ページ）も分かるよねってことで、
指定の数字が見つかるまでループをぶん回すという力技で問題を解決!!

普段、頭の良さそうなIT屋のイメージを、
キレイサッパリ払拭するくらいの脳筋プレイでもどうにかなるので、
こんなレベルでもイケるんだと自信を持ってくれたら幸いです。
Android SDK 35 (Android 15) で setStatusBarColor などがdepreceted関連のメモ

# Android 15 で setStatusBarColor が deprecated (かつもはや機能しない) Javadoc確認


> setNavigationBarColor and R.attr#navigationBarColor are deprecated and don't affect gesture navigation.

Behavior changes: Apps targeting Android 15 or higher  |  Android Developers
https://developer.android.com/about/versions/15/behavior-changes-15

ではあるが、Javadocの差分を毎回確認するのが面倒なのでメモです.


# Window#setStatusBarColor(int)

Window  |  Android Developers
https://developer.android.com/reference/android/view/Window#setStatusBarColor(int)

## Android SDK 34 (Android 14)

```java
    /**
     * Sets the color of the status bar to {@code color}.
     *
     * For this to take effect,
     * the window must be drawing the system bar backgrounds with
     * {@link android.view.WindowManager.LayoutParams#FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS} and
     * {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS} must not be set.
     *
     * If {@code color} is not opaque, consider setting
     * {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
     * {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
     * <p>
     * The transitionName for the view background will be "android:status:background".
     * </p>
     */
    public abstract void setStatusBarColor(@ColorInt int color);
```


## Android SDK 35 (Android 15)


```java
    /**
     * Sets the color of the status bar to {@code color}.
     *
     * For this to take effect,
     * the window must be drawing the system bar backgrounds with
     * {@link android.view.WindowManager.LayoutParams#FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS} and
     * {@link android.view.WindowManager.LayoutParams#FLAG_TRANSLUCENT_STATUS} must not be set.
     *
     * If {@code color} is not opaque, consider setting
     * {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_STABLE} and
     * {@link android.view.View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN}.
     * <p>
     * The transitionName for the view background will be "android:status:background".
     *
     * <p>
     * If the color is transparent and the window enforces the status bar contrast, the system
     * will determine whether a scrim is necessary and draw one on behalf of the app to ensure
     * that the status bar has enough contrast with the contents of this app, and set an appropriate
     * effective bar background accordingly.
     *
     * <p>
     * If the app targets
     * {@link android.os.Build.VERSION_CODES#VANILLA_ICE_CREAM VANILLA_ICE_CREAM} or above,
     * the color will be transparent and cannot be changed.
     *
     * @see #setNavigationBarContrastEnforced
     * @deprecated Draw proper background behind {@link WindowInsets.Type#statusBars()}} instead.
     */
    @Deprecated
    public abstract void setStatusBarColor(@ColorInt int color);
```
【Rails6.1】ActionController::BadRequest (Invalid request parameters: Invalid encoding for parameter: )の対処法

## はじめに
Rails6.1へのアップデート中に以下のエラーが出たので、このエラーの対応方法をまとめていきます。
```ruby
ActionController::BadRequest (Invalid request parameters: Invalid encoding for parameter: xxxxx)
```

## 問題
Rails6.1からUTF-8以外を含むPOSTリクエストはエラーが出るようになったようです。

> Catch invalid UTF-8 parameters for POST requests and respond with BadRequest.

https://github.com/rails/rails/blob/6-1-stable/actionpack/CHANGELOG.md#rails-610-december-09-2020

## 解決方法
skip_parameter_encodingを対象のアクションに対して設定します。
```ruby
class TestController < ApplicationController
  skip_parameter_encoding :create
end
```

## 参考

https://github.com/rails/rails/blob/6-1-stable/actionpack/CHANGELOG.md#rails-610-december-09-2020

https://aruma256.dev/blog/2022/11/17/anonymous-controller.html
MySQL INSERT

## MySQLでデータを登録する
```
insert into テーブル名　(カラム名) values (登録したい値);
```
例） :convenience_store: ← :cake:
```
insert into my_shop (product_name) values ('cake');
```

## 複数のカラムにデータを入れる場合
```
insert into テーブル名　(カラム名1, カラム名2) values (カラム名1に登録したい値, カラム名2に登録したい値);
```
例） :convenience_store: ← ( :cake: , :yen: )
```
insert into my_shop (product_name, price) values ('cake', 450);
```

## 複数のレコードを一括で登録する場合
```
insert into テーブル名　(カラム名1, カラム名2) values
                     (カラム名1に登録したい値, カラム名2に登録したい値),
                     (カラム名1に登録したい値, カラム名2に登録したい値),
                     (カラム名1に登録したい値, カラム名2に登録したい値),
                     (カラム名1に登録したい値, カラム名2に登録したい値),
                     (カラム名1に登録したい値, カラム名2に登録したい値);
```
例）　:convenience_store: ← ( :cake: , :yen: ) , ( :tangerine: , :yen: ) , ( :melon: , :yen: ) , ( :apple: , :yen: ) , ( :beer: , :yen: )
```
insert into my_shop (product_name, price) values
                     ('cake', 150),
                     ('tangerine', 120),
                     ('melon', 900),
                     ('apple', 450),
                     ('beer', 550);
```
  
終
【WordPress】マルチサイトの機能を使って英語サイトを作る

＜＜　要件　＞＞
<ul>
    <li>すでに運用しているWordPressで、英語サイトを作成したい</li>
    <li>CMSの仕様やデザイン等は既存の日本語サイトと全く同じ</li>
    <li>英語サイトのアドレスは'https://既存サイトドメイン/en/'とする</li>
</ul>

<hr>

＜＜　実装方法 ＞＞
<ul>
    <li>マルチサイト機能を使って作成</li>
</ul>

<hr>

＜＜ 手順 ＞＞
<ol>
<li>テスト環境の準備
    <ul>
        <li>プラグイン（All in one wp migration）を使用して本番環境をテスト環境に反映</li>
        <li>プラグインは一旦全て無効化する</li>
    </ul>
</li>

<hr>

<li>管理画面 > ツール > ネットワークの設置
    <ul>
        <li>サブディレクトリ形式を使用
    </ul>
</li>

<hr>

<li>wp-config.phpに追記

    define('MULTISITE', true);
    define('SUBDOMAIN_INSTALL', false);
    define('DOMAIN_CURRENT_SITE', 'sample186.7b-demo.com');
    define('PATH_CURRENT_SITE', '/');
    define('SITE_ID_CURRENT_SITE', 1);
    define('BLOG_ID_CURRENT_SITE', 1);
    
    define('NOBLOGREDIRECT', 'http://(ドメイン)');

</li>

<hr>

<li>.htacessに追記（書き換え）


    # BEGIN WordPress
    # "BEGIN WordPress" から "END WordPress" までのディレクティブ (行) は
    # 動的に生成され、WordPress フィルターによってのみ修正が可能です。
    # これらのマーカー間にあるディレクティブへのいかなる変更も上書きされてしまいます。
    
    RewriteEngine On
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
    RewriteBase /
    
    # add a trailing slash to /wp-admin
    RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
    
    RewriteCond %{REQUEST_FILENAME} -f [OR]
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^ - [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) wp/$2 [L]
    RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ wp/$2 [L]
    RewriteRule . index.php [L]
    
    # END WordPress

</li>

<hr>

<li>再ログインして『サイトを追加』
    
</li>

</ol>

<hr>

＜＜ 参考サイト ＞＞
<ul>
    <li>
        <p>
        WordPressのマルチサイトとは？メリット・デメリットや具体的な作成方法を解説<br>
        <a href="https://www.conoha.jp/lets-wp/wp-multisite/" target="_blank">https://www.conoha.jp/lets-wp/wp-multisite/</a>
        </p>
    </li>
    <li>
        <p>WordPessのマルチサイトで参加サイトに子サイトが表示されない場合の解決法<br>
        <a href="https://free-leaf.org/tomorrow/display-child-site-in-join-site/" target="_blank">https://free-leaf.org/tomorrow/display-child-site-in-join-site/</a>
        </p>
    </li>
</ul>
Logback のログローテートにおけるファイルロックの挙動

# 概要

Logback でログローテートを行っている場合、新しいファイルが出力されるまでは、システム日時が切り替わったとしても、古いファイルがロックされ続ける。

例えば、日次ローテートの場合を考える。システム日付が8月5日のときに、8月4日までのファイルを別ディレクトリに移動しようとしたとする。8月5日はまだアクセスがなく、ログファイルが出力されていない。このとき、8月4日のファイルがまだロックされており、移動や削除が行えない。

```
AccessLog-2024-08-03.log
AccessLog-2024-08-04.log <- 8月5日になっても、次のファイルができない限りロックされたまま
```

古いログを別の場所に移動するようなバッチを作る際に気をつけた方がよいポイントである。

# 検証

以下の環境でテスト用の Web アプリを作って検証。

* Windows 11 23H2
* Java 17
* Spring Boot 3.3.1

今回は検証のため1分おきにローテートしてみる。logback.xml を以下のように設定。

```xml
<configuration>
	<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<fileNamePattern>logs/AccessLog-%d{yyyy-MM-dd-HHmm}.log</fileNamePattern>
		</rollingPolicy>
		<encoder>
			<pattern>%d{yyyy-MM-dd'T'HH:mm:ss'Z'} - %m%n</pattern>
		</encoder>
	</appender>
	<root level="INFO">
		<appender-ref ref="FILE" />
	</root>
</configuration>
```

PowerToys の File Locksmith でロック状況を見てみる。18:06 より後のログを出力していない状態では、システム時刻が 18:08 になってもファイルがロックされたままであることがわかる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177927/a759272f-8b1d-a82c-ad4e-3b3f45d59046.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177927/b23ed236-45d6-49d7-7e78-ceb85ac8a065.png)

新しいログファイルが作成されると、18:06 のファイルはロックが解除される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177927/4b9ce7ca-6a03-a7fc-03c3-2086b2c98180.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/177927/c9beca99-942e-672a-c470-fe360989ca0f.png)
[TryHackMe] Intermediate Nmap #Writeup

# はじめに
備忘録です。

# Find the flag!
nmapを実行。

```
$ nmap 10.10.182.176

Starting Nmap 7.60 ( https://nmap.org ) at 2024-08-03 05:21 BST
Nmap scan report for ip-10-10-182-176.eu-west-1.compute.internal (10.10.182.176)
Host is up (0.00012s latency).
Not shown: 997 closed ports
PORT      STATE SERVICE
22/tcp    open  ssh
2222/tcp  open  EtherNetIP-1
31337/tcp open  Elite
MAC Address: 02:18:15:B7:E5:2F (Unknown)

Nmap done: 1 IP address (1 host up) scanned in 1.81 seconds
```
31337ポートをブラウザで覗くと以下の内容が書いてあった。

>In case I forget - user:pass
ubuntu:Dafdas!!/str0ng

このIDとパスワードをsshでつかってみる。

```
$ ssh ubuntu@10.10.182.176
The authenticity of host '10.10.182.176 (10.10.182.176)' can't be established.
ECDSA key fingerprint is SHA256:tD+Aiagv/4teueystsEl6q9ZNvNF9C8v+dsZj3fhbdQ.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.182.176' (ECDSA) to the list of known hosts.
ubuntu@10.10.182.176's password: 
Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.13.0-1014-aws x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

This system has been minimized by removing packages and content that are
not required on a system that users do not log into.

To restore this content, you can run the 'unminimize' command.

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

$ ls
$ cd ..
$ ls
ubuntu	user
$ cd user
$ ls
flag.txt
$ cat *
flag{251f309497a18888dde5222761ea88e4}
```
あっさり見つかった。

:::note
flag{251f309497a18888dde5222761ea88e4}
:::
JP1にてジョブのスケジュール設定でつまずいた話

# はじめに
JP1を触るようになって、1年ほど経ちました。
参画しているプロジェクトでJP1を使用しており、ジョブのスケジュール設定の仕方で実行するジョブの挙動が変わり、想定通りの挙動を実現するために苦労した話を書きます。
# JP1/AJS（Job Management Partner 1/Automatic Job Management System）とは
JP1/AJS（Job Management Partner 1/Automatic Job Management System）は、日立製作所が提供するジョブ管理ソフトウェアの一部であり、企業のIT運用を自動化し、効率的に管理するための重要なツールです。
　
主要機能としては、以下の5つです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/76dffae9-15e9-6210-bb5b-7ac8ddc0722f.png)
# ジョブスケジュール設定で苦戦したこと
私がジョブのスケジュール設定で苦労したことは、
日を跨ぐルートジョブネット内のネストジョブネットのスケジュールを設定する際の実行日付の指定です。

JP1では各ジョブネットでスケジュールルールの設定が可能で、以下のようなスケジュール設定画面で設定できます。詳しい設定方法は、[マニュアル](https://itpfdoc.hitachi.co.jp/manuals/3020/30203S0133/AJSZ0055.HTM)をご覧ください。

**【スケジュール設定画面】**
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/d2729a8f-660f-8496-2d06-9107f692db12.png" width="60%">

今回は以下のようなジョブネットを例に説明します。
ジョブネット①(ルートジョブネット)　起動時間：2024/7/24の20:00
ジョブネットA(ネストジョブネット)　起動時間：2024/7/24の20:15
ジョブネットB(ネストジョブネット)　起動時間：2024/7/25の1:15
※以下、ジョブネットA→ジョブA、ジョブネットB→ジョブB　

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/9f984482-30b9-c62e-29f9-8651d3be9856.png)

 
　上記の場合の各ジョブネットのスケジュール設定は以下で設定しました。
　**【スケジュール設定】**　
　・ジョブネット①
 　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/18da5e1e-1f11-ab32-1a25-d8c5ba91e7f1.png" width="60%">

　・ジョブA
 　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/015fafeb-c1d9-cb14-3675-0b61033ee396.png" width="60%">
　
 　・ジョブB
  　<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/bb9fdd5f-0f64-f2f7-5cf7-03804180272e.png" width="60%">

　
上記のスケジュール設定でジョブネット①を起動したところ、
ジョブネット①が7/24の20:00に起動されたのち、
<INS>ジョブAは7/24の20:15に起動・正常終了されましたが、
ジョブBは7/25の1:15に起動されませんでした。</INS>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/b5a47261-1ed6-6005-0327-4b5918a3fa57.png)



原因はジョブBのスケジュール設定の方法が誤っていたことでした。
ジョブBのスケジュールはジョブネット①のスケジュールに合わせて、設定しなければいけませんでした。

<INS>ジョブBの正しいスケジュール設定は2024/7/25の1:15ではなく、2024/7/24の25:15と設定する必要がありました。</INS>

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/fa47c715-7a58-8c8b-6ea1-43df7a761e2b.png" width="60%">


ジョブBのスケジュール設定を上記のように変更し、
ジョブネット①を起動したところ、ジョブA、ジョブBどちらも起動・正常終了されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3836584/9f089caf-a129-5eb9-489c-52fe3f9411a0.png)
# まとめ
日を跨ぐルートジョブネット内のネストジョブネットのスケジュール設定をする際は、スケジュール設定の起動日時をルートジョブネットの起動日時に合わせる必要があります。
また、上記のジョブBの起動時間のように「25:15」というような時間を指定するにはルートジョブネットの時間制を「48時間制」にしておく必要があります。
ジョブのスケジュール設定において同じ事象でお困りの方の参考になれば幸いです。
2024年7月30日のactions/runner-imagesの更新でdocker-composeコマンドが廃止された

> [Ubuntu, Windows] Docker Compose v1 will be removed from images on July, 29

2024年の7月30日の更新でUbuntuとWindowsのImageで`docker-compose`が使えなくなりました。
完全に廃止されるまでは3~4日かかるようなので、数日後に使えなくなった人もいると思います。

https://github.com/actions/runner-images/releases/tag/ubuntu22%2F20240730.2

Docker compose v1を利用している場合はv2への更新や、過去のバージョンを指定する変更が必要になります。

この機会にv2へ更新するのはいかがでしょうか。

https://docs.docker.com/compose/migrate/
YAMLの基本を学んでPythonでYAMLを使ってみよう！

# PythonでYAMLを使ってみよう！基本からサンプルコードまで

YAMLは、人間が読みやすい形式でデータを記述するためのマークアップ言語です。構造化されたデータの表現に適しており、設定ファイルやデータのシリアル化に広く使用されています。本記事では、YAMLの基本的な概念から、Pythonを使ったサンプルコードまで紹介します。

## YAMLの基本構文

YAMLには、データを表現するためのいくつかのスタイルがあります。代表的なものとして「ブロックスタイル」と「フロースタイル」があります。

### ブロックスタイル

ブロックスタイルは、インデントを使用して階層構造を表現する方法です。最も一般的なYAMLの記述形式です。

```yaml
# config.yaml
database:
  host: localhost
  port: 3306
  user: root
  password: secret
  name: mydatabase
```

### フロースタイル

フロースタイルは、インラインでデータを表現する方法です。2種類あります。

#### シーケンス

シーケンス（配列）をインラインで表現する方法です。

```yaml
numbers: [1, 2, 3, 4, 5]
```

#### マッピング

キーと値のペアをインラインで表現する方法です。

```yaml
user: {name: John, age: 30, city: Tokyo}
```

## データ型

YAMLはさまざまなデータ型をサポートしています。以下に代表的なものを紹介します。

### 文字列

```yaml
name: "YAML Example"
```

### 数値

```yaml
integer: 10
float: 3.14
```

### 真偽値

```yaml
is_active: true
```

### Null値

```yaml
no_value: null
```

### 日付

```yaml
date: 2024-08-05
```

## 改行を扱う方法

YAMLで複数行の文字列を扱う場合、`|`（リテラル）または`>`（折りたたみ）のシンボルを使います。

### リテラル

改行をそのまま保持します。

```yaml
description: |
  これはYAMLの
  改行を保持する
  例です。
```

### 折りたたみ

改行を空白に置き換えます。

```yaml
description: >
  これはYAMLの
  改行を空白に置き換える
  例です。
```

## 区切り文字について

YAMLでは、ドキュメントの区切りとして`---`と`...`を使用します。

### `---`

新しいドキュメントの開始を示します。

```yaml
---
name: "First Document"
---
name: "Second Document"
```

### `...`

ドキュメントの終了を示します。

```yaml
name: "YAML Document"
...
```

## PythonでYAMLを使ったサンプルプログラム

では、実際にPythonを使ってYAMLファイルを読み込むサンプルプログラムを作成してみましょう。`PyYAML`というライブラリを使います。

### 環境の準備

まず、`PyYAML`をインストールします。

```bash
pip install pyyaml
```

### サンプルコード

以下のPythonプログラムは、YAMLファイルを読み込み、その内容を表示する簡単な例です。

```python
import yaml

# YAML 設定ファイルを読み込む関数
def load_config(file_path):
    with open(file_path, 'r') as file:
        config = yaml.safe_load(file)
    return config

# 設定内容を表示する関数
def display_config(config):
    print("データベース設定:")
    print(f"ホスト: {config['database']['host']}")
    print(f"ポート: {config['database']['port']}")
    print(f"ユーザー: {config['database']['user']}")
    print(f"パスワード: {config['database']['password']}")
    print(f"データベース名: {config['database']['name']}")
    
    print("\nロギング設定:")
    print(f"レベル: {config['logging']['level']}")
    print(f"ログファイル: {config['logging']['file']}")

# メイン処理
if __name__ == "__main__":
    config = load_config('config.yaml') #ここはパスを適宜調整してください
    display_config(config)
```

### 実行結果

`config.yaml`ファイルの内容を以下のように表示します。

```yaml
データベース設定:
ホスト: localhost
ポート: 3306
ユーザー: root
パスワード: secret
データベース名: mydatabase

ロギング設定:
レベル: DEBUG
ログファイル: /var/log/myapp.log
```

## まとめ

この記事では、YAMLの基本的な構文やデータ型、Pythonを使ったサンプルコードを紹介しました。YAMLは読みやすく、設定ファイルなどに最適です。Pythonと組み合わせることで、簡単に設定ファイルを扱うことができるので、ぜひ試してみてください。
Workbook のマップを緯度経度で表示する

緯度経度の情報をワークブックの地図で視覚化する。SigninLogs の LocationDetails.geoCoordinates にそれぞれ緯度 (latitude) と 経度 (longitude) があるので取り出す。集計に使うので string 型に変換する。

```KQL
SigninLogs
| extend latitude = tostring(LocationDetails.geoCoordinates.latitude)
| extend longitude = tostring(LocationDetails.geoCoordinates.longitude)
| summarize count() by latitude,longitude
```

視覚化のオプションでマップを選択、緯度と経度の列名を指定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247864/ca093306-7fdd-f975-dd7b-667593754a9a.png)

緯度経度の集計結果が地図に表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/247864/ffd0f0b0-cd57-74c9-96e4-f6f597a85bc6.png)
Microsoft Azure Fundamentals[AZ-900]を受験してみました。

## はじめに
おはこんばんにちは。キティちゃんです。最近暑いなと思ったら急に雨が降ってきたりと天気の急激な変化に辟易しています。今日はつい最近受験したAzureの資格試験のことについて書いていきたいと思います。

## きっかけ
Azureは新卒の時に触れる機会があったきりで、それ以降触ったことがなかったのと、AWS以外のクラウドサービスについての知見もほしいと思ったことが受験のきっかけです。

## Microsoft Azure Fundamentals（以降AZ-900）とは
Azureに関しての基礎知識を問う試験となっており、Azre初学者向けの試験となっています。試験範囲は以下のようになっているそうです。

#### 1.クラウドの概念	25～30%
#### 2.Azure のアーキテクチャとサービス	35～40%
#### 3.Azure の管理とガバナンス	30～35%

どれかに偏ることなく、満遍なく出題されますので、どこかの学習が疎かだったりすると、試験に合格することが難しくなってしまいます。とはいえ、700点以上で合格となるため、どれか一つの項目でも飛びぬけて正答率が高ければ、他が平均的な正答率であっても、合格する可能性は十分にあります。

## AZ-900対策教材
今回の勉強には以下2つを使用しました。
#### 1.徹底攻略 Microsoft Azure Fundamentals教科書［AZ-900］対応
https://book.impress.co.jp/books/1119101171

#### 2.【6万人が受講】AZ-900 Microsoft Azure Fundamentals模擬試験問題集（7回分490問）
https://www.udemy.com/course/az-900-microsoft-azure-fundamentals4176/?couponCode=ST4MT73124

## 徹底攻略 Microsoft Azure Fundamentals教科書［AZ-900］対応
このシリーズ本はよく黒本とか言われているのを耳にしますが、そのシリーズのAzure版です。この本は重要な点が簡潔にまとめられており、非常に読みやすい1冊となっております。また、章ごとに振り返りの演習問題が10問程度あり、読んだ内容を理解しているかの確認をすることもできます。
注意点として非常に読みやすい1冊ではあるのですが、あくまでAzureではどんなサービスを提供しているのかについて簡単にまとめてくれているだけなので、1つ1つのサービスについては深掘りはされていません。なので、この1冊だけで合格しようとするのは無理だと思います（実務でAzureを触れている人は除きます）。

## 【6万人が受講】AZ-900 Microsoft Azure Fundamentals模擬試験問題集（7回分490問）
徹底本にプラスして、このUdemyが提供している模擬問題集を解くことをお勧めします。こちらの問題集は、問題数が多いですが、解説も充実しているため、1つ1つのサービスについての基礎知識も補うことができるのでとても充実はしていると思います。解説を読んでも理解できない場合は、copilotとか使って自分なりに調べるでも全然いいと思います。どちらかというと、こっちの模擬問題集に注力するほうが試験の得点も伸びるかなという印象でした。

## スケジュール感
受験するにあたって、以下のようなスケジュール感で動きました。

5月～6月頃：徹底本を使って基礎を抑える
6月～7月頃：模擬問題集を全て100％の正答率になるまで毎日く
7月～受験日(7月末)：徹底本を軽く読む＋模擬問題集の苦手な問題or理解しきれていない問題をブックマークして解説をよく読む

今回は何よりも1回で受かりたかったので、だいぶ慎重にスケジュールを立てました。もう少し早く受験することもできなくはなかったのですが、近くの試験会場を確保できなかったので、だいぶ遅めになりました。

## 受験日当日
顔写真付き身分証と保険証、社員証は準備しておきました。あとは見直しができるように徹底本も持っていきました。あとは最後の最後まで模擬問題集をひたすら解きました。

## 試験を受けてみて
当日の問題は35問と比較的少なめで、試験時間もは45分だった気がしましたが、余裕をもって解き終わりました。1回全て解き終わった瞬間に「あ、受かったな」という謎の確信がありました。

## 受験結果
1000点満点のうち700点以上が合格となりますが、私の得点は794点と比較的余裕をもっての合格でした。

## 感想
何とか1回の受験で合格することができたのは良かったなと思います。ただ、この試験だけではなく、他の試験でもいえるのですが、配点が謎なのとどの問題を間違えて、どの問題があっていたのかが分からないので復習できないのがとても辛いところです。

## 次回に向けて
次は何を受験するかというのはある程度決めてはいるので、頑張って勉強しようかと思います。何を受けるかはお楽しみに。

## 終わりに
今回はAZ-900に一発で受かることができてホッとしています。今後AZ-900の受験を検討している方は是非頑張ってください。この記事が誰かのお役に立てれば幸いです。
あと徹底本も隅から隅まで読むことをお勧めします。意外と試験で得点を狙うためのヒントもあります。
RX210のmruby/cでfib(32)

MRBの書き込みが簡単にできるようになったので調べてみました。

```ruby
def fib(n)
  if n<=2 then
    1
  else
    fib(n-1) + fib(n-2)
  end
end

def nump v
  a = []
  k = 0
  while v != 0
    n = v % 10
    n += 0x30
    a << n
    v /= 10
    k += 1
  end
#  a.reverse! NG
#  a.each do |n|
#   serial_write(n)
#  end
  while k >= 0
   serial_write(a[k])
   k -= 1
  end
end

serial_init()

while true
  nump fib(32)
  serial_write(0x2c)
end
```

![スクリーンショット 2024-08-05 17.58.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/3d7bc02f-007f-0744-03fa-b5b627b69aa7.png)

184秒でした。動作クロックが50MHzなので正常にパフォーマンスが出ていると思われます。

参考

https://qiita.com/yamori813/items/42cf2c4c0a95d22b956a
Python 総当たり相関係数

## はじめに
Yellowfin が参照するデータベースにデータを取り込む前に、プログラムで様々な処理を施しておきたい場面は多くあると思います。
例えば、数多くのパターンの相関係数を事前に集計しておけば、その後の実装が楽になり、またパフォーマンスの向上にもつながります。

## Python データ処理

#### データフレームにデータ読み込み
CSV ファイルから、3 名の生徒の各教科の点数を、データフレームに読み込みます。
```python:CSV 
import pandas as pd
df = pd.read_csv("score.csv")
```
データフレームの中身は以下のようになりました。
|名前|教科|点数|
|---|---|---|
|山田|国語|60|
|山田|算数|72|
|山田|理科|75|
|山田|社会|97|
|山田|英語|66|
|榎本|国語|75|
|榎本|算数|78|
|榎本|理科|93|
|榎本|社会|82|
|榎本|英語|68|
|北村|国語|74|
|北村|算数|74|
|北村|理科|80|
|北村|社会|90|
|北村|英語|84|

#### 横持ち変換
テータを縦持ちから横持ちに変換します。pivot_table() 関数を使うと、簡単にデータ変換できます。
```python:pivot
df_pivot = df.pivot_table(values=['点数'], index=['名前'], columns=['教科'], aggfunc=['mean'])
df_pivot.columns = df_pivot.columns.get_level_values(2)
```
この時点で、データフレーム内のデータは以下のような形になります。
縦軸に名前、横軸に教科のクロス集計表に、教科の単位で点数の平均を取ったものが配置されました。
|教科|国語|理科|社会|算数|英語|
|---|---|---|---|---|---|
|名前||||||
|北村|63.0|78.0|78.0|100.0|90.0|
|山田|69.0|66.0|80.0|65.0|76.0|
|榎本|95.0|74.0|96.0|70.0|82.0|

#### 相関係数
corr() 関数を使えば、上記データフレームから、各教科総当たりの相関係数が簡単に算出できます。
```python:correlation
df_corr = df_pivot.corr()
```

結果、データフレームの中身は以下のようになりました。
|教科|国語|理科|社会|算数|英語|
|---|---|---|---|---|---|
|教科||||||
|国語|1.000000|0.012829|0.997131|-0.538318|-0.256683|
|理科|0.012829|1.000000|0.088475|0.835766|0.963123|
|社会|0.997131|0.088475|1.000000|-0.472988|-0.182794|
|算数|-0.538318|0.835766|-0.472988|1.000000|0.952683|
|英語|-0.256683|0.963123|-0.182794|0.952683|1.000000|

## Yellowfin からのデータ参照
#### データベースへのデータコピー
データフレームの中身をデータベースのテーブルにコピーすれば、Yellowfin がデータを参照できるようになります。
ここまでの説明では、動きを分かりやすく説明するために、少量のデータを使って処理の流れを説明しました。
実際には、大量のデータを使って処理することになるかと思います。大量のデータをデータベースに反映するためのベストプラクティスを[こちら](https://qiita.com/ExtremeCarvFJ/items/35b8b58aa90514bbe29c)にまとめているので、併せてご確認ください。AWS Redshift に格納する場合のベストプラクティスではありますが、他環境においても類似の考え方を持ち込むことは可能だと思います。たぶん。

#### Yellowfin から参照
その後、データベースにアップロードされたデータを、Yellowfin から参照してチャートやダッシュボードを作成します。
Yellowfin コンテンツの作成に関する詳細は[過去の記事](https://qiita.com/ExtremeCarvFJ)をご確認ください。

## 最後に
統計解析に使える Python ライブラリは数多く存在します。我々は完全にその恩恵を授かってますね。
また、Pandas を用いると、構造化データとしてデータを扱うことができるため、データベースや BI ツールととても相性が良いと感じています (感度には個人差あり)。
便利な世の中になったもんですな。

では皆様、良いデータ分析を!
[paiza]長テーブルのうなぎ屋 (paizaランク B 相当)

# 江戸っ子への偏見がすごいw
```text
ただしお客さんは江戸っ子なので、それら座席のうち、いずれか一つでも既に先客に座られている座席があった場合、
一人も座らずにグループ全員で怒って帰ってしまいます。江戸っ子は気が早いんでぃ。
```
この問題の世界の住人はヤベェ奴らしかおらんのか。。。

https://paiza.jp/works/mondai/b_rank_skillcheck_sample/long-table

# 面倒くさいので画面パタメータをListでもらった後のFunctionだけ
ちなみに引数のListを作ってる箇所は[こっちの記事](https://qiita.com/AsilHatake/items/842548e48ae4a0eae119)に書いてあるYO!!

```javascript:longTable.js
// [問題文（原文）]
// 東京の下町に長テーブルで有名な老舗うなぎ屋がありました。
// 
// そのうなぎ屋にはとても大きい長テーブルがあり、テーブルの周りにn個の座席が配置されています。
// 座席には、時計回りに1, 2, …, nと番号が振られています。
// 座席はテーブルの周りに配置されているので、座席番号nの座席と1の座席は隣接しています。
// 今、m個のグループの人達が座席に順番に座りに来ます。i番目(1≦i≦m)のグループの人数をa_i人とします。
// 彼らは、長テーブルに並んだ座席の内、ある連続するa_i個の座席に一斉に座ろうとします。
// 
// ただしお客さんは江戸っ子なので、それら座席のうち、いずれか一つでも既に先客に座られている座席があった場合、
// 一人も座らずにグループ全員で怒って帰ってしまいます。江戸っ子は気が早いんでぃ。
// 
// 入力では、i番目のグループが座ろうとする連続した座席の位置は、整数b_iにより指定されます。
// i番目のグループは、座席番号b_iの座席を始点として、そこから時計回りにa_i個分の座席に座ろうとします。
// 
// 最後のグループが座りに来た後、無事に長テーブルの座席に着席出来ている人数を出力するプログラムを作成してください。
function longTable(lines) {
  // 入力は以下のフォーマットで与えられます。
  // 入力はm+1行から成ります。
  // 1行目にはn(座席数)とm(グループ数)が半角スペース区切りで入力されます。
  // i+1行目(1≦i≦m)には2個の整数a_i(グループの人数)とb_i(着席開始座席番号)が半角スペース区切りで入力されます。

  // 入力チェック面倒くさいので正常系のみ対応するよ
  const [seatCnt, groupCnt] = lines[0].split(" ").map(v => Number(v));
  let seats = {};
  Array.from({ length: seatCnt }).forEach((_, i) => seats[i + 1] = false);
  lines.slice(1).forEach(line => {
    const [group, startSeat] = line.split(" ").map(v => Number(v));
    // 全員座れるかチェック（駄目ならreturnして次のグループへ）
    for (let i = 0; i < group; i++) 
      if (seats[(startSeat + i) > seatCnt ? 1 : startSeat + i]) return;
    // 座れる場合だけ設定
    for (let i = 0; i < group; i++)
      seats[(startSeat + i) > seatCnt ? 1 : startSeat + i] = true;
  });

  // 最後のグループが座りに来た後、無事に座席に着席出来ている人数を1行で出力してください。
  console.log(Object.values(seats).filter(v => v).length);

}

module.exports = {
  longTable
};
```
for文2回書いてるのマジで気持ち悪いけど、座れるかチェックと席案内を一緒に書ける気がしなかった。。。
wordpress yoast SEOのサイトマップが作れない問題

# 概要
タイトルの通り、**wordpressのyoastプラグインSEOのサイトマップが作れない問題**に遭遇しました。
色々と調べて試してみてもなかなか解決しませんでした。
しかし、自分で考えながらたどり着いた手法がうまくいったので紹介します。

# 発生した問題
![スクリーンショット 2024-08-05 15.28.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853740/b88b12cb-b2b5-c5d4-86e1-ddfad2a09c4f.png)

上記画像は、wordpress ダッシュボード左側のタブの「yoast SEO」>「設定」の一部です。
画像の中央にある「XMLサイトマップ」の機能を有効にした場合、通常であれば`ドメイン名+//sitemap_index.xml`にブラウザでアクセスすると、xmlサイトマップが表示されるはずでした。
しかし、問題を解決するまではドメインのメインページにリダイレクトされてしまうケースが発生。
この記事では、本件の解決方法をご紹介します。

# 解決手順
前提として、私は[こちら](https://kacfg.com/ec2-wordpress/)のサイトを参考にして、wordpressを構築しました。
サイト構築環境は以下の通り：
* AWS EC2, amazon linux2
* nginx 1.22.1
* wordpress 6.6.1
* SEOプラグイン：Yoast SEO

### wordpress上の操作
1. まず最初に、他のSEOプラグインや、xmlサイトマップを作るようなプラグインがある場合は、それらを無効にします
1. wordpressダッシュボードの左側のタブの中から、「yoast SEO」>「ツール」ページを開きます
![スクリーンショット 2024-08-05 15.51.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853740/a82c83f6-308f-dfc7-6978-35d0388c4177.png)
1. ツールページの中の、上から二つ目の「ファイルエディタ」をクリックします
![スクリーンショット 2024-08-05 15.53.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853740/5060e61d-1d59-a7a1-bb42-3f3d37c9d670.png)
1. 「ファイルエディタ」を開いた時、下の画面のようになっていない場合は、robots.txtを作成するボタンをクリックしてください。
![スクリーンショット 2024-08-05 16.05.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853740/7480e5a0-c8aa-dfe5-7c80-c2cfd2475793.png)
1. `Sitemap`の次に続くリンクへアクセスしてみてください。この状態で正しく（下の画像のような）xmlサイトマップが表示されれば無問題。表示されない方は次のステップへ進んでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853740/9a23a65c-0de8-a21e-13f4-dce2a33d0a47.png)

### EC2上の操作
`robots.txt`が作られていても、`.htaccess`というファイルがないと、サイトマップは作られないようです。
手動でこちらのファイルを作成し、中身を記述することでサイトマップが作れます。
1. EC2インスタンスにアクセスします
1. wordpressのルートディレクトリにアクセスします。これはwordpressダッシュボード左側の、「ツール」>「サイトヘルス」にアクセスし、上の方にある「情報」タブをクリックします。すると「WordPressディレクトリの場所」という項目があります（下の画像参照）。ここにコマンド上でアクセスしてください
![スクリーンショット 2024-08-05 16.22.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3853740/7c8793c5-bc24-e180-73e6-52df73759603.png)
1. 以下のコマンドで「.htaccess」ファイルを作成します
    ```
    sudo touch .htaccess
    ```
1. 次に、このファイルの中身を編集します。以下のコマンドを実行します
    ```
    sudo vim .htaccess
    ```
1. ファイルの中には以下の内容を記述し、保存してください
    ```
    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
    # END WordPress
    ```
1. これでサイトマップが動くはずです。「ドメイン名+/sitemap_index.xml」にブラウザでアクセスし、サイトマップが表示されているかをご確認ください。

# 最後に
サイトマップができたあとは[google search console](https://search.google.com/search-console/about?hl=ja)に登録するなどして、Googleからの検索流入が増えるはずです！
結構重要な設定が手動で行わなければいけないのは致命的だと感じました。
今後こういった役に立つ、わかりやすい記事を投稿していきますので、よければフォローお願い致します。
[ブログ]()も書いています。ご興味があればぜひご覧ください！
SwiftへのOpenCV導入が無理だった

# はじめに

Swiftから直でOpenCvを呼び出せるらしいのだが、なんか無理だった。
「import opencv2」の時点でエラーになる。
Swiftプロジェクトにopencv2.framework（あるいはopencv2.xcframework）を取り込むところまではできているはずなのだが、原因も解決方法もよくわからなかった。
記録だけ残しておく。

# 導入ができたと思われる事例

https://dev.classmethod.jp/articles/build-opencv2-xcframework-manually/

https://qiita.com/treastrain/items/0090d1103033b20de054

https://blog.goo.ne.jp/yoossh/e/5cb9520d392d79da3dff13da05e76e8a

この通りにやっているはずだが、なんか無理。なんか見逃しているのだろうか？
自前でビルドからやってxcframeworkを作ってみても、なんかダメだった。

opencv2.xcframework
opencv2.framework
この二つは別もの。XCが新しいらしい。

# 備考

どうも、もろもろのバージョン関係で依存性があるっぽい。それも断片でそれっぽい感じがするだけなので、何が間違っているのかもよくわからない。

・Macのバージョン、機種、M1以降のチップであるか否か
・「Obj-C / Swift bindings」のサポートは OpenCv4.4.0 以降～
・Xcodeバージョン
・Swiftバージョン
・ビルド関連ツールのバージョン（python,cmake,brew）

Mac以外のバージョンは現時点の最新バージョンに更新して試したが駄目だった。

2020年時点で可能となっているのに、2024年現在でもイマイチ情報が少ない。
AIに聞いてもわからない。
海外フォーラムで似たようなQAがあるが、結局よくわからず。

OpenCv多用するわけじゃないのでCpp側をバイパスする古い方法で解決することにした。
あとで別記事にするかも。
画面上の文字をキャプチャして、そのままクリップボードに保存する方法(Windows10,11)

### 画面上の文字をキャプチャして、そのままクリップボードに保存する方法(Windows10,11)

Mircrosoftが提供する「Microsoft PowerToys」の機能「Text Extractor」を用いて、画面上のカーソルできない文字を、範囲指定でクリップボードに保存する方法を紹介します。
なお、日本語以外にも対応していますが、今回はアメリカ英語、韓国語、中国語の紹介にとどめます。

[Text Extractor公式ドキュメント](https://learn.microsoft.com/ja-jp/windows/powertoys/text-extractor#supported-languages)をもとに設定を行います。

:::note warn
公式ドキュメントにありますが、読み取りは完璧ではないようです。使用する際は出力が正しいかチェックする必要があります。
:::

## 1. MicrosoftStoreで「PowerToys」をダウンロードする

[スタート] を選択し、「Microsoft Store」と入力、選択してアプリを開く。
「PowerToys」と検索して、「Microsoft PowerToys」をダウンロードする。


## 2. 「Text Extractor」を有効にする

ダウンロード完了後、[Windows]キー + [Q]キーを押し、「PowerToys」で検索し、設定アプリを開きます。
「Power Toys」の設定画面から、「Text Extractor」を有効なモジュールに切り替える。
(最初から有効ならOK、無効なモジュールは下のほうにあるよ)
  
![有効後イメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3839302/61147b39-531e-3fcc-2f83-d73da976d49c.png)
こうなっていればOK

ここまで出来たら、[Windows]キー + [Shift]キー + [T]キーで使用できます。
あとは範囲選択さえすれば、自動でクリップボードに保存されます。

ただし、対応言語がデフォルトで日本語のみなので、外国語を読み込みたい場合は下記を参照してください。

## 3.外国語のための設定準備をするためにPowerShellを開く
設定の為に、[Windows]キーと[X]キー同時押しして、「Windows PowerShell(管理者)」を開く
**※(管理者)の方じゃないと設定できないよ**

## 4.言語に応じて設定をする
以下をコピーして、PowerShell上に右クリックで貼り付け。
[Enter]で確定してください。

:::note warn
なお、キャプチャ範囲指定時の上部にある言語を対応する言語に変更しないと上手く動きません
:::

~~~PowerShell:アメリカ英語
$Capability = Get-WindowsCapability -Online | Where-Object { $_.Name -Like 'Language.OCR*en-US*' }
$Capability | Add-WindowsCapability -Online
~~~

~~~PowerShell:韓国語
 $Capability = Get-WindowsCapability -Online | Where-Object { $_.Name -Like 'Language.OCR*ko-KR*' }
 $Capability | Add-WindowsCapability -Online
~~~

~~~PowerShell:中国語
 $Capability = Get-WindowsCapability -Online | Where-Object { $_.Name -Like 'Language.OCR*zh-TW*' }
 $Capability | Add-WindowsCapability -Online
 ~~~

 ## まとめ
初投稿の記事が技術者ぽくないとは思いますが、まあ便利だしいいよね
PowerToysの設定画面からショートカットキーを替えたら便利だと思います。
お疲れさまでした！
ESP32: SPIFFS のファイルのリスト

ファイル -> スケッチ例 -> SPIFFS -> SPIFFS_Test を参考にしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/3bde3dab-244f-4555-b597-549f9fab9f07.png)

Ubuntu 24.04 だとコードは次の場所にあります。

```text
.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/examples/SPIFFS_Test
```

## プログラム

```text:SPIFFS_List.ino
// ---------------------------------------------------------------------
/*
	SPIFFS_List.ino

						Aug/05/2024
*/
// ---------------------------------------------------------------------
#include "FS.h"
#include "SPIFFS.h"

#define FORMAT_SPIFFS_IF_FAILED true

// ---------------------------------------------------------------------
void listDir(fs::FS &fs, const char *dirname, uint8_t levels) {
	Serial.printf("Listing directory: %s\r\n", dirname);

	File root = fs.open(dirname);
	if (!root) {
		Serial.println("- failed to open directory");
		return;
	}
	if (!root.isDirectory()) {
		Serial.println(" - not a directory");
		return;
	}

	File file = root.openNextFile();
	while (file) {
		if (file.isDirectory()) {
			Serial.print("	DIR : ");
			Serial.println(file.name());
			if (levels) {
				listDir(fs, file.path(), levels - 1);
			}
		} else {
			Serial.print("	FILE: ");
			Serial.print(file.name());
			Serial.print("\tSIZE: ");
			Serial.println(file.size());
		}
		file = root.openNextFile();
	}
}

// ---------------------------------------------------------------------
void setup() {
	Serial.begin(115200);
	if (!SPIFFS.begin(FORMAT_SPIFFS_IF_FAILED)) {
		Serial.println("SPIFFS Mount Failed");
		return;
	}

	listDir(SPIFFS, "/", 0);

	Serial.println("Test complete");
}

// ---------------------------------------------------------------------
void loop() {}
// ---------------------------------------------------------------------
```
ABC365Dを解いた


筆者はレート700弱の茶色コーダ

今回はこの問題を解いていく

https://atcoder.jp/contests/abc365/tasks/abc365_d

# 実装コード

[貪欲法ではこのケースで解けないらしい](https://atcoder.jp/contests/abc365/editorial/10600)。
なのでどの手を出すのかを使って動的計画法を組めば良いようだ。

```python
from itertools import product
import sys
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
def err(*args): print(*args, file=sys.stderr)

win = {"R":"P","P":"S","S":"R"}
lose = {"R":"S","P":"R","S":"P"}

def main():
    N = rI()
    S = rS()
    
    H =[{k:0 for k in "RPS"} for _ in range(N+1)]
    
    for i,s in enumerate(S,start=1):
        for k1,k2 in product("RPS",repeat=2):
            if k1 == lose[s] or k1 == k2: continue
            is_won = k1 == win[s]
            H[i][k1] = max(H[i][k1],H[i-1][k2] + (1 if is_won else 0))
                    
    ans = max(H[N].values())    
    print(ans)
    
if __name__ == '__main__':
    main()

```


# まとめ
ABC365Dを解いた、実装には動的計画法を使用した。

# 感想
コンテストの時間中は貪欲法で実装してWAを出して、なぜ解けないのか分からず、
しかも、視点を変えて動的計画法をするという発想もなく、次の問題に飛ばしてしまった。

動的計画法を使いこなしたいと思っている身でこのようなミスは致命的といえる。
このようなミスが無いように動的計画法を使う意識を持っておきたい。