OmniAICreator/Qiita-1.07M huggingface dataset:
ARC164回答メモ

0.はじめに
　ARC久々だなーと思い調べたら、前回は7/9なので、2か月ぶりでした。
　その時はQIITA記事書けない位の惨敗でした。
　今回も、Aすら解ける気はしなかったのですが、あがいているうちに
　なんとかAだけは解け、Bも時間は足りませんでしたが
　解き方を模索できるくらいは問題を理解できました。
　結果として、レート+17と昨日と合わせて今週だけで+34も
　あがりました。


1.A - Sum equals LCM
　初見でレーティング参加を後悔しましたが、試行錯誤の上
　なんとか解いていけました。

　【考え方１】
　　　N=6の例をみて、最小公倍数が6になる
　　　かつ、合計が6以下となる、2個以上の数列は2と3であるが
　　　そこに1を足している・・・
　　　→合計の条件を満たすために、1はいくらでも追加できる。
　　　　→最小公倍数をみたすリストの合計がNを超えなければ
　　　　 そこに1を追加していけば条件を満たす
　　　　　→最小公倍数をみたすリストの合計がNを超えないためには
　　　　　 Nが素数でなければよい、
　　　　　（素数だと、リストは2個以上の値が必要なため、
　　　　　　１とNが最小公倍数リスト候補となり足すとNを超えてしまう。）
　　　★Nが素数でなければなんとかなる！
　　　→実装した結果WA

　　【考え方２】
　　　　N=4の例を見て、素数でもなんとかならないことを悟る
　　　★Nが5以下は条件を満たさない！
　　　→実装した結果WA

　　【考え方３】
　　　　N=9の時を考えると、素数ではないが、リスト候補には、3しか上らず
　　　3が2つあっても最小公倍数は3のため、条件を満たさない
　　　★Nが素数で2回割れたらだめ！
　　　→実装した結果WA

　　【考え方４】
　　　　N=27の時を考えると、素数ではないが、リスト候補には、3しか上らず
　　　3が3つあっても最小公倍数は3のため、条件を満たさない
　　　★Nが素数で2回以上割れたらだめ！
　　　→実装した結果WA

　　【考え方５】
　　　　N=72の時を考えると、素数で２回以上割れるが、A=9,8,1を55個
　　　　と、条件を満たせる。
　　　★Nが素数のべき乗だったらだめ！
　　　→実装した結果AC

　　と、トライアンドエラーを繰り返して正解にたどり着きました。

　　【実装】
　　　　[素数リスト作成]
　　　　　実装は、１つ１つ素数で割っていったらまにあわなそうだったので
　　　　　まず素数のリストを作ろうと思い、ぐぐったら、エラトステネスの篩で
　　　　　素数を求める例があったのでこぴって使いました。
　　　　　素数リストの上限は、Nの最大値の0.5乗≒31623までとし
　　　　　最初に素数リストLを作成。
　　　　[条件を満たさないかの判定関数 is_prime、条件を満たさない時Trueを返す]
　　　　　※考え方の最初、素数だったらだめ！というときに作った関数なので
　　　　　　素数判定のような関数名になっている
　　　　　1)変数chkに0をセット
　　　　　　(chk:n以外で素数で割切れるかつ、素数のべき乗でない場合1をセット)
　　　　　2)for文でリストLの要素をxに入れて一つずつチェック
　　　　　　2-1)nがxで割り切れる場合
　　　　　　2-1-1)chkNにnをxで割った値をセット
　　　　　　2-1-2)変数flgに0をセット
　　　　　　2-1-3)flgが0の間以下を繰り返す
　　　　　　　　2-1-3-1)chkNがxで割り切れる場合
　　　　　　　　　　2-1-3-1-1)chkNにchkNをxで割った値をセット
　　　　　　　　　　　　2-1-3-1-1-1)chkNがxで割り切れない場合flgに1をセット
　　　　　　　　2-1-3-2)chkNがxで割り切れない場合はflgに1をセット
　　　　　　　　 ↑ここら辺はループしているのに次のループでするべき判定を
　　　　　　　　　 先取りしていて冗長なのでごちゃっとしている
　　　　　　2-1-4)chkNが1の時、nはxのべき乗であるためTrue(条件を満たさない)を返す
　　　　　　2-1-5)chkNが1でない時、chkに1をセット
　　　　　 2-2)nがxで割り切れない場合は次のxへ
　　　　　3)chkが0の場合、Trueを1の場合Falseを返す
　　　　[メイン処理部分]
　　　　　1)Tを読み込む
　　　　　2)以下T回繰り返し
　　　　　　2-1)Nを読み込む
　　　　　　2-2)Nが5以下の時Noを出力
　　　　　　2-3)Nが6以上の場合
　　　　　　　　2-3-1)is_prime(N)の戻り値がTrueの場合Noを出力
　　　　　　　　2-3-1)is_prime(N)の戻り値がFalseの場合Yesを出力
　忘れないようにまとめましたが無駄に長くなったし
　内容も書き直したくなるくらい無駄が多いなと思います・・・。

　https://atcoder.jp/contests/arc165/submissions/45679114

2.B - Sliding Window Sort 2
　コンテスト中はなんとなく直感でこうすればよさそうというのは
　思い浮かんだのですが、実装まで落とし込めませんでした。
　まぁ、解説を読んでもパット理解できなかったので、直感も
　あってたかはわかりませんが・・・。
　解説を読んで理解した考え方を忘れないよう自分の言葉でメモ。

　【考え方】
　　１）操作をすることによって、辞書順が大きくなることは無い。
　　　　最大でも、元のリストと同じ状態。
　　　　→操作しても辞書順が変わらないケースは
　　　　 リストの値が、K個昇順に並んでいる場合なので
　　　　 そのような並びがあった場合は、リストをそのまま出力して終了
　　２）辞書順を大きくするためには、なるべく元のリストの儘が良い。
　　　変える場合も、先頭の方は変えない方がよいので
　　　リストのうしろから、K個をソートしたリストを回答候補1として保持
　　３）回答候補１と元のリストを先頭から比較して、一番最初に
　　　差異が出た位置をiとしたとき、iの前の部分が昇順に並んでいたら
　　　その並び順を活かす方が変化が少ないため、iを含むK個の列の値のうち
　　　iより前の部分の昇順な並びが最大になるような位置からK個を
　　　ソートした値を回答候補2として保持
　　４）回答候補１と回答候補２のうち、辞書順で大きい方を出力して終了

　一応メモとして残しましたが、解説放送を見た方が、理解しやすいかと思いました。

　https://atcoder.jp/contests/arc165/submissions/45688012


以上
VSCodeでDenoをTypeScriptで厳格な型チェックを行いデバッグする設定

# 前提
・nodeがインストールされている
・TypeScriptがグローバルインストールされている


# フォルダ構成
MY-PROJECT
├─ sample.ts
├─ tsconfig.json
└─ .vscode
　　├─ launch.json
　　├─ settings.json
　　└─ tasks.json



```json:tsconfig.json
{
  //コンパイルオプション
  "compilerOptions": {
    //厳格なチェックを行う(省略値はfalse)
    "strict": true,
    //暗黙のany型の使用を許可したい時falseとする(strict=trueの時の省略値はtrueのため)
    "noImplicitAny": true,
    //JavaScriptファイルを作成しない(コンパイルチェックのみ行いたい時true)
    "noEmit": true
  }
}
```

```json:launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      //debugの名称(任意)デバッグ開始ボタンのプルダウンメニューの選択肢に表示される
      "name": "Deno",
      "type": "pwa-node",
      "request": "launch",
      "cwd": "${workspaceFolder}",
      "runtimeExecutable": "deno",
      "runtimeArgs": ["run", "--unstable", "--inspect-brk", "-A", "${file}"],
      //tasks.jsonで定義したtaskにリンクする
      //デバッグ実行時のコンパイルチェックが重いときはコメントアウト
      //そのかわりコンパイルチェックは自前でコマンドラインでtscコマンドで実行する
      "preLaunchTask": "Compile TypeScript",
      "attachSimplePort": 9229
    }
  ]
}
```

```json:settings.json
{
  "deno.enable": true,
  "deno.lint": true,
  "deno.unstable": true
}
```

```json:tasks.json
{
  "version": "2.0.0",
  "tasks": [
    {
      //taskの名称(任意)launch.jsonなどからこの名称を使ってリンクさせる
      "label": "Compile TypeScript",
      "type": "shell",
      "command": "tsc",
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}
```

```javascript:sample.ts
const keyArray = ["a", "b", "c", "d", "e"];
const valueArray = [1, 2, 3, 4, 5];
const json: any  = {};  //"noImplicitAny": false とすればanyは省略可能

valueArray.forEach((item, index) => {
  json[keyArray[index]] = item;
});

console.log(json); //{a: 1, b: 2, c: 3, d: 4, e: 5}
```
Javascript Primer　非同期処理編のメモ

#### 非同期処理: 
プログラムの実行中に他のタスクを待たずに進行する処理方法で、非同期のタスクを指定し、後でその結果を取得します。

#### 同期処理: 
タスクが順番に実行され、前のタスクが完了するまで次のタスクが開始されない処理方法。

#### 非同期処理はメインスレッドで実行される: 
基本的には非同期処理も同期処理と同じようにメインスレッドで実行されます。

#### [ES2015] Promise: 
JavaScriptで非同期処理をより効率的に扱うためのオブジェクト。

#### Promiseインスタンスの作成: 
new Promise() を使用してPromiseインスタンスを生成します。

#### Promise.prototype.thenとPromise.prototype.catch: 
Promiseの状態が変化したときに実行されるコールバック関数を設定するためのメソッド。

#### Promiseと例外: 
Promise内で発生した例外は自動的に捕捉され、catch メソッドで処理できます。

#### Promiseの状態: 
Promiseインスタンスの状態は作成時にPendingとなり、一度でもFulfilledまたはRejectedへ変化すると、それ以降状態は変化しなくなります。 そのため、FulfilledまたはRejectedの状態であることをSettled（不変）と呼びます。

#### Promise.resolve: 
解決済みのPromiseを返す静的メソッド。

#### Promise.reject: 
拒否されたPromiseを返す静的メソッド。

#### Promiseチェーン: 
複数の非同期処理を順番に連鎖させる方法。

#### Promiseチェーンで逐次処理: 
Promiseチェーン内で前の処理が完了するのを待ってから次の処理を実行する方法。

#### Promise.allで複数のPromiseをまとめる: 
複数のPromiseを同時に実行し、全ての結果を待つためのメソッド。

#### Promise.race: 
複数のPromiseの中で最も早く解決または拒否されたものを返すメソッド。

#### [ES2017] Async Function: 
非同期処理をより簡潔に記述できる構文。

#### Async Functionの定義: 
async キーワードを使って関数を非同期関数に定義します。

#### Async FunctionはPromiseを返す: 
非同期関数は自動的にPromiseインスタンスを返す。

#### await式: 
非同期関数内で非同期処理が完了するのを待つための式。

#### Promiseチェーンをawait式で表現する: 
非同期関数内でPromiseチェーンをシンプルに表現する方法。

#### Async Functionと組み合わせ: 
非同期関数を他の非同期処理と組み合わせて使用する。

#### Async Functionと反復処理: 
非同期関数をループ内で使用して非同期な反復処理を実現する。

#### Promise APIとAsync Functionを組み合わせる: 
PromiseベースのコードとAsync Functionを組み合わせて非同期処理を管理する。

#### await式はAsync Functionの直下でのみ利用可能: 
await式は非同期関数内でしか使用できません。

#### [ES2022] Module直下でのawait式: 
モジュールのトップレベルでawaitを使用できるようになった機能。
Javaで「平方根と立方根を取得する」の動作を確認してみた

# 概要

Javaで「平方根と立方根を取得する」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/math/index5.html

# 実装

以下のファイルを作成しました。
```JSample5_1.java
class JSample5_1{
  public static void main(String[] args){
    System.out.println("sqrt(16) = " + Math.sqrt(16));
    System.out.println("sqrt(30) = " + Math.sqrt(30));
    System.out.println("sqrt(-25) = " + Math.sqrt(-25));

    System.out.println("cbrt(8) = " + Math.cbrt(8));
    System.out.println("cbrt(40) = " + Math.cbrt(40));
    System.out.println("cbrt(-64) = " + Math.cbrt(-64));
  }
}
```

以下のコマンドを実行しました。
```
$ javac JSample5_1.java 
$ java JSample5_1 
sqrt(16) = 4.0
sqrt(30) = 5.477225575051661
sqrt(-25) = NaN
cbrt(8) = 2.0
cbrt(40) = 3.419951893353394
cbrt(-64) = -4.0
```

# まとめ
何かの役に立てばと。
PostgreSQLサーバーの動作環境

# PostgreSQLインストール後確認すること
Postresqlをインストールした際に、データディレクトリと設定ファイルの場所については確認しておく事  

## 設定ファイルの置き場所が違う場合がある
いろんな記事を読んでいると、postgresユーザーのホームディレクトリにデータディレクトリが置かれている場合が多く、最近の設定は複数バージョンの環境を作っても競合しないようにバージョン番号などで分けている場合が多い。

## Debian Linux 11の場合
su -
でルートになる。
su - postgres
でpostgresユーザーになる。
pwd
でフォルダを確認すると
/var/lib/postgres
ls で内容を確認してみると 13 というフォルダがありその下に main　がある構造

## ディレクトリの確認方法
psql コマンドを起動

データディレクトリを確認
show data_directory;
/var/lib/postgresql/13/main と表示される

設定ファイルを確認
show config_file;
/etc/postgresql/13/main/postgresql.conf

これを確認することで、どんな環境でも設定ファイルを効率的に探すことが出来る。
探検Elixir: OTP 26のマップに関する不思議な冒険

:::note info
ChatGPT先生にたたき台をまず作ってもらって、推敲を重ね、正確性を期して投稿をしました。実験的な記事です。
:::

https://help.qiita.com/ja/articles/qiita-community-guideline#ai

「[AIが生成した内容は正確性を確かめよう](https://help.qiita.com/ja/articles/qiita-community-guideline#ai)」に従いました。



# プロローグ: 魔法の舞台

私は、エンジニアとしての日々を魔法のような冒険と捉えています。
今回の冒険は、「不老不死の霊薬」を意味する[Elixir](https://elixir-lang.org/)という素晴らしいプログラミング言語の舞台裏に潜む不思議な順序を視察する旅です。
魔法の舞台には、[Elixir](https://elixir-lang.org/) 1.15.5のOTP 26とOTP 25のバージョンが用意され、そこで奇妙な出来事が繰り広げられます。

マップは順不同なデータ構造です。

この記事では[Docker](https://www.docker.com/)で[Elixir](https://elixir-lang.org/)のプログラム例を動かすことにします。

OTP = Open Telecom Platformのことで、[Elixir](https://elixir-lang.org/)の土台となっている[Erlang](https://www.erlang.org/)のことだと思ってもらって差し支えないと思います。

# 第一幕: OTP 26の不思議なマップ

OTP 26の舞台で、次の魔法の詠唱を行います。

```elixir
docker run --rm -it hexpm/elixir:1.15.5-erlang-26.0.2-alpine-3.18.2 iex
---
iex> %{a: 1, b: 2, c: 3}
%{c: 3, a: 1, b: 2}
```

驚くことに、魔法が解けると `:c` と `:a` の順序が入れ替わるのです。まるで魔法使いの手にかかったかのように、マップの順序が作成時と異なる順序で結果が出力されます。

# 第二幕: OTP 25の奇妙な演技

次に、OTP 25の世界へと足を踏み入れましょう。

```elixir
docker run --rm -it hexpm/elixir:1.15.5-erlang-25.3.2.5-alpine-3.18.2 iex
---
iex> %{a: 1, b: 2, c: 3}
%{a: 1, b: 2, c: 3}
```

ここで奇妙なことに注目してください。舞台裏では、 `:a` と `:c` が別の順序で登場します。
Elixirの魔法は、OTP 25と26の世界では微妙に違ったステップダンスを踊ります。

# 第三幕: Elixirの魅力の魔法

[Elixir](https://elixir-lang.org/)という素敵な世俗派関数型言語[^1]でプログラミングを楽しみました。 
その素敵具合は「[Elixir Saves Pinterest $2 Million a Year In Server Costs](https://paraxial.io/blog/elixir-savings)」によく現れています。
開発者も経営者もこの事実に瞠目することでしょう。**$2 Million/年の節約ですってよ！、奥さん。**

https://paraxial.io/blog/elixir-savings


[^1]: @kikuyuta 先生の「[世俗派関数型言語 Elixir を関数型言語風に使ってみたらやっぱり関数型言語みたいだった](https://qiita.com/kikuyuta/items/afa4c264720eb29d9760)」より。[Elixir](https://elixir-lang.org/)はコワくないですよ〜。

大きく意訳をいれますが、「[Elixir](https://elixir-lang.org/)は、生産性の向上、柔軟性の確保、スケーラビリティの向上をもたらす言語であり、その全ての要因がコスト削減につながる可能性がある」というようなことが述べられています。

[Elixir](https://elixir-lang.org/)の魔法は、そのマップの微妙な変化に留まらず、エコシステム全体に広がっています。
私たちは、この魔法の舞台裏で不思議なことが起こることを楽しむ冒険者なのです。

# エピローグ: 魔法の舞台の幕が下りる

魔法の舞台裏でのOTP 26とOTP 25の不思議なマップの冒険をお楽しみいただけましたでしょうか。
[Elixir](https://elixir-lang.org/)の魅力は、そのエレガントなシンタックス、耐障害性、スケーラビリティに溢れています。
そして、その魅力の一部が、このような奇妙な魔法の実験に宿っているのです。

私たちは、新しい技術の冒険に出発し、問題を解決し、魔法のような瞬間を楽しむ準備ができています。
Elixirの世界では、魔法がいつも微笑んで待っているのです。




---

:::note info
ChatGPT先生にたたき台をまず作ってもらって、推敲を重ね、正確性を期して投稿をしました。実験的な記事です。
:::

https://help.qiita.com/ja/articles/qiita-community-guideline#ai

「[AIが生成した内容は正確性を確かめよう](https://help.qiita.com/ja/articles/qiita-community-guideline#ai)」に従いました。

---

# さいごに

OTP 26とOTP 25では、マップを出力した際にキーの並び順が異なります。
「[Erlang/OTP 26 Highlights](https://www.erlang.org/blog/otp-26-highlights/)」に書いてある「[Improvements of maps](https://www.erlang.org/blog/otp-26-highlights/#improvements-of-maps)」が影響しているものと思われます。

それではごいっしょに！
「いやぁ、[Qiita](https://qiita.com/)って本当にいいもんですね～。それではまたご一緒に投稿を楽しみましょう」

<iframe width="960" height="540" src="https://www.youtube.com/embed/TsYL6oN8SXs" title="水野晴郎さん　映画って本当にいいもんですね" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
生成AIで東北きりたんと琴葉茜ちゃんがいちゃいちゃする動画を作った5

# [前回]()までのあらすじ
[Bing Chat](https://www.bing.com/search?form=MW00X7&OCID=MY02AA&q=Bing+AI&showconv=1)はBGMが作れないのに作れる振りをする。

# 動画を作ろう（続き）
## BGMを探そう
生成AIで無料でダウンロード可能なBGMを作成できるサイトは見つからなかった。
仕方が無いので[ニコニ・コモンズ](https://commons.nicovideo.jp/)で適当なBGMを漁る。

* [待ち合わせ](https://commons.nicovideo.jp/works/nc107860)
* [遊園地](https://commons.nicovideo.jp/works/nc313247)
* [夕日](https://commons.nicovideo.jp/works/nc238716)
* [エンドロール](https://commons.nicovideo.jp/works/nc289427)

## YMM4で動画を編集しよう

ここをやってくれるAIの完成が待たれる。

ここで、VoiceroidUtilとYMMの台本機能が併用できないことに気づく。お排泄物。
仕方が無いので台本からVoiceroidUtilにコピペする作業を繰り返す。
ここをやってくれるAIの完成が待たれる。

テキストをコピペするだけではなく、読み誤りの確認と修正、立ち絵の配置、サイズと位置調整、BGMの音量調整、フェードアウトの設定、背景画像の配置、位置調整、フェードインの設定、字幕の位置調整、字幕の下地の配置、etc, etcと「動画編集」の一言で片づけられる無数の作業を手作業でこなす。
ここをやってくれるAIの完成が待たれる。

# できた

https://www.nicovideo.jp/watch/sm42776425

完成した感想は動画にも書きました。
あとは、必要なBGMや画像は生成AIに決めてもらいたいというのがあります。
今回、どんなBGMや背景画像が必要かはこちらで決めましたが、生成AIに決めてもらって、なんなら生成プロンプトまで作成してほしいです。
TypeScriptでメソッドチェーンを使って与えた文字列を次々に変換する方法

こちらの記事でやっていることと同じことをメソッドチェーンを使って実現できるのではと思い

https://qiita.com/hasesiu/items/dbefc1496bc1ba3fa4df

ChatGPT に以下の質問をしてみた

>typescriptでメソッドチェーンを使って与えた文字列を変換するサンプルコードをお願いします

ChatGPT が回答したコードはこちらです

```typescript
class StringManipulator {
  private value: string;

  constructor(input: string) {
    this.value = input;
  }

  // 文字列を大文字に変換するメソッド
  toUpperCase(): this {
    this.value = this.value.toUpperCase();
    return this;
  }

  // 文字列を小文字に変換するメソッド
  toLowerCase(): this {
    this.value = this.value.toLowerCase();
    return this;
  }

  // 文字列を逆順にするメソッド
  reverse(): this {
    this.value = this.value.split('').reverse().join('');
    return this;
  }

  // 現在の文字列を返すメソッド
  getValue(): string {
    return this.value;
  }
}

// 使用例
const text = "Hello, World!";
const manipulatedText = new StringManipulator(text)
  .toUpperCase()
  .reverse()
  .toLowerCase()
  .getValue();

console.log(manipulatedText); // "dlrow ,olleh!"
```

個人的には
```getValue()```を```toString()```としたいです
SQLインジェクションによる認証回避の練習問題について考えてみました

https://qiita.com/ockeghem/items/787f74801a24e1fc6960
上記記事の練習問題についての私の回答

UserID : **`' union select '' as id, 'admin' as userid, '$2y$10$Ur8VTGkSgaF808C4krzvhOsLLxDzgHxhrVms6aUsnaLxmay3DV/ra' as password, '' as email; -- '`**
Password : **何も入力しない**

`password`カラムに突っ込んでいるハッシュ値はローカルで `password_hash('', PASSWORD_BCRYPT)` として取得したもので、`password_verify()`で`true`が返る組み合わせなら別に何でも良いです。
これを`userid`を`admin`としたカラムと一緒にunionで結合させています。

この結果、`login.php`内でのsqlは

```sql:
SELECT * FROM users WHERE userid = '' union select '' as id, 'admin' as userid, '$2y$10$Ur8VTGkSgaF808C4krzvhOsLLxDzgHxhrVms6aUsnaLxmay3DV/ra' as password, '' as email; -- ''
```

となり、`userid`が`admin`な、パスワードは空文字列でログイン成立できてしまうレコードが返るわけです。
2023/9/18主にITとかセキュリティの記事

Azure リソースの Dangling DNS (未解決の DNS エントリ) を特定する(9/15)
https://qiita.com/himatsumoto/items/4c9c3a12d901e6446c5e

ChatGPTなどのLLMを狙う「プロンプトインジェクション攻撃」「データポイズニング攻撃」とは？　NCSC(9/16)
https://atmarkit.itmedia.co.jp/ait/articles/2309/16/news044.html

AWS Application Migration Service による大規模な移行と自動パッチ(9/15)
https://aws.amazon.com/jp/blogs/news/migrating-and-automating-patching-at-scale-with-aws-application-migration-service/

Amazonで不正アクセス多発か？(9/16)
https://www.zaikei.co.jp/article/20230916/738108.html

CoinEX不正流出事件、被害者補償など発表(9/16)
https://coinpost.jp/?p=481956

サイバー攻撃、大手クラウドを悪用　4月から急増(9/16)
https://www.nikkei.com/article/DGXZQOUC23BCO0T20C23A8000000/

Seria「X公式アカウント」本部が完全否定、偽アカウント削除へ……他企業の中の人も騙される事態に(9/16)
https://news.nicovideo.jp/watch/nw13406626

「あなたのポルノ動画がアップされた」というメールが届いたときにとるべき行動(9/16)
https://forbesjapan.com/articles/detail/65942

USB充電ステーションには要注意。実際にあった詐欺の手口とは？(9/16)
https://news.yahoo.co.jp/articles/df2b3df51ebf1c8aca6cbdd4d9113cfd81c06f65

今回は見送られたものの…東京にNATOの連絡事務所を置く案が急浮上？(9/16)
https://news.nifty.com/article/entame/showbizd/12270-2558200/

未来のAIによる「感情のハッキング」という脅威　「人類滅亡までの最悪なシナリオ」を専門家が提唱(9/16)
https://news.yahoo.co.jp/articles/4b92c067ee27c6c2c8cb94b2b45a1f197a886a3d

機密資格の２４年法制化へ加速　政府、重要技術の国外流出防止(9/16)
https://www.sanyonews.jp/article/1452737/

いったい誰が？工事用電光掲示板が乗っ取られ、やばい文字が表示される(9/15)
https://karapaia.com/archives/52325604.html

不正アクセス控訴審、前橋市側は争う姿勢　東京高裁(9/16)
https://www.jomo-news.co.jp/articles/-/345234

「ハワイの火事は米国の気象兵器が原因」中国が生成AIを駆使し陰謀論を拡散か(9/16)
https://news.yahoo.co.jp/articles/49db37c9a991b0d0d9d75145e3d7864537f93c1b?source=rss

東大、深層ニューラルネットワークの隠れ層にゆらぎを導入し脆弱性を軽減(9/16)
https://www.nikkei.com/article/DGXZRSP662060_U3A910C2000000/

日本は台湾のドラえもん？(9/16)
https://agora-web.jp/archives/230915064930.html
初心者によるgitコマンドの備忘録

# gitコマンドのまとめ（備忘録）です。

忘れたときやこれなんだったっけ？って時に思い出せればという気持ちでアウトプットしました。
gitのイメージをまとめてみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3559951/363092b8-dc05-69ad-12ae-b196de7daa8b.png)

## 1. リポジトリ作成に使うコマンド

`$ git init`
* カレントディレクトリにローカルリポジトリを新しく作成する。作成されたリポジトリには **.git** という名前のディレクトリが作成され、gitのプログラムはこの **.git** ディレクトリを使用することで、リポジトリのバージョン変更履歴を管理している。


`$ git clone コピーするディレクトリ名（or URL）`
* すでに存在しているリポジトリ(ローカルでもリモートでもどちらでも)を指定したディレクトリにコピーする。コピーするリポジトリはgithubのURL（github上のリポジトリ）をコピーして使用することが多い印象。指定するディレクトリは省略可能で、その場合はカレントディレクトリにコピーされる。

## 2. リモートリポジトリから行動するコマンド
originとはリモートリポジトリのローカルに登録されている名前で、mainはローカルのmainブランチを指す

`$ git push マージ先のリモートリポジトリ マージ元のローカルリポジトリ`
* ローカルリポジトリの変更点をリモートリポジトリにアップロードする。ただし自身が想定していない変更をリモートリポジトリにマージしてしまうと、チームに迷惑になるので`$ git diff`で変更部分を確認することが推奨されている。
    * `$ git push origin main`で ***push*** することが多い印象

`$ git pull マージ元のリモートリポジトリ マージ先のローカルリポジトリ`
* チーム開発で他の仲間がリモートリポジトリにマージした変更内容を、自身のローカルリポジトリに取り込むためのコマンド。
    * `$ git pull origin main`で ***pull*** することが多い印象

---
## 3. コミットを操作するコマンド

`$ git add`
* 新たに追加・変更・削除したファイルを作業ディレクトリからステージングエリアに追加するコマンドです。コミット時にはステージングエリアに追加されたファイルが全てローカルリポジトリに加えられる。
    * `$ git add .`でカレントディレクトリ配下で追加・変更・削除された部分を一括で追加できる。


`$ git commit -m "メッセージ"`
* インデックスに存在する全ての変更されたファイルをコミットする（ローカルリポジトリにマージする）コマンド。
    * `-m` でメッセージを追加するオプション

`$ git log`
* コミットの履歴を表示する。履歴閲覧を終了する場合は`q`を入力する

---
## 4. 作業ツリーを操作するコマンド
作業ツリーとは、ユーザーが実際に変更するファイルの格納されたディレクトリで、前述の`$ git init`コマンドでリポジトリを作成したディレクトリとも言い換えられます。


`$ git status`
* 指定したディレクトリ内に下記の条件を満たすファイルがあれば、一覧で表示するコマンドです。
    * gitの管理対象に含まれていない（新たに追加した）ファイル
    * ステージングエリアに追加されたが、まだコミットされていないファイル
    * ステージングエリアに追加されていないが、変更されているファイル

* ディレクトリを省略すると、作業ツリー全体のファイル状態を表示する。


`$ git diff`
* 作業ツリー内の指定ファイルをリモートリポジトリのものと比較して、差分のある箇所を表示するコマンドです。
* ディレクトリを指定した場合は、ディレクトリ内にある全ファイルの差分を一括で表示可能。ディレクトリを省略した場合は、作業ツリー内にある全ファイルの差分を表示する。


---
## 5. ブランチを操作するコマンド
ブランチとは、リモートリポジトリやローカルリポジトリをコピーして、分岐リポジトリを作る機能です。チーム開発や個人開発でよく使われる。

`$ git branch`
* ブランチの一覧を表示したり、作成・削除するなどのブランチ操作を行う。

`$ git switch -c branch名`
* 現在処理対象になっているブランチを基点に新たなブランチを作成するコマンド。

`$ git checkout -b branch名`も同じコマンドである。

`$ git switch branch名`
* 処理対象のブランチを切り替えるコマンド。

`$ git checkout branch名`も同じコマンドであるが、*入力したブランチがローカルに存在していない**かつ**リモートに対応ブランチが存在している場合のみ新しくブランチが作成できる。*

`$ git fetch リモート名 branch名`
* リモートにあるブランチの最新情報をそれに対応しているローカルのブランチに反映させるコマンド。`branch名`を省略するとリモートのブランチすべての最新情報を反映できる。

例えば
```
$ git fetch origin 
$ git checkout issues/#
```
と入力すると、リモートのブランチの最新情報をすべて取得し、そのまま、`issues/#`という新しいブランチをローカルに作成することができる。これはgithubでissuesとそれに対応したリモートブランチを作成したあとにローカルに対応させるために用いる。

## 図にまとめてみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3559951/d47609b3-a1cb-1574-464a-79726ae8dbcc.png)
間違っていたらご指摘いただけると幸いです。




**参考にしたウェブサイト様**
https://www.sejuku.net/blog/5816
https://docs.github.com/ja/get-started/quickstart/hello-world#creating-a-repository
HasuraをGCPで構築した話

# 前置き
HasuraをGCPで構築し、個人開発を円滑に進めたいと思いCloud Run + Cloud SQLの構成でAuth Proxy経由接続する方法があまり見つからなかったのでメモとして残しています

# 作業手順
1. サービスアカウントの作成（Cloud SQL Auth Proxy用）
1. Cloud SQLインスタンスの作成（PostgresSQL）
1. Docker imageをArtifact ResitoryにPush
1. Cloud RunでHasuraを起動

# サービスアカウントの作成（Cloud SQL Auth Proxy用）
Cloud SQL Auth Proxy用のサービスアカウントを作成します
作成したサービスアカウントは構築するCloud Runに紐付ける予定です
付与する権限は、『Cloud SQL Client』のみでOK！
![スクリーンショット 2023-09-18 0.02.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2230428/355e282c-9e43-78d2-9d39-a60b1b5b0af4.png)

# Cloud SQLインスタンスの作成（PostgresSQL）
Hasura接続用のDBを構築します
今回は、個人開発用なので最小構成にしています
**▼ 構成**
種類： PostgresSQL 15.2（デフォルト）
マシン構成：　db-g1-small（1vCPU, 1.7GB）
ストレージ： SSD 10GB

# Docker imageをArtifact ResitoryにPush
まずは、ArtifactRepositoryにリポジトリを作成します
コンソール画面からポチポチして作成しました

次にローカルにHasuraのDocker Imageをぷるっと
```bash
docker pull hasura/graphql-engine:latest
```

Tagをつけてあげる
```bash
docker tag hasura/graphql-engine:latest \
us-central1-docker.pkg.dev/< ProjectID >/< RepositoryName >/< IMAGE >
```

Pushの前に、なんだか忘れてしまったおまじない
たしかArtifact Registryへ認証を通すおまじない、、、
```bash
gcloud auth configure-docker us-central1-docker.pkg.dev
```

Artifact RegistryへPush
```bash
docker push \
us-central1-docker.pkg.dev/< ProjectID >/< RepositoryName >/< IMAGE >
```

リポジトリにPushされていることを確認
![スクリーンショット 2023-09-18 0.18.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2230428/008ac1a9-4691-3fa0-8935-431a04a9dad6.png)

# Cloud RunでHasuraを起動
Artifact RepositoryにPushしたイメージからリビジョンを作成します
**▼ 構成**
ほんとに最小構成で設定しました！

![スクリーンショット 2023-09-18 0.20.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2230428/85d616f0-4f38-c3ba-3326-c8687312814c.png)
![スクリーンショット 2023-09-18 0.20.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2230428/6b8255aa-d57c-eb13-e487-642786d114d5.png)
![スクリーンショット 2023-09-18 0.21.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2230428/4e6709f1-234a-bbc0-e151-105146eb610d.png)

**■ 環境変更**
HASURA_GRAPHQL_ADMIN_SECRET： Hasuraコンソールにアクセスする時のパスワード
HASURA_GRAPHQL_ENABLE_CONSOLE： Hasuraコンソールにアクセスする場合はTRUEに
HASURA_GRAPHQL_SERVER_PORT： 起動するポート
HASURA_GRAPHQL_DATABASE_URL： DBのURL（Auth Proxy経由で癖があるので詳細を下記に記載）

## ポイントは３点！
① 環境変数のCloud SQL Auth Proxy用にセットする
**HASURA_GRAPHQL_DATABASE_URL**という変数名に、『postgres://\<user>:\<password>@/\<database>?host=/cloudsql/\<instance_name>』の形式でセットする

② Cloud SQL接続に作成したDBを選択する
正直、これを選択しないと接続されないかわかりませんが？アイコンをホバーするとProxyを自動化されるとあったので選択しないと接続できないっぽい

③ セキュリティタブからデフォルトサービスアカウントのものから最初に作成したサービスアカウントに選択する
これの選択を忘れるとProxy周りがうまく通らないっぽいので作成したサービスアカウントを設定
デフォルトのサービスアカウントに『Cloud SQL Client』を足していいのかもしれませんが権限を最小限にしたいので最初に作成したものを選択しました

リビジョンの起動が終わったら、発行されたCloud RunのURLからHasuraのコンソール画面へ入る！
環境変数で設定した、HASURA_GRAPHQL_ADMIN_SECRETでログインできれば成功 🎉

# おしまい
イメージをそのままCloud Runで動かすだけであればすごい簡単にHasuraを構築することができました！
Hasuraは、コード管理できるのでプロダクトで使う場合はコード管理するした方がリリースタイミングでHasuraコンソールからポチポチするより良さそう！（どうやるかは全然イメージわかないですが、、、）

あとは、『HASURA_GRAPHQL_ADMIN_SECRET』と『HASURA_GRAPHQL_DATABASE_URL』をSecretManagerとかで管理して、リブジョンする際に参照するように設定すれば一通り良さそう！！

最後まで読んでいただきましてありがとうございます 🙇‍♂️
terraform で ebs が gp2 のものをレポートする遊び

# tl;dr

- 最近アドカレしか qiita 書いてないのでたまにはと思って
- terraform でこんな遊び方もできるんだよ例
- Amazon EBS のボリュームタイプ gp2 をレポートにして出力する遊び
- API の実行コスト以外は元々かかってると思うしこれ自体ではほぼゼロコスト（のはず）

# code

```terraform aws_ebs.tf
# 取得条件
data "aws_ebs_volumes" "gp2" {
  filter {
    name   = "volume-type"
    values = ["gp2"]
  }
}

# 条件に合致した各データ
data "aws_ebs_volume" "gp2" {
  for_each = toset(data.aws_ebs_volumes.gp2.ids)
  filter {
    name   = "volume-id"
    values = [each.value]
  }
}

output "gp2" {
  value = templatefile("${path.module}/report.tftpl", { volumes = [for s in data.aws_ebs_volume.gp2 : s] })
}

```

```terraform report.tftpl
ID, IOPS, SIZE, Name
%{ for v in volumes ~}
${v.id},${v.iops},${v.size},${try(v.tags.Name,"-")}
%{ endfor ~}
```

# 雑な説明

- aws 設定は好きにしていい（環境変数で設定してあれば aws provider は書かなくていい。ぶっちゃけ上の２ファイルだけ置いて plan して大丈夫）
- リージョン別に実行したり、同時に複数リージョンを見たりは自由課題ってことで（手元に数がなくてページングとかも試してない。何件いけるのか不明）
- aws_ebs_volume"s" で gp2 の ebs を複数取得して、aws_ebs_volume を for_each でぶん回して必要な数だけ作る
- templatefile() を使ってテンプレートを読み込み、aws_ebs_volume の数だけループして出力する
- だけ。

# まとめ？

- Amazon EBS は gp3 にするとコストメリットがあるので、まだ gp2 のボリュームがあるなら切り替えを検討しましょう
- terraform は IaC のツールだけど単純には Provider を介したインターフェースみたいなもんなのでインフラを作るだけじゃなくてこういうレポート的なものを作ることもできる的な話（各クラウドの data source 次第）
- 他にもこんな小ネタ見たいなぁ（誰か書かないかなぁチラッ）
OpenAPI入門

OpenAPIは一度実務で使用したのですが、あまり分からず使用していたので調べて整理してみました。

## 概要
OpenAPIは正式には「Open API Specification」の略でREST API(RESTの原則に基づいて設計されたAPI)の記述フォーマットを指します。
RESTAPIはWebアプリケーションで情報をやり取りする際の規格で、OpenAPIは安全に通信するためにどのような形式にしたらいいかの仕様の定義になります。

Excelでもできますが、OpenAPIの方が管理など仕様が統一されてるので使いやすいです。

## OpenAPIとSwagger
OpenAPIは元々Swaggerという名前でしたが、SwaggerがOpenAPI Initiativeに寄贈されたことでOpenAPIという名前になりました。

Swaggerの代表的なツールは以下になります。
- Swagger Editor・・・ブラウザでAPIの仕様書を書くためのエディター
- Swagger UI・・・APIの仕様書からドキュメントを作るためのツール
- Swagger Codegen・・・API仕様書からコードを作成するツール

他にもモックサーバーの作成やテストの実行もできます。

## 書き方
yamlかjsonで定義ファイルを記述します。
[詳しくはこちら](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md)



OpenAPIがどんなものかは分かったと思います。
クラウド日記

マイクロソフトとオラクル、「Oracle Database@Azure」発表！！
Azure上でのOracle Exadataベースのマネージドサービスを提供

Oracle Database@Azureは、Microsoft Azureのデータセンター上でOracle Exadataが稼働し、Oracle Exadata Database services、Oracle Autonomous Database services、Oracle Real Application Clusters(RAC)が利用可能となりました。

https://blogs.microsoft.com/blog/2023/09/14/microsoft-expands-partnership-with-oracle-to-bring-customers-mission-critical-database-workloads-to-azure/

今までOCI以外で、RAC提供が出来ないのが当たり前でしたが、ついにAzure上でOracle RACが利用出来るようになるとは感慨深いですね・・

今後、他のクラウドでも同様なことが進むのでしょうか。
日本語特化モデルをGoogle Colaboratoryを動かしてみた

2023年08月22日に東京大学から発表された、日本語に特化したAIモデルをGoogle Colaboratory上で動かしてみました。
このモデルはhugging faceで公開されています。

ちなみにモデル名を変更すれば、今話題のcodellamaなども動かせます！
今後もどんどん色々なモデルが出てくると思うので試してみると楽しいかも。

記事 https://www.t.u-tokyo.ac.jp/press/pr2023-08-18-001
hugging face https://huggingface.co/
モデル https://huggingface.co/matsuo-lab/weblab-10b-instruction-sft
codellamaのモデル https://huggingface.co/codellama/CodeLlama-7b-hf

以下のコードを実行するのに課金が必要かもしれません。課金済み(Colab Pro)の状態で実行しています。
途中でメモリ不足でクラッシュしたので増量して再度実行しました

# 今回動かすコード
```
import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

# 学習済みファイルのダウンロード部分
tokenizer = AutoTokenizer.from_pretrained("matsuo-lab/weblab-10b")
model = AutoModelForCausalLM.from_pretrained("matsuo-lab/weblab-10b", torch_dtype=torch.float16)

if torch.cuda.is_available():
    model = model.to("cuda")

# llm実行部分
text = "吾輩は猫である。"
token_ids = tokenizer.encode(text, add_special_tokens=False, return_tensors="pt")

with torch.no_grad():
    output_ids = model.generate(
        token_ids.to(model.device),
        max_new_tokens=100,
        do_sample=True,
        temperature=0.7,
        top_p=0.95
    )

output = tokenizer.decode(output_ids.tolist()[0])
print(output)
```

# 動かす手順
## 手順1
まずはGoogle Colaboratoryでgpuを動かす設定を行います
![スクリーンショット 2023-09-17 20.38.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115880/5871b660-0f13-b3c6-7c79-5b9cd587b127.png)
![スクリーンショット 2023-09-17 20.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115880/0ca93099-469c-af8d-33c0-95b5520b89ac.png)

## 手順2
以下のコマンドを実行してgpuが使用できているかを確認します
```
!nvidia-smi
```
![スクリーンショット 2023-09-17 20.39.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115880/b3577cd5-bae2-5074-aa7e-0ae9b8a88c07.png)

## 手順3
必要なライブラリをインストールします
```
!pip install git+https://github.com/huggingface/transformers.git@main accelerate
```
![スクリーンショット 2023-09-17 20.42.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115880/e8ff52dc-2556-a859-572b-0629a44819f0.png)

## 手順4
上記のコードのファイルの不ダウンロード部分を実行します
約22GBのデータをダウンロードするのに7分ほどかかりました。何回かダウンロードを繰り返すと激遅になります

google driveとマウントすることもできるようです。
https://note.com/npaka/n/n0b942a95ca5b

### 画像は後ほど

## 手順5
llmの実行を行います

### 画像は後ほど



## Google Colaboratoryのコードの入力欄を増やす方法
画面上部の「+ コード」のボタンを押します
![コードの増やし方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/115880/19ee6e66-0b57-7b94-2d44-7cc017e047be.png)

# 今後やりたいこと
物理や数学に特化したAIモデルそのものを作りたいです。物理の新しい理論を答えてくれるようなAIがあったらとても面白いと思っています。
まだどんな風にやればいいかよくわからずllmを勉強中です。(おそらくfine tuningが候補かな)

# 最後に
以前から興味のあった日本語特化モデルを動かすことに成功しました！
このコードを参考にhugging　face上に公開されているAIモデルを実行することが可能となるので、ぜひ参考にしてみてください。
【DeviseTokenAuth】SNS認証時にomniauth_external_window.html.erbが表示されない場合の対処法

## 状況
DeviseToeknAuthを使用してSNS認証でログインしたところ`omniauth_external_window.html.erb`が表示されませんでした。

## 対処法

`OmniauthCallbacksController`に以下の記述を追記することで表示されるようになりました。

```rb
  include ActionView::Layouts
  include ActionController::Rendering
```

## 参考

https://github.com/lynndylanhurley/devise_token_auth/issues/1591
プロダクトマネージャーのしごと(O'REILLY)の感想

9/5にオライリー・ジャパンより出版された「プロダクトマネージャーのしごと」を読み終えました。
特に印象に残った個所を中心に感想をまとめておきます。

https://www.oreilly.co.jp/books/9784814400430/

# なぜ読んだのか
私はエンジニアでありPdMではありませんが、何か新しいプロダクトや機能を開発する際に「うん、正しい方向に向かっている」と自信をもって開発を進められるように、プロダクトマネージメントの分野も積極的に学習しています。またエンジニアとPdMは親和性の高い職種だと考えています。自身の市場価値を高めるためにもPdMとしての知見も身につけてやろうと企んでいます。

# ざっくり感想
当初はPdMがよく使ってそうなフレームワーク(BMC等)とかロードマップの書き方みたいなものが学べることを期待していましたが、そうではなくPdMとして重要なマインド、心構えみたいな内容が多く書かれています。むしろフレームワークは「有用なフィクション」として、ロードマップは「チームが会話をするきっかけとなるドキュメント」として表現されています。フレームワークを使いこなせるとか、見栄えの良いロードマップや資料が作成できる、といったスキルはPdMに必ずしも必要なものではないのだなあと本書を読んで実感しました。

# 特に印象に残った点・実践したい点

### 4章 過剰コミュニケーションの技術

- 「良いPdMは当たり前のことを必要以上に明確に説明しようとする。悪いPdMは当たり前のことを絶対に説明しない。」
→自分の「当たり前」が他人にとっても「当たり前」とは限らないため。「当たり前」は時にコミュニケーションにおいて大惨事を引き起こす可能性がある。

### 6章 ユーザーに話しかける

- ユーザーリサーチでは一般論ではなく具体的な例をヒアリングする。（その方が答えてもらいやすい）
✕：普段ランチで何を食べますか？一番好きな食べ物は何ですか？
〇：最後に食べた食事について細かく教えてください。

- ペルソナ活用のコツ
  1. ペルソナはリサーチに基づいて設定すること。 そうしなければステレオタイプのペルソナが出来上がる。
  2. ペルソナは定期的に見直す。マーケットも人も時と共に変化していく。
  3. ペルソナを明確にすることで、ターゲットでないユーザーを明確にする。


### 7章 「ベストプラクティス」のワーストなところ
- 他社での成功事例が自社でも成功するとは限らない。
- フレームワークやモデルは有用なフィクションとして活用すべき。成功を保証するものではない。

### 8章 アジャイルについての素晴らしくも残念な真実
- アジャイルの本質は「コラボレーションする、デリバリーする、内省する、改善する」の4点。
→思考停止で「アジャイルだから～しなければならない」と考えること自体がそもそもアジャイルに違反している。
- アジャイルな取り組み（デイリースタンドアップ等）が上手くいっているかどうかを判断するためには以下の質問を考えるとよい。
  1. その取り組みの目的は何か？
  2. その取り組みの目的の達成度を10段階で表すと？

### 9章 ドキュメントは無限に時間を浪費する
- ロードマップのREADMEを作成して、ロードマップに対するチームの共通理解を作る。
- 最高のドキュメントは不完全。（あえて議論するきっかけを残す）
- 最初のドラフトは原則1ページ、また1時間以内に作成すること。
→私の経験的にも、詳細まで丁寧に書いた長編のドキュメントよりも、本当に伝えたいことだけ書いたシンプルなドキュメントの方が圧倒的に読んでもらいやすい。
- 人にテンプレートを埋めるように依頼する前に最低三回は自分で埋める。

### 10章 ビジョン、ミッション、達成目標、戦略を始めとしたイケてる言葉たち
- アウトプットとアウトカムのシーソー（アウトカムを具体的に決めれば、アウトプットは柔軟に決定できるようになる。）
- 戦略と日々の職務実行はつながりのあるものでなければならない。（日々の業務の意思決定に役立つものでなければならない。）
- 優れた戦略はシンプルで明快。パワーポイントを使って延々と説明する必要のないもの。
- 優れた戦略の特徴
  - 「ユーザーは誰？」「解決したい課題は何？」「私たちがその課題を解決するのにふさわしい会社である理由は？」といった単純な質問に答えられるもの。
  - チーム全員が暗唱できる1,2行のもの。
  - 「何を作らないか」を決めるときに役立つもの。
  - しばらくすると古臭く思えてくる。(定期的な見直しが必要)


### 12章 優先順位づけ：すべてのよりどころ
- 引き算の解決策
→機能、機能性を引き算(削除)することがユーザーやビジネスにとって付加価値になる場合もある。


以上です。次は前職で出向先子会社→親会社に復帰するときに、出向先の上司からもらった「ジョブ理論」を読みたいと思います！
cisco 1832i backupimageについてのメモ

先日、1832iのpriorityとbackupのOSを共に目的のバージョンへ変更しようとしたところ
何度かやり直す羽目になったのでメモ。

APのOSはそれぞれ part1 / part2 どちらを priority として立ち上げるかを決めてから
OSを読み込んでいるようで、<font color="Red">show boot</font> コマンドで確認が可能。

```
AP-Name#show boot 
BOOT path-list:      part1
Console Baudrate:    9600
Enable Break:        yes
Manual Boot:         no
Memory Debug:        no
Crashkernel:         
```
<font color="White"></font>
<font color="White"></font>
読み込む path については、part1=priority、part2=backup では無いよう。

OS立ち上げ後に<font color="Red">show version</font> コマンドで priority と backup が出力される。
現在priorityとして立ち上げているOSのバージョンを確認することができる。

```
AP-Name#show version

～中略～

Processor board ID xxxxxxxxxxx
AP Running Image     : 8.10.130.0
Primary Boot Image   : 8.10.130.0
Backup Boot Image    : 8.5.140.0
```
<font color="White"></font>
<font color="White"></font>
<font color="Red">config boot path</font> コマンドで part1 / part2 の切り替えを行える。

[Cisco Aironet Wave 2 アクセス ポイント リリース 8.7 コマンド リファレンス](https://www.cisco.com/c/ja_jp/td/docs/wireless/access_point/wave2-ap/command-reference/8-7/b-cisco-wave2-ap-cr/b-cisco-wave2-ap-cr_chapter_0100.html#wp4029784446)

<font color="White"></font>
<font color="White"></font>
OS立ち上げ前に、Hit ESC key to stop autoboot: の5秒カウント中にEscを押下し、
U-bootモードで切り替えも可能。

```
Power Type: 802.3af POE or Others detected...
Signature returns 0
BL signing verification success, continue to run... 
Auto boot mode, use bootipq directly

Hit ESC key to stop autoboot:  5
```
[AP 1832 1852 で Secondary Image で起動させる方法](https://community.cisco.com/t5/tkb-%E3%83%AF%E3%82%A4%E3%83%A4%E3%83%AC%E3%82%B9-%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88/ap-1832-1852-%E3%81%A7-secondary-image-%E3%81%A7%E8%B5%B7%E5%8B%95%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95/ta-p/3163661)
記事を書く目的と構成について

# 記事を書く目的
目的は、2つあります。

**＜1つ目＞**
　自分が作業で学んだ内容の整理と理屈を確認すること。

**＜2つ目＞**
　新人エンジニアが記事を読んで何かの手助けになること

## 1つ目の目的について
1つ目については、教えてもらった内容や学んだ内容を自分で解釈し、
どのような理屈（仕組み）になっているかを理解したいと思い、設定しました。

作業をしていて、どのように進めてよいか分からなかった内容を教えてもらうことがありましたが、理屈を教えてもらえず、修正方法や記載内容など。「答え」だけを教えてもらうことが多く、なぜその「答え」になるか分からない場面が多くありました。

また、１～2年目で知識がない中説明を受け、「何を言っているんだろう・・」状態になり、説明された内容のついていけない、何が分からないか分からない状態になり、整理ができないことがよくありました。

「答え」を出すための理屈を理解する「解釈する場」や教えてもらった内容の「整理をする場」として記事を書き、エンジニアとして必要な知識を蓄えたいと考え、目的を設定しました。

## 2つ目の目的について
2つ目については、知識があまりない新人エンジニアという弱い立場の方の役に立てれればと思い、設定しました。

知識がなく右も左も分からない中、何を聞いて作業を進めてよいか、作業で困ったことをどのように（ツールやエディタなど使って）解決するか分からないことが多くあると思います。

新人が疑問に思うことや分からないことを何とか解釈した内容を質問すると、「当たり前のことなんで聞くの」、「馬鹿だろ」など理不尽に責め立てられてしまい、理不尽に壊されてしまうことがあることをよく聞きます。

自分としては、
「仕事ができる（裁量権がある）からといって人を壊してよい」
ことは間違っていると強く思っています。

弱い立場のエンジニアを理不尽に壊されないよう、何か手助けになれればと考え記事を残してみようと思いました。

# 記事の構成について
記事を次のような構成で作成していこうと考えています。

＜記事構成＞
　1、事象について
　2、教えてもらった内容
　3、教えてもらった内容の補足や調べた内容
　4、実際の使用方法

## 1、事象について
どのようなことで困ったのか、問題が起きたのかをイメージしやすくすることを目的として記載します。

## 2、教えてもらった内容
教えてもらった内容をそのまま記載します。
。

## 3、教えてもらった内容の補足や調べた内容
「2、教えてもらった内容」から、内容を解釈するのに、どのように解釈したか、どのように調べたかを記載して、自分がどう整理したかを思い出せることを目的として記載します。

## 4、実際の使用方法や使用のされ方
作業イメージや解釈イメージを湧かせやすいことを目的として記載します。
キャプチャーや図などを使用して、内容をまとめたいと考えています。
Nishika 金融時系列分析18位解法


<br>

[実際の順位表](https://competition.nishika.com/competitions/finance_ts/ranking)

![ranking.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181973/149053ec-32aa-3bea-652d-8212e3601d42.png)



<br>

## TLDR

- 基本的には[このトピック](https://competition.nishika.com/competitions/finance_ts/topics/630)をそのまま丸パクリ。
- 加えて、説明変数のクラスタリングにより説明変数の総合得点化を行った。
- クラスタ数・アンサンブルするモデル数・エポック数についてハイパーパラメータ探索を行った。その際の評価を慎重に行った。
- Notebookは[こちら](https://competition.nishika.com/competitions/finance_ts/topics/640)


<br>

## コンペ概要

> 本コンペでは、金融関連企業様のデータを用いて、数百の匿名特徴量を用い、金融に関する或るターゲット値を予測することをテーマとします。
> 予測精度の評価はcosine similarityにて行います。
> このコンペティションでは、テストデータの約29%により暫定スコアが計算され、残りの約71%により最終スコアが計算されます。


https://competition.nishika.com/competitions/finance_ts/summary より引用


特徴量が匿名であり、この項目はどういう意味があるのか、などの推測が難しくなっている。

また、評価指標がコサイン類似度であることもなかなか癖があり、難しい点と個人的には思う。


<br>

## EDA

- 各説明変数は5段階になっている。アンケート的なものを想像し、似たような項目はまとめて総合得点化することが効果的かもしれないと考えた。
- targetの値が10段階しかないことがわかる。
  - 最終的には連続値として回帰を行ったが、multiclassで10クラスの確率を予測し、10クラスの値を予測確率で重みつき平均をとったものも効果的だったように思う。[^1]
- [こちらのトピック](https://competition.nishika.com/competitions/finance_ts/topics/629)より、スコアのばらつきが大きそうであることを確認。


[^1]: 単純に前処理も何もせず、shuffleありの5-foldで10クラスの分類をLightGBMで行い、重みつき平均を行ったものが、privateスコアは0.037098と2位相当のスコアになっていた。しかしpublicスコアが0.031396と少々低く、最終提出の中に含めることはできなかった。[実際のnotebook](https://competition.nishika.com/competitions/finance_ts/topics/651)

<br>

## 前加工＋モデル作成

- 説明変数の類似項目がどれかは匿名化によって一見では分からないため、[こちらのブログ](https://datadriven-rnd.com/hierarchical-clustering/)を参考に、相関係数（絶対値はかけなかった）で説明変数のクラスタリングを行った。
  - クラスタ数を後述のハイパーパラメータとして探索し、220を採用した。このクラスタ内の説明変数の和を新たな説明変数として用い、変数を220まで減らすことができた。
    - もちろん、説明変数を減らすことで情報が減っているので、やるべきかという問題はある。
    - 絶対値をかけてクラスタリングを行い、その正負を考慮して和を取る方が良さそうだが、すぐには実装が思いつかなかったため断念。
- [こちらのトピック](https://competition.nishika.com/competitions/finance_ts/topics/630)より、以下の2点を丸パクリ。
  - グループ (id // 10,000) の追加。テストデータのグループは66に設定。
  - LightGBMでの回帰モデルを作成とバギングとアンサンブル


<br>

## ハイパーパラメータの調整

- クラスタ数・アンサンブルするモデル数・エポック数についてハイパーパラメータ探索を行った。
  - trainデータを40万件と26万件に分けてコサイン類似度のスコアを見て最も良さそうなパラメータを採用する。
  - その際に、±0.01程度スコアが前後することが分かっていたので、26万件からランダムに29%と71%に分けて1000回スコアを出してその分布（平均値）を見ることにより決定した。
  - また、publicスコアが低い（分布の下側にいる）場合にprivateスコアが高くなる（分布の上側にいる）傾向にあるような気がしたが、提出したpublicスコアが高いか低いかわからないしあまり意味はない？


<br>

## 結果

以上の方法により、Publicスコア0.049781、Privateスコア0.033341で18位となった。

（Publicスコアは黒魔術[^2]入りのものが0.0565と自己ベストだったが、そちらのPrivateスコアは0.014404。）

[Nishika内のトピックにnotebookアリ](https://competition.nishika.com/competitions/finance_ts/topics/640)

宝くじ・運ゲーコンペと噂されているように、偶然で上位に行く可能性が十分にあるコンペだと思われるので、今回の解法が良いものかは分からないが、実際大きなshakeが起きなかったので、ハイパーパラメータ探索などにおいて堅いものを選べたのではないかと思っている。

[^2]: 丸パクリしたトピックに記載のある後処理。
エンティティ認証技術

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/8ce1cb3f-d428-76da-17c6-6fd2e89dbd22.png)
　エンティティ認証（主体認証）は、ユーザやホストが本物であるのかどうかを確かめる技術です。エンティティ認証は、本人だけが知っている知識の有無を確認する、本人だけが持っている所有物を確認するといった方法で行います。本人だけが知っている知識の有無を確認する方法には、パスワード認証があります。本人だけが持っている所有物を確認する方法には、バイオメトリクス認証やICカードによる認証があります。

１：パスワード認証
　正しいパスワードを知っているかどうかで本人の確認をします。クライアント側でユーザIDとパスワードを入力し、それらをサーバに送ります。サーバ側では、サーバに登録されているユーザID、パスワードと一致するのかを確認します。一致すれば、本人であるとみなします。
　なお、サーバでは、パスワードをパスワードファイルと呼ばれるファイルに登録しておきます。パスワードファイル中にパスワードを平文で記録しておくと、攻撃を受けてパスワードファイルが盗まれてしまった時に、大量のパスワードが漏洩してしまいます。そこで、パスワードのハッシュ値をパスワードファイルに登録しておくことが一般的です。この場合、サーバは、送られてきたパスワードのハッシュ値を計算し、パスワードファイル中のハッシュ値と一致するかどうかで、正しいパスワードが入力されたかどうかで、正しいパスワードが入力されたかどうかを判断します。

２：チャレンジレスポンス認証
　パスワードを平文でサーバに送ると、途中で第三者に盗聴され、盗み取られてしまう危険があります。パスワードを暗号化したとしても、盗んだユーザIDと暗号化パスワードをそのまま利用して認証を受けること（リプレイ攻撃）が可能ですから、危険性は減りません。そこで、サーバにパスワードを直接伝えることなく、確かにパスワードを知っていると確認させる方法が考え出されました。チャレンジレスポンス認証です。チャレンジレスポンス認証では、パスワードを「使う」ことによって、知っていることの証です。

「チャレンジレスポンス認証の手順」
①サーバが乱数を用いて数値を作ります。これをチャレンジと言います。チャレンジが、毎回同じ値だとリプレイ攻撃の対象にされて危険ですので、乱数で毎回異なった値にするところが肝心な点です。

②チャレンジをクライアントに送ります。クライアントは、パスワードを鍵として使って、チャレンジを暗号化します。暗号化されたチャレンジをレスポンスと言います。

③レスポンスをサーバに送ります。途中で第三者が盗聴していたとしても、レスポンス（暗号化された暗数）が第三者の手に渡るだけなので、実害はありません。レスポンスから、暗号化に使った鍵（パスワード）を推測することはほぼ不可能です。

④サーバは、パスワードファイルに登録されているパスワードを鍵として使って、レスポンスを復号します。復号して得られた数値とチャレンジを比較します。両者が一致した場合、すなわち、正しく復号できた場合は「クライアントは登録されているパスワードを鍵として使って暗号化した」ことになります。登録されているパスワードを鍵として使えるのは本人しかなません。つまり、クライアントは本人です。

「公開鍵を用いたチャレンジレスポンス認証」
　チャレンジをパスワードで暗号化していたことに代えて、チャレンジにクライアント（ユーザ）の秘密鍵を使ってディジタル署名をつけ、このディジタル署名をレスポンスとして返す方法があります。サーバでは、受領したディジタル署名をクライアント（ユーザ）の公開鍵を利用して認証します。このような方法を、公開鍵における認証と言っています。なお、サーバがディジタルh染井の認証に利用する公開鍵は、事前にサーバに登録しておくか、公開鍵証明書をその都度サーバに送るします。

３：バイオメトリクス認証（生体認証）
　バイオメトリクス認証は、指紋、声、顔といった生体情報で本人確認を行う方法です。代表的なものに、
①指紋：光学式センサや薄型静電式センサを用いて、特徴点抽出方式やパターンマッチングにより照合する。

②声帯：事前に登録した音声の周波数パターンと照合する。

③虹彩：虹彩（目の奥の模様）のパターン照合する。

④掌の静脈：LED光源からの赤外線照射をお行い、静脈のパターンを照合する。

があります。

　登録されている生体情報とのチェックを厳しくすると、指に怪我をしたとか、風邪でガラガラ声であったとか、そういったことでも、登録されている生体情報と違うと判断されてしまいます。本人でも認証に失敗するわけです。このように本人でもに認証に失敗する確率を本人拒否率（FRR）と言います。
　一方で、本人拒否率を下げようとして、登録されている生体情報とのチェックを甘くすると、少しの違いは気にしないことになります。その結果、他人でも認証されてしまいます。このように、他人であっても認証に成功する確率を他人受入率（FAR）と言います。

結局、
・他人拒否率を下げると他人受入率は上がる。
・他人受入率を下げると本人拒否率は上がる。
のです。運用の利便性とご認証の度合いを考慮して、適切なレベルでチェックすることが重要です。
EC2上のUbuntuコンテナで、perfを使う準備

メモる。
ホストのカーネルは、Ubuntu22.04 


# 手順

以下最初の1回目のみ。

```sh
sudo apt update && sudo apt install -y docker.io
sudo /bin/su -c "echo 'kernel.perf_event_paranoid = -1' >> /etc/sysctl.conf"
sudo sysctl -p
```

<details>
<summary>必要な理由</summary>

これをすっ飛ばすと、perf record 実行時の以下のエラーが発生する。

```sh
$ sudo perf record miniruby

# Error:
# Access to performance monitoring and observability operations is limited.
# Consider adjusting /proc/sys/kernel/perf_event_paranoid setting to open
# access to performance monitoring and observability operations for processes
# without CAP_PERFMON, CAP_SYS_PTRACE or CAP_SYS_ADMIN Linux capability.
# More information can be found at 'Perf events and tool security' document:
# https://www.kernel.org/doc/html/latest/admin-guide/perf-security.html
# perf_event_paranoid setting is 4:
#   -1: Allow use of (almost) all events by all users
#       Ignore mlock limit after perf_event_mlock_kb without CAP_IPC_LOCK
# >= 0: Disallow raw and ftrace function tracepoint access
# >= 1: Disallow CPU event access
# >= 2: Disallow kernel profiling
# To make the adjusted perf_event_paranoid setting permanent preserve it
# in /etc/sysctl.conf (e.g. kernel.perf_event_paranoid = <setting>)
````

</details>




以下の内容をDockerfileとしておく。

```dockerfile
FROM ubuntu:22.04
# For apt intall gcc (ref. https://www.linuxmaster.jp/linux_blog/2022/02/ubuntu2004failed-to-fetch-404-not-found.html)
RUN rm -rf /var/lib/apt/lists/*
RUN apt update
RUN apt install -y \
  # sudo \
  curl \
  git \
  gcc \
  autoconf \
  gperf \
  ruby \
  make \
  bison
RUN git clone -b ruby_3_1 https://github.com/ruby/ruby.git
WORKDIR /ruby
# https://docs.ruby-lang.org/en/master/contributing/building_ruby_md.html
RUN ./autogen.sh
RUN mkdir build
WORKDIR /ruby/build
RUN mkdir ~/.rubies
RUN ../configure --prefix="${HOME}/.rubies/ruby-master"
RUN make miniruby

RUN apt install sudo
RUN sudo apt install -y\
  linux-tools-$(uname -r) \
  vim
# ref. https://qiita.com/k0kubun/items/b094c4b9bd4fe0027a48
RUN sudo apt install -y libc6-dbg
RUN touch ../test.rb
```

ドッカーイメージをビルドし、コンテナ内に入る。

```sh
sudo docker build . -t fsp
sudo docker run -it --privileged fsp /bin/bash
```

コンテナ内で、`../test.rb`を編集し、プロファイリングしたいRubyプログラムを書く。
以下でプロファイリングする。

```
perf record -- ./miniruby ../test.rb
perf report
```
wp typerocket proのプラグイン作成ジェネレーターが便利

# 概要

WordPressに対してモダンな処理を追加するtyperocketなるプラグインを見つけたため有料機能になりますが、購入して試してみました。

https://typerocket.com/docs/v6/get-started/


## typerocketを継承したプラグインを作成する
typerocketをインストールして初期設定をするとGalaxy コマンドが利用できるようになります。

プラグインの雛形を作成します。

```php
php galaxy make:plugin MyPluginName "My Plugin"
```

作成されたプラグインをインストールするとwp_optionsに対して値を保存する簡単なプラグインが作成されます。(BasePluginというクラスを継承しています)

![test2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280639/abf23607-140a-85e5-b66d-1f1876087fac.jpeg)


### マイグレーションファイルを作成する
マイグレーション機能をつける事もできます。laravelのようにphpでマイグレーションファイルを作成することもできるようですが、デフォルトはsql

```php
php galaxy_my_plugin make:migration add_my_custom_table
```


```sql:1694948655.add_my_custom_table.sql
-- Description: For reusable page builder components
-- >>> Up >>>
CREATE TABLE `{!!prefix!!}my_custom_tables` (
  id bigint(20) unsigned NOT NULL auto_increment,
  name varchar(191) NOT NULL default '',
  value longtext NOT NULL,
  PRIMARY KEY  (id),
  UNIQUE KEY name (name)
);

-- >>> Down >>>
DROP TABLE IF EXISTS `{!!prefix!!}my_custom_tables`;
```


### モデルを作成する
laravelのようにリレーションも貼れるようです。
```php
php galaxy_my_plugin make:model base my_custom_table
```


## 感想
無料版ではプラグイン作成機能が使えないのが残念です。
有料版を購入すれば、独自機能の開発が高速化するのは間違いなさそう。
(買い切りライセンスなら良かった...)

以前は似たようなプラグインで「wp-mvc」がありましたが、メンテナンスが止まっていそうなので、今後使うならtyperocketかなと思います。

https://wpmvc.org/

他にもWordPressに対してMVCを追加するプロジェクトなどがありますが、ディレクトリが独自になったりする

https://www.rareloop.com/posts/comparing-modern-mvc-wordpress-frameworks/?s=06
Xcodeでスペースを表示する方法

SwiftUIを勉強中なので、Xcodeを使用しているのですが、スペースが余分に入っている箇所などがあり、パッと見わからないので、表示する方法を探しました。


Editor -> invisibles 

![スクリーンショット 2023-09-17 21.44.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/88661edf-121d-13fe-343c-8f5d399141c9.png)


こちらにチェックが付くとスペースが見えるようになります。

![スクリーンショット 2023-09-17 21.44.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274615/160649ec-df81-98be-fd53-60fd573376be.png)

パソコンを買い替えた時など再度設定する時に忘れているかもしれないので、見直せるように残しておこうと思います。
基本情報対策：小学生にもわかる？Classを使った単方向リストの作成。

単方向リストは以前結構学んで、大分自信がついてきたので色々といてみたのですが、

サンプル問題のこちらの問題の動きがいまいちわからず、動きをしっかり追ってみました。

python での記述です。

## 問題：問題なので、こちらのコードは実行できません。

太文字が問題です。

```python
class ListElement:
    def __init__(self, val):
        self.val = val
        self.next = None

# 大域変数の初期化
ListHead = None
curr = None
#current現在地
prev = None
#previosひとつ前

def append(qval):
    global ListHead  # 大域変数を参照するためのキーワード

    curr = List(qval)  # 新しいリストの要素を作成

    if  **<問題A:ListHeadが未定義　or 未定義でない>** :  
        ListHead = curr
    else:
        prev = ListHead
        while prev.next is not None:
            prev = prev.next
        prev.next = **<問題B：ここに何が入るかな？>**
```

### 回答：

問題A:未定義

問題B：curr

なんとなく解けるのではないでしょうか。

ただコードをの動きがいまいちわかりませんね。

## 疑問：

1. if ListHead is None:は実行されるのか？

2.while prev.next is not None:はループに入るのか？

3.while prev.next is not None:は何回実行されるのか？

4.curr,prev,prev.nextの動き

そのため実際にコードを修正し、実行できるようにしてみました。

A,B,Cの順番でリストに入れます。

### 実行用コード：

```python
class ListElement:
    def __init__(self, val):
        self.val = val
        self.next = None

# 大域変数の初期化
ListHead = None
curr = None
prev = None

def append(qval):
    global ListHead, curr, prev  # 大域変数を参照するためのキーワード

    curr = ListElement(qval)  # 新しいリストの要素を作成

    if ListHead is None:  # リストが空の場合
        ListHead = curr#ここで初めてリストの参照ができる。
    else:
        prev = ListHead
        while prev.next is not None:
            prev = prev.next
        prev.next = curr

# A, B, Cをリストに追加
append("A")
append("B")
append("C")

# 確認のためにリストの内容を表示
def print_list():
    global ListHead
    temp = ListHead
    while temp:
        print(temp.val)
        temp = temp.next

print_list()
```

実行できたのではないでしょうか。

## 動きを考えてみよう！
    Aの参照を1とするまた、B:2，C:3とする！
### 1. if ListHead is None:は実行されるのか？

1**.Aを追加するとき**

- 初めて**`append`**関数が呼び出されると、**`curr`**は新しい**`List`**オブジェクト（A）の参照（1）を保持します。
- **`ListHead`**はまだ**`None`**なので、**`ListHead`**に**`curr`**の参照（1）が設定されます。
- **if ListHead is None:ここで実行される**
- **`prev`**はまだ使用されていません。

状態：

- **`ListHead`** = 1（Aの参照）
- **`curr`** = 1（Aの参照）
- **`prev`** = 未使用

### while prev.next is not None:のループには入るのか？

**2.Bを追加するとき**

- **`append`**関数が再度呼び出され、**`curr`**は新しい**`List`**オブジェクト（B）の参照（2）を保持します。
- **`ListHead`**はAの参照（1）なので、elseブロックに進みます。
- **`prev`**に**`ListHead`**の参照（1、Aの参照）が設定されます。
- **`prev.next`**は**`None`**（Aの次の要素はまだない）なので、whileループは実行されず、直接**`prev.next`**に**`curr`**（Bの参照、2）が設定されます。
- **while prev.next is not None:には今回はループに入らない。**

状態：

- **`ListHead`** = 1（Aの参照）
- **`curr`** = 2（Bの参照）
- **`prev`** = 1（Aの参照）
- **`prev.next`** = 2（Bの参照）

**3.Cを追加するとき**

- **`append`**関数が再度呼び出され、**`curr`**は新しい**`List`**オブジェクト（C）の参照（3）を保持します。
- **`ListHead`**はAの参照（1）なので、elseブロックに進みます。
- **`prev`**に**`ListHead`**の参照（1、Aの参照）が設定されます。
- **`prev.next`**はBの参照（2）なので、**whileループに入ります。**
- **`prev`**はBの参照（2）に更新され、その**`prev.next`**（Bの次の要素）は**`None`**です。ループは終了し、**`prev.next`**に**`curr`**（Cの参照、3）が設定されます。

状態：

- **`ListHead`** = 1（Aの参照）
- **`curr`** = 3（Cの参照）
- **`prev`** = 2（Bの参照）
- **`prev.next`** = 3（Cの参照）

最終的に、**`ListHead`**がAを指し、Aの**`next`**がBを指し、Bの**`next`**がCを指す形の単方向リンクドリストが完成します。

## 結果：

何か問題によって考え方が結構違うので、問題解きまくるしかないなあ。

prev.next.nextを最後に使う、どこに使うかわからないコードよりはだいぶましな問題だとは思う。
Apache Digest認証の設定とユーザー登録・削除を実施してみた

# はじめに
Apache Digest認証の設定とユーザー登録・削除を実施してみました。

以下の記事を参考にしました。
https://qiita.com/miyuki_samitani/items/ccf9217a058019ca8d59
https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/699apachedigest.html
https://www.javadrive.jp/apache/allow/index9.html#section4

# 設定手順

````
# vi /etc/httpd/conf/httpd.conf
````
以下の行を追加しました。
````
   130  # Further relax access to the default document root:
   131  <Directory "/var/www/html">
   132      AuthType Digest
   133      AuthName "Digest Auth"
   134      AuthUserFile "/etc/httpd/conf/.digestpass"
   135      Require valid-user
   136  </Directory>

````
## Digest test1ユーザー登録した


````
htdigest [-c] パスワードファイル レルム ユーザー名
````

````
#  htdigest -c /etc/httpd/conf/.digestpass "Digest Auth" test1
Adding password for test1 in realm Digest Auth.
New password: <パスワード設定>
Re-type new password: <再度パスワード設定>
````

## Digest test2ユーザーを登録した
-cオプションは新規にパスワードファイルを作成するため
ユーザー追加する際は-cオプションは不要です。
```
# htdigest /etc/httpd/conf/.digestpass "Digest Auth" test2
Adding user test2 in realm Digest Auth
New password: <パスワード設定>
Re-type new password: <パスワード設定>
[root@localhost conf]#
````

## パスワードファイルの中身を確認してみた
2つのユーザーがパスワードファイルに登録されていることを確認した
```
# cat /etc/httpd/conf/.digestpass
test1:Digest Auth:60d5cda3e4411ac0226f838a6cf6be4c
test2:Digest Auth:21b5fbaf7785f1f60f55850aaae62047
```
## apacheの文法チェックした
```
httpd -t
```
### apacheサービスを再起動した
```
systemctl restart httpd
```
## ブラウザでログイン確認した
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/6621732e-330d-8739-1b2c-ad15f81a3b86.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/c0c8b773-a1c1-4978-7446-651376775aeb.png)


## Digest test1ユーザーを削除しました
ユーザー削除後はapacheの再起動は不要です。
```
# vi /etc/httpd/conf/.digestpass
```

変更前
```
test1:Digest Auth:60d5cda3e4411ac0226f838a6cf6be4c ←削除
test2:Digest Auth:21b5fbaf7785f1f60f55850aaae62047　
test3:Digest Auth:e08259e6350386250a31d98c8dbb376b
```
変更後
```
test2:Digest Auth:21b5fbaf7785f1f60f55850aaae62047
test3:Digest Auth:e08259e6350386250a31d98c8dbb376b
```
## ブラウザで削除したtest1ユーザーでログインを試してみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599002/5998d498-1f08-37f4-15c1-574930908865.png)


test1ユーザーでログイン出来ませんでした。

## apacheのアクセスログを確認した
アクセスログを見ると401でUnauthorizedになりました。
参考にしたサイト
https://ipeinc.jp/media/401-error/
```
# tail -n 1 /etc/httpd/logs/access_log
192.168.0.24 - test1 [17/Sep/2023:21:06:03 +0900] "GET /index.html HTTP/1.1" 401 381 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36"
```
# まとめ
ダイジェスト認証をハンズオンする大事さを改めて感じました。
本番環境ではダイジェスト登録時に誤ってhtdigest -c パスワードファイル
で新規にユーザー登録して既存のユーザー情報を誤って消してしまうリスクがあります。
コマンドのオプションの意味を普段から理解して作業する習慣を付けた方が良いです。
gormでtime.Time型を使用する

gormでレコード取得をする際に以下のエラーが出ました。

```bash
sql: Scan error on column index 3, name \"updated_at\": unsupported Scan, storing driver.Value type []uint8 into type *time.Time
```

updated_atカラムの型をサポートしてない的なことが書いてあるので少し調べました。

## 解決策

gormの公式ドキュメントにも記載がありましたが、
time.Time型を扱うには、接続時のDSN情報に`parseTime`を指定する必要がありました。

> 注 time.Time を正しく処理するには、パラメータとして parseTime を含める必要があります。 (その他のパラメータ) UTF-8 エンコーディングを完全にサポートするには、 charset=utf8 を charset=utf8mb4 に変更する必要があります。

https://gorm.io/ja_JP/docs/connecting_to_the_database.html

goのsqlドライバのgithubにも詳細が記載されていましたが、
`parseTime=true`と指定をすることで、DATETIME型のデータをtime.Time型に変換してくれるそうです。

> `parseTime=true` changes the output type of DATE and DATETIME values to time.Time instead of []byte / string The date or datetime like 0000-00-00 00:00:00 is converted into zero value of time.Time.
> 
> parseTime=trueは、DATEおよびDATETIME値の出力タイプを[]byte / stringの代わりにtime.Timeに変更します。0000-00-00 00:00:00のような日付または日時は、time.Timeのゼロ値に変換されます。

https://github.com/go-sql-driver/mysql#parameters

なので接続時のDSN情報に`parseTime=true`を追加するだけで問題なく解決できました。

```go
dsn := "root:root@tcp(127.0.0.1:3306)/db_name?charset=utf8&parseTime=true"
```

## 参考

https://stackoverflow.com/questions/45040319/unsupported-scan-storing-driver-value-type-uint8-into-type-time-time