Qiita
Python
Flask
データ分析
新人プログラマ応援

あなたの時間を無限に奪うQiita記事集できました(特に初心者にオススメ!)

あなたの時間を無限に奪う理由

上位1~2%の超人気記事を集めた 「Qiitaの殿堂」 の新機能。
技術タグごとの記事を時系列で一括で見れるビューが加わりました。

Qiita殿堂入り記事のタグごとまとめ
↑↑ にアクセス!

興味のある技術タグに限定して見れるので、本気で時間泥棒です
時系列に人気記事が並ぶため、タイトルを眺めるだけでも面白いです。
特に、その技術を始めようとする初心者の方にもオススメできます♪
(見た目など不十分ですが、面白かったので先に公開します)

ぜひ一度、好きなタグの記事を見てください。
(ポエム系が嫌いな人にとっては技術タグで見れるので捗るかも)

さらに、今年のいいね獲得ランキングを公開!

Qiita ユーザランキング(年別)
↑↑ にアクセス!

2018年、誰が現在一位か、またはTOP10も、ここには書きません。
ご自身の目で確認してください!
また、3000名以上表示しています。
ご自身や、お知り合いのアカウントの状況も確認できるかも!?

Qiita公式のトップページの「ユーザランキング(全て)」はほぼ固定だし、
週次や月次は、ほぼその期間中の一つの記事で決まってますよね。
昔の方がいいねが3倍以上獲得しやすい、って話もあり、
1年ごとくらいで集計したほうが、レース的になって楽しい?と思いました

上位ユーザや、ライバルユーザが、どんな記事を書いているのか、
ユーザごとに見るのも良いヒマつぶしに勉強になります♪

※2017年のいいね数でソート、なども出来ます。
※他のデータと同様に、月次くらいで更新していく予定です。

Qiitaの殿堂 とは?(改めて)

Qiitaの殿堂は、
上位1~2%の超人気記事を月ごとのランキング形式で紹介するサイト
見逃した良記事が多数見つかる
データ分析結果もグラフ化して公開中

詳しくは、以下の投稿をご参照。

作成動機

  • 良い記事 ⇒ いいね ⇒ 嬉しい ⇒ 良い記事 の循環を良くしたい
  • 良い記事が過去の時の中に埋没されてしまいがち
    • 検索で出る課題解決型の良い記事ではなく、「面白い記事」の話
  • ゴミ記事書くな vs 兎に角アウトプット の論争は、条件付きでアウトプット派
    • 条件=「良記事が目立つ仕組みが様々な角度からいろいろ存在すること」
      • 例えばテニスなどスポーツ界でも、アマチュアが増えるのは良いこと
      • 裾野が広い方が、その分野が伸びるのは原則レベルの当たり前な話
      • でも、プロの放送に混ざって初心者がテレビに映っていたら?
      • 一見してすぐ分かる/除外出来ても、イヤという声も理解できる
      • (ミスした人を放映/注目したら、本人もイヤ、初心者にも悪影響)
    • 書くな、目立たぬ所で書け、規約守れ、とかは本質的な解決策ではない
      • 「練習場」を準備することは全く否定はしない、むしろ大賛成
      • ゴミをフィルタする試みも良い。ミスした人には優しく指摘
      • 何かの意思を持って行動することは、クチだけよりずっと良い
    • ただ、真にやるべきは、良いものを賞賛し目標化して、みなを"煽る"こと
    • みんなが見たいものをきちんとピックアップ、放送をすることが王道
    • 適切な注目の有無が、誰もが参加しやすい心理的安全性に繋がる
  • いいねだけが絶対指標ではないが、いいねは必要悪的な存在
    • きちんと称賛、きちんと喜べると、日本の技術者全体が発展
    • 経済におけるお金、身体における血液、的な存在へ
    • (低いいね記事からの、AIによるピックアップも、前に挑戦している
  • 現状のQiitaは、名画があるのに乱雑に置かれてホコリをかぶる美術館
    • Qiitaで、役立った、新しい知識が得れた経験は多いハズ(名画はある)
    • でも、最近描かれた一部の絵が入り口にあるだけ
    • 検索も弱く、名画の前にゴミが覆い被さるような場合も
  • ピックアップ力が弱い/視点が足りない感
    • 「トレンド系」は、直近の話題性は高いが、ライトユーザお断り状態
    • ユーザランキングは固定化or意味が乏しく、"煽り"として不十分
    • 特定技術を知りたい初心者が、ふわっと検索しても良記事にたどり着けない
  • 様々な角度から、良記事/良ユーザが目立ち、賞賛されれば、好循環は回る
    • そこで、過去までさかのぼり「殿堂入り」は、作るのが楽な割に有効
      • 名誉感を出すと、書き手もモチベも向上するのでは
    • そこで、「年ごと」ユーザランキングならペナントレース感
      • 感覚的には、N年前=1/N化して積算する値が良い気がする
      • 初年度は1倍、1年たつと半分、2年で1/3か1/4とか
      • TOP10ではなく、TOP3000表示。身近なライバルを作成="煽り"
    • そこで、「タグごと」に出せば初めて見に来た初心者にも過去が伝わる
    • (Qiita公式に差し上げたい)
  • 建設的に「行動」する意思、様々な観点の意見を「尊重」する気持ち
    • 少なくとも自分が見たいと思った角度が見れないなら「行動」する意思
    • 理想は大きく(日本全体向上)、やることは小さく(ショボい技術から)
    • 「いいね」することも小さな前向きな「行動」
    • 様々な意見/行動があって良い。否定だけするのは止めれば、前進する

以下は、サイトの技術的な内容を記載

以降は、サイトの技術的な話を少し記載します。(興味のある人だけ)
ほぼ全て、以下の記事に記載済みで、多少の工夫をここに追記します。

ユーザ名ごとの集計は、辞書形式を使い、月ごとに実施

ユーザごとの情報が欲しいからといって、
sqliteのDBにユーザの人数分のクエリを投げるようなことをしては、
いつまでも処理が終わらなくなります。

Qiitaの全期間の情報はかなり重いため、一度に参照するのではなく、
基本的に「月ごと」にDBから取得してきて、
その「月ごと」データに対して集計処理を繰り返すのがベターです。
(GCPの無料インスタンスなので非力です)

また、「ユーザごとに集計」する場合、どんなユーザが居るか分からないため、
pythonの辞書形式を使い、.setdefaultで、
初めて出てきたユーザ名に対してはデフォルト値を与えるようにすると、
集計がしやすいです。
(つまり、「ユーザ系のAPI」ではなく「記事情報」からデータを作っています。
 「Contribution」ではなく、純粋な記事へのいいね数だけ見ています)
Pythonでデータ分析/集計をする際には良く使う手法だと思われます。

一部を抜粋したコードとしては、こんな感じです。

ユーザごと集計の心臓部分抜粋
#「item_list」は、月ごとに取得した記事のデータ
for item in item_list:
    #いいね数
    iine = item[2]
    #ユーザID
    user_id = item[8]
    #ユーザ名
    user_name = item[9]
    #user_followers_count
    user_followers_count = item[12]
    #件数
    user_items_count = item[14]

    try:
        #初めて出たキー(ユーザ名)ならばデフォルト設定する。
        usr_dict.setdefault(user_id, {'名前': '', 'Followers': '', '総投稿数': 0, '~2015年
': 0, '2016年': 0, '2017年': 0, '2018年': 0})
        #文字数制限
        usr_dict[user_id]['名前'] = user_name[:20]
        usr_dict[user_id]['Followers'] = user_followers_count
        usr_dict[user_id]['総投稿数'] = user_items_count
        if year>2017:
            usr_dict[user_id]['2018年'] += iine
        elif year==2017:
            usr_dict[user_id]['2017年'] += iine
        elif year==2016:
            usr_dict[user_id]['2016年'] += iine
        elif year<2016:
            usr_dict[user_id]['~2015年'] += iine
    except:
        import traceback
        traceback.print_exc()
        pass

FlaskのStatic領域を活用、DBアクセスを無しに

ユーザがサイトを訪れる際には、
DBアクセス(またはQiitaAPIの利用)を一切しないようにしています。

事前に、集計データや、記事リストを、
FlaskのStatic領域にファイル(CSVやHTML)として出力しておき、
ユーザがサイトを訪れる際には、それを参照するだけ、です。

GCPの無料枠運用でサーバが貧弱なのもありますが、
余計な(複雑な)処理が入らないため、
エラー等でサイトが落ちるのを未然に防げます。

例えば、タグの目次のページを例に説明します。
以下のようなHTMLになっています。

タグの目次ページから抜粋
<head>
<script src="jquery-1.11.2.min.js"></script>
<script>
  //htmlパーツ読み込み
  $(function() {
       $("#main_data").load("/static/TAG_DENDOU/TAG_MIDASI.html");
  });
</script>
</head>

<body>
<h1>Qiita殿堂入り記事のタグごとまとめ(β)</h1>
<hr>

<div id="main_data">
  ここに、タグごとの記事情報が読み込まれます
</div>

</body>

TAG_MIDASI.htmlは、事前にpythonで生成した、
ほぼただのテキストデータ的な、タグ情報のリストが書かれています。
<li>自然言語処理 (68)</li> のような羅列)

「中央に表示するデータ」+ 「タイトルや装飾など」

の二つをhtmlファイルとして分離し、データはpythonで事前にバッチ生成。
タイトルや装飾などhtml全体は、普通のhtmlとして用意しておき、
$("#main_data").load の部分でデータを読み込んでいます。

Flaskを使う場合、pythonの変数をhtml側に渡せるため、
通常は、templateフォルダ側に、メインとなるhtmlを配置し、
python内の値として表示用のデータを与えることが多いかもしれません。

ここでは、あまりやり方に拘らず、Flaskを使いつつも、
simpleHTTPServerと同様の低レベルな扱い方をして、
ただのhtml分割と同様の手法を採用しました。作成とメンテが楽です。

定期的に情報を更新すると言っても、瞬間的には「静的サイト」であるため、
Flask内の処理は対して要りません。また、static領域のファイルの更新は、
「ctrl+F5」で適用され、template側と違いFlask再起動が不要な点も楽です。

(マジメな人から見ればたぶんバッドノウハウです。
 あくまで軽度に運用、平易に作りたい人向け)

余談ですが、何かサービスやアプリを個人開発しようと思いつつ、
一回も"リリース"までたどり着いたことのない人は多い気がします。
最初からなぜか理想を高く持ちすぎてしまい、「公開」まで
辿り着く前に力尽き飽きることが多いのではないでしょうか。
最小の手間で、多少はユーザが使えるレベル、を作り、
まず「公開」を目指すのが良い、と考えます。
Webサービスでも、リアルタイムにデータ更新する要件を捨てても、
十分有用な場合があり、その割に難易度は一気に下がります。
捨てる箇所は必ずしもDB部分でなくても良いのですが、
リリースまで行かない人は、技術力が低いのではなく、
なにかの割り切り、最小化について、考慮不足なのかなと思います。

csv2table.jsで、行ごとに交互に色を付ける方法

csv2table.jsは、CSVファイルを読み込んで、
表形式でHTML内に表示できるライブラリです。
見やすくするために、行ごとに交互に色を付けたくなります。

Qiita ユーザランキング(年別)のページで採用しています。

onload :部分で、evenの場合に背景色を設定すればOK!

csv2table.js部分抜粋
<div id="user_ranking" class="collapse">
     user_ranking<br>
  <div id="user_ranking"></div>
</div>

<script>
    $(function(){
      $('#user_ranking').csv2table('./user_iine.csv',{
          onload : function(id,op,data,ary){
          $('tr:even','#'+id).css('background','#eee')
        }
      });
     });
</script>

おしまい!

Qiitaの殿堂」 が
みなさまにとって、良い知見が得れる場になりますように!

もし良い知見が得られたら
「いいね」や「他の人への紹介」も、
とても素晴らしい前向きな行動だと思います!