OmniAICreator/Qiita-1.07M huggingface dataset:
MUIのAutocompleteの基本を抑える

## はじめに
Google検索などで、テキストボックスに値を入力すると、入力候補の値がプルダウンでサジェストされるのを見たことがあるかと思います。

あのUIを表現できるのが、MUIのAutocompleteです。

業務で使う機会があったので、その基本的な使い方を抑えてみます。

## 基本の使い方
### 画面例
まず、先に画面例から示します。
![demo_basic.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251137/ea5c5565-b04a-c497-3ed5-57b4be617508.gif)

### コード例
このような挙動が以下のコードで簡単に実装できます。
```react
import { Autocomplete, TextField } from "@mui/material";
import { useState } from "react";
interface Fruit {
  value: string;
  label: string;
}
const films: Fruit[] = [
  { value: 'apple', label:'りんご'},
  { value: 'banana', label:'ばなな'},
  { value: 'cherry', label:'さくらんぼ'},
];

const BasicAutocomplete = () => {
  const [value, setValue] = useState<Fruit | null>(null);

  return (
    <Autocomplete
      value={value}
      onChange={(_e, newValue: Fruit | null) => {
        setValue(newValue);
      }}
      options={films}
      getOptionLabel={(option) => option.label}
      renderInput={(params) => (
        <TextField {...params} label="フルーツを選択" variant="outlined" />
      )}
    />
  );
};

export default BasicAutocomplete;
```
### コード解説
Autcompleteコンポーネントの基本的なプロパティについて確認していきます。
#### value
設定されている値です。
これはMUIのどのコンポーネントでも基本的に同じなので特段の解説は不要かと思います。

#### onChange
値が変更されたときの挙動です。
こちらも特段の解説はしません。

#### options
選択可能な値を配列で指定します。
これがプルダウンでサジェストされる値になります。

#### getOptionLabel
プルダウンに表示される表示名を設定する関数を指定します。
関数は引数にoptionsの要素を受け取ります。
戻り値として、設定したい表示名を指定します。

#### renderInput
入力フィールドのレンダリングをカスタマイズできます。
基本的にはTextFieldコンポーネントを指定します。

ここで使用しているのは本当にごく一部で、ほかにも多くのオプションを指定できます。
値のフィルタリングや、複数選択の制御、フォーカスを当てたときの挙動など、本当にさまざまなカスタマイズができます。

詳細は以下を参照してください

https://mui.com/material-ui/api/autocomplete/

## まとめ
基礎の基礎の使い方をまとめました。
これだけだとあまり内容が充実していないので、よくあるエラーやより細かいカスタマイズについて、今後内容を追記していければと思っています。
Tips: lazy.nvimでnvim-treesitterをセットアップする

## この記事は何
最近シンタックスハイライトをnvim-treesitterで行うようになったのですが、lazy.nvimでのセットアップ方法に少し詰まったので記事にまとめました。

## TL;DR

https://github.com/nvim-treesitter/nvim-treesitter/wiki/Installation#lazynvim

## lazy.nvimとは
lazy.nvimとは、Neovimで利用できるプラグインマネージャーです。

https://github.com/folke/lazy.nvim

機能等についてはドキュメントを参考にしてください。

https://lazy.folke.io/

## nvim-treesitterとは
tree-sitterとは、シンタックスハイライトの解析に特化したパーサーです。
tree-sitterを用いることで、正規表現だけでは表現が難しいようなシンタックスハイライトも実現しやすく、
より正確で詳細なコード解析が可能になります。

https://tree-sitter.github.io/tree-sitter/

そしてnvim-treesitterとは、その名の通りtree-sitterをNeovimで簡単に利用可能にするプラグインです。

https://github.com/nvim-treesitter/nvim-treesitter


## lazy.nvimでのnvim-treesitterのセットアップの難しさ
[README](https://github.com/nvim-treesitter/nvim-treesitter)には`vim-plug`の設定方法については書かれていますが、lazy.nvimでの設定方法については書かれておらず、設定自体も単純なライブラリと比べると若干ピーキーなインターフェースになっているため、正しく設定するのが少し難しいです。
実際正しく設定ができておらず、tree-sitterが動いていなかったようなケースもあるようです。

https://zenn.dev/atoyr/articles/8802733f238e6d

## 設定方法
設定方法をそれぞれ試している記事はありますが、正しい設定はなんなのか色々調べたところ、なんとnvim-treesitterのリポジトリにズバリ答えが載っていました。
nvim-treesitterのWikiに参考の設定が掲載されています。

https://github.com/nvim-treesitter/nvim-treesitter/wiki/Installation#lazynvim

こちらの設定をそのまま使うことで、まずは使える状態にはできました。
三項演算子について語ろう

### はじめに
チェリー本を読んでて疑問に思ったこと、備忘含めて書こうと思いました。

### 三項演算子ってなに
**三項演算子**（条件演算子）はある条件に基づいて異なる値を返すための方法です。

### 三項演算子の構造を見てみる
チェリー本に以下のサンプルコードが書いてあり
sum_value = n.even? ? n * 10:nの部分が三項演算子を使っています。
even? ?で自分も??状態でした。

```
numbers = [1,2,3,4]
sum = 0
numbers.each do |n|
  sum_value = n.even? ? n * 10 : n 
  sum += sum_value
end
```
### 三項演算子の書き方

```
条件 ? 条件が真のときの値 : 条件が偽のときの値
```
even?は偶数ならTure, 奇数ならFalseを返す関数です。
つまり
nが偶数なら n * 10
nが奇数なら n を返すといった処理になっています。
上記処理の結果は64となります。
Tips #018 リストのアイテムに添付された複数の添付ファイルを配列に格納するのに格闘した話

https://qiita.com/Novskiiiiiiiiii/items/47bae227fc234242e4d8

備忘のために箇条書きだけど残しておく。

やりたいこと

    リストから特定のアイテムを取得
    ↓
    アイテムの添付ファイルを取得
    ↓
    1アイテムごとにメールにまとめて添付して送る
    ↓
    1アイテムごとにSharePointの任意のライブラリに添付ファイルを格納

いちおう以下のような感じで実現はできた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/8ca5bf3c-1f12-c54d-c326-58f4be9507d5.png)

    １．Array変数を定義
    ２．複数の項目の取得
    ３．添付ファイルの取得
    ４．添付ファイルのコンテンツの取得
    ５．Array変数に添付ファイルの数だけ格納
    ６．メールの添付にArray変数をセット
    ７．Array変数のFor Eachでファイルの作成で添付ファイルの数だけアップロード

特にてこずったのは２点

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/d76159f4-5fa5-132b-cdcf-711ad8f313a2.png)

    {
      "Name": @{item()?['DisplayName']},
      "ContentBytes": @{body('添付ファイルのコンテンツの取得')}
    }

↑　Array変数に追加するときのパラメータ。

あと、ファイル作成の時のパラメータ。
Code viewだときちんと表示されるのに、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/e67e2978-54f0-dfa4-bedf-f077ef14fe92.png)

実行後に設定欄を見るとさも間違ってる風に表示されているから焦るじゃん。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3891071/1176bc14-d803-b293-1878-49d5fb1ce5a2.png)

まあとりあえず先週末に仕事で解消しなかった問題はクリア出来たので、
明日はスタートダッシュを決められそう。

JSONの勉強しながら通勤しよう。

https://qiita.com/Novskiiiiiiiiii/items/85b581926590dc5e4e39
rails の lib 自動読み込み

railsで自作moduleを作成したときにエラーに出くわした

```
uninitialized constant Hoge::Fuga::Piyo (NameError)
```

以下の設定でlibディレクトリ以下のファイルはすべて勝手に読み込まれると思っていた
```config/application.rb
module App
  class Application < Rails::Application
    ...
    config.autoload_lib(ignore: %w[assets tasks])
    ...
  end
end
```

### libディレクトリ構造
ファイルの置き場所はmoduleの定義に合わせないと読み込まれない
```lib/hoge/fuga/piyo.rb
module Hoge
  module Fuga
    module Piyo
      def custome_method
        ...
      end
    end
  end
end
```
上記の場合は `lib/hoge/fuga/piyo.rb` にファイルを配置する


classの場合も同様

```lib/hoge/fuga/piyo.rb
module Hoge
  module Fuga
    class Piyo
      def custome_method
        ...
      end
    end
  end
end
```
上記の場合も `lib/hoge/fuga/piyo.rb` にファイルを配置する
最新のMac miniが発売！

# 最新機発売！
11/8(金)、ついに最新Mac miniが発売されました🥳

普段Macを愛用している私が最新Mac miniのいいところをまとめてみました
（月並みではありますが...）

https://www.apple.com/jp/mac-mini/?afid=p238%7CsRYOX7QLr-dc_mtid_20925emn40401_pcrid_720008344489_pgrid_173241858681_pexid__ptid_kwd-95092228_&cid=wwa-jp-kwgo-mac-slid--Core-Macmini-Avail-

# M4チップ搭載
やはり一番の見どころはこの点でしょうか？

すでにMacBook Proには搭載されているM4チップですが、新型Mac miniにも搭載されます。（上位モデルではM4 Proも選択可能）

10コアCPU構成で高度なマルチタスクでもストレスフリーな操作性が期待できますし、機械学習機能にも優れているそうです

ついこの前解禁されたApple Intelligenceの正確度にも期待です！

以下の記事を参考にさせていただきました

https://tech-gadget.reinforz.co.jp/987


# 名に恥じないサイズ
本体サイズは12.7センチ四方と、前モデルよりひと回り小さくなっており、**mini**という名前に負けないサイズ感です

私が持っているiPhone SE(第3世代)の高さが14センチ弱でしたので、一辺の長さはiPhone SEより短いということになります😱

スタイリッシュなデザインも個人的にはかなり刺さりますね

デスク内でスペースを取りませんし、お部屋が映えること間違いなし！

# 価格帯
最低グレードのものであれば94,800円~
M4Proチップ搭載モデルでも218,800円~

と、他のミニPCで同じスペックのものと比較するとかなりお買い得なのでは？

👇各グレードの価格

https://www.apple.com/jp/shop/buy-mac/mac-mini

### 欲しい...
3年目にしてやっとリーダブルコードを読み始めた

## 目的は？
3年目になるまで、いろいろと自己研鑽で頑張ってきましたが、その内容は主に資格取得に向けた勉強であることが多かったです。
でも実際にエンジニアとしての技術力や価値を上げていくためには、実務の中で使える知識であったり理解、経験が必要だと感じるようになりました。
まずそのはじめの一歩として、本来1年目の段階で読むべきであるような名著を読んでみようと思います。
そして、これまでは問題を解くという形でアウトプットをしてきましたが、本を読むということだけではアウトプットが十分にできないかなと感じたので、自己満ブログを残すことでアウトプットしていこうと考えました。
もし暇がある方はお付き合いください

## 1日目
今日、書籍を購入してほんの少し読み始めました。読んだこと少しずつ自分の言葉でアウトプットしていこうと思います。
 - __読みやすいコードとは？__
 リーダブルコードの中で、「読みやすいコード」の定義としては、__見た瞬間に何をしているかがわかる、最短時間で保守や改修ができるコードである__、というものでした。
 ここで重要なのは、どんなソースでも上記のような状態にしておくということかなと思います。自分しか関わらないプロジェクトだと思っていても、半年後の自分が今の自分と同じ目線で見れるとも限らない。1年間自分が関わると思っていたが人員調整で他者に引き継がないといけないというケースがざらにあるからです。


 - __変数名やメソッド名にこだわれ__
 連番を表す（for文でのインデックスなど）場合以外は、名前にこだわることで何をしているかを短時間で推測できるようになるとのことでした。
 可能な限り具体的にどのような操作が行われるメソッドなのか、どのような値が代入される変数なのかをニュアンスを含めて単語で表現することが重要なんだという解釈をしました。


 ## 最後に
 初めてテックブログを書きました。まだまだ人に見せられるようなものではないことはとても理解していますが、まずは自分のアウトプットを重ねることを目的に頑張ろうと思います。
 第一弾はスモールスタートということでこの辺で終わりにしようと思います。
【React】setCount(count + 1) と setCount((prevCount) => prevCount + 1) の違い

Reactの教材では、カウントボタンを例にuseStateの説明がされていることが多いと思います。
```jsx
export const App = () => {
  const [count, setCount] = useState(0);
  const handleCountUp = () => {
    setCount(count + 1);
  }

  return (
    <>
      <button onClick={handleCountUp}>カウント</button>
      <p>{count}</p>
    </>
  )
}
```

カウントボタンを押して2ずつ増やしたい場合、`setCount(count + 1)`を2行書いてボタンを押しても実際は1しか増えず、`setCount((prevCount) => prevCount + 1)`のようにアロー関数の形にして2行書くことで2ずつ増えるようになります。これもセットで説明されていることが多いと思います。

この理由がいまいち腑に落ちず「とりあえずそういう風に書けばいいんだな」という程度で済ませていたのですが、自分なりに咀嚼できたのでまとめます。

ここで理解しておくべきReactの挙動は
1. __stateの更新を検知したらコンポーネントが再度上から評価される(再レンダリング)__
2. __関数内で同じset関数が複数回実行されていても、関数内の処理が終わるまでは更新が反映されない__

ということです。

2については、公式ドキュメント([一連の state の更新をキューに入れる – React](https://ja.react.dev/learn/queueing-a-series-of-state-updates))に以下のように記載があります。
> イベントハンドラ内のすべてのコードが実行されるまで、React は state の更新処理を待機します。このため、再レンダーはこれらの setNumber() 呼び出しがすべて終わった後で行われます。

> イベントハンドラおよびその中のコードがすべて完了した後まで、UI は更新されないということでもあります。このような動作はバッチ処理（バッチング）とも呼ばれ、これにより React アプリの動作が格段に素早くなります。またこれは、変数のうち一部のみが更新された「中途半端な」レンダー結果に混乱させられずに済むということでもあります。


バッチ処理は「データを一定時間あるいは一定量ごとにまとめて処理する」という意味です。
1回の更新のたびにちまちまコンポーネントを上から評価してしまうとパフォーマンスが悪くなってしまうため、このような挙動になっている、ということですね。

たとえばカウントが0の状態で2つ増やす場合、
```jsx
const handleCountUp = () => {
  setCount(count + 1);
  setCount(count + 1);
}
```
と書けばいいように思えるのですが、実際は以下のようになっています。

```jsx
const handleCountUp = () => {
  setCount(0 + 1); // 0 + 1 = 0 だが、まだ関数内の処理が終わっていないため更新されず、stateは0のままで次の処理に移る
  setCount(0 + 1); // 現在のstateは0なので0が代入される => 関数内の処理が終了して更新が反映される、stateは1になる
}
```

実行中の関数内の処理が終わるまでは`setCount`が複数回実行されていても更新が反映されません。つまりこの2行は全く同じことをしています。
よって、ボタンを押しても1しか増えないのです。

前述したように、2つずつ増やす場合は以下のようにアロー関数の形で更新します。
```jsx
const handleCountUp = () => {
  setCount((prevCount) => prevCount + 1);
  setCount((prevCount) => prevCount + 1);
}
```
アロー関数の形にすることで、現在のstateに+1してそれを新しいstateとして返すようReact側で実装してくれています。先程の公式ドキュメントによると __更新用関数__ と呼ぶそうです。つまり、関数内のすべての処理の終了を待たずにstateの更新を反映させることができます。

```jsx
const handleCountUp = () => {
  setCount((0) => 0 + 1); // stateが1に更新される
  setCount((1) => 1 + 1); // 現在のstateは1なので1が代入される => 2に更新される
}
```

あとは前述した通り、関数内のすべての処理が終わればコンポーネントが上から再評価されるため、ボタンを押すことでカウントが0から2になります。

以上、自分なりに咀嚼した`setCount(count + 1)`と`setCount((prevCount) => prevCount + 1)`の挙動の違いです。誤り等ありましたらご指摘いただけますと幸いです。
【完璧理解】MAモデルについて、ChatGPTに聞きまくった。

#  MAモデルとは？
MAモデル（移動平均モデル）は、「過去の予測誤差」 が現在のデータに影響を与えると仮定するモデルです。

目的：過去のデータやノイズの影響を理解し、未来のデータを予測する。
基本構造：MA(1)モデル（移動平均1次モデル）は次のように書かれます：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/437b65d1-8750-abc4-9a39-fd4b1e7100ad.png)

## 質問1 予測はあくまで予測なんで、なんで未来に影響与えるの？
回答from:ChatGPT
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/d087b234-2d75-aa89-f56b-37cdde169f4a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/f74bf7ab-53e9-3df3-f7a9-6478b2970494.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/5398a750-26bd-93bf-9394-454245125575.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/55353e23-8ede-8617-4eb3-6c8768977aac.png)

## 質問2 予測誤差が常に存在することを前提に、なぜ過去の誤差が未来に影響すると考えるのか？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/c6d72dd9-c5ef-46ea-721f-2430050520a6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/f5209a48-0794-b037-b048-8131f82389ef.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/9b5b1dd4-64a0-e6e9-10c2-9b87832d7e0f.png)

##質問3 でも予測ミスがあり得ると思います。どうやって自分のミスかそうでないか判断する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/37593aa4-7694-591a-a585-99312cd7cc39.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/6bbb20fe-7125-4940-5cd0-60dc43108535.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/f0c56a34-fed1-063e-eca2-fe58206cb09c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3804860/b82f3ecb-24d9-254d-9361-be0c84d3b2b5.png)
重み付き区間スケジューリング問題のDP解法 O(NlogN)

# 問題概要
https://atcoder.jp/contests/typical-algorithm/tasks/typical_algorithm_b/editorial
この問題の各区間に重みがあるとしたとき、その得られる重みの最大を求めます。なお、上記リンクの問題は閉区間の[L,R]となっていますが、この記事では「R+=1」をすることによる半開区間の[L,R)として説明します(dpの遷移的に[L,R]だと、ある区間の仕事が終わったその日から新しい仕事を始められてしまうので、半開区間だとそれを防げる)。

# 解法
- LとRをまとめて座標圧縮する(DP配列のサイズ的に座標圧縮が必要)
- 座圧後の状態でグラフを作成する
-> 各頂点について、今がi番目の頂点としたときにi+1番目の頂点に重み0の辺を張る
-> 各区間のLからRに対して、入力で渡された重みの辺を張る
- 構成されたグラフはDAGなのでDPができる。dp[i]=i番目の頂点まで見たときの得られた重みのmax

という流れで解くことができます。座標圧縮をする関係上、計算量にO(logN)がついて、O(NlogN)になります。DP自体はO(N)です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3701202/c9808107-630a-ccd5-e522-7da31d159ee9.png)

図にするとこんな感じになります。上が入力時の区間で、下が座圧して辺を追加したときのグラフです。コードを実装してみるとこんな感じになります。

```C++:C++
#include <bits/stdc++.h>
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;

#define rep(i,n) for(ll i = 0; i < (n); ++i)
#define chmax(x,y) x = max(x,y);

using ll = long long;
using vl = vc<ll>; using vvl = vv<ll>; using vvvl = vv<vl>; using vvvvl = vv<vvl>;
using P = pair<ll, ll>;

//------------------------------------------

template<typename T = ll>
struct CC {//snukeさんの座標圧縮
    bool initialized;
    vector<T> xs;
    CC() : initialized(false) {}
    void add(T x) { xs.push_back(x); }
    void init() {
        sort(xs.begin(), xs.end());
        xs.erase(unique(xs.begin(), xs.end()), xs.end());
        initialized = true;
    }
    ll operator()(T x) {
        if (!initialized) init();
        return upper_bound(xs.begin(), xs.end(), x) - xs.begin() - 1;
    }
    T operator[](ll i) {
        if (!initialized) init();
        return xs[i];
    }
    ll size() {
        if (!initialized) init();
        return xs.size();
    }
};

int main() {
    ll n;
    cin >> n;
    CC cc;//座標圧縮用
    
    //[l,r)の区間の重みがc
    vl l(n), r(n), c(n);
    rep(i, n)cin >> l[i] >> r[i] >> c[i];

    rep(i, n) {//座標圧縮用のデータに追加する
        cc.add(l[i]);
        cc.add(r[i]);
    }

    rep(i, n) {//座圧後の番号に更新する
        l[i] = cc(l[i]);
        r[i] = cc(r[i]);
    }

    ll sz = cc.size();

    vv<P>to(sz);//各区間のlとrを頂点として見た時に、各頂点から生えている辺の(行先,重み)を持つ
    rep(i, n) {//各区間のLから生やす
        to[l[i]].emplace_back(r[i], c[i]);
    }
    rep(i, sz)to[i].emplace_back(i + 1, 0);//すぐ右の頂点に重み0を生やす、これによって「今見てる区間を採用しない」のような遷移ができる

    vl dp(sz + 1, 0);//dp[i]=i番目の頂点まで見たときのmax。先頭に番兵を入れている

    rep(i, sz) {//配るDP
        for (auto [t, c] : to[i]) {//辺が生えてる行先に配る
            chmax(dp[t], dp[i] + c);
        }
    }
    cout << dp[sz] << endl;
}
```
重み付き区間スケジューリング問題が調べた感じどこのサイトにもないので、重み無しの問題で使用したところACできました。R++をして半開区間にしています(サンプルが弱いらしいのでミスがあるかもしれません)。
https://atcoder.jp/contests/typical-algorithm/submissions/59664175

重みがmを超えないように区間を選んだときに、最大で何個区間を選べるか？という問題だとしてもDP配列に現在の重みを乗せればいけそうですね(TLEする制約が来たらどうするのかは知りません())


ちなみにk個区間が被るのを許すという問題設定では最小費用流で解けるらしいです(蟻本より)。私には最小費用流を理解できていないので解けません。

# 終わりに
重み付き区間スケジューリング問題の解法が気になって調べたのに誰も記事にしてなかったので書きました。解法をわかりやすく教えてくださったsnukeさんに感謝します(snukeさんから学んだことを記事にしただけなので、このアルゴリズムは正しいという謎の予防線)。
https://www.youtube.com/live/a723sprlaVk?si=poEvfNJFQOxWGnHr&t=11532
SNMP クライアントを作成してみる

# SNMP クライアント

前回（[SNMP 入門のための環境構築](https://qiita.com/tkhr68000/items/48245f6b9430d8302534)）の続きで、クライアント側を作ってみます。

## WPFアプリ

WPFアプリを準備します。
### Nuget

WPFアプリからSNMPの通信を行うため、NuGetライブラリを追加します。
今回は以下のライブラリを追加します。

[Lextm.SharpSnmpLib](https://www.nuget.org/packages/lextm.sharpsnmplib/)

### SNMPリクエスト

SNMPリクエスト部分の処理を以下に示します。

```cs
var endpoint = new IPEndPoint(IPAddress.Parse(_ipAddress), _port);
var community = new OctetString(_community);
var result = Messenger.Get(VersionCode.V1, endpoint, community, new List<Variable> { new Variable(new ObjectIdentifier(oid)) }, 6000);

if (result.Count > 0 && result[0].Data.TypeCode != SnmpType.NoSuchObject)
{
    return result[0].Data.ToString();
}
else
{
    throw new Exception("SNMPリクエストが失敗しました。");
}
```

## まとめ

作成したソースコードはGitHubに登録しました。詳細は以下のリンクからご覧いただけます。

https://github.com/TakahiroSato68000/SnmpSampleApp
【Drupal】Entity の標準 Route を 変更 / 無効化 したい

「標準のRouteを無効化したい。」って時ありますよね。
え、あんまりしっくりこないですか？

例えばNode。標準で「/node/{node}」ってルートが登録されていると思います。

データとしての登録はしたい。でも、ページは生成したくない。

そんなシチュエーションです。

今回は Routeを 「変更 / 無効化」 する方法について紹介しようと思います。

## 実装手順
今回は3ファイル作成するのみ！！
コード量少ないです。
ささっと説明しますのでお付き合いいただけると幸いです。

### 1. モジュールのセットアップ
DrupalのRoutingには専用のイベントがあるのでそこをサブスクライブするのが一般的な手法です。

#### 1-1. モジュールの作成
モジュールを作成します。
```md
web/modules/app/
├── README.md
└── app.info.yml
└── src
    └ Routing
        └ RouteSubscriber.php
```

#### 1-2. Serviceの登録
`app.services.yml`ファイルに、「app.route_subscribe」サービスを登録します。
```php:web/modules/app/app.services.yml
app.route_subscribe
    class: "\\Drupal\\app\\Routing\\RouteSubscriber"
    tags:
      - { name: "event_subscriber" }
```

`RouteSubscriberBase`を拡張して、RouteのSubscribeするServiceファイルを生成します。
```php:RouteSubscriber.php
class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    // ここにRouteへの処理を書く.
  }
}
```

### 2. Routeの無効化(削除)
```php:RouteSubscriber.php
class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    $collection->remove('entity.node.canonical');
  }
}
```

なんとこれだけ。簡単ですよね。
/node/{node} にアクセスしても、404が返されます。

### 3. Routeの変更
#### 3-1. 自前のControllerを適用させたい。
```php:RouteSubscriber.php
class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.node.canonical')) {
      $route->setDefault('_controller', '\\Drupal\\app\\Controller\\AppArticle');
      $route->setOption('parameters', [
        'node' => [
          'type' => 'entity:node',
        ],
      ]);
    }

  }
}
```
RouteのParameterにEntityをセットすることで、別途ロードすることなくNodeオブジェクトを取得することができます。

#### 3-2. ページのタイトルを変更したい。
```php:RouteSubscriber.php
class RouteSubscriber extends RouteSubscriberBase {

  protected function alterRoutes(RouteCollection $collection) {
    if ($route = $collection->get('entity.node.canonical')) {
      $route->setTitle('_title', 'Qiita - @umekikazuya');
    }

  }
}
```

## まとめ
いかがでしょうか？

セキュアなシステムを作る上で、「公開すべきじゃないルート」「運用上必要ないルート等」、気になる箇所いろいろあると思います。
Routingへの介入、といってもできることいろいろあります。

カスタマイズして、Controllerに飛ばすことでなんでもできますよね。
- リダイレクトコントローラーに飛ばす。
- ファイルをダウンロードさせる。
- アクセスでバッジ起動する。

発想次第でいろんなことができるかな、と思います。
業務経験を振り返る【2021/4/1 - 2022/4/1】

# はじめに
2024年11月からフリーランスエンジニアとして働く予定で、未経験からスタートしてこれまで４年弱経過したので、棚卸し&備忘のため業務経験を振り返ようと思う。

# 1社目 小規模SIer In 福岡 【2021/4 - 2022/10】
もともと2020年に新卒で某広告代理店に就職したが、労働環境の過酷さや希望していた業務内容との相違から、3ヶ月で退職した。その後はフリーターとして働きながら、2021年4月に第2新卒として再就職の機会を探していた。

しかし、短期間で退職した求職者を採用する求人にはなかなか出会えず、厳しい就職活動を強いられることとなった。その中で偶然見つけたのが1社目の会社である。

この会社は東京・大阪・福岡に拠点を持ち、当時は福岡のみの募集であった。内定はいただいたが、福岡勤務が必須条件であった（当時は大阪に住んでいた）。しかし、未経験からIT業界に入る数少ないチャンスであると考え、思い切って福岡への移住を決意した。2021年秋、格安のシェアハウスを見つけて引っ越しを終え、無事にIT業界での仕事をスタートさせた。

## 研修時代【2021/4 - 2021/6】
こうして入社を果たしたが、新卒と同様の扱いを受けることとなり、3ヶ月間の外部研修を受講する機会を得ることができた。IT未経験の私にとって、給料をもらいながらIT知識を身につけられるこの機会は大変ありがたかった。プログラミングスクールに通うのと同等の知識を習得する場を得たと思う。 （IT業界未経験で志望する方には、技術研修を実施している企業への入社を強くおすすめしたい）

研修内容は以下のようであった。

- 4月：IT基礎、HTML、CSS、PHPを学び、簡単なブログアプリを作成
- 5月：Javaの文法やサーブレットの学習
- 6月：Javaを利用したチームでの模擬開発演習

振り返ると、特に高度な内容ではなく、ローカル環境上でのアプリケーション完成が目標であったため、実務での開発経験とは異なる部分もあった。しかし、同じレベルのメンバーと議論しながら演習を進めていく過程には学ぶことが多かった。

## 資格取得期間【2021/7】
3ヶ月間の研修が終わり、自社内で資格取得のための学習期間が設けられた。当時社内ではSalesforceとAWSの学習組に分かれ、希望を研修期間中に聞かれていた。

私はAWSを希望していたため、AWS CLFおよびAWS SAAの学習を進めた。約15営業日と限られた期間であったが、資格取得に多くの業務時間を費やすことができたため、両方の資格を取得することができた。

その後、7月後半からは社内の受託案件にアサインされる運びとなった。

## 初業務！ セキュリティ企業のECサイト運用保守【2021/8 - 2022/10】
この案件への参画が決まったときは嬉しかった。未経験にもかかわらず、Webアプリケーションの開発に携われると思ったからである。

- アプリケーションはAWS ECS上にホストされている
- バックエンドはLaravel、フロントエンドはVue.js
- Docker上での開発

など、未経験者にとってハードルが高い内容であったが、やる気に満ちていた。しかし、実際にアサインされてから知ったのが、この案件が引き継ぎ業務であったということである。

### 実務未経験で前任者の引き継ぎ
前任者が離職することに伴い、引き継ぎを行うこととなった。それも1ヶ月である。まずはプロジェクトの概況から開発環境、デプロイ手順などを引き継ぎながら、先方から依頼を受けているFAQページの作成を担当することとなった。

なお、設計書などは存在せず、あるのはプログラムと簡単なメモ程度であったため、プログラムを読み解きながら仕様を理解しなければならず、非常に苦労したことを覚えている。

新卒で会社を見極めることは難しいが、未経験であるならば、可能であれば社員数の多い会社への就職をおすすめしたい。少人数でかつ人の入れ替わりが激しい職場では、スキル不足の社員がプロジェクトの主担当として配置される可能性が高まるからである。

さらに当時私は在宅勤務で、オフィスもほぼ存在しない状態（シェアオフィスの1席をレンタルしている状況）であったため、気軽に質問できる先輩もおらず、非常に苦労した。経験が浅いうちは出社でき、質問しやすい雰囲気の職場が望ましいと痛感した。

### 苦労はしたが、良い経験を積めた
日々わからないことだらけで、自己流で先方の依頼に応える日々であった。保守性や品質の高いプログラムには仕上げられなかったと思うが、なんとか自分が離職するまでに全ての依頼を完遂することができた。特に、バックエンドとフロントエンドの開発経験を積めたことは、自身にとって貴重な経験となっている。


## Amazon Connect導入支援【2021/11 - 2022/10】
ECサイトの運用保守業務に慣れてきた頃、並行してAmazon Connectの導入支援業務も担当することとなった。顧客から依頼があれば、提案・見積もり・実装・運用保守までを一貫して実施する内容であった。

Amazon Connectはカスタマイズで拡張が可能であるが、提案内容としてはAmazon Connect内の設定で完結するものが多かった。カスタマイズには多くの工数がかかり、費用面での制約があったためである。そのため、要件のヒアリングや提案力、顧客との折衝能力が求められる業務であった。

しかし、私としては開発経験を積んでいきたいと考えていたため、業務内容が希望に適わず、1年弱担当した後、開発や幅広いAWSを扱える職場を求めて転職を決意した（2022年4月頃と記憶している）。

## 転職活動へ、そしてAWSパートナー企業へ
文章が長くなってしまったので、分けて記載することとする。
同じような経歴の方、未経験からIT就職する方の参考になりますように。
Siv3Dでゲームをいくつか作ってシリーズ化した話

## はじめに
※初めてなのでお見苦しい所があると思いますがご了承ください。
初めまして。otokujiです。
私はつい最近までコードの世界に足を踏み入れずにずっとScratchで遊んでいたのですが、
昨年ついにScratchの限界を感じてしまったのでコードの世界に足を踏み入れようとなったきっかけの
Siv3Dでゲームをいくつか作成した話をしようと思います。
## 作成したもの
### 熟語パズル

漢字が落ちてくる落ち物パズルです。
二字熟語ができると熟語になる漢字が消えます。
スコア100点ごと、ほかにも一度に二つ以上熟語を作れるとアイテムが手に入ります。
### スピード読み仮名
上に表示された熟語の読みを素早く当てるゲームです。
間違えると選択肢の数が減るサポート付きです。
レベルを選ぶことができ、
レベル1：2 ~ 6字
レベル2：7 ~ 9字
レベル3：9 ~ 11(約25)字
の字数の熟語が出題されます。（読み仮名の字数です）
### クラフト
熟語パズルで手に入ったアイテム（部首）を使用して漢字を作れます。
### ランチャー
熟語パズル、スピード読み仮名、クラフトを選んで起動できるランチャーです。
## 今後の展望
### 現在制作中の機能
ランチャーで熟語パズル、スピード読み仮名、クラフトの背景色を変更できるように
### 今後の予定
熟語パズルの3,4字熟語の対応
ゲーム内通貨の仕様実装
メインゲームの製作
メインゲームで使用可能なアイテムをクラフトで製作できるように
## 公式サイト
こちらのプログラムはサイトからダウンロードできますので、ぜひ皆さまやってみてください。
（定期的に更新していますので、historyページをたまにでもご覧いただけると幸いです）
https://sites.google.com/view/digikanofficial/home?pli=15
## 動画
未踏ジュニア成果報告会で発表したときの動画です。
https://www.youtube.com/watch?v=uR5StA0dQkM
Apple Silicon MacのPytorhのDataLoaderが遅い理由と解消方法

#　はじめに
新しくM4 MaxのMacを購入してディープラーニング関連のベンチマークをしていたのですが、どうもGPUの履歴がスカスカだったので、なにが原因か調べてみました。ここでは、原因と対策方法について紹介します。

# GPUがサボりまくっている
PytorchのベンチマークのためにResnet18でCIFAR10の学習を行うコードを実行してみたのですが、どうも遅い

GPUの履歴を見ると、GPUが間欠でしか動いていない。下図みたいに、一瞬動作して、その後待ち時間がずっと続く形でした。ちなみに、処理時間は**392.62**秒。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526717/4a00032a-a95c-8dbc-583b-696627d67829.png)


このような挙動ってWindowsで学習させたときにも経験があって、その時はDataLoaderが問題だったので、とりあえず`num_workers=0`にして実行してみました。すると、処理時間は**38.41**秒。

# 原因はプロセスの起動・終了が遅い

Windowsの時は、プロセスの起動・終了が遅いのが原因で、Windowsでは、

`persistent_workers=True`

という設定で解決していたのでそれを試してみる。

処理時間は**35.80**秒。結果を見ると1EPOCH目が19秒で、それ移行は4秒程度でEPOCHが終了している。

やはり、プロセスの起動が遅いらしい。

# 解決策

少し調べてみると、`multiprocessing_context`というオプションがあり、デフォルトは"spawn"で、"fork"と"forkserver"を選べるらしい。

とりあえず、"fork"を選んでみる（`persistent_workers`は削除）

結果は**21.50**秒！

GPUの履歴を見てもGPUがずっと動いていることを確認できた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3526717/9202abac-650d-2205-df12-cb0600c71bcb.png)


# まとめ
MacOSのPytorchのプロセス起動（spwan）は遅いみたいです。forkを設定すると高速に動作せることができましたので参考になればと思います。

結論は、「`multiprocessing_context="falk"`を設定する」ことです。

ちなみに、この速度であればGoogle ColabのGPU（T4）より高速です。
【Nerves】シリアルコンソールに切り替える方法

# はじめに

Nervesでは、コンソールに```iex>```が表示されます。
この出力は、HDMIやシリアルコンソールに出力されます。
rpi4等HDMIがある場合は、HDMIに出力がデフォルトになっていますが、この設定を変更する事ができます。

今回は、M5Stack Core MP135を例に、シリアルコンソールに切り替える方法を紹介します。

ラズパイでも同様の方法で可能だと思います。

## シリアルコンソールの用意

シリアルコンソールを使うためには、USBシリアル変換が必要です。

amazon等で購入できます。3.3Vのものを選びます。

以前は安いものを使っていたんですが、チップが正規品ではない為に、標準のドライバが使えない問題が多々あり、安すぎないものを選ぶのが良いかとおもいます。

私が使っているのは[これ](https://amzn.asia/d/05xYKgl)です。

この製品は、Windows11で特にドライバーのインストール作業無しで、使えました。

## 機器との接続

M5Stack Core MP135には、Port Cがシリアルポートになっています。
ケーブルは、スイッチサイエンスで[購入](https://www.switch-science.com/collections/m5stack/products/8305)しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/a0e8b620-df3f-cb67-27cb-90662338203b.png)

重要な点は、USBシリアル変換の正しいピンに接続する事です。
TXDとRXDを接続する必要があるので、間違えないように注意してください。

| M5Stack Core MP135 | USBシリアル |
| --- | --- |
| 黄(TXD) | RXD |
| 白(RXD) | TXD |
| 赤(5V) | 接続しない |
| 黒(GND) | GND |

赤色の5Vは、接続しないでください。誤って接続すると機器やUSBシリアル変換が壊れる可能性があるので気をつけましょう。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/64f9aaab-fd9e-9735-cc31-54d075bf7005.png)


# config.exsの設定

config.exsに以下の設定を追加します。

```
config :nerves, :erlinit,
  ctty: "ttySTM0"
```

ラズパイ4の場合は、```ttyS0```
ラズパイ3の場合は、```ttyAMA0```
を指定します。

ドキュメント
https://hexdocs.pm/nerves/advanced-configuration.html#overriding-erlinit-config-from-mix-config

後は通常通りビルドします。

# 実行

PCにシリアルコンソールを接続して、ターミナルソフトを起動します。
ターミナルソフトの設定は、ボーレートは115200bpsに設定します。

電源を入れると、シリアルコンソールにログが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/532235/93e3772b-8590-e74d-28ba-5fb82146f091.png)

# まとめ

HDMI出力の方が、モニターやキーボードで操作したい場合は、便利ですが、シリアルコンソールの方が、文字として入出力できるので、Windowsでの切り取り貼り付けができて便利です。

よく使う場合は、USBシリアル変換の常備をお勧めします。
Cloudflare Pagesで複数のパスに対してBasic認証


## 事前準備

```
$ npm install wrangler --save-dev
$ mkdir app
$ touch app/index.html
$ mkdir functions
$ vim functions/_middleware.js
$ npx wrangler pages dev app
```

## _middleware.js

```js:functions/_middleware.js
const authSettings = [
  { path: "/protected2", username: "user2", password: "pass2" },
  { path: "/", username: "user1", password: "pass1" },
  // 必要に応じて追加
];

function isAuthorized(authHeader, validCredentials) {
  if (!authHeader || !authHeader.startsWith("Basic ")) {
    return false;
  }
  const [login, password] = atob(authHeader.split(" ")[1]).split(":");
  return validCredentials.some(cred => cred.username === login && cred.password === password);
}

export async function onRequest(context) {
  const { request } = context;
  const { pathname } = new URL(request.url);

  const matchedAuthSettings = authSettings.find(
    setting => pathname === setting.path || pathname.startsWith(setting.path)
  );

  if (matchedAuthSettings) {
    const authHeader = request.headers.get("Authorization");
    const isValid = isAuthorized(authHeader, [matchedAuthSettings]);

    if (!isValid) {
      return new Response("Unauthorized", {
        status: 401,
        headers: {
          "WWW-Authenticate": 'Basic realm="Restricted Area"'
        },
      });
    }
  }

  return await context.next();
}
```

## 確認

```shell
$ curl -I http://localhost:8788
HTTP/1.1 401 Unauthorized
$ curl -I -u user1:pass1 http://localhost:8788
HTTP/1.1 200 OK
$ curl -I -u user1:pass1 http://localhost:8788/protected2
HTTP/1.1 401 Unauthorized
$ curl -I -u user2:pass2 http://localhost:8788/protected2
HTTP/1.1 200 OK
```
OMC233A(273)

https://onlinemathcontest.com/contests/OMC233/tasks/8303

左辺を変形すると、
$=((2^2)^{sinα})^{cosα}$
$=2^{2×sinα×cosα}$
$=2^{2sinαcosα}$
$=2^{sin2α}$。

右辺は、
$=2^{\frac{1}{2}}$。

指数部$sin2α=\frac{1}{2}$より、
$2α=2nπ+\frac{1}{6}π$ $…①$
$2α=2nπ+\frac{5}{6}π$ $…②$
$(n=0,1…)$

$①$、$②$の両辺を$2$で割ると、
$α=(n+\frac{1}{12})π$ $…①'$
$α=(n+\frac{5}{12})π$ $…②'$

$0<\frac{1}{12}<\frac{5}{12}<1$なので、昇順に並べると、
$(①',n=0),(②',n=0),(①',n=1),(②',n=1),(①',n=2),…$となります。
したがって$20$番目は、$②'$、かつ$n=9$となるので、
$α=(9+\frac{5}{12})π$。

$\frac{a}{b}π$の形にすると、
$(9+\frac{5}{12})π=\frac{9×12+5}{12}π$
$=\frac{113}{12}π$
となり、
$a+b=125$。
[備忘録]　読んだロボット工学に関する記事をまとめた

# はじめに
　こんにちは，Umamusume22です．ロボット工学の知識が業務で必要であるため自主的にロボット工学の勉強に取り組んでいます．大学時代にロボット工学の勉強をやっていなかったので社会人になって勉強しています．(遅い)　
　今日はロボット工学に関して分かりやすく説明している動画や記事を読んでいました．読んだ内容を忘れないために備忘録としてyoutubeのリンクと読んだ記事のurlを下記に貼っておきます．概要も記載しておきます．
 

# 読んだ記事とYoutubeのURL
[1] "【図解】運動学入門：順運動学と逆運動学について解説！"
https://developers.agirobots.com/jp/introduction-to-kinematics/

#### [1]の概要
　運動学と逆運動学の概要から導出方法まで非常に分かりやすく説明されている[1]．ロボットアームの図が沢山載っているため，初学者でも理解しやすい．しかし，三角関数や行列など大学数学までの知識が必要．

 [2] "回転行列の導出"
 https://youtube.com/shorts/NzsLR2LWRBM?si=nJ181o9VL_Y3Id2Q

 #### [2]の概要
 1分で解説しているショート動画．回転行列がどのように導出されているのか図形を用いて説明されている．図形を書いて数式を求めることが出来たら回転行列の公式を暗記する必要がない．

# 最後に
　記事の内容が短くて申し訳ありません．備忘録として読んだ記事のリンクを貼っておきました．[1]の記事で運動学を勉強しました．同時変換行列を用いてロボットの関節角度からエンドエフェクタの位置を求めることが出来ました．次は逆運動学を勉強します．

 ここまで記事を読んでいただきありがとうございました！

 ※ウマ娘の声をフーリエ変換した記事や水栓の開閉判定をLineに通知する記事も書いています．suzuが私です．興味がある方はぜひご覧ください！
https://vigne-cla.com/31-1/#toc5

※noteも始めました．
https://note.com/madoka235/n/nbba2153326e1

ぜひフォローよろしくお願いします!
初めてのwebアプリ個人開発：フレンド機能付き匿名ブログ

「気になった匿名投稿を見つけた。どんな人なのか気になる」

「匿名で意見を吐き出したいけど、もし共感してくれる人がいるなら繋がってみたい」

と思ったことはありますか？

そんなニーズに応えるべく（そして私が使ってみたく）、匿名だけど繋がりを持てるアプリ「匿名フレンド」を作ってみました。

### 匿名フレンド

https://anonymous-friend-diary.com

(2024/1/4追記)
現在、サーバーのコストがかさんでいるため、一時的にアプリを停止しています。申し訳ありません😢

# 開発のきっかけと背景
世の中に出回っているブログサービスやSNSは、実名のものと匿名のものに分かれています。ここで言う実名とは、誰が何を投稿したかがわかるという意味で使っています。

- **実名サービス**: アメブロ、Instagram、Facebook、Xなど
- **匿名サービス**: はてな匿名ダイアリー、5ちゃんねる、ガルちゃんなど

匿名だけど、気になった誰かと繋がれる。そんな場を用意してみたく、アプリを作りました。

## アプリの機能と特徴

匿名で投稿できるブログです。ログインなしでも使えます。\
それ以外に、このアプリの特徴として「フレンド機能」があります。

・投稿に対して「フレンドリクエスト」が行える

・リクエストが送った相手に承認されると、フレンドとなる

・フレンドはお互いがどんな投稿をしているのか閲覧できる

https://anonymous-friend-diary.com

## 技術スタック

・Rails 7
業務でRailsに触れていたこともあり、個人開発でもバックエンドとして使用しました。別のフレームワークも学んでいますが、Railsは描きやすさとコード量の圧縮が素晴らしいです。

・AWS
構成図はこんな感じです。EC2がパブリックサブネットに置かれているのが気になりますが、ローカルからsshでアクセスできるようにしたかった+SGで管理できるから、という理由で配置しています。
インフラはCloudFormationで管理しています。構成やインスタンスタイプを変えたりするのがとても楽です。
Auroraが予想以上に高くて他の手段を検討中...

（追記）
結局この構成は辞めて、Auroraを使わずEC2にDBサーバーを立ち上げる方法を採りました。ついでにEC2のスペックも過剰だったので、現在のアクセス頻度で動く限界まで下げました。
![構成図5.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676792/c68835b5-cd29-81e7-015e-bc057b1eb141.png)

## 学び

初めてのwebアプリ開発ということで、色々学びがありました。

1. 考えることがメチャクチャ多い  
   最初は「Railsで開発して、インフラはAWS使うぞ」くらいの気持ちでと意気込んでいましたが、蓋を開けてみると、環境構築、フロントのデザイン、コストの見積もりなど、「アプリをリリースする」までにかかる手間暇が想像以上でした。
2. モチベーションを保つのが難しい
   アプリのアイデアを思いついた時がモチベーションのピークで、最初は勢いに任せてコードをかきまくっていましたが、時間が経つと「このアプリ、ほんとに使われるのか...？」と疑心暗鬼になったり、実装場でぶつかる課題がいつまでも解決しなかったりと、だんだん開発のモチベーションが下がっていきました。この辺は今後も課題になりそうです。



# 今後の展望

今後は、投稿に対するいいねやコメント機能、フレンド同士のDM機能などを開発予定です。





しかし、自分が作ったサービが世界中どこでも使えるようになるというのは嬉しいですね。初めてドメインを発行してアクセスしたときは感動しました。

気軽に投稿できるので、気持ちを吐き出したいときも適当に呟きたい時もぜひ！

https://anonymous-friend-diary.com
ソートを利用したアルゴリズム問題解決

### アルゴリズムの主要なプロセス

1. **2進数の1の個数を数える**:
   - 与えられた配列 `nums` の各整数について、その数を2進数に変換したときの1の個数を数えます。
   - `cur` 変数を用いて各整数を2進数に変換し、ループを通して1の個数（`cnt`）をカウントします。

2. **優先度キューに追加**:
   - 各整数（`num`）とその数の1の個数（`cnt`）を `Node` オブジェクトとして作成し、優先度キュー `pq` に追加します。
   - `PriorityQueue<Node>` は `Node` オブジェクトの `compareTo` メソッドを使用してソートされます。`compareTo` メソッドは次の基準に従ってノードをソートします：
     - 1の個数（`cnt`）が少ない順に昇順でソート。
     - 1の個数が同じ場合は、整数の値（`val`）が小さい順にソート。

3. **ソート結果を配列として返す**:
   - 優先度キューからノードを一つずつ取り出し、`answer` 配列に格納します。
   - キューが空になるまで繰り返し、ソートされた `Node` オブジェクトの `val` を `answer` 配列に入れます。

### 実行例

#### 入力: `{5, 6, 7, 8, 9}`

1. **各整数の1の個数を計算**:
   - `5`（2進数: `101`）→ `1`の個数: `2`
   - `6`（2進数: `110`）→ `1`の個数: `2`
   - `7`（2進数: `111`）→ `1`の個数: `3`
   - `8`（2進数: `1000`）→ `1`の個数: `1`
   - `9`（2進数: `1001`）→ `1`の個数: `2`

2. **ソート結果**:
   - 1の個数（`cnt`）基準で昇順にソートし、同じ場合は値自体（`val`）基準でソート：
   - `8` (1の個数: `1`)
   - `5` (1の個数: `2`)
   - `6` (1の個数: `2`)
   - `9` (1の個数: `2`)
   - `7` (1の個数: `3`)

   結果の配列は `[8, 5, 6, 9, 7]` です。

### Node クラスの役割

- **Node クラス**: 各整数の値（`val`）と2進数に変換したときの1の個数（`cnt`）を格納します。
- **Comparable インターフェースの実装**: `compareTo` メソッドを通してソート基準を定義します。`cnt` 値を基準にソートし、同じ場合は `val` 値を基準にソートします。

このアルゴリズムは **優先度キュー** と **2進数演算** を利用して、整数配列を特定の条件でソートし、効率的に結果を返す方式です。

``` java
import java.util.*;

public class Solution {
    public int[] solution(int[] nums){
        int[] answer = new int[nums.length];
        PriorityQueue<Node> pq = new PriorityQueue<>();
        for (int num : nums) {
            int cur = num;
            int cnt = 0;
            while (cur > 0) {
                if (cur % 2 == 1) {
                    cnt++;
                }
                cur /= 2;
            }
            pq.add(new Node(num, cnt));
        }
        int idx = 0;
        while(!pq.isEmpty()){
            Node cur = pq.poll();
            answer[idx] = cur.val;
            idx++;
        }

        return answer;
    }

    public static void main(String[] args){
        Solution T = new Solution();
        System.out.println(Arrays.toString(T.solution(new int[]{5, 6, 7, 8, 9})));
        System.out.println(Arrays.toString(T.solution(new int[]{5, 4, 3, 2, 1})));
        System.out.println(Arrays.toString(T.solution(new int[]{12, 5, 7, 23, 45, 21, 17})));
    }
}
class Node implements Comparable<Node>{
    public int val;
    public int cnt;

    Node(int val , int cnt){
        this.val = val;
        this.cnt = cnt;
    }

    @Override
    public int compareTo(Node o) {
        if(this.cnt == o.cnt){
            return this.val - o.val;
        }
        return this.cnt - o.cnt;
    }
}
```
Repository not foundのエラー解決する方法

以下コマンドでもう一度リモートリポジトリをセットし直す。  
```
git remote set-url origin [リポジトリのSSHパス] git remote set-url origin 
```
```
git@github.com:xxx/abc.git  // 例
```

切り替えコマンドとかは以下参照
https://zenn.dev/taichifukumoto/articles/how-to-use-multiple-github-accounts
バイナリ変換した適当な文字列からロゴを作成する

p5.jsを使う。
https://p5js.org/

```javascript
let phrase = "なにか適当な文字列";
  let binaryRepresentation = stringToUTF16Binary(phrase);
  binaryRepresentation += '0000'

function dotGrid() {
  
  let xDist = 10;
  let yDist = 10;

  let xOffset = 50;
  let yOffset = 50;

  let r0 = 1;
  let r1 = 5;

  let phrase = "なにか適当な文字列";
  let binaryRepresentation = stringToUTF16Binary(phrase);

  console.log(`Binary representation of "${phrase}": ${binaryRepresentation}`);

  binaryRepresentation += '0000'

  const colsPerRow = 10;

  background(255);
  fill('black')
  for (let i = 0; i < binaryRepresentation.length; i++) {
    const x = i % colsPerRow * xDist + xOffset;
    const y = Math.floor(i/colsPerRow) * yDist + yOffset;
    const b = binaryRepresentation[i];
    
    circle(x, y, b === '0' ? r0 : r1);
    
  }
  
}

function dotGridAnimated() {
  
  let xDist = 10;
  let yDist = 10;

  let xOffset = 50;
  let yOffset = 350;

  let r0 = 2;
  let r1 = 5;

  const colsPerRow = 10;
  
  fill('white')
  strokeWeight(0)
  rect(xOffset-10, yOffset-10, 200, 200)

  fill('black')
  
  for (let i = 0; i < Math.min((millis()/10) % (binaryRepresentation.length + 100), binaryRepresentation.length); i++) {
    const x = i % colsPerRow * xDist + xOffset;
    const y = Math.floor(i/colsPerRow) * yDist + yOffset;
    const b = binaryRepresentation[i];
    
    circle(x, y, b === '0' ? r0 : r1);
    
  }
  
}

function lines() {
  
  let xDist = 10;
  let yDist = 10;

  let xOffset = 50;
  let yOffset = 200;

  let r0 = 1;
  let r1 = 10;

  let phrase = "なにか適当な文字列";
  let binaryRepresentation = stringToUTF16Binary(phrase);

  console.log(`Binary representation of "${phrase}": ${binaryRepresentation}`);


  const colsPerRow = 10;

  let x = xOffset;
  let y = yOffset;
  let xMax = 180;

  fill('black')
  stroke('black')
  strokeWeight(1);
  
  for (let i = 0; i < binaryRepresentation.length; i++) {
    const b = binaryRepresentation[i];
    const len = b === '0' ? r0 : r1;
    line(x, y, x+len, y);
    x += len + xDist;
    if(x >= xMax){
      x = xOffset;
      y += yDist;
    }
    
    
  }
  
}

function setup() {
  createCanvas(800, 800);
    background(255);
  dotGrid();
  lines();
}

function draw() {
  dotGridAnimated();
}
```
【Next.js】使用しているNext.jsのバージョンを確認する方法 Next.js

コードを書いているときに今使っているNext.jsがどのバージョンなのかを確認するための方法

package.jsonを開き、dependencies > next で確認できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/622183/a8a757f6-4de5-9863-8a00-b724dcd534a9.png)


キャプチャの場合は15.0.3を使用していることをがわかる。

なかなかないシチュエーションだが、
npx create-next-appをした後に「あれ最新版入れたっけ？」となったときに確認したことがあったので備忘まで。

# 宣伝
最近ブログ作ったのでよかった読んでください

https://blog.mochiken.tech/


# 参考

https://stackoverflow.com/questions/69884200/check-on-which-nextjs-version-is-the-project-based
Haskellでラムダ計算：算術編１

Haskellで算術のラムダ計算を行いますが、今回は[Rojas2015 A Tutorial Introduction to the Lambda Calculus](https://personal.utdallas.edu/~gupta/courses/apl/lambda.pdf) を参考にします。

## 自然数の定義 ##
自然数は以下のように定義します。
$\textbf{0}\equiv \lambda s z.s$
$\textbf{1}\equiv \lambda s z.s(z)$
$\textbf{2}\equiv \lambda s z.s(s(z))$
$\textbf{3}\equiv \lambda s z.s(s(s(z)))$

関数$\textbf{3}$を変数$f$と$a$に適用すると、
$$\textbf{3}f a \rightarrow (\lambda s z.s(s(sｚ)))f a\rightarrow f(f(fa))$$

これを見るとプログラミング言語の`FOR i=1 TO 3`を表していて、３回繰り返しの抽象的な形式になっている。我々は自然数を何か物のように考えているが、ラムダ形式や関数型プログラミングの世界では、何らかの操作を$n$回繰り返すという風に抽象化されていて、面白い。
ゼロ回の場合は、$\textbf{0}f a \equiv(\lambda s z.s)fa\rightarrow a$と記述され、これは何もしなかったことになっています。つまり、無（ない）のではなく、操作しなかった（動詞）という意味です。物（名詞）的表現ではなく、操作（動詞）的表現になっている。これはまるで哲学のようです。
インドの哲学で有とか無とか言うけれども、これはむしろ、無為や有為と解釈する方がよいのかもしれません。老子の思想に近いのかもしれないです。３回為すことを老子的に言うと、"為為為"とかなるのでしょうか。

Haskellで書けば、以下の通り：$f a$は値が必要なので、とりあえず、add1 0を入れて評価しました。
```
zero s z = z
one s z = s(z)
two s z = s(s(z))
three s z = s(s(s(z)))
add1 n = n + 1

main = do print $ three add1 0
ghci> mian
3
```

## successor関数S ##
successor関数を定義します。
$$\textbf{S}\equiv\lambda n a b.a(nab)$$

$\textbf{S}$に$\textbf{0}$を適用すると、

$\textbf{S}\textbf{0}
\equiv(\lambda n a b.a(nab))\textbf{0}
\rightarrow\lambda a b.a(\textbf{0}ab)
\rightarrow\lambda a b.a((\lambda sz.z)ab)
\rightarrow\lambda a b.a(b)\equiv\textbf{1}$
$\textbf{S}\textbf{1}
\equiv(\lambda n a b.a(nab))\textbf{1}
\rightarrow\lambda a b.a(\textbf{1}ab)
\rightarrow\lambda a b.a((\lambda sz.s(z))ab)$
$\rightarrow\lambda a b.a(a(b))\equiv\textbf{2}$
$\textbf{S}\textbf{2}
\equiv(\lambda n a b.a(nab))\textbf{2}
\rightarrow\lambda a b.a(\textbf{2}ab)
\rightarrow\lambda a b.a((\lambda sz.s(s(z)))ab)$
$\rightarrow\lambda a b.a(a(a(b)))\equiv\textbf{3}$

```
zero s z = z
one s z = s(z)
two s z = s(s(z))
three s z = s(s(s(z)))

succ' n a b = a (n a b)
add1 n = n + 1

main = do
    print $ succ' zero add1 0
    print $ succ' one add1 0
    print $ succ' two add1 0
ghci> main
1
2
3
```
succは既に定義されているので、succ'と名前を変えました。

## 加算
加算については、例えば$2+3$は以下のように記述できます。

$$2\textbf{S}3\equiv(\lambda s z.s(s(z)))\textbf{S}\textbf{3}\rightarrow\textbf{S}(\textbf{S}\textbf{3})\rightarrow\textbf{S}\textbf{4}\rightarrow\textbf{5}$$

一般に、$m+n$は$m\textbf{S}n$となります。こんな風に加算を定義できるのは面白いですね。

```
main = do
    print $ two succ' three add1 0
ghci> main
5
```

コードは下記のところ：

https://github.com/kawagashira/lambda
システム設計｜スケーラビリティの理解を深める

# はじめに

エンジニアのみなさま、日々の学習本当にお疲れ様です！
また本記事まで足を運んでいただき本当に感謝です。
最後まで読んでもらえると幸いです。

-------------

前回の投稿でシステム設計を学ぶためのオープンソースプロジェクト **「system-design-primer」** を紹介しました。

https://qiita.com/ho_na/items/347060b0dde79750b94a

[システム設計トピックス: まずはここから](https://github.com/donnemartin/system-design-primer/blob/master/README-ja.md#%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A8%AD%E8%A8%88%E3%83%88%E3%83%94%E3%83%83%E3%82%AF%E3%82%B9-%E3%81%BE%E3%81%9A%E3%81%AF%E3%81%93%E3%81%93%E3%81%8B%E3%82%89
)の順番に沿って、システム設計に必要な観点の理解を深めていこうと思います。

第一弾は **スケーラビリティ** についてアウトプットしていきます！

:::note info

system-design-primerで取り上げられているトピックスは以下になります。

垂直スケーリング
水平スケーリング
キャッシング
ロードバランシング
データベースレプリケーション
データベースパーティション

:::


# スケーラビリティとは

システムの負荷の増加に応じて拡張できる能力を指します。

システムの負荷の要因としては、**『ユーザー数』** や **『データ量』** の増加が挙げられます。

システムをリリースした後、設計当初の想定よりもユーザー数や扱うデータ量が増えると負荷がかかり、システムの応答速度などに影響が出てきます。スケーラビリティを考慮することで、システムのパフォーマンスや安定性を維持し、将来的な改修や拡張にかかるコストを抑えることができます。


# 垂直スケーリングと水平スケーリング

![スクリーンショット 2024-11-10 19.49.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/b2a1e427-4a12-6cf4-400e-619d43c1587c.png)


# キャッシング

![スクリーンショット 2024-11-10 17.34.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/a8f39918-4688-84e7-b5ab-807ff1633c76.png)

頻繁にアクセスされるデータを一時的に高速なメモリ（キャッシュ）に保存することで、データベースやアプリケーションサーバーへのアクセスを減らし、システムの応答速度を向上させる方法です。

キャッシュの適用箇所の例で言うと、ECサイトでは **『商品情報や価格表示』** や **『ユーザーのブラウジング履歴』** 、ソーシャルメディアやニュースサイトでは **『トレンド記事や人気投稿』** 、データ分析やレポート生成では **『定期的に実行される分析や集計処理の結果』** などが挙げられます。

# ロードバランシング

![スクリーンショット 2024-11-10 18.56.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744730/1123b135-52b2-1e87-e445-592487d92de9.png)

**ロードバランサー** の仕組みを使います。水平スケーリングで複数のサーバーを用いる際には、ロードバランサーを使用してリクエストの振り分けを行うことで、システム全体の安定性が向上します。ラウンドロビンやIPベースの分散方法が一般的ですが、サーバーの応答状況に応じて動的に負荷分散を行う手法もあります。

# データベースレプリケーション



データベースの内容を複数のサーバーにコピーし、読み取りリクエストを複数のデータベースに分散させることで、読み取りパフォーマンスの向上と冗長性の確保を図る方法です。マスタースレーブ型やマルチマスター型のレプリケーション方式があり、可用性が向上するだけでなく、障害発生時の復旧も迅速になります。ただし、リアルタイム性が求められるアプリケーションでは、レプリケーションの遅延による整合性の問題に注意が必要です。

# データベースパーティション

データを分割して別のテーブルやデータベースに格納することで、データ量が多い場合でも効率的に処理できるようにする手法です。水平パーティション（データの行ごとに分割）や垂直パーティション（特定の列ごとに分割）などの方式があります。パーティションにより、特定のデータへのアクセスや更新が集中した場合でも負荷を分散させられるため、大量データの効率的な処理が可能になります。

# さいごに

スケーラビリティの向上には、上記の手法を組み合わせて用いることが効果的です。例えば、水平スケーリングとロードバランシングを併用することで、大量のリクエストにも迅速に対応でき、キャッシングとデータベースレプリケーションを組み合わせることで、読み取り性能を向上させつつ、データの一貫性も保てます。さらに、データベースパーティションにより、特定のデータに対するアクセスの負荷を分散できるため、柔軟かつ持続可能なシステム設計が可能になります。

と書きましたが、正直まだまだ理解が足りていない部分も多いと思います。
ニュアンスが違ったり、こういう考え方もあるよ！があればぜひコメントで教えていただけると嬉しいです...！
お手柔らかにお願いしますm(_ _)m


# おまけ

弊社のご紹介もさせてください！

### 「日本で一番エンジニアが成長できる会社を創る」

https://prum.jp/

### エンジニアリングの募集

https://www.wantedly.com/projects/1808638

### PM・Webディレクションの募集

https://www.wantedly.com/projects/1355235

### セールス・事業開発の募集

https://www.wantedly.com/projects/1792065

### コーポレート系の募集

https://www.wantedly.com/projects/1752874

### コンサルティングの募集

https://www.wantedly.com/projects/1794481

弊社メンバーは日々学習した内容をアウトプットしております！
少しでもご興味を持たれた方は求人を見てみてください！
ご応募もお待ちしております！

### 最後までご覧いただき、ありがとうございました！
「await」と「waitFor」の違いと「TypeError: Cannot read properties of null (reading 'length')」エラーの解決方法 (Jest、Testing Library)


# はじめに
awaitとawait waitForの違いを理解できておらず、なかなか解決できませんでした。

# 問題
TypeError: Cannot read properties of null (reading 'length')のエラーが発生する。


```shell-session
// エラーメッセージ

TypeError: Cannot read properties of null (reading 'length')

49 | //   console.log("newRecordCount", newRecordCount);
50 |
> 51 |   await expect(recordCount  + 1).toBe(newRecords.length);
         |                                                  ^
52 | });
53 |

at length (src/tests/componenteSample.spec.jsx:51:50)
at call (src/tests/componenteSample.spec.jsx:2:1)
at Generator.tryCatch (src/tests/componenteSample.spec.jsx:2:1)
at Generator._invoke [as next] (src/tests/componenteSample.spec.jsx:2:1)
at asyncGeneratorStep (src/tests/componenteSample.spec.jsx:2:1)
at asyncGeneratorStep (src/tests/componenteSample.spec.jsx:2:1)
```

# 解決方法

```jsx
// エラーのコード

const newRecords = await waitFor(() => {
  const elements = screen.getAllByTestId('record');
  if (elements.length > recordCount) {
    return elements;
  }
  return null;
});

const newRecordCount = newRecords.length;
await expect(recordCount + 1).toBe(newRecords.length);
```

### await
copilotの解説は以下。
> await は、Promise が解決される（resolve または reject される）まで待機する演算子
非同期関数内で使用され、処理を一時停止する

「await expect(recordCount + 1).toBe(newRecordCount);」は、
awaitを付けてもexpectの結果が返るまで待機するという意味にはならない。

- console.logで確認すると、undefinedが返ってきていた
- awaitの場合、undefinedが返ってきたら再計算しない

### await waitFor
copilotの解説は以下。
> waitFor は、特定の条件が満たされるまで繰り返し実行される関数
React Testing Library で使用され、非同期にレンダリングされる要素や状態の変化を待つために使用する
デフォルトの間隔は50msで、デフォルトのタイムアウトは1000ms(copilot)

- expectを同期的に待機するためには、waitFor関数の中でexpectを使用すればよい
- waitFor内でexpectを使用することで、条件が満たされるまで待機できる

Testing Libraryのドキュメントによると、waitForはタイムアウトに達するまで何度でもコールバックを実行する。デフォルトの間隔は50msで、デフォルトのタイムアウトは1000ms。

```jsx
// 成功したコード
await waitFor(() => {
  const newRecords = screen.getAllByTestId('record');
  const newRecordCount = newRecords.length;

  console.log("newRecordCount", newRecordCount);

  expect(recordCount + 1).toBe(newRecordCount);
});
```

# 参考
async function内でPromiseの結果（resolve、reject）が返されるまで待機する（処理を一時停止する）演算子のこと。
https://qiita.com/soarflat/items/1a9613e023200bbebcb3#await%E3%81%A8%E3%81%AF

testing-libraryのドキュメント
https://testing-library.com/docs/dom-testing-library/api-async/#waitfor
Gemfileにgemを記載しても、bundle installで認識されない

## 起きていた事象
- インストールしたいgemをGemfileに記載しても、bundle installでインストールできない

## 原因
- 何らかの操作で、環境変数BUNDLE_GEMFILEが設定されており、特定のディレクトリにあるGemfileしか読み込まない設定になっていた

## 解決策
- bundle configを実行し、環境変数BUNDLE_GEMFILEが設定されているか確認する
- 設定されていたら、unset BUNDLE_GEMFILEで設定を削除する
- source ~/.bashrcで設定を反映させる

## 解決に至った経緯
- Gemfileにgemを記載して、bundle installを実行しても、以下が表示され、インストールできない
```
The Gemfile specifies no dependencies
```
- Bundlerのバージョンや依存関係が原因かと思い、調べたが、特に解決できず
- bundlerについて調べていくうちに、bundle configで設定を確認できることが判明
- 実行すると、特定のディレクトリからGemfileが読み込まれていることを確認
- そのGemfileを削除し、bundle installを再度実行すると、新たなエラーメッセージが出現
```
No such file or directory @ rb_sysopen -　(指定されたパス)
```
- 指定されたパスにGemfileがないのでエラーになっている
- プロジェクトごとのGemfileを使うようにするためにはどうすればいいかを調べると、環境変数が関係していることが判明
- 環境変数の設定を削除する方法を調べ、削除し、再度bundle installを実行すると、無事に解決

## 感想
- 検索しても同じような症状の方が見つからず、解決までにかなり時間がかかってしまった
- 一度諦め、gem installで個別にインストールしていたが、納得できず、再度解決を試みた
- bundle installの仕組みを理解することで、無事に解決することができた
docker-conpose-upでpackage.jsonが見つからないエラー

エラー内容
```docker
ERROR [service 4/6] COPY ./service/package.json ./
failed to solve: failed to compute cache key: failed to calculate checksum of ref d476e395-dc31-41e5-8a72-003e0f005629::om95zmtnkz48duec9643xj82m: "/service/package.json": not found
```

原因

ディレクトリ構造
```docker
project/
├── docker/
│   ├── web/
│   │   └── Dockerfile
│   └── service/
│       └── Dockerfile
├── service/
│   ├── package.json
│   ├── pnpm-lock.yaml
│   └── ...
└── web/
    └── ...
pnpm-workspace.yaml
```

```docker
build:
      context: ./
      dockerfile: web/Dockerfile
```
 context: ./にしていることで、１個上の階層のserviceとwebのpackage.jsonにアクセスできないため見つからないというエラーになった
 contextで指定したビルドコンテキストはdockerfile: web/Dockerfileのパス指定のときに使用するだけでなく、これ以降のスクリプトすべてに影響する。

ビルドコンテキストとは
 Docker がイメージをビルドするときに利用するファイルやディレクトリの範囲
［論文読み］Evaporation and disjoining pressure of ultrathin film on substrate 


# Abstract
- 個体上に乗ったごく薄い液体の乾燥をMDシミュレーションによって解析した。
- 乾燥の特性は、単純なLJ液体の三相共存状態と分離圧に基づいたモデルを比較することで得た。
- MD解析の結果、高エネルギー個体表面に乗った液体薄膜はただの液体薄膜に比べ乾燥速度が小さかった。この原因は薄膜が個体表面のポテンシャルを受けたため。
- 気体の動力学に基づく平均場理論と分離圧の古典的ハマカー理論の比較から、液体厚さが界面領域程度の時、サイズの不一致が見られた。
- この不一致はMD計算によって分離圧を引き出すことで消滅する。
- この事実は液体薄膜の乾燥モデルとして分離圧の積分項が適格に表しているといえる。

# introduction
- 背景説明（いかに世間にあふれているか、いかに社会に対して重要か）
    - 薄い薄膜の乾燥は社会にあふれている。肌の汗が渇くこと、薄膜の蒸発潜熱を利用した冷却デバイスなど
- 現在の理解（今はどんな理論で、どんな問題があるか）
    - 液体薄膜の蒸発はたいてい気体の動力学で説明されるが、それは古典的な熱力学にを用いている。しかし極々薄い薄膜は個体基盤の影響も受ける。これを説明するために分離圧が使える。この分離圧は、古典論をハマカー理論によって拡張した際に生まれたもの。
- 一般的に言われている手法の批評（この方法の弱点）
    - しかしこの理論は薄膜をバルクのスラブと考えるため、その過程から外れるような表面付近の領域には弱い
-先行研究の紹介（主にMD）
    - 実験による検証はほぼない。
    - MDシミュレーションによる研究はいろいろある。理解は進んでいるが平均場理論に立脚している。
- 先行研究ができていないあらたな方法の提示
    - 
- この論文で何をするか
    - この記事では固体基盤上の無極性液体薄膜のMDシミュレーションによる乾燥を解析する。
    - 分子の直径と同等の厚さの駅膜から直接乾燥の性質を解析する。一方で、間接的に分離圧の計算から特性を解析する。
    - 両者を実験と比較することで、液体薄膜のモデル化手法としてどちらが良いか議論する。

# method

# result
- 蒸発速度は液膜が薄くなるほど遅くなった。気体領域に存在する分子の速度分布はMaxwell-boltzman分布に従うことがわかった。
- 原子間相互作用のみから計算したハマカー定数から蒸発速度を求めると、MDシミュレーションの結果と比較して、液膜が薄くなるにしたがって結果を過大評価した。しかし、ハマカー定数をMDの結果で得られる分離圧から算出して用いると、MDと良い一致を示した。

# conclusion
- MDの結果、液体薄膜は個体基盤からの相互作用によって乾燥しずらくなることがわ買った。これは古典的な理想気体の平均場理論からは得られず、MDシミュレーションによって算出された分離圧を考慮することで初めてMDの結果を再現する。

# 気になったこと
- 乾燥現象を考えるには、分離圧を理解する必要がありそう。
- 実験との比較がないので、データの活用の仕方が難しい。⇒実験からの検証あったりする？
- 分離圧を算出する化学使っている化学ポテンシャルはWidom Insertion Methodを使っているらしい⇒
- heltz-knudsenの式は気液界面での平衡乾燥に使えたが、これはより広い現象に使えるということかも
-
Google Cloud認定資格 Professional Cloud Architect試験 合格体験記

# はじめに
実務経験8ヶ月目の私が、Google Cloud認定資格 Professional Cloud Architect試験(PCA)に合格するまでに行った学習内容を記録している記事です。</br>
**学習期間は2週間、40~50時間で合格**しました。</br>
そこで得た個人的な知見を記載しています。
本記事がどなたかの参考になれば幸いです。

- [Google Cloud認定 Professional Cloud Architect試験](https://cloud.google.com/learn/certification/cloud-architect?hl=ja)

## 受験時の私のスペック
- エンジニア歴8ヶ月(Ansible, AWS, Python)
- 保有資格：AWS SAA, LPIC-1
  - それぞれ合格体験記を書いています。 </br>
[AWS SAA合格体験記](https://qiita.com/beagle_masato/items/8b58640526bea826abb2), [LPIC-1 101合格体験記](https://qiita.com/beagle_masato/items/4bc84242c69d5525515e), [LPIC-1 102合格体験記](https://qiita.com/beagle_masato/items/a44a441a1758014d500c)

## なぜ受験するのか
- 現在の現場でIaCツールを使用しており、クラウド方面の知識をつけたかったため
## 学習内容

### 書籍
Google Cloudの全体感を掴むために書籍を使用しました。</br>
使用した書籍は以下のものです。図解が多いため直感的に理解できます。</br>
[図解即戦力 Google Cloudのしくみと技術がこれ1冊でしっかりわかる教科書［改訂2版］](https://www.amazon.co.jp/E5-9B-B3-E8-A7-A3-E5-8D-B3-E6-88-A6-E5-8A-9B-Google-Cloud-E3-81-AE-E3-81-97-E3-81-8F-E3-81-BF-E3-8/dp/429714347X/ref=dp_ob_title_bk)</br>

これを3~4日で読了しました。サーっと読みながら曖昧な部分は適宜**Google Cloud公式サイト**も見ていました。
また、Google Cloudで特徴的なサービスは重点的に読みましたが、**クラウドでほぼ共通のサービス(Google Storage, Google Compute Engineなど)は読み飛ばしました**。

#### Google Cloud公式サイト
やはり公式のサイトは知識を深めるのに役立ちます。</br>
最も使用したサイトは[クラウド間でサービスを比較しているサイト](https://cloud.google.com/docs/get-started/aws-azure-gcp-service-comparison?hl=ja)です。</br>
私はAWSの知識があったため、こちらのサイトで </br>
**「Google Cloudの〇〇ってサービスはAWSの〇〇と同じような内容だな」** </br>
という形で理解をしていました。完全に一致するわけではありませんが、ほぼ同じ概念のサービスが多いので、スッと頭に入ってきやすかったです。</br>


### 問題演習
問題演習は以下の3つの教材を使用しました。
- [ExamTopics](https://www.examtopics.com/)(無料枠のみ 65問)
- [Udemy【最短攻略】Google Cloud 認定 Professional Cloud Architect 模擬問題集](https://www.udemy.com/course/google-cloud-professional-cloud-architect-i/?srsltid=AfmBOopbVaGJdT34x-_Io3Euz4eZFVrhZ5jPvWMEF6X66rJEm-SNAST2&couponCode=KEEPLEARNING)(170問)
- [Google Cloud公式模擬試験](https://cloud.google.com/learn/certification/cloud-architect?hl=ja)(20問)

</br>
約10日でそれぞれの問題集を3周ずつ解き、すべて100％答えられるような状態にしました。</br>
正直なところ、これらの問題集と同じ問題が本番で7割程度で出題されるレベルなので、これらの問題集の答えさえ覚えていれば合格できるような気さえしています、、、笑


## 本番の問題の感覚
上でも示したように、あれらの問題集をやっていれば十分受かってしまうような難易度でした。</br>
もちろん、問題集にはなかったような問題も出題されるのですが、問題集の応用といったような感じで、理解していれば十分解けるような問題でした。</br>
私個人の話をすると、試験は40分で終了し、点数は分かりませんが、体感85~90%合っていると思います。</br>

## 合格を目指すにあたってのTips
合格だけ目指すならとにかく全体感をサッと掴んで、問題演習に進んだ方が吉かなと思いました。</br>
問題演習においては、答えの丸暗記だけだと合格できるか不安なので、書籍や公式サイトを見るなどしてしっかり理解しましょう。

## 最後に
本記事をお読みいただきありがとうございました。</br>
資格取得をきっかけにGoogle Cloudを業務で活用していき、さらなる理解を進めていきたいと思います。</br>
この記事がどなたかの参考になれば幸いです。