北見の御菓子を食べまくる会。北見菓子。
宣伝しないと人は来ない→ぼっちが御菓子勝手に食ってる謎の会→ヤバい
ということで、TwitterBotが頑張って宣伝すればいいと思い、書き始めることに。
1.概要
以下の面子で戦うことに。
python2.7.2
tweepy1.8
さくらのvpsの一番安いの借りてるから、そこで働いてもらう事に。
OSはFreesBSDで、バージョンが...
% uname -a
どうやら、8.1のようです。
じゃあ、ソースとか載せてみます。
#! /usr/local/bin/python # -*- coding: utf-8 -*- import tweepy import datetime import random sweets = [ "マンゴープリン", "チーズケーキ", "シュークリーム", "チョコケーキ", "コーヒーゼリー", "ワッフル" ] def authentication(): consumer_key = "" consumer_secret = "" access_key = "" access_secret = "" auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_key, access_secret) return tweepy.API(auth_handler = auth) api = authentication() def tweet(tweet_str): api.update_status(tweet_str.decode("utf8")) url = "http://atnd.org/events/31345" lim = datetime.datetime(2012, 8, 7, 15) - datetime.datetime.now() hours = lim.days * 24 + int(lim.seconds / 3600) time = "後" + str(hours) + "h" if hours >= 0: tweet(random.choice(sweets) + "とか買ってくる!皆で御菓子食べよう!→ " + url + " [" + time + "]")
御菓子のリストとか雑ですね。
# はてなのスーパーpre記法はすごいですね。色までついちゃって。
また、tweepyとかpythonの最初の方の躓きポイントは、
にちょろっと書いてあります。(書いたのが自分だからもう何でも有り。)
2.記事を書くきっかけ
実はこのソースは、version 1.1くらいのもの。
hours = lim.days * 24 + int(lim.seconds / 3600) time = "後" + str(hours) + "h" if hours >= 0: tweet(random.choice(sweets) + "とか買ってくる!皆で御菓子食べよう!→ " + url + " [" + time + "]")
の部分はもともと、
time = "後" + str(lim.days * 24 + int(lim.seconds / 3600)) + "h" if lim.days > 0 or lim.seconds > 0: tweet(random.choice(sweets) + "とか買ってくる!皆で御菓子食べよう!→ " + url + " [" + time + "]")
って感じになってた。
何がしたかったかというと、
「cronに設定しておくのはいいんだけど、イベント終了時に速攻でcronから消すのめんどいから、時間見てツイートするかどうかくらい、自分で判断しろよbotめ」
ということ。
これでいいべー。とか思ってたら、
[ 後 - 3 h ]
全然かいくぐってんじゃねぇか。
どうしたどうしたと言いながら
% crontab -e
仕方なかった。しかし、なぜこんなことになっちゃったんでしょうね。
3.datetimeとtimedelta
時間云々をいじくる時にはdatetimeモジュールの力を借りましょう。
使い方とかは無視して、今回躓いたところを書き残しておきます。
あと、これ以降
#! /usr/local/bin/python # -*- coding: utf-8 -*- import datetime
は省略して書いてありますので、ご了承ください。
timedelta.hourなんてなかった
timedeltaのインスタンスが持ってるのは days, seconds, microseconds の3つだそうです。
hoge = datetime.timedelta(hours=10) print hoge.hour 実行結果: Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'datetime.timedelta' object has no attribute 'hour'
怒られた。当然である。ややこしくねー?
インスタンス生成するときは hours ぶち込めるのに、見れないとか。
しかし、datetime.hourはある。
hoge = datetime.datetime(2012, 8, 19, hour=5) print hoge.hour 実行結果: 5
s 付くとか付かないとか以前に、そもそも hour が無い訳ないという思い込みに時間を喰われました。
timedelta.secondsは負にならない
改めて見ると、何故見落としたのか理解に苦しみます。
せっかくなので、ちょっと実験してみました。
today = datetime.datetime(2012, 8, 19, 0) yesterday = datetime.datetime(2012, 8, 18, 12) ty = today - yesterday print ty.days, "日", ty.seconds / 3600, "時間" yt = yesterday - today print yt.days, "日", yt.seconds / 3600, "時間" 実行結果: 0 日 12 時間 -1 日 12 時間
これでわかったのは、「days日後のhours時間後」という見方をしていること。
0日後の12時間後 → 0 * 24 時間 + 12 時間 後 = 12 時間後 -1日後の12時間後 → -1 * 24 時間 + 12 時間 後 = -12 時間後
秒は常に正であることから、時間を進めることしか出来ないってこと。
そこで、正負を持てる、つまり時間を進めたり戻したりできる日で調整するって感じかなぁ。