Qiitaでプログラミング言語トレンド


# 1. 概要
日本ではプログラミング言語のトレンドはどんな感じか知りたいので、Qiitaの過去データを取得して分析してみましょう。以下の写真は世界でのトレンドです（参考：[PYPLサイト](http://pypl.github.io/PYPL.html)）。
![世界のプログラミング言語トレンド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/1d426f44-37c4-1a9c-d57d-41b6544f5b9d.png)


# 2. データ取得

## 2.1. APIの利用
APIの制限のため、問題がいくつか発生しました：

1. 全部投稿を取得するAPIがありません（全部は580000投稿ぐらいがある）。
2. APIによる一回の上限は１万投稿です（100ページ * 100投稿/1ページ）。
3. 実際は5900投稿を取得すると、403エラーが発生してから、APIをアクセスできない（スパムから保護するため、1時間60リクエストだけ）
→　あるタグの投稿数は5900投稿以下のためフィルターを適用します（Stocksの数は30以上）。AWSのEC2インスタンスを適用して取得した時、403エラーになると、インスタンスを再起動しました（新しいIPになる）。
4. あるタグの投稿数は5900以下なのに、全部投稿を取得できません。2017年09月の時点ぐらいには500エラーが発生しました。
→　最後取得できた投稿の作成日を保存して、新しいリクエストを作ります。

で、以上の問題を解決すると、以下のコードです。

```js

let axios = require("axios")
let fs = require("fs")
let csvStr = require("csv-stringify/lib/sync")

let PAGE_MAX = 55

function parse_response(response, record_num, outcsv) {
    for (record_idx = 0; record_idx < record_num; record_idx++) {
        let record = []
        id = response["data"][record_idx]["id"]
        comments_count = response["data"][record_idx]["comments_count"]
        likes_count = response["data"][record_idx]["likes_count"]
        reactions_count = response["data"][record_idx]["reactions_count"]
        tags = response["data"][record_idx]["tags"]
        tags_str = ""
        for(tag_num = 0; tag_num < tags.length; tag_num++){
            tags_str = tags_str.concat(', ', tags[tag_num]["name"])
        }
        title = response["data"][record_idx]["title"]
        user_id = response["data"][record_idx]["user"]["id"]
        created_at = response["data"][record_idx]["created_at"]
        record.push(id, comments_count, likes_count, reactions_count, 
                    tags_str, title, user_id, created_at)
        outcsv.push(record)
    }
    return outcsv
}

async function getArticle(tag) {
    let outcsv = []
    let columns = ["id", "comments_count", "likes_count", "reactions_count",
                   "tags", "title", "user_id", "created_at"]
    outcsv.push(columns) 
    let last_date = "2020-09-28"
    let record_sum = 0
    for (page = 1; page <= PAGE_MAX; page++){
        let response =  await axios.get("https://qiita.com/api/v2/items?page=" + 
                        page + "&per_page=100&query=" + 
                        encodeURIComponent("stocks:>30") + "+" + 
                        encodeURIComponent("tag:" + tag))
        record_num = response["data"].length
        if(record_num != 0){
            outcsv = parse_response(response, record_num, outcsv)
            record_sum = record_sum + record_num
            last_date = response["data"][record_num-1]["created_at"].split('T')[0]
            console.log(record_sum + ":" + last_date)
        }
        if(record_num < 100){
            break
        }
    }

    for (page = 1; page <= PAGE_MAX; page++) {
        let response =  await axios.get("https://qiita.com/api/v2/items?page=" +
                        page + "&per_page=100&query=" +
                        encodeURIComponent("stocks:>30") + "+" + 
                        encodeURIComponent("tag:" + tag) + "+" + 
                        encodeURIComponent("created:<" + last_date))
        record_num = response["data"].length
        if(record_num != 0){
            outcsv = parse_response(response, record_num, outcsv)
            record_sum = record_sum + record_num
            console.log(record_sum)
        }
        if(record_num < 100){
            break
        }
    }
    fs.writeFileSync(tag + ".csv", csvStr(outcsv))
}

// それぞれのタグを変更する：C, C++, C#, Go, Java, Javascript, Kotlin, Objective-C, 
// PHP, R, Ruby, Swift, Typescript
getArticle("python") 
```

## 2.2. アウトプットデータ
結果のデータは各投稿のID,コメント数、LGTM数、絵文字リアクション数、タグ、タイトル、筆者のID、投稿の日時です。

| 言語      | データ投稿数 | 全部投稿数  |
|----------|:-------------:|------:|
|Python     |5337    |46000|
|Javascript |5305    |37257|
|Ruby	    |2927    |29307|
|PHP        |2010   |21088|
|Java	    |1568	|15905|
|Swift	    |2577	|15317|
|C#	        |815	|10319|
|Go	        |1021	|9084|
|C++	    |630	|8006|
|Typescript	|701	|5891|
|Kotlin	    |287	|4100|
|Objective-C|935	|4010|
|R	        |204	|3526|
|C	        |261	|3305|

# 3. トレンド
以上の結果のデータをTableauに入れてグラフを作成しましょう！

## 3.1. 全体グラフ
![トレンド.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/f374633a-275e-871c-b62c-fda9b685e2f5.png)

横軸は投稿の作成日です（単位：年間）。
縦軸は各言語のタグの投稿数の割合です（単位：パーセント）。

## 3.2. 結果を分析しよう
### 3.2.1. Python
![python.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/11bd3485-843e-0a44-9206-cb4845e420b9.png)
投稿数に基づと、2012年のPython言語ユーザーの割合は4％でした。その後、急速な成長により、この率は2014年にPHP、2015年にRubyとSwift、2016年にJavascriptを上回りました。現在、Pythonは一番人気がある言語（35％）になりました。

### 3.2.2. Javascript
![js.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/7730ed69-cecd-6bc3-d43a-f0e2116fea79.png)
2012年、JSの投稿数の割合は22％でしたが、2014年までに徐々に18％減少しました。現在、その割合は26％になり、人気がある言語トップで2位にランクされています。

### 3.2.3. Ruby
![ruby.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/96dc0fbe-8dfa-afb1-d9f9-4222630c29ad.png)
2012年、Rubyの投稿数の割合は35％に達し1位になりました。その後、何年にも渡って継続的に減少しています。現在、4％になりました。

### 3.2.4. Typescript
![typescript.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/04b2437d-74bc-2e04-67a8-651f9eb715b9.png)
2013年から始まり、近頃の3年間の高い成長により、現在、3位（10％）になりました。

### 3.2.5. Swift/Objective-C
![swift_objective-c.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/fd96abc9-6391-61cf-a1ca-3620ba7505f0.png)
Swiftの発達とともに、Objective-Cは衰退していました（0.24％）。全体として、iOSの言語は2015年，2016年に人気があり、最近、少し減少しました。

### 3.2.6. 他の言語
**PHP**
![php.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/f0cc0b68-0cab-760a-da06-ae714ba91c8e.png)

**Java**
![java.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/2cfa89d0-8c4b-40f7-2e5e-7320618c459c.png)

**C/C++**
![c_c++.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/c9818cab-ed78-2610-2ffa-6e8bce4697d8.png)

**C#**
![c#.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/b35d7ea0-04fe-83c9-60be-a7f636d56a30.png)

**Go**
![go.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/af29852a-72a8-a6d9-12f1-cffc7f56ee3a.png)

**R**
![r.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/db2373bb-623c-9a3c-deab-b454496bd785.png)

**Kotlin**
![kotlin.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/b489634b-78cf-71ac-f417-083c23d07e94.png)

# 4. よく投稿した時間、曜日
![作成日.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/33868efa-d3b7-69b2-fdc1-5904bd92146c.png)
よく投稿した曜日は月曜日です。

![作成時間.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521590/5f2789d2-bdbd-fb87-60bd-1617e270e83a.png)
よく投稿した時間は0時です。特には22時から24時までですよね。

ご参考までに！

##　参考
[結局Qiita記事ってどれぐらい書けばいいのさ](https://qiita.com/canonno/items/57f917147b3d6ae106e9)