OmniAICreator/Qiita-1.07M huggingface dataset:
Java Gold SE 11を受けての感想

# Java Gold SE 11の概要
## Java Gold SE 11（以下Java Gold）とは
Java Gold SE 11とは、オラクル認定資格の一つで、
* Java Bronze
* Java Silver
* Java Gold
の3つの試験の一番難しい資格のことです。
受けるにはJava Silverに合格していることが必要です。

## Java Goldの試験範囲
Java Goldの試験範囲は、以下の項目です。
細かい説明は[こちらのURL](https://www.oracle.com/jp/education/certification/1z0-816-jpn-31705-ja.html "Java SE 11 Programmer II (1Z0-816-JPN) 試験")を参照してください。
* Javaの基礎
* 例外処理とアサーション
* Javaのインタフェース
* 汎用とコレクション
* 関数型インタフェースとラムダ式
* JavaストリームAPI
* 組込み関数型インタフェース
* ストリームに対するラムダ演算
* モジュール型アプリケーションに移行する
* モジュール型アプリケーションにおけるサービス
* 並列処理
* 並列ストリーム
* I/O（基本およびNIO2）
* Java SEアプリケーションにおけるセキュア・コーディング
* JDBCによるデータベース・アプリケーション
* ローカライズ
* アノテーション

## 試験時間
試験時間や問題数、合格に必要な正解率はそれぞれ
* 試験時間：150分
* 問題数：80問
* 合格に必要な正解率：63%
です。

## 使用した参考書
今回資格の勉強をするにあたって使用した参考書は以下の二つです。
* [オラクル認定資格教科書 Javaプログラマ Gold SE11](https://www.amazon.co.jp/%E3%82%AA%E3%83%A9%E3%82%AF%E3%83%AB%E8%AA%8D%E5%AE%9A%E8%B3%87%E6%A0%BC%E6%95%99%E7%A7%91%E6%9B%B8-Java%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E-Gold-SE11-%E8%A9%A6%E9%A8%93%E7%95%AA%E5%8F%B71Z0-816/dp/4798162027/ref=pd_lpo_2?pd_rd_w=bsgzc&content-id=amzn1.sym.d769922e-188a-40cc-a180-3315f856e8d6&pf_rd_p=d769922e-188a-40cc-a180-3315f856e8d6&pf_rd_r=9D14GXXTHTMW32Q33ZCX&pd_rd_wg=JATtd&pd_rd_r=0918187b-7d1c-484a-b309-3322552c5924&pd_rd_i=4798162027&psc=1)
* [徹底攻略Java SE 11 Gold問題集](https://www.amazon.co.jp/%E5%BE%B9%E5%BA%95%E6%94%BB%E7%95%A5Java-SE-11-Gold%E5%95%8F%E9%A1%8C%E9%9B%86-1Z0-816/dp/4295012564)

いわゆる紫本と黒本です。

## 勉強方法と勉強期間
勉強方法としては、
1. 紫本を１通り読み、それぞれの章末問題と最後の演習問題を解く
1. 1で間違えた問題を中心に、分からないところの内容を復習する
1. 黒本の問題集を解く

というオーソドックス？なやり方でした。
Java Silverと被る部分も多く、勉強期間としては1日1時間を1ヶ月程度で行けました。

## 結果と参考書への感想
結果としては、88%で合格することができました。
紫本と黒本で出た問題と類似の問題が非常に多く、これらの参考書の問題が解け、その理由が分かっていればまず合格することができるという感じでした（回し者ではないです）。
紫本のテキストの部分は正直読んでいると眠気に襲われるので、テストの合格を目的とするならば、さらっと読んで問題の復習をしっかりとやるのが効率的だと思います。

## Javaの力はついたのか
Javaの資格をとってみて、
* オブジェクトの型への意識
* 参照できるものとできないものの理解
* 例外処理への理解
* Stream APIの使い方

あたりの、普段の開発ではそこまで意識しない部分についての理解は深まったのかと感じました。
一方で、これを取ったからといって、実装力が高まるとかではないなと思いました。
後、コンパイルエラーかどうかを聞かれる問題がそこそこあるのですが、コンパイルエラーになるかどうかをプログラムだけで判断する能力は本当に必要なのかと思ったり思わなかったりします。
いづれにしても体系的な知識を得るには良い試験だったと思うので、実際にJavaで開発を行っていけば、Java Goldに感謝する日が来るかもしれません。
[Linux]/etc/crontabと/var/spool/cron/[user]

# はじめに
先日、業務中にどんな日時バッチを行なっているのか気になって/etc/cron/配下を調べてみました。しかし、そのフォルダ配下には私が探しているバッチプログラムがありませんでした。少し気になって調べたところ、/var/spool/cron/{user}に書かれていたので、その違いを議事録として残しておきます。
# Cronのおさらい
そもそもcronとは、Linuxのジョブを自動実行するためのデーモンのことを指します。実行したいプログラムをスケジューリングすることで、定期実行を行なってくれるのでバッチに使われます。ある特定の日時に一度だけ実行したい場合はcronではなくatコマンドを用いるといいと思います。

# /etc/crontabと/var/spool/cronディレクトリの違い
## /etc/crontab 
・利用者:root
・システム全体に適用したいジョブを定期実行したいときに用いる
・ファイルの記載方法は`分 時 日 月 曜日 ユーザ コマンド`
・/etc/crontabは「大元の設定ファイル」のイメージなのでできるだけ編集しない方がいい
・システム全体に適用したいジョブがある場合は、
`/etc/cron.hourly`,`/etc/cron.daily`,`/etc/cron.weekly`,`/etc/cron.monthly`配下のファイルに設定を行う(/etc/crontabに、上4つのディレクトリが時間ごとに定期実行されるように設定されている)
・ファイルの編集は`vi /etc/crontab`


## /var/spool/cron/{user}
・利用者:各user
・ユーザーごとのジョブの定期実行に用いる
・ファイルの記載方法は`分 時 日 月 曜日 コマンド`(etc/crontabファイルと違ってユーザは指定しない)
・ファイルの作成/編集 は`crontab -e`

## 終わりに
Djangoのカスタムコマンドを作成して、cronに登録しておくと便利そうですね。

## 参考記事
https://www.express.nec.co.jp/linux/distributions/knowledge/system/crond.html

https://qiita.com/takahashi-kazuki/items/77d669d4414c6ec185f9
「AWS Amplify Studioではじめるフロントエンド+バックエンド統合開発」 輪読会①

## 開催日時
2022.11.6

## はじめに
初回は今後の進め方を議論しました。

## 終わった頃にどうなっていたいか
- Amplify(Studio)の基本を習得している
    - Figmaによる簡易的なデザインができる
    - Figimaから簡易的なプロトタイピングができる
- 皆、仲良くなって新たなコミュニティができる、コミュニケーションが生まれる☺️

全体方針
- 他人を攻撃しない、互いにリスペクトする
- しょぼくてもアウトプット中心
  - Qiitaなど
:::note info
Qiitaは活動記録を投稿予定。各自、纏めたければ纏めてQiitaへ投稿。強制はしない。各会は録画してYoutube限定公開するかも。
:::
- 1冊はやりきりたい(全部やらなくても必要そうなところだけでもよいかも)
:::note info
開催周期は隔週
:::
- Amplify(Studio)以外(例えばJavascriptやReactなど)はそこまで手厚くやらない。
    - Chapter3,5,6,7に集中する
    - Chapter2 は各自やる
    - Chapter3(次回:11/19~11/20頃を予定)
        - 2Hくらいハンズオン
        - 初回はOKAPEE&Abeがハンズオン #グダると思いますが生暖かい目で…
        - 最初の会はみんなのバックグラウンドを話してもらう

## 事前準備は?
- 事前にパラパラとでも目を通せるとよい
    - できれば何かアウトプットしてみること
統計検定2級受験への過程

# 前提
- 統計検定2級を受けるにわたって過程をまとめ
- 2022年12月中には受験予定
- 統計については、学部の授業でかじった程度、機械学習の本などで簡易に得た知見が少しあり

# 行った方法
1. 日本統計学会公式任的　統計検定2級対応　統計学基礎
1. 統計検定 2級 公式問題集 2018~2021年

# 備忘
- 2022/11/6 udemyで、2時間ほど学習
sam initがWindowsで失敗する場合はパスの文字列設定の上限を変更する。

IntellJでSAM Applicationを作成しようとしたときに引っかかったのでメモする

## 起きた事象

sam init を実行しようとしたところ以下のエラーが発生

```
Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)
Error: Unstable state when updating repo. Check that you have permissions to create/delete files in C:\Users\masas\AppData\Roaming\AWS SAM directory or file an issue at h
ttps://github.com/aws/aws-sam-cli/issues
```

エクスプローラーからファイルのパーミッションをいじっても変化がなし

原因はパーミッションではなくWindowsのパスの上限が260文字にデフォルトの制限に引っかかりファイルが認識できないことらしい

## 解消方法

PowerShellでLongPathsEnabledの設定をすることで解消できる。

PowerShellを管理者モードで開き以下をコマンドを実行

```
PS C:\Windows\system32> New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" `
>> >> -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
```

以下のようにコマンドが通れば正常完了

```
C:\Users\masas\IdeaProjects\untitled1>sam init 

You can preselect a particular runtime or package type when using the `sam init` experience.
Call `sam init --help` to learn more.

Which template source would you like to use?
        1 - AWS Quick Start Templates
        2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
        1 - Hello World Example
        2 - Multi-step workflow
        3 - Serverless API
        4 - Scheduled task
        5 - Standalone function
        6 - Data processing
        7 - Infrastructure event management
        8 - Serverless Connector Hello World Example
        9 - Multi-step workflow with Connectors
        10 - Lambda EFS example
        11 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: y

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: N

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]:

Project name [sam-app]:


Cloning from https://github.com/aws/aws-sam-cli-app-templates (process may take a moment)

    -----------------------
    Generating application:
    -----------------------
    Name: sam-app
    Runtime: python3.9
    Architectures: x86_64
    Dependency Manager: pip
    Application Template: hello-world
    Output Directory: .

    Next steps can be found in the README file at ./sam-app/README.md


    Commands you can use next
    =========================
    [*] Create pipeline: cd sam-app && sam pipeline init --bootstrap
    [*] Validate SAM template: cd sam-app && sam validate
    [*] Test Function in the Cloud: cd sam-app && sam sync --stack-name {stack-name} --watch
```

## 参考リンク

[パスの最大長の制限(Microsoft)](https://learn.microsoft.com/ja-jp/windows/win32/fileio/maximum-file-path-limitation?tabs=registry)
[sam init quickstart templates failing on windows #4031](https://github.com/aws/aws-sam-cli/issues/4031#issuecomment-1183633630)
[【SAM + Cognito + Amplify ライブラリでログイン機能を実装した React アプリを作成】Part1 - SAM で API 作成](https://blog.css-net.co.jp/entry/sam-amplify-react-01)
Visual Studio Code　おすすめ拡張機能

https://zenn.dev/toono_f/articles/38fd6ce1cf82e5


https://qiita.com/mayobimu/items/12c65c27c2098385283b




https://codezine.jp/article/detail/16467



https://qiita.com/ckbys/items/019b2bc32c3d1a95673a


https://zenn.dev/nameless_sn/articles/recommended_vscode
TypeScriptでQiita記事のPV情報を取得してみるメモ


Denoでの利用で勉強中メモです。

Fetch APIを使うサンプルとして前に書いた記事をベースにTypeScript版にしてみました。 

https://qiita.com/n0bisuke/items/40d0c7831d22c4f1868b

今回は`/items/:itemid`のAPIなので記事の情報取得ですね。


```ts
const BASE_URL = `https://qiita.com/api/v2`;

const getQiita = async (url: string): Promise<string | null> => {

    const ITEM_ID = url.split(`/items/`)[1]; //ITEMIDを抽出
    const ENDPOINT = `${BASE_URL}/items/${ITEM_ID}`;

    try {
        const options = {
            headers:{
                'Authorization': `Bearer <トークン>`,
                'Content-Type': 'application/json'
            }
        }

        const jsonResponse = await fetch(ENDPOINT, options);
        const jsonData = await jsonResponse.json();
        // console.log(jsonData);
        return jsonData.page_views_count;
    } catch (error) {
        throw new Error(error);
    }
}

// const url = `https://qiita.com/n0bisuke/items/b0cf0c416aa8e46bdb1b`;
const url = `https://qiita.com/atoms50/items/69c79fe8e38487e31825`;
const pv = await getQiita(url);
console.log(pv);
```

## PVの値は自分じゃないと取れないので注意試してみる

実行するとPVが取れます。

ただPVの値はトークン認証しているユーザー（この場合だと自分）の記事のみ見れるみたいです。

- 自身の記事の場合

https://qiita.com/n0bisuke/items/b0cf0c416aa8e46bdb1b

```bash
$ deno run --allow-net qiita.ts
863
```

- よしだくんの記事の場合

https://qiita.com/atoms50/items/69c79fe8e38487e31825

```bash
$ deno run --allow-net qiita.ts
null
```

他にも他人の記事だと取れないパラメータがあるかもしれないですね。

## 参考

https://deno.land/manual@v1.26.2/examples/fetch_data
Live Sass Compilerでコンパイルすると毎回ターミナルが出てくる件

最近VSCodeで、Live Sass Compiler v5があったので更新してみたが、コンパイルするたびにターミナルが出きたので原因探ってみた時のメモ。

## メモ内容
エラー出た時のみ、ターミナルで警告して欲しい時の設定。

## 設定方法
### ① **v5.○.○** のLive Sass Compilerの「拡張機能設定」

![スクリーンショット 2022-11-06 15.09.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625899/96d78fa2-7c24-4624-a4a4-1de2fa680812.png)


### ② 下の方の、「Show Output Window On」までスクロール

![スクリーンショット 2022-11-06 15.09.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625899/898c1bca-8219-4b3b-47fa-a367e547c2f9.png)


### ③ プルダウンで「Error」を選択

![スクリーンショット 2022-11-06 15.11.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/625899/35663f82-9fa1-9c5a-edad-55c65e980d02.png)

以上。
ブラウザアプリからローカルマシンを操作する方法

基本的にブラウザは厳格にサンドボックス化されているため、WebアプリからMac/PCを操作することは不可能です。
しかし最近はブラウザUI付きの開発環境が続々出てきていて、ボタンクリックでローカルディレクトリが作成され、型枠生成されたりして、完全にブラウザからローカルマシンを操作してますよね。

これをどうやっているのかと言うと、シンプルにlocalhostでサーバーを立ち上げ、そこにAPI通信してサーバー側（ローカルのjsファイル等）からローカルマシンを操作しています。
![スクリーンショット 2022-11-06 14.21.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/191185/393f2560-31a1-3233-7bc0-e2ecff8ff6fa.png)
こんな感じ。
なので、どうやってもローカルにサーバーを立ち上げていないと成立しません。
パターンとしては、

**CLIとセットにし、コマンドを打つと同時にサーバーを立ち上げてからWebアプリを開く。**

これしかないんじゃないかな。
とりあえず、[VueCLI](https://cli.vuejs.org/dev-guide/ui-api.html)の```vue ui```コマンドに関してはまんまこのやり方です。
危なっかしい感じもしますが、完全にフリーダムな実装ができると思います。

[Electron](https://www.electronjs.org) に関してはIPC（プロセス間通信）とか言う技術で実現してるらしいですが、まだソースコード見てないのでよく分かってません。何となくIPCの方がlocalhost剥き出しにするよりは安全な感じはしてますが、完全にパッケージ化しないといけないと思うので、気軽な機能には使えないような印象を持っています。（と言ってもElectronはかなり気軽に実装できます）

何にしてもUIを簡単に作れるのは素晴らしいですね。
新人に教えたいコードを書く時に注意していること

最近、若手に教えることが増えてきて、ふと思ったので書くことにしました。

「プログラムを書く」

システム開発をしていると切っても切り離せない作業ですが、プロジェクトチームで担当している時に「できる限り全員同じようなコードを書き残したい」と思っています。
そのため、ある程度のコーディングルールは決めて、システムチームで共有しています。

PHPのコーディングルール規約は、こちらのページが分かりやすくてオススメです。
まだまだPHPを始めたばかりの人は、一読しておいて損しません（というより一読しておくべきページです...笑）

https://www.infiniteloop.co.jp/docs/psr/psr-2-coding-style-guide.php

実際の現場は、上記だけを守っていればよいというわけではありません。
フレームワークを使ったりしていると、「クエリをベタに書く」 or 「フレームワーク独自のクエリビルダで統一する」などなど臨機応変に対応する場面があると思います。

今回はもう少し基礎的なルール・書く時の注意点を書いていこうと思います。

## 変数名は分かりやすく

ネットで調べるとたくさん記事が出てくるので、知っているかもしれませんが・・・

変数や関数は、見るだけで「何をしている」のか分かるもののほうが良いです。

理由は、後で手を加える時や、修正の時に、コードを深く読まなくても分かりやすくするためです。

開発のシーンでは、最初に開発した人と、運用・改修していく人が違うことは多々あります。

「自分が分かれば大丈夫」
でコードを書いていると、後々大きな手間が発生します（数ヶ月後の自分も変数名なんて覚え切れてないので、コードを読み直すハメになりますしね...笑）

**変数名は見て一発で分かるもの**にしましょう！！

## 一言でわかるコメントを書く

こちらも変数名と同じく、数ヶ月後の自分はコードの中身などさっぱり覚えてないので、**プログラムがどこで何をしているか分かるようにしておくために**書きます。

最初のうちは、余分だなと感じるくらい書いてもいいと思っています。
慣れてきたら、必要な箇所にだけ記載することができるようになりますよ。

他の誰かが改修する時の手助けにもなるので、同じ開発チームの人をことを思うなら書いているほうが丁寧ですね。

## 専用のメソッドより何回も使えるメソッドを

共通化できる処理は、常に共通メソッドとして独立させましょう。
画面1と画面2、画面3で同じ処理をしているなら、共通の処理としてまとめたほうがプログラム的にも読みやすいです。
（例として、ログイン画面と登録画面でパスワードを暗号化する処理があるなら、暗号化は共通の処理としたほうがいいですね）

**共通の処理をどの画面からも使えるように作ると、より汎用性が上がります。**
逆に、渡す値などを各画面固有のものにしか対応していないように作ると、画面の数だけ同じ処理を作成することになります。

こんなふうに作ってしまうと、作る時にも時間がかかりますし、修正の時にも全部に同じ修正を加える必要が出てきます（この時、凡ミスが起こったりもすると、さらに面倒です...笑）

### さいごに

自分も新人の頃は、
**「この変数なんだっけ？」** とか
**「共通処理で何しているか分からない...」**
と思っていましたが、変数名をわかりやすくすることや、共通メソッドを作成することが非常に重要と思っています。

システム開発は個人でもできますが、長期的に管理・運用していくのはチームのことが多いです。
全員が分かりやすく、改修しやすいシステム開発を心掛けたいですね。
Assert.Thatを使いましょう - NUnit2005

次のように警告(Warning)が表示されていたのでテストコードを修正しました。

```sh
warning NUnit2005: Consider using the constraint model, Assert.That(actual, Is.EqualTo(expected)), instead of the classic model, Assert.AreEqual(expected, actual)
```

なんでも```Assert.AreEqual(expected, actual)```だとActualとExpectedの順番を間違えやすいということで```Assert.That()```を使いましょうとのこと([source](https://docs.nunit.org/articles/nunit-analyzers/NUnit2005.html))。

ConstrainモデルのConstrainについては下記。
https://docs.nunit.org/articles/nunit/writing-tests/constraints/Constraints.html
EclipseをIntelliJ IDEA風に設定する

Eclipse を IntelliJ IDEA に近づけて、各々の IDE を併用したときに違和感なく使用できるようにするための設定やプラグインを記載します。

## 環境
* Windows 10
* Pleiades All in One Eclipse 2022

## 変更前
インストール直後はこのような見た目でした。
ここから IntelliJ IDEA の Darcula テーマに近づけるように設定変更していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/1d5dd74f-f342-fde1-646e-56937ee2938e.png)

## 1. テーマ
プラグインの Darkest Dark Theme with DevStyle でテーマを近づけます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/1c610035-1ba0-0d84-4c3a-f92443a8a99c.png)

ワークベンチ・テーマで Dark Gray (Darkest Dark) 、エディター・テーマで IntelliJ IDEA Dark を選択します。
これで色味がかなり近づきます。
更に「テーマの背景」をチェックすると背景色も近づきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/2f3af06f-32fb-eae2-6186-521db114f707.png)

色味が異なる部分もあり、フィールドや引数などが青系の色味になっています。
これはこれで見やすいので、私はこのまま使っています。
更にカスタマイズしたければ以下から変更できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/15094ff3-0335-1526-55ba-d37e37f9c68f.png)


## 2. フォント
IntelliJ IDEA は JetBrains Mono というフォントです。
リンク先からフォントをダウンロードできます。

https://www.jetbrains.com/ja-jp/lp/mono/

zip を解凍し、ttf フォルダの JetBrainsMono-Regular.ttf を右クリックしてインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/6bc267c0-fa96-7989-66b4-213b76d2c6c0.png)

これで Eclipse 上でフォントを選択できるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/c6b5295c-159a-d11c-cbe9-816082db0dec.png)

## 3. ショートカット
プラグインの IntelliJ IDEA keymap for Eclipse でショートカットを近づけます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/c6a5460b-37a2-4b05-2473-e170088da9cd.png)

スキームで IntelliJ IDEA を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/7223d5d3-67d4-ca68-5b63-5bf0e8eb0c83.png)

## 4. 自動保存
自動保存も設定できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/e401f03b-f7a9-be0c-30e2-8c4027d6d96c.png)

## 5. 英語化
私は英語の勉強も兼ねて英語化して利用しています。
eclipse.ini の以下2行を削除するか#でコメントアウトすることで英語化できます。

```
-Xverify:none
-javaagent:～/pleiades.jar
```

## 変更後
最終的にこのような見た目になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/422235/b3225089-29ba-5ea5-d631-e550b9acfa7f.png)

その他にもリンク先に IntelliJ IDEA から Eclipse へ移行するための設定がまとめられているため参考にしてください。

https://techfact555.blogspot.com/2020/04/change-eclipsespring-tool-suite-sts-ide.html

他にオススメの設定などがあればコメントください :raised_hands:
BertJapaneseTokenizer を用いる際に必要なライブラリ

#### BertJapaneseTokenizerをhugging faceのcl-tohokuのbartモデルを利用する際に必要なライブラリのメモ

###### mecabとfugashiが使えればOK


```.tsx:Bash
pip install mecab-python3
pip install unidic
pip install ipadic
pip install fugashi

```
Raspberry Pi へMongo DBをインストールする際のメモ

# Raspberry PiへのMongo DBインストール方法
以下記事を参考にインストール：
https://www.mongodb.com/developer/products/mongodb/mongodb-on-raspberry-pi/
* そもそも32bitのRaspberry Pi OSを使っている場合は最初に64bitのRaspberry Pi OSへアップグレードが必要。（32bitの場合はかなり古いmongoしか使えない）
* Mongo DBはv4.4より上のバージョンにアップグレードしようとしてもエラーとなるので余計なことはしない方が良い。

## Mongo　DB v6⇨v4への変更で修正した箇所
* "insertMany"関数がサポートされていないので、"create"関数に修正
DBeaverのいいところ


## SSH経由でアクセスできる

データベースがLISTENしてるポートがむき出しのことってほとんどない。
そとから接続できるのはsshのポートだけ。
SSHであれば公開鍵認証で強い認証が使える。

それができないDB-GUIはポートフォワードでlocalhost:3306に接続するとリモートサーバーにフォワードされる仕組みを取る必要がある。やりゃあいいけど、接続先が増えると大変。だからssh経由でアクセスできる必要がある。

## mac,win,linuxのマルチプラットフォーム

JavaでUIが作られてるからOS跨いで使える。サーバーサイドエンジニアにとっては手元PCのOSは何でもいいんだけど、開発者同士で情報交換する上では、同じフロントを使うほうがいい。ただ、Macの場合はSequelAceという扱いやすいDB-GUIがあるので使ってる人はすくなさそう。

## 本番、検証、開発で色を変えれる

接続先に応じて背景色が変えれる。地味だけどこういう気遣いができるあたりがプロの道具。

## SQLのコード補完が賢い

select  from tablename

と書いてから

select | from tablename

とカーソルを戻すのがちょっと面倒だけど、コード補完が賢いおかげでSQLを素で書く心理的負担が少ない。

## SQLのスクリプトが残る

前回のSQLを参考に作りたいときなど便利。似て非なるSQLが大半なので、これまでのSQLが残ってることは大事。

## テキスト形式で出力ができる

地味に嬉しいのがテキスト形式での出力。SQLの出力結果がテキストベースでも出せる。エビデンスの報告がテキストベースでできちゃう。GUIだけではなくCUIとの相性もいい。

## エクセルにも貼りやすい

当然タブ区切りテキストとしてコピーも可能なので、そのままエクセルにコピペできる。

## 対応データベースエンジンが豊富

Javaで作られてるからこその強み。ほとんどのデータベースはJDBCドライバを提供しているから、接続先が豊富。データベースサーバーのプロダクトが変わってもUIはほとんど変わらず使える。MySQLもPostgresもOracleもAthenaも同じUIで管理できる。

特にMySQLとPostgesは、CUIの使い方がまるで違うので混乱する。MySQL使いがpsl上で「exit」「quit」とジタバタすることはよくある。Dbeaverなら本当に同じように使える。

## 無料

DBeaverも有料版はあるんだけど、無料版でも十分使える。

## UIがきれいというか普通

Javaで作られたUIってフォントがにじむことがある。DBerverはEclipseと同じUIキットを使ってるため、フォントのレンダリングが違和感がない。フォントのにじみは「アンチエイリアスだからこれがきれいなのだ」という理屈はどうでもいい。他のアプリと同じ描画をすることが大事。
【Qiita】diff:'ファイル名'で差分コードの左上にファイル名を表示する方法

### 対象とする読者
「Qiitaの記事で、差分コードの左上にファイル名を表示したいなぁ...。」
と頭の片隅で思っている人。
<br>
（↓こんなイメージ）
```diff:index.html
- hogehoge
+ hoge
```

### 結論
\```diff:index.html
hogehoge
\```
<br>
これを丸ごとコピーでOK！

### 補足
ファイル名を表示させる場合と
表示させない場合での色の付け方の違い
```diff_html
- hogehoge
+ hoge
```

```diff:index.html
- hogehoge
+ hoge
```
UbuntuでsudoするとX serverに接続拒否されるとき

CASAのパイプラインを自前のサーバーで走らせようとしたときに、```sudo``` でCASA開くとX serverに接続拒否されて困ったのでメモ。

non-root userで
```
xauth list $DISPLAY
```
で表示される文字列をすべてコピーしておき、
```
sudo -s
```
でログイン後
```
xauth add [上でコピーした文字列]
```
でOK。ここで ```xauth:  file /root/.Xauthority does not exist``` みたいなエラー吐くときは ```touch /root/.Xauthority``` してから ```xauth add``` をやる。以上。
まずはTOPページを出してみよう〜CURD機能の説明を添えて〜

#### 超初心者のための覚え書きです

まずはTOPページをブラウザに反映させるまでの手順をサクッと。
①コントローラーを作成
②アクションを定義
③ルーティング
④viewファイル作成
⑤サーバーを起動
⑥URLへアクセス

##### コントローラーを作成

```
rails g controller homes
```
コントローラーの名前は複数形で小文字で書くこと。
私はWebアプリ初作成の時、コントローラーを単数形で作成してエラー起こしました。
コントローラーは、ルーティングをもとに処理を実行して、対応する画面を表示させます。
画面に渡すデータ（インスタンス変数）を定義してくれます。

##### TOPアクション定義

作成したhomesコントローラーにTOPページを表示するための定義をしていきます。
```ruby:controller/homes_controller.rb
class HomesController < ApplicationController
  def top  
  end
end
```

##### ルーティング

ルーティングの役割は「URLとアクションを結びつけること」です。
特定のURLにアクセスしたときに、どのコントローラーのどのアクションに処理を振るかを定義します。
```
HTTPメソッド 'URL' => 'コントローラー＃アクション'
```
このHTTPメソッドについては最後に説明しています。
```ruby:config/routes.rb
  get 'top' => 'homes#top'
```
このルーティングの意味は「TOP」のURLにアクセスがあった場合、「homesコントローラー」の「TOPアクション」の処理を呼び出す、という記述になります。

##### viewの作成

ビューファイルは必ずコントローラー名のフォルダ内に作成します。
そして「ビューファイルの名前は、アクション名と同じ名前にする」ルールを忘れずに。
今回の場合だと「top.html.erb」の名前で作成します。
```ruby:views/top.html.erb
<h1>好きな言葉をどうぞ</h1>
```
これでサーバーを起動するとTOPページが表示されます。
起動したらURLの最後に'/top'を加えてください。
うまくいけば先ほどビューで記述した言葉が表示されるはずです。

#### HTTPリクエストメソッドとは

初学者のときに必ずよく目にするこのHTTPリクエストメソッド。
初めは理解しづらいですが、この理解はすごく重要です。
よくHTTPリクエストメソッドと言いますが、その名の通り「リクエスト」なのです。
一概にWebサイトを使用といっても目的はたくさんありますよね？
ただその情報を見たいだけなのか、もしくは自分が何かを登録したいのか、情報を消したいのか。
この「リクエスト」の種類を表しているのがHTTPリクエストメソッドです。
「GET」「POST」「DELITE」...などありますが、大体使うのは「GET」と「POST」です。

・GET・・・名前の通り情報を「GET」します。なにかを閲覧しているときは全てGETです。
・POST・・・POSTの通り、投稿やデータを送るとき、アカウントの作成など「新規作成」で使います。
・DELITE・・・名前のまんまです。データを消します。
・PUT・・・データが存在するときは更新、データがないときは新規作成します。
・PATCH・・・こちらも更新しますが、PUTと違うのはデータが存在するものいに対して更新をします。

下記でHTTPメソッドをわかりやすく説明していますのでよければ参照ください。
>https://wa3.i-3-i.info/word11405.html

#### CRUDとは

CRUD=クラッド。
Webアプリケーションは基本的にこの４つの機能でできている。
C = Create(生成)
R = Read(読み取り)
U = Update(更新)
D = Delete（削除）
この基本機能の頭文字を取ってCRUDと言います。

#### CRUDと7つのアクション

Railsではコントローラーの基本アクションが7つあります。
[index/show/new/create/edit/update/destroy]
勉強始めたばかりの頃にペアで覚えるんだよーと教わりました。

Create・・・新しく作る(create・new)
Read・・・読む、閲覧する(index・show)
Update・・・更新(edit・update)
Delete・・・そしてひとりぼっちのdestroy(消す)

勉強始めはこのMVC（モデル/ビュー/コントローラー）の動きと、CRUD機能の理解は必須です。
初心者の皆さん一緒に頑張りましょう。
【Laravel】Bootstrapが使えなくなった時の原因と解決法

LaravelでBootstrapを使っていたが、
いきなりBootstrapが適用されなくなった。

先程解決したので、原因と解決法を記す。

## 原因
**下記のいずれかのコマンドを実行したのが原因。**
- `npm run build`
- `npm run dev`



何故なら、上記コマンド実行時に
- vite.config.js（ディレクトリ直下）
- resources/js/app.js
この2つのファイルが書き換えられたから。

## 解決法
下記ファイルを書き換えて、
`npm run build`を実行したら
うまくいった。
<br>
```diff:vite.config.js
  import { defineConfig } from 'vite';
  import laravel from 'laravel-vite-plugin';
+ import path from 'path'
  import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [
        laravel({
            input: [
                'resources/sass/app.scss',
                'resources/js/app.js',
            ],
            refresh: true,
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
    resolve: {
        alias: {
            '~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'),
        }
    },   
+	resolve: {
+		alias: {
+			'~bootstrap': path.resolve(__dirname, 'node_modules/bootstrap'),
+			vue: 'vue/dist/vue.esm-bundler.js'
+		}
+	}
});

```
:::note warn
コンマの位置が正しいか確認した方が良い。
:::
<br>
<br>


```diff:resources/js/app.js
/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

  import './bootstrap';
+ import '../sass/app.scss'

import { createApp } from 'vue';

/**
 * Next, we will create a fresh Vue application instance. You may then begin
 * registering components with the application instance so they are ready
 * to use in your application's views. An example is included for you.
 */

const app = createApp({});

import ExampleComponent from './components/ExampleComponent.vue';
app.component('example-component', ExampleComponent);

/**
 * The following block of code may be used to automatically register your
 * Vue components. It will recursively scan this directory for the Vue
 * components and automatically register them with their "basename".
 *
 * Eg. ./components/ExampleComponent.vue -> <example-component></example-component>
 */

// Object.entries(import.meta.glob('./**/*.vue', { eager: true })).forEach(([path, definition]) => {
//     app.component(path.split('/').pop().replace(/\.\w+$/, ''), definition.default);
// });

/**
 * Finally, we will attach the application instance to a HTML element with
 * an "id" attribute of "app". This element is included with the "auth"
 * scaffolding. Otherwise, you will need to add an element yourself.
 */

app.mount('#app');

```
【最終日】BOTをDiscordに認めさせよう【PythonでDiscordBOTを作ろう！】

# BOTをDiscordに認めさせよう

ついに、最終日がやってきました。
私は眠いので寝ますね。

# 100サーバー制限とは？

BOTが、どんどんと導入されていくと、100サーバー以上は申請なしでは導入できなくなります。
85サーバーを超えるとDiscord公式からDMとメールがやってきます。

ここら辺は実体験をまとめたノートを見てもらった方が早いです。

https://nattyan-tv.github.io/nira-note/bot/notes/doomsday

とりあえず、申請をして、BOTをDiscordに認めさせなければなりません。

85サーバーを超える前から先に準備をしておきましょう。
備えあれば憂いなしです。

# 必要なもの
まず、申請には個人の証明が必要です。
マイナンバーカードや運転免許証、パスポートなどが必要なのでご用意ください。

あとは...根気とかですかね？

# 流れ
## まず...

まず、BOTに「タグ」と「利用規約・プライバシーポリシー」を設定する必要があります。

タグについては特に深く考えないで良いと思いますが、利用規約とプライバシーポリシーはちゃんと考えなければなりません。

## 利用規約とプライバシーポリシー
利用規約もプライバシーポリシーも、どちらもインターネット上に公開する必要があります。
その際、GitHub Pagesや、GitHub Gistといった、無料でインターネット上に公開出来るものを使用すると便利です。
また、私は利用規約及びプライバシーポリシーの本文は日本語で押し切りました。もしかしたら英語の方がいいかもしれません。

### 利用規約
基本的に無の状態から作り上げるのはなかなかきついです。
そんな時はひな形を使いましょう。

https://kiyaku.jp/hinagata/gp.html

この時、最後の方にひな形を使用したことを明記しておくといいですね。

利用規約で気をつけて欲しいのは第一条です。
誰、どこに対してこの利用規約が適応されるのかしっかりと書いておきましょう。

参考までに、にらBOTの利用規約はこちらです。

https://nira.f5.si/terms_of_service.html


### プライバシーポリシー
こちらも同様にひな形を使用していきましょう。

https://kiyaku.jp/hinagata/privacy.html

プライバシーポリシーで気を付けて欲しいのも第一条です。
個人情報を明確に定義しておく必要があります。

参考までに、にらBOTのプライバシーポリシーはこちらです。

https://nira.f5.si/privacy_policy.html

## 申請プロセス

85サーバーを超えて、メッセージがやってきました。
すると、そこには「認証してね^^」的なものが。

Discord Developer Portalに連れて行かれて、その後個人情報の提出を求められます。

そうすると、いくつかの質問があなたを待っています。

そこでは、「アプリケーションの詳細（どのようなBOTか）」「どのようなデータを保存するか」「個人情報や送られたメッセージ本文を保存するか」「BOT利用者のセキュリティー的疑問に対応する場所はあるか」「どのような環境・言語でBOTをホストしているか」などの質問がされます。
また、同時に「[特権インテント](https://qiita.com/nattyan_tv/items/0bf051141a1abfcdd48c#intentの有効化)」の使用の是非についても問われます。

ここではちゃんと素直に書いておきましょう。
後で面倒な事になりそうです。

また、できることなら「ユニークな」機能を増やしておいて、全ての特権インテントを取得出来るようにしましょう。
後からの申請はめんどくさいです。

この時、画像（実際の動作画像）を用いて説明をするとなお良いでしょう。


## 多分最後の課題
実際に申請リクエストが送られると、多くの場合は担当者との1対1のメールのやりとりが始まります。

ここでは、そのメールの内容について詳細は伏せますが、申請リクエストの深掘り版みたいな感じです。
ここで申請が通れば、おめでとうございます！

あなたのBOTは認証されました！

（その内容を受け取った後、いつになっても認証バッヂが付かない場合は、サポートに連絡した方がいいです。）

## 最後に...!

BOTが認証されたら、あなたは「認証されたらデベロッパー」としての威厳を保たなければなりません。
とは言っても、ある程度のセキュリティ意識を保っておくことぐらいがいいと思います。

例えば、サーバーでSSHパスワードログインの無効化（[公開鍵認証方式](https://qiita.com/tag1216/items/5d06bad7468f731f590e#公開鍵認証方式での接続)）、rootログインの無効化をしたり...
[トークン](https://qiita.com/nattyan_tv/items/e39cd136d4dbc70a8964#トークンの取得)が流出しないように気をつけたり...

とりあえず、向上心を持ってこれからも開発を続けていけばいいと思います。

# まとめ
さて、25日間お疲れ様でした。私もお疲れ様でした。
大体2ヶ月で全ての記事を書き終えた（この記事を書いてるのは12/19）のですが、その間に2回も体調不良になりました。みなさんは気をつけましょう。

この記事は、いつかDiscordBOTを作る方の参考にでもなってくれればいいです。
そして、色んな所に細かいミスがあったかもしれません。（初心者向けだし私も初心者だから許される！）
みなさんもトライアンドエラーで頑張りましょう！

さて、何故私がこの記事を書いたか。
なんかQiitaに書きたかったからです(？)（後は老化防止）

さて、今年ももうすぐ終わります。
今日はクリスマスです。~~（残念ながら彼女はいませんが）~~
悔いの残らない年にしましょう。
あぁ...なんか「悔いの残らない」で四葉思い出した...ﾓｳﾑﾘ...ｺﾞﾄﾖﾒﾐﾖ...[^1]

それでは！
みなさま！
短い間でしたが！
ありがとうございました！
良いクリスマスを！
そして！
良いお年を！

__来年も頑張りましょう！__

これまでありがとうございました！
NattyanTV先生の次回作にご期待ください！（しないでね）



[^1]: 見てない人は是非見てほしいんですけど、[五等分の花嫁](https://www.amazon.co.jp/五等分の花嫁/dp/B07M7F3HVP)で四葉がこんな台詞を言ったのが健気で可愛かったです。（ネタバレをせず作品の良い所を言う良い例）
【24日目】データを保存しよう【PythonでDiscordBOTを作ろう！】

# データの保存
例えば、ユーザーの情報を記録しておいたり、ユーザーの選択を変数に保存していて、BOTが再起動した後にもそのデータを読み込みたいってときありますよね。
そんな時に使える方法を解説します。

# ローカルに保存する
変数をローカルに保存する方法はいくつかあります。
JSONで保存したり...生テキストで保存したり...
今回は、pickleについて解説します。

Pickleとは！
ピクルスから来てます。（本当に）
オブジェクトをゴニョゴニョにして保存するライブラリです。

```py
import pickle

hensu = {"name": "nattyantv", "description": "Cat Engineer"}

with open('data.pkl', 'wb') as f:
    pickle.dump(hensu, f)
```

こういう感じにすると、`hensu`が`data.pkl`というファイルで保存されます。
読み込むには、
```py
import pickle

with open('data.pkl', 'rb') as f:
    hensu = pickle.load(f)

print(hensu)
# {"name": "nattyantv", "description": "Cat Engineer"}
```
こんな感じにします。

オブジェクトを完全に保存（一部のオブジェクトを除く）することができます。

# データベースを使う方法
こっちの方がデータの管理がしやすい場合があります。
（ファイルに保存した方がバックアップとかは管理しやすい）

データベースは大体SQL関連のものが使われたりします。
痛い目を見たくない方は、データベースの自作なんかしないで、ちゃんとでかいやつを使いましょう。

https://qiita.com/nattyan_tv/items/4cdae737a308b7c62644

いろんな派閥があります。
私はMongoDBをこれから使っていく予定です。
SQL構文覚えなくて楽だしね！()

もちろん、データベースのアクセスに関しても、非同期のライブラリを探しましょう。
多分あります。（MongoDBであればmotor）

また、データベースについては、VPSなんかを使うことをお勧めします。
MongoDBであれば、Altasという無料で使えるシャーディングサーバーがあります。
東京リージョンのGCSとかAWSとかが使えるのでおすすめです。

# もうすぐクリスマスだねぇ...
さて、今日はクリスマスイブです。（本当はクリスマスイブってクリスマスの前日の夜のことを指すんだってさ）
まぁ、私はきっと家に引きこもってることでしょう。
彼女ちゃんでもいれば遊んでるかもしれませんが。
残念ながら、ねこじにあには彼女がいません。
~~絶賛募集中だよ^o^~~

ってなわけで、明日はクリスマスです。
そして、泣いても笑ってもアドベントカレンダー最終日です。
最後まで一緒にいきましょう！
次回の記事もお楽しみに！
【23日目】コードは非同期処理で。【PythonでDiscordBOTを作ろう！】

# 例えば...
コマンドにいろんな機能をつけていくと、例えば外部のAPIをコールしたり、ファイルを読み込んだりすると思います。
ここで、大変重要なことなんですけど、「非同期処理」を忘れないでください！！！！
本当に。

初めて作ったBOTでは、APIコールを全て同期処理で行っていたので、APIコール中に別のコマンド処理が一切できないという問題がありました。
そこでPR貰いながら色々理解しました。
ここでは、「同期処理を非同期処理として実行する方法」については紹介しません。
私が理解しきれていないのと、それを書いてると日が暮れてしまうからです。

では、何を紹介するか？
見落としがちな同期処理について書いていきましょう。

# 見落としがちな同期処理
ファイル操作
例えば、ファイルを読み込んだりする際に、普通に`open()`とか使ったりしてませんか？
普通のPythonであれば別に何でもいいと思うんですけど、ここは非同期の世界です。

## `aiofiles`
aiofilesというモジュールを使うと、ファイルの操作（読み込み/書き込み）を非同期で行えます。

同期処理であれば
```py
with open('nikki.txt', mode='r') as f:
    print(f.read())
```
という感じに書くものでも、

```py
import aiofiles

async with aiofiles.open('nikki.txt', mode='r') as f:
    print(await f.read())
```
という感じに書く必要があります。
こうしないと、ファイルの読み込みでブロッキングをしてしまうので、ちゃんと`aiofiles`で書きましょう。

## `aiohttp`
APIコールとかする時、本当に気をつけないといけません。

通常、requestsなどを使う、ネットワーク関連の操作は、`aiohttp`というものを使いましょう。

```py
import requests

resp = requests.get("https://httpbin.org/json")
data = resp.json()
print(data["slideshow"]["author"])
```
通常、このように書く処理は、

```py
import aiohttp

async with aiohttp.ClientSession() as session:
        async with session.get("https://httpbin.org/json") as resp:
            data = await resp.json()
            print(data["slideshow"]["author"])
```
このように書く必要があります。
こうすることで、リクエストを非同期で行うことができます。

GET以外でも、`session.post`とかってすればPOSTも非同期で行えます。

# 非同期処理があるかも！
今使ってるAPIコール系ライブラリの中にも、もしかしたらドキュメントに載ってない非同期処理があるかもしれません。
まずは、ライブラリのGitHub（ソースコード）を見てみてください。
`async`とかがあればきっとそこら辺が非同期処理かもしれません。
実際、よく使っているライブラリの`a2s`や`mcstatus`の中にも非同期処理がありました。

# そろそろ！
APIコールとかもしちゃったらそろそろ本格的なBOTです。
でも、再起動したらデータって消えちゃいますよね。
何かデータを保存したいとき、どうすればいいのでしょうか。

ってなわけで、次回はデータの保存について解説します。
さらば！
【21日目】Cogでコマンドを管理しよう【PythonでDiscordBOTを作ろう！】

# Cogでコマンドを管理しよう
きっと向上心の高いみなさんなら、めちゃくちゃたくさんコマンドを作っていると思います。
ってなわけで、コマンドを沢山作っていくと、`main.py`の1ファイルだけではコマンドの管理とかが大変になると思います。
また、例えばコマンドをちょっと修正した際に毎度毎度BOTを再起動するのは手間ですよね。
それらを解決できるのがCogという機能です。

# Cogとは？
大雑把にいうと、コマンドなどを一つのクラスにまとめることができるもので、コマンドを別のファイルにまとめることが出来るってわけです。
とりあえず`dog.py`というファイルを作ってみましょう。

```python:dog.py
from nextcord.ext import commands

class Dog(commands.Cog):
    def __init__(self, bot: commands.Bot):
        self.bot = bot

def setup(bot):
   bot.add_cog(Dog(bot))
```
これがCogの原型です。

次に、`main.py`の`bot.run`までにコードを追加します。
```diff_python:main.py
+ bot.load_extension("dog")

  bot.run("TOKEN")
```

これで準備はできました。

まず、`bot.load_extension("dog")`で、ファイル`dog.py`を読み込みます。（Extensionの読み込み）
すると、`dog.py`の`setup`関数が実行されます。（Extensionのセットアップ）
そして、インスタンス化された`Dog`がBOTにCogとして追加されるという原理です。（Cogの追加）

準備はできましたが、このままでは特に何にもできないので、Cogにコマンドを追加しましょう。

```diff_python:dog.py
  from nextcord.ext import commands

  class Dog(commands.Cog):
      def __init__(self, bot: commands.Bot):
          self.bot = bot

+     @commands.command()
+     async def dog(self, ctx: commands.Context):
+         await ctx.reply("わおーん！")

  def setup(bot):
     bot.add_cog(Dog(bot))
```
こんな感じに追加します。

まず、今まで`bot.command`だったのが`commands.command`になりました。
Cog内ではこのように、一部のデコレーターなどに変化がある場合があります。

また、新しく`self`という引数が付きましたが、これはPythonの仕様としてClass内の関数にはselfがくっつく（インスタンス化されたクラスからコマンドを呼び出すと第一引数にインスタンス化されたクラスが渡る）というものです。
詳しくは`Python class self`とかで調べてみてください。

これで実行してみましょう。
![AA067701-B559-4C5B-A637-8B6DEC86ECB8.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/01e3c404-3717-cafa-23ed-372c258b5110.jpeg)

普通にコマンドが実行できましたね。

# Extension
`extension`関連の関数には`load_extension`以外にも`reload_extension`や`unload_extension`があります。
この`reload_extension`を実行すると、BOTを再起動しなくてもコマンドの更新などが行えます。
詳細は省略しますが、自分でデバッグ用コマンドを作成したり、`jishaku`や`onami`といったデバッグツールを入れることで楽にコマンドの管理ができたりします。頭の片隅に置いてきましょう。

# 次回
多くのPy製DiscordBOTはCogを活用していると思います。
では、よりもっと本物に近づけましょう。さて、何が足りないか？

次回はスラッシュコマンドをご紹介します。
では、次回の記事をお楽しみに！
【20日目】コマンドのグループを作ってみよう【PythonでDiscordBOTを作ろう！】

# コマンドのグループを作ってみよう
挨拶っていろんな種類がありますよね。
ってなわけで、前回作成した`greed`コマンドを成長させてみましょう！

# `bot.group()`
機能自体は前から知っていたのですが、実際に使い始めたのはこの記事を書く前日からです。
それもちゃんとは理解しきれていません。
ｶﾞｯ...説明します。がんばります。

まず、このデコレーターでは「コマンドグループ」を作成することができます。
これはどういう時に使うかというと、例えば設定を追加するコマンド、削除するコマンド、確認するコマンド...
`c!setting [add/del/check]`とあった際に、`setting`というグループを作って、その中のコマンドとして`add`と`del`と`check`をそれぞれ作ることができます。
管理が楽になったりします。

前回の挨拶コマンドを改造していきましょう。
```diff_python:main.py
- @bot.command()
+ @bot.group()
  async def greed(ctx: commands.Context):
      await ctx.reply("ｺﾝﾁﾜｰｯｽ")
```
とりあえずこれで実行してみましょう。

特に実感湧きませんよね。
そしたらグループに対してサブコマンドを作ってみましょう。
下記コードを追加してください。

```py
@greed.command()
async def goodmorning(ctx: commands.Context):
    await ctx.reply("ｵﾊﾖｳｯ...")
```

これで実行して`c!greed goodmorning`と実行してみましょう。

![09257ADC-1456-40AB-A59F-BD66E9A2B42B.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/bcc8ec45-0aa0-c170-e22f-8ff9ff7472b2.jpeg)


あれ、「ｺﾝﾁﾜｰｯｽ」と「ｵﾊﾖｳｯ...」の両方が表示されてしまいます。

`c!greed`に対して`goodmorning`があるときは「おはよう」だけで、それ以外の場合は「こんにちは」を表示させたいのです。難しいですね。
そんな時は、コマンドが処理されたかを調べれば良いのです。

```diff_python:main.py
  @bot.group()
  async def greed(ctx: commands.Context):
+     if not ctx.invoked_subcommand:
          await ctx.reply("ｺﾝﾁﾜｰｯｽ")
```
これでやってみましょう。

![1A348CAD-41A3-4A81-BC84-23BED53B0C13.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/03c8bfdf-e4bf-1035-632a-7145f5a49860.jpeg)


こんな風に、サブコマンドが実行されなかった場合に、`greed`内の返信が行われましたね。

これがコマンドグループの大まかな概要です。

# D4DPy Groopy Mix!
さて、コマンドグループについてある程度理解していただけたでしょうか。
これで沢山コマンドを作ってください！

さて...たくさんコマンドを作ると、一つのファイルで管理するのは大変ですよね...？

次回はそこら辺です！
次回もよろしく！
【19日目】コマンドフレームワークを使ってみよう【PythonでDiscordBOTを作ろう！】

# コマンドフレームワークを使ってみよう
より簡単にコマンドを扱えるようになるフレームワーク

## コマンドフレームワークとは？
先程まで、`on_message`を使用したコマンド判定を行っていました。
が、これには自力ではめんどくさくいつか限界が訪れてしまいます。
これを解決するために、主なラッパーにはコマンドフレームワークという、コマンドの作成から設定、管理に至るまで凄く簡単に行う事が出来る機能があります。

# プリフィックス設定をしよう
プリフィックスは前回までと同様に`c!`とします。
これを読み込ませてあげる必要があります。
botのインスタンス化時に設定することができます。

```diff_python:main.py
- bot = commands.Bot(intents=intents)
+ bot = commands.Bot(intents=intents, command_prefix="c!")
```
たったこれだけで設定することができます。
あとは、コマンドを作るだけです。

# 挨拶コマンドを作ろう
挨拶してくれるコマンドを作りましょう。
とりあえず、一旦何も考えないで`on_message`の部分は消しておいてください。後で説明します。
`on_message`の上のデコレーターを消すだけでいいです。
```diff_python:main.py
- @bot.event
  async def on_message(message: nextcord.Message):
      ...
```
そしたら次のコードを追加してみましょう。
```python:main.py
@bot.command()
async def greed(ctx: commands.Context):
    await ctx.reply("ｺﾝﾁﾜｰｯｽ")
```
そしたらBOTを実行して、`c!greed`と実行してみましょう。

![C7CB9928-192D-4508-866A-D6F13E8CFE9B.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/27e13413-5afc-18cd-818e-02063c0fbf0b.jpeg)

すると、挨拶を返してくれます！！

この種類のコマンドを「コンテキストコマンド」と言います。
覚えておいてくれると嬉しいです。

というわけで、説明していきますね。

## `@bot.command()`
関数をコンテキストコマンドにするためのデコレータです。
色々設定項目はありますが、特に何も書かなくても普通に動きます。

## `ctx: commands.Context`
コンテキストコマンドに与えられる関数です。
よく`ctx`が使われてるからctxにしてるだけです。

`commands.Context`はコンテキストオブジェクトと呼ばれ、メッセージオブジェクトや、ユーザーオブジェクトなど、いろいろな情報が含まれています。
すごいわかりやすい説明だと、メッセージオブジェクトの拡張版です。

## `ctx.reply()`
コンテキストオブジェクトの関数です。
`message.reply()`と同様に、メッセージに対してリプライを飛ばします。

# おおすごいすごい
これが簡単なコンテキストコマンドの説明です。
これをたくさん作ることでBOTは完成していきます。

では、先ほど削除した`on_message`。
つけるとどうなるのでしょうか。
答えは、コマンドが正常に動作しなくなります。

このコンテキストコマンド、所詮はラッパーがメッセージを解析してコマンド風に扱えるようにしているだけ。DiscordのAPIに公式に用意されている者ではありません。
そのため、`on_message`を作ると、「メッセージを解析してコマンド風に扱えるようにする処理」が`on_message`にオーバーライドされてしまい、`on_message`の処理のみが行われてしまいます。
よって、コマンドの処理が行われなくなってしまいます。

しかし、もちろん対策はあります。
コマンドと`on_message`を両立させる方法もあります。

## `process_commands`
```py
@bot.event
async def on_message(message):
    # on_messageの処理
    await bot.process_commands(message)
```
こんな風に、`on_message`の最後にコマンド解析をする関数を入れることでコマンドの解析が行われます。

## `bot.listen`
```py
@bot.listen('on_message')
async def on_message(message):
    # on_messageの処理
```
こんな風に、`bot.event`の代わりに`bot.listen`を使用することで、メッセージの処理と解析の両方を行うことができます。
私はこれが好きです。

# コマンドやでぇ...ﾄﾞﾔｧ...
世の中のBOTプログラマの大半はこんな感じで作っていきます。
...もちろんまだまだ足りません。

クリスマスまで後少しです。
そ、そ、そ、そりゃあ私はクリスマスぐらい超絶美少女とデートする約束が...~~（絶賛募集中）~~

つまり、もうすぐこの記事シリーズも終わってしまいます。
私も頑張って書いてるので、褒めてくれてもいいんですよもちろん。

では、次の記事で！
【18日目】コマンド風のやつを再現しよう②【PythonでDiscordBOTを作ろう！】

# コマンド風のやつを再現してみましょう！②

## 復習
なんかコマンドっぽいやつを再現します。
![image](https://camo.qiitausercontent.com/5f9da8411f61fa9c65c993245fcc4668bdb03428/68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f313130373938342f34326235323464662d373633652d343939322d386362372d6436326463386536663762622e706e67)
参考画像です。

# `startswith`
Pythonだけじゃなくて色んな言語に含まれています。
`文字列.startswith(検索文字)`という感じに使い、`True/False`が返ってきます。
これだったら、いちいち文字数とかを入れてスライスしたりする必要性がなくなります。
試しにやってみましょう。

```diff_python:main.py
  import nextcord
  from nextcord.ext import commands

  intents = nextcord.Intents.all()
  intents.typing = False

  bot = commands.Bot(intents=intents)

  PREFIX = "c!"

  @bot.event
  async def on_message(message: nextcord.Message):
-     if message.content[:len(PREFIX)] == PREFIX:
+     if message.content.startswith(PREFIX):
          # コマンド処理
          await message.reply("コマンドだね！")

  bot.run("TOKEN")
```

基本的に処理の一部分を変えただけなので、普通に動きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/a21c9e78-0ebe-cb33-2a08-3c4d8092c4ba.png)
（代り映えしねぇなぁ...時間が変わっただけじゃん...）

さぁ、結構コマンドっぽくなってきましたね。
しかしこのまんまやってると実はすごくめんどくさいんですよね。

何のコマンドを使ったのか...どんな引数が入ったのか...
これらを自分で処理していくと、大変地獄です。
寝る暇もなくなってしまいます。（？？？）

# 実はー...
ここまで頑張ってコマンド風のものを作っていただいたのは、「コマンド」という親しみやすいものを使ってPythonの文字列操作を覚えてもらっただけです。（？）

しかし、皆様が頑張らなくても、多くのDiscordAPIラッパーにはコマンド（風文字列）を処理するための機能が備わっています。
その名も*Bot commands framework*。

では予習です。
コマンドフレームワークのAPIリファレンスを少し読んでおきましょう。
意味は分からなくてもいいです。
なんとなく雰囲気でもつかんでみてください。

https://docs.nextcord.dev/en/stable/ext/commands/commands.html

あ、もちろん翻訳してもいいのよ？

# Next is `Commands Framrwork`...
むしろDiscordのBOT作成はここからが本番みたいなところあります。
残り記事数も少なくなってきましたので、いい感じに文言をまとめて頑張っていきます！

というわけで、今日の記事はここまでです。
 もしよろしければ記事へのいいねをして、次回記事をお楽しみに！
【17日目】コマンド風のやつを再現しよう①【PythonでDiscordBOTを作ろう！】

# コマンド風のやつを再現してみましょう！①
Discordで、BOTを操作する時って、大体プリフィックス部とコマンド部に分かれた文字列を送信しますよね。
例えば、画像にある私のにらBOTのヘルプコマンドであれば、プリフィックスは`n!`、コマンドは`help`、これを合わせて`n!help`という文字を送信します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/42b524df-763e-4992-8cb7-d62dc8e6f7bb.png)

プリフィックスはBOT毎に固定されていて、プリフィックスによって操作するBOTを選びますよね。
今回はこんな機構を**再現**していきます。あくまでも再現フェーズです。

というわけで、色々な方法があるので、少し記事を分けてみましょう。
これを通っていけば、にらBOTの初期段階までは作れると思います...

# 文字列同一判定
さて、前回と前々回で`スライス`を紹介したのは、ここに繋がります。
プリフィックスは最初につけるので、スライスを使用して文字列の最初を切り出し、それとプリフィックスが同一かどうかを判定する方法です。

せっかくですので、このクリスマスBOTのプリフィックスは`c!`にしましょうか。

プリフィックスは`c!`で2文字なので、送られてきたメッセージの先頭2文字が`c!`だったらそれがコマンドだとわかります。
なのでそれを判定しましょう。

```py:main.py
import nextcord
from nextcord.ext import commands

intents = nextcord.Intents.all()
intents.typing = False

bot = commands.Bot(intents=intents)

PREFIX = "c!"

@bot.event
async def on_message(message: nextcord.Message):
    if message.content[:2] == PREFIX:
        # コマンド処理
        await message.reply("コマンドだね！")

bot.run("TOKEN")
```

とりあえずこんな感じでしょうか。
これで一回動かしてみましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/7ba054cf-81ef-d9e4-2950-516369972c6a.png)

すると、`c!`から始まるコマンドみたいなメッセージにのみ反応しますよね！

これがコマンドの始まりです。
ちなみにこれは、私がにらBOTを作り始めた初期の時に使っていたコマンド風処理方法です。
ちなみに今のコマンドのも、この処理を一部受け継いでいたりしてすごいめんどくさいことになっています。
なので、これは基本的に使わないようにしましょう。（Q: 紹介した意味）

ですが、一応文字列の判定は色々な分野で使うと思うので、勉強しておいて損はないでしょう！！！！

そして、プログラミングにおいては`参照を多くする`というのが大事らしいです。
例えばプリフィックスの文字数が変わった際に、スライス内の数値も変えなければなりません。
ならば、プリフィックスを変えただけで勝手にスライス数値も変わったら嬉しいですよね。

```diff_python:main.py
  import nextcord
  from nextcord.ext import commands

  intents = nextcord.Intents.all()
  intents.typing = False

  bot = commands.Bot(intents=intents)

  PREFIX = "c!"

  @bot.event
  async def on_message(message: nextcord.Message):
-     if message.content[:2] == PREFIX:
+     if message.content[:len(PREFIX)] == PREFIX:
          # コマンド処理
          await message.reply("コマンドだね！")

  bot.run("TOKEN")
```

`len`は、文字列に使えば文字数を返してくれる関数です。
これで、プリフィックスを変えるだけで勝手に変わってくれますね！

# Next is `startswith`...
友人プログラマーが教えてくれたやつです。
色んな言語に存在するやつです。
素直にこれにしておけばよかったです（小声）（震え）
皆さんは私みたいにならないようにしましょう。

というわけで、今日の記事はここまでです。
 もしよろしければ記事へのいいねをして、次回記事をお楽しみに！
【16日目】ギコギコはしなさそうなスライサー！　～後編～【PythonでDiscordBOTを作ろう！】


# 無限大の刃物　〜後編〜
（一応自分で書いたネタは擦ります）

# 復習
`スライサー`とは、文字列などを切り裂き、抜き出したりするときに使う。

「あいうえお」という例文を使っているが、それぞれの文字はプログラムの中では下記の通りに処理される。

文字|位置
---|---
あ|0文字目
い|1文字目
う|2文字目
え|3文字目
お|4文字目

また、`[n:m]`は`n文字目からm-1文字目`みたいな感じの意味だから気をつけてほしい。

ちなみに実行コードは下記の通りだ。

```python:repl
>>> 'あいうえお'[0:3]
'あいう'
>>> 'あいうえお'[:4]
'あいうえ'
>>> 'あいうえお'[2:]
'うえお'
>>> 'あいうえお'[3]
'え'
>>> 'あいうえお'[3:10]
'えお'
>>> 'あいうえお'[:-2]
'あいう'
```


### `[3]`

なんか急にコロンが消えましたね。どうしたんでしょうか。セミコロンに進化でもしてくれるのでしょうか。だとしたら今すぐ飴をあげなきゃいけませんね。それかBボタン連打でも。

このコロンなしの場合は「3文字目だけ」という意味です。

なので、先ほどの表に照らし合わせて、3文字目は「え」なので、結果としては「え」となります。
これは少しおぼえておいた方がいいです。（そのうち文字以外にも使います。）

### `[3:10]`
これはそのまんま考えましょう。
`3文字目から10文字目`。

「えーと...10文字もありましたっけ...？」

このように、5文字しかない中で、本当はMAXが「4」ですが、それより多く指定することもできます。
この場合、Pythonでは特に何も起きず、普通に最後まで帰ってきます。

しかし、とても推奨されないものです。
基本的には、範囲内でのみ使いましょう。
後で「範囲外でもいけるんだよな」みたいな知識で色々作ってると、エラーが起きたりする場合があります。

### `[:-2]`
マイナスですね。
0文字目より下に行くと思ったあなた、観点は素晴らしいですが違います。

マイナス数字は、最後からの数字を表しています。
よって、`-2`は最後から2文字目を表していることになりますね。

よりわかりやすく説明しましょう。
`[:-0]`は`あいうえお`（0だから変化なし）
`[:-1]`は`あいうえ`
`[:-2]`は`あいう`
です。（？）
まぁ、減っていくと考えて貰えば...

結果として、`あいう`となります。

# どうよ！　これがスライサーよ！
これがスライサーです。
文字列や、配列などを分裂させます。

次回は、このスライサーや更に新しい関数を使って、コマンドっぽいものを再現してみましょう。

というわけで、今日の記事はここまでです。 もしよろしければ記事へのいいねをして、次回記事をお楽しみに！
【15日目】ギコギコしなさそうなスライサー！　～前編～【PythonでDiscordBOTを作ろう！】

# ギコギコはしません！！！！　〜前編〜
一度刃が入ればｽｩｰｰって感じです。

# スライスとは文字とかを分解します（早々の結論）
Pythonに限らずほとんどのプログラミング言語には、「スライス」という機能があります。
スライスでは、イテラブルオブジェクトの特定の範囲のものを切り出す作業のことを指します。

はてイテラブルオブジェクト？となった方が大半だと思います。
イテラブルオブジェクトとは「文字列」「バイト列」「配列」「タプル」「セット」型のものを言います。
（タプルとセット以外は）〜〜列とあるように、これらのオブジェクトは列なんです。（多分）

イテラブルオブジェクトとかについては、下の方の記事が参考になると思うので、そちらを参考にしてください。

https://science-log.com/python%e3%83%97%e3%83%ad%e3%82%b0%e3%83%a9%e3%83%9f%e3%83%b3%e3%82%b0tips%e9%9b%86/%e3%80%90python%e3%80%91%e3%82%a4%e3%83%86%e3%83%a9%e3%83%96%e3%83%ab%e3%82%aa%e3%83%96%e3%82%b8%e3%82%a7%e3%82%af%e3%83%88%e3%81%a8%e3%81%af/

例えば文字列のn文字目からm文字目まで取り出したいという時に行う作業をスライスと言います。

## スライス系ならPythonメーカー！
例文`あいうえお`を使って遊びましょう。

Pythonのスライスは、スライスしたいものの後に`[はじめ:おわり]`って感じにやります。
そして、コロンは「〜」という意味。なので`はじめ〜おわり`って訳なんですね。

まずは、コードと実行結果を見てみましょう。
勘の鋭い方はこれだけで理解されてしまうかもしれません。

```python:repl
>>> 'あいうえお'[0:3]
'あいう'
>>> 'あいうえお'[:4]
'あいうえ'
>>> 'あいうえお'[2:]
'うえお'
>>> 'あいうえお'[3]
'え'
>>> 'あいうえお'[3:10]
'えお'
>>> 'あいうえお'[:-2]
'あいう'
```

こんな感じです。
3個づつ分けて、前編後編で紹介します。
順番に説明していきますね。

### `[0:3]`
これは、`0文字目`〜`2文字目`の間を抜き取るという意味です。

ん？となったでしょう。

#### まずは、0文字目の謎について。
多くの言語では、皆さんが1文字目だと思ってる「あ」が0文字目となります。
「n文字目」というよりも「n個目」というのがさらに近いような気がします。
なので、0スタートで考えてください。

という訳で、簡単な表を作りました。

文字|位置
---|---
あ|0文字目
い|1文字目
う|2文字目
え|3文字目
お|4文字目

これを、せめて今日含めて2日間だけは頭に叩き込んでてください。

#### 次に`3`なのに`2文字目`の謎について
`[0:3]`だと、0〜3というような感じの意味になりそうですよね。
実は大きな罠なんです。
`[n:m]`は、`n文字目の文字から、m-1文字目までの文字`というような意味なんです。
なので、プログラミングとしては`0〜3`ですが、人間が理解する上では`0〜2`なんです。

となるので、結果としては0文字目から2文字目までの3文字で「あいう」となります。

### `[:4]`
はい。
コロンの前に数字がないですね。
[Typo](https://wa3.i-3-i.info/word1675.html)ですか！？って思った方！違います！

コロンの前の数字、前数字（勝手に名付けた）がない場合は、そこには「最初」が入ると思ってください。
つまり、最初の文字から4文字目というような感じになります。
ほぼ`[0:4]`と同じような意味です。

結果としては、`最初の文字から3文字目までの4文字`なので、「あいうえ」となります。

### `[2:]`
おお、今度は後の数字がないですね。
最近数字の誘拐が増えてるらしいので気をつけてくださいね。

コロンの後の数字、後数字がない場合には、そこには「最後」が入ると思ってください。
前にやったやつにすごく似てますよね。
つまり、2文字目から最後の文字までというような感じになります。

この後数字がない場合、`[n:m]`は`n文字目からm-1文字目`の法則は適応されず、最後の文字までちゃんと入り、結果としては2文字目から最後の文字までで「うえお」となります。

# 後編へ続く！
あんまり変に量が多すぎると頭に入ってこないです。
私も授業内容は少なければ少ないほど嬉しいですもの。

次回、無限大の<ruby>刃物<rp>(</rp><rt>スライサー</rt><rp>)</rp></ruby>　〜後編〜！（コナン風（小並感））

というわけで、今日の記事はここまでです。 もしよろしければ記事へのいいねをして、次回記事をお楽しみに！
【14日目】正規表現と最近できた落とし穴②【PythonでDiscordBOTを作ろう！】

# 今度こそ正規表現

猫に反応するにはこうやってみましょう。

```py:main.py - async def on_message
@bot.event
async def on_message(message: nextcord.Message):
    if re.search(r"[ねネﾈ][こコｺ]|猫", message.content):
        await message.reply("にゃーん")
```

はて...となったと思います。

分解して考えます。

## `[ねネﾈ]`
この`[]`（かくかっこ）の説明です。
かくかっこは、中の文字どれかと判定します。
```py
re.search(r"[ねネﾈ]", "ね") # 〇
re.search(r"[ねネﾈ]", "ネ") # 〇
re.search(r"[ねネﾈ]", "ﾈ")  # 〇
re.search(r"[ねネﾈ]", "な")  # ×
```

## `[ねネﾈ][こコｺ]`
分かりやすく考えるためには`[ねネﾈ]`と`[こコｺ]`をそれぞれ一文字だと思ってください。
たとえば、それぞれ`A`と`B`とおきましょう。
```py
re.search(r"AB", "AB") # 〇
re.search(r"AB", "A") # ×
re.search(r"AB", "B")  # ×
re.search(r"AB", "BA")  # ×
```
すると、普通の文字のように、ちゃんと文字並びじゃないと判定があっていないことになります。
あたりまえですよね。

これの、`A`と`B`を、`[ねネﾈ]`と`[こコｺ]`にして置き換えます。
```py
re.search(r"[ねネﾈ][こコｺ]", "ねこ") # 〇
re.search(r"[ねネﾈ][こコｺ]", "ネｺ") # 〇
re.search(r"[ねネﾈ][こコｺ]", "ﾈこ") # 〇
re.search(r"[ねネﾈ][こコｺ]", "こね") # ×
```
よって、1文字目が、「ね」か「ネ」か「ﾈ」に当てはまり、2文字目が「こ」か「コ」か「ｺ」に当てはまる文字列が`[ねネﾈ][こコｺ]`となります。
分かりやすく言えば「[シュレディンガーの猫](https://nazology.net/archives/107875)」です！
「ね」と「ネ」と「ﾈ」の状態が同時に存在している文字列です。（ﾅﾆｿﾚ）

## `猫`
[猫です。よろしくお願いします。](http://scp-jp.wikidot.com/scp-040-jp)
```py
re.search(r"猫", "猫") # 〇
re.search(r"猫", "犬") # ×
```

## `[ねネﾈ][こコｺ]|猫`
最後です。
この縦棒`|`についてです。
JavaScriptをやってるような人なら分かる人もいるかもしれませんが、`または`です。

`A|B`だったら、「AまたはB」です。
AかBだったら判定に合っていることになります。
```py
re.search(r"猫|犬", "猫") # 〇
re.search(r"猫|犬", "犬") # 〇
re.search(r"猫|犬", "鳥") # ×
```

## おっしゃ完璧や！

正規表現の詳しい書き方については、優しい方がまとめていただいてる記事を載せさせていただきます。

https://qiita.com/tossh/items/635aea9a529b9deb3038

というわけで、先ほどのコードを実行してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1107984/1060c6c5-c01d-d98b-4caf-aa75f1b2aa65.png)

というわけで、猫に反応するBOTが出来上がりました。

これで相手方にも喜ばれますね。

# 次回予告

次回は、ギコギコはせずスーっと切れるスライサーとかについて紹介したいと思います。

というわけで、今日の記事はここまでです。 もしよろしければ記事へのいいねをして、次回記事をお楽しみに！
【11日目】メッセージオブジェクトのデータ【PythonでDiscordBOTを作ろう！】

# メッセージオブジェクトのデータ
メッセージオブジェクト(`nextcord.Message`)には、データと関数が含まれています。
他にも、多くのオブジェクトにはデータと関数の両方が含まれています。
今回はデータについてご紹介しましょう。

# データ
APIリファレンス内で`Attributes`と書かれているところにあるものです。
nextcordであれば以下の通りです。
```:Attributes
activity
application
attachments
author
channel
channel_mentions
clean_content
components
content
created_at
edited_at
embeds
flags
guild
id
interaction
jump_url
mention_everyone
mentions
nonce
pinned
raw_channel_mentions
raw_mentions
raw_role_mentions
reactions
reference
role_mentions
stickers
system_content
thread
tts
type
webhook_id
```


一個一個全部説明していると、多分日が暮れ...いやクリスマスまで時間あるからいいのか...いやでも疲れてしまうので、全部は書きません。
代表的なものを説明します。

## `content`
`Message.content`として読める、`str`のデータです。
中には、メッセージ本文が含まれています。

さて、`str`についても説明が必要ですね。
strとは、Pythonのデフォルト型の一つで、文字列型です。
型とかに関する詳しい情報は下記のページがわかりやすいと思うのでご覧ください！

https://dot-blog.jp/news/python-object-type/

これを使って、メッセージ文をprintするコードを書いてみましょう。

```py:main.py - async def on_message
@bot.event
async def on_message(message):
    print(message.content)
```

これで実行してみると...

```sh
$ python main.py
ChristmasBOT
おーいみてるー？
```

と、こんな風に、メッセージ本文が出力されました。
これで、使い方はもうバッチリですよね。

## `author`
`Message.author`として読める`Union [User | Member]`のデータです。

### は？Unionってなに？
初見では私も分かりませんでしたわ〜！

Unionとは「結合」という意味の単語。
つまり、`Union [A | B]`とは、AとBの型の結合となります。

例えば、Aというオブジェクトには`hoge`というデータがあり、Bというオブジェクトには`piyo`というデータがあるとします。
そしてCというAとBのUnionのオブジェクトがあるとします。

```py
# Aにはhogeは存在するがpiyoは存在しない
A.hoge # hogehoge
A.piyo # Error

# Bにはpiyoは存在するがhogeは存在しない
B.hoge # Error
B.piyo # piyopiyo

# CはAとBの結合なので両方アクセスできる
C.hoge # hogehoge
C.piyo # piyopiyo
```

という様な感じで、両方の型に存在するデータや関数にアクセス出来るのが結合、Unionと思ってくれれば大丈夫だと思います。

## User...? Member...?
はい。この`author`の中にはさらにオブジェクトがあります。
例えば`Member`の中には`name`というデータがあります。
これにアクセスするには`message.author.name`と書けばアクセス出来ます。

とりあえず、試してみましょう。

```py:main.py - async def on_message
@bot.event
async def on_message(message):
    print(message.author.name)
```

これで実行してみると...

```sh
$ python main.py
ChristmasBOT
NattyanTV
```

と、メッセージを送信すると、送信したユーザーの名前が表示されます。

これで、ある程度オブジェクトの基礎については理解していただいたでしょうか...
まぁ習うより慣れろです。何度もトライアンドエラーしてみましょう。(`try: and except:`)

# ついに次回は....！
ついに次回、BOTっぽくなります！
これをすると「BOTっぽいなこれ」と思わず叫びたくなるでしょう。

というわけで、今日の記事はここまでです。 もしよろしければ記事へのいいねをして、次回記事をお楽しみに！

# どうでもいい補足
VSCodeとかを使っている人なら、オートコレクトを使用する事で、より便利に、より素早く開発をする事が出来ます。
オートコレクトとは

こんなので、例えば`message`の中にはどんなデータ、どんな関数が格納されてるか忘れちゃっても案外これでなんとかなります。
また、ワンクリックで出せるので人によっては開発スピードがレベチで上がります。

まずは、Pythonなどの必要な拡張機能を入れてください。
そしたらコードを編集します。

```diff_python:main.py - async def on_message
  @bot.event
- async def on_message(message):
+ async def on_message(message: nextcord.Message):
      print(message.author.name)
```

このように「`変数名: 変数の型`」とすると、その変数がその型なんだなーとVSCode側が理解してくれて、次に使用できるデータや関数を表示してくれる様になります。
また、スペルミスや、存在しないデータを指定した場合はエラーが表示されるので、ミスを対処しやすいです。

VSCodeには色々とおすすめの拡張機能があります。
下記の方の記事が参考になると思いますので、ぜひ入れてみてください！

https://qiita.com/nanato12/items/ddf26487eb30714251c3