PythonとC言語を勝負させた結果をLINE Botで通知してみた。

# どうしてPythonとC言語を戦わせる必要があるのか？
>まず最初に言っておかなければなりません。
>この戦いは、完全に私の勝手な想いによって始まりました。
>だから、PythonもC言語も悪くはありません。

#### 皆さん、Pythonって聞くとどんなことを想像しますか？

 - 機械学習ができる
 - Webサイトのスクレイピングができる
 - 初心者が入りやすい
 - **なんかかっこいい**

#### はい、ではC言語は？
 - 初心者殺しの異名を持っている
 - セミコロンを殺したくなる
 - 意味わからないエラーが〇キブリみたいに出てくる
 - **なんか嫌い**
 - ~~臭い、汚い、きつい~~

これが __現実__ です。
簡単に言うとみんな __Pythonが大好きで、C言語は大嫌い__ 、、、
扱いづらいと思われているC言語ですが、実はあらゆる場所で使われているんです。
例えばみんな大好きPythonだって、C言語を元に作られているんですよーってね:sparkling_heart:

私は業務でC言語を扱っているため、C言語とは相棒みたいなものです！(~~離れたくても離れられない~~)

だからこんな扱いを受けているC言語を見ていられなくて、私は決意しました！

それなら、Pythonと戦わせて目にもの見せてやれば良いじゃないか！！と。
**C言語舐めんなよ！！**(どの立場？)

はい、ごめんなさい:pray:

本当はC言語を少しでも救ってやりたくなったんです。
人気では負けていますが、何か勝てるものがあるんじゃないか、、、と。そしたら救われるんじゃないか、、、と！

# まず、どれくらい人気の差があるの？

まずは敵との差を知らねばなりません(完全にC言語側に立ってる)
Qiita記事に登録されているタグで比較すればその差がわかるはず！
ってことで、まずはQiitaAPIを使ってC言語とPythonの登録タグ数を取得しました！

:::note
   QiitaAPIはQiitaから様々なデータを取得したり投稿の実行することを可能にするものです。
:::
> 使用したQiitaAPIは以下です。実装環境は[作り方](#作り方)と被るのでここでは省略し、アクセスしたURLのみ載せます。
> - QiitaAPIについて：[QiitaAPIドキュメントリンク](https://qiita.com/api/v2/docs#get-apiv2items)
> - C言語タグ取得URL ： ``` https://qiita.com/api/v2/tags/C ```
> - Pythonタグ取得URL： ``` https://qiita.com/api/v2/tags/Python ```

#### 結果は・・・ 

|      |  記事数(items_count) | フォロワー数(followes_count) | 
| :---: | :---: | :---: |
| Python | 66369(14倍)  | 126609(3.7倍)  |
| C言語 | 4697  | 34111  |

> 2022/09/24時点

めちゃ差あるやーん！:dizzy_face:
でも人気っていうのは記事数とかフォロワーで決まるものじゃないから！:angry:

ってことで、せっかくですので人気の差をまざまざと見せつけられた __QiitaAPI__ を使って取り出した情報で勝負してやることにしました！

# 勝負ルール

## 使用する情報

まずQiitaAPIにて最新10件の記事の情報をそれぞれ取得します。
そして、以下の情報を用いて勝負を実施します！

 - コメント数(comments_count)
 - いいね数(likes_count)
 - リアクション数(reactions_count)
 - ストック数(stocks_count)
 - 投稿したユーザーのフォロワー数(user.followers_count)

## 勝負はタイマン勝負と、総合戦力戦の2つ

勝負のイメージとしては以下です！
#### (前提条件)１記事ずつ勝負する

![CとPythonの勝負.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756612/5f530202-2283-f58b-d598-9bd749287242.png)

### その記事内の情報にて勝敗が決まる。つまり、１勝負において５つの勝敗が決する。
![CvsPython2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756612/dcab564a-7fa1-41eb-3741-33803990af13.png)

### 最後は総戦力にて戦う

すべての情報の __合計値__ の勝負を行います！

![CvsPython3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756612/22354ff5-8c29-7905-04b2-95c9960e5312.png)

## 結果をLINE BotにてLINEに送信！！

この2つの言語の勇姿をぜひ残すためにも！
また全ての人に知ってもらうためにも！
日本人が一番使っているアプリであるLINEに通知してやろうと思います:muscle:

C言語の勇姿をぜひ！！

# 実行環境

 - Node.js v16.16.0
 - nom v8.11.0
 - line/bot-sdk 7.5.2
 - axios 0.27.2
 - Visual Studio Code v1.71.2

# 作り方

## 全体像

![CvsPython構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756612/ca3df59c-1dfb-8bbd-728f-b0aafefd1fdf.png)


## QiitaAPIから記事情報を取得

``` javascript: QiitaAPI
const axios = require("axios");
async function qiitaApi() {
  // QiitaAPIを使用しています
  let responseC = await axios.get("https://qiita.com/api/v2/items?page=1&per_page=10&query=tag%3AC");
  let responsePython = await axios.get("https://qiita.com/api/v2/items?page=1&per_page10&query=tag%3APython");

}
```
:::note
axiosを使用するためnpm i axiosでライブラリをインストールしてください
:::
## 記事情報を用いて勝敗結果を演算

``` javascript: 勝敗結果演算

   // 勝敗を格納するためのオブジェクト宣言、C言語、Pythonと引き分けを用意する
   let C_WinCount = {
    comments:0,
    likes:0,
    reaction:0,
    stocks:0,
    followers:0,
    total_count:0,
  }
  let PythonWinCount = {
    comments:0,
    likes:0,
    reaction:0,
    stocks:0,
    followers:0,
    total_count:0,
  }
  let DrawWinCount = {
    comments:0,
    likes:0,
    reaction:0,
    stocks:0,
    followers:0
  }
  // 一応取得記事数が合わなかったときのための処理  
  const resLength = responseC.data.length < responsePython.data.length ? responseC.data.length : responsePython.data.length;
  // ひたすら比較する
  for (let i = 0; i < resLength; i++){
    // コメント勝負
    if (responseC.data[i].comments_count > responsePython.data[i].comments_count){
      C_WinCount.comments++;
    }
    else if (responseC.data[i].comments_count < responsePython.data[i].comments_count){
      PythonWinCount.comments++;
    }
    else {
      DrawWinCount.comments++;
    }
    // いいね勝負
    if (responseC.data[i].likes_count > responsePython.data[i].likes_count){
      C_WinCount.likes++;
    }
    else if (responseC.data[i].likes_count < responsePython.data[i].likes_count){
      PythonWinCount.likes++;
    }
    else {
      DrawWinCount.likes++;
    }
    // リアクション勝負
    if (responseC.data[i].reactions_count > responsePython.data[i].reactions_count){
      C_WinCount.reaction++;
    }
    else if (responseC.data[i].reactions_count < responsePython.data[i].reactions_count){
      PythonWinCount.reaction++;
    }
    else {
      DrawWinCount.reaction++;
    }
    // ストック数勝負
    if (responseC.data[i].stocks_count > responsePython.data[i].stocks_count){
      C_WinCount.stocks++;
    }
    else if (responseC.data[i].stocks_count < responsePython.data[i].stocks_count){
      PythonWinCount.stocks++;
    }
    else {
      DrawWinCount.stocks++;
    }
    // ユーザーフォロワー数勝負
    if (responseC.data[i].user.followers_count > responsePython.data[i].user.followers_count){
      C_WinCount.followers++;
    }
    else if (responseC.data[i].user.followers_count < responsePython.data[i].user.followers_count){
      PythonWinCount.followers++;
    }
    else {
      DrawWinCount.followers++;
    }
    // 総戦力に備える
    C_WinCount.total_count += responseC.data[i].comments_count + responseC.data[i].likes_count + responseC.data[i].reactions_count + responseC.data[i].stocks_count + responseC.data[i].user.followers_count;
    PythonWinCount.total_count += responsePython.data[i].comments_count + responsePython.data[i].likes_count + responsePython.data[i].reactions_count + responsePython.data[i].stocks_count + responsePython.data[i].user.followers_count;
    
  }
  let totalResult;
  // 最終決戦
  if (C_WinCount.total_count > PythonWinCount.total_count){
    totalResult = "Cの完全勝利！！";
  }
  else if (C_WinCount.total_count < PythonWinCount.total_count){
    totalResult = "く、、、";
  }
  else {
    totalResult = "良い勝負だった";
  }


```

ここまでで一旦、勝敗に関する演算処理は終了とします。
続きまして**LINE Bot**の製作に入ります。

## LINE Botの製作

事前準備諸々は書き出すと長くなるので、下の記事を参考にしてください。
> 参考記事： [1時間でLINE BOTを作るハンズオン](https://qiita.com/n0bisuke/items/ceaa09ef8898bee8369d)

``` javascript: LINE Botコード
'use strict';
// linesdkの読み込み
const line = require('@line/bot-sdk');
// axiosモジュールを読み込む
const axios = require('axios');
// QiitaAPIファイルを読み込む
const responsQiita = require("./qiitaApiConnect")

const config = {
    // ここは各々の環境に合わせて変更してください。
    channelSecret: '*********************************',
    channelAccessToken: '************************************'
};
const client = new line.Client(config);


const main = async () => {
    // QiitaAPIからの勝負結果を受け取る
    // 返答処理はここの時点ではまだ実装していません
    const responsData = await responsQiita.QiitaApi;
    console.log(responsData);
    
    const messages = [{
        type: 'text',
        text: "最新１０件の勝負の結果が出ました・・・"
    },
    // 結果を通知
    responsData,
];

    try {
        const res = await client.broadcast(messages);
        console.log(res);        
    } catch (error) {
        console.log(`エラー: ${error.statusMessage}`);
        console.log(error.originalError.response.data);
    }
}

main();

```
:::note
npm i @line/bot-sdk にSDKをダウンロードしておいてください。
:::
## 勝敗結果の送信内容を、QiitaAPIの取得関数に追加し戻り値に設定する

QiitaAPIの取得を担当している関数に、LINEに通知する内容を作成する処理を追加し、戻り値として設定します。

``` javascript: 通知情報作成
 
async function qiitaApi() {
    
    ~~ 前略 ~~
  // 通知内容作成
  "コメント勝負結果：" + '\n' +
  "  ・C言語勝利数:   " + C_WinCount.comments + "勝"+'\n' +
  "  ・Python勝利数: " + PythonWinCount.comments+"勝" + '\n' +
  "  ・引き分け数:   " + DrawWinCount.comments + '\n' +

  "いいね勝負結果：" + '\n' +
  "  ・C言語勝利数:   " + C_WinCount.likes +"勝" +'\n' +
  "  ・Python勝利数: " + PythonWinCount.likes +"勝"+ '\n' +
  "  ・引き分け数:   " + DrawWinCount.likes + '\n' +

  "リアクション勝負結果：" + '\n' +
  "  ・C言語勝利数:   " + C_WinCount.reaction +"勝" +'\n' +
  "  ・Python勝利数: " + PythonWinCount.reaction +"勝"+ '\n' +
  "  ・引き分け数:   " + DrawWinCount.reaction + '\n' +

  "ストック数勝負結果：" + '\n' +
  "  ・C言語勝利数:   " + C_WinCount.stocks +"勝" +'\n' +
  "  ・Python勝利数: " + PythonWinCount.stocks +"勝"+ '\n' +
  "  ・引き分け数:   " + DrawWinCount.stocks + '\n' +

  "フォロワー数勝負結果：" + '\n' +
  "  ・C言語勝利数:   " + C_WinCount.followers +"勝" +'\n' +
  "  ・Python勝利数: " + PythonWinCount.followers +"勝"+ '\n' +
  "  ・引き分け数:   " + DrawWinCount.followers + '\n' + '\n' +

  "トータル勝負・・・" + totalResult;

  console.log(resultData)
  // 戻り値として設定 なおLINE Botのプッシュ通知のフォーマットにしておく
  return {
    type: "text",
    text: resultData,
  }
}
// 外部公開する場合は以下が必要
exports.QiitaApi = qiitaApi();

```

# 完成！

__C言語とPythonの勇姿をご覧ください！！__

![IMG_1044.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2756612/d82eccc3-13eb-85f5-b889-08cf961a70d0.png)


# 果たして結果は・・・？

圧倒的C言語の勝利！！:v:

みなさんこれがC言語なのです！
例え人気で負けていたとしても実力では負けていないのです！

感動した！！:sob:

# 真面目に考察とかしてみたり

今回の勝負は記事に対する反応を比較してみました。
結果C言語が勝利したわけですが、この理由はなんだろうと考えてみました。

おそらく、記事が少ないことが勝因なのかな？と思います。
Qiitaに限らずC言語ってそもそも情報が少ないイメージがあります(難しいものならたくさんある)。それだけ見る人が集中して結果反応数が増えたのかと！

あとわざわざC言語を記事にする人はそれなりのベテランだったりするので、それだけ良い記事が多いのかな？
ひとまず、私としては満足いく結果が得られました！

# これからやってみたいこと

勝負する期間を選んだり、C言語とPythonだけではなくいろいろな言語で勝負できるようにしてみたいです！
例えば、LINEにてユーザー側でそのあたりを設定できたりしたら、もうちょっとおもしろくなるかな？:smirk:

# おわりに

最後までお読みいただきありがとうございました！
APIとかLINE Botとか案外簡単に実装できることに感動です。
あと、やっぱりC言語が勝ってくれたことに感無量、、、

これからももっといろいろ作れる人になりたいと思いましたので、また投稿できたらと思います！