[[ともっくす alloc] init]

ともっくすの雑多な日記と技術的なメモ

Google Analyticsで曜日別とか時間別でのアクセス数とかを知りたい

タイトル通り.

アクセスなんてまだまだ全然少ないけど,0ではないという現状.

はてなブログアクセス解析を見てみると,土曜日と日曜日が圧倒的に少ない.

で,何曜日が一番アクセス数が多いんだ?という素朴な疑問に至る.

というわけで,Google Analyticsを使って,曜日別・時間別のアクセス数を調べる.

色々ググったけれども,なんかうまくいない.

で,最終的になんとかなったので,ブログにメモ的なアレ.

Google Analyticsでカスタムレポート!

曜日別レポート

曜日別レポートから.

まず,Google Analyticsのこのページの「カスタマイズ」を選択する.

f:id:o_tomox:20131216181031p:plain


そしたら,カスタムレポートを作成するページになる.

今回は既に作成してあるので,2つのカスタムレポートがあるが,作成したことがないなら,何も表示されない.

で,「新しいカスタムレポート」を選択する.

f:id:o_tomox:20131216181244p:plain


実際にカスタムレポートの詳細を設定していく.

「タイトル」は分かりやすいものを入力する.
ここでは,「曜日別レポート」になっている.

「指標グループ」にはカスタムレポートで見たい内容を設定する.

「ディメンション」を「曜日の名前」とする.
ここで,曜日の名前が選択できない場合には,指標グループの内容を変えてみたら選択できるようになるかも.
指標によっては,曜日の名前が選択できない場合がある.多分.

で,最後に保存する.

f:id:o_tomox:20131216181707p:plain


これで,曜日別のカスタムレポートができた.

実際に【カスタマイズ > 曜日別レポート】から見てみると,こんな感じ.

曜日が訪問数の多い順番に並んでいるのが分かる.

つまり,このブログは,金水の訪問数が多く,土日の訪問数が少ないということ.

まあ,どっちにしても少ないんだけど,恥ずかしいから隠しておく.

f:id:o_tomox:20131216181955p:plain

時間別レポート

時間別レポートも曜日別レポートと途中まで同じで,「ディメンション」を「時」にするだけ.

f:id:o_tomox:20131216182124p:plain


これで,時間別レポートができて,実際に見てみると,こんな感じ.

訪問数の多い時間が順番に並んでいる.

このブログはなぜか15時が多い.

普通,昼間とか夜のような気がするんだけど.

f:id:o_tomox:20131216182301p:plain


まあ,こんな感じ!

Facebookの友達といつ友達になったかが知りたい

Facebookの友達のpostを見て,「この人といつ友達になったんだ?」と思うことがあった.

で,いつ友達になったかを知る方法.


プロフィールからアクティビティログを見る.

そしたら,こんな感じで,過去のアクティビティログがずらーって並んでる.

f:id:o_tomox:20131212173255p:plain

で,「他を見る」を選択すると,項目が増える.

f:id:o_tomox:20131212173328p:plain

そして,その中から「友達」を選択する.

そうすると,リクエスト送信と友達になるっていうアクティビティだけが表示されるので,そこを辿っていくと,特定の友達といつ友達になったかがわかる.

f:id:o_tomox:20131212173518p:plain

mkvirtualenvで作った環境名を変更したい

過去に

mkvirtualenv env-hoge

という風にenv-hogeという環境を作ったものの,env-fugaに変えたいと思ったときのやり方.

virtualenvには,

  • mkvirtualenv: 環境を作成する
  • cpvirtualenv: 環境をコピーする
  • rmvirtualenv: 環境を削除する

っていうのがある.

つまり,

cpvirtualenv env-hoge env-fuga
rmvirtualenv env-hoge

とすればいい.

ただし,環境を削除する前に,deactivateでその削除した環境から出ておく必要がある.

Flaskでurl_forを使うときに相対URLじゃなくて絶対URLが欲しい

FlaskであるビューのURLを取得したいとき,たいていはurl_forメソッドを使う.

ただ,url_forはデフォルトでは相対URLしか返してくれない.

絶対URLが欲しいときには,_external=Trueをパラメータとして与えるといい.

例えば,

url = url_for("index", _external=True)

みたいにする.

「ゲームマスターのための人狼」というアプリを公開した

タイトルの通り.

ゆっくりと(じっくりではない)開発を進めてきたアプリがようやく公開に至ったので,報告をば.


アプリ名は「ゲームマスターのための人狼」

人狼というゲームを行うときに使用する.

人狼についての説明は素晴らしい他サイト様を参考に.

で,その人狼にはゲームマスターという司会進行役の人が必要になるのだけど,結構慣れてないと難しい.

そんなゲームマスターの助けてくれるのが,今回公開したアプリ.


特徴としては,

  • ゲームマスター役の人は指示に従って入力したり,表示されるセリフを読むだけで,ゲームを進行できる
  • 初めから多くの役職が登録されている
  • ゲームの流れやゲームの成績(勝率や人狼になった回数)を確認することができる

といったことがある.


ゲームマスター無しで遊べるアプリとかもあるけど,ゲームマスターは生身の人がした方が楽しい気がする.というスタンス.


アプリのアイコン
f:id:o_tomox:20131206183733p:plain

スクリーンショット
f:id:o_tomox:20131206183830p:plain:w200|f:id:o_tomox:20131206183837p:plain:w200|f:id:o_tomox:20131206183844p:plain:w200
f:id:o_tomox:20131206183850p:plain:w200|f:id:o_tomox:20131206183855p:plain:w200

こんな感じのアプリ.


開発者からみた,このアプリの問題は,このアプリは1人がダウンロードすればいいからダウンロード数が伸びなさそうなところ.

まあ,そもそもダウンロードなんてされないわけだけど.


良ければ使って下さい.

フィードバックも待ってます.

Flaskのチュートリアルをやってみる② 〜ビューから実行まで

前回の続き.

ビュー

エントリーページ

データベースに保存されている全てのエントリーの一覧のページ.ルートでもある.

以下をflaskr.pyに追記する.

@app.route('/')
def show_entries():
    cur = g.db.execute('select title, text from entries order by id desc')
    entries = [dict(title=row[0], text=row[1]) for row in cur.fetchall()]
    return render_template('show_entries.html', entries=entries)

データベースから全てのエントリーを取り出し,レンダリングテンプレートとしてshow_entries.htmlを指定している.

エントリー追加

エントリーを追加するためのページで,ログインしているユーザしかアクセスできない.

以下をflaskr.pyに追記する.

@app.route('/add', methods=['POST'])
def add_entry():
    if not session.get('logged_in'):
        abort(401)
    g.db.execute('insert into entries (title, text) values (?, ?)',
                 [request.form['title'], request.form['text']])
    g.db.commit()
    flash(u'新しいエントリーが追加されました')
    return redirect(url_for('show_entries'))

POSTリクエストのみが受け付けられ,エントリーの追加処理が正常終了するとshow_entriesページにリダイレクトされる.

ユーザがログインしているかどうかの判定には,sessionのlogged_inを使用している.

続きを読む

Flaskのチュートリアルをやってみる① 〜環境設定からデータベースまで

Flaskのチュートリアルをやるに当たって参考にしたサイトはこちら.

本家と日本語訳サイトがあるが,日本語訳サイトは本家に比べて古いので若干異なる部分があるうえ,日本語訳されていない部分が多い.

ということで,英語に抵抗がないならもちろん本家で,苦手なら日本語訳サイトを見つつ本家と比べながら進めるのが良いかと.

とりあえず,日本語訳サイトだけを鵜呑みにするのは良くないかもしれない.

完成版.
f:id:o_tomox:20131127184519p:plain

チュートリアルをそのままじゃなくて,ちょっと変えてるので,一応GitHubにあげとこう.
> o-tomox/flaskr · GitHub

内容

このチュートリアルではflaskrというブログアプリケーションを作成する.

すごく簡単にできる.

機能としては以下がある.

  1. 設定したユーザーのみがログイン,ログアウト可能
  2. ログインした状態でのみ新規エントリーを作成可能
  3. すべてのエントリーを表示可能で,新しいエントリーが上に表示

全てチュートリアル通りに記述するわけではないことに注意.

で,チュートリアルは基本的に全て英語だが,以降は日本語で作っていく.

変な日本語があったとしても,それは原文にほぼ忠実だからだと思ってほしい…

環境設定等

まず,Flaskをインストールして,以下のようなフォルダを作成する.

/flaskr
    /static
    /templates

実際には,こんな感じで作成していく.

$ mkvirtualenv env-flasktut
$ pip install Flask
$ mkdir flaskr
$ cd flaskr
$ mkdir static templates

staticフォルダには,CSSやJSファイル,各種画像を置いていき,templatesフォルダには,Jinja2テンプレートファイルを置いていく.

で,次にflaskrで使うデータベースを用意する.

schema.sqlというファイルを作り,以下を記述する.

drop table if exists entries;
create table entries (
  id integer primary key autoincrement,
  title string not null,
  text string not null
);

見たらわかるように,これは各エントリーを格納しておくテーブルで,titleとtextという属性を持つ.

続きを読む

Flaskについて勉強してみたいのでとりあえずインストールとかしてみる

過去にチュートリアルをしたり,簡単なWebアプリケーションを作ったり,Pyramidはちょっとだけかじった.

で,今回はFlaskに挑戦しようと思う.

Pyramidも全然理解していないのにとか,そういうのは,まあ,いいでしょう.

なんで,Flaskをやってみようと思ったかというと,なんとなく.

一つを完全に平らげるのもいいけど,俺の今のポテンシャルだとどうせ途中でお腹いっぱいになるので,それなら色んな料理をちょっとずつ味見しようと思ったって感じ.

Flaskとは

Wikipedia様によると,

Flask(フラスク)は、プログラミング言語Python用の、軽量なウェブアプリケーションフレームワークである。Werkzeug WSGIツールキットとJinja2テンプレートエンジンを基に作られている。BSDライセンスで公開されている。

Flask - Wikipedia

ということらしい.

さらに,

Flaskは、標準で提供する機能を最小限に保っているため、自身を「マイクロフレームワーク」と呼んでいる。Flask自身は、他のフレームワークがしばしば持っているような、データベース抽象化レイヤやフォーム値の検証などの機能を持たない。

Flask - Wikipedia

だと.

まあ,つまり,FlaskはWerkzeugとJinja2をベースにした小さいフレームワークで必要最低限の機能しか持たないということ.多分.

インストール

virtualenvwrapperを使った場合だと,

$ mkvirtualenv env-flask
$ pip install Flask

これだけ.

Hello World

hello.pyというファイルを作って,以下を記述する.

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return "Hello World!"

if __name__ == '__main__':
    app.run()

で,env-flask環境で,実行するだけ.

$ python hello.py
 * Running on http://127.0.0.1:5000/

こんな感じになるので,http://127.0.0.1:5000/にアクセスする.

すると,画面に「Hello World!」と表示される.



次はチュートリアルをしてみよう.

GitHubのロゴとかオクトキャットとかの画像が欲しい

GitHubのロゴとかオクトキャットの画像を使いたいと思うことがあるかもしれない.

オクトキャットとは,GitHubの猫+タコのキャラクター.

これ.


で,画像は公式サイトから手に入れることができる.
> GitHub Logos and Usage · GitHub

zipファイルをダウンロードすると,中身はpngとかjpgとかpsdとかvectorとか,色々ある.

好きなのを使えばいい.


利用規約みたいなのもある.

Do these awesome things

  1. Use the Octocat or GitHub logo to link to GitHub
  2. Use the Mark in social buttons to link to your GitHub profile or project
  3. Use the Octocat or GitHub logo to advertise that your product has built-in GitHub integration
  4. Use the Octocat or GitHub logo in a blog post or news article about GitHub

Please don’t do these things

  1. Use the Octocat or GitHub logo for your application' s icon
  2. Create a modified version of the Octocat or GitHub logo
  3. Integrate the Octocat or GitHub logo into your logo
  4. Use any GitHub artwork without permission
  5. Sell any GitHub artwork without permission
  6. Change the colors, dimensions or add your own text/images


まあ,改変せずに普通に使えばいいかと.

NSArrayの全ての要素に対して一斉にメッセージを送りたい

NSArrayの全ての要素に対して一括で同じ処理をしたいときなんかがある.

全ての要素が同じインスタンスメソッドを持っているなら,それを簡単に実行することができる.


まあ,例えば,クラスPersonの属性に身長heightがあって,さらに身長を1cm伸ばすようなインスタンスメソッドgrowUpがあるとする.

で,NSArrayの要素として,Personのインスタンスがたくさん入ってるときに,その全ての要素に対してgrowUpを呼びたいときがあるかもしれない.*1

そんなときは,NSArrayのメソッドのmakeObjectsPerformSelector:を使えばいい.引数は呼ばたいメソッドのセレクタ

引数を与えたいときは,makeObjectsPerformSelector:withObject:を使う.

使ってみる

こんな感じのクラスがあったとき,

Personクラス

  • 属性:height
  • メソッド:growUp(heightを1だけ増やす)
  • メソッド:growUpWithDifference:(heightを引数分増やす)

こんな感じでできる.

Person *ichiro = [[Person alloc] init];
Person *jiro = [[Person alloc] init];
Person *saburo = [[Person alloc] init];

NSArray *members = @[ichiro, jiro, saburo];

// 全員の身長が1cm伸びる
[members makeObjectsPerformSelector:@selector(growUp)];

// 全員の身長が10cm伸びる
// プリミティブ型は渡せないので変換する必要がある
[members makeObjectsPerformSelector:@selector(growUpWithDifference:) withObject:@(10)];


enumerateObjectsUsingBlock:ってのもあるんだけど,どっちを使うのがいいんだろうか.

適材適所なのかどうなのか.

それに,これって,mapだよね? たぶん.

*1:もっと実用的な例を考えるのが面倒だったとかそういうわけではない