OmniAICreator/Qiita-1.07M huggingface dataset:
ChatGPTを自作Chrome拡張機能でカスタマイズする方法

# ChatGPTをオレオレ機能で強化してえんだッッッ

# いいぞ、許すッッッ

# やり方を以下に教えるッ

その前にイメージ図
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665557/7c9c9072-3aba-11af-9014-09c5798b6536.png)

この例ですと、赤矢印の先にラジオボタンが追加されています。
それでは作り方に行きましょう。

# 流れ
１．フォルダを作る
２．マニフェストファイルを作る
３．ペイントなどでロゴを作る
４．javascriptファイルを作る
５．一式揃ったフォルダをテストの為にChromeへ格納する
６．実行

# １．フォルダを作る
お好きな場所に、以下のような構成でフォルダを作って下さい。
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665557/49f37bd9-d9da-6c9a-04f7-9764473787f1.png)

# ２．マニフェストファイルを作る
```
{
    "manifest_version": 3,
    "name": "your-extension-name",
    "version": "0.0.1",
    "description": "拡張機能の説明文",
    "icons": {
        "16": "icon16.png",
        "48": "icon48.png",
        "128": "icon128.png"
    },
    "default_locale": "ja",
    "action": {
        "default_icon": "popup16.png",
        "default_popup": "popup.html"
    },
    "content_scripts": [
        {
            "matches": [
                "https://chat.openai.com/chat/*"
            ],
            "css": [
                "css/style.css"
            ],
            "js": [
                "js/content-script.js"
            ],
            "run_at": "document_end",
            "all_frames": true
        }
    ]
}
```
2023年現在、manifest_versionは3じゃないとダメらしいです。
default_localeをjpにしていますが、通常はenにしておくと吉。
※jpにすると、messages.jsonファイルを用意しなければエラーとなる

# ３．ペイントなどでロゴを作る

私はファイアーアルパカで作りました。
ロゴ画像のサイズを簡単に変更&保存出来るので。
ペイントでも出来るんでしょうか？

# ４．javascriptファイルを作る
```javascript
function waitForPageLoad() {
    // ページが完全に読み込まれるまで待機する
    if (document.readyState !== "complete") {
        setTimeout(waitForPageLoad, 1000);
        return;
    }

    // 指定した要素が表示されるまで待機する
    const targetElement = document.querySelector('wcg-slash-commands-menu');
    if (targetElement === null) {
        setTimeout(waitForPageLoad, 1000);
        return;
    }

    {
        const newDiv = document.createElement('div');
        const newInput = document.createElement('input');
        newInput.type = 'radio';
        newInput.name = 'radio';
        const newInput2 = document.createElement('input');
        newInput2.type = 'radio';
        newInput2.name = 'radio';
        const newTextNode = document.createTextNode('結果をCSV出力する');
        const newTextNode2 = document.createTextNode('結果をCSV出力しない');
        newDiv.appendChild(newInput);
        newDiv.appendChild(newTextNode);
        newDiv.appendChild(newInput2);
        newDiv.appendChild(newTextNode2);
        targetElement.prepend(newDiv);
    }
}

waitForPageLoad();

```

なんでこんな処理になってるかって言うと、ChatGPT君はページ読み込み後にDOMを作るからです。
なので、DOMが作られるのを待ってから、要素を挿入しています。

# ５．一式揃ったフォルダをテストの為にChromeへ格納する
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2665557/c01d4b3b-a3a7-7649-e8a8-5e875f587aff.png)
Chromeのextensions画面へ移動し、
「パッケージ化されていない拡張機能を読み込む」
で、今回作ったフォルダを指定します。

# ６．実行

拡張機能をChromeの右上の拡張アイコンから有効化します。
その後、ChatGPTへアクセス
すると、冒頭のイメージの通りになります。

# ７．終わり


**実はこれ全部ChatGPT君に全部教わったッ**

**普段javascript触ってないし、拡張機能を作るの初めてだったけど、教わったから40分～1時間で終わったッ**

**余りにもッッッChatGPT君優秀ッッッ！**

**月たったの20ドルッ　すごッ**

**終わりッ**

**良かったら「あったら良いな」っていう機能をコメントして言ってねッ！作るからッ（多分**
Pythonの仮想環境の構築

## 前提のOS
Linux系のOSを前提として記載しています。

## 仮想環境の構築
pythonベースのアプリのスムーズなリリースを行うため、最低限のライブラリ環境を構築するために、標準搭載されている「venv」による仮想環境を構築する。
```
$ mkdir [project directory]
$ cd [project directory]
```
仮想環境の作成
```
$ python3 -m venv [newenvname]
```
仮想環境のアクティベーション
```
$ source [newenvname]/bin/activate
([newenvname])$ #アクティベーションすると括弧付きで仮想環境名が表示される。
```
仮想環境のディアクティベーション
```
([newenvname])$ deactivate
```

解説記事（仮想環境とは）  
https://www.sejuku.net/blog/68423  
  
Pythonでできる事（概要）説明動画  
https://www.youtube.com/watch?v=a9ANhQPvhgY
Flask環境構築手順まとめ

### 構築の前提に必要な知識

### Flaskとは  
Flask（フラスク）は、プログラミング言語Python用の、軽量なウェブアプリケーションフレームワークである。標準で提供する機能を最小限に保っているため、自身を「マイクロフレームワーク」と呼んでいる。そのため、初学者には学習しやすい。しかし、日本語のコンテンツが充実していないのが特徴。Jinja2をテンプレートエンジンとして、WEB開発しやすくなっていて、Pythonベースであるため、バックヤードでは、Pythonプログラミング言語の知識を十分に活かせることができます。  

### Flaskの環境構築
ラズパイ上でFlaskを構築するディレクトリを作成し、仮想環境をアクティベーションする。

以下はLinuxの構築例  
※Windowsの場合は若干差異はあります。

```
$ mkdir hello_flask
$ cd hello_flask
$ python3 -m venv venv
$ source venv/bin/activate
```
(任意)Flaskインストール前の仮想環境にインストールされているライブラリの確認
```
(venv) $ pip list
```

Flaskをインストールする。
```
(venv) $ pip install flask
```

(任意)Flaskインストール後の仮想環境にインストールされているライブラリの確認
```
(venv) $ pip list
Package       Version
------------- -------
click         7.1.2
Flask         1.1.2
itsdangerous  1.1.0
Jinja2        2.11.2
MarkupSafe    1.1.1
pip           18.1
pkg-resources 0.0.0
setuptools    40.8.0
Werkzeug      1.0.1
```  

requirement.txtからパッケージをインストールする場合  

```  
pip install -r requirement.txt
```
  
### host='0.0.0.0'の指定が大事 
--- 
0.0.0.0を指定しない場合は、ラズパイ本体のブラウザのみは動作するが、外部（リモートPC/Mobileなど）からアクセスできない。  
  
### 参考動画  
- [4分半で分かるFlask環境構築](https://youtu.be/M_U0AC_oBXQ)
- [0.0.0.0と127.0.0.1とlocalhostの違いについて](https://youtu.be/yL8zces3hKg)
Gitの使い方まとめ

## gitとは
チームで共同開発する場合コードを共有しながら作業できる技術で、gitコマンドまたは、UIツールを使ってコードの管理を行う。また、CI/CDを駆使した場合、自動ビルド、リリースが可能となる

## Windows PCの場合
[git for windows](https://gitforwindows.org/)をインストールする。

## 個人の識別情報の設定
Git上で誰か作業しているかを識別するための設定
この情報を設定していないとCommitはできない
```
$ git config --global user.name "your name"
$ git config --global user.email "your email"
```

### よく使われるgitコマンド
```terminal
# Githubからクローンする（1回目のみ）
git clone https://<address>

# 2回目以後のクローンではなくoriginと同期する
git pull

# ローカルの変更ファイルすべて追加する
git add .

# 限定したファイルを追加（Pythonファイルのみ）
git add *.py

# 追加変更の内容を確認する
git status

# コミットする
git commit -m 'コミット内容'

# プッシュする
git push

# ローカルブランチとリモートブランチを指定してpushする
git push origin <local branch>:<remote branch>

# ローカルブランチとリモートブランチを指定してpushする（強制）
git push -f origin <local branch>:<remote branch>

#現在のブランチを確認する
git branch -a

#ブランチを切り替える
git switch <branch_name>

```

### SSL検証の無効化
gitの設定にSSL検証の無効化を行っていましたが、セキュリティ的によろしくないとのことなので、次の設定を行ってしまった場合は、設定の削除を実施してください。
このリポジトリのオレオレ証明書のSSL検証を無効化の設定
```
$ git config --global http.sslVerify false
```
SSL検証を無効化の設定の削除
```
$ git config --global --unset http.sslVerify
```

#### 環境によって上手く接続できない場合は以下を実行  
OS情報 :　
Linux raspberrypi 4.19.118-v7+  
Debian 10.4

```
$ sudo apt-get install --reinstall ca-certificates
$ sudo mkdir /usr/local/share/ca-certificates/cacert.org
$ sudo wget -P /usr/local/share/ca-certificates/cacert.org http://www.cacert.org/certs/root.crt http://www.cacert.org/certs/class3.crt
$ sudo update-ca-certificates
$ git config --global http.sslCAinfo /etc/ssl/certs/ca-certificates.crt
$ git config http.sslVerify false
```

---
## git コマンド
gitコマンドは色々ありますが、ひとまずgitbucketのリポジトリ複製を行うgit cloneコマンドを記載します。

### git clone(リポジトリの複製)
オレオレ認証によるhttpsを設定しているため、git cloneコマンドを実施する際は、オプション「GIT_SSL_NO_VERIFY=true」を付してください。  
実行例：対象リポジトリ「respi_works/basic」
```
GIT_SSL_NO_VERIFY=true git clone https://mjec.ddns.net:39862/git/raspi_works/basic.git
```
# git の使い方
*** 
```
#ローカルのブランチをリモートのブランチから強制上書きする
git reset --hard origin/<branch_name>

#強制Push
git push -f

#ブランチの切り替え
git switch <branch_name>

#変更を追加、コミット、Pushの一連操作
git add .
git commit -m "<commit text>"

#コミットの内容を上書き（変更Editerを表示しない）
git commit --amend --no-edit

#push （上記のコミットの場合は、強制上書きしないとPushできない）
git push -f origin local_branch:origin_branch

# gitコメントまとめる（2はコミットの階層を示す）

git rebase -i HEAD~2
editerでpick=>squashにして閉じる
再度#を入れて閉じる
git push -f origin local_branch:origin_branch

#現在のブランチを確認する
git branch -a   

#ブランチ削除(Local)
git branch -D <Local_branch>
 
#リモートブランチ削除する場合
git push --delete origin branch_name

#リモートブランチで削除されたブランチを反映する
git fetch -p 

#リモートブランチをマージする場合
git merge origin <ブランチ名>

#取得と作成を同時に行うとき
git checkout -b create_branch origin/copy_from_branch 

#コミットをなかったにすることができる
git rest --soft HEAD

#ローカルブランチを最新にする方法
git branch -a
git fetch origin -p
git reset --hard origin/<branch_name>
git log

#上書きコミットする方法
git add .
git commit --amend --no-edit
git push -f origin <local branch>:<remote branch>

#状態を確認
git log

#行動履歴を見る
git reflog

#Originの情報を見る
git remote -v
```
ChatGPTとA-Frameで遊びました

# 概要

楽しそうなイベントがあったのでChatGPT入門のため参加してみました。

ChatGPTとA-Frameで遊ぼう - connpass
https://xr-fukuoka.connpass.com/event/278334/

https://youtu.be/FFQSKJUCBm0

ChatGPTに何をどのように伝えればいいかをシンプルなサンプルで解説いただいてわかりやすかったです。成果物もかなり遊べるものでした。以下のページで公開されてます。ChatGPTのAPIKeyがあれば試せます。

GitHub - TakashiYoshinaga/ChatGPT-A-Frame-Sample
https://github.com/TakashiYoshinaga/ChatGPT-A-Frame-Sample

# A-Frame

ブラウザで3Dシーンを手軽に作れる楽しいフレームワーク。

A-Frame – Make WebVR
https://aframe.io/

# サンプルの仕組み

作って欲しいシーンをChatGPTに投げて、返ってきたコードを抽出してページに埋め込んでそのままプレビューできる、という仕組みでした。なるほど、いいアイデア。

https://www.docswell.com/s/Tks_Yoshinaga/5Q882V-ChatGPT#p1

## ChatGPTへのリクエスト

このサンプルでChatGPT APIを使ってどんな感じにリクエストするのかがよく理解できました。

**キャラ付けできる**

A-Frameのコードを描いてくれるキャラとして指定することで、より正確な答えを返してくれるようになる、ということだと思います。サンプルでは以下のようなキャラ付けがされてました。role="system"を使ってこの情報を伝えるということでした。

> role: "system", content: "あなたA-Frameバージョン1.4.0以降のPrimitive Elementのタグを教えるアシスタントです。"

**命令を伝える**

role="user"を使って作って欲しいシーンを文章で伝えてリクエストします。使ってほしくないタグなどがある場合は文章に含めることで考慮したコードを返してくれます。結果をコードブロックに記述してもらうことで、回答からコード部分を抽出できる工夫がされてました。

> role: "user", content: "立方体を描いてください。a-camera,a-assets,a-animation,a-lightは使用しない。結果はコードブロックに記述。"

**過去の文脈も反映**

https://www.docswell.com/s/Tks_Yoshinaga/5Q882V-ChatGPT#p75

受け取った回答をrole="assistant"として追加し、さらに命令を追加してChatGPTにリクエストすることで過去のやり取りを考慮した回答が得られるということでした。そうすることで「立方体を描いて」の後に「その立方体を半分のサイズにして」みたいなやりとりでシーンを作っていくことができました。

また、受け取った回答の必要な部分だけ（今回だとコードブロックだけ）をassistantとして追加することで、ChatGPTからのレスポンス向上、利用料削減が期待できるというアイデアも紹介いただきました。ちょっと改ざんして伝える、これはいろいろ使えそう。

# サンプルで遊んだ結果

３つの立方体を描いてもらいました。

![2023-03-25_11h28_59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/2f7c6350-3602-f041-4438-9b084660b992.png)

同じ命令でも違う結果になります。

![2023-03-25_11h30_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/c3d285f3-67ca-a9a9-3c80-e34fa1698be2.png)

雰囲気のある背景が貼られました。どこから拾ってきたんだろう。

![2023-03-25_11h39_39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/579071/8d8b12d3-1cbc-6d18-8ad5-fbab389c4646.png)

# 感想

なかなか指示が伝わりにくいときもありましたが、それも含めて楽しめました。gpt-4だともっと賢いんでしょうね（しかしまだ料金高そう）。2時間でさっくり入門できてとてもいいイベントでした。ありがとうございました。
Linuc(学習用）

●SSH・・安全に通信するための仕組み

・SSHに関係するファイル（＊クライアント側）
・ssh_config(configは設定の意味。クライアント側のSSHの設定）
・id_rsa(rsaは暗号の意味。秘密鍵）
・id_rsa.pub(公開鍵）
・known_hosts(ホスト認証のための公開鍵）

＊ホームディレクトリ直下の.sshに保存される

・SSHに関係するファイル（＊ホスト側）
・sshd_config（dがつくとホスト側）
・ssh_host_rsa_key(秘密鍵）
・ssh_host_rsa_key.pub(公開鍵）
・authorized_key(クライアントが認証した鍵）

＊基本的には／ectディレクトリ直下のsshファイルに保存

①公開鍵と秘密鍵のペアを作成
ssh-keygen・・sshの公開鍵と秘密鍵を作成
②公開鍵をリモートホストに登録
ssh-copy-id・・クライアントが作成した公開鍵をサーバーに登録
③sshでリモートホストにログイン
ssh
④sshでリモートホストからログアウト
exit

●仮想マシン・・OSの上に仮想的なコンピュータを作成する
①ホストOS型・・仮想化ソフトをダウンロードすることで構築できる、
②ハイパーバイザー型・・Linuxで用いられる仮想化の手段、

・KVN・・Linuxカーネルに標準的に組み込まれている仮想化システム、ハイパーバイザ型
・Libvirt・・仮想マシンの管理を便利にするためのソフトウェアの集まり

●コンテナ・・そのアプリケーションが必要とする設定をまとめて仮想的にまとめてしまう。複数作ることができてアプリが棲み分けられる。アプリを環境ごとに独立させて管理。
仮想マシンとは違ってOSやハードウェアの部分は共有する。
cgpups・・コンテナごとのリソースを管理
namespace・・ユーザー権限を管理する

●ブートプロセス（linuxが起動するまでの流れ）とsystemd・・コンピュータの起動について

・コンピュータが起動するとまずUEFO（GUIで操作できる)/BIOSが起動する
・Linuxが起動すると[linit]またはsystemdが起動し、システムを管理
・「systemd」はユニットという単位でシステムを管理
・ユーザーはsystemctlのコマンドを用いてシステムを管理する

・systemdとは


●Linuxコマンド

＊パス・・ファイルやディレクトリの場所を記述したもの

・clear・・画面をクリア
・cd・・何も指定しないとホームディレクトリに戻る、指定するとそのディレクトリに移動
・mkdir -p・・サブディレクトリを含むディレクトリの作成
・cat・・ファイルの内容を確認する
・exit・・ログアウト
・useradd・・ユーザーの追加
・passwd・・ユーザーにパスワードの設定
・su・・ユーザーの切り替え
・reboot・・再起動
・history・・履歴

●スーパーユーザーと一般ユーザー
・普段は使わないスーパーユーザー（root)と一般ユーザーに分けられる
Ruby

●rubyとは・・・オブジェクト指向の言語。RubyはWEBアプリケーションの「システム」をつくるためのプログラミング言語。すべての値がオブジェクトになっている

ex）オブジェクトの種類はクラスというが、1.1 や "hello world" などの実際の値のことはインスタンスと呼ぶ。

●print・・出力
 puts・・出力（改行）
 p・・出力（デバック用）

●変数と定数・・慣習的に定数の頭文字は大文字

●良く使うメソッド・・upcase,upcase!
upcase は文字列を大文字にしたものを返すだけ、upcase! は文字列を大文字にしたものを返しつつ、元の文字列も大文字に書き換えるという違い。

●? がつくメソッド・・これは真偽値を返すメソッド

●リスト・・範囲を指定することでき、colors[0..2] とすると、colors[0] から colors[2] までを引っ張る。...と３つの時は直前まで引っ張る。
要素の末尾に何らかの要素をくっつけたい場合には、push というメソッド
colors << "silver"という書き方

●文字列を数値に変換・・整数に変換したい場合は to integer という意味で「y.to_i」、浮動小数点数にしたい場合は to float という意味で「y.to_f

●ハッシュと配列の相互変換
ハッシュから配列にするには　scores.to_a
配列からハッシュにするには　scores.to_a.to_h

●%の記法
Q は実は省略できるので %(hello) でも "hello" と全く同じ意味
配列においても["red","blue"]は%W(red blue)と同じ意味
●繰り返し処理・・配列.each do |変数名| *処理の終わりにはend

●ハッシュ・・複数の値を一括で管理する方法。ハッシュはそれぞれの値にキーと呼ばれる名前をつけて管理する。　　　　　{キー1 => 値1, キー2 => 値2}のようにつくる。キーと値の間は「=>」でつなぐ。
       *省略した書き方が一般的。具体的には「:key =>」を「key:」というように省略。

●メソッドとは、複数の処理を1つにまとめたもの

def メソッド名(引数名）で引数を指定

●条件分岐・・case ... when ... else ... end

●繰り返し処理・・whileを用いた繰り返し,永遠に繰り返すloop
              ループを抜けるための break、そしてループを 1 回スキップするための nextと一　　　　　　　　緒に用いられることが多い
●戻り値・・真偽値を返すメソッドは、メソッド名の末尾に「?」をつける。
         returnは、戻り値を返すだけでなく、メソッドの処理を終了させる性質も持っている。
         よって、returnの後にあるメソッドの処理は実行されないので注意。

●キーワード関数・・引数の数が多くなると、呼び出し側で値がどの引数に入るのかがわかりにくくなる
　　　　　　　　　　① 定義側で、引数の後にコロンを付ける② 呼び出し側で、値の前に引数名を書く

●オブジェクト指向
●クラスのデータを定義する方法の1つに「attr_accessor シンボル」を使う方法がある

●クラス（設計図）を元に、新しくインスタンスを生成するには、「クラス名.new」とする。
インスタンス.変数名 = 値でそのインスタンス変数に値をセット

●インスタンスメソッドの中では、特殊な変数「self」を用いて「self.変数名」とすることで、インスタンス変数を扱うことができるようになる.インスタンス変数は変数名の前に @ をつけるルール

●initializeメソッド・・インスタンスの生成時に必ず実行したい処理をメソッドを呼び出すことなく実行することができます

●インスタンス変数にアクセスするためのメソッド。attr_accessor, attr_reader
ちなみに値を設定するほうのメソッドを setter、そして値を取得するほうのメソッドを getter、2 つを合わせてアクセサと呼んだりする

●self はそのメソッドを受け取っているインスタンス自身を指す

class クラス名

 def initialize()
    処理
  end

end

●クラスメソッド・・クラスから直接取り出すことのできるクラスメソッドも存在する。クラス変数には @@ をつけることがルール

●入力受付・・入力を受け付けるには「gets.chomp」を使う。このコードが実行されると、コンソールが入力待機状態になる。gets.chomp.to_i」とすることで、入力された内容を数値に変換し、計算などにも使えるようになる。

●オーバーライド・・親クラスにあるメソッドと同じ名前のメソッドを子クラスで定義すると、メソッドを上書きすることができる

super
オーバーライドしたメソッドの中で「super」とすることで、親クラスの同名のメソッドを呼び出すことができる

●クラスメソッド・・・クラスメソッドは、「def クラス名.メソッド名」とすることで定義できる。インスタンスメソッドとの違いはメソッド名の前にクラス名を書く必要がある点
マーケットリサーチの基本

●マーケティング志向の超基本

マーケティングとは・・顧客ニーズを捉え、売れる商品と売れる仕組みを作ること

・マーケティングの実践ステップ・・高速でRPDCAを回していくことが重要

●顧客ニーズを理解する・・現状とありたき姿のギャップ。このギャップが顧客ニーズ
・顧客ニーズの分析①What②why③how④which

これら4つの顧客ニーズを明らかにしていく時にリサーチが大切になってくる。顕在ニーズから、潜在ニーズ、そしてインサイトに至るまで「なぜ」を繰り返していくことが大切。

●ターゲットと独自価値の提供
独自価値・・ターゲットのニーズを満たす自社独自の価値。ただし顧客価値を満たすことが大前提

●3C分析の活用・・顧客、競合、自社の三つの視点から分析することが有効
・3C分析の目的は顧客ニーズ・ターゲット・独自価値を明確にすること。

●3C分析の流れ・・①ターゲット顧客の分析②競合の分析③自社の分析④ポジショニングマップ作成
　　　　　　　　　＊ここは何度も行ったり来たりしながら考えを深めていくことが大切

●価値を作る・届ける・・マーケティングミックスの4Pを活用し、価値の作り方、届け方を考える
　　　　　　　　　　　　＊同じ商品でも希求の仕方によって結果が異なる

●効果測定・改善・・KGI,KPIの達成度をチェックしやりっぱなしにしない。
基本情報技術者（学習用）

●セキュリティ

・セキュリティマネジメントの三要素
１・・機密性・情報の外部漏洩がない
２・・完全性・情報を書きかえられない
３・・可用性・情報を必要な時に変えられる

・不正のトライアングル
１・機会
２・動機、プレッシャー
３・姿勢・正当化

・公開鍵基板（PKI)・・盗聴されても解読できないようにするのが暗号化の仕組みだが、それでは本人確認ができないのでデジタル署名によってデータの真正性を保証する。しかし公開鍵が本物かわからない。CAが公開鍵がその人のものであることを保証する。つまり公開鍵の真正性を保証するデジタル申請書がある。このように認証期間と公開鍵暗号を用いて安全性を保証する仕組みをPKIという

・DMZ・・非武装地帯・セキュリティを保ちつつ、外部からの内部からも容易にアクセスできる場所。webサーバーやインターネットへのアクセスはだれでの簡単にできるが、LANへのアクセスを難しくする

・プロキシサーバー・・インターネットに接続する代理サーバのこと

・パケットフィルタリング・・パケットを無条件に通過させるのではなく、予め指定したルールに則って選別

・VPN・・仮想的な通路を作り出し、それによって安全性の高いネットワークを作り出す

Oauth・・アプリケーション間の認証の仕組み

●サイバー攻撃・・セキュリティに関する脆弱性を利用し、不正にデータを利用したり、改竄をすること

・バックドア・・悪意をもって設置されたアクセス経路
基本情報技術者4（学習用）

●SQLの文法
・関係演算
１、選択・特定の行（レコード）を取り出す
２、射影・特定の列（属性）を取り出す
３、結合・複数のテーブルをくっつける

●SQL文・関係データベースを操作するための言語のこと

・INSERT INTO テーブル名　VALUES（値）・・・既存のテーブルにデータを挿入する
ex) INSERT INTO クラス名簿 VALUES(11033, "大野太郎”,4,"国語")
＊文字列としてデータを与える時は""を入れるが変数名には入れない

・SELECT * FROM テーブル名・・データの抽出
ex)SELECT * FROM クラス名簿

・SELECT * FROM テーブル名 WHERE 条件・・特定のデータを抽出する
ex)SELECT * FROM クラス名簿 WHERE 生徒番号=19191

・UPDATE　テーブル名 SET カラム名 =　値, WHERE 条件・・・既存のレコードを変更
EX)UPDATE　クラス名簿　SET専攻=化学, WHERE 生徒番号=13453


●ストアドプロシージャ・・よく使うSQL文をまとめて保存しておくこと

●再帰関数は、関数内で自分自身を読み出す構造になっている関数
Git/GitHub（学習用）

●Gitはバージョン管理システム・・どのファイルを「誰が」「何を」「いつ」「なんのために」変更したのかが残せる。

●Gitの仕組み・・　①変更履歴を順々に保存する②記録する際にメッセージをつける

●開発の流れ
リポジトリ：変更履歴を記録する場所
commit：個人リポジトリに変更履歴を記録。
push:共有リポジトリに変更を共有。

・複数人での開発の流れ
pull:共有リポジトリの情報を同期

●GitHubとは・・Gitリポジトリのホスティングサービス。

●Githubの特徴・・プルリクエストによるコラボレーション。他チームのソフトウェアが見える。

●ローカルリポジトリの作成・・"git init"コマンドでリポジトリを新規作成

●Gitの基本的なワークフロー
①ファイルの変更をステージングエリアに追加する
②ローカルリポジトリにコミットする
③リモートリポジトリにプッシュする

●変更をコミットする流れ
ファイルを変更したら
①ステージングエリアに追加・・複数ファイルを変更した時に、コミットするファイルを選択するためにあるのが、ステージングエリア*コミットの前にaddする
②リポジトリにメッセージをつけてコミット・・コミットすることで変更がリポジトリ内に時系列で記録される。

●わかりやすいコミットメッセージを書く。他のメンバーがわかるように「何をどのように変更したのか」
１行目・・変更内容の要約
2行目・・空白
３行目・・変更の理由

●ファイルの新規作成、削除、複数ファイルを変更した時もコミットできる

●現在の状況を確認する・・Git statusコマンドでGitリポジトリの状況を確認できる

●変更履歴を確認・・git logコマンドでリポジトリにコミットされたログを確認する

●変更差分の確認・・git diffコマンドでファイルの変更差分を確認

●リモートリポジトリに登録・・git remote addコマンドでローカルリポジトリをリモートリポジトリに格納できる

●管理していないファイルをGitの管理から外す
.ignoreに指定することでgitの管理から外すことができる
・git rmコマンドでコミットしたファイルをGitから外す
RustのMySQLでURLが正しいのに接続できない

# はじめに

久しぶりに昔作成したリポジトリをクローンしてきて.envを設定したところ、なぜかDBに接続できなかったのでまとめます

# 問題

DBに接続したところ以下のエラーがでました


```
failures:

---- presentation::controller::user_controller::test::crud_scenario stdout ----
=============================
database_url: mysql://root:password@127.0.0.1:3306/sample_test
thread 'main' panicked at 'assertion failed: result.is_ok()', src/infrastructure/user_repository.rs:32:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

環境変数は以下のように設定しています。

```.env
DATABASE_URL=mysql://root:password@127.0.0.1:3306/sample
TEST_DATABASE_URL=mysql://root:password@127.0.0.1:3306/sample_test
```

これは正しいURLでした。
また読み込みは以下のようにしています


```rust:util.rs
    let database_url = if cfg!(test) {
        env::var("TEST_DATABASE_URL").expect("TEST_DATABASE_URL must be set")
    } else {
        env::var("DATABASE_URL").expect("DATABASE_URL must be set")
    };
```

いままで問題なく読み込めていたのになぜか接続ができません

# 解決方法

.envを以下のようにしたところ接続できました

```.env
DATABASE_URL="mysql://root:password@127.0.0.1:3306/sample"
TEST_DATABASE_URL="mysql://root:password@localhost:3306/sample_test"
```

URLを""で囲む必要があるようです

# おわりに

こういう地味に引っかかりそうなところは注意が必要です
GitHub Pagesを使って無料でWebサイトを公開する方法

# はじめに
本記事では、静的ウェブサイトを無料かつ簡単に公開するやり方についてご紹介します。
利用するサービスはGitHub Pagesです。

#### GitHub Pagesとは
GitHubの機能の1つで、
HTML、CSS、JavaScript、画像を利用した静的ウェブサイトを公開できるサービスです。

# 使い方
※もしすでにGitHubにコードをアップロードしていて、
　あとは公開だけしたいという方は以下の1~3はスキップしていただいて大丈夫です。
### 1. GitHubアカウントの作成
GitHubのアカウントを作成しましょう。
無料アカウントで大丈夫です。


https://github.com/

### 2. リポジトリの作成
※作成済みの方で、もしprivateで作成している場合は、リポジトリの`Settings`の`Change repository visibility`からpublicに変更しましょう。

リポジトリを作成します。
リポジトリとは、webページのソースコードをまとめて置いておく箱のようなものです。
画面右上の＋ボタンをクリックすると`New repository`と表示されるのでクリックします。

- `Repository name`には任意の文字を入れることができます。
ここで指定した文字が実際に公開されるサイトのURLの一部になります。
例）`https://[アカウント名].github.io/[リポジトリ名]/`
- サイトを公開するためリポジトリは`Public`にします。
![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724947/77da4b9c-dd7f-0ed1-35a8-87192081f16b.png)
その他の設定はデフォルトのままでOKです。
ここまでできたら`Create repository`ボタンを押します。

### 3. ファイルのアップロード
`Create repository`ボタンを押した後、以下のような画面になります。
HTML, CSS, JavaScript, 画像ファイルをアップロードしましょう。
`creating a new file`でも`uploading an existing file`でもどちらでも良いですが
個人的なおすすめは、まず`index.html`など特にフォルダの中に入っていないファイルを`uploading an existing file`でまとめてアップロードします。
![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724947/b7639750-8c80-ec96-5a64-ad6d638cbef8.png)

残りはフォルダが必要なファイルです。
1つでもファイルをアップロードすると以下のような画面になるので、`Add file`をクリックして`Create new file`をクリックします。
![image3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724947/2e03045f-ffb4-9f8e-c675-95a60402f7ce.png)

以下のようにファイル名を入力できる画面になります。
![image4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724947/a2789740-a262-1649-09fd-9868f2c50963.png)

例えば、cssフォルダの中にstyle.cssをアップロードしたい場合は、ファイル名の入力欄に以下を入力します。
`css/style.css`
スラッシュを入れることでフォルダが作れます。

また、画像ファイルを１つのフォルダにまとめて入れたい場合は、少しコミット履歴が荒れますが、
一旦正しいフォルダ名の中に適当なファイルを1つ作成して、フォルダを作成した後にまとめて画像ファイルをアップロードします。
そしてファイルのアップロードが終わったら最初に作ったダミーファイルを削除します。

### 4. 公開設定
ファイルのアップロードができたら公開するための設定をします。
とてもシンプルです。

まず、公開するリポジトリのページの`Settings`をクリック。
![image5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724947/119f0dfe-8719-53e1-079b-4176ee6328c8.png)
続いて赤枠の`Pages`をクリック。
![image6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724947/242150e9-3de9-dd4f-862e-bd0c5d3d4cb1.png)
赤枠の`None`をクリックして`main`を選択して、保存します。
![image7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724947/a8a6693a-ee0b-e3b9-6541-ae4255289048.png)

以上で設定は完了です。
しばらくすると以下のような画面になりますので、`Visit site`をクリックすると実際に公開されているページにアクセスできます。
![image8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2724947/37420834-08b1-d0a5-b1eb-392d237ebef0.png)

# 参考文献
詳細を確認したい場合は以下を参考にしてみてください。

https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages

https://prog-8.com/docs/github-pages
Django ローカル環境 Apache 接続設定（windows）

・Djangoは venv で作成。

### ■Apache ./conf/httpd.conf

``` httpd.conf
############ Python Django 用設定　追加 ############
 
LoadFile C:/Users/natsume/AppData\Local/Programs/Python/Python39/python39.dll
 
LoadModule wsgi_module C:/Users\natsume/AppData/Local/Programs/Python/Python39/Lib\site-packages/mod_wsgi/server/mod_wsgi.cp39-win_amd64.pyd
 
WSGIPythonHome C:/Users\natsume/AppData/Local/Programs/Python/Python39
WSGIScriptAlias / D:/Django/django_project/django_project/wsgi.py
WSGIPythonPath D:/Django/django_project/django_project
 
<Directory D:/Django/django_project/django_project>
  <Files wsgi.py>
    Require all granted
  </Files>
</Directory>
 
Alias /static/ D:/Django/django_project/static
 
<Directory D:/Django/django_project/static>
  Require all granted
</Directory>
 
############ Python Django 用設定　追加 END ############
```

### ■django の設定ファイル setting.py
Apacheのポート番号に合わせる

```py setting.py 

### Apacheの環境に合わせる
# ALLOWED_HOSTS =
# ALLOWED_HOSTS = ['localhost','127.0.0.1','*', '127.0.0.1:8082']
ALLOWED_HOSTS = ['localhost','127.0.0.1:8082','*','localhost:8082']
```
Googleデジタルマーケティング＆Eコマース：Google Ads・GoogleアナリティクスのデータをCSVにエクスポートする

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/41012708-dfb2-da45-b1a3-5a683fab51bc.png" width="800">

Google Adsと Googleアナリティクスのデータは、CSVファイルにエクスポートして表計算ソフトで分析することができます。

# Google Ads

Google Adsのデータをキャンペーンごとにエクスポートしたい理由の1つは、分析や比較のために過去のキャンペーンのデータのアーカイブを保持するためです。

ここでは、Google Adsからキャンペーンデータをエクスポートする方法を説明します。

- まず、現在と過去のキャンペーンのリストに移動します。キャンペーンを選択する前に、そのキャンペーンから必要なデータの期間を確認し、必要であれば変更します。デフォルトでは、過去30日間となっています。開始日を変更することで、さらに遡ってレポートを作成することができます。
- データ列が、エクスポートしたいデータをすべて含んでいることを確認します。別のデータ列を追加する必要がある場合は、「列」アイコンをクリックして追加してください。
- キャンペーンレポートに必要なデータが含まれていることを確認したら、キャンペーンのボックスにチェックを入れ、データをCSVファイルとしてダウンロードするよう選択します。また、PDFなど異なるファイル形式でデータをエクスポートするオプションもあります。キャンペーンのデータをCSVファイルにすると、こんな感じです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/eb96ffa5-6636-2193-c881-60485cc76b8f.png" width="５00">


# Googleアナリティクス

Googleアナリティクスでは、レポートを共有することができます。レポートを共有する場合、レポートへのリンクをコピーし、そのリンクを他の人と共有します。リンクを共有する相手は、データを見るためにGoogleアナリティクスのビューアーロールを持っている必要があります。

例えば、レポートのスナップショットを共有するとします。「共有」アイコンをクリックすると、リンクをクリップボードにコピーして、メール、テキストメッセージ、またはプレゼンテーションに貼り付けて他の人と共有することができます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/3add7262-dd41-7be2-b684-2ec9332da567.png" width="５00">

また、データをCSVファイルやPDFファイルにエクスポートすることもできます。手順は、Google Adsからデータをエクスポートする場合と同様です。エクスポートするには、共有リンクではなく、「ファイルをダウンロード」を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/d26f10eb-05f9-cf2c-3a72-f5300960db7a.png" width="300">

レポートスナップショットのデータをCSVファイルにすると、こんな感じです。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/7018472d-abb8-acba-2403-77bbef08c9e3.png" width="300">

:::note info
Google AdsやGoogleアナリティクスなどのアナリティクスツールからデータをエクスポートすることで、将来の分析のためにデータを保存することができます。他のキャンペーンのデータと比較することができます。意外にも、過去の傾向の分析から新たな発見があることもあるデータです。 
:::
Unixコマンドライン操作【基礎編②】

コマンドラインの基礎知識について1から復習中なので、
主に自分の備忘のために学んだことを記録しておこうと思います。の２つ目

教材はRuby on Railsチュートリアルのコマンドライン編です。
第3章のファイル操作について書こうと思いますが、3章からは有料コンテンツのため
覚えたコマンドだけ簡単に！（前回もそうでしたが。。）

macOSを使っています。

1.リダイレクト、追記

「>」・・出力内容を別ファイルにリダイレクト
※本来ターミナル上に出力される内容を別ファイルを作ってその中に出力する。みたいなイメージ？

例： $ echo foo > foo.txt
「foo」というテキストが「foo.txt」というファイルの中に出力される

ちなみにやっていて気がついたのですが、
同じファイル名（すでに存在しているファイル）に対してもう一度リダイレクトを行うと、最後にリダイレクトした内容でファイルの中身が置き換えられるようです。
使ったことはありませんでしたが、気をつけたほうがよさそう

上書きではなく、追記の場合は次のコマンドを使います。

「>>」・・出力をファイル名に「追加」する

例：　$ echo bar >> foo.txt
これにより、最初に作ったファイル「foo.txt」の2行目に「bar」というテキストが追加されます。

2.ファイルの中身の確認

cat + ファイル名

手っ取り早くファイルの中身を確認するためにcatコマンドをこのように使用します。

3.ファイル内容の比較

diff + ファイル1 + ファイル2

ファイル1と2で差異のある部分が出力されます。
（差異がない場合は何も出力されません）

4.ファイルのリストの表示

「ls」・・カレントディレクトリの中身を表示

※ls + フォルダ名で、指定したフォルダの中身も確認できるようでした。
（このやり方は載っていなかったので、あんまりこういう使い方はしないんですかね？）

また
*（ワイルドカード文字）を使って、リストに表示するファイルしぼりこむことができます。

例: $ ls *.txt
拡張子が.txtのファイルだけ表示します。

他に
「ls -l」　(lsにオプションで-lをつける）を使うとロングフォームで表示することができます。
※ロングフォーム・・バイト数や最終更新日時付き

他にはオプションで「-rtl」　（r,t,lは順不同）があり
最終更新日時の降順になります。（rが逆順、tが更新日時の新しい順に並べるオプション）

またオプションで「-a」を使えば、
隠しファイル（.で始まるファイル）も含めてすべてリストに表示することができます。

5.空のファイルの作成

touch + ファイル名

指定したファイル名で新規ファイルを生成します

6.リネーム

mv + 旧ファイル名+ 新ファイル名

旧ファイル名を新ファイル名に変更します

7.コピー

cp + コピー元ファイル　+ 新ファイル

コピー元ファイルの内容が、新ファイルとしてコピーされます 

8.削除

rm + ファイル名

指定したファイルを削除します。
（オプションなしだと、削除してよいかどうかを確認されます。）

オプションで「-f」をつければ、確認なしで強制削除されます。

※存在しないファイルを削除しようとした場合
「-f」をつけていないと、エラーメッセージのようなものが出ますが、
「-f」をつけていると、スルーされる（何も削除しないし、エラーも出さない）


今回はこんなところで！

ありがとうございました。
【ChatGPT】AttributeError: 'ChatGPTLLMPredictor' object has no attribute '_llm'【GPT-index】【Llama-index】

# エラー内容
GPTindexでChatGPTLLMPredictorを使おうと、するとエラーが出る
(いくつかの使用記事があるが、現在は使えないよう)

```
AttributeError: 'ChatGPTLLMPredictor' object has no attribute '_llm'
```

# 解決法
githubのissueを確認すると、製作者から以下のコメントがある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404462/001471a7-cbec-386e-11c0-df22d6d0d6f6.png)

https://github.com/jerryjliu/llama_index/issues/789

要するに、ChatGPTLLMPredictorはもうサポートしないとのこと。

代わりの方法が以下のnotebookに記載されている

https://github.com/jerryjliu/llama_index/blob/main/examples/vector_indices/SimpleIndexDemo-ChatGPT.ipynb

要約すると大体以下の通り

```
from gpt_index import GPTSimpleVectorIndex, SimpleDirectoryReader, LLMPredictor
from langchain.chat_models import ChatOpenAI

llm_predictor = LLMPredictor(llm=ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo"))
```
AtCoder Diff逆転

Diffが逆転しているところを調べました。
## ABC001～041
なし。
## ABC042～125
ABC046 C>D
ABC100 B>C
ABC112 C>D
ABC125 C>D
## ABC126~211
ABC155 D>E
ABC161 E>F
ABC165 C>D
ABC171 C>D
ABC174 C>D
ABC176 D>E
ABC179 D>E
ABC185 E>F
ABC190 E>F
ABC191 D>E
ABC192 D>E
ABC195 B>C
ABC198 D>E
ABC207 D>E
## ABC212~295
ABC212 F>G
ABC218 C>E>D
ABC219 F>G
ABC220 E>F
ABC221 G>H
ABC225 F>G
ABC227 E>F>G
ABC231 E>F
ABC232 C>D
ABC243 F>G
ABC245 E>F
ABC249 A>B E>F
ABC251 D>E
ABC254 G>Ex
ABC255 G>Ex
ABC258 B>C
ABC259 G>Ex
ABC261 G>Ex
ABC262 G>Ex
ABC264 C>D
ABC267 G>Ex
ABC268 E>F
ABC270 D>E
ABC272 F>G
ABC275 C>D
ABC283 E>F
ABC291 G>Ex
ABC292 G>Ex
ABC293 F>G
ABC294 F>G
ABC295 B>C F>E>G

## ARC001~ARC057
ARC019 C>D
ARC029 B>C
ARC047 B>C
ARC055 B>C
## ARC058～ARC103 (ABCとの重複は除く)
ARC060 D>E
ARC064 D>E
ARC065 E>F
ARC082 E>F
ARC094 D>E
ARC103 D>E
## ARC104~ARC158
ARC105 C>D
ARC106 E>F
ARC108 E>F
ARC110 E>F
ARC114 D>E
ARC115 A>B
ARC118 B>C
ARC119 D>E
ARC121 D>E
ARC122 A>B
ARC132 E>F
ARC136 C>D
ARC150 E>F
ARC158 D>E
ChatGPTによるAWS開発での革新的な変化と、SEの役割が消失する未来

今回はChatGPTに準ずるAIの導入でAWS業務がどう変わっていくのかを
開発過程に沿って考えていきましょう！
※自身の考えをまとめる為の記事です。
私もまだ初学者なので、皆さんの知見をコメントで共有していただけると幸いです。


偉大なる方の記事はこちら

> [驚くべき完成度！AWSでサーバレスAPIの作成をChatGPTに頼んだ結果〜AWSエンジニアの役割が変化する?!〜](https://qiita.com/takuma818t/items/ff89ed5ba7c41ae7f2e5)


## 想定の前提
* ChatGPTが99%の正確な回答・コードを生成できる
* ライセンスに縛られず、企業活動で自由に活用できる
* API使用に基本的な制限がない（昨今のTwitterのような、、、）
  
## 上流過程
いわゆるシステムの上流過程では、**顧客の要求をかみ砕く**必要があります。
ChatGPTにそんなことが可能なのでしょうか、、、
### 1. 要件定義
要件定義では顧客からの要求をかみ砕き、要件定義書という形で資料をアウトプットします。

SIerの立場からすると、正直要件定義にChatGPTを挟む余地はありません。
しかし、顧客やノウハウの少ない中小企業の立場からすると、ChatGPTを利用して開発を進めることができます。
向こうからあらかじめ使いたいAWSサービスなどをAIに提案させ、それをSIer側に伝えてくる、、、などという
頭が痛くなる状況が発生すると思われます。しかも、その内容の正答率は99%なのですから。
そしてそのうち、ChatGPTがSIerの立場になるのです。下記の条件以外は。

1. 業務上の秘密情報を入力できない（情報管理の懸念）
2. 複雑な業務ロジック・要件（非機能含む）に対応するのが難しい
> 参考:[ChatGPTを日本企業はどう使う？｢禁止｣ドコモ、｢模索｣楽天、｢自社開発｣LINE…14社調査](https://www.businessinsider.jp/post-265674)

   
こういった要件の場合は**SIerとしての出番**だと思います。

### 2. 設計
もし要件定義をChatGPTで行えるのだとすると、基本設計書のようなものは「**この要求の設計をアウトプットして！**」と
頼めば終わりでしょう。もしくは、そのようなサービスが出てきてもおかしくありません。
ChatGPT APIは優秀なので、サービス側で仕様書の型を決めてしまえば、それに沿ってアウトプットしてくれるでしょう。

きっと、堅実な性格の代表の日本人は後30年は人の手でチェックすると考えられます。加えて、個人事業主でない限り、**責任は
開発者(とマネージャー）にある**わけで、社長にはありませんので。
となると、そこにも職の需要が生まれそうです。
中途半端な知識の持ち主は淘汰され、高度な専門知識を持つ人たちのみが生き残る、、、怖い世界です。
そしてそんな時代に生まれてきた人が大人になる頃には、AIより知識が無い人しかいなくなるのでしょうか。。。
たすけてドラえもん。。

## 下流工程
下流工程はいわゆるSEであり、**AIの登場でほぼ消失する**と考えます。
どういったことが取って代わられるのか、見ていきましょう。

###  1. 製造

ここがやはり本題です。AWS開発では、IaC（Infrastracture as Code）という考え方で、
AWSサービスの実装をコード化できます。そして、これを可能にしているのがCloudFormationというサービスです。
そして、そういったものを含めて製造を頼めばやってくれるでしょう。加えて、**ChatGPTとの間に一つサービスを挟み、**
**そういった実装をすべてシームレスに行ってくれるようなサービスが登場する**と予想します。
現状では実装やテストは自身がしなければなりませんが、そういったサービスの登場で実装すら手を煩わせることはなくなるでしょう。


### 2. テスト
ここまで読んでくださった方にはお分かりかもしれませんが、テスト項目の作成は、要望に沿って作成してくれます。
テストはパターンなので、AIの得意とするところです。
最近はExcelにChatGPTを連携させる機能も出てきました。
> 参考：[「ChatGPT」でExcelやWordが劇的進化、マイクロソフト「Microsoft 365 Copilot」の衝撃](https://www.sbbit.jp/article/cont1/109819)


実施内容については確認する必要があります。品質を担保するのが難しいです。（AIが作って、AIがテストしてだと、いまいち信用できないという人としての感情の問題もある）
そう言うのを気にしない企業体質であれば問題ありませんが。ステークホルダーには様々なタイプがいると思いますので、一概には言えません。

### 4. 実装
実装は人の手でする必要があるでしょう。AIに多くの工程が奪われた今、人に必要とされているのは「**責任**」です。
実環境で問題なく動くかどうかなどは人が確認する必要があるでしょう。

## 運用・保守
運用、保守はAIの苦手とするところです。特に運用はまず無理でしょう。起きたバグやクレームに対し対処を考えるのは人の役割です。リスクを含め対処は人が考える必要があります。ただし、それは開発側ではないかもしれませんが。その思考過程にもChatGPTが絡んできます。「AWSでこういう対処をしたいのだけれど、影響はどのようなものがある？」などを、**CloudFormationのコードとともに聞けば調査しなくても即答えてくれます**ので。
CloudFormationは偉大ですね。

### まとめ

開発工程を詳細に見てきましたが、AWS業務に関してまとめていうと、「開発の仕事がなくなる」ということです。
これはほかのサービスと比べても、IaCの概念のお陰で特に顕著です。
既存のシステムを勉強するというよりかは、新しいサービスを作っていくところに人の価値が生まれてくるのかもしれませんね。
UbuntuのVirtualBoxにWindowのライセンスを登録する

## 最初に

日経Linux 2022年11月号を書店で見かけまして、Ubuntu 22.04 LTSを特集していることを知りました。
その時は立ち読みもせずにそのまま流してしまったのですが、後になって気になり（気になったときには、次の号が出てしまって書店では買えなくなっていました）、Kindle版を購入して記事を一通り読みました。

その記事の中で、Windowsがプリインストールされているマシンに登録されているライセンス情報は、仮想マシンを作成する際に使用できることを知りました。

Ubuntuにも関心を持ち始めたところでしたので、WindowsがプリインストールされているマシンにUbuntuをホストOSとしてインストールして、ゲスト・仮想マシンとしてWindowsをインストールして見ようと考え、実施してみました。

プリインストールされたWindowsを消し、別のOS（本例ではUbuntu Desktop 22.04 LTS）をインストールした後、VirtualBoxでWindowsを仮想マシンとして動かす場合には、BIOS・UFEIに登録されているWindowsのライセンス情報をVirtualBoxに認識させることができます。

## 環境について

### ホスト

* マシンはThinkPad L390
    * 中古品を購入した（3万円台）
    * CPUはCore i5-8265U（4コア8スレッド） 1.6GHz
    * メモリは16GB
    * ストレージはNVMe SSD 500GB
    * Windows 10がプリインストールされていた
* Ubuntu Desktop 22.04 LTSをクリーンインストールした
* Windows 10のISOイメージは、マイクロソフトのサイトからダウンロード済み
    * https://www.microsoft.com/ja-jp/software-download/windows10
* セキュアブートは途中で無効にした
    * 購入時はセキュアブートが有効になっていた
    * 有効なままで作業を始めてしまって、途中でエラーが発生したので、補足としてそのことを書いておく

### ゲスト、仮想マシン

* OSはWindows 10とする
* ライセンスはL390のファームウェアに書き込まれていることを確認したので、そちらを使用した

## 手順

### ホスト: ファームウェアに書き込まれたライセンス情報を確認する

以下のコマンドでライセンス情報が表示されれば、この先の作業を進められます。

```
$ sudo strings /sys/firmware/acpi/tables/MSDM
MSDMU
xxxxxxxx
xxxx
xxxxx-xxxxx-xxxxx-xxxxx-xxxxx
```

### ホスト: ファームウェアに書き込まれたライセンス情報をファイルに書き出す

ユーザーのホームディレクトリにある、VirtualBox共有フォルダ（VirtualBox VMs）に任意のディレクトリを作成して保存します。

```
$ sudo cat /sys/firmware/acpi/tables/MSDM > ~/"VirtualBox VMs"/Windows/msdm
```

### ホスト: 書き出したライセンス情報をVirtualBoxに登録する

```
$ VBoxManage setextradata Windows VBoxInternal/Devices/acpi/0/Config/CustomTable ~/"VirtualBox VMs"/Windows/msdm
```

ここまでできれば、VirtualBoxで仮想マシンを作成してWindows 10のインストールを行ったときに、仮想マシン上のWindows 10でライセンスの認証が行われます。


## 補足: セキュアブート有効時に発生したエラー

セキュアブートを有効にしたままでホストにUbuntuのインストールはできました。その後、VirtualBoxのインストールもできました。

ただ、書き出したライセンス情報をVirtualBoxに登録するところで下記のエラーが発生しました。

```
$ VBoxManage setextradata Windows VBoxInternal/Devices/acpi/0/Config/CustomTable ~/"VirtualBox VMs"/Windows/msdm 
WARNING: The character device /dev/vboxdrv does not exist.
	 Please install the virtualbox-dkms package and the appropriate
	 headers, most likely linux-headers-generic.

	 You will not be able to start VMs until this problem is fixed.
```

エラーメッセージの`WARNING: The character device /dev/vboxdrv does not exist.`からあたりを付けて調べてみたところ、セキュアブートの設定に行き当たり、セキュアブートを無効化したら先に勧めました。

セキュアブートを有効にしたままでも、このエラーを回避することはできるようですが、今回はセキュアブートを無効にするという対応を取っています。

Ubuntu自体はセキュアブートに対応しているとのことなので、セキュアブートを有効化した状態で作業を進める方法は機会を改めて行ってみたいと思います。
yt-dlp,VideoDownloadHelperを使用しないWeb上の動画保存方法

# 動機
とある会員制音楽系サイトの動画チュートリアルを購入、動画を視聴する度にパケ代が発生して、ただでさえブルーシート生活で困窮しているのにこれ以上家計を圧迫できない。いつもお世話になっているyt-dlpは使用できず、ググってみるとChrome拡張のVideo DownloadHelperを使えだのなんだの。色々試したが保存できず、どうしたもんか。てことで試行錯誤して成功したので備忘録として残しておきます。

# 手順の概要
1. 会員サイトにログインしてクッキーをぶっこ抜く
1. ストリーミング用プレイリストのURLを取得
1. ffmpegを使用して動画を保存

# 前提
1. OS：Mac, Linux

# 詳細手順
1. 会員制サイトにログインして保存したい動画を再生する
1. Chromeの **「ハンバーガーアイコン」「その他のツール」「デベロッパーツール」** を開いて **「ネットワーク」** タブをクリック
1. ストリーミング用プレイリストファイル(m3u8)を探してURLを取得
    * 右クリック
    * コピー
    * **リンクのアドレス** をコピー
        * この例の場合、720p, 1080p, originalとプレイリストがあり最も画質の良いoriginalのm3u8を選択している
![0000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342159/80f61885-a0a0-323b-a423-649b6208220b.png)
1. クッキーを取得
    * デベロッパーツールを使用する場合
        1. 対象のtsファイルを選択
        1. **ヘッダー**タブを選択
        1. **リクエストヘッダー**のcookieを右クリック
        1. **値をコピー**を選択
![0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342159/5ffe6ca3-7fa8-4457-7b3f-9d6946f6052a.png)

    * Chrome拡張のEditThisCookieを使用する場合
        1. **Cookieのエクスポート** を選択
![0002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342159/bbbccce4-ee5e-6fd9-4621-b1304b85f464.png)
1. 上記で取得したURL、cookieからffmpegでtsから動画ファイルを構築
    * 再エンコを行わず(無劣化)、コンテナをtsからmp4に変更している
    * ポイントは「-heaers」オプションと　**「 cookie: 」**　の文字列
    ``` bash
    % ffmpeg -headers "cookie: <<取得したCookie>>" -i <<m3u8のURL>> -c:v copy -c:a copy <<出力ファイル名>>.mp4
    ```

    * cookieが長い場合、例えばcookie.txtなどにファイルを保存しておいてシェル展開しても良い
    ``` bash
    ffmpeg -headers "cookie: "`cat ./cookie.txt` -i <<m3u8のURL>> -c:v copy -c:a copy <<出力ファイル名>>.mp4
    ```

以上です。
本当の意味でbeforeやafter疑似要素のcontentプロパティで日本語が文字化けする問題を回避する

# 結論

```html
<link rel="stylesheet" href="style.css" type="text/css;charset=UTF-8">
```

# おわりに

昨今は文字セットにUTF-8を使うのは当たり前になっています。
そんな中、CSSでcontentに日本語を書くと文字化けするという現象に出会いました。

解決策を調べると「UNICODEに変換したものを代わりに書けばいいですよ～（ドヤァ）」とあります。

**あほか！！**

そんなこといちいちやってられっかって話ですよ。
やってらんねぇよ

結局HTML側で読み込むときのMIMEタイプで文字セットにUTF-8を指定すればいいわけですが、あまりよく探してませんが、日本語の記事では書かれていない解決策でした。
誰かの情報をうのみにして拡散する悪い風習が良く表れていますね。
メモ：ターミナルでエイリアス登録

```
vi ~/.bashrc
```

iで編集モードに入り、ファイルの下に下記のように記述。
（sと打ったら「rails s」が動くようにした）
```
alias s='rails s'
```

`esc`を押して編集モードから脱出し、
`:w`で保存、`:q`でファイルを閉じる。

その後、これでファイルをリロード。
```
source ~/.bashrc
```
pnpmでpackage.jsonのscriptsに引数を渡す方法

# 結論
明示的に環境変数を設定する[^1]。

[^1]: [npm との違い](https://pnpm.io/ja/pnpm-cli#npm-%E3%81%A8%E3%81%AE%E9%81%95%E3%81%84)

```json:package.json
{
  "scripts": {
    "hello": "echo Hello, $name!"
  }
}
```

```sh
$ name=World pnpm hello

> echo Hello, $name!

Hello, World!
```

# 補足: npmの場合
npmの場合は、次のように書いてコマンドライン引数に渡すことができます[^2]。

[^2]: [package.jsonのscriptsに引数を渡す方法](https://zenn.dev/jojojo/articles/df1ff83890f83b)

```json:package.json
{
  "scripts": {
    "hello": "echo Hello, $npm_config_name!"
  }
}
```

```sh
$ npm run hello -name World

> echo Hello, $npm_config_name!

Hello, World!
```

:::note info
引数の渡し方は下記のいずれでもOKです:thumbsup:

1. `-name World`
2. `-name=World`
3. `--name World`
4. `--name=World`
:::
ChatGPTで将来の予測は出来るのか？

__はじめに__
先日WBCで日本が世界一になりましたね．
決勝のアメリカvs日本，私はリアルタイムで見ていましたが，9回2アウトからの大谷翔平vsトラウトは手に汗握るものがありましたね．
WBCが日本代表チームも解散，大谷翔平選手も大リーグに戻ります．
そこで3月30日から始まる大リーグの来シーズン，大谷翔平選手はどのような活躍をするのでしょうか．
私自身は野球に詳しくないので詳そうな人（？）に聞いてみましょう．
そう，ChatGPTです.

~~某知恵袋ではありません.私はせっかちなので質問してから回答が来るまでの間も待てないのです.~~

__本題__
早速ChatGPTに聞いてみました．
その結果はこちら
![スクリーンショット (3899).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292130/d3a3c270-77f0-439a-50cd-6374dd0e4720.png)
ChatGPTでも遠い未来の事は予測出来ないという事なのでしょうか．


次は回答が複数存在する質問に変えてみました．
![スクリーンショット (3900).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292130/93611cf2-4436-f90e-14ce-edb33920a315.png)
有力候補となると怪我や運も絡むので予想は難しい，ということでしょうか．
ここでnew　chatに切り替えて全く同じ質問をすると具体的な回答を得られる場合もありました．

その次は回答の幅をさらに広げてみました．
すると...？
![スクリーンショット (3901).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3292130/59460903-2568-a691-0337-2d1977e3144e.png)
なんと！候補が出るようになりました．
ただ，残念な事に大谷翔平選手は候補に挙がりませんでした...

余談ですがchatを切り替えて全く同じ質問すると候補の選手，選出理由が少しづつ変わります．
大谷翔平選手も稀に候補に挙げられていました．
因みに一番多く候補として挙げられたのは __マイク・トラウト__ 選手でした．
来シーズンのメジャーリーグは彼に注目して見るのも良いかもしれませんね！

__結論__
ChatGPTで将来の予想をすることは出来る．
ただ質問の方法，使用する単語，それまでどんな会話をしていたか等で回答が変化する場合がある．
全く同じ質問をしても得られる回答が異なる場合がある．

よって，複数回同じ質問をして頻繁に得られる回答が予想として最もらしい解なのではないでしょうか．
ChatGPTの予想が当たるかどうか，大リーグの来シーズンに期待です！
【PHP】ls -l php*で7.2だけで7.4が出てこない場合 (&Your PHP installation appears to be missing...エラー)

# 概要
* WordPressがPHP7.4以上を推奨とのことで、PHP7.4をインストールしたのに、`ls -l php*`で確認しても、ApacheがロードするPHPバージョンが7.2だけで、7.4が出てきませんでした。今回そのエラー対応をしたので、解決手順を残します。
* また、上記解決後にWordpressで`Your PHP installation appears to be missing the MySQL extension which is required by WordPress.　`というエラーが表示されたのでその対処法も記します。

# 解決手順
* まず、パッケージマネージャーを最新に更新します。

```terminal
$ sudo apt-get update
```

* PHP 7.4をインストールするために必要なパッケージをインストールします。

```terminal
$ sudo apt-get install php7.4

、Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package php7.4
E: Couldn't find any package by glob 'php7.4'
E: Couldn't find any package by regex 'php7.4
```

* あれ、なんかエラーメッセージが返ってきました。`E: Unable to locate package php7.4`ととあるので、パッケージリポジトリにPHP 7.4が含まれていないらしい。手動でリポジトリを追加してみます。
* apt-transport-httpsパッケージをインストールします。

```terminal
$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
```

* Ondrej PHPリポジトリを追加します。
    * Ondrej PHPリポジトリとは：DebianおよびUbuntu LinuxディストリビューションのためのPHPの公式リポジトリの1つ。DebianやUbuntuなどには、標準でPHPのパッケージが含まれていますが、最新バージョンを簡単にインストールできること・セキュリティアップデートに迅速に対応していること・複数のPHPバージョンを提供していることなどの理由から、Ondřej PHP リポジトリを利用することが推奨されます。また、Linuxディストリビューションに含まれるPHPのバージョンだと古い場合があるらしい。
    * PPAとは：Ubuntuやその他のDebian系Linuxディストリビューションで利用される、個人用パッケージアーカイブ（Personal Package Archive）の略称。ppa:ユーザー名/リポジトリ名という形式でアクセスします。

```terminal
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt-get update
```


* 改めて、PHP 7.4をインストールします。

```terminal
$ sudo apt-get install php7.4
```

* 今回はうまくいったようです。以下でApacheが見ているPHPバージョンを確認します。
    * 以下でディレクトリで、Apacheサーバーで現在有効になっているモジュールのリスト（以下であればphp）を確認することができます。
    * Apacheが起動するとき、`mods-enabled`ディレクトリ内のシンボリックリンクが読み込まれ、有効になったモジュールが自動的にロードされます。これにより、Apacheサーバーが必要に応じて拡張され、特定の機能を実行できるようになります。


```terminal
$ cd /etc/apache2/mods-enabled/
$ ls -l php*
```

* しかし、上記実行してもまだ7.2になっています。PHP 7.2が既にインストールされており、ディストリビューションがデフォルトで使用するバージョンを変更しないためか、現在のバージョンが7.2のままっぽい。
* Apacheに対してPHP7.2を無効にし、7.4を有効にします。

```terminal
$ sudo a2dismod php7.2
$ sudo a2enmod php7.4
$ sudo systemctl restart apache2
```

* `ls -l php*`コマンドを実行して、PHP 7.4が表示されるかどうかを確認します。今回は7.4を確認できました。
* よし、これでOK!と思い、Wordpress管理画面を開いたら、以下のメッセージが出てきました。

```
Your PHP installation appears to be missing the MySQL extension which is required by WordPress.　
```

* WordPressがMySQL用のPHP拡張機能（extension）を検出できないよう。おそらく、7.2であれば検出できたのでしょうが、7.4にしたことでmissingになってしまったのでしょう。PHPのバージョンを変えるとこういったモジュール無効エラーがしばしば見られるので要注意です。
    * 別記事でまとめたモジュールエラーはこちら：[【Wordpress】一部ページが「重大なエラーが発生しました」＆サイトヘルスで「1つ以上の必須モジュールが存在しません」が表示された場合](https://qiita.com/Ryo-0131/items/23c572da36eac43c9fc4)
* PHP7.4指定でMySQL用拡張機能をインストールします。

```terminal
$ sudo apt-get install php7.4-mysql
$ sudo systemctl restart apache2
```

* 無事に表示されました！！やったぁー！！
「panic: proto: file "〇〇.proto" is already registered」とエラーが起きた際の対処法

# はじめに
現在、GoとgRPCを扱っている案件に参画しています。
そこでgRPCを更新し、取り込んで実装を進めて、Goでテストを走らせた時に、題名のエラーに遭遇しました。
解決までに少し時間がかかったため、同じような状態になっている方のお役に立てればと思います！

# 結論
環境変数に、`GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn`を追記して、エラーを回避した形になります。

```
GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn
```

# 何が起こったのか？
テストを走らせた時に、以下のエラーが発生しました。

```shell:ターミナル
panic: proto: file "〇〇.proto" is already registered
	previously from: "github.com/△△/△△"
	currently from:  "github.com/□□/□□"
See https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict
```

:::note warn
〇〇などには、ファイル名やリポジトリ名が入っています。
今回の実装では、gRPCは別リポジトリで実装しており、それをGo側のリポジトリにrequireで取り込んでいる形となっています。
:::

# 原因の特定
エラー文を見てみると、`〇〇.proto`が既に登録されているとあります。
`previously`と`currently`のそれぞれのリポジトリを見にいくと、確かに`〇〇.proto`がありました。

ただ、`See https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict`とあったので、見に行くことにしました。
英語で記載されていますが、よく見てみると、以下の記述があります。

>At program execution. The behavior for handling conflicts when executing a particular Go binary can be set with an environment variable: `GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn ./main`

>訳：プログラム実行時。特定の Go バイナリを実行するときの競合を処理するための動作は、環境変数で設定できます。

調べてみると、登録されている名前が同じだと、競合してpanicエラーを起こすのはどうやら仕様のようです。
https://github.com/protocolbuffers/protobuf-go/blob/b0a9446/reflect/protoregistry/registry.go#L44-L65

ただ、競合は起こしますが、実装自体に影響は及ばさないため、このpanicエラーを回避するために、環境変数を設定して回避することにしました。

# 対応方法
今回の実装で環境変数を追加するには、Dockerfileとci.ymlに記載が必要でした。

```dockerfile:Dockerfile
ENV GOLANG_PROTOBUF_REGISTRATION_CONFLICT=warn
```
```yaml:.github/workflows/ci.yml
- run: make test
  env:
    GOLANG_PROTOBUF_REGISTRATION_CONFLICT: warn
```

記載後、テストを走らせると、無事エラーを回避することができました。

```shell:ターミナル
WARNING: proto: file "〇〇.proto" is already registered
	previously from: "github.com/△△/△△"
	currently from:  "github.com/□□/□□"
See https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict
```

# まとめ
環境変数の追加以外に、解決方法としては、`.proto`のファイル名を変更することが挙げられます。
ただ、実装の影響範囲が広かったため、今回は環境変数を追加する形とさせていただきました。

同じエラーに遭遇した際は、参考にしていただけますと幸いです。
最後までお読みいただきありがとうございました！

# 参考文献
- https://protobuf.dev/reference/go/faq/#fix-namespace-conflict
- [Go:Protocol BuffersのNamespaceが競合したらpanicするのはなんで？](https://scrapbox.io/dojineko/Go:Protocol_Buffers%E3%81%AENamespace%E3%81%8C%E7%AB%B6%E5%90%88%E3%81%97%E3%81%9F%E3%82%89panic%E3%81%99%E3%82%8B%E3%81%AE%E3%81%AF%E3%81%AA%E3%82%93%E3%81%A7%EF%BC%9F)
- https://github.com/protocolbuffers/protobuf-go/blob/b0a9446/reflect/protoregistry/registry.go#L44-L65
Googleデジタルマーケティング＆Eコマース：Google Adsを設定する

# はじめに

”Googleデジタルマーケティング＆Eコマース プロフェッショナル認定証"　の受講が完了しました(2022/3/3)。私がこのコースから得られた素晴らしい体験を、テーマごとに分割して、わかりやすくご紹介しています。興味を持たれた方は、是非下記を受講してみてください。

https://jp.coursera.org/professional-certificates/google-digital-marketing-ecommerce

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/41012708-dfb2-da45-b1a3-5a683fab51bc.png" width="800">

# Google Adsを設定する

## 前提条件

Google Adsのアカウントを設定する前に、以下のものが必要です。

- Googleアカウント
- ビジネスのためのWebサイト

ウWebサイトをお持ちでない場合でも、スマートキャンペーンを利用することができます。スマート キャンペーン機能を使用すると、必ずしも専用のウェブサイトを持たずに、Google 検索、Google マップ、Gmail、YouTube、および特定の Google パートナーWebサイトに広告を掲載することができます。

## アカウントを設定する

Google広告のアカウントを新規に設定するには、以下の手順を完了する必要があります。

1. キャンペーン目標を決定する。
1. キャンペーンの種類を選択する。
1. 選択したキャンペーンタイプに基づいて、キャンペーンの設定と機能を構成する。
1. 広告グループを使用するかどうかを決定する。
1. 広告を作成する。
1. 課金情報（支払い方法など）を入力する。

### Steps 1 through 3: Campaign goals, types, and settings

キャンペーンを作成したら、目標を選択します。これは、キャンペーンの主な目的である必要があります。例えば、サイトへの訪問者数を増やすことが主な目的である場合、目標に「ウェブサイトのトラフィック」を選択します。

次の表は、さまざまな種類のキャンペーンで使用される目標のカテゴリをまとめたものです。キャンペーンの設定は異なり、選択したキャンペーンタイプに依存します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2358573/e13be725-a2d1-31da-c710-c6f44d06c3cb.png" width="７00">

### Steps 4 and 5: Ad groups and ads

広告グループには、共有のキーワードセットをターゲットとする1つまたは複数の広告が含まれています。広告グループは、キーワードに基づいて広告を整理するのに非常に便利で、最も関連性の高いキーワードに基づいてキャンペーンに適した広告を選択することができます。事業目的別に分けられた少数の広告グループと大規模な広告グループは、トラフィックを集約し、広告ごとのインプレッション数を増加させます。

### Step 6: Billing

アカウントの支払い方法は、通貨とお客様のビジネスが登録されている国によって異なります。

広告を作成する際には、特定の請求先情報が必要となり、以下を含みます。

- Billing country: determines the other billing options
- Time zone
- Account type (*Business* or *Individual*)
- Billing name and address for the account
- Name, phone number, and email address for the account’s primary contact.
- Payment method information
ChatGPTのレスポンス時間改善策

ChatGPTのトライアルが大ブームですが、応答待ち時間が長いと感じられている方が多いと思います。
APIには、Streamモードが用意してあって省略時はオフですが、これをオンにすると、だいぶ早く感じられますね。
テストBenchでオンとオフを試せるようにしましたので、APIキーを用意して確認して見て下さい。
https://mori1-hakua.tokyo/gadget/testBench.html
![StreamPro.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935344/1c21f95e-2757-bc75-d82f-8a073f69a41a.png)
Rubocopの導入

Gemfileに以下の2行を追加する

```ruby:Gemfile
group :development do
# 〜 省略 〜
  gem 'rubocop'
  gem 'rubocop-rails' 
# 〜 省略 〜
end
```
bundle installで反映させる

```:ターミナル
bundle install
```

### 参考
* [VSCodeでRubocopを使う - Qiita](https://qiita.com/d0ne1s/items/a3566aca023d11f2bfc4)
ChatGPTを使ってプログラム実行、リファクタリング、テストをやってみた

## この記事は何
記事投稿キャンペーン「ChatGPTなどの活用方法を発信しよう！」の参加記事です。

https://qiita.com/official-events/b80ebe828fa453edf260

ChatGPTの可能性を色々模索している中で試したことを記事としてまとめました。

## ChatGPTとは
ChatGPTについてはすでに多くの記事が投稿されていますので、割愛します。
以下の記事などをご参考ください。

https://qiita.com/omiita/items/c355bc4c26eca2817324

## 思ったこと

https://gigazine.net/news/20221206-virtual-machine-inside-chatgpt/

の記事を読み、「ChatGPTはコンピュータの処理のエミュレートもできるのでは？」と考えました。
つまり、ChatGPT上でプログラムの実行も行えそうです。

## 実際に試した

ChatGPT上でプログラムが実行できそうか、試してみました。

まずはRuby。今回はフィボナッチ数列のプログラムが実行できるか試してみました。
ちなみにコードは https://qiita.com/zooootech/items/d8ca1e9d8cfde5646591 の記事のものを実行しています。

![スクリーンショット 2023-03-25 9.02.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158501/1fac922c-ca80-5f38-cbd8-8ceb073a9849.png)

できていそうです！
では次はPython。
https://qiita.com/dovedove/items/3456c4f317a5c680f437 の記事のコードを試してみます。

![スクリーンショット 2023-03-25 9.06.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158501/688bc518-35bb-951f-1788-eb1a0d4af66f.png)


同じくできていそうです！

最後にC言語です。
こちらんのプログラムは https://qiita.com/keitean/items/18d667db7030c8add8c4 のコードを参考にしました。

![スクリーンショット 2023-03-25 9.10.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158501/045cb015-b82a-af89-e005-650bb02b381f.png)

実行できました。

どこまで可能なのかはわからないですが、フィボナッチぐらいの処理であればChatGPT上でエミュレートできることがわかりました。

## リファクタリングをしてみる
最近ChatGPTの利用方法として「要件に合わせたプログラムを生成してもらう」事例をよくみます。
しかしその逆の渡したプログラムのエミュレートをしてもらうことができることもわかりました。
これだけでも簡単なスクリプトであれば環境構築をせずとも実行できてしまう、とても画期的なものですが、
今回はこのエミュレートできる特性を用いて以下のことをChatGPTだけでやってみたいと思います。

1. コードのリファクタリング
1. リファクタリングしたコードが正しいかテストをする

今回は先ほど用いたRubyのフィボナッチ数列のコードのリファクタリングをしてみます。

![スクリーンショット 2023-03-25 9.18.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158501/4aae56f4-34ff-e7f4-18c9-170bb0696ea1.png)


できました！

## テストをしてみる。
前項でリファクタリングができたことは確認できましたが、本当にリファクタリング前後で同じ処理をしているかも検証したいです。

とりあえず以下のようなプロンプトを投げてみました。

![スクリーンショット 2023-03-25 9.19.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158501/9756ee4d-1040-e7d5-bbd4-d945eb219cff.png)

ただしそうです。
ただ、これだけだと本当に検証をしているのか（適当に言っていないか）わからないので、少し意地悪をしてみます。

### 関数の処理は同じだが出力する文字列の表現が違う。

リファクタリング後のコードの出力から「第」を消してみます。

![スクリーンショット 2023-03-25 9.21.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158501/f0bdbb7b-cdcc-c463-65d3-030822ae53b3.png)

ちゃんと認識できていそうです。

### 余計な処理を入れてみる
フィボナッチ数列の処理に関わるところは同じですが、二つの目のプログラムに最後余計な出力を出してみます。

![スクリーンショット 2023-03-25 9.23.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158501/b494c9c2-c6c2-db6d-4246-0b2aae61b46a.png)

ちゃんと認識できていそうです。

### 結果は変わらないけど余計な処理を入れる
結果自体はかわらない状態で、使っていない不要なメソッドを追加してみます。

![スクリーンショット 2023-03-25 9.24.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158501/5b3102d0-87bd-165a-f6a9-4085dd0b0a14.png)

これも認識されていそうです。

## まとめ

今回はChagGPTでコードの実行→リファクタリング→テスト
を行ってみました。
どれだけ精度が出るかはわかりませんが、今回のユースケースぐらいであればかなりの精度で処理を行えそうです。
現在でもこれだけのことができるということは、本当に近い将来いまの開発体験の常識が変わっていきそうです。

※なお、この記事のタイトルとタグはChatGPTに生成してもらいました。
Spring Security その3.5〜defaultSuccessUrl

前回まで
[Spring Security その１〜ログイン機能の実装](https://qiita.com/daiki7010/items/fd4fdf8afd51c3ca9917)
[Spring Security その２〜DB認証](https://qiita.com/daiki7010/items/c838bff7bd456e002e1b)
[Spring Security その2.5〜デフォルトのログアウト画面](https://qiita.com/daiki7010/items/0b9409bb1297c36778d6)
[Spring Security その３〜ログイン画面のカスタマイズ](https://qiita.com/daiki7010/items/f0f176ec3ef8af5ab370)

前回作成したログイン画面のカスタマイズで少しハマってしまったこと。
「defaultSuccessUrl」の役割

defaultSuccessUrlに/toppage と指定しても、認証後に/toppageに遷移しないことがある。
例えば：認証前に「/secondPage」 にアクセスした場合、一度ログインページに遷移し、認証が完了すると「<font color="Red">/secondPage</font>」に遷移する。

? defaultSuccessUrlの説明ではログイン認証後に遷移するURL という説明が多かった。
なぜ、toppageに遷移しないんだ？

公式の説明を読むと、答えは簡単だった

:::note
ユーザーが認証前にセキュリティで保護されたページにアクセスしなかった場合、認証後にユーザーがリダイレクトされる場所を指定します。
:::

上記の例では認証前にセキュリティで保護されたページ（secondPage）にアクセスをしたので、認証後はそのURLに遷移となった。

これはspringSecurityでは直前にアクセスしていたURLを「SavedRequest」に保存され、認証後にはこの保存したURLにリダイレクトとなるからだ。

では、絶対にdefaultSuccessUrlに指定したページに遷移させたい場合はどうするのか。
defaultSuccessUrlにパラメータ「alwaysUse」にTrueを設定するだけ。

実際にはこんな感じ
```java
     .defaultSuccessUrl("/toppage",true)  //②
```
※コードの全体像は[Spring Security その３〜ログイン画面のカスタマイズ](https://qiita.com/daiki7010/items/f0f176ec3ef8af5ab370)を参照してください

これで、ログイン認証後は必ず/toppageへ遷移することとなる。
【java】ArrayList(コレクション)での要素数の取得

```Java
import java.util.ArrayList;

public class Main {
    public static void main(String... args) {
        ArrayList<String> fruits = new ArrayList<>();

        fruits.add("apple");
        fruits.add("melon");
        fruits.add("lemon");

        System.out.println(fruits.size());
    }
}
```

出力はこうなる
```
3
```