OmniAICreator/Qiita-1.07M huggingface dataset:
[Excel VBA] 最下行の行番号を取得する (フィルタ解除不要版)

### ざっくり説明
データが入力されている最下行の行番号を返してくれます。

列を指定することもできますし、
シート全体の中での最下行を求めることもできます。
<font color="red">→ 差別化ポイント①</font>
フィルタ解除なしに最下行を求めることができます。
<font color="red">→ 差別化ポイント②</font>

### コード
```vb:最下行の行番号を取得する(フィルタ解除不要版)
Function GetLastRowNumber(ByVal WS As Worksheet, Optional ByVal colNumber As Long = 0) As Long
'================================
'用途　　：最下行 行番号の取得
'--------------------------------
'第一引数：Worksheetオブジェクト (Worksheet型)
'第二引数：対象列番号 (Long型)
'戻り値　：最下行 行番号 (Long型)
'特記事項：第ニ引数の省略でWS全体の最下行を返す
'================================
    Dim usedrangeArr As Variant
    usedrangeArr = WS.UsedRange

    Dim tentativeLastRowNumber As Long
    Dim tentativeLastColumnNumber As Long
    tentativeLastRowNumber = WS.UsedRange.Row + WS.UsedRange.Rows.Count - 1
    tentativeLastColumnNumber = WS.UsedRange.Column + WS.UsedRange.Columns.Count - 1

    Dim lastRowNumber As Long: lastRowNumber = 0
    If colNumber <> 0 Then
        lastRowNumber = GetSpecificLastRowNumber(WS, colNumber, tentativeLastRowNumber)
    Else
        Dim tmpLastRowNumber As Long
        Dim i As Long
        For i = 1 To tentativeLastColumnNumber
            tmpLastRowNumber = GetSpecificLastRowNumber(WS, i, tentativeLastRowNumber)
            If tmpLastRowNumber > lastRowNumber Then
                lastRowNumber = tmpLastRowNumber
            End If
        Next
    End If

    GetLastRowNumber = lastRowNumber
End Function

Function GetSpecificLastRowNumber(ByVal WS As Worksheet, ByVal colNumber As Long, ByVal tentativeLastRowNumber As Long) As Long
    Dim rowValues_arr As Variant
    rowValues_arr = WS.Columns(colNumber)

    Dim lastRowNumber As Long
    Dim i As Long
    For i = tentativeLastRowNumber To 1 Step -1
        If Not IsEmpty(rowValues_arr(i, 1)) Then
            lastRowNumber = i
            Exit For
        End If
    Next

    GetSpecificLastRowNumber = lastRowNumber
End Function
```

### 使用方法
1つ目のGetLastRowNumber関数の、
第一引数にWorksheetオブジェクトを指定し、
第二引数(任意)に列番号を渡します。

第二引数が入力されている場合は その列番号での最下行の行番号を返し、
第二引数が未入力(もしくは0)の場合は そのシート内での最下行の行番号を返します。

※2つのFunctionがセットです。が、ユーザが直接使うのは`GetLastRowNumber()`のみです。

### 仕様等
- 1行目から最下行の間に空白セルがあっても最下行の行番号を求められます

- **第二引数で何も入力されていない列の列番号を指定した場合、**
**最下行の行番号は 0 が返ってきます！**

後者ですが、"既に入力されているセルの1つ下のセルに新たに内容を追加する"
という運用を想定しているためこのような仕様になっています。

### 注意点
引数なしでの処理はUsedRangeの範囲を走査してるからそれなりに重いカモ🦆
検証は別途記事書こうかな

### その他
フィルタ解除してもいいなら下記のマクロのほうがオススメ

https://qiita.com/ivkamisz/items/25f4d777255cefa4f475



2024/8/23追記
検証しようかなって言いましたが
フィルタ解除必要な方の処理が早すぎて比較とかできませんでした

フィルタ解除**必要**版：300列2000行での最下行取得10セット 0.01秒以下
フィルタ解除**不要**版：300列2000行での最下行取得10セット 0.08秒
HTMLの`<section>`タグと`<article>`タグの使い分け

HTMLには、コンテンツの意味を明確にするため、様々なタグがあります。その中でも、`<section>`タグと`<article>`タグは、コンテンツのセクションを表現するために頻繁に使用されます。しかし、それぞれの使い方に違いがあります。

## `<section>`タグ
`<section>`タグは、文書の中でテーマごとにコンテンツをまとめるために使います。例えば、ニュースサイトでは、政治、スポーツ、エンタメといったカテゴリごとに利用します。`<section>`タグは、その内容があるテーマに関連していることを示すために使います。

```html
<section>
  <h2>政治</h2>
  <p>政治に関する記事がここに入ります。</p>
</section>
```

## `<article>`タグ
一方、`<article>`タグは、独立したコンテンツを示すために使います。このタグの内容は、他の場所でもそのまま使えるような、自己完結した情報を表します。ブログの記事、ニュース記事、製品レビューなどに使われます。

```html
<article>
  <h1>新しいJavaScriptフレームワークの紹介</h1>
  <p>このフレームワークは...</p>
</article>
```

## 使い分けのポイント
- **`<section>`タグ**: 関連する複数のコンテンツをグループ化したいときに使います。
- **`<article>`タグ**: 独立したコンテンツや、文脈に依存しない内容に使います。

この使い分けを理解することで、よりわかりやすいHTMLを記述できるようになります。特に、SEOやアクセシビリティの観点からも重要なポイントなので、ぜひ意識して使い分けてみてください！
【独り言】人は自分のキャラクターのせいでやらない努力をしない言い訳をつくる

ただの独り言。
最近プログラミングをしていて感じた気をつけないといけない部分。

### 人は自分のキャラクターのせいで努力しない言い訳を作ってしまう
「自分は賢くないから」「自分は体が弱いから」「自分は子供がいるから」「自分は忙しいから」そういった理由でやらない言い訳を作ることで努力を諦めてしまう。

自分の場合は、プログラミングをしている時に「自分はプログラミングのセンスがないから」「自分は頭が悪いから」「自分は高卒だから」と言い訳をして複雑な難しいことを考えようとするのをやめてしまっている自分がいることに気づいた。
とにかく行動をすることで自分は今まで結果を出してきた過去があるから、がむしゃらに行動することこそが結果を出すには最も重要だと信じてきた。だから複雑なことやわからないことが多い事象を考える時に頭のキャパがいっぱいになったら「やっぱり自分はプログラミングのセンスがないから」と努力しない言い訳を作ってしまうことがあった。

大事なのは、ただ結果を出すことだけ考えること。またもしマイナスなことを考えてしまっていることに気がついたら「結果を出すことが大事。脳死で行動するのではなく仮説を立ててから行動しよう」と頭の中で唱えて切り替えをする。すぐにはできないかもしれないけど、繰り返し練習をしてマインドを変えていく。
AtCoder 勉強記録[C++] その54

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## C - Matrix Reducing
[C - Matrix Reducing](https://atcoder.jp/contests/abc264/tasks/abc264_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vec = vector<int>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define mod 998244353

int main() {
  ll h1, w1;
  cin >> h1 >> w1;
  vector<vector<int>> a(h1, vector<int>(w1));
  rep(i, h1) rep(j, w1) cin >> a[i][j];
  ll h2, w2;
  cin >> h2 >> w2;
  vector<vector<int>> b(h2, vector<int>(w2));
  rep(i, h2) rep(j, w2) cin >> b[i][j];
  for(int hbit = 0; hbit < (1<<h1); hbit++){
    for(int wbit = 0; wbit < (1<<w1); wbit++){
      vector<int> vh, vw;
      for(int i = 0; i < h1; i++) {
        if(hbit&(1<<i)) vh.push_back(i);
      }
      for(int i = 0; i < w1; i++){
        if(wbit&(1<<i)) vw.push_back(i);
      }
      if(vh.size()!=h2 || vw.size()!=w2) continue;
      bool ok = true;
      for(int i = 0; i < h2; i++){
        for(int j = 0; j < w2; j++){
          if(a[vh[i]][vw[j]] != b[i][j]) ok = false;
        }
      }
      if(ok) {
        cout << "Yes" << endl;
        exit(0);
      }
    }
  }
  cout << "No" << endl;
}
```
### 解法
bit全探索を用いて`A`から削除する行と列を全探索し、行と列を削除して`A`の残った配列と`B`が等しいかを判定することで結果が求まる。
## B - Postal Card
[B - Postal Card](https://atcoder.jp/contests/abc287/tasks/abc287_b)
解法
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ull = unsigned long long;
using vec = vector<int>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define mod 998244353

int main() {
  ll n, m;
  cin >> n >> m;
  vector<string> s(n);
  rep(i, n) cin >> s[i];
  vector<string> t(m);
  rep(i, m) cin >> t[i];
  vector<bool> jud(n, false);
  ll res = 0;
  for(int i = 0; i < n; i++){
    for(int j = 0; j < m; j++){
      bool ok = true;
      for(int k = 0; k < 3; k++){
        if(s[i][k+3] != t[j][k]) ok = false;
      }
      if(ok && !jud[i]) {
        jud[i] = true;
        res++;
      }
    }
  }
  cout << res << endl;
}
```
### 解法
すべての`S`が使用済みかどうかを判別する配列を用意しておく。その後、`S`の末尾3文字と、`T`が一致するかどうか全探索を行い、一致した場合に該当する`S`を使用済みにする。
Railsのparamsとは

# paramsとは
paramsとは**リクエスト**が発生した際にroutes、Controllerに渡されるパラメータ。

`params[:id]`などで、Viewからroutesを通り、Controller側に渡される。
なお、`config/routes.rb`では、このように書かれている。
```
get 'users/:id/articles', to: 'articles#show', as: 'user_articles'
```
これの`:id`がそう。
Controllerには`params[:id]`と書いてidを取得できる。

# リクエストとは
リクエストはクライアント側がサーバー側に何かこれがほしいと要求をしサーバー側がそれに対してレスポンスをするときに発生しているあれ。

レスポンスをするということはクライアントが**何のリソースが欲しいか**を特定する必要がある。
なので、クライアント側が特定をするための最低限の情報を渡さなければならない。

最低限の情報とは、例えばデータベースで言うとidだったり、user_idだったり。

idさえあれば、データベースからリソースを探してクライアントにレスポンスできるので、パラメータが必要。

# リクエストとはどういうときに発生しているのか？
1. フォームを送信するとき
1. リンクをクリックしたとき
1. URLを直接ブラウザに入力したとき
1. リダイレクトしたとき

### フォームを送信するとき
フォームはView側で`edit`や`new`画面などに作るであろう`form_with`メソッドを使用したときに作られるもの。
なお、Controllerに渡す際は`update`、`create`、`delete`などのアクションを使うときに`form_wit`hでリソースの値を入れてデータ更新、作成、削除をする。

例：
```
<% = form_with(model: user, url user_path, local, true, method: :post) do | form | %>
```

HTTPメソッドは`PATCH`、`PUT`、`DELETE`、`POST`がある。

### リンクをクリックしたとき
リンクなのでページを遷移するなどのイベントが発生する。
なお、ページ遷移先は`hoge_path(hoge.id)`で、この`hoge.id`がパラメータ。

例：
```
= link_to('クリックしてね', hoge_path(hoge.id), method: :patch, data { cnfirm: 'クリックしたよ' })
```

### URLを直接ブラウザに入力したとき
ページを直接開く際も`edit`や`new`、`show`、`delete`など、特定のリソースを取得する際にどのリソースを取ってくるか情報が必要になるため、パラメータを使ってサーバー側（Controller→Model）にレスポンスを要求しなければならない。

例：
```
https://qiita.com/drafts/exampleidhogefuga111/edit
```
この`exampleidhogefuga111`がそう。
これで`app/controller/drafts_controller`に`exampleidhogefuga111`を渡して、Controllerで`params[:id]`と書くと、paramsに`exampleidhogefuga111`が入っている。
Controllerでは
```
def edit
  article = Article.find(`exampleidhogefuga111`)
  
  コードが続く
end
```
などでリソースをとってきているだろう。

### リダイレクトをしたとき
```
= redirect_to user_path(@user, foo: 'bar', baz: 'qux'), notice: 'ユーザーだよ'
```

# routesでのパラメータ
`routes`でのルートの定義の方法は２種類
`resources`を使うときと、直接URLを書くとき

`resources`を使うときはこう書く
```
resources :users, only: %i[new create show] do
  resources :user_images, only: :index
end
```
このとき、例えば、ページを開くときにリソースが必要だなっていうときはshowのとき
URLはこうなる

```
GET 'users/:id/user_images' to: 'users/user_images#show' as users_user_images_show_path
```

これの`:id`がそうで、リクエストが発生した際にはここを通って、Controller側に`params[:id]`が渡される。
ところで本物のAIはいつになったらできるのですか？

最近巷に雨後の筍のごとく湧き出てきているAIを僭称するワードサラダではなく、本物のAIはいつになったらできるのですか？

本物のAIのみわけかた？

そんなもん「リーマン予想解いて」って聞くだけだ。
もしくは「なんか10億円稼いできて」でもいいぞ。
後者はAIじゃなくてもいいから私で試してくれ。
WARNING: The Python tkinter extension was not compiled and GUI subsystem has been detected. Missing the Tk toolkit?の対処法

# 事の起こり

pyenvで最新版のPython(Python 3.12.1)をインストールしようとした時に以下の警告が表示されました。

**WARNING: The Python tkinter extension was not compiled and GUI subsystem has been detected. Missing the Tk toolkit?**

# 対処法
Homebrewでpython-tkをインストールします。

```bash
brew install python-tk
```

再度pyenvでPython 3.12.1をインストールします。今度は成功しました。

```bash
$ pyenv install 3.12.1
python-build: use openssl@3 from homebrew
python-build: use readline from homebrew
Downloading Python-3.12.1.tar.xz...
-> https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tar.xz
Installing Python-3.12.1...
python-build: use tcl-tk from homebrew
python-build: use readline from homebrew
python-build: use ncurses from homebrew
python-build: use zlib from xcode sdk
Installed Python-3.12.1 to /Users/yuhkiyano/.anyenv/envs/pyenv/versions/3.12.1
```

# Reference
https://a1026302.hatenablog.com/entry/2023/10/15/130454
【UiPath】読み取り専用ファイルを削除する小技

実はUiPathで読み取り専用ファイルを削除する場合、Deleteアクティビティだけでは削除できない。これは、.NETが読み取り専用ファイルを削除できない仕様になっているからである。

試しに、読み取り専用ファイルをDeleteアクティビティのみで削除してみる

# １．読み取り専用ファイルの準備
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/5180eda6-6e67-5a08-454d-0e7671123dc0.png)

# ２．読み取り専用ファイルを削除するアクティビティを準備
以下の通り、DeleteFileアクティビティで１．で準備したファイルを削除してみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/b435e346-9024-b3a8-1002-13c8b7c1b493.png)

# ３．エラー発生
このように、通常、右クリック＞削除できるファイルでもUiPathでは、エラーではじかれてしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/b0943e79-c88a-d041-02dc-4895c618d5a2.png)

# ４．回避策
Invoke Codeを用いて、以下のコードを入力する。
```
File.SetAttributes(“ファイルフルパス”, FileAttributes.Normal)
```
`File.SetAttributes("ファイルフルパス", FileAttributes.Normal)`は、指定されたファイルの属性を設定するためのコード。
具体的には、このコードの意味は以下の通り

- `File.SetAttributes`:
  - `System.IO.File`クラスの静的メソッドで、ファイルの属性を設定する

- `"delete-me.txt"`:
  - 属性を設定する対象のファイル名です。この場合、カレントディレクトリにある「delete-me.txt」ファイルの属性が設定される

- `FileAttributes.Normal`:
  - ファイルの属性を`Normal`（通常）に設定します。この属性は、ファイルが特別な属性（読み取り専用、隠しファイル、システムファイルなど）を持たないことを意味する
##### 簡単にまとめると:
このコードは、"delete-me.txt"というファイルの属性を通常の状態（特別な属性が付いていない状態）にリセットする。たとえば、ファイルが以前に「読み取り専用」や「隠しファイル」などの属性を持っていた場合、このコードを実行することで、それらの属性が解除される。

# ５．改善後の処理結果
一度、削除対象のファイルを通常に戻して、削除したことで処理は正常に終了した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/bd1900af-421c-db1b-1a52-94271f1d8e01.png)

##### 処理結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/9f53b0c1-d1fd-81a3-7e0c-a086d875744b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/d17933e7-2900-67b1-60ac-53c99cf3ac47.png)

# ６．まとめ
今回の事象は読み取り専用ファイルでも削除はできるだろうという思い込みから、発生したバグだが、こういったことは要件定義の段階から懸念するべきなので、些細な事でも実際に動かしてから回答するように心がけようと思った。
【Linux】コマンドでアーカイブを作成・展開する方法

## アーカイブの作成
```:ターミナル
$  tar cvf アーカイブ名 対象ファイル1 対象ファイル2　...
```
```:ターミナル
$ tar cvf sample.tar test_1.txt test_2.txt
```

## アーカイブの展開
```:ターミナル
$  tar xvf アーカイブ名 対象ファイル1 対象ファイル2　...
```

```:ターミナル
$ tar xvf sample.tar
```
伸びる背景、linear-gradientまとめ

お疲れ様です。

かなり前に、伸びる背景の記事を投稿いたしましたが、結果が分かりづらかったかと思いますので、改めてcodepenさんにてどんな感じの動きになるのかを再投稿のような形でご案内できたらと思います:relaxed:

また、グラデーションの内容ついでで、cssの linear-gradient と radial-gradient を使ったグラデーションについても勉強しましたので、一緒に載せておきます。

<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="RwzMXJO" data-pen-title="Untitled" data-user="mtzkmy" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/mtzkmy/pen/RwzMXJO">
  Untitled</a> by mtzkmy (<a href="https://codepen.io/mtzkmy">@mtzkmy</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

「伸び～る背景」のコードだけ投稿前に順番を入れ替えたので、cssのコードは順番がhtmlとは違っており、見づらくなってしまい申し訳ありません:cold_sweat:
それと不要なコードも消し忘れております…

cssで linear-gradient を使ってのグラデーションは簡単にできてびっくりでした！
カラーコードさえ調べれば、好きなようにグラデーションできますし、
%を使えば、**「#〇〇〇の部分は少なめor多めにしたい」**ができます。

角度によって方向の指定もできますので、今回は90deg（左から右にグラデーションする）にしていますが、ここの角度の部分を to bottom right とすると、角度は45度指定になりますが、右下へ向かってグラデーションしていくといったこともできるようです。
左右だけではなく、 top とすると上から下への方向も可能です。

円形にグラデーションする radial-gradient についてですが、ご覧の通りではありますが**fff 20%の部分が中心から見て20%の範囲**の色指定で、**ff66cc 70%が、外側**の色指定になっています:art:

最後の縞模様についてですが、%を使って色の範囲を指定していきますが、コードの通り、次の色と色の間をなくしてぴったりと範囲指定しておかないと色と色の間でグラデーションになってしまい、縞模様になりませんでしたのでご注意を:sweat_smile:（経験済）
ChatGPTで英語学習①

# この記事で分かること
- ChatGPTを使った画像付きオリジナル英単語帳の作成方法
    →作成した単語帳は[YouTubeチャンネル](http://www.youtube.com/@eiai_eng_x_AI)で確認できます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3865261/2263290b-c99f-249e-7eca-7d5434138ca0.png)

# はじめに
いま話題のChatGPTを使って英語学習に役立つツールを作り、ここで紹介していきます。今回は英単語学習編としてTOEIC600点以上を目指す方を主なターゲットにオリジナルの英単語帳の作成を行います！

# 目的
これまで英単語帳を勉強してきて、覚えづらいな、つまらないな、と思ったことはありませんか？？私は英単語の覚えづらさの原因は英単語を見てもイメージが頭の中でわかないことだと思っています。そこで画像も作れるChatGPTの特長を最大限活かし、「マンガで覚える英単語帳」の作成を目指します！

# 目次
1. 英単語のリストアップ
1. 英単語の例文作成
1. 例文にあった画像の作成

# 1. 英単語のリストアップ
まずTOEIC600点を目指すのに必要な英単語をChatGPTに聞いてみます。プロンプトは以下のとおりです。

```python:プロンプト
TOEICで600点以上をめざすのに必要な動詞を10個リストアップして
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3865261/77119bc7-3858-6b48-23cf-f7562be0649b.png)


- 今回は例として　10語出力して、と指定しましたが、ChatGPTは数字を正確に守ってくれるわけではなく、あくまで目安になるだけです。今回は500語の単語帳にすることとしたので、何度か同じプロンプトを実行しています

- [英単語のサイト](https://ejje.weblio.jp/)で出力された単語のレベルを調べたところ、　%は当該サイトでもTOEIC600点以上のレベルだと紹介されていました


# 2. 英単語の例文作成
続いて英単語に沿った例文を生成してもらいます。このとき例文に出てくる単語が難しくなりすぎないようにCEFRレベルもプロンプトに含めます。CEFRについてはこちら

プロンプトは以下のとおりです。

```python: プロンプト
requreを述語とする英単語帳にありそうな例文を作ってください。ただし使用するほかの単語のCEFRレベルはB1までとしてください
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3865261/6cf09670-85ca-6bd2-3f7f-39f6bc4980bf.png)

いかがでしょうか？？単語帳で見たことのあるような長さ、内容の例文になっているかと思います。

# 3. 例文にあった画像の作成
さて、いよいよ例文に沿った画像を作成してもらいましょう！今回は先ほどのrequireの例文に対して画像を作成してみます。

生成した画像はこちら
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3865261/f5ee6dfb-fe14-5857-1baa-68776cb631f1.png)

- 例文 : The job requires a good understanding of basic computer skills.

いかがでしょうか？？イメージしにくい単語もこのように例文と画像とともにみてみると覚えやすく感じるのではないでしょうか？？

# さいごに
ここまでオリジナルの単語帳の作成を目指して、ChatGPTを用いた単語のリストアップ、例文の作成、画像の作成を行ってきました。このようにして作成した単語帳を[YouTube](https://www.youtube.com/@eiai_eng_x_AI)上でアップしています。音声生成AIを用いた例文・単語の読み上げ付きになっているので、ぜひご覧ください！！

さいごまで読んでいただき、ありがとうございました。このアカウントでは、AIを用いた学習の効率化やプログラミングに関するtipsなどを紹介していきます。またYouTubeなど他のアプリともどんどん連携していくのでそちらもチェックしていただけるとうれしいです！！
How Much Does Generative AI Really Cost? A Comprehensive Breakdown

The cost of implementing generative AI can vary widely depending on several factors, including the complexity of the project, the type of AI model being used, the required data, the development process, and the ongoing maintenance and support.


Here’s a breakdown of potential costs:


Development Costs:


Custom AI Development: Building a generative AI model from scratch can be expensive, ranging from $50,000 to over $500,000, depending on the project's complexity, the expertise required, and the amount of data needed.


Pre-trained Models: Using pre-trained models or AI services offered by companies like OpenAI, Google, or AWS can reduce costs. Licensing fees for these services can range from a few thousand dollars to tens of thousands per month, depending on usage.


Infrastructure Costs:


Computational Resources: Generative AI models, especially large ones, require significant computational power, which can drive up costs. Cloud-based solutions (e.g., AWS, Azure) can charge anywhere from $100 to thousands of dollars per month based on the usage of GPUs and storage.


On-Premise Infrastructure: If you choose to build an on-premise solution, the initial setup cost for servers, GPUs, and other hardware can run into hundreds of thousands of dollars.


Data Acquisition and Management:


Data Collection: Gathering and preparing the data needed to train a generative AI model can be costly, especially if you require large, high-quality datasets. Costs can vary from a few thousand to several hundred thousand dollars depending on the data's complexity and quantity.


Data Storage: Storing large datasets can also incur significant costs, especially if you are using cloud storage solutions.


Ongoing Maintenance and Support:


Model Updates: AI models require regular updates and fine-tuning to stay effective, especially in dynamic environments. This can involve additional costs for ongoing development and data management.
Technical Support: Hiring a team to manage and maintain the AI system or outsourcing this function to a service provider can add to the overall cost. Support contracts can range from $10,000 to $100,000+ annually.


Licensing and Subscriptions:


Software Licenses: Depending on the tools and platforms used, there may be licensing fees for software, frameworks, or APIs, which could add a few thousand dollars to the budget.


Subscription Services: Ongoing access to AI tools, platforms, or datasets might require subscription fees that range from a few hundred to several thousand dollars per month.


In summary, the cost of implementing <a href="https://www.intellectyx.com/generative-ai-development-services/">generative AI development services</a> can range from tens of thousands to millions of dollars, depending on your specific needs and goals. For smaller projects or companies, leveraging pre-built models and cloud-based solutions can significantly reduce costs, while large enterprises with complex needs may invest heavily in custom development and infrastructure.
GGUF 変換メモ

Python の Transformers ライブラリで使用される safetensors 形式から、llama.cpp で使用される GGUF 形式への変換と量子化についてのメモです。

# clone

Hugging Face にある git リポジトリから clone すると、変換には使わないファイルも含まれます。ダウンロードサイズが巨大になって、帯域やディスクを圧迫します。

必要なファイルだけ取得するには、ダウンロードをライブラリに任せるのが簡単です。

モデルのページに Python のサンプルが載っていれば、`from_pretrained` まで実行すれば良いです。

例として次のモデルを使用します。

https://huggingface.co/HODACHI/Borea-Phi-3.5-mini-Instruct-Coding

サンプルの当該箇所を抜粋します。

```py:抜粋
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline

model = AutoModelForCausalLM.from_pretrained(
    "HODACHI/Borea-Phi-3.5-mini-Instruct-Coding", 
    #device_map="cuda", 
    torch_dtype="auto", 
    trust_remote_code=True, 
)
tokenizer = AutoTokenizer.from_pretrained("HODACHI/Borea-Phi-3.5-mini-Instruct-Coding")
```

:::note warn
* `model` と `tokenizer` で別々にダウンロードが行われます。片方だけでは完全に動作するファイル一式が得られません。
* ダウンロードだけで、推論は行わないため、CUDA の設定はコメントアウトしています。
:::

デフォルトのダウンロード先はホームディレクトリの .cache/huggingface/hub/ 以下になります。環境変数 `HUGGINGFACE_HUB_CACHE` により変更できます。

```text:例 (Windows)
set HUGGINGFACE_HUB_CACHE=D:\llm\.cache
```

# 変換

最終的に Q4_K_M などで量子化する場合、変換は 2 段階で行います。

1. BFloat16 の GGUF に変換
2. 量子化

それぞれ llama.cpp に含まれるツールを使用します。

https://github.com/ggerganov/llama.cpp

1. convert_hf_to_gguf.py  
   * `pip install -r requirements.txt` で Python のライブラリをインストール
   * llama.cpp のバイナリに依存しないため、ビルド不要
2. llama-quantize
   * 要ビルド

:::note warn
convert_hf_to_gguf.py は Q8_0 への変換をサポートしています。しかし Q4_K_M などが目的であれば、2 段階の量子化による劣化を避けるため、まずは BFloat16 にしておくのが無難です。
:::

それぞれのツールの使い方は、引数なしで実行すれば確認できます。例を示します。

```sh:変換例
python convert_hf_to_gguf.py --outfile foo-bf16.gguf --outtype bf16 foo-dir
./llama-quantize foo-bf16.gguf foo-Q4_K_M.gguf Q4_K_M
```
```mermaid
graph LR
    A[foo-dir] -->|convert_hf_to_gguf.py| B[foo-bf16.gguf] -->|llama-quantize| C[foo-Q4_K_M.gguf]
```

量子化形式の選択については、以下の記事が参考になります。

https://sc-bakushu.hatenablog.com/entry/2024/02/26/062547

# fbgemm.dll

Windows で torch-2.4.0 が fbgemm.dll でエラーになる問題が発生します。私の環境では VC_redist.X64 をインストールして、バージョンを 2.3.1 に下げることで動作しました。

原因が 2 種類（libomp140 と VC_redist）あるため、情報がやや錯綜しています。

2.4.0 が必要な場合、libomp140.x86_64.dll を手動で追加すれば回避できます。

https://note.com/mayu_hiraizumi/n/n3db157e3c801

2.3.1 は、VC_redist.X64 のインストールで解決すると思われます。

https://knowledge-oasis.net/fix/fix-winerror-126/

次の記事では 2.1.2 まで下げていますが、VC_redist.X64 をインストールすれば、そこまで下げなくても良さそうです。

https://qiita.com/UKI_datascience/items/2626dba5bba8f51fcb85

# Ollama

Ollama だけでも変換ができるようです。

https://note.com/lucas_san/n/n02a3365ccc7c
【UiPath】ワイルドカードを使用したファイルの存在確認・ファイルパス取得・ファイルコピー

## はじめに
UiPathで、ワイルドカードを使用して単一のファイルの存在確認・ファイルパス取得・ファイル名取得・ファイルコピーを行う方法を紹介します。

UiPathの「ファイルの存在を確認」アクティビティや「ファイルをコピー」アクティビティはワイルドカードには対応していないため、その代替として使用することができます。

::: note warn
本記事の方法は、フォルダ内に単一の対象ファイルがあることを想定しています。

フォルダ内に複数の対象ファイルがある場合は、最初のファイルのみ検知し、その他のファイルは検知できません。

例）フォルダ内の「file*.xlsx」を検知する場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/d3dfa0e7-4bea-293d-123c-f7796efbc19c.png)

フォルダ内の複数の対象ファイルを検知する場合は「繰り返し（フォルダー内の各ファイル）」アクティビティを使用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/c27cdd6d-2390-bd53-bf20-7d8e554915be.png)
:::
## ワイルドカードを使用したファイルの存在確認
```vb
'// 構文１
'Dir("ワイルドカードを含むファイルパス") <> ""
Dir("C:\work\file*.txt") <> ""

'// 構文２
'Directory.GetFiles("フォルダパス","ワイルドカードを含むファイル名").Length > 0
Directory.GetFiles("C:\work","file*.txt").Length > 0
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/8dffd65e-ada1-8c16-6a1b-d8a69d94d6cb.png)

## ワイルドカードを含むファイルパスから実際のファイルパス取得
「フォルダパス」と「ワイルドカードを含むファイル名」を次の構文に渡します。
```vb
'Directory.GetFiles("フォルダパス","ワイルドカードを含むファイル名")(0)
Directory.GetFiles("C:\work","file*.txt")(0)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/56f991e1-53aa-291c-f2ae-259e6207fa6e.png)

## ワイルドカードを含むファイルパスから実際のファイル名取得
```vb
'Dir("ワイルドカードを含むファイルパス")
Dir("C:\work\file*.txt")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/266c2426-ae62-29a1-dffa-b050c336593d.png)


## ワイルドカードを使用したファイルコピー
応用例として、ワイルドカードを使用したファイルコピーの方法を紹介します。汎用的に使用できるよう、引数を使用するワークフローの形式にしています。

#### 引数
以下のString型の引数を用意します。
strRawFileName：ファイル名（ワイルドカードにも対応）
strSourceDirPath：コピー元フォルダパス
strTargetDirPath：コピー先フォルダパス

#### 変数
以下のString型の変数を用意します。
strFileName：実際のファイル名
strSourceFilePath：コピー元ファイルパス
strTargetFilePath：コピー先ファイルパス

#### ワークフロー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2650961/462044ce-6c50-a48e-5c40-bdbc447a8557.png)


```vb
'参考）VBAのコードで書くと以下のようなイメージになります。
Sub CopyFile_with_wildcard(ByVal strRawFileName As String, _
                           ByVal strSourceDirPath As String, _
                           ByVal strTargetDirPath As String)
    
    Dim strFileName As String
    Dim strSourceFilePath As String
    Dim strTargetFilePath As String
    
    If Dir(strSourceDirPath & "\" & strRawFileName) <> "" Then
    
        strFileName = Dir(strSourceDirPath & "\" & strRawFileName)
        strSourceFilePath = strSourceDirPath & "\" & strFileName
        strTargetFilePath = strTargetDirPath & "\" & strFileName
        
        FileCopy strSourceFilePath, strTargetFilePath
    
    Else
        'ファイルが存在しない場合の処理
        
    End If
    
End Sub
```

## おわりに
業務でファイル名の末尾のみ変更になった単一のファイルを操作することが多いため、本記事の処理は重宝しています。

皆さんの業務のお役に立てると幸いです。
Javaで「LITERALフラグ(パターンの中のメタ文字が特別な意味を持たなくなる)」の動作を確認してみた

# 概要

Javaで「LITERALフラグ(パターンの中のメタ文字が特別な意味を持たなくなる)」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/start/regex/index23.html

# 実装

以下のファイルを作成しました。
```JSample23_1.java
import java.util.regex.*;

class JSample23_1{
  public static void main(String[] args){
    String target1 = "A1B";
    String target2 = "A240B";
    String target3 = "A[0-9]*B";

    String regex = "A[0-9]*B";
    Pattern p1 = Pattern.compile(regex);

    Matcher m1_1 = p1.matcher(target1);
    System.out.println(target1 + ":" + m1_1.find());
    Matcher m1_2 = p1.matcher(target2);
    System.out.println(target2 + ":" + m1_2.find());
    Matcher m1_3 = p1.matcher(target3);
    System.out.println(target3 + ":" + m1_3.find());

    System.out.println("---- ----");

    Pattern p2 = 
      Pattern.compile(regex, Pattern.LITERAL);
    
    Matcher m2_1 = p2.matcher(target1);
    System.out.println(target1 + ":" + m2_1.find());
    Matcher m2_2 = p2.matcher(target2);
    System.out.println(target2 + ":" + m2_2.find());
    Matcher m2_3 = p2.matcher(target3);
    System.out.println(target3 + ":" + m2_3.find());
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample23_1.java 
$ java JSample23_1 
A1B:true
A240B:true
A[0-9]*B:false
---- ----
A1B:false
A240B:false
A[0-9]*B:true
```

# まとめ

何かの役に立てばと。
【Codewars】オススメの問題【正規表現】

# はじめに

オススメの問題があったので紹介します。

:::note
ぜひ正規表現で解いてみてほしいです。
:::
# 問題紹介

7kyuの問題です。つまり簡単とされる部類。

https://www.codewars.com/kata/54ba84be607a92aa900000f1/solutions/javascript

とはいっても、アルゴリズム問題を解き慣れていない人には少しタフかも。

CodeWars についてはこちら

https://qiita.com/kohki_takatama/items/2ae2808b931e943262b8

# 答えと解説
:::note
<details><summary>答えと解説</summary>

JavaScriptで解説しますが、どの言語でも同様の挙動だと思います。

```js
const isIsogram = str => !/(.).*\1/i.test(str)
```

> `(.)` -> 任意の1文字
> `.*` -> 0回以上の文字の連続（つまり、間に文字がどれだけあっても、なくても）
> `\1` -> 最初に出てきた1文字（つまり、「もう一度同じ文字が出てきた」）
> `/i` -> 大文字と小文字を区別しない

つまり、**「大文字と小文字関係なく」「文中に2回登場する1文字」** にマッチします。

これを `!` で否定しているため
**「マッチする場合」は`false` <->「マッチしない場合」は`true`** を返します。
</details>
:::

:::note warn
<details><summary>もう一つの Clever な解法</summary>

Codewarsには**Clever（天才、思いつかない、ニッチ、ギーク）** という評価基準があるのですが、
まさに**Clever** だと思ったものを紹介します。

>```js
>function isIsogram(str){
>	return new Set(str.toUpperCase()).size == str.length;
>}
>```

これは、`Set`というJavaScriptの仕様を使用したものです。
[Set - JavaScript| MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Set#:~:text=%E3%81%AE%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A7%E3%81%99%E3%80%82-,Set%20%E3%81%AB%E9%87%8D%E8%A4%87%E3%81%99%E3%82%8B%E5%80%A4%E3%81%AF%E6%A0%BC%E7%B4%8D%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82,-Set%20%E5%86%85%E3%81%AE)
`Set`は`Array`のようなものなのですが、「重複を許さない」という違いがあります。

---

ここでは以下の操作をしています。
「文字列を大文字、もしくは小文字に統一」->「`Set`にする」
これにより、重複する文字が`Set`内で1文字になります。

その後、`Set`の長さ（`size`）と、元の文字列の長さ（`length`）が同一であれば、
「`Set`が短くなっていない -> 重複していない」ということがわかります。

同一でない場合は、重複があったということですね。

---

仕様を理解し、思いつくからこその回答。**Clever** です。
</details>
:::
# おわりに
Codewars オススメの問題があればぜひ教えて下さい。

言語はJavaScript, Ruby, Haskellです。

（※Haskellは超簡単なもので解けるか解けないかレベルです。）
【アップデート】AWS Backup は、EC2 上の SAP HANA のクロスリージョンおよびクロスアカウント バックアップをサポートしました

こんばんは、Koderaです。
AWS BackupがEC2 上の SAP HANA のクロスリージョンおよびクロスアカウント バックアップをサポートしました。
https://aws.amazon.com/about-aws/whats-new/2024/08/aws-backup-cross-region-cross-account-copy-sap-hana-ec2/


## アップデート内容
AWS BackupがEC2 上の SAP HANAクロスリージョンおよびクロスアカウント バックアップをサポートしました。
ドキュメントヒストリーも20日日付で更新されていますね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858908/d7930557-27b2-5784-674c-0855b4f06727.png)



Organizations内でリージョンを超えたコピーおよびAWSアカウントを越えてスナップショット バックアップをコピーできるようになりました。


## 前提条件
AWS Backupの対応には、以下の前提条件があります。
大まかな内容としては、SAP HANAデータベースへの管理アクセスと、AWSアカウントに新しいIAM ロールとポリシーの作成です。

1)SAP HANA データベースを実行する Amazon EC2 インスタンスに必要な権限を設定します。
`AWSBackupDataTransferAccess`
`AWSBackupRestoreAccessForSAPHANA`
`AWSBackupServiceRolePolicyForBackup`
<br>
2) AWS Secrets Manager に認証情報を登録します。

`[{
"DatabaseName": "<YOUR_SID>/<YOUR_DATABASE_NAME>",
"CredentialType": "ADMIN",
"SecretId": "<YOUR_SECRET_NAME>"
}, 
{
"DatabaseName": "<YOUR_SID>/<ANOTHER_ONE_OF_YOUR_DATABASE_NAME>",
"CredentialType": "ADMIN",
"SecretId": "<YOUR_SECRET_NAME>"
}]`

<br>

3)SAP エージェント用の AWS Backint と AWS Systems Manager をインストールします。
AWS Backintについては、`AWSSAP-InstallBackintForAWSBackup`をRun Commandで実行します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858908/1824437e-ec15-e423-19dc-b96028f7f14c.png)

<br>

4)SSM エージェントが有効化されているか確認します。
`sudo systemctl status amazon-ssm-agent`
<br>


5）SAP HANA データベースの登録を行います。
// Command template
aws ssm-sap register-application \
--application-id <myApplication> \
--application-type HANA \
--instances <YOUR_EC2_INSTANCE_ID> \
--sap-instance-number <YOUR_HANA_SYSTEM_NUMBER> \
--sid <YOUR_HANA_SID> \
--region us-east-1 \
--credentials file://<PATH_TO_YOUR_CREDENTIALS_JSON_FILE>

各 HANA インスタンスを1回のみ登録することがベスト プラクティスです。
複数登録されることにより、同じデータベースに複数のARNが作成されてしまい、正しくバックアップを取得できなくなるリスクがあるためです。


## まとめ
SAP HANAのフル バックアップと INC (増分) の 2 種類のデータ バックアップをサポートします。 
AWS Backup は、各バックアップ操作中にどのタイプが使用されるかを最適化します。

### カタログのバックアップ
SAP HANA は、カタログと呼ばれる独自のマニフェストを維持します。 AWS Backup はこのカタログと対話します。新しいバックアップごとに、カタログにエントリが作成されます。

### 継続的ログ バックアップ (トランザクション ログ)
ポイント イン タイム リカバリ (PITR) 機能の場合、SAP HANA は最新のバックアップ以降のすべてのトランザクションをトレースします。


### FULL
完全バックアップは、完全なデータベースのバックアップです。

### INC
増分バックアップは、前回のバックアップ以降、SAP HANA データベースに加えられたすべての変更をバックアップします。

今回のアップデートにより、リージョン間、アカウント間でコピーを作成できるため、ダウンタイムのリスクが軽減され、災害復旧とビジネス継続性の要件をより確実に満たせるようになりました。
スナップショット コピーは、ソース アカウントが偶発的または悪意のある削除、災害、またはランサムウェアによって中断された場合に備えて、追加でデータの保護がされるようになります。
初めてのOFDM変調器導入：マスプロ製HDEC3MDで地デジ波を楽しむ

# OFDM変調器、買っちった！！
先日OFDM変調器を購入したので、その使用感や設定方法について紹介します。はじめての記事がこれで合っているのか、私には分かりません……
だって受信環境や録画システムに関する記事はレビュー的なモノから技術的なモノまで溢れてるじゃないですか……となるとみんな大好き自主放送かな？と思ってしまったわけです。


## 購入したもの
* OFDM変調器
マスプロ製 HDEC3MD

一般家庭向け？？？にリリースされているのはXHEAD2だけですが、ちょうど良い中古品が見つからなかったので、こちらを選びました。なお、お値段4諭吉サンほどでした。
（余談ですがこの記事を書き始めた2024年8月末の段階で未だに栄一サンには出会えて居ません。実在するの？）

:::note info
ワンルームや寝室など静かな場所にOFDM変調器を設置しようという奇特な方には、こちらの機器のファンがうるさいかもしれないので、ファンレス（らしい）XHEAD2をおすすめします。
:::

強者はアリエクでISDB-Tのモジュレータを買ってくるようですが、私にはそこまでの度胸はありません……

:::note warn
強者の方曰く、OFDM変調器は普通に国内産を買った方が良いとのことです。
:::
ヤフオクで中日電子やDXアンテナのOFDM変調器もちょくちょく見かけるので、もしよければこんな中身のない変態記事を読んでいるあなたも買ってみませんか？

## できること
当然OFDM変調器なので地デジ波の生成ができます。これで宅内自主放送が出来ますね？！

下の表にある通り、この機種は業務用機器の中ではライトユーザー向けのためHDMI入力も可能なため、いろいろな民生機からでている信号をそのまま地デジ波として送信可能です。
HDCPな信号は中華製の怪しいスプリッタを噛ませることで再生できることを確認しましたが、詳しくない領域なので深入りはしません。

| 入力端子 | 対応規格 |
|:-:|:-|
|HDMI|1080/59.94p<br>1080/60p<br>1080/59.94i<br>1080/60i<br>480/59.94p<br>480/60p<br>480/59.94i<br>480/60i|
|SDI|HD-SDI・3G-SDI<br>1080/59.94p<br>1080/60p<br>1080/59.94i<br>1080/60i<br1080/29.97p<br>1080/30p<br>SD-SDI<br>480/59.94i<br>480/60i|
|RCA|アナログコンポジット(NTSC)|

上記の入力端子に加えて、SDカードに保存された映像（1映像）を再生できます。今回はSDカードの映像を地デジ波として送信（といっても実際に電波に乗せたらダメです）してみよう！という記事です。

## 導入編
設定する必要があったのは以下の項目です。ネット上には当該機の説明書が転がっていませんが、後継機のものとそんなに操作方法は変わらないようです。（私が設定した段階では後継機の仕様書が転がっていましたが、いまは検索にヒットしないようです……）
* ネットワーク設定
GUIにアクセスするためには、まずネットワーク設定を行います。【メニュー／決定】を長押しし、【システム設定】⇒【ネットワーク設定】から、IPアドレス・サブネットマスク・デフォルトゲートウェイを設定しました。
* 時刻取得設定
システム本体の時刻の取得方法を設定できます。RF入力に壁のコンセントから来る地デジ信号を入れてあげると時刻補正が可能です。このほか、NTPサーバーをIPアドレスで指定して補正することも可能です。
* 送信チャンネル
この装置の要でもある地デジ出力の送信チャンネルを設定します。1～62ch、C13～C63chの設定が可能です。

## SDカード映像の送信編
上記でネットワーク設定を行うことでGUIにアクセスできます。（たしか初回起動時にパスワードやらを設定した気がします）
私の環境では、設定用のGUI画面がFirefoxやChromeだと崩れてしまったり一部が表示できなかったりしました。忌まわしきMS-Edgeであれば正しく表示できました、何でだよ。

![2024-08-22_212247.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831804/5a313ad2-254b-946c-503e-d384b1205584.jpeg)
メイン画面はかんたん設定画面のようです。一般的にはこの画面から設定すれば良いようです。

---
SDカードに入れた映像を出力したい場合やTSサービスを複数送信したい場合は詳細設定からでないと設定できないようです。今回はSDカードに入れた映像を送信したいと思います。
![2024-08-22_212445.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831804/3e92dcfd-b2ac-0412-8260-245daa077e4d.jpeg)


SDカードに入れる映像は指定形式でエンコードしてあげないといけないようです（MPEG2-TSならいけるやろ、と録画したTSを入れたところちゃんとダメでした）
動画のエンコードに関しても私は詳しくないので、[皆木慎吾氏の記事](https://www.minagi.jp/2013/09/16/tvmw5ofdm/ "［テクニカルメモ］OFDM変調器　PV-200H、HDEC2MD、DEM9203のSDカードから送出する映像ファイルを作成するための、TMPGEnc Video Mastering Works 5の設定。")を参考にさせて頂きました。

https://www.minagi.jp/2013/09/16/tvmw5ofdm/

---
試しに設定を「神奈川県」「リモコンID：10CH」「地域事業者識別 O(14)」と設定したところ以下のような形で地デジチャンネルを生成することが出来ました！
![2024-08-22_212210.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3831804/1728368c-c1c7-63c7-1eec-0929e74724fe.jpeg)

また機会があれば複数の入力系統から複数サービスで送信する際の設定追い込みなどをしてみようと思います。
つたない文章ではありましたが、ここまで読んで頂きありがとうございました。
ビット計算の練習【Atcoder】2進数で表したときのiビット目に注目する問題

## 記事の内容
この記事で紹介したいのは、

n までの整数の中で、2進数で表したときに j ビット目が1である数の個数を効率的に数える

という考え方を紹介します。

## なぜこの考え方に注目したのか
AtCoderのABCにて出題されたこの問題を解くために必要な考え方だからです。

https://atcoder.jp/contests/abc356/tasks/abc356_d

色々と勉強になる考え方なので、記録のために記事化しておきたいです。
整数問題やビットの考え方のいい練習になるはずです。


## 問題の具体化
目的は、n までの整数の中で、2進数で表したときに j ビット目が1である数の個数を数えることです。
n = 13 の場合の整数（0から13まで）を2進数で表すと次のようになります。
j＝２、つまり、２ビット目に注目します。

```python
0:  0000
1:  0001
2:  0010
3:  0011
4:  0100
5:  0101
6:  0110
7:  0111
8:  1000
9:  1001
10: 1010
11: 1011
12: 1100
13: 1101
```
このとき、2ビット目（j = 2）が1であるのは 4, 5, 6, 7, 12, 13 で、合計6つあります。
よって、求める数は６です。

# 答えを求めるコード
答えを求めるコードはこちらです。（くどいくらいコメントを入れています。）

```python
# 関数 f(j, n): jビット目のカウントを計算する
def f(j, n):
    p2 = (1 << j)  # 2^j を計算
    k = n // (2 * p2)  # n を 2 * 2^j で割った商を計算
    res = k * p2  # 商に 2^j を掛けた結果を res に保存
    l = n % (2 * p2)  # n を 2 * 2^j で割った余りを計算
    if l >= p2:  # もし余りが 2^j 以上であれば
        res += (l - p2 + 1)  # res に (余り - 2^j + 1) を足す
    return res
```

## なぜこのコードで計算できるのか
私は、最初にこのコードを見たときに、なぜこの方法で答えが得られるのかわかりませんでした。そのため、このコードで答えが求められる理由を具体的に解説します。

関数 f(j, n) のアルゴリズムが動作する理由は、2進数におけるビットの規則性を利用して、j ビット目が立っている（つまり 1 である）数を効率的に数えるためです。これを理解するために、ビットのパターンがどのように繰り返されるかを考えます。

### 2進数でのビットパターンの周期性
2進数では、各ビットは特定の周期で 0 と 1 を繰り返します。たとえば、ビットの位置が固定されている場合、そのビットが 1 になる回数には周期的なパターンがあります。

例えば、j = 2 の場合（2ビット目）、そのビットが 1 になるのは次のような周期で発生します。

* ビットのパターン: 00 01 10 11 (4つの数ごとに周期)
4つの数（00, 01, 10, 11）のうち、2ビット目 が 1 であるのは、10 と 11 のときです。

### f(j, n) の具体的な流れ
1. k = n // (2 * p2)
この部分は、n を 2 * p2 で割り、その整数部分 k を得ることで、j ビット目が完全に周期を満たす回数を求めています。
例えば、p2 = 4 の場合、この計算は「j ビット目が 1 である完全な周期がいくつ含まれるか」を計算しています。周期ごとに p2 個のビットが 1 になるため、k * p2 がその範囲での 1 の個数となります。

2. l = n % (2 * p2)
次に、n が完全な周期に収まらない余り（残りの部分）を計算します。この余り部分が、次の部分での計算に使われます。

3. if l >= p2
ここで、余り l が p2 以上であれば、その残りの範囲でも j ビット目が 1 になる範囲があるため、その数だけ追加します。具体的には、余り l が p2 以上であれば、l - p2 + 1 の個数が 1 であると計算されます。

### まとめ: なぜこの方法で求められるのか
* ビットの周期性の利用: 2進数におけるビットの値が 0 と 1 を繰り返す周期性を利用しています。j ビット目が 1 になる周期を 2^j で表し、そのビットが 1 になる数の範囲を効率的に計算しています。
* 完全な周期のカウント: n を 2 * p2 で割ることで、j ビット目が 1 である完全な周期が何回含まれているかを数え、その中で 1 が出現する回数を計算しています。
* 部分的な周期の処理: 余りの部分を別途処理することで、n が完全な周期に含まれない場合でも、正確に 1 になるビットの個数を計算しています。


## 関連記事
* [論理学って何を扱うの？論理学入門](https://qiita.com/kyogoku_meta/items/7dc1c17f78bc36d11346)
* [線形代数の「背景と概念」をもっとよく分かりたい【数学弱者・凡人のための線形代数入門】](https://qiita.com/kyogoku_meta/items/077e9972dcd7b08d6473)
* [弱者・凡人のための競技プログラミング入門『競技プログラミングの鉄則』本を使いこなしたい ①二分探索](https://qiita.com/kyogoku_meta/items/91b32773f045d0ef560b)
* [弱者・凡人のための競プロ入門『競技プログラミングの鉄則』を使いこなしたい！『グラフ』編](https://qiita.com/kyogoku_meta/items/1c735119b0b93cb24d0e)
新たな画像拡大のAccDiffusionを試す

https://huggingface.co/spaces/fffiloni/AccDiffusion
3分以上、時間かかります。

他と比べて、使いたいという要素は今のところないです。

## 画像変わりすぎ

元画像

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54688/7a1a98e6-64af-4a4a-ab36-0d8bac66fbd4.png)

2 x 拡大画像

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/54688/e981eb61-2b20-6a6f-f04d-a6200806ff2c.png)
【アップデート】新しいDirect Connectロケーションがクアラルンプールに開設されました

こんばんは。Koderaです。
新しいDirect Connectロケーションがクアラルンプールに開設されました。
https://aws.amazon.com/about-aws/whats-new/2024/08/aws-direct-connect-location-expansion-malaysia/

## Direct Connect ロケーションとは
Direct Connectは、AWSとユーザーとの間に専用のネットワークを提供するサービスのことです。オフィスやシステムが稼働するデータセンターからインターネットを介さずにAWSと接続することができます。インターネット経由ではないので、セキュアかつ回線状況の影響を受けずに、安定した通信ができます。

AWS Direct Connect ロケーションとは、対応するリージョンでの AWS へのアクセスの中継地となるものです。 パブリックリージョン または AWS GovCloud (US) の単一の接続を使用して、他のすべてのパブリックリージョンのパブリック AWS のサービスにアクセスすることができます。


## アップデート内容
「CSF Telcohub 1 Data Center」という名称で、Chinaリージョンを除くすべての商用リージョン、Govリージョンとローカルゾーンからアクセス可能です。

この「CSF Telcohub 1 Data Center」は、マレーシアでは2つ目のDirect Connectロケーションです。
MACsec 暗号化が利用可能な専用の 10 Gbps および 100 Gbps 接続が提供されます。
AWS Direct Connect のロケーションのいずれかから、どの AWS リージョンにもアクセスできます (中国を除く)。
表の「Assocoated AWS Region」列が、接続のデフォルトのリージョンです。 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3858908/b9f37111-005f-7db0-53d3-4330d3dbc71e.png)


本アップデートでは、Menara AIMS データセンターにある既存のクアラルンプール ダイレクト コネクト ロケーションに 10Gbps および 100Gbps MACsec サービスを追加することも発表されました。

## まとめ
新しいDirect Connectロケーションがクアラルンプールに開設されました。世界では145以上のDirect Connectロケーションが存在しているそうです。
ネットワークで語る，工学

# 結論
![science_v2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/e299c631-80d2-f0b5-2180-1062963ec28e.png)

[データはこちら](https://github.com/HAL7000-S/network_database/tree/main)
https://github.com/HAL7000-S/network_database/tree/main


# 前提
物性値や変数を
数式を介してつないでいます．

著者が履修済みなのは，
- 力学
    - 電磁気学
- 材料力学
    - 弾性力学
- 熱力学
- 流体力学
    - 伝熱工学

です．
統計力学・量子力学・化学も書きたかったけど未履修．
熱力->化学ポテンシャルとか
どなたか追記お願いします．

使ったのはgephiというグラフソフトです．
ForceAtrasでまとめています

まず左真ん中あたりに初等力学
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/ec8b688a-5ad8-36d0-59f4-861f8a59cd58.png)

上のほうに行くと材料力学
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/b6e5f3d7-7788-26a2-acb7-a6d08cba522e.png)

その右に構成方程式・連続体力学関係で流体力学
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/88510c1a-442b-464a-56c0-7797bf7fc3e2.png)

その右下に流体関係で熱工学
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/41543f97-e4e8-63ba-9289-5c107aad61a5.png)

左下には光・エネルギー関連で電磁気につながり，
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/c51ad86f-f6cf-dc0b-0668-1cc60d1b6d2f.png)

周波数とか力学関連で一周しました．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647496/fd82dfe2-7780-849f-c6ad-6545feb6f86b.png)

以上です．これがやりたかっただけ．
私は特に新しい気付きとかはなかったですが，何かの参考になれば幸いです．

おわり！閉店！
[Excel VBA] 最下行の行番号を取得する

### ざっくり説明
データが入力されている最下行の行番号を返してくれます。

列を指定することもできますし、
シート全体の中での最下行を求めることもできます。
<font color="red">→ ここ差別化ポイント！</font>

### コード
```vb:最下行の行番号を取得する
Function GetLastRowNumber(ByVal WS As Worksheet, Optional ByVal colNumber As Long = 0) As Long
'================================
'用途　　：最下行 行番号の取得
'--------------------------------
'第一引数：Worksheetオブジェクト (Worksheet型)
'第二引数：対象列番号 (Long型)
'戻り値　：最下行 行番号 (Long型)
'特記事項：第ニ引数の省略でWS全体の最下行を返す
'================================
    Dim lastRowNumber As Long
    If colNumber <> 0 Then
        lastRowNumber = WS.Cells(WS.Rows.Count, colNumber).End(xlUp).Row
        
        If WS.Cells(1, colNumber) = "" Then
            lastRowNumber = 0
        End If
    Else
        lastRowNumber = Range("A1").SpecialCells(xlLastCell).Row
    End If
    
    GetLastRowNumber = lastRowNumber
End Function
```

### 使用方法
第一引数にWorksheetオブジェクトを指定し、
第二引数(任意)に列番号を渡します。

第二引数が入力されている場合は その列番号での最下行の行番号を返し、
第二引数が未入力(もしくは0)の場合は そのシート内での最下行の行番号を返します。

### 仕様等
- 1行目から最下行の間に空白セルがあっても最下行の行番号を求められます

- **第二引数で何も入力されていない列の列番号を指定した場合、**
**最下行の行番号は 0 が返ってきます！**

後者ですが、"既に入力されているセルの1つ下のセルに新たに内容を追加する"
という運用を想定しているためこのような仕様になっています。

仕様が不要な方は
```vb
        If WS.Cells(1, colNumber) = "" Then
            lastRowNumber = 0
        End If
```
を消してください。
何も入力されていない列の列番号を指定した場合は 1 が返ってくるようになります。

### 注意点
- 非表示行がある場合 正常に動作しない可能性があります
- フィルタが設定されている場合 正常に動作しない可能性があります

フィルタの解除には以下記事の`ClearFilter()`が使えます。
関数内で呼び出してもいいですし、
サブルーチンの関数を使う直前で使ってもいいです。

https://qiita.com/ivkamisz/items/ae339c835f9aab29dc6a


### その他
~~フィルタをかけたまま最下行を求められる方法もあるけどそれはまた追々…~~

2024/8/23追記
フィルタかけたまま最下行を求められる関数を書きました

https://qiita.com/ivkamisz/items/c4e61d84dd7852a27b4e
LiONオフラインMeetup

# お詫び
- 今日はコミュニティメンバーに向けているため、身内ノリ多めです
- 楽しい（というか、楽しむ）コミュニティだよ！ということが言いたいので、ぜひ様子をチラ見してください

## コミュニティ概要
運営にちょっと近い立場としては、今日のメインコンテンツかもしれない、と思っている。
というのも、コミュニティ自体の概要の話を最近参画していただいた方々にお話しする機会があまりなかったこともあって、このコミュニティが何をやっているのか分からないという事もある。

コミュニティに入った後に、どういう動き方をすると良いかという話はなかなか聞けないのでかなりレアだなと。
少なくとも、私がお世話になってきたコミュニティで概要レベルの話を聞いたことがなかったので、エンジニアコミュニティは実力者優遇の傾向を感じさせやすいのかもしれないな、と思った。

## LT
### 「ITベンチャーとLinux：イノベーションの源泉」大塚氏
- ITベンチャーとLinuxの関係
  - 安定性と柔軟性
  - コスト効率の良さ
    - 事業設立面
    - ライブラリ
    - スケーラビリティ
  - 豊富なコミュニティサポート
- オープンソースの力

活用例としてAWSによるブロックチェーン技術を挙げられていた
とはいえ、人材育成・セキュリティ対策の必要性・重要性が高まる。

これだけオポチュニティがあるので「今やるならITベンチャー（Linuxエンジニア）はいいぞ」

### 「生成AI活用分科会と活動案内」わた氏(Me)
https://qiita.com/nomurasan/items/b04d22a305d9a722d8d3

いいね・感想くれたら喜びます
みんなでワイワイやってほしいのでSlackを推奨してます

VSCodeの拡大・縮小表示

- AIを使って問題を生成して、いいね/だめねをつけてもらうか
- プロンプトをみんなで作ろう！

### 「LiONのロゴにこめた思い」西川氏
https://qiita.com/HeavyGauge24/items/45663b5580c13c752cf2

「多様性を認め合い、エンジニア同士が個人の成長を感じながら作り上げていくコミュニティ」

- 赤：LiON
- 青：LinuC
- 緑：OSS-DB
- オレンジ：HTML５

と、４つのプロジェクトも表したい

### 裏テーマ
（これはぜひ本人から聞いてほしい！）

## メンバー自己紹介
Slack自己紹介チャンネル参照！

ネットワーキングへ〜
第2回 SVG ハンバーガーアイコン＋hover

# はじめに
第1回で作成したハンバーガーアイコンにhoverをつけたときに円が表示するようなものを作ります。
SVG用のCSSがあるようですが、よく理解していないので、これまでやっていたような方法で試そうと思います。

# 今回実施する内容
「第19回 JavaScript アニメーションによるモーダルサイドバー（translateX）」で作成したハンバーアイコンのようなものです。
![humbergerIcon2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/fabf0b7d-99b7-9687-b2fb-2c866781765a.gif)


# ソースコード(Git Hub)
https://github.com/Build-Mount/SVG_02_humbergerIcon2

# 環境
OS: Windows 11 JP (64bit)
バージョン 127.0.2651.105 (公式ビルド) (64 ビット)

# 参考

# 用語

# 実現方法
前回、SVGでハンバーガーアイコンは作成しました。
`humbergerIcon.svg`
上記を`img`タグで設定します。
※hoverした時にそなえてハンバーガーアイコンの見直しをしました。詳細は、「[ハンバーガーアイコンの設計](https://qiita.com/drafts/7b4101afcd1c23ffb227/edit#%E3%83%8F%E3%83%B3%E3%83%90%E3%83%BC%E3%82%AC%E3%83%BC%E3%82%A2%E3%82%A4%E3%82%B3%E3%83%B3%E3%81%AE%E8%A8%AD%E8%A8%88)」をご覧ください。
その`img`タグにクラスセレクターを設定し、hoverしたときに、`img`タグを円にし、背景色を設定します。


```html:menu.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="menu.css" type="text/css">
    <title>menu</title>
</head>
<body>
    <img src="humbergerIcon.svg" class="menuIcon"/>
</body>
</html>
```

```css:menu.css
/* menu Icon用開始 */
.menuIcon {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 32px;
  height: 32px;
}

.menuIcon:hover {
  background-color: #ccc;
  border-radius: 50%;
}

/* menu Icon用終了*/
```

```html:humbergericon.svg
<?xml version="1.0" standalone="no"?>
<svg width="32px" height="32px" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" version="1.1">
  <title>Example humberger icon</title>
  <desc>Example humberger icon</desc>
  <path d="M9 10 L24 10" stroke="black" stroke-width="2"/>
  <path d="M9 16 L24 16" stroke="black" stroke-width="2" />
  <path d="M9 22 L24 22" stroke="black" stroke-width="2" />
</svg>
```

## ハンバーガーアイコンの設計
第1回で作成したハンバーガーアイコンですが、hoverしたときに〇をつけるようにするために、形を見直しました。
- 図のように32x32の枠を作ります。単位はviewport想定しているのでありません。
- 半径16の円を記載します。
- 真ん中に記載の正方形にハンバーガーアイコンがきれいに収まるように設計します。
- 今後図形を作るときはこの正方形内に極力収まるようにアイコンをデザインします。

![humbergerIcon設計.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405480/7ae98ec7-0161-e53d-14eb-a796fb6d6325.jpeg)

第1回のものよりもバランスはよくなったのかなと思います。

# おわりに
このくらいなら、意外と簡単にできるとわかりました。
SVGを外部ファイルにすると、CSSが動作しないとかなんとか記事を見かけたのですが、SVGを操作しているわけではなく、`img`タグを操作しているだけなので、大丈夫ってことですね。
コンテナ化されたデータベースでのマイグレーションの実行方法

<h1>はじめに</h1>

データベースのマイグレーションは、アプリケーションの進化と共に必要となる作業の一つです。Dockerを利用したコンテナ化された環境でのデータベースマイグレーションは、その複雑さを増す一方で、正しく行えば多くのメリットをもたらします。この記事では、Dockerを使用してコンテナ化されたデータベースでマイグレーションを実行する方法について、具体的なコード例を交えながら解説します。

<h2>Dockerとコンテナ化の基礎</h2>
<h3>Dockerとは何か？</h3>
Dockerは、ソフトウェアのデプロイを簡素化するためのコンテナ化技術です。コンテナは、アプリケーションとその依存関係をまとめてパッケージ化し、どこでも一貫して実行できるようにします。これにより、環境間の違いによる問題を軽減することができます。

<h3>コンテナ化の利点</h3>
コンテナ化により、開発環境と本番環境の違いを最小限に抑えることができ、開発者は本番環境に近い条件でテストを行うことができます。また、リソースの効率的な利用やスケーラビリティの向上もコンテナ化の大きなメリットです。

<h3>データベースのコンテナ化の概要</h3>
データベースのコンテナ化は、データベースをコンテナ内で実行することを意味します。これにより、簡単にデプロイ、スケーリング、および管理が可能となり、データベースの管理が一貫性を持って行われます。

<h3>マイグレーションとは何か？</h3>
データベースマイグレーションの定義
データベースマイグレーションとは、データベースのスキーマやデータそのものを新しいバージョンに更新するプロセスです。アプリケーションの進化に伴い、新しいフィーチャーの追加やデータ構造の変更が必要になるため、マイグレーションは避けて通れない作業となります。

<h3>なぜマイグレーションが必要か？</h3>
マイグレーションを行わないと、古いスキーマに依存したコードが原因で、アプリケーションが正常に動作しなくなる可能性があります。新機能を追加したり、パフォーマンスを向上させたりするためには、データベースのマイグレーションが必要不可欠です。

<h3>一般的なマイグレーションの課題</h3>
マイグレーションには多くの課題があります。例えば、データの損失や整合性の問題、ダウンタイムの発生などです。これらの課題を克服するためには、事前の計画と十分なテストが必要です。

<h2>コンテナ化された環境でのマイグレーションの重要性</h2>
<h3>一貫性と再現性の向上</h3>
コンテナ化された環境では、マイグレーションのプロセスが一貫して実行されるため、環境ごとの違いによるエラーが発生しにくくなります。また、再現性が高いため、問題が発生した場合でも迅速に原因を特定し、解決することが可能です。

<h3>環境依存性の排除</h3>
コンテナ化により、特定のOSやソフトウェアのバージョンに依存することなく、同じマイグレーションプロセスを異なる環境で実行できます。これにより、環境間の差異が原因で発生する問題を減らすことができます。

<h3>マイグレーションの自動化</h3>
DockerとCI/CDツールを組み合わせることで、データベースマイグレーションを自動化することができます。これにより、手動の作業を減らし、ヒューマンエラーのリスクを最小限に抑えることができます。
ASP.NET Framework ViewとControllerのルーティング

```txt
{サーバのアドレス}/{View・Controller直下のディレクトリ
名}/{メソッド名}
```

- メソッドを指定しない場合、Viewのページ名と同じ名前のメソッドが自動的に呼び出される
- 呼び出されるメソッドは、対象のディレクトリ名のフォルダにある`{View・Controller直下のディレクトリ
名}Controller.cs`ファイルから検索される
- **ディレクトリの階層構造をurlで指定することはできない**
実務経験ゼロでDatabricks 認定データエンジニアアソシエイト合格体験記



## はじめに

タイトル詐欺すみません、私は実務経験あります。実務経験ゼロで合格したのはプレッシャーに追われた同僚の話です（後半でお話いたします）
依然、いろんな現場でエンジニアとしてのキャリアを築く上で、資格取得は重要な一歩であることは間違いないと感じます。今回は、私がDatabricks 認定データエンジニアアソシエイトに合格した経験をお話しします。特に、実務経験の重要性と使用した問題集について詳しく触れたいと思います。タイトルと真逆ですみません。

## 試験の概要

https://www.databricks.com/jp/learn/certification/data-engineer-associate

- **試験内容**: 60問の多肢選択問題
- **制限時間**: 120分
- **合格ライン**: 70%
- **試験費用**: 200ドル
- **受験方法**: オンライン受験

## 主な出題範囲

1. **Databricksレイクハウスプラットフォーム**（15-20%）
2. **ETLパイプラインの実装**（35-40%）
3. **データセットの管理**（15-20%）
4. **データガバナンスの実装**（10-15%）
5. **ワークフローの実装と管理**（15-20%）

## 実務経験の重要性

合格の最大の要因は、間違いなく日々の業務でDatabricksを使用していたことです。特に以下の点が試験に直結しました：

1. **Delta LakeやSparkを使ったETLパイプラインの実装経験**
2. **Unity Catalogを用いたデータガバナンスの実践**
3. **Databricks Jobsを使ったワークフローの管理**

これらの経験があったからこそ、問題集の内容をより深く理解し、実践的な視点から解答することができました。例えば、Delta Lakeのマージ操作やSparkのパフォーマンスチューニングに関する問題では、実際にあ～こんなことあったなと思い出したりながら解答できました。

## 使用した問題集

試験直前の試験勉強では、以下の問題集を使用しました。

https://note.com/data_ku/m/m523f94d5d2b8

ただし、問題集だけでなく、Databricksの公式ドキュメントも併せて参照することで、より深い理解につながりました。

## 学習方法

1. **問題集を一通り解く**
2. **間違えた問題や不安な箇所を公式ドキュメントで確認**
3. **実務で使用している機能と問題集の内容を照らし合わせる**
4. **模擬テストで最終確認**

なんの工夫もない内容ですね。。。でもこの方法により、理論と実践のバランスの取れた学習ができました。

## 同僚の体験

会社で大量に配られたバウチャー（無料受験チケット）。私の同僚は別プロジェクト(AWSメイン)にアサインされていましたが資格取得せよとの強烈プレッシャーにまけ、実務経験がほとんどないまま、上記問題集だけを使って学習し、合格を果たしました。
しかし、実際の業務で困難に直面することは間違いないかと。。。機会があればそのあたりも今度加工と思います。


資格取得を目指す方には、可能な限り実務経験を積んだ上で、問題集などの教材を活用することをお勧めします。実務経験と体系的な学習を組み合わせることで、不安や現場の応用力もつくのではないでしょうか。
Meta QuestのASWを無効にしてVRChatのフレームレートを改善する方法

# はじめに

こんにちは。
ジョジョ好きなXRクリエイターの [もふるね](https://twitter.com/mofurune_k) です。

VRChatの重いワールドで顔を左右に振ったとき、視界の端が波のように揺れて見える問題があったのですが、解決したのでここにその解決策を記します。

環境
・Meta Quest Link使用

PCスペック
CPU　：AMD Ryzen 5 5600X 6-Core Processor
GPU　：NVIDIA GeForce RTX 3060
マザボ：ASRock B550 PG Riptide


# 参考資料

[Oculusにて設定しているフレームレートの半分になってしまう原因や対処法について。【ゆっくり解説】](https://www.youtube.com/watch?v=GAMF1oWqWEg)
[Oculusデバッグツール | Oculus開発者](
https://developer.oculus.com/documentation/native/pc/dg-debug-tool/?locale=ja_JP)


# 原因

Meta Questは初期状態でASW（Asynchronos Spacewarp）という機能が有効になっています。
ASWとは、フレームレート（1秒あたりの描画枚数）が十分でないときに、直前のフレームから次のフレームを予測して生成して、擬似的にフレームレートを維持する機能です。
詳しく言うと、最大フレームレートが72fpsの場合、アプリが72fpsのフレームの送信に失敗したときに半分の36fpsだけ描画し、残りの36fpsは予測した画像を描画します。

しかしASWにはメリットとデメリットがあります。

メリット
・PCの負担が少なくなる
・ゆっくりな動きは自然に見える

デメリット
・つよつよPCでも最大の半分のフレームしか出せない
・速い動きはブレて見える


# ASWの無効化

ASWを無効にする方法

OculusDebugToolを起動します。Meta Quest Linkが使えてる人は、すでにダウンロードされてるので、以下のディレクトリにあります。
C:\Program Files\Oculus\Support\oculus-diagnostics\OculusDebugTool

起動したら、Asynchronos SpacewarpをDisabledにします。

![c5c5da746e0f534a63ae99489a463963.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518924/1858d2e1-9497-58b2-037a-3f05fa1d08d0.png)

これで完了です！

フレームレートがいつも30代fpsだったところ、ASWを無効化することで+10fpsくらい向上しました！
速く動いてもブレない！やったー！


# おわりに

PCの性能は良いはずなのに、振り向いたときなどに視界の端の描画がおかしい～と、フレンドに相談したところ、ASWについて教えてもらって解決できました。
Quest本体の設定でASWを無効化できればいいのに、わざわざPC側からOculusDebugToolを起動しないと変えられないんですよね。うーん、不親切。
Virtual Desktopを使ってる人は、Virtual Desktopの設定からASWの無効化ができるみたいです。

それでは、快適なぶいちゃライフを送りましょう～！